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