~ubuntu-branches/ubuntu/utopic/suricata/utopic

« back to all changes in this revision

Viewing changes to src/util-decode-der.c

  • Committer: Package Import Robot
  • Author(s): Pierre Chifflier
  • Date: 2012-07-22 22:27:36 UTC
  • mfrom: (1.1.13)
  • Revision ID: package-import@ubuntu.com-20120722222736-s2bcw3ruzenagjam
Tags: 1.3-1
* Imported Upstream version 1.3
* Add build-dependency on libnss3-dev and libnspr4-dev
* Bump Standards Version to 3.9.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2011-2012 ANSSI
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 * 1. Redistributions of source code must retain the above copyright
 
9
 *    notice, this list of conditions and the following disclaimer.
 
10
 * 2. Redistributions in binary form must reproduce the above copyright
 
11
 *    notice, this list of conditions and the following disclaimer in the
 
12
 *    documentation and/or other materials provided with the distribution.
 
13
 * 3. The name of the author may not be used to endorse or promote products
 
14
 *    derived from this software without specific prior written permission.
 
15
 *
 
16
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 
17
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 
18
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 
19
 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
20
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
21
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 
22
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 
23
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 
24
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 
25
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
26
 */
 
27
 
 
28
/**
 
29
 * \file
 
30
 *
 
31
 * \author Pierre Chifflier <pierre.chifflier@ssi.gouv.fr>
 
32
 *
 
33
 */
 
34
 
 
35
/*
 
36
 * An ASN.1 Parser for DER-encoded structures.
 
37
 * This parser is not written to be complete or fast, but is rather
 
38
 * focused on stability and security.
 
39
 * It does not support all ASN.1 structure, only a meaningful subset
 
40
 * to decode x509v3 certificates (See RFC 3280).
 
41
 *
 
42
 * References (like 8.19.4) are relative to the ISO/IEC 8825-1:2003 document
 
43
 *
 
44
 */
 
45
 
 
46
#include <stdio.h>
 
47
#include <stdlib.h>
 
48
#include <string.h>
 
49
#include <unistd.h>
 
50
 
 
51
#include <inttypes.h>
 
52
 
 
53
#include <sys/types.h>
 
54
#include <sys/stat.h>
 
55
#include <fcntl.h>
 
56
 
 
57
#include "suricata-common.h"
 
58
 
 
59
#include "util-decode-der.h"
 
60
 
 
61
#define MAX_OID_LENGTH 256
 
62
 
 
63
static Asn1Generic * DecodeAsn1DerBitstring(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
 
64
static Asn1Generic * DecodeAsn1DerBoolean(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
 
65
static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
 
66
static Asn1Generic * DecodeAsn1DerInteger(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
 
67
static Asn1Generic * DecodeAsn1DerNull(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
 
68
static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
 
69
static Asn1Generic * DecodeAsn1DerUTF8String(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode);
 
70
static Asn1Generic * DecodeAsn1DerOid(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
 
71
static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
 
72
static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
 
73
static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
 
74
static Asn1Generic * DecodeAsn1DerT61String(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
 
75
static Asn1Generic * DecodeAsn1DerUTCTime(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode);
 
76
 
 
77
static Asn1Generic * Asn1GenericNew(void)
 
78
{
 
79
    Asn1Generic *obj;
 
80
 
 
81
    obj = SCMalloc(sizeof(Asn1Generic));
 
82
    if (obj != NULL)
 
83
        memset(obj, 0, sizeof(Asn1Generic));
 
84
 
 
85
    return obj;
 
86
}
 
87
 
 
88
static void Asn1SequenceAppend(Asn1Generic *seq, Asn1Generic *node)
 
89
{
 
90
    Asn1Generic *it, *new_container;
 
91
 
 
92
    if (seq->data == NULL) {
 
93
        seq->data = node;
 
94
        return;
 
95
    }
 
96
 
 
97
    new_container = Asn1GenericNew();
 
98
    if (new_container == NULL)
 
99
        return;
 
100
    new_container->data = node;
 
101
 
 
102
    for (it=seq; it->next != NULL; it=it->next)
 
103
        ;
 
104
 
 
105
    it->next = new_container;
 
106
}
 
107
 
 
108
static Asn1Generic * DecodeAsn1DerGeneric(const unsigned char *buffer, uint32_t max_size, uint8_t depth, int seq_index, uint32_t *errcode)
 
109
{
 
110
    const unsigned char *d_ptr = buffer;
 
111
    uint32_t numbytes, el_max_size;
 
112
    Asn1ElementType el;
 
113
    uint8_t c;
 
114
    uint32_t i;
 
115
    Asn1Generic *child;
 
116
    uint8_t el_type;
 
117
 
 
118
    el.cls = (d_ptr[0] & 0xc0) >> 6;
 
119
    el.pc = (d_ptr[0] & 0x20) >> 5;
 
120
    el.tag = (d_ptr[0] & 0x1f);
 
121
 
 
122
    el_type = el.tag;
 
123
 
 
124
    if (el.tag == 0x1f)
 
125
        return NULL;
 
126
 
 
127
    switch (el.cls) {
 
128
        case ASN1_CLASS_CONTEXTSPEC:
 
129
            /* get element type from definition
 
130
             * see http://www.ietf.org/rfc/rfc3280.txt)
 
131
             */
 
132
            if (depth == 2 && el.tag == 0) {
 
133
                el_type = ASN1_SEQUENCE; /* TBSCertificate */
 
134
                break;
 
135
            }
 
136
            if (depth == 2 && el.tag == 1) {
 
137
                el_type = ASN1_BITSTRING; /* issuerUniqueID */
 
138
                break;
 
139
            }
 
140
            if (depth == 2 && el.tag == 2) {
 
141
                el_type = ASN1_BITSTRING; /* subjectUniqueID */
 
142
                break;
 
143
            }
 
144
            if (depth == 2 && el.tag == 3) {
 
145
                el_type = ASN1_SEQUENCE; /* extensions */
 
146
                break;
 
147
            }
 
148
            /* unknown context specific value - do not decode */
 
149
            break;
 
150
    };
 
151
 
 
152
    el_max_size = max_size - (d_ptr-buffer);
 
153
    switch (el_type) {
 
154
        case ASN1_INTEGER:
 
155
            child = DecodeAsn1DerInteger(d_ptr, el_max_size, depth+1, errcode);
 
156
            break;
 
157
        case ASN1_BOOLEAN:
 
158
            child = DecodeAsn1DerBoolean(d_ptr, el_max_size, depth+1, errcode);
 
159
            break;
 
160
        case ASN1_NULL:
 
161
            child = DecodeAsn1DerNull(d_ptr, el_max_size, depth+1, errcode);
 
162
            break;
 
163
        case ASN1_BITSTRING:
 
164
            child = DecodeAsn1DerBitstring(d_ptr, el_max_size, depth+1, errcode);
 
165
            break;
 
166
        case ASN1_OID:
 
167
            child = DecodeAsn1DerOid(d_ptr, el_max_size, depth+1, errcode);
 
168
            break;
 
169
        case ASN1_IA5STRING:
 
170
            child = DecodeAsn1DerIA5String(d_ptr, el_max_size, depth+1, errcode);
 
171
            break;
 
172
        case ASN1_OCTETSTRING:
 
173
            child = DecodeAsn1DerOctetString(d_ptr, el_max_size, depth+1, errcode);
 
174
            break;
 
175
        case ASN1_UTF8STRING:
 
176
            child = DecodeAsn1DerUTF8String(d_ptr, el_max_size, depth+1, errcode);
 
177
            break;
 
178
        case ASN1_PRINTSTRING:
 
179
            child = DecodeAsn1DerPrintableString(d_ptr, el_max_size, depth+1, errcode);
 
180
            break;
 
181
        case ASN1_SEQUENCE:
 
182
            child = DecodeAsn1DerSequence(d_ptr, el_max_size, depth+1, errcode);
 
183
            break;
 
184
        case ASN1_SET:
 
185
            child = DecodeAsn1DerSet(d_ptr, el_max_size, depth+1, errcode);
 
186
            break;
 
187
        case ASN1_T61STRING:
 
188
            child = DecodeAsn1DerT61String(d_ptr, el_max_size, depth+1, errcode);
 
189
            break;
 
190
        case ASN1_UTCTIME:
 
191
            child = DecodeAsn1DerUTCTime(d_ptr, el_max_size, depth+1, errcode);
 
192
            break;
 
193
        default:
 
194
            /* unknown ASN.1 type */
 
195
            child = NULL;
 
196
            child = Asn1GenericNew();
 
197
            if (child == NULL)
 
198
                break;
 
199
            child->type = el.tag;
 
200
            /* total sequence length */
 
201
            const unsigned char * save_d_ptr = d_ptr;
 
202
            d_ptr++;
 
203
            c = d_ptr[0];
 
204
            if ((c & (1<<7))>>7 == 0) { /* short form 8.1.3.4 */
 
205
                child->length = c;
 
206
                d_ptr++;
 
207
            } else { /* long form 8.1.3.5 */
 
208
                numbytes = c & 0x7f;
 
209
                if (numbytes > el_max_size) {
 
210
                    SCFree(child);
 
211
                    if (errcode)
 
212
                        *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
 
213
                    return NULL;
 
214
                }
 
215
                child->length = 0;
 
216
                d_ptr++;
 
217
                for (i=0; i<numbytes; i++) {
 
218
                    child->length = child->length<<8 | d_ptr[0];
 
219
                    d_ptr++;
 
220
                }
 
221
            }
 
222
            /* fix the length for unknown objects, else
 
223
             * sequence parsing will fail
 
224
             */
 
225
            child->length += (d_ptr - save_d_ptr);
 
226
            break;
 
227
    };
 
228
    if (child == NULL)
 
229
        return NULL;
 
230
 
 
231
    child->header = el;
 
232
    return child;
 
233
}
 
234
 
 
235
static Asn1Generic * DecodeAsn1DerInteger(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode)
 
236
{
 
237
    const unsigned char *d_ptr = buffer;
 
238
    uint8_t numbytes;
 
239
    uint32_t value;
 
240
    uint32_t i;
 
241
    Asn1Generic *a;
 
242
 
 
243
    numbytes = d_ptr[1];
 
244
 
 
245
    if (numbytes > size) {
 
246
        if (errcode)
 
247
            *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
 
248
        return NULL;
 
249
    }
 
250
 
 
251
    d_ptr += 2;
 
252
 
 
253
    value = 0;
 
254
    /* Here we need to ensure that numbytes is less than 4
 
255
       so integer affectation is possible. We set the value
 
256
       to 0xffffffff which is by convention the unknown value.
 
257
       In this case, the hexadecimal value must be used. */
 
258
    if (numbytes > 4) {
 
259
        value = 0xffffffff;
 
260
    } else {
 
261
        for (i=0; i<numbytes; i++) {
 
262
            value = value<<8 | d_ptr[i];
 
263
        }
 
264
    }
 
265
 
 
266
    a = Asn1GenericNew();
 
267
    if (a == NULL)
 
268
        return NULL;
 
269
    a->type = ASN1_INTEGER;
 
270
    a->length = (d_ptr - buffer) + numbytes;
 
271
    a->value = value;
 
272
 
 
273
    a->str = SCMalloc(2*numbytes + 1);
 
274
    if (a->str == NULL) {
 
275
        SCFree(a);
 
276
        return NULL;
 
277
    }
 
278
    for (i=0; i<numbytes; i++) {
 
279
        snprintf(a->str + 2*i, 2*(numbytes-i)+1, "%02X", d_ptr[i]);
 
280
    }
 
281
    a->str[2*numbytes]='\0';
 
282
 
 
283
    return a;
 
284
}
 
285
 
 
286
static int DecodeAsn1BuildValue(const unsigned char **d_ptr, uint32_t *val, uint8_t numbytes, uint32_t *errcode)
 
287
{
 
288
    int i;
 
289
    uint32_t value = 0;
 
290
    if (numbytes > 4) {
 
291
        if (errcode)
 
292
            *errcode = ERR_DER_INVALID_SIZE;
 
293
        /* too big won't fit: set it to 0xffffffff by convention */
 
294
        value = 0xffffffff;
 
295
        *val = value;
 
296
        return -1;
 
297
    } else {
 
298
        for (i=0; i<numbytes; i++) {
 
299
            value = value<<8 | (*d_ptr)[0];
 
300
            (*d_ptr)++;
 
301
        }
 
302
    }
 
303
    *val = value;
 
304
    return 0;
 
305
}
 
306
 
 
307
static Asn1Generic * DecodeAsn1DerBoolean(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode)
 
308
{
 
309
    const unsigned char *d_ptr = buffer;
 
310
    uint8_t numbytes;
 
311
    uint32_t value;
 
312
    Asn1Generic *a;
 
313
 
 
314
    numbytes = d_ptr[1];
 
315
    d_ptr += 2;
 
316
 
 
317
    if (DecodeAsn1BuildValue(&d_ptr, &value, numbytes, errcode) == -1) {
 
318
        return NULL;
 
319
    }
 
320
    a = Asn1GenericNew();
 
321
    if (a == NULL)
 
322
        return NULL;
 
323
    a->type = ASN1_BOOLEAN;
 
324
    a->length = (d_ptr - buffer);
 
325
    a->value = value;
 
326
 
 
327
    return a;
 
328
}
 
329
 
 
330
static Asn1Generic * DecodeAsn1DerNull(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode)
 
331
{
 
332
    const unsigned char *d_ptr = buffer;
 
333
    uint8_t numbytes;
 
334
    uint32_t value;
 
335
    Asn1Generic *a;
 
336
 
 
337
    numbytes = d_ptr[1];
 
338
    d_ptr += 2;
 
339
    if (DecodeAsn1BuildValue(&d_ptr, &value, numbytes, errcode) == -1) {
 
340
        return NULL;
 
341
    }
 
342
    a = Asn1GenericNew();
 
343
    if (a == NULL)
 
344
        return NULL;
 
345
    a->type = ASN1_NULL;
 
346
    a->length = (d_ptr - buffer);
 
347
    a->value = 0;
 
348
 
 
349
    return a;
 
350
}
 
351
 
 
352
static Asn1Generic * DecodeAsn1DerBitstring(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
 
353
{
 
354
    const unsigned char *d_ptr = buffer;
 
355
    uint32_t length;
 
356
    uint8_t numbytes, c;
 
357
    Asn1Generic *a;
 
358
 
 
359
    d_ptr++;
 
360
 
 
361
    /* size */
 
362
    c = d_ptr[0];
 
363
    if ((c & (1<<7))>>7 == 0) { /* short form 8.1.3.4 */
 
364
        length = c;
 
365
        d_ptr++;
 
366
    } else { /* long form 8.1.3.5 */
 
367
        numbytes = c & 0x7f;
 
368
        d_ptr++;
 
369
        if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
 
370
            return NULL;
 
371
        }
 
372
    }
 
373
    if (length > max_size)
 
374
        return NULL;
 
375
 
 
376
    a = Asn1GenericNew();
 
377
    if (a == NULL)
 
378
        return NULL;
 
379
    a->type = ASN1_BITSTRING;
 
380
    a->strlen = length;
 
381
    a->str = SCMalloc(length);
 
382
    if (a->str == NULL) {
 
383
        SCFree(a);
 
384
        return NULL;
 
385
    }
 
386
    memcpy(a->str, (const char*)d_ptr, length);
 
387
 
 
388
    d_ptr += length;
 
389
 
 
390
    a->length = (d_ptr - buffer);
 
391
    return a;
 
392
}
 
393
 
 
394
static Asn1Generic * DecodeAsn1DerOid(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
 
395
{
 
396
    const unsigned char *d_ptr = buffer;
 
397
    uint32_t oid_length, oid_value;
 
398
    uint8_t numbytes, c;
 
399
    Asn1Generic *a;
 
400
    uint32_t i;
 
401
 
 
402
    d_ptr++;
 
403
 
 
404
    /* size */
 
405
    c = d_ptr[0];
 
406
    if ((c & (1<<7))>>7 == 0) { /* short form 8.1.3.4 */
 
407
        oid_length = c;
 
408
        d_ptr++;
 
409
    } else { /* long form 8.1.3.5 */
 
410
        numbytes = c & 0x7f;
 
411
        d_ptr++;
 
412
        if (DecodeAsn1BuildValue(&d_ptr, &oid_length, numbytes, errcode) == -1) {
 
413
            return NULL;
 
414
        }
 
415
    }
 
416
    if (oid_length > max_size)
 
417
        return NULL;
 
418
 
 
419
    a = Asn1GenericNew();
 
420
    if (a == NULL)
 
421
        return NULL;
 
422
    a->type = ASN1_OID;
 
423
    a->str = SCMalloc(MAX_OID_LENGTH);
 
424
    if (a->str == NULL) {
 
425
        SCFree(a);
 
426
        return NULL;
 
427
    }
 
428
 
 
429
    /* first element = X*40 + Y (See 8.19.4) */
 
430
    snprintf(a->str, MAX_OID_LENGTH, "%d.%d", (d_ptr[0]/40), (d_ptr[0]%40));
 
431
    d_ptr++;
 
432
 
 
433
    /* sub-identifiers are multi valued, coded and 7 bits, first bit of the 8bits is used
 
434
       to indicate, if a new value is starting */
 
435
    for (i=1; i<oid_length; ) {
 
436
        int s = strlen(a->str);
 
437
        c = d_ptr[0];
 
438
        oid_value = 0;
 
439
        while ( i<oid_length && (c & (1<<7)) == 1<<7 ) {
 
440
            oid_value = oid_value<<7 | (c & ~(1<<7));
 
441
            d_ptr++;
 
442
            c = d_ptr[0];
 
443
            i++;
 
444
        }
 
445
        oid_value = oid_value<<7 | c;
 
446
        d_ptr++;
 
447
        i++;
 
448
        snprintf(a->str + s, MAX_OID_LENGTH - s, ".%d", oid_value);
 
449
    }
 
450
 
 
451
    a->length = (d_ptr - buffer);
 
452
    return a;
 
453
}
 
454
 
 
455
static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
 
456
{
 
457
    const unsigned char *d_ptr = buffer;
 
458
    uint32_t length, numbytes;
 
459
    Asn1Generic *a;
 
460
    unsigned char c;
 
461
 
 
462
    d_ptr++;
 
463
 
 
464
    /* total sequence length */
 
465
    c = d_ptr[0];
 
466
    if ((c & (1<<7))>>7 == 0) { /* short form 8.1.3.4 */
 
467
        length = c;
 
468
        d_ptr++;
 
469
    } else { /* long form 8.1.3.5 */
 
470
        numbytes = c & 0x7f;
 
471
        d_ptr++;
 
472
        if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
 
473
            return NULL;
 
474
        }
 
475
    }
 
476
    if (length > max_size)
 
477
        return NULL;
 
478
 
 
479
    a = Asn1GenericNew();
 
480
    if (a == NULL)
 
481
        return NULL;
 
482
    a->type = ASN1_IA5STRING;
 
483
    a->strlen = length;
 
484
    a->str = SCMalloc(length+1);
 
485
    if (a->str == NULL) {
 
486
        SCFree(a);
 
487
        return NULL;
 
488
    }
 
489
    strlcpy(a->str, (const char*)d_ptr, length+1);
 
490
 
 
491
    d_ptr += length;
 
492
 
 
493
    a->length = (d_ptr - buffer);
 
494
    return a;
 
495
}
 
496
 
 
497
static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
 
498
{
 
499
    const unsigned char *d_ptr = buffer;
 
500
    uint32_t length, numbytes;
 
501
    Asn1Generic *a;
 
502
    unsigned char c;
 
503
 
 
504
    d_ptr++;
 
505
 
 
506
    /* total sequence length */
 
507
    c = d_ptr[0];
 
508
    if ((c & (1<<7))>>7 == 0) { /* short form 8.1.3.4 */
 
509
        length = c;
 
510
        d_ptr++;
 
511
    } else { /* long form 8.1.3.5 */
 
512
        numbytes = c & 0x7f;
 
513
        d_ptr++;
 
514
        if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
 
515
            return NULL;
 
516
        }
 
517
    }
 
518
    if (length > max_size)
 
519
        return NULL;
 
520
 
 
521
    a = Asn1GenericNew();
 
522
    if (a == NULL)
 
523
        return NULL;
 
524
    a->type = ASN1_OCTETSTRING;
 
525
    a->strlen = length;
 
526
    /* Add one to the octet string for the 0. This will then
 
527
     * allow us to use the string in printf */
 
528
    a->str = SCMalloc(length + 1);
 
529
    if (a->str == NULL) {
 
530
        SCFree(a);
 
531
        return NULL;
 
532
    }
 
533
    memcpy(a->str, (const char*)d_ptr, length);
 
534
    a->str[length] = 0;
 
535
 
 
536
    d_ptr += length;
 
537
 
 
538
    a->length = (d_ptr - buffer);
 
539
    return a;
 
540
}
 
541
 
 
542
static Asn1Generic * DecodeAsn1DerUTF8String(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
 
543
{
 
544
    Asn1Generic *a = DecodeAsn1DerOctetString(buffer, max_size, depth, errcode);
 
545
    if (a != NULL)
 
546
        a->type = ASN1_UTF8STRING;
 
547
    return a;
 
548
}
 
549
 
 
550
static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
 
551
{
 
552
    const unsigned char *d_ptr = buffer;
 
553
    uint32_t length, numbytes;
 
554
    Asn1Generic *a;
 
555
    unsigned char c;
 
556
 
 
557
    d_ptr++;
 
558
 
 
559
    /* total sequence length */
 
560
    c = d_ptr[0];
 
561
    if ((c & (1<<7))>>7 == 0) { /* short form 8.1.3.4 */
 
562
        length = c;
 
563
        d_ptr++;
 
564
    } else { /* long form 8.1.3.5 */
 
565
        numbytes = c & 0x7f;
 
566
        d_ptr++;
 
567
        if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
 
568
            return NULL;
 
569
        }
 
570
    }
 
571
    if (length > max_size)
 
572
        return NULL;
 
573
 
 
574
    a = Asn1GenericNew();
 
575
    if (a == NULL)
 
576
        return NULL;
 
577
    a->type = ASN1_PRINTSTRING;
 
578
    a->strlen = length;
 
579
    a->str = SCMalloc(length+1);
 
580
    if (a->str == NULL) {
 
581
        SCFree(a);
 
582
        return NULL;
 
583
    }
 
584
    strlcpy(a->str, (const char*)d_ptr, length+1);
 
585
    a->str[length] = '\0';
 
586
 
 
587
    d_ptr += length;
 
588
 
 
589
    a->length = (d_ptr - buffer);
 
590
    return a;
 
591
}
 
592
 
 
593
static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
 
594
{
 
595
    const unsigned char *d_ptr = buffer;
 
596
    uint32_t d_length, parsed_bytes, numbytes, el_max_size;
 
597
    uint8_t c;
 
598
    uint32_t seq_index;
 
599
    Asn1Generic *node;
 
600
    Asn1Generic *child;
 
601
 
 
602
    d_ptr++;
 
603
 
 
604
    node = Asn1GenericNew();
 
605
    if (node == NULL)
 
606
        return NULL;
 
607
    node->type = ASN1_SEQUENCE;
 
608
 
 
609
    /* total sequence length */
 
610
    c = d_ptr[0];
 
611
    if ((c & (1<<7))>>7 == 0) { /* short form 8.1.3.4 */
 
612
        d_length = c;
 
613
        d_ptr++;
 
614
    } else { /* long form 8.1.3.5 */
 
615
        numbytes = c & 0x7f;
 
616
        d_ptr++;
 
617
        if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) {
 
618
            free(node);
 
619
            return NULL;
 
620
        }
 
621
    }
 
622
    node->length = d_length + (d_ptr - buffer);
 
623
    if (node->length > max_size) {
 
624
        free(node);
 
625
        return NULL;
 
626
    }
 
627
 
 
628
    parsed_bytes = 0;
 
629
    seq_index = 0;
 
630
 
 
631
    /* decode child elements */
 
632
    while (parsed_bytes < d_length) {
 
633
        el_max_size = max_size - (d_ptr-buffer);
 
634
        child = DecodeAsn1DerGeneric(d_ptr, el_max_size, depth, seq_index, errcode);
 
635
 
 
636
        if (child == NULL) {
 
637
            break;
 
638
        }
 
639
        Asn1SequenceAppend(node, child);
 
640
        parsed_bytes += child->length;
 
641
        d_ptr += child->length;
 
642
        seq_index++;
 
643
    }
 
644
 
 
645
    return (Asn1Generic *)node;
 
646
}
 
647
 
 
648
static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
 
649
{
 
650
    const unsigned char *d_ptr = buffer;
 
651
    uint32_t d_length, numbytes, el_max_size;
 
652
    uint8_t c;
 
653
    uint32_t seq_index;
 
654
    Asn1Generic *node;
 
655
    Asn1Generic *child;
 
656
 
 
657
    d_ptr++;
 
658
 
 
659
    node = Asn1GenericNew();
 
660
    if (node == NULL)
 
661
        return NULL;
 
662
    node->type = ASN1_SET;
 
663
    node->data = NULL;
 
664
 
 
665
    /* total sequence length */
 
666
    c = d_ptr[0];
 
667
    if ((c & (1<<7))>>7 == 0) { /* short form 8.1.3.4 */
 
668
        d_length = c;
 
669
        d_ptr++;
 
670
    } else { /* long form 8.1.3.5 */
 
671
        numbytes = c & 0x7f;
 
672
        d_ptr++;
 
673
        if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) {
 
674
            free(node);
 
675
            return NULL;
 
676
        }
 
677
    }
 
678
    node->length = d_length + (d_ptr - buffer);
 
679
 
 
680
    if (node->length > max_size) {
 
681
        if (errcode)
 
682
            *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
 
683
        free(node);
 
684
        return NULL;
 
685
    }
 
686
 
 
687
    seq_index = 0;
 
688
 
 
689
    el_max_size = max_size - (d_ptr-buffer);
 
690
    child = DecodeAsn1DerGeneric(d_ptr, el_max_size, depth, seq_index, errcode);
 
691
 
 
692
    node->data = child;
 
693
 
 
694
    return (Asn1Generic *)node;
 
695
}
 
696
 
 
697
static Asn1Generic * DecodeAsn1DerT61String(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
 
698
{
 
699
    Asn1Generic *a;
 
700
 
 
701
    a = DecodeAsn1DerIA5String(buffer, max_size, depth, errcode);
 
702
    if (a != NULL)
 
703
        a->type = ASN1_T61STRING;
 
704
 
 
705
    return a;
 
706
}
 
707
 
 
708
static Asn1Generic * DecodeAsn1DerUTCTime(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode)
 
709
{
 
710
    Asn1Generic *a;
 
711
 
 
712
    a = DecodeAsn1DerIA5String(buffer, max_size, depth, errcode);
 
713
    if (a != NULL)
 
714
        a->type = ASN1_UTCTIME;
 
715
 
 
716
    return a;
 
717
}
 
718
 
 
719
Asn1Generic * DecodeDer(const unsigned char *buffer, uint32_t size, uint32_t *errcode)
 
720
{
 
721
    const unsigned char *d_ptr = buffer;
 
722
    uint32_t d_length, numbytes;
 
723
    Asn1Generic *cert;
 
724
    uint8_t c;
 
725
 
 
726
    /* Check that buffer is an ASN.1 structure (basic checks) */
 
727
    if (d_ptr[0] != 0x30 && d_ptr[1] != 0x82) /* Sequence */
 
728
        return NULL;
 
729
 
 
730
    c = d_ptr[1];
 
731
    if ((c & (1<<7))>>7 != 1)
 
732
        return NULL;
 
733
 
 
734
    numbytes = c & 0x7f;
 
735
    d_ptr += 2;
 
736
    if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) {
 
737
        return NULL;
 
738
    }
 
739
    if (d_length+(d_ptr-buffer) != size)
 
740
        return NULL;
 
741
 
 
742
    if (errcode)
 
743
        *errcode = 0;
 
744
 
 
745
    cert = DecodeAsn1DerGeneric(buffer, size, 0 /* depth */, 0, errcode);
 
746
 
 
747
    return cert;
 
748
}
 
749
 
 
750
void DerFree(Asn1Generic *a)
 
751
{
 
752
    Asn1Generic *it, *n;
 
753
 
 
754
    if (a == NULL)
 
755
        return;
 
756
 
 
757
    it = a;
 
758
    while (it) {
 
759
        n = it->next;
 
760
        if (it->data) {
 
761
            DerFree(it->data);
 
762
        }
 
763
        if (it->str)
 
764
            free(it->str);
 
765
        memset(it, 0xff, sizeof(Asn1Generic));
 
766
        SCFree(it);
 
767
        it = n;
 
768
    }
 
769
}