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
9 * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
16 @file der_decode_sequence_ex.c
17 ASN.1 DER, decode a SEQUENCE, Tom St Denis
24 @param in The DER encoded input
25 @param inlen The size of the input
26 @param list The list of items to decode
27 @param outlen The number of items in the list
28 @param ordered Search an unordeded or ordered list
29 @return CRYPT_OK on success
31 int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
32 ltc_asn1_list *list, unsigned long outlen, int ordered)
35 unsigned long size, x, y, z, i, blksize;
38 LTC_ARGCHK(in != NULL);
39 LTC_ARGCHK(list != NULL);
43 return CRYPT_INVALID_PACKET;
46 /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */
48 if (in[x] != 0x30 && in[x] != 0x31) {
49 return CRYPT_INVALID_PACKET;
55 } else if (in[x] & 0x80) {
56 if (in[x] < 0x81 || in[x] > 0x83) {
57 return CRYPT_INVALID_PACKET;
61 /* would reading the len bytes overrun? */
63 return CRYPT_INVALID_PACKET;
69 blksize = (blksize << 8) | (unsigned long)in[x++];
73 /* would this blksize overflow? */
74 if (x + blksize > inlen) {
75 return CRYPT_INVALID_PACKET;
78 /* mark all as unused */
79 for (i = 0; i < outlen; i++) {
85 for (i = 0; i < outlen; i++) {
90 if (!ordered && list[i].used == 1) { continue; }
92 if (type == LTC_ASN1_EOL) {
97 case LTC_ASN1_BOOLEAN:
99 if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) {
102 if ((err = der_length_boolean(&z)) != CRYPT_OK) {
107 case LTC_ASN1_INTEGER:
109 if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) {
110 if (!ordered) { continue; }
113 if ((err = der_length_integer(data, &z)) != CRYPT_OK) {
118 case LTC_ASN1_SHORT_INTEGER:
120 if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) {
121 if (!ordered) { continue; }
124 if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) {
130 case LTC_ASN1_BIT_STRING:
132 if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
133 if (!ordered) { continue; }
137 if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) {
142 case LTC_ASN1_OCTET_STRING:
144 if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) {
145 if (!ordered) { continue; }
149 if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) {
155 if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) {
156 if (!ordered) { continue; }
157 err = CRYPT_INVALID_PACKET;
163 case LTC_ASN1_OBJECT_IDENTIFIER:
165 if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) {
166 if (!ordered) { continue; }
170 if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) {
175 case LTC_ASN1_IA5_STRING:
177 if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
178 if (!ordered) { continue; }
182 if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) {
188 case LTC_ASN1_PRINTABLE_STRING:
190 if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) {
191 if (!ordered) { continue; }
195 if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) {
200 case LTC_ASN1_UTF8_STRING:
202 if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) {
203 if (!ordered) { continue; }
207 if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) {
212 case LTC_ASN1_UTCTIME:
214 if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
215 if (!ordered) { continue; }
222 if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) {
223 if (!ordered) { continue; }
226 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
232 case LTC_ASN1_SEQUENCE:
233 /* 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)) {
235 err = CRYPT_INVALID_PACKET;
240 if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
241 if (!ordered) { continue; }
244 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
250 case LTC_ASN1_CHOICE:
252 if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
253 if (!ordered) { continue; }
259 err = CRYPT_INVALID_ARG;
266 /* restart the decoder */
271 for (i = 0; i < outlen; i++) {
272 if (list[i].used == 0) {
273 err = CRYPT_INVALID_PACKET;
285 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c,v $ */
286 /* $Revision: 1.15 $ */
287 /* $Date: 2006/11/26 02:25:18 $ */