Annotation of embedaddon/strongswan/src/libstrongswan/plugins/x509/x509_cert.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
                      3:  * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
                      4:  * Copyright (C) 2002 Mario Strasser
                      5:  * Copyright (C) 2000-2017 Andreas Steffen
                      6:  * Copyright (C) 2006-2009 Martin Willi
                      7:  * Copyright (C) 2008-2017 Tobias Brunner
                      8:  * HSR Hochschule fuer Technik Rapperswil
                      9:  *
                     10:  * This program is free software; you can redistribute it and/or modify it
                     11:  * under the terms of the GNU General Public License as published by the
                     12:  * Free Software Foundation; either version 2 of the License, or (at your
                     13:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     14:  *
                     15:  * This program is distributed in the hope that it will be useful, but
                     16:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     17:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     18:  * for more details.
                     19:  */
                     20: 
                     21: #define _GNU_SOURCE
                     22: 
                     23: #include <sys/stat.h>
                     24: #include <time.h>
                     25: #include <unistd.h>
                     26: #include <string.h>
                     27: #include <stdio.h>
                     28: 
                     29: #include "x509_cert.h"
                     30: 
                     31: #include <library.h>
                     32: #include <utils/debug.h>
                     33: #include <asn1/oid.h>
                     34: #include <asn1/asn1.h>
                     35: #include <asn1/asn1_parser.h>
                     36: #include <crypto/hashers/hasher.h>
                     37: #include <credentials/keys/private_key.h>
                     38: #include <collections/linked_list.h>
                     39: #include <utils/identification.h>
                     40: #include <selectors/traffic_selector.h>
                     41: 
                     42: /**
                     43:  * Different kinds of generalNames
                     44:  */
                     45: typedef enum {
                     46:        GN_OTHER_NAME =         0,
                     47:        GN_RFC822_NAME =        1,
                     48:        GN_DNS_NAME =           2,
                     49:        GN_X400_ADDRESS =       3,
                     50:        GN_DIRECTORY_NAME =     4,
                     51:        GN_EDI_PARTY_NAME = 5,
                     52:        GN_URI =                        6,
                     53:        GN_IP_ADDRESS =         7,
                     54:        GN_REGISTERED_ID =      8,
                     55: } generalNames_t;
                     56: 
                     57: 
                     58: typedef struct private_x509_cert_t private_x509_cert_t;
                     59: 
                     60: /**
                     61:  * Private data of a x509_cert_t object.
                     62:  */
                     63: struct private_x509_cert_t {
                     64:        /**
                     65:         * Public interface for this certificate.
                     66:         */
                     67:        x509_cert_t public;
                     68: 
                     69:        /**
                     70:         * X.509 certificate encoding in ASN.1 DER format
                     71:         */
                     72:        chunk_t encoding;
                     73: 
                     74:        /**
                     75:         * SHA1 hash of the DER encoding of this X.509 certificate
                     76:         */
                     77:        chunk_t encoding_hash;
                     78: 
                     79:        /**
                     80:         * X.509 certificate body over which signature is computed
                     81:         */
                     82:        chunk_t tbsCertificate;
                     83: 
                     84:        /**
                     85:         * Version of the X.509 certificate
                     86:         */
                     87:        u_int version;
                     88: 
                     89:        /**
                     90:         * Serial number of the X.509 certificate
                     91:         */
                     92:        chunk_t serialNumber;
                     93: 
                     94:        /**
                     95:         * ID representing the certificate issuer
                     96:         */
                     97:        identification_t *issuer;
                     98: 
                     99:        /**
                    100:         * Start time of certificate validity
                    101:         */
                    102:        time_t notBefore;
                    103: 
                    104:        /**
                    105:         * End time of certificate validity
                    106:         */
                    107:        time_t notAfter;
                    108: 
                    109:        /**
                    110:         * ID representing the certificate subject
                    111:         */
                    112:        identification_t *subject;
                    113: 
                    114:        /**
                    115:         * List of subjectAltNames as identification_t
                    116:         */
                    117:        linked_list_t *subjectAltNames;
                    118: 
                    119:        /**
                    120:         * List of crlDistributionPoints as x509_cdp_t*
                    121:         */
                    122:        linked_list_t *crl_uris;
                    123: 
                    124:        /**
                    125:         * List of ocspAccessLocations as allocated char*
                    126:         */
                    127:        linked_list_t *ocsp_uris;
                    128: 
                    129:        /**
                    130:         * List of ipAddrBlocks as traffic_selector_t
                    131:         */
                    132:        linked_list_t *ipAddrBlocks;
                    133: 
                    134:        /**
                    135:         * List of permitted name constraints
                    136:         */
                    137:        linked_list_t *permitted_names;
                    138: 
                    139:        /**
                    140:         * List of excluded name constraints
                    141:         */
                    142:        linked_list_t *excluded_names;
                    143: 
                    144:        /**
                    145:         * List of certificatePolicies, as x509_cert_policy_t
                    146:         */
                    147:        linked_list_t *cert_policies;
                    148: 
                    149:        /**
                    150:         * List of policyMappings, as x509_policy_mapping_t
                    151:         */
                    152:        linked_list_t *policy_mappings;
                    153: 
                    154:        /**
                    155:         * certificate's embedded public key
                    156:         */
                    157:        public_key_t *public_key;
                    158: 
                    159:        /**
                    160:         * Subject Key Identifier
                    161:         */
                    162:        chunk_t subjectKeyIdentifier;
                    163: 
                    164:        /**
                    165:         * Authority Key Identifier
                    166:         */
                    167:        chunk_t authKeyIdentifier;
                    168: 
                    169:        /**
                    170:         * Authority Key Serial Number
                    171:         */
                    172:        chunk_t authKeySerialNumber;
                    173: 
                    174:        /**
                    175:         * Optional OID of an [unsupported] critical extension
                    176:         */
                    177:        chunk_t critical_extension_oid;
                    178: 
                    179:        /**
                    180:         * Path Length Constraint
                    181:         */
                    182:        u_char pathLenConstraint;
                    183: 
                    184:        /**
                    185:         * requireExplicitPolicy Constraint
                    186:         */
                    187:        u_char require_explicit;
                    188: 
                    189:        /**
                    190:         * inhibitPolicyMapping Constraint
                    191:         */
                    192:        u_char inhibit_mapping;
                    193: 
                    194:        /**
                    195:         * inhibitAnyPolicy Constraint
                    196:         */
                    197:        u_char inhibit_any;
                    198: 
                    199:        /**
                    200:         * x509 constraints and other flags
                    201:         */
                    202:        x509_flag_t flags;
                    203: 
                    204:        /**
                    205:         * Signature scheme
                    206:         */
                    207:        signature_params_t *scheme;
                    208: 
                    209:        /**
                    210:         * Signature
                    211:         */
                    212:        chunk_t signature;
                    213: 
                    214:        /**
                    215:         * Certificate parsed from blob/file?
                    216:         */
                    217:        bool parsed;
                    218: 
                    219:        /**
                    220:         * reference count
                    221:         */
                    222:        refcount_t ref;
                    223: };
                    224: 
                    225: /**
                    226:  * Convert a generalName to a string
                    227:  */
                    228: static bool gn_to_string(identification_t *id, char **uri)
                    229: {
                    230:        int len;
                    231: 
                    232: #ifdef USE_FUZZING
                    233:        chunk_t proper;
                    234:        chunk_printable(id->get_encoding(id), &proper, '?');
                    235:        len = asprintf(uri, "%.*s", (int)proper.len, proper.ptr);
                    236:        chunk_free(&proper);
                    237: #else
                    238:        len = asprintf(uri, "%Y", id);
                    239: #endif
                    240:        if (!len)
                    241:        {
                    242:                free(*uri);
                    243:                return FALSE;
                    244:        }
                    245:        return len > 0;
                    246: }
                    247: 
                    248: /**
                    249:  * Destroy a CertificatePolicy
                    250:  */
                    251: static void cert_policy_destroy(x509_cert_policy_t *this)
                    252: {
                    253:        free(this->oid.ptr);
                    254:        free(this->cps_uri);
                    255:        free(this->unotice_text);
                    256:        free(this);
                    257: }
                    258: 
                    259: /**
                    260:  * Free policy mapping
                    261:  */
                    262: static void policy_mapping_destroy(x509_policy_mapping_t *mapping)
                    263: {
                    264:        free(mapping->issuer.ptr);
                    265:        free(mapping->subject.ptr);
                    266:        free(mapping);
                    267: }
                    268: 
                    269: /**
                    270:  * Parse a length constraint from an unwrapped integer
                    271:  */
                    272: static u_int parse_constraint(chunk_t object)
                    273: {
                    274:        switch (object.len)
                    275:        {
                    276:                case 0:
                    277:                        return 0;
                    278:                case 1:
                    279:                        return (object.ptr[0] & 0x80) ? X509_NO_CONSTRAINT : object.ptr[0];
                    280:                default:
                    281:                        return X509_NO_CONSTRAINT;
                    282:        }
                    283: }
                    284: 
                    285: /**
                    286:  * ASN.1 definition of a basicConstraints extension
                    287:  */
                    288: static const asn1Object_t basicConstraintsObjects[] = {
                    289:        { 0, "basicConstraints",        ASN1_SEQUENCE,  ASN1_NONE                       }, /*  0 */
                    290:        { 1,   "CA",                            ASN1_BOOLEAN,   ASN1_DEF|ASN1_BODY      }, /*  1 */
                    291:        { 1,   "pathLenConstraint",     ASN1_INTEGER,   ASN1_OPT|ASN1_BODY      }, /*  2 */
                    292:        { 1,   "end opt",                       ASN1_EOC,               ASN1_END                        }, /*  3 */
                    293:        { 0, "exit",                            ASN1_EOC,               ASN1_EXIT                       }
                    294: };
                    295: #define BASIC_CONSTRAINTS_CA           1
                    296: #define BASIC_CONSTRAINTS_PATH_LEN     2
                    297: 
                    298: /**
                    299:  * Extracts the basicConstraints extension
                    300:  */
                    301: static bool parse_basicConstraints(chunk_t blob, int level0,
                    302:                                                                   private_x509_cert_t *this)
                    303: {
                    304:        asn1_parser_t *parser;
                    305:        chunk_t object;
                    306:        int objectID;
                    307:        bool isCA = FALSE;
                    308:        bool success;
                    309: 
                    310:        parser = asn1_parser_create(basicConstraintsObjects, blob);
                    311:        parser->set_top_level(parser, level0);
                    312: 
                    313:        while (parser->iterate(parser, &objectID, &object))
                    314:        {
                    315:                switch (objectID)
                    316:                {
                    317:                        case BASIC_CONSTRAINTS_CA:
                    318:                                isCA = object.len && *object.ptr;
                    319:                                DBG2(DBG_ASN, "  %s", isCA ? "TRUE" : "FALSE");
                    320:                                if (isCA)
                    321:                                {
                    322:                                        this->flags |= X509_CA;
                    323:                                }
                    324:                                break;
                    325:                        case BASIC_CONSTRAINTS_PATH_LEN:
                    326:                                if (isCA)
                    327:                                {
                    328:                                        this->pathLenConstraint = parse_constraint(object);
                    329:                                }
                    330:                                break;
                    331:                        default:
                    332:                                break;
                    333:                }
                    334:        }
                    335:        success = parser->success(parser);
                    336:        parser->destroy(parser);
                    337: 
                    338:        return success;
                    339: }
                    340: 
                    341: /**
                    342:  * ASN.1 definition of otherName
                    343:  */
                    344: static const asn1Object_t otherNameObjects[] = {
                    345:        {0, "type-id",  ASN1_OID,                       ASN1_BODY       }, /* 0 */
                    346:        {0, "value",    ASN1_CONTEXT_C_0,       ASN1_BODY       }, /* 1 */
                    347:        {0, "exit",             ASN1_EOC,                       ASN1_EXIT       }
                    348: };
                    349: #define ON_OBJ_ID_TYPE         0
                    350: #define ON_OBJ_VALUE           1
                    351: 
                    352: /**
                    353:  * Extracts an otherName
                    354:  */
                    355: static bool parse_otherName(chunk_t *blob, int level0, id_type_t *type)
                    356: {
                    357:        asn1_parser_t *parser;
                    358:        chunk_t object;
                    359:        int objectID;
                    360:        int oid = OID_UNKNOWN;
                    361:        bool success = FALSE;
                    362: 
                    363:        parser = asn1_parser_create(otherNameObjects, *blob);
                    364:        parser->set_top_level(parser, level0);
                    365: 
                    366:        while (parser->iterate(parser, &objectID, &object))
                    367:        {
                    368:                switch (objectID)
                    369:                {
                    370:                        case ON_OBJ_ID_TYPE:
                    371:                                oid = asn1_known_oid(object);
                    372:                                break;
                    373:                        case ON_OBJ_VALUE:
                    374:                                switch (oid)
                    375:                                {
                    376:                                        case OID_XMPP_ADDR:
                    377:                                                if (asn1_parse_simple_object(&object, ASN1_UTF8STRING,
                    378:                                                                        parser->get_level(parser)+1, "xmppAddr"))
                    379:                                                {       /* we handle xmppAddr as RFC822 addr */
                    380:                                                        *blob = object;
                    381:                                                        *type = ID_RFC822_ADDR;
                    382:                                                }
                    383:                                                else
                    384:                                                {
                    385:                                                        goto end;
                    386:                                                }
                    387:                                                break;
                    388:                                        case OID_USER_PRINCIPAL_NAME:
                    389:                                                if (asn1_parse_simple_object(&object, ASN1_UTF8STRING,
                    390:                                                                        parser->get_level(parser)+1, "msUPN"))
                    391:                                                {       /* we handle UPNs as RFC822 addr */
                    392:                                                        *blob = object;
                    393:                                                        *type = ID_RFC822_ADDR;
                    394:                                                }
                    395:                                                else
                    396:                                                {
                    397:                                                        goto end;
                    398:                                                }
                    399:                                                break;
                    400:                                }
                    401:                                break;
                    402:                        default:
                    403:                                break;
                    404:                }
                    405:        }
                    406:        success = parser->success(parser);
                    407: 
                    408: end:
                    409:        parser->destroy(parser);
                    410:        return success;
                    411: }
                    412: 
                    413: /**
                    414:  * ASN.1 definition of generalName
                    415:  */
                    416: static const asn1Object_t generalNameObjects[] = {
                    417:        { 0, "otherName",               ASN1_CONTEXT_C_0,  ASN1_OPT|ASN1_BODY   }, /*  0 */
                    418:        { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /*  1 */
                    419:        { 0, "rfc822Name",              ASN1_CONTEXT_S_1,  ASN1_OPT|ASN1_BODY   }, /*  2 */
                    420:        { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /*  3 */
                    421:        { 0, "dnsName",                 ASN1_CONTEXT_S_2,  ASN1_OPT|ASN1_BODY   }, /*  4 */
                    422:        { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /*  5 */
                    423:        { 0, "x400Address",             ASN1_CONTEXT_S_3,  ASN1_OPT|ASN1_BODY   }, /*  6 */
                    424:        { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /*  7 */
                    425:        { 0, "directoryName",   ASN1_CONTEXT_C_4,  ASN1_OPT|ASN1_BODY   }, /*  8 */
                    426:        { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /*  9 */
                    427:        { 0, "ediPartyName",    ASN1_CONTEXT_C_5,  ASN1_OPT|ASN1_BODY   }, /* 10 */
                    428:        { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /* 11 */
                    429:        { 0, "URI",                             ASN1_CONTEXT_S_6,  ASN1_OPT|ASN1_BODY   }, /* 12 */
                    430:        { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /* 13 */
                    431:        { 0, "ipAddress",               ASN1_CONTEXT_S_7,  ASN1_OPT|ASN1_BODY   }, /* 14 */
                    432:        { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /* 15 */
                    433:        { 0, "registeredID",    ASN1_CONTEXT_S_8,  ASN1_OPT|ASN1_BODY   }, /* 16 */
                    434:        { 0, "end choice",              ASN1_EOC,          ASN1_END                             }, /* 17 */
                    435:        { 0, "exit",                    ASN1_EOC,          ASN1_EXIT                    }
                    436: };
                    437: #define GN_OBJ_OTHER_NAME               0
                    438: #define GN_OBJ_RFC822_NAME              2
                    439: #define GN_OBJ_DNS_NAME                         4
                    440: #define GN_OBJ_X400_ADDRESS             6
                    441: #define GN_OBJ_DIRECTORY_NAME   8
                    442: #define GN_OBJ_EDI_PARTY_NAME  10
                    443: #define GN_OBJ_URI                             12
                    444: #define GN_OBJ_IP_ADDRESS              14
                    445: #define GN_OBJ_REGISTERED_ID   16
                    446: 
                    447: /**
                    448:  * Extracts a generalName
                    449:  */
                    450: static identification_t *parse_generalName(chunk_t blob, int level0)
                    451: {
                    452:        asn1_parser_t *parser;
                    453:        chunk_t object;
                    454:        int objectID ;
                    455: 
                    456:        identification_t *gn = NULL;
                    457: 
                    458:        parser = asn1_parser_create(generalNameObjects, blob);
                    459:        parser->set_top_level(parser, level0);
                    460: 
                    461:        while (parser->iterate(parser, &objectID, &object))
                    462:        {
                    463:                id_type_t id_type = ID_ANY;
                    464: 
                    465:                switch (objectID)
                    466:                {
                    467:                        case GN_OBJ_RFC822_NAME:
                    468:                                id_type = ID_RFC822_ADDR;
                    469:                                break;
                    470:                        case GN_OBJ_DNS_NAME:
                    471:                                id_type = ID_FQDN;
                    472:                                break;
                    473:                        case GN_OBJ_URI:
                    474:                                id_type = ID_DER_ASN1_GN_URI;
                    475:                                break;
                    476:                        case GN_OBJ_DIRECTORY_NAME:
                    477:                                id_type = ID_DER_ASN1_DN;
                    478:                                break;
                    479:                        case GN_OBJ_IP_ADDRESS:
                    480:                                switch (object.len)
                    481:                                {
                    482:                                        case 4:
                    483:                                                id_type = ID_IPV4_ADDR;
                    484:                                                break;
                    485:                                        case 16:
                    486:                                                id_type = ID_IPV6_ADDR;
                    487:                                                break;
                    488:                                        default:
                    489:                                                break;
                    490:                                }
                    491:                                break;
                    492:                        case GN_OBJ_OTHER_NAME:
                    493:                                if (!parse_otherName(&object, parser->get_level(parser)+1,
                    494:                                                                         &id_type))
                    495:                                {
                    496:                                        goto end;
                    497:                                }
                    498:                                break;
                    499:                        case GN_OBJ_X400_ADDRESS:
                    500:                        case GN_OBJ_EDI_PARTY_NAME:
                    501:                        case GN_OBJ_REGISTERED_ID:
                    502:                        default:
                    503:                                break;
                    504:                }
                    505:                if (id_type != ID_ANY)
                    506:                {
                    507:                        gn = identification_create_from_encoding(id_type, object);
                    508:                        DBG2(DBG_ASN, "  '%Y'", gn);
                    509:                        goto end;
                    510:                }
                    511:        }
                    512: 
                    513: end:
                    514:        parser->destroy(parser);
                    515:        return gn;
                    516: }
                    517: 
                    518: /**
                    519:  * ASN.1 definition of generalNames
                    520:  */
                    521: static const asn1Object_t generalNamesObjects[] = {
                    522:        { 0, "generalNames",    ASN1_SEQUENCE,  ASN1_LOOP }, /* 0 */
                    523:        { 1,   "generalName",   ASN1_EOC,               ASN1_RAW  }, /* 1 */
                    524:        { 0, "end loop",                ASN1_EOC,               ASN1_END  }, /* 2 */
                    525:        { 0, "exit",                    ASN1_EOC,               ASN1_EXIT }
                    526: };
                    527: #define GENERAL_NAMES_GN       1
                    528: 
                    529: /**
                    530:  * Extracts one or several GNs and puts them into a chained list
                    531:  */
                    532: bool x509_parse_generalNames(chunk_t blob, int level0, bool implicit,
                    533:                                                         linked_list_t *list)
                    534: {
                    535:        asn1_parser_t *parser;
                    536:        chunk_t object;
                    537:        identification_t *gn;
                    538:        int objectID;
                    539:        bool success = FALSE;
                    540: 
                    541:        parser = asn1_parser_create(generalNamesObjects, blob);
                    542:        parser->set_top_level(parser, level0);
                    543:        parser->set_flags(parser, implicit, FALSE);
                    544: 
                    545:        while (parser->iterate(parser, &objectID, &object))
                    546:        {
                    547:                if (objectID == GENERAL_NAMES_GN)
                    548:                {
                    549:                        gn = parse_generalName(object, parser->get_level(parser)+1);
                    550:                        if (!gn)
                    551:                        {
                    552:                                goto end;
                    553:                        }
                    554:                        list->insert_last(list, (void *)gn);
                    555:                }
                    556:        }
                    557:        success = parser->success(parser);
                    558: 
                    559: end:
                    560:        parser->destroy(parser);
                    561: 
                    562:        return success;
                    563: }
                    564: 
                    565: /**
                    566:  * ASN.1 definition of a authorityKeyIdentifier extension
                    567:  */
                    568: static const asn1Object_t authKeyIdentifierObjects[] = {
                    569:        { 0, "authorityKeyIdentifier",          ASN1_SEQUENCE,          ASN1_NONE                       }, /* 0 */
                    570:        { 1,   "keyIdentifier",                         ASN1_CONTEXT_S_0,       ASN1_OPT|ASN1_BODY      }, /* 1 */
                    571:        { 1,   "end opt",                                       ASN1_EOC,                       ASN1_END                        }, /* 2 */
                    572:        { 1,   "authorityCertIssuer",           ASN1_CONTEXT_C_1,       ASN1_OPT|ASN1_OBJ       }, /* 3 */
                    573:        { 1,   "end opt",                                       ASN1_EOC,                       ASN1_END                        }, /* 4 */
                    574:        { 1,   "authorityCertSerialNumber",     ASN1_CONTEXT_S_2,       ASN1_OPT|ASN1_BODY      }, /* 5 */
                    575:        { 1,   "end opt",                                       ASN1_EOC,                       ASN1_END                        }, /* 6 */
                    576:        { 0, "exit",                                            ASN1_EOC,                       ASN1_EXIT                       }
                    577: };
                    578: #define AUTH_KEY_ID_KEY_ID                     1
                    579: #define AUTH_KEY_ID_CERT_ISSUER                3
                    580: #define AUTH_KEY_ID_CERT_SERIAL                5
                    581: 
                    582: /**
                    583:  * Extracts an authoritykeyIdentifier
                    584:  */
                    585: chunk_t x509_parse_authorityKeyIdentifier(chunk_t blob, int level0,
                    586:                                                                                                chunk_t *authKeySerialNumber)
                    587: {
                    588:        asn1_parser_t *parser;
                    589:        chunk_t object;
                    590:        int objectID;
                    591:        chunk_t authKeyIdentifier = chunk_empty;
                    592: 
                    593:        *authKeySerialNumber = chunk_empty;
                    594: 
                    595:        parser = asn1_parser_create(authKeyIdentifierObjects, blob);
                    596:        parser->set_top_level(parser, level0);
                    597: 
                    598:        while (parser->iterate(parser, &objectID, &object))
                    599:        {
                    600:                switch (objectID)
                    601:                {
                    602:                        case AUTH_KEY_ID_KEY_ID:
                    603:                                authKeyIdentifier = chunk_clone(object);
                    604:                                break;
                    605:                        case AUTH_KEY_ID_CERT_ISSUER:
                    606:                                /* TODO: x509_parse_generalNames(object, level+1, TRUE); */
                    607:                                break;
                    608:                        case AUTH_KEY_ID_CERT_SERIAL:
                    609:                                *authKeySerialNumber = object;
                    610:                                break;
                    611:                        default:
                    612:                                break;
                    613:                }
                    614:        }
                    615:        parser->destroy(parser);
                    616: 
                    617:        return authKeyIdentifier;
                    618: }
                    619: 
                    620: /**
                    621:  * ASN.1 definition of a authorityInfoAccess extension
                    622:  */
                    623: static const asn1Object_t authInfoAccessObjects[] = {
                    624:        { 0, "authorityInfoAccess",     ASN1_SEQUENCE,  ASN1_LOOP }, /* 0 */
                    625:        { 1,   "accessDescription",     ASN1_SEQUENCE,  ASN1_NONE }, /* 1 */
                    626:        { 2,     "accessMethod",        ASN1_OID,               ASN1_BODY }, /* 2 */
                    627:        { 2,     "accessLocation",      ASN1_EOC,               ASN1_RAW  }, /* 3 */
                    628:        { 0, "end loop",                        ASN1_EOC,               ASN1_END  }, /* 4 */
                    629:        { 0, "exit",                            ASN1_EOC,               ASN1_EXIT }
                    630: };
                    631: #define AUTH_INFO_ACCESS_METHOD                2
                    632: #define AUTH_INFO_ACCESS_LOCATION      3
                    633: 
                    634: /**
                    635:  * Extracts an authorityInfoAcess location
                    636:  */
                    637: static bool parse_authorityInfoAccess(chunk_t blob, int level0,
                    638:                                                                          private_x509_cert_t *this)
                    639: {
                    640:        asn1_parser_t *parser;
                    641:        chunk_t object;
                    642:        int objectID;
                    643:        int accessMethod = OID_UNKNOWN;
                    644:        bool success = FALSE;
                    645: 
                    646:        parser = asn1_parser_create(authInfoAccessObjects, blob);
                    647:        parser->set_top_level(parser, level0);
                    648: 
                    649:        while (parser->iterate(parser, &objectID, &object))
                    650:        {
                    651:                switch (objectID)
                    652:                {
                    653:                        case AUTH_INFO_ACCESS_METHOD:
                    654:                                accessMethod = asn1_known_oid(object);
                    655:                                break;
                    656:                        case AUTH_INFO_ACCESS_LOCATION:
                    657:                        {
                    658:                                switch (accessMethod)
                    659:                                {
                    660:                                        case OID_OCSP:
                    661:                                        case OID_CA_ISSUERS:
                    662:                                                {
                    663:                                                        identification_t *id;
                    664:                                                        char *uri;
                    665: 
                    666:                                                        id = parse_generalName(object,
                    667:                                                                                        parser->get_level(parser)+1);
                    668:                                                        if (id == NULL)
                    669:                                                        {
                    670:                                                                /* parsing went wrong - abort */
                    671:                                                                goto end;
                    672:                                                        }
                    673:                                                        DBG2(DBG_ASN, "  '%Y'", id);
                    674:                                                        if (accessMethod == OID_OCSP &&
                    675:                                                                gn_to_string(id, &uri))
                    676:                                                        {
                    677:                                                                this->ocsp_uris->insert_last(this->ocsp_uris, uri);
                    678:                                                        }
                    679:                                                        id->destroy(id);
                    680:                                                }
                    681:                                                break;
                    682:                                        default:
                    683:                                                /* unknown accessMethod, ignoring */
                    684:                                                break;
                    685:                                }
                    686:                                break;
                    687:                        }
                    688:                        default:
                    689:                                break;
                    690:                }
                    691:        }
                    692:        success = parser->success(parser);
                    693: 
                    694: end:
                    695:        parser->destroy(parser);
                    696: 
                    697:        return success;
                    698: }
                    699: 
                    700: /**
                    701:  * Extract KeyUsage flags
                    702:  */
                    703: static void parse_keyUsage(chunk_t blob, private_x509_cert_t *this)
                    704: {
                    705:        enum {
                    706:                KU_DIGITAL_SIGNATURE =  0,
                    707:                KU_NON_REPUDIATION =    1,
                    708:                KU_KEY_ENCIPHERMENT =   2,
                    709:                KU_DATA_ENCIPHERMENT =  3,
                    710:                KU_KEY_AGREEMENT =              4,
                    711:                KU_KEY_CERT_SIGN =              5,
                    712:                KU_CRL_SIGN =                   6,
                    713:                KU_ENCIPHER_ONLY =              7,
                    714:                KU_DECIPHER_ONLY =              8,
                    715:        };
                    716: 
                    717:        /* to be compliant with RFC 4945 specific KUs have to be included */
                    718:        this->flags &= ~X509_IKE_COMPLIANT;
                    719: 
                    720:        if (asn1_unwrap(&blob, &blob) == ASN1_BIT_STRING && blob.len)
                    721:        {
                    722:                int bit, byte, unused = blob.ptr[0];
                    723: 
                    724:                blob = chunk_skip(blob, 1);
                    725:                for (byte = 0; byte < blob.len; byte++)
                    726:                {
                    727:                        for (bit = 0; bit < 8; bit++)
                    728:                        {
                    729:                                if (byte == blob.len - 1 && bit > (7 - unused))
                    730:                                {
                    731:                                        break;
                    732:                                }
                    733:                                if (blob.ptr[byte] & 1 << (7 - bit))
                    734:                                {
                    735:                                        switch (byte * 8 + bit)
                    736:                                        {
                    737:                                                case KU_CRL_SIGN:
                    738:                                                        this->flags |= X509_CRL_SIGN;
                    739:                                                        break;
                    740:                                                case KU_DIGITAL_SIGNATURE:
                    741:                                                case KU_NON_REPUDIATION:
                    742:                                                        this->flags |= X509_IKE_COMPLIANT;
                    743:                                                        break;
                    744:                                                case KU_KEY_CERT_SIGN:
                    745:                                                        /* we use the caBasicConstraint, MUST be set */
                    746:                                                case KU_KEY_ENCIPHERMENT:
                    747:                                                case KU_DATA_ENCIPHERMENT:
                    748:                                                case KU_KEY_AGREEMENT:
                    749:                                                case KU_ENCIPHER_ONLY:
                    750:                                                case KU_DECIPHER_ONLY:
                    751:                                                        break;
                    752:                                        }
                    753:                                }
                    754:                        }
                    755:                }
                    756:        }
                    757: }
                    758: 
                    759: /**
                    760:  * ASN.1 definition of a extendedKeyUsage extension
                    761:  */
                    762: static const asn1Object_t extendedKeyUsageObjects[] = {
                    763:        { 0, "extendedKeyUsage",        ASN1_SEQUENCE,  ASN1_LOOP }, /* 0 */
                    764:        { 1,   "keyPurposeID",          ASN1_OID,               ASN1_BODY }, /* 1 */
                    765:        { 0, "end loop",                        ASN1_EOC,               ASN1_END  }, /* 2 */
                    766:        { 0, "exit",                            ASN1_EOC,               ASN1_EXIT }
                    767: };
                    768: #define EXT_KEY_USAGE_PURPOSE_ID       1
                    769: 
                    770: /**
                    771:  * Extracts extendedKeyUsage OIDs
                    772:  */
                    773: static bool parse_extendedKeyUsage(chunk_t blob, int level0,
                    774:                                                                   private_x509_cert_t *this)
                    775: {
                    776:        asn1_parser_t *parser;
                    777:        chunk_t object;
                    778:        int objectID;
                    779:        bool success;
                    780: 
                    781:        parser = asn1_parser_create(extendedKeyUsageObjects, blob);
                    782:        parser->set_top_level(parser, level0);
                    783: 
                    784:        while (parser->iterate(parser, &objectID, &object))
                    785:        {
                    786:                if (objectID == EXT_KEY_USAGE_PURPOSE_ID)
                    787:                {
                    788:                        switch (asn1_known_oid(object))
                    789:                        {
                    790:                                case OID_SERVER_AUTH:
                    791:                                        this->flags |= X509_SERVER_AUTH;
                    792:                                        break;
                    793:                                case OID_CLIENT_AUTH:
                    794:                                        this->flags |= X509_CLIENT_AUTH;
                    795:                                        break;
                    796:                                case OID_IKE_INTERMEDIATE:
                    797:                                        this->flags |= X509_IKE_INTERMEDIATE;
                    798:                                        break;
                    799:                                case OID_OCSP_SIGNING:
                    800:                                        this->flags |= X509_OCSP_SIGNER;
                    801:                                        break;
                    802:                                case OID_MS_SMARTCARD_LOGON:
                    803:                                        this->flags |= X509_MS_SMARTCARD_LOGON;
                    804:                                        break;
                    805:                                default:
                    806:                                        break;
                    807:                        }
                    808:                }
                    809:        }
                    810:        success = parser->success(parser);
                    811:        parser->destroy(parser);
                    812: 
                    813:        return success;
                    814: }
                    815: 
                    816: /**
                    817:  * ASN.1 definition of crlDistributionPoints
                    818:  */
                    819: static const asn1Object_t crlDistributionPointsObjects[] = {
                    820:        { 0, "crlDistributionPoints",   ASN1_SEQUENCE,    ASN1_LOOP            }, /*  0 */
                    821:        { 1,   "DistributionPoint",     ASN1_SEQUENCE,    ASN1_NONE            }, /*  1 */
                    822:        { 2,     "distributionPoint",   ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_CHOICE }, /*  2 */
                    823:        { 3,       "fullName",          ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ    }, /*  3 */
                    824:        { 3,       "end choice",        ASN1_EOC,         ASN1_END|ASN1_CH     }, /*  4 */
                    825:        { 3,       "nameRelToCRLIssuer",ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY   }, /*  5 */
                    826:        { 3,       "end choice",        ASN1_EOC,         ASN1_END|ASN1_CH     }, /*  6 */
                    827:        { 2,     "end opt/choices",     ASN1_EOC,         ASN1_END|ASN1_CHOICE }, /*  7 */
                    828:        { 2,     "reasons",             ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY   }, /*  8 */
                    829:        { 2,     "end opt",             ASN1_EOC,         ASN1_END             }, /*  9 */
                    830:        { 2,     "crlIssuer",           ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_OBJ    }, /* 10 */
                    831:        { 2,     "end opt",             ASN1_EOC,         ASN1_END             }, /* 11 */
                    832:        { 0, "end loop",                ASN1_EOC,         ASN1_END             }, /* 12 */
                    833:        { 0, "exit",                    ASN1_EOC,         ASN1_EXIT            }
                    834: };
                    835: #define CRL_DIST_POINTS                                 1
                    836: #define CRL_DIST_POINTS_FULLNAME        3
                    837: #define CRL_DIST_POINTS_ISSUER         10
                    838: 
                    839: /**
                    840:  * Add entry to the list of each pairing of URI and Issuer
                    841:  */
                    842: static void add_cdps(linked_list_t *list, linked_list_t *uris,
                    843:                                         linked_list_t *issuers)
                    844: {
                    845:        identification_t *issuer, *id;
                    846:        enumerator_t *enumerator;
                    847:        x509_cdp_t *cdp;
                    848:        char *uri;
                    849: 
                    850:        while (uris->remove_last(uris, (void**)&id) == SUCCESS)
                    851:        {
                    852:                if (gn_to_string(id, &uri))
                    853:                {
                    854:                        if (issuers->get_count(issuers))
                    855:                        {
                    856:                                enumerator = issuers->create_enumerator(issuers);
                    857:                                while (enumerator->enumerate(enumerator, &issuer))
                    858:                                {
                    859:                                        INIT(cdp,
                    860:                                                .uri = strdup(uri),
                    861:                                                .issuer = issuer->clone(issuer),
                    862:                                        );
                    863:                                        list->insert_last(list, cdp);
                    864:                                }
                    865:                                enumerator->destroy(enumerator);
                    866:                                free(uri);
                    867:                        }
                    868:                        else
                    869:                        {
                    870:                                INIT(cdp,
                    871:                                        .uri = uri,
                    872:                                );
                    873:                                list->insert_last(list, cdp);
                    874:                        }
                    875:                }
                    876:                id->destroy(id);
                    877:        }
                    878:        while (issuers->remove_last(issuers, (void**)&id) == SUCCESS)
                    879:        {
                    880:                id->destroy(id);
                    881:        }
                    882: }
                    883: 
                    884: /**
                    885:  * Extracts one or several crlDistributionPoints into a list
                    886:  */
                    887: bool x509_parse_crlDistributionPoints(chunk_t blob, int level0,
                    888:                                                                          linked_list_t *list)
                    889: {
                    890:        linked_list_t *uris, *issuers;
                    891:        asn1_parser_t *parser;
                    892:        chunk_t object;
                    893:        int objectID;
                    894:        bool success = FALSE;
                    895: 
                    896:        uris = linked_list_create();
                    897:        issuers = linked_list_create();
                    898:        parser = asn1_parser_create(crlDistributionPointsObjects, blob);
                    899:        parser->set_top_level(parser, level0);
                    900: 
                    901:        while (parser->iterate(parser, &objectID, &object))
                    902:        {
                    903:                switch (objectID)
                    904:                {
                    905:                        case CRL_DIST_POINTS:
                    906:                                add_cdps(list, uris, issuers);
                    907:                                break;
                    908:                        case CRL_DIST_POINTS_FULLNAME:
                    909:                                if (!x509_parse_generalNames(object,
                    910:                                                                parser->get_level(parser) + 1, TRUE, uris))
                    911:                                {
                    912:                                        goto end;
                    913:                                }
                    914:                                break;
                    915:                        case CRL_DIST_POINTS_ISSUER:
                    916:                                if (!x509_parse_generalNames(object,
                    917:                                                                parser->get_level(parser) + 1, TRUE, issuers))
                    918:                                {
                    919:                                        goto end;
                    920:                                }
                    921:                                break;
                    922:                        default:
                    923:                                break;
                    924:                }
                    925:        }
                    926:        success = parser->success(parser);
                    927:        add_cdps(list, uris, issuers);
                    928: 
                    929: end:
                    930:        parser->destroy(parser);
                    931:        uris->destroy_offset(uris, offsetof(identification_t, destroy));
                    932:        issuers->destroy_offset(issuers, offsetof(identification_t, destroy));
                    933: 
                    934:        return success;
                    935: }
                    936: 
                    937: /**
                    938:  * ASN.1 definition of nameConstraints
                    939:  */
                    940: static const asn1Object_t nameConstraintsObjects[] = {
                    941:        { 0, "nameConstraints",                 ASN1_SEQUENCE,          ASN1_NONE                       }, /*  0 */
                    942:        { 1,   "permittedSubtrees",             ASN1_CONTEXT_C_0,       ASN1_OPT|ASN1_LOOP      }, /*  1 */
                    943:        { 2,     "generalSubtree",              ASN1_SEQUENCE,          ASN1_BODY                       }, /*  2 */
                    944:        { 1,   "end loop",                              ASN1_EOC,                       ASN1_END                        }, /*  3 */
                    945:        { 1,   "excludedSubtrees",              ASN1_CONTEXT_C_1,       ASN1_OPT|ASN1_LOOP      }, /*  4 */
                    946:        { 2,     "generalSubtree",              ASN1_SEQUENCE,          ASN1_BODY                       }, /*  5 */
                    947:        { 1,   "end loop",                              ASN1_EOC,                       ASN1_END                        }, /*  6 */
                    948:        { 0, "exit",                                    ASN1_EOC,                       ASN1_EXIT                       }
                    949: };
                    950: #define NAME_CONSTRAINT_PERMITTED 2
                    951: #define NAME_CONSTRAINT_EXCLUDED  5
                    952: 
                    953: /**
                    954:  * Parse permitted/excluded nameConstraints
                    955:  */
                    956: static bool parse_nameConstraints(chunk_t blob, int level0,
                    957:                                                                  private_x509_cert_t *this)
                    958: {
                    959:        asn1_parser_t *parser;
                    960:        identification_t *id;
                    961:        chunk_t object;
                    962:        int objectID;
                    963:        bool success = FALSE;
                    964: 
                    965:        parser = asn1_parser_create(nameConstraintsObjects, blob);
                    966:        parser->set_top_level(parser, level0);
                    967: 
                    968:        while (parser->iterate(parser, &objectID, &object))
                    969:        {
                    970:                switch (objectID)
                    971:                {
                    972:                        case NAME_CONSTRAINT_PERMITTED:
                    973:                                id = parse_generalName(object, parser->get_level(parser) + 1);
                    974:                                if (!id)
                    975:                                {
                    976:                                        goto end;
                    977:                                }
                    978:                                this->permitted_names->insert_last(this->permitted_names, id);
                    979:                                break;
                    980:                        case NAME_CONSTRAINT_EXCLUDED:
                    981:                                id = parse_generalName(object, parser->get_level(parser) + 1);
                    982:                                if (!id)
                    983:                                {
                    984:                                        goto end;
                    985:                                }
                    986:                                this->excluded_names->insert_last(this->excluded_names, id);
                    987:                                break;
                    988:                        default:
                    989:                                break;
                    990:                }
                    991:        }
                    992:        success = parser->success(parser);
                    993: 
                    994: end:
                    995:        parser->destroy(parser);
                    996: 
                    997:        return success;
                    998: }
                    999: 
                   1000: /**
                   1001:  * ASN.1 definition of a certificatePolicies extension
                   1002:  */
                   1003: static const asn1Object_t certificatePoliciesObject[] = {
                   1004:        { 0, "certificatePolicies",      ASN1_SEQUENCE,  ASN1_LOOP            }, /*  0 */
                   1005:        { 1,   "policyInformation",      ASN1_SEQUENCE,  ASN1_NONE            }, /*  1 */
                   1006:        { 2,     "policyId",             ASN1_OID,       ASN1_BODY            }, /*  2 */
                   1007:        { 2,     "qualifiers",           ASN1_SEQUENCE,  ASN1_OPT|ASN1_LOOP   }, /*  3 */
                   1008:        { 3,       "qualifierInfo",      ASN1_SEQUENCE,  ASN1_NONE            }, /*  4 */
                   1009:        { 4,         "qualifierId",      ASN1_OID,       ASN1_BODY            }, /*  5 */
                   1010:        { 4,         "qualifier",        ASN1_EOC,       ASN1_CHOICE          }, /*  6 */
                   1011:        { 5,           "cPSuri",         ASN1_IA5STRING, ASN1_OPT|ASN1_BODY   }, /*  7 */
                   1012:        { 5,           "end choice",     ASN1_EOC,       ASN1_END|ASN1_CH     }, /*  8 */
                   1013:        { 5,           "userNotice",     ASN1_SEQUENCE,  ASN1_OPT|ASN1_BODY   }, /*  9 */
                   1014:        { 6,             "explicitText", ASN1_EOC,       ASN1_RAW             }, /* 10 */
                   1015:        { 5,           "end choice",     ASN1_EOC,       ASN1_END|ASN1_CH     }, /* 11 */
                   1016:        { 4,         "end choices",      ASN1_EOC,       ASN1_END|ASN1_CHOICE }, /* 12 */
                   1017:        { 2,     "end opt/loop",         ASN1_EOC,       ASN1_END             }, /* 13 */
                   1018:        { 0, "end loop",                 ASN1_EOC,       ASN1_END             }, /* 14 */
                   1019:        { 0, "exit",                     ASN1_EOC,       ASN1_EXIT            }
                   1020: };
                   1021: #define CERT_POLICY_ID              2
                   1022: #define CERT_POLICY_QUALIFIER_ID    5
                   1023: #define CERT_POLICY_CPS_URI         7
                   1024: #define CERT_POLICY_EXPLICIT_TEXT  10
                   1025: 
                   1026: /**
                   1027:  * Parse certificatePolicies
                   1028:  */
                   1029: static bool parse_certificatePolicies(chunk_t blob, int level0,
                   1030:                                                                          private_x509_cert_t *this)
                   1031: {
                   1032:        x509_cert_policy_t *policy = NULL;
                   1033:        asn1_parser_t *parser;
                   1034:        chunk_t object;
                   1035:        int objectID, qualifier = OID_UNKNOWN;
                   1036:        bool success;
                   1037: 
                   1038:        parser = asn1_parser_create(certificatePoliciesObject, blob);
                   1039:        parser->set_top_level(parser, level0);
                   1040: 
                   1041:        while (parser->iterate(parser, &objectID, &object))
                   1042:        {
                   1043:                switch (objectID)
                   1044:                {
                   1045:                        case CERT_POLICY_ID:
                   1046:                                INIT(policy,
                   1047:                                        .oid = chunk_clone(object),
                   1048:                                );
                   1049:                                this->cert_policies->insert_last(this->cert_policies, policy);
                   1050:                                break;
                   1051:                        case CERT_POLICY_QUALIFIER_ID:
                   1052:                                qualifier = asn1_known_oid(object);
                   1053:                                break;
                   1054:                        case CERT_POLICY_CPS_URI:
                   1055:                                if (policy && !policy->cps_uri && object.len &&
                   1056:                                        qualifier == OID_POLICY_QUALIFIER_CPS &&
                   1057:                                        chunk_printable(object, NULL, 0))
                   1058:                                {
                   1059:                                        policy->cps_uri = strndup(object.ptr, object.len);
                   1060:                                }
                   1061:                                break;
                   1062:                        case CERT_POLICY_EXPLICIT_TEXT:
                   1063:                                /* TODO */
                   1064:                                break;
                   1065:                        default:
                   1066:                                break;
                   1067:                }
                   1068:        }
                   1069:        success = parser->success(parser);
                   1070:        parser->destroy(parser);
                   1071: 
                   1072:        return success;
                   1073: }
                   1074: 
                   1075: /**
                   1076:  * ASN.1 definition of a policyMappings extension
                   1077:  */
                   1078: static const asn1Object_t policyMappingsObjects[] = {
                   1079:        { 0, "policyMappings",                  ASN1_SEQUENCE,  ASN1_LOOP                       }, /*  0 */
                   1080:        { 1,   "policyMapping",                 ASN1_SEQUENCE,  ASN1_NONE                       }, /*  1 */
                   1081:        { 2,     "issuerPolicy",                ASN1_OID,               ASN1_BODY                       }, /*  2 */
                   1082:        { 2,     "subjectPolicy",               ASN1_OID,               ASN1_BODY                       }, /*  3 */
                   1083:        { 0, "end loop",                                ASN1_EOC,               ASN1_END                        }, /*  4 */
                   1084:        { 0, "exit",                                    ASN1_EOC,               ASN1_EXIT                       }
                   1085: };
                   1086: #define POLICY_MAPPING                 1
                   1087: #define POLICY_MAPPING_ISSUER  2
                   1088: #define POLICY_MAPPING_SUBJECT 3
                   1089: 
                   1090: /**
                   1091:  * Parse policyMappings
                   1092:  */
                   1093: static bool parse_policyMappings(chunk_t blob, int level0,
                   1094:                                                                 private_x509_cert_t *this)
                   1095: {
                   1096:        x509_policy_mapping_t *map = NULL;
                   1097:        asn1_parser_t *parser;
                   1098:        chunk_t object;
                   1099:        int objectID;
                   1100:        bool success;
                   1101: 
                   1102:        parser = asn1_parser_create(policyMappingsObjects, blob);
                   1103:        parser->set_top_level(parser, level0);
                   1104: 
                   1105:        while (parser->iterate(parser, &objectID, &object))
                   1106:        {
                   1107:                switch (objectID)
                   1108:                {
                   1109:                        case POLICY_MAPPING:
                   1110:                                INIT(map);
                   1111:                                this->policy_mappings->insert_last(this->policy_mappings, map);
                   1112:                                break;
                   1113:                        case POLICY_MAPPING_ISSUER:
                   1114:                                if (map && !map->issuer.len)
                   1115:                                {
                   1116:                                        map->issuer = chunk_clone(object);
                   1117:                                }
                   1118:                                break;
                   1119:                        case POLICY_MAPPING_SUBJECT:
                   1120:                                if (map && !map->subject.len)
                   1121:                                {
                   1122:                                        map->subject = chunk_clone(object);
                   1123:                                }
                   1124:                                break;
                   1125:                        default:
                   1126:                                break;
                   1127:                }
                   1128:        }
                   1129:        success = parser->success(parser);
                   1130:        parser->destroy(parser);
                   1131: 
                   1132:        return success;
                   1133: }
                   1134: 
                   1135: /**
                   1136:  * ASN.1 definition of a policyConstraints extension
                   1137:  */
                   1138: static const asn1Object_t policyConstraintsObjects[] = {
                   1139:        { 0, "policyConstraints",               ASN1_SEQUENCE,          ASN1_NONE                       }, /*  0 */
                   1140:        { 1,   "requireExplicitPolicy", ASN1_CONTEXT_C_0,       ASN1_OPT|ASN1_NONE      }, /*  1 */
                   1141:        { 2,     "SkipCerts",                   ASN1_INTEGER,           ASN1_BODY                       }, /*  2 */
                   1142:        { 1,   "end opt",                               ASN1_EOC,                       ASN1_END                        }, /*  3 */
                   1143:        { 1,   "inhibitPolicyMapping",  ASN1_CONTEXT_C_1,       ASN1_OPT|ASN1_NONE      }, /*  4 */
                   1144:        { 2,     "SkipCerts",                   ASN1_INTEGER,           ASN1_BODY                       }, /*  5 */
                   1145:        { 1,   "end opt",                               ASN1_EOC,                       ASN1_END                        }, /*  6 */
                   1146:        { 0, "exit",                                    ASN1_EOC,                       ASN1_EXIT                       }
                   1147: };
                   1148: #define POLICY_CONSTRAINT_EXPLICIT 2
                   1149: #define POLICY_CONSTRAINT_INHIBIT  5
                   1150: 
                   1151: /**
                   1152:  * Parse policyConstraints
                   1153:  */
                   1154: static bool parse_policyConstraints(chunk_t blob, int level0,
                   1155:                                                                        private_x509_cert_t *this)
                   1156: {
                   1157:        asn1_parser_t *parser;
                   1158:        chunk_t object;
                   1159:        int objectID;
                   1160:        bool success;
                   1161: 
                   1162:        parser = asn1_parser_create(policyConstraintsObjects, blob);
                   1163:        parser->set_top_level(parser, level0);
                   1164: 
                   1165:        while (parser->iterate(parser, &objectID, &object))
                   1166:        {
                   1167:                switch (objectID)
                   1168:                {
                   1169:                        case POLICY_CONSTRAINT_EXPLICIT:
                   1170:                                this->require_explicit = parse_constraint(object);
                   1171:                                break;
                   1172:                        case POLICY_CONSTRAINT_INHIBIT:
                   1173:                                this->inhibit_mapping = parse_constraint(object);
                   1174:                                break;
                   1175:                        default:
                   1176:                                break;
                   1177:                }
                   1178:        }
                   1179:        success = parser->success(parser);
                   1180:        parser->destroy(parser);
                   1181: 
                   1182:        return success;
                   1183: }
                   1184: 
                   1185: /**
                   1186:  * ASN.1 definition of ipAddrBlocks according to RFC 3779
                   1187:  */
                   1188: static const asn1Object_t ipAddrBlocksObjects[] = {
                   1189:        { 0, "ipAddrBlocks",            ASN1_SEQUENCE,     ASN1_LOOP            }, /*  0 */
                   1190:        { 1,   "ipAddressFamily",       ASN1_SEQUENCE,     ASN1_NONE            }, /*  1 */
                   1191:        { 2,     "addressFamily",       ASN1_OCTET_STRING, ASN1_BODY            }, /*  2 */
                   1192:        { 2,     "ipAddressChoice",     ASN1_EOC,          ASN1_CHOICE          }, /*  3 */
                   1193:        { 3,       "inherit",           ASN1_NULL,         ASN1_OPT             }, /*  4 */
                   1194:        { 3,       "end choice",        ASN1_EOC,          ASN1_END|ASN1_CH     }, /*  5 */
                   1195:        { 3,       "addressesOrRanges", ASN1_SEQUENCE,     ASN1_OPT|ASN1_LOOP   }, /*  6 */
                   1196:        { 4,         "addressOrRange",  ASN1_EOC,          ASN1_CHOICE          }, /*  7 */
                   1197:        { 5,           "addressPrefix", ASN1_BIT_STRING,   ASN1_OPT|ASN1_BODY   }, /*  8 */
                   1198:        { 5,           "end choice",    ASN1_EOC,          ASN1_END|ASN1_CH     }, /*  9 */
                   1199:        { 5,           "addressRange",  ASN1_SEQUENCE,     ASN1_OPT             }, /* 10 */
                   1200:        { 6,             "min",         ASN1_BIT_STRING,   ASN1_BODY            }, /* 11 */
                   1201:        { 6,             "max",         ASN1_BIT_STRING,   ASN1_BODY            }, /* 12 */
                   1202:        { 5,           "end choice",    ASN1_EOC,          ASN1_END|ASN1_CH     }, /* 13 */
                   1203:        { 4,         "end choices",     ASN1_EOC,          ASN1_END|ASN1_CHOICE }, /* 14 */
                   1204:        { 3,       "end loop/choice",   ASN1_EOC,          ASN1_END|ASN1_CH     }, /* 15 */
                   1205:        { 2,     "end choices",         ASN1_EOC,          ASN1_END|ASN1_CHOICE }, /* 16 */
                   1206:        { 0, "end loop",                ASN1_EOC,          ASN1_END             }, /* 17 */
                   1207:        { 0, "exit",                    ASN1_EOC,          ASN1_EXIT            }
                   1208: };
                   1209: #define IP_ADDR_BLOCKS_FAMILY       2
                   1210: #define IP_ADDR_BLOCKS_INHERIT      4
                   1211: #define IP_ADDR_BLOCKS_PREFIX       8
                   1212: #define IP_ADDR_BLOCKS_MIN         11
                   1213: #define IP_ADDR_BLOCKS_MAX         12
                   1214: 
                   1215: static bool check_address_object(ts_type_t ts_type, chunk_t object)
                   1216: {
                   1217:        switch (ts_type)
                   1218:        {
                   1219:                case TS_IPV4_ADDR_RANGE:
                   1220:                        if (object.len > 5)
                   1221:                        {
                   1222:                                DBG1(DBG_ASN, "IPv4 address object is larger than 5 octets");
                   1223:                                return FALSE;
                   1224:                        }
                   1225:                        break;
                   1226:                case TS_IPV6_ADDR_RANGE:
                   1227:                        if (object.len > 17)
                   1228:                        {
                   1229:                                DBG1(DBG_ASN, "IPv6 address object is larger than 17 octets");
                   1230:                                return FALSE;
                   1231:                        }
                   1232:                        break;
                   1233:                default:
                   1234:                        DBG1(DBG_ASN, "unknown address family");
                   1235:                        return FALSE;
                   1236:        }
                   1237:        if (object.len == 0)
                   1238:        {
                   1239:                DBG1(DBG_ASN, "An ASN.1 bit string must contain at least the "
                   1240:                         "initial octet");
                   1241:                return FALSE;
                   1242:        }
                   1243:        if (object.len == 1 && object.ptr[0] != 0)
                   1244:        {
                   1245:                DBG1(DBG_ASN, "An empty ASN.1 bit string must contain a zero "
                   1246:                         "initial octet");
                   1247:                return FALSE;
                   1248:        }
                   1249:        if (object.ptr[0] > 7)
                   1250:        {
                   1251:                DBG1(DBG_ASN, "number of unused bits is too large");
                   1252:                return FALSE;
                   1253:        }
                   1254:        return TRUE;
                   1255: }
                   1256: 
                   1257: static bool parse_ipAddrBlocks(chunk_t blob, int level0,
                   1258:                                                           private_x509_cert_t *this)
                   1259: {
                   1260:        asn1_parser_t *parser;
                   1261:        chunk_t object, min_object;
                   1262:        ts_type_t ts_type = 0;
                   1263:        traffic_selector_t *ts;
                   1264:        int objectID;
                   1265:        bool success = FALSE;
                   1266: 
                   1267:        parser = asn1_parser_create(ipAddrBlocksObjects, blob);
                   1268:        parser->set_top_level(parser, level0);
                   1269: 
                   1270:        while (parser->iterate(parser, &objectID, &object))
                   1271:        {
                   1272:                switch (objectID)
                   1273:                {
                   1274:                        case IP_ADDR_BLOCKS_FAMILY:
                   1275:                                ts_type = 0;
                   1276:                                if (object.len == 2 && object.ptr[0] == 0)
                   1277:                                {
                   1278:                                        if (object.ptr[1] == 1)
                   1279:                                        {
                   1280:                                                ts_type = TS_IPV4_ADDR_RANGE;
                   1281:                                        }
                   1282:                                        else if (object.ptr[1] == 2)
                   1283:                                        {
                   1284:                                                ts_type = TS_IPV6_ADDR_RANGE;
                   1285:                                        }
                   1286:                                        else
                   1287:                                        {
                   1288:                                                break;
                   1289:                                        }
                   1290:                                        DBG2(DBG_ASN, "  %N", ts_type_name, ts_type);
                   1291:                                }
                   1292:                                break;
                   1293:                        case IP_ADDR_BLOCKS_INHERIT:
                   1294:                                DBG1(DBG_ASN, "inherit choice is not supported");
                   1295:                                break;
                   1296:                        case IP_ADDR_BLOCKS_PREFIX:
                   1297:                                if (!check_address_object(ts_type, object))
                   1298:                                {
                   1299:                                        goto end;
                   1300:                                }
                   1301:                                ts = traffic_selector_create_from_rfc3779_format(ts_type,
                   1302:                                                                                                        object, object);
                   1303:                                DBG2(DBG_ASN, "  %R", ts);
                   1304:                                this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts);
                   1305:                                break;
                   1306:                        case IP_ADDR_BLOCKS_MIN:
                   1307:                                if (!check_address_object(ts_type, object))
                   1308:                                {
                   1309:                                        goto end;
                   1310:                                }
                   1311:                                min_object = object;
                   1312:                                break;
                   1313:                        case IP_ADDR_BLOCKS_MAX:
                   1314:                                if (!check_address_object(ts_type, object))
                   1315:                                {
                   1316:                                        goto end;
                   1317:                                }
                   1318:                                ts = traffic_selector_create_from_rfc3779_format(ts_type,
                   1319:                                                                                                        min_object, object);
                   1320:                                DBG2(DBG_ASN, "  %R", ts);
                   1321:                                this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts);
                   1322:                                break;
                   1323:                        default:
                   1324:                                break;
                   1325:                }
                   1326:        }
                   1327:        success = parser->success(parser);
                   1328:        this->flags |= X509_IP_ADDR_BLOCKS;
                   1329: 
                   1330: end:
                   1331:        parser->destroy(parser);
                   1332: 
                   1333:        return success;
                   1334: }
                   1335: 
                   1336: /**
                   1337:  * ASN.1 definition of an X.509v3 x509_cert
                   1338:  */
                   1339: static const asn1Object_t certObjects[] = {
                   1340:        { 0, "x509",                                    ASN1_SEQUENCE,          ASN1_OBJ                        }, /*  0 */
                   1341:        { 1,   "tbsCertificate",                ASN1_SEQUENCE,          ASN1_OBJ                        }, /*  1 */
                   1342:        { 2,     "DEFAULT v1",                  ASN1_CONTEXT_C_0,       ASN1_DEF                        }, /*  2 */
                   1343:        { 3,       "version",                   ASN1_INTEGER,           ASN1_BODY                       }, /*  3 */
                   1344:        { 2,     "serialNumber",                ASN1_INTEGER,           ASN1_BODY                       }, /*  4 */
                   1345:        { 2,     "signature",                   ASN1_EOC,                       ASN1_RAW                        }, /*  5 */
                   1346:        { 2,     "issuer",                              ASN1_SEQUENCE,          ASN1_OBJ                        }, /*  6 */
                   1347:        { 2,     "validity",                    ASN1_SEQUENCE,          ASN1_NONE                       }, /*  7 */
                   1348:        { 3,       "notBefore",                 ASN1_EOC,                       ASN1_RAW                        }, /*  8 */
                   1349:        { 3,       "notAfter",                  ASN1_EOC,                       ASN1_RAW                        }, /*  9 */
                   1350:        { 2,     "subject",                             ASN1_SEQUENCE,          ASN1_OBJ                        }, /* 10 */
                   1351:        { 2,     "subjectPublicKeyInfo",ASN1_SEQUENCE,          ASN1_RAW                        }, /* 11 */
                   1352:        { 2,     "issuerUniqueID",              ASN1_CONTEXT_C_1,       ASN1_OPT                        }, /* 12 */
                   1353:        { 2,     "end opt",                             ASN1_EOC,                       ASN1_END                        }, /* 13 */
                   1354:        { 2,     "subjectUniqueID",             ASN1_CONTEXT_C_2,       ASN1_OPT                        }, /* 14 */
                   1355:        { 2,     "end opt",                             ASN1_EOC,                       ASN1_END                        }, /* 15 */
                   1356:        { 2,     "optional extensions", ASN1_CONTEXT_C_3,       ASN1_OPT                        }, /* 16 */
                   1357:        { 3,       "extensions",                ASN1_SEQUENCE,          ASN1_LOOP                       }, /* 17 */
                   1358:        { 4,         "extension",               ASN1_SEQUENCE,          ASN1_NONE                       }, /* 18 */
                   1359:        { 5,           "extnID",                ASN1_OID,                       ASN1_BODY                       }, /* 19 */
                   1360:        { 5,           "critical",              ASN1_BOOLEAN,           ASN1_DEF|ASN1_BODY      }, /* 20 */
                   1361:        { 5,           "extnValue",             ASN1_OCTET_STRING,      ASN1_BODY                       }, /* 21 */
                   1362:        { 3,       "end loop",                  ASN1_EOC,                       ASN1_END                        }, /* 22 */
                   1363:        { 2,     "end opt",                             ASN1_EOC,                       ASN1_END                        }, /* 23 */
                   1364:        { 1,   "signatureAlgorithm",    ASN1_EOC,                       ASN1_RAW                        }, /* 24 */
                   1365:        { 1,   "signatureValue",                ASN1_BIT_STRING,        ASN1_BODY                       }, /* 25 */
                   1366:        { 0, "exit",                                    ASN1_EOC,                       ASN1_EXIT                       }
                   1367: };
                   1368: #define X509_OBJ_TBS_CERTIFICATE                                1
                   1369: #define X509_OBJ_VERSION                                                3
                   1370: #define X509_OBJ_SERIAL_NUMBER                                  4
                   1371: #define X509_OBJ_SIG_ALG                                                5
                   1372: #define X509_OBJ_ISSUER                                                         6
                   1373: #define X509_OBJ_NOT_BEFORE                                             8
                   1374: #define X509_OBJ_NOT_AFTER                                              9
                   1375: #define X509_OBJ_SUBJECT                                               10
                   1376: #define X509_OBJ_SUBJECT_PUBLIC_KEY_INFO               11
                   1377: #define X509_OBJ_OPTIONAL_EXTENSIONS                   16
                   1378: #define X509_OBJ_EXTN_ID                                               19
                   1379: #define X509_OBJ_CRITICAL                                              20
                   1380: #define X509_OBJ_EXTN_VALUE                                            21
                   1381: #define X509_OBJ_ALGORITHM                                             24
                   1382: #define X509_OBJ_SIGNATURE                                             25
                   1383: 
                   1384: /**
                   1385:  * Parses an X.509v3 certificate
                   1386:  */
                   1387: static bool parse_certificate(private_x509_cert_t *this)
                   1388: {
                   1389:        asn1_parser_t *parser;
                   1390:        chunk_t object;
                   1391:        int objectID;
                   1392:        int extn_oid = OID_UNKNOWN;
                   1393:        signature_params_t sig_alg = {};
                   1394:        bool success = FALSE;
                   1395:        bool critical = FALSE;
                   1396: 
                   1397:        parser = asn1_parser_create(certObjects, this->encoding);
                   1398: 
                   1399:        /* unless we see a keyUsage extension we are compliant with RFC 4945 */
                   1400:        this->flags |= X509_IKE_COMPLIANT;
                   1401: 
                   1402:        while (parser->iterate(parser, &objectID, &object))
                   1403:        {
                   1404:                u_int level = parser->get_level(parser)+1;
                   1405: 
                   1406:                switch (objectID)
                   1407:                {
                   1408:                        case X509_OBJ_TBS_CERTIFICATE:
                   1409:                                this->tbsCertificate = object;
                   1410:                                break;
                   1411:                        case X509_OBJ_VERSION:
                   1412:                                this->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
                   1413:                                if (this->version < 1 || this->version > 3)
                   1414:                                {
                   1415:                                        DBG1(DBG_ASN, "X.509v%d not supported", this->version);
                   1416:                                        goto end;
                   1417:                                }
                   1418:                                else
                   1419:                                {
                   1420:                                        DBG2(DBG_ASN, "  X.509v%d", this->version);
                   1421:                                }
                   1422:                                break;
                   1423:                        case X509_OBJ_SERIAL_NUMBER:
                   1424:                                this->serialNumber = object;
                   1425:                                break;
                   1426:                        case X509_OBJ_SIG_ALG:
                   1427:                                if (!signature_params_parse(object, level, &sig_alg))
                   1428:                                {
                   1429:                                        DBG1(DBG_ASN, "  unable to parse signature algorithm");
                   1430:                                        goto end;
                   1431:                                }
                   1432:                                break;
                   1433:                        case X509_OBJ_ISSUER:
                   1434:                                this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
                   1435:                                DBG2(DBG_ASN, "  '%Y'", this->issuer);
                   1436:                                break;
                   1437:                        case X509_OBJ_NOT_BEFORE:
                   1438:                                this->notBefore = asn1_parse_time(object, level);
                   1439:                                break;
                   1440:                        case X509_OBJ_NOT_AFTER:
                   1441:                                this->notAfter = asn1_parse_time(object, level);
                   1442:                                break;
                   1443:                        case X509_OBJ_SUBJECT:
                   1444:                                this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object);
                   1445:                                DBG2(DBG_ASN, "  '%Y'", this->subject);
                   1446:                                break;
                   1447:                        case X509_OBJ_SUBJECT_PUBLIC_KEY_INFO:
                   1448:                                DBG2(DBG_ASN, "-- > --");
                   1449:                                this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
                   1450:                                                KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END);
                   1451:                                DBG2(DBG_ASN, "-- < --");
                   1452:                                if (this->public_key == NULL)
                   1453:                                {
                   1454:                                        goto end;
                   1455:                                }
                   1456:                                break;
                   1457:                        case X509_OBJ_OPTIONAL_EXTENSIONS:
                   1458:                                if (this->version != 3)
                   1459:                                {
                   1460:                                        DBG1(DBG_ASN, "Only X.509v3 certificates have extensions");
                   1461:                                        goto end;
                   1462:                                }
                   1463:                                break;
                   1464:                        case X509_OBJ_EXTN_ID:
                   1465:                                extn_oid = asn1_known_oid(object);
                   1466:                                break;
                   1467:                        case X509_OBJ_CRITICAL:
                   1468:                                critical = object.len && *object.ptr;
                   1469:                                DBG2(DBG_ASN, "  %s", critical ? "TRUE" : "FALSE");
                   1470:                                break;
                   1471:                        case X509_OBJ_EXTN_VALUE:
                   1472:                        {
                   1473:                                switch (extn_oid)
                   1474:                                {
                   1475:                                        case OID_SUBJECT_KEY_ID:
                   1476:                                                if (!asn1_parse_simple_object(&object, ASN1_OCTET_STRING,
                   1477:                                                                                                          level, "keyIdentifier"))
                   1478:                                                {
                   1479:                                                        goto end;
                   1480:                                                }
                   1481:                                                this->subjectKeyIdentifier = object;
                   1482:                                                break;
                   1483:                                        case OID_SUBJECT_ALT_NAME:
                   1484:                                                if (!x509_parse_generalNames(object, level, FALSE,
                   1485:                                                                                                         this->subjectAltNames))
                   1486:                                                {
                   1487:                                                        goto end;
                   1488:                                                }
                   1489:                                                break;
                   1490:                                        case OID_BASIC_CONSTRAINTS:
                   1491:                                                if (!parse_basicConstraints(object, level, this))
                   1492:                                                {
                   1493:                                                        goto end;
                   1494:                                                }
                   1495:                                                break;
                   1496:                                        case OID_CRL_DISTRIBUTION_POINTS:
                   1497:                                                if (!x509_parse_crlDistributionPoints(object, level,
                   1498:                                                                                                                          this->crl_uris))
                   1499:                                                {
                   1500:                                                        goto end;
                   1501:                                                }
                   1502:                                                break;
                   1503:                                        case OID_AUTHORITY_KEY_ID:
                   1504:                                                chunk_free(&this->authKeyIdentifier);
                   1505:                                                this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(
                   1506:                                                                        object, level, &this->authKeySerialNumber);
                   1507:                                                break;
                   1508:                                        case OID_AUTHORITY_INFO_ACCESS:
                   1509:                                                if (!parse_authorityInfoAccess(object, level, this))
                   1510:                                                {
                   1511:                                                        goto end;
                   1512:                                                }
                   1513:                                                break;
                   1514:                                        case OID_KEY_USAGE:
                   1515:                                                parse_keyUsage(object, this);
                   1516:                                                break;
                   1517:                                        case OID_EXTENDED_KEY_USAGE:
                   1518:                                                if (!parse_extendedKeyUsage(object, level, this))
                   1519:                                                {
                   1520:                                                        goto end;
                   1521:                                                }
                   1522:                                                break;
                   1523:                                        case OID_IP_ADDR_BLOCKS:
                   1524:                                                if (!parse_ipAddrBlocks(object, level, this))
                   1525:                                                {
                   1526:                                                        goto end;
                   1527:                                                }
                   1528:                                                break;
                   1529:                                        case OID_NAME_CONSTRAINTS:
                   1530:                                                if (!parse_nameConstraints(object, level, this))
                   1531:                                                {
                   1532:                                                        goto end;
                   1533:                                                }
                   1534:                                                break;
                   1535:                                        case OID_CERTIFICATE_POLICIES:
                   1536:                                                if (!parse_certificatePolicies(object, level, this))
                   1537:                                                {
                   1538:                                                        goto end;
                   1539:                                                }
                   1540:                                                break;
                   1541:                                        case OID_POLICY_MAPPINGS:
                   1542:                                                if (!parse_policyMappings(object, level, this))
                   1543:                                                {
                   1544:                                                        goto end;
                   1545:                                                }
                   1546:                                                break;
                   1547:                                        case OID_POLICY_CONSTRAINTS:
                   1548:                                                if (!parse_policyConstraints(object, level, this))
                   1549:                                                {
                   1550:                                                        goto end;
                   1551:                                                }
                   1552:                                                break;
                   1553:                                        case OID_INHIBIT_ANY_POLICY:
                   1554:                                                if (!asn1_parse_simple_object(&object, ASN1_INTEGER,
                   1555:                                                                                                          level, "inhibitAnyPolicy"))
                   1556:                                                {
                   1557:                                                        goto end;
                   1558:                                                }
                   1559:                                                this->inhibit_any = parse_constraint(object);
                   1560:                                                break;
                   1561:                                        case OID_NS_REVOCATION_URL:
                   1562:                                        case OID_NS_CA_REVOCATION_URL:
                   1563:                                        case OID_NS_CA_POLICY_URL:
                   1564:                                        case OID_NS_COMMENT:
                   1565:                                                if (!asn1_parse_simple_object(&object, ASN1_IA5STRING,
                   1566:                                                                                        level, oid_names[extn_oid].name))
                   1567:                                                {
                   1568:                                                        goto end;
                   1569:                                                }
                   1570:                                                break;
                   1571:                                        default:
                   1572:                                                if (critical && lib->settings->get_bool(lib->settings,
                   1573:                                                        "%s.x509.enforce_critical", TRUE, lib->ns))
                   1574:                                                {
                   1575:                                                        DBG1(DBG_ASN, "critical '%s' extension not supported",
                   1576:                                                                 (extn_oid == OID_UNKNOWN) ? "unknown" :
                   1577:                                                                 (char*)oid_names[extn_oid].name);
                   1578:                                                        goto end;
                   1579:                                                }
                   1580:                                                break;
                   1581:                                }
                   1582:                                break;
                   1583:                        }
                   1584:                        case X509_OBJ_ALGORITHM:
                   1585:                                INIT(this->scheme);
                   1586:                                if (!signature_params_parse(object, level, this->scheme))
                   1587:                                {
                   1588:                                        DBG1(DBG_ASN, "  unable to parse signature algorithm");
                   1589:                                        goto end;
                   1590:                                }
                   1591:                                if (!signature_params_equal(this->scheme, &sig_alg))
                   1592:                                {
                   1593:                                        DBG1(DBG_ASN, "  signature algorithms do not agree");
                   1594:                                        goto end;
                   1595:                                }
                   1596:                                break;
                   1597:                        case X509_OBJ_SIGNATURE:
                   1598:                                this->signature = chunk_skip(object, 1);
                   1599:                                break;
                   1600:                        default:
                   1601:                                break;
                   1602:                }
                   1603:        }
                   1604:        success = parser->success(parser);
                   1605: 
                   1606: end:
                   1607:        parser->destroy(parser);
                   1608:        signature_params_clear(&sig_alg);
                   1609:        if (success)
                   1610:        {
                   1611:                hasher_t *hasher;
                   1612: 
                   1613:                /* check if the certificate is self-signed */
                   1614:                if (this->public.interface.interface.issued_by(
                   1615:                                                                                        &this->public.interface.interface,
                   1616:                                                                                        &this->public.interface.interface,
                   1617:                                                                                        NULL))
                   1618:                {
                   1619:                        this->flags |= X509_SELF_SIGNED;
                   1620:                }
                   1621:                /* create certificate hash */
                   1622:                hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
                   1623:                if (!hasher ||
                   1624:                        !hasher->allocate_hash(hasher, this->encoding, &this->encoding_hash))
                   1625:                {
                   1626:                        DESTROY_IF(hasher);
                   1627:                        DBG1(DBG_ASN, "  unable to create hash of certificate, SHA1 not supported");
                   1628:                        return FALSE;
                   1629:                }
                   1630:                hasher->destroy(hasher);
                   1631:        }
                   1632:        return success;
                   1633: }
                   1634: 
                   1635: METHOD(certificate_t, get_type, certificate_type_t,
                   1636:        private_x509_cert_t *this)
                   1637: {
                   1638:        return CERT_X509;
                   1639: }
                   1640: 
                   1641: METHOD(certificate_t, get_subject, identification_t*,
                   1642:        private_x509_cert_t *this)
                   1643: {
                   1644:        return this->subject;
                   1645: }
                   1646: 
                   1647: METHOD(certificate_t, get_issuer, identification_t*,
                   1648:        private_x509_cert_t *this)
                   1649: {
                   1650:        return this->issuer;
                   1651: }
                   1652: 
                   1653: METHOD(certificate_t, has_subject, id_match_t,
                   1654:        private_x509_cert_t *this, identification_t *subject)
                   1655: {
                   1656:        identification_t *current;
                   1657:        enumerator_t *enumerator;
                   1658:        id_match_t match, best;
                   1659:        chunk_t encoding;
                   1660: 
                   1661:        if (subject->get_type(subject) == ID_KEY_ID)
                   1662:        {
                   1663:                encoding = subject->get_encoding(subject);
                   1664: 
                   1665:                if (this->encoding_hash.len &&
                   1666:                        chunk_equals(this->encoding_hash, encoding))
                   1667:                {
                   1668:                        return ID_MATCH_PERFECT;
                   1669:                }
                   1670:                if (this->subjectKeyIdentifier.len &&
                   1671:                        chunk_equals(this->subjectKeyIdentifier, encoding))
                   1672:                {
                   1673:                        return ID_MATCH_PERFECT;
                   1674:                }
                   1675:                if (this->public_key &&
                   1676:                        this->public_key->has_fingerprint(this->public_key, encoding))
                   1677:                {
                   1678:                        return ID_MATCH_PERFECT;
                   1679:                }
                   1680:                if (chunk_equals(this->serialNumber, encoding))
                   1681:                {
                   1682:                        return ID_MATCH_PERFECT;
                   1683:                }
                   1684:        }
                   1685:        best = this->subject->matches(this->subject, subject);
                   1686:        enumerator = this->subjectAltNames->create_enumerator(this->subjectAltNames);
                   1687:        while (enumerator->enumerate(enumerator, &current))
                   1688:        {
                   1689:                match = current->matches(current, subject);
                   1690:                if (match > best)
                   1691:                {
                   1692:                        best = match;
                   1693:                }
                   1694:        }
                   1695:        enumerator->destroy(enumerator);
                   1696:        return best;
                   1697: }
                   1698: 
                   1699: METHOD(certificate_t, has_issuer, id_match_t,
                   1700:        private_x509_cert_t *this, identification_t *issuer)
                   1701: {
                   1702:        /* issuerAltNames currently not supported */
                   1703:        return this->issuer->matches(this->issuer, issuer);
                   1704: }
                   1705: 
                   1706: METHOD(certificate_t, issued_by, bool,
                   1707:        private_x509_cert_t *this, certificate_t *issuer,
                   1708:        signature_params_t **scheme)
                   1709: {
                   1710:        public_key_t *key;
                   1711:        bool valid;
                   1712:        x509_t *x509 = (x509_t*)issuer;
                   1713: 
                   1714:        if (&this->public.interface.interface == issuer)
                   1715:        {
                   1716:                if (this->flags & X509_SELF_SIGNED)
                   1717:                {
                   1718:                        if (scheme)
                   1719:                        {
                   1720:                                *scheme = signature_params_clone(this->scheme);
                   1721:                        }
                   1722:                        return TRUE;
                   1723:                }
                   1724:        }
                   1725:        else
                   1726:        {
                   1727:                if (issuer->get_type(issuer) != CERT_X509)
                   1728:                {
                   1729:                        return FALSE;
                   1730:                }
                   1731:                if (!(x509->get_flags(x509) & X509_CA))
                   1732:                {
                   1733:                        return FALSE;
                   1734:                }
                   1735:        }
                   1736:        if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
                   1737:        {
                   1738:                return FALSE;
                   1739:        }
                   1740: 
                   1741:        /* get the public key of the issuer */
                   1742:        key = issuer->get_public_key(issuer);
                   1743:        if (!key)
                   1744:        {
                   1745:                return FALSE;
                   1746:        }
                   1747:        valid = key->verify(key, this->scheme->scheme, this->scheme->params,
                   1748:                                                this->tbsCertificate, this->signature);
                   1749:        key->destroy(key);
                   1750:        if (valid && scheme)
                   1751:        {
                   1752:                *scheme = signature_params_clone(this->scheme);
                   1753:        }
                   1754:        return valid;
                   1755: }
                   1756: 
                   1757: METHOD(certificate_t, get_public_key, public_key_t*,
                   1758:        private_x509_cert_t *this)
                   1759: {
                   1760:        this->public_key->get_ref(this->public_key);
                   1761:        return this->public_key;
                   1762: }
                   1763: 
                   1764: METHOD(certificate_t, get_ref, certificate_t*,
                   1765:        private_x509_cert_t *this)
                   1766: {
                   1767:        ref_get(&this->ref);
                   1768:        return &this->public.interface.interface;
                   1769: }
                   1770: 
                   1771: METHOD(certificate_t, get_validity, bool,
                   1772:        private_x509_cert_t *this, time_t *when, time_t *not_before,
                   1773:        time_t *not_after)
                   1774: {
                   1775:        time_t t = when ? *when : time(NULL);
                   1776: 
                   1777:        if (not_before)
                   1778:        {
                   1779:                *not_before = this->notBefore;
                   1780:        }
                   1781:        if (not_after)
                   1782:        {
                   1783:                *not_after = this->notAfter;
                   1784:        }
                   1785:        return (t >= this->notBefore && t <= this->notAfter);
                   1786: }
                   1787: 
                   1788: METHOD(certificate_t, get_encoding, bool,
                   1789:        private_x509_cert_t *this, cred_encoding_type_t type, chunk_t *encoding)
                   1790: {
                   1791:        if (type == CERT_ASN1_DER)
                   1792:        {
                   1793:                *encoding = chunk_clone(this->encoding);
                   1794:                return TRUE;
                   1795:        }
                   1796:        return lib->encoding->encode(lib->encoding, type, NULL, encoding,
                   1797:                                                CRED_PART_X509_ASN1_DER, this->encoding, CRED_PART_END);
                   1798: }
                   1799: 
                   1800: METHOD(certificate_t, equals, bool,
                   1801:        private_x509_cert_t *this, certificate_t *other)
                   1802: {
                   1803:        chunk_t encoding;
                   1804:        bool equal;
                   1805: 
                   1806:        if (this == (private_x509_cert_t*)other)
                   1807:        {
                   1808:                return TRUE;
                   1809:        }
                   1810:        if (other->get_type(other) != CERT_X509)
                   1811:        {
                   1812:                return FALSE;
                   1813:        }
                   1814:        if (other->equals == (void*)equals)
                   1815:        {       /* skip allocation if we have the same implementation */
                   1816:                return chunk_equals(this->encoding, ((private_x509_cert_t*)other)->encoding);
                   1817:        }
                   1818:        if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
                   1819:        {
                   1820:                return FALSE;
                   1821:        }
                   1822:        equal = chunk_equals(this->encoding, encoding);
                   1823:        free(encoding.ptr);
                   1824:        return equal;
                   1825: }
                   1826: 
                   1827: METHOD(x509_t, get_flags, x509_flag_t,
                   1828:        private_x509_cert_t *this)
                   1829: {
                   1830:        return this->flags;
                   1831: }
                   1832: 
                   1833: METHOD(x509_t, get_serial, chunk_t,
                   1834:        private_x509_cert_t *this)
                   1835: {
                   1836:        return this->serialNumber;
                   1837: }
                   1838: 
                   1839: METHOD(x509_t, get_subjectKeyIdentifier, chunk_t,
                   1840:        private_x509_cert_t *this)
                   1841: {
                   1842:        if (this->subjectKeyIdentifier.ptr)
                   1843:        {
                   1844:                return this->subjectKeyIdentifier;
                   1845:        }
                   1846:        else
                   1847:        {
                   1848:                chunk_t fingerprint;
                   1849: 
                   1850:                if (this->public_key->get_fingerprint(this->public_key,
                   1851:                                                                        KEYID_PUBKEY_SHA1, &fingerprint))
                   1852:                {
                   1853:                        return fingerprint;
                   1854:                }
                   1855:                else
                   1856:                {
                   1857:                        return chunk_empty;
                   1858:                }
                   1859:        }
                   1860: }
                   1861: 
                   1862: METHOD(x509_t, get_authKeyIdentifier, chunk_t,
                   1863:        private_x509_cert_t *this)
                   1864: {
                   1865:        return this->authKeyIdentifier;
                   1866: }
                   1867: 
                   1868: METHOD(x509_t, get_constraint, u_int,
                   1869:        private_x509_cert_t *this, x509_constraint_t type)
                   1870: {
                   1871:        switch (type)
                   1872:        {
                   1873:                case X509_PATH_LEN:
                   1874:                        return this->pathLenConstraint;
                   1875:                case X509_REQUIRE_EXPLICIT_POLICY:
                   1876:                        return this->require_explicit;
                   1877:                case X509_INHIBIT_POLICY_MAPPING:
                   1878:                        return this->inhibit_mapping;
                   1879:                case X509_INHIBIT_ANY_POLICY:
                   1880:                        return this->inhibit_any;
                   1881:                default:
                   1882:                        return X509_NO_CONSTRAINT;
                   1883:        }
                   1884: }
                   1885: 
                   1886: METHOD(x509_t, create_subjectAltName_enumerator, enumerator_t*,
                   1887:        private_x509_cert_t *this)
                   1888: {
                   1889:        return this->subjectAltNames->create_enumerator(this->subjectAltNames);
                   1890: }
                   1891: 
                   1892: METHOD(x509_t, create_ocsp_uri_enumerator, enumerator_t*,
                   1893:        private_x509_cert_t *this)
                   1894: {
                   1895:        return this->ocsp_uris->create_enumerator(this->ocsp_uris);
                   1896: }
                   1897: 
                   1898: METHOD(x509_t, create_crl_uri_enumerator, enumerator_t*,
                   1899:        private_x509_cert_t *this)
                   1900: {
                   1901:        return this->crl_uris->create_enumerator(this->crl_uris);
                   1902: }
                   1903: 
                   1904: METHOD(x509_t, create_ipAddrBlock_enumerator, enumerator_t*,
                   1905:        private_x509_cert_t *this)
                   1906: {
                   1907:        return this->ipAddrBlocks->create_enumerator(this->ipAddrBlocks);
                   1908: }
                   1909: 
                   1910: METHOD(x509_t, create_name_constraint_enumerator, enumerator_t*,
                   1911:        private_x509_cert_t *this, bool perm)
                   1912: {
                   1913:        if (perm)
                   1914:        {
                   1915:                return this->permitted_names->create_enumerator(this->permitted_names);
                   1916:        }
                   1917:        return this->excluded_names->create_enumerator(this->excluded_names);
                   1918: }
                   1919: 
                   1920: METHOD(x509_t, create_cert_policy_enumerator, enumerator_t*,
                   1921:        private_x509_cert_t *this)
                   1922: {
                   1923:        return this->cert_policies->create_enumerator(this->cert_policies);
                   1924: }
                   1925: 
                   1926: METHOD(x509_t, create_policy_mapping_enumerator, enumerator_t*,
                   1927:        private_x509_cert_t *this)
                   1928: {
                   1929:        return this->policy_mappings->create_enumerator(this->policy_mappings);
                   1930: }
                   1931: 
                   1932: METHOD(certificate_t, destroy, void,
                   1933:        private_x509_cert_t *this)
                   1934: {
                   1935:        if (ref_put(&this->ref))
                   1936:        {
                   1937:                this->subjectAltNames->destroy_offset(this->subjectAltNames,
                   1938:                                                                        offsetof(identification_t, destroy));
                   1939:                this->crl_uris->destroy_function(this->crl_uris,
                   1940:                                                                                 (void*)x509_cdp_destroy);
                   1941:                this->ocsp_uris->destroy_function(this->ocsp_uris, free);
                   1942:                this->ipAddrBlocks->destroy_offset(this->ipAddrBlocks,
                   1943:                                                                                offsetof(traffic_selector_t, destroy));
                   1944:                this->permitted_names->destroy_offset(this->permitted_names,
                   1945:                                                                                offsetof(identification_t, destroy));
                   1946:                this->excluded_names->destroy_offset(this->excluded_names,
                   1947:                                                                                offsetof(identification_t, destroy));
                   1948:                this->cert_policies->destroy_function(this->cert_policies,
                   1949:                                                                                          (void*)cert_policy_destroy);
                   1950:                this->policy_mappings->destroy_function(this->policy_mappings,
                   1951:                                                                                          (void*)policy_mapping_destroy);
                   1952:                signature_params_destroy(this->scheme);
                   1953:                DESTROY_IF(this->issuer);
                   1954:                DESTROY_IF(this->subject);
                   1955:                DESTROY_IF(this->public_key);
                   1956:                chunk_free(&this->authKeyIdentifier);
                   1957:                chunk_free(&this->encoding);
                   1958:                chunk_free(&this->encoding_hash);
                   1959:                chunk_free(&this->critical_extension_oid);
                   1960:                if (!this->parsed)
                   1961:                {       /* only parsed certificates point these fields to "encoded" */
                   1962:                        chunk_free(&this->signature);
                   1963:                        chunk_free(&this->serialNumber);
                   1964:                        chunk_free(&this->tbsCertificate);
                   1965:                }
                   1966:                free(this);
                   1967:        }
                   1968: }
                   1969: 
                   1970: /**
                   1971:  * create an empty but initialized X.509 certificate
                   1972:  */
                   1973: static private_x509_cert_t* create_empty(void)
                   1974: {
                   1975:        private_x509_cert_t *this;
                   1976: 
                   1977:        INIT(this,
                   1978:                .public = {
                   1979:                        .interface = {
                   1980:                                .interface = {
                   1981:                                        .get_type = _get_type,
                   1982:                                        .get_subject = _get_subject,
                   1983:                                        .get_issuer = _get_issuer,
                   1984:                                        .has_subject = _has_subject,
                   1985:                                        .has_issuer = _has_issuer,
                   1986:                                        .issued_by = _issued_by,
                   1987:                                        .get_public_key = _get_public_key,
                   1988:                                        .get_validity = _get_validity,
                   1989:                                        .get_encoding = _get_encoding,
                   1990:                                        .equals = _equals,
                   1991:                                        .get_ref = _get_ref,
                   1992:                                        .destroy = _destroy,
                   1993:                                },
                   1994:                                .get_flags = _get_flags,
                   1995:                                .get_serial = _get_serial,
                   1996:                                .get_subjectKeyIdentifier = _get_subjectKeyIdentifier,
                   1997:                                .get_authKeyIdentifier = _get_authKeyIdentifier,
                   1998:                                .get_constraint = _get_constraint,
                   1999:                                .create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
                   2000:                                .create_crl_uri_enumerator = _create_crl_uri_enumerator,
                   2001:                                .create_ocsp_uri_enumerator = _create_ocsp_uri_enumerator,
                   2002:                                .create_ipAddrBlock_enumerator = _create_ipAddrBlock_enumerator,
                   2003:                                .create_name_constraint_enumerator = _create_name_constraint_enumerator,
                   2004:                                .create_cert_policy_enumerator = _create_cert_policy_enumerator,
                   2005:                                .create_policy_mapping_enumerator = _create_policy_mapping_enumerator,
                   2006:                        },
                   2007:                },
                   2008:                .version = 1,
                   2009:                .subjectAltNames = linked_list_create(),
                   2010:                .crl_uris = linked_list_create(),
                   2011:                .ocsp_uris = linked_list_create(),
                   2012:                .ipAddrBlocks = linked_list_create(),
                   2013:                .permitted_names = linked_list_create(),
                   2014:                .excluded_names = linked_list_create(),
                   2015:                .cert_policies = linked_list_create(),
                   2016:                .policy_mappings = linked_list_create(),
                   2017:                .pathLenConstraint = X509_NO_CONSTRAINT,
                   2018:                .require_explicit = X509_NO_CONSTRAINT,
                   2019:                .inhibit_mapping = X509_NO_CONSTRAINT,
                   2020:                .inhibit_any = X509_NO_CONSTRAINT,
                   2021:                .ref = 1,
                   2022:        );
                   2023:        return this;
                   2024: }
                   2025: 
                   2026: /**
                   2027:  * Build a generalName from an id
                   2028:  */
                   2029: chunk_t build_generalName(identification_t *id)
                   2030: {
                   2031:        int context;
                   2032: 
                   2033:        switch (id->get_type(id))
                   2034:        {
                   2035:                case ID_DER_ASN1_GN:
                   2036:                        return chunk_clone(id->get_encoding(id));
                   2037:                case ID_RFC822_ADDR:
                   2038:                        context = ASN1_CONTEXT_S_1;
                   2039:                        break;
                   2040:                case ID_FQDN:
                   2041:                        context = ASN1_CONTEXT_S_2;
                   2042:                        break;
                   2043:                case ID_DER_ASN1_DN:
                   2044:                        context = ASN1_CONTEXT_C_4;
                   2045:                        break;
                   2046:                case ID_IPV4_ADDR:
                   2047:                case ID_IPV6_ADDR:
                   2048:                        context = ASN1_CONTEXT_S_7;
                   2049:                        break;
                   2050:                default:
                   2051:                        DBG1(DBG_ASN, "encoding %N as generalName not supported",
                   2052:                                 id_type_names, id->get_type(id));
                   2053:                        return chunk_empty;
                   2054:        }
                   2055:        return asn1_wrap(context, "c", id->get_encoding(id));
                   2056: }
                   2057: 
                   2058: /**
                   2059:  * Encode a linked list of subjectAltNames
                   2060:  */
                   2061: chunk_t x509_build_subjectAltNames(linked_list_t *list)
                   2062: {
                   2063:        chunk_t subjectAltNames = chunk_empty, name;
                   2064:        enumerator_t *enumerator;
                   2065:        identification_t *id;
                   2066: 
                   2067:        if (list->get_count(list) == 0)
                   2068:        {
                   2069:                return chunk_empty;
                   2070:        }
                   2071: 
                   2072:        enumerator = list->create_enumerator(list);
                   2073:        while (enumerator->enumerate(enumerator, &id))
                   2074:        {
                   2075:                name = build_generalName(id);
                   2076:                subjectAltNames = chunk_cat("mm", subjectAltNames, name);
                   2077:        }
                   2078:        enumerator->destroy(enumerator);
                   2079: 
                   2080:        return asn1_wrap(ASN1_SEQUENCE, "mm",
                   2081:                                                asn1_build_known_oid(OID_SUBJECT_ALT_NAME),
                   2082:                                                asn1_wrap(ASN1_OCTET_STRING, "m",
                   2083:                                                        asn1_wrap(ASN1_SEQUENCE, "m", subjectAltNames)
                   2084:                                                )
                   2085:                                         );
                   2086: }
                   2087: 
                   2088: /**
                   2089:  * Encode CRL distribution points extension from a x509_cdp_t list
                   2090:  */
                   2091: chunk_t x509_build_crlDistributionPoints(linked_list_t *list, int extn)
                   2092: {
                   2093:        chunk_t crlDistributionPoints = chunk_empty;
                   2094:        enumerator_t *enumerator;
                   2095:        x509_cdp_t *cdp;
                   2096: 
                   2097:        if (list->get_count(list) == 0)
                   2098:        {
                   2099:                return chunk_empty;
                   2100:        }
                   2101: 
                   2102:        enumerator = list->create_enumerator(list);
                   2103:        while (enumerator->enumerate(enumerator, &cdp))
                   2104:        {
                   2105:                chunk_t distributionPoint, crlIssuer = chunk_empty;
                   2106: 
                   2107:                if (cdp->issuer)
                   2108:                {
                   2109:                        crlIssuer = asn1_wrap(ASN1_CONTEXT_C_2, "m",
                   2110:                                                        build_generalName(cdp->issuer));
                   2111:                }
                   2112:                distributionPoint = asn1_wrap(ASN1_SEQUENCE, "mm",
                   2113:                                        asn1_wrap(ASN1_CONTEXT_C_0, "m",
                   2114:                                                asn1_wrap(ASN1_CONTEXT_C_0, "m",
                   2115:                                                        asn1_wrap(ASN1_CONTEXT_S_6, "c",
                   2116:                                                                chunk_create(cdp->uri, strlen(cdp->uri))))),
                   2117:                                        crlIssuer);
                   2118:                crlDistributionPoints = chunk_cat("mm", crlDistributionPoints,
                   2119:                                                                                  distributionPoint);
                   2120:        }
                   2121:        enumerator->destroy(enumerator);
                   2122: 
                   2123:        return asn1_wrap(ASN1_SEQUENCE, "mm",
                   2124:                                asn1_build_known_oid(extn),
                   2125:                                asn1_wrap(ASN1_OCTET_STRING, "m",
                   2126:                                        asn1_wrap(ASN1_SEQUENCE, "m", crlDistributionPoints)));
                   2127: }
                   2128: 
                   2129: static chunk_t generate_ts(traffic_selector_t *ts)
                   2130: {
                   2131:        chunk_t from, to;
                   2132:        uint8_t minbits = 0, maxbits = 0, unused;
                   2133:        host_t *net;
                   2134:        int bit, byte;
                   2135: 
                   2136:        if (ts->to_subnet(ts, &net, &minbits))
                   2137:        {
                   2138:                unused = round_up(minbits, BITS_PER_BYTE) - minbits;
                   2139:                from = asn1_wrap(ASN1_BIT_STRING, "m",
                   2140:                        chunk_cat("cc", chunk_from_thing(unused),
                   2141:                                                        chunk_create(net->get_address(net).ptr,
                   2142:                                                                                 (minbits + unused) / BITS_PER_BYTE)));
                   2143:                net->destroy(net);
                   2144:                return from;
                   2145:        }
                   2146:        net->destroy(net);
                   2147: 
                   2148:        from = ts->get_from_address(ts);
                   2149:        for (byte = from.len - 1; byte >= 0; byte--)
                   2150:        {
                   2151:                if (from.ptr[byte] != 0)
                   2152:                {
                   2153:                        minbits = byte * BITS_PER_BYTE + BITS_PER_BYTE;
                   2154:                        for (bit = 0; bit < BITS_PER_BYTE; bit++)
                   2155:                        {
                   2156:                                if (from.ptr[byte] & 1 << bit)
                   2157:                                {
                   2158:                                        break;
                   2159:                                }
                   2160:                                minbits--;
                   2161:                        }
                   2162:                        break;
                   2163:                }
                   2164:        }
                   2165:        to = ts->get_to_address(ts);
                   2166:        for (byte = to.len - 1; byte >= 0; byte--)
                   2167:        {
                   2168:                if (to.ptr[byte] != 0xFF)
                   2169:                {
                   2170:                        maxbits = byte * BITS_PER_BYTE + BITS_PER_BYTE;
                   2171:                        for (bit = 0; bit < BITS_PER_BYTE; bit++)
                   2172:                        {
                   2173:                                if ((to.ptr[byte] & 1 << bit) == 0)
                   2174:                                {
                   2175:                                        break;
                   2176:                                }
                   2177:                                maxbits--;
                   2178:                        }
                   2179:                        break;
                   2180:                }
                   2181:        }
                   2182:        unused = round_up(minbits, BITS_PER_BYTE) - minbits;
                   2183:        from = asn1_wrap(ASN1_BIT_STRING, "m",
                   2184:                        chunk_cat("cc", chunk_from_thing(unused),
                   2185:                                                        chunk_create(from.ptr,
                   2186:                                                                                 (minbits + unused) / BITS_PER_BYTE)));
                   2187:        unused = round_up(maxbits, BITS_PER_BYTE) - maxbits;
                   2188:        to = asn1_wrap(ASN1_BIT_STRING, "m",
                   2189:                        chunk_cat("cc", chunk_from_thing(unused),
                   2190:                                                        chunk_create(to.ptr,
                   2191:                                                                                 (maxbits + unused) / BITS_PER_BYTE)));
                   2192:        return asn1_wrap(ASN1_SEQUENCE, "mm", from, to);
                   2193: }
                   2194: 
                   2195: /**
                   2196:  * Generate and sign a new certificate
                   2197:  */
                   2198: static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
                   2199:                                         private_key_t *sign_key, int digest_alg)
                   2200: {
                   2201:        const chunk_t keyUsageCrlSign = chunk_from_chars(0x01, 0x02);
                   2202:        const chunk_t keyUsageCertSignCrlSign = chunk_from_chars(0x01, 0x06);
                   2203:        chunk_t extensions = chunk_empty, extendedKeyUsage = chunk_empty;
                   2204:        chunk_t serverAuth = chunk_empty, clientAuth = chunk_empty;
                   2205:        chunk_t ocspSigning = chunk_empty, certPolicies = chunk_empty;
                   2206:        chunk_t basicConstraints = chunk_empty, nameConstraints = chunk_empty;
                   2207:        chunk_t keyUsage = chunk_empty, keyUsageBits = chunk_empty;
                   2208:        chunk_t subjectAltNames = chunk_empty, policyMappings = chunk_empty;
                   2209:        chunk_t subjectKeyIdentifier = chunk_empty, authKeyIdentifier = chunk_empty;
                   2210:        chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty;
                   2211:        chunk_t policyConstraints = chunk_empty, inhibitAnyPolicy = chunk_empty;
                   2212:        chunk_t ikeIntermediate = chunk_empty, msSmartcardLogon = chunk_empty;
                   2213:        chunk_t ipAddrBlocks = chunk_empty, sig_scheme = chunk_empty;
                   2214:        chunk_t criticalExtension = chunk_empty;
                   2215:        identification_t *issuer, *subject;
                   2216:        chunk_t key_info;
                   2217:        hasher_t *hasher;
                   2218:        enumerator_t *enumerator;
                   2219:        char *uri;
                   2220: 
                   2221:        subject = cert->subject;
                   2222:        if (sign_cert)
                   2223:        {
                   2224:                issuer = sign_cert->get_subject(sign_cert);
                   2225:                if (!cert->public_key)
                   2226:                {
                   2227:                        return FALSE;
                   2228:                }
                   2229:        }
                   2230:        else
                   2231:        {       /* self signed */
                   2232:                issuer = subject;
                   2233:                if (!cert->public_key)
                   2234:                {
                   2235:                        cert->public_key = sign_key->get_public_key(sign_key);
                   2236:                }
                   2237:                cert->flags |= X509_SELF_SIGNED;
                   2238:        }
                   2239:        cert->issuer = issuer->clone(issuer);
                   2240:        if (!cert->notBefore)
                   2241:        {
                   2242:                cert->notBefore = time(NULL);
                   2243:        }
                   2244:        if (!cert->notAfter)
                   2245:        {       /* defaults to 1 year from now */
                   2246:                cert->notAfter = cert->notBefore + 60 * 60 * 24 * 365;
                   2247:        }
                   2248: 
                   2249:        /* select signature scheme, if not already specified */
                   2250:        if (!cert->scheme)
                   2251:        {
                   2252:                INIT(cert->scheme,
                   2253:                        .scheme = signature_scheme_from_oid(
                   2254:                                                                hasher_signature_algorithm_to_oid(digest_alg,
                   2255:                                                                                                sign_key->get_type(sign_key))),
                   2256:                );
                   2257:        }
                   2258:        if (cert->scheme->scheme == SIGN_UNKNOWN)
                   2259:        {
                   2260:                return FALSE;
                   2261:        }
                   2262:        if (!signature_params_build(cert->scheme, &sig_scheme))
                   2263:        {
                   2264:                return FALSE;
                   2265:        }
                   2266: 
                   2267:        if (!cert->public_key->get_encoding(cert->public_key,
                   2268:                                                                                PUBKEY_SPKI_ASN1_DER, &key_info))
                   2269:        {
                   2270:                chunk_free(&sig_scheme);
                   2271:                return FALSE;
                   2272:        }
                   2273: 
                   2274:        /* encode subjectAltNames */
                   2275:        subjectAltNames = x509_build_subjectAltNames(cert->subjectAltNames);
                   2276: 
                   2277:        crlDistributionPoints = x509_build_crlDistributionPoints(cert->crl_uris,
                   2278:                                                                                                OID_CRL_DISTRIBUTION_POINTS);
                   2279: 
                   2280:        /* encode OCSP URIs in authorityInfoAccess extension */
                   2281:        enumerator = cert->ocsp_uris->create_enumerator(cert->ocsp_uris);
                   2282:        while (enumerator->enumerate(enumerator, &uri))
                   2283:        {
                   2284:                chunk_t accessDescription;
                   2285: 
                   2286:                accessDescription = asn1_wrap(ASN1_SEQUENCE, "mm",
                   2287:                                                                asn1_build_known_oid(OID_OCSP),
                   2288:                                                                asn1_wrap(ASN1_CONTEXT_S_6, "c",
                   2289:                                                                                  chunk_create(uri, strlen(uri))));
                   2290:                authorityInfoAccess = chunk_cat("mm", authorityInfoAccess,
                   2291:                                                                                accessDescription);
                   2292:        }
                   2293:        enumerator->destroy(enumerator);
                   2294:        if (authorityInfoAccess.ptr)
                   2295:        {
                   2296:                authorityInfoAccess = asn1_wrap(ASN1_SEQUENCE, "mm",
                   2297:                                        asn1_build_known_oid(OID_AUTHORITY_INFO_ACCESS),
                   2298:                                        asn1_wrap(ASN1_OCTET_STRING, "m",
                   2299:                                                asn1_wrap(ASN1_SEQUENCE, "m", authorityInfoAccess)));
                   2300:        }
                   2301: 
                   2302:        /* build CA basicConstraint and keyUsage flags for CA certificates */
                   2303:        if (cert->flags & X509_CA)
                   2304:        {
                   2305:                chunk_t pathLenConstraint = chunk_empty;
                   2306: 
                   2307:                if (cert->pathLenConstraint != X509_NO_CONSTRAINT)
                   2308:                {
                   2309:                        pathLenConstraint = asn1_integer("c",
                   2310:                                                                        chunk_from_thing(cert->pathLenConstraint));
                   2311:                }
                   2312:                basicConstraints = asn1_wrap(ASN1_SEQUENCE, "mmm",
                   2313:                                                                asn1_build_known_oid(OID_BASIC_CONSTRAINTS),
                   2314:                                                                asn1_wrap(ASN1_BOOLEAN, "c",
                   2315:                                                                        chunk_from_chars(0xFF)),
                   2316:                                                                asn1_wrap(ASN1_OCTET_STRING, "m",
                   2317:                                                                                asn1_wrap(ASN1_SEQUENCE, "mm",
                   2318:                                                                                        asn1_wrap(ASN1_BOOLEAN, "c",
                   2319:                                                                                                chunk_from_chars(0xFF)),
                   2320:                                                                                        pathLenConstraint)));
                   2321:                /* set CertificateSign and implicitly CRLsign */
                   2322:                keyUsageBits = keyUsageCertSignCrlSign;
                   2323:        }
                   2324:        else if (cert->flags & X509_CRL_SIGN)
                   2325:        {
                   2326:                keyUsageBits = keyUsageCrlSign;
                   2327:        }
                   2328:        if (keyUsageBits.len)
                   2329:        {
                   2330:                keyUsage = asn1_wrap(ASN1_SEQUENCE, "mmm",
                   2331:                                                asn1_build_known_oid(OID_KEY_USAGE),
                   2332:                                                asn1_wrap(ASN1_BOOLEAN, "c", chunk_from_chars(0xFF)),
                   2333:                                                asn1_wrap(ASN1_OCTET_STRING, "m",
                   2334:                                                        asn1_wrap(ASN1_BIT_STRING, "c", keyUsageBits)));
                   2335:        }
                   2336: 
                   2337:        /* add extendedKeyUsage flags */
                   2338:        if (cert->flags & X509_SERVER_AUTH)
                   2339:        {
                   2340:                serverAuth = asn1_build_known_oid(OID_SERVER_AUTH);
                   2341:        }
                   2342:        if (cert->flags & X509_CLIENT_AUTH)
                   2343:        {
                   2344:                clientAuth = asn1_build_known_oid(OID_CLIENT_AUTH);
                   2345:        }
                   2346:        if (cert->flags & X509_IKE_INTERMEDIATE)
                   2347:        {
                   2348:                ikeIntermediate = asn1_build_known_oid(OID_IKE_INTERMEDIATE);
                   2349:        }
                   2350:        if (cert->flags & X509_OCSP_SIGNER)
                   2351:        {
                   2352:                ocspSigning = asn1_build_known_oid(OID_OCSP_SIGNING);
                   2353:        }
                   2354:        if (cert->flags & X509_MS_SMARTCARD_LOGON)
                   2355:        {
                   2356:                msSmartcardLogon = asn1_build_known_oid(OID_MS_SMARTCARD_LOGON);
                   2357:        }
                   2358: 
                   2359:        if (serverAuth.ptr  || clientAuth.ptr || ikeIntermediate.ptr ||
                   2360:                ocspSigning.ptr || msSmartcardLogon.ptr)
                   2361:        {
                   2362:                extendedKeyUsage = asn1_wrap(ASN1_SEQUENCE, "mm",
                   2363:                                                                asn1_build_known_oid(OID_EXTENDED_KEY_USAGE),
                   2364:                                                                asn1_wrap(ASN1_OCTET_STRING, "m",
                   2365:                                                                        asn1_wrap(ASN1_SEQUENCE, "mmmmm",
                   2366:                                                                                serverAuth, clientAuth, ikeIntermediate,
                   2367:                                                                                ocspSigning, msSmartcardLogon)));
                   2368:        }
                   2369: 
                   2370:        /* add subjectKeyIdentifier to CA and OCSP signer certificates */
                   2371:        if (cert->flags & (X509_CA | X509_OCSP_SIGNER | X509_CRL_SIGN))
                   2372:        {
                   2373:                chunk_t keyid;
                   2374: 
                   2375:                if (cert->public_key->get_fingerprint(cert->public_key,
                   2376:                                                                                          KEYID_PUBKEY_SHA1, &keyid))
                   2377:                {
                   2378:                        subjectKeyIdentifier = asn1_wrap(ASN1_SEQUENCE, "mm",
                   2379:                                                                        asn1_build_known_oid(OID_SUBJECT_KEY_ID),
                   2380:                                                                        asn1_wrap(ASN1_OCTET_STRING, "m",
                   2381:                                                                                asn1_wrap(ASN1_OCTET_STRING, "c", keyid)));
                   2382:                }
                   2383:        }
                   2384: 
                   2385:        /* add the keyid authKeyIdentifier for non self-signed certificates */
                   2386:        if (sign_cert)
                   2387:        {
                   2388:                chunk_t keyid;
                   2389: 
                   2390:                if (sign_key->get_fingerprint(sign_key, KEYID_PUBKEY_SHA1, &keyid))
                   2391:                {
                   2392:                        authKeyIdentifier = asn1_wrap(ASN1_SEQUENCE, "mm",
                   2393:                                                        asn1_build_known_oid(OID_AUTHORITY_KEY_ID),
                   2394:                                                        asn1_wrap(ASN1_OCTET_STRING, "m",
                   2395:                                                                asn1_wrap(ASN1_SEQUENCE, "m",
                   2396:                                                                        asn1_wrap(ASN1_CONTEXT_S_0, "c", keyid))));
                   2397:                }
                   2398:        }
                   2399: 
                   2400:        if (cert->ipAddrBlocks->get_count(cert->ipAddrBlocks))
                   2401:        {
                   2402:                chunk_t v4blocks = chunk_empty, v6blocks = chunk_empty, block;
                   2403:                traffic_selector_t *ts;
                   2404: 
                   2405:                enumerator = cert->ipAddrBlocks->create_enumerator(cert->ipAddrBlocks);
                   2406:                while (enumerator->enumerate(enumerator, &ts))
                   2407:                {
                   2408:                        switch (ts->get_type(ts))
                   2409:                        {
                   2410:                                case TS_IPV4_ADDR_RANGE:
                   2411:                                        block = generate_ts(ts);
                   2412:                                        v4blocks = chunk_cat("mm", v4blocks, block);
                   2413:                                        break;
                   2414:                                case TS_IPV6_ADDR_RANGE:
                   2415:                                        block = generate_ts(ts);
                   2416:                                        v6blocks = chunk_cat("mm", v6blocks, block);
                   2417:                                        break;
                   2418:                                default:
                   2419:                                        break;
                   2420:                        }
                   2421:                }
                   2422:                enumerator->destroy(enumerator);
                   2423: 
                   2424:                if (v4blocks.ptr)
                   2425:                {
                   2426:                        v4blocks = asn1_wrap(ASN1_SEQUENCE, "mm",
                   2427:                                                asn1_wrap(ASN1_OCTET_STRING, "c",
                   2428:                                                        chunk_from_chars(0x00,0x01)),
                   2429:                                                asn1_wrap(ASN1_SEQUENCE, "m", v4blocks));
                   2430:                }
                   2431:                if (v6blocks.ptr)
                   2432:                {
                   2433:                        v6blocks = asn1_wrap(ASN1_SEQUENCE, "mm",
                   2434:                                                asn1_wrap(ASN1_OCTET_STRING, "c",
                   2435:                                                        chunk_from_chars(0x00,0x02)),
                   2436:                                                asn1_wrap(ASN1_SEQUENCE, "m", v6blocks));
                   2437:                }
                   2438:                ipAddrBlocks = asn1_wrap(ASN1_SEQUENCE, "mm",
                   2439:                                                asn1_build_known_oid(OID_IP_ADDR_BLOCKS),
                   2440:                                                asn1_wrap(ASN1_OCTET_STRING, "m",
                   2441:                                                        asn1_wrap(ASN1_SEQUENCE, "mm",
                   2442:                                                                v4blocks, v6blocks)));
                   2443:                cert->flags |= X509_IP_ADDR_BLOCKS;
                   2444:        }
                   2445: 
                   2446:        if (cert->permitted_names->get_count(cert->permitted_names) ||
                   2447:                cert->excluded_names->get_count(cert->excluded_names))
                   2448:        {
                   2449:                chunk_t permitted = chunk_empty, excluded = chunk_empty, subtree;
                   2450:                identification_t *id;
                   2451: 
                   2452:                enumerator = create_name_constraint_enumerator(cert, TRUE);
                   2453:                while (enumerator->enumerate(enumerator, &id))
                   2454:                {
                   2455:                        subtree = asn1_wrap(ASN1_SEQUENCE, "m", build_generalName(id));
                   2456:                        permitted = chunk_cat("mm", permitted, subtree);
                   2457:                }
                   2458:                enumerator->destroy(enumerator);
                   2459:                if (permitted.ptr)
                   2460:                {
                   2461:                        permitted = asn1_wrap(ASN1_CONTEXT_C_0, "m", permitted);
                   2462:                }
                   2463: 
                   2464:                enumerator = create_name_constraint_enumerator(cert, FALSE);
                   2465:                while (enumerator->enumerate(enumerator, &id))
                   2466:                {
                   2467:                        subtree = asn1_wrap(ASN1_SEQUENCE, "m", build_generalName(id));
                   2468:                        excluded = chunk_cat("mm", excluded, subtree);
                   2469:                }
                   2470:                enumerator->destroy(enumerator);
                   2471:                if (excluded.ptr)
                   2472:                {
                   2473:                        excluded = asn1_wrap(ASN1_CONTEXT_C_1, "m", excluded);
                   2474:                }
                   2475: 
                   2476:                nameConstraints = asn1_wrap(ASN1_SEQUENCE, "mm",
                   2477:                                                        asn1_build_known_oid(OID_NAME_CONSTRAINTS),
                   2478:                                                        asn1_wrap(ASN1_OCTET_STRING, "m",
                   2479:                                                                asn1_wrap(ASN1_SEQUENCE, "mm",
                   2480:                                                                        permitted, excluded)));
                   2481:        }
                   2482: 
                   2483:        if (cert->cert_policies->get_count(cert->cert_policies))
                   2484:        {
                   2485:                x509_cert_policy_t *policy;
                   2486: 
                   2487:                enumerator = create_cert_policy_enumerator(cert);
                   2488:                while (enumerator->enumerate(enumerator, &policy))
                   2489:                {
                   2490:                        chunk_t chunk = chunk_empty, cps = chunk_empty, notice = chunk_empty;
                   2491: 
                   2492:                        if (policy->cps_uri)
                   2493:                        {
                   2494:                                cps = asn1_wrap(ASN1_SEQUENCE, "mm",
                   2495:                                                asn1_build_known_oid(OID_POLICY_QUALIFIER_CPS),
                   2496:                                                asn1_wrap(ASN1_IA5STRING, "c",
                   2497:                                                        chunk_create(policy->cps_uri,
                   2498:                                                                                 strlen(policy->cps_uri))));
                   2499:                        }
                   2500:                        if (policy->unotice_text)
                   2501:                        {
                   2502:                                notice = asn1_wrap(ASN1_SEQUENCE, "mm",
                   2503:                                                        asn1_build_known_oid(OID_POLICY_QUALIFIER_UNOTICE),
                   2504:                                                        asn1_wrap(ASN1_SEQUENCE, "m",
                   2505:                                                                asn1_wrap(ASN1_VISIBLESTRING, "c",
                   2506:                                                                        chunk_create(policy->unotice_text,
                   2507:                                                                                strlen(policy->unotice_text)))));
                   2508:                        }
                   2509:                        if (cps.len || notice.len)
                   2510:                        {
                   2511:                                chunk = asn1_wrap(ASN1_SEQUENCE, "mm", cps, notice);
                   2512:                        }
                   2513:                        chunk = asn1_wrap(ASN1_SEQUENCE, "mm",
                   2514:                                                asn1_wrap(ASN1_OID, "c", policy->oid), chunk);
                   2515:                        certPolicies = chunk_cat("mm", certPolicies, chunk);
                   2516:                }
                   2517:                enumerator->destroy(enumerator);
                   2518: 
                   2519:                certPolicies = asn1_wrap(ASN1_SEQUENCE, "mm",
                   2520:                                                        asn1_build_known_oid(OID_CERTIFICATE_POLICIES),
                   2521:                                                        asn1_wrap(ASN1_OCTET_STRING, "m",
                   2522:                                                                asn1_wrap(ASN1_SEQUENCE, "m", certPolicies)));
                   2523:        }
                   2524: 
                   2525:        if (cert->policy_mappings->get_count(cert->policy_mappings))
                   2526:        {
                   2527:                x509_policy_mapping_t *mapping;
                   2528: 
                   2529:                enumerator = create_policy_mapping_enumerator(cert);
                   2530:                while (enumerator->enumerate(enumerator, &mapping))
                   2531:                {
                   2532:                        chunk_t chunk;
                   2533: 
                   2534:                        chunk = asn1_wrap(ASN1_SEQUENCE, "mm",
                   2535:                                                asn1_wrap(ASN1_OID, "c", mapping->issuer),
                   2536:                                                asn1_wrap(ASN1_OID, "c", mapping->subject));
                   2537:                        policyMappings = chunk_cat("mm", policyMappings, chunk);
                   2538:                }
                   2539:                enumerator->destroy(enumerator);
                   2540: 
                   2541:                policyMappings = asn1_wrap(ASN1_SEQUENCE, "mm",
                   2542:                                                        asn1_build_known_oid(OID_POLICY_MAPPINGS),
                   2543:                                                        asn1_wrap(ASN1_OCTET_STRING, "m",
                   2544:                                                                asn1_wrap(ASN1_SEQUENCE, "m", policyMappings)));
                   2545:        }
                   2546: 
                   2547:        if (cert->inhibit_mapping != X509_NO_CONSTRAINT ||
                   2548:                cert->require_explicit != X509_NO_CONSTRAINT)
                   2549:        {
                   2550:                chunk_t inhibit = chunk_empty, explicit = chunk_empty;
                   2551: 
                   2552:                if (cert->require_explicit != X509_NO_CONSTRAINT)
                   2553:                {
                   2554:                        explicit = asn1_wrap(ASN1_CONTEXT_C_0, "m",
                   2555:                                                asn1_integer("c",
                   2556:                                                        chunk_from_thing(cert->require_explicit)));
                   2557:                }
                   2558:                if (cert->inhibit_mapping != X509_NO_CONSTRAINT)
                   2559:                {
                   2560:                        inhibit = asn1_wrap(ASN1_CONTEXT_C_1, "m",
                   2561:                                                asn1_integer("c",
                   2562:                                                        chunk_from_thing(cert->inhibit_mapping)));
                   2563:                }
                   2564:                policyConstraints = asn1_wrap(ASN1_SEQUENCE, "mmm",
                   2565:                                                asn1_build_known_oid(OID_POLICY_CONSTRAINTS),
                   2566:                                                asn1_wrap(ASN1_BOOLEAN, "c", chunk_from_chars(0xFF)),
                   2567:                                                asn1_wrap(ASN1_OCTET_STRING, "m",
                   2568:                                                        asn1_wrap(ASN1_SEQUENCE, "mm",
                   2569:                                                                explicit, inhibit)));
                   2570:        }
                   2571: 
                   2572:        if (cert->inhibit_any != X509_NO_CONSTRAINT)
                   2573:        {
                   2574:                inhibitAnyPolicy = asn1_wrap(ASN1_SEQUENCE, "mmm",
                   2575:                                asn1_build_known_oid(OID_INHIBIT_ANY_POLICY),
                   2576:                                asn1_wrap(ASN1_BOOLEAN, "c", chunk_from_chars(0xFF)),
                   2577:                                asn1_wrap(ASN1_OCTET_STRING, "m",
                   2578:                                        asn1_integer("c",
                   2579:                                                chunk_from_thing(cert->inhibit_any))));
                   2580:        }
                   2581: 
                   2582:        if (cert->critical_extension_oid.len > 0)
                   2583:        {
                   2584:                criticalExtension = asn1_wrap(ASN1_SEQUENCE, "mmm",
                   2585:                                        asn1_simple_object(ASN1_OID, cert->critical_extension_oid),
                   2586:                                        asn1_simple_object(ASN1_BOOLEAN, chunk_from_chars(0xFF)),
                   2587:                                        asn1_simple_object(ASN1_OCTET_STRING, chunk_empty));
                   2588:        }
                   2589: 
                   2590:        if (basicConstraints.ptr || subjectAltNames.ptr || authKeyIdentifier.ptr ||
                   2591:                crlDistributionPoints.ptr || nameConstraints.ptr || ipAddrBlocks.ptr)
                   2592:        {
                   2593:                extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m",
                   2594:                                                asn1_wrap(ASN1_SEQUENCE, "mmmmmmmmmmmmmmm",
                   2595:                                                        basicConstraints, keyUsage, subjectKeyIdentifier,
                   2596:                                                        authKeyIdentifier, subjectAltNames,
                   2597:                                                        extendedKeyUsage, crlDistributionPoints,
                   2598:                                                        authorityInfoAccess, nameConstraints, certPolicies,
                   2599:                                                        policyMappings, policyConstraints, inhibitAnyPolicy,
                   2600:                                                        ipAddrBlocks, criticalExtension));
                   2601:        }
                   2602: 
                   2603:        cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmccmcmm",
                   2604:                asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2),
                   2605:                asn1_integer("c", cert->serialNumber),
                   2606:                sig_scheme,
                   2607:                issuer->get_encoding(issuer),
                   2608:                asn1_wrap(ASN1_SEQUENCE, "mm",
                   2609:                        asn1_from_time(&cert->notBefore, ASN1_UTCTIME),
                   2610:                        asn1_from_time(&cert->notAfter, ASN1_UTCTIME)),
                   2611:                subject->get_encoding(subject),
                   2612:                key_info, extensions);
                   2613: 
                   2614:        if (!sign_key->sign(sign_key, cert->scheme->scheme, cert->scheme->params,
                   2615:                                                cert->tbsCertificate, &cert->signature))
                   2616:        {
                   2617:                chunk_free(&sig_scheme);
                   2618:                return FALSE;
                   2619:        }
                   2620:        cert->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm", cert->tbsCertificate,
                   2621:                                                           sig_scheme,
                   2622:                                                           asn1_bitstring("c", cert->signature));
                   2623: 
                   2624:        hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
                   2625:        if (!hasher ||
                   2626:                !hasher->allocate_hash(hasher, cert->encoding, &cert->encoding_hash))
                   2627:        {
                   2628:                DESTROY_IF(hasher);
                   2629:                return FALSE;
                   2630:        }
                   2631:        hasher->destroy(hasher);
                   2632:        return TRUE;
                   2633: }
                   2634: 
                   2635: /**
                   2636:  * See header.
                   2637:  */
                   2638: x509_cert_t *x509_cert_load(certificate_type_t type, va_list args)
                   2639: {
                   2640:        x509_flag_t flags = 0;
                   2641:        chunk_t blob = chunk_empty;
                   2642: 
                   2643:        while (TRUE)
                   2644:        {
                   2645:                switch (va_arg(args, builder_part_t))
                   2646:                {
                   2647:                        case BUILD_BLOB_ASN1_DER:
                   2648:                                blob = va_arg(args, chunk_t);
                   2649:                                continue;
                   2650:                        case BUILD_X509_FLAG:
                   2651:                                flags |= va_arg(args, x509_flag_t);
                   2652:                                continue;
                   2653:                        case BUILD_END:
                   2654:                                break;
                   2655:                        default:
                   2656:                                return NULL;
                   2657:                }
                   2658:                break;
                   2659:        }
                   2660: 
                   2661:        if (blob.ptr)
                   2662:        {
                   2663:                private_x509_cert_t *cert = create_empty();
                   2664: 
                   2665:                cert->encoding = chunk_clone(blob);
                   2666:                cert->parsed = TRUE;
                   2667:                if (parse_certificate(cert))
                   2668:                {
                   2669:                        cert->flags |= flags;
                   2670:                        return &cert->public;
                   2671:                }
                   2672:                destroy(cert);
                   2673:        }
                   2674:        return NULL;
                   2675: }
                   2676: 
                   2677: /**
                   2678:  * See header.
                   2679:  */
                   2680: x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
                   2681: {
                   2682:        private_x509_cert_t *cert;
                   2683:        certificate_t *sign_cert = NULL;
                   2684:        private_key_t *sign_key = NULL;
                   2685:        hash_algorithm_t digest_alg = HASH_SHA256;
                   2686:        u_int constraint;
                   2687: 
                   2688:        cert = create_empty();
                   2689:        while (TRUE)
                   2690:        {
                   2691:                switch (va_arg(args, builder_part_t))
                   2692:                {
                   2693:                        case BUILD_X509_FLAG:
                   2694:                                cert->flags |= va_arg(args, x509_flag_t);
                   2695:                                continue;
                   2696:                        case BUILD_SIGNING_KEY:
                   2697:                                sign_key = va_arg(args, private_key_t*);
                   2698:                                continue;
                   2699:                        case BUILD_SIGNING_CERT:
                   2700:                                sign_cert = va_arg(args, certificate_t*);
                   2701:                                continue;
                   2702:                        case BUILD_PUBLIC_KEY:
                   2703:                                cert->public_key = va_arg(args, public_key_t*);
                   2704:                                cert->public_key->get_ref(cert->public_key);
                   2705:                                continue;
                   2706:                        case BUILD_SUBJECT:
                   2707:                                cert->subject = va_arg(args, identification_t*);
                   2708:                                cert->subject = cert->subject->clone(cert->subject);
                   2709:                                continue;
                   2710:                        case BUILD_SUBJECT_ALTNAMES:
                   2711:                        {
                   2712:                                enumerator_t *enumerator;
                   2713:                                identification_t *id;
                   2714:                                linked_list_t *list;
                   2715: 
                   2716:                                list = va_arg(args, linked_list_t*);
                   2717:                                enumerator = list->create_enumerator(list);
                   2718:                                while (enumerator->enumerate(enumerator, &id))
                   2719:                                {
                   2720:                                        cert->subjectAltNames->insert_last(cert->subjectAltNames,
                   2721:                                                                                                        id->clone(id));
                   2722:                                }
                   2723:                                enumerator->destroy(enumerator);
                   2724:                                continue;
                   2725:                        }
                   2726:                        case BUILD_CRL_DISTRIBUTION_POINTS:
                   2727:                        {
                   2728:                                enumerator_t *enumerator;
                   2729:                                linked_list_t *list;
                   2730:                                x509_cdp_t *in, *cdp;
                   2731: 
                   2732:                                list = va_arg(args, linked_list_t*);
                   2733:                                enumerator = list->create_enumerator(list);
                   2734:                                while (enumerator->enumerate(enumerator, &in))
                   2735:                                {
                   2736:                                        INIT(cdp,
                   2737:                                                .uri = strdup(in->uri),
                   2738:                                                .issuer = in->issuer ? in->issuer->clone(in->issuer) : NULL,
                   2739:                                        );
                   2740:                                        cert->crl_uris->insert_last(cert->crl_uris, cdp);
                   2741:                                }
                   2742:                                enumerator->destroy(enumerator);
                   2743:                                continue;
                   2744:                        }
                   2745:                        case BUILD_OCSP_ACCESS_LOCATIONS:
                   2746:                        {
                   2747:                                enumerator_t *enumerator;
                   2748:                                linked_list_t *list;
                   2749:                                char *uri;
                   2750: 
                   2751:                                list = va_arg(args, linked_list_t*);
                   2752:                                enumerator = list->create_enumerator(list);
                   2753:                                while (enumerator->enumerate(enumerator, &uri))
                   2754:                                {
                   2755:                                        cert->ocsp_uris->insert_last(cert->ocsp_uris, strdup(uri));
                   2756:                                }
                   2757:                                enumerator->destroy(enumerator);
                   2758:                                continue;
                   2759:                        }
                   2760:                        case BUILD_PATHLEN:
                   2761:                                constraint = va_arg(args, u_int);
                   2762:                                cert->pathLenConstraint = (constraint < 128) ?
                   2763:                                                                                   constraint : X509_NO_CONSTRAINT;
                   2764:                                continue;
                   2765:                        case BUILD_ADDRBLOCKS:
                   2766:                        {
                   2767:                                enumerator_t *enumerator;
                   2768:                                traffic_selector_t *ts;
                   2769:                                linked_list_t *list;
                   2770: 
                   2771:                                list = va_arg(args, linked_list_t*);
                   2772:                                enumerator = list->create_enumerator(list);
                   2773:                                while (enumerator->enumerate(enumerator, &ts))
                   2774:                                {
                   2775:                                        cert->ipAddrBlocks->insert_last(cert->ipAddrBlocks,
                   2776:                                                                                                        ts->clone(ts));
                   2777:                                }
                   2778:                                enumerator->destroy(enumerator);
                   2779:                                continue;
                   2780:                        }
                   2781:                        case BUILD_PERMITTED_NAME_CONSTRAINTS:
                   2782:                        {
                   2783:                                enumerator_t *enumerator;
                   2784:                                linked_list_t *list;
                   2785:                                identification_t *constraint;
                   2786: 
                   2787:                                list = va_arg(args, linked_list_t*);
                   2788:                                enumerator = list->create_enumerator(list);
                   2789:                                while (enumerator->enumerate(enumerator, &constraint))
                   2790:                                {
                   2791:                                        cert->permitted_names->insert_last(cert->permitted_names,
                   2792:                                                                                                constraint->clone(constraint));
                   2793:                                }
                   2794:                                enumerator->destroy(enumerator);
                   2795:                                continue;
                   2796:                        }
                   2797:                        case BUILD_EXCLUDED_NAME_CONSTRAINTS:
                   2798:                        {
                   2799:                                enumerator_t *enumerator;
                   2800:                                linked_list_t *list;
                   2801:                                identification_t *constraint;
                   2802: 
                   2803:                                list = va_arg(args, linked_list_t*);
                   2804:                                enumerator = list->create_enumerator(list);
                   2805:                                while (enumerator->enumerate(enumerator, &constraint))
                   2806:                                {
                   2807:                                        cert->excluded_names->insert_last(cert->excluded_names,
                   2808:                                                                                                constraint->clone(constraint));
                   2809:                                }
                   2810:                                enumerator->destroy(enumerator);
                   2811:                                continue;
                   2812:                        }
                   2813:                        case BUILD_CERTIFICATE_POLICIES:
                   2814:                        {
                   2815:                                enumerator_t *enumerator;
                   2816:                                linked_list_t *list;
                   2817:                                x509_cert_policy_t *policy, *in;
                   2818: 
                   2819:                                list = va_arg(args, linked_list_t*);
                   2820:                                enumerator = list->create_enumerator(list);
                   2821:                                while (enumerator->enumerate(enumerator, &in))
                   2822:                                {
                   2823:                                        INIT(policy,
                   2824:                                                .oid = chunk_clone(in->oid),
                   2825:                                                .cps_uri = strdupnull(in->cps_uri),
                   2826:                                                .unotice_text = strdupnull(in->unotice_text),
                   2827:                                        );
                   2828:                                        cert->cert_policies->insert_last(cert->cert_policies, policy);
                   2829:                                }
                   2830:                                enumerator->destroy(enumerator);
                   2831:                                continue;
                   2832:                        }
                   2833:                        case BUILD_POLICY_MAPPINGS:
                   2834:                        {
                   2835:                                enumerator_t *enumerator;
                   2836:                                linked_list_t *list;
                   2837:                                x509_policy_mapping_t* mapping, *in;
                   2838: 
                   2839:                                list = va_arg(args, linked_list_t*);
                   2840:                                enumerator = list->create_enumerator(list);
                   2841:                                while (enumerator->enumerate(enumerator, &in))
                   2842:                                {
                   2843:                                        INIT(mapping,
                   2844:                                                .issuer = chunk_clone(in->issuer),
                   2845:                                                .subject = chunk_clone(in->subject),
                   2846:                                        );
                   2847:                                        cert->policy_mappings->insert_last(cert->policy_mappings,
                   2848:                                                                                                           mapping);
                   2849:                                }
                   2850:                                enumerator->destroy(enumerator);
                   2851:                                continue;
                   2852:                        }
                   2853:                        case BUILD_POLICY_REQUIRE_EXPLICIT:
                   2854:                                constraint = va_arg(args, u_int);
                   2855:                                cert->require_explicit = (constraint < 128) ?
                   2856:                                                                                  constraint : X509_NO_CONSTRAINT;
                   2857:                                continue;
                   2858:                        case BUILD_POLICY_INHIBIT_MAPPING:
                   2859:                                constraint = va_arg(args, u_int);
                   2860:                                cert->inhibit_mapping = (constraint < 128) ?
                   2861:                                                                                 constraint : X509_NO_CONSTRAINT;
                   2862:                                continue;
                   2863:                        case BUILD_POLICY_INHIBIT_ANY:
                   2864:                                constraint = va_arg(args, u_int);
                   2865:                                cert->inhibit_any = (constraint < 128) ?
                   2866:                                                                         constraint : X509_NO_CONSTRAINT;
                   2867:                                continue;
                   2868:                        case BUILD_NOT_BEFORE_TIME:
                   2869:                                cert->notBefore = va_arg(args, time_t);
                   2870:                                continue;
                   2871:                        case BUILD_NOT_AFTER_TIME:
                   2872:                                cert->notAfter = va_arg(args, time_t);
                   2873:                                continue;
                   2874:                        case BUILD_SERIAL:
                   2875:                                cert->serialNumber = chunk_clone(va_arg(args, chunk_t));
                   2876:                                continue;
                   2877:                        case BUILD_SIGNATURE_SCHEME:
                   2878:                                cert->scheme = va_arg(args, signature_params_t*);
                   2879:                                cert->scheme = signature_params_clone(cert->scheme);
                   2880:                                continue;
                   2881:                        case BUILD_DIGEST_ALG:
                   2882:                                digest_alg = va_arg(args, int);
                   2883:                                continue;
                   2884:                        case BUILD_CRITICAL_EXTENSION:
                   2885:                                cert->critical_extension_oid = chunk_clone(va_arg(args, chunk_t));
                   2886:                                continue;
                   2887:                        case BUILD_END:
                   2888:                                break;
                   2889:                        default:
                   2890:                                destroy(cert);
                   2891:                                return NULL;
                   2892:                }
                   2893:                break;
                   2894:        }
                   2895: 
                   2896:        if (sign_key && generate(cert, sign_cert, sign_key, digest_alg))
                   2897:        {
                   2898:                return &cert->public;
                   2899:        }
                   2900:        destroy(cert);
                   2901:        return NULL;
                   2902: }

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