1 /*
2  * Copyright (C) 2011-2012 Free Software Foundation, Inc.
3  * Copyright (C) 2016-2017 Red Hat, Inc.
4  *
5  * Author: Simon Josefsson, Nikos Mavrogiannopoulos
6  *
7  * This file is part of GnuTLS.
8  *
9  * The GnuTLS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program.  If not, see <https://www.gnu.org/licenses/>
21  *
22  */
23 
24 /* Online Certificate Status Protocol - RFC 2560
25  */
26 
27 #include "gnutls_int.h"
28 #include <global.h>
29 #include "errors.h"
30 #include <libtasn1.h>
31 #include <pk.h>
32 #include "common.h"
33 #include "verify-high.h"
34 #include "x509.h"
35 #include "ocsp.h"
36 
37 #include <gnutls/ocsp.h>
38 #include <auth/cert.h>
39 
40 #include <assert.h>
41 
42 typedef struct gnutls_ocsp_req_int {
43 	ASN1_TYPE req;
44 	unsigned init;
45 } gnutls_ocsp_req_int;
46 
47 typedef struct gnutls_ocsp_resp_int {
48 	ASN1_TYPE resp;
49 	gnutls_datum_t response_type_oid;
50 	ASN1_TYPE basicresp;
51 	gnutls_datum_t der;
52 	unsigned init;
53 } gnutls_ocsp_resp_int;
54 
55 #define MAX_TIME 64
56 
57 /**
58  * gnutls_ocsp_req_init:
59  * @req: A pointer to the type to be initialized
60  *
61  * This function will initialize an OCSP request structure.
62  *
63  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
64  *   negative error value.
65  **/
gnutls_ocsp_req_init(gnutls_ocsp_req_t * req)66 int gnutls_ocsp_req_init(gnutls_ocsp_req_t * req)
67 {
68 	gnutls_ocsp_req_t tmp =
69 	    gnutls_calloc(1, sizeof(gnutls_ocsp_req_int));
70 	int ret;
71 
72 	if (!tmp)
73 		return GNUTLS_E_MEMORY_ERROR;
74 
75 	ret = asn1_create_element(_gnutls_get_pkix(), "PKIX1.OCSPRequest",
76 				  &tmp->req);
77 	if (ret != ASN1_SUCCESS) {
78 		gnutls_assert();
79 		gnutls_free(tmp);
80 		return _gnutls_asn2err(ret);
81 	}
82 
83 	*req = tmp;
84 
85 	return GNUTLS_E_SUCCESS;
86 }
87 
88 /**
89  * gnutls_ocsp_req_deinit:
90  * @req: The data to be deinitialized
91  *
92  * This function will deinitialize a OCSP request structure.
93  **/
gnutls_ocsp_req_deinit(gnutls_ocsp_req_t req)94 void gnutls_ocsp_req_deinit(gnutls_ocsp_req_t req)
95 {
96 	if (!req)
97 		return;
98 
99 	if (req->req)
100 		asn1_delete_structure(&req->req);
101 
102 	req->req = NULL;
103 	gnutls_free(req);
104 }
105 
106 /**
107  * gnutls_ocsp_resp_init:
108  * @resp: A pointer to the type to be initialized
109  *
110  * This function will initialize an OCSP response structure.
111  *
112  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
113  *   negative error value.
114  **/
gnutls_ocsp_resp_init(gnutls_ocsp_resp_t * resp)115 int gnutls_ocsp_resp_init(gnutls_ocsp_resp_t * resp)
116 {
117 	gnutls_ocsp_resp_t tmp =
118 	    gnutls_calloc(1, sizeof(gnutls_ocsp_resp_int));
119 	int ret;
120 
121 	if (!tmp)
122 		return GNUTLS_E_MEMORY_ERROR;
123 
124 	ret = asn1_create_element(_gnutls_get_pkix(),
125 				  "PKIX1.OCSPResponse", &tmp->resp);
126 	if (ret != ASN1_SUCCESS) {
127 		gnutls_assert();
128 		gnutls_free(tmp);
129 		return _gnutls_asn2err(ret);
130 	}
131 
132 	ret = asn1_create_element(_gnutls_get_pkix(),
133 				  "PKIX1.BasicOCSPResponse",
134 				  &tmp->basicresp);
135 	if (ret != ASN1_SUCCESS) {
136 		gnutls_assert();
137 		asn1_delete_structure(&tmp->resp);
138 		gnutls_free(tmp);
139 		return _gnutls_asn2err(ret);
140 	}
141 
142 	*resp = tmp;
143 
144 	return GNUTLS_E_SUCCESS;
145 }
146 
147 /**
148  * gnutls_ocsp_resp_deinit:
149  * @resp: The data to be deinitialized
150  *
151  * This function will deinitialize a OCSP response structure.
152  **/
gnutls_ocsp_resp_deinit(gnutls_ocsp_resp_t resp)153 void gnutls_ocsp_resp_deinit(gnutls_ocsp_resp_t resp)
154 {
155 	if (!resp)
156 		return;
157 
158 	if (resp->resp)
159 		asn1_delete_structure(&resp->resp);
160 	gnutls_free(resp->response_type_oid.data);
161 	if (resp->basicresp)
162 		asn1_delete_structure(&resp->basicresp);
163 
164 	resp->resp = NULL;
165 	resp->basicresp = NULL;
166 
167 	gnutls_free(resp->der.data);
168 	gnutls_free(resp);
169 }
170 
171 /**
172  * gnutls_ocsp_req_import:
173  * @req: The data to store the parsed request.
174  * @data: DER encoded OCSP request.
175  *
176  * This function will convert the given DER encoded OCSP request to
177  * the native #gnutls_ocsp_req_t format. The output will be stored in
178  * @req.
179  *
180  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
181  *   negative error value.
182  **/
183 int
gnutls_ocsp_req_import(gnutls_ocsp_req_t req,const gnutls_datum_t * data)184 gnutls_ocsp_req_import(gnutls_ocsp_req_t req, const gnutls_datum_t * data)
185 {
186 	int ret = 0;
187 
188 	if (req == NULL || data == NULL) {
189 		gnutls_assert();
190 		return GNUTLS_E_INVALID_REQUEST;
191 	}
192 
193 	if (req->init) {
194 		/* Any earlier _asn1_strict_der_decode will modify the ASN.1
195 		   structure, so we need to replace it with a fresh
196 		   structure. */
197 		asn1_delete_structure(&req->req);
198 
199 		ret = asn1_create_element(_gnutls_get_pkix(),
200 					  "PKIX1.OCSPRequest", &req->req);
201 		if (ret != ASN1_SUCCESS) {
202 			gnutls_assert();
203 			return _gnutls_asn2err(ret);
204 		}
205 	}
206 	req->init = 1;
207 
208 	ret = _asn1_strict_der_decode(&req->req, data->data, data->size, NULL);
209 	if (ret != ASN1_SUCCESS) {
210 		gnutls_assert();
211 		return _gnutls_asn2err(ret);
212 	}
213 
214 	return GNUTLS_E_SUCCESS;
215 }
216 
217 /**
218  * gnutls_ocsp_resp_import:
219  * @resp: The data to store the parsed response.
220  * @data: DER encoded OCSP response.
221  *
222  * This function will convert the given DER encoded OCSP response to
223  * the native #gnutls_ocsp_resp_t format.  It also decodes the Basic
224  * OCSP Response part, if any.  The output will be stored in @resp.
225  *
226  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
227  *   negative error value.
228  **/
229 int
gnutls_ocsp_resp_import(gnutls_ocsp_resp_t resp,const gnutls_datum_t * data)230 gnutls_ocsp_resp_import(gnutls_ocsp_resp_t resp,
231 			const gnutls_datum_t * data)
232 {
233 	return gnutls_ocsp_resp_import2(resp, data, GNUTLS_X509_FMT_DER);
234 }
235 
236 /**
237  * gnutls_ocsp_resp_import2:
238  * @resp: The data to store the parsed response.
239  * @data: DER or PEM encoded OCSP response.
240  * @fmt: DER or PEM
241  *
242  * This function will convert the given OCSP response to
243  * the native #gnutls_ocsp_resp_t format.  It also decodes the Basic
244  * OCSP Response part, if any.  The output will be stored in @resp.
245  *
246  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
247  *   negative error value.
248  *
249  * Since: 3.6.3
250  **/
251 int
gnutls_ocsp_resp_import2(gnutls_ocsp_resp_t resp,const gnutls_datum_t * data,gnutls_x509_crt_fmt_t fmt)252 gnutls_ocsp_resp_import2(gnutls_ocsp_resp_t resp,
253 			 const gnutls_datum_t *data,
254 			 gnutls_x509_crt_fmt_t fmt)
255 {
256 	int ret = 0;
257 	gnutls_datum_t der;
258 
259 	if (resp == NULL || data == NULL) {
260 		gnutls_assert();
261 		return GNUTLS_E_INVALID_REQUEST;
262 	}
263 
264 	der.data = data->data;
265 	der.size = data->size;
266 
267 	if (fmt == GNUTLS_X509_FMT_PEM) {
268 		ret = gnutls_pem_base64_decode2(BARE_PEM_OCSP_RESPONSE, data, &der);
269 		if (ret < 0) {
270 			return gnutls_assert_val(ret);
271 		}
272 	}
273 
274 	if (resp->init != 0) {
275 		/* Any earlier _asn1_strict_der_decode will modify the ASN.1
276 		   structure, so we need to replace it with a fresh
277 		   structure. */
278 		asn1_delete_structure(&resp->resp);
279 		if (resp->basicresp)
280 			asn1_delete_structure(&resp->basicresp);
281 
282 		ret = asn1_create_element(_gnutls_get_pkix(),
283 					  "PKIX1.OCSPResponse",
284 					  &resp->resp);
285 		if (ret != ASN1_SUCCESS) {
286 			gnutls_assert();
287 			ret = _gnutls_asn2err(ret);
288 			goto cleanup;
289 		}
290 
291 		ret = asn1_create_element(_gnutls_get_pkix(),
292 					  "PKIX1.BasicOCSPResponse",
293 					  &resp->basicresp);
294 		if (ret != ASN1_SUCCESS) {
295 			gnutls_assert();
296 			ret = _gnutls_asn2err(ret);
297 			goto cleanup;
298 		}
299 
300 		gnutls_free(resp->der.data);
301 	}
302 
303 	resp->init = 1;
304 	ret = _asn1_strict_der_decode(&resp->resp, der.data, der.size, NULL);
305 	if (ret != ASN1_SUCCESS) {
306 		gnutls_assert();
307 		ret = _gnutls_asn2err(ret);
308 		goto cleanup;
309 	}
310 
311 	if (gnutls_ocsp_resp_get_status(resp) !=
312 	    GNUTLS_OCSP_RESP_SUCCESSFUL) {
313 		ret = GNUTLS_E_SUCCESS;
314 		goto cleanup;
315 	}
316 
317 	ret =
318 	    _gnutls_x509_read_value(resp->resp,
319 				    "responseBytes.responseType",
320 				    &resp->response_type_oid);
321 	if (ret < 0) {
322 		gnutls_assert();
323 		goto cleanup;
324 	}
325 #define OCSP_BASIC "1.3.6.1.5.5.7.48.1.1"
326 
327 	if (resp->response_type_oid.size == sizeof(OCSP_BASIC)
328 	    && memcmp(resp->response_type_oid.data, OCSP_BASIC,
329 		      resp->response_type_oid.size) == 0) {
330 
331 		ret =
332 		    _gnutls_x509_read_value(resp->resp,
333 					    "responseBytes.response", &resp->der);
334 		if (ret < 0) {
335 			gnutls_assert();
336 			goto cleanup;
337 		}
338 
339 		ret =
340 		    _asn1_strict_der_decode(&resp->basicresp, resp->der.data, resp->der.size,
341 				      NULL);
342 		if (ret != ASN1_SUCCESS) {
343 			gnutls_assert();
344 			ret = _gnutls_asn2err(ret);
345 			goto cleanup;
346 		}
347 	} else {
348 		asn1_delete_structure(&resp->basicresp);
349 		resp->basicresp = NULL;
350 	}
351 
352 	ret = GNUTLS_E_SUCCESS;
353 cleanup:
354 	if (der.data != data->data)
355 		gnutls_free(der.data);
356 	return ret;
357 }
358 
359 /**
360  * gnutls_ocsp_req_export:
361  * @req: Holds the OCSP request
362  * @data: newly allocate buffer holding DER encoded OCSP request
363  *
364  * This function will export the OCSP request to DER format.
365  *
366  * Returns: In case of failure a negative error code will be
367  *   returned, and 0 on success.
368  **/
gnutls_ocsp_req_export(gnutls_ocsp_req_const_t req,gnutls_datum_t * data)369 int gnutls_ocsp_req_export(gnutls_ocsp_req_const_t req, gnutls_datum_t * data)
370 {
371 	int ret;
372 
373 	if (req == NULL || data == NULL) {
374 		gnutls_assert();
375 		return GNUTLS_E_INVALID_REQUEST;
376 	}
377 
378 	/* XXX remove when we support these fields */
379 	(void)asn1_write_value(req->req, "tbsRequest.requestorName", NULL, 0);
380 	(void)asn1_write_value(req->req, "optionalSignature", NULL, 0);
381 
382 	/* prune extension field if we don't have any extension */
383 	ret = gnutls_ocsp_req_get_extension(req, 0, NULL, NULL, NULL);
384 	if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
385 		(void)asn1_write_value(req->req, "tbsRequest.requestExtensions",
386 				 NULL, 0);
387 
388 	return _gnutls_x509_get_raw_field(req->req, "", data);
389 }
390 
391 /**
392  * gnutls_ocsp_resp_export:
393  * @resp: Holds the OCSP response
394  * @data: newly allocate buffer holding DER encoded OCSP response
395  *
396  * This function will export the OCSP response to DER format.
397  *
398  * Returns: In case of failure a negative error code will be
399  *   returned, and 0 on success.
400  **/
gnutls_ocsp_resp_export(gnutls_ocsp_resp_const_t resp,gnutls_datum_t * data)401 int gnutls_ocsp_resp_export(gnutls_ocsp_resp_const_t resp, gnutls_datum_t * data)
402 {
403 	return gnutls_ocsp_resp_export2(resp, data, GNUTLS_X509_FMT_DER);
404 }
405 
406 /**
407  * gnutls_ocsp_resp_export2:
408  * @resp: Holds the OCSP response
409  * @data: newly allocate buffer holding DER or PEM encoded OCSP response
410  * @fmt: DER or PEM
411  *
412  * This function will export the OCSP response to DER or PEM format.
413  *
414  * Returns: In case of failure a negative error code will be
415  *   returned, and 0 on success.
416  *
417  * Since: 3.6.3
418  **/
gnutls_ocsp_resp_export2(gnutls_ocsp_resp_const_t resp,gnutls_datum_t * data,gnutls_x509_crt_fmt_t fmt)419 int gnutls_ocsp_resp_export2(gnutls_ocsp_resp_const_t resp, gnutls_datum_t * data,
420 			     gnutls_x509_crt_fmt_t fmt)
421 {
422 	int ret;
423 	gnutls_datum_t der;
424 
425 	if (resp == NULL || data == NULL) {
426 		gnutls_assert();
427 		return GNUTLS_E_INVALID_REQUEST;
428 	}
429 
430 	ret = _gnutls_x509_get_raw_field(resp->resp, "", &der);
431 	if (ret < 0)
432 		return gnutls_assert_val(ret);
433 
434 	if (fmt == GNUTLS_X509_FMT_DER) {
435 		data->data = der.data;
436 		data->size = der.size;
437 		return ret;
438 	} else {
439 		ret = gnutls_pem_base64_encode2("OCSP RESPONSE", &der, data);
440 		gnutls_free(der.data);
441 		if (ret < 0)
442 			return gnutls_assert_val(ret);
443 
444 		return 0;
445 	}
446 }
447 
448 /**
449  * gnutls_ocsp_req_get_version:
450  * @req: should contain a #gnutls_ocsp_req_t type
451  *
452  * This function will return the version of the OCSP request.
453  * Typically this is always 1 indicating version 1.
454  *
455  * Returns: version of OCSP request, or a negative error code on error.
456  **/
gnutls_ocsp_req_get_version(gnutls_ocsp_req_const_t req)457 int gnutls_ocsp_req_get_version(gnutls_ocsp_req_const_t req)
458 {
459 	if (req == NULL) {
460 		gnutls_assert();
461 		return GNUTLS_E_INVALID_REQUEST;
462 	}
463 
464 	return _gnutls_x509_get_version(req->req, "tbsRequest.version");
465 }
466 
467 /**
468  * gnutls_ocsp_req_get_cert_id:
469  * @req: should contain a #gnutls_ocsp_req_t type
470  * @indx: Specifies which extension OID to get. Use (0) to get the first one.
471  * @digest: output variable with #gnutls_digest_algorithm_t hash algorithm
472  * @issuer_name_hash: output buffer with hash of issuer's DN
473  * @issuer_key_hash: output buffer with hash of issuer's public key
474  * @serial_number: output buffer with serial number of certificate to check
475  *
476  * This function will return the certificate information of the
477  * @indx'ed request in the OCSP request.  The information returned
478  * corresponds to the CertID structure:
479  *
480  * <informalexample><programlisting>
481  *    CertID	  ::=     SEQUENCE {
482  *	hashAlgorithm       AlgorithmIdentifier,
483  *	issuerNameHash      OCTET STRING, -- Hash of Issuer's DN
484  *	issuerKeyHash       OCTET STRING, -- Hash of Issuers public key
485  *	serialNumber	CertificateSerialNumber }
486  * </programlisting></informalexample>
487  *
488  * Each of the pointers to output variables may be NULL to indicate
489  * that the caller is not interested in that value.
490  *
491  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
492  *   negative error code is returned.  If you have reached the last
493  *   CertID available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
494  *   returned.
495  **/
496 int
gnutls_ocsp_req_get_cert_id(gnutls_ocsp_req_const_t req,unsigned indx,gnutls_digest_algorithm_t * digest,gnutls_datum_t * issuer_name_hash,gnutls_datum_t * issuer_key_hash,gnutls_datum_t * serial_number)497 gnutls_ocsp_req_get_cert_id(gnutls_ocsp_req_const_t req,
498 			    unsigned indx,
499 			    gnutls_digest_algorithm_t * digest,
500 			    gnutls_datum_t * issuer_name_hash,
501 			    gnutls_datum_t * issuer_key_hash,
502 			    gnutls_datum_t * serial_number)
503 {
504 	gnutls_datum_t sa;
505 	char name[MAX_NAME_SIZE];
506 	int ret;
507 
508 	if (req == NULL) {
509 		gnutls_assert();
510 		return GNUTLS_E_INVALID_REQUEST;
511 	}
512 
513 	snprintf(name, sizeof(name),
514 		 "tbsRequest.requestList.?%u.reqCert.hashAlgorithm.algorithm",
515 		 indx + 1);
516 	ret = _gnutls_x509_read_value(req->req, name, &sa);
517 	if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
518 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
519 	else if (ret < 0) {
520 		gnutls_assert();
521 		return ret;
522 	}
523 
524 	ret = gnutls_oid_to_digest((char *) sa.data);
525 	_gnutls_free_datum(&sa);
526 	if (ret < 0) {
527 		gnutls_assert();
528 		return ret;
529 	}
530 
531 	if (digest)
532 		*digest = ret;
533 
534 	if (issuer_name_hash) {
535 		snprintf(name, sizeof(name),
536 			 "tbsRequest.requestList.?%u.reqCert.issuerNameHash",
537 			 indx + 1);
538 		ret =
539 		    _gnutls_x509_read_value(req->req, name,
540 					    issuer_name_hash);
541 		if (ret != GNUTLS_E_SUCCESS) {
542 			gnutls_assert();
543 			return ret;
544 		}
545 	}
546 
547 	if (issuer_key_hash) {
548 		snprintf(name, sizeof(name),
549 			 "tbsRequest.requestList.?%u.reqCert.issuerKeyHash",
550 			 indx + 1);
551 		ret =
552 		    _gnutls_x509_read_value(req->req, name,
553 					    issuer_key_hash);
554 		if (ret != GNUTLS_E_SUCCESS) {
555 			gnutls_assert();
556 			if (issuer_name_hash)
557 				gnutls_free(issuer_name_hash->data);
558 			return ret;
559 		}
560 	}
561 
562 	if (serial_number) {
563 		snprintf(name, sizeof(name),
564 			 "tbsRequest.requestList.?%u.reqCert.serialNumber",
565 			 indx + 1);
566 		ret =
567 		    _gnutls_x509_read_value(req->req, name, serial_number);
568 		if (ret != GNUTLS_E_SUCCESS) {
569 			gnutls_assert();
570 			if (issuer_name_hash)
571 				gnutls_free(issuer_name_hash->data);
572 			if (issuer_key_hash)
573 				gnutls_free(issuer_key_hash->data);
574 			return ret;
575 		}
576 	}
577 
578 	return GNUTLS_E_SUCCESS;
579 }
580 
581 /**
582  * gnutls_ocsp_req_add_cert_id:
583  * @req: should contain a #gnutls_ocsp_req_t type
584  * @digest: hash algorithm, a #gnutls_digest_algorithm_t value
585  * @issuer_name_hash: hash of issuer's DN
586  * @issuer_key_hash: hash of issuer's public key
587  * @serial_number: serial number of certificate to check
588  *
589  * This function will add another request to the OCSP request for a
590  * particular certificate having the issuer name hash of
591  * @issuer_name_hash and issuer key hash of @issuer_key_hash (both
592  * hashed using @digest) and serial number @serial_number.
593  *
594  * The information needed corresponds to the CertID structure:
595  *
596  * <informalexample><programlisting>
597  *    CertID	  ::=     SEQUENCE {
598  *	hashAlgorithm       AlgorithmIdentifier,
599  *	issuerNameHash      OCTET STRING, -- Hash of Issuer's DN
600  *	issuerKeyHash       OCTET STRING, -- Hash of Issuers public key
601  *	serialNumber	CertificateSerialNumber }
602  * </programlisting></informalexample>
603  *
604  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
605  *   negative error code is returned.
606  **/
607 int
gnutls_ocsp_req_add_cert_id(gnutls_ocsp_req_t req,gnutls_digest_algorithm_t digest,const gnutls_datum_t * issuer_name_hash,const gnutls_datum_t * issuer_key_hash,const gnutls_datum_t * serial_number)608 gnutls_ocsp_req_add_cert_id(gnutls_ocsp_req_t req,
609 			    gnutls_digest_algorithm_t digest,
610 			    const gnutls_datum_t * issuer_name_hash,
611 			    const gnutls_datum_t * issuer_key_hash,
612 			    const gnutls_datum_t * serial_number)
613 {
614 	int result;
615 	const char *oid;
616 
617 	if (req == NULL || issuer_name_hash == NULL
618 	    || issuer_key_hash == NULL || serial_number == NULL) {
619 		gnutls_assert();
620 		return GNUTLS_E_INVALID_REQUEST;
621 	}
622 
623 	oid = _gnutls_x509_digest_to_oid(hash_to_entry(digest));
624 	if (oid == NULL) {
625 		gnutls_assert();
626 		return GNUTLS_E_INVALID_REQUEST;
627 	}
628 
629 	result =
630 	    asn1_write_value(req->req, "tbsRequest.requestList", "NEW", 1);
631 	if (result != ASN1_SUCCESS) {
632 		gnutls_assert();
633 		return _gnutls_asn2err(result);
634 	}
635 
636 	result = asn1_write_value
637 	    (req->req,
638 	     "tbsRequest.requestList.?LAST.reqCert.hashAlgorithm.algorithm",
639 	     oid, 1);
640 	if (result != ASN1_SUCCESS) {
641 		gnutls_assert();
642 		return _gnutls_asn2err(result);
643 	}
644 
645 	/* XXX we don't support any algorithm with parameters */
646 	result = asn1_write_value
647 	    (req->req,
648 	     "tbsRequest.requestList.?LAST.reqCert.hashAlgorithm.parameters",
649 	     ASN1_NULL, ASN1_NULL_SIZE);
650 	if (result != ASN1_SUCCESS) {
651 		gnutls_assert();
652 		return _gnutls_asn2err(result);
653 	}
654 
655 	result = asn1_write_value
656 	    (req->req,
657 	     "tbsRequest.requestList.?LAST.reqCert.issuerNameHash",
658 	     issuer_name_hash->data, issuer_name_hash->size);
659 	if (result != ASN1_SUCCESS) {
660 		gnutls_assert();
661 		return _gnutls_asn2err(result);
662 	}
663 
664 	result = asn1_write_value
665 	    (req->req,
666 	     "tbsRequest.requestList.?LAST.reqCert.issuerKeyHash",
667 	     issuer_key_hash->data, issuer_key_hash->size);
668 	if (result != ASN1_SUCCESS) {
669 		gnutls_assert();
670 		return _gnutls_asn2err(result);
671 	}
672 
673 	result = asn1_write_value
674 	    (req->req, "tbsRequest.requestList.?LAST.reqCert.serialNumber",
675 	     serial_number->data, serial_number->size);
676 	if (result != ASN1_SUCCESS) {
677 		gnutls_assert();
678 		return _gnutls_asn2err(result);
679 	}
680 
681 	/* XXX add separate function that can add extensions too */
682 	result = asn1_write_value
683 	    (req->req,
684 	     "tbsRequest.requestList.?LAST.singleRequestExtensions", NULL,
685 	     0);
686 	if (result != ASN1_SUCCESS) {
687 		gnutls_assert();
688 		return _gnutls_asn2err(result);
689 	}
690 
691 	return GNUTLS_E_SUCCESS;
692 }
693 
694 /**
695  * gnutls_ocsp_req_add_cert:
696  * @req: should contain a #gnutls_ocsp_req_t type
697  * @digest: hash algorithm, a #gnutls_digest_algorithm_t value
698  * @issuer: issuer of @subject certificate
699  * @cert: certificate to request status for
700  *
701  * This function will add another request to the OCSP request for a
702  * particular certificate.  The issuer name hash, issuer key hash, and
703  * serial number fields is populated as follows.  The issuer name and
704  * the serial number is taken from @cert.  The issuer key is taken
705  * from @issuer.  The hashed values will be hashed using the @digest
706  * algorithm, normally %GNUTLS_DIG_SHA1.
707  *
708  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
709  *   negative error code is returned.
710  **/
711 int
gnutls_ocsp_req_add_cert(gnutls_ocsp_req_t req,gnutls_digest_algorithm_t digest,gnutls_x509_crt_t issuer,gnutls_x509_crt_t cert)712 gnutls_ocsp_req_add_cert(gnutls_ocsp_req_t req,
713 			 gnutls_digest_algorithm_t digest,
714 			 gnutls_x509_crt_t issuer, gnutls_x509_crt_t cert)
715 {
716 	int ret;
717 	gnutls_datum_t sn, tmp, inh, ikh;
718 	uint8_t inh_buf[MAX_HASH_SIZE];
719 	uint8_t ikh_buf[MAX_HASH_SIZE];
720 	size_t inhlen = MAX_HASH_SIZE;
721 	size_t ikhlen = MAX_HASH_SIZE;
722 
723 	if (req == NULL || issuer == NULL || cert == NULL) {
724 		gnutls_assert();
725 		return GNUTLS_E_INVALID_REQUEST;
726 	}
727 
728 	ret = _gnutls_x509_der_encode(cert->cert,
729 				      "tbsCertificate.issuer.rdnSequence",
730 				      &tmp, 0);
731 	if (ret != GNUTLS_E_SUCCESS) {
732 		gnutls_assert();
733 		return ret;
734 	}
735 
736 	ret = gnutls_fingerprint(digest, &tmp, inh_buf, &inhlen);
737 	gnutls_free(tmp.data);
738 	if (ret != GNUTLS_E_SUCCESS) {
739 		gnutls_assert();
740 		return ret;
741 	}
742 	inh.size = inhlen;
743 	inh.data = inh_buf;
744 
745 	ret = _gnutls_x509_read_value
746 	    (issuer->cert,
747 	     "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey", &tmp);
748 	if (ret != GNUTLS_E_SUCCESS) {
749 		gnutls_assert();
750 		return ret;
751 	}
752 
753 	ret = gnutls_fingerprint(digest, &tmp, ikh_buf, &ikhlen);
754 	gnutls_free(tmp.data);
755 	if (ret != GNUTLS_E_SUCCESS) {
756 		gnutls_assert();
757 		return ret;
758 	}
759 	ikh.size = ikhlen;
760 	ikh.data = ikh_buf;
761 
762 	ret =
763 	    _gnutls_x509_read_value(cert->cert,
764 				    "tbsCertificate.serialNumber", &sn);
765 	if (ret != GNUTLS_E_SUCCESS) {
766 		gnutls_assert();
767 		return ret;
768 	}
769 
770 	ret = gnutls_ocsp_req_add_cert_id(req, digest, &inh, &ikh, &sn);
771 	gnutls_free(sn.data);
772 	if (ret != GNUTLS_E_SUCCESS) {
773 		gnutls_assert();
774 		return ret;
775 	}
776 
777 	return GNUTLS_E_SUCCESS;
778 }
779 
780 /**
781  * gnutls_ocsp_req_get_extension:
782  * @req: should contain a #gnutls_ocsp_req_t type
783  * @indx: Specifies which extension OID to get. Use (0) to get the first one.
784  * @oid: will hold newly allocated buffer with OID of extension, may be NULL
785  * @critical: output variable with critical flag, may be NULL.
786  * @data: will hold newly allocated buffer with extension data, may be NULL
787  *
788  * This function will return all information about the requested
789  * extension in the OCSP request.  The information returned is the
790  * OID, the critical flag, and the data itself.  The extension OID
791  * will be stored as a string.  Any of @oid, @critical, and @data may
792  * be NULL which means that the caller is not interested in getting
793  * that information back.
794  *
795  * The caller needs to deallocate memory by calling gnutls_free() on
796  * @oid->data and @data->data.
797  *
798  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
799  *   negative error code is returned.  If you have reached the last
800  *   extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
801  *   be returned.
802  **/
803 int
gnutls_ocsp_req_get_extension(gnutls_ocsp_req_const_t req,unsigned indx,gnutls_datum_t * oid,unsigned int * critical,gnutls_datum_t * data)804 gnutls_ocsp_req_get_extension(gnutls_ocsp_req_const_t req,
805 			      unsigned indx,
806 			      gnutls_datum_t * oid,
807 			      unsigned int *critical,
808 			      gnutls_datum_t * data)
809 {
810 	int ret;
811 	char str_critical[10];
812 	char name[MAX_NAME_SIZE];
813 	int len;
814 
815 	if (!req) {
816 		gnutls_assert();
817 		return GNUTLS_E_INVALID_REQUEST;
818 	}
819 
820 	snprintf(name, sizeof(name),
821 		 "tbsRequest.requestExtensions.?%u.critical", indx + 1);
822 	len = sizeof(str_critical);
823 	ret = asn1_read_value(req->req, name, str_critical, &len);
824 	if (ret == ASN1_ELEMENT_NOT_FOUND)
825 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
826 	else if (ret != ASN1_SUCCESS) {
827 		gnutls_assert();
828 		return _gnutls_asn2err(ret);
829 	}
830 
831 	if (critical) {
832 		if (str_critical[0] == 'T')
833 			*critical = 1;
834 		else
835 			*critical = 0;
836 	}
837 
838 	if (oid) {
839 		snprintf(name, sizeof(name),
840 			 "tbsRequest.requestExtensions.?%u.extnID",
841 			 indx + 1);
842 		ret = _gnutls_x509_read_value(req->req, name, oid);
843 		if (ret != GNUTLS_E_SUCCESS) {
844 			gnutls_assert();
845 			return ret;
846 		}
847 	}
848 
849 	if (data) {
850 		snprintf(name, sizeof(name),
851 			 "tbsRequest.requestExtensions.?%u.extnValue",
852 			 indx + 1);
853 		ret = _gnutls_x509_read_value(req->req, name, data);
854 		if (ret != GNUTLS_E_SUCCESS) {
855 			gnutls_assert();
856 			if (oid)
857 				gnutls_free(oid->data);
858 			return ret;
859 		}
860 	}
861 
862 	return GNUTLS_E_SUCCESS;
863 }
864 
865 /**
866  * gnutls_ocsp_req_set_extension:
867  * @req: should contain a #gnutls_ocsp_req_t type
868  * @oid: buffer with OID of extension as a string.
869  * @critical: critical flag, normally false.
870  * @data: the extension data
871  *
872  * This function will add an extension to the OCSP request.  Calling
873  * this function multiple times for the same OID will overwrite values
874  * from earlier calls.
875  *
876  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
877  *   negative error code is returned.
878  **/
879 int
gnutls_ocsp_req_set_extension(gnutls_ocsp_req_t req,const char * oid,unsigned int critical,const gnutls_datum_t * data)880 gnutls_ocsp_req_set_extension(gnutls_ocsp_req_t req,
881 			      const char *oid,
882 			      unsigned int critical,
883 			      const gnutls_datum_t * data)
884 {
885 	if (req == NULL || oid == NULL || data == NULL) {
886 		gnutls_assert();
887 		return GNUTLS_E_INVALID_REQUEST;
888 	}
889 
890 	return _gnutls_set_extension(req->req, "tbsRequest.requestExtensions", oid,
891 			     data, critical);
892 }
893 
894 /**
895  * gnutls_ocsp_req_get_nonce:
896  * @req: should contain a #gnutls_ocsp_req_t type
897  * @critical: whether nonce extension is marked critical, or NULL
898  * @nonce: will hold newly allocated buffer with nonce data
899  *
900  * This function will return the OCSP request nonce extension data.
901  *
902  * The caller needs to deallocate memory by calling gnutls_free() on
903  * @nonce->data.
904  *
905  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
906  *   negative error code is returned.
907  **/
908 int
gnutls_ocsp_req_get_nonce(gnutls_ocsp_req_const_t req,unsigned int * critical,gnutls_datum_t * nonce)909 gnutls_ocsp_req_get_nonce(gnutls_ocsp_req_const_t req,
910 			  unsigned int *critical, gnutls_datum_t * nonce)
911 {
912 	int ret;
913 	gnutls_datum_t tmp;
914 
915 	if (req == NULL || nonce == NULL) {
916 		gnutls_assert();
917 		return GNUTLS_E_INVALID_REQUEST;
918 	}
919 
920 	ret = _gnutls_get_extension(req->req, "tbsRequest.requestExtensions",
921 			    GNUTLS_OCSP_NONCE, 0, &tmp, critical);
922 	if (ret != GNUTLS_E_SUCCESS) {
923 		gnutls_assert();
924 		return ret;
925 	}
926 
927 	ret =
928 	    _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING, tmp.data,
929 				       (size_t) tmp.size, nonce, 0);
930 	if (ret < 0) {
931 		gnutls_assert();
932 		gnutls_free(tmp.data);
933 		return ret;
934 	}
935 
936 	gnutls_free(tmp.data);
937 
938 	return GNUTLS_E_SUCCESS;
939 }
940 
941 /**
942  * gnutls_ocsp_req_set_nonce:
943  * @req: should contain a #gnutls_ocsp_req_t type
944  * @critical: critical flag, normally false.
945  * @nonce: the nonce data
946  *
947  * This function will add an nonce extension to the OCSP request.
948  * Calling this function multiple times will overwrite values from
949  * earlier calls.
950  *
951  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
952  *   negative error code is returned.
953  **/
954 int
gnutls_ocsp_req_set_nonce(gnutls_ocsp_req_t req,unsigned int critical,const gnutls_datum_t * nonce)955 gnutls_ocsp_req_set_nonce(gnutls_ocsp_req_t req,
956 			  unsigned int critical,
957 			  const gnutls_datum_t * nonce)
958 {
959 	int ret;
960 	gnutls_datum_t dernonce;
961 	unsigned char temp[SIZEOF_UNSIGNED_LONG_INT + 1];
962 	int len;
963 
964 	if (req == NULL || nonce == NULL) {
965 		gnutls_assert();
966 		return GNUTLS_E_INVALID_REQUEST;
967 	}
968 
969 	asn1_length_der(nonce->size, temp, &len);
970 
971 	dernonce.size = 1 + len + nonce->size;
972 	dernonce.data = gnutls_malloc(dernonce.size);
973 	if (dernonce.data == NULL) {
974 		gnutls_assert();
975 		return GNUTLS_E_MEMORY_ERROR;
976 	}
977 
978 	dernonce.data[0] = '\x04';
979 	memcpy(dernonce.data + 1, temp, len);
980 	memcpy(dernonce.data + 1 + len, nonce->data, nonce->size);
981 
982 	ret = _gnutls_set_extension(req->req, "tbsRequest.requestExtensions",
983 			    GNUTLS_OCSP_NONCE, &dernonce, critical);
984 	gnutls_free(dernonce.data);
985 	if (ret != GNUTLS_E_SUCCESS) {
986 		gnutls_assert();
987 		return ret;
988 	}
989 
990 	return ret;
991 }
992 
993 /**
994  * gnutls_ocsp_req_randomize_nonce:
995  * @req: should contain a #gnutls_ocsp_req_t type
996  *
997  * This function will add or update an nonce extension to the OCSP
998  * request with a newly generated random value.
999  *
1000  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1001  *   negative error code is returned.
1002  **/
gnutls_ocsp_req_randomize_nonce(gnutls_ocsp_req_t req)1003 int gnutls_ocsp_req_randomize_nonce(gnutls_ocsp_req_t req)
1004 {
1005 	int ret;
1006 	uint8_t rndbuf[23];
1007 	gnutls_datum_t nonce = { rndbuf, sizeof(rndbuf) };
1008 
1009 	if (req == NULL) {
1010 		gnutls_assert();
1011 		return GNUTLS_E_INVALID_REQUEST;
1012 	}
1013 
1014 	ret = gnutls_rnd(GNUTLS_RND_NONCE, rndbuf, sizeof(rndbuf));
1015 	if (ret != GNUTLS_E_SUCCESS) {
1016 		gnutls_assert();
1017 		return ret;
1018 	}
1019 
1020 	ret = gnutls_ocsp_req_set_nonce(req, 0, &nonce);
1021 	if (ret != GNUTLS_E_SUCCESS) {
1022 		gnutls_assert();
1023 		return ret;
1024 	}
1025 
1026 	return GNUTLS_E_SUCCESS;
1027 }
1028 
1029 /**
1030  * gnutls_ocsp_resp_get_status:
1031  * @resp: should contain a #gnutls_ocsp_resp_t type
1032  *
1033  * This function will return the status of a OCSP response, an
1034  * #gnutls_ocsp_resp_status_t enumeration.
1035  *
1036  * Returns: status of OCSP request as a #gnutls_ocsp_resp_status_t, or
1037  *   a negative error code on error.
1038  **/
gnutls_ocsp_resp_get_status(gnutls_ocsp_resp_const_t resp)1039 int gnutls_ocsp_resp_get_status(gnutls_ocsp_resp_const_t resp)
1040 {
1041 	uint8_t str[1];
1042 	int len, ret;
1043 
1044 	if (resp == NULL) {
1045 		gnutls_assert();
1046 		return GNUTLS_E_INVALID_REQUEST;
1047 	}
1048 
1049 	len = sizeof(str);
1050 	ret = asn1_read_value(resp->resp, "responseStatus", str, &len);
1051 	if (ret != ASN1_SUCCESS) {
1052 		gnutls_assert();
1053 		return _gnutls_asn2err(ret);
1054 	}
1055 
1056 	if (len != 1)
1057 		return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
1058 
1059 	switch (str[0]) {
1060 	case GNUTLS_OCSP_RESP_SUCCESSFUL:
1061 	case GNUTLS_OCSP_RESP_MALFORMEDREQUEST:
1062 	case GNUTLS_OCSP_RESP_INTERNALERROR:
1063 	case GNUTLS_OCSP_RESP_TRYLATER:
1064 	case GNUTLS_OCSP_RESP_SIGREQUIRED:
1065 	case GNUTLS_OCSP_RESP_UNAUTHORIZED:
1066 		break;
1067 	default:
1068 		return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
1069 	}
1070 
1071 	return (int) str[0];
1072 }
1073 
1074 /**
1075  * gnutls_ocsp_resp_get_response:
1076  * @resp: should contain a #gnutls_ocsp_resp_t type
1077  * @response_type_oid: newly allocated output buffer with response type OID
1078  * @response: newly allocated output buffer with DER encoded response
1079  *
1080  * This function will extract the response type OID in and the
1081  * response data from an OCSP response.  Normally the
1082  * @response_type_oid is always "1.3.6.1.5.5.7.48.1.1" which means the
1083  * @response should be decoded as a Basic OCSP Response, but
1084  * technically other response types could be used.
1085  *
1086  * This function is typically only useful when you want to extract the
1087  * response type OID of an response for diagnostic purposes.
1088  * Otherwise gnutls_ocsp_resp_import() will decode the basic OCSP
1089  * response part and the caller need not worry about that aspect.
1090  *
1091  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1092  *   negative error value.
1093  **/
1094 int
gnutls_ocsp_resp_get_response(gnutls_ocsp_resp_const_t resp,gnutls_datum_t * response_type_oid,gnutls_datum_t * response)1095 gnutls_ocsp_resp_get_response(gnutls_ocsp_resp_const_t resp,
1096 			      gnutls_datum_t * response_type_oid,
1097 			      gnutls_datum_t * response)
1098 {
1099 	int ret;
1100 
1101 	if (resp == NULL) {
1102 		gnutls_assert();
1103 		return GNUTLS_E_INVALID_REQUEST;
1104 	}
1105 
1106 	if (response_type_oid != NULL) {
1107 		ret =
1108 		    _gnutls_x509_read_value(resp->resp,
1109 					    "responseBytes.responseType",
1110 					    response_type_oid);
1111 		if (ret < 0) {
1112 			gnutls_assert();
1113 			return ret;
1114 		}
1115 	}
1116 
1117 	if (response != NULL) {
1118 		ret =
1119 		    _gnutls_x509_read_value(resp->resp,
1120 					    "responseBytes.response",
1121 					    response);
1122 		if (ret < 0) {
1123 			gnutls_assert();
1124 			return ret;
1125 		}
1126 	}
1127 
1128 	return GNUTLS_E_SUCCESS;
1129 }
1130 
1131 /**
1132  * gnutls_ocsp_resp_get_version:
1133  * @resp: should contain a #gnutls_ocsp_resp_t type
1134  *
1135  * This function will return the version of the Basic OCSP Response.
1136  * Typically this is always 1 indicating version 1.
1137  *
1138  * Returns: version of Basic OCSP response, or a negative error code
1139  *   on error.
1140  **/
gnutls_ocsp_resp_get_version(gnutls_ocsp_resp_const_t resp)1141 int gnutls_ocsp_resp_get_version(gnutls_ocsp_resp_const_t resp)
1142 {
1143 	if (resp == NULL) {
1144 		gnutls_assert();
1145 		return GNUTLS_E_INVALID_REQUEST;
1146 	}
1147 
1148 	return _gnutls_x509_get_version(resp->resp, "tbsResponseData.version");
1149 }
1150 
1151 /**
1152  * gnutls_ocsp_resp_get_responder:
1153  * @resp: should contain a #gnutls_ocsp_resp_t type
1154  * @dn: newly allocated buffer with name
1155  *
1156  * This function will extract the name of the Basic OCSP Response in
1157  * the provided buffer. The name will be in the form
1158  * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
1159  * will be ASCII or UTF-8 encoded, depending on the certificate data.
1160  *
1161  * If the responder ID is not a name but a hash, this function
1162  * will return zero and the @dn elements will be set to %NULL.
1163  *
1164  * The caller needs to deallocate memory by calling gnutls_free() on
1165  * @dn->data.
1166  *
1167  * This function does not output a fully RFC4514 compliant string, if
1168  * that is required see gnutls_ocsp_resp_get_responder2().
1169  *
1170  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1171  *   negative error code is returned. When no data exist it will
1172  *   return success and set @dn elements to zero.
1173  **/
1174 int
gnutls_ocsp_resp_get_responder(gnutls_ocsp_resp_const_t resp,gnutls_datum_t * dn)1175 gnutls_ocsp_resp_get_responder(gnutls_ocsp_resp_const_t resp,
1176 			       gnutls_datum_t * dn)
1177 {
1178 	int ret;
1179 
1180 	ret = gnutls_ocsp_resp_get_responder2(resp, dn, GNUTLS_X509_DN_FLAG_COMPAT);
1181 	if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1182 		dn->data = NULL;
1183 		dn->size = 0;
1184 		return 0; /* for backwards compatibility */
1185 	}
1186 
1187 	return ret;
1188 }
1189 
1190 /**
1191  * gnutls_ocsp_resp_get_responder2:
1192  * @resp: should contain a #gnutls_ocsp_resp_t type
1193  * @dn: newly allocated buffer with name
1194  * @flags: zero or %GNUTLS_X509_DN_FLAG_COMPAT
1195  *
1196  * This function will extract the name of the Basic OCSP Response in
1197  * the provided buffer. The name will be in the form
1198  * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
1199  * will be ASCII or UTF-8 encoded, depending on the certificate data.
1200  *
1201  * If the responder ID is not a name but a hash, this function
1202  * will return zero and the @dn elements will be set to %NULL.
1203  *
1204  * The caller needs to deallocate memory by calling gnutls_free() on
1205  * @dn->data.
1206  *
1207  * When the flag %GNUTLS_X509_DN_FLAG_COMPAT is specified, the output
1208  * format will match the format output by previous to 3.5.6 versions of GnuTLS
1209  * which was not not fully RFC4514-compliant.
1210  *
1211  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1212  *   negative error code is returned. When no data exist it will return
1213  *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE.
1214  **/
1215 int
gnutls_ocsp_resp_get_responder2(gnutls_ocsp_resp_const_t resp,gnutls_datum_t * dn,unsigned flags)1216 gnutls_ocsp_resp_get_responder2(gnutls_ocsp_resp_const_t resp,
1217 			        gnutls_datum_t * dn, unsigned flags)
1218 {
1219 	if (resp == NULL || dn == NULL) {
1220 		gnutls_assert();
1221 		return GNUTLS_E_INVALID_REQUEST;
1222 	}
1223 
1224 	dn->data = NULL;
1225 	dn->size = 0;
1226 
1227 	return _gnutls_x509_get_dn(resp->basicresp,
1228 				  "tbsResponseData.responderID.byName",
1229 				  dn, flags);
1230 }
1231 
1232 /**
1233  * gnutls_ocsp_resp_get_responder_by_key:
1234  * @resp: should contain a #gnutls_ocsp_resp_t type
1235  * @type: should be %GNUTLS_OCSP_RESP_ID_KEY or %GNUTLS_OCSP_RESP_ID_DN
1236  * @raw: newly allocated buffer with the raw ID
1237  *
1238  * This function will extract the raw key (or DN) ID of the Basic OCSP Response in
1239  * the provided buffer. If the responder ID is not a key ID then
1240  * this function will return %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE.
1241  *
1242  * The caller needs to deallocate memory by calling gnutls_free() on
1243  * @dn->data.
1244  *
1245  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1246  *   negative error code is returned.
1247  **/
1248 int
gnutls_ocsp_resp_get_responder_raw_id(gnutls_ocsp_resp_const_t resp,unsigned type,gnutls_datum_t * raw)1249 gnutls_ocsp_resp_get_responder_raw_id(gnutls_ocsp_resp_const_t resp,
1250 				      unsigned type,
1251 				      gnutls_datum_t * raw)
1252 {
1253 	int ret;
1254 
1255 	if (resp == NULL || raw == NULL) {
1256 		gnutls_assert();
1257 		return GNUTLS_E_INVALID_REQUEST;
1258 	}
1259 
1260 	if (type == GNUTLS_OCSP_RESP_ID_KEY)
1261 		ret = _gnutls_x509_read_value(resp->basicresp, "tbsResponseData.responderID.byKey", raw);
1262 	else {
1263 		gnutls_datum_t tmp;
1264 
1265 		/* simply reading a CHOICE of CHOICE value doesn't work in libtasn1 */
1266 		ret = _gnutls_x509_get_raw_field2(resp->basicresp, &resp->der,
1267 					  "tbsResponseData.responderID.byName",
1268 					  &tmp);
1269 		if (ret >= 0) {
1270 			int real;
1271 			/* skip the tag */
1272 			if (tmp.size < 2) {
1273 				gnutls_assert();
1274 				ret = GNUTLS_E_ASN1_GENERIC_ERROR;
1275 				goto fail;
1276 			}
1277 
1278 			tmp.data++;
1279 			tmp.size--;
1280 
1281 			ret = asn1_get_length_der(tmp.data, tmp.size, &real);
1282 			if (ret < 0) {
1283 				gnutls_assert();
1284 				ret = GNUTLS_E_ASN1_GENERIC_ERROR;
1285 				goto fail;
1286 			}
1287 
1288 			if (tmp.size < (unsigned)real) {
1289 				gnutls_assert();
1290 				ret = GNUTLS_E_ASN1_GENERIC_ERROR;
1291 				goto fail;
1292 			}
1293 
1294 			tmp.data+=real;
1295 			tmp.size-=real;
1296 
1297 			ret = _gnutls_set_datum(raw, tmp.data, tmp.size);
1298 		}
1299 	}
1300 
1301 	if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND || ret == GNUTLS_E_ASN1_VALUE_NOT_FOUND)
1302 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1303 
1304  fail:
1305 	return ret;
1306 }
1307 
1308 /**
1309  * gnutls_ocsp_resp_get_produced:
1310  * @resp: should contain a #gnutls_ocsp_resp_t type
1311  *
1312  * This function will return the time when the OCSP response was
1313  * signed.
1314  *
1315  * Returns: signing time, or (time_t)-1 on error.
1316  **/
gnutls_ocsp_resp_get_produced(gnutls_ocsp_resp_const_t resp)1317 time_t gnutls_ocsp_resp_get_produced(gnutls_ocsp_resp_const_t resp)
1318 {
1319 	char ttime[MAX_TIME];
1320 	int len, ret;
1321 	time_t c_time;
1322 
1323 	if (resp == NULL || resp->basicresp == NULL) {
1324 		gnutls_assert();
1325 		return (time_t) (-1);
1326 	}
1327 
1328 	len = sizeof(ttime) - 1;
1329 	ret =
1330 	    asn1_read_value(resp->basicresp, "tbsResponseData.producedAt",
1331 			    ttime, &len);
1332 	if (ret != ASN1_SUCCESS) {
1333 		gnutls_assert();
1334 		return (time_t) (-1);
1335 	}
1336 
1337 	c_time = _gnutls_x509_generalTime2gtime(ttime);
1338 
1339 	return c_time;
1340 }
1341 
1342 /**
1343  * gnutls_ocsp_resp_check_crt:
1344  * @resp: should contain a #gnutls_ocsp_resp_t type
1345  * @indx: Specifies response number to get. Use (0) to get the first one.
1346  * @crt: The certificate to check
1347  *
1348  * This function will check whether the OCSP response
1349  * is about the provided certificate.
1350  *
1351  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1352  *   negative error code is returned.
1353  *
1354  * Since: 3.1.3
1355  **/
1356 int
gnutls_ocsp_resp_check_crt(gnutls_ocsp_resp_const_t resp,unsigned int indx,gnutls_x509_crt_t crt)1357 gnutls_ocsp_resp_check_crt(gnutls_ocsp_resp_const_t resp,
1358 			   unsigned int indx, gnutls_x509_crt_t crt)
1359 {
1360 	int ret;
1361 	gnutls_digest_algorithm_t digest;
1362 	gnutls_datum_t rdn_hash = { NULL, 0 }, rserial = {
1363 	NULL, 0};
1364 	gnutls_datum_t cserial = { NULL, 0 };
1365 	gnutls_datum_t dn = { NULL, 0 };
1366 	uint8_t cdn_hash[MAX_HASH_SIZE];
1367 	size_t t, hash_len;
1368 
1369 	if (resp == NULL)
1370 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1371 
1372 	ret =
1373 	    gnutls_ocsp_resp_get_single(resp, indx, &digest, &rdn_hash,
1374 					NULL, &rserial, NULL, NULL, NULL,
1375 					NULL, NULL);
1376 	if (ret < 0)
1377 		return gnutls_assert_val(ret);
1378 
1379 	if (rserial.size == 0 || digest == GNUTLS_DIG_UNKNOWN) {
1380 		ret = gnutls_assert_val(GNUTLS_E_OCSP_RESPONSE_ERROR);
1381 		goto cleanup;
1382 	}
1383 
1384 	hash_len = _gnutls_hash_get_algo_len(hash_to_entry(digest));
1385 	if (hash_len != rdn_hash.size) {
1386 		ret = gnutls_assert_val(GNUTLS_E_OCSP_RESPONSE_ERROR);
1387 		goto cleanup;
1388 	}
1389 
1390 	cserial.size = rserial.size;
1391 	cserial.data = gnutls_malloc(cserial.size);
1392 	if (cserial.data == NULL) {
1393 		ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1394 		goto cleanup;
1395 	}
1396 
1397 	t = cserial.size;
1398 	ret = gnutls_x509_crt_get_serial(crt, cserial.data, &t);
1399 	if (ret < 0) {
1400 		gnutls_assert();
1401 		goto cleanup;
1402 	}
1403 	cserial.size = t;
1404 
1405 	if (rserial.size != cserial.size
1406 	    || memcmp(cserial.data, rserial.data, rserial.size) != 0) {
1407 		ret = GNUTLS_E_OCSP_RESPONSE_ERROR;
1408 		gnutls_assert();
1409 		goto cleanup;
1410 	}
1411 
1412 	ret = gnutls_x509_crt_get_raw_issuer_dn(crt, &dn);
1413 	if (ret < 0) {
1414 		gnutls_assert();
1415 		goto cleanup;
1416 	}
1417 
1418 	ret = _gnutls_hash_fast(digest, dn.data, dn.size, cdn_hash);
1419 	if (ret < 0) {
1420 		gnutls_assert();
1421 		goto cleanup;
1422 	}
1423 
1424 	if (memcmp(cdn_hash, rdn_hash.data, hash_len) != 0) {
1425 		ret = GNUTLS_E_OCSP_RESPONSE_ERROR;
1426 		gnutls_assert();
1427 		goto cleanup;
1428 	}
1429 
1430 	ret = 0;
1431 
1432       cleanup:
1433 	gnutls_free(rdn_hash.data);
1434 	gnutls_free(rserial.data);
1435 	gnutls_free(cserial.data);
1436 	gnutls_free(dn.data);
1437 
1438 	return ret;
1439 }
1440 
1441 /**
1442  * gnutls_ocsp_resp_get_single:
1443  * @resp: should contain a #gnutls_ocsp_resp_t type
1444  * @indx: Specifies response number to get. Use (0) to get the first one.
1445  * @digest: output variable with #gnutls_digest_algorithm_t hash algorithm
1446  * @issuer_name_hash: output buffer with hash of issuer's DN
1447  * @issuer_key_hash: output buffer with hash of issuer's public key
1448  * @serial_number: output buffer with serial number of certificate to check
1449  * @cert_status: a certificate status, a #gnutls_ocsp_cert_status_t enum.
1450  * @this_update: time at which the status is known to be correct.
1451  * @next_update: when newer information will be available, or (time_t)-1 if unspecified
1452  * @revocation_time: when @cert_status is %GNUTLS_OCSP_CERT_REVOKED, holds time of revocation.
1453  * @revocation_reason: revocation reason, a #gnutls_x509_crl_reason_t enum.
1454  *
1455  * This function will return the certificate information of the
1456  * @indx'ed response in the Basic OCSP Response @resp.  The
1457  * information returned corresponds to the OCSP SingleResponse structure
1458  * except the final singleExtensions.
1459  *
1460  * Each of the pointers to output variables may be NULL to indicate
1461  * that the caller is not interested in that value.
1462  *
1463  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1464  *   negative error code is returned.  If you have reached the last
1465  *   CertID available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1466  *   returned.
1467  **/
1468 int
gnutls_ocsp_resp_get_single(gnutls_ocsp_resp_const_t resp,unsigned indx,gnutls_digest_algorithm_t * digest,gnutls_datum_t * issuer_name_hash,gnutls_datum_t * issuer_key_hash,gnutls_datum_t * serial_number,unsigned int * cert_status,time_t * this_update,time_t * next_update,time_t * revocation_time,unsigned int * revocation_reason)1469 gnutls_ocsp_resp_get_single(gnutls_ocsp_resp_const_t resp,
1470 			    unsigned indx,
1471 			    gnutls_digest_algorithm_t * digest,
1472 			    gnutls_datum_t * issuer_name_hash,
1473 			    gnutls_datum_t * issuer_key_hash,
1474 			    gnutls_datum_t * serial_number,
1475 			    unsigned int *cert_status,
1476 			    time_t * this_update,
1477 			    time_t * next_update,
1478 			    time_t * revocation_time,
1479 			    unsigned int *revocation_reason)
1480 {
1481 	char name[MAX_NAME_SIZE];
1482 	int ret, result;
1483 	char oidtmp[MAX_OID_SIZE];
1484 	int len;
1485 	char ttime[MAX_TIME];
1486 
1487 	/* initialize any allocated values to NULL, to allow deallocation
1488 	 * on error. */
1489 	if (issuer_name_hash)
1490 		issuer_name_hash->data = NULL;
1491 	if (issuer_key_hash)
1492 		issuer_key_hash->data = NULL;
1493 	if (serial_number)
1494 		serial_number->data = NULL;
1495 
1496 	if (digest) {
1497 		snprintf(name, sizeof(name),
1498 			 "tbsResponseData.responses.?%u.certID.hashAlgorithm.algorithm",
1499 			 indx + 1);
1500 		len = sizeof(oidtmp);
1501 		result = asn1_read_value(resp->basicresp, name, oidtmp, &len);
1502 		if (result == ASN1_ELEMENT_NOT_FOUND) {
1503 			return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1504 		} else if (result != ASN1_SUCCESS) {
1505 			gnutls_assert();
1506 			return _gnutls_asn2err(result);
1507 		}
1508 
1509 		ret = gnutls_oid_to_digest(oidtmp);
1510 		if (ret < 0) {
1511 			gnutls_assert();
1512 			return ret;
1513 		}
1514 
1515 		*digest = ret;
1516 	}
1517 
1518 	if (issuer_name_hash) {
1519 		snprintf(name, sizeof(name),
1520 			 "tbsResponseData.responses.?%u.certID.issuerNameHash",
1521 			 indx + 1);
1522 		ret = _gnutls_x509_read_value(resp->basicresp, name,
1523 					      issuer_name_hash);
1524 		if (ret < 0) {
1525 			gnutls_assert();
1526 			return ret;
1527 		}
1528 	}
1529 
1530 	if (issuer_key_hash) {
1531 		snprintf(name, sizeof(name),
1532 			 "tbsResponseData.responses.?%u.certID.issuerKeyHash",
1533 			 indx + 1);
1534 		ret = _gnutls_x509_read_value(resp->basicresp, name,
1535 					      issuer_key_hash);
1536 		if (ret < 0) {
1537 			gnutls_assert();
1538 			goto fail;
1539 		}
1540 	}
1541 
1542 	if (serial_number) {
1543 		snprintf(name, sizeof(name),
1544 			 "tbsResponseData.responses.?%u.certID.serialNumber",
1545 			 indx + 1);
1546 		ret = _gnutls_x509_read_value(resp->basicresp, name,
1547 					      serial_number);
1548 		if (ret < 0) {
1549 			gnutls_assert();
1550 			goto fail;
1551 		}
1552 	}
1553 
1554 	if (cert_status) {
1555 		snprintf(name, sizeof(name),
1556 			 "tbsResponseData.responses.?%u.certStatus",
1557 			 indx + 1);
1558 
1559 		len = sizeof(oidtmp);
1560 		result = asn1_read_value(resp->basicresp, name, oidtmp, &len);
1561 		if (result == ASN1_ELEMENT_NOT_FOUND) {
1562 			gnutls_assert();
1563 			ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1564 			goto fail;
1565 		} else if (result != ASN1_SUCCESS) {
1566 			gnutls_assert();
1567 			ret = _gnutls_asn2err(result);
1568 			goto fail;
1569 		}
1570 
1571 		if (len == 5 && memcmp(oidtmp, "good", len) == 0)
1572 			*cert_status = GNUTLS_OCSP_CERT_GOOD;
1573 		else if (len == 8
1574 			 && memcmp(oidtmp, "revoked", len) == 0)
1575 			*cert_status = GNUTLS_OCSP_CERT_REVOKED;
1576 		else if (len == 8
1577 			 && memcmp(oidtmp, "unknown", len) == 0)
1578 			*cert_status = GNUTLS_OCSP_CERT_UNKNOWN;
1579 		else {
1580 			gnutls_assert();
1581 			ret = GNUTLS_E_ASN1_DER_ERROR;
1582 			goto fail;
1583 		}
1584 	}
1585 
1586 	if (this_update) {
1587 		snprintf(name, sizeof(name),
1588 			 "tbsResponseData.responses.?%u.thisUpdate",
1589 			 indx + 1);
1590 		len = sizeof(ttime) - 1;
1591 		result = asn1_read_value(resp->basicresp, name, ttime, &len);
1592 		if (result != ASN1_SUCCESS) {
1593 			gnutls_assert();
1594 			ret = GNUTLS_E_ASN1_DER_ERROR;
1595 			goto fail;
1596 		} else {
1597 			*this_update =
1598 			    _gnutls_x509_generalTime2gtime(ttime);
1599 		}
1600 	}
1601 
1602 	if (next_update) {
1603 		snprintf(name, sizeof(name),
1604 			 "tbsResponseData.responses.?%u.nextUpdate",
1605 			 indx + 1);
1606 		len = sizeof(ttime) - 1;
1607 		result = asn1_read_value(resp->basicresp, name, ttime, &len);
1608 		if (result != ASN1_SUCCESS) {
1609 			gnutls_assert();
1610 			*next_update = (time_t) (-1);
1611 		} else
1612 			*next_update =
1613 			    _gnutls_x509_generalTime2gtime(ttime);
1614 	}
1615 
1616 	if (revocation_time) {
1617 		snprintf(name, sizeof(name),
1618 			 "tbsResponseData.responses.?%u.certStatus."
1619 			 "revoked.revocationTime", indx + 1);
1620 		len = sizeof(ttime) - 1;
1621 		result = asn1_read_value(resp->basicresp, name, ttime, &len);
1622 		if (result != ASN1_SUCCESS) {
1623 			gnutls_assert();
1624 			*revocation_time = (time_t) (-1);
1625 		} else
1626 			*revocation_time =
1627 			    _gnutls_x509_generalTime2gtime(ttime);
1628 	}
1629 
1630 	/* revocation_reason */
1631 	if (revocation_reason) {
1632 		snprintf(name, sizeof(name),
1633 			 "tbsResponseData.responses.?%u.certStatus."
1634 			 "revoked.revocationReason", indx + 1);
1635 
1636 		ret = _gnutls_x509_read_uint(resp->basicresp, name,
1637 					     revocation_reason);
1638 		if (ret < 0)
1639 			*revocation_reason =
1640 			    GNUTLS_X509_CRLREASON_UNSPECIFIED;
1641 	}
1642 
1643 	return GNUTLS_E_SUCCESS;
1644  fail:
1645 	if (issuer_name_hash)
1646 		gnutls_free(issuer_name_hash->data);
1647 	if (issuer_key_hash)
1648 		gnutls_free(issuer_key_hash->data);
1649 	if (serial_number)
1650 		gnutls_free(serial_number->data);
1651 	return ret;
1652 }
1653 
1654 /**
1655  * gnutls_ocsp_resp_get_extension:
1656  * @resp: should contain a #gnutls_ocsp_resp_t type
1657  * @indx: Specifies which extension OID to get. Use (0) to get the first one.
1658  * @oid: will hold newly allocated buffer with OID of extension, may be NULL
1659  * @critical: output variable with critical flag, may be NULL.
1660  * @data: will hold newly allocated buffer with extension data, may be NULL
1661  *
1662  * This function will return all information about the requested
1663  * extension in the OCSP response.  The information returned is the
1664  * OID, the critical flag, and the data itself.  The extension OID
1665  * will be stored as a string.  Any of @oid, @critical, and @data may
1666  * be NULL which means that the caller is not interested in getting
1667  * that information back.
1668  *
1669  * The caller needs to deallocate memory by calling gnutls_free() on
1670  * @oid->data and @data->data.
1671  *
1672  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1673  *   negative error code is returned.  If you have reached the last
1674  *   extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
1675  *   be returned.
1676  **/
1677 int
gnutls_ocsp_resp_get_extension(gnutls_ocsp_resp_const_t resp,unsigned indx,gnutls_datum_t * oid,unsigned int * critical,gnutls_datum_t * data)1678 gnutls_ocsp_resp_get_extension(gnutls_ocsp_resp_const_t resp,
1679 			       unsigned indx,
1680 			       gnutls_datum_t * oid,
1681 			       unsigned int *critical,
1682 			       gnutls_datum_t * data)
1683 {
1684 	int ret;
1685 	char str_critical[10];
1686 	char name[MAX_NAME_SIZE];
1687 	int len;
1688 
1689 	if (!resp) {
1690 		gnutls_assert();
1691 		return GNUTLS_E_INVALID_REQUEST;
1692 	}
1693 
1694 	snprintf(name, sizeof(name),
1695 		 "tbsResponseData.responseExtensions.?%u.critical",
1696 		 indx + 1);
1697 	len = sizeof(str_critical);
1698 	ret = asn1_read_value(resp->basicresp, name, str_critical, &len);
1699 	if (ret == ASN1_ELEMENT_NOT_FOUND)
1700 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1701 	else if (ret != ASN1_SUCCESS) {
1702 		gnutls_assert();
1703 		return _gnutls_asn2err(ret);
1704 	}
1705 
1706 	if (critical) {
1707 		if (str_critical[0] == 'T')
1708 			*critical = 1;
1709 		else
1710 			*critical = 0;
1711 	}
1712 
1713 	if (oid) {
1714 		snprintf(name, sizeof(name),
1715 			 "tbsResponseData.responseExtensions.?%u.extnID",
1716 			 indx + 1);
1717 		ret = _gnutls_x509_read_value(resp->basicresp, name, oid);
1718 		if (ret != GNUTLS_E_SUCCESS) {
1719 			gnutls_assert();
1720 			return ret;
1721 		}
1722 	}
1723 
1724 	if (data) {
1725 		snprintf(name, sizeof(name),
1726 			 "tbsResponseData.responseExtensions.?%u.extnValue",
1727 			 indx + 1);
1728 		ret = _gnutls_x509_read_value(resp->basicresp, name, data);
1729 		if (ret != GNUTLS_E_SUCCESS) {
1730 			gnutls_assert();
1731 			if (oid)
1732 				gnutls_free(oid->data);
1733 			return ret;
1734 		}
1735 	}
1736 
1737 	return GNUTLS_E_SUCCESS;
1738 }
1739 
1740 /**
1741  * gnutls_ocsp_resp_get_nonce:
1742  * @resp: should contain a #gnutls_ocsp_resp_t type
1743  * @critical: whether nonce extension is marked critical
1744  * @nonce: will hold newly allocated buffer with nonce data
1745  *
1746  * This function will return the Basic OCSP Response nonce extension
1747  * data.
1748  *
1749  * The caller needs to deallocate memory by calling gnutls_free() on
1750  * @nonce->data.
1751  *
1752  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1753  *   negative error code is returned.
1754  **/
1755 int
gnutls_ocsp_resp_get_nonce(gnutls_ocsp_resp_const_t resp,unsigned int * critical,gnutls_datum_t * nonce)1756 gnutls_ocsp_resp_get_nonce(gnutls_ocsp_resp_const_t resp,
1757 			   unsigned int *critical, gnutls_datum_t * nonce)
1758 {
1759 	int ret;
1760 	gnutls_datum_t tmp;
1761 
1762 	ret =
1763 	    _gnutls_get_extension(resp->basicresp,
1764 			  "tbsResponseData.responseExtensions",
1765 			  GNUTLS_OCSP_NONCE, 0, &tmp, critical);
1766 	if (ret != GNUTLS_E_SUCCESS) {
1767 		gnutls_assert();
1768 		return ret;
1769 	}
1770 
1771 	ret =
1772 	    _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING, tmp.data,
1773 				       (size_t) tmp.size, nonce, 0);
1774 	if (ret < 0) {
1775 		gnutls_assert();
1776 		gnutls_free(tmp.data);
1777 		return ret;
1778 	}
1779 
1780 	gnutls_free(tmp.data);
1781 
1782 	return GNUTLS_E_SUCCESS;
1783 }
1784 
1785 /**
1786  * gnutls_ocsp_resp_get_signature_algorithm:
1787  * @resp: should contain a #gnutls_ocsp_resp_t type
1788  *
1789  * This function will return a value of the #gnutls_sign_algorithm_t
1790  * enumeration that is the signature algorithm that has been used to
1791  * sign the OCSP response.
1792  *
1793  * Returns: a #gnutls_sign_algorithm_t value, or a negative error code
1794  *   on error.
1795  **/
gnutls_ocsp_resp_get_signature_algorithm(gnutls_ocsp_resp_const_t resp)1796 int gnutls_ocsp_resp_get_signature_algorithm(gnutls_ocsp_resp_const_t resp)
1797 {
1798 	int ret;
1799 	gnutls_datum_t sa;
1800 
1801 	ret = _gnutls_x509_read_value(resp->basicresp,
1802 				      "signatureAlgorithm.algorithm", &sa);
1803 	if (ret < 0) {
1804 		gnutls_assert();
1805 		return ret;
1806 	}
1807 
1808 	ret = gnutls_oid_to_sign((char *) sa.data);
1809 
1810 	_gnutls_free_datum(&sa);
1811 
1812 	return ret;
1813 }
1814 
1815 /**
1816  * gnutls_ocsp_resp_get_signature:
1817  * @resp: should contain a #gnutls_ocsp_resp_t type
1818  * @sig: newly allocated output buffer with signature data
1819  *
1820  * This function will extract the signature field of a OCSP response.
1821  *
1822  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1823  *   negative error value.
1824  **/
1825 int
gnutls_ocsp_resp_get_signature(gnutls_ocsp_resp_const_t resp,gnutls_datum_t * sig)1826 gnutls_ocsp_resp_get_signature(gnutls_ocsp_resp_const_t resp,
1827 			       gnutls_datum_t * sig)
1828 {
1829 	int ret;
1830 
1831 	if (resp == NULL || sig == NULL) {
1832 		gnutls_assert();
1833 		return GNUTLS_E_INVALID_REQUEST;
1834 	}
1835 
1836 	ret = _gnutls_x509_read_value(resp->basicresp, "signature", sig);
1837 	if (ret != GNUTLS_E_SUCCESS) {
1838 		gnutls_assert();
1839 		return ret;
1840 	}
1841 
1842 	return GNUTLS_E_SUCCESS;
1843 }
1844 
1845 /**
1846  * gnutls_ocsp_resp_get_certs:
1847  * @resp: should contain a #gnutls_ocsp_resp_t type
1848  * @certs: newly allocated array with #gnutls_x509_crt_t certificates
1849  * @ncerts: output variable with number of allocated certs.
1850  *
1851  * This function will extract the X.509 certificates found in the
1852  * Basic OCSP Response.  The @certs output variable will hold a newly
1853  * allocated zero-terminated array with X.509 certificates.
1854  *
1855  * Every certificate in the array needs to be de-allocated with
1856  * gnutls_x509_crt_deinit() and the array itself must be freed using
1857  * gnutls_free().
1858  *
1859  * Both the @certs and @ncerts variables may be NULL.  Then the
1860  * function will work as normal but will not return the NULL:d
1861  * information.  This can be used to get the number of certificates
1862  * only, or to just get the certificate array without its size.
1863  *
1864  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1865  *   negative error value.
1866  **/
1867 int
gnutls_ocsp_resp_get_certs(gnutls_ocsp_resp_const_t resp,gnutls_x509_crt_t ** certs,size_t * ncerts)1868 gnutls_ocsp_resp_get_certs(gnutls_ocsp_resp_const_t resp,
1869 			   gnutls_x509_crt_t ** certs, size_t * ncerts)
1870 {
1871 	int ret;
1872 	size_t ctr = 0, i;
1873 	gnutls_x509_crt_t *tmpcerts = NULL, *tmpcerts2;
1874 	gnutls_datum_t c = { NULL, 0 };
1875 
1876 	if (resp == NULL) {
1877 		gnutls_assert();
1878 		return GNUTLS_E_INVALID_REQUEST;
1879 	}
1880 
1881 	tmpcerts = gnutls_malloc(sizeof(*tmpcerts));
1882 	if (tmpcerts == NULL) {
1883 		gnutls_assert();
1884 		return GNUTLS_E_MEMORY_ERROR;
1885 	}
1886 
1887 	for (;;) {
1888 		char name[MAX_NAME_SIZE];
1889 
1890 		snprintf(name, sizeof(name), "certs.?%u",
1891 			 (unsigned int) (ctr + 1));
1892 		ret =
1893 		    _gnutls_x509_der_encode(resp->basicresp, name, &c, 0);
1894 		if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1895 			break;
1896 		if (ret != GNUTLS_E_SUCCESS) {
1897 			gnutls_assert();
1898 			goto error;
1899 		}
1900 
1901 		tmpcerts2 =
1902 		    gnutls_realloc_fast(tmpcerts,
1903 					(ctr + 2) * sizeof(*tmpcerts));
1904 		if (tmpcerts2 == NULL) {
1905 			gnutls_assert();
1906 			ret = GNUTLS_E_MEMORY_ERROR;
1907 			goto error;
1908 		}
1909 		tmpcerts = tmpcerts2;
1910 
1911 		ret = gnutls_x509_crt_init(&tmpcerts[ctr]);
1912 		if (ret != GNUTLS_E_SUCCESS) {
1913 			gnutls_assert();
1914 			goto error;
1915 		}
1916 		ctr++;
1917 
1918 		ret = gnutls_x509_crt_import(tmpcerts[ctr - 1], &c,
1919 					     GNUTLS_X509_FMT_DER);
1920 		if (ret != GNUTLS_E_SUCCESS) {
1921 			gnutls_assert();
1922 			goto error;
1923 		}
1924 
1925 		gnutls_free(c.data);
1926 	}
1927 
1928 	tmpcerts[ctr] = NULL;
1929 
1930 	if (ncerts)
1931 		*ncerts = ctr;
1932 	if (certs)
1933 		*certs = tmpcerts;
1934 	else {
1935 		/* clean up memory */
1936 		ret = GNUTLS_E_SUCCESS;
1937 		goto error;
1938 	}
1939 
1940 	return GNUTLS_E_SUCCESS;
1941 
1942       error:
1943 	gnutls_free(c.data);
1944 	for (i = 0; i < ctr; i++)
1945 		gnutls_x509_crt_deinit(tmpcerts[i]);
1946 	gnutls_free(tmpcerts);
1947 	return ret;
1948 }
1949 
1950 /* Search the OCSP response for a certificate matching the responderId
1951    mentioned in the OCSP response. */
find_signercert(gnutls_ocsp_resp_const_t resp)1952 static gnutls_x509_crt_t find_signercert(gnutls_ocsp_resp_const_t resp)
1953 {
1954 	int rc;
1955 	gnutls_x509_crt_t *certs = NULL;
1956 	size_t ncerts = 0, i;
1957 	gnutls_datum_t riddn = {NULL, 0};
1958 	gnutls_datum_t keyid = {NULL, 0};
1959 	gnutls_x509_crt_t signercert = NULL;
1960 
1961 	rc = gnutls_ocsp_resp_get_responder_raw_id(resp, GNUTLS_OCSP_RESP_ID_DN, &riddn);
1962 	if (rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1963 		gnutls_assert();
1964 		rc = gnutls_ocsp_resp_get_responder_raw_id(resp, GNUTLS_OCSP_RESP_ID_KEY, &keyid);
1965 	}
1966 	if (rc != GNUTLS_E_SUCCESS) {
1967 		gnutls_assert();
1968 		return NULL;
1969 	}
1970 
1971 	rc = gnutls_ocsp_resp_get_certs(resp, &certs, &ncerts);
1972 	if (rc != GNUTLS_E_SUCCESS) {
1973 		gnutls_assert();
1974 		signercert = NULL;
1975 		goto quit;
1976 	}
1977 
1978 	for (i = 0; i < ncerts; i++) {
1979 		assert(certs[i] != NULL);
1980 		_gnutls_cert_log("checking whether signed against", certs[i]);
1981 		if (keyid.data != NULL) {
1982 			uint8_t digest[64]; /* to support longer key IDs */
1983 			gnutls_datum_t spki;
1984 			size_t digest_size = sizeof(digest);
1985 			int len;
1986 
1987 			_gnutls_debug_log("checking key ID against SPK identifier\n");
1988 
1989 			/* check subject key identifier as well, some certificates
1990 			 * match that, but not the hash */
1991 			rc = gnutls_x509_crt_get_subject_key_id(certs[i], digest, &digest_size, NULL);
1992 			if (rc >= 0 && digest_size == keyid.size &&
1993 			    memcmp(keyid.data, digest, digest_size) == 0) {
1994 				signercert = certs[i];
1995 				goto quit;
1996 			}
1997 
1998 			_gnutls_debug_log("checking key ID against SPKI hash\n");
1999 
2000 			/* continue with checking the hash */
2001 			rc = _gnutls_x509_get_raw_field2(certs[i]->cert, &certs[i]->der,
2002 					  "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
2003 					  &spki);
2004 			if (rc < 0 || spki.size < 6) {
2005 				gnutls_assert();
2006 				signercert = NULL;
2007 				continue;
2008 			}
2009 
2010 			/* For some reason the protocol requires we skip the
2011 			 * tag, length and number of unused bits.
2012 			 */
2013 			if (spki.data[0] != 0x03) { /* bit string */
2014 				gnutls_assert();
2015 				signercert = NULL;
2016 				continue;
2017 			}
2018 
2019 			rc = asn1_get_length_der(spki.data+1, spki.size-1, &len);
2020 			if (rc <= 0) {
2021 				gnutls_assert();
2022 				signercert = NULL;
2023 				continue;
2024 			}
2025 			len += 1+1; /* skip unused bits as well */
2026 			if (len >= (int)spki.size) {
2027 				gnutls_assert();
2028 				signercert = NULL;
2029 				continue;
2030 			}
2031 
2032 			rc = gnutls_hash_fast(GNUTLS_DIG_SHA1, spki.data+len, spki.size-len, digest);
2033 			if (rc < 0) {
2034 				gnutls_assert();
2035 				signercert = NULL;
2036 				continue;
2037 			}
2038 
2039 			if ((20 == keyid.size) &&
2040 				memcmp(keyid.data, digest, 20) == 0) {
2041 				signercert = certs[i];
2042 				goto quit;
2043 			}
2044 			gnutls_assert();
2045 		} else {
2046 			_gnutls_debug_log("checking issuer DN\n");
2047 
2048 			assert(riddn.data != NULL);
2049 			if ((certs[i]->raw_dn.size == riddn.size)
2050 			    && memcmp(riddn.data, certs[i]->raw_dn.data, riddn.size) == 0) {
2051 				signercert = certs[i];
2052 				goto quit;
2053 			}
2054 			gnutls_assert();
2055 		}
2056 	}
2057 
2058 	gnutls_assert();
2059 	signercert = NULL;
2060 
2061       quit:
2062 	gnutls_free(riddn.data);
2063 	gnutls_free(keyid.data);
2064 	for (i = 0; i < ncerts; i++)
2065 		if (certs[i] != signercert)
2066 			gnutls_x509_crt_deinit(certs[i]);
2067 	gnutls_free(certs);
2068 	return signercert;
2069 }
2070 
2071 static int
_ocsp_resp_verify_direct(gnutls_ocsp_resp_const_t resp,gnutls_x509_crt_t signercert,unsigned int * verify,unsigned int flags)2072 _ocsp_resp_verify_direct(gnutls_ocsp_resp_const_t resp,
2073 			 gnutls_x509_crt_t signercert,
2074 			 unsigned int *verify, unsigned int flags)
2075 {
2076 	gnutls_datum_t sig = { NULL };
2077 	gnutls_datum_t data = { NULL };
2078 	gnutls_pubkey_t pubkey = NULL;
2079 	int sigalg;
2080 	int rc;
2081 
2082 	if (resp == NULL || signercert == NULL) {
2083 		gnutls_assert();
2084 		return GNUTLS_E_INVALID_REQUEST;
2085 	}
2086 
2087 	rc = gnutls_ocsp_resp_get_signature_algorithm(resp);
2088 	if (rc < 0) {
2089 		gnutls_assert();
2090 		goto done;
2091 	}
2092 	sigalg = rc;
2093 
2094 	rc = _gnutls_x509_get_raw_field2(resp->basicresp, &resp->der, "tbsResponseData", &data);
2095 	if (rc != GNUTLS_E_SUCCESS) {
2096 		gnutls_assert();
2097 		goto done;
2098 	}
2099 
2100 	rc = gnutls_pubkey_init(&pubkey);
2101 	if (rc != GNUTLS_E_SUCCESS) {
2102 		gnutls_assert();
2103 		goto done;
2104 	}
2105 
2106 	_gnutls_cert_log("ocsp signer", signercert); \
2107 
2108 	rc = gnutls_pubkey_import_x509(pubkey, signercert, 0);
2109 	if (rc != GNUTLS_E_SUCCESS) {
2110 		gnutls_assert();
2111 		goto done;
2112 	}
2113 
2114 	rc = gnutls_ocsp_resp_get_signature(resp, &sig);
2115 	if (rc != GNUTLS_E_SUCCESS) {
2116 		gnutls_assert();
2117 		goto done;
2118 	}
2119 
2120 	rc = gnutls_pubkey_verify_data2(pubkey, sigalg, flags, &data, &sig);
2121 	if (rc == GNUTLS_E_PK_SIG_VERIFY_FAILED) {
2122 		gnutls_assert();
2123 		*verify = GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE;
2124 	} else if (rc < 0) {
2125 		gnutls_assert();
2126 		goto done;
2127 	} else
2128 		*verify = 0;
2129 
2130 	rc = GNUTLS_E_SUCCESS;
2131 
2132       done:
2133 	gnutls_free(sig.data);
2134 	gnutls_pubkey_deinit(pubkey);
2135 
2136 	return rc;
2137 }
2138 
vstatus_to_ocsp_status(unsigned int status)2139 static inline unsigned int vstatus_to_ocsp_status(unsigned int status)
2140 {
2141 	unsigned int ostatus;
2142 
2143 	if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
2144 		ostatus = GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM;
2145 	else if (status & GNUTLS_CERT_NOT_ACTIVATED)
2146 		ostatus = GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED;
2147 	else if (status & GNUTLS_CERT_EXPIRED)
2148 		ostatus = GNUTLS_OCSP_VERIFY_CERT_EXPIRED;
2149 	else
2150 		ostatus = GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER;
2151 
2152 	return ostatus;
2153 }
2154 
check_ocsp_purpose(gnutls_x509_crt_t signercert)2155 static int check_ocsp_purpose(gnutls_x509_crt_t signercert)
2156 {
2157 	char oidtmp[MAX_OID_SIZE];
2158 	size_t oidsize;
2159 	int indx, rc;
2160 
2161 	for (indx = 0;; indx++) {
2162 		oidsize = sizeof(oidtmp);
2163 		rc = gnutls_x509_crt_get_key_purpose_oid(signercert, indx,
2164 							 oidtmp, &oidsize,
2165 							 NULL);
2166 
2167 		if (rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
2168 			gnutls_assert();
2169 			return rc;
2170 		} else if (rc == GNUTLS_E_SHORT_MEMORY_BUFFER) {
2171 			gnutls_assert();
2172 			continue;
2173 		} else if (rc != GNUTLS_E_SUCCESS) {
2174 			return gnutls_assert_val(rc);
2175 		}
2176 
2177 		if (memcmp(oidtmp, GNUTLS_KP_OCSP_SIGNING, oidsize) != 0) {
2178 			gnutls_assert();
2179 			continue;
2180 		}
2181 		break;
2182 	}
2183 
2184 	return 0;
2185 }
2186 
2187 /**
2188  * gnutls_ocsp_resp_verify_direct:
2189  * @resp: should contain a #gnutls_ocsp_resp_t type
2190  * @issuer: certificate believed to have signed the response
2191  * @verify: output variable with verification status, an #gnutls_ocsp_verify_reason_t
2192  * @flags: verification flags from #gnutls_certificate_verify_flags
2193  *
2194  * Verify signature of the Basic OCSP Response against the public key
2195  * in the @issuer certificate.
2196  *
2197  * The output @verify variable will hold verification status codes
2198  * (e.g., %GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND,
2199  * %GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) which are only valid if the
2200  * function returned %GNUTLS_E_SUCCESS.
2201  *
2202  * Note that the function returns %GNUTLS_E_SUCCESS even when
2203  * verification failed.  The caller must always inspect the @verify
2204  * variable to find out the verification status.
2205  *
2206  * The @flags variable should be 0 for now.
2207  *
2208  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2209  *   negative error value.
2210  **/
2211 int
gnutls_ocsp_resp_verify_direct(gnutls_ocsp_resp_const_t resp,gnutls_x509_crt_t issuer,unsigned int * verify,unsigned int flags)2212 gnutls_ocsp_resp_verify_direct(gnutls_ocsp_resp_const_t resp,
2213 			       gnutls_x509_crt_t issuer,
2214 			       unsigned int *verify, unsigned int flags)
2215 {
2216 	gnutls_x509_crt_t signercert;
2217 	int rc;
2218 
2219 	if (resp == NULL || issuer == NULL) {
2220 		gnutls_assert();
2221 		return GNUTLS_E_INVALID_REQUEST;
2222 	}
2223 
2224 	signercert = find_signercert(resp);
2225 	if (!signercert) {
2226 		signercert = issuer;
2227 	} else if (!gnutls_x509_crt_equals(signercert, issuer)) {
2228 
2229 		/* response contains a signer. Verify him */
2230 
2231 		unsigned int vtmp;
2232 
2233 		rc = gnutls_x509_crt_verify(signercert, &issuer, 1, flags,
2234 					    &vtmp);
2235 		if (rc != GNUTLS_E_SUCCESS) {
2236 			gnutls_assert();
2237 			goto done;
2238 		}
2239 
2240 		if (vtmp != 0) {
2241 			_gnutls_reason_log("cert verification", vtmp);
2242 			*verify = vstatus_to_ocsp_status(vtmp);
2243 			gnutls_assert();
2244 			rc = GNUTLS_E_SUCCESS;
2245 			goto done;
2246 		}
2247 
2248 		rc = check_ocsp_purpose(signercert);
2249 		if (rc < 0) {
2250 			gnutls_assert();
2251 			*verify = GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR;
2252 			rc = GNUTLS_E_SUCCESS;
2253 			goto done;
2254 		}
2255 	}
2256 
2257 	rc = _ocsp_resp_verify_direct(resp, signercert, verify, flags);
2258 
2259       done:
2260 	if (signercert != issuer)
2261 		gnutls_x509_crt_deinit(signercert);
2262 
2263 	return rc;
2264 }
2265 
2266 /**
2267  * gnutls_ocsp_resp_verify:
2268  * @resp: should contain a #gnutls_ocsp_resp_t type
2269  * @trustlist: trust anchors as a #gnutls_x509_trust_list_t type
2270  * @verify: output variable with verification status, an #gnutls_ocsp_verify_reason_t
2271  * @flags: verification flags from #gnutls_certificate_verify_flags
2272  *
2273  * Verify signature of the Basic OCSP Response against the public key
2274  * in the certificate of a trusted signer.  The @trustlist should be
2275  * populated with trust anchors.  The function will extract the signer
2276  * certificate from the Basic OCSP Response and will verify it against
2277  * the @trustlist.  A trusted signer is a certificate that is either
2278  * in @trustlist, or it is signed directly by a certificate in
2279  * @trustlist and has the id-ad-ocspSigning Extended Key Usage bit
2280  * set.
2281  *
2282  * The output @verify variable will hold verification status codes
2283  * (e.g., %GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND,
2284  * %GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) which are only valid if the
2285  * function returned %GNUTLS_E_SUCCESS.
2286  *
2287  * Note that the function returns %GNUTLS_E_SUCCESS even when
2288  * verification failed.  The caller must always inspect the @verify
2289  * variable to find out the verification status.
2290  *
2291  * The @flags variable should be 0 for now.
2292  *
2293  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2294  *   negative error value.
2295  **/
2296 int
gnutls_ocsp_resp_verify(gnutls_ocsp_resp_const_t resp,gnutls_x509_trust_list_t trustlist,unsigned int * verify,unsigned int flags)2297 gnutls_ocsp_resp_verify(gnutls_ocsp_resp_const_t resp,
2298 			gnutls_x509_trust_list_t trustlist,
2299 			unsigned int *verify, unsigned int flags)
2300 {
2301 	gnutls_x509_crt_t signercert = NULL;
2302 	int rc;
2303 
2304 	/* Algorithm:
2305 	   1. Find signer cert.
2306 	   1a. Search in OCSP response Certificate field for responderID.
2307 	   1b. Verify that signer cert is trusted.
2308 	   2a. It is in trustlist?
2309 	   2b. It has OCSP key usage and directly signed by a CA in trustlist?
2310 	   3. Verify signature of Basic Response using public key from signer cert.
2311 	 */
2312 
2313 	signercert = find_signercert(resp);
2314 	if (!signercert) {
2315 		gnutls_datum_t dn;
2316 
2317 		rc = gnutls_ocsp_resp_get_responder_raw_id(resp, GNUTLS_OCSP_RESP_ID_DN, &dn);
2318 		if (rc < 0) {
2319 			gnutls_assert();
2320 			*verify = GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND;
2321 			rc = GNUTLS_E_SUCCESS;
2322 			goto done;
2323 		}
2324 
2325 		rc = gnutls_x509_trust_list_get_issuer_by_dn(trustlist, &dn, &signercert, 0);
2326 		gnutls_free(dn.data);
2327 
2328 		if (rc < 0) {
2329 			gnutls_assert();
2330 			*verify = GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND;
2331 			rc = GNUTLS_E_SUCCESS;
2332 			goto done;
2333 		}
2334 	} else {
2335 		/* Either the signer is directly trusted (i.e., in trustlist) or it
2336 		   is directly signed by something in trustlist and has proper OCSP
2337 		   extkeyusage. */
2338 		rc = _gnutls_trustlist_inlist(trustlist, signercert);
2339 		if (rc == 0) {
2340 			/* not in trustlist, need to verify signature and bits */
2341 			unsigned vtmp;
2342 			gnutls_typed_vdata_st vdata;
2343 
2344 			vdata.type = GNUTLS_DT_KEY_PURPOSE_OID;
2345 			vdata.data = (void*)GNUTLS_KP_OCSP_SIGNING;
2346 			vdata.size = 0;
2347 
2348 			gnutls_assert();
2349 
2350 			rc = gnutls_x509_trust_list_verify_crt2(trustlist,
2351 								&signercert, 1,
2352 								&vdata, 1,
2353 								flags, &vtmp, NULL);
2354 			if (rc != GNUTLS_E_SUCCESS) {
2355 				gnutls_assert();
2356 				goto done;
2357 			}
2358 
2359 			if (vtmp != 0) {
2360 				*verify = vstatus_to_ocsp_status(vtmp);
2361 				gnutls_assert();
2362 				rc = GNUTLS_E_SUCCESS;
2363 				goto done;
2364 			}
2365 		}
2366 	}
2367 
2368 	rc = check_ocsp_purpose(signercert);
2369 	if (rc < 0) {
2370 		gnutls_assert();
2371 		*verify = GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR;
2372 		rc = GNUTLS_E_SUCCESS;
2373 		goto done;
2374 	}
2375 
2376 	rc = _ocsp_resp_verify_direct(resp, signercert, verify, flags);
2377 
2378       done:
2379 	gnutls_x509_crt_deinit(signercert);
2380 
2381 	return rc;
2382 }
2383 
2384 /**
2385  * gnutls_x509_ocsp_resp_list_import2:
2386  * @ocsps: Will hold the parsed OCSP response list.
2387  * @size: It will contain the size of the list.
2388  * @resp_data: The PEM encoded OCSP list.
2389  * @format: One of %GNUTLS_X509_FMT_PEM or %GNUTLS_X509_FMT_DER
2390  * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
2391  *
2392  * This function will convert the given PEM encoded OCSP response list
2393  * to the native gnutls_ocsp_resp_t format. The output will be stored
2394  * in @ocsps which will be allocated and initialized.
2395  *
2396  * The OCSP responses should have a header of "OCSP RESPONSE".
2397  *
2398  * To deinitialize responses, you need to deinitialize each %gnutls_ocsp_resp_t
2399  * structure independently, and use gnutls_free() at @ocsps.
2400  *
2401  * In PEM files, when no OCSP responses are detected
2402  * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2403  *
2404  * Returns: the number of responses read or a negative error value.
2405  *
2406  * Since: 3.6.3
2407  **/
2408 int
gnutls_ocsp_resp_list_import2(gnutls_ocsp_resp_t ** ocsps,unsigned int * size,const gnutls_datum_t * resp_data,gnutls_x509_crt_fmt_t format,unsigned int flags)2409 gnutls_ocsp_resp_list_import2(gnutls_ocsp_resp_t **ocsps,
2410 			     unsigned int *size,
2411 			     const gnutls_datum_t *resp_data,
2412 			     gnutls_x509_crt_fmt_t format,
2413 			     unsigned int flags)
2414 {
2415 	gnutls_ocsp_resp_t resp = NULL;
2416 	gnutls_ocsp_resp_t *new_ocsps;
2417 	int ret;
2418 	unsigned i;
2419 
2420 
2421 	if (format == GNUTLS_X509_FMT_PEM) {
2422 		/* load multiple responses */
2423 		gnutls_datum_t p = {resp_data->data, resp_data->size};
2424 
2425 		*size = 0;
2426 		*ocsps = NULL;
2427 
2428 		p.data = memmem(p.data, p.size, PEM_OCSP_RESPONSE,
2429 				sizeof(PEM_OCSP_RESPONSE)-1);
2430 		if (p.data == NULL) {
2431 			ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2432 			goto cleanup;
2433 		}
2434 
2435 		p.size -= p.data - resp_data->data;
2436 		if (p.size <= 0) {
2437 			ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2438 			goto cleanup;
2439 		}
2440 
2441 		do {
2442 			ret = gnutls_ocsp_resp_init(&resp);
2443 			if (ret < 0) {
2444 				gnutls_assert();
2445 				goto fail;
2446 			}
2447 
2448 			ret = gnutls_ocsp_resp_import2(resp, &p, GNUTLS_X509_FMT_PEM);
2449 			if (ret < 0) {
2450 				gnutls_assert();
2451 				goto fail;
2452 			}
2453 
2454 			new_ocsps = gnutls_realloc(*ocsps, (*size + 1)*sizeof(gnutls_ocsp_resp_t));
2455 			if (new_ocsps == NULL) {
2456 				resp = NULL;
2457 				gnutls_assert();
2458 				goto fail;
2459 			}
2460 
2461 			new_ocsps[*size] = resp;
2462 			resp = NULL;
2463 			(*size)++;
2464 			*ocsps = new_ocsps;
2465 
2466 			p.data++;
2467 			p.size--;
2468 
2469 			p.data = memmem(p.data, p.size, PEM_OCSP_RESPONSE,
2470 					sizeof(PEM_OCSP_RESPONSE)-1);
2471 			if (p.data == NULL)
2472 				break;
2473 			p.size = resp_data->size - (p.data - resp_data->data);
2474 		} while(p.size > 0);
2475 	} else {
2476 		/* DER: load a single response */
2477 		ret = gnutls_ocsp_resp_init(&resp);
2478 		if (ret < 0) {
2479 			return gnutls_assert_val(ret);
2480 		}
2481 
2482 		ret = gnutls_ocsp_resp_import2(resp, resp_data, GNUTLS_X509_FMT_DER);
2483 		if (ret < 0) {
2484 			gnutls_assert();
2485 			goto cleanup;
2486 		}
2487 
2488 		*ocsps = gnutls_malloc(1*sizeof(gnutls_ocsp_resp_t));
2489 		if (*ocsps == NULL) {
2490 			gnutls_assert();
2491 			ret = GNUTLS_E_MEMORY_ERROR;
2492 			goto cleanup;
2493 		}
2494 
2495 		(*ocsps)[0] = resp;
2496 		resp = NULL;
2497 		*size = 1;
2498 	}
2499 
2500 	ret = 0;
2501 	goto cleanup;
2502 
2503  fail:
2504 	for (i=0;i<*size;i++) {
2505 		gnutls_ocsp_resp_deinit((*ocsps)[i]);
2506 	}
2507 	gnutls_free(*ocsps);
2508 
2509  cleanup:
2510 	if (resp)
2511 		gnutls_ocsp_resp_deinit(resp);
2512 	return ret;
2513 }
2514 
2515 /* This returns -1 if the OCSP response is invalid (revoked) or its
2516  * data are too old. It returns -2 if it cannot determine the expiration
2517  * time, and would otherwise treat it as too old.
2518  * Otherwise it returns the time after which that data  is invalid.
2519  */
_gnutls_ocsp_get_validity(gnutls_ocsp_resp_const_t resp)2520 time_t _gnutls_ocsp_get_validity(gnutls_ocsp_resp_const_t resp)
2521 {
2522 	unsigned int cert_status;
2523 	time_t rtime, vtime, ntime, now;
2524 	int ret;
2525 
2526 	ret = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, NULL,
2527 					  &cert_status, &vtime, &ntime,
2528 					  &rtime, NULL);
2529 	if (ret < 0) {
2530 		_gnutls_debug_log("There was an error parsing the OCSP response: %s\n",
2531 				  gnutls_strerror(ret));
2532 		return gnutls_assert_val(-1);
2533 	}
2534 
2535 	if (cert_status != GNUTLS_OCSP_CERT_GOOD &&
2536 	    cert_status != GNUTLS_OCSP_CERT_UNKNOWN) {
2537 		_gnutls_debug_log("The OCSP response status (%d) is invalid\n",
2538 				  cert_status);
2539 		return gnutls_assert_val(-1);
2540 	}
2541 
2542 	now = gnutls_time(0);
2543 
2544 	if (ntime == -1) {
2545 		/* This is a problematic case, and there is no consensus on how
2546 		 * to treat these responses. It doesn't contain the time after which
2547 		 * the response is invalid, thus it is an OCSP response effectively
2548 		 * valid forever defeating the purpose of OCSP. We set here the same
2549 		 * limit we apply when verifying responses. */
2550 		if (now - vtime > MAX_OCSP_VALIDITY_SECS) {
2551 			_gnutls_debug_log("The OCSP response is old\n");
2552 			return gnutls_assert_val(-2);
2553 		}
2554 
2555 		return now + MAX_OCSP_VALIDITY_SECS;
2556 	} else {
2557 		/* there is a newer OCSP answer, don't trust this one */
2558 		if (ntime < now) {
2559 			_gnutls_debug_log("There is a newer OCSP response\n");
2560 			return gnutls_assert_val(-1);
2561 		}
2562 
2563 		return ntime;
2564 	}
2565 }
2566 
_gnutls_ocsp_verify_status_to_str(gnutls_ocsp_verify_reason_t r,char out[MAX_OCSP_MSG_SIZE])2567 const char *_gnutls_ocsp_verify_status_to_str(gnutls_ocsp_verify_reason_t r, char out[MAX_OCSP_MSG_SIZE])
2568 {
2569 	gnutls_buffer_st str;
2570 	gnutls_datum_t buf;
2571 	int ret;
2572 
2573 	_gnutls_buffer_init(&str);
2574 
2575 	if (r == 0)
2576 		_gnutls_buffer_append_str(&str,
2577 					  _
2578 					  ("The OCSP response is trusted. "));
2579 
2580 	if (r & GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND)
2581 		_gnutls_buffer_append_str(&str,
2582 					  _
2583 					  ("The OCSP response's signer could not be found. "));
2584 
2585 	if (r & GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR)
2586 		_gnutls_buffer_append_str(&str,
2587 					  _
2588 					  ("Error in the signer's key usageflags. "));
2589 
2590 	if (r & GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER)
2591 		_gnutls_buffer_append_str(&str,
2592 					  _
2593 					  ("The OCSP response's signer is not trusted. "));
2594 
2595 	if (r & GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM)
2596 		_gnutls_buffer_append_str(&str,
2597 					  _
2598 					  ("The OCSP response depends on insecure algorithms. "));
2599 
2600 	if (r & GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE)
2601 		_gnutls_buffer_append_str(&str,
2602 					  _
2603 					  ("The OCSP response's signature cannot be validated. "));
2604 
2605 	if (r & GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED)
2606 		_gnutls_buffer_append_str(&str,
2607 					  _
2608 					  ("The OCSP response's signer's certificate is not activated. "));
2609 
2610 	if (r & GNUTLS_OCSP_VERIFY_CERT_EXPIRED)
2611 		_gnutls_buffer_append_str(&str,
2612 					  _
2613 					  ("The OCSP response's signer's certificate is expired. "));
2614 
2615 	ret = _gnutls_buffer_to_datum(&str, &buf, 1);
2616 	if (ret < 0)
2617 		return _("Memory error");
2618 
2619 	snprintf(out, MAX_OCSP_MSG_SIZE, "%s", buf.data);
2620 	gnutls_free(buf.data);
2621 
2622 	return out;
2623 }
2624