1 /* ocsp.c - OCSP (rfc2560)
2 * Copyright (C) 2003, 2004, 2005, 2006, 2012 g10 Code GmbH
4 * This file is part of KSBA.
6 * KSBA is free software; you can redistribute it and/or modify
7 * it under the terms of either
9 * - the GNU Lesser General Public License as published by the Free
10 * Software Foundation; either version 3 of the License, or (at
11 * your option) any later version.
15 * - the GNU General Public License as published by the Free
16 * Software Foundation; either version 2 of the License, or (at
17 * your option) any later version.
19 * or both in parallel, as here.
21 * KSBA is distributed in the hope that it will be useful, but WITHOUT
22 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
24 * License for more details.
26 * You should have received a copies of the GNU General Public License
27 * and the GNU Lesser General Public License along with this program;
28 * if not, see <http://www.gnu.org/licenses/>.
43 #include "der-encoder.h"
48 static const char oidstr_sha1[] = "1.3.14.3.2.26";
49 static const char oidstr_ocsp_basic[] = "1.3.6.1.5.5.7.48.1.1";
50 static const char oidstr_ocsp_nonce[] = "1.3.6.1.5.5.7.48.1.2";
55 dump_hex (const unsigned char *p, size_t n)
58 fputs ("none", stderr);
62 fprintf (stderr, " %02X", *p);
69 parse_skip (unsigned char const **buf, size_t *len, struct tag_info *ti)
73 assert (ti->length <= *len);
80 parse_sequence (unsigned char const **buf, size_t *len, struct tag_info *ti)
84 err = _ksba_ber_parse_tl (buf, len, ti);
87 else if (!(ti->class == CLASS_UNIVERSAL && ti->tag == TYPE_SEQUENCE
88 && ti->is_constructed) )
89 err = gpg_error (GPG_ERR_INV_OBJ);
90 else if (ti->length > *len)
91 err = gpg_error (GPG_ERR_BAD_BER);
96 parse_enumerated (unsigned char const **buf, size_t *len, struct tag_info *ti,
101 err = _ksba_ber_parse_tl (buf, len, ti);
104 else if (!(ti->class == CLASS_UNIVERSAL && ti->tag == TYPE_ENUMERATED
105 && !ti->is_constructed) )
106 err = gpg_error (GPG_ERR_INV_OBJ);
107 else if (!ti->length)
108 err = gpg_error (GPG_ERR_TOO_SHORT);
109 else if (maxlen && ti->length > maxlen)
110 err = gpg_error (GPG_ERR_TOO_LARGE);
111 else if (ti->length > *len)
112 err = gpg_error (GPG_ERR_BAD_BER);
118 parse_integer (unsigned char const **buf, size_t *len, struct tag_info *ti)
122 err = _ksba_ber_parse_tl (buf, len, ti);
125 else if (!(ti->class == CLASS_UNIVERSAL && ti->tag == TYPE_INTEGER
126 && !ti->is_constructed) )
127 err = gpg_error (GPG_ERR_INV_OBJ);
128 else if (!ti->length)
129 err = gpg_error (GPG_ERR_TOO_SHORT);
130 else if (ti->length > *len)
131 err = gpg_error (GPG_ERR_BAD_BER);
137 parse_octet_string (unsigned char const **buf, size_t *len, struct tag_info *ti)
141 err= _ksba_ber_parse_tl (buf, len, ti);
144 else if (!(ti->class == CLASS_UNIVERSAL && ti->tag == TYPE_OCTET_STRING
145 && !ti->is_constructed) )
146 err = gpg_error (GPG_ERR_INV_OBJ);
147 else if (!ti->length)
148 err = gpg_error (GPG_ERR_TOO_SHORT);
149 else if (ti->length > *len)
150 err = gpg_error (GPG_ERR_BAD_BER);
156 /* Note that R_BOOL will only be set if a value has been given. Thus
157 the caller should set it to the default value prior to calling this
158 function. Obviously no call to parse_skip is required after
159 calling this function. */
161 parse_optional_boolean (unsigned char const **buf, size_t *len, int *r_bool)
166 err = _ksba_ber_parse_tl (buf, len, &ti);
170 err = gpg_error (GPG_ERR_TOO_SHORT);
171 else if (ti.length > *len)
172 err = gpg_error (GPG_ERR_BAD_BER);
173 else if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_BOOLEAN
174 && !ti.is_constructed)
177 err = gpg_error (GPG_ERR_BAD_BER);
179 parse_skip (buf, len, &ti);
182 { /* Undo the read. */
193 parse_object_id_into_str (unsigned char const **buf, size_t *len, char **oid)
199 err = _ksba_ber_parse_tl (buf, len, &ti);
202 else if (!(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OBJECT_ID
203 && !ti.is_constructed) )
204 err = gpg_error (GPG_ERR_INV_OBJ);
206 err = gpg_error (GPG_ERR_TOO_SHORT);
207 else if (ti.length > *len)
208 err = gpg_error (GPG_ERR_BAD_BER);
209 else if (!(*oid = ksba_oid_to_str (*buf, ti.length)))
210 err = gpg_error_from_errno (errno);
221 parse_asntime_into_isotime (unsigned char const **buf, size_t *len,
222 ksba_isotime_t isotime)
227 err = _ksba_ber_parse_tl (buf, len, &ti);
230 else if ( !(ti.class == CLASS_UNIVERSAL
231 && (ti.tag == TYPE_UTC_TIME || ti.tag == TYPE_GENERALIZED_TIME)
232 && !ti.is_constructed) )
233 err = gpg_error (GPG_ERR_INV_OBJ);
234 else if (ti.length > *len)
235 err = gpg_error (GPG_ERR_INV_BER);
236 else if (!(err = _ksba_asntime_to_iso (*buf, ti.length,
237 ti.tag == TYPE_UTC_TIME, isotime)))
238 parse_skip (buf, len, &ti);
245 parse_context_tag (unsigned char const **buf, size_t *len, struct tag_info *ti,
250 err = _ksba_ber_parse_tl (buf, len, ti);
253 else if (!(ti->class == CLASS_CONTEXT && ti->tag == tag
254 && ti->is_constructed) )
255 err = gpg_error (GPG_ERR_INV_OBJ);
256 else if (ti->length > *len)
257 err = gpg_error (GPG_ERR_BAD_BER);
264 /* Create a new OCSP object and retrun it in R_OCSP. Return 0 on
265 success or an error code.
268 ksba_ocsp_new (ksba_ocsp_t *r_ocsp)
270 *r_ocsp = xtrycalloc (1, sizeof **r_ocsp);
272 return gpg_error_from_errno (errno);
278 release_ocsp_certlist (struct ocsp_certlist_s *cl)
282 struct ocsp_certlist_s *tmp = cl->next;
283 ksba_cert_release (cl->cert);
291 release_ocsp_extensions (struct ocsp_extension_s *ex)
295 struct ocsp_extension_s *tmp = ex->next;
302 /* Release the OCSP object and all its resources. Passing NULL for
303 OCSP is a valid nop. */
305 ksba_ocsp_release (ksba_ocsp_t ocsp)
307 struct ocsp_reqitem_s *ri;
311 xfree (ocsp->digest_oid);
312 xfree (ocsp->request_buffer);
313 for (; (ri=ocsp->requestlist); ri = ocsp->requestlist )
315 ocsp->requestlist = ri->next;
316 ksba_cert_release (ri->cert);
317 ksba_cert_release (ri->issuer_cert);
318 release_ocsp_extensions (ri->single_extensions);
319 xfree (ri->serialno);
321 xfree (ocsp->sigval);
322 xfree (ocsp->responder_id.name);
323 xfree (ocsp->responder_id.keyid);
324 release_ocsp_certlist (ocsp->received_certs);
325 release_ocsp_extensions (ocsp->response_extensions);
331 /* Set the hash algorithm to be used for signing the request to OID.
332 Using this function will force the creation of a signed
335 ksba_ocsp_set_digest_algo (ksba_ocsp_t ocsp, const char *oid)
337 if (!ocsp || !oid || !*oid)
338 return gpg_error (GPG_ERR_INV_VALUE);
339 if (ocsp->digest_oid)
340 xfree (ocsp->digest_oid);
341 ocsp->digest_oid = xtrystrdup (oid);
342 if (!ocsp->digest_oid)
343 return gpg_error_from_errno (errno);
349 ksba_ocsp_set_requestor (ksba_ocsp_t ocsp, ksba_cert_t cert)
353 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
357 /* Add the certificate CERT for which the status is to be requested
358 and it's issuer certificate ISSUER_CERT to the context. This
359 function may be called multiple time to create a list of targets to
360 get combined into one actual request. */
362 ksba_ocsp_add_target (ksba_ocsp_t ocsp,
363 ksba_cert_t cert, ksba_cert_t issuer_cert)
365 struct ocsp_reqitem_s *ri;
367 if (!ocsp || !cert || !issuer_cert)
368 return gpg_error (GPG_ERR_INV_VALUE);
370 ri = xtrycalloc (1, sizeof *ri);
372 return gpg_error_from_errno (errno);
373 ksba_cert_ref (cert);
375 ksba_cert_ref (issuer_cert);
376 ri->issuer_cert = issuer_cert;
378 ri->next = ocsp->requestlist;
379 ocsp->requestlist = ri;
385 /* Set the nonce to be used for the request to the content of the
386 buffer NONCE of size NONCELEN. Libksba may have an upper limit of
387 the allowed size of the nonce; if the supplied nonce is larger it
388 will be truncated and the actual used length of the nonce returned.
389 To detect the implementation limit (which should be considered as a
390 good suggestion), the function may be called with NULL for NONCE,
391 in which case the maximal usable noncelength is returned. The
392 function returns the length of the nonce which will be used. */
394 ksba_ocsp_set_nonce (ksba_ocsp_t ocsp, unsigned char *nonce, size_t noncelen)
399 return sizeof ocsp->nonce;
400 if (noncelen > sizeof ocsp->nonce)
401 noncelen = sizeof ocsp->nonce;
404 memcpy (ocsp->nonce, nonce, noncelen);
405 /* Reset the high bit. We do this to make sure that we have a
406 positive integer and thus we don't need to prepend a leading
407 zero which would be needed then. */
408 ocsp->nonce[0] &= 0x7f;
410 ocsp->noncelen = noncelen;
415 /* Compute the SHA-1 nameHash for the certificate CERT and put it in
416 the buffer SHA1_BUFFER which must have been allocated to at least
419 issuer_name_hash (ksba_cert_t cert, unsigned char *sha1_buffer)
422 const unsigned char *ptr;
423 size_t length, dummy;
425 err = _ksba_cert_get_subject_dn_ptr (cert, &ptr, &length);
428 err = _ksba_hash_buffer (NULL, ptr, length, 20, sha1_buffer, &dummy);
429 if (!err && dummy != 20)
430 err = gpg_error (GPG_ERR_BUG);
435 /* Compute the SHA-1 hash of the public key of CERT and put it in teh
436 buffer SHA1_BUFFER which must have been allocated with at least 20
439 issuer_key_hash (ksba_cert_t cert, unsigned char *sha1_buffer)
442 const unsigned char *ptr;
443 size_t length, dummy;
445 err = _ksba_cert_get_public_key_ptr (cert, &ptr, &length);
448 err = _ksba_hash_buffer (NULL, ptr, length, 20, sha1_buffer, &dummy);
449 if (!err && dummy != 20)
450 err = gpg_error (GPG_ERR_BUG);
456 /* Write the extensions for a request to WOUT. */
458 write_request_extensions (ksba_ocsp_t ocsp, ksba_writer_t wout)
465 ksba_writer_t w1 = NULL;
466 ksba_writer_t w2 = NULL;
469 return 0; /* We do only support the nonce extension. */
471 /* Create writer objects for construction of the extension. */
472 err = ksba_writer_new (&w2);
474 err = ksba_writer_set_mem (w2, 256);
476 err = ksba_writer_new (&w1);
478 err = ksba_writer_set_mem (w1, 256);
482 /* Write OID and and nonce. */
483 err = ksba_oid_from_str (oidstr_ocsp_nonce, &buf, &buflen);
486 err = _ksba_ber_write_tl (w1, TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, buflen);
488 err = ksba_writer_write (w1, buf, buflen);
489 xfree (buf); buf = NULL;
490 /* We known that the nonce is short enough to put the tag into 2 bytes, thus
491 we write the encapsulating octet string directly with a fixed length. */
493 err = _ksba_ber_write_tl (w1, TYPE_OCTET_STRING, CLASS_UNIVERSAL, 0,
496 err = _ksba_ber_write_tl (w1, TYPE_INTEGER, CLASS_UNIVERSAL, 0,
499 err = ksba_writer_write (w1, ocsp->nonce, ocsp->noncelen);
501 /* Put a sequence around. */
502 p = ksba_writer_snatch_mem (w1, &derlen);
505 err = ksba_writer_error (w1);
508 err = _ksba_ber_write_tl (w2, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, derlen);
510 err = ksba_writer_write (w2, p, derlen);
513 /* Put the sequence around all extensions. */
514 err = ksba_writer_set_mem (w1, 256);
517 p = ksba_writer_snatch_mem (w2, &derlen);
520 err = ksba_writer_error (w2);
523 err = _ksba_ber_write_tl (w1, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, derlen);
525 err = ksba_writer_write (w1, p, derlen);
528 /* And put a context tag around everything. */
529 p = ksba_writer_snatch_mem (w1, &derlen);
532 err = ksba_writer_error (w1);
535 err = _ksba_ber_write_tl (wout, 2, CLASS_CONTEXT, 1, derlen);
537 err = ksba_writer_write (wout, p, derlen);
542 ksba_writer_release (w2);
543 ksba_writer_release (w1);
548 /* Build a request from the current context. The function checks that
549 all necessary information have been set and stores the prepared
550 request in the context. A subsequent ksba_ocsp_build_request may
551 then be used to retrieve this request. Optional the requestmay be
552 signed beofre calling ksba_ocsp_build_request.
555 ksba_ocsp_prepare_request (ksba_ocsp_t ocsp)
558 struct ocsp_reqitem_s *ri;
560 const unsigned char *der;
562 ksba_writer_t w1 = NULL;
563 ksba_writer_t w2 = NULL;
564 ksba_writer_t w3 = NULL;
565 ksba_writer_t w4, w5, w6, w7; /* Used as aliases. */
568 return gpg_error (GPG_ERR_INV_VALUE);
570 xfree (ocsp->request_buffer);
571 ocsp->request_buffer = NULL;
572 ocsp->request_buflen = 0;
574 if (!ocsp->requestlist)
575 return gpg_error (GPG_ERR_MISSING_ACTION);
577 /* Create three writer objects for construction of the request. */
578 err = ksba_writer_new (&w3);
580 err = ksba_writer_set_mem (w3, 2048);
582 err = ksba_writer_new (&w2);
584 err = ksba_writer_new (&w1);
589 /* Loop over all single requests. */
590 for (ri=ocsp->requestlist; ri; ri = ri->next)
592 err = ksba_writer_set_mem (w2, 256);
594 err = ksba_writer_set_mem (w1, 256);
598 /* Write the AlgorithmIdentifier. */
599 err = _ksba_der_write_algorithm_identifier (w1, oidstr_sha1, NULL, 0);
603 /* Compute the issuerNameHash and write it into the CertID object. */
604 err = issuer_name_hash (ri->issuer_cert, ri->issuer_name_hash);
606 err = _ksba_ber_write_tl (w1, TYPE_OCTET_STRING, CLASS_UNIVERSAL, 0,20);
608 err = ksba_writer_write (w1, ri->issuer_name_hash, 20);
612 /* Compute the issuerKeyHash and write it. */
613 err = issuer_key_hash (ri->issuer_cert, ri->issuer_key_hash);
615 err = _ksba_ber_write_tl (w1, TYPE_OCTET_STRING, CLASS_UNIVERSAL, 0,20);
617 err = ksba_writer_write (w1, ri->issuer_key_hash, 20);
621 /* Write the serialNumber of the certificate to be checked. */
622 err = _ksba_cert_get_serial_ptr (ri->cert, &der, &derlen);
624 err = _ksba_ber_write_tl (w1, TYPE_INTEGER, CLASS_UNIVERSAL, 0, derlen);
626 err = ksba_writer_write (w1, der, derlen);
629 xfree (ri->serialno);
630 ri->serialno = xtrymalloc (derlen);
632 err = gpg_error_from_errno (errno);
635 memcpy (ri->serialno, der, derlen);
636 ri->serialnolen = derlen;
639 /* Now write it out as a sequence to the outer certID object. */
640 p = ksba_writer_snatch_mem (w1, &derlen);
643 err = ksba_writer_error (w1);
646 err = _ksba_ber_write_tl (w2, TYPE_SEQUENCE, CLASS_UNIVERSAL,
649 err = ksba_writer_write (w2, p, derlen);
654 /* Here we would write singleRequestExtensions. */
656 /* Now write it out as a sequence to the outer Request object. */
657 p = ksba_writer_snatch_mem (w2, &derlen);
660 err = ksba_writer_error (w2);
663 err = _ksba_ber_write_tl (w3, TYPE_SEQUENCE, CLASS_UNIVERSAL,
666 err = ksba_writer_write (w3, p, derlen);
671 } /* End of looping over single requests. */
673 /* Reuse writers; for clarity, use new names. */
676 err = ksba_writer_set_mem (w4, 2048);
678 err = ksba_writer_set_mem (w5, 2048);
682 /* Put a sequence tag before the requestList. */
683 p = ksba_writer_snatch_mem (w3, &derlen);
686 err = ksba_writer_error (w3);
689 err = _ksba_ber_write_tl (w4, TYPE_SEQUENCE, CLASS_UNIVERSAL,
692 err = ksba_writer_write (w4, p, derlen);
697 /* The requestExtensions go here. */
698 err = write_request_extensions (ocsp, w4);
700 /* Write the tbsRequest. */
702 /* The version is default, thus we don't write it. */
704 /* The requesterName would go here. */
706 /* Write the requestList. */
707 p = ksba_writer_snatch_mem (w4, &derlen);
710 err = ksba_writer_error (w4);
713 err = _ksba_ber_write_tl (w5, TYPE_SEQUENCE, CLASS_UNIVERSAL,
716 err = ksba_writer_write (w5, p, derlen);
721 /* Reuse writers; for clarity, use new names. */
724 err = ksba_writer_set_mem (w6, 2048);
726 err = ksba_writer_set_mem (w7, 2048);
730 /* Prepend a sequence tag. */
731 p = ksba_writer_snatch_mem (w5, &derlen);
734 err = ksba_writer_error (w5);
737 err = _ksba_ber_write_tl (w6, TYPE_SEQUENCE, CLASS_UNIVERSAL,
740 err = ksba_writer_write (w6, p, derlen);
745 /* Write the ocspRequest. */
747 /* Note that we do not support the optional signature, because this
748 saves us one writer object. */
750 /* Prepend a sequence tag. */
751 /* p = ksba_writer_snatch_mem (w6, &derlen); */
754 /* err = ksba_writer_error (w6); */
757 /* err = _ksba_ber_write_tl (w7, TYPE_SEQUENCE, CLASS_UNIVERSAL, */
760 /* err = ksba_writer_write (w7, p, derlen); */
761 /* xfree (p); p = NULL; */
766 /* Read out the entire request. */
767 p = ksba_writer_snatch_mem (w6, &derlen);
770 err = ksba_writer_error (w6);
773 ocsp->request_buffer = p;
774 ocsp->request_buflen = derlen;
778 ksba_writer_release (w3);
779 ksba_writer_release (w2);
780 ksba_writer_release (w1);
786 ksba_ocsp_hash_request (ksba_ocsp_t ocsp,
787 void (*hasher)(void *, const void *,
794 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
799 ksba_ocsp_set_sig_val (ksba_ocsp_t ocsp,
800 ksba_const_sexp_t sigval)
804 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
809 ksba_ocsp_add_cert (ksba_ocsp_t ocsp, ksba_cert_t cert)
813 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
818 /* Build a request from the current context. The function checks that
819 all necessary information have been set and then returns an
820 allocated buffer with the resulting request.
823 ksba_ocsp_build_request (ksba_ocsp_t ocsp,
824 unsigned char **r_buffer, size_t *r_buflen)
828 if (!ocsp || !r_buffer || !r_buflen)
829 return gpg_error (GPG_ERR_INV_VALUE);
833 if (!ocsp->requestlist)
834 return gpg_error (GPG_ERR_MISSING_ACTION);
835 if (!ocsp->request_buffer)
837 /* No prepare done, do it now. */
838 err = ksba_ocsp_prepare_request (ocsp);
841 assert (ocsp->request_buffer);
843 *r_buffer = ocsp->request_buffer;
844 *r_buflen = ocsp->request_buflen;
845 ocsp->request_buffer = NULL;
846 ocsp->request_buflen = 0;
853 Parse the response extensions and store them aways. While doing
854 this we also check the nonce extension. A typical data ASN.1 blob
855 with only the nonce extension as passed to this function is:
859 OBJECT IDENTIFIER ocspNonce (1 3 6 1 5 5 7 48 1 2)
860 OCTET STRING, encapsulates {
862 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50
869 parse_response_extensions (ksba_ocsp_t ocsp,
870 const unsigned char *data, size_t datalen)
877 assert (!ocsp->response_extensions);
878 err = parse_sequence (&data, &datalen, &ti);
884 struct ocsp_extension_s *ex;
887 err = parse_sequence (&data, &datalen, &ti);
890 if (length < ti.nhdr + ti.length)
892 err = gpg_error (GPG_ERR_BAD_BER);
895 length -= ti.nhdr + ti.length;
898 err = parse_object_id_into_str (&data, &datalen, &oid);
902 err = parse_optional_boolean (&data, &datalen, &is_crit);
905 err = parse_octet_string (&data, &datalen, &ti);
908 if (!strcmp (oid, oidstr_ocsp_nonce))
910 err = parse_integer (&data, &datalen, &ti);
913 if (ocsp->noncelen != ti.length
914 || memcmp (ocsp->nonce, data, ti.length))
917 ocsp->good_nonce = 1;
919 ex = xtrymalloc (sizeof *ex + strlen (oid) + ti.length);
922 err = gpg_error_from_errno (errno);
926 strcpy (ex->data, oid);
927 ex->data[strlen (oid)] = 0;
928 ex->off = strlen (oid) + 1;
930 memcpy (ex->data + ex->off, data, ti.length);
931 ex->next = ocsp->response_extensions;
932 ocsp->response_extensions = ex;
934 parse_skip (&data, &datalen, &ti); /* Skip the octet string / integer. */
944 Parse single extensions and store them away.
947 parse_single_extensions (struct ocsp_reqitem_s *ri,
948 const unsigned char *data, size_t datalen)
955 assert (ri && !ri->single_extensions);
956 err = parse_sequence (&data, &datalen, &ti);
962 struct ocsp_extension_s *ex;
965 err = parse_sequence (&data, &datalen, &ti);
968 if (length < ti.nhdr + ti.length)
970 err = gpg_error (GPG_ERR_BAD_BER);
973 length -= ti.nhdr + ti.length;
976 err = parse_object_id_into_str (&data, &datalen, &oid);
980 err = parse_optional_boolean (&data, &datalen, &is_crit);
983 err = parse_octet_string (&data, &datalen, &ti);
986 ex = xtrymalloc (sizeof *ex + strlen (oid) + ti.length);
989 err = gpg_error_from_errno (errno);
993 strcpy (ex->data, oid);
994 ex->data[strlen (oid)] = 0;
995 ex->off = strlen (oid) + 1;
997 memcpy (ex->data + ex->off, data, ti.length);
998 ex->next = ri->single_extensions;
999 ri->single_extensions = ex;
1001 parse_skip (&data, &datalen, &ti); /* Skip the octet string / integer. */
1010 /* Parse the first part of a response:
1012 OCSPResponse ::= SEQUENCE {
1013 responseStatus OCSPResponseStatus,
1014 responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
1016 OCSPResponseStatus ::= ENUMERATED {
1017 successful (0), --Response has valid confirmations
1018 malformedRequest (1), --Illegal confirmation request
1019 internalError (2), --Internal error in issuer
1020 tryLater (3), --Try again later
1022 sigRequired (5), --Must sign the request
1023 unauthorized (6) --Request unauthorized
1026 ResponseBytes ::= SEQUENCE {
1027 responseType OBJECT IDENTIFIER,
1028 response OCTET STRING }
1030 On success the RESPONSE_STATUS field of OCSP will be set to the
1031 response status and DATA will now point to the first byte in the
1032 octet string of the response; RLEN will be set to the length of
1033 this octet string. Note thate DATALEN is also updated but might
1034 point to a value larger than RLEN points to, if the provided data
1035 is a part of a larger image. */
1037 parse_response_status (ksba_ocsp_t ocsp,
1038 unsigned char const **data, size_t *datalen,
1046 /* Parse the OCSPResponse sequence. */
1047 err = parse_sequence (data, datalen, &ti);
1050 /* Parse the OCSPResponseStatus. */
1051 err = parse_enumerated (data, datalen, &ti, 1);
1056 case 0: ocsp->response_status = KSBA_OCSP_RSPSTATUS_SUCCESS; break;
1057 case 1: ocsp->response_status = KSBA_OCSP_RSPSTATUS_MALFORMED; break;
1058 case 2: ocsp->response_status = KSBA_OCSP_RSPSTATUS_INTERNAL; break;
1059 case 3: ocsp->response_status = KSBA_OCSP_RSPSTATUS_TRYLATER; break;
1060 case 5: ocsp->response_status = KSBA_OCSP_RSPSTATUS_SIGREQUIRED; break;
1061 case 6: ocsp->response_status = KSBA_OCSP_RSPSTATUS_UNAUTHORIZED; break;
1062 default: ocsp->response_status = KSBA_OCSP_RSPSTATUS_OTHER; break;
1064 parse_skip (data, datalen, &ti);
1066 if (ocsp->response_status)
1067 return 0; /* This is an error reponse; we have to stop here. */
1069 /* We have a successful reponse status, thus we check that
1070 ResponseBytes are actually available. */
1071 err = parse_context_tag (data, datalen, &ti, 0);
1074 err = parse_sequence (data, datalen, &ti);
1077 err = parse_object_id_into_str (data, datalen, &oid);
1080 if (strcmp (oid, oidstr_ocsp_basic))
1083 return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
1087 /* Check that the next field is an octet string. */
1088 err = parse_octet_string (data, datalen, &ti);
1091 *rlength = ti.length;
1095 /* Parse the object:
1097 SingleResponse ::= SEQUENCE {
1099 certStatus CertStatus,
1100 thisUpdate GeneralizedTime,
1101 nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
1102 singleExtensions [1] EXPLICIT Extensions OPTIONAL }
1104 CertStatus ::= CHOICE {
1105 good [0] IMPLICIT NULL,
1106 revoked [1] IMPLICIT RevokedInfo,
1107 unknown [2] IMPLICIT UnknownInfo }
1109 RevokedInfo ::= SEQUENCE {
1110 revocationTime GeneralizedTime,
1111 revocationReason [0] EXPLICIT CRLReason OPTIONAL }
1113 UnknownInfo ::= NULL -- this can be replaced with an enumeration
1118 parse_single_response (ksba_ocsp_t ocsp,
1119 unsigned char const **data, size_t *datalen)
1123 const unsigned char *savedata;
1124 const unsigned char *endptr;
1128 ksba_isotime_t this_update, next_update, revocation_time;
1129 int look_for_request;
1130 const unsigned char *name_hash;
1131 const unsigned char *key_hash;
1132 const unsigned char *serialno;
1134 struct ocsp_reqitem_s *request_item = NULL;
1136 /* The SingeResponse sequence. */
1137 err = parse_sequence (data, datalen, &ti);
1140 endptr = *data + ti.length;
1144 hashAlgorithm AlgorithmIdentifier,
1145 issuerNameHash OCTET STRING, -- Hash of Issuer's DN
1146 issuerKeyHash OCTET STRING, -- Hash of Issuers public key
1147 serialNumber CertificateSerialNumber }
1149 err = parse_sequence (data, datalen, &ti);
1152 err = _ksba_parse_algorithm_identifier (*data, *datalen, &n, &oid);
1155 assert (n <= *datalen);
1158 /* fprintf (stderr, "algorithmIdentifier is `%s'\n", oid); */
1159 look_for_request = !strcmp (oid, oidstr_sha1);
1162 err = parse_octet_string (data, datalen, &ti);
1166 /* fprintf (stderr, "issuerNameHash="); */
1167 /* dump_hex (*data, ti.length); */
1168 /* putc ('\n', stderr); */
1169 if (ti.length != 20)
1170 look_for_request = 0; /* Can't be a SHA-1 digest. */
1171 parse_skip (data, datalen, &ti);
1173 err = parse_octet_string (data, datalen, &ti);
1177 /* fprintf (stderr, "issuerKeyHash="); */
1178 /* dump_hex (*data, ti.length); */
1179 /* putc ('\n', stderr); */
1180 if (ti.length != 20)
1181 look_for_request = 0; /* Can't be a SHA-1 digest. */
1182 parse_skip (data, datalen, &ti);
1184 err= parse_integer (data, datalen, &ti);
1188 serialnolen = ti.length;
1189 /* fprintf (stderr, "serialNumber="); */
1190 /* dump_hex (*data, ti.length); */
1191 /* putc ('\n', stderr); */
1192 parse_skip (data, datalen, &ti);
1194 if (look_for_request)
1196 for (request_item = ocsp->requestlist;
1197 request_item; request_item = request_item->next)
1198 if (!memcmp (request_item->issuer_name_hash, name_hash, 20)
1199 && !memcmp (request_item->issuer_key_hash, key_hash, 20)
1200 && request_item->serialnolen == serialnolen
1201 && !memcmp (request_item->serialno, serialno, serialnolen))
1202 break; /* Got it. */
1207 CertStatus ::= CHOICE {
1208 good [0] IMPLICIT NULL,
1209 revoked [1] IMPLICIT RevokedInfo,
1210 unknown [2] IMPLICIT UnknownInfo }
1212 *revocation_time = 0;
1213 err = _ksba_ber_parse_tl (data, datalen, &ti);
1216 if (ti.length > *datalen)
1217 return gpg_error (GPG_ERR_BAD_BER);
1218 else if (ti.class == CLASS_CONTEXT && ti.tag == 0 && !ti.is_constructed)
1221 ; /* Cope with zero length objects. */
1222 else if (*datalen && !**data)
1223 { /* Skip the NULL. */
1228 return gpg_error (GPG_ERR_INV_OBJ);
1231 request_item->status = KSBA_STATUS_GOOD;
1233 else if (ti.class == CLASS_CONTEXT && ti.tag == 1 && ti.is_constructed)
1235 ksba_crl_reason_t reason = KSBA_CRLREASON_UNSPECIFIED;
1237 err = parse_asntime_into_isotime (data, datalen, revocation_time);
1240 /* fprintf (stderr, "revocationTime=%s\n", revocation_time); */
1242 savedatalen = *datalen;
1243 err = parse_context_tag (data, datalen, &ti, 0);
1247 *datalen = savedatalen;
1250 { /* Got a revocationReason. */
1251 err = parse_enumerated (data, datalen, &ti, 1);
1256 case 0: reason = KSBA_CRLREASON_UNSPECIFIED; break;
1257 case 1: reason = KSBA_CRLREASON_KEY_COMPROMISE; break;
1258 case 2: reason = KSBA_CRLREASON_CA_COMPROMISE; break;
1259 case 3: reason = KSBA_CRLREASON_AFFILIATION_CHANGED; break;
1260 case 4: reason = KSBA_CRLREASON_SUPERSEDED; break;
1261 case 5: reason = KSBA_CRLREASON_CESSATION_OF_OPERATION; break;
1262 case 6: reason = KSBA_CRLREASON_CERTIFICATE_HOLD; break;
1263 case 8: reason = KSBA_CRLREASON_REMOVE_FROM_CRL; break;
1264 case 9: reason = KSBA_CRLREASON_PRIVILEGE_WITHDRAWN; break;
1265 case 10: reason = KSBA_CRLREASON_AA_COMPROMISE; break;
1266 default: reason = KSBA_CRLREASON_OTHER; break;
1268 parse_skip (data, datalen, &ti);
1270 /* fprintf (stderr, "revocationReason=%04x\n", reason); */
1273 request_item->status = KSBA_STATUS_REVOKED;
1274 _ksba_copy_time (request_item->revocation_time, revocation_time);
1275 request_item->revocation_reason = reason;
1278 else if (ti.class == CLASS_CONTEXT && ti.tag == 2 && !ti.is_constructed
1282 ; /* Cope with zero length objects. */
1284 { /* Skip the NULL. */
1288 else /* The comment indicates that an enumeration may come here. */
1290 err = parse_enumerated (data, datalen, &ti, 0);
1293 fprintf (stderr, "libksba: unknownReason with an enum of "
1294 "length %u detected\n",
1295 (unsigned int)ti.length);
1296 parse_skip (data, datalen, &ti);
1299 request_item->status = KSBA_STATUS_UNKNOWN;
1302 err = gpg_error (GPG_ERR_INV_OBJ);
1305 err = parse_asntime_into_isotime (data, datalen, this_update);
1308 /* fprintf (stderr, "thisUpdate=%s\n", this_update); */
1310 _ksba_copy_time (request_item->this_update, this_update);
1312 /* nextUpdate is optional. */
1313 if (*data >= endptr)
1316 err = _ksba_ber_parse_tl (data, datalen, &ti);
1319 if (ti.length > *datalen)
1320 return gpg_error (GPG_ERR_BAD_BER);
1321 else if (ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed)
1322 { /* have nextUpdate */
1323 err = parse_asntime_into_isotime (data, datalen, next_update);
1326 /* fprintf (stderr, "nextUpdate=%s\n", next_update); */
1328 _ksba_copy_time (request_item->next_update, next_update);
1330 else if (ti.class == CLASS_CONTEXT && ti.tag == 1 && ti.is_constructed)
1331 { /* Undo that read. */
1333 *datalen += ti.nhdr;
1336 err = gpg_error (GPG_ERR_INV_OBJ);
1338 /* singleExtensions is optional */
1339 if (*data >= endptr)
1341 err = _ksba_ber_parse_tl (data, datalen, &ti);
1344 if (ti.length > *datalen)
1345 return gpg_error (GPG_ERR_BAD_BER);
1346 if (ti.class == CLASS_CONTEXT && ti.tag == 1 && ti.is_constructed)
1350 err = parse_single_extensions (request_item, *data, ti.length);
1354 parse_skip (data, datalen, &ti);
1357 err = gpg_error (GPG_ERR_INV_OBJ);
1362 /* Parse the object:
1364 ResponseData ::= SEQUENCE {
1365 version [0] EXPLICIT Version DEFAULT v1,
1366 responderID ResponderID,
1367 producedAt GeneralizedTime,
1368 responses SEQUENCE OF SingleResponse,
1369 responseExtensions [1] EXPLICIT Extensions OPTIONAL }
1371 ResponderID ::= CHOICE {
1378 parse_response_data (ksba_ocsp_t ocsp,
1379 unsigned char const **data, size_t *datalen)
1383 const unsigned char *savedata;
1385 size_t responses_length;
1387 /* The out er sequence. */
1388 err = parse_sequence (data, datalen, &ti);
1392 /* The optional version field. */
1394 savedatalen = *datalen;
1395 err = parse_context_tag (data, datalen, &ti, 0);
1399 *datalen = savedatalen;
1403 /* FIXME: check that the version matches. */
1404 parse_skip (data, datalen, &ti);
1407 /* The responderID field. */
1408 assert (!ocsp->responder_id.name);
1409 assert (!ocsp->responder_id.keyid);
1410 err = _ksba_ber_parse_tl (data, datalen, &ti);
1413 if (ti.length > *datalen)
1414 return gpg_error (GPG_ERR_BAD_BER);
1415 else if (ti.class == CLASS_CONTEXT && ti.tag == 1 && ti.is_constructed)
1417 err = _ksba_derdn_to_str (*data, ti.length, &ocsp->responder_id.name);
1420 parse_skip (data, datalen, &ti);
1422 else if (ti.class == CLASS_CONTEXT && ti.tag == 2 && ti.is_constructed)
1424 err = parse_octet_string (data, datalen, &ti);
1428 return gpg_error (GPG_ERR_INV_OBJ); /* Zero length key id. */
1429 ocsp->responder_id.keyid = xtrymalloc (ti.length);
1430 if (!ocsp->responder_id.keyid)
1431 return gpg_error_from_errno (errno);
1432 memcpy (ocsp->responder_id.keyid, *data, ti.length);
1433 ocsp->responder_id.keyidlen = ti.length;
1434 parse_skip (data, datalen, &ti);
1437 err = gpg_error (GPG_ERR_INV_OBJ);
1439 /* The producedAt field. */
1440 err = parse_asntime_into_isotime (data, datalen, ocsp->produced_at);
1444 /* The responses field set. */
1445 err = parse_sequence (data, datalen, &ti);
1448 responses_length = ti.length;
1449 while (responses_length)
1451 savedatalen = *datalen;
1452 err = parse_single_response (ocsp, data, datalen);
1455 assert (responses_length >= savedatalen - *datalen);
1456 responses_length -= savedatalen - *datalen;
1459 /* The optional responseExtensions set. */
1461 savedatalen = *datalen;
1462 err = parse_context_tag (data, datalen, &ti, 1);
1465 err = parse_response_extensions (ocsp, *data, ti.length);
1468 parse_skip (data, datalen, &ti);
1470 else if (gpg_err_code (err) == GPG_ERR_INV_OBJ)
1473 *datalen = savedatalen;
1482 /* Parse the entire response message pointed to by MSG of length
1485 parse_response (ksba_ocsp_t ocsp, const unsigned char *msg, size_t msglen)
1489 const unsigned char *msgstart;
1490 const unsigned char *endptr;
1496 err = parse_response_status (ocsp, &msg, &msglen, &len);
1499 msglen = len; /* We don't care about any extra bytes provided to us. */
1500 if (ocsp->response_status)
1502 /* fprintf (stderr,"response status found to be %d - stop\n", */
1503 /* ocsp->response_status); */
1507 /* Now that we are sure that it is a BasicOCSPResponse, we can parse
1508 the really important things:
1510 BasicOCSPResponse ::= SEQUENCE {
1511 tbsResponseData ResponseData,
1512 signatureAlgorithm AlgorithmIdentifier,
1513 signature BIT STRING,
1514 certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
1516 err = parse_sequence (&msg, &msglen, &ti);
1519 endptr = msg + ti.length;
1521 ocsp->hash_offset = msg - msgstart;
1522 err = parse_response_data (ocsp, &msg, &msglen);
1525 ocsp->hash_length = msg - msgstart - ocsp->hash_offset;
1527 /* The signatureAlgorithm and the signature. We only need to get the
1528 length of both objects and let a specialized function do the
1532 err = parse_sequence (&msg, &msglen, &ti);
1535 parse_skip (&msg, &msglen, &ti);
1536 err= _ksba_ber_parse_tl (&msg, &msglen, &ti);
1539 if (!(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_BIT_STRING
1540 && !ti.is_constructed) )
1541 err = gpg_error (GPG_ERR_INV_OBJ);
1542 else if (!ti.length)
1543 err = gpg_error (GPG_ERR_TOO_SHORT);
1544 else if (ti.length > msglen)
1545 err = gpg_error (GPG_ERR_BAD_BER);
1546 parse_skip (&msg, &msglen, &ti);
1548 xfree (ocsp->sigval); ocsp->sigval = NULL;
1549 err = _ksba_sigval_to_sexp (s, len, &ocsp->sigval);
1553 /* Parse the optional sequence of certificates. */
1555 return 0; /* It's optional, so stop now. */
1556 err = parse_context_tag (&msg, &msglen, &ti, 0);
1557 if (gpg_err_code (err) == GPG_ERR_INV_OBJ)
1558 return 0; /* Not the right tag. Stop here. */
1561 err = parse_sequence (&msg, &msglen, &ti);
1565 return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1569 struct ocsp_certlist_s *cl, **cl_tail;
1571 assert (!ocsp->received_certs);
1572 cl_tail = &ocsp->received_certs;
1573 endptr = msg + ti.length;
1574 while (msg < endptr)
1576 /* Find the length of the certificate. */
1578 err = parse_sequence (&msg, &msglen, &ti);
1581 err = ksba_cert_new (&cert);
1584 err = ksba_cert_init_from_mem (cert, msg - ti.nhdr,
1585 ti.nhdr + ti.length);
1588 ksba_cert_release (cert);
1591 parse_skip (&msg, &msglen, &ti);
1592 cl = xtrycalloc (1, sizeof *cl);
1594 err = gpg_error_from_errno (errno);
1597 ksba_cert_release (cert);
1598 return gpg_error (GPG_ERR_ENOMEM);
1603 cl_tail = &cl->next;
1611 /* Given the OCSP context and a binary reponse message of MSGLEN bytes
1612 in MSG, this fucntion parses the response and prepares it for
1613 signature verification. The status from the server is returned in
1614 RESPONSE_STATUS and must be checked even if the function returns
1615 without an error. */
1617 ksba_ocsp_parse_response (ksba_ocsp_t ocsp,
1618 const unsigned char *msg, size_t msglen,
1619 ksba_ocsp_response_status_t *response_status)
1622 struct ocsp_reqitem_s *ri;
1624 if (!ocsp || !msg || !msglen || !response_status)
1625 return gpg_error (GPG_ERR_INV_VALUE);
1627 if (!ocsp->requestlist)
1628 return gpg_error (GPG_ERR_MISSING_ACTION);
1630 /* Reset the fields used to track the response. This is so that we
1631 can use the parse function a second time for the same
1632 request. This is useful in case of a TryLater response status. */
1633 ocsp->response_status = KSBA_OCSP_RSPSTATUS_NONE;
1634 release_ocsp_certlist (ocsp->received_certs);
1635 release_ocsp_extensions (ocsp->response_extensions);
1636 ocsp->received_certs = NULL;
1637 ocsp->hash_length = 0;
1638 ocsp->bad_nonce = 0;
1639 ocsp->good_nonce = 0;
1640 xfree (ocsp->responder_id.name);
1641 ocsp->responder_id.name = NULL;
1642 xfree (ocsp->responder_id.keyid);
1643 ocsp->responder_id.keyid = NULL;
1644 for (ri=ocsp->requestlist; ri; ri = ri->next)
1646 ri->status = KSBA_STATUS_NONE;
1647 *ri->this_update = 0;
1648 *ri->next_update = 0;
1649 *ri->revocation_time = 0;
1650 ri->revocation_reason = 0;
1651 release_ocsp_extensions (ri->single_extensions);
1654 /* Run the actual parser. */
1655 err = parse_response (ocsp, msg, msglen);
1656 *response_status = ocsp->response_status;
1658 /* FIXME: find duplicates in the request list and set them to the
1661 if (*response_status == KSBA_OCSP_RSPSTATUS_SUCCESS)
1662 if (ocsp->bad_nonce || (ocsp->noncelen && !ocsp->good_nonce))
1663 *response_status = KSBA_OCSP_RSPSTATUS_REPLAYED;
1669 /* Return the digest algorithm to be used for the signature or NULL in
1670 case of an error. The returned pointer is valid as long as the
1671 context is valid and no other ksba_ocsp_parse_response or
1672 ksba_ocsp_build_request has been used. */
1674 ksba_ocsp_get_digest_algo (ksba_ocsp_t ocsp)
1676 return ocsp? ocsp->digest_oid : NULL;
1680 /* Hash the data of the response using the hash function HASHER which
1681 will be passed HASHER_ARG as its first argument and a pointer and a
1682 length of the data to be hashed. This hash function might be called
1683 several times and should update the hash context. The algorithm to
1684 be used for the hashing can be retrieved using
1685 ksba_ocsp_get_digest_algo. Note that MSG and MSGLEN should be
1686 indentical to the values passed to ksba_ocsp_parse_response. */
1688 ksba_ocsp_hash_response (ksba_ocsp_t ocsp,
1689 const unsigned char *msg, size_t msglen,
1690 void (*hasher)(void *, const void *, size_t length),
1694 if (!ocsp || !msg || !hasher)
1695 return gpg_error (GPG_ERR_INV_VALUE);
1696 if (!ocsp->hash_length)
1697 return gpg_error (GPG_ERR_MISSING_ACTION);
1698 if (ocsp->hash_offset + ocsp->hash_length >= msglen)
1699 return gpg_error (GPG_ERR_CONFLICT);
1701 hasher (hasher_arg, msg + ocsp->hash_offset, ocsp->hash_length);
1706 /* Return the actual signature in a format suitable to be used as
1707 input to Libgcrypt's verification function. The caller must free
1708 the returned string and that function may be called only once after
1709 a successful ksba_ocsp_parse_response. Returns NULL for an invalid
1710 handle or if no signature is available. If PRODUCED_AT is not NULL,
1711 it will receive the time the response was signed. */
1713 ksba_ocsp_get_sig_val (ksba_ocsp_t ocsp, ksba_isotime_t produced_at)
1719 if (!ocsp || !ocsp->sigval )
1723 _ksba_copy_time (produced_at, ocsp->produced_at);
1726 ocsp->sigval = NULL;
1731 /* Return the responder ID for the current response into R_NAME or
1732 into R_KEYID. On sucess either R_NAME or R_KEYID will receive an
1733 allocated object. If R_NAME or R_KEYID has been passed as NULL but
1734 a value is available the errorcode GPG_ERR_NO_DATA is returned.
1735 Caller must release the values stored at R_NAME or R_KEYID; the
1736 function stores NULL tehre in case of an error. */
1738 ksba_ocsp_get_responder_id (ksba_ocsp_t ocsp,
1739 char **r_name, ksba_sexp_t *r_keyid)
1747 return gpg_error (GPG_ERR_INV_VALUE);
1749 if (ocsp->responder_id.name && r_name)
1751 *r_name = xtrystrdup (ocsp->responder_id.name);
1753 return gpg_error_from_errno (errno);
1755 else if (ocsp->responder_id.keyid && r_keyid)
1760 sprintf (numbuf,"(%lu:", (unsigned long)ocsp->responder_id.keyidlen);
1761 numbuflen = strlen (numbuf);
1762 *r_keyid = xtrymalloc (numbuflen + ocsp->responder_id.keyidlen + 2);
1764 return gpg_error_from_errno (errno);
1765 strcpy (*r_keyid, numbuf);
1766 memcpy (*r_keyid+numbuflen,
1767 ocsp->responder_id.keyid, ocsp->responder_id.keyidlen);
1768 (*r_keyid)[numbuflen + ocsp->responder_id.keyidlen] = ')';
1769 (*r_keyid)[numbuflen + ocsp->responder_id.keyidlen + 1] = 0;
1772 gpg_error (GPG_ERR_NO_DATA);
1778 /* Get optional certificates out of a response. The caller may use
1779 * this in a loop to get all certificates. The returned certificate
1780 * is a shallow copy of the original one; the caller must still use
1781 * ksba_cert_release() to free it. Returns: A certificate object or
1782 * NULL for end of list or error. */
1784 ksba_ocsp_get_cert (ksba_ocsp_t ocsp, int idx)
1786 struct ocsp_certlist_s *cl;
1788 if (!ocsp || idx < 0)
1791 for (cl=ocsp->received_certs; cl && idx; cl = cl->next, idx--)
1795 ksba_cert_ref (cl->cert);
1802 /* Return the status of the certificate CERT for the last response
1803 done on the context OCSP. CERT must be the same certificate as
1804 used for the request; only a shallow compare is done (i.e. the
1805 pointers are compared). R_STATUS returns the status value,
1806 R_THIS_UPDATE and R_NEXT_UPDATE are the corresponding OCSP response
1807 values, R_REVOCATION_TIME is only set to the revocation time if the
1808 indicated status is revoked, R_REASON will be set to the reason
1809 given for a revocation. All the R_* arguments may be given as NULL
1810 if the value is not required. The function return 0 on success,
1811 GPG_ERR_NOT_FOUND if CERT was not used in the request or any other
1812 error code. Note that the caller should have checked the signature
1813 of the entire reponse to be good before using the stati retruned by
1816 ksba_ocsp_get_status (ksba_ocsp_t ocsp, ksba_cert_t cert,
1817 ksba_status_t *r_status,
1818 ksba_isotime_t r_this_update,
1819 ksba_isotime_t r_next_update,
1820 ksba_isotime_t r_revocation_time,
1821 ksba_crl_reason_t *r_reason)
1823 struct ocsp_reqitem_s *ri;
1825 if (!ocsp || !cert || !r_status)
1826 return gpg_error (GPG_ERR_INV_VALUE);
1827 if (!ocsp->requestlist)
1828 return gpg_error (GPG_ERR_MISSING_ACTION);
1830 /* Find the certificate. We don't care about the issuer certificate
1831 and stop at the first match. The implementation may be optimized
1832 by keeping track of the last certificate found to start with the
1833 next one then. Given that a usual request consists only of a few
1834 certificates, this does not make much sense in reality. */
1835 for (ri=ocsp->requestlist; ri; ri = ri->next)
1836 if (ri->cert == cert)
1839 return gpg_error (GPG_ERR_NOT_FOUND);
1841 *r_status = ri->status;
1843 _ksba_copy_time (r_this_update, ri->this_update);
1845 _ksba_copy_time (r_next_update, ri->next_update);
1846 if (r_revocation_time)
1847 _ksba_copy_time (r_revocation_time, ri->revocation_time);
1849 *r_reason = ri->revocation_reason;
1854 /* WARNING: The returned values ares only valid as long as no other
1855 ocsp function is called on the same context. */
1857 ksba_ocsp_get_extension (ksba_ocsp_t ocsp, ksba_cert_t cert, int idx,
1858 char const **r_oid, int *r_crit,
1859 unsigned char const **r_der, size_t *r_derlen)
1861 struct ocsp_extension_s *ex;
1864 return gpg_error (GPG_ERR_INV_VALUE);
1865 if (!ocsp->requestlist)
1866 return gpg_error (GPG_ERR_MISSING_ACTION);
1868 return gpg_error (GPG_ERR_INV_INDEX);
1872 /* Return extensions for the certificate (singleExtensions). */
1873 struct ocsp_reqitem_s *ri;
1875 for (ri=ocsp->requestlist; ri; ri = ri->next)
1876 if (ri->cert == cert)
1879 return gpg_error (GPG_ERR_NOT_FOUND);
1881 for (ex=ri->single_extensions; ex && idx; ex = ex->next, idx--)
1884 return gpg_error (GPG_ERR_EOF); /* No more extensions. */
1888 /* Return extensions for the response (responseExtensions). */
1889 for (ex=ocsp->response_extensions; ex && idx; ex = ex->next, idx--)
1892 return gpg_error (GPG_ERR_EOF); /* No more extensions. */
1900 *r_der = ex->data + ex->off;
1902 *r_derlen = ex->len;