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

1.1       misho       1: /*
                      2:  * Copyright (C) 2017 Tobias Brunner
                      3:  * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
                      4:  * Copyright (C) 2003 Martin Berner, Lukas Suter
                      5:  * Copyright (C) 2002-2017 Andreas Steffen
                      6:  * Copyright (C) 2009 Martin Willi
                      7:  * HSR Hochschule fuer Technik Rapperswil
                      8:  *
                      9:  * This program is free software; you can redistribute it and/or modify it
                     10:  * under the terms of the GNU General Public License as published by the
                     11:  * Free Software Foundation; either version 2 of the License, or (at your
                     12:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     13:  *
                     14:  * This program is distributed in the hope that it will be useful, but
                     15:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     16:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     17:  * for more details.
                     18:  */
                     19: 
                     20: #include "x509_ac.h"
                     21: 
                     22: #include <time.h>
                     23: 
                     24: #include <library.h>
                     25: #include <utils/debug.h>
                     26: #include <asn1/oid.h>
                     27: #include <asn1/asn1.h>
                     28: #include <asn1/asn1_parser.h>
                     29: #include <utils/identification.h>
                     30: #include <collections/linked_list.h>
                     31: #include <credentials/certificates/x509.h>
                     32: #include <credentials/keys/private_key.h>
                     33: 
                     34: extern chunk_t x509_parse_authorityKeyIdentifier(chunk_t blob,
                     35:                                                                        int level0, chunk_t *authKeySerialNumber);
                     36: 
                     37: typedef struct private_x509_ac_t private_x509_ac_t;
                     38: 
                     39: /**
                     40:  * private data of x509_ac_t object
                     41:  */
                     42: struct private_x509_ac_t {
                     43: 
                     44:        /**
                     45:         * public functions
                     46:         */
                     47:        x509_ac_t public;
                     48: 
                     49:        /**
                     50:         * X.509 attribute certificate encoding in ASN.1 DER format
                     51:         */
                     52:        chunk_t encoding;
                     53: 
                     54:        /**
                     55:         * X.509 attribute certificate body over which signature is computed
                     56:         */
                     57:        chunk_t certificateInfo;
                     58: 
                     59:        /**
                     60:         * Version of the X.509 attribute certificate
                     61:         */
                     62:        u_int version;
                     63: 
                     64:        /**
                     65:         * Serial number of the X.509 attribute certificate
                     66:         */
                     67:        chunk_t serialNumber;
                     68: 
                     69:        /**
                     70:         * ID representing the issuer of the holder certificate
                     71:         */
                     72:        identification_t *holderIssuer;
                     73: 
                     74:        /**
                     75:         * Serial number of the holder certificate
                     76:         */
                     77:        identification_t *holderSerial;
                     78: 
                     79:        /**
                     80:         * ID representing the holder
                     81:         */
                     82:        identification_t *entityName;
                     83: 
                     84:        /**
                     85:         * ID representing the attribute certificate issuer
                     86:         */
                     87:        identification_t *issuerName;
                     88: 
                     89:        /**
                     90:         * Start time of certificate validity
                     91:         */
                     92:        time_t notBefore;
                     93: 
                     94:        /**
                     95:         * End time of certificate validity
                     96:         */
                     97:        time_t notAfter;
                     98: 
                     99:        /**
                    100:         * List of group attributes, as group_t
                    101:         */
                    102:        linked_list_t *groups;
                    103: 
                    104:        /**
                    105:         * Authority Key Identifier
                    106:         */
                    107:        chunk_t authKeyIdentifier;
                    108: 
                    109:        /**
                    110:         * Authority Key Serial Number
                    111:         */
                    112:        chunk_t authKeySerialNumber;
                    113: 
                    114:        /**
                    115:         * No revocation information available
                    116:         */
                    117:        bool noRevAvail;
                    118: 
                    119:        /**
                    120:         * Signature scheme
                    121:         */
                    122:        signature_params_t *scheme;
                    123: 
                    124:        /**
                    125:         * Signature
                    126:         */
                    127:        chunk_t signature;
                    128: 
                    129:        /**
                    130:         * Holder certificate
                    131:         */
                    132:        certificate_t *holderCert;
                    133: 
                    134:        /**
                    135:         * Signer certificate
                    136:         */
                    137:        certificate_t *signerCert;
                    138: 
                    139:        /**
                    140:        * Signer private key;
                    141:        */
                    142:        private_key_t *signerKey;
                    143: 
                    144:        /**
                    145:         * reference count
                    146:         */
                    147:        refcount_t ref;
                    148: };
                    149: 
                    150: /**
                    151:  * Group definition, an IETF attribute
                    152:  */
                    153: typedef struct {
                    154:        /** Attribute type */
                    155:        ac_group_type_t type;
                    156:        /* attribute value */
                    157:        chunk_t value;
                    158: } group_t;
                    159: 
                    160: /**
                    161:  * Clean up a group entry
                    162:  */
                    163: static void group_destroy(group_t *group)
                    164: {
                    165:        free(group->value.ptr);
                    166:        free(group);
                    167: }
                    168: 
                    169: static chunk_t ASN1_noRevAvail_ext = chunk_from_chars(
                    170:        0x30, 0x09,
                    171:                  0x06, 0x03,
                    172:                                0x55, 0x1d, 0x38,
                    173:                  0x04, 0x02,
                    174:                                0x05, 0x00
                    175: );
                    176: 
                    177: /**
                    178:  * declaration of function implemented in x509_cert.c
                    179:  */
                    180: extern bool x509_parse_generalNames(chunk_t blob, int level0, bool implicit,
                    181:                                                                        linked_list_t *list);
                    182: /**
                    183:  * parses a directoryName
                    184:  */
                    185: static bool parse_directoryName(chunk_t blob, int level, bool implicit,
                    186:                                                                identification_t **name)
                    187: {
                    188:        identification_t *directoryName;
                    189:        enumerator_t *enumerator;
                    190:        bool first = TRUE;
                    191:        linked_list_t *list;
                    192: 
                    193:        list = linked_list_create();
                    194:        if (!x509_parse_generalNames(blob, level, implicit, list))
                    195:        {
                    196:                list->destroy(list);
                    197:                return FALSE;
                    198:        }
                    199: 
                    200:        enumerator = list->create_enumerator(list);
                    201:        while (enumerator->enumerate(enumerator, &directoryName))
                    202:        {
                    203:                if (first)
                    204:                {
                    205:                        *name = directoryName;
                    206:                        first = FALSE;
                    207:                }
                    208:                else
                    209:                {
                    210:                        DBG1(DBG_ASN, "more than one directory name - first selected");
                    211:                        directoryName->destroy(directoryName);
                    212:                        break;
                    213:                }
                    214:        }
                    215:        enumerator->destroy(enumerator);
                    216:        list->destroy(list);
                    217: 
                    218:        if (first)
                    219:        {
                    220:                DBG1(DBG_ASN, "no directoryName found");
                    221:                return FALSE;
                    222:        }
                    223:        return TRUE;
                    224: }
                    225: 
                    226: /**
                    227:  * ASN.1 definition of roleSyntax
                    228:  */
                    229: static const asn1Object_t roleSyntaxObjects[] =
                    230: {
                    231:        { 0, "roleSyntax",              ASN1_SEQUENCE,          ASN1_NONE }, /* 0 */
                    232:        { 1,   "roleAuthority", ASN1_CONTEXT_C_0,       ASN1_OPT |
                    233:                                                                                                ASN1_OBJ  }, /* 1 */
                    234:        { 1,   "end opt",               ASN1_EOC,                       ASN1_END  }, /* 2 */
                    235:        { 1,   "roleName",              ASN1_CONTEXT_C_1,       ASN1_OBJ  }, /* 3 */
                    236:        { 0, "exit",                    ASN1_EOC,                       ASN1_EXIT }
                    237: };
                    238: 
                    239: /**
                    240:  * Parses roleSyntax
                    241:  */
                    242: static void parse_roleSyntax(chunk_t blob, int level0)
                    243: {
                    244:        asn1_parser_t *parser;
                    245:        chunk_t object;
                    246:        int objectID;
                    247: 
                    248:        parser = asn1_parser_create(roleSyntaxObjects, blob);
                    249:        parser->set_top_level(parser, level0);
                    250: 
                    251:        while (parser->iterate(parser, &objectID, &object))
                    252:        {
                    253:                switch (objectID)
                    254:                {
                    255:                        default:
                    256:                                break;
                    257:                }
                    258:        }
                    259:        parser->destroy(parser);
                    260: }
                    261: 
                    262: /**
                    263:  * ASN.1 definition of ietfAttrSyntax
                    264:  */
                    265: static const asn1Object_t ietfAttrSyntaxObjects[] =
                    266: {
                    267:        { 0, "ietfAttrSyntax",          ASN1_SEQUENCE,          ASN1_NONE }, /*  0 */
                    268:        { 1,   "policyAuthority",       ASN1_CONTEXT_C_0,       ASN1_OPT |
                    269:                                                                                                        ASN1_BODY }, /*  1 */
                    270:        { 1,   "end opt",                       ASN1_EOC,                       ASN1_END  }, /*  2 */
                    271:        { 1,   "values",                        ASN1_SEQUENCE,          ASN1_LOOP }, /*  3 */
                    272:        { 2,     "octets",                      ASN1_OCTET_STRING,      ASN1_OPT |
                    273:                                                                                                        ASN1_BODY }, /*  4 */
                    274:        { 2,     "end choice",          ASN1_EOC,                       ASN1_END  }, /*  5 */
                    275:        { 2,     "oid",                         ASN1_OID,                       ASN1_OPT |
                    276:                                                                                                        ASN1_BODY }, /*  6 */
                    277:        { 2,     "end choice",          ASN1_EOC,                       ASN1_END  }, /*  7 */
                    278:        { 2,     "string",                      ASN1_UTF8STRING,        ASN1_OPT |
                    279:                                                                                                        ASN1_BODY }, /*  8 */
                    280:        { 2,     "end choice",          ASN1_EOC,                       ASN1_END  }, /*  9 */
                    281:        { 1,   "end loop",                      ASN1_EOC,                       ASN1_END  }, /* 10 */
                    282:        { 0, "exit",                            ASN1_EOC,                       ASN1_EXIT }
                    283: };
                    284: #define IETF_ATTR_OCTETS        4
                    285: #define IETF_ATTR_OID           6
                    286: #define IETF_ATTR_STRING        8
                    287: 
                    288: /**
                    289:  * Parse group memberships, IETF attributes
                    290:  */
                    291: static bool parse_groups(private_x509_ac_t *this, chunk_t encoded, int level0)
                    292: {
                    293:        ac_group_type_t type;
                    294:        group_t *group;
                    295:        asn1_parser_t *parser;
                    296:        chunk_t object;
                    297:        int objectID;
                    298:        bool success;
                    299: 
                    300:        parser = asn1_parser_create(ietfAttrSyntaxObjects, encoded);
                    301:        parser->set_top_level(parser, level0);
                    302:        while (parser->iterate(parser, &objectID, &object))
                    303:        {
                    304:                switch (objectID)
                    305:                {
                    306:                        case IETF_ATTR_OCTETS:
                    307:                                type = AC_GROUP_TYPE_OCTETS;
                    308:                                break;
                    309:                        case IETF_ATTR_OID:
                    310:                                type = AC_GROUP_TYPE_OID;
                    311:                                break;
                    312:                        case IETF_ATTR_STRING:
                    313:                                type = AC_GROUP_TYPE_STRING;
                    314:                                break;
                    315:                        default:
                    316:                                continue;
                    317:                }
                    318:                INIT(group,
                    319:                        .type = type,
                    320:                        .value = chunk_clone(object),
                    321:                );
                    322:                this->groups->insert_last(this->groups, group);
                    323:        }
                    324:        success = parser->success(parser);
                    325:        parser->destroy(parser);
                    326: 
                    327:        return success;
                    328: }
                    329: 
                    330: /**
                    331:  * ASN.1 definition of an X509 attribute certificate
                    332:  */
                    333: static const asn1Object_t acObjects[] =
                    334: {
                    335:        { 0, "AttributeCertificate",                    ASN1_SEQUENCE,            ASN1_OBJ  }, /*  0 */
                    336:        { 1,   "AttributeCertificateInfo",              ASN1_SEQUENCE,            ASN1_OBJ  }, /*  1 */
                    337:        { 2,       "version",                                   ASN1_INTEGER,             ASN1_DEF |
                    338:                                                                                                                                  ASN1_BODY }, /*  2 */
                    339:        { 2,       "holder",                                    ASN1_SEQUENCE,            ASN1_NONE }, /*  3 */
                    340:        { 3,         "baseCertificateID",               ASN1_CONTEXT_C_0,         ASN1_OPT  }, /*  4 */
                    341:        { 4,           "issuer",                                ASN1_SEQUENCE,            ASN1_OBJ  }, /*  5 */
                    342:        { 4,           "serial",                                ASN1_INTEGER,             ASN1_BODY }, /*  6 */
                    343:        { 4,         "issuerUID",                               ASN1_BIT_STRING,          ASN1_OPT |
                    344:                                                                                                                                  ASN1_BODY }, /*  7 */
                    345:        { 4,         "end opt",                                 ASN1_EOC,                         ASN1_END  }, /*  8 */
                    346:        { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /*  9 */
                    347:        { 3,       "entityName",                                ASN1_CONTEXT_C_1,         ASN1_OPT |
                    348:                                                                                                                                  ASN1_OBJ  }, /* 10 */
                    349:        { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /* 11 */
                    350:        { 3,         "objectDigestInfo",                ASN1_CONTEXT_C_2,         ASN1_OPT  }, /* 12 */
                    351:        { 4,           "digestedObjectType",    ASN1_ENUMERATED,          ASN1_BODY }, /* 13 */
                    352:        { 4,           "otherObjectTypeID",             ASN1_OID,                         ASN1_OPT |
                    353:                                                                                                                                  ASN1_BODY }, /* 14 */
                    354:        { 4,         "end opt",                                 ASN1_EOC,                         ASN1_END  }, /* 15 */
                    355:        { 4,         "digestAlgorithm",                 ASN1_EOC,                         ASN1_RAW  }, /* 16 */
                    356:        { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /* 17 */
                    357:        { 2,       "v2Form",                                    ASN1_CONTEXT_C_0,         ASN1_NONE }, /* 18 */
                    358:        { 3,         "issuerName",                              ASN1_SEQUENCE,            ASN1_OPT |
                    359:                                                                                                                                  ASN1_OBJ  }, /* 19 */
                    360:        { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /* 20 */
                    361:        { 3,         "baseCertificateID",               ASN1_CONTEXT_C_0,         ASN1_OPT  }, /* 21 */
                    362:        { 4,           "issuerSerial",                  ASN1_SEQUENCE,            ASN1_NONE }, /* 22 */
                    363:        { 5,             "issuer",                              ASN1_SEQUENCE,            ASN1_OBJ  }, /* 23 */
                    364:        { 5,         "serial",                                  ASN1_INTEGER,             ASN1_BODY }, /* 24 */
                    365:        { 5,           "issuerUID",                             ASN1_BIT_STRING,          ASN1_OPT |
                    366:                                                                                                                                  ASN1_BODY }, /* 25 */
                    367:        { 5,           "end opt",                               ASN1_EOC,                         ASN1_END  }, /* 26 */
                    368:        { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /* 27 */
                    369:        { 3,       "objectDigestInfo",                  ASN1_CONTEXT_C_1,         ASN1_OPT  }, /* 28 */
                    370:        { 4,           "digestInfo",                    ASN1_SEQUENCE,            ASN1_OBJ  }, /* 29 */
                    371:        { 5,     "digestedObjectType",                  ASN1_ENUMERATED,          ASN1_BODY }, /* 30 */
                    372:        { 5,         "otherObjectTypeID",               ASN1_OID,                         ASN1_OPT |
                    373:                                                                                                                                  ASN1_BODY }, /* 31 */
                    374:        { 5,           "end opt",                               ASN1_EOC,                         ASN1_END  }, /* 32 */
                    375:        { 5,           "digestAlgorithm",               ASN1_EOC,                         ASN1_RAW  }, /* 33 */
                    376:        { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /* 34 */
                    377:        { 2,       "signature",                                 ASN1_EOC,                         ASN1_RAW  }, /* 35 */
                    378:        { 2,       "serialNumber",                              ASN1_INTEGER,             ASN1_BODY }, /* 36 */
                    379:        { 2,       "attrCertValidityPeriod",    ASN1_SEQUENCE,            ASN1_NONE }, /* 37 */
                    380:        { 3,         "notBeforeTime",                   ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 38 */
                    381:        { 3,         "notAfterTime",                    ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 39 */
                    382:        { 2,       "attributes",                                ASN1_SEQUENCE,            ASN1_LOOP }, /* 40 */
                    383:        { 3,       "attribute",                                 ASN1_SEQUENCE,            ASN1_NONE }, /* 41 */
                    384:        { 4,         "type",                                    ASN1_OID,                         ASN1_BODY }, /* 42 */
                    385:        { 4,         "values",                                  ASN1_SET,                         ASN1_LOOP }, /* 43 */
                    386:        { 5,           "value",                                 ASN1_EOC,                         ASN1_RAW  }, /* 44 */
                    387:        { 4,           "end loop",                              ASN1_EOC,                         ASN1_END  }, /* 45 */
                    388:        { 2,     "end loop",                                    ASN1_EOC,                         ASN1_END  }, /* 46 */
                    389:        { 2,     "extensions",                                  ASN1_SEQUENCE,            ASN1_LOOP }, /* 47 */
                    390:        { 3,       "extension",                                 ASN1_SEQUENCE,            ASN1_NONE }, /* 48 */
                    391:        { 4,         "extnID",                                  ASN1_OID,                         ASN1_BODY }, /* 49 */
                    392:        { 4,         "critical",                                ASN1_BOOLEAN,             ASN1_DEF |
                    393:                                                                                                                                  ASN1_BODY }, /* 50 */
                    394:        { 4,         "extnValue",                               ASN1_OCTET_STRING,        ASN1_BODY }, /* 51 */
                    395:        { 2,     "end loop",                                    ASN1_EOC,                         ASN1_END  }, /* 52 */
                    396:        { 1,   "signatureAlgorithm",                    ASN1_EOC,                         ASN1_RAW  }, /* 53 */
                    397:        { 1,   "signatureValue",                                ASN1_BIT_STRING,          ASN1_BODY }, /* 54 */
                    398:        { 0, "exit",                                                    ASN1_EOC,                         ASN1_EXIT }
                    399: };
                    400: #define AC_OBJ_CERTIFICATE_INFO                 1
                    401: #define AC_OBJ_VERSION                          2
                    402: #define AC_OBJ_HOLDER_ISSUER            5
                    403: #define AC_OBJ_HOLDER_SERIAL            6
                    404: #define AC_OBJ_ENTITY_NAME                     10
                    405: #define AC_OBJ_ISSUER_NAME                     19
                    406: #define AC_OBJ_ISSUER                          23
                    407: #define AC_OBJ_SIG_ALG                         35
                    408: #define AC_OBJ_SERIAL_NUMBER           36
                    409: #define AC_OBJ_NOT_BEFORE                      38
                    410: #define AC_OBJ_NOT_AFTER                       39
                    411: #define AC_OBJ_ATTRIBUTE_TYPE          42
                    412: #define AC_OBJ_ATTRIBUTE_VALUE         44
                    413: #define AC_OBJ_EXTN_ID                         49
                    414: #define AC_OBJ_CRITICAL                                50
                    415: #define AC_OBJ_EXTN_VALUE                      51
                    416: #define AC_OBJ_ALGORITHM                       53
                    417: #define AC_OBJ_SIGNATURE                       54
                    418: 
                    419: /**
                    420:  * Parses an X.509 attribute certificate
                    421:  */
                    422: static bool parse_certificate(private_x509_ac_t *this)
                    423: {
                    424:        asn1_parser_t *parser;
                    425:        chunk_t object;
                    426:        int objectID;
                    427:        int type     = OID_UNKNOWN;
                    428:        int extn_oid = OID_UNKNOWN;
                    429:        signature_params_t sig_alg = {};
                    430:        bool success = FALSE;
                    431:        bool critical;
                    432: 
                    433:        parser = asn1_parser_create(acObjects, this->encoding);
                    434: 
                    435:        while (parser->iterate(parser, &objectID, &object))
                    436:        {
                    437:                u_int level = parser->get_level(parser)+1;
                    438: 
                    439:                switch (objectID)
                    440:                {
                    441:                        case AC_OBJ_CERTIFICATE_INFO:
                    442:                                this->certificateInfo = object;
                    443:                                break;
                    444:                        case AC_OBJ_VERSION:
                    445:                                this->version = (object.len) ? (1 + (u_int)*object.ptr) : 1;
                    446:                                DBG2(DBG_ASN, "  v%d", this->version);
                    447:                                if (this->version != 2)
                    448:                                {
                    449:                                        DBG1(DBG_ASN, "v%d attribute certificates are not "
                    450:                                                 "supported", this->version);
                    451:                                        goto end;
                    452:                                }
                    453:                                break;
                    454:                        case AC_OBJ_HOLDER_ISSUER:
                    455:                                if (!parse_directoryName(object, level, FALSE,
                    456:                                                                                 &this->holderIssuer))
                    457:                                {
                    458:                                        goto end;
                    459:                                }
                    460:                                break;
                    461:                        case AC_OBJ_HOLDER_SERIAL:
                    462:                                this->holderSerial = identification_create_from_encoding(
                    463:                                                                                                                        ID_KEY_ID, object);
                    464:                                break;
                    465:                        case AC_OBJ_ENTITY_NAME:
                    466:                                if (!parse_directoryName(object, level, TRUE,
                    467:                                                                                 &this->entityName))
                    468:                                {
                    469:                                        goto end;
                    470:                                }
                    471:                                break;
                    472:                        case AC_OBJ_ISSUER_NAME:
                    473:                                if (!parse_directoryName(object, level, FALSE,
                    474:                                                                                 &this->issuerName))
                    475:                                {
                    476:                                        goto end;
                    477:                                }
                    478:                                break;
                    479:                        case AC_OBJ_SIG_ALG:
                    480:                                if (!signature_params_parse(object, level, &sig_alg))
                    481:                                {
                    482:                                        DBG1(DBG_ASN, "  unable to parse signature algorithm");
                    483:                                        goto end;
                    484:                                }
                    485:                                break;
                    486:                        case AC_OBJ_SERIAL_NUMBER:
                    487:                                this->serialNumber = chunk_clone(object);
                    488:                                break;
                    489:                        case AC_OBJ_NOT_BEFORE:
                    490:                                this->notBefore = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
                    491:                                break;
                    492:                        case AC_OBJ_NOT_AFTER:
                    493:                                this->notAfter = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
                    494:                                break;
                    495:                        case AC_OBJ_ATTRIBUTE_TYPE:
                    496:                                type = asn1_known_oid(object);
                    497:                                break;
                    498:                        case AC_OBJ_ATTRIBUTE_VALUE:
                    499:                        {
                    500:                                switch (type)
                    501:                                {
                    502:                                        case OID_AUTHENTICATION_INFO:
                    503:                                                DBG2(DBG_ASN, "  need to parse authenticationInfo");
                    504:                                                break;
                    505:                                        case OID_ACCESS_IDENTITY:
                    506:                                                DBG2(DBG_ASN, "  need to parse accessIdentity");
                    507:                                                break;
                    508:                                        case OID_CHARGING_IDENTITY:
                    509:                                                DBG2(DBG_ASN, "  need to parse chargingIdentity");
                    510:                                                break;
                    511:                                        case OID_GROUP:
                    512:                                                DBG2(DBG_ASN, "-- > --");
                    513:                                                if (!parse_groups(this, object, level))
                    514:                                                {
                    515:                                                        goto end;
                    516:                                                }
                    517:                                                DBG2(DBG_ASN, "-- < --");
                    518:                                                break;
                    519:                                        case OID_ROLE:
                    520:                                                parse_roleSyntax(object, level);
                    521:                                                break;
                    522:                                        default:
                    523:                                                break;
                    524:                                }
                    525:                                break;
                    526:                        }
                    527:                        case AC_OBJ_EXTN_ID:
                    528:                                extn_oid = asn1_known_oid(object);
                    529:                                break;
                    530:                        case AC_OBJ_CRITICAL:
                    531:                                critical = object.len && *object.ptr;
                    532:                                DBG2(DBG_ASN, "  %s",(critical)?"TRUE":"FALSE");
                    533:                                break;
                    534:                        case AC_OBJ_EXTN_VALUE:
                    535:                        {
                    536:                                switch (extn_oid)
                    537:                                {
                    538:                                        case OID_CRL_DISTRIBUTION_POINTS:
                    539:                                                DBG2(DBG_ASN, "  need to parse crlDistributionPoints");
                    540:                                                break;
                    541:                                        case OID_AUTHORITY_KEY_ID:
                    542:                                                this->authKeyIdentifier =
                    543:                                                                x509_parse_authorityKeyIdentifier(object,
                    544:                                                                                        level, &this->authKeySerialNumber);
                    545:                                                break;
                    546:                                        case OID_TARGET_INFORMATION:
                    547:                                                DBG2(DBG_ASN, "  need to parse targetInformation");
                    548:                                                break;
                    549:                                        case OID_NO_REV_AVAIL:
                    550:                                                this->noRevAvail = TRUE;
                    551:                                                break;
                    552:                                        default:
                    553:                                                break;
                    554:                                }
                    555:                                break;
                    556:                        }
                    557:                        case AC_OBJ_ALGORITHM:
                    558:                                INIT(this->scheme);
                    559:                                if (!signature_params_parse(object, level, this->scheme))
                    560:                                {
                    561:                                        DBG1(DBG_ASN, "  unable to parse signature algorithm");
                    562:                                        goto end;
                    563:                                }
                    564:                                if (!signature_params_equal(this->scheme, &sig_alg))
                    565:                                {
                    566:                                        DBG1(DBG_ASN, "  signature algorithms do not agree");
                    567:                                        goto end;
                    568:                                }
                    569:                                break;
                    570:                        case AC_OBJ_SIGNATURE:
                    571:                                this->signature = chunk_skip(object, 1);
                    572:                                break;
                    573:                        default:
                    574:                                break;
                    575:                }
                    576:        }
                    577:        success = parser->success(parser);
                    578: 
                    579: end:
                    580:        parser->destroy(parser);
                    581:        signature_params_clear(&sig_alg);
                    582:        return success;
                    583: }
                    584: 
                    585: /**
                    586:  * build directoryName
                    587:  */
                    588: static chunk_t build_directoryName(asn1_t tag, chunk_t name)
                    589: {
                    590:        return asn1_wrap(tag, "m",
                    591:                                asn1_simple_object(ASN1_CONTEXT_C_4, name));
                    592: }
                    593: 
                    594: /**
                    595:  * build holder
                    596:  */
                    597: static chunk_t build_holder(private_x509_ac_t *this)
                    598: {
                    599:        x509_t* x509 = (x509_t*)this->holderCert;
                    600:        identification_t *issuer, *subject;
                    601: 
                    602:        issuer = this->holderCert->get_issuer(this->holderCert);
                    603:        subject = this->holderCert->get_subject(this->holderCert);
                    604: 
                    605:        return asn1_wrap(ASN1_SEQUENCE, "mm",
                    606:                asn1_wrap(ASN1_CONTEXT_C_0, "mm",
                    607:                        build_directoryName(ASN1_SEQUENCE, issuer->get_encoding(issuer)),
                    608:                        asn1_simple_object(ASN1_INTEGER, x509->get_serial(x509))),
                    609:                build_directoryName(ASN1_CONTEXT_C_1, subject->get_encoding(subject)));
                    610: }
                    611: 
                    612: /**
                    613:  * build v2Form
                    614:  */
                    615: static chunk_t build_v2_form(private_x509_ac_t *this)
                    616: {
                    617:        identification_t *subject;
                    618: 
                    619:        subject = this->signerCert->get_subject(this->signerCert);
                    620:        return asn1_wrap(ASN1_CONTEXT_C_0, "m",
                    621:                                build_directoryName(ASN1_SEQUENCE,
                    622:                                        subject->get_encoding(subject)));
                    623: }
                    624: 
                    625: /**
                    626:  * build attrCertValidityPeriod
                    627:  */
                    628: static chunk_t build_attr_cert_validity(private_x509_ac_t *this)
                    629: {
                    630:        return asn1_wrap(ASN1_SEQUENCE, "mm",
                    631:                                asn1_from_time(&this->notBefore, ASN1_GENERALIZEDTIME),
                    632:                                asn1_from_time(&this->notAfter, ASN1_GENERALIZEDTIME));
                    633: }
                    634: 
                    635: /**
                    636:  * build attribute type
                    637:  */
                    638: static chunk_t build_attribute_type(int type, chunk_t content)
                    639: {
                    640:        return asn1_wrap(ASN1_SEQUENCE, "mm",
                    641:                                asn1_build_known_oid(type),
                    642:                                asn1_wrap(ASN1_SET, "m", content));
                    643: }
                    644: 
                    645: /**
                    646:  * build attributes
                    647:  */
                    648: static chunk_t build_attributes(private_x509_ac_t *this)
                    649: {
                    650:        enumerator_t *enumerator;
                    651:        group_t *group;
                    652:        chunk_t values;
                    653:        size_t size = 0, len;
                    654:        u_char *pos;
                    655: 
                    656:        /* precalculate the total size of all values */
                    657:        enumerator = this->groups->create_enumerator(this->groups);
                    658:        while (enumerator->enumerate(enumerator, &group))
                    659:        {
                    660:                len = group->value.len;
                    661:                size += 1 + (len > 0) + (len >= 128) +
                    662:                                (len >= 256) + (len >= 65536) + len;
                    663:        }
                    664:        enumerator->destroy(enumerator);
                    665: 
                    666:        pos = asn1_build_object(&values, ASN1_SEQUENCE, size);
                    667: 
                    668:        enumerator = this->groups->create_enumerator(this->groups);
                    669:        while (enumerator->enumerate(enumerator, &group))
                    670:        {
                    671:                chunk_t attr;
                    672:                asn1_t type;
                    673: 
                    674:                switch (group->type)
                    675:                {
                    676:                        case AC_GROUP_TYPE_OCTETS:
                    677:                                type = ASN1_OCTET_STRING;
                    678:                                break;
                    679:                        case AC_GROUP_TYPE_STRING:
                    680:                                type = ASN1_UTF8STRING;
                    681:                                break;
                    682:                        case AC_GROUP_TYPE_OID:
                    683:                                type = ASN1_OID;
                    684:                                break;
                    685:                        default:
                    686:                                continue;
                    687:                }
                    688:                attr = asn1_simple_object(type, group->value);
                    689: 
                    690:                memcpy(pos, attr.ptr, attr.len);
                    691:                pos += attr.len;
                    692:                free(attr.ptr);
                    693:        }
                    694:        enumerator->destroy(enumerator);
                    695: 
                    696:        return asn1_wrap(ASN1_SEQUENCE, "m",
                    697:                                build_attribute_type(OID_GROUP,
                    698:                                        asn1_wrap(ASN1_SEQUENCE, "m", values)));
                    699: }
                    700: 
                    701: /**
                    702:  * build authorityKeyIdentifier
                    703:  */
                    704: static chunk_t build_authorityKeyIdentifier(private_x509_ac_t *this)
                    705: {
                    706:        chunk_t keyIdentifier = chunk_empty;
                    707:        chunk_t authorityCertIssuer;
                    708:        chunk_t authorityCertSerialNumber;
                    709:        identification_t *issuer;
                    710:        public_key_t *public;
                    711:        x509_t *x509;
                    712: 
                    713:        x509 = (x509_t*)this->signerCert;
                    714:        issuer = this->signerCert->get_issuer(this->signerCert);
                    715:        public = this->signerCert->get_public_key(this->signerCert);
                    716:        if (public)
                    717:        {
                    718:                if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &keyIdentifier))
                    719:                {
                    720:                        this->authKeyIdentifier = chunk_clone(keyIdentifier);
                    721:                        keyIdentifier = asn1_simple_object(ASN1_CONTEXT_S_0, keyIdentifier);
                    722:                }
                    723:                public->destroy(public);
                    724:        }
                    725:        authorityCertIssuer = build_directoryName(ASN1_CONTEXT_C_1,
                    726:                                                                                        issuer->get_encoding(issuer));
                    727:        authorityCertSerialNumber = asn1_simple_object(ASN1_CONTEXT_S_2,
                    728:                                                                                        x509->get_serial(x509));
                    729:        return asn1_wrap(ASN1_SEQUENCE, "mm",
                    730:                                asn1_build_known_oid(OID_AUTHORITY_KEY_ID),
                    731:                                asn1_wrap(ASN1_OCTET_STRING, "m",
                    732:                                        asn1_wrap(ASN1_SEQUENCE, "mmm",
                    733:                                                keyIdentifier,
                    734:                                                authorityCertIssuer,
                    735:                                                authorityCertSerialNumber
                    736:                                        )
                    737:                                )
                    738:                   );
                    739: }
                    740: 
                    741: /**
                    742:  * build extensions
                    743:  */
                    744: static chunk_t build_extensions(private_x509_ac_t *this)
                    745: {
                    746:        return asn1_wrap(ASN1_SEQUENCE, "mc",
                    747:                                build_authorityKeyIdentifier(this),
                    748:                                ASN1_noRevAvail_ext);
                    749: }
                    750: 
                    751: /**
                    752:  * build attributeCertificateInfo
                    753:  */
                    754: static chunk_t build_attr_cert_info(private_x509_ac_t *this, chunk_t sig_scheme)
                    755: {
                    756:        return asn1_wrap(ASN1_SEQUENCE, "cmmcmmmm",
                    757:                                ASN1_INTEGER_1,
                    758:                                build_holder(this),
                    759:                                build_v2_form(this),
                    760:                                sig_scheme,
                    761:                                asn1_simple_object(ASN1_INTEGER, this->serialNumber),
                    762:                                build_attr_cert_validity(this),
                    763:                                build_attributes(this),
                    764:                                build_extensions(this));
                    765: }
                    766: 
                    767: /**
                    768:  * build an X.509 attribute certificate
                    769:  */
                    770: static bool build_ac(private_x509_ac_t *this, hash_algorithm_t digest_alg)
                    771: {
                    772:        chunk_t signatureValue, attributeCertificateInfo, sig_scheme;
                    773:        private_key_t *key = this->signerKey;
                    774: 
                    775:        if (!this->scheme)
                    776:        {
                    777:                INIT(this->scheme,
                    778:                        .scheme = signature_scheme_from_oid(
                    779:                                                                hasher_signature_algorithm_to_oid(digest_alg,
                    780:                                                                                                key->get_type(key))),
                    781:                );
                    782:        }
                    783:        if (this->scheme->scheme == SIGN_UNKNOWN)
                    784:        {
                    785:                return FALSE;
                    786:        }
                    787:        if (!signature_params_build(this->scheme, &sig_scheme))
                    788:        {
                    789:                return FALSE;
                    790:        }
                    791: 
                    792:        attributeCertificateInfo = build_attr_cert_info(this, sig_scheme);
                    793:        if (!key->sign(key, this->scheme->scheme, this->scheme->params,
                    794:                                   attributeCertificateInfo, &signatureValue))
                    795:        {
                    796:                free(attributeCertificateInfo.ptr);
                    797:                free(sig_scheme.ptr);
                    798:                return FALSE;
                    799:        }
                    800:        this->encoding = asn1_wrap(ASN1_SEQUENCE, "mmm",
                    801:                                                attributeCertificateInfo,
                    802:                                                sig_scheme,
                    803:                                                asn1_bitstring("m", signatureValue));
                    804:        return TRUE;
                    805: }
                    806: 
                    807: METHOD(ac_t, get_serial, chunk_t,
                    808:        private_x509_ac_t *this)
                    809: {
                    810:        return this->serialNumber;
                    811: }
                    812: 
                    813: METHOD(ac_t, get_holderSerial, chunk_t,
                    814:        private_x509_ac_t *this)
                    815: {
                    816:        if (this->holderSerial)
                    817:        {
                    818:                return this->holderSerial->get_encoding(this->holderSerial);
                    819:        }
                    820:        return chunk_empty;
                    821: }
                    822: 
                    823: METHOD(ac_t, get_holderIssuer, identification_t*,
                    824:        private_x509_ac_t *this)
                    825: {
                    826:        return this->holderIssuer;
                    827: }
                    828: 
                    829: METHOD(ac_t, get_authKeyIdentifier, chunk_t,
                    830:        private_x509_ac_t *this)
                    831: {
                    832:        return this->authKeyIdentifier;
                    833: }
                    834: 
                    835: CALLBACK(attr_filter, bool,
                    836:        void *null, enumerator_t *orig, va_list args)
                    837: {
                    838:        group_t *group;
                    839:        ac_group_type_t *type;
                    840:        chunk_t *out;
                    841: 
                    842:        VA_ARGS_VGET(args, type, out);
                    843: 
                    844:        while (orig->enumerate(orig, &group))
                    845:        {
                    846:                if (group->type == AC_GROUP_TYPE_STRING &&
                    847:                        !chunk_printable(group->value, NULL, 0))
                    848:                {       /* skip non-printable strings */
                    849:                        continue;
                    850:                }
                    851:                *type = group->type;
                    852:                *out = group->value;
                    853:                return TRUE;
                    854:        }
                    855:        return FALSE;
                    856: }
                    857: 
                    858: METHOD(ac_t, create_group_enumerator, enumerator_t*,
                    859:        private_x509_ac_t *this)
                    860: {
                    861:        return enumerator_create_filter(
                    862:                                                        this->groups->create_enumerator(this->groups),
                    863:                                                        attr_filter, NULL, NULL);
                    864: }
                    865: 
                    866: METHOD(certificate_t, get_type, certificate_type_t,
                    867:        private_x509_ac_t *this)
                    868: {
                    869:        return CERT_X509_AC;
                    870: }
                    871: 
                    872: METHOD(certificate_t, get_subject, identification_t*,
                    873:        private_x509_ac_t *this)
                    874: {
                    875:        if (this->entityName)
                    876:        {
                    877:                return this->entityName;
                    878:        }
                    879:        return this->holderSerial;
                    880: }
                    881: 
                    882: METHOD(certificate_t, get_issuer, identification_t*,
                    883:        private_x509_ac_t *this)
                    884: {
                    885:        return this->issuerName;
                    886: }
                    887: 
                    888: METHOD(certificate_t, has_subject, id_match_t,
                    889:        private_x509_ac_t *this, identification_t *subject)
                    890: {
                    891:        id_match_t entity = ID_MATCH_NONE, serial = ID_MATCH_NONE;
                    892: 
                    893:        if (this->entityName)
                    894:        {
                    895:                entity = this->entityName->matches(this->entityName, subject);
                    896:        }
                    897:        if (this->holderSerial)
                    898:        {
                    899:                serial = this->holderSerial->matches(this->holderSerial, subject);
                    900:        }
                    901:        return max(entity, serial);
                    902: }
                    903: 
                    904: METHOD(certificate_t, has_issuer, id_match_t,
                    905:        private_x509_ac_t *this, identification_t *issuer)
                    906: {
                    907:        if (issuer->get_type(issuer) == ID_KEY_ID &&
                    908:                this->authKeyIdentifier.ptr &&
                    909:                chunk_equals(this->authKeyIdentifier, issuer->get_encoding(issuer)))
                    910:        {
                    911:                return ID_MATCH_PERFECT;
                    912:        }
                    913:        return this->issuerName->matches(this->issuerName, issuer);
                    914: }
                    915: 
                    916: METHOD(certificate_t, issued_by, bool,
                    917:        private_x509_ac_t *this, certificate_t *issuer,
                    918:        signature_params_t **scheme)
                    919: {
                    920:        public_key_t *key;
                    921:        bool valid;
                    922:        x509_t *x509 = (x509_t*)issuer;
                    923: 
                    924:        /* check if issuer is an X.509 AA certificate */
                    925:        if (issuer->get_type(issuer) != CERT_X509)
                    926:        {
                    927:                return FALSE;
                    928:        }
                    929:        if (!(x509->get_flags(x509) & X509_AA))
                    930:        {
                    931:                return FALSE;
                    932:        }
                    933: 
                    934:        /* get the public key of the issuer */
                    935:        key = issuer->get_public_key(issuer);
                    936: 
                    937:        /* compare keyIdentifiers if available, otherwise use DNs */
                    938:        if (this->authKeyIdentifier.ptr && key)
                    939:        {
                    940:                chunk_t fingerprint;
                    941: 
                    942:                if (!key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fingerprint) ||
                    943:                        !chunk_equals(fingerprint, this->authKeyIdentifier))
                    944:                {
                    945:                        return FALSE;
                    946:                }
                    947:        }
                    948:        else
                    949:        {
                    950:                if (!this->issuerName->equals(this->issuerName,
                    951:                                                                          issuer->get_subject(issuer)))
                    952:                {
                    953:                        return FALSE;
                    954:                }
                    955:        }
                    956: 
                    957:        if (!key)
                    958:        {
                    959:                return FALSE;
                    960:        }
                    961:        valid = key->verify(key, this->scheme->scheme, this->scheme->params,
                    962:                                                this->certificateInfo, this->signature);
                    963:        key->destroy(key);
                    964:        if (valid && scheme)
                    965:        {
                    966:                *scheme = signature_params_clone(this->scheme);
                    967:        }
                    968:        return valid;
                    969: }
                    970: 
                    971: METHOD(certificate_t, get_public_key, public_key_t*,
                    972:        private_x509_ac_t *this)
                    973: {
                    974:        return NULL;
                    975: }
                    976: 
                    977: METHOD(certificate_t, get_ref, certificate_t*,
                    978:        private_x509_ac_t *this)
                    979: {
                    980:        ref_get(&this->ref);
                    981:        return &this->public.interface.certificate;
                    982: }
                    983: 
                    984: METHOD(certificate_t, get_validity, bool,
                    985:        private_x509_ac_t *this, time_t *when, time_t *not_before, time_t *not_after)
                    986: {
                    987:        time_t t = when ? *when : time(NULL);
                    988: 
                    989:        if (not_before)
                    990:        {
                    991:                *not_before = this->notBefore;
                    992:        }
                    993:        if (not_after)
                    994:        {
                    995:                *not_after = this->notAfter;
                    996:        }
                    997:        return (t >= this->notBefore && t <= this->notAfter);
                    998: }
                    999: 
                   1000: METHOD(certificate_t, get_encoding, bool,
                   1001:        private_x509_ac_t *this, cred_encoding_type_t type, chunk_t *encoding)
                   1002: {
                   1003:        if (type == CERT_ASN1_DER)
                   1004:        {
                   1005:                *encoding = chunk_clone(this->encoding);
                   1006:                return TRUE;
                   1007:        }
                   1008:        return lib->encoding->encode(lib->encoding, type, NULL, encoding,
                   1009:                                        CRED_PART_X509_AC_ASN1_DER, this->encoding, CRED_PART_END);
                   1010: }
                   1011: 
                   1012: METHOD(certificate_t, equals, bool,
                   1013:        private_x509_ac_t *this, certificate_t *other)
                   1014: {
                   1015:        chunk_t encoding;
                   1016:        bool equal;
                   1017: 
                   1018:        if ((certificate_t*)this == other)
                   1019:        {
                   1020:                return TRUE;
                   1021:        }
                   1022:        if (other->equals == _equals)
                   1023:        {       /* skip allocation if we have the same implementation */
                   1024:                return chunk_equals(this->encoding,
                   1025:                                                        ((private_x509_ac_t*)other)->encoding);
                   1026:        }
                   1027:        if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
                   1028:        {
                   1029:                return FALSE;
                   1030:        }
                   1031:        equal = chunk_equals(this->encoding, encoding);
                   1032:        free(encoding.ptr);
                   1033:        return equal;
                   1034: }
                   1035: 
                   1036: METHOD(certificate_t, destroy, void,
                   1037:        private_x509_ac_t *this)
                   1038: {
                   1039:        if (ref_put(&this->ref))
                   1040:        {
                   1041:                DESTROY_IF(this->holderIssuer);
                   1042:                DESTROY_IF(this->holderSerial);
                   1043:                DESTROY_IF(this->entityName);
                   1044:                DESTROY_IF(this->issuerName);
                   1045:                DESTROY_IF(this->holderCert);
                   1046:                DESTROY_IF(this->signerCert);
                   1047:                DESTROY_IF(this->signerKey);
                   1048:                this->groups->destroy_function(this->groups, (void*)group_destroy);
                   1049:                signature_params_destroy(this->scheme);
                   1050:                free(this->serialNumber.ptr);
                   1051:                free(this->authKeyIdentifier.ptr);
                   1052:                free(this->encoding.ptr);
                   1053:                free(this);
                   1054:        }
                   1055: }
                   1056: 
                   1057: /**
                   1058:  * create an empty but initialized X.509 attribute certificate
                   1059:  */
                   1060: static private_x509_ac_t *create_empty(void)
                   1061: {
                   1062:        private_x509_ac_t *this;
                   1063: 
                   1064:        INIT(this,
                   1065:                .public = {
                   1066:                        .interface = {
                   1067:                                .certificate = {
                   1068:                                        .get_type = _get_type,
                   1069:                                        .get_subject = _get_subject,
                   1070:                                        .get_issuer = _get_issuer,
                   1071:                                        .has_subject = _has_subject,
                   1072:                                        .has_issuer = _has_issuer,
                   1073:                                        .issued_by = _issued_by,
                   1074:                                        .get_public_key = _get_public_key,
                   1075:                                        .get_validity = _get_validity,
                   1076:                                        .get_encoding = _get_encoding,
                   1077:                                        .equals = _equals,
                   1078:                                        .get_ref = _get_ref,
                   1079:                                        .destroy = _destroy,
                   1080:                                },
                   1081:                                .get_serial = _get_serial,
                   1082:                                .get_holderSerial = _get_holderSerial,
                   1083:                                .get_holderIssuer = _get_holderIssuer,
                   1084:                                .get_authKeyIdentifier = _get_authKeyIdentifier,
                   1085:                                .create_group_enumerator = _create_group_enumerator,
                   1086:                        },
                   1087:                },
                   1088:                .groups = linked_list_create(),
                   1089:                .ref = 1,
                   1090:        );
                   1091: 
                   1092:        return this;
                   1093: }
                   1094: 
                   1095: /**
                   1096:  * See header.
                   1097:  */
                   1098: x509_ac_t *x509_ac_load(certificate_type_t type, va_list args)
                   1099: {
                   1100:        chunk_t blob = chunk_empty;
                   1101: 
                   1102:        while (TRUE)
                   1103:        {
                   1104:                switch (va_arg(args, builder_part_t))
                   1105:                {
                   1106:                        case BUILD_BLOB_ASN1_DER:
                   1107:                                blob = va_arg(args, chunk_t);
                   1108:                                continue;
                   1109:                        case BUILD_END:
                   1110:                                break;
                   1111:                        default:
                   1112:                                return NULL;
                   1113:                }
                   1114:                break;
                   1115:        }
                   1116:        if (blob.ptr)
                   1117:        {
                   1118:                private_x509_ac_t *ac = create_empty();
                   1119: 
                   1120:                ac->encoding = chunk_clone(blob);
                   1121:                if (parse_certificate(ac))
                   1122:                {
                   1123:                        return &ac->public;
                   1124:                }
                   1125:                destroy(ac);
                   1126:        }
                   1127:        return NULL;
                   1128: }
                   1129: 
                   1130: /**
                   1131:  * Add groups from a list into AC group memberships
                   1132:  */
                   1133: static void add_groups_from_list(private_x509_ac_t *this, linked_list_t *list)
                   1134: {
                   1135:        enumerator_t *enumerator;
                   1136:        group_t *group;
                   1137:        char *name;
                   1138: 
                   1139:        enumerator = list->create_enumerator(list);
                   1140:        while (enumerator->enumerate(enumerator, &name))
                   1141:        {
                   1142:                INIT(group,
                   1143:                        .type = AC_GROUP_TYPE_STRING,
                   1144:                        .value = chunk_clone(chunk_from_str(name)),
                   1145:                );
                   1146:                this->groups->insert_last(this->groups, group);
                   1147:        }
                   1148:        enumerator->destroy(enumerator);
                   1149: }
                   1150: 
                   1151: /**
                   1152:  * See header.
                   1153:  */
                   1154: x509_ac_t *x509_ac_gen(certificate_type_t type, va_list args)
                   1155: {
                   1156:        hash_algorithm_t digest_alg = HASH_SHA1;
                   1157:        private_x509_ac_t *ac;
                   1158: 
                   1159:        ac = create_empty();
                   1160:        while (TRUE)
                   1161:        {
                   1162:                switch (va_arg(args, builder_part_t))
                   1163:                {
                   1164:                        case BUILD_NOT_BEFORE_TIME:
                   1165:                                ac->notBefore = va_arg(args, time_t);
                   1166:                                continue;
                   1167:                        case BUILD_NOT_AFTER_TIME:
                   1168:                                ac->notAfter = va_arg(args, time_t);
                   1169:                                continue;
                   1170:                        case BUILD_SERIAL:
                   1171:                                ac->serialNumber = chunk_clone(va_arg(args, chunk_t));
                   1172:                                continue;
                   1173:                        case BUILD_AC_GROUP_STRINGS:
                   1174:                                add_groups_from_list(ac, va_arg(args, linked_list_t*));
                   1175:                                continue;
                   1176:                        case BUILD_CERT:
                   1177:                                ac->holderCert = va_arg(args, certificate_t*);
                   1178:                                ac->holderCert->get_ref(ac->holderCert);
                   1179:                                continue;
                   1180:                        case BUILD_SIGNING_CERT:
                   1181:                                ac->signerCert = va_arg(args, certificate_t*);
                   1182:                                ac->signerCert->get_ref(ac->signerCert);
                   1183:                                continue;
                   1184:                        case BUILD_SIGNING_KEY:
                   1185:                                ac->signerKey = va_arg(args, private_key_t*);
                   1186:                                ac->signerKey->get_ref(ac->signerKey);
                   1187:                                continue;
                   1188:                        case BUILD_SIGNATURE_SCHEME:
                   1189:                                ac->scheme = va_arg(args, signature_params_t*);
                   1190:                                ac->scheme = signature_params_clone(ac->scheme);
                   1191:                                continue;
                   1192:                        case BUILD_DIGEST_ALG:
                   1193:                                digest_alg = va_arg(args, int);
                   1194:                                continue;
                   1195:                        case BUILD_END:
                   1196:                                break;
                   1197:                        default:
                   1198:                                destroy(ac);
                   1199:                                return NULL;
                   1200:                }
                   1201:                break;
                   1202:        }
                   1203: 
                   1204:        if (ac->signerKey && ac->holderCert && ac->signerCert &&
                   1205:                ac->holderCert->get_type(ac->holderCert) == CERT_X509 &&
                   1206:                ac->signerCert->get_type(ac->signerCert) == CERT_X509)
                   1207:        {
                   1208:                if (build_ac(ac, digest_alg))
                   1209:                {
                   1210:                        return &ac->public;
                   1211:                }
                   1212:        }
                   1213:        destroy(ac);
                   1214:        return NULL;
                   1215: }

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