Annotation of embedaddon/strongswan/src/libstrongswan/plugins/openssl/openssl_x509.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2011-2017 Tobias Brunner
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * Copyright (C) 2010 Martin Willi
                      6:  * Copyright (C) 2010 revosec AG
                      7:  *
                      8:  * This program is free software; you can redistribute it and/or modify it
                      9:  * under the terms of the GNU General Public License as published by the
                     10:  * Free Software Foundation; either version 2 of the License, or (at your
                     11:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     12:  *
                     13:  * This program is distributed in the hope that it will be useful, but
                     14:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     15:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     16:  * for more details.
                     17:  */
                     18: 
                     19: /*
                     20:  * Copyright (C) 2013 Michael Rossberg
                     21:  * Copyright (C) 2013 Technische Universität Ilmenau
                     22:  *
                     23:  * Copyright (C) 2010 secunet Security Networks AG
                     24:  * Copyright (C) 2010 Thomas Egerer
                     25:  *
                     26:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                     27:  * of this software and associated documentation files (the "Software"), to deal
                     28:  * in the Software without restriction, including without limitation the rights
                     29:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     30:  * copies of the Software, and to permit persons to whom the Software is
                     31:  * furnished to do so, subject to the following conditions:
                     32:  *
                     33:  * The above copyright notice and this permission notice shall be included in
                     34:  * all copies or substantial portions of the Software.
                     35:  *
                     36:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     37:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     38:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
                     39:  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     40:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     41:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     42:  * THE SOFTWARE.
                     43:  */
                     44: 
                     45: #define _GNU_SOURCE
                     46: #include <stdio.h>
                     47: #include <openssl/x509.h>
                     48: #include <openssl/x509v3.h>
                     49: 
                     50: #include "openssl_x509.h"
                     51: #include "openssl_util.h"
                     52: 
                     53: #include <utils/debug.h>
                     54: #include <asn1/oid.h>
                     55: #include <collections/linked_list.h>
                     56: #include <selectors/traffic_selector.h>
                     57: 
                     58: /* IP Addr block extension support was introduced with 0.9.8e */
                     59: #if OPENSSL_VERSION_NUMBER < 0x0090805fL
                     60: #define OPENSSL_NO_RFC3779
                     61: #endif
                     62: 
                     63: /* added with 1.0.2 */
                     64: #if OPENSSL_VERSION_NUMBER < 0x10002000L
                     65: static inline void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, const X509 *x) {
                     66:        if (psig) { *psig = x->signature; }
                     67:        if (palg) { *palg = x->sig_alg; }
                     68: }
                     69: #endif
                     70: 
                     71: /* added with 1.1.0 when X509 etc. was made opaque */
                     72: #if OPENSSL_VERSION_NUMBER < 0x10100000L
                     73: #define X509_get0_extensions(x509) ({ (x509)->cert_info->extensions; })
                     74: #define X509_get0_tbs_sigalg(x509) ({ (x509)->cert_info->signature; })
                     75: #define X509_ALGOR_get0(oid, ppt, ppv, alg) ({ *(oid) = (alg)->algorithm; })
                     76: #define X509_PUBKEY_get0_param(oid, pk, len, pa, pub) X509_ALGOR_get0(oid, NULL, NULL, (pub)->algor)
                     77: #define X509v3_addr_get_afi v3_addr_get_afi
                     78: #define X509v3_addr_get_range v3_addr_get_range
                     79: #define X509v3_addr_is_canonical v3_addr_is_canonical
                     80: #define X509_get0_notBefore X509_get_notBefore
                     81: #define X509_get0_notAfter X509_get_notAfter
                     82: #endif
                     83: 
                     84: typedef struct private_openssl_x509_t private_openssl_x509_t;
                     85: 
                     86: /**
                     87:  * Private data of an openssl_x509_t object.
                     88:  */
                     89: struct private_openssl_x509_t {
                     90: 
                     91:        /**
                     92:         * Public openssl_x509_t interface.
                     93:         */
                     94:        openssl_x509_t public;
                     95: 
                     96:        /**
                     97:         * OpenSSL certificate representation
                     98:         */
                     99:        X509 *x509;
                    100: 
                    101:        /**
                    102:         * DER encoded certificate
                    103:         */
                    104:        chunk_t encoding;
                    105: 
                    106:        /**
                    107:         * SHA1 hash of the certificate
                    108:         */
                    109:        chunk_t hash;
                    110: 
                    111:        /**
                    112:         * X509 flags
                    113:         */
                    114:        x509_flag_t flags;
                    115: 
                    116:        /**
                    117:         * Pathlen constraint
                    118:         */
                    119:        u_char pathlen;
                    120: 
                    121:        /**
                    122:         * certificate subject
                    123:         */
                    124:        identification_t *subject;
                    125: 
                    126:        /**
                    127:         * certificate issuer
                    128:         */
                    129:        identification_t *issuer;
                    130: 
                    131:        /**
                    132:         * Certificates public key
                    133:         */
                    134:        public_key_t *pubkey;
                    135: 
                    136:        /**
                    137:         * subjectKeyIdentifier as read from cert
                    138:         */
                    139:        chunk_t subjectKeyIdentifier;
                    140: 
                    141:        /**
                    142:         * authorityKeyIdentifier as read from cert
                    143:         */
                    144:        chunk_t authKeyIdentifier;
                    145: 
                    146:        /**
                    147:         * Start time of certificate validity
                    148:         */
                    149:        time_t notBefore;
                    150: 
                    151:        /**
                    152:         * End time of certificate validity
                    153:         */
                    154:        time_t notAfter;
                    155: 
                    156:        /**
                    157:         * Signature scheme of the certificate
                    158:         */
                    159:        signature_params_t *scheme;
                    160: 
                    161:        /**
                    162:         * subjectAltNames
                    163:         */
                    164:        linked_list_t *subjectAltNames;
                    165: 
                    166:        /**
                    167:         * issuerAltNames
                    168:         */
                    169:        linked_list_t *issuerAltNames;
                    170: 
                    171:        /**
                    172:         * List of CRL URIs, as x509_cdp_t
                    173:         */
                    174:        linked_list_t *crl_uris;
                    175: 
                    176:        /**
                    177:         * List of OCSP URIs
                    178:         */
                    179:        linked_list_t *ocsp_uris;
                    180: 
                    181:        /**
                    182:         * List of ipAddrBlocks as traffic_selector_t
                    183:         */
                    184:        linked_list_t *ipAddrBlocks;
                    185: 
                    186: 
                    187:        /**
                    188:         * References to this cert
                    189:         */
                    190:        refcount_t ref;
                    191: };
                    192: 
                    193: /**
                    194:  * Convert a GeneralName to an identification_t.
                    195:  */
                    196: static identification_t *general_name2id(GENERAL_NAME *name)
                    197: {
                    198:        if (!name)
                    199:        {
                    200:                return NULL;
                    201:        }
                    202:        switch (name->type)
                    203:        {
                    204:                case GEN_EMAIL:
                    205:                        return identification_create_from_encoding(ID_RFC822_ADDR,
                    206:                                        openssl_asn1_str2chunk(name->d.rfc822Name));
                    207:                case GEN_DNS:
                    208:                        return identification_create_from_encoding(ID_FQDN,
                    209:                                        openssl_asn1_str2chunk(name->d.dNSName));
                    210:                case GEN_URI:
                    211:                        return identification_create_from_encoding(ID_DER_ASN1_GN_URI,
                    212:                                        openssl_asn1_str2chunk(name->d.uniformResourceIdentifier));
                    213:                case GEN_IPADD:
                    214:                {
                    215:                        chunk_t chunk = openssl_asn1_str2chunk(name->d.iPAddress);
                    216:                        if (chunk.len == 4)
                    217:                        {
                    218:                                return identification_create_from_encoding(ID_IPV4_ADDR, chunk);
                    219:                        }
                    220:                        if (chunk.len == 16)
                    221:                        {
                    222:                                return identification_create_from_encoding(ID_IPV6_ADDR, chunk);
                    223:                        }
                    224:                        return NULL;
                    225:                }
                    226:                case GEN_DIRNAME :
                    227:                        return openssl_x509_name2id(name->d.directoryName);
                    228:                case GEN_OTHERNAME:
                    229:                        if (OBJ_obj2nid(name->d.otherName->type_id) == NID_ms_upn &&
                    230:                                name->d.otherName->value->type == V_ASN1_UTF8STRING)
                    231:                        {
                    232:                                return identification_create_from_encoding(ID_RFC822_ADDR,
                    233:                                                        openssl_asn1_str2chunk(
                    234:                                                                name->d.otherName->value->value.utf8string));
                    235:                        }
                    236:                        return NULL;
                    237:                default:
                    238:                        return NULL;
                    239:        }
                    240: }
                    241: 
                    242: METHOD(x509_t, get_flags, x509_flag_t,
                    243:        private_openssl_x509_t *this)
                    244: {
                    245:        return this->flags;
                    246: }
                    247: 
                    248: METHOD(x509_t, get_serial, chunk_t,
                    249:        private_openssl_x509_t *this)
                    250: {
                    251:        return openssl_asn1_str2chunk(X509_get_serialNumber(this->x509));
                    252: }
                    253: 
                    254: METHOD(x509_t, get_subjectKeyIdentifier, chunk_t,
                    255:        private_openssl_x509_t *this)
                    256: {
                    257:        chunk_t fingerprint;
                    258: 
                    259:        if (this->subjectKeyIdentifier.len)
                    260:        {
                    261:                return this->subjectKeyIdentifier;
                    262:        }
                    263:        if (this->pubkey->get_fingerprint(this->pubkey, KEYID_PUBKEY_SHA1,
                    264:                                                                          &fingerprint))
                    265:        {
                    266:                return fingerprint;
                    267:        }
                    268:        return chunk_empty;
                    269: }
                    270: 
                    271: METHOD(x509_t, get_authKeyIdentifier, chunk_t,
                    272:        private_openssl_x509_t *this)
                    273: {
                    274:        if (this->authKeyIdentifier.len)
                    275:        {
                    276:                return this->authKeyIdentifier;
                    277:        }
                    278:        return chunk_empty;
                    279: }
                    280: 
                    281: METHOD(x509_t, get_constraint, u_int,
                    282:        private_openssl_x509_t *this, x509_constraint_t type)
                    283: {
                    284:        switch (type)
                    285:        {
                    286:                case X509_PATH_LEN:
                    287:                        return this->pathlen;
                    288:                default:
                    289:                        return X509_NO_CONSTRAINT;
                    290:        }
                    291: }
                    292: 
                    293: METHOD(x509_t, create_subjectAltName_enumerator, enumerator_t*,
                    294:        private_openssl_x509_t *this)
                    295: {
                    296:        return this->subjectAltNames->create_enumerator(this->subjectAltNames);
                    297: }
                    298: 
                    299: METHOD(x509_t, create_crl_uri_enumerator, enumerator_t*,
                    300:        private_openssl_x509_t *this)
                    301: {
                    302:        return this->crl_uris->create_enumerator(this->crl_uris);
                    303: }
                    304: 
                    305: METHOD(x509_t, create_ocsp_uri_enumerator, enumerator_t*,
                    306:        private_openssl_x509_t *this)
                    307: {
                    308:        return this->ocsp_uris->create_enumerator(this->ocsp_uris);
                    309: }
                    310: 
                    311: METHOD(x509_t, create_ipAddrBlock_enumerator, enumerator_t*,
                    312:        private_openssl_x509_t *this)
                    313: {
                    314:        return this->ipAddrBlocks->create_enumerator(this->ipAddrBlocks);
                    315: }
                    316: 
                    317: METHOD(certificate_t, get_type, certificate_type_t,
                    318:        private_openssl_x509_t *this)
                    319: {
                    320:        return CERT_X509;
                    321: }
                    322: 
                    323: METHOD(certificate_t, get_subject, identification_t*,
                    324:        private_openssl_x509_t *this)
                    325: {
                    326:        return this->subject;
                    327: }
                    328: 
                    329: METHOD(certificate_t, get_issuer, identification_t*,
                    330:        private_openssl_x509_t *this)
                    331: {
                    332:        return this->issuer;
                    333: }
                    334: 
                    335: METHOD(certificate_t, has_subject, id_match_t,
                    336:        private_openssl_x509_t *this, identification_t *subject)
                    337: {
                    338:        identification_t *current;
                    339:        enumerator_t *enumerator;
                    340:        id_match_t match, best;
                    341:        chunk_t encoding;
                    342: 
                    343:        if (subject->get_type(subject) == ID_KEY_ID)
                    344:        {
                    345:                encoding = subject->get_encoding(subject);
                    346: 
                    347:                if (chunk_equals(this->hash, encoding))
                    348:                {
                    349:                        return ID_MATCH_PERFECT;
                    350:                }
                    351:                if (this->subjectKeyIdentifier.len &&
                    352:                        chunk_equals(this->subjectKeyIdentifier, encoding))
                    353:                {
                    354:                        return ID_MATCH_PERFECT;
                    355:                }
                    356:                if (this->pubkey &&
                    357:                        this->pubkey->has_fingerprint(this->pubkey, encoding))
                    358:                {
                    359:                        return ID_MATCH_PERFECT;
                    360:                }
                    361:                if (chunk_equals(get_serial(this), encoding))
                    362:                {
                    363:                        return ID_MATCH_PERFECT;
                    364:                }
                    365:        }
                    366:        best = this->subject->matches(this->subject, subject);
                    367:        enumerator = create_subjectAltName_enumerator(this);
                    368:        while (enumerator->enumerate(enumerator, &current))
                    369:        {
                    370:                match = current->matches(current, subject);
                    371:                if (match > best)
                    372:                {
                    373:                        best = match;
                    374:                }
                    375:        }
                    376:        enumerator->destroy(enumerator);
                    377:        return best;
                    378: }
                    379: 
                    380: METHOD(certificate_t, has_issuer, id_match_t,
                    381:        private_openssl_x509_t *this, identification_t *issuer)
                    382: {
                    383:        /* issuerAltNames currently not supported */
                    384:        return this->issuer->matches(this->issuer, issuer);
                    385: }
                    386: 
                    387: METHOD(certificate_t, issued_by, bool,
                    388:        private_openssl_x509_t *this, certificate_t *issuer,
                    389:        signature_params_t **scheme)
                    390: {
                    391:        public_key_t *key;
                    392:        bool valid;
                    393:        x509_t *x509 = (x509_t*)issuer;
                    394: #if OPENSSL_VERSION_NUMBER >= 0x10100000L
                    395:        const ASN1_BIT_STRING *sig;
                    396: #else
                    397:        ASN1_BIT_STRING *sig;
                    398: #endif
                    399:        chunk_t tbs;
                    400: 
                    401:        if (&this->public.x509.interface == issuer)
                    402:        {
                    403:                if (this->flags & X509_SELF_SIGNED)
                    404:                {
                    405:                        valid = TRUE;
                    406:                        goto out;
                    407:                }
                    408:        }
                    409:        else
                    410:        {
                    411:                if (issuer->get_type(issuer) != CERT_X509)
                    412:                {
                    413:                        return FALSE;
                    414:                }
                    415:                if (!(x509->get_flags(x509) & X509_CA))
                    416:                {
                    417:                        return FALSE;
                    418:                }
                    419:        }
                    420:        if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
                    421:        {
                    422:                return FALSE;
                    423:        }
                    424:        key = issuer->get_public_key(issuer);
                    425:        if (!key)
                    426:        {
                    427:                return FALSE;
                    428:        }
                    429:        /* i2d_re_X509_tbs() was added with 1.1.0 when X509 was made opaque */
                    430: #if OPENSSL_VERSION_NUMBER >= 0x10100000L
                    431:        tbs = openssl_i2chunk(re_X509_tbs, this->x509);
                    432: #else
                    433:        tbs = openssl_i2chunk(X509_CINF, this->x509->cert_info);
                    434: #endif
                    435:        X509_get0_signature(&sig, NULL, this->x509);
                    436:        valid = key->verify(key, this->scheme->scheme, this->scheme->params, tbs,
                    437:                                                openssl_asn1_str2chunk(sig));
                    438:        free(tbs.ptr);
                    439:        key->destroy(key);
                    440: 
                    441: out:
                    442:        if (valid && scheme)
                    443:        {
                    444:                *scheme = signature_params_clone(this->scheme);
                    445:        }
                    446:        return valid;
                    447: }
                    448: 
                    449: METHOD(certificate_t, get_public_key, public_key_t*,
                    450:        private_openssl_x509_t *this)
                    451: {
                    452:        return this->pubkey->get_ref(this->pubkey);
                    453: }
                    454: 
                    455: METHOD(certificate_t, get_validity, bool,
                    456:        private_openssl_x509_t *this,
                    457:        time_t *when, time_t *not_before, time_t *not_after)
                    458: {
                    459:        time_t t;
                    460: 
                    461:        if (when)
                    462:        {
                    463:                t = *when;
                    464:        }
                    465:        else
                    466:        {
                    467:                t = time(NULL);
                    468:        }
                    469:        if (not_before)
                    470:        {
                    471:                *not_before = this->notBefore;
                    472:        }
                    473:        if (not_after)
                    474:        {
                    475:                *not_after = this->notAfter;
                    476:        }
                    477:        return (t >= this->notBefore && t <= this->notAfter);
                    478: }
                    479: 
                    480: METHOD(certificate_t, get_encoding, bool,
                    481:        private_openssl_x509_t *this, cred_encoding_type_t type, chunk_t *encoding)
                    482: {
                    483:        if (type == CERT_ASN1_DER)
                    484:        {
                    485:                *encoding = chunk_clone(this->encoding);
                    486:                return TRUE;
                    487:        }
                    488:        return lib->encoding->encode(lib->encoding, type, NULL, encoding,
                    489:                                                CRED_PART_X509_ASN1_DER, this->encoding, CRED_PART_END);
                    490: }
                    491: 
                    492: 
                    493: METHOD(certificate_t, equals, bool,
                    494:        private_openssl_x509_t *this, certificate_t *other)
                    495: {
                    496:        chunk_t encoding;
                    497:        bool equal;
                    498: 
                    499:        if (this == (private_openssl_x509_t*)other)
                    500:        {
                    501:                return TRUE;
                    502:        }
                    503:        if (other->get_type(other) != CERT_X509)
                    504:        {
                    505:                return FALSE;
                    506:        }
                    507:        if (other->equals == (void*)equals)
                    508:        {       /* skip allocation if we have the same implementation */
                    509:                encoding = ((private_openssl_x509_t*)other)->encoding;
                    510:                return chunk_equals(this->encoding, encoding);
                    511:        }
                    512:        if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
                    513:        {
                    514:                return FALSE;
                    515:        }
                    516:        equal = chunk_equals(this->encoding, encoding);
                    517:        free(encoding.ptr);
                    518:        return equal;
                    519: }
                    520: 
                    521: METHOD(certificate_t, get_ref, certificate_t*,
                    522:        private_openssl_x509_t *this)
                    523: {
                    524:        ref_get(&this->ref);
                    525:        return &this->public.x509.interface;
                    526: }
                    527: 
                    528: METHOD(certificate_t, destroy, void,
                    529:        private_openssl_x509_t *this)
                    530: {
                    531:        if (ref_put(&this->ref))
                    532:        {
                    533:                if (this->x509)
                    534:                {
                    535:                        X509_free(this->x509);
                    536:                }
                    537:                signature_params_destroy(this->scheme);
                    538:                DESTROY_IF(this->subject);
                    539:                DESTROY_IF(this->issuer);
                    540:                DESTROY_IF(this->pubkey);
                    541:                free(this->subjectKeyIdentifier.ptr);
                    542:                free(this->authKeyIdentifier.ptr);
                    543:                free(this->encoding.ptr);
                    544:                free(this->hash.ptr);
                    545:                this->subjectAltNames->destroy_offset(this->subjectAltNames,
                    546:                                                                                offsetof(identification_t, destroy));
                    547:                this->issuerAltNames->destroy_offset(this->issuerAltNames,
                    548:                                                                                offsetof(identification_t, destroy));
                    549:                this->crl_uris->destroy_function(this->crl_uris,
                    550:                                                                                 (void*)x509_cdp_destroy);
                    551:                this->ocsp_uris->destroy_function(this->ocsp_uris, free);
                    552:                this->ipAddrBlocks->destroy_offset(this->ipAddrBlocks,
                    553:                                                                                offsetof(traffic_selector_t, destroy));
                    554:                free(this);
                    555:        }
                    556: }
                    557: 
                    558: /**
                    559:  * Create an empty certificate
                    560:  */
                    561: static private_openssl_x509_t *create_empty()
                    562: {
                    563:        private_openssl_x509_t *this;
                    564: 
                    565:        INIT(this,
                    566:                .public = {
                    567:                        .x509 = {
                    568:                                .interface = {
                    569:                                        .get_type = _get_type,
                    570:                                        .get_subject = _get_subject,
                    571:                                        .get_issuer = _get_issuer,
                    572:                                        .has_subject = _has_subject,
                    573:                                        .has_issuer = _has_issuer,
                    574:                                        .issued_by = _issued_by,
                    575:                                        .get_public_key = _get_public_key,
                    576:                                        .get_validity = _get_validity,
                    577:                                        .get_encoding = _get_encoding,
                    578:                                        .equals = _equals,
                    579:                                        .get_ref = _get_ref,
                    580:                                        .destroy = _destroy,
                    581:                                },
                    582:                                .get_flags = _get_flags,
                    583:                                .get_serial = _get_serial,
                    584:                                .get_subjectKeyIdentifier = _get_subjectKeyIdentifier,
                    585:                                .get_authKeyIdentifier = _get_authKeyIdentifier,
                    586:                                .get_constraint = _get_constraint,
                    587:                                .create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
                    588:                                .create_crl_uri_enumerator = _create_crl_uri_enumerator,
                    589:                                .create_ocsp_uri_enumerator = _create_ocsp_uri_enumerator,
                    590:                                .create_ipAddrBlock_enumerator = _create_ipAddrBlock_enumerator,
                    591:                                .create_name_constraint_enumerator = (void*)enumerator_create_empty,
                    592:                                .create_cert_policy_enumerator = (void*)enumerator_create_empty,
                    593:                                .create_policy_mapping_enumerator = (void*)enumerator_create_empty,
                    594:                        },
                    595:                },
                    596:                .subjectAltNames = linked_list_create(),
                    597:                .issuerAltNames = linked_list_create(),
                    598:                .crl_uris = linked_list_create(),
                    599:                .ocsp_uris = linked_list_create(),
                    600:                .ipAddrBlocks = linked_list_create(),
                    601:                .pathlen = X509_NO_CONSTRAINT,
                    602:                .ref = 1,
                    603:        );
                    604: 
                    605:        return this;
                    606: }
                    607: 
                    608: /**
                    609:  * parse an extension containing GENERAL_NAMES into a list
                    610:  */
                    611: static bool parse_generalNames_ext(linked_list_t *list,
                    612:                                                                   X509_EXTENSION *ext)
                    613: {
                    614:        GENERAL_NAMES *names;
                    615:        GENERAL_NAME *name;
                    616:        identification_t *id;
                    617:        int i, num;
                    618: 
                    619:        names = X509V3_EXT_d2i(ext);
                    620:        if (!names)
                    621:        {
                    622:                return FALSE;
                    623:        }
                    624: 
                    625:        num = sk_GENERAL_NAME_num(names);
                    626:        for (i = 0; i < num; i++)
                    627:        {
                    628:                name = sk_GENERAL_NAME_value(names, i);
                    629:                id = general_name2id(name);
                    630:                if (id)
                    631:                {
                    632:                        list->insert_last(list, id);
                    633:                }
                    634:                GENERAL_NAME_free(name);
                    635:        }
                    636:        sk_GENERAL_NAME_free(names);
                    637:        return TRUE;
                    638: }
                    639: 
                    640: /**
                    641:  * parse basic constraints
                    642:  */
                    643: static bool parse_basicConstraints_ext(private_openssl_x509_t *this,
                    644:                                                                           X509_EXTENSION *ext)
                    645: {
                    646:        BASIC_CONSTRAINTS *constraints;
                    647:        long pathlen;
                    648: 
                    649:        constraints = (BASIC_CONSTRAINTS*)X509V3_EXT_d2i(ext);
                    650:        if (constraints)
                    651:        {
                    652:                if (constraints->ca)
                    653:                {
                    654:                        this->flags |= X509_CA;
                    655:                }
                    656:                if (constraints->pathlen)
                    657:                {
                    658: 
                    659:                        pathlen = ASN1_INTEGER_get(constraints->pathlen);
                    660:                        this->pathlen = (pathlen >= 0 && pathlen < 128) ?
                    661:                                                         pathlen : X509_NO_CONSTRAINT;
                    662:                }
                    663:                BASIC_CONSTRAINTS_free(constraints);
                    664:                return TRUE;
                    665:        }
                    666:        return FALSE;
                    667: }
                    668: 
                    669: /**
                    670:  * parse key usage
                    671:  */
                    672: static bool parse_keyUsage_ext(private_openssl_x509_t *this,
                    673:                                                           X509_EXTENSION *ext)
                    674: {
                    675:        ASN1_BIT_STRING *usage;
                    676: 
                    677:        /* to be compliant with RFC 4945 specific KUs have to be included */
                    678:        this->flags &= ~X509_IKE_COMPLIANT;
                    679: 
                    680:        usage = X509V3_EXT_d2i(ext);
                    681:        if (usage)
                    682:        {
                    683:                if (usage->length > 0)
                    684:                {
                    685:                        int flags = usage->data[0];
                    686:                        if (usage->length > 1)
                    687:                        {
                    688:                                flags |= usage->data[1] << 8;
                    689:                        }
                    690:                        if (flags & X509v3_KU_CRL_SIGN)
                    691:                        {
                    692:                                this->flags |= X509_CRL_SIGN;
                    693:                        }
                    694:                        if (flags & X509v3_KU_DIGITAL_SIGNATURE ||
                    695:                                flags & X509v3_KU_NON_REPUDIATION)
                    696:                        {
                    697:                                this->flags |= X509_IKE_COMPLIANT;
                    698:                        }
                    699:                        if (flags & X509v3_KU_KEY_CERT_SIGN)
                    700:                        {
                    701:                                /* we use the caBasicConstraint, MUST be set */
                    702:                        }
                    703:                }
                    704:                ASN1_BIT_STRING_free(usage);
                    705:                return TRUE;
                    706:        }
                    707:        return FALSE;
                    708: }
                    709: 
                    710: /**
                    711:  * Parse ExtendedKeyUsage
                    712:  */
                    713: static bool parse_extKeyUsage_ext(private_openssl_x509_t *this,
                    714:                                                                  X509_EXTENSION *ext)
                    715: {
                    716:        EXTENDED_KEY_USAGE *usage;
                    717:        int i;
                    718: 
                    719:        usage = X509V3_EXT_d2i(ext);
                    720:        if (usage)
                    721:        {
                    722:                for (i = 0; i < sk_ASN1_OBJECT_num(usage); i++)
                    723:                {
                    724:                        switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(usage, i)))
                    725:                        {
                    726:                                case NID_server_auth:
                    727:                                        this->flags |= X509_SERVER_AUTH;
                    728:                                        break;
                    729:                                case NID_client_auth:
                    730:                                        this->flags |= X509_CLIENT_AUTH;
                    731:                                        break;
                    732:                                case NID_OCSP_sign:
                    733:                                        this->flags |= X509_OCSP_SIGNER;
                    734:                                        break;
                    735:                                default:
                    736:                                        break;
                    737:                        }
                    738:                }
                    739:                sk_ASN1_OBJECT_pop_free(usage, ASN1_OBJECT_free);
                    740:                return TRUE;
                    741:        }
                    742:        return FALSE;
                    743: }
                    744: 
                    745: /**
                    746:  * Parse CRL distribution points
                    747:  */
                    748: bool openssl_parse_crlDistributionPoints(X509_EXTENSION *ext,
                    749:                                                                                 linked_list_t *list)
                    750: {
                    751:        CRL_DIST_POINTS *cdps;
                    752:        DIST_POINT *cdp;
                    753:        identification_t *id, *issuer;
                    754:        x509_cdp_t *entry;
                    755:        char *uri;
                    756:        int i, j, k, point_num, name_num, issuer_num, len;
                    757: 
                    758:        cdps = X509V3_EXT_d2i(ext);
                    759:        if (!cdps)
                    760:        {
                    761:                return FALSE;
                    762:        }
                    763:        point_num = sk_DIST_POINT_num(cdps);
                    764:        for (i = 0; i < point_num; i++)
                    765:        {
                    766:                cdp = sk_DIST_POINT_value(cdps, i);
                    767:                if (cdp)
                    768:                {
                    769:                        if (cdp->distpoint && cdp->distpoint->type == 0 &&
                    770:                                cdp->distpoint->name.fullname)
                    771:                        {
                    772:                                name_num = sk_GENERAL_NAME_num(cdp->distpoint->name.fullname);
                    773:                                for (j = 0; j < name_num; j++)
                    774:                                {
                    775:                                        id = general_name2id(sk_GENERAL_NAME_value(
                    776:                                                                                        cdp->distpoint->name.fullname, j));
                    777:                                        if (id)
                    778:                                        {
                    779:                                                len = asprintf(&uri, "%Y", id);
                    780:                                                if (!len)
                    781:                                                {
                    782:                                                        free(uri);
                    783:                                                }
                    784:                                                else if (len > 0)
                    785:                                                {
                    786:                                                        if (cdp->CRLissuer)
                    787:                                                        {
                    788:                                                                issuer_num = sk_GENERAL_NAME_num(cdp->CRLissuer);
                    789:                                                                for (k = 0; k < issuer_num; k++)
                    790:                                                                {
                    791:                                                                        issuer = general_name2id(
                    792:                                                                                sk_GENERAL_NAME_value(cdp->CRLissuer, k));
                    793:                                                                        if (issuer)
                    794:                                                                        {
                    795:                                                                                INIT(entry,
                    796:                                                                                        .uri = strdup(uri),
                    797:                                                                                        .issuer = issuer,
                    798:                                                                                );
                    799:                                                                                list->insert_last(list, entry);
                    800:                                                                        }
                    801:                                                                }
                    802:                                                                free(uri);
                    803:                                                        }
                    804:                                                        else
                    805:                                                        {
                    806:                                                                INIT(entry,
                    807:                                                                        .uri = uri,
                    808:                                                                );
                    809:                                                                list->insert_last(list, entry);
                    810:                                                        }
                    811:                                                }
                    812:                                                id->destroy(id);
                    813:                                        }
                    814:                                }
                    815:                        }
                    816: 
                    817:                        DIST_POINT_free(cdp);
                    818:                }
                    819:        }
                    820:        sk_DIST_POINT_free(cdps);
                    821:        return TRUE;
                    822: }
                    823: 
                    824: /**
                    825:  * Parse authorityInfoAccess with OCSP URIs
                    826:  */
                    827: static bool parse_authorityInfoAccess_ext(private_openssl_x509_t *this,
                    828:                                                                                  X509_EXTENSION *ext)
                    829: {
                    830:        AUTHORITY_INFO_ACCESS *infos;
                    831:        ACCESS_DESCRIPTION *desc;
                    832:        identification_t *id;
                    833:        int i, num, len;
                    834:        char *uri;
                    835: 
                    836:        infos = X509V3_EXT_d2i(ext);
                    837:        if (!infos)
                    838:        {
                    839:                return FALSE;
                    840:        }
                    841:        num = sk_ACCESS_DESCRIPTION_num(infos);
                    842:        for (i = 0; i < num; i++)
                    843:        {
                    844:                desc = sk_ACCESS_DESCRIPTION_value(infos, i);
                    845:                if (desc)
                    846:                {
                    847:                        if (openssl_asn1_known_oid(desc->method) == OID_OCSP)
                    848:                        {
                    849:                                id = general_name2id(desc->location);
                    850:                                if (id)
                    851:                                {
                    852:                                        len = asprintf(&uri, "%Y", id);
                    853:                                        if (!len)
                    854:                                        {
                    855:                                                free(uri);
                    856:                                        }
                    857:                                        else if (len > 0)
                    858:                                        {
                    859:                                                this->ocsp_uris->insert_last(this->ocsp_uris, uri);
                    860:                                        }
                    861:                                        id->destroy(id);
                    862:                                }
                    863:                        }
                    864:                        ACCESS_DESCRIPTION_free(desc);
                    865:                }
                    866:        }
                    867:        sk_ACCESS_DESCRIPTION_free(infos);
                    868:        return TRUE;
                    869: }
                    870: 
                    871: #ifndef OPENSSL_NO_RFC3779
                    872: 
                    873: /**
                    874:  * Parse a single block of ipAddrBlock extension
                    875:  */
                    876: static void parse_ipAddrBlock_ext_fam(private_openssl_x509_t *this,
                    877:                                                                          IPAddressFamily *fam)
                    878: {
                    879:        const IPAddressOrRanges *list;
                    880:        IPAddressOrRange *aor;
                    881:        traffic_selector_t *ts;
                    882:        ts_type_t type;
                    883:        chunk_t from, to;
                    884:        int i, afi;
                    885: 
                    886:        if (fam->ipAddressChoice->type != IPAddressChoice_addressesOrRanges)
                    887:        {
                    888:                return;
                    889:        }
                    890: 
                    891:        afi = X509v3_addr_get_afi(fam);
                    892:        switch (afi)
                    893:        {
                    894:                case IANA_AFI_IPV4:
                    895:                        from = chunk_alloca(4);
                    896:                        to = chunk_alloca(4);
                    897:                        type = TS_IPV4_ADDR_RANGE;
                    898:                        break;
                    899:                case IANA_AFI_IPV6:
                    900:                        from = chunk_alloca(16);
                    901:                        to = chunk_alloca(16);
                    902:                        type = TS_IPV6_ADDR_RANGE;
                    903:                        break;
                    904:                default:
                    905:                        return;
                    906:        }
                    907: 
                    908:        list = fam->ipAddressChoice->u.addressesOrRanges;
                    909:        for (i = 0; i < sk_IPAddressOrRange_num(list); i++)
                    910:        {
                    911:                aor = sk_IPAddressOrRange_value(list, i);
                    912:                if (X509v3_addr_get_range(aor, afi, from.ptr, to.ptr, from.len) > 0)
                    913:                {
                    914:                        ts = traffic_selector_create_from_bytes(0, type, from, 0, to, 65535);
                    915:                        if (ts)
                    916:                        {
                    917:                                this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts);
                    918:                        }
                    919:                }
                    920:        }
                    921: }
                    922: 
                    923: /**
                    924:  * Parse ipAddrBlock extension
                    925:  */
                    926: static bool parse_ipAddrBlock_ext(private_openssl_x509_t *this,
                    927:                                                                  X509_EXTENSION *ext)
                    928: {
                    929:        STACK_OF(IPAddressFamily) *blocks;
                    930:        IPAddressFamily *fam;
                    931: 
                    932:        blocks = (STACK_OF(IPAddressFamily)*)X509V3_EXT_d2i(ext);
                    933:        if (!blocks)
                    934:        {
                    935:                return FALSE;
                    936:        }
                    937: 
                    938:        if (!X509v3_addr_is_canonical(blocks))
                    939:        {
                    940:                sk_IPAddressFamily_free(blocks);
                    941:                return FALSE;
                    942:        }
                    943: 
                    944:        while (sk_IPAddressFamily_num(blocks) > 0)
                    945:        {
                    946:                fam = sk_IPAddressFamily_pop(blocks);
                    947:                parse_ipAddrBlock_ext_fam(this, fam);
                    948:                IPAddressFamily_free(fam);
                    949:        }
                    950:        sk_IPAddressFamily_free(blocks);
                    951: 
                    952:        this->flags |= X509_IP_ADDR_BLOCKS;
                    953:        return TRUE;
                    954: }
                    955: #endif /* !OPENSSL_NO_RFC3779 */
                    956: 
                    957: /**
                    958:  * Parse authorityKeyIdentifier extension
                    959:  */
                    960: static bool parse_authKeyIdentifier_ext(private_openssl_x509_t *this,
                    961:                                                                                X509_EXTENSION *ext)
                    962: {
                    963:        AUTHORITY_KEYID *keyid;
                    964: 
                    965:        keyid = (AUTHORITY_KEYID*)X509V3_EXT_d2i(ext);
                    966:        if (keyid)
                    967:        {
                    968:                free(this->authKeyIdentifier.ptr);
                    969:                this->authKeyIdentifier = chunk_clone(
                    970:                                                                                openssl_asn1_str2chunk(keyid->keyid));
                    971:                AUTHORITY_KEYID_free(keyid);
                    972:                return TRUE;
                    973:        }
                    974:        return FALSE;
                    975: }
                    976: 
                    977: /**
                    978:  * Parse subjectKeyIdentifier extension
                    979:  */
                    980: static bool parse_subjectKeyIdentifier_ext(private_openssl_x509_t *this,
                    981:                                                                                   X509_EXTENSION *ext)
                    982: {
                    983:        chunk_t ostr;
                    984: 
                    985:        ostr = openssl_asn1_str2chunk(X509_EXTENSION_get_data(ext));
                    986:        /* quick and dirty unwrap of octet string */
                    987:        if (ostr.len > 2 &&
                    988:                ostr.ptr[0] == V_ASN1_OCTET_STRING && ostr.ptr[1] == ostr.len - 2)
                    989:        {
                    990:                free(this->subjectKeyIdentifier.ptr);
                    991:                this->subjectKeyIdentifier = chunk_clone(chunk_skip(ostr, 2));
                    992:                return TRUE;
                    993:        }
                    994:        return FALSE;
                    995: }
                    996: 
                    997: /**
                    998:  * Parse X509 extensions we are interested in
                    999:  */
                   1000: static bool parse_extensions(private_openssl_x509_t *this)
                   1001: {
                   1002:        const STACK_OF(X509_EXTENSION) *extensions;
                   1003:        int i, num;
                   1004: 
                   1005:        /* unless we see a keyUsage extension we are compliant with RFC 4945 */
                   1006:        this->flags |= X509_IKE_COMPLIANT;
                   1007: 
                   1008:        extensions = X509_get0_extensions(this->x509);
                   1009:        if (extensions)
                   1010:        {
                   1011:                num = sk_X509_EXTENSION_num(extensions);
                   1012: 
                   1013:                for (i = 0; i < num; i++)
                   1014:                {
                   1015:                        X509_EXTENSION *ext;
                   1016:                        bool ok;
                   1017: 
                   1018:                        ext = sk_X509_EXTENSION_value(extensions, i);
                   1019:                        switch (OBJ_obj2nid(X509_EXTENSION_get_object(ext)))
                   1020:                        {
                   1021:                                case NID_info_access:
                   1022:                                        ok = parse_authorityInfoAccess_ext(this, ext);
                   1023:                                        break;
                   1024:                                case NID_authority_key_identifier:
                   1025:                                        ok = parse_authKeyIdentifier_ext(this, ext);
                   1026:                                        break;
                   1027:                                case NID_subject_key_identifier:
                   1028:                                        ok = parse_subjectKeyIdentifier_ext(this, ext);
                   1029:                                        break;
                   1030:                                case NID_subject_alt_name:
                   1031:                                        ok = parse_generalNames_ext(this->subjectAltNames, ext);
                   1032:                                        break;
                   1033:                                case NID_issuer_alt_name:
                   1034:                                        ok = parse_generalNames_ext(this->issuerAltNames, ext);
                   1035:                                        break;
                   1036:                                case NID_basic_constraints:
                   1037:                                        ok = parse_basicConstraints_ext(this, ext);
                   1038:                                        break;
                   1039:                                case NID_key_usage:
                   1040:                                        ok = parse_keyUsage_ext(this, ext);
                   1041:                                        break;
                   1042:                                case NID_ext_key_usage:
                   1043:                                        ok = parse_extKeyUsage_ext(this, ext);
                   1044:                                        break;
                   1045:                                case NID_crl_distribution_points:
                   1046:                                        ok = openssl_parse_crlDistributionPoints(ext, this->crl_uris);
                   1047:                                        break;
                   1048: #ifndef OPENSSL_NO_RFC3779
                   1049:                                case NID_sbgp_ipAddrBlock:
                   1050:                                        ok = parse_ipAddrBlock_ext(this, ext);
                   1051:                                        break;
                   1052: #endif /* !OPENSSL_NO_RFC3779 */
                   1053:                                default:
                   1054:                                        ok = X509_EXTENSION_get_critical(ext) == 0 ||
                   1055:                                                 !lib->settings->get_bool(lib->settings,
                   1056:                                                                        "%s.x509.enforce_critical", TRUE, lib->ns);
                   1057:                                        if (!ok)
                   1058:                                        {
                   1059:                                                char buf[80] = "";
                   1060: 
                   1061:                                                OBJ_obj2txt(buf, sizeof(buf),
                   1062:                                                                        X509_EXTENSION_get_object(ext), 0);
                   1063:                                                DBG1(DBG_LIB, "found unsupported critical X.509 "
                   1064:                                                         "extension: %s", buf);
                   1065:                                        }
                   1066:                                        break;
                   1067:                        }
                   1068:                        if (!ok)
                   1069:                        {
                   1070:                                return FALSE;
                   1071:                        }
                   1072:                }
                   1073:        }
                   1074:        return TRUE;
                   1075: }
                   1076: 
                   1077: /**
                   1078:  * Parse a DER encoded x509 certificate
                   1079:  */
                   1080: static bool parse_certificate(private_openssl_x509_t *this)
                   1081: {
                   1082:        const unsigned char *ptr = this->encoding.ptr;
                   1083:        hasher_t *hasher;
                   1084:        chunk_t chunk, sig_scheme, sig_scheme_tbs;
                   1085:        ASN1_OBJECT *oid;
                   1086: #if OPENSSL_VERSION_NUMBER >= 0x10100000L
                   1087:        const X509_ALGOR *alg;
                   1088: #else
                   1089:        X509_ALGOR *alg;
                   1090: #endif
                   1091:        key_type_t ed_type = KEY_ED448;
                   1092: 
                   1093:        this->x509 = d2i_X509(NULL, &ptr, this->encoding.len);
                   1094:        if (!this->x509)
                   1095:        {
                   1096:                return FALSE;
                   1097:        }
                   1098:        if (X509_get_version(this->x509) < 0 || X509_get_version(this->x509) > 2)
                   1099:        {
                   1100:                DBG1(DBG_LIB, "unsupported x509 version: %d",
                   1101:                         X509_get_version(this->x509) + 1);
                   1102:                return FALSE;
                   1103:        }
                   1104: 
                   1105:        this->subject = openssl_x509_name2id(X509_get_subject_name(this->x509));
                   1106:        this->issuer = openssl_x509_name2id(X509_get_issuer_name(this->x509));
                   1107: 
                   1108:        if (!X509_PUBKEY_get0_param(&oid, NULL, NULL, NULL,
                   1109:                                                            X509_get_X509_PUBKEY(this->x509)))
                   1110:        {
                   1111:                return FALSE;
                   1112:        }
                   1113:        switch (openssl_asn1_known_oid(oid))
                   1114:        {
                   1115:                case OID_RSASSA_PSS:
                   1116:                        /* TODO: we should treat such keys special and use the params as
                   1117:                         * restrictions regarding the use of this key (or rather the
                   1118:                         * associated private key) */
                   1119:                case OID_RSA_ENCRYPTION:
                   1120:                        this->pubkey = lib->creds->create(lib->creds,
                   1121:                                        CRED_PUBLIC_KEY, KEY_RSA, BUILD_BLOB_ASN1_DER,
                   1122:                                        openssl_asn1_str2chunk(X509_get0_pubkey_bitstr(this->x509)),
                   1123:                                        BUILD_END);
                   1124:                        break;
                   1125:                case OID_EC_PUBLICKEY:
                   1126:                        /* for ECDSA, we need the full subjectPublicKeyInfo, as it contains
                   1127:                         * the curve parameters. */
                   1128:                        chunk = openssl_i2chunk(X509_PUBKEY, X509_get_X509_PUBKEY(this->x509));
                   1129:                        this->pubkey = lib->creds->create(lib->creds,
                   1130:                                        CRED_PUBLIC_KEY, KEY_ECDSA, BUILD_BLOB_ASN1_DER,
                   1131:                                        chunk, BUILD_END);
                   1132:                        free(chunk.ptr);
                   1133:                        break;
                   1134:                case OID_ED25519:
                   1135:                        ed_type = KEY_ED25519;
                   1136:                        /* fall-through */
                   1137:                case OID_ED448:
                   1138:                        /* for EdDSA, the parsers expect the full subjectPublicKeyInfo */
                   1139:                        chunk = openssl_i2chunk(X509_PUBKEY, X509_get_X509_PUBKEY(this->x509));
                   1140:                        this->pubkey = lib->creds->create(lib->creds,
                   1141:                                        CRED_PUBLIC_KEY, ed_type, BUILD_BLOB_ASN1_DER,
                   1142:                                        chunk, BUILD_END);
                   1143:                        free(chunk.ptr);
                   1144:                        break;
                   1145:                default:
                   1146:                        DBG1(DBG_LIB, "unsupported public key algorithm");
                   1147:                        break;
                   1148:        }
                   1149:        if (!this->subject || !this->issuer || !this->pubkey)
                   1150:        {
                   1151:                return FALSE;
                   1152:        }
                   1153: 
                   1154:        this->notBefore = openssl_asn1_to_time(X509_get0_notBefore(this->x509));
                   1155:        this->notAfter = openssl_asn1_to_time(X509_get0_notAfter(this->x509));
                   1156: 
                   1157:        /* while X509_ALGOR_cmp() is declared in the headers of older OpenSSL
                   1158:         * versions, at least on Ubuntu 14.04 it is not actually defined */
                   1159:        X509_get0_signature(NULL, &alg, this->x509);
                   1160:        sig_scheme = openssl_i2chunk(X509_ALGOR, (X509_ALGOR*)alg);
                   1161:        alg = X509_get0_tbs_sigalg(this->x509);
                   1162:        sig_scheme_tbs = openssl_i2chunk(X509_ALGOR, (X509_ALGOR*)alg);
                   1163:        if (!chunk_equals(sig_scheme, sig_scheme_tbs))
                   1164:        {
                   1165:                free(sig_scheme_tbs.ptr);
                   1166:                free(sig_scheme.ptr);
                   1167:                return FALSE;
                   1168:        }
                   1169:        free(sig_scheme_tbs.ptr);
                   1170: 
                   1171:        INIT(this->scheme);
                   1172:        if (!signature_params_parse(sig_scheme, 0, this->scheme))
                   1173:        {
                   1174:                DBG1(DBG_ASN, "unable to parse signature algorithm");
                   1175:                free(sig_scheme.ptr);
                   1176:                return FALSE;
                   1177:        }
                   1178:        free(sig_scheme.ptr);
                   1179: 
                   1180:        if (!parse_extensions(this))
                   1181:        {
                   1182:                return FALSE;
                   1183:        }
                   1184: 
                   1185:        hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
                   1186:        if (!hasher || !hasher->allocate_hash(hasher, this->encoding, &this->hash))
                   1187:        {
                   1188:                DESTROY_IF(hasher);
                   1189:                return FALSE;
                   1190:        }
                   1191:        hasher->destroy(hasher);
                   1192: 
                   1193:        if (issued_by(this, &this->public.x509.interface, NULL))
                   1194:        {
                   1195:                this->flags |= X509_SELF_SIGNED;
                   1196:        }
                   1197:        return TRUE;
                   1198: }
                   1199: 
                   1200: openssl_x509_t *openssl_x509_load(certificate_type_t type, va_list args)
                   1201: {
                   1202:        chunk_t blob = chunk_empty;
                   1203:        x509_flag_t flags = 0;
                   1204: 
                   1205:        while (TRUE)
                   1206:        {
                   1207:                switch (va_arg(args, builder_part_t))
                   1208:                {
                   1209:                        case BUILD_BLOB_ASN1_DER:
                   1210:                                blob = va_arg(args, chunk_t);
                   1211:                                continue;
                   1212:                        case BUILD_X509_FLAG:
                   1213:                                flags |= va_arg(args, x509_flag_t);
                   1214:                                continue;
                   1215:                        case BUILD_END:
                   1216:                                break;
                   1217:                        default:
                   1218:                                return NULL;
                   1219:                }
                   1220:                break;
                   1221:        }
                   1222: 
                   1223:        if (blob.ptr)
                   1224:        {
                   1225:                private_openssl_x509_t *this;
                   1226: 
                   1227:                this = create_empty();
                   1228:                this->encoding = chunk_clone(blob);
                   1229:                this->flags |= flags;
                   1230:                if (parse_certificate(this))
                   1231:                {
                   1232:                        return &this->public;
                   1233:                }
                   1234:                DBG1(DBG_LIB, "OpenSSL X.509 parsing failed");
                   1235:                destroy(this);
                   1236:        }
                   1237:        return NULL;
                   1238: }

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