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

1.1       misho       1: /*
                      2:  * Copyright (C) 2005 Jan Hutter, Martin Willi
                      3:  * Copyright (C) 2009-2017 Andreas Steffen
                      4:  * HSR Hochschule fuer Technik Rapperswil
                      5:  *
                      6:  * This program is free software; you can redistribute it and/or modify it
                      7:  * under the terms of the GNU General Public License as published by the
                      8:  * Free Software Foundation; either version 2 of the License, or (at your
                      9:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     10:  *
                     11:  * This program is distributed in the hope that it will be useful, but
                     12:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     13:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     14:  * for more details.
                     15:  */
                     16: 
                     17: #include "x509_pkcs10.h"
                     18: 
                     19: #include <library.h>
                     20: #include <utils/debug.h>
                     21: #include <asn1/oid.h>
                     22: #include <asn1/asn1.h>
                     23: #include <asn1/asn1_parser.h>
                     24: #include <credentials/keys/private_key.h>
                     25: #include <collections/linked_list.h>
                     26: #include <utils/identification.h>
                     27: 
                     28: typedef struct private_x509_pkcs10_t private_x509_pkcs10_t;
                     29: 
                     30: /**
                     31:  * Private data of a x509_pkcs10_t object.
                     32:  */
                     33: struct private_x509_pkcs10_t {
                     34:        /**
                     35:         * Public interface for this certificate.
                     36:         */
                     37:        x509_pkcs10_t public;
                     38: 
                     39:        /**
                     40:         * PKCS#10 certificate request encoding in ASN.1 DER format
                     41:         */
                     42:        chunk_t encoding;
                     43: 
                     44:        /**
                     45:         * PKCS#10 request body over which signature is computed
                     46:         */
                     47:        chunk_t certificationRequestInfo;
                     48: 
                     49:        /**
                     50:         * Version of the PKCS#10 certificate request
                     51:         */
                     52:        u_int version;
                     53: 
                     54:        /**
                     55:         * ID representing the certificate subject
                     56:         */
                     57:        identification_t *subject;
                     58: 
                     59:        /**
                     60:         * List of subjectAltNames as identification_t
                     61:         */
                     62:        linked_list_t *subjectAltNames;
                     63: 
                     64:        /**
                     65:         * certificate's embedded public key
                     66:         */
                     67:        public_key_t *public_key;
                     68: 
                     69:        /**
                     70:         * challenge password
                     71:         */
                     72:        chunk_t challengePassword;
                     73: 
                     74:        /**
                     75:         * Signature scheme
                     76:         */
                     77:        signature_params_t *scheme;
                     78: 
                     79:        /**
                     80:         * Signature
                     81:         */
                     82:        chunk_t signature;
                     83: 
                     84:        /**
                     85:         * Is the certificate request self-signed?
                     86:         */
                     87:        bool self_signed;
                     88: 
                     89:        /**
                     90:         * Certificate request parsed from blob/file?
                     91:         */
                     92:        bool parsed;
                     93: 
                     94:        /**
                     95:         * reference count
                     96:         */
                     97:        refcount_t ref;
                     98: };
                     99: 
                    100: /**
                    101:  * Imported from x509_cert.c
                    102:  */
                    103: extern bool x509_parse_generalNames(chunk_t blob, int level0, bool implicit,
                    104:                                                                        linked_list_t *list);
                    105: extern chunk_t x509_build_subjectAltNames(linked_list_t *list);
                    106: 
                    107: METHOD(certificate_t, get_type, certificate_type_t,
                    108:        private_x509_pkcs10_t *this)
                    109: {
                    110:        return CERT_PKCS10_REQUEST;
                    111: }
                    112: 
                    113: METHOD(certificate_t, get_subject, identification_t*,
                    114:        private_x509_pkcs10_t *this)
                    115: {
                    116:        return this->subject;
                    117: }
                    118: 
                    119: METHOD(certificate_t, has_subject, id_match_t,
                    120:        private_x509_pkcs10_t *this, identification_t *subject)
                    121: {
                    122:        return this->subject->matches(this->subject, subject);
                    123: }
                    124: 
                    125: METHOD(certificate_t, issued_by, bool,
                    126:        private_x509_pkcs10_t *this, certificate_t *issuer,
                    127:        signature_params_t **scheme)
                    128: {
                    129:        public_key_t *key;
                    130:        bool valid;
                    131: 
                    132:        if (&this->public.interface.interface != issuer)
                    133:        {
                    134:                return FALSE;
                    135:        }
                    136:        if (this->self_signed)
                    137:        {
                    138:                valid = TRUE;
                    139:        }
                    140:        else
                    141:        {
                    142:                /* get the public key contained in the certificate request */
                    143:                key = this->public_key;
                    144:                if (!key)
                    145:                {
                    146:                        return FALSE;
                    147:                }
                    148:                valid = key->verify(key, this->scheme->scheme, this->scheme->params,
                    149:                                                        this->certificationRequestInfo, this->signature);
                    150:        }
                    151:        if (valid && scheme)
                    152:        {
                    153:                *scheme = signature_params_clone(this->scheme);
                    154:        }
                    155:        return valid;
                    156: }
                    157: 
                    158: METHOD(certificate_t, get_public_key, public_key_t*,
                    159:        private_x509_pkcs10_t *this)
                    160: {
                    161:        this->public_key->get_ref(this->public_key);
                    162:        return this->public_key;
                    163: }
                    164: 
                    165: METHOD(certificate_t, get_validity, bool,
                    166:        private_x509_pkcs10_t *this, time_t *when, time_t *not_before,
                    167:        time_t *not_after)
                    168: {
                    169:        if (not_before)
                    170:        {
                    171:                *not_before = 0;
                    172:        }
                    173:        if (not_after)
                    174:        {
                    175:                *not_after = ~0;
                    176:        }
                    177:        return TRUE;
                    178: }
                    179: 
                    180: METHOD(certificate_t, get_encoding, bool,
                    181:        private_x509_pkcs10_t *this, cred_encoding_type_t type, chunk_t *encoding)
                    182: {
                    183:        if (type == CERT_ASN1_DER)
                    184:        {
                    185:                *encoding = chunk_clone(this->encoding);
                    186:                return TRUE;
                    187:        }
                    188:        return lib->encoding->encode(lib->encoding, type, NULL, encoding,
                    189:                                        CRED_PART_PKCS10_ASN1_DER, this->encoding, CRED_PART_END);
                    190: }
                    191: 
                    192: METHOD(certificate_t, equals, bool,
                    193:        private_x509_pkcs10_t *this, certificate_t *other)
                    194: {
                    195:        chunk_t encoding;
                    196:        bool equal;
                    197: 
                    198:        if (this == (private_x509_pkcs10_t*)other)
                    199:        {
                    200:                return TRUE;
                    201:        }
                    202:        if (other->get_type(other) != CERT_PKCS10_REQUEST)
                    203:        {
                    204:                return FALSE;
                    205:        }
                    206:        if (other->equals == (void*)equals)
                    207:        {       /* skip allocation if we have the same implementation */
                    208:                return chunk_equals(this->encoding, ((private_x509_pkcs10_t*)other)->encoding);
                    209:        }
                    210:        if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
                    211:        {
                    212:                return FALSE;
                    213:        }
                    214:        equal = chunk_equals(this->encoding, encoding);
                    215:        free(encoding.ptr);
                    216:        return equal;
                    217: }
                    218: 
                    219: METHOD(certificate_t, get_ref, certificate_t*,
                    220:        private_x509_pkcs10_t *this)
                    221: {
                    222:        ref_get(&this->ref);
                    223:        return &this->public.interface.interface;
                    224: }
                    225: 
                    226: METHOD(pkcs10_t, get_challengePassword, chunk_t,
                    227:        private_x509_pkcs10_t *this)
                    228: {
                    229:        return this->challengePassword;
                    230: }
                    231: 
                    232: METHOD(pkcs10_t, create_subjectAltName_enumerator, enumerator_t*,
                    233:        private_x509_pkcs10_t *this)
                    234: {
                    235:        return this->subjectAltNames->create_enumerator(this->subjectAltNames);
                    236: }
                    237: 
                    238: /**
                    239:  * ASN.1 definition of a PKCS#10 extension request
                    240:  */
                    241: static const asn1Object_t extensionRequestObjects[] = {
                    242:        { 0, "extensions",   ASN1_SEQUENCE,     ASN1_LOOP           }, /* 0 */
                    243:        { 1,   "extension",   ASN1_SEQUENCE,     ASN1_NONE          }, /* 1 */
                    244:        { 2,     "extnID",        ASN1_OID,          ASN1_BODY          }, /* 2 */
                    245:        { 2,     "critical",  ASN1_BOOLEAN,      ASN1_DEF|ASN1_BODY }, /* 3 */
                    246:        { 2,     "extnValue", ASN1_OCTET_STRING, ASN1_BODY          }, /* 4 */
                    247:        { 1, "end loop",      ASN1_EOC,          ASN1_END                       }, /* 5 */
                    248:        { 0, "exit",          ASN1_EOC,          ASN1_EXIT          }
                    249: };
                    250: #define PKCS10_EXTN_ID                 2
                    251: #define PKCS10_EXTN_CRITICAL   3
                    252: #define PKCS10_EXTN_VALUE              4
                    253: 
                    254: /**
                    255:  * Parses a PKCS#10 extension request
                    256:  */
                    257: static bool parse_extension_request(private_x509_pkcs10_t *this, chunk_t blob, int level0)
                    258: {
                    259:        asn1_parser_t *parser;
                    260:        chunk_t object;
                    261:        int objectID;
                    262:        int extn_oid = OID_UNKNOWN;
                    263:        bool success = FALSE;
                    264:        bool critical;
                    265: 
                    266:        parser = asn1_parser_create(extensionRequestObjects, blob);
                    267:        parser->set_top_level(parser, level0);
                    268: 
                    269:        while (parser->iterate(parser, &objectID, &object))
                    270:        {
                    271:                u_int level = parser->get_level(parser)+1;
                    272: 
                    273:                switch (objectID)
                    274:                {
                    275:                        case PKCS10_EXTN_ID:
                    276:                                extn_oid = asn1_known_oid(object);
                    277:                                break;
                    278:                        case PKCS10_EXTN_CRITICAL:
                    279:                                critical = object.len && *object.ptr;
                    280:                                DBG2(DBG_ASN, "  %s", critical ? "TRUE" : "FALSE");
                    281:                                break;
                    282:                        case PKCS10_EXTN_VALUE:
                    283:                        {
                    284:                                switch (extn_oid)
                    285:                                {
                    286:                                        case OID_SUBJECT_ALT_NAME:
                    287:                                                if (!x509_parse_generalNames(object, level, FALSE,
                    288:                                                                                                         this->subjectAltNames))
                    289:                                                {
                    290:                                                        goto end;
                    291:                                                }
                    292:                                                break;
                    293:                                        default:
                    294:                                                break;
                    295:                                }
                    296:                                break;
                    297:                        }
                    298:                        default:
                    299:                                break;
                    300:                }
                    301:        }
                    302:        success = parser->success(parser);
                    303: 
                    304: end:
                    305:        parser->destroy(parser);
                    306: 
                    307:        return success;
                    308: }
                    309: 
                    310: /**
                    311:  * Parses a PKCS#10 challenge password
                    312:  */
                    313: static bool parse_challengePassword(private_x509_pkcs10_t *this, chunk_t blob, int level)
                    314: {
                    315:        char tag;
                    316: 
                    317:        if (blob.len < 2)
                    318:        {
                    319:                DBG1(DBG_ASN, "L%d - challengePassword:  ASN.1 object smaller "
                    320:                         "than 2 octets", level);
                    321:                return FALSE;
                    322:        }
                    323:        tag = *blob.ptr;
                    324:        if (tag < ASN1_UTF8STRING || tag > ASN1_IA5STRING)
                    325:        {
                    326:                DBG1(DBG_ASN, "L%d - challengePassword:  ASN.1 object is not "
                    327:                         "a character string", level);
                    328:                return FALSE;
                    329:        }
                    330:        if (asn1_length(&blob) == ASN1_INVALID_LENGTH)
                    331:        {
                    332:                DBG1(DBG_ASN, "L%d - challengePassword:  ASN.1 object has an "
                    333:                         "invalid length", level);
                    334:                return FALSE;
                    335:        }
                    336:        DBG2(DBG_ASN, "L%d - challengePassword:", level);
                    337:        DBG4(DBG_ASN, "  '%.*s'", (int)blob.len, blob.ptr);
                    338:        return TRUE;
                    339: }
                    340: 
                    341: /**
                    342:  * ASN.1 definition of a PKCS#10 certificate request
                    343:  */
                    344: static const asn1Object_t certificationRequestObjects[] = {
                    345:        { 0, "certificationRequest",       ASN1_SEQUENCE,    ASN1_OBJ  }, /*  0 */
                    346:        { 1,   "certificationRequestInfo", ASN1_SEQUENCE,    ASN1_OBJ  }, /*  1 */
                    347:        { 2,     "version",                ASN1_INTEGER,     ASN1_BODY }, /*  2 */
                    348:        { 2,     "subject",                ASN1_SEQUENCE,    ASN1_OBJ  }, /*  3 */
                    349:        { 2,     "subjectPublicKeyInfo",   ASN1_SEQUENCE,    ASN1_RAW  }, /*  4 */
                    350:        { 2,     "attributes",             ASN1_CONTEXT_C_0, ASN1_LOOP }, /*  5 */
                    351:        { 3,       "attribute",            ASN1_SEQUENCE,    ASN1_NONE }, /*  6 */
                    352:        { 4,         "type",               ASN1_OID,         ASN1_BODY }, /*  7 */
                    353:        { 4,         "values",             ASN1_SET,         ASN1_LOOP }, /*  8 */
                    354:        { 5,           "value",            ASN1_EOC,         ASN1_RAW  }, /*  9 */
                    355:        { 4,         "end loop",           ASN1_EOC,         ASN1_END  }, /* 10 */
                    356:        { 2,     "end loop",               ASN1_EOC,         ASN1_END  }, /* 11 */
                    357:        { 1,   "signatureAlgorithm",       ASN1_EOC,         ASN1_RAW  }, /* 12 */
                    358:        { 1,    "signature",               ASN1_BIT_STRING,  ASN1_BODY }, /* 13 */
                    359:        { 0, "exit",                       ASN1_EOC,         ASN1_EXIT }
                    360: };
                    361: #define PKCS10_CERT_REQUEST_INFO                1
                    362: #define PKCS10_VERSION                                  2
                    363: #define PKCS10_SUBJECT                                  3
                    364: #define PKCS10_SUBJECT_PUBLIC_KEY_INFO  4
                    365: #define PKCS10_ATTR_TYPE                                7
                    366: #define PKCS10_ATTR_VALUE                               9
                    367: #define PKCS10_ALGORITHM                               12
                    368: #define PKCS10_SIGNATURE                               13
                    369: 
                    370: /**
                    371:  * Parses a PKCS#10 certificate request
                    372:  */
                    373: static bool parse_certificate_request(private_x509_pkcs10_t *this)
                    374: {
                    375:        asn1_parser_t *parser;
                    376:        chunk_t object;
                    377:        int objectID;
                    378:        int attr_oid = OID_UNKNOWN;
                    379:        bool success = FALSE;
                    380: 
                    381:        parser = asn1_parser_create(certificationRequestObjects, this->encoding);
                    382: 
                    383:        while (parser->iterate(parser, &objectID, &object))
                    384:        {
                    385:                u_int level = parser->get_level(parser)+1;
                    386: 
                    387:                switch (objectID)
                    388:                {
                    389:                        case PKCS10_CERT_REQUEST_INFO:
                    390:                                this->certificationRequestInfo = object;
                    391:                                break;
                    392:                        case PKCS10_VERSION:
                    393:                                if (object.len > 0 && *object.ptr != 0)
                    394:                                {
                    395:                                        DBG1(DBG_ASN, "PKCS#10 certificate request format is "
                    396:                                                 "not version 1");
                    397:                                        goto end;
                    398:                                }
                    399:                                break;
                    400:                        case PKCS10_SUBJECT:
                    401:                                this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object);
                    402:                                DBG2(DBG_ASN, "  '%Y'", this->subject);
                    403:                                break;
                    404:                        case PKCS10_SUBJECT_PUBLIC_KEY_INFO:
                    405:                                this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
                    406:                                                KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END);
                    407:                                if (!this->public_key)
                    408:                                {
                    409:                                        goto end;
                    410:                                }
                    411:                                break;
                    412:                        case PKCS10_ATTR_TYPE:
                    413:                                attr_oid = asn1_known_oid(object);
                    414:                                break;
                    415:                        case PKCS10_ATTR_VALUE:
                    416:                                switch (attr_oid)
                    417:                                {
                    418:                                        case OID_EXTENSION_REQUEST:
                    419:                                                if (!parse_extension_request(this, object, level))
                    420:                                                {
                    421:                                                        goto end;
                    422:                                                }
                    423:                                                break;
                    424:                                        case OID_CHALLENGE_PASSWORD:
                    425:                                                if (!parse_challengePassword(this, object, level))
                    426:                                                {
                    427:                                                        goto end;
                    428:                                                }
                    429:                                                break;
                    430:                                        default:
                    431:                                                break;
                    432:                                }
                    433:                                break;
                    434:                        case PKCS10_ALGORITHM:
                    435:                                INIT(this->scheme);
                    436:                                if (!signature_params_parse(object, level, this->scheme))
                    437:                                {
                    438:                                        DBG1(DBG_ASN, "  unable to parse signature algorithm");
                    439:                                        goto end;
                    440:                                }
                    441:                                break;
                    442:                        case PKCS10_SIGNATURE:
                    443:                                this->signature = chunk_skip(object, 1);
                    444:                                break;
                    445:                        default:
                    446:                                break;
                    447:                }
                    448:        }
                    449:        success = parser->success(parser);
                    450: 
                    451: end:
                    452:        parser->destroy(parser);
                    453:        if (success)
                    454:        {
                    455:                /* check if the certificate request is self-signed */
                    456:                if (issued_by(this, &this->public.interface.interface, NULL))
                    457:                {
                    458:                        this->self_signed = TRUE;
                    459:                }
                    460:                else
                    461:                {
                    462:                        DBG1(DBG_LIB, "certificate request is not self-signed");
                    463:                        success = FALSE;
                    464:                }
                    465:        }
                    466:        return success;
                    467: }
                    468: 
                    469: METHOD(certificate_t, destroy, void,
                    470:        private_x509_pkcs10_t *this)
                    471: {
                    472:        if (ref_put(&this->ref))
                    473:        {
                    474:                this->subjectAltNames->destroy_offset(this->subjectAltNames,
                    475:                                                                        offsetof(identification_t, destroy));
                    476:                signature_params_destroy(this->scheme);
                    477:                DESTROY_IF(this->subject);
                    478:                DESTROY_IF(this->public_key);
                    479:                chunk_free(&this->encoding);
                    480:                if (!this->parsed)
                    481:                {       /* only parsed certificate requests point these fields to "encoded" */
                    482:                        chunk_free(&this->certificationRequestInfo);
                    483:                        chunk_free(&this->challengePassword);
                    484:                        chunk_free(&this->signature);
                    485:                }
                    486:                free(this);
                    487:        }
                    488: }
                    489: 
                    490: /**
                    491:  * create an empty but initialized PKCS#10 certificate request
                    492:  */
                    493: static private_x509_pkcs10_t* create_empty(void)
                    494: {
                    495:        private_x509_pkcs10_t *this;
                    496: 
                    497:        INIT(this,
                    498:                .public = {
                    499:                        .interface = {
                    500:                                .interface = {
                    501:                                        .get_type = _get_type,
                    502:                                        .get_subject = _get_subject,
                    503:                                        .get_issuer = _get_subject,
                    504:                                        .has_subject = _has_subject,
                    505:                                        .has_issuer = _has_subject,
                    506:                                        .issued_by = _issued_by,
                    507:                                        .get_public_key = _get_public_key,
                    508:                                        .get_validity = _get_validity,
                    509:                                        .get_encoding = _get_encoding,
                    510:                                        .equals = _equals,
                    511:                                        .get_ref = _get_ref,
                    512:                                        .destroy = _destroy,
                    513:                                },
                    514:                                .get_challengePassword = _get_challengePassword,
                    515:                                .create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
                    516:                        },
                    517:                },
                    518:                .subjectAltNames = linked_list_create(),
                    519:                .ref = 1,
                    520:        );
                    521: 
                    522:        return this;
                    523: }
                    524: 
                    525: /**
                    526:  * Generate and sign a new certificate request
                    527:  */
                    528: static bool generate(private_x509_pkcs10_t *cert, private_key_t *sign_key,
                    529:                                         int digest_alg)
                    530: {
                    531:        chunk_t key_info, subjectAltNames, attributes;
                    532:        chunk_t extensionRequest  = chunk_empty;
                    533:        chunk_t challengePassword = chunk_empty, sig_scheme = chunk_empty;
                    534:        identification_t *subject;
                    535: 
                    536:        subject = cert->subject;
                    537:        cert->public_key = sign_key->get_public_key(sign_key);
                    538: 
                    539:        /* select signature scheme, if not already specified */
                    540:        if (!cert->scheme)
                    541:        {
                    542:                INIT(cert->scheme,
                    543:                        .scheme = signature_scheme_from_oid(
                    544:                                                                hasher_signature_algorithm_to_oid(digest_alg,
                    545:                                                                                                sign_key->get_type(sign_key))),
                    546:                );
                    547:        }
                    548:        if (cert->scheme->scheme == SIGN_UNKNOWN)
                    549:        {
                    550:                return FALSE;
                    551:        }
                    552:        if (!signature_params_build(cert->scheme, &sig_scheme))
                    553:        {
                    554:                return FALSE;
                    555:        }
                    556: 
                    557:        if (!cert->public_key->get_encoding(cert->public_key,
                    558:                                                                                PUBKEY_SPKI_ASN1_DER, &key_info))
                    559:        {
                    560:                chunk_free(&sig_scheme);
                    561:                return FALSE;
                    562:        }
                    563: 
                    564:        /* encode subjectAltNames */
                    565:        subjectAltNames = x509_build_subjectAltNames(cert->subjectAltNames);
                    566: 
                    567:        if (subjectAltNames.ptr)
                    568:        {
                    569:                extensionRequest = asn1_wrap(ASN1_SEQUENCE, "mm",
                    570:                                        asn1_build_known_oid(OID_EXTENSION_REQUEST),
                    571:                                        asn1_wrap(ASN1_SET, "m",
                    572:                                                asn1_wrap(ASN1_SEQUENCE, "m", subjectAltNames)
                    573:                                        ));
                    574:        }
                    575:        if (cert->challengePassword.len > 0)
                    576:        {
                    577:                asn1_t type = asn1_is_printablestring(cert->challengePassword) ?
                    578:                                                                ASN1_PRINTABLESTRING : ASN1_T61STRING;
                    579: 
                    580:                challengePassword = asn1_wrap(ASN1_SEQUENCE, "mm",
                    581:                                        asn1_build_known_oid(OID_CHALLENGE_PASSWORD),
                    582:                                        asn1_wrap(ASN1_SET, "m",
                    583:                                                asn1_simple_object(type, cert->challengePassword)
                    584:                                        )
                    585:                        );
                    586:        }
                    587:        attributes = asn1_wrap(ASN1_CONTEXT_C_0, "mm", extensionRequest,
                    588:                                                                                                   challengePassword);
                    589: 
                    590:        cert->certificationRequestInfo = asn1_wrap(ASN1_SEQUENCE, "ccmm",
                    591:                                                        ASN1_INTEGER_0,
                    592:                                                        subject->get_encoding(subject),
                    593:                                                        key_info,
                    594:                                                        attributes);
                    595: 
                    596:        if (!sign_key->sign(sign_key, cert->scheme->scheme, cert->scheme->params,
                    597:                                                cert->certificationRequestInfo, &cert->signature))
                    598:        {
                    599:                chunk_free(&sig_scheme);
                    600:                return FALSE;
                    601:        }
                    602: 
                    603:        cert->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm",
                    604:                                                           cert->certificationRequestInfo,
                    605:                                                           sig_scheme,
                    606:                                                           asn1_bitstring("c", cert->signature));
                    607:        return TRUE;
                    608: }
                    609: 
                    610: /**
                    611:  * See header.
                    612:  */
                    613: x509_pkcs10_t *x509_pkcs10_load(certificate_type_t type, va_list args)
                    614: {
                    615:        chunk_t blob = chunk_empty;
                    616: 
                    617:        while (TRUE)
                    618:        {
                    619:                switch (va_arg(args, builder_part_t))
                    620:                {
                    621:                        case BUILD_BLOB_ASN1_DER:
                    622:                                blob = va_arg(args, chunk_t);
                    623:                                continue;
                    624:                        case BUILD_END:
                    625:                                break;
                    626:                        default:
                    627:                                return NULL;
                    628:                }
                    629:                break;
                    630:        }
                    631: 
                    632:        if (blob.ptr)
                    633:        {
                    634:                private_x509_pkcs10_t *cert = create_empty();
                    635: 
                    636:                cert->encoding = chunk_clone(blob);
                    637:                cert->parsed = TRUE;
                    638:                if (parse_certificate_request(cert))
                    639:                {
                    640:                        return &cert->public;
                    641:                }
                    642:                destroy(cert);
                    643:        }
                    644:        return NULL;
                    645: }
                    646: 
                    647: /**
                    648:  * See header.
                    649:  */
                    650: x509_pkcs10_t *x509_pkcs10_gen(certificate_type_t type, va_list args)
                    651: {
                    652:        private_x509_pkcs10_t *cert;
                    653:        private_key_t *sign_key = NULL;
                    654:        hash_algorithm_t digest_alg = HASH_SHA1;
                    655: 
                    656:        cert = create_empty();
                    657:        while (TRUE)
                    658:        {
                    659:                switch (va_arg(args, builder_part_t))
                    660:                {
                    661:                        case BUILD_SIGNING_KEY:
                    662:                                sign_key = va_arg(args, private_key_t*);
                    663:                                continue;
                    664:                        case BUILD_SUBJECT:
                    665:                                cert->subject = va_arg(args, identification_t*);
                    666:                                cert->subject = cert->subject->clone(cert->subject);
                    667:                                continue;
                    668:                        case BUILD_SUBJECT_ALTNAMES:
                    669:                        {
                    670:                                enumerator_t *enumerator;
                    671:                                identification_t *id;
                    672:                                linked_list_t *list;
                    673: 
                    674:                                list = va_arg(args, linked_list_t*);
                    675:                                enumerator = list->create_enumerator(list);
                    676:                                while (enumerator->enumerate(enumerator, &id))
                    677:                                {
                    678:                                        cert->subjectAltNames->insert_last(cert->subjectAltNames,
                    679:                                                                                                           id->clone(id));
                    680:                                }
                    681:                                enumerator->destroy(enumerator);
                    682:                                continue;
                    683:                        }
                    684:                        case BUILD_CHALLENGE_PWD:
                    685:                                cert->challengePassword = chunk_clone(va_arg(args, chunk_t));
                    686:                                continue;
                    687:                        case BUILD_SIGNATURE_SCHEME:
                    688:                                cert->scheme = va_arg(args, signature_params_t*);
                    689:                                cert->scheme = signature_params_clone(cert->scheme);
                    690:                                continue;
                    691:                        case BUILD_DIGEST_ALG:
                    692:                                digest_alg = va_arg(args, int);
                    693:                                continue;
                    694:                        case BUILD_END:
                    695:                                break;
                    696:                        default:
                    697:                                destroy(cert);
                    698:                                return NULL;
                    699:                }
                    700:                break;
                    701:        }
                    702: 
                    703:        if (sign_key && generate(cert, sign_key, digest_alg))
                    704:        {
                    705:                return &cert->public;
                    706:        }
                    707:        destroy(cert);
                    708:        return NULL;
                    709: }
                    710: 

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