Annotation of embedaddon/strongswan/src/libstrongswan/plugins/openssl/openssl_crl.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:  * Copyright (C) 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) 2010 secunet Security Networks AG
                     21:  * Copyright (C) 2010 Thomas Egerer
                     22:  *
                     23:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                     24:  * of this software and associated documentation files (the "Software"), to deal
                     25:  * in the Software without restriction, including without limitation the rights
                     26:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     27:  * copies of the Software, and to permit persons to whom the Software is
                     28:  * furnished to do so, subject to the following conditions:
                     29:  *
                     30:  * The above copyright notice and this permission notice shall be included in
                     31:  * all copies or substantial portions of the Software.
                     32:  *
                     33:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     34:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     35:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
                     36:  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     37:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     38:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     39:  * THE SOFTWARE.
                     40:  */
                     41: 
                     42: #include "openssl_crl.h"
                     43: #include "openssl_util.h"
                     44: 
                     45: #include <openssl/x509.h>
                     46: #include <openssl/x509v3.h>
                     47: 
                     48: #include <utils/debug.h>
                     49: #include <collections/enumerator.h>
                     50: #include <credentials/certificates/x509.h>
                     51: 
                     52: #if OPENSSL_VERSION_NUMBER < 0x10100000L
                     53: static inline void X509_CRL_get0_signature(const X509_CRL *crl, ASN1_BIT_STRING **psig, X509_ALGOR **palg) {
                     54:        if (psig) { *psig = crl->signature; }
                     55:        if (palg) { *palg = crl->sig_alg; }
                     56: }
                     57: #define X509_REVOKED_get0_serialNumber(r) ({ (r)->serialNumber; })
                     58: #define X509_REVOKED_get0_revocationDate(r) ({ (r)->revocationDate; })
                     59: #define X509_CRL_get0_extensions(c) ({ (c)->crl->extensions; })
                     60: #define ASN1_STRING_get0_data(a) ASN1_STRING_data(a)
                     61: #define X509_CRL_get0_lastUpdate(c) X509_CRL_get_lastUpdate(c)
                     62: #define X509_CRL_get0_nextUpdate(c) X509_CRL_get_nextUpdate(c)
                     63: #endif
                     64: 
                     65: typedef struct private_openssl_crl_t private_openssl_crl_t;
                     66: 
                     67: /**
                     68:  * Private data of an openssl_crl_t object.
                     69:  */
                     70: struct private_openssl_crl_t {
                     71: 
                     72:        /**
                     73:         * Public openssl_crl_t interface.
                     74:         */
                     75:        openssl_crl_t public;
                     76: 
                     77:        /**
                     78:         * OpenSSL representation of a CRL
                     79:         */
                     80:        X509_CRL *crl;
                     81: 
                     82:        /**
                     83:         * DER encoding of the CRL
                     84:         */
                     85:        chunk_t encoding;
                     86: 
                     87:        /**
                     88:         * Serial Number (crlNumber) of the CRL)
                     89:         */
                     90:        chunk_t serial;
                     91: 
                     92:        /**
                     93:         * Number of base CRL (deltaCrlIndicator), if a delta CRL
                     94:         */
                     95:        chunk_t base;
                     96: 
                     97:        /**
                     98:         * List of Freshest CRL distribution points
                     99:         */
                    100:        linked_list_t *crl_uris;
                    101: 
                    102:        /**
                    103:         * AuthorityKeyIdentifier of the issuing CA
                    104:         */
                    105:        chunk_t authKeyIdentifier;
                    106: 
                    107:        /**
                    108:         * Date of this CRL
                    109:         */
                    110:        time_t thisUpdate;
                    111: 
                    112:        /**
                    113:         * Date of next CRL expected
                    114:         */
                    115:        time_t nextUpdate;
                    116: 
                    117:        /**
                    118:         * Issuer of this CRL
                    119:         */
                    120:        identification_t *issuer;
                    121: 
                    122:        /**
                    123:         * Signature scheme used in this CRL
                    124:         */
                    125:        signature_params_t *scheme;
                    126: 
                    127:        /**
                    128:         * References to this CRL
                    129:         */
                    130:        refcount_t ref;
                    131: };
                    132: 
                    133: /**
                    134:  * Enumerator over revoked certificates
                    135:  */
                    136: typedef struct {
                    137:        /**
                    138:         * Implements enumerator_t
                    139:         */
                    140:        enumerator_t public;
                    141: 
                    142:        /**
                    143:         * stack of revoked certificates
                    144:         */
                    145:        STACK_OF(X509_REVOKED) *stack;
                    146: 
                    147:        /**
                    148:         * Total number of revoked certificates
                    149:         */
                    150:        int num;
                    151: 
                    152:        /**
                    153:         * Current position of enumerator
                    154:         */
                    155:        int i;
                    156: } crl_enumerator_t;
                    157: 
                    158: /**
                    159:  * from openssl_x509
                    160:  */
                    161: bool openssl_parse_crlDistributionPoints(X509_EXTENSION *ext,
                    162:                                                                                 linked_list_t *list);
                    163: 
                    164: METHOD(enumerator_t, crl_enumerate, bool,
                    165:        crl_enumerator_t *this, va_list args)
                    166: {
                    167:        crl_reason_t *reason;
                    168:        chunk_t *serial;
                    169:        time_t *date;
                    170: 
                    171:        VA_ARGS_VGET(args, serial, date, reason);
                    172: 
                    173:        if (this->i < this->num)
                    174:        {
                    175:                X509_REVOKED *revoked;
                    176:                ASN1_ENUMERATED *crlrsn;
                    177: 
                    178:                revoked = sk_X509_REVOKED_value(this->stack, this->i);
                    179:                if (serial)
                    180:                {
                    181:                        *serial = openssl_asn1_str2chunk(
                    182:                                                                        X509_REVOKED_get0_serialNumber(revoked));
                    183:                }
                    184:                if (date)
                    185:                {
                    186:                        *date = openssl_asn1_to_time(
                    187:                                                                        X509_REVOKED_get0_revocationDate(revoked));
                    188:                }
                    189:                if (reason)
                    190:                {
                    191:                        *reason = CRL_REASON_UNSPECIFIED;
                    192:                        crlrsn = X509_REVOKED_get_ext_d2i(revoked, NID_crl_reason,
                    193:                                                                                          NULL, NULL);
                    194:                        if (crlrsn)
                    195:                        {
                    196:                                if (ASN1_STRING_type(crlrsn) == V_ASN1_ENUMERATED &&
                    197:                                        ASN1_STRING_length(crlrsn) == 1)
                    198:                                {
                    199:                                        *reason = *ASN1_STRING_get0_data(crlrsn);
                    200:                                }
                    201:                                ASN1_STRING_free(crlrsn);
                    202:                        }
                    203:                }
                    204:                this->i++;
                    205:                return TRUE;
                    206:        }
                    207:        return FALSE;
                    208: }
                    209: 
                    210: METHOD(crl_t, create_enumerator, enumerator_t*,
                    211:        private_openssl_crl_t *this)
                    212: {
                    213:        crl_enumerator_t *enumerator;
                    214: 
                    215:        INIT(enumerator,
                    216:                .public = {
                    217:                        .enumerate = enumerator_enumerate_default,
                    218:                        .venumerate = _crl_enumerate,
                    219:                        .destroy = (void*)free,
                    220:                },
                    221:                .stack = X509_CRL_get_REVOKED(this->crl),
                    222:        );
                    223:        if (!enumerator->stack)
                    224:        {
                    225:                free(enumerator);
                    226:                return enumerator_create_empty();
                    227:        }
                    228:        enumerator->num = sk_X509_REVOKED_num(enumerator->stack);
                    229:        return &enumerator->public;
                    230: }
                    231: 
                    232: METHOD(crl_t, get_serial, chunk_t,
                    233:        private_openssl_crl_t *this)
                    234: {
                    235:        return this->serial;
                    236: }
                    237: 
                    238: METHOD(crl_t, is_delta_crl, bool,
                    239:        private_openssl_crl_t *this, chunk_t *base_crl)
                    240: {
                    241:        if (this->base.len)
                    242:        {
                    243:                if (base_crl)
                    244:                {
                    245:                        *base_crl = this->base;
                    246:                }
                    247:                return TRUE;
                    248:        }
                    249:        return FALSE;
                    250: }
                    251: 
                    252: METHOD(crl_t, create_delta_crl_uri_enumerator, enumerator_t*,
                    253:        private_openssl_crl_t *this)
                    254: {
                    255:        return this->crl_uris->create_enumerator(this->crl_uris);
                    256: }
                    257: 
                    258: METHOD(crl_t, get_authKeyIdentifier, chunk_t,
                    259:        private_openssl_crl_t *this)
                    260: {
                    261:        return this->authKeyIdentifier;
                    262: }
                    263: 
                    264: METHOD(certificate_t, get_type, certificate_type_t,
                    265:        private_openssl_crl_t *this)
                    266: {
                    267:        return CERT_X509_CRL;
                    268: }
                    269: 
                    270: METHOD(certificate_t, get_subject_or_issuer, identification_t*,
                    271:        private_openssl_crl_t *this)
                    272: {
                    273:        return this->issuer;
                    274: }
                    275: 
                    276: METHOD(certificate_t, has_subject_or_issuer, id_match_t,
                    277:        private_openssl_crl_t *this, identification_t *id)
                    278: {
                    279:        if (id->get_type(id) == ID_KEY_ID &&
                    280:                chunk_equals(this->authKeyIdentifier, id->get_encoding(id)))
                    281:        {
                    282:                return ID_MATCH_PERFECT;
                    283:        }
                    284:        return this->issuer->matches(this->issuer, id);
                    285: }
                    286: 
                    287: METHOD(certificate_t, issued_by, bool,
                    288:        private_openssl_crl_t *this, certificate_t *issuer,
                    289:        signature_params_t **scheme)
                    290: {
                    291:        chunk_t fingerprint, tbs;
                    292:        public_key_t *key;
                    293:        x509_t *x509;
                    294: #if OPENSSL_VERSION_NUMBER >= 0x10100000L
                    295:        const ASN1_BIT_STRING *sig;
                    296: #else
                    297:        ASN1_BIT_STRING *sig;
                    298: #endif
                    299:        bool valid;
                    300: 
                    301:        if (issuer->get_type(issuer) != CERT_X509)
                    302:        {
                    303:                return FALSE;
                    304:        }
                    305:        x509 = (x509_t*)issuer;
1.1.1.2 ! misho     306:        if (!(x509->get_flags(x509) & (X509_CA | X509_CRL_SIGN)))
1.1       misho     307:        {
                    308:                return FALSE;
                    309:        }
                    310:        key = issuer->get_public_key(issuer);
                    311:        if (!key)
                    312:        {
                    313:                return FALSE;
                    314:        }
                    315:        if (this->authKeyIdentifier.ptr && key)
                    316:        {
                    317:                if (!key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fingerprint) ||
                    318:                        !chunk_equals(fingerprint, this->authKeyIdentifier))
                    319:                {
                    320:                        return FALSE;
                    321:                }
                    322:        }
                    323:        else
                    324:        {
                    325:                if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
                    326:                {
                    327:                        return FALSE;
                    328:                }
                    329:        }
                    330:        /* i2d_re_X509_CRL_tbs() was added with 1.1.0 when X509_CRL became opaque */
                    331: #if OPENSSL_VERSION_NUMBER >= 0x10100000L
                    332:        tbs = openssl_i2chunk(re_X509_CRL_tbs, this->crl);
                    333: #else
                    334:        tbs = openssl_i2chunk(X509_CRL_INFO, this->crl->crl);
                    335: #endif
                    336:        X509_CRL_get0_signature(this->crl, &sig, NULL);
                    337:        valid = key->verify(key, this->scheme->scheme, this->scheme->params, tbs,
                    338:                                                openssl_asn1_str2chunk(sig));
                    339:        free(tbs.ptr);
                    340:        key->destroy(key);
                    341:        if (valid && scheme)
                    342:        {
                    343:                *scheme = signature_params_clone(this->scheme);
                    344:        }
                    345:        return valid;
                    346: }
                    347: 
                    348: METHOD(certificate_t, get_public_key, public_key_t*,
                    349:        private_openssl_crl_t *this)
                    350: {
                    351:        return NULL;
                    352: }
                    353: 
                    354: METHOD(certificate_t, get_validity, bool,
                    355:        private_openssl_crl_t *this,
                    356:        time_t *when, time_t *not_before, time_t *not_after)
                    357: {
                    358:        time_t t = when ? *when : time(NULL);
                    359: 
                    360:        if (not_before)
                    361:        {
                    362:                *not_before = this->thisUpdate;
                    363:        }
                    364:        if (not_after)
                    365:        {
                    366:                *not_after = this->nextUpdate;
                    367:        }
                    368:        return (t >= this->thisUpdate && t <= this->nextUpdate);
                    369: }
                    370: 
                    371: METHOD(certificate_t, get_encoding, bool,
                    372:        private_openssl_crl_t *this, cred_encoding_type_t type, chunk_t *encoding)
                    373: {
                    374:        if (type == CERT_ASN1_DER)
                    375:        {
                    376:                *encoding = chunk_clone(this->encoding);
                    377:                return TRUE;
                    378:        }
                    379:        return lib->encoding->encode(lib->encoding, type, NULL, encoding,
                    380:                                        CRED_PART_X509_CRL_ASN1_DER, this->encoding, CRED_PART_END);
                    381: }
                    382: 
                    383: METHOD(certificate_t, equals, bool,
                    384:        private_openssl_crl_t *this, certificate_t *other)
                    385: {
                    386:        chunk_t encoding;
                    387:        bool equal;
                    388: 
                    389:        if (&this->public.crl.certificate == other)
                    390:        {
                    391:                return TRUE;
                    392:        }
                    393:        if (other->equals == (void*)equals)
                    394:        {       /* skip allocation if we have the same implementation */
                    395:                return chunk_equals(this->encoding,
                    396:                                                        ((private_openssl_crl_t*)other)->encoding);
                    397:        }
                    398:        if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
                    399:        {
                    400:                return FALSE;
                    401:        }
                    402:        equal = chunk_equals(this->encoding, encoding);
                    403:        free(encoding.ptr);
                    404:        return equal;
                    405: }
                    406: 
                    407: METHOD(certificate_t, get_ref, certificate_t*,
                    408:        private_openssl_crl_t *this)
                    409: {
                    410:        ref_get(&this->ref);
                    411:        return &this->public.crl.certificate;
                    412: }
                    413: 
                    414: METHOD(certificate_t, destroy, void,
                    415:        private_openssl_crl_t *this)
                    416: {
                    417:        if (ref_put(&this->ref))
                    418:        {
                    419:                if (this->crl)
                    420:                {
                    421:                        X509_CRL_free(this->crl);
                    422:                }
                    423:                signature_params_destroy(this->scheme);
                    424:                this->crl_uris->destroy_function(this->crl_uris,
                    425:                                                                                 (void*)x509_cdp_destroy);
                    426:                DESTROY_IF(this->issuer);
                    427:                free(this->authKeyIdentifier.ptr);
                    428:                free(this->base.ptr);
                    429:                free(this->serial.ptr);
                    430:                free(this->encoding.ptr);
                    431:                free(this);
                    432:        }
                    433: }
                    434: 
                    435: /**
                    436:  * Create an empty CRL.
                    437:  */
                    438: static private_openssl_crl_t *create_empty()
                    439: {
                    440:        private_openssl_crl_t *this;
                    441: 
                    442:        INIT(this,
                    443:                .public = {
                    444:                        .crl = {
                    445:                                .certificate = {
                    446:                                        .get_type = _get_type,
                    447:                                        .get_subject = _get_subject_or_issuer,
                    448:                                        .get_issuer = _get_subject_or_issuer,
                    449:                                        .has_subject = _has_subject_or_issuer,
                    450:                                        .has_issuer = _has_subject_or_issuer,
                    451:                                        .issued_by = _issued_by,
                    452:                                        .get_public_key = _get_public_key,
                    453:                                        .get_validity = _get_validity,
                    454:                                        .get_encoding = _get_encoding,
                    455:                                        .equals = _equals,
                    456:                                        .get_ref = _get_ref,
                    457:                                        .destroy = _destroy,
                    458:                                },
                    459:                                .get_serial = _get_serial,
                    460:                                .get_authKeyIdentifier = _get_authKeyIdentifier,
                    461:                                .is_delta_crl = _is_delta_crl,
                    462:                                .create_delta_crl_uri_enumerator = _create_delta_crl_uri_enumerator,
                    463:                                .create_enumerator = _create_enumerator,
                    464:                        },
                    465:                },
                    466:                .crl_uris = linked_list_create(),
                    467:                .ref = 1,
                    468:        );
                    469:        return this;
                    470: }
                    471: 
                    472: /**
                    473:  * Parse the authKeyIdentifier extension
                    474:  */
                    475: static bool parse_authKeyIdentifier_ext(private_openssl_crl_t *this,
                    476:                                                                                X509_EXTENSION *ext)
                    477: {
                    478:        AUTHORITY_KEYID *keyid;
                    479: 
                    480:        keyid = (AUTHORITY_KEYID *)X509V3_EXT_d2i(ext);
                    481:        if (keyid)
                    482:        {
                    483:                free(this->authKeyIdentifier.ptr);
                    484:                this->authKeyIdentifier = chunk_clone(
                    485:                                                openssl_asn1_str2chunk(keyid->keyid));
                    486:                AUTHORITY_KEYID_free(keyid);
                    487:                return TRUE;
                    488:        }
                    489:        return FALSE;
                    490: }
                    491: 
                    492: /**
                    493:  * Quick and dirty INTEGER unwrap for crlNumber/deltaCrlIndicator extensions
                    494:  */
                    495: static bool parse_integer_ext(X509_EXTENSION *ext, chunk_t *out)
                    496: {
                    497:        chunk_t chunk;
                    498: 
                    499:        chunk = openssl_asn1_str2chunk(X509_EXTENSION_get_data(ext));
                    500:        if (chunk.len > 1 && chunk.ptr[0] == V_ASN1_INTEGER &&
                    501:                chunk.ptr[1] == chunk.len - 2)
                    502:        {
                    503:                chunk = chunk_skip(chunk, 2);
                    504:                free(out->ptr);
                    505:                *out = chunk_clone(chunk);
                    506:                return TRUE;
                    507:        }
                    508:        return FALSE;
                    509: }
                    510: 
                    511: /**
                    512:  * Parse X509 CRL extensions
                    513:  */
                    514: static bool parse_extensions(private_openssl_crl_t *this)
                    515: {
                    516:        bool ok;
                    517:        int i, num;
                    518:        X509_EXTENSION *ext;
                    519:        const STACK_OF(X509_EXTENSION) *extensions;
                    520: 
                    521:        extensions = X509_CRL_get0_extensions(this->crl);
                    522:        if (extensions)
                    523:        {
                    524:                num = sk_X509_EXTENSION_num(extensions);
                    525:                for (i = 0; i < num; ++i)
                    526:                {
                    527:                        ext = sk_X509_EXTENSION_value(extensions, i);
                    528: 
                    529:                        switch (OBJ_obj2nid(X509_EXTENSION_get_object(ext)))
                    530:                        {
                    531:                                case NID_authority_key_identifier:
                    532:                                        ok = parse_authKeyIdentifier_ext(this, ext);
                    533:                                        break;
                    534:                                case NID_crl_number:
                    535:                                        ok = parse_integer_ext(ext, &this->serial);
                    536:                                        break;
                    537:                                case NID_delta_crl:
                    538:                                        ok = parse_integer_ext(ext, &this->base);
                    539:                                        break;
                    540:                                case NID_freshest_crl:
                    541:                                        ok = openssl_parse_crlDistributionPoints(ext, this->crl_uris);
                    542:                                        break;
                    543:                                case NID_issuing_distribution_point:
                    544:                                        /* TODO support of IssuingDistributionPoints */
                    545:                                        ok = TRUE;
                    546:                                        break;
                    547:                                default:
                    548:                                        ok = X509_EXTENSION_get_critical(ext) == 0 ||
                    549:                                                 !lib->settings->get_bool(lib->settings,
                    550:                                                                        "%s.x509.enforce_critical", TRUE, lib->ns);
                    551:                                        if (!ok)
                    552:                                        {
                    553:                                                DBG1(DBG_LIB, "found unsupported critical X.509 "
                    554:                                                         "CRL extension");
                    555:                                        }
                    556:                                        break;
                    557:                        }
                    558:                        if (!ok)
                    559:                        {
                    560:                                return FALSE;
                    561:                        }
                    562:                }
                    563:        }
                    564:        return TRUE;
                    565: }
                    566: 
                    567: /**
                    568:  * Parse a X509 CRL
                    569:  */
                    570: static bool parse_crl(private_openssl_crl_t *this)
                    571: {
                    572:        const unsigned char *ptr = this->encoding.ptr;
                    573:        chunk_t sig_scheme;
                    574: #if OPENSSL_VERSION_NUMBER >= 0x10100000L
                    575:        const X509_ALGOR *alg;
                    576: #else
                    577:        X509_ALGOR *alg;
                    578: #endif
                    579: 
                    580:        this->crl = d2i_X509_CRL(NULL, &ptr, this->encoding.len);
                    581:        if (!this->crl)
                    582:        {
                    583:                return FALSE;
                    584:        }
                    585: 
                    586:        X509_CRL_get0_signature(this->crl, NULL, &alg);
                    587:        sig_scheme = openssl_i2chunk(X509_ALGOR, (X509_ALGOR*)alg);
                    588:        INIT(this->scheme);
                    589:        if (!signature_params_parse(sig_scheme, 0, this->scheme))
                    590:        {
                    591:                DBG1(DBG_ASN, "unable to parse signature algorithm");
                    592:                free(sig_scheme.ptr);
                    593:                return FALSE;
                    594:        }
                    595:        free(sig_scheme.ptr);
                    596: 
                    597:        this->issuer = openssl_x509_name2id(X509_CRL_get_issuer(this->crl));
                    598:        if (!this->issuer)
                    599:        {
                    600:                return FALSE;
                    601:        }
                    602:        this->thisUpdate = openssl_asn1_to_time(X509_CRL_get0_lastUpdate(this->crl));
                    603:        this->nextUpdate = openssl_asn1_to_time(X509_CRL_get0_nextUpdate(this->crl));
                    604: 
                    605:        return parse_extensions(this);
                    606: }
                    607: 
                    608: /**
                    609:  * Load the CRL.
                    610:  */
                    611: openssl_crl_t *openssl_crl_load(certificate_type_t type, va_list args)
                    612: {
                    613:        chunk_t blob = chunk_empty;
                    614: 
                    615:        while (TRUE)
                    616:        {
                    617:                switch (va_arg(args, builder_part_t))
                    618:                {
                    619:                        case BUILD_BLOB_ASN1_DER:
                    620:                                blob = va_arg(args, chunk_t);
                    621:                                continue;
                    622:                        case BUILD_END:
                    623:                                break;
                    624:                        default:
                    625:                                return NULL;
                    626:                }
                    627:                break;
                    628:        }
                    629:        if (blob.ptr)
                    630:        {
                    631:                private_openssl_crl_t *this = create_empty();
                    632: 
                    633:                this->encoding = chunk_clone(blob);
                    634:                if (parse_crl(this))
                    635:                {
                    636:                        return &this->public;
                    637:                }
                    638:                destroy(this);
                    639:        }
                    640:        return NULL;
                    641: }

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