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

1.1       misho       1: /*
                      2:  * Copyright (C) 2017-2019 Tobias Brunner
                      3:  * Copyright (C) 2008-2009 Martin Willi
                      4:  * Copyright (C) 2007-2015 Andreas Steffen
                      5:  * HSR Hochschule fuer Technik Rapperswil
                      6:  *
                      7:  * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
                      8:  *
                      9:  * This program is free software; you can redistribute it and/or modify it
                     10:  * under the terms of the GNU General Public License as published by the
                     11:  * Free Software Foundation; either version 2 of the License, or (at your
                     12:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     13:  *
                     14:  * This program is distributed in the hope that it will be useful, but
                     15:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     16:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     17:  * for more details.
                     18:  */
                     19: 
                     20: #include "x509_ocsp_response.h"
                     21: 
                     22: #include <time.h>
                     23: 
                     24: #include <asn1/oid.h>
                     25: #include <asn1/asn1.h>
                     26: #include <asn1/asn1_parser.h>
                     27: #include <utils/identification.h>
                     28: #include <collections/linked_list.h>
                     29: #include <utils/debug.h>
                     30: 
                     31: #include <library.h>
                     32: #include <credentials/certificates/x509.h>
                     33: #include <credentials/certificates/crl.h>
                     34: 
                     35: /**
                     36:  * how long do we use an OCSP response without a nextUpdate
                     37:  */
                     38: #define OCSP_DEFAULT_LIFETIME 30
                     39: 
                     40: /* defined in wincrypt.h */
                     41: #ifdef OCSP_RESPONSE
                     42: # undef OCSP_RESPONSE
                     43: #endif
                     44: 
                     45: typedef struct private_x509_ocsp_response_t private_x509_ocsp_response_t;
                     46: 
                     47: /**
                     48:  * Private data of a ocsp_t object.
                     49:  */
                     50: struct private_x509_ocsp_response_t {
                     51:        /**
                     52:         * Public interface for this ocsp object.
                     53:         */
                     54:        x509_ocsp_response_t public;
                     55: 
                     56:        /**
                     57:         * complete encoded OCSP response
                     58:         */
                     59:        chunk_t encoding;
                     60: 
                     61:        /**
                     62:         * data for signature verification
                     63:         */
                     64:        chunk_t tbsResponseData;
                     65: 
                     66:        /**
                     67:         * signature scheme
                     68:         */
                     69:        signature_params_t *scheme;
                     70: 
                     71:        /**
                     72:         * signature
                     73:         */
                     74:        chunk_t signature;
                     75: 
                     76:        /**
                     77:         * name or keyid of the responder
                     78:         */
                     79:        identification_t *responderId;
                     80: 
                     81:        /**
                     82:         * time of response production
                     83:         */
                     84:        time_t producedAt;
                     85: 
                     86:        /**
                     87:         * latest nextUpdate in this OCSP response
                     88:         */
                     89:        time_t usableUntil;
                     90: 
                     91:        /**
                     92:         * list of included certificates
                     93:         */
                     94:        linked_list_t *certs;
                     95: 
                     96:        /**
                     97:         * Linked list of OCSP responses, single_response_t
                     98:         */
                     99:        linked_list_t *responses;
                    100: 
                    101:        /**
                    102:         * Nonce required for ocsp request and response
                    103:         */
                    104:        chunk_t nonce;
                    105: 
                    106:        /**
                    107:         * reference counter
                    108:         */
                    109:        refcount_t ref;
                    110: };
                    111: 
                    112: /**
                    113:  * single response contained in OCSP response
                    114:  */
                    115: typedef struct {
                    116:        /** hash algorithm OID to for the two hashes */
                    117:        int hashAlgorithm;
                    118:        /** hash of issuer DN */
                    119:        chunk_t issuerNameHash;
                    120:        /** issuerKeyID */
                    121:        chunk_t issuerKeyHash;
                    122:        /** serial number of certificate */
                    123:        chunk_t serialNumber;
                    124:        /** OCSP certificate status */
                    125:        cert_validation_t status;
                    126:        /** time of revocation, if revoked */
                    127:        time_t revocationTime;
                    128:        /** revocation reason, if revoked */
                    129:        crl_reason_t revocationReason;
                    130:        /** creation of associated CRL */
                    131:        time_t thisUpdate;
                    132:        /** creation of next CRL */
                    133:        time_t nextUpdate;
                    134: } single_response_t;
                    135: 
                    136: /* our OCSP response version implementation */
                    137: #define OCSP_BASIC_RESPONSE_VERSION 1
                    138: 
                    139: METHOD(ocsp_response_t, get_status, cert_validation_t,
                    140:        private_x509_ocsp_response_t *this, x509_t *subject, x509_t *issuer,
                    141:        time_t *revocation_time, crl_reason_t *revocation_reason,
                    142:        time_t *this_update, time_t *next_update)
                    143: {
                    144:        enumerator_t *enumerator;
                    145:        single_response_t *response;
                    146:        cert_validation_t status = VALIDATION_FAILED;
                    147:        certificate_t *issuercert = &issuer->interface;
                    148: 
                    149:        enumerator = this->responses->create_enumerator(this->responses);
                    150:        while (enumerator->enumerate(enumerator, &response))
                    151:        {
                    152:                hasher_t *hasher;
                    153:                identification_t *id;
                    154:                cred_encoding_type_t type;
                    155:                chunk_t hash, fingerprint;
                    156: 
                    157:                /* check serial first, is cheaper */
                    158:                if (!chunk_equals(subject->get_serial(subject), response->serialNumber))
                    159:                {
                    160:                        continue;
                    161:                }
                    162:                /* check issuerKeyHash if available */
                    163:                if (response->issuerKeyHash.ptr)
                    164:                {
                    165:                        public_key_t *public;
                    166: 
                    167:                        public = issuercert->get_public_key(issuercert);
                    168:                        if (!public)
                    169:                        {
                    170:                                continue;
                    171:                        }
                    172:                        switch (response->hashAlgorithm)
                    173:                        {
                    174:                                case OID_SHA1:
                    175:                                        type = KEYID_PUBKEY_SHA1;
                    176:                                        break;
                    177:                                default:
                    178:                                        public->destroy(public);
                    179:                                        continue;
                    180:                        }
                    181:                        if (!public->get_fingerprint(public, type, &fingerprint) ||
                    182:                                !chunk_equals(response->issuerKeyHash, fingerprint))
                    183:                        {
                    184:                                public->destroy(public);
                    185:                                continue;
                    186:                        }
                    187:                        public->destroy(public);
                    188:                }
                    189:                /* check issuerNameHash, if available */
                    190:                else if (response->issuerNameHash.ptr)
                    191:                {
                    192:                        id = issuercert->get_subject(issuercert);
                    193:                        hasher = lib->crypto->create_hasher(lib->crypto,
                    194:                                                        hasher_algorithm_from_oid(response->hashAlgorithm));
                    195:                        if (!hasher ||
                    196:                                !hasher->allocate_hash(hasher, id->get_encoding(id), &hash))
                    197:                        {
                    198:                                DESTROY_IF(hasher);
                    199:                                continue;
                    200:                        }
                    201:                        hasher->destroy(hasher);
                    202:                        if (!chunk_equals(hash, response->issuerNameHash))
                    203:                        {
                    204:                                free(hash.ptr);
                    205:                                continue;
                    206:                        }
                    207:                        free(hash.ptr);
                    208:                }
                    209:                else
                    210:                {
                    211:                        continue;
                    212:                }
                    213:                /* got a match */
                    214:                status = response->status;
                    215:                *revocation_time = response->revocationTime;
                    216:                *revocation_reason = response->revocationReason;
                    217:                *this_update = response->thisUpdate;
                    218:                *next_update = response->nextUpdate;
                    219: 
                    220:                break;
                    221:        }
                    222:        enumerator->destroy(enumerator);
                    223:        return status;
                    224: }
                    225: 
                    226: METHOD(ocsp_response_t, create_cert_enumerator, enumerator_t*,
                    227:        private_x509_ocsp_response_t *this)
                    228: {
                    229:        return this->certs->create_enumerator(this->certs);
                    230: }
                    231: 
                    232: CALLBACK(filter, bool,
                    233:        void *data, enumerator_t *orig, va_list args)
                    234: {
                    235:        single_response_t *response;
                    236:        cert_validation_t *status;
                    237:        crl_reason_t *revocationReason;
                    238:        chunk_t *serialNumber;
                    239:        time_t *revocationTime;
                    240: 
                    241:        VA_ARGS_VGET(args, serialNumber, status, revocationTime, revocationReason);
                    242: 
                    243:        if (orig->enumerate(orig, &response))
                    244:        {
                    245:                if (serialNumber)
                    246:                {
                    247:                        *serialNumber = response->serialNumber;
                    248:                }
                    249:                if (status)
                    250:                {
                    251:                        *status = response->status;
                    252:                }
                    253:                if (revocationTime)
                    254:                {
                    255:                        *revocationTime = response->revocationTime;
                    256:                }
                    257:                if (revocationReason)
                    258:                {
                    259:                        *revocationReason = response->revocationReason;
                    260:                }
                    261:                return TRUE;
                    262:        }
                    263:        return FALSE;
                    264: }
                    265: 
                    266: METHOD(ocsp_response_t, create_response_enumerator, enumerator_t*,
                    267:        private_x509_ocsp_response_t *this)
                    268: {
                    269:        return enumerator_create_filter(
                    270:                                this->responses->create_enumerator(this->responses),
                    271:                                filter, NULL, NULL);
                    272: }
                    273: 
                    274: METHOD(ocsp_response_t, get_nonce, chunk_t,
                    275:        private_x509_ocsp_response_t *this)
                    276: {
                    277:        return this->nonce;
                    278: }
                    279: 
                    280: /**
                    281:  * ASN.1 definition of singleResponse
                    282:  */
                    283: static const asn1Object_t singleResponseObjects[] = {
                    284:        { 0, "singleResponse",                          ASN1_SEQUENCE,                  ASN1_BODY }, /*  0 */
                    285:        { 1,   "certID",                                        ASN1_SEQUENCE,                  ASN1_NONE }, /*  1 */
                    286:        { 2,     "algorithm",                           ASN1_EOC,                               ASN1_RAW  }, /*  2 */
                    287:        { 2,     "issuerNameHash",                      ASN1_OCTET_STRING,              ASN1_BODY }, /*  3 */
                    288:        { 2,     "issuerKeyHash",                       ASN1_OCTET_STRING,              ASN1_BODY }, /*  4 */
                    289:        { 2,     "serialNumber",                        ASN1_INTEGER,                   ASN1_BODY }, /*  5 */
                    290:        { 1,   "certStatusGood",                        ASN1_CONTEXT_S_0,               ASN1_OPT  }, /*  6 */
                    291:        { 1,   "end opt",                                       ASN1_EOC,                               ASN1_END  }, /*  7 */
                    292:        { 1,   "certStatusRevoked",                     ASN1_CONTEXT_C_1,               ASN1_OPT  }, /*  8 */
                    293:        { 2,     "revocationTime",                      ASN1_GENERALIZEDTIME,   ASN1_BODY }, /*  9 */
                    294:        { 2,     "revocationReason",            ASN1_CONTEXT_C_0,               ASN1_OPT  }, /* 10 */
                    295:        { 3,       "crlReason",                         ASN1_ENUMERATED,                ASN1_BODY }, /* 11 */
                    296:        { 2,     "end opt",                                     ASN1_EOC,                               ASN1_END  }, /* 12 */
                    297:        { 1,   "end opt",                                       ASN1_EOC,                               ASN1_END  }, /* 13 */
                    298:        { 1,   "certStatusUnknown",                     ASN1_CONTEXT_S_2,               ASN1_OPT  }, /* 14 */
                    299:        { 1,   "end opt",                                       ASN1_EOC,                               ASN1_END  }, /* 15 */
                    300:        { 1,   "thisUpdate",                            ASN1_GENERALIZEDTIME,   ASN1_BODY }, /* 16 */
                    301:        { 1,   "nextUpdateContext",                     ASN1_CONTEXT_C_0,               ASN1_OPT  }, /* 17 */
                    302:        { 2,     "nextUpdate",                          ASN1_GENERALIZEDTIME,   ASN1_BODY }, /* 18 */
                    303:        { 1,   "end opt",                                       ASN1_EOC,                               ASN1_END  }, /* 19 */
                    304:        { 1,   "singleExtensionsContext",       ASN1_CONTEXT_C_1,               ASN1_OPT  }, /* 20 */
                    305:        { 2,     "singleExtensions",            ASN1_SEQUENCE,                  ASN1_LOOP }, /* 21 */
                    306:        { 3,       "extension",                         ASN1_SEQUENCE,                  ASN1_NONE }, /* 22 */
                    307:        { 4,         "extnID",                          ASN1_OID,                               ASN1_BODY }, /* 23 */
                    308:        { 4,         "critical",                        ASN1_BOOLEAN,                   ASN1_BODY |
                    309:                                                                                                                                ASN1_DEF  }, /* 24 */
                    310:        { 4,         "extnValue",                       ASN1_OCTET_STRING,              ASN1_BODY }, /* 25 */
                    311:        { 2,     "end loop",                            ASN1_EOC,                               ASN1_END  }, /* 26 */
                    312:        { 1,   "end opt",                                       ASN1_EOC,                               ASN1_END  }, /* 27 */
                    313:        { 0, "exit",                                            ASN1_EOC,                               ASN1_EXIT }
                    314: };
                    315: #define SINGLE_RESPONSE_ALGORITHM                                       2
                    316: #define SINGLE_RESPONSE_ISSUER_NAME_HASH                        3
                    317: #define SINGLE_RESPONSE_ISSUER_KEY_HASH                                 4
                    318: #define SINGLE_RESPONSE_SERIAL_NUMBER                           5
                    319: #define SINGLE_RESPONSE_CERT_STATUS_GOOD                        6
                    320: #define SINGLE_RESPONSE_CERT_STATUS_REVOKED                     8
                    321: #define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME     9
                    322: #define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON         11
                    323: #define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN                    14
                    324: #define SINGLE_RESPONSE_THIS_UPDATE                                    16
                    325: #define SINGLE_RESPONSE_NEXT_UPDATE                                    18
                    326: #define SINGLE_RESPONSE_EXT_ID                                         23
                    327: #define SINGLE_RESPONSE_CRITICAL                                       24
                    328: #define SINGLE_RESPONSE_EXT_VALUE                                      25
                    329: 
                    330: /**
                    331:  * Parse a single OCSP response
                    332:  */
                    333: static bool parse_singleResponse(private_x509_ocsp_response_t *this,
                    334:                                                                 chunk_t blob, int level0)
                    335: {
                    336:        asn1_parser_t *parser;
                    337:        chunk_t object;
                    338:        int objectID;
                    339:        bool success = FALSE;
                    340: 
                    341:        single_response_t *response;
                    342: 
                    343:        response = malloc_thing(single_response_t);
                    344:        response->hashAlgorithm = OID_UNKNOWN;
                    345:        response->issuerNameHash = chunk_empty;
                    346:        response->issuerKeyHash = chunk_empty;
                    347:        response->serialNumber = chunk_empty;
                    348:        response->status = VALIDATION_FAILED;
                    349:        response->revocationTime = 0;
                    350:        response->revocationReason = CRL_REASON_UNSPECIFIED;
                    351:        response->thisUpdate = UNDEFINED_TIME;
                    352:        /* if nextUpdate is missing, we give it a short lifetime */
                    353:        response->nextUpdate = this->producedAt + OCSP_DEFAULT_LIFETIME;
                    354: 
                    355:        parser = asn1_parser_create(singleResponseObjects, blob);
                    356:        parser->set_top_level(parser, level0);
                    357: 
                    358:        while (parser->iterate(parser, &objectID, &object))
                    359:        {
                    360:                switch (objectID)
                    361:                {
                    362:                        case SINGLE_RESPONSE_ALGORITHM:
                    363:                                response->hashAlgorithm = asn1_parse_algorithmIdentifier(object,
                    364:                                                                                        parser->get_level(parser)+1, NULL);
                    365:                                break;
                    366:                        case SINGLE_RESPONSE_ISSUER_NAME_HASH:
                    367:                                response->issuerNameHash = object;
                    368:                                break;
                    369:                        case SINGLE_RESPONSE_ISSUER_KEY_HASH:
                    370:                                response->issuerKeyHash = object;
                    371:                                break;
                    372:                        case SINGLE_RESPONSE_SERIAL_NUMBER:
                    373:                                response->serialNumber = object;
                    374:                                break;
                    375:                        case SINGLE_RESPONSE_CERT_STATUS_GOOD:
                    376:                                response->status = VALIDATION_GOOD;
                    377:                                break;
                    378:                        case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
                    379:                                response->status = VALIDATION_REVOKED;
                    380:                                break;
                    381:                        case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
                    382:                                response->revocationTime = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
                    383:                                break;
                    384:                        case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
                    385:                                if (object.len == 1)
                    386:                                {
                    387:                                        response->revocationReason = *object.ptr;
                    388:                                }
                    389:                                break;
                    390:                        case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
                    391:                                response->status = VALIDATION_FAILED;
                    392:                                break;
                    393:                        case SINGLE_RESPONSE_THIS_UPDATE:
                    394:                                response->thisUpdate = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
                    395:                                break;
                    396:                        case SINGLE_RESPONSE_NEXT_UPDATE:
                    397:                                response->nextUpdate = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
                    398:                                if (response->nextUpdate > this->usableUntil)
                    399:                                {
                    400:                                        this->usableUntil = response->nextUpdate;
                    401:                                }
                    402:                                break;
                    403:                }
                    404:        }
                    405:        success = parser->success(parser);
                    406:        parser->destroy(parser);
                    407:        if (success)
                    408:        {
                    409:                if (this->usableUntil == UNDEFINED_TIME)
                    410:                {
                    411:                        this->usableUntil = this->producedAt + OCSP_DEFAULT_LIFETIME;
                    412:                }
                    413:                this->responses->insert_last(this->responses, response);
                    414:        }
                    415:        else
                    416:        {
                    417:                free(response);
                    418:        }
                    419:        return success;
                    420: }
                    421: 
                    422: /**
                    423:  * ASN.1 definition of responses
                    424:  */
                    425: static const asn1Object_t responsesObjects[] = {
                    426:        { 0, "responses",                       ASN1_SEQUENCE,  ASN1_LOOP }, /* 0 */
                    427:        { 1,   "singleResponse",        ASN1_EOC,               ASN1_RAW  }, /* 1 */
                    428:        { 0, "end loop",                        ASN1_EOC,               ASN1_END  }, /* 2 */
                    429:        { 0, "exit",                            ASN1_EOC,               ASN1_EXIT }
                    430: };
                    431: #define RESPONSES_SINGLE_RESPONSE      1
                    432: 
                    433: /**
                    434:  * Parse all responses
                    435:  */
                    436: static bool parse_responses(private_x509_ocsp_response_t *this,
                    437:                                                        chunk_t blob, int level0)
                    438: {
                    439:        asn1_parser_t *parser;
                    440:        chunk_t object;
                    441:        int objectID;
                    442:        bool success = FALSE;
                    443: 
                    444:        parser = asn1_parser_create(responsesObjects, blob);
                    445:        parser->set_top_level(parser, level0);
                    446: 
                    447:        while (parser->iterate(parser, &objectID, &object))
                    448:        {
                    449:                switch (objectID)
                    450:                {
                    451:                        case RESPONSES_SINGLE_RESPONSE:
                    452:                                if (!parse_singleResponse(this, object,
                    453:                                                                                  parser->get_level(parser)+1))
                    454:                                {
                    455:                                        goto end;
                    456:                                }
                    457:                                break;
                    458:                        default:
                    459:                                break;
                    460:                }
                    461:        }
                    462:        success = parser->success(parser);
                    463: 
                    464: end:
                    465:        parser->destroy(parser);
                    466:        return success;
                    467: }
                    468: 
                    469: /**
                    470:  * ASN.1 definition of basicResponse
                    471:  */
                    472: static const asn1Object_t basicResponseObjects[] = {
                    473:        { 0, "BasicOCSPResponse",                               ASN1_SEQUENCE,                  ASN1_NONE }, /*  0 */
                    474:        { 1,   "tbsResponseData",                               ASN1_SEQUENCE,                  ASN1_OBJ  }, /*  1 */
                    475:        { 2,     "versionContext",                              ASN1_CONTEXT_C_0,               ASN1_NONE |
                    476:                                                                                                                                        ASN1_DEF  }, /*  2 */
                    477:        { 3,       "version",                                   ASN1_INTEGER,                   ASN1_BODY }, /*  3 */
                    478:        { 2,     "responderIdContext",                  ASN1_CONTEXT_C_1,               ASN1_OPT  }, /*  4 */
                    479:        { 3,       "responderIdByName",                 ASN1_SEQUENCE,                  ASN1_OBJ  }, /*  5 */
                    480:        { 2,     "end choice",                                  ASN1_EOC,                               ASN1_END  }, /*  6 */
                    481:        { 2,     "responderIdContext",                  ASN1_CONTEXT_C_2,               ASN1_OPT  }, /*  7 */
                    482:        { 3,       "responderIdByKey",                  ASN1_OCTET_STRING,              ASN1_BODY }, /*  8 */
                    483:        { 2,     "end choice",                                  ASN1_EOC,                               ASN1_END  }, /*  9 */
                    484:        { 2,     "producedAt",                                  ASN1_GENERALIZEDTIME,   ASN1_BODY }, /* 10 */
                    485:        { 2,     "responses",                                   ASN1_SEQUENCE,                  ASN1_OBJ  }, /* 11 */
                    486:        { 2,     "responseExtensionsContext",   ASN1_CONTEXT_C_1,               ASN1_OPT  }, /* 12 */
                    487:        { 3,       "responseExtensions",                ASN1_SEQUENCE,                  ASN1_LOOP }, /* 13 */
                    488:        { 4,         "extension",                               ASN1_SEQUENCE,                  ASN1_NONE }, /* 14 */
                    489:        { 5,           "extnID",                                ASN1_OID,                               ASN1_BODY }, /* 15 */
                    490:        { 5,           "critical",                              ASN1_BOOLEAN,                   ASN1_BODY |
                    491:                                                                                                                                        ASN1_DEF  }, /* 16 */
                    492:        { 5,           "extnValue",                             ASN1_OCTET_STRING,              ASN1_BODY }, /* 17 */
                    493:        { 3,       "end loop",                                  ASN1_EOC,                               ASN1_END  }, /* 18 */
                    494:        { 2,     "end opt",                                             ASN1_EOC,                               ASN1_END  }, /* 19 */
                    495:        { 1,   "signatureAlgorithm",                    ASN1_EOC,                               ASN1_RAW  }, /* 20 */
                    496:        { 1,   "signature",                                             ASN1_BIT_STRING,                ASN1_BODY }, /* 21 */
                    497:        { 1,   "certsContext",                                  ASN1_CONTEXT_C_0,               ASN1_OPT  }, /* 22 */
                    498:        { 2,     "certs",                                               ASN1_SEQUENCE,                  ASN1_LOOP }, /* 23 */
                    499:        { 3,       "certificate",                               ASN1_SEQUENCE,                  ASN1_RAW  }, /* 24 */
                    500:        { 2,     "end loop",                                    ASN1_EOC,                               ASN1_END  }, /* 25 */
                    501:        { 1,   "end opt",                                               ASN1_EOC,                               ASN1_END  }, /* 26 */
                    502:        { 0, "exit",                                                    ASN1_EOC,                               ASN1_EXIT }
                    503: };
                    504: #define BASIC_RESPONSE_TBS_DATA                 1
                    505: #define BASIC_RESPONSE_VERSION          3
                    506: #define BASIC_RESPONSE_ID_BY_NAME       5
                    507: #define BASIC_RESPONSE_ID_BY_KEY        8
                    508: #define BASIC_RESPONSE_PRODUCED_AT     10
                    509: #define BASIC_RESPONSE_RESPONSES       11
                    510: #define BASIC_RESPONSE_EXT_ID          15
                    511: #define BASIC_RESPONSE_CRITICAL                16
                    512: #define BASIC_RESPONSE_EXT_VALUE       17
                    513: #define BASIC_RESPONSE_ALGORITHM       20
                    514: #define BASIC_RESPONSE_SIGNATURE       21
                    515: #define BASIC_RESPONSE_CERTIFICATE     24
                    516: 
                    517: /**
                    518:  * Parse a basicOCSPResponse
                    519:  */
                    520: static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this,
                    521:                                                                        chunk_t blob, int level0)
                    522: {
                    523:        asn1_parser_t *parser;
                    524:        chunk_t object;
                    525:        chunk_t responses = chunk_empty;
                    526:        int objectID;
                    527:        int extn_oid = OID_UNKNOWN;
                    528:        u_int responses_level = level0;
                    529:        certificate_t *cert;
                    530:        bool success = FALSE;
                    531:        bool critical;
                    532: 
                    533:        parser = asn1_parser_create(basicResponseObjects, blob);
                    534:        parser->set_top_level(parser, level0);
                    535: 
                    536:        while (parser->iterate(parser, &objectID, &object))
                    537:        {
                    538:                switch (objectID)
                    539:                {
                    540:                        case BASIC_RESPONSE_TBS_DATA:
                    541:                                this->tbsResponseData = object;
                    542:                                break;
                    543:                        case BASIC_RESPONSE_VERSION:
                    544:                        {
                    545:                                u_int version = (object.len)? (1 + (u_int)*object.ptr) : 1;
                    546: 
                    547:                                if (version != OCSP_BASIC_RESPONSE_VERSION)
                    548:                                {
                    549:                                        DBG1(DBG_ASN, "  ocsp ResponseData version %d not "
                    550:                                                 "supported", version);
                    551:                                        goto end;
                    552:                                }
                    553:                                break;
                    554:                        }
                    555:                        case BASIC_RESPONSE_ID_BY_NAME:
                    556:                                this->responderId = identification_create_from_encoding(
                    557:                                                                                                        ID_DER_ASN1_DN, object);
                    558:                                DBG2(DBG_ASN, "  '%Y'", this->responderId);
                    559:                                break;
                    560:                        case BASIC_RESPONSE_ID_BY_KEY:
                    561:                                this->responderId = identification_create_from_encoding(
                    562:                                                                                                        ID_KEY_ID, object);
                    563:                                DBG2(DBG_ASN, "  '%Y'", this->responderId);
                    564:                                break;
                    565:                        case BASIC_RESPONSE_PRODUCED_AT:
                    566:                                this->producedAt = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
                    567:                                break;
                    568:                        case BASIC_RESPONSE_RESPONSES:
                    569:                                responses = object;
                    570:                                responses_level = parser->get_level(parser)+1;
                    571:                                break;
                    572:                        case BASIC_RESPONSE_EXT_ID:
                    573:                                extn_oid = asn1_known_oid(object);
                    574:                                break;
                    575:                        case BASIC_RESPONSE_CRITICAL:
                    576:                                critical = object.len && *object.ptr;
                    577:                                DBG2(DBG_ASN, "  %s", critical ? "TRUE" : "FALSE");
                    578:                                break;
                    579:                        case BASIC_RESPONSE_EXT_VALUE:
                    580:                                if (extn_oid == OID_NONCE &&
                    581:                                        asn1_parse_simple_object(&object, ASN1_OCTET_STRING,
                    582:                                                                                parser->get_level(parser)+1, "nonce"))
                    583:                                {
                    584:                                        this->nonce = object;
                    585:                                }
                    586:                                break;
                    587:                        case BASIC_RESPONSE_ALGORITHM:
                    588:                                INIT(this->scheme);
                    589:                                if (!signature_params_parse(object, parser->get_level(parser)+1,
                    590:                                                                                        this->scheme))
                    591:                                {
                    592:                                        DBG1(DBG_ASN, "  unable to parse signature algorithm");
                    593:                                        goto end;
                    594:                                }
                    595:                                break;
                    596:                        case BASIC_RESPONSE_SIGNATURE:
                    597:                                this->signature = chunk_skip(object, 1);
                    598:                                break;
                    599:                        case BASIC_RESPONSE_CERTIFICATE:
                    600:                        {
                    601:                                cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,CERT_X509,
                    602:                                                                                  BUILD_BLOB_ASN1_DER, object,
                    603:                                                                                  BUILD_END);
                    604:                                if (cert)
                    605:                                {
                    606:                                        this->certs->insert_last(this->certs, cert);
                    607:                                }
                    608:                                break;
                    609:                        }
                    610:                }
                    611:        }
                    612:        success = parser->success(parser);
                    613: 
                    614: end:
                    615:        parser->destroy(parser);
                    616:        if (success)
                    617:        {
                    618:                if (!this->responderId)
                    619:                {
                    620:                        this->responderId = identification_create_from_encoding(ID_ANY,
                    621:                                                                        chunk_empty);
                    622:                }
                    623:                success = parse_responses(this, responses, responses_level);
                    624:        }
                    625:        return success;
                    626: }
                    627: 
                    628: /**
                    629:  * ASN.1 definition of ocspResponse
                    630:  */
                    631: static const asn1Object_t ocspResponseObjects[] = {
                    632:        { 0, "OCSPResponse",                    ASN1_SEQUENCE,          ASN1_NONE }, /* 0 */
                    633:        { 1,   "responseStatus",                ASN1_ENUMERATED,        ASN1_BODY }, /* 1 */
                    634:        { 1,   "responseBytesContext",  ASN1_CONTEXT_C_0,       ASN1_OPT  }, /* 2 */
                    635:        { 2,     "responseBytes",               ASN1_SEQUENCE,          ASN1_NONE }, /* 3 */
                    636:        { 3,       "responseType",              ASN1_OID,                       ASN1_BODY }, /* 4 */
                    637:        { 3,       "response",                  ASN1_OCTET_STRING,      ASN1_BODY }, /* 5 */
                    638:        { 1,   "end opt",                               ASN1_EOC,                       ASN1_END  }, /* 6 */
                    639:        { 0, "exit",                                    ASN1_EOC,                       ASN1_EXIT }
                    640: };
                    641: #define OCSP_RESPONSE_STATUS   1
                    642: #define OCSP_RESPONSE_TYPE             4
                    643: #define OCSP_RESPONSE                  5
                    644: 
                    645: /**
                    646:  * Parse OCSPResponse object
                    647:  */
                    648: static bool parse_OCSPResponse(private_x509_ocsp_response_t *this)
                    649: {
                    650:        asn1_parser_t *parser;
                    651:        chunk_t object;
                    652:        int objectID;
                    653:        int responseType = OID_UNKNOWN;
                    654:        bool success = FALSE;
                    655:        ocsp_status_t status;
                    656: 
                    657:        parser = asn1_parser_create(ocspResponseObjects, this->encoding);
                    658: 
                    659:        while (parser->iterate(parser, &objectID, &object))
                    660:        {
                    661:                switch (objectID)
                    662:                {
                    663:                        case OCSP_RESPONSE_STATUS:
                    664:                                status = (ocsp_status_t)*object.ptr;
                    665:                                switch (status)
                    666:                                {
                    667:                                        case OCSP_SUCCESSFUL:
                    668:                                                break;
                    669:                                        default:
                    670:                                                DBG1(DBG_LIB, "  ocsp response status: %N",
                    671:                                                         ocsp_status_names, status);
                    672:                                                goto end;
                    673:                                }
                    674:                                break;
                    675:                        case OCSP_RESPONSE_TYPE:
                    676:                                responseType = asn1_known_oid(object);
                    677:                                break;
                    678:                        case OCSP_RESPONSE:
                    679:                                switch (responseType)
                    680:                                {
                    681:                                        case OID_BASIC:
                    682:                                                success = parse_basicOCSPResponse(this, object,
                    683:                                                                                                parser->get_level(parser)+1);
                    684:                                                break;
                    685:                                        default:
                    686:                                                DBG1(DBG_LIB, "  ocsp response type %#B not supported",
                    687:                                                         &object);
                    688:                                                goto end;
                    689:                                }
                    690:                                break;
                    691:                }
                    692:        }
                    693:        success &= parser->success(parser);
                    694: 
                    695: end:
                    696:        parser->destroy(parser);
                    697:        return success;
                    698: }
                    699: 
                    700: METHOD(certificate_t, get_type, certificate_type_t,
                    701:        private_x509_ocsp_response_t *this)
                    702: {
                    703:        return CERT_X509_OCSP_RESPONSE;
                    704: }
                    705: 
                    706: METHOD(certificate_t, get_issuer, identification_t*,
                    707:        private_x509_ocsp_response_t *this)
                    708: {
                    709:        return this->responderId;
                    710: }
                    711: 
                    712: METHOD(certificate_t, has_issuer, id_match_t,
                    713:        private_x509_ocsp_response_t *this, identification_t *issuer)
                    714: {
                    715:        return this->responderId->matches(this->responderId, issuer);
                    716: }
                    717: 
                    718: METHOD(certificate_t, issued_by, bool,
                    719:        private_x509_ocsp_response_t *this, certificate_t *issuer,
                    720:        signature_params_t **scheme)
                    721: {
                    722:        public_key_t *key;
                    723:        bool valid;
                    724:        x509_t *x509 = (x509_t*)issuer;
                    725: 
                    726:        if (issuer->get_type(issuer) != CERT_X509)
                    727:        {
                    728:                return FALSE;
                    729:        }
                    730:        if (this->responderId->get_type(this->responderId) == ID_KEY_ID)
                    731:        {
                    732:                chunk_t fingerprint;
                    733: 
                    734:                key = issuer->get_public_key(issuer);
                    735:                if (!key ||
                    736:                        !key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fingerprint) ||
                    737:                        !chunk_equals(fingerprint,
                    738:                                                  this->responderId->get_encoding(this->responderId)))
                    739:                {
                    740:                        DESTROY_IF(key);
                    741:                        return FALSE;
                    742:                }
                    743:                key->destroy(key);
                    744:        }
                    745:        else
                    746:        {
                    747:                if (!this->responderId->equals(this->responderId,
                    748:                                                                           issuer->get_subject(issuer)))
                    749:                {
                    750:                        return FALSE;
                    751:                }
                    752:        }
                    753:        if (!(x509->get_flags(x509) & X509_OCSP_SIGNER) &&
                    754:                !(x509->get_flags(x509) & X509_CA))
                    755:        {
                    756:                return FALSE;
                    757:        }
                    758: 
                    759:        key = issuer->get_public_key(issuer);
                    760:        if (!key)
                    761:        {
                    762:                return FALSE;
                    763:        }
                    764:        valid = key->verify(key, this->scheme->scheme, this->scheme->params,
                    765:                                                this->tbsResponseData, this->signature);
                    766:        key->destroy(key);
                    767:        if (valid && scheme)
                    768:        {
                    769:                *scheme = signature_params_clone(this->scheme);
                    770:        }
                    771:        return valid;
                    772: }
                    773: 
                    774: METHOD(certificate_t, get_public_key, public_key_t*,
                    775:        private_x509_ocsp_response_t *this)
                    776: {
                    777:        return NULL;
                    778: }
                    779: 
                    780: METHOD(certificate_t, get_validity, bool,
                    781:        private_x509_ocsp_response_t *this, time_t *when,
                    782:        time_t *not_before, time_t *not_after)
                    783: {
                    784:        time_t t = when ? *when : time(NULL);
                    785: 
                    786:        if (not_before)
                    787:        {
                    788:                *not_before = this->producedAt;
                    789:        }
                    790:        if (not_after)
                    791:        {
                    792:                *not_after = this->usableUntil;
                    793:        }
                    794:        return (t < this->usableUntil);
                    795: }
                    796: 
                    797: METHOD(certificate_t, get_encoding, bool,
                    798:        private_x509_ocsp_response_t *this, cred_encoding_type_t type,
                    799:        chunk_t *encoding)
                    800: {
                    801:        if (type == CERT_ASN1_DER)
                    802:        {
                    803:                *encoding = chunk_clone(this->encoding);
                    804:                return TRUE;
                    805:        }
                    806:        return lib->encoding->encode(lib->encoding, type, NULL, encoding,
                    807:                                CRED_PART_X509_OCSP_RES_ASN1_DER, this->encoding, CRED_PART_END);
                    808: }
                    809: 
                    810: METHOD(certificate_t, equals, bool,
                    811:        private_x509_ocsp_response_t *this, certificate_t *other)
                    812: {
                    813:        chunk_t encoding;
                    814:        bool equal;
                    815: 
                    816:        if (this == (private_x509_ocsp_response_t*)other)
                    817:        {
                    818:                return TRUE;
                    819:        }
                    820:        if (other->get_type(other) != CERT_X509_OCSP_RESPONSE)
                    821:        {
                    822:                return FALSE;
                    823:        }
                    824:        if (other->equals == (void*)equals)
                    825:        {       /* skip allocation if we have the same implementation */
                    826:                return chunk_equals(this->encoding, ((private_x509_ocsp_response_t*)other)->encoding);
                    827:        }
                    828:        if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
                    829:        {
                    830:                return FALSE;
                    831:        }
                    832:        equal = chunk_equals(this->encoding, encoding);
                    833:        free(encoding.ptr);
                    834:        return equal;
                    835: }
                    836: 
                    837: METHOD(certificate_t, get_ref, certificate_t*,
                    838:        private_x509_ocsp_response_t *this)
                    839: {
                    840:        ref_get(&this->ref);
                    841:        return &this->public.interface.certificate;
                    842: }
                    843: 
                    844: METHOD(certificate_t, destroy, void,
                    845:        private_x509_ocsp_response_t *this)
                    846: {
                    847:        if (ref_put(&this->ref))
                    848:        {
                    849:                this->certs->destroy_offset(this->certs, offsetof(certificate_t, destroy));
                    850:                this->responses->destroy_function(this->responses, free);
                    851:                signature_params_destroy(this->scheme);
                    852:                DESTROY_IF(this->responderId);
                    853:                free(this->encoding.ptr);
                    854:                free(this);
                    855:        }
                    856: }
                    857: 
                    858: /**
                    859:  * load an OCSP response
                    860:  */
                    861: static x509_ocsp_response_t *load(chunk_t blob)
                    862: {
                    863:        private_x509_ocsp_response_t *this;
                    864: 
                    865:        INIT(this,
                    866:                .public = {
                    867:                        .interface = {
                    868:                                .certificate = {
                    869:                                        .get_type = _get_type,
                    870:                                        .get_subject = _get_issuer,
                    871:                                        .get_issuer = _get_issuer,
                    872:                                        .has_subject = _has_issuer,
                    873:                                        .has_issuer = _has_issuer,
                    874:                                        .issued_by = _issued_by,
                    875:                                        .get_public_key = _get_public_key,
                    876:                                        .get_validity = _get_validity,
                    877:                                        .get_encoding = _get_encoding,
                    878:                                        .equals = _equals,
                    879:                                        .get_ref = _get_ref,
                    880:                                        .destroy = _destroy,
                    881:                                },
                    882:                                .get_nonce = _get_nonce,
                    883:                                .get_status = _get_status,
                    884:                                .create_cert_enumerator = _create_cert_enumerator,
                    885:                                .create_response_enumerator = _create_response_enumerator,
                    886:                        },
                    887:                },
                    888:                .ref = 1,
                    889:                .encoding = chunk_clone(blob),
                    890:                .producedAt = UNDEFINED_TIME,
                    891:                .usableUntil = UNDEFINED_TIME,
                    892:                .responses = linked_list_create(),
                    893:                .certs = linked_list_create(),
                    894:        );
                    895: 
                    896:        if (!parse_OCSPResponse(this))
                    897:        {
                    898:                destroy(this);
                    899:                return NULL;
                    900:        }
                    901:        return &this->public;
                    902: }
                    903: 
                    904: /**
                    905:  * See header.
                    906:  */
                    907: x509_ocsp_response_t *x509_ocsp_response_load(certificate_type_t type,
                    908:                                                                                          va_list args)
                    909: {
                    910:        chunk_t blob = chunk_empty;
                    911: 
                    912:        while (TRUE)
                    913:        {
                    914:                switch (va_arg(args, builder_part_t))
                    915:                {
                    916:                        case BUILD_BLOB_ASN1_DER:
                    917:                                blob = va_arg(args, chunk_t);
                    918:                                continue;
                    919:                        case BUILD_END:
                    920:                                break;
                    921:                        default:
                    922:                                return NULL;
                    923:                }
                    924:                break;
                    925:        }
                    926:        if (blob.ptr)
                    927:        {
                    928:                return load(blob);
                    929:        }
                    930:        return NULL;
                    931: }

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