1*780fb4a2SCy Schubert /* 2*780fb4a2SCy Schubert * SSL/TLS interface functions for OpenSSL - BoringSSL OCSP 3*780fb4a2SCy Schubert * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> 4*780fb4a2SCy Schubert * 5*780fb4a2SCy Schubert * This software may be distributed under the terms of the BSD license. 6*780fb4a2SCy Schubert * See README for more details. 7*780fb4a2SCy Schubert */ 8*780fb4a2SCy Schubert 9*780fb4a2SCy Schubert #include "includes.h" 10*780fb4a2SCy Schubert 11*780fb4a2SCy Schubert #include <openssl/ssl.h> 12*780fb4a2SCy Schubert #include <openssl/err.h> 13*780fb4a2SCy Schubert #include <openssl/x509v3.h> 14*780fb4a2SCy Schubert #ifdef OPENSSL_IS_BORINGSSL 15*780fb4a2SCy Schubert #include <openssl/asn1.h> 16*780fb4a2SCy Schubert #include <openssl/asn1t.h> 17*780fb4a2SCy Schubert #endif /* OPENSSL_IS_BORINGSSL */ 18*780fb4a2SCy Schubert 19*780fb4a2SCy Schubert #include "common.h" 20*780fb4a2SCy Schubert #include "tls_openssl.h" 21*780fb4a2SCy Schubert 22*780fb4a2SCy Schubert 23*780fb4a2SCy Schubert #ifdef OPENSSL_IS_BORINGSSL 24*780fb4a2SCy Schubert 25*780fb4a2SCy Schubert static void tls_show_errors(int level, const char *func, const char *txt) 26*780fb4a2SCy Schubert { 27*780fb4a2SCy Schubert unsigned long err; 28*780fb4a2SCy Schubert 29*780fb4a2SCy Schubert wpa_printf(level, "OpenSSL: %s - %s %s", 30*780fb4a2SCy Schubert func, txt, ERR_error_string(ERR_get_error(), NULL)); 31*780fb4a2SCy Schubert 32*780fb4a2SCy Schubert while ((err = ERR_get_error())) { 33*780fb4a2SCy Schubert wpa_printf(MSG_INFO, "OpenSSL: pending error: %s", 34*780fb4a2SCy Schubert ERR_error_string(err, NULL)); 35*780fb4a2SCy Schubert } 36*780fb4a2SCy Schubert } 37*780fb4a2SCy Schubert 38*780fb4a2SCy Schubert 39*780fb4a2SCy Schubert /* 40*780fb4a2SCy Schubert * CertID ::= SEQUENCE { 41*780fb4a2SCy Schubert * hashAlgorithm AlgorithmIdentifier, 42*780fb4a2SCy Schubert * issuerNameHash OCTET STRING, -- Hash of Issuer's DN 43*780fb4a2SCy Schubert * issuerKeyHash OCTET STRING, -- Hash of Issuer's public key 44*780fb4a2SCy Schubert * serialNumber CertificateSerialNumber } 45*780fb4a2SCy Schubert */ 46*780fb4a2SCy Schubert typedef struct { 47*780fb4a2SCy Schubert X509_ALGOR *hashAlgorithm; 48*780fb4a2SCy Schubert ASN1_OCTET_STRING *issuerNameHash; 49*780fb4a2SCy Schubert ASN1_OCTET_STRING *issuerKeyHash; 50*780fb4a2SCy Schubert ASN1_INTEGER *serialNumber; 51*780fb4a2SCy Schubert } CertID; 52*780fb4a2SCy Schubert 53*780fb4a2SCy Schubert /* 54*780fb4a2SCy Schubert * ResponseBytes ::= SEQUENCE { 55*780fb4a2SCy Schubert * responseType OBJECT IDENTIFIER, 56*780fb4a2SCy Schubert * response OCTET STRING } 57*780fb4a2SCy Schubert */ 58*780fb4a2SCy Schubert typedef struct { 59*780fb4a2SCy Schubert ASN1_OBJECT *responseType; 60*780fb4a2SCy Schubert ASN1_OCTET_STRING *response; 61*780fb4a2SCy Schubert } ResponseBytes; 62*780fb4a2SCy Schubert 63*780fb4a2SCy Schubert /* 64*780fb4a2SCy Schubert * OCSPResponse ::= SEQUENCE { 65*780fb4a2SCy Schubert * responseStatus OCSPResponseStatus, 66*780fb4a2SCy Schubert * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL } 67*780fb4a2SCy Schubert */ 68*780fb4a2SCy Schubert typedef struct { 69*780fb4a2SCy Schubert ASN1_ENUMERATED *responseStatus; 70*780fb4a2SCy Schubert ResponseBytes *responseBytes; 71*780fb4a2SCy Schubert } OCSPResponse; 72*780fb4a2SCy Schubert 73*780fb4a2SCy Schubert ASN1_SEQUENCE(ResponseBytes) = { 74*780fb4a2SCy Schubert ASN1_SIMPLE(ResponseBytes, responseType, ASN1_OBJECT), 75*780fb4a2SCy Schubert ASN1_SIMPLE(ResponseBytes, response, ASN1_OCTET_STRING) 76*780fb4a2SCy Schubert } ASN1_SEQUENCE_END(ResponseBytes); 77*780fb4a2SCy Schubert 78*780fb4a2SCy Schubert ASN1_SEQUENCE(OCSPResponse) = { 79*780fb4a2SCy Schubert ASN1_SIMPLE(OCSPResponse, responseStatus, ASN1_ENUMERATED), 80*780fb4a2SCy Schubert ASN1_EXP_OPT(OCSPResponse, responseBytes, ResponseBytes, 0) 81*780fb4a2SCy Schubert } ASN1_SEQUENCE_END(OCSPResponse); 82*780fb4a2SCy Schubert 83*780fb4a2SCy Schubert IMPLEMENT_ASN1_FUNCTIONS(OCSPResponse); 84*780fb4a2SCy Schubert 85*780fb4a2SCy Schubert /* 86*780fb4a2SCy Schubert * ResponderID ::= CHOICE { 87*780fb4a2SCy Schubert * byName [1] Name, 88*780fb4a2SCy Schubert * byKey [2] KeyHash } 89*780fb4a2SCy Schubert */ 90*780fb4a2SCy Schubert typedef struct { 91*780fb4a2SCy Schubert int type; 92*780fb4a2SCy Schubert union { 93*780fb4a2SCy Schubert X509_NAME *byName; 94*780fb4a2SCy Schubert ASN1_OCTET_STRING *byKey; 95*780fb4a2SCy Schubert } value; 96*780fb4a2SCy Schubert } ResponderID; 97*780fb4a2SCy Schubert 98*780fb4a2SCy Schubert /* 99*780fb4a2SCy Schubert * RevokedInfo ::= SEQUENCE { 100*780fb4a2SCy Schubert * revocationTime GeneralizedTime, 101*780fb4a2SCy Schubert * revocationReason [0] EXPLICIT CRLReason OPTIONAL } 102*780fb4a2SCy Schubert */ 103*780fb4a2SCy Schubert typedef struct { 104*780fb4a2SCy Schubert ASN1_GENERALIZEDTIME *revocationTime; 105*780fb4a2SCy Schubert ASN1_ENUMERATED *revocationReason; 106*780fb4a2SCy Schubert } RevokedInfo; 107*780fb4a2SCy Schubert 108*780fb4a2SCy Schubert /* 109*780fb4a2SCy Schubert * CertStatus ::= CHOICE { 110*780fb4a2SCy Schubert * good [0] IMPLICIT NULL, 111*780fb4a2SCy Schubert * revoked [1] IMPLICIT RevokedInfo, 112*780fb4a2SCy Schubert * unknown [2] IMPLICIT UnknownInfo } 113*780fb4a2SCy Schubert */ 114*780fb4a2SCy Schubert typedef struct { 115*780fb4a2SCy Schubert int type; 116*780fb4a2SCy Schubert union { 117*780fb4a2SCy Schubert ASN1_NULL *good; 118*780fb4a2SCy Schubert RevokedInfo *revoked; 119*780fb4a2SCy Schubert ASN1_NULL *unknown; 120*780fb4a2SCy Schubert } value; 121*780fb4a2SCy Schubert } CertStatus; 122*780fb4a2SCy Schubert 123*780fb4a2SCy Schubert /* 124*780fb4a2SCy Schubert * SingleResponse ::= SEQUENCE { 125*780fb4a2SCy Schubert * certID CertID, 126*780fb4a2SCy Schubert * certStatus CertStatus, 127*780fb4a2SCy Schubert * thisUpdate GeneralizedTime, 128*780fb4a2SCy Schubert * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, 129*780fb4a2SCy Schubert * singleExtensions [1] EXPLICIT Extensions OPTIONAL } 130*780fb4a2SCy Schubert */ 131*780fb4a2SCy Schubert typedef struct { 132*780fb4a2SCy Schubert CertID *certID; 133*780fb4a2SCy Schubert CertStatus *certStatus; 134*780fb4a2SCy Schubert ASN1_GENERALIZEDTIME *thisUpdate; 135*780fb4a2SCy Schubert ASN1_GENERALIZEDTIME *nextUpdate; 136*780fb4a2SCy Schubert STACK_OF(X509_EXTENSION) *singleExtensions; 137*780fb4a2SCy Schubert } SingleResponse; 138*780fb4a2SCy Schubert 139*780fb4a2SCy Schubert /* 140*780fb4a2SCy Schubert * ResponseData ::= SEQUENCE { 141*780fb4a2SCy Schubert * version [0] EXPLICIT Version DEFAULT v1, 142*780fb4a2SCy Schubert * responderID ResponderID, 143*780fb4a2SCy Schubert * producedAt GeneralizedTime, 144*780fb4a2SCy Schubert * responses SEQUENCE OF SingleResponse, 145*780fb4a2SCy Schubert * responseExtensions [1] EXPLICIT Extensions OPTIONAL } 146*780fb4a2SCy Schubert */ 147*780fb4a2SCy Schubert typedef struct { 148*780fb4a2SCy Schubert ASN1_INTEGER *version; 149*780fb4a2SCy Schubert ResponderID *responderID; 150*780fb4a2SCy Schubert ASN1_GENERALIZEDTIME *producedAt; 151*780fb4a2SCy Schubert STACK_OF(SingleResponse) *responses; 152*780fb4a2SCy Schubert STACK_OF(X509_EXTENSION) *responseExtensions; 153*780fb4a2SCy Schubert } ResponseData; 154*780fb4a2SCy Schubert 155*780fb4a2SCy Schubert /* 156*780fb4a2SCy Schubert * BasicOCSPResponse ::= SEQUENCE { 157*780fb4a2SCy Schubert * tbsResponseData ResponseData, 158*780fb4a2SCy Schubert * signatureAlgorithm AlgorithmIdentifier, 159*780fb4a2SCy Schubert * signature BIT STRING, 160*780fb4a2SCy Schubert * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } 161*780fb4a2SCy Schubert */ 162*780fb4a2SCy Schubert typedef struct { 163*780fb4a2SCy Schubert ResponseData *tbsResponseData; 164*780fb4a2SCy Schubert X509_ALGOR *signatureAlgorithm; 165*780fb4a2SCy Schubert ASN1_BIT_STRING *signature; 166*780fb4a2SCy Schubert STACK_OF(X509) *certs; 167*780fb4a2SCy Schubert } BasicOCSPResponse; 168*780fb4a2SCy Schubert 169*780fb4a2SCy Schubert ASN1_SEQUENCE(CertID) = { 170*780fb4a2SCy Schubert ASN1_SIMPLE(CertID, hashAlgorithm, X509_ALGOR), 171*780fb4a2SCy Schubert ASN1_SIMPLE(CertID, issuerNameHash, ASN1_OCTET_STRING), 172*780fb4a2SCy Schubert ASN1_SIMPLE(CertID, issuerKeyHash, ASN1_OCTET_STRING), 173*780fb4a2SCy Schubert ASN1_SIMPLE(CertID, serialNumber, ASN1_INTEGER) 174*780fb4a2SCy Schubert } ASN1_SEQUENCE_END(CertID); 175*780fb4a2SCy Schubert 176*780fb4a2SCy Schubert ASN1_CHOICE(ResponderID) = { 177*780fb4a2SCy Schubert ASN1_EXP(ResponderID, value.byName, X509_NAME, 1), 178*780fb4a2SCy Schubert ASN1_EXP(ResponderID, value.byKey, ASN1_OCTET_STRING, 2) 179*780fb4a2SCy Schubert } ASN1_CHOICE_END(ResponderID); 180*780fb4a2SCy Schubert 181*780fb4a2SCy Schubert ASN1_SEQUENCE(RevokedInfo) = { 182*780fb4a2SCy Schubert ASN1_SIMPLE(RevokedInfo, revocationTime, ASN1_GENERALIZEDTIME), 183*780fb4a2SCy Schubert ASN1_EXP_OPT(RevokedInfo, revocationReason, ASN1_ENUMERATED, 0) 184*780fb4a2SCy Schubert } ASN1_SEQUENCE_END(RevokedInfo); 185*780fb4a2SCy Schubert 186*780fb4a2SCy Schubert ASN1_CHOICE(CertStatus) = { 187*780fb4a2SCy Schubert ASN1_IMP(CertStatus, value.good, ASN1_NULL, 0), 188*780fb4a2SCy Schubert ASN1_IMP(CertStatus, value.revoked, RevokedInfo, 1), 189*780fb4a2SCy Schubert ASN1_IMP(CertStatus, value.unknown, ASN1_NULL, 2) 190*780fb4a2SCy Schubert } ASN1_CHOICE_END(CertStatus); 191*780fb4a2SCy Schubert 192*780fb4a2SCy Schubert ASN1_SEQUENCE(SingleResponse) = { 193*780fb4a2SCy Schubert ASN1_SIMPLE(SingleResponse, certID, CertID), 194*780fb4a2SCy Schubert ASN1_SIMPLE(SingleResponse, certStatus, CertStatus), 195*780fb4a2SCy Schubert ASN1_SIMPLE(SingleResponse, thisUpdate, ASN1_GENERALIZEDTIME), 196*780fb4a2SCy Schubert ASN1_EXP_OPT(SingleResponse, nextUpdate, ASN1_GENERALIZEDTIME, 0), 197*780fb4a2SCy Schubert ASN1_EXP_SEQUENCE_OF_OPT(SingleResponse, singleExtensions, 198*780fb4a2SCy Schubert X509_EXTENSION, 1) 199*780fb4a2SCy Schubert } ASN1_SEQUENCE_END(SingleResponse); 200*780fb4a2SCy Schubert 201*780fb4a2SCy Schubert ASN1_SEQUENCE(ResponseData) = { 202*780fb4a2SCy Schubert ASN1_EXP_OPT(ResponseData, version, ASN1_INTEGER, 0), 203*780fb4a2SCy Schubert ASN1_SIMPLE(ResponseData, responderID, ResponderID), 204*780fb4a2SCy Schubert ASN1_SIMPLE(ResponseData, producedAt, ASN1_GENERALIZEDTIME), 205*780fb4a2SCy Schubert ASN1_SEQUENCE_OF(ResponseData, responses, SingleResponse), 206*780fb4a2SCy Schubert ASN1_EXP_SEQUENCE_OF_OPT(ResponseData, responseExtensions, 207*780fb4a2SCy Schubert X509_EXTENSION, 1) 208*780fb4a2SCy Schubert } ASN1_SEQUENCE_END(ResponseData); 209*780fb4a2SCy Schubert 210*780fb4a2SCy Schubert ASN1_SEQUENCE(BasicOCSPResponse) = { 211*780fb4a2SCy Schubert ASN1_SIMPLE(BasicOCSPResponse, tbsResponseData, ResponseData), 212*780fb4a2SCy Schubert ASN1_SIMPLE(BasicOCSPResponse, signatureAlgorithm, X509_ALGOR), 213*780fb4a2SCy Schubert ASN1_SIMPLE(BasicOCSPResponse, signature, ASN1_BIT_STRING), 214*780fb4a2SCy Schubert ASN1_EXP_SEQUENCE_OF_OPT(BasicOCSPResponse, certs, X509, 0) 215*780fb4a2SCy Schubert } ASN1_SEQUENCE_END(BasicOCSPResponse); 216*780fb4a2SCy Schubert 217*780fb4a2SCy Schubert IMPLEMENT_ASN1_FUNCTIONS(BasicOCSPResponse); 218*780fb4a2SCy Schubert 219*780fb4a2SCy Schubert #define sk_SingleResponse_num(sk) \ 220*780fb4a2SCy Schubert sk_num(CHECKED_CAST(_STACK *, STACK_OF(SingleResponse) *, sk)) 221*780fb4a2SCy Schubert 222*780fb4a2SCy Schubert #define sk_SingleResponse_value(sk, i) \ 223*780fb4a2SCy Schubert ((SingleResponse *) \ 224*780fb4a2SCy Schubert sk_value(CHECKED_CAST(_STACK *, STACK_OF(SingleResponse) *, sk), (i))) 225*780fb4a2SCy Schubert 226*780fb4a2SCy Schubert 227*780fb4a2SCy Schubert static char * mem_bio_to_str(BIO *out) 228*780fb4a2SCy Schubert { 229*780fb4a2SCy Schubert char *txt; 230*780fb4a2SCy Schubert size_t rlen; 231*780fb4a2SCy Schubert int res; 232*780fb4a2SCy Schubert 233*780fb4a2SCy Schubert rlen = BIO_ctrl_pending(out); 234*780fb4a2SCy Schubert txt = os_malloc(rlen + 1); 235*780fb4a2SCy Schubert if (!txt) { 236*780fb4a2SCy Schubert BIO_free(out); 237*780fb4a2SCy Schubert return NULL; 238*780fb4a2SCy Schubert } 239*780fb4a2SCy Schubert 240*780fb4a2SCy Schubert res = BIO_read(out, txt, rlen); 241*780fb4a2SCy Schubert BIO_free(out); 242*780fb4a2SCy Schubert if (res < 0) { 243*780fb4a2SCy Schubert os_free(txt); 244*780fb4a2SCy Schubert return NULL; 245*780fb4a2SCy Schubert } 246*780fb4a2SCy Schubert 247*780fb4a2SCy Schubert txt[res] = '\0'; 248*780fb4a2SCy Schubert return txt; 249*780fb4a2SCy Schubert } 250*780fb4a2SCy Schubert 251*780fb4a2SCy Schubert 252*780fb4a2SCy Schubert static char * generalizedtime_str(ASN1_GENERALIZEDTIME *t) 253*780fb4a2SCy Schubert { 254*780fb4a2SCy Schubert BIO *out; 255*780fb4a2SCy Schubert 256*780fb4a2SCy Schubert out = BIO_new(BIO_s_mem()); 257*780fb4a2SCy Schubert if (!out) 258*780fb4a2SCy Schubert return NULL; 259*780fb4a2SCy Schubert 260*780fb4a2SCy Schubert if (!ASN1_GENERALIZEDTIME_print(out, t)) { 261*780fb4a2SCy Schubert BIO_free(out); 262*780fb4a2SCy Schubert return NULL; 263*780fb4a2SCy Schubert } 264*780fb4a2SCy Schubert 265*780fb4a2SCy Schubert return mem_bio_to_str(out); 266*780fb4a2SCy Schubert } 267*780fb4a2SCy Schubert 268*780fb4a2SCy Schubert 269*780fb4a2SCy Schubert static char * responderid_str(ResponderID *rid) 270*780fb4a2SCy Schubert { 271*780fb4a2SCy Schubert BIO *out; 272*780fb4a2SCy Schubert 273*780fb4a2SCy Schubert out = BIO_new(BIO_s_mem()); 274*780fb4a2SCy Schubert if (!out) 275*780fb4a2SCy Schubert return NULL; 276*780fb4a2SCy Schubert 277*780fb4a2SCy Schubert switch (rid->type) { 278*780fb4a2SCy Schubert case 0: 279*780fb4a2SCy Schubert X509_NAME_print_ex(out, rid->value.byName, 0, XN_FLAG_ONELINE); 280*780fb4a2SCy Schubert break; 281*780fb4a2SCy Schubert case 1: 282*780fb4a2SCy Schubert i2a_ASN1_STRING(out, rid->value.byKey, V_ASN1_OCTET_STRING); 283*780fb4a2SCy Schubert break; 284*780fb4a2SCy Schubert default: 285*780fb4a2SCy Schubert BIO_free(out); 286*780fb4a2SCy Schubert return NULL; 287*780fb4a2SCy Schubert } 288*780fb4a2SCy Schubert 289*780fb4a2SCy Schubert return mem_bio_to_str(out); 290*780fb4a2SCy Schubert } 291*780fb4a2SCy Schubert 292*780fb4a2SCy Schubert 293*780fb4a2SCy Schubert static char * octet_string_str(ASN1_OCTET_STRING *o) 294*780fb4a2SCy Schubert { 295*780fb4a2SCy Schubert BIO *out; 296*780fb4a2SCy Schubert 297*780fb4a2SCy Schubert out = BIO_new(BIO_s_mem()); 298*780fb4a2SCy Schubert if (!out) 299*780fb4a2SCy Schubert return NULL; 300*780fb4a2SCy Schubert 301*780fb4a2SCy Schubert i2a_ASN1_STRING(out, o, V_ASN1_OCTET_STRING); 302*780fb4a2SCy Schubert return mem_bio_to_str(out); 303*780fb4a2SCy Schubert } 304*780fb4a2SCy Schubert 305*780fb4a2SCy Schubert 306*780fb4a2SCy Schubert static char * integer_str(ASN1_INTEGER *i) 307*780fb4a2SCy Schubert { 308*780fb4a2SCy Schubert BIO *out; 309*780fb4a2SCy Schubert 310*780fb4a2SCy Schubert out = BIO_new(BIO_s_mem()); 311*780fb4a2SCy Schubert if (!out) 312*780fb4a2SCy Schubert return NULL; 313*780fb4a2SCy Schubert 314*780fb4a2SCy Schubert i2a_ASN1_INTEGER(out, i); 315*780fb4a2SCy Schubert return mem_bio_to_str(out); 316*780fb4a2SCy Schubert } 317*780fb4a2SCy Schubert 318*780fb4a2SCy Schubert 319*780fb4a2SCy Schubert static char * algor_str(X509_ALGOR *alg) 320*780fb4a2SCy Schubert { 321*780fb4a2SCy Schubert BIO *out; 322*780fb4a2SCy Schubert 323*780fb4a2SCy Schubert out = BIO_new(BIO_s_mem()); 324*780fb4a2SCy Schubert if (!out) 325*780fb4a2SCy Schubert return NULL; 326*780fb4a2SCy Schubert 327*780fb4a2SCy Schubert i2a_ASN1_OBJECT(out, alg->algorithm); 328*780fb4a2SCy Schubert return mem_bio_to_str(out); 329*780fb4a2SCy Schubert } 330*780fb4a2SCy Schubert 331*780fb4a2SCy Schubert 332*780fb4a2SCy Schubert static char * extensions_str(const char *title, STACK_OF(X509_EXTENSION) *ext) 333*780fb4a2SCy Schubert { 334*780fb4a2SCy Schubert BIO *out; 335*780fb4a2SCy Schubert 336*780fb4a2SCy Schubert if (!ext) 337*780fb4a2SCy Schubert return NULL; 338*780fb4a2SCy Schubert 339*780fb4a2SCy Schubert out = BIO_new(BIO_s_mem()); 340*780fb4a2SCy Schubert if (!out) 341*780fb4a2SCy Schubert return NULL; 342*780fb4a2SCy Schubert 343*780fb4a2SCy Schubert if (!X509V3_extensions_print(out, title, ext, 0, 0)) { 344*780fb4a2SCy Schubert BIO_free(out); 345*780fb4a2SCy Schubert return NULL; 346*780fb4a2SCy Schubert } 347*780fb4a2SCy Schubert return mem_bio_to_str(out); 348*780fb4a2SCy Schubert } 349*780fb4a2SCy Schubert 350*780fb4a2SCy Schubert 351*780fb4a2SCy Schubert static int ocsp_resp_valid(ASN1_GENERALIZEDTIME *thisupd, 352*780fb4a2SCy Schubert ASN1_GENERALIZEDTIME *nextupd) 353*780fb4a2SCy Schubert { 354*780fb4a2SCy Schubert time_t now, tmp; 355*780fb4a2SCy Schubert 356*780fb4a2SCy Schubert if (!ASN1_GENERALIZEDTIME_check(thisupd)) { 357*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 358*780fb4a2SCy Schubert "OpenSSL: Invalid OCSP response thisUpdate"); 359*780fb4a2SCy Schubert return 0; 360*780fb4a2SCy Schubert } 361*780fb4a2SCy Schubert 362*780fb4a2SCy Schubert time(&now); 363*780fb4a2SCy Schubert tmp = now + 5 * 60; /* allow five minute clock difference */ 364*780fb4a2SCy Schubert if (X509_cmp_time(thisupd, &tmp) > 0) { 365*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: OCSP response not yet valid"); 366*780fb4a2SCy Schubert return 0; 367*780fb4a2SCy Schubert } 368*780fb4a2SCy Schubert 369*780fb4a2SCy Schubert if (!nextupd) 370*780fb4a2SCy Schubert return 1; /* OK - no limit on response age */ 371*780fb4a2SCy Schubert 372*780fb4a2SCy Schubert if (!ASN1_GENERALIZEDTIME_check(nextupd)) { 373*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 374*780fb4a2SCy Schubert "OpenSSL: Invalid OCSP response nextUpdate"); 375*780fb4a2SCy Schubert return 0; 376*780fb4a2SCy Schubert } 377*780fb4a2SCy Schubert 378*780fb4a2SCy Schubert tmp = now - 5 * 60; /* allow five minute clock difference */ 379*780fb4a2SCy Schubert if (X509_cmp_time(nextupd, &tmp) < 0) { 380*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: OCSP response expired"); 381*780fb4a2SCy Schubert return 0; 382*780fb4a2SCy Schubert } 383*780fb4a2SCy Schubert 384*780fb4a2SCy Schubert if (ASN1_STRING_cmp(nextupd, thisupd) < 0) { 385*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 386*780fb4a2SCy Schubert "OpenSSL: OCSP response nextUpdate before thisUpdate"); 387*780fb4a2SCy Schubert return 0; 388*780fb4a2SCy Schubert } 389*780fb4a2SCy Schubert 390*780fb4a2SCy Schubert /* Both thisUpdate and nextUpdate are valid */ 391*780fb4a2SCy Schubert return -1; 392*780fb4a2SCy Schubert } 393*780fb4a2SCy Schubert 394*780fb4a2SCy Schubert 395*780fb4a2SCy Schubert static int issuer_match(X509 *cert, X509 *issuer, CertID *certid) 396*780fb4a2SCy Schubert { 397*780fb4a2SCy Schubert X509_NAME *iname; 398*780fb4a2SCy Schubert ASN1_BIT_STRING *ikey; 399*780fb4a2SCy Schubert const EVP_MD *dgst; 400*780fb4a2SCy Schubert unsigned int len; 401*780fb4a2SCy Schubert unsigned char md[EVP_MAX_MD_SIZE]; 402*780fb4a2SCy Schubert ASN1_OCTET_STRING *hash; 403*780fb4a2SCy Schubert char *txt; 404*780fb4a2SCy Schubert 405*780fb4a2SCy Schubert dgst = EVP_get_digestbyobj(certid->hashAlgorithm->algorithm); 406*780fb4a2SCy Schubert if (!dgst) { 407*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 408*780fb4a2SCy Schubert "OpenSSL: Could not find matching hash algorithm for OCSP"); 409*780fb4a2SCy Schubert return -1; 410*780fb4a2SCy Schubert } 411*780fb4a2SCy Schubert 412*780fb4a2SCy Schubert iname = X509_get_issuer_name(cert); 413*780fb4a2SCy Schubert if (!X509_NAME_digest(iname, dgst, md, &len)) 414*780fb4a2SCy Schubert return -1; 415*780fb4a2SCy Schubert hash = ASN1_OCTET_STRING_new(); 416*780fb4a2SCy Schubert if (!hash) 417*780fb4a2SCy Schubert return -1; 418*780fb4a2SCy Schubert if (!ASN1_OCTET_STRING_set(hash, md, len)) { 419*780fb4a2SCy Schubert ASN1_OCTET_STRING_free(hash); 420*780fb4a2SCy Schubert return -1; 421*780fb4a2SCy Schubert } 422*780fb4a2SCy Schubert 423*780fb4a2SCy Schubert txt = octet_string_str(hash); 424*780fb4a2SCy Schubert if (txt) { 425*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: calculated issuerNameHash: %s", 426*780fb4a2SCy Schubert txt); 427*780fb4a2SCy Schubert os_free(txt); 428*780fb4a2SCy Schubert } 429*780fb4a2SCy Schubert 430*780fb4a2SCy Schubert if (ASN1_OCTET_STRING_cmp(certid->issuerNameHash, hash)) { 431*780fb4a2SCy Schubert ASN1_OCTET_STRING_free(hash); 432*780fb4a2SCy Schubert return -1; 433*780fb4a2SCy Schubert } 434*780fb4a2SCy Schubert 435*780fb4a2SCy Schubert ikey = X509_get0_pubkey_bitstr(issuer); 436*780fb4a2SCy Schubert if (!ikey || 437*780fb4a2SCy Schubert !EVP_Digest(ikey->data, ikey->length, md, &len, dgst, NULL) || 438*780fb4a2SCy Schubert !ASN1_OCTET_STRING_set(hash, md, len)) { 439*780fb4a2SCy Schubert ASN1_OCTET_STRING_free(hash); 440*780fb4a2SCy Schubert return -1; 441*780fb4a2SCy Schubert } 442*780fb4a2SCy Schubert 443*780fb4a2SCy Schubert txt = octet_string_str(hash); 444*780fb4a2SCy Schubert if (txt) { 445*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: calculated issuerKeyHash: %s", 446*780fb4a2SCy Schubert txt); 447*780fb4a2SCy Schubert os_free(txt); 448*780fb4a2SCy Schubert } 449*780fb4a2SCy Schubert 450*780fb4a2SCy Schubert if (ASN1_OCTET_STRING_cmp(certid->issuerKeyHash, hash)) { 451*780fb4a2SCy Schubert ASN1_OCTET_STRING_free(hash); 452*780fb4a2SCy Schubert return -1; 453*780fb4a2SCy Schubert } 454*780fb4a2SCy Schubert 455*780fb4a2SCy Schubert ASN1_OCTET_STRING_free(hash); 456*780fb4a2SCy Schubert return 0; 457*780fb4a2SCy Schubert } 458*780fb4a2SCy Schubert 459*780fb4a2SCy Schubert 460*780fb4a2SCy Schubert static X509 * ocsp_find_signer(STACK_OF(X509) *certs, ResponderID *rid) 461*780fb4a2SCy Schubert { 462*780fb4a2SCy Schubert unsigned int i; 463*780fb4a2SCy Schubert unsigned char hash[SHA_DIGEST_LENGTH]; 464*780fb4a2SCy Schubert 465*780fb4a2SCy Schubert if (rid->type == 0) { 466*780fb4a2SCy Schubert /* byName */ 467*780fb4a2SCy Schubert return X509_find_by_subject(certs, rid->value.byName); 468*780fb4a2SCy Schubert } 469*780fb4a2SCy Schubert 470*780fb4a2SCy Schubert /* byKey */ 471*780fb4a2SCy Schubert if (rid->value.byKey->length != SHA_DIGEST_LENGTH) 472*780fb4a2SCy Schubert return NULL; 473*780fb4a2SCy Schubert for (i = 0; i < sk_X509_num(certs); i++) { 474*780fb4a2SCy Schubert X509 *x = sk_X509_value(certs, i); 475*780fb4a2SCy Schubert 476*780fb4a2SCy Schubert X509_pubkey_digest(x, EVP_sha1(), hash, NULL); 477*780fb4a2SCy Schubert if (os_memcmp(rid->value.byKey->data, hash, 478*780fb4a2SCy Schubert SHA_DIGEST_LENGTH) == 0) 479*780fb4a2SCy Schubert return x; 480*780fb4a2SCy Schubert } 481*780fb4a2SCy Schubert 482*780fb4a2SCy Schubert return NULL; 483*780fb4a2SCy Schubert } 484*780fb4a2SCy Schubert 485*780fb4a2SCy Schubert 486*780fb4a2SCy Schubert enum ocsp_result check_ocsp_resp(SSL_CTX *ssl_ctx, SSL *ssl, X509 *cert, 487*780fb4a2SCy Schubert X509 *issuer, X509 *issuer_issuer) 488*780fb4a2SCy Schubert { 489*780fb4a2SCy Schubert const uint8_t *resp_data; 490*780fb4a2SCy Schubert size_t resp_len; 491*780fb4a2SCy Schubert OCSPResponse *resp; 492*780fb4a2SCy Schubert int status; 493*780fb4a2SCy Schubert ResponseBytes *bytes; 494*780fb4a2SCy Schubert const u8 *basic_data; 495*780fb4a2SCy Schubert size_t basic_len; 496*780fb4a2SCy Schubert BasicOCSPResponse *basic; 497*780fb4a2SCy Schubert ResponseData *rd; 498*780fb4a2SCy Schubert char *txt; 499*780fb4a2SCy Schubert int i, num; 500*780fb4a2SCy Schubert unsigned int j, num_resp; 501*780fb4a2SCy Schubert SingleResponse *matching_resp = NULL, *cmp_sresp; 502*780fb4a2SCy Schubert enum ocsp_result result = OCSP_INVALID; 503*780fb4a2SCy Schubert X509_STORE *store; 504*780fb4a2SCy Schubert STACK_OF(X509) *untrusted = NULL, *certs = NULL, *chain = NULL; 505*780fb4a2SCy Schubert X509_STORE_CTX ctx; 506*780fb4a2SCy Schubert X509 *signer, *tmp_cert; 507*780fb4a2SCy Schubert int signer_trusted = 0; 508*780fb4a2SCy Schubert EVP_PKEY *skey; 509*780fb4a2SCy Schubert int ret; 510*780fb4a2SCy Schubert char buf[256]; 511*780fb4a2SCy Schubert 512*780fb4a2SCy Schubert txt = integer_str(X509_get_serialNumber(cert)); 513*780fb4a2SCy Schubert if (txt) { 514*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 515*780fb4a2SCy Schubert "OpenSSL: Searching OCSP response for peer certificate serialNumber: %s", txt); 516*780fb4a2SCy Schubert os_free(txt); 517*780fb4a2SCy Schubert } 518*780fb4a2SCy Schubert 519*780fb4a2SCy Schubert SSL_get0_ocsp_response(ssl, &resp_data, &resp_len); 520*780fb4a2SCy Schubert if (resp_data == NULL || resp_len == 0) { 521*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: No OCSP response received"); 522*780fb4a2SCy Schubert return OCSP_NO_RESPONSE; 523*780fb4a2SCy Schubert } 524*780fb4a2SCy Schubert 525*780fb4a2SCy Schubert wpa_hexdump(MSG_DEBUG, "OpenSSL: OCSP response", resp_data, resp_len); 526*780fb4a2SCy Schubert 527*780fb4a2SCy Schubert resp = d2i_OCSPResponse(NULL, &resp_data, resp_len); 528*780fb4a2SCy Schubert if (!resp) { 529*780fb4a2SCy Schubert wpa_printf(MSG_INFO, "OpenSSL: Failed to parse OCSPResponse"); 530*780fb4a2SCy Schubert return OCSP_INVALID; 531*780fb4a2SCy Schubert } 532*780fb4a2SCy Schubert 533*780fb4a2SCy Schubert status = ASN1_ENUMERATED_get(resp->responseStatus); 534*780fb4a2SCy Schubert if (status != 0) { 535*780fb4a2SCy Schubert wpa_printf(MSG_INFO, "OpenSSL: OCSP responder error %d", 536*780fb4a2SCy Schubert status); 537*780fb4a2SCy Schubert return OCSP_INVALID; 538*780fb4a2SCy Schubert } 539*780fb4a2SCy Schubert 540*780fb4a2SCy Schubert bytes = resp->responseBytes; 541*780fb4a2SCy Schubert 542*780fb4a2SCy Schubert if (!bytes || 543*780fb4a2SCy Schubert OBJ_obj2nid(bytes->responseType) != NID_id_pkix_OCSP_basic) { 544*780fb4a2SCy Schubert wpa_printf(MSG_INFO, 545*780fb4a2SCy Schubert "OpenSSL: Could not find BasicOCSPResponse"); 546*780fb4a2SCy Schubert return OCSP_INVALID; 547*780fb4a2SCy Schubert } 548*780fb4a2SCy Schubert 549*780fb4a2SCy Schubert basic_data = ASN1_STRING_data(bytes->response); 550*780fb4a2SCy Schubert basic_len = ASN1_STRING_length(bytes->response); 551*780fb4a2SCy Schubert wpa_hexdump(MSG_DEBUG, "OpenSSL: BasicOCSPResponse", 552*780fb4a2SCy Schubert basic_data, basic_len); 553*780fb4a2SCy Schubert 554*780fb4a2SCy Schubert basic = d2i_BasicOCSPResponse(NULL, &basic_data, basic_len); 555*780fb4a2SCy Schubert if (!basic) { 556*780fb4a2SCy Schubert wpa_printf(MSG_INFO, 557*780fb4a2SCy Schubert "OpenSSL: Could not parse BasicOCSPResponse"); 558*780fb4a2SCy Schubert OCSPResponse_free(resp); 559*780fb4a2SCy Schubert return OCSP_INVALID; 560*780fb4a2SCy Schubert } 561*780fb4a2SCy Schubert 562*780fb4a2SCy Schubert rd = basic->tbsResponseData; 563*780fb4a2SCy Schubert 564*780fb4a2SCy Schubert if (basic->certs) { 565*780fb4a2SCy Schubert untrusted = sk_X509_dup(basic->certs); 566*780fb4a2SCy Schubert if (!untrusted) 567*780fb4a2SCy Schubert goto fail; 568*780fb4a2SCy Schubert 569*780fb4a2SCy Schubert num = sk_X509_num(basic->certs); 570*780fb4a2SCy Schubert for (i = 0; i < num; i++) { 571*780fb4a2SCy Schubert X509 *extra_cert; 572*780fb4a2SCy Schubert 573*780fb4a2SCy Schubert extra_cert = sk_X509_value(basic->certs, i); 574*780fb4a2SCy Schubert X509_NAME_oneline(X509_get_subject_name(extra_cert), 575*780fb4a2SCy Schubert buf, sizeof(buf)); 576*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 577*780fb4a2SCy Schubert "OpenSSL: BasicOCSPResponse cert %s", buf); 578*780fb4a2SCy Schubert 579*780fb4a2SCy Schubert if (!sk_X509_push(untrusted, extra_cert)) { 580*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 581*780fb4a2SCy Schubert "OpenSSL: Could not add certificate to the untrusted stack"); 582*780fb4a2SCy Schubert } 583*780fb4a2SCy Schubert } 584*780fb4a2SCy Schubert } 585*780fb4a2SCy Schubert 586*780fb4a2SCy Schubert store = SSL_CTX_get_cert_store(ssl_ctx); 587*780fb4a2SCy Schubert if (issuer) { 588*780fb4a2SCy Schubert if (X509_STORE_add_cert(store, issuer) != 1) { 589*780fb4a2SCy Schubert tls_show_errors(MSG_INFO, __func__, 590*780fb4a2SCy Schubert "OpenSSL: Could not add issuer to certificate store"); 591*780fb4a2SCy Schubert } 592*780fb4a2SCy Schubert certs = sk_X509_new_null(); 593*780fb4a2SCy Schubert if (certs) { 594*780fb4a2SCy Schubert tmp_cert = X509_dup(issuer); 595*780fb4a2SCy Schubert if (tmp_cert && !sk_X509_push(certs, tmp_cert)) { 596*780fb4a2SCy Schubert tls_show_errors( 597*780fb4a2SCy Schubert MSG_INFO, __func__, 598*780fb4a2SCy Schubert "OpenSSL: Could not add issuer to OCSP responder trust store"); 599*780fb4a2SCy Schubert X509_free(tmp_cert); 600*780fb4a2SCy Schubert sk_X509_free(certs); 601*780fb4a2SCy Schubert certs = NULL; 602*780fb4a2SCy Schubert } 603*780fb4a2SCy Schubert if (certs && issuer_issuer) { 604*780fb4a2SCy Schubert tmp_cert = X509_dup(issuer_issuer); 605*780fb4a2SCy Schubert if (tmp_cert && 606*780fb4a2SCy Schubert !sk_X509_push(certs, tmp_cert)) { 607*780fb4a2SCy Schubert tls_show_errors( 608*780fb4a2SCy Schubert MSG_INFO, __func__, 609*780fb4a2SCy Schubert "OpenSSL: Could not add issuer's issuer to OCSP responder trust store"); 610*780fb4a2SCy Schubert X509_free(tmp_cert); 611*780fb4a2SCy Schubert } 612*780fb4a2SCy Schubert } 613*780fb4a2SCy Schubert } 614*780fb4a2SCy Schubert } 615*780fb4a2SCy Schubert 616*780fb4a2SCy Schubert signer = ocsp_find_signer(certs, rd->responderID); 617*780fb4a2SCy Schubert if (!signer) 618*780fb4a2SCy Schubert signer = ocsp_find_signer(untrusted, rd->responderID); 619*780fb4a2SCy Schubert else 620*780fb4a2SCy Schubert signer_trusted = 1; 621*780fb4a2SCy Schubert if (!signer) { 622*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 623*780fb4a2SCy Schubert "OpenSSL: Could not find OCSP signer certificate"); 624*780fb4a2SCy Schubert goto fail; 625*780fb4a2SCy Schubert } 626*780fb4a2SCy Schubert 627*780fb4a2SCy Schubert skey = X509_get_pubkey(signer); 628*780fb4a2SCy Schubert if (!skey) { 629*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 630*780fb4a2SCy Schubert "OpenSSL: Could not get OCSP signer public key"); 631*780fb4a2SCy Schubert goto fail; 632*780fb4a2SCy Schubert } 633*780fb4a2SCy Schubert if (ASN1_item_verify(ASN1_ITEM_rptr(ResponseData), 634*780fb4a2SCy Schubert basic->signatureAlgorithm, basic->signature, 635*780fb4a2SCy Schubert basic->tbsResponseData, skey) <= 0) { 636*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 637*780fb4a2SCy Schubert "OpenSSL: BasicOCSPResponse signature is invalid"); 638*780fb4a2SCy Schubert goto fail; 639*780fb4a2SCy Schubert } 640*780fb4a2SCy Schubert 641*780fb4a2SCy Schubert X509_NAME_oneline(X509_get_subject_name(signer), buf, sizeof(buf)); 642*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 643*780fb4a2SCy Schubert "OpenSSL: Found OCSP signer certificate %s and verified BasicOCSPResponse signature", 644*780fb4a2SCy Schubert buf); 645*780fb4a2SCy Schubert 646*780fb4a2SCy Schubert if (!X509_STORE_CTX_init(&ctx, store, signer, untrusted)) 647*780fb4a2SCy Schubert goto fail; 648*780fb4a2SCy Schubert X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); 649*780fb4a2SCy Schubert ret = X509_verify_cert(&ctx); 650*780fb4a2SCy Schubert chain = X509_STORE_CTX_get1_chain(&ctx); 651*780fb4a2SCy Schubert X509_STORE_CTX_cleanup(&ctx); 652*780fb4a2SCy Schubert if (ret <= 0) { 653*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 654*780fb4a2SCy Schubert "OpenSSL: Could not validate OCSP signer certificate"); 655*780fb4a2SCy Schubert goto fail; 656*780fb4a2SCy Schubert } 657*780fb4a2SCy Schubert 658*780fb4a2SCy Schubert if (!chain || sk_X509_num(chain) <= 0) { 659*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: No OCSP signer chain found"); 660*780fb4a2SCy Schubert goto fail; 661*780fb4a2SCy Schubert } 662*780fb4a2SCy Schubert 663*780fb4a2SCy Schubert if (!signer_trusted) { 664*780fb4a2SCy Schubert X509_check_purpose(signer, -1, 0); 665*780fb4a2SCy Schubert if ((signer->ex_flags & EXFLAG_XKUSAGE) && 666*780fb4a2SCy Schubert (signer->ex_xkusage & XKU_OCSP_SIGN)) { 667*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 668*780fb4a2SCy Schubert "OpenSSL: OCSP signer certificate delegation OK"); 669*780fb4a2SCy Schubert } else { 670*780fb4a2SCy Schubert tmp_cert = sk_X509_value(chain, sk_X509_num(chain) - 1); 671*780fb4a2SCy Schubert if (X509_check_trust(tmp_cert, NID_OCSP_sign, 0) != 672*780fb4a2SCy Schubert X509_TRUST_TRUSTED) { 673*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 674*780fb4a2SCy Schubert "OpenSSL: OCSP signer certificate not trusted"); 675*780fb4a2SCy Schubert result = OCSP_NO_RESPONSE; 676*780fb4a2SCy Schubert goto fail; 677*780fb4a2SCy Schubert } 678*780fb4a2SCy Schubert } 679*780fb4a2SCy Schubert } 680*780fb4a2SCy Schubert 681*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: OCSP version: %lu", 682*780fb4a2SCy Schubert ASN1_INTEGER_get(rd->version)); 683*780fb4a2SCy Schubert 684*780fb4a2SCy Schubert txt = responderid_str(rd->responderID); 685*780fb4a2SCy Schubert if (txt) { 686*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: OCSP responderID: %s", 687*780fb4a2SCy Schubert txt); 688*780fb4a2SCy Schubert os_free(txt); 689*780fb4a2SCy Schubert } 690*780fb4a2SCy Schubert 691*780fb4a2SCy Schubert txt = generalizedtime_str(rd->producedAt); 692*780fb4a2SCy Schubert if (txt) { 693*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: OCSP producedAt: %s", 694*780fb4a2SCy Schubert txt); 695*780fb4a2SCy Schubert os_free(txt); 696*780fb4a2SCy Schubert } 697*780fb4a2SCy Schubert 698*780fb4a2SCy Schubert num_resp = sk_SingleResponse_num(rd->responses); 699*780fb4a2SCy Schubert if (num_resp == 0) { 700*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 701*780fb4a2SCy Schubert "OpenSSL: No OCSP SingleResponse within BasicOCSPResponse"); 702*780fb4a2SCy Schubert result = OCSP_NO_RESPONSE; 703*780fb4a2SCy Schubert goto fail; 704*780fb4a2SCy Schubert } 705*780fb4a2SCy Schubert cmp_sresp = sk_SingleResponse_value(rd->responses, 0); 706*780fb4a2SCy Schubert for (j = 0; j < num_resp; j++) { 707*780fb4a2SCy Schubert SingleResponse *sresp; 708*780fb4a2SCy Schubert CertID *cid1, *cid2; 709*780fb4a2SCy Schubert 710*780fb4a2SCy Schubert sresp = sk_SingleResponse_value(rd->responses, j); 711*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: OCSP SingleResponse %u/%u", 712*780fb4a2SCy Schubert j + 1, num_resp); 713*780fb4a2SCy Schubert 714*780fb4a2SCy Schubert txt = algor_str(sresp->certID->hashAlgorithm); 715*780fb4a2SCy Schubert if (txt) { 716*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 717*780fb4a2SCy Schubert "OpenSSL: certID hashAlgorithm: %s", txt); 718*780fb4a2SCy Schubert os_free(txt); 719*780fb4a2SCy Schubert } 720*780fb4a2SCy Schubert 721*780fb4a2SCy Schubert txt = octet_string_str(sresp->certID->issuerNameHash); 722*780fb4a2SCy Schubert if (txt) { 723*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 724*780fb4a2SCy Schubert "OpenSSL: certID issuerNameHash: %s", txt); 725*780fb4a2SCy Schubert os_free(txt); 726*780fb4a2SCy Schubert } 727*780fb4a2SCy Schubert 728*780fb4a2SCy Schubert txt = octet_string_str(sresp->certID->issuerKeyHash); 729*780fb4a2SCy Schubert if (txt) { 730*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 731*780fb4a2SCy Schubert "OpenSSL: certID issuerKeyHash: %s", txt); 732*780fb4a2SCy Schubert os_free(txt); 733*780fb4a2SCy Schubert } 734*780fb4a2SCy Schubert 735*780fb4a2SCy Schubert txt = integer_str(sresp->certID->serialNumber); 736*780fb4a2SCy Schubert if (txt) { 737*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 738*780fb4a2SCy Schubert "OpenSSL: certID serialNumber: %s", txt); 739*780fb4a2SCy Schubert os_free(txt); 740*780fb4a2SCy Schubert } 741*780fb4a2SCy Schubert 742*780fb4a2SCy Schubert switch (sresp->certStatus->type) { 743*780fb4a2SCy Schubert case 0: 744*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: certStatus: good"); 745*780fb4a2SCy Schubert break; 746*780fb4a2SCy Schubert case 1: 747*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: certStatus: revoked"); 748*780fb4a2SCy Schubert break; 749*780fb4a2SCy Schubert default: 750*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: certStatus: unknown"); 751*780fb4a2SCy Schubert break; 752*780fb4a2SCy Schubert } 753*780fb4a2SCy Schubert 754*780fb4a2SCy Schubert txt = generalizedtime_str(sresp->thisUpdate); 755*780fb4a2SCy Schubert if (txt) { 756*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: thisUpdate: %s", txt); 757*780fb4a2SCy Schubert os_free(txt); 758*780fb4a2SCy Schubert } 759*780fb4a2SCy Schubert 760*780fb4a2SCy Schubert if (sresp->nextUpdate) { 761*780fb4a2SCy Schubert txt = generalizedtime_str(sresp->nextUpdate); 762*780fb4a2SCy Schubert if (txt) { 763*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: nextUpdate: %s", 764*780fb4a2SCy Schubert txt); 765*780fb4a2SCy Schubert os_free(txt); 766*780fb4a2SCy Schubert } 767*780fb4a2SCy Schubert } 768*780fb4a2SCy Schubert 769*780fb4a2SCy Schubert txt = extensions_str("singleExtensions", 770*780fb4a2SCy Schubert sresp->singleExtensions); 771*780fb4a2SCy Schubert if (txt) { 772*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: %s", txt); 773*780fb4a2SCy Schubert os_free(txt); 774*780fb4a2SCy Schubert } 775*780fb4a2SCy Schubert 776*780fb4a2SCy Schubert cid1 = cmp_sresp->certID; 777*780fb4a2SCy Schubert cid2 = sresp->certID; 778*780fb4a2SCy Schubert if (j > 0 && 779*780fb4a2SCy Schubert (OBJ_cmp(cid1->hashAlgorithm->algorithm, 780*780fb4a2SCy Schubert cid2->hashAlgorithm->algorithm) != 0 || 781*780fb4a2SCy Schubert ASN1_OCTET_STRING_cmp(cid1->issuerNameHash, 782*780fb4a2SCy Schubert cid2->issuerNameHash) != 0 || 783*780fb4a2SCy Schubert ASN1_OCTET_STRING_cmp(cid1->issuerKeyHash, 784*780fb4a2SCy Schubert cid2->issuerKeyHash) != 0)) { 785*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 786*780fb4a2SCy Schubert "OpenSSL: Different OCSP response issuer information between SingleResponse values within BasicOCSPResponse"); 787*780fb4a2SCy Schubert goto fail; 788*780fb4a2SCy Schubert } 789*780fb4a2SCy Schubert 790*780fb4a2SCy Schubert if (!matching_resp && issuer && 791*780fb4a2SCy Schubert ASN1_INTEGER_cmp(sresp->certID->serialNumber, 792*780fb4a2SCy Schubert X509_get_serialNumber(cert)) == 0 && 793*780fb4a2SCy Schubert issuer_match(cert, issuer, sresp->certID) == 0) { 794*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 795*780fb4a2SCy Schubert "OpenSSL: This response matches peer certificate"); 796*780fb4a2SCy Schubert matching_resp = sresp; 797*780fb4a2SCy Schubert } 798*780fb4a2SCy Schubert } 799*780fb4a2SCy Schubert 800*780fb4a2SCy Schubert txt = extensions_str("responseExtensions", rd->responseExtensions); 801*780fb4a2SCy Schubert if (txt) { 802*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, "OpenSSL: %s", txt); 803*780fb4a2SCy Schubert os_free(txt); 804*780fb4a2SCy Schubert } 805*780fb4a2SCy Schubert 806*780fb4a2SCy Schubert if (!matching_resp) { 807*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 808*780fb4a2SCy Schubert "OpenSSL: Could not find OCSP response that matches the peer certificate"); 809*780fb4a2SCy Schubert result = OCSP_NO_RESPONSE; 810*780fb4a2SCy Schubert goto fail; 811*780fb4a2SCy Schubert } 812*780fb4a2SCy Schubert 813*780fb4a2SCy Schubert if (!ocsp_resp_valid(matching_resp->thisUpdate, 814*780fb4a2SCy Schubert matching_resp->nextUpdate)) { 815*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 816*780fb4a2SCy Schubert "OpenSSL: OCSP response not valid at this time"); 817*780fb4a2SCy Schubert goto fail; 818*780fb4a2SCy Schubert } 819*780fb4a2SCy Schubert 820*780fb4a2SCy Schubert if (matching_resp->certStatus->type == 1) { 821*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 822*780fb4a2SCy Schubert "OpenSSL: OCSP response indicated that the peer certificate has been revoked"); 823*780fb4a2SCy Schubert result = OCSP_REVOKED; 824*780fb4a2SCy Schubert goto fail; 825*780fb4a2SCy Schubert } 826*780fb4a2SCy Schubert 827*780fb4a2SCy Schubert if (matching_resp->certStatus->type != 0) { 828*780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 829*780fb4a2SCy Schubert "OpenSSL: OCSP response did not indicate good status"); 830*780fb4a2SCy Schubert result = OCSP_NO_RESPONSE; 831*780fb4a2SCy Schubert goto fail; 832*780fb4a2SCy Schubert } 833*780fb4a2SCy Schubert 834*780fb4a2SCy Schubert /* OCSP response indicated the certificate is good. */ 835*780fb4a2SCy Schubert result = OCSP_GOOD; 836*780fb4a2SCy Schubert fail: 837*780fb4a2SCy Schubert sk_X509_pop_free(chain, X509_free); 838*780fb4a2SCy Schubert sk_X509_free(untrusted); 839*780fb4a2SCy Schubert sk_X509_pop_free(certs, X509_free); 840*780fb4a2SCy Schubert BasicOCSPResponse_free(basic); 841*780fb4a2SCy Schubert OCSPResponse_free(resp); 842*780fb4a2SCy Schubert 843*780fb4a2SCy Schubert return result; 844*780fb4a2SCy Schubert } 845*780fb4a2SCy Schubert 846*780fb4a2SCy Schubert #endif /* OPENSSL_IS_BORINGSSL */ 847