comparison libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c @ 1471:6dba84798cd5

Update to libtomcrypt 1.18.1, merged with Dropbear changes
author Matt Johnston <matt@ucc.asn.au>
date Fri, 09 Feb 2018 21:44:05 +0800
parents f849a5ca2efc
children
comparison
equal deleted inserted replaced
1470:8bba51a55704 1471:6dba84798cd5
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$ */