Mercurial > dropbear
comparison libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c @ 399:a707e6148060
merge of '5fdf69ca60d1683cdd9f4c2595134bed26394834'
and '6b61c50f4cf888bea302ac8fcf5dbb573b443251'
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 03 Feb 2007 08:20:34 +0000 |
parents | 0cbe8f6dbf9e |
children | f849a5ca2efc |
comparison
equal
deleted
inserted
replaced
394:17d097fc111c | 399:a707e6148060 |
---|---|
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.com | |
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, void *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 = 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 = 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 void *tmp; | |
91 if (mp_init(&tmp) != CRYPT_OK) { | |
92 return CRYPT_MEM; | |
93 } | |
94 | |
95 if (mp_2expt(tmp, mp_count_bits(num)) != CRYPT_OK || mp_sub(num, tmp, num) != CRYPT_OK) { | |
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.4 $ */ | |
110 /* $Date: 2006/03/31 14:15:35 $ */ |