1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
6 * The library is free for all purposes without any express
13 @file der_decode_sequence_ex.c
14 ASN.1 DER, decode a SEQUENCE, Tom St Denis
21 @param in The DER encoded input
22 @param inlen The size of the input
23 @param list The list of items to decode
24 @param outlen The number of items in the list
25 @param ordered Search an unordeded or ordered list
26 @return CRYPT_OK on success
28 int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
29 ltc_asn1_list *list, unsigned long outlen, int ordered)
33 unsigned long size, x, y, z, blksize;
36 LTC_ARGCHK(in != NULL);
37 LTC_ARGCHK(list != NULL);
41 return CRYPT_INVALID_PACKET;
44 /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */
46 if (in[x] != 0x30 && in[x] != 0x31) {
47 return CRYPT_INVALID_PACKET;
51 /* check if the msb is set, which signals that the
52 * 7 lsb bits represent the number of bytes of the length
57 if (in[x] < 0x81 || in[x] > 0x83) {
58 return CRYPT_INVALID_PACKET;
62 /* would reading the len bytes overrun? */
64 return CRYPT_INVALID_PACKET;
70 blksize = (blksize << 8) | (unsigned long)in[x++];
74 /* would this blksize overflow? */
75 if (x + blksize > inlen) {
76 return CRYPT_INVALID_PACKET;
79 /* mark all as unused */
80 for (i = 0; i < (int)outlen; i++) {
86 for (i = 0; i < (int)outlen; i++) {
91 if (!ordered && list[i].used == 1) { continue; }
93 if (type == LTC_ASN1_EOL) {
98 case LTC_ASN1_BOOLEAN:
100 if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) {
101 if (!ordered) { continue; }
104 if ((err = der_length_boolean(&z)) != CRYPT_OK) {
109 case LTC_ASN1_INTEGER:
111 if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) {
112 if (!ordered) { continue; }
115 if ((err = der_length_integer(data, &z)) != CRYPT_OK) {
120 case LTC_ASN1_SHORT_INTEGER:
122 if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) {
123 if (!ordered) { continue; }
126 if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) {
132 case LTC_ASN1_BIT_STRING:
134 if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
135 if (!ordered) { continue; }
139 if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) {
144 case LTC_ASN1_RAW_BIT_STRING:
146 if ((err = der_decode_raw_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
147 if (!ordered) { continue; }
151 if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) {
156 case LTC_ASN1_OCTET_STRING:
158 if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) {
159 if (!ordered) { continue; }
163 if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) {
169 if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) {
170 if (!ordered) { continue; }
171 err = CRYPT_INVALID_PACKET;
177 case LTC_ASN1_OBJECT_IDENTIFIER:
179 if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) {
180 if (!ordered) { continue; }
184 if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) {
189 case LTC_ASN1_TELETEX_STRING:
191 if ((err = der_decode_teletex_string(in + x, z, data, &size)) != CRYPT_OK) {
192 if (!ordered) { continue; }
196 if ((err = der_length_teletex_string(data, size, &z)) != CRYPT_OK) {
201 case LTC_ASN1_IA5_STRING:
203 if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
204 if (!ordered) { continue; }
208 if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) {
214 case LTC_ASN1_PRINTABLE_STRING:
216 if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) {
217 if (!ordered) { continue; }
221 if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) {
226 case LTC_ASN1_UTF8_STRING:
228 if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) {
229 if (!ordered) { continue; }
233 if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) {
238 case LTC_ASN1_UTCTIME:
240 if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
241 if (!ordered) { continue; }
246 case LTC_ASN1_GENERALIZEDTIME:
248 if ((err = der_decode_generalizedtime(in + x, &z, data)) != CRYPT_OK) {
249 if (!ordered) { continue; }
256 if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) {
257 if (!ordered) { continue; }
260 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
266 case LTC_ASN1_SEQUENCE:
267 /* detect if we have the right type */
268 if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) {
269 err = CRYPT_INVALID_PACKET;
274 if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
275 if (!ordered) { continue; }
278 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
284 case LTC_ASN1_CHOICE:
286 if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
287 if (!ordered) { continue; }
292 case LTC_ASN1_CONSTRUCTED:
293 case LTC_ASN1_CONTEXT_SPECIFIC:
295 err = CRYPT_INVALID_ARG;
302 /* restart the decoder */
307 for (i = 0; i < (int)outlen; i++) {
308 if (list[i].used == 0) {
309 err = CRYPT_INVALID_PACKET;
317 err = CRYPT_INPUT_TOO_LONG;
326 /* ref: $Format:%D$ */
327 /* git commit: $Format:%H$ */
328 /* commit time: $Format:%ai$ */