xref: /freebsd/contrib/wpa/src/crypto/tls_openssl_ocsp.c (revision 780fb4a2fa9a9aee5ac48a60b790f567c0dc13e9)
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