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>
29 #include <gnutls_pk.h>
32 #include "verify-high.h"
34 #include <gnutls/ocsp.h>
35 #include <auth/cert.h>
37 typedef struct gnutls_ocsp_req_int
40 } gnutls_ocsp_req_int
;
42 typedef struct gnutls_ocsp_resp_int
45 gnutls_datum_t response_type_oid
;
47 } gnutls_ocsp_resp_int
;
52 * gnutls_ocsp_req_init:
53 * @req: The structure to be initialized
55 * This function will initialize an OCSP request structure.
57 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
58 * negative error value.
61 gnutls_ocsp_req_init (gnutls_ocsp_req_t
* req
)
63 gnutls_ocsp_req_t tmp
= gnutls_calloc (1, sizeof (gnutls_ocsp_req_int
));
67 return GNUTLS_E_MEMORY_ERROR
;
69 ret
= asn1_create_element (_gnutls_get_pkix (), "PKIX1.OCSPRequest",
71 if (ret
!= ASN1_SUCCESS
)
75 return _gnutls_asn2err (ret
);
80 return GNUTLS_E_SUCCESS
;
84 * gnutls_ocsp_req_deinit:
85 * @req: The structure to be deinitialized
87 * This function will deinitialize a OCSP request structure.
90 gnutls_ocsp_req_deinit (gnutls_ocsp_req_t req
)
96 asn1_delete_structure (&req
->req
);
104 * gnutls_ocsp_resp_init:
105 * @resp: The structure to be initialized
107 * This function will initialize an OCSP response structure.
109 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
110 * negative error value.
113 gnutls_ocsp_resp_init (gnutls_ocsp_resp_t
* resp
)
115 gnutls_ocsp_resp_t tmp
= gnutls_calloc (1, sizeof (gnutls_ocsp_resp_int
));
119 return GNUTLS_E_MEMORY_ERROR
;
121 ret
= asn1_create_element (_gnutls_get_pkix (),
122 "PKIX1.OCSPResponse", &tmp
->resp
);
123 if (ret
!= ASN1_SUCCESS
)
127 return _gnutls_asn2err (ret
);
130 ret
= asn1_create_element (_gnutls_get_pkix (),
131 "PKIX1.BasicOCSPResponse", &tmp
->basicresp
);
132 if (ret
!= ASN1_SUCCESS
)
135 asn1_delete_structure (&tmp
->resp
);
137 return _gnutls_asn2err (ret
);
142 return GNUTLS_E_SUCCESS
;
146 * gnutls_ocsp_resp_deinit:
147 * @resp: The structure to be deinitialized
149 * This function will deinitialize a OCSP response structure.
152 gnutls_ocsp_resp_deinit (gnutls_ocsp_resp_t resp
)
158 asn1_delete_structure (&resp
->resp
);
159 gnutls_free (resp
->response_type_oid
.data
);
161 asn1_delete_structure (&resp
->basicresp
);
164 resp
->response_type_oid
.data
= NULL
;
165 resp
->basicresp
= NULL
;
171 * gnutls_ocsp_req_import:
172 * @req: The structure to store the parsed request.
173 * @data: DER encoded OCSP request.
175 * This function will convert the given DER encoded OCSP request to
176 * the native #gnutls_ocsp_req_t format. The output will be stored in
179 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
180 * negative error value.
183 gnutls_ocsp_req_import (gnutls_ocsp_req_t req
,
184 const gnutls_datum_t
* data
)
188 if (req
== NULL
|| data
== NULL
)
191 return GNUTLS_E_INVALID_REQUEST
;
196 /* Any earlier asn1_der_decoding will modify the ASN.1
197 structure, so we need to replace it with a fresh
199 asn1_delete_structure (&req
->req
);
201 ret
= asn1_create_element (_gnutls_get_pkix (),
202 "PKIX1.OCSPRequest", &req
->req
);
203 if (ret
!= ASN1_SUCCESS
)
206 return _gnutls_asn2err (ret
);
210 ret
= asn1_der_decoding (&req
->req
, data
->data
, data
->size
, NULL
);
211 if (ret
!= ASN1_SUCCESS
)
214 return _gnutls_asn2err (ret
);
217 return GNUTLS_E_SUCCESS
;
221 * gnutls_ocsp_resp_import:
222 * @resp: The structure to store the parsed response.
223 * @data: DER encoded OCSP response.
225 * This function will convert the given DER encoded OCSP response to
226 * the native #gnutls_ocsp_resp_t format. It also decodes the Basic
227 * OCSP Response part, if any. The output will be stored in @resp.
229 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
230 * negative error value.
233 gnutls_ocsp_resp_import (gnutls_ocsp_resp_t resp
,
234 const gnutls_datum_t
* data
)
238 if (resp
== NULL
|| data
== NULL
)
241 return GNUTLS_E_INVALID_REQUEST
;
246 /* Any earlier asn1_der_decoding will modify the ASN.1
247 structure, so we need to replace it with a fresh
249 asn1_delete_structure (&resp
->resp
);
251 ret
= asn1_create_element (_gnutls_get_pkix (),
252 "PKIX1.OCSPResponse", &resp
->resp
);
253 if (ret
!= ASN1_SUCCESS
)
256 return _gnutls_asn2err (ret
);
260 ret
= asn1_der_decoding (&resp
->resp
, data
->data
, data
->size
, NULL
);
261 if (ret
!= ASN1_SUCCESS
)
264 return _gnutls_asn2err (ret
);
267 if (gnutls_ocsp_resp_get_status (resp
) != GNUTLS_OCSP_RESP_SUCCESSFUL
)
268 return GNUTLS_E_SUCCESS
;
270 ret
= _gnutls_x509_read_value (resp
->resp
, "responseBytes.responseType",
271 &resp
->response_type_oid
, 0);
278 #define OCSP_BASIC "1.3.6.1.5.5.7.48.1.1"
280 if (resp
->response_type_oid
.size
== sizeof (OCSP_BASIC
)
281 && memcmp (resp
->response_type_oid
.data
, OCSP_BASIC
,
282 resp
->response_type_oid
.size
) == 0)
288 asn1_delete_structure (&resp
->basicresp
);
290 ret
= asn1_create_element (_gnutls_get_pkix (),
291 "PKIX1.BasicOCSPResponse", &resp
->basicresp
);
292 if (ret
!= ASN1_SUCCESS
)
295 return _gnutls_asn2err (ret
);
299 ret
= _gnutls_x509_read_value (resp
->resp
, "responseBytes.response",
307 ret
= asn1_der_decoding (&resp
->basicresp
, d
.data
, d
.size
, NULL
);
308 gnutls_free (d
.data
);
309 if (ret
!= ASN1_SUCCESS
)
312 return _gnutls_asn2err (ret
);
316 resp
->basicresp
= NULL
;
318 return GNUTLS_E_SUCCESS
;
322 export (ASN1_TYPE node
, const char *name
, gnutls_datum_t
* data
)
327 ret
= asn1_der_coding (node
, name
, NULL
, &len
, NULL
);
328 if (ret
!= ASN1_MEM_ERROR
)
331 return _gnutls_asn2err (ret
);
334 data
->data
= gnutls_malloc (len
);
335 if (data
->data
== NULL
)
336 return GNUTLS_E_MEMORY_ERROR
;
337 ret
= asn1_der_coding (node
, name
, data
->data
, &len
, NULL
);
338 if (ret
!= ASN1_SUCCESS
)
341 return _gnutls_asn2err (ret
);
344 return GNUTLS_E_SUCCESS
;
348 * gnutls_ocsp_req_export:
349 * @req: Holds the OCSP request
350 * @data: newly allocate buffer holding DER encoded OCSP request
352 * This function will export the OCSP request to DER format.
354 * Returns: In case of failure a negative error code will be
355 * returned, and 0 on success.
358 gnutls_ocsp_req_export (gnutls_ocsp_req_t req
, gnutls_datum_t
* data
)
362 if (req
== NULL
|| data
== NULL
)
365 return GNUTLS_E_INVALID_REQUEST
;
368 /* XXX remove when we support these fields */
369 asn1_write_value (req
->req
, "tbsRequest.requestorName", NULL
, 0);
370 asn1_write_value (req
->req
, "optionalSignature", NULL
, 0);
372 /* prune extension field if we don't have any extension */
373 ret
= gnutls_ocsp_req_get_extension (req
, 0, NULL
, NULL
, NULL
);
374 if (ret
== GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
)
375 asn1_write_value (req
->req
, "tbsRequest.requestExtensions", NULL
, 0);
377 return export (req
->req
, "", data
);
381 * gnutls_ocsp_resp_export:
382 * @resp: Holds the OCSP response
383 * @data: newly allocate buffer holding DER encoded OCSP response
385 * This function will export the OCSP response to DER format.
387 * Returns: In case of failure a negative error code will be
388 * returned, and 0 on success.
391 gnutls_ocsp_resp_export (gnutls_ocsp_resp_t resp
, gnutls_datum_t
* data
)
393 if (resp
== NULL
|| data
== NULL
)
396 return GNUTLS_E_INVALID_REQUEST
;
399 return export (resp
->resp
, "", data
);
403 * gnutls_ocsp_req_get_version:
404 * @req: should contain a #gnutls_ocsp_req_t structure
406 * This function will return the version of the OCSP request.
407 * Typically this is always 1 indicating version 1.
409 * Returns: version of OCSP request, or a negative error code on error.
412 gnutls_ocsp_req_get_version (gnutls_ocsp_req_t req
)
420 return GNUTLS_E_INVALID_REQUEST
;
423 len
= sizeof (version
);
424 ret
= asn1_read_value (req
->req
, "tbsRequest.version", version
, &len
);
425 if (ret
!= ASN1_SUCCESS
)
427 if (ret
== ASN1_ELEMENT_NOT_FOUND
)
428 return 1; /* the DEFAULT version */
430 return _gnutls_asn2err (ret
);
433 return (int) version
[0] + 1;
437 * gnutls_ocsp_req_get_cert_id:
438 * @req: should contain a #gnutls_ocsp_req_t structure
439 * @indx: Specifies which extension OID to get. Use (0) to get the first one.
440 * @digest: output variable with #gnutls_digest_algorithm_t hash algorithm
441 * @issuer_name_hash: output buffer with hash of issuer's DN
442 * @issuer_key_hash: output buffer with hash of issuer's public key
443 * @serial_number: output buffer with serial number of certificate to check
445 * This function will return the certificate information of the
446 * @indx'ed request in the OCSP request. The information returned
447 * corresponds to the CertID structure:
449 * <informalexample><programlisting>
450 * CertID ::= SEQUENCE {
451 * hashAlgorithm AlgorithmIdentifier,
452 * issuerNameHash OCTET STRING, -- Hash of Issuer's DN
453 * issuerKeyHash OCTET STRING, -- Hash of Issuers public key
454 * serialNumber CertificateSerialNumber }
455 * </programlisting></informalexample>
457 * Each of the pointers to output variables may be NULL to indicate
458 * that the caller is not interested in that value.
460 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
461 * negative error code is returned. If you have reached the last
462 * CertID available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
466 gnutls_ocsp_req_get_cert_id (gnutls_ocsp_req_t req
,
468 gnutls_digest_algorithm_t
*digest
,
469 gnutls_datum_t
*issuer_name_hash
,
470 gnutls_datum_t
*issuer_key_hash
,
471 gnutls_datum_t
*serial_number
)
474 char name
[ASN1_MAX_NAME_SIZE
];
480 return GNUTLS_E_INVALID_REQUEST
;
483 snprintf (name
, sizeof (name
),
484 "tbsRequest.requestList.?%u.reqCert.hashAlgorithm.algorithm",
486 ret
= _gnutls_x509_read_value (req
->req
, name
, &sa
, 0);
487 if (ret
== GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
)
488 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
495 ret
= _gnutls_x509_oid_to_digest ((char*)sa
.data
);
496 _gnutls_free_datum (&sa
);
506 if (issuer_name_hash
)
508 snprintf (name
, sizeof (name
),
509 "tbsRequest.requestList.?%u.reqCert.issuerNameHash", indx
+ 1);
510 ret
= _gnutls_x509_read_value (req
->req
, name
, issuer_name_hash
, 0);
511 if (ret
!= GNUTLS_E_SUCCESS
)
520 snprintf (name
, sizeof (name
),
521 "tbsRequest.requestList.?%u.reqCert.issuerKeyHash", indx
+ 1);
522 ret
= _gnutls_x509_read_value (req
->req
, name
, issuer_key_hash
, 0);
523 if (ret
!= GNUTLS_E_SUCCESS
)
526 if (issuer_name_hash
)
527 gnutls_free (issuer_name_hash
->data
);
534 snprintf (name
, sizeof (name
),
535 "tbsRequest.requestList.?%u.reqCert.serialNumber", indx
+ 1);
536 ret
= _gnutls_x509_read_value (req
->req
, name
, serial_number
, 0);
537 if (ret
!= GNUTLS_E_SUCCESS
)
540 if (issuer_name_hash
)
541 gnutls_free (issuer_name_hash
->data
);
543 gnutls_free (issuer_key_hash
->data
);
548 return GNUTLS_E_SUCCESS
;
552 * gnutls_ocsp_req_add_cert_id:
553 * @req: should contain a #gnutls_ocsp_req_t structure
554 * @digest: hash algorithm, a #gnutls_digest_algorithm_t value
555 * @issuer_name_hash: hash of issuer's DN
556 * @issuer_key_hash: hash of issuer's public key
557 * @serial_number: serial number of certificate to check
559 * This function will add another request to the OCSP request for a
560 * particular certificate having the issuer name hash of
561 * @issuer_name_hash and issuer key hash of @issuer_key_hash (both
562 * hashed using @digest) and serial number @serial_number.
564 * The information needed corresponds to the CertID structure:
566 * <informalexample><programlisting>
567 * CertID ::= SEQUENCE {
568 * hashAlgorithm AlgorithmIdentifier,
569 * issuerNameHash OCTET STRING, -- Hash of Issuer's DN
570 * issuerKeyHash OCTET STRING, -- Hash of Issuers public key
571 * serialNumber CertificateSerialNumber }
572 * </programlisting></informalexample>
574 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
575 * negative error code is returned.
578 gnutls_ocsp_req_add_cert_id (gnutls_ocsp_req_t req
,
579 gnutls_digest_algorithm_t digest
,
580 const gnutls_datum_t
*issuer_name_hash
,
581 const gnutls_datum_t
*issuer_key_hash
,
582 const gnutls_datum_t
*serial_number
)
587 if (req
== NULL
|| issuer_name_hash
== NULL
588 || issuer_key_hash
== NULL
|| serial_number
== NULL
)
591 return GNUTLS_E_INVALID_REQUEST
;
594 oid
= _gnutls_x509_digest_to_oid (digest
);
598 return GNUTLS_E_INVALID_REQUEST
;
601 result
= asn1_write_value (req
->req
, "tbsRequest.requestList", "NEW", 1);
602 if (result
!= ASN1_SUCCESS
)
605 return _gnutls_asn2err (result
);
608 result
= asn1_write_value
609 (req
->req
, "tbsRequest.requestList.?LAST.reqCert.hashAlgorithm.algorithm",
611 if (result
!= ASN1_SUCCESS
)
614 return _gnutls_asn2err (result
);
617 /* XXX we don't support any algorithm with parameters */
618 result
= asn1_write_value
619 (req
->req
, "tbsRequest.requestList.?LAST.reqCert.hashAlgorithm.parameters",
620 ASN1_NULL
, ASN1_NULL_SIZE
);
621 if (result
!= ASN1_SUCCESS
)
624 return _gnutls_asn2err (result
);
627 result
= asn1_write_value
628 (req
->req
, "tbsRequest.requestList.?LAST.reqCert.issuerNameHash",
629 issuer_name_hash
->data
, issuer_name_hash
->size
);
630 if (result
!= ASN1_SUCCESS
)
633 return _gnutls_asn2err (result
);
636 result
= asn1_write_value
637 (req
->req
, "tbsRequest.requestList.?LAST.reqCert.issuerKeyHash",
638 issuer_key_hash
->data
, issuer_key_hash
->size
);
639 if (result
!= ASN1_SUCCESS
)
642 return _gnutls_asn2err (result
);
645 result
= asn1_write_value
646 (req
->req
, "tbsRequest.requestList.?LAST.reqCert.serialNumber",
647 serial_number
->data
, serial_number
->size
);
648 if (result
!= ASN1_SUCCESS
)
651 return _gnutls_asn2err (result
);
654 /* XXX add separate function that can add extensions too */
655 result
= asn1_write_value
656 (req
->req
, "tbsRequest.requestList.?LAST.singleRequestExtensions",
658 if (result
!= ASN1_SUCCESS
)
661 return _gnutls_asn2err (result
);
664 return GNUTLS_E_SUCCESS
;
668 * gnutls_ocsp_req_add_cert:
669 * @req: should contain a #gnutls_ocsp_req_t structure
670 * @digest: hash algorithm, a #gnutls_digest_algorithm_t value
671 * @issuer: issuer of @subject certificate
672 * @cert: certificate to request status for
674 * This function will add another request to the OCSP request for a
675 * particular certificate. The issuer name hash, issuer key hash, and
676 * serial number fields is populated as follows. The issuer name and
677 * the serial number is taken from @cert. The issuer key is taken
678 * from @issuer. The hashed values will be hashed using the @digest
679 * algorithm, normally %GNUTLS_DIG_SHA1.
681 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
682 * negative error code is returned.
685 gnutls_ocsp_req_add_cert (gnutls_ocsp_req_t req
,
686 gnutls_digest_algorithm_t digest
,
687 gnutls_x509_crt_t issuer
,
688 gnutls_x509_crt_t cert
)
691 gnutls_datum_t sn
, tmp
, inh
, ikh
;
692 uint8_t inh_buf
[MAX_HASH_SIZE
];
693 uint8_t ikh_buf
[MAX_HASH_SIZE
];
694 size_t inhlen
= MAX_HASH_SIZE
;
695 size_t ikhlen
= MAX_HASH_SIZE
;
697 if (req
== NULL
|| issuer
== NULL
|| cert
== NULL
)
700 return GNUTLS_E_INVALID_REQUEST
;
703 ret
= _gnutls_x509_der_encode (cert
->cert
,
704 "tbsCertificate.issuer.rdnSequence",
706 if (ret
!= GNUTLS_E_SUCCESS
)
712 ret
= gnutls_fingerprint (digest
, &tmp
, inh_buf
, &inhlen
);
713 gnutls_free (tmp
.data
);
714 if (ret
!= GNUTLS_E_SUCCESS
)
722 ret
= _gnutls_x509_read_value
723 (issuer
->cert
, "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
725 if (ret
!= GNUTLS_E_SUCCESS
)
731 ret
= gnutls_fingerprint (digest
, &tmp
, ikh_buf
, &ikhlen
);
732 gnutls_free (tmp
.data
);
733 if (ret
!= GNUTLS_E_SUCCESS
)
741 ret
= _gnutls_x509_read_value (cert
->cert
, "tbsCertificate.serialNumber",
743 if (ret
!= GNUTLS_E_SUCCESS
)
749 ret
= gnutls_ocsp_req_add_cert_id (req
, digest
, &inh
, &ikh
, &sn
);
750 gnutls_free (sn
.data
);
751 if (ret
!= GNUTLS_E_SUCCESS
)
757 return GNUTLS_E_SUCCESS
;
761 * gnutls_ocsp_req_get_extension:
762 * @req: should contain a #gnutls_ocsp_req_t structure
763 * @indx: Specifies which extension OID to get. Use (0) to get the first one.
764 * @oid: will hold newly allocated buffer with OID of extension, may be NULL
765 * @critical: output variable with critical flag, may be NULL.
766 * @data: will hold newly allocated buffer with extension data, may be NULL
768 * This function will return all information about the requested
769 * extension in the OCSP request. The information returned is the
770 * OID, the critical flag, and the data itself. The extension OID
771 * will be stored as a string. Any of @oid, @critical, and @data may
772 * be NULL which means that the caller is not interested in getting
773 * that information back.
775 * The caller needs to deallocate memory by calling gnutls_free() on
776 * @oid->data and @data->data.
778 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
779 * negative error code is returned. If you have reached the last
780 * extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
784 gnutls_ocsp_req_get_extension (gnutls_ocsp_req_t req
,
787 unsigned int *critical
,
788 gnutls_datum_t
*data
)
791 char str_critical
[10];
792 char name
[ASN1_MAX_NAME_SIZE
];
798 return GNUTLS_E_INVALID_REQUEST
;
801 snprintf (name
, sizeof (name
), "tbsRequest.requestExtensions.?%u.critical",
803 len
= sizeof (str_critical
);
804 ret
= asn1_read_value (req
->req
, name
, str_critical
, &len
);
805 if (ret
== ASN1_ELEMENT_NOT_FOUND
)
806 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
807 else if (ret
!= ASN1_SUCCESS
)
810 return _gnutls_asn2err (ret
);
815 if (str_critical
[0] == 'T')
823 snprintf (name
, sizeof (name
),
824 "tbsRequest.requestExtensions.?%u.extnID", indx
+ 1);
825 ret
= _gnutls_x509_read_value (req
->req
, name
, oid
, 0);
826 if (ret
!= GNUTLS_E_SUCCESS
)
835 snprintf (name
, sizeof (name
),
836 "tbsRequest.requestExtensions.?%u.extnValue", indx
+ 1);
837 ret
= _gnutls_x509_read_value (req
->req
, name
, data
, 0);
838 if (ret
!= GNUTLS_E_SUCCESS
)
842 gnutls_free (oid
->data
);
847 return GNUTLS_E_SUCCESS
;
851 * gnutls_ocsp_req_set_extension:
852 * @req: should contain a #gnutls_ocsp_req_t structure
853 * @oid: buffer with OID of extension as a string.
854 * @critical: critical flag, normally false.
855 * @data: the extension data
857 * This function will add an extension to the OCSP request. Calling
858 * this function multiple times for the same OID will overwrite values
859 * from earlier calls.
861 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
862 * negative error code is returned.
865 gnutls_ocsp_req_set_extension (gnutls_ocsp_req_t req
,
867 unsigned int critical
,
868 const gnutls_datum_t
*data
)
870 if (req
== NULL
|| oid
== NULL
|| data
== NULL
)
873 return GNUTLS_E_INVALID_REQUEST
;
876 return set_extension (req
->req
, "tbsRequest.requestExtensions", oid
,
881 * gnutls_ocsp_req_get_nonce:
882 * @req: should contain a #gnutls_ocsp_req_t structure
883 * @critical: whether nonce extension is marked critical, or NULL
884 * @nonce: will hold newly allocated buffer with nonce data
886 * This function will return the OCSP request nonce extension data.
888 * The caller needs to deallocate memory by calling gnutls_free() on
891 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
892 * negative error code is returned.
895 gnutls_ocsp_req_get_nonce (gnutls_ocsp_req_t req
,
896 unsigned int *critical
,
897 gnutls_datum_t
*nonce
)
903 if (req
== NULL
|| nonce
== NULL
)
906 return GNUTLS_E_INVALID_REQUEST
;
909 ret
= get_extension (req
->req
, "tbsRequest.requestExtensions",
910 GNUTLS_OCSP_NONCE
, 0,
912 if (ret
!= GNUTLS_E_SUCCESS
)
918 ret
= _gnutls_x509_decode_octet_string (NULL
, tmp
.data
, (size_t) tmp
.size
,
920 if (ret
!= GNUTLS_E_SHORT_MEMORY_BUFFER
)
923 gnutls_free (tmp
.data
);
927 nonce
->data
= gnutls_malloc (l
);
928 if (nonce
->data
== NULL
)
931 gnutls_free (tmp
.data
);
932 return GNUTLS_E_MEMORY_ERROR
;
935 ret
= _gnutls_x509_decode_octet_string (NULL
, tmp
.data
, (size_t) tmp
.size
,
937 gnutls_free (tmp
.data
);
938 if (ret
!= GNUTLS_E_SUCCESS
)
945 return GNUTLS_E_SUCCESS
;
949 * gnutls_ocsp_req_set_nonce:
950 * @req: should contain a #gnutls_ocsp_req_t structure
951 * @critical: critical flag, normally false.
952 * @nonce: the nonce data
954 * This function will add an nonce extension to the OCSP request.
955 * Calling this function multiple times will overwrite values from
958 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
959 * negative error code is returned.
962 gnutls_ocsp_req_set_nonce (gnutls_ocsp_req_t req
,
963 unsigned int critical
,
964 const gnutls_datum_t
*nonce
)
967 gnutls_datum_t dernonce
;
968 unsigned char temp
[SIZEOF_UNSIGNED_LONG_INT
+ 1];
971 if (req
== NULL
|| nonce
== NULL
)
974 return GNUTLS_E_INVALID_REQUEST
;
977 asn1_length_der (nonce
->size
, temp
, &len
);
979 dernonce
.size
= 1 + len
+ nonce
->size
;
980 dernonce
.data
= gnutls_malloc (dernonce
.size
);
981 if (dernonce
.data
== NULL
)
984 return GNUTLS_E_MEMORY_ERROR
;
987 dernonce
.data
[0] = '\x04';
988 memcpy (dernonce
.data
+ 1, temp
, len
);
989 memcpy (dernonce
.data
+ 1 + len
, nonce
->data
, nonce
->size
);
991 ret
= set_extension (req
->req
, "tbsRequest.requestExtensions",
992 GNUTLS_OCSP_NONCE
, &dernonce
, critical
);
993 gnutls_free (dernonce
.data
);
994 if (ret
!= GNUTLS_E_SUCCESS
)
1004 * gnutls_ocsp_req_randomize_nonce:
1005 * @req: should contain a #gnutls_ocsp_req_t structure
1007 * This function will add or update an nonce extension to the OCSP
1008 * request with a newly generated random value.
1010 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1011 * negative error code is returned.
1014 gnutls_ocsp_req_randomize_nonce (gnutls_ocsp_req_t req
)
1018 gnutls_datum_t nonce
= { rndbuf
, sizeof (rndbuf
) };
1023 return GNUTLS_E_INVALID_REQUEST
;
1026 ret
= gnutls_rnd (GNUTLS_RND_NONCE
, rndbuf
, sizeof (rndbuf
));
1027 if (ret
!= GNUTLS_E_SUCCESS
)
1033 ret
= gnutls_ocsp_req_set_nonce (req
, 0, &nonce
);
1034 if (ret
!= GNUTLS_E_SUCCESS
)
1040 return GNUTLS_E_SUCCESS
;
1044 * gnutls_ocsp_resp_get_status:
1045 * @resp: should contain a #gnutls_ocsp_resp_t structure
1047 * This function will return the status of a OCSP response, an
1048 * #gnutls_ocsp_resp_status_t enumeration.
1050 * Returns: status of OCSP request as a #gnutls_ocsp_resp_status_t, or
1051 * a negative error code on error.
1054 gnutls_ocsp_resp_get_status (gnutls_ocsp_resp_t resp
)
1062 return GNUTLS_E_INVALID_REQUEST
;
1066 ret
= asn1_read_value (resp
->resp
, "responseStatus", str
, &len
);
1067 if (ret
!= ASN1_SUCCESS
)
1070 return _gnutls_asn2err (ret
);
1075 case GNUTLS_OCSP_RESP_SUCCESSFUL
:
1076 case GNUTLS_OCSP_RESP_MALFORMEDREQUEST
:
1077 case GNUTLS_OCSP_RESP_INTERNALERROR
:
1078 case GNUTLS_OCSP_RESP_TRYLATER
:
1079 case GNUTLS_OCSP_RESP_SIGREQUIRED
:
1080 case GNUTLS_OCSP_RESP_UNAUTHORIZED
:
1083 return GNUTLS_E_UNEXPECTED_PACKET
;
1086 return (int) str
[0];
1090 * gnutls_ocsp_resp_get_response:
1091 * @resp: should contain a #gnutls_ocsp_resp_t structure
1092 * @response_type_oid: newly allocated output buffer with response type OID
1093 * @response: newly allocated output buffer with DER encoded response
1095 * This function will extract the response type OID in and the
1096 * response data from an OCSP response. Normally the
1097 * @response_type_oid is always "1.3.6.1.5.5.7.48.1.1" which means the
1098 * @response should be decoded as a Basic OCSP Response, but
1099 * technically other response types could be used.
1101 * This function is typically only useful when you want to extract the
1102 * response type OID of an response for diagnostic purposes.
1103 * Otherwise gnutls_ocsp_resp_import() will decode the basic OCSP
1104 * response part and the caller need not worry about that aspect.
1106 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1107 * negative error value.
1110 gnutls_ocsp_resp_get_response (gnutls_ocsp_resp_t resp
,
1111 gnutls_datum_t
*response_type_oid
,
1112 gnutls_datum_t
*response
)
1119 return GNUTLS_E_INVALID_REQUEST
;
1122 if (response_type_oid
!= NULL
)
1124 ret
= _gnutls_x509_read_value (resp
->resp
, "responseBytes.responseType",
1125 response_type_oid
, 0);
1133 if (response
!= NULL
)
1135 ret
= _gnutls_x509_read_value (resp
->resp
, "responseBytes.response",
1144 return GNUTLS_E_SUCCESS
;
1148 * gnutls_ocsp_resp_get_version:
1149 * @resp: should contain a #gnutls_ocsp_resp_t structure
1151 * This function will return the version of the Basic OCSP Response.
1152 * Typically this is always 1 indicating version 1.
1154 * Returns: version of Basic OCSP response, or a negative error code
1158 gnutls_ocsp_resp_get_version (gnutls_ocsp_resp_t resp
)
1166 return GNUTLS_E_INVALID_REQUEST
;
1169 len
= sizeof (version
);
1170 ret
= asn1_read_value (resp
->resp
, "tbsResponseData.version", version
, &len
);
1171 if (ret
!= ASN1_SUCCESS
)
1173 if (ret
== ASN1_ELEMENT_NOT_FOUND
)
1174 return 1; /* the DEFAULT version */
1176 return _gnutls_asn2err (ret
);
1179 return (int) version
[0] + 1;
1183 * gnutls_ocsp_resp_get_responder:
1184 * @resp: should contain a #gnutls_ocsp_resp_t structure
1185 * @dn: newly allocated buffer with name
1187 * This function will extract the name of the Basic OCSP Response in
1188 * the provided buffer. The name will be in the form
1189 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
1190 * will be ASCII or UTF-8 encoded, depending on the certificate data.
1192 * The caller needs to deallocate memory by calling gnutls_free() on
1195 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1196 * negative error code is returned.
1199 gnutls_ocsp_resp_get_responder (gnutls_ocsp_resp_t resp
,
1205 if (resp
== NULL
|| dn
== NULL
)
1208 return GNUTLS_E_INVALID_REQUEST
;
1211 ret
= _gnutls_x509_parse_dn
1212 (resp
->basicresp
, "tbsResponseData.responderID.byName",
1214 if (ret
!= GNUTLS_E_SHORT_MEMORY_BUFFER
)
1220 dn
->data
= gnutls_malloc (l
);
1221 if (dn
->data
== NULL
)
1224 return GNUTLS_E_MEMORY_ERROR
;
1227 ret
= _gnutls_x509_parse_dn
1228 (resp
->basicresp
, "tbsResponseData.responderID.byName",
1229 (char*)dn
->data
, &l
);
1230 if (ret
!= GNUTLS_E_SUCCESS
)
1238 return GNUTLS_E_SUCCESS
;
1242 * gnutls_ocsp_resp_get_produced:
1243 * @resp: should contain a #gnutls_ocsp_resp_t structure
1245 * This function will return the time when the OCSP response was
1248 * Returns: signing time, or (time_t)-1 on error.
1251 gnutls_ocsp_resp_get_produced (gnutls_ocsp_resp_t resp
)
1253 char ttime
[MAX_TIME
];
1257 if (resp
== NULL
|| resp
->basicresp
== NULL
)
1260 return (time_t) (-1);
1263 len
= sizeof (ttime
) - 1;
1264 ret
= asn1_read_value (resp
->basicresp
, "tbsResponseData.producedAt",
1266 if (ret
!= ASN1_SUCCESS
)
1269 return (time_t) (-1);
1272 c_time
= _gnutls_x509_generalTime2gtime (ttime
);
1278 * gnutls_ocsp_resp_check_crt:
1279 * @resp: should contain a #gnutls_ocsp_resp_t structure
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 gnutls_x509_crt_t crt
)
1293 gnutls_digest_algorithm_t digest
;
1294 gnutls_datum_t rdn_hash
= {NULL
, 0}, rserial
= {NULL
, 0};
1295 gnutls_datum_t cserial
= {NULL
, 0};
1296 gnutls_datum_t dn
= {NULL
, 0};
1297 uint8_t cdn_hash
[MAX_HASH_SIZE
];
1300 ret
= gnutls_ocsp_resp_get_single (resp
, 0, &digest
, &rdn_hash
, NULL
,
1301 &rserial
, NULL
, NULL
, NULL
, NULL
, NULL
);
1303 return gnutls_assert_val(ret
);
1305 if (rserial
.size
== 0 || digest
== GNUTLS_DIG_UNKNOWN
)
1307 ret
= gnutls_assert_val(GNUTLS_E_OCSP_RESPONSE_ERROR
);
1311 hash_len
= _gnutls_hash_get_algo_len(digest
);
1312 if (hash_len
!= rdn_hash
.size
)
1314 ret
= gnutls_assert_val(GNUTLS_E_OCSP_RESPONSE_ERROR
);
1318 cserial
.size
= rserial
.size
;
1319 cserial
.data
= gnutls_malloc(cserial
.size
);
1320 if (cserial
.data
== NULL
)
1322 ret
= gnutls_assert_val(GNUTLS_E_MEMORY_ERROR
);
1327 ret
= gnutls_x509_crt_get_serial(crt
, cserial
.data
, &t
);
1334 if (rserial
.size
!= cserial
.size
|| memcmp(cserial
.data
, rserial
.data
, rserial
.size
) != 0)
1336 ret
= GNUTLS_E_OCSP_RESPONSE_ERROR
;
1341 ret
= gnutls_x509_crt_get_raw_issuer_dn(crt
, &dn
);
1348 ret
= _gnutls_hash_fast( digest
, dn
.data
, dn
.size
, cdn_hash
);
1355 if (memcmp(cdn_hash
, rdn_hash
.data
, hash_len
) != 0)
1357 ret
= GNUTLS_E_OCSP_RESPONSE_ERROR
;
1365 gnutls_free(rdn_hash
.data
);
1366 gnutls_free(rserial
.data
);
1367 gnutls_free(cserial
.data
);
1368 gnutls_free(dn
.data
);
1374 * gnutls_ocsp_resp_get_single:
1375 * @resp: should contain a #gnutls_ocsp_resp_t structure
1376 * @indx: Specifies which extension OID to get. Use (0) to get the first one.
1377 * @digest: output variable with #gnutls_digest_algorithm_t hash algorithm
1378 * @issuer_name_hash: output buffer with hash of issuer's DN
1379 * @issuer_key_hash: output buffer with hash of issuer's public key
1380 * @serial_number: output buffer with serial number of certificate to check
1381 * @cert_status: a certificate status, a #gnutls_ocsp_cert_status_t enum.
1382 * @this_update: time at which the status is known to be correct.
1383 * @next_update: when newer information will be available, or (time_t)-1 if unspecified
1384 * @revocation_time: when @cert_status is %GNUTLS_OCSP_CERT_REVOKED, holds time of revocation.
1385 * @revocation_reason: revocation reason, a #gnutls_x509_crl_reason_t enum.
1387 * This function will return the certificate information of the
1388 * @indx'ed response in the Basic OCSP Response @resp. The
1389 * information returned corresponds to the OCSP SingleResponse structure
1390 * except the final singleExtensions.
1392 * Each of the pointers to output variables may be NULL to indicate
1393 * that the caller is not interested in that value.
1395 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1396 * negative error code is returned. If you have reached the last
1397 * CertID available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1401 gnutls_ocsp_resp_get_single (gnutls_ocsp_resp_t resp
,
1403 gnutls_digest_algorithm_t
*digest
,
1404 gnutls_datum_t
*issuer_name_hash
,
1405 gnutls_datum_t
*issuer_key_hash
,
1406 gnutls_datum_t
*serial_number
,
1407 unsigned int *cert_status
,
1408 time_t *this_update
,
1409 time_t *next_update
,
1410 time_t *revocation_time
,
1411 unsigned int *revocation_reason
)
1414 char name
[ASN1_MAX_NAME_SIZE
];
1417 snprintf (name
, sizeof (name
),
1418 "tbsResponseData.responses.?%u.certID.hashAlgorithm.algorithm",
1420 ret
= _gnutls_x509_read_value (resp
->basicresp
, name
, &sa
, 0);
1421 if (ret
== GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
)
1422 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1429 ret
= _gnutls_x509_oid_to_digest ((char*)sa
.data
);
1430 _gnutls_free_datum (&sa
);
1440 if (issuer_name_hash
)
1442 snprintf (name
, sizeof (name
),
1443 "tbsResponseData.responses.?%u.certID.issuerNameHash",
1445 ret
= _gnutls_x509_read_value (resp
->basicresp
, name
,
1446 issuer_name_hash
, 0);
1447 if (ret
!= GNUTLS_E_SUCCESS
)
1454 if (issuer_key_hash
)
1456 snprintf (name
, sizeof (name
),
1457 "tbsResponseData.responses.?%u.certID.issuerKeyHash",
1459 ret
= _gnutls_x509_read_value (resp
->basicresp
, name
,
1460 issuer_key_hash
, 0);
1461 if (ret
!= GNUTLS_E_SUCCESS
)
1464 if (issuer_name_hash
)
1465 gnutls_free (issuer_name_hash
->data
);
1472 snprintf (name
, sizeof (name
),
1473 "tbsResponseData.responses.?%u.certID.serialNumber",
1475 ret
= _gnutls_x509_read_value (resp
->basicresp
, name
,
1477 if (ret
!= GNUTLS_E_SUCCESS
)
1480 if (issuer_name_hash
)
1481 gnutls_free (issuer_name_hash
->data
);
1482 if (issuer_key_hash
)
1483 gnutls_free (issuer_key_hash
->data
);
1490 snprintf (name
, sizeof (name
),
1491 "tbsResponseData.responses.?%u.certStatus",
1493 ret
= _gnutls_x509_read_value (resp
->basicresp
, name
, &sa
, 0);
1494 if (ret
== GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
)
1495 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1501 if (sa
.size
== 5 && memcmp (sa
.data
, "good", sa
.size
) == 0)
1502 *cert_status
= GNUTLS_OCSP_CERT_GOOD
;
1503 else if (sa
.size
== 8 && memcmp (sa
.data
, "revoked", sa
.size
) == 0)
1504 *cert_status
= GNUTLS_OCSP_CERT_REVOKED
;
1505 else if (sa
.size
== 8 && memcmp (sa
.data
, "unknown", sa
.size
) == 0)
1506 *cert_status
= GNUTLS_OCSP_CERT_UNKNOWN
;
1510 gnutls_free (sa
.data
);
1511 return GNUTLS_E_ASN1_DER_ERROR
;
1513 gnutls_free (sa
.data
);
1518 char ttime
[MAX_TIME
];
1521 snprintf (name
, sizeof (name
),
1522 "tbsResponseData.responses.?%u.thisUpdate",
1524 len
= sizeof (ttime
) - 1;
1525 ret
= asn1_read_value (resp
->basicresp
, name
, ttime
, &len
);
1526 if (ret
!= ASN1_SUCCESS
)
1529 *this_update
= (time_t) (-1);
1532 *this_update
= _gnutls_x509_generalTime2gtime (ttime
);
1537 char ttime
[MAX_TIME
];
1540 snprintf (name
, sizeof (name
),
1541 "tbsResponseData.responses.?%u.nextUpdate",
1543 len
= sizeof (ttime
) - 1;
1544 ret
= asn1_read_value (resp
->basicresp
, name
, ttime
, &len
);
1545 if (ret
!= ASN1_SUCCESS
)
1548 *next_update
= (time_t) (-1);
1551 *next_update
= _gnutls_x509_generalTime2gtime (ttime
);
1554 if (revocation_time
)
1556 char ttime
[MAX_TIME
];
1559 snprintf (name
, sizeof (name
),
1560 "tbsResponseData.responses.?%u.certStatus."
1561 "revoked.revocationTime",
1563 len
= sizeof (ttime
) - 1;
1564 ret
= asn1_read_value (resp
->basicresp
, name
, ttime
, &len
);
1565 if (ret
!= ASN1_SUCCESS
)
1568 *revocation_time
= (time_t) (-1);
1571 *revocation_time
= _gnutls_x509_generalTime2gtime (ttime
);
1574 /* revocation_reason */
1576 return GNUTLS_E_SUCCESS
;
1580 * gnutls_ocsp_resp_get_extension:
1581 * @resp: should contain a #gnutls_ocsp_resp_t structure
1582 * @indx: Specifies which extension OID to get. Use (0) to get the first one.
1583 * @oid: will hold newly allocated buffer with OID of extension, may be NULL
1584 * @critical: output variable with critical flag, may be NULL.
1585 * @data: will hold newly allocated buffer with extension data, may be NULL
1587 * This function will return all information about the requested
1588 * extension in the OCSP response. The information returned is the
1589 * OID, the critical flag, and the data itself. The extension OID
1590 * will be stored as a string. Any of @oid, @critical, and @data may
1591 * be NULL which means that the caller is not interested in getting
1592 * that information back.
1594 * The caller needs to deallocate memory by calling gnutls_free() on
1595 * @oid->data and @data->data.
1597 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1598 * negative error code is returned. If you have reached the last
1599 * extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
1603 gnutls_ocsp_resp_get_extension (gnutls_ocsp_resp_t resp
,
1605 gnutls_datum_t
*oid
,
1606 unsigned int *critical
,
1607 gnutls_datum_t
*data
)
1610 char str_critical
[10];
1611 char name
[ASN1_MAX_NAME_SIZE
];
1617 return GNUTLS_E_INVALID_REQUEST
;
1620 snprintf (name
, sizeof (name
),
1621 "tbsResponseData.responseExtensions.?%u.critical",
1623 len
= sizeof (str_critical
);
1624 ret
= asn1_read_value (resp
->basicresp
, name
, str_critical
, &len
);
1625 if (ret
== ASN1_ELEMENT_NOT_FOUND
)
1626 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1627 else if (ret
!= ASN1_SUCCESS
)
1630 return _gnutls_asn2err (ret
);
1635 if (str_critical
[0] == 'T')
1643 snprintf (name
, sizeof (name
),
1644 "tbsResponseData.responseExtensions.?%u.extnID", indx
+ 1);
1645 ret
= _gnutls_x509_read_value (resp
->basicresp
, name
, oid
, 0);
1646 if (ret
!= GNUTLS_E_SUCCESS
)
1655 snprintf (name
, sizeof (name
),
1656 "tbsResponseData.responseExtensions.?%u.extnValue", indx
+ 1);
1657 ret
= _gnutls_x509_read_value (resp
->basicresp
, name
, data
, 0);
1658 if (ret
!= GNUTLS_E_SUCCESS
)
1662 gnutls_free (oid
->data
);
1667 return GNUTLS_E_SUCCESS
;
1671 * gnutls_ocsp_resp_get_nonce:
1672 * @resp: should contain a #gnutls_ocsp_resp_t structure
1673 * @critical: whether nonce extension is marked critical
1674 * @nonce: will hold newly allocated buffer with nonce data
1676 * This function will return the Basic OCSP Response nonce extension
1679 * The caller needs to deallocate memory by calling gnutls_free() on
1682 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1683 * negative error code is returned.
1686 gnutls_ocsp_resp_get_nonce (gnutls_ocsp_resp_t resp
,
1687 unsigned int *critical
,
1688 gnutls_datum_t
*nonce
)
1694 ret
= get_extension (resp
->basicresp
, "tbsResponseData.responseExtensions",
1695 GNUTLS_OCSP_NONCE
, 0,
1697 if (ret
!= GNUTLS_E_SUCCESS
)
1703 ret
= _gnutls_x509_decode_octet_string (NULL
, tmp
.data
, (size_t) tmp
.size
,
1705 if (ret
!= GNUTLS_E_SHORT_MEMORY_BUFFER
)
1708 gnutls_free (tmp
.data
);
1712 nonce
->data
= gnutls_malloc (l
);
1713 if (nonce
->data
== NULL
)
1716 gnutls_free (tmp
.data
);
1717 return GNUTLS_E_MEMORY_ERROR
;
1720 ret
= _gnutls_x509_decode_octet_string (NULL
, tmp
.data
, (size_t) tmp
.size
,
1722 gnutls_free (tmp
.data
);
1723 if (ret
!= GNUTLS_E_SUCCESS
)
1730 return GNUTLS_E_SUCCESS
;
1734 * gnutls_ocsp_resp_get_signature_algorithm:
1735 * @resp: should contain a #gnutls_ocsp_resp_t structure
1737 * This function will return a value of the #gnutls_sign_algorithm_t
1738 * enumeration that is the signature algorithm that has been used to
1739 * sign the OCSP response.
1741 * Returns: a #gnutls_sign_algorithm_t value, or a negative error code
1745 gnutls_ocsp_resp_get_signature_algorithm (gnutls_ocsp_resp_t resp
)
1750 ret
= _gnutls_x509_read_value (resp
->basicresp
,
1751 "signatureAlgorithm.algorithm", &sa
, 0);
1758 ret
= _gnutls_x509_oid2sign_algorithm ((char*)sa
.data
);
1760 _gnutls_free_datum (&sa
);
1766 * gnutls_ocsp_resp_get_signature:
1767 * @resp: should contain a #gnutls_ocsp_resp_t structure
1768 * @sig: newly allocated output buffer with signature data
1770 * This function will extract the signature field of a OCSP response.
1772 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1773 * negative error value.
1776 gnutls_ocsp_resp_get_signature (gnutls_ocsp_resp_t resp
,
1777 gnutls_datum_t
*sig
)
1781 if (resp
== NULL
|| sig
== NULL
)
1784 return GNUTLS_E_INVALID_REQUEST
;
1787 ret
= _gnutls_x509_read_value (resp
->basicresp
, "signature", sig
, 2);
1788 if (ret
!= GNUTLS_E_SUCCESS
)
1794 return GNUTLS_E_SUCCESS
;
1798 * gnutls_ocsp_resp_get_certs:
1799 * @resp: should contain a #gnutls_ocsp_resp_t structure
1800 * @certs: newly allocated array with #gnutls_x509_crt_t certificates
1801 * @ncerts: output variable with number of allocated certs.
1803 * This function will extract the X.509 certificates found in the
1804 * Basic OCSP Response. The @certs output variable will hold a newly
1805 * allocated zero-terminated array with X.509 certificates.
1807 * Every certificate in the array needs to be de-allocated with
1808 * gnutls_x509_crt_deinit() and the array itself must be freed using
1811 * Both the @certs and @ncerts variables may be NULL. Then the
1812 * function will work as normal but will not return the NULL:d
1813 * information. This can be used to get the number of certificates
1814 * only, or to just get the certificate array without its size.
1816 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1817 * negative error value.
1820 gnutls_ocsp_resp_get_certs (gnutls_ocsp_resp_t resp
,
1821 gnutls_x509_crt_t
** certs
,
1826 gnutls_x509_crt_t
*tmpcerts
= NULL
, *tmpcerts2
;
1827 gnutls_datum_t c
= { NULL
, 0 };
1832 return GNUTLS_E_INVALID_REQUEST
;
1835 tmpcerts
= gnutls_malloc (sizeof (*tmpcerts
));
1836 if (tmpcerts
== NULL
)
1839 return GNUTLS_E_MEMORY_ERROR
;
1844 char name
[ASN1_MAX_NAME_SIZE
];
1846 snprintf (name
, sizeof (name
), "certs.?%u", (unsigned int)(ctr
+ 1));
1847 ret
= _gnutls_x509_der_encode (resp
->basicresp
, name
, &c
, 0);
1848 if (ret
== GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
)
1850 if (ret
!= GNUTLS_E_SUCCESS
)
1856 tmpcerts2
= gnutls_realloc (tmpcerts
, (ctr
+ 2) * sizeof (*tmpcerts
));
1857 if (tmpcerts2
== NULL
)
1860 ret
= GNUTLS_E_MEMORY_ERROR
;
1863 tmpcerts
= tmpcerts2
;
1865 ret
= gnutls_x509_crt_init (&tmpcerts
[ctr
]);
1866 if (ret
!= GNUTLS_E_SUCCESS
)
1873 ret
= gnutls_x509_crt_import (tmpcerts
[ctr
- 1], &c
,
1874 GNUTLS_X509_FMT_DER
);
1875 if (ret
!= GNUTLS_E_SUCCESS
)
1881 gnutls_free (c
.data
);
1885 tmpcerts
[ctr
] = NULL
;
1893 /* clean up memory */
1894 ret
= GNUTLS_E_SUCCESS
;
1898 return GNUTLS_E_SUCCESS
;
1901 gnutls_free (c
.data
);
1902 for (i
= 0; i
< ctr
; i
++)
1903 gnutls_x509_crt_deinit (tmpcerts
[i
]);
1904 gnutls_free (tmpcerts
);
1908 /* Search the OCSP response for a certificate matching the responderId
1909 mentioned in the OCSP response. */
1910 static gnutls_x509_crt_t
1911 find_signercert (gnutls_ocsp_resp_t resp
)
1914 gnutls_x509_crt_t
* certs
;
1915 size_t ncerts
= 0, i
;
1916 gnutls_datum_t riddn
;
1917 gnutls_x509_crt_t signercert
= NULL
;
1919 rc
= gnutls_ocsp_resp_get_responder (resp
, &riddn
);
1920 if (rc
!= GNUTLS_E_SUCCESS
)
1926 rc
= gnutls_ocsp_resp_get_certs (resp
, &certs
, &ncerts
);
1927 if (rc
!= GNUTLS_E_SUCCESS
)
1930 gnutls_free (riddn
.data
);
1934 for (i
= 0; i
< ncerts
; i
++)
1937 size_t crtdnsize
= 0;
1940 rc
= gnutls_x509_crt_get_dn (certs
[i
], NULL
, &crtdnsize
);
1941 if (rc
!= GNUTLS_E_SHORT_MEMORY_BUFFER
)
1947 crtdn
= gnutls_malloc (crtdnsize
);
1954 rc
= gnutls_x509_crt_get_dn (certs
[i
], crtdn
, &crtdnsize
);
1955 if (rc
!= GNUTLS_E_SUCCESS
)
1958 gnutls_free (crtdn
);
1962 cmpok
= (crtdnsize
== riddn
.size
)
1963 && memcmp (riddn
.data
, crtdn
, crtdnsize
);
1965 gnutls_free (crtdn
);
1969 signercert
= certs
[i
];
1978 gnutls_free (riddn
.data
);
1979 for (i
= 0; i
< ncerts
; i
++)
1980 if (certs
[i
] != signercert
)
1981 gnutls_x509_crt_deinit (certs
[i
]);
1982 gnutls_free (certs
);
1987 _ocsp_resp_verify_direct (gnutls_ocsp_resp_t resp
,
1988 gnutls_x509_crt_t signercert
,
1989 unsigned int *verify
,
1992 gnutls_datum_t sig
= { NULL
};
1993 gnutls_datum_t data
= { NULL
};
1994 gnutls_pubkey_t pubkey
= NULL
;
1998 if (resp
== NULL
|| signercert
== NULL
)
2001 return GNUTLS_E_INVALID_REQUEST
;
2004 rc
= gnutls_ocsp_resp_get_signature_algorithm (resp
);
2012 rc
= export (resp
->basicresp
, "tbsResponseData", &data
);
2013 if (rc
!= GNUTLS_E_SUCCESS
)
2019 rc
= gnutls_pubkey_init (&pubkey
);
2020 if (rc
!= GNUTLS_E_SUCCESS
)
2026 rc
= gnutls_pubkey_import_x509 (pubkey
, signercert
, 0);
2027 if (rc
!= GNUTLS_E_SUCCESS
)
2033 rc
= gnutls_ocsp_resp_get_signature (resp
, &sig
);
2034 if (rc
!= GNUTLS_E_SUCCESS
)
2040 rc
= gnutls_pubkey_verify_data2 (pubkey
, sigalg
, 0, &data
, &sig
);
2041 if (rc
== GNUTLS_E_PK_SIG_VERIFY_FAILED
)
2044 *verify
= GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE
;
2054 rc
= GNUTLS_E_SUCCESS
;
2057 gnutls_free (data
.data
);
2058 gnutls_free (sig
.data
);
2059 gnutls_pubkey_deinit (pubkey
);
2064 static inline unsigned int vstatus_to_ocsp_status(unsigned int status
)
2066 unsigned int ostatus
;
2068 if (status
& GNUTLS_CERT_INSECURE_ALGORITHM
)
2069 ostatus
= GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM
;
2070 else if (status
& GNUTLS_CERT_NOT_ACTIVATED
)
2071 ostatus
= GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED
;
2072 else if (status
& GNUTLS_CERT_EXPIRED
)
2073 ostatus
= GNUTLS_OCSP_VERIFY_CERT_EXPIRED
;
2075 ostatus
= GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER
;
2080 static int check_ocsp_purpose(gnutls_x509_crt_t signercert
)
2082 char oidtmp
[sizeof (GNUTLS_KP_OCSP_SIGNING
)];
2086 for (indx
= 0; ; indx
++)
2088 oidsize
= sizeof (oidtmp
);
2089 rc
= gnutls_x509_crt_get_key_purpose_oid (signercert
, indx
,
2092 if (rc
== GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
)
2097 else if (rc
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
2102 else if (rc
!= GNUTLS_E_SUCCESS
)
2104 return gnutls_assert_val(rc
);
2107 if (memcmp (oidtmp
, GNUTLS_KP_OCSP_SIGNING
, oidsize
) != 0)
2119 * gnutls_ocsp_resp_verify_direct:
2120 * @resp: should contain a #gnutls_ocsp_resp_t structure
2121 * @issuer: certificate believed to have signed the response
2122 * @verify: output variable with verification status, an #gnutls_ocsp_cert_status_t
2123 * @flags: verification flags, 0 for now.
2125 * Verify signature of the Basic OCSP Response against the public key
2126 * in the @issuer certificate.
2128 * The output @verify variable will hold verification status codes
2129 * (e.g., %GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND,
2130 * %GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) which are only valid if the
2131 * function returned %GNUTLS_E_SUCCESS.
2133 * Note that the function returns %GNUTLS_E_SUCCESS even when
2134 * verification failed. The caller must always inspect the @verify
2135 * variable to find out the verification status.
2137 * The @flags variable should be 0 for now.
2139 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2140 * negative error value.
2143 gnutls_ocsp_resp_verify_direct (gnutls_ocsp_resp_t resp
,
2144 gnutls_x509_crt_t issuer
,
2145 unsigned int *verify
,
2148 gnutls_x509_crt_t signercert
;
2151 if (resp
== NULL
|| issuer
== NULL
)
2154 return GNUTLS_E_INVALID_REQUEST
;
2157 signercert
= find_signercert (resp
);
2160 signercert
= issuer
;
2162 else /* response contains a signer. Verify him */
2166 rc
= gnutls_x509_crt_verify (signercert
, &issuer
, 1, 0, &vtmp
);
2167 if (rc
!= GNUTLS_E_SUCCESS
)
2175 *verify
= vstatus_to_ocsp_status(vtmp
);
2177 rc
= GNUTLS_E_SUCCESS
;
2181 rc
= check_ocsp_purpose(signercert
);
2185 *verify
= GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR
;
2186 rc
= GNUTLS_E_SUCCESS
;
2191 rc
= _ocsp_resp_verify_direct(resp
, signercert
, verify
, flags
);
2194 if (signercert
!= issuer
)
2195 gnutls_x509_crt_deinit(signercert
);
2201 * gnutls_ocsp_resp_verify:
2202 * @resp: should contain a #gnutls_ocsp_resp_t structure
2203 * @trustlist: trust anchors as a #gnutls_x509_trust_list_t structure
2204 * @verify: output variable with verification status, an #gnutls_ocsp_cert_status_t
2205 * @flags: verification flags, 0 for now.
2207 * Verify signature of the Basic OCSP Response against the public key
2208 * in the certificate of a trusted signer. The @trustlist should be
2209 * populated with trust anchors. The function will extract the signer
2210 * certificate from the Basic OCSP Response and will verify it against
2211 * the @trustlist. A trusted signer is a certificate that is either
2212 * in @trustlist, or it is signed directly by a certificate in
2213 * @trustlist and has the id-ad-ocspSigning Extended Key Usage bit
2216 * The output @verify variable will hold verification status codes
2217 * (e.g., %GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND,
2218 * %GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) which are only valid if the
2219 * function returned %GNUTLS_E_SUCCESS.
2221 * Note that the function returns %GNUTLS_E_SUCCESS even when
2222 * verification failed. The caller must always inspect the @verify
2223 * variable to find out the verification status.
2225 * The @flags variable should be 0 for now.
2227 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2228 * negative error value.
2231 gnutls_ocsp_resp_verify (gnutls_ocsp_resp_t resp
,
2232 gnutls_x509_trust_list_t trustlist
,
2233 unsigned int *verify
,
2236 gnutls_x509_crt_t signercert
= NULL
;
2240 1. Find signer cert.
2241 1a. Search in OCSP response Certificate field for responderID.
2242 1b. Verify that signer cert is trusted.
2243 2a. It is in trustlist?
2244 2b. It has OCSP key usage and directly signed by a CA in trustlist?
2245 3. Verify signature of Basic Response using public key from signer cert.
2248 signercert
= find_signercert (resp
);
2251 /* XXX Search in trustlist for certificate matching
2252 responderId as well? */
2254 *verify
= GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND
;
2255 rc
= GNUTLS_E_SUCCESS
;
2259 /* Either the signer is directly trusted (i.e., in trustlist) or it
2260 is directly signed by something in trustlist and has proper OCSP
2262 rc
= _gnutls_trustlist_inlist (trustlist
, signercert
);
2270 /* not in trustlist, need to verify signature and bits */
2271 gnutls_x509_crt_t issuer
;
2276 rc
= gnutls_x509_trust_list_get_issuer (trustlist
, signercert
,
2278 if (rc
!= GNUTLS_E_SUCCESS
)
2281 *verify
= GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER
;
2282 rc
= GNUTLS_E_SUCCESS
;
2286 rc
= gnutls_x509_crt_verify (signercert
, &issuer
, 1, 0, &vtmp
);
2287 if (rc
!= GNUTLS_E_SUCCESS
)
2295 *verify
= vstatus_to_ocsp_status(vtmp
);
2297 rc
= GNUTLS_E_SUCCESS
;
2301 rc
= check_ocsp_purpose(signercert
);
2305 *verify
= GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR
;
2306 rc
= GNUTLS_E_SUCCESS
;
2311 rc
= _ocsp_resp_verify_direct (resp
, signercert
, verify
, flags
);
2314 gnutls_x509_crt_deinit (signercert
);