]> pd.if.org Git - zpackage/blob - libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / pk / asn1 / der / sequence / der_decode_sequence_ex.c
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 #include "tomcrypt.h"
10
11
12 /**
13   @file der_decode_sequence_ex.c
14   ASN.1 DER, decode a SEQUENCE, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /**
20    Decode a SEQUENCE
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
27 */
28 int der_decode_sequence_ex(const unsigned char *in, unsigned long  inlen,
29                            ltc_asn1_list *list,     unsigned long  outlen, int ordered)
30 {
31    int           err, i;
32    ltc_asn1_type type;
33    unsigned long size, x, y, z, blksize;
34    void          *data;
35
36    LTC_ARGCHK(in   != NULL);
37    LTC_ARGCHK(list != NULL);
38
39    /* get blk size */
40    if (inlen < 2) {
41       return CRYPT_INVALID_PACKET;
42    }
43
44    /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */
45    x = 0;
46    if (in[x] != 0x30 && in[x] != 0x31) {
47       return CRYPT_INVALID_PACKET;
48    }
49    ++x;
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     */
54    if (in[x] < 128) {
55       blksize = in[x++];
56    } else {
57       if (in[x] < 0x81 || in[x] > 0x83) {
58          return CRYPT_INVALID_PACKET;
59       }
60       y = in[x++] & 0x7F;
61
62       /* would reading the len bytes overrun? */
63       if (x + y > inlen) {
64          return CRYPT_INVALID_PACKET;
65       }
66
67       /* read len */
68       blksize = 0;
69       while (y--) {
70           blksize = (blksize << 8) | (unsigned long)in[x++];
71       }
72    }
73
74    /* would this blksize overflow? */
75    if (x + blksize > inlen) {
76       return CRYPT_INVALID_PACKET;
77    }
78
79    /* mark all as unused */
80    for (i = 0; i < (int)outlen; i++) {
81        list[i].used = 0;
82    }
83
84    /* ok read data */
85    inlen = blksize;
86    for (i = 0; i < (int)outlen; i++) {
87        z    = 0;
88        type = list[i].type;
89        size = list[i].size;
90        data = list[i].data;
91        if (!ordered && list[i].used == 1) { continue; }
92
93        if (type == LTC_ASN1_EOL) {
94           break;
95        }
96
97        switch (type) {
98            case LTC_ASN1_BOOLEAN:
99                z = inlen;
100                if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) {
101                    if (!ordered) { continue; }
102                    goto LBL_ERR;
103                }
104                if ((err = der_length_boolean(&z)) != CRYPT_OK) {
105                    goto LBL_ERR;
106                }
107                break;
108
109            case LTC_ASN1_INTEGER:
110                z = inlen;
111                if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) {
112                   if (!ordered) {  continue; }
113                   goto LBL_ERR;
114                }
115                if ((err = der_length_integer(data, &z)) != CRYPT_OK) {
116                   goto LBL_ERR;
117                }
118                break;
119
120            case LTC_ASN1_SHORT_INTEGER:
121                z = inlen;
122                if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) {
123                   if (!ordered) { continue; }
124                   goto LBL_ERR;
125                }
126                if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) {
127                   goto LBL_ERR;
128                }
129
130                break;
131
132            case LTC_ASN1_BIT_STRING:
133                z = inlen;
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) {
147                   if (!ordered) { continue; }
148                   goto LBL_ERR;
149                }
150                list[i].size = size;
151                if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) {
152                   goto LBL_ERR;
153                }
154                break;
155
156            case LTC_ASN1_OCTET_STRING:
157                z = inlen;
158                if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) {
159                   if (!ordered) { continue; }
160                   goto LBL_ERR;
161                }
162                list[i].size = size;
163                if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) {
164                   goto LBL_ERR;
165                }
166                break;
167
168            case LTC_ASN1_NULL:
169                if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) {
170                   if (!ordered) { continue; }
171                   err = CRYPT_INVALID_PACKET;
172                   goto LBL_ERR;
173                }
174                z = 2;
175                break;
176
177            case LTC_ASN1_OBJECT_IDENTIFIER:
178                z = inlen;
179                if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) {
180                   if (!ordered) { continue; }
181                   goto LBL_ERR;
182                }
183                list[i].size = size;
184                if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) {
185                   goto LBL_ERR;
186                }
187                break;
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
201            case LTC_ASN1_IA5_STRING:
202                z = inlen;
203                if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
204                   if (!ordered) { continue; }
205                   goto LBL_ERR;
206                }
207                list[i].size = size;
208                if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) {
209                   goto LBL_ERR;
210                }
211                break;
212
213
214            case LTC_ASN1_PRINTABLE_STRING:
215                z = inlen;
216                if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) {
217                   if (!ordered) { continue; }
218                   goto LBL_ERR;
219                }
220                list[i].size = size;
221                if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) {
222                   goto LBL_ERR;
223                }
224                break;
225
226            case LTC_ASN1_UTF8_STRING:
227                z = inlen;
228                if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) {
229                   if (!ordered) { continue; }
230                   goto LBL_ERR;
231                }
232                list[i].size = size;
233                if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) {
234                   goto LBL_ERR;
235                }
236                break;
237
238            case LTC_ASN1_UTCTIME:
239                z = inlen;
240                if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
241                   if (!ordered) { continue; }
242                   goto LBL_ERR;
243                }
244                break;
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
254            case LTC_ASN1_SET:
255                z = inlen;
256                if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) {
257                   if (!ordered) { continue; }
258                   goto LBL_ERR;
259                }
260                if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
261                   goto LBL_ERR;
262                }
263                break;
264
265            case LTC_ASN1_SETOF:
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;
270                   goto LBL_ERR;
271                }
272
273                z = inlen;
274                if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
275                   if (!ordered) { continue; }
276                   goto LBL_ERR;
277                }
278                if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
279                   goto LBL_ERR;
280                }
281                break;
282
283
284            case LTC_ASN1_CHOICE:
285                z = inlen;
286                if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
287                   if (!ordered) { continue; }
288                   goto LBL_ERR;
289                }
290                break;
291
292            case LTC_ASN1_CONSTRUCTED:
293            case LTC_ASN1_CONTEXT_SPECIFIC:
294            case LTC_ASN1_EOL:
295                err = CRYPT_INVALID_ARG;
296                goto LBL_ERR;
297        }
298        x           += z;
299        inlen       -= z;
300        list[i].used = 1;
301        if (!ordered) {
302           /* restart the decoder */
303           i = -1;
304        }
305    }
306
307    for (i = 0; i < (int)outlen; i++) {
308       if (list[i].used == 0) {
309           err = CRYPT_INVALID_PACKET;
310           goto LBL_ERR;
311       }
312    }
313
314    if (inlen == 0) {
315       err = CRYPT_OK;
316    } else {
317       err = CRYPT_INPUT_TOO_LONG;
318    }
319
320 LBL_ERR:
321    return err;
322 }
323
324 #endif
325
326 /* ref:         $Format:%D$ */
327 /* git commit:  $Format:%H$ */
328 /* commit time: $Format:%ai$ */