Annotation of embedaddon/strongswan/src/libstrongswan/asn1/asn1.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2006 Martin Will
                      3:  * Copyright (C) 2000-2016 Andreas Steffen
                      4:  *
                      5:  * HSR Hochschule fuer Technik Rapperswil
                      6:  *
                      7:  * This program is free software; you can redistribute it and/or modify it
                      8:  * under the terms of the GNU General Public License as published by the
                      9:  * Free Software Foundation; either version 2 of the License, or (at your
                     10:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     11:  *
                     12:  * This program is distributed in the hope that it will be useful, but
                     13:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     14:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     15:  * for more details.
                     16:  */
                     17: 
                     18: #include <stdio.h>
                     19: #include <string.h>
                     20: #include <time.h>
                     21: 
                     22: #include <utils/debug.h>
                     23: 
                     24: #include "oid.h"
                     25: #include "asn1.h"
                     26: #include "asn1_parser.h"
                     27: 
                     28: /**
                     29:  * Commonly used ASN1 values.
                     30:  */
                     31: const chunk_t ASN1_INTEGER_0 = chunk_from_chars(0x02, 0x01, 0x00);
                     32: const chunk_t ASN1_INTEGER_1 = chunk_from_chars(0x02, 0x01, 0x01);
                     33: const chunk_t ASN1_INTEGER_2 = chunk_from_chars(0x02, 0x01, 0x02);
                     34: 
                     35: /*
                     36:  * Described in header
                     37:  */
                     38: chunk_t asn1_algorithmIdentifier_params(int oid, chunk_t params)
                     39: {
                     40:        return asn1_wrap(ASN1_SEQUENCE, "mm", asn1_build_known_oid(oid), params);
                     41: }
                     42: 
                     43: /*
                     44:  * Described in header
                     45:  */
                     46: chunk_t asn1_algorithmIdentifier(int oid)
                     47: {
                     48:        chunk_t parameters;
                     49: 
                     50:        /* some algorithmIdentifiers have a NULL parameters field and some do not */
                     51:        switch (oid)
                     52:        {
                     53:                case OID_ECDSA_WITH_SHA1:
                     54:                case OID_ECDSA_WITH_SHA224:
                     55:                case OID_ECDSA_WITH_SHA256:
                     56:                case OID_ECDSA_WITH_SHA384:
                     57:                case OID_ECDSA_WITH_SHA512:
                     58:                case OID_ED25519:
                     59:                case OID_ED448:
                     60:                        parameters = chunk_empty;
                     61:                        break;
                     62:                default:
                     63:                        parameters = asn1_simple_object(ASN1_NULL, chunk_empty);
                     64:                        break;
                     65:        }
                     66:        return asn1_algorithmIdentifier_params(oid, parameters);
                     67: }
                     68: 
                     69: /*
                     70:  * Defined in header.
                     71:  */
                     72: int asn1_known_oid(chunk_t object)
                     73: {
                     74:        int oid = 0;
                     75: 
                     76:        while (object.len)
                     77:        {
                     78:                if (oid_names[oid].octet == *object.ptr)
                     79:                {
                     80:                        if (--object.len == 0 || oid_names[oid].down == 0)
                     81:                        {
                     82:                                return oid;               /* found terminal symbol */
                     83:                        }
                     84:                        else
                     85:                        {
                     86:                                object.ptr++; oid++; /* advance to next hex octet */
                     87:                        }
                     88:                }
                     89:                else
                     90:                {
                     91:                        if (oid_names[oid].next)
                     92:                        {
                     93:                                oid = oid_names[oid].next;
                     94:                        }
                     95:                        else
                     96:                        {
                     97:                                return OID_UNKNOWN;
                     98:                        }
                     99:                }
                    100:        }
                    101:        return OID_UNKNOWN;
                    102: }
                    103: 
                    104: /*
                    105:  * Defined in header.
                    106:  */
                    107: chunk_t asn1_build_known_oid(int n)
                    108: {
                    109:        chunk_t oid;
                    110:        int i;
                    111: 
                    112:        if (n < 0 || n >= OID_MAX)
                    113:        {
                    114:                return chunk_empty;
                    115:        }
                    116: 
                    117:        i = oid_names[n].level + 1;
                    118:        oid = chunk_alloc(2 + i);
                    119:        oid.ptr[0] = ASN1_OID;
                    120:        oid.ptr[1] = i;
                    121: 
                    122:        do
                    123:        {
                    124:                if (oid_names[n].level >= i)
                    125:                {
                    126:                        n--;
                    127:                        continue;
                    128:                }
                    129:                oid.ptr[--i + 2] = oid_names[n--].octet;
                    130:        }
                    131:        while (i > 0);
                    132: 
                    133:        return oid;
                    134: }
                    135: 
                    136: /**
                    137:  * Returns the number of bytes required to encode the given OID node
                    138:  */
                    139: static int bytes_required(u_int val)
                    140: {
                    141:        int shift, required = 1;
                    142: 
                    143:        /* sufficient to handle 32 bit node numbers */
                    144:        for (shift = 28; shift; shift -= 7)
                    145:        {
                    146:                if (val >> shift)
                    147:                {       /* do not encode leading zeroes */
                    148:                        required++;
                    149:                }
                    150:        }
                    151:        return required;
                    152: }
                    153: 
                    154: /*
                    155:  * Defined in header.
                    156:  */
                    157: chunk_t asn1_oid_from_string(char *str)
                    158: {
                    159:        enumerator_t *enumerator;
                    160:        size_t buf_len = 64;
                    161:        u_char buf[buf_len];
                    162:        char *end;
                    163:        int i = 0, pos = 0, req, shift;
                    164:        u_int val, first = 0;
                    165: 
                    166:        enumerator = enumerator_create_token(str, ".", "");
                    167:        while (enumerator->enumerate(enumerator, &str))
                    168:        {
                    169:                val = strtoul(str, &end, 10);
                    170:                req = bytes_required(val);
                    171:                if (end == str || pos + req > buf_len)
                    172:                {
                    173:                        pos = 0;
                    174:                        break;
                    175:                }
                    176:                switch (i++)
                    177:                {
                    178:                        case 0:
                    179:                                first = val;
                    180:                                break;
                    181:                        case 1:
                    182:                                buf[pos++] = first * 40 + val;
                    183:                                break;
                    184:                        default:
                    185:                                for (shift = (req - 1) * 7; shift; shift -= 7)
                    186:                                {
                    187:                                        buf[pos++] = 0x80 | ((val >> shift) & 0x7F);
                    188:                                }
                    189:                                buf[pos++] = val & 0x7F;
                    190:                }
                    191:        }
                    192:        enumerator->destroy(enumerator);
                    193: 
                    194:        return chunk_clone(chunk_create(buf, pos));
                    195: }
                    196: 
                    197: /*
                    198:  * Defined in header.
                    199:  */
                    200: char *asn1_oid_to_string(chunk_t oid)
                    201: {
                    202:        size_t len = 64;
                    203:        char buf[len], *pos = buf;
                    204:        int written;
                    205:        u_int val;
                    206: 
                    207:        if (!oid.len)
                    208:        {
                    209:                return NULL;
                    210:        }
                    211:        val = oid.ptr[0] / 40;
                    212:        written = snprintf(buf, len, "%u.%u", val, oid.ptr[0] - val * 40);
                    213:        oid = chunk_skip(oid, 1);
                    214:        if (written < 0 || written >= len)
                    215:        {
                    216:                return NULL;
                    217:        }
                    218:        pos += written;
                    219:        len -= written;
                    220:        val = 0;
                    221: 
                    222:        while (oid.len)
                    223:        {
                    224:                val = (val << 7) + (u_int)(oid.ptr[0] & 0x7f);
                    225: 
                    226:                if (oid.ptr[0] < 128)
                    227:                {
                    228:                        written = snprintf(pos, len, ".%u", val);
                    229:                        if (written < 0 || written >= len)
                    230:                        {
                    231:                                return NULL;
                    232:                        }
                    233:                        pos += written;
                    234:                        len -= written;
                    235:                        val = 0;
                    236:                }
                    237:                oid = chunk_skip(oid, 1);
                    238:        }
                    239:        return (val == 0) ? strdup(buf) : NULL;
                    240: }
                    241: 
                    242: /*
                    243:  * Defined in header.
                    244:  */
                    245: size_t asn1_length(chunk_t *blob)
                    246: {
                    247:        u_char n;
                    248:        size_t len;
                    249: 
                    250:        if (blob->len < 2)
                    251:        {
                    252:                DBG2(DBG_ASN, "insufficient number of octets to parse ASN.1 length");
                    253:                return ASN1_INVALID_LENGTH;
                    254:        }
                    255: 
                    256:        /* read length field, skip tag and length */
                    257:        n = blob->ptr[1];
                    258:        blob->ptr += 2;
                    259:        blob->len -= 2;
                    260: 
                    261:        if ((n & 0x80) == 0)
                    262:        {       /* single length octet */
                    263:                if (n > blob->len)
                    264:                {
                    265:                        DBG2(DBG_ASN, "length is larger than remaining blob size");
                    266:                        return ASN1_INVALID_LENGTH;
                    267:                }
                    268:                return n;
                    269:        }
                    270: 
                    271:        /* composite length, determine number of length octets */
                    272:        n &= 0x7f;
                    273: 
                    274:        if (n == 0 || n > blob->len)
                    275:        {
                    276:                DBG2(DBG_ASN, "number of length octets invalid");
                    277:                return ASN1_INVALID_LENGTH;
                    278:        }
                    279: 
                    280:        if (n > sizeof(len))
                    281:        {
                    282:                DBG2(DBG_ASN, "number of length octets is larger than limit of"
                    283:                         " %d octets", (int)sizeof(len));
                    284:                return ASN1_INVALID_LENGTH;
                    285:        }
                    286: 
                    287:        len = 0;
                    288: 
                    289:        while (n-- > 0)
                    290:        {
                    291:                len = 256*len + *blob->ptr++;
                    292:                blob->len--;
                    293:        }
                    294:        if (len > blob->len)
                    295:        {
                    296:                DBG2(DBG_ASN, "length is larger than remaining blob size");
                    297:                return ASN1_INVALID_LENGTH;
                    298:        }
                    299:        return len;
                    300: }
                    301: 
                    302: /*
                    303:  * See header.
                    304:  */
                    305: int asn1_unwrap(chunk_t *blob, chunk_t *inner)
                    306: {
                    307:        chunk_t res;
                    308:        u_char len;
                    309:        int type;
                    310: 
                    311:        if (blob->len < 2)
                    312:        {
                    313:                return ASN1_INVALID;
                    314:        }
                    315:        type = blob->ptr[0];
                    316:        len = blob->ptr[1];
                    317:        *blob = chunk_skip(*blob, 2);
                    318: 
                    319:        if ((len & 0x80) == 0)
                    320:        {       /* single length octet */
                    321:                res.len = len;
                    322:        }
                    323:        else
                    324:        {       /* composite length, determine number of length octets */
                    325:                len &= 0x7f;
                    326:                if (len == 0 || len > blob->len || len > sizeof(res.len))
                    327:                {
                    328:                        return ASN1_INVALID;
                    329:                }
                    330:                res.len = 0;
                    331:                while (len-- > 0)
                    332:                {
                    333:                        res.len = 256 * res.len + blob->ptr[0];
                    334:                        *blob = chunk_skip(*blob, 1);
                    335:                }
                    336:        }
                    337:        if (res.len > blob->len)
                    338:        {
                    339:                return ASN1_INVALID;
                    340:        }
                    341:        res.ptr = blob->ptr;
                    342:        *blob = chunk_skip(*blob, res.len);
                    343:        /* updating inner not before we are finished allows a caller to pass
                    344:         * blob = inner */
                    345:        *inner = res;
                    346:        return type;
                    347: }
                    348: 
                    349: static const int days[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
                    350: static const int tm_leap_1970 = 477;
                    351: 
                    352: /**
                    353:  * Converts ASN.1 UTCTIME or GENERALIZEDTIME into calendar time
                    354:  */
                    355: time_t asn1_to_time(const chunk_t *utctime, asn1_t type)
                    356: {
                    357:        int tm_year, tm_mon, tm_day, tm_hour, tm_min, tm_sec;
                    358:        int tm_leap_4, tm_leap_100, tm_leap_400, tm_leap;
                    359:        int tz_hour, tz_min, tz_offset;
                    360:        time_t tm_days, tm_secs;
                    361:        char buf[BUF_LEN], *eot = NULL;
                    362: 
                    363:        snprintf(buf, sizeof(buf), "%.*s", (int)utctime->len, utctime->ptr);
                    364: 
                    365:        if ((eot = strchr(buf, 'Z')) != NULL)
                    366:        {
                    367:                tz_offset = 0; /* Zulu time with a zero time zone offset */
                    368:        }
                    369:        else if ((eot = strchr(buf, '+')) != NULL)
                    370:        {
                    371:                if (sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min) != 2)
                    372:                {
                    373:                        return 0; /* error in positive timezone offset format */
                    374:                }
                    375:                tz_offset = 3600*tz_hour + 60*tz_min;  /* positive time zone offset */
                    376:        }
                    377:        else if ((eot = strchr(buf, '-')) != NULL)
                    378:        {
                    379:                if (sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min) != 2)
                    380:                {
                    381:                        return 0; /* error in negative timezone offset format */
                    382:                }
                    383:                tz_offset = -3600*tz_hour - 60*tz_min;  /* negative time zone offset */
                    384:        }
                    385:        else
                    386:        {
                    387:                return 0; /* error in time format */
                    388:        }
                    389: 
                    390:        /* parse ASN.1 time string */
                    391:        {
                    392:                const char* format = (type == ASN1_UTCTIME)? "%2d%2d%2d%2d%2d":
                    393:                                                                                                         "%4d%2d%2d%2d%2d";
                    394: 
                    395:                if (sscanf(buf, format, &tm_year, &tm_mon, &tm_day,
                    396:                                                                &tm_hour, &tm_min) != 5)
                    397:                {
                    398:                        return 0; /* error in [yy]yymmddhhmm time format */
                    399:                }
                    400:        }
                    401: 
                    402:        /* is there a seconds field? */
                    403:        if ((eot - buf) == ((type == ASN1_UTCTIME)?12:14))
                    404:        {
                    405:                if (sscanf(eot-2, "%2d", &tm_sec) != 1)
                    406:                {
                    407:                        return 0; /* error in ss seconds field format */
                    408:                }
                    409:        }
                    410:        else
                    411:        {
                    412:                tm_sec = 0;
                    413:        }
                    414: 
                    415:        /* representation of two-digit years */
                    416:        if (type == ASN1_UTCTIME)
                    417:        {
                    418:                tm_year += (tm_year < 50) ? 2000 : 1900;
                    419:        }
                    420: 
                    421:        /* prevent obvious 32 bit integer overflows */
                    422:        if (sizeof(time_t) == 4 && (tm_year > 2038 || tm_year < 1901))
                    423:        {
                    424:                return TIME_32_BIT_SIGNED_MAX;
                    425:        }
                    426: 
                    427:        /* representation of months as 0..11*/
                    428:        if (tm_mon < 1 || tm_mon > 12)
                    429:        {
                    430:                return 0;
                    431:        }
                    432:        tm_mon--;
                    433: 
                    434:        /* representation of days as 0..30 */
                    435:        if (tm_day < 1 || tm_day > 31)
                    436:        {       /* we don't actually validate the day in relation to tm_year/tm_mon */
                    437:                return 0;
                    438:        }
                    439:        tm_day--;
                    440: 
                    441:        if (tm_hour < 0 || tm_hour > 23 ||
                    442:                tm_min < 0 || tm_min > 59 ||
                    443:                tm_sec < 0 || tm_sec > 60 /* allow leap seconds */)
                    444:        {
                    445:                return 0;
                    446:        }
                    447: 
                    448:        /* number of leap years between last year and 1970? */
                    449:        tm_leap_4 = (tm_year - 1) / 4;
                    450:        tm_leap_100 = tm_leap_4 / 25;
                    451:        tm_leap_400 = tm_leap_100 / 4;
                    452:        tm_leap = tm_leap_4 - tm_leap_100 + tm_leap_400 - tm_leap_1970;
                    453: 
                    454:        /* if date later then February, is the current year a leap year? */
                    455:        if (tm_mon > 1 && (tm_year % 4 == 0) &&
                    456:                (tm_year % 100 != 0 || tm_year % 400 == 0))
                    457:        {
                    458:                tm_leap++;
                    459:        }
                    460:        tm_days = 365 * (tm_year - 1970) + days[tm_mon] + tm_day + tm_leap;
                    461:        tm_secs = 60 * (60 * (24 * tm_days + tm_hour) + tm_min) + tm_sec - tz_offset;
                    462: 
                    463:        if (sizeof(time_t) == 4)
                    464:        {       /* has a 32 bit signed integer overflow occurred? */
                    465:                if (tm_year > 1970 && tm_secs < 0)
                    466:                {       /* depending on the time zone, the first days in 1970 may result in
                    467:                         * a negative value, but dates after 1970 never will */
                    468:                        return TIME_32_BIT_SIGNED_MAX;
                    469:                }
                    470:                if (tm_year < 1969 && tm_secs > 0)
                    471:                {       /* similarly, tm_secs is not positive for dates before 1970, except
                    472:                         * for the last days in 1969, depending on the time zone */
                    473:                        return TIME_32_BIT_SIGNED_MAX;
                    474:                }
                    475:        }
                    476:        return tm_secs;
                    477: }
                    478: 
                    479: /**
                    480:  *  Convert a date into ASN.1 UTCTIME or GENERALIZEDTIME format
                    481:  */
                    482: chunk_t asn1_from_time(const time_t *time, asn1_t type)
                    483: {
                    484:        int offset;
                    485:        const char *format;
                    486:        char buf[BUF_LEN];
                    487:        chunk_t formatted_time;
                    488:        struct tm t = {};
                    489: 
                    490:        gmtime_r(time, &t);
                    491:        /* RFC 5280 says that dates through the year 2049 MUST be encoded as UTCTIME
                    492:         * and dates in 2050 or later MUST be encoded as GENERALIZEDTIME. We only
                    493:         * enforce the latter to avoid overflows but allow callers to force the
                    494:         * encoding to GENERALIZEDTIME */
                    495:        type = (t.tm_year >= 150) ? ASN1_GENERALIZEDTIME : type;
                    496:        if (type == ASN1_GENERALIZEDTIME)
                    497:        {
                    498:                format = "%04d%02d%02d%02d%02d%02dZ";
                    499:                offset = 1900;
                    500:        }
                    501:        else /* ASN1_UTCTIME */
                    502:        {
                    503:                format = "%02d%02d%02d%02d%02d%02dZ";
                    504:                offset = (t.tm_year < 100) ? 0 : -100;
                    505:        }
                    506:        snprintf(buf, BUF_LEN, format, t.tm_year + offset,
                    507:                         t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
                    508:        formatted_time.ptr = buf;
                    509:        formatted_time.len = strlen(buf);
                    510:        return asn1_simple_object(type, formatted_time);
                    511: }
                    512: 
                    513: /*
                    514:  * Defined in header.
                    515:  */
                    516: void asn1_debug_simple_object(chunk_t object, asn1_t type, bool private)
                    517: {
                    518:        int oid;
                    519: 
                    520:        switch (type)
                    521:        {
                    522:                case ASN1_OID:
                    523:                        oid = asn1_known_oid(object);
                    524:                        if (oid == OID_UNKNOWN)
                    525:                        {
                    526:                                char *oid_str = asn1_oid_to_string(object);
                    527: 
                    528:                                if (!oid_str)
                    529:                                {
                    530:                                        break;
                    531:                                }
                    532:                                DBG2(DBG_ASN, "  %s", oid_str);
                    533:                                free(oid_str);
                    534:                        }
                    535:                        else
                    536:                        {
                    537:                                DBG2(DBG_ASN, "  '%s'", oid_names[oid].name);
                    538:                        }
                    539:                        return;
                    540:                case ASN1_UTF8STRING:
                    541:                case ASN1_IA5STRING:
                    542:                case ASN1_PRINTABLESTRING:
                    543:                case ASN1_T61STRING:
                    544:                case ASN1_VISIBLESTRING:
                    545:                        DBG2(DBG_ASN, "  '%.*s'", (int)object.len, object.ptr);
                    546:                        return;
                    547:                case ASN1_UTCTIME:
                    548:                case ASN1_GENERALIZEDTIME:
                    549:                        {
                    550:                                time_t time = asn1_to_time(&object, type);
                    551: 
                    552:                                DBG2(DBG_ASN, "  '%T'", &time, TRUE);
                    553:                        }
                    554:                        return;
                    555:                default:
                    556:                        break;
                    557:        }
                    558:        if (private)
                    559:        {
                    560:                DBG4(DBG_ASN, "%B", &object);
                    561:        }
                    562:        else
                    563:        {
                    564:                DBG3(DBG_ASN, "%B", &object);
                    565:        }
                    566: }
                    567: 
                    568: /**
                    569:  * parse an ASN.1 simple type
                    570:  */
                    571: bool asn1_parse_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name)
                    572: {
                    573:        size_t len;
                    574: 
                    575:        /* an ASN.1 object must possess at least a tag and length field */
                    576:        if (object->len < 2)
                    577:        {
                    578:                DBG2(DBG_ASN, "L%d - %s:  ASN.1 object smaller than 2 octets", level,
                    579:                         name);
                    580:                return FALSE;
                    581:        }
                    582: 
                    583:        if (*object->ptr != type)
                    584:        {
                    585:                DBG2(DBG_ASN, "L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
                    586:                         level, name, type, *object->ptr);
                    587:                return FALSE;
                    588:        }
                    589: 
                    590:        len = asn1_length(object);
                    591: 
                    592:        if (len == ASN1_INVALID_LENGTH)
                    593:        {
                    594:                DBG2(DBG_ASN, "L%d - %s:  length of ASN.1 object invalid or too large",
                    595:                         level, name);
                    596:                return FALSE;
                    597:        }
                    598: 
                    599:        DBG2(DBG_ASN, "L%d - %s:", level, name);
                    600:        asn1_debug_simple_object(*object, type, FALSE);
                    601:        return TRUE;
                    602: }
                    603: 
                    604: /*
                    605:  * Described in header
                    606:  */
                    607: uint64_t asn1_parse_integer_uint64(chunk_t blob)
                    608: {
                    609:        uint64_t val = 0;
                    610:        int i;
                    611: 
                    612:        for (i = 0; i < blob.len; i++)
                    613:        {       /* if it is longer than 8 bytes, we just use the 8 LSBs */
                    614:                val <<= 8;
                    615:                val |= (uint64_t)blob.ptr[i];
                    616:        }
                    617:        return val;
                    618: }
                    619: 
                    620: /*
                    621:  * Described in header
                    622:  */
                    623: chunk_t asn1_integer_from_uint64(uint64_t val)
                    624: {
                    625:        u_char buf[sizeof(val)];
                    626:        chunk_t enc = chunk_empty;
                    627: 
                    628:        if (val < 0x100)
                    629:        {
                    630:                buf[0] = (u_char)val;
                    631:                return chunk_clone(chunk_create(buf, 1));
                    632:        }
                    633:        for (enc.ptr = buf + sizeof(val); val; enc.len++, val >>= 8)
                    634:        {       /* fill the buffer from the end */
                    635:                *(--enc.ptr) = val & 0xff;
                    636:        }
                    637:        return chunk_clone(enc);
                    638: }
                    639: 
                    640: /**
                    641:  * ASN.1 definition of an algorithmIdentifier
                    642:  */
                    643: static const asn1Object_t algorithmIdentifierObjects[] = {
                    644:        { 0, "algorithmIdentifier",     ASN1_SEQUENCE,          ASN1_NONE                       }, /* 0 */
                    645:        { 1,   "algorithm",                     ASN1_OID,                       ASN1_BODY                       }, /* 1 */
                    646:        { 1,   "parameters",            ASN1_OID,                       ASN1_RAW|ASN1_OPT       }, /* 2 */
                    647:        { 1,   "end opt",                       ASN1_EOC,                       ASN1_END                        }, /* 3 */
                    648:        { 1,   "parameters",            ASN1_SEQUENCE,          ASN1_RAW|ASN1_OPT       }, /* 4 */
                    649:        { 1,   "end opt",                       ASN1_EOC,                       ASN1_END                        }, /* 5 */
                    650:        { 1,   "parameters",            ASN1_OCTET_STRING,      ASN1_RAW|ASN1_OPT       }, /* 6 */
                    651:        { 1,   "end opt",                       ASN1_EOC,                       ASN1_END                        }, /* 7 */
                    652:        { 0, "exit",                            ASN1_EOC,                       ASN1_EXIT                       }
                    653: };
                    654: #define ALGORITHM_ID_ALG                               1
                    655: #define ALGORITHM_ID_PARAMETERS_OID            2
                    656: #define ALGORITHM_ID_PARAMETERS_SEQ            4
                    657: #define ALGORITHM_ID_PARAMETERS_OCT            6
                    658: 
                    659: /*
                    660:  * Defined in header
                    661:  */
                    662: int asn1_parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters)
                    663: {
                    664:        asn1_parser_t *parser;
                    665:        chunk_t object;
                    666:        int objectID;
                    667:        int alg = OID_UNKNOWN;
                    668: 
                    669:        parser = asn1_parser_create(algorithmIdentifierObjects, blob);
                    670:        parser->set_top_level(parser, level0);
                    671: 
                    672:        while (parser->iterate(parser, &objectID, &object))
                    673:        {
                    674:                switch (objectID)
                    675:                {
                    676:                        case ALGORITHM_ID_ALG:
                    677:                                alg = asn1_known_oid(object);
                    678:                                break;
                    679:                        case ALGORITHM_ID_PARAMETERS_OID:
                    680:                        case ALGORITHM_ID_PARAMETERS_SEQ:
                    681:                        case ALGORITHM_ID_PARAMETERS_OCT:
                    682:                                if (parameters != NULL)
                    683:                                {
                    684:                                        *parameters = object;
                    685:                                }
                    686:                                break;
                    687:                        default:
                    688:                                break;
                    689:                }
                    690:        }
                    691:        parser->destroy(parser);
                    692:        return alg;
                    693: }
                    694: 
                    695: /*
                    696:  *  tests if a blob contains a valid ASN.1 set or sequence
                    697:  */
                    698: bool is_asn1(chunk_t blob)
                    699: {
                    700:        u_int len;
                    701:        u_char tag;
                    702: 
                    703:        if (!blob.len || !blob.ptr)
                    704:        {
                    705:                return FALSE;
                    706:        }
                    707: 
                    708:        tag = *blob.ptr;
                    709:        if (tag != ASN1_SEQUENCE && tag != ASN1_SET && tag != ASN1_OCTET_STRING)
                    710:        {
                    711:                DBG2(DBG_ASN, "  file content is not binary ASN.1");
                    712:                return FALSE;
                    713:        }
                    714: 
                    715:        len = asn1_length(&blob);
                    716: 
                    717:        if (len == ASN1_INVALID_LENGTH)
                    718:        {
                    719:                return FALSE;
                    720:        }
                    721: 
                    722:        /* exact match */
                    723:        if (len == blob.len)
                    724:        {
                    725:                return TRUE;
                    726:        }
                    727: 
                    728:        /* some websites append a surplus newline character to the blob */
                    729:        if (len + 1 == blob.len && *(blob.ptr + len) == '\n')
                    730:        {
                    731:                return TRUE;
                    732:        }
                    733: 
                    734:        DBG2(DBG_ASN, "  file size does not match ASN.1 coded length");
                    735:        return FALSE;
                    736: }
                    737: 
                    738: /*
                    739:  * Defined in header.
                    740:  */
                    741: bool asn1_is_printablestring(chunk_t str)
                    742: {
                    743:        const char printablestring_charset[] =
                    744:                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '()+,-./:=?";
                    745:        u_int i;
                    746: 
                    747:        for (i = 0; i < str.len; i++)
                    748:        {
                    749:                if (strchr(printablestring_charset, str.ptr[i]) == NULL)
                    750:                {
                    751:                        return FALSE;
                    752:                }
                    753:        }
                    754:        return TRUE;
                    755: }
                    756: 
                    757: /**
                    758:  * codes ASN.1 lengths up to a size of 16'777'215 bytes
                    759:  */
                    760: static void asn1_code_length(size_t length, chunk_t *code)
                    761: {
                    762:        if (length < 128)
                    763:        {
                    764:                code->ptr[0] = length;
                    765:                code->len = 1;
                    766:        }
                    767:        else if (length < 256)
                    768:        {
                    769:                code->ptr[0] = 0x81;
                    770:                code->ptr[1] = (u_char) length;
                    771:                code->len = 2;
                    772:        }
                    773:        else if (length < 65536)
                    774:        {
                    775:                code->ptr[0] = 0x82;
                    776:                code->ptr[1] = length >> 8;
                    777:                code->ptr[2] = length & 0x00ff;
                    778:                code->len = 3;
                    779:        }
                    780:        else
                    781:        {
                    782:                code->ptr[0] = 0x83;
                    783:                code->ptr[1] = length >> 16;
                    784:                code->ptr[2] = (length >> 8) & 0x00ff;
                    785:                code->ptr[3] = length & 0x0000ff;
                    786:                code->len = 4;
                    787:        }
                    788: }
                    789: 
                    790: /**
                    791:  * build an empty asn.1 object with tag and length fields already filled in
                    792:  */
                    793: u_char* asn1_build_object(chunk_t *object, asn1_t type, size_t datalen)
                    794: {
                    795:        u_char length_buf[4];
                    796:        chunk_t length = { length_buf, 0 };
                    797:        u_char *pos;
                    798: 
                    799:        /* code the asn.1 length field */
                    800:        asn1_code_length(datalen, &length);
                    801: 
                    802:        /* allocate memory for the asn.1 TLV object */
                    803:        object->len = 1 + length.len + datalen;
                    804:        object->ptr = malloc(object->len);
                    805: 
                    806:        /* set position pointer at the start of the object */
                    807:        pos = object->ptr;
                    808: 
                    809:        /* copy the asn.1 tag field and advance the pointer */
                    810:        *pos++ = type;
                    811: 
                    812:        /* copy the asn.1 length field and advance the pointer */
                    813:        memcpy(pos, length.ptr, length.len);
                    814:        pos += length.len;
                    815: 
                    816:        return pos;
                    817: }
                    818: 
                    819: /**
                    820:  * Build a simple ASN.1 object
                    821:  */
                    822: chunk_t asn1_simple_object(asn1_t tag, chunk_t content)
                    823: {
                    824:        chunk_t object;
                    825: 
                    826:        u_char *pos = asn1_build_object(&object, tag, content.len);
                    827:        memcpy(pos, content.ptr, content.len);
                    828: 
                    829:        return object;
                    830: }
                    831: 
                    832: /**
                    833:  * Build an ASN.1 BIT_STRING object
                    834:  */
                    835: chunk_t asn1_bitstring(const char *mode, chunk_t content)
                    836: {
                    837:        chunk_t object;
                    838:        u_char *pos = asn1_build_object(&object, ASN1_BIT_STRING, 1 + content.len);
                    839: 
                    840:        *pos++ = 0x00;
                    841:        memcpy(pos, content.ptr, content.len);
                    842:        if (*mode == 'm')
                    843:        {
                    844:                free(content.ptr);
                    845:        }
                    846:        return object;
                    847: }
                    848: 
                    849: /**
                    850:  * Build an ASN.1 INTEGER object
                    851:  */
                    852: chunk_t asn1_integer(const char *mode, chunk_t content)
                    853: {
                    854:        chunk_t zero = chunk_from_chars(0x00), object;
                    855:        size_t len;
                    856:        u_char *pos;
                    857:        bool move;
                    858: 
                    859:        if (content.len == 0)
                    860:        {       /* make sure 0 is encoded properly */
                    861:                content = zero;
                    862:                move = FALSE;
                    863:        }
                    864:        else
                    865:        {
                    866:                move = (*mode == 'm');
                    867:        }
                    868: 
                    869:        /* ASN.1 integers must be positive numbers in two's complement */
                    870:        len = content.len + ((*content.ptr & 0x80) ? 1 : 0);
                    871:        pos = asn1_build_object(&object, ASN1_INTEGER, len);
                    872:        if (len > content.len)
                    873:        {
                    874:                *pos++ = 0x00;
                    875:        }
                    876:        memcpy(pos, content.ptr, content.len);
                    877: 
                    878:        if (move)
                    879:        {
                    880:                free(content.ptr);
                    881:        }
                    882:        return object;
                    883: }
                    884: 
                    885: /**
                    886:  * Build an ASN.1 object from a variable number of individual chunks.
                    887:  * Depending on the mode, chunks either are moved ('m') or copied ('c').
                    888:  */
                    889: chunk_t asn1_wrap(asn1_t type, const char *mode, ...)
                    890: {
                    891:        chunk_t construct;
                    892:        va_list chunks;
                    893:        u_char *pos;
                    894:        int i;
                    895:        int count = strlen(mode);
                    896: 
                    897:        /* sum up lengths of individual chunks */
                    898:        va_start(chunks, mode);
                    899:        construct.len = 0;
                    900:        for (i = 0; i < count; i++)
                    901:        {
                    902:                chunk_t ch = va_arg(chunks, chunk_t);
                    903:                construct.len += ch.len;
                    904:        }
                    905:        va_end(chunks);
                    906: 
                    907:        /* allocate needed memory for construct */
                    908:        pos = asn1_build_object(&construct, type, construct.len);
                    909: 
                    910:        /* copy or move the chunks */
                    911:        va_start(chunks, mode);
                    912:        for (i = 0; i < count; i++)
                    913:        {
                    914:                chunk_t ch = va_arg(chunks, chunk_t);
                    915: 
                    916:                memcpy(pos, ch.ptr, ch.len);
                    917:                pos += ch.len;
                    918: 
                    919:                switch (*mode++)
                    920:                {
                    921:                        case 's':
                    922:                                chunk_clear(&ch);
                    923:                                break;
                    924:                        case 'm':
                    925:                                free(ch.ptr);
                    926:                                break;
                    927:                        default:
                    928:                                break;
                    929:                }
                    930:        }
                    931:        va_end(chunks);
                    932: 
                    933:        return construct;
                    934: }
                    935: 
                    936: /**
                    937:  * ASN.1 definition of time
                    938:  */
                    939: static const asn1Object_t timeObjects[] = {
                    940:        { 0, "utcTime",                 ASN1_UTCTIME,                   ASN1_OPT|ASN1_BODY      }, /* 0 */
                    941:        { 0, "end opt",                 ASN1_EOC,                               ASN1_END                        }, /* 1 */
                    942:        { 0, "generalizeTime",  ASN1_GENERALIZEDTIME,   ASN1_OPT|ASN1_BODY      }, /* 2 */
                    943:        { 0, "end opt",                 ASN1_EOC,                               ASN1_END                        }, /* 3 */
                    944:        { 0, "exit",                    ASN1_EOC,                               ASN1_EXIT                       }
                    945: };
                    946: #ifdef TIME_UTC
                    947: /* used by C11 timespec_get(), <time.h> */
                    948: # undef TIME_UTC
                    949: #endif
                    950: #define TIME_UTC                       0
                    951: #define TIME_GENERALIZED       2
                    952: 
                    953: /**
                    954:  * extracts and converts a UTCTIME or GENERALIZEDTIME object
                    955:  */
                    956: time_t asn1_parse_time(chunk_t blob, int level0)
                    957: {
                    958:        asn1_parser_t *parser;
                    959:        chunk_t object;
                    960:        int objectID;
                    961:        time_t utc_time = 0;
                    962: 
                    963:        parser= asn1_parser_create(timeObjects, blob);
                    964:        parser->set_top_level(parser, level0);
                    965: 
                    966:        while (parser->iterate(parser, &objectID, &object))
                    967:        {
                    968:                if (objectID == TIME_UTC || objectID == TIME_GENERALIZED)
                    969:                {
                    970:                        utc_time = asn1_to_time(&object, (objectID == TIME_UTC)
                    971:                                                                        ? ASN1_UTCTIME : ASN1_GENERALIZEDTIME);
                    972:                }
                    973:        }
                    974:        parser->destroy(parser);
                    975:        return utc_time;
                    976: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>