Mercurial > dropbear
comparison libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c @ 285:1b9e69c058d2
propagate from branch 'au.asn.ucc.matt.ltc.dropbear' (head 20dccfc09627970a312d77fb41dc2970b62689c3)
to branch 'au.asn.ucc.matt.dropbear' (head fdf4a7a3b97ae5046139915de7e40399cceb2c01)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Wed, 08 Mar 2006 13:23:58 +0000 |
parents | |
children | 0cbe8f6dbf9e |
comparison
equal
deleted
inserted
replaced
281:997e6f7dc01e | 285:1b9e69c058d2 |
---|---|
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
2 * | |
3 * LibTomCrypt is a library that provides various cryptographic | |
4 * algorithms in a highly modular and flexible manner. | |
5 * | |
6 * The library is free for all purposes without any express | |
7 * guarantee it works. | |
8 * | |
9 * Tom St Denis, [email protected], http://libtomcrypt.org | |
10 */ | |
11 #include "tomcrypt.h" | |
12 | |
13 /** | |
14 @file der_decode_integer.c | |
15 ASN.1 DER, decode an integer, Tom St Denis | |
16 */ | |
17 | |
18 | |
19 #ifdef LTC_DER | |
20 | |
21 /** | |
22 Read a mp_int integer | |
23 @param in The DER encoded data | |
24 @param inlen Size of DER encoded data | |
25 @param num The first mp_int to decode | |
26 @return CRYPT_OK if successful | |
27 */ | |
28 int der_decode_integer(const unsigned char *in, unsigned long inlen, mp_int *num) | |
29 { | |
30 unsigned long x, y, z; | |
31 int err; | |
32 | |
33 LTC_ARGCHK(num != NULL); | |
34 LTC_ARGCHK(in != NULL); | |
35 | |
36 /* min DER INTEGER is 0x02 01 00 == 0 */ | |
37 if (inlen < (1 + 1 + 1)) { | |
38 return CRYPT_INVALID_PACKET; | |
39 } | |
40 | |
41 /* ok expect 0x02 when we AND with 0001 1111 [1F] */ | |
42 x = 0; | |
43 if ((in[x++] & 0x1F) != 0x02) { | |
44 return CRYPT_INVALID_PACKET; | |
45 } | |
46 | |
47 /* now decode the len stuff */ | |
48 z = in[x++]; | |
49 | |
50 if ((z & 0x80) == 0x00) { | |
51 /* short form */ | |
52 | |
53 /* will it overflow? */ | |
54 if (x + z > inlen) { | |
55 return CRYPT_INVALID_PACKET; | |
56 } | |
57 | |
58 /* no so read it */ | |
59 if ((err = mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in + x, z))) != CRYPT_OK) { | |
60 return err; | |
61 } | |
62 } else { | |
63 /* long form */ | |
64 z &= 0x7F; | |
65 | |
66 /* will number of length bytes overflow? (or > 4) */ | |
67 if (((x + z) > inlen) || (z > 4) || (z == 0)) { | |
68 return CRYPT_INVALID_PACKET; | |
69 } | |
70 | |
71 /* now read it in */ | |
72 y = 0; | |
73 while (z--) { | |
74 y = ((unsigned long)(in[x++])) | (y << 8); | |
75 } | |
76 | |
77 /* now will reading y bytes overrun? */ | |
78 if ((x + y) > inlen) { | |
79 return CRYPT_INVALID_PACKET; | |
80 } | |
81 | |
82 /* no so read it */ | |
83 if ((err = mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in + x, y))) != CRYPT_OK) { | |
84 return err; | |
85 } | |
86 } | |
87 | |
88 /* see if it's negative */ | |
89 if (in[x] & 0x80) { | |
90 mp_int tmp; | |
91 if (mp_init(&tmp) != MP_OKAY) { | |
92 return CRYPT_MEM; | |
93 } | |
94 | |
95 if (mp_2expt(&tmp, mp_count_bits(num)) != MP_OKAY || mp_sub(num, &tmp, num) != MP_OKAY) { | |
96 mp_clear(&tmp); | |
97 return CRYPT_MEM; | |
98 } | |
99 mp_clear(&tmp); | |
100 } | |
101 | |
102 return CRYPT_OK; | |
103 | |
104 } | |
105 | |
106 #endif | |
107 | |
108 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c,v $ */ | |
109 /* $Revision: 1.2 $ */ | |
110 /* $Date: 2005/06/01 00:06:05 $ */ |