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