If revocation reason cannot be read set it to GNUTLS_X509_CRLREASON_UNSPECIFIED.
[gnutls.git] / lib / x509 / ocsp.c
blob8756431a71aacc88debb9ccf8053748fa69ea5ae
1 /*
2 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
3 * Author: Simon Josefsson
5 * This file is part of GnuTLS.
7 * The GnuTLS is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 3 of
10 * the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>
22 /* Online Certificate Status Protocol - RFC 2560
25 #include <gnutls_int.h>
26 #include <gnutls_global.h>
27 #include <gnutls_errors.h>
28 #include <libtasn1.h>
29 #include <gnutls_pk.h>
30 #include "common.h"
31 #include "verify-high.h"
33 #include <gnutls/ocsp.h>
34 #include <auth/cert.h>
36 typedef struct gnutls_ocsp_req_int
38 ASN1_TYPE req;
39 } gnutls_ocsp_req_int;
41 typedef struct gnutls_ocsp_resp_int
43 ASN1_TYPE resp;
44 gnutls_datum_t response_type_oid;
45 ASN1_TYPE basicresp;
46 } gnutls_ocsp_resp_int;
48 #define MAX_TIME 64
50 /**
51 * gnutls_ocsp_req_init:
52 * @req: The structure to be initialized
54 * This function will initialize an OCSP request structure.
56 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
57 * negative error value.
58 **/
59 int
60 gnutls_ocsp_req_init (gnutls_ocsp_req_t * req)
62 gnutls_ocsp_req_t tmp = gnutls_calloc (1, sizeof (gnutls_ocsp_req_int));
63 int ret;
65 if (!tmp)
66 return GNUTLS_E_MEMORY_ERROR;
68 ret = asn1_create_element (_gnutls_get_pkix (), "PKIX1.OCSPRequest",
69 &tmp->req);
70 if (ret != ASN1_SUCCESS)
72 gnutls_assert ();
73 gnutls_free (tmp);
74 return _gnutls_asn2err (ret);
77 *req = tmp;
79 return GNUTLS_E_SUCCESS;
82 /**
83 * gnutls_ocsp_req_deinit:
84 * @req: The structure to be deinitialized
86 * This function will deinitialize a OCSP request structure.
87 **/
88 void
89 gnutls_ocsp_req_deinit (gnutls_ocsp_req_t req)
91 if (!req)
92 return;
94 if (req->req)
95 asn1_delete_structure (&req->req);
97 req->req = NULL;
99 gnutls_free (req);
103 * gnutls_ocsp_resp_init:
104 * @resp: The structure to be initialized
106 * This function will initialize an OCSP response structure.
108 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
109 * negative error value.
112 gnutls_ocsp_resp_init (gnutls_ocsp_resp_t * resp)
114 gnutls_ocsp_resp_t tmp = gnutls_calloc (1, sizeof (gnutls_ocsp_resp_int));
115 int ret;
117 if (!tmp)
118 return GNUTLS_E_MEMORY_ERROR;
120 ret = asn1_create_element (_gnutls_get_pkix (),
121 "PKIX1.OCSPResponse", &tmp->resp);
122 if (ret != ASN1_SUCCESS)
124 gnutls_assert ();
125 gnutls_free (tmp);
126 return _gnutls_asn2err (ret);
129 ret = asn1_create_element (_gnutls_get_pkix (),
130 "PKIX1.BasicOCSPResponse", &tmp->basicresp);
131 if (ret != ASN1_SUCCESS)
133 gnutls_assert ();
134 asn1_delete_structure (&tmp->resp);
135 gnutls_free (tmp);
136 return _gnutls_asn2err (ret);
139 *resp = tmp;
141 return GNUTLS_E_SUCCESS;
145 * gnutls_ocsp_resp_deinit:
146 * @resp: The structure to be deinitialized
148 * This function will deinitialize a OCSP response structure.
150 void
151 gnutls_ocsp_resp_deinit (gnutls_ocsp_resp_t resp)
153 if (!resp)
154 return;
156 if (resp->resp)
157 asn1_delete_structure (&resp->resp);
158 gnutls_free (resp->response_type_oid.data);
159 if (resp->basicresp)
160 asn1_delete_structure (&resp->basicresp);
162 resp->resp = NULL;
163 resp->response_type_oid.data = NULL;
164 resp->basicresp = NULL;
166 gnutls_free (resp);
170 * gnutls_ocsp_req_import:
171 * @req: The structure to store the parsed request.
172 * @data: DER encoded OCSP request.
174 * This function will convert the given DER encoded OCSP request to
175 * the native #gnutls_ocsp_req_t format. The output will be stored in
176 * @req.
178 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
179 * negative error value.
182 gnutls_ocsp_req_import (gnutls_ocsp_req_t req,
183 const gnutls_datum_t * data)
185 int ret = 0;
187 if (req == NULL || data == NULL)
189 gnutls_assert ();
190 return GNUTLS_E_INVALID_REQUEST;
193 if (req->req)
195 /* Any earlier asn1_der_decoding will modify the ASN.1
196 structure, so we need to replace it with a fresh
197 structure. */
198 asn1_delete_structure (&req->req);
200 ret = asn1_create_element (_gnutls_get_pkix (),
201 "PKIX1.OCSPRequest", &req->req);
202 if (ret != ASN1_SUCCESS)
204 gnutls_assert ();
205 return _gnutls_asn2err (ret);
209 ret = asn1_der_decoding (&req->req, data->data, data->size, NULL);
210 if (ret != ASN1_SUCCESS)
212 gnutls_assert ();
213 return _gnutls_asn2err (ret);
216 return GNUTLS_E_SUCCESS;
220 * gnutls_ocsp_resp_import:
221 * @resp: The structure to store the parsed response.
222 * @data: DER encoded OCSP response.
224 * This function will convert the given DER encoded OCSP response to
225 * the native #gnutls_ocsp_resp_t format. It also decodes the Basic
226 * OCSP Response part, if any. The output will be stored in @resp.
228 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
229 * negative error value.
232 gnutls_ocsp_resp_import (gnutls_ocsp_resp_t resp,
233 const gnutls_datum_t * data)
235 int ret = 0;
237 if (resp == NULL || data == NULL)
239 gnutls_assert ();
240 return GNUTLS_E_INVALID_REQUEST;
243 if (resp->resp)
245 /* Any earlier asn1_der_decoding will modify the ASN.1
246 structure, so we need to replace it with a fresh
247 structure. */
248 asn1_delete_structure (&resp->resp);
250 ret = asn1_create_element (_gnutls_get_pkix (),
251 "PKIX1.OCSPResponse", &resp->resp);
252 if (ret != ASN1_SUCCESS)
254 gnutls_assert ();
255 return _gnutls_asn2err (ret);
259 ret = asn1_der_decoding (&resp->resp, data->data, data->size, NULL);
260 if (ret != ASN1_SUCCESS)
262 gnutls_assert ();
263 return _gnutls_asn2err (ret);
266 if (gnutls_ocsp_resp_get_status (resp) != GNUTLS_OCSP_RESP_SUCCESSFUL)
267 return GNUTLS_E_SUCCESS;
269 ret = _gnutls_x509_read_value (resp->resp, "responseBytes.responseType",
270 &resp->response_type_oid, 0);
271 if (ret < 0)
273 gnutls_assert ();
274 return ret;
277 #define OCSP_BASIC "1.3.6.1.5.5.7.48.1.1"
279 if (resp->response_type_oid.size == sizeof (OCSP_BASIC)
280 && memcmp (resp->response_type_oid.data, OCSP_BASIC,
281 resp->response_type_oid.size) == 0)
283 gnutls_datum_t d;
285 if (resp->basicresp)
287 asn1_delete_structure (&resp->basicresp);
289 ret = asn1_create_element (_gnutls_get_pkix (),
290 "PKIX1.BasicOCSPResponse", &resp->basicresp);
291 if (ret != ASN1_SUCCESS)
293 gnutls_assert ();
294 return _gnutls_asn2err (ret);
298 ret = _gnutls_x509_read_value (resp->resp, "responseBytes.response",
299 &d, 0);
300 if (ret < 0)
302 gnutls_assert ();
303 return ret;
306 ret = asn1_der_decoding (&resp->basicresp, d.data, d.size, NULL);
307 gnutls_free (d.data);
308 if (ret != ASN1_SUCCESS)
310 gnutls_assert ();
311 return _gnutls_asn2err (ret);
314 else
315 resp->basicresp = NULL;
317 return GNUTLS_E_SUCCESS;
320 static int
321 export (ASN1_TYPE node, const char *name, gnutls_datum_t * data)
323 int ret;
324 int len = 0;
326 ret = asn1_der_coding (node, name, NULL, &len, NULL);
327 if (ret != ASN1_MEM_ERROR)
329 gnutls_assert ();
330 return _gnutls_asn2err (ret);
332 data->size = len;
333 data->data = gnutls_malloc (len);
334 if (data->data == NULL)
335 return GNUTLS_E_MEMORY_ERROR;
336 ret = asn1_der_coding (node, name, data->data, &len, NULL);
337 if (ret != ASN1_SUCCESS)
339 gnutls_assert ();
340 return _gnutls_asn2err (ret);
343 return GNUTLS_E_SUCCESS;
347 * gnutls_ocsp_req_export:
348 * @req: Holds the OCSP request
349 * @data: newly allocate buffer holding DER encoded OCSP request
351 * This function will export the OCSP request to DER format.
353 * Returns: In case of failure a negative error code will be
354 * returned, and 0 on success.
357 gnutls_ocsp_req_export (gnutls_ocsp_req_t req, gnutls_datum_t * data)
359 int ret;
361 if (req == NULL || data == NULL)
363 gnutls_assert ();
364 return GNUTLS_E_INVALID_REQUEST;
367 /* XXX remove when we support these fields */
368 asn1_write_value (req->req, "tbsRequest.requestorName", NULL, 0);
369 asn1_write_value (req->req, "optionalSignature", NULL, 0);
371 /* prune extension field if we don't have any extension */
372 ret = gnutls_ocsp_req_get_extension (req, 0, NULL, NULL, NULL);
373 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
374 asn1_write_value (req->req, "tbsRequest.requestExtensions", NULL, 0);
376 return export (req->req, "", data);
380 * gnutls_ocsp_resp_export:
381 * @resp: Holds the OCSP response
382 * @data: newly allocate buffer holding DER encoded OCSP response
384 * This function will export the OCSP response to DER format.
386 * Returns: In case of failure a negative error code will be
387 * returned, and 0 on success.
390 gnutls_ocsp_resp_export (gnutls_ocsp_resp_t resp, gnutls_datum_t * data)
392 if (resp == NULL || data == NULL)
394 gnutls_assert ();
395 return GNUTLS_E_INVALID_REQUEST;
398 return export (resp->resp, "", data);
402 * gnutls_ocsp_req_get_version:
403 * @req: should contain a #gnutls_ocsp_req_t structure
405 * This function will return the version of the OCSP request.
406 * Typically this is always 1 indicating version 1.
408 * Returns: version of OCSP request, or a negative error code on error.
411 gnutls_ocsp_req_get_version (gnutls_ocsp_req_t req)
413 uint8_t version[8];
414 int len, ret;
416 if (req == NULL)
418 gnutls_assert ();
419 return GNUTLS_E_INVALID_REQUEST;
422 len = sizeof (version);
423 ret = asn1_read_value (req->req, "tbsRequest.version", version, &len);
424 if (ret != ASN1_SUCCESS)
426 if (ret == ASN1_ELEMENT_NOT_FOUND)
427 return 1; /* the DEFAULT version */
428 gnutls_assert ();
429 return _gnutls_asn2err (ret);
432 return (int) version[0] + 1;
436 * gnutls_ocsp_req_get_cert_id:
437 * @req: should contain a #gnutls_ocsp_req_t structure
438 * @indx: Specifies which extension OID to get. Use (0) to get the first one.
439 * @digest: output variable with #gnutls_digest_algorithm_t hash algorithm
440 * @issuer_name_hash: output buffer with hash of issuer's DN
441 * @issuer_key_hash: output buffer with hash of issuer's public key
442 * @serial_number: output buffer with serial number of certificate to check
444 * This function will return the certificate information of the
445 * @indx'ed request in the OCSP request. The information returned
446 * corresponds to the CertID structure:
448 * <informalexample><programlisting>
449 * CertID ::= SEQUENCE {
450 * hashAlgorithm AlgorithmIdentifier,
451 * issuerNameHash OCTET STRING, -- Hash of Issuer's DN
452 * issuerKeyHash OCTET STRING, -- Hash of Issuers public key
453 * serialNumber CertificateSerialNumber }
454 * </programlisting></informalexample>
456 * Each of the pointers to output variables may be NULL to indicate
457 * that the caller is not interested in that value.
459 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
460 * negative error code is returned. If you have reached the last
461 * CertID available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
462 * returned.
465 gnutls_ocsp_req_get_cert_id (gnutls_ocsp_req_t req,
466 unsigned indx,
467 gnutls_digest_algorithm_t *digest,
468 gnutls_datum_t *issuer_name_hash,
469 gnutls_datum_t *issuer_key_hash,
470 gnutls_datum_t *serial_number)
472 gnutls_datum_t sa;
473 char name[ASN1_MAX_NAME_SIZE];
474 int ret;
476 if (req == NULL)
478 gnutls_assert ();
479 return GNUTLS_E_INVALID_REQUEST;
482 snprintf (name, sizeof (name),
483 "tbsRequest.requestList.?%u.reqCert.hashAlgorithm.algorithm",
484 indx + 1);
485 ret = _gnutls_x509_read_value (req->req, name, &sa, 0);
486 if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
487 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
488 else if (ret < 0)
490 gnutls_assert ();
491 return ret;
494 ret = _gnutls_x509_oid_to_digest ((char*)sa.data);
495 _gnutls_free_datum (&sa);
496 if (ret < 0)
498 gnutls_assert ();
499 return ret;
502 if (digest)
503 *digest = ret;
505 if (issuer_name_hash)
507 snprintf (name, sizeof (name),
508 "tbsRequest.requestList.?%u.reqCert.issuerNameHash", indx + 1);
509 ret = _gnutls_x509_read_value (req->req, name, issuer_name_hash, 0);
510 if (ret != GNUTLS_E_SUCCESS)
512 gnutls_assert ();
513 return ret;
517 if (issuer_key_hash)
519 snprintf (name, sizeof (name),
520 "tbsRequest.requestList.?%u.reqCert.issuerKeyHash", indx + 1);
521 ret = _gnutls_x509_read_value (req->req, name, issuer_key_hash, 0);
522 if (ret != GNUTLS_E_SUCCESS)
524 gnutls_assert ();
525 if (issuer_name_hash)
526 gnutls_free (issuer_name_hash->data);
527 return ret;
531 if (serial_number)
533 snprintf (name, sizeof (name),
534 "tbsRequest.requestList.?%u.reqCert.serialNumber", indx + 1);
535 ret = _gnutls_x509_read_value (req->req, name, serial_number, 0);
536 if (ret != GNUTLS_E_SUCCESS)
538 gnutls_assert ();
539 if (issuer_name_hash)
540 gnutls_free (issuer_name_hash->data);
541 if (issuer_key_hash)
542 gnutls_free (issuer_key_hash->data);
543 return ret;
547 return GNUTLS_E_SUCCESS;
551 * gnutls_ocsp_req_add_cert_id:
552 * @req: should contain a #gnutls_ocsp_req_t structure
553 * @digest: hash algorithm, a #gnutls_digest_algorithm_t value
554 * @issuer_name_hash: hash of issuer's DN
555 * @issuer_key_hash: hash of issuer's public key
556 * @serial_number: serial number of certificate to check
558 * This function will add another request to the OCSP request for a
559 * particular certificate having the issuer name hash of
560 * @issuer_name_hash and issuer key hash of @issuer_key_hash (both
561 * hashed using @digest) and serial number @serial_number.
563 * The information needed corresponds to the CertID structure:
565 * <informalexample><programlisting>
566 * CertID ::= SEQUENCE {
567 * hashAlgorithm AlgorithmIdentifier,
568 * issuerNameHash OCTET STRING, -- Hash of Issuer's DN
569 * issuerKeyHash OCTET STRING, -- Hash of Issuers public key
570 * serialNumber CertificateSerialNumber }
571 * </programlisting></informalexample>
573 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
574 * negative error code is returned.
577 gnutls_ocsp_req_add_cert_id (gnutls_ocsp_req_t req,
578 gnutls_digest_algorithm_t digest,
579 const gnutls_datum_t *issuer_name_hash,
580 const gnutls_datum_t *issuer_key_hash,
581 const gnutls_datum_t *serial_number)
583 int result;
584 const char *oid;
586 if (req == NULL || issuer_name_hash == NULL
587 || issuer_key_hash == NULL || serial_number == NULL)
589 gnutls_assert ();
590 return GNUTLS_E_INVALID_REQUEST;
593 oid = _gnutls_x509_digest_to_oid (digest);
594 if (oid == NULL)
596 gnutls_assert ();
597 return GNUTLS_E_INVALID_REQUEST;
600 result = asn1_write_value (req->req, "tbsRequest.requestList", "NEW", 1);
601 if (result != ASN1_SUCCESS)
603 gnutls_assert ();
604 return _gnutls_asn2err (result);
607 result = asn1_write_value
608 (req->req, "tbsRequest.requestList.?LAST.reqCert.hashAlgorithm.algorithm",
609 oid, 1);
610 if (result != ASN1_SUCCESS)
612 gnutls_assert ();
613 return _gnutls_asn2err (result);
616 /* XXX we don't support any algorithm with parameters */
617 result = asn1_write_value
618 (req->req, "tbsRequest.requestList.?LAST.reqCert.hashAlgorithm.parameters",
619 ASN1_NULL, ASN1_NULL_SIZE);
620 if (result != ASN1_SUCCESS)
622 gnutls_assert ();
623 return _gnutls_asn2err (result);
626 result = asn1_write_value
627 (req->req, "tbsRequest.requestList.?LAST.reqCert.issuerNameHash",
628 issuer_name_hash->data, issuer_name_hash->size);
629 if (result != ASN1_SUCCESS)
631 gnutls_assert ();
632 return _gnutls_asn2err (result);
635 result = asn1_write_value
636 (req->req, "tbsRequest.requestList.?LAST.reqCert.issuerKeyHash",
637 issuer_key_hash->data, issuer_key_hash->size);
638 if (result != ASN1_SUCCESS)
640 gnutls_assert ();
641 return _gnutls_asn2err (result);
644 result = asn1_write_value
645 (req->req, "tbsRequest.requestList.?LAST.reqCert.serialNumber",
646 serial_number->data, serial_number->size);
647 if (result != ASN1_SUCCESS)
649 gnutls_assert ();
650 return _gnutls_asn2err (result);
653 /* XXX add separate function that can add extensions too */
654 result = asn1_write_value
655 (req->req, "tbsRequest.requestList.?LAST.singleRequestExtensions",
656 NULL, 0);
657 if (result != ASN1_SUCCESS)
659 gnutls_assert ();
660 return _gnutls_asn2err (result);
663 return GNUTLS_E_SUCCESS;
667 * gnutls_ocsp_req_add_cert:
668 * @req: should contain a #gnutls_ocsp_req_t structure
669 * @digest: hash algorithm, a #gnutls_digest_algorithm_t value
670 * @issuer: issuer of @subject certificate
671 * @cert: certificate to request status for
673 * This function will add another request to the OCSP request for a
674 * particular certificate. The issuer name hash, issuer key hash, and
675 * serial number fields is populated as follows. The issuer name and
676 * the serial number is taken from @cert. The issuer key is taken
677 * from @issuer. The hashed values will be hashed using the @digest
678 * algorithm, normally %GNUTLS_DIG_SHA1.
680 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
681 * negative error code is returned.
684 gnutls_ocsp_req_add_cert (gnutls_ocsp_req_t req,
685 gnutls_digest_algorithm_t digest,
686 gnutls_x509_crt_t issuer,
687 gnutls_x509_crt_t cert)
689 int ret;
690 gnutls_datum_t sn, tmp, inh, ikh;
691 uint8_t inh_buf[MAX_HASH_SIZE];
692 uint8_t ikh_buf[MAX_HASH_SIZE];
693 size_t inhlen = MAX_HASH_SIZE;
694 size_t ikhlen = MAX_HASH_SIZE;
696 if (req == NULL || issuer == NULL || cert == NULL)
698 gnutls_assert ();
699 return GNUTLS_E_INVALID_REQUEST;
702 ret = _gnutls_x509_der_encode (cert->cert,
703 "tbsCertificate.issuer.rdnSequence",
704 &tmp, 0);
705 if (ret != GNUTLS_E_SUCCESS)
707 gnutls_assert ();
708 return ret;
711 ret = gnutls_fingerprint (digest, &tmp, inh_buf, &inhlen);
712 gnutls_free (tmp.data);
713 if (ret != GNUTLS_E_SUCCESS)
715 gnutls_assert ();
716 return ret;
718 inh.size = inhlen;
719 inh.data = inh_buf;
721 ret = _gnutls_x509_read_value
722 (issuer->cert, "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
723 &tmp, 2);
724 if (ret != GNUTLS_E_SUCCESS)
726 gnutls_assert ();
727 return ret;
730 ret = gnutls_fingerprint (digest, &tmp, ikh_buf, &ikhlen);
731 gnutls_free (tmp.data);
732 if (ret != GNUTLS_E_SUCCESS)
734 gnutls_assert ();
735 return ret;
737 ikh.size = ikhlen;
738 ikh.data = ikh_buf;
740 ret = _gnutls_x509_read_value (cert->cert, "tbsCertificate.serialNumber",
741 &sn, 0);
742 if (ret != GNUTLS_E_SUCCESS)
744 gnutls_assert ();
745 return ret;
748 ret = gnutls_ocsp_req_add_cert_id (req, digest, &inh, &ikh, &sn);
749 gnutls_free (sn.data);
750 if (ret != GNUTLS_E_SUCCESS)
752 gnutls_assert ();
753 return ret;
756 return GNUTLS_E_SUCCESS;
760 * gnutls_ocsp_req_get_extension:
761 * @req: should contain a #gnutls_ocsp_req_t structure
762 * @indx: Specifies which extension OID to get. Use (0) to get the first one.
763 * @oid: will hold newly allocated buffer with OID of extension, may be NULL
764 * @critical: output variable with critical flag, may be NULL.
765 * @data: will hold newly allocated buffer with extension data, may be NULL
767 * This function will return all information about the requested
768 * extension in the OCSP request. The information returned is the
769 * OID, the critical flag, and the data itself. The extension OID
770 * will be stored as a string. Any of @oid, @critical, and @data may
771 * be NULL which means that the caller is not interested in getting
772 * that information back.
774 * The caller needs to deallocate memory by calling gnutls_free() on
775 * @oid->data and @data->data.
777 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
778 * negative error code is returned. If you have reached the last
779 * extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
780 * be returned.
783 gnutls_ocsp_req_get_extension (gnutls_ocsp_req_t req,
784 unsigned indx,
785 gnutls_datum_t *oid,
786 unsigned int *critical,
787 gnutls_datum_t *data)
789 int ret;
790 char str_critical[10];
791 char name[ASN1_MAX_NAME_SIZE];
792 int len;
794 if (!req)
796 gnutls_assert ();
797 return GNUTLS_E_INVALID_REQUEST;
800 snprintf (name, sizeof (name), "tbsRequest.requestExtensions.?%u.critical",
801 indx + 1);
802 len = sizeof (str_critical);
803 ret = asn1_read_value (req->req, name, str_critical, &len);
804 if (ret == ASN1_ELEMENT_NOT_FOUND)
805 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
806 else if (ret != ASN1_SUCCESS)
808 gnutls_assert ();
809 return _gnutls_asn2err (ret);
812 if (critical)
814 if (str_critical[0] == 'T')
815 *critical = 1;
816 else
817 *critical = 0;
820 if (oid)
822 snprintf (name, sizeof (name),
823 "tbsRequest.requestExtensions.?%u.extnID", indx + 1);
824 ret = _gnutls_x509_read_value (req->req, name, oid, 0);
825 if (ret != GNUTLS_E_SUCCESS)
827 gnutls_assert ();
828 return ret;
832 if (data)
834 snprintf (name, sizeof (name),
835 "tbsRequest.requestExtensions.?%u.extnValue", indx + 1);
836 ret = _gnutls_x509_read_value (req->req, name, data, 0);
837 if (ret != GNUTLS_E_SUCCESS)
839 gnutls_assert ();
840 if (oid)
841 gnutls_free (oid->data);
842 return ret;
846 return GNUTLS_E_SUCCESS;
850 * gnutls_ocsp_req_set_extension:
851 * @req: should contain a #gnutls_ocsp_req_t structure
852 * @oid: buffer with OID of extension as a string.
853 * @critical: critical flag, normally false.
854 * @data: the extension data
856 * This function will add an extension to the OCSP request. Calling
857 * this function multiple times for the same OID will overwrite values
858 * from earlier calls.
860 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
861 * negative error code is returned.
864 gnutls_ocsp_req_set_extension (gnutls_ocsp_req_t req,
865 const char *oid,
866 unsigned int critical,
867 const gnutls_datum_t *data)
869 if (req == NULL || oid == NULL || data == NULL)
871 gnutls_assert ();
872 return GNUTLS_E_INVALID_REQUEST;
875 return set_extension (req->req, "tbsRequest.requestExtensions", oid,
876 data, critical);
880 * gnutls_ocsp_req_get_nonce:
881 * @req: should contain a #gnutls_ocsp_req_t structure
882 * @critical: whether nonce extension is marked critical, or NULL
883 * @nonce: will hold newly allocated buffer with nonce data
885 * This function will return the OCSP request nonce extension data.
887 * The caller needs to deallocate memory by calling gnutls_free() on
888 * @nonce->data.
890 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
891 * negative error code is returned.
894 gnutls_ocsp_req_get_nonce (gnutls_ocsp_req_t req,
895 unsigned int *critical,
896 gnutls_datum_t *nonce)
898 int ret;
899 size_t l = 0;
900 gnutls_datum_t tmp;
902 if (req == NULL || nonce == NULL)
904 gnutls_assert ();
905 return GNUTLS_E_INVALID_REQUEST;
908 ret = get_extension (req->req, "tbsRequest.requestExtensions",
909 GNUTLS_OCSP_NONCE, 0,
910 &tmp, critical);
911 if (ret != GNUTLS_E_SUCCESS)
913 gnutls_assert ();
914 return ret;
917 ret = _gnutls_x509_decode_octet_string (NULL, tmp.data, (size_t) tmp.size,
918 NULL, &l);
919 if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
921 gnutls_assert ();
922 gnutls_free (tmp.data);
923 return ret;
926 nonce->data = gnutls_malloc (l);
927 if (nonce->data == NULL)
929 gnutls_assert ();
930 gnutls_free (tmp.data);
931 return GNUTLS_E_MEMORY_ERROR;
934 ret = _gnutls_x509_decode_octet_string (NULL, tmp.data, (size_t) tmp.size,
935 nonce->data, &l);
936 gnutls_free (tmp.data);
937 if (ret != GNUTLS_E_SUCCESS)
939 gnutls_assert ();
940 return ret;
942 nonce->size = l;
944 return GNUTLS_E_SUCCESS;
948 * gnutls_ocsp_req_set_nonce:
949 * @req: should contain a #gnutls_ocsp_req_t structure
950 * @critical: critical flag, normally false.
951 * @nonce: the nonce data
953 * This function will add an nonce extension to the OCSP request.
954 * Calling this function multiple times will overwrite values from
955 * earlier calls.
957 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
958 * negative error code is returned.
961 gnutls_ocsp_req_set_nonce (gnutls_ocsp_req_t req,
962 unsigned int critical,
963 const gnutls_datum_t *nonce)
965 int ret;
966 gnutls_datum_t dernonce;
967 unsigned char temp[SIZEOF_UNSIGNED_LONG_INT + 1];
968 int len;
970 if (req == NULL || nonce == NULL)
972 gnutls_assert ();
973 return GNUTLS_E_INVALID_REQUEST;
976 asn1_length_der (nonce->size, temp, &len);
978 dernonce.size = 1 + len + nonce->size;
979 dernonce.data = gnutls_malloc (dernonce.size);
980 if (dernonce.data == NULL)
982 gnutls_assert ();
983 return GNUTLS_E_MEMORY_ERROR;
986 dernonce.data[0] = '\x04';
987 memcpy (dernonce.data + 1, temp, len);
988 memcpy (dernonce.data + 1 + len, nonce->data, nonce->size);
990 ret = set_extension (req->req, "tbsRequest.requestExtensions",
991 GNUTLS_OCSP_NONCE, &dernonce, critical);
992 gnutls_free (dernonce.data);
993 if (ret != GNUTLS_E_SUCCESS)
995 gnutls_assert ();
996 return ret;
999 return ret;
1003 * gnutls_ocsp_req_randomize_nonce:
1004 * @req: should contain a #gnutls_ocsp_req_t structure
1006 * This function will add or update an nonce extension to the OCSP
1007 * request with a newly generated random value.
1009 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1010 * negative error code is returned.
1013 gnutls_ocsp_req_randomize_nonce (gnutls_ocsp_req_t req)
1015 int ret;
1016 uint8_t rndbuf[23];
1017 gnutls_datum_t nonce = { rndbuf, sizeof (rndbuf) };
1019 if (req == NULL)
1021 gnutls_assert ();
1022 return GNUTLS_E_INVALID_REQUEST;
1025 ret = gnutls_rnd (GNUTLS_RND_NONCE, rndbuf, sizeof (rndbuf));
1026 if (ret != GNUTLS_E_SUCCESS)
1028 gnutls_assert ();
1029 return ret;
1032 ret = gnutls_ocsp_req_set_nonce (req, 0, &nonce);
1033 if (ret != GNUTLS_E_SUCCESS)
1035 gnutls_assert ();
1036 return ret;
1039 return GNUTLS_E_SUCCESS;
1043 * gnutls_ocsp_resp_get_status:
1044 * @resp: should contain a #gnutls_ocsp_resp_t structure
1046 * This function will return the status of a OCSP response, an
1047 * #gnutls_ocsp_resp_status_t enumeration.
1049 * Returns: status of OCSP request as a #gnutls_ocsp_resp_status_t, or
1050 * a negative error code on error.
1053 gnutls_ocsp_resp_get_status (gnutls_ocsp_resp_t resp)
1055 uint8_t str[1];
1056 int len, ret;
1058 if (resp == NULL)
1060 gnutls_assert ();
1061 return GNUTLS_E_INVALID_REQUEST;
1064 len = sizeof (str);
1065 ret = asn1_read_value (resp->resp, "responseStatus", str, &len);
1066 if (ret != ASN1_SUCCESS)
1068 gnutls_assert ();
1069 return _gnutls_asn2err (ret);
1072 switch (str[0])
1074 case GNUTLS_OCSP_RESP_SUCCESSFUL:
1075 case GNUTLS_OCSP_RESP_MALFORMEDREQUEST:
1076 case GNUTLS_OCSP_RESP_INTERNALERROR:
1077 case GNUTLS_OCSP_RESP_TRYLATER:
1078 case GNUTLS_OCSP_RESP_SIGREQUIRED:
1079 case GNUTLS_OCSP_RESP_UNAUTHORIZED:
1080 break;
1081 default:
1082 return GNUTLS_E_UNEXPECTED_PACKET;
1085 return (int) str[0];
1089 * gnutls_ocsp_resp_get_response:
1090 * @resp: should contain a #gnutls_ocsp_resp_t structure
1091 * @response_type_oid: newly allocated output buffer with response type OID
1092 * @response: newly allocated output buffer with DER encoded response
1094 * This function will extract the response type OID in and the
1095 * response data from an OCSP response. Normally the
1096 * @response_type_oid is always "1.3.6.1.5.5.7.48.1.1" which means the
1097 * @response should be decoded as a Basic OCSP Response, but
1098 * technically other response types could be used.
1100 * This function is typically only useful when you want to extract the
1101 * response type OID of an response for diagnostic purposes.
1102 * Otherwise gnutls_ocsp_resp_import() will decode the basic OCSP
1103 * response part and the caller need not worry about that aspect.
1105 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1106 * negative error value.
1109 gnutls_ocsp_resp_get_response (gnutls_ocsp_resp_t resp,
1110 gnutls_datum_t *response_type_oid,
1111 gnutls_datum_t *response)
1113 int ret;
1115 if (resp == NULL)
1117 gnutls_assert ();
1118 return GNUTLS_E_INVALID_REQUEST;
1121 if (response_type_oid != NULL)
1123 ret = _gnutls_x509_read_value (resp->resp, "responseBytes.responseType",
1124 response_type_oid, 0);
1125 if (ret < 0)
1127 gnutls_assert ();
1128 return ret;
1132 if (response != NULL)
1134 ret = _gnutls_x509_read_value (resp->resp, "responseBytes.response",
1135 response, 0);
1136 if (ret < 0)
1138 gnutls_assert ();
1139 return ret;
1143 return GNUTLS_E_SUCCESS;
1147 * gnutls_ocsp_resp_get_version:
1148 * @resp: should contain a #gnutls_ocsp_resp_t structure
1150 * This function will return the version of the Basic OCSP Response.
1151 * Typically this is always 1 indicating version 1.
1153 * Returns: version of Basic OCSP response, or a negative error code
1154 * on error.
1157 gnutls_ocsp_resp_get_version (gnutls_ocsp_resp_t resp)
1159 uint8_t version[8];
1160 int len, ret;
1162 if (resp == NULL)
1164 gnutls_assert ();
1165 return GNUTLS_E_INVALID_REQUEST;
1168 len = sizeof (version);
1169 ret = asn1_read_value (resp->resp, "tbsResponseData.version", version, &len);
1170 if (ret != ASN1_SUCCESS)
1172 if (ret == ASN1_ELEMENT_NOT_FOUND)
1173 return 1; /* the DEFAULT version */
1174 gnutls_assert ();
1175 return _gnutls_asn2err (ret);
1178 return (int) version[0] + 1;
1182 * gnutls_ocsp_resp_get_responder:
1183 * @resp: should contain a #gnutls_ocsp_resp_t structure
1184 * @dn: newly allocated buffer with name
1186 * This function will extract the name of the Basic OCSP Response in
1187 * the provided buffer. The name will be in the form
1188 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
1189 * will be ASCII or UTF-8 encoded, depending on the certificate data.
1191 * The caller needs to deallocate memory by calling gnutls_free() on
1192 * @dn->data.
1194 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1195 * negative error code is returned.
1198 gnutls_ocsp_resp_get_responder (gnutls_ocsp_resp_t resp,
1199 gnutls_datum_t *dn)
1201 int ret;
1202 size_t l = 0;
1204 if (resp == NULL || dn == NULL)
1206 gnutls_assert ();
1207 return GNUTLS_E_INVALID_REQUEST;
1210 ret = _gnutls_x509_parse_dn
1211 (resp->basicresp, "tbsResponseData.responderID.byName",
1212 NULL, &l);
1213 if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
1215 gnutls_assert ();
1216 return ret;
1219 dn->data = gnutls_malloc (l);
1220 if (dn->data == NULL)
1222 gnutls_assert ();
1223 return GNUTLS_E_MEMORY_ERROR;
1226 ret = _gnutls_x509_parse_dn
1227 (resp->basicresp, "tbsResponseData.responderID.byName",
1228 (char*)dn->data, &l);
1229 if (ret != GNUTLS_E_SUCCESS)
1231 gnutls_assert ();
1232 return ret;
1235 dn->size = l;
1237 return GNUTLS_E_SUCCESS;
1241 * gnutls_ocsp_resp_get_produced:
1242 * @resp: should contain a #gnutls_ocsp_resp_t structure
1244 * This function will return the time when the OCSP response was
1245 * signed.
1247 * Returns: signing time, or (time_t)-1 on error.
1249 time_t
1250 gnutls_ocsp_resp_get_produced (gnutls_ocsp_resp_t resp)
1252 char ttime[MAX_TIME];
1253 int len, ret;
1254 time_t c_time;
1256 if (resp == NULL || resp->basicresp == NULL)
1258 gnutls_assert ();
1259 return (time_t) (-1);
1262 len = sizeof (ttime) - 1;
1263 ret = asn1_read_value (resp->basicresp, "tbsResponseData.producedAt",
1264 ttime, &len);
1265 if (ret != ASN1_SUCCESS)
1267 gnutls_assert ();
1268 return (time_t) (-1);
1271 c_time = _gnutls_x509_generalTime2gtime (ttime);
1273 return c_time;
1277 * gnutls_ocsp_resp_check_crt:
1278 * @resp: should contain a #gnutls_ocsp_resp_t structure
1279 * @indx: Specifies response number to get. Use (0) to get the first one.
1280 * @crt: The certificate to check
1282 * This function will check whether the OCSP response
1283 * is about the provided certificate.
1285 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1286 * negative error code is returned.
1289 gnutls_ocsp_resp_check_crt (gnutls_ocsp_resp_t resp,
1290 unsigned int indx,
1291 gnutls_x509_crt_t crt)
1293 int ret;
1294 gnutls_digest_algorithm_t digest;
1295 gnutls_datum_t rdn_hash = {NULL, 0}, rserial = {NULL, 0};
1296 gnutls_datum_t cserial = {NULL, 0};
1297 gnutls_datum_t dn = {NULL, 0};
1298 uint8_t cdn_hash[MAX_HASH_SIZE];
1299 size_t t, hash_len;
1301 ret = gnutls_ocsp_resp_get_single (resp, indx, &digest, &rdn_hash, NULL,
1302 &rserial, NULL, NULL, NULL, NULL, NULL);
1303 if (ret < 0)
1304 return gnutls_assert_val(ret);
1306 if (rserial.size == 0 || digest == GNUTLS_DIG_UNKNOWN)
1308 ret = gnutls_assert_val(GNUTLS_E_OCSP_RESPONSE_ERROR);
1309 goto cleanup;
1312 hash_len = _gnutls_hash_get_algo_len(digest);
1313 if (hash_len != rdn_hash.size)
1315 ret = gnutls_assert_val(GNUTLS_E_OCSP_RESPONSE_ERROR);
1316 goto cleanup;
1319 cserial.size = rserial.size;
1320 cserial.data = gnutls_malloc(cserial.size);
1321 if (cserial.data == NULL)
1323 ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1324 goto cleanup;
1327 t = cserial.size;
1328 ret = gnutls_x509_crt_get_serial(crt, cserial.data, &t);
1329 if (ret < 0)
1331 gnutls_assert();
1332 goto cleanup;
1335 if (rserial.size != cserial.size || memcmp(cserial.data, rserial.data, rserial.size) != 0)
1337 ret = GNUTLS_E_OCSP_RESPONSE_ERROR;
1338 gnutls_assert();
1339 goto cleanup;
1342 ret = gnutls_x509_crt_get_raw_issuer_dn(crt, &dn);
1343 if (ret < 0)
1345 gnutls_assert();
1346 goto cleanup;
1349 ret = _gnutls_hash_fast( digest, dn.data, dn.size, cdn_hash);
1350 if (ret < 0)
1352 gnutls_assert();
1353 goto cleanup;
1356 if (memcmp(cdn_hash, rdn_hash.data, hash_len) != 0)
1358 ret = GNUTLS_E_OCSP_RESPONSE_ERROR;
1359 gnutls_assert();
1360 goto cleanup;
1363 ret = 0;
1365 cleanup:
1366 gnutls_free(rdn_hash.data);
1367 gnutls_free(rserial.data);
1368 gnutls_free(cserial.data);
1369 gnutls_free(dn.data);
1371 return ret;
1375 * gnutls_ocsp_resp_get_single:
1376 * @resp: should contain a #gnutls_ocsp_resp_t structure
1377 * @indx: Specifies response number to get. Use (0) to get the first one.
1378 * @digest: output variable with #gnutls_digest_algorithm_t hash algorithm
1379 * @issuer_name_hash: output buffer with hash of issuer's DN
1380 * @issuer_key_hash: output buffer with hash of issuer's public key
1381 * @serial_number: output buffer with serial number of certificate to check
1382 * @cert_status: a certificate status, a #gnutls_ocsp_cert_status_t enum.
1383 * @this_update: time at which the status is known to be correct.
1384 * @next_update: when newer information will be available, or (time_t)-1 if unspecified
1385 * @revocation_time: when @cert_status is %GNUTLS_OCSP_CERT_REVOKED, holds time of revocation.
1386 * @revocation_reason: revocation reason, a #gnutls_x509_crl_reason_t enum.
1388 * This function will return the certificate information of the
1389 * @indx'ed response in the Basic OCSP Response @resp. The
1390 * information returned corresponds to the OCSP SingleResponse structure
1391 * except the final singleExtensions.
1393 * Each of the pointers to output variables may be NULL to indicate
1394 * that the caller is not interested in that value.
1396 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1397 * negative error code is returned. If you have reached the last
1398 * CertID available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1399 * returned.
1402 gnutls_ocsp_resp_get_single (gnutls_ocsp_resp_t resp,
1403 unsigned indx,
1404 gnutls_digest_algorithm_t *digest,
1405 gnutls_datum_t *issuer_name_hash,
1406 gnutls_datum_t *issuer_key_hash,
1407 gnutls_datum_t *serial_number,
1408 unsigned int *cert_status,
1409 time_t *this_update,
1410 time_t *next_update,
1411 time_t *revocation_time,
1412 unsigned int *revocation_reason)
1414 gnutls_datum_t sa;
1415 char name[ASN1_MAX_NAME_SIZE];
1416 int ret;
1418 snprintf (name, sizeof (name),
1419 "tbsResponseData.responses.?%u.certID.hashAlgorithm.algorithm",
1420 indx + 1);
1421 ret = _gnutls_x509_read_value (resp->basicresp, name, &sa, 0);
1422 if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1423 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1424 else if (ret < 0)
1426 gnutls_assert ();
1427 return ret;
1430 ret = _gnutls_x509_oid_to_digest ((char*)sa.data);
1431 _gnutls_free_datum (&sa);
1432 if (ret < 0)
1434 gnutls_assert ();
1435 return ret;
1438 if (digest)
1439 *digest = ret;
1441 if (issuer_name_hash)
1443 snprintf (name, sizeof (name),
1444 "tbsResponseData.responses.?%u.certID.issuerNameHash",
1445 indx + 1);
1446 ret = _gnutls_x509_read_value (resp->basicresp, name,
1447 issuer_name_hash, 0);
1448 if (ret != GNUTLS_E_SUCCESS)
1450 gnutls_assert ();
1451 return ret;
1455 if (issuer_key_hash)
1457 snprintf (name, sizeof (name),
1458 "tbsResponseData.responses.?%u.certID.issuerKeyHash",
1459 indx + 1);
1460 ret = _gnutls_x509_read_value (resp->basicresp, name,
1461 issuer_key_hash, 0);
1462 if (ret != GNUTLS_E_SUCCESS)
1464 gnutls_assert ();
1465 if (issuer_name_hash)
1466 gnutls_free (issuer_name_hash->data);
1467 return ret;
1471 if (serial_number)
1473 snprintf (name, sizeof (name),
1474 "tbsResponseData.responses.?%u.certID.serialNumber",
1475 indx + 1);
1476 ret = _gnutls_x509_read_value (resp->basicresp, name,
1477 serial_number, 0);
1478 if (ret != GNUTLS_E_SUCCESS)
1480 gnutls_assert ();
1481 if (issuer_name_hash)
1482 gnutls_free (issuer_name_hash->data);
1483 if (issuer_key_hash)
1484 gnutls_free (issuer_key_hash->data);
1485 return ret;
1489 if (cert_status)
1491 snprintf (name, sizeof (name),
1492 "tbsResponseData.responses.?%u.certStatus",
1493 indx + 1);
1494 ret = _gnutls_x509_read_value (resp->basicresp, name, &sa, 0);
1495 if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1496 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1497 else if (ret < 0)
1499 gnutls_assert ();
1500 return ret;
1502 if (sa.size == 5 && memcmp (sa.data, "good", sa.size) == 0)
1503 *cert_status = GNUTLS_OCSP_CERT_GOOD;
1504 else if (sa.size == 8 && memcmp (sa.data, "revoked", sa.size) == 0)
1505 *cert_status = GNUTLS_OCSP_CERT_REVOKED;
1506 else if (sa.size == 8 && memcmp (sa.data, "unknown", sa.size) == 0)
1507 *cert_status = GNUTLS_OCSP_CERT_UNKNOWN;
1508 else
1510 gnutls_assert ();
1511 gnutls_free (sa.data);
1512 return GNUTLS_E_ASN1_DER_ERROR;
1514 gnutls_free (sa.data);
1517 if (this_update)
1519 char ttime[MAX_TIME];
1520 int len;
1522 snprintf (name, sizeof (name),
1523 "tbsResponseData.responses.?%u.thisUpdate",
1524 indx + 1);
1525 len = sizeof (ttime) - 1;
1526 ret = asn1_read_value (resp->basicresp, name, ttime, &len);
1527 if (ret != ASN1_SUCCESS)
1529 gnutls_assert ();
1530 *this_update = (time_t) (-1);
1532 else
1533 *this_update = _gnutls_x509_generalTime2gtime (ttime);
1536 if (next_update)
1538 char ttime[MAX_TIME];
1539 int len;
1541 snprintf (name, sizeof (name),
1542 "tbsResponseData.responses.?%u.nextUpdate",
1543 indx + 1);
1544 len = sizeof (ttime) - 1;
1545 ret = asn1_read_value (resp->basicresp, name, ttime, &len);
1546 if (ret != ASN1_SUCCESS)
1548 gnutls_assert ();
1549 *next_update = (time_t) (-1);
1551 else
1552 *next_update = _gnutls_x509_generalTime2gtime (ttime);
1555 if (revocation_time)
1557 char ttime[MAX_TIME];
1558 int len;
1560 snprintf (name, sizeof (name),
1561 "tbsResponseData.responses.?%u.certStatus."
1562 "revoked.revocationTime",
1563 indx + 1);
1564 len = sizeof (ttime) - 1;
1565 ret = asn1_read_value (resp->basicresp, name, ttime, &len);
1566 if (ret != ASN1_SUCCESS)
1568 gnutls_assert ();
1569 *revocation_time = (time_t) (-1);
1571 else
1572 *revocation_time = _gnutls_x509_generalTime2gtime (ttime);
1575 /* revocation_reason */
1576 if (revocation_reason)
1578 snprintf (name, sizeof (name),
1579 "tbsResponseData.responses.?%u.certStatus."
1580 "revoked.revocationReason",
1581 indx + 1);
1583 ret = _gnutls_x509_read_uint (resp->basicresp, name,
1584 revocation_reason);
1585 if (ret < 0)
1586 *revocation_reason = GNUTLS_X509_CRLREASON_UNSPECIFIED;
1589 return GNUTLS_E_SUCCESS;
1593 * gnutls_ocsp_resp_get_extension:
1594 * @resp: should contain a #gnutls_ocsp_resp_t structure
1595 * @indx: Specifies which extension OID to get. Use (0) to get the first one.
1596 * @oid: will hold newly allocated buffer with OID of extension, may be NULL
1597 * @critical: output variable with critical flag, may be NULL.
1598 * @data: will hold newly allocated buffer with extension data, may be NULL
1600 * This function will return all information about the requested
1601 * extension in the OCSP response. The information returned is the
1602 * OID, the critical flag, and the data itself. The extension OID
1603 * will be stored as a string. Any of @oid, @critical, and @data may
1604 * be NULL which means that the caller is not interested in getting
1605 * that information back.
1607 * The caller needs to deallocate memory by calling gnutls_free() on
1608 * @oid->data and @data->data.
1610 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1611 * negative error code is returned. If you have reached the last
1612 * extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
1613 * be returned.
1616 gnutls_ocsp_resp_get_extension (gnutls_ocsp_resp_t resp,
1617 unsigned indx,
1618 gnutls_datum_t *oid,
1619 unsigned int *critical,
1620 gnutls_datum_t *data)
1622 int ret;
1623 char str_critical[10];
1624 char name[ASN1_MAX_NAME_SIZE];
1625 int len;
1627 if (!resp)
1629 gnutls_assert ();
1630 return GNUTLS_E_INVALID_REQUEST;
1633 snprintf (name, sizeof (name),
1634 "tbsResponseData.responseExtensions.?%u.critical",
1635 indx + 1);
1636 len = sizeof (str_critical);
1637 ret = asn1_read_value (resp->basicresp, name, str_critical, &len);
1638 if (ret == ASN1_ELEMENT_NOT_FOUND)
1639 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1640 else if (ret != ASN1_SUCCESS)
1642 gnutls_assert ();
1643 return _gnutls_asn2err (ret);
1646 if (critical)
1648 if (str_critical[0] == 'T')
1649 *critical = 1;
1650 else
1651 *critical = 0;
1654 if (oid)
1656 snprintf (name, sizeof (name),
1657 "tbsResponseData.responseExtensions.?%u.extnID", indx + 1);
1658 ret = _gnutls_x509_read_value (resp->basicresp, name, oid, 0);
1659 if (ret != GNUTLS_E_SUCCESS)
1661 gnutls_assert ();
1662 return ret;
1666 if (data)
1668 snprintf (name, sizeof (name),
1669 "tbsResponseData.responseExtensions.?%u.extnValue", indx + 1);
1670 ret = _gnutls_x509_read_value (resp->basicresp, name, data, 0);
1671 if (ret != GNUTLS_E_SUCCESS)
1673 gnutls_assert ();
1674 if (oid)
1675 gnutls_free (oid->data);
1676 return ret;
1680 return GNUTLS_E_SUCCESS;
1684 * gnutls_ocsp_resp_get_nonce:
1685 * @resp: should contain a #gnutls_ocsp_resp_t structure
1686 * @critical: whether nonce extension is marked critical
1687 * @nonce: will hold newly allocated buffer with nonce data
1689 * This function will return the Basic OCSP Response nonce extension
1690 * data.
1692 * The caller needs to deallocate memory by calling gnutls_free() on
1693 * @nonce->data.
1695 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1696 * negative error code is returned.
1699 gnutls_ocsp_resp_get_nonce (gnutls_ocsp_resp_t resp,
1700 unsigned int *critical,
1701 gnutls_datum_t *nonce)
1703 int ret;
1704 size_t l = 0;
1705 gnutls_datum_t tmp;
1707 ret = get_extension (resp->basicresp, "tbsResponseData.responseExtensions",
1708 GNUTLS_OCSP_NONCE, 0,
1709 &tmp, critical);
1710 if (ret != GNUTLS_E_SUCCESS)
1712 gnutls_assert ();
1713 return ret;
1716 ret = _gnutls_x509_decode_octet_string (NULL, tmp.data, (size_t) tmp.size,
1717 NULL, &l);
1718 if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
1720 gnutls_assert ();
1721 gnutls_free (tmp.data);
1722 return ret;
1725 nonce->data = gnutls_malloc (l);
1726 if (nonce->data == NULL)
1728 gnutls_assert ();
1729 gnutls_free (tmp.data);
1730 return GNUTLS_E_MEMORY_ERROR;
1733 ret = _gnutls_x509_decode_octet_string (NULL, tmp.data, (size_t) tmp.size,
1734 nonce->data, &l);
1735 gnutls_free (tmp.data);
1736 if (ret != GNUTLS_E_SUCCESS)
1738 gnutls_assert ();
1739 return ret;
1741 nonce->size = l;
1743 return GNUTLS_E_SUCCESS;
1747 * gnutls_ocsp_resp_get_signature_algorithm:
1748 * @resp: should contain a #gnutls_ocsp_resp_t structure
1750 * This function will return a value of the #gnutls_sign_algorithm_t
1751 * enumeration that is the signature algorithm that has been used to
1752 * sign the OCSP response.
1754 * Returns: a #gnutls_sign_algorithm_t value, or a negative error code
1755 * on error.
1758 gnutls_ocsp_resp_get_signature_algorithm (gnutls_ocsp_resp_t resp)
1760 int ret;
1761 gnutls_datum_t sa;
1763 ret = _gnutls_x509_read_value (resp->basicresp,
1764 "signatureAlgorithm.algorithm", &sa, 0);
1765 if (ret < 0)
1767 gnutls_assert ();
1768 return ret;
1771 ret = _gnutls_x509_oid2sign_algorithm ((char*)sa.data);
1773 _gnutls_free_datum (&sa);
1775 return ret;
1779 * gnutls_ocsp_resp_get_signature:
1780 * @resp: should contain a #gnutls_ocsp_resp_t structure
1781 * @sig: newly allocated output buffer with signature data
1783 * This function will extract the signature field of a OCSP response.
1785 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1786 * negative error value.
1789 gnutls_ocsp_resp_get_signature (gnutls_ocsp_resp_t resp,
1790 gnutls_datum_t *sig)
1792 int ret;
1794 if (resp == NULL || sig == NULL)
1796 gnutls_assert ();
1797 return GNUTLS_E_INVALID_REQUEST;
1800 ret = _gnutls_x509_read_value (resp->basicresp, "signature", sig, 2);
1801 if (ret != GNUTLS_E_SUCCESS)
1803 gnutls_assert ();
1804 return ret;
1807 return GNUTLS_E_SUCCESS;
1811 * gnutls_ocsp_resp_get_certs:
1812 * @resp: should contain a #gnutls_ocsp_resp_t structure
1813 * @certs: newly allocated array with #gnutls_x509_crt_t certificates
1814 * @ncerts: output variable with number of allocated certs.
1816 * This function will extract the X.509 certificates found in the
1817 * Basic OCSP Response. The @certs output variable will hold a newly
1818 * allocated zero-terminated array with X.509 certificates.
1820 * Every certificate in the array needs to be de-allocated with
1821 * gnutls_x509_crt_deinit() and the array itself must be freed using
1822 * gnutls_free().
1824 * Both the @certs and @ncerts variables may be NULL. Then the
1825 * function will work as normal but will not return the NULL:d
1826 * information. This can be used to get the number of certificates
1827 * only, or to just get the certificate array without its size.
1829 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1830 * negative error value.
1833 gnutls_ocsp_resp_get_certs (gnutls_ocsp_resp_t resp,
1834 gnutls_x509_crt_t ** certs,
1835 size_t *ncerts)
1837 int ret;
1838 size_t ctr = 0, i;
1839 gnutls_x509_crt_t *tmpcerts = NULL, *tmpcerts2;
1840 gnutls_datum_t c = { NULL, 0 };
1842 if (resp == NULL)
1844 gnutls_assert ();
1845 return GNUTLS_E_INVALID_REQUEST;
1848 tmpcerts = gnutls_malloc (sizeof (*tmpcerts));
1849 if (tmpcerts == NULL)
1851 gnutls_assert ();
1852 return GNUTLS_E_MEMORY_ERROR;
1855 for (;;)
1857 char name[ASN1_MAX_NAME_SIZE];
1859 snprintf (name, sizeof (name), "certs.?%u", (unsigned int)(ctr + 1));
1860 ret = _gnutls_x509_der_encode (resp->basicresp, name, &c, 0);
1861 if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1862 break;
1863 if (ret != GNUTLS_E_SUCCESS)
1865 gnutls_assert ();
1866 goto error;
1869 tmpcerts2 = gnutls_realloc (tmpcerts, (ctr + 2) * sizeof (*tmpcerts));
1870 if (tmpcerts2 == NULL)
1872 gnutls_assert ();
1873 ret = GNUTLS_E_MEMORY_ERROR;
1874 goto error;
1876 tmpcerts = tmpcerts2;
1878 ret = gnutls_x509_crt_init (&tmpcerts[ctr]);
1879 if (ret != GNUTLS_E_SUCCESS)
1881 gnutls_assert ();
1882 goto error;
1884 ctr++;
1886 ret = gnutls_x509_crt_import (tmpcerts[ctr - 1], &c,
1887 GNUTLS_X509_FMT_DER);
1888 if (ret != GNUTLS_E_SUCCESS)
1890 gnutls_assert ();
1891 goto error;
1894 gnutls_free (c.data);
1895 c.data = NULL;
1898 tmpcerts[ctr] = NULL;
1900 if (ncerts)
1901 *ncerts = ctr;
1902 if (certs)
1903 *certs = tmpcerts;
1904 else
1906 /* clean up memory */
1907 ret = GNUTLS_E_SUCCESS;
1908 goto error;
1911 return GNUTLS_E_SUCCESS;
1913 error:
1914 gnutls_free (c.data);
1915 for (i = 0; i < ctr; i++)
1916 gnutls_x509_crt_deinit (tmpcerts[i]);
1917 gnutls_free (tmpcerts);
1918 return ret;
1921 /* Search the OCSP response for a certificate matching the responderId
1922 mentioned in the OCSP response. */
1923 static gnutls_x509_crt_t
1924 find_signercert (gnutls_ocsp_resp_t resp)
1926 int rc;
1927 gnutls_x509_crt_t * certs;
1928 size_t ncerts = 0, i;
1929 gnutls_datum_t riddn;
1930 gnutls_x509_crt_t signercert = NULL;
1932 rc = gnutls_ocsp_resp_get_responder (resp, &riddn);
1933 if (rc != GNUTLS_E_SUCCESS)
1935 gnutls_assert ();
1936 return NULL;
1939 rc = gnutls_ocsp_resp_get_certs (resp, &certs, &ncerts);
1940 if (rc != GNUTLS_E_SUCCESS)
1942 gnutls_assert ();
1943 gnutls_free (riddn.data);
1944 return NULL;
1947 for (i = 0; i < ncerts; i++)
1949 char *crtdn;
1950 size_t crtdnsize = 0;
1951 int cmpok;
1953 rc = gnutls_x509_crt_get_dn (certs[i], NULL, &crtdnsize);
1954 if (rc != GNUTLS_E_SHORT_MEMORY_BUFFER)
1956 gnutls_assert ();
1957 goto quit;
1960 crtdn = gnutls_malloc (crtdnsize);
1961 if (crtdn == NULL)
1963 gnutls_assert ();
1964 goto quit;
1967 rc = gnutls_x509_crt_get_dn (certs[i], crtdn, &crtdnsize);
1968 if (rc != GNUTLS_E_SUCCESS)
1970 gnutls_assert ();
1971 gnutls_free (crtdn);
1972 goto quit;
1975 cmpok = (crtdnsize == riddn.size)
1976 && memcmp (riddn.data, crtdn, crtdnsize);
1978 gnutls_free (crtdn);
1980 if (cmpok == 0)
1982 signercert = certs[i];
1983 goto quit;
1987 gnutls_assert ();
1988 signercert = NULL;
1990 quit:
1991 gnutls_free (riddn.data);
1992 for (i = 0; i < ncerts; i++)
1993 if (certs[i] != signercert)
1994 gnutls_x509_crt_deinit (certs[i]);
1995 gnutls_free (certs);
1996 return signercert;
1999 static int
2000 _ocsp_resp_verify_direct (gnutls_ocsp_resp_t resp,
2001 gnutls_x509_crt_t signercert,
2002 unsigned int *verify,
2003 unsigned int flags)
2005 gnutls_datum_t sig = { NULL };
2006 gnutls_datum_t data = { NULL };
2007 gnutls_pubkey_t pubkey = NULL;
2008 int sigalg;
2009 int rc;
2011 if (resp == NULL || signercert == NULL)
2013 gnutls_assert ();
2014 return GNUTLS_E_INVALID_REQUEST;
2017 rc = gnutls_ocsp_resp_get_signature_algorithm (resp);
2018 if (rc < 0)
2020 gnutls_assert ();
2021 goto done;
2023 sigalg = rc;
2025 rc = export (resp->basicresp, "tbsResponseData", &data);
2026 if (rc != GNUTLS_E_SUCCESS)
2028 gnutls_assert ();
2029 goto done;
2032 rc = gnutls_pubkey_init (&pubkey);
2033 if (rc != GNUTLS_E_SUCCESS)
2035 gnutls_assert ();
2036 goto done;
2039 rc = gnutls_pubkey_import_x509 (pubkey, signercert, 0);
2040 if (rc != GNUTLS_E_SUCCESS)
2042 gnutls_assert ();
2043 goto done;
2046 rc = gnutls_ocsp_resp_get_signature (resp, &sig);
2047 if (rc != GNUTLS_E_SUCCESS)
2049 gnutls_assert ();
2050 goto done;
2053 rc = gnutls_pubkey_verify_data2 (pubkey, sigalg, 0, &data, &sig);
2054 if (rc == GNUTLS_E_PK_SIG_VERIFY_FAILED)
2056 gnutls_assert ();
2057 *verify = GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE;
2059 else if (rc < 0)
2061 gnutls_assert ();
2062 goto done;
2064 else
2065 *verify = 0;
2067 rc = GNUTLS_E_SUCCESS;
2069 done:
2070 gnutls_free (data.data);
2071 gnutls_free (sig.data);
2072 gnutls_pubkey_deinit (pubkey);
2074 return rc;
2077 static inline unsigned int vstatus_to_ocsp_status(unsigned int status)
2079 unsigned int ostatus;
2081 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
2082 ostatus = GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM;
2083 else if (status & GNUTLS_CERT_NOT_ACTIVATED)
2084 ostatus = GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED;
2085 else if (status & GNUTLS_CERT_EXPIRED)
2086 ostatus = GNUTLS_OCSP_VERIFY_CERT_EXPIRED;
2087 else
2088 ostatus = GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER;
2090 return ostatus;
2093 static int check_ocsp_purpose(gnutls_x509_crt_t signercert)
2095 char oidtmp[sizeof (GNUTLS_KP_OCSP_SIGNING)];
2096 size_t oidsize;
2097 int indx, rc;
2099 for (indx = 0; ; indx++)
2101 oidsize = sizeof (oidtmp);
2102 rc = gnutls_x509_crt_get_key_purpose_oid (signercert, indx,
2103 oidtmp, &oidsize,
2104 NULL);
2105 if (rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
2107 gnutls_assert();
2108 return rc;
2110 else if (rc == GNUTLS_E_SHORT_MEMORY_BUFFER)
2112 gnutls_assert ();
2113 continue;
2115 else if (rc != GNUTLS_E_SUCCESS)
2117 return gnutls_assert_val(rc);
2120 if (memcmp (oidtmp, GNUTLS_KP_OCSP_SIGNING, oidsize) != 0)
2122 gnutls_assert ();
2123 continue;
2125 break;
2128 return 0;
2132 * gnutls_ocsp_resp_verify_direct:
2133 * @resp: should contain a #gnutls_ocsp_resp_t structure
2134 * @issuer: certificate believed to have signed the response
2135 * @verify: output variable with verification status, an #gnutls_ocsp_cert_status_t
2136 * @flags: verification flags, 0 for now.
2138 * Verify signature of the Basic OCSP Response against the public key
2139 * in the @issuer certificate.
2141 * The output @verify variable will hold verification status codes
2142 * (e.g., %GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND,
2143 * %GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) which are only valid if the
2144 * function returned %GNUTLS_E_SUCCESS.
2146 * Note that the function returns %GNUTLS_E_SUCCESS even when
2147 * verification failed. The caller must always inspect the @verify
2148 * variable to find out the verification status.
2150 * The @flags variable should be 0 for now.
2152 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2153 * negative error value.
2156 gnutls_ocsp_resp_verify_direct (gnutls_ocsp_resp_t resp,
2157 gnutls_x509_crt_t issuer,
2158 unsigned int *verify,
2159 unsigned int flags)
2161 gnutls_x509_crt_t signercert;
2162 int rc;
2164 if (resp == NULL || issuer == NULL)
2166 gnutls_assert ();
2167 return GNUTLS_E_INVALID_REQUEST;
2170 signercert = find_signercert (resp);
2171 if (!signercert)
2173 signercert = issuer;
2175 else /* response contains a signer. Verify him */
2177 unsigned int vtmp;
2179 rc = gnutls_x509_crt_verify (signercert, &issuer, 1, 0, &vtmp);
2180 if (rc != GNUTLS_E_SUCCESS)
2182 gnutls_assert ();
2183 goto done;
2186 if (vtmp != 0)
2188 *verify = vstatus_to_ocsp_status(vtmp);
2189 gnutls_assert ();
2190 rc = GNUTLS_E_SUCCESS;
2191 goto done;
2194 rc = check_ocsp_purpose(signercert);
2195 if (rc < 0)
2197 gnutls_assert ();
2198 *verify = GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR;
2199 rc = GNUTLS_E_SUCCESS;
2200 goto done;
2204 rc = _ocsp_resp_verify_direct(resp, signercert, verify, flags);
2206 done:
2207 if (signercert != issuer)
2208 gnutls_x509_crt_deinit(signercert);
2210 return rc;
2214 * gnutls_ocsp_resp_verify:
2215 * @resp: should contain a #gnutls_ocsp_resp_t structure
2216 * @trustlist: trust anchors as a #gnutls_x509_trust_list_t structure
2217 * @verify: output variable with verification status, an #gnutls_ocsp_cert_status_t
2218 * @flags: verification flags, 0 for now.
2220 * Verify signature of the Basic OCSP Response against the public key
2221 * in the certificate of a trusted signer. The @trustlist should be
2222 * populated with trust anchors. The function will extract the signer
2223 * certificate from the Basic OCSP Response and will verify it against
2224 * the @trustlist. A trusted signer is a certificate that is either
2225 * in @trustlist, or it is signed directly by a certificate in
2226 * @trustlist and has the id-ad-ocspSigning Extended Key Usage bit
2227 * set.
2229 * The output @verify variable will hold verification status codes
2230 * (e.g., %GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND,
2231 * %GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) which are only valid if the
2232 * function returned %GNUTLS_E_SUCCESS.
2234 * Note that the function returns %GNUTLS_E_SUCCESS even when
2235 * verification failed. The caller must always inspect the @verify
2236 * variable to find out the verification status.
2238 * The @flags variable should be 0 for now.
2240 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2241 * negative error value.
2244 gnutls_ocsp_resp_verify (gnutls_ocsp_resp_t resp,
2245 gnutls_x509_trust_list_t trustlist,
2246 unsigned int *verify,
2247 unsigned int flags)
2249 gnutls_x509_crt_t signercert = NULL;
2250 int rc;
2252 /* Algorithm:
2253 1. Find signer cert.
2254 1a. Search in OCSP response Certificate field for responderID.
2255 1b. Verify that signer cert is trusted.
2256 2a. It is in trustlist?
2257 2b. It has OCSP key usage and directly signed by a CA in trustlist?
2258 3. Verify signature of Basic Response using public key from signer cert.
2261 signercert = find_signercert (resp);
2262 if (!signercert)
2264 /* XXX Search in trustlist for certificate matching
2265 responderId as well? */
2266 gnutls_assert ();
2267 *verify = GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND;
2268 rc = GNUTLS_E_SUCCESS;
2269 goto done;
2272 /* Either the signer is directly trusted (i.e., in trustlist) or it
2273 is directly signed by something in trustlist and has proper OCSP
2274 extkeyusage. */
2275 rc = _gnutls_trustlist_inlist (trustlist, signercert);
2276 if (rc < 0)
2278 gnutls_assert ();
2279 goto done;
2281 if (rc == 1)
2283 /* not in trustlist, need to verify signature and bits */
2284 gnutls_x509_crt_t issuer;
2285 unsigned vtmp;
2287 gnutls_assert ();
2289 rc = gnutls_x509_trust_list_get_issuer (trustlist, signercert,
2290 &issuer, 0);
2291 if (rc != GNUTLS_E_SUCCESS)
2293 gnutls_assert ();
2294 *verify = GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER;
2295 rc = GNUTLS_E_SUCCESS;
2296 goto done;
2299 rc = gnutls_x509_crt_verify (signercert, &issuer, 1, 0, &vtmp);
2300 if (rc != GNUTLS_E_SUCCESS)
2302 gnutls_assert ();
2303 goto done;
2306 if (vtmp != 0)
2308 *verify = vstatus_to_ocsp_status(vtmp);
2309 gnutls_assert ();
2310 rc = GNUTLS_E_SUCCESS;
2311 goto done;
2314 rc = check_ocsp_purpose(signercert);
2315 if (rc < 0)
2317 gnutls_assert ();
2318 *verify = GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR;
2319 rc = GNUTLS_E_SUCCESS;
2320 goto done;
2324 rc = _ocsp_resp_verify_direct (resp, signercert, verify, flags);
2326 done:
2327 gnutls_x509_crt_deinit (signercert);
2329 return rc;