Mercurial > dropbear
comparison libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c @ 1511:5916af64acd4 fuzz
merge from main
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 17 Feb 2018 19:29:51 +0800 |
parents | 6dba84798cd5 |
children |
comparison
equal
deleted
inserted
replaced
1457:32f990cc96b1 | 1511:5916af64acd4 |
---|---|
3 * LibTomCrypt is a library that provides various cryptographic | 3 * LibTomCrypt is a library that provides various cryptographic |
4 * algorithms in a highly modular and flexible manner. | 4 * algorithms in a highly modular and flexible manner. |
5 * | 5 * |
6 * The library is free for all purposes without any express | 6 * The library is free for all purposes without any express |
7 * guarantee it works. | 7 * guarantee it works. |
8 * | |
9 * Tom St Denis, [email protected], http://libtom.org | |
10 */ | 8 */ |
11 #include "tomcrypt.h" | 9 #include "tomcrypt.h" |
12 #include <stdarg.h> | |
13 | 10 |
14 | 11 |
15 /** | 12 /** |
16 @file der_decode_sequence_ex.c | 13 @file der_decode_sequence_ex.c |
17 ASN.1 DER, decode a SEQUENCE, Tom St Denis | 14 ASN.1 DER, decode a SEQUENCE, Tom St Denis |
29 @return CRYPT_OK on success | 26 @return CRYPT_OK on success |
30 */ | 27 */ |
31 int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, | 28 int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, |
32 ltc_asn1_list *list, unsigned long outlen, int ordered) | 29 ltc_asn1_list *list, unsigned long outlen, int ordered) |
33 { | 30 { |
34 int err, type; | 31 int err, i; |
35 unsigned long size, x, y, z, i, blksize; | 32 ltc_asn1_type type; |
33 unsigned long size, x, y, z, blksize; | |
36 void *data; | 34 void *data; |
37 | 35 |
38 LTC_ARGCHK(in != NULL); | 36 LTC_ARGCHK(in != NULL); |
39 LTC_ARGCHK(list != NULL); | 37 LTC_ARGCHK(list != NULL); |
40 | 38 |
41 /* get blk size */ | 39 /* get blk size */ |
42 if (inlen < 2) { | 40 if (inlen < 2) { |
43 return CRYPT_INVALID_PACKET; | 41 return CRYPT_INVALID_PACKET; |
44 } | 42 } |
45 | 43 |
48 if (in[x] != 0x30 && in[x] != 0x31) { | 46 if (in[x] != 0x30 && in[x] != 0x31) { |
49 return CRYPT_INVALID_PACKET; | 47 return CRYPT_INVALID_PACKET; |
50 } | 48 } |
51 ++x; | 49 ++x; |
52 | 50 |
51 /* check if the msb is set, which signals that the | |
52 * 7 lsb bits represent the number of bytes of the length | |
53 */ | |
53 if (in[x] < 128) { | 54 if (in[x] < 128) { |
54 blksize = in[x++]; | 55 blksize = in[x++]; |
55 } else if (in[x] & 0x80) { | 56 } else { |
56 if (in[x] < 0x81 || in[x] > 0x83) { | 57 if (in[x] < 0x81 || in[x] > 0x83) { |
57 return CRYPT_INVALID_PACKET; | 58 return CRYPT_INVALID_PACKET; |
58 } | 59 } |
59 y = in[x++] & 0x7F; | 60 y = in[x++] & 0x7F; |
60 | 61 |
66 /* read len */ | 67 /* read len */ |
67 blksize = 0; | 68 blksize = 0; |
68 while (y--) { | 69 while (y--) { |
69 blksize = (blksize << 8) | (unsigned long)in[x++]; | 70 blksize = (blksize << 8) | (unsigned long)in[x++]; |
70 } | 71 } |
71 } | 72 } |
72 | 73 |
73 /* would this blksize overflow? */ | 74 /* would this blksize overflow? */ |
74 if (x + blksize > inlen) { | 75 if (x + blksize > inlen) { |
75 return CRYPT_INVALID_PACKET; | 76 return CRYPT_INVALID_PACKET; |
76 } | 77 } |
77 | 78 |
78 /* mark all as unused */ | 79 /* mark all as unused */ |
79 for (i = 0; i < outlen; i++) { | 80 for (i = 0; i < (int)outlen; i++) { |
80 list[i].used = 0; | 81 list[i].used = 0; |
81 } | 82 } |
82 | 83 |
83 /* ok read data */ | 84 /* ok read data */ |
84 inlen = blksize; | 85 inlen = blksize; |
85 for (i = 0; i < outlen; i++) { | 86 for (i = 0; i < (int)outlen; i++) { |
86 z = 0; | 87 z = 0; |
87 type = list[i].type; | 88 type = list[i].type; |
88 size = list[i].size; | 89 size = list[i].size; |
89 data = list[i].data; | 90 data = list[i].data; |
90 if (!ordered && list[i].used == 1) { continue; } | 91 if (!ordered && list[i].used == 1) { continue; } |
91 | 92 |
92 if (type == LTC_ASN1_EOL) { | 93 if (type == LTC_ASN1_EOL) { |
93 break; | 94 break; |
94 } | 95 } |
95 | 96 |
96 switch (type) { | 97 switch (type) { |
97 case LTC_ASN1_BOOLEAN: | 98 case LTC_ASN1_BOOLEAN: |
98 z = inlen; | 99 z = inlen; |
99 if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) { | 100 if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) { |
101 if (!ordered) { continue; } | |
100 goto LBL_ERR; | 102 goto LBL_ERR; |
101 } | 103 } |
102 if ((err = der_length_boolean(&z)) != CRYPT_OK) { | 104 if ((err = der_length_boolean(&z)) != CRYPT_OK) { |
103 goto LBL_ERR; | 105 goto LBL_ERR; |
104 } | 106 } |
105 break; | 107 break; |
106 | 108 |
107 case LTC_ASN1_INTEGER: | 109 case LTC_ASN1_INTEGER: |
108 z = inlen; | 110 z = inlen; |
109 if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) { | 111 if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) { |
110 if (!ordered) { continue; } | 112 if (!ordered) { continue; } |
111 goto LBL_ERR; | 113 goto LBL_ERR; |
122 goto LBL_ERR; | 124 goto LBL_ERR; |
123 } | 125 } |
124 if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) { | 126 if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) { |
125 goto LBL_ERR; | 127 goto LBL_ERR; |
126 } | 128 } |
127 | 129 |
128 break; | 130 break; |
129 | 131 |
130 case LTC_ASN1_BIT_STRING: | 132 case LTC_ASN1_BIT_STRING: |
131 z = inlen; | 133 z = inlen; |
132 if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) { | 134 if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) { |
135 if (!ordered) { continue; } | |
136 goto LBL_ERR; | |
137 } | |
138 list[i].size = size; | |
139 if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { | |
140 goto LBL_ERR; | |
141 } | |
142 break; | |
143 | |
144 case LTC_ASN1_RAW_BIT_STRING: | |
145 z = inlen; | |
146 if ((err = der_decode_raw_bit_string(in + x, z, data, &size)) != CRYPT_OK) { | |
133 if (!ordered) { continue; } | 147 if (!ordered) { continue; } |
134 goto LBL_ERR; | 148 goto LBL_ERR; |
135 } | 149 } |
136 list[i].size = size; | 150 list[i].size = size; |
137 if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { | 151 if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { |
157 err = CRYPT_INVALID_PACKET; | 171 err = CRYPT_INVALID_PACKET; |
158 goto LBL_ERR; | 172 goto LBL_ERR; |
159 } | 173 } |
160 z = 2; | 174 z = 2; |
161 break; | 175 break; |
162 | 176 |
163 case LTC_ASN1_OBJECT_IDENTIFIER: | 177 case LTC_ASN1_OBJECT_IDENTIFIER: |
164 z = inlen; | 178 z = inlen; |
165 if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) { | 179 if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) { |
166 if (!ordered) { continue; } | 180 if (!ordered) { continue; } |
167 goto LBL_ERR; | 181 goto LBL_ERR; |
170 if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) { | 184 if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) { |
171 goto LBL_ERR; | 185 goto LBL_ERR; |
172 } | 186 } |
173 break; | 187 break; |
174 | 188 |
189 case LTC_ASN1_TELETEX_STRING: | |
190 z = inlen; | |
191 if ((err = der_decode_teletex_string(in + x, z, data, &size)) != CRYPT_OK) { | |
192 if (!ordered) { continue; } | |
193 goto LBL_ERR; | |
194 } | |
195 list[i].size = size; | |
196 if ((err = der_length_teletex_string(data, size, &z)) != CRYPT_OK) { | |
197 goto LBL_ERR; | |
198 } | |
199 break; | |
200 | |
175 case LTC_ASN1_IA5_STRING: | 201 case LTC_ASN1_IA5_STRING: |
176 z = inlen; | 202 z = inlen; |
177 if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) { | 203 if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) { |
178 if (!ordered) { continue; } | 204 if (!ordered) { continue; } |
179 goto LBL_ERR; | 205 goto LBL_ERR; |
215 if (!ordered) { continue; } | 241 if (!ordered) { continue; } |
216 goto LBL_ERR; | 242 goto LBL_ERR; |
217 } | 243 } |
218 break; | 244 break; |
219 | 245 |
246 case LTC_ASN1_GENERALIZEDTIME: | |
247 z = inlen; | |
248 if ((err = der_decode_generalizedtime(in + x, &z, data)) != CRYPT_OK) { | |
249 if (!ordered) { continue; } | |
250 goto LBL_ERR; | |
251 } | |
252 break; | |
253 | |
220 case LTC_ASN1_SET: | 254 case LTC_ASN1_SET: |
221 z = inlen; | 255 z = inlen; |
222 if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) { | 256 if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) { |
223 if (!ordered) { continue; } | 257 if (!ordered) { continue; } |
224 goto LBL_ERR; | 258 goto LBL_ERR; |
225 } | 259 } |
226 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { | 260 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { |
227 goto LBL_ERR; | 261 goto LBL_ERR; |
228 } | 262 } |
229 break; | 263 break; |
230 | 264 |
231 case LTC_ASN1_SETOF: | 265 case LTC_ASN1_SETOF: |
232 case LTC_ASN1_SEQUENCE: | 266 case LTC_ASN1_SEQUENCE: |
233 /* detect if we have the right type */ | 267 /* detect if we have the right type */ |
234 if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) { | 268 if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) { |
235 err = CRYPT_INVALID_PACKET; | 269 err = CRYPT_INVALID_PACKET; |
253 if (!ordered) { continue; } | 287 if (!ordered) { continue; } |
254 goto LBL_ERR; | 288 goto LBL_ERR; |
255 } | 289 } |
256 break; | 290 break; |
257 | 291 |
258 default: | 292 case LTC_ASN1_CONSTRUCTED: |
293 case LTC_ASN1_CONTEXT_SPECIFIC: | |
294 case LTC_ASN1_EOL: | |
259 err = CRYPT_INVALID_ARG; | 295 err = CRYPT_INVALID_ARG; |
260 goto LBL_ERR; | 296 goto LBL_ERR; |
261 } | 297 } |
262 x += z; | 298 x += z; |
263 inlen -= z; | 299 inlen -= z; |
264 list[i].used = 1; | 300 list[i].used = 1; |
265 if (!ordered) { | 301 if (!ordered) { |
266 /* restart the decoder */ | 302 /* restart the decoder */ |
267 i = -1; | 303 i = -1; |
268 } | 304 } |
269 } | 305 } |
270 | 306 |
271 for (i = 0; i < outlen; i++) { | 307 for (i = 0; i < (int)outlen; i++) { |
272 if (list[i].used == 0) { | 308 if (list[i].used == 0) { |
273 err = CRYPT_INVALID_PACKET; | 309 err = CRYPT_INVALID_PACKET; |
274 goto LBL_ERR; | 310 goto LBL_ERR; |
275 } | 311 } |
276 } | 312 } |
277 err = CRYPT_OK; | 313 |
314 if (inlen == 0) { | |
315 err = CRYPT_OK; | |
316 } else { | |
317 err = CRYPT_INPUT_TOO_LONG; | |
318 } | |
278 | 319 |
279 LBL_ERR: | 320 LBL_ERR: |
280 return err; | 321 return err; |
281 } | 322 } |
282 | 323 |
283 #endif | 324 #endif |
284 | 325 |
285 /* $Source$ */ | 326 /* ref: $Format:%D$ */ |
286 /* $Revision$ */ | 327 /* git commit: $Format:%H$ */ |
287 /* $Date$ */ | 328 /* commit time: $Format:%ai$ */ |