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_get_single:
1279 * @resp: should contain a #gnutls_ocsp_resp_t structure
1280 * @indx: Specifies which extension OID to get. Use (0) to get the first one.
1281 * @digest: output variable with #gnutls_digest_algorithm_t hash algorithm
1282 * @issuer_name_hash: output buffer with hash of issuer's DN
1283 * @issuer_key_hash: output buffer with hash of issuer's public key
1284 * @serial_number: output buffer with serial number of certificate to check
1285 * @cert_status: a certificate status, a #gnutls_ocsp_cert_status_t enum.
1286 * @this_update: time at which the status is known to be correct.
1287 * @next_update: when newer information will be available, or (time_t)-1 if unspecified
1288 * @revocation_time: when @cert_status is %GNUTLS_OCSP_CERT_REVOKED, holds time of revocation.
1289 * @revocation_reason: revocation reason, a #gnutls_x509_crl_reason_t enum.
1291 * This function will return the certificate information of the
1292 * @indx'ed response in the Basic OCSP Response @resp. The
1293 * information returned corresponds to the SingleResponse structure
1294 * except the final singleExtensions, reproduced here for illustration:
1296 * <informalexample><programlisting>
1297 * SingleResponse ::= SEQUENCE {
1299 * certStatus CertStatus,
1300 * thisUpdate GeneralizedTime,
1301 * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
1302 * singleExtensions [1] EXPLICIT Extensions OPTIONAL }
1304 * CertID ::= SEQUENCE {
1305 * hashAlgorithm AlgorithmIdentifier,
1306 * issuerNameHash OCTET STRING, -- Hash of Issuer's DN
1307 * issuerKeyHash OCTET STRING, -- Hash of Issuers public key
1308 * serialNumber CertificateSerialNumber }
1310 * CertStatus ::= CHOICE {
1311 * good [0] IMPLICIT NULL,
1312 * revoked [1] IMPLICIT RevokedInfo,
1313 * unknown [2] IMPLICIT UnknownInfo }
1315 * RevokedInfo ::= SEQUENCE {
1316 * revocationTime GeneralizedTime,
1317 * revocationReason [0] EXPLICIT CRLReason OPTIONAL }
1318 * </programlisting></informalexample>
1320 * Each of the pointers to output variables may be NULL to indicate
1321 * that the caller is not interested in that value.
1323 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1324 * negative error code is returned. If you have reached the last
1325 * CertID available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1329 gnutls_ocsp_resp_get_single (gnutls_ocsp_resp_t resp
,
1331 gnutls_digest_algorithm_t
*digest
,
1332 gnutls_datum_t
*issuer_name_hash
,
1333 gnutls_datum_t
*issuer_key_hash
,
1334 gnutls_datum_t
*serial_number
,
1335 unsigned int *cert_status
,
1336 time_t *this_update
,
1337 time_t *next_update
,
1338 time_t *revocation_time
,
1339 unsigned int *revocation_reason
)
1342 char name
[ASN1_MAX_NAME_SIZE
];
1345 snprintf (name
, sizeof (name
),
1346 "tbsResponseData.responses.?%u.certID.hashAlgorithm.algorithm",
1348 ret
= _gnutls_x509_read_value (resp
->basicresp
, name
, &sa
, 0);
1349 if (ret
== GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
)
1350 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1357 ret
= _gnutls_x509_oid_to_digest ((char*)sa
.data
);
1358 _gnutls_free_datum (&sa
);
1368 if (issuer_name_hash
)
1370 snprintf (name
, sizeof (name
),
1371 "tbsResponseData.responses.?%u.certID.issuerNameHash",
1373 ret
= _gnutls_x509_read_value (resp
->basicresp
, name
,
1374 issuer_name_hash
, 0);
1375 if (ret
!= GNUTLS_E_SUCCESS
)
1382 if (issuer_key_hash
)
1384 snprintf (name
, sizeof (name
),
1385 "tbsResponseData.responses.?%u.certID.issuerKeyHash",
1387 ret
= _gnutls_x509_read_value (resp
->basicresp
, name
,
1388 issuer_key_hash
, 0);
1389 if (ret
!= GNUTLS_E_SUCCESS
)
1392 if (issuer_name_hash
)
1393 gnutls_free (issuer_name_hash
->data
);
1400 snprintf (name
, sizeof (name
),
1401 "tbsResponseData.responses.?%u.certID.serialNumber",
1403 ret
= _gnutls_x509_read_value (resp
->basicresp
, name
,
1405 if (ret
!= GNUTLS_E_SUCCESS
)
1408 if (issuer_name_hash
)
1409 gnutls_free (issuer_name_hash
->data
);
1410 if (issuer_key_hash
)
1411 gnutls_free (issuer_key_hash
->data
);
1418 snprintf (name
, sizeof (name
),
1419 "tbsResponseData.responses.?%u.certStatus",
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
;
1429 if (sa
.size
== 5 && memcmp (sa
.data
, "good", sa
.size
) == 0)
1430 *cert_status
= GNUTLS_OCSP_CERT_GOOD
;
1431 else if (sa
.size
== 8 && memcmp (sa
.data
, "revoked", sa
.size
) == 0)
1432 *cert_status
= GNUTLS_OCSP_CERT_REVOKED
;
1433 else if (sa
.size
== 8 && memcmp (sa
.data
, "unknown", sa
.size
) == 0)
1434 *cert_status
= GNUTLS_OCSP_CERT_UNKNOWN
;
1438 gnutls_free (sa
.data
);
1439 return GNUTLS_E_ASN1_DER_ERROR
;
1441 gnutls_free (sa
.data
);
1446 char ttime
[MAX_TIME
];
1449 snprintf (name
, sizeof (name
),
1450 "tbsResponseData.responses.?%u.thisUpdate",
1452 len
= sizeof (ttime
) - 1;
1453 ret
= asn1_read_value (resp
->basicresp
, name
, ttime
, &len
);
1454 if (ret
!= ASN1_SUCCESS
)
1457 *this_update
= (time_t) (-1);
1460 *this_update
= _gnutls_x509_generalTime2gtime (ttime
);
1465 char ttime
[MAX_TIME
];
1468 snprintf (name
, sizeof (name
),
1469 "tbsResponseData.responses.?%u.nextUpdate",
1471 len
= sizeof (ttime
) - 1;
1472 ret
= asn1_read_value (resp
->basicresp
, name
, ttime
, &len
);
1473 if (ret
!= ASN1_SUCCESS
)
1476 *next_update
= (time_t) (-1);
1479 *next_update
= _gnutls_x509_generalTime2gtime (ttime
);
1482 if (revocation_time
)
1484 char ttime
[MAX_TIME
];
1487 snprintf (name
, sizeof (name
),
1488 "tbsResponseData.responses.?%u.certStatus."
1489 "revoked.revocationTime",
1491 len
= sizeof (ttime
) - 1;
1492 ret
= asn1_read_value (resp
->basicresp
, name
, ttime
, &len
);
1493 if (ret
!= ASN1_SUCCESS
)
1496 *revocation_time
= (time_t) (-1);
1499 *revocation_time
= _gnutls_x509_generalTime2gtime (ttime
);
1502 /* revocation_reason */
1504 return GNUTLS_E_SUCCESS
;
1508 * gnutls_ocsp_resp_get_extension:
1509 * @resp: should contain a #gnutls_ocsp_resp_t structure
1510 * @indx: Specifies which extension OID to get. Use (0) to get the first one.
1511 * @oid: will hold newly allocated buffer with OID of extension, may be NULL
1512 * @critical: output variable with critical flag, may be NULL.
1513 * @data: will hold newly allocated buffer with extension data, may be NULL
1515 * This function will return all information about the requested
1516 * extension in the OCSP response. The information returned is the
1517 * OID, the critical flag, and the data itself. The extension OID
1518 * will be stored as a string. Any of @oid, @critical, and @data may
1519 * be NULL which means that the caller is not interested in getting
1520 * that information back.
1522 * The caller needs to deallocate memory by calling gnutls_free() on
1523 * @oid->data and @data->data.
1525 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1526 * negative error code is returned. If you have reached the last
1527 * extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
1531 gnutls_ocsp_resp_get_extension (gnutls_ocsp_resp_t resp
,
1533 gnutls_datum_t
*oid
,
1534 unsigned int *critical
,
1535 gnutls_datum_t
*data
)
1538 char str_critical
[10];
1539 char name
[ASN1_MAX_NAME_SIZE
];
1545 return GNUTLS_E_INVALID_REQUEST
;
1548 snprintf (name
, sizeof (name
),
1549 "tbsResponseData.responseExtensions.?%u.critical",
1551 len
= sizeof (str_critical
);
1552 ret
= asn1_read_value (resp
->basicresp
, name
, str_critical
, &len
);
1553 if (ret
== ASN1_ELEMENT_NOT_FOUND
)
1554 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1555 else if (ret
!= ASN1_SUCCESS
)
1558 return _gnutls_asn2err (ret
);
1563 if (str_critical
[0] == 'T')
1571 snprintf (name
, sizeof (name
),
1572 "tbsResponseData.responseExtensions.?%u.extnID", indx
+ 1);
1573 ret
= _gnutls_x509_read_value (resp
->basicresp
, name
, oid
, 0);
1574 if (ret
!= GNUTLS_E_SUCCESS
)
1583 snprintf (name
, sizeof (name
),
1584 "tbsResponseData.responseExtensions.?%u.extnValue", indx
+ 1);
1585 ret
= _gnutls_x509_read_value (resp
->basicresp
, name
, data
, 0);
1586 if (ret
!= GNUTLS_E_SUCCESS
)
1590 gnutls_free (oid
->data
);
1595 return GNUTLS_E_SUCCESS
;
1599 * gnutls_ocsp_resp_get_nonce:
1600 * @resp: should contain a #gnutls_ocsp_resp_t structure
1601 * @critical: whether nonce extension is marked critical
1602 * @nonce: will hold newly allocated buffer with nonce data
1604 * This function will return the Basic OCSP Response nonce extension
1607 * The caller needs to deallocate memory by calling gnutls_free() on
1610 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1611 * negative error code is returned.
1614 gnutls_ocsp_resp_get_nonce (gnutls_ocsp_resp_t resp
,
1615 unsigned int *critical
,
1616 gnutls_datum_t
*nonce
)
1622 ret
= get_extension (resp
->basicresp
, "tbsResponseData.responseExtensions",
1623 GNUTLS_OCSP_NONCE
, 0,
1625 if (ret
!= GNUTLS_E_SUCCESS
)
1631 ret
= _gnutls_x509_decode_octet_string (NULL
, tmp
.data
, (size_t) tmp
.size
,
1633 if (ret
!= GNUTLS_E_SHORT_MEMORY_BUFFER
)
1636 gnutls_free (tmp
.data
);
1640 nonce
->data
= gnutls_malloc (l
);
1641 if (nonce
->data
== NULL
)
1644 gnutls_free (tmp
.data
);
1645 return GNUTLS_E_MEMORY_ERROR
;
1648 ret
= _gnutls_x509_decode_octet_string (NULL
, tmp
.data
, (size_t) tmp
.size
,
1650 gnutls_free (tmp
.data
);
1651 if (ret
!= GNUTLS_E_SUCCESS
)
1658 return GNUTLS_E_SUCCESS
;
1662 * gnutls_ocsp_resp_get_signature_algorithm:
1663 * @resp: should contain a #gnutls_ocsp_resp_t structure
1665 * This function will return a value of the #gnutls_sign_algorithm_t
1666 * enumeration that is the signature algorithm that has been used to
1667 * sign the OCSP response.
1669 * Returns: a #gnutls_sign_algorithm_t value, or a negative error code
1673 gnutls_ocsp_resp_get_signature_algorithm (gnutls_ocsp_resp_t resp
)
1678 ret
= _gnutls_x509_read_value (resp
->basicresp
,
1679 "signatureAlgorithm.algorithm", &sa
, 0);
1686 ret
= _gnutls_x509_oid2sign_algorithm ((char*)sa
.data
);
1688 _gnutls_free_datum (&sa
);
1694 * gnutls_ocsp_resp_get_signature:
1695 * @resp: should contain a #gnutls_ocsp_resp_t structure
1696 * @sig: newly allocated output buffer with signature data
1698 * This function will extract the signature field of a OCSP response.
1700 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1701 * negative error value.
1704 gnutls_ocsp_resp_get_signature (gnutls_ocsp_resp_t resp
,
1705 gnutls_datum_t
*sig
)
1709 if (resp
== NULL
|| sig
== NULL
)
1712 return GNUTLS_E_INVALID_REQUEST
;
1715 ret
= _gnutls_x509_read_value (resp
->basicresp
, "signature", sig
, 2);
1716 if (ret
!= GNUTLS_E_SUCCESS
)
1722 return GNUTLS_E_SUCCESS
;
1726 * gnutls_ocsp_resp_get_certs:
1727 * @resp: should contain a #gnutls_ocsp_resp_t structure
1728 * @certs: newly allocated array with #gnutls_x509_crt_t certificates
1729 * @ncerts: output variable with number of allocated certs.
1731 * This function will extract the X.509 certificates found in the
1732 * Basic OCSP Response. The @certs output variable will hold a newly
1733 * allocated zero-terminated array with X.509 certificates.
1735 * Every certificate in the array needs to be de-allocated with
1736 * gnutls_x509_crt_deinit() and the array itself must be freed using
1739 * Both the @certs and @ncerts variables may be NULL. Then the
1740 * function will work as normal but will not return the NULL:d
1741 * information. This can be used to get the number of certificates
1742 * only, or to just get the certificate array without its size.
1744 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1745 * negative error value.
1748 gnutls_ocsp_resp_get_certs (gnutls_ocsp_resp_t resp
,
1749 gnutls_x509_crt_t
** certs
,
1754 gnutls_x509_crt_t
*tmpcerts
= NULL
, *tmpcerts2
;
1755 gnutls_datum_t c
= { NULL
, 0 };
1760 return GNUTLS_E_INVALID_REQUEST
;
1763 tmpcerts
= gnutls_malloc (sizeof (*tmpcerts
));
1764 if (tmpcerts
== NULL
)
1767 return GNUTLS_E_MEMORY_ERROR
;
1772 char name
[ASN1_MAX_NAME_SIZE
];
1774 snprintf (name
, sizeof (name
), "certs.?%u", (unsigned int)(ctr
+ 1));
1775 ret
= _gnutls_x509_der_encode (resp
->basicresp
, name
, &c
, 0);
1776 if (ret
== GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
)
1778 if (ret
!= GNUTLS_E_SUCCESS
)
1784 tmpcerts2
= gnutls_realloc (tmpcerts
, (ctr
+ 2) * sizeof (*tmpcerts
));
1785 if (tmpcerts2
== NULL
)
1788 ret
= GNUTLS_E_MEMORY_ERROR
;
1791 tmpcerts
= tmpcerts2
;
1793 ret
= gnutls_x509_crt_init (&tmpcerts
[ctr
]);
1794 if (ret
!= GNUTLS_E_SUCCESS
)
1801 ret
= gnutls_x509_crt_import (tmpcerts
[ctr
- 1], &c
,
1802 GNUTLS_X509_FMT_DER
);
1803 if (ret
!= GNUTLS_E_SUCCESS
)
1809 gnutls_free (c
.data
);
1813 tmpcerts
[ctr
] = NULL
;
1821 /* clean up memory */
1822 ret
= GNUTLS_E_SUCCESS
;
1826 return GNUTLS_E_SUCCESS
;
1829 gnutls_free (c
.data
);
1830 for (i
= 0; i
< ctr
; i
++)
1831 gnutls_x509_crt_deinit (tmpcerts
[i
]);
1832 gnutls_free (tmpcerts
);
1836 /* Search the OCSP response for a certificate matching the responderId
1837 mentioned in the OCSP response. */
1838 static gnutls_x509_crt_t
1839 find_signercert (gnutls_ocsp_resp_t resp
)
1842 gnutls_x509_crt_t
* certs
;
1843 size_t ncerts
= 0, i
;
1844 gnutls_datum_t riddn
;
1845 gnutls_x509_crt_t signercert
= NULL
;
1847 rc
= gnutls_ocsp_resp_get_responder (resp
, &riddn
);
1848 if (rc
!= GNUTLS_E_SUCCESS
)
1854 rc
= gnutls_ocsp_resp_get_certs (resp
, &certs
, &ncerts
);
1855 if (rc
!= GNUTLS_E_SUCCESS
)
1858 gnutls_free (riddn
.data
);
1862 for (i
= 0; i
< ncerts
; i
++)
1865 size_t crtdnsize
= 0;
1868 rc
= gnutls_x509_crt_get_dn (certs
[i
], NULL
, &crtdnsize
);
1869 if (rc
!= GNUTLS_E_SHORT_MEMORY_BUFFER
)
1875 crtdn
= gnutls_malloc (crtdnsize
);
1882 rc
= gnutls_x509_crt_get_dn (certs
[i
], crtdn
, &crtdnsize
);
1883 if (rc
!= GNUTLS_E_SUCCESS
)
1886 gnutls_free (crtdn
);
1890 cmpok
= (crtdnsize
== riddn
.size
)
1891 && memcmp (riddn
.data
, crtdn
, crtdnsize
);
1893 gnutls_free (crtdn
);
1897 signercert
= certs
[i
];
1906 gnutls_free (riddn
.data
);
1907 for (i
= 0; i
< ncerts
; i
++)
1908 if (certs
[i
] != signercert
)
1909 gnutls_x509_crt_deinit (certs
[i
]);
1910 gnutls_free (certs
);
1915 _ocsp_resp_verify_direct (gnutls_ocsp_resp_t resp
,
1916 gnutls_x509_crt_t signercert
,
1917 unsigned int *verify
,
1920 gnutls_datum_t sig
= { NULL
};
1921 gnutls_datum_t data
= { NULL
};
1922 gnutls_pubkey_t pubkey
= NULL
;
1926 if (resp
== NULL
|| signercert
== NULL
)
1929 return GNUTLS_E_INVALID_REQUEST
;
1932 rc
= gnutls_ocsp_resp_get_signature_algorithm (resp
);
1940 rc
= export (resp
->basicresp
, "tbsResponseData", &data
);
1941 if (rc
!= GNUTLS_E_SUCCESS
)
1947 rc
= gnutls_pubkey_init (&pubkey
);
1948 if (rc
!= GNUTLS_E_SUCCESS
)
1954 rc
= gnutls_pubkey_import_x509 (pubkey
, signercert
, 0);
1955 if (rc
!= GNUTLS_E_SUCCESS
)
1961 rc
= gnutls_ocsp_resp_get_signature (resp
, &sig
);
1962 if (rc
!= GNUTLS_E_SUCCESS
)
1968 rc
= gnutls_pubkey_verify_data2 (pubkey
, sigalg
, 0, &data
, &sig
);
1969 if (rc
== GNUTLS_E_PK_SIG_VERIFY_FAILED
)
1972 *verify
= GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE
;
1982 rc
= GNUTLS_E_SUCCESS
;
1985 gnutls_free (data
.data
);
1986 gnutls_free (sig
.data
);
1987 gnutls_pubkey_deinit (pubkey
);
1992 static inline unsigned int vstatus_to_ocsp_status(unsigned int status
)
1994 unsigned int ostatus
;
1996 if (status
& GNUTLS_CERT_INSECURE_ALGORITHM
)
1997 ostatus
= GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM
;
1998 else if (status
& GNUTLS_CERT_NOT_ACTIVATED
)
1999 ostatus
= GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED
;
2000 else if (status
& GNUTLS_CERT_EXPIRED
)
2001 ostatus
= GNUTLS_OCSP_VERIFY_CERT_EXPIRED
;
2003 ostatus
= GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER
;
2008 static int check_ocsp_purpose(gnutls_x509_crt_t signercert
)
2010 char oidtmp
[sizeof (GNUTLS_KP_OCSP_SIGNING
)];
2014 for (indx
= 0; ; indx
++)
2016 oidsize
= sizeof (oidtmp
);
2017 rc
= gnutls_x509_crt_get_key_purpose_oid (signercert
, indx
,
2020 if (rc
== GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
)
2025 else if (rc
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
2030 else if (rc
!= GNUTLS_E_SUCCESS
)
2032 return gnutls_assert_val(rc
);
2035 if (memcmp (oidtmp
, GNUTLS_KP_OCSP_SIGNING
, oidsize
) != 0)
2047 * gnutls_ocsp_resp_verify_direct:
2048 * @resp: should contain a #gnutls_ocsp_resp_t structure
2049 * @issuer: certificate believed to have signed the response
2050 * @verify: output variable with verification status, an #gnutls_ocsp_cert_status_t
2051 * @flags: verification flags, 0 for now.
2053 * Verify signature of the Basic OCSP Response against the public key
2054 * in the @issuer certificate.
2056 * The output @verify variable will hold verification status codes
2057 * (e.g., %GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND,
2058 * %GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) which are only valid if the
2059 * function returned %GNUTLS_E_SUCCESS.
2061 * Note that the function returns %GNUTLS_E_SUCCESS even when
2062 * verification failed. The caller must always inspect the @verify
2063 * variable to find out the verification status.
2065 * The @flags variable should be 0 for now.
2067 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2068 * negative error value.
2071 gnutls_ocsp_resp_verify_direct (gnutls_ocsp_resp_t resp
,
2072 gnutls_x509_crt_t issuer
,
2073 unsigned int *verify
,
2076 gnutls_x509_crt_t signercert
;
2079 if (resp
== NULL
|| issuer
== NULL
)
2082 return GNUTLS_E_INVALID_REQUEST
;
2085 signercert
= find_signercert (resp
);
2088 signercert
= issuer
;
2090 else /* response contains a signer. Verify him */
2094 rc
= gnutls_x509_crt_verify (signercert
, &issuer
, 1, 0, &vtmp
);
2095 if (rc
!= GNUTLS_E_SUCCESS
)
2103 *verify
= vstatus_to_ocsp_status(vtmp
);
2105 rc
= GNUTLS_E_SUCCESS
;
2109 rc
= check_ocsp_purpose(signercert
);
2113 *verify
= GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR
;
2114 rc
= GNUTLS_E_SUCCESS
;
2119 rc
= _ocsp_resp_verify_direct(resp
, signercert
, verify
, flags
);
2122 if (signercert
!= issuer
)
2123 gnutls_x509_crt_deinit(signercert
);
2129 * gnutls_ocsp_resp_verify:
2130 * @resp: should contain a #gnutls_ocsp_resp_t structure
2131 * @trustlist: trust anchors as a #gnutls_x509_trust_list_t structure
2132 * @verify: output variable with verification status, an #gnutls_ocsp_cert_status_t
2133 * @flags: verification flags, 0 for now.
2135 * Verify signature of the Basic OCSP Response against the public key
2136 * in the certificate of a trusted signer. The @trustlist should be
2137 * populated with trust anchors. The function will extract the signer
2138 * certificate from the Basic OCSP Response and will verify it against
2139 * the @trustlist. A trusted signer is a certificate that is either
2140 * in @trustlist, or it is signed directly by a certificate in
2141 * @trustlist and has the id-ad-ocspSigning Extended Key Usage bit
2144 * The output @verify variable will hold verification status codes
2145 * (e.g., %GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND,
2146 * %GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) which are only valid if the
2147 * function returned %GNUTLS_E_SUCCESS.
2149 * Note that the function returns %GNUTLS_E_SUCCESS even when
2150 * verification failed. The caller must always inspect the @verify
2151 * variable to find out the verification status.
2153 * The @flags variable should be 0 for now.
2155 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2156 * negative error value.
2159 gnutls_ocsp_resp_verify (gnutls_ocsp_resp_t resp
,
2160 gnutls_x509_trust_list_t trustlist
,
2161 unsigned int *verify
,
2164 gnutls_x509_crt_t signercert
= NULL
;
2168 1. Find signer cert.
2169 1a. Search in OCSP response Certificate field for responderID.
2170 1b. Verify that signer cert is trusted.
2171 2a. It is in trustlist?
2172 2b. It has OCSP key usage and directly signed by a CA in trustlist?
2173 3. Verify signature of Basic Response using public key from signer cert.
2176 signercert
= find_signercert (resp
);
2179 /* XXX Search in trustlist for certificate matching
2180 responderId as well? */
2182 *verify
= GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND
;
2183 rc
= GNUTLS_E_SUCCESS
;
2187 /* Either the signer is directly trusted (i.e., in trustlist) or it
2188 is directly signed by something in trustlist and has proper OCSP
2190 rc
= _gnutls_trustlist_inlist (trustlist
, signercert
);
2198 /* not in trustlist, need to verify signature and bits */
2199 gnutls_x509_crt_t issuer
;
2204 rc
= gnutls_x509_trust_list_get_issuer (trustlist
, signercert
,
2206 if (rc
!= GNUTLS_E_SUCCESS
)
2209 *verify
= GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER
;
2210 rc
= GNUTLS_E_SUCCESS
;
2214 rc
= gnutls_x509_crt_verify (signercert
, &issuer
, 1, 0, &vtmp
);
2215 if (rc
!= GNUTLS_E_SUCCESS
)
2223 *verify
= vstatus_to_ocsp_status(vtmp
);
2225 rc
= GNUTLS_E_SUCCESS
;
2229 rc
= check_ocsp_purpose(signercert
);
2233 *verify
= GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR
;
2234 rc
= GNUTLS_E_SUCCESS
;
2239 rc
= _ocsp_resp_verify_direct (resp
, signercert
, verify
, flags
);
2242 gnutls_x509_crt_deinit (signercert
);