Mercurial > dropbear
comparison src/pk/asn1/der/der_decode_integer.c @ 191:1c15b283127b libtomcrypt-orig
Import of libtomcrypt 1.02 with manual path rename rearrangement etc
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 06 May 2005 13:23:02 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
143:5d99163f7e32 | 191:1c15b283127b |
---|---|
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 /* decodes a DER INTEGER in [in]. You have to tell this function | |
22 * how many bytes are available [inlen]. It will then attempt to | |
23 * read the INTEGER. If all goes well it stores the number of bytes | |
24 * read in [inlen] and the number in [num]. | |
25 */ | |
26 /** | |
27 Read a mp_int integer | |
28 @param in The DER encoded data | |
29 @param inlen [in] Size of the in data, [out] number of bytes read | |
30 @param num The first mp_int to decode | |
31 @return CRYPT_OK if successful | |
32 */ | |
33 int der_decode_integer(const unsigned char *in, unsigned long *inlen, mp_int *num) | |
34 { | |
35 unsigned long tmplen, y, z; | |
36 | |
37 LTC_ARGCHK(num != NULL); | |
38 LTC_ARGCHK(in != NULL); | |
39 LTC_ARGCHK(inlen != NULL); | |
40 | |
41 /* save copy of max output size */ | |
42 tmplen = *inlen; | |
43 *inlen = 0; | |
44 | |
45 /* min DER INTEGER is 0x02 01 00 == 0 */ | |
46 if (tmplen < (1 + 1 + 1)) { | |
47 return CRYPT_INVALID_PACKET; | |
48 } | |
49 | |
50 /* ok expect 0x02 when we AND with 0011 1111 [3F] */ | |
51 if ((*in++ & 0x3F) != 0x02) { | |
52 return CRYPT_INVALID_PACKET; | |
53 } | |
54 ++(*inlen); | |
55 | |
56 /* now decode the len stuff */ | |
57 z = *in++; | |
58 ++(*inlen); | |
59 | |
60 if ((z & 0x80) == 0x00) { | |
61 /* short form */ | |
62 | |
63 /* will it overflow? */ | |
64 if (*inlen + z > tmplen) { | |
65 return CRYPT_INVALID_PACKET; | |
66 } | |
67 | |
68 /* no so read it */ | |
69 (*inlen) += z; | |
70 return mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in, z)); | |
71 } else { | |
72 /* long form */ | |
73 z &= 0x7F; | |
74 | |
75 /* will number of length bytes overflow? (or > 4) */ | |
76 if (((*inlen + z) > tmplen) || (z > 4)) { | |
77 return CRYPT_INVALID_PACKET; | |
78 } | |
79 | |
80 /* now read it in */ | |
81 y = 0; | |
82 while (z--) { | |
83 y = ((unsigned long)(*in++)) | (y << 8); | |
84 ++(*inlen); | |
85 } | |
86 | |
87 /* now will reading y bytes overrun? */ | |
88 if ((*inlen + y) > tmplen) { | |
89 return CRYPT_INVALID_PACKET; | |
90 } | |
91 | |
92 /* no so read it */ | |
93 (*inlen) += y; | |
94 return mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in, y)); | |
95 } | |
96 } | |
97 | |
98 #endif |