2 /* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
6 This file was transfered to Richard Levitte from CertCo by Kathy
7 Weinhold in mid-spring 2000 to be included in OpenSSL or released
10 /* ====================================================================
11 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in
22 * the documentation and/or other materials provided with the
25 * 3. All advertising materials mentioning features or use of this
26 * software must display the following acknowledgment:
27 * "This product includes software developed by the OpenSSL Project
28 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
30 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
31 * endorse or promote products derived from this software without
32 * prior written permission. For written permission, please contact
33 * openssl-core@openssl.org.
35 * 5. Products derived from this software may not be called "OpenSSL"
36 * nor may "OpenSSL" appear in their names without prior written
37 * permission of the OpenSSL Project.
39 * 6. Redistributions of any form whatsoever must retain the following
41 * "This product includes software developed by the OpenSSL Project
42 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
44 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
45 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
47 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
48 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
53 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
55 * OF THE POSSIBILITY OF SUCH DAMAGE.
56 * ====================================================================
58 * This product includes cryptographic software written by Eric Young
59 * (eay@cryptsoft.com). This product includes software written by Tim
60 * Hudson (tjh@cryptsoft.com).
66 #include <openssl/objects.h>
67 #include <openssl/asn1_mac.h>
68 #include <openssl/x509.h>
69 #include <openssl/pem.h>
70 #include <openssl/x509v3.h>
71 #include <openssl/safestack.h>
72 #include <openssl/ocsp.h>
74 static STACK_OF(X509_EXTENSION
) *ext_dup(STACK_OF(X509_EXTENSION
) *fr
)
77 STACK_OF(X509_EXTENSION
) *to
= NULL
;
79 if (!(to
= sk_X509_EXTENSION_dup(fr
)))
81 for (i
= 0; i
< sk_X509_EXTENSION_num(fr
); i
++)
83 sk_X509_EXTENSION_set(to
, i
,
84 X509_EXTENSION_dup(sk_X509_EXTENSION_value(fr
, i
)));
85 if (! sk_X509_EXTENSION_value(to
, i
))
90 if (to
) sk_X509_EXTENSION_pop_free(to
, X509_EXTENSION_free
);
94 OCSP_CERTID
*OCSP_cert_id_new(const EVP_MD
*dgst
,
95 X509_NAME
*issuerName
,
96 ASN1_BIT_STRING
* issuerKey
,
97 ASN1_INTEGER
*serialNumber
)
102 OCSP_CERTID
*cid
= NULL
;
103 unsigned char md
[EVP_MAX_MD_SIZE
];
106 if (!(cid
= OCSP_CERTID_new())) goto err
;
108 alg
= cid
->hashAlgorithm
;
109 if (alg
->algorithm
!= NULL
) ASN1_OBJECT_free(alg
->algorithm
);
110 if ((nid
= EVP_MD_type(dgst
)) == NID_undef
)
112 OCSPerr(OCSP_F_CERT_ID_NEW
,OCSP_R_UNKNOWN_NID
);
115 if (!(alg
->algorithm
=OBJ_nid2obj(nid
))) goto err
;
116 if ((alg
->parameter
=ASN1_TYPE_new()) == NULL
) goto err
;
117 alg
->parameter
->type
=V_ASN1_NULL
;
119 if (!X509_NAME_digest(issuerName
, dgst
, md
, &i
)) goto digerr
;
120 if (!(ASN1_OCTET_STRING_set(cid
->issuerNameHash
, md
, i
))) goto err
;
122 /* Calculate the issuerKey hash, excluding tag and length */
123 EVP_DigestInit(&ctx
,dgst
);
124 EVP_DigestUpdate(&ctx
,issuerKey
->data
, issuerKey
->length
);
125 EVP_DigestFinal(&ctx
,md
,&i
);
127 if (!(ASN1_OCTET_STRING_set(cid
->issuerKeyHash
, md
, i
))) goto err
;
129 if (cid
->serialNumber
!= NULL
) ASN1_INTEGER_free(cid
->serialNumber
);
130 if (!(cid
->serialNumber
= ASN1_INTEGER_dup(serialNumber
))) goto err
;
133 OCSPerr(OCSP_F_CERT_ID_NEW
,OCSP_R_DIGEST_ERR
);
135 if (cid
) OCSP_CERTID_free(cid
);
139 OCSP_CERTSTATUS
*OCSP_cert_status_new(int status
, int reason
, char *tim
)
141 OCSP_REVOKEDINFO
*ri
;
142 OCSP_CERTSTATUS
*cs
= NULL
;
144 if (!(cs
= OCSP_CERTSTATUS_new())) goto err
;
145 if ((cs
->tag
= status
) == V_OCSP_CERTSTATUS_REVOKED
)
149 OCSPerr(OCSP_F_CERT_STATUS_NEW
,OCSP_R_REVOKED_NO_TIME
);
152 if (!(cs
->revoked
= ri
= OCSP_REVOKEDINFO_new())) goto err
;
153 if (!ASN1_GENERALIZEDTIME_set_string(ri
->revocationTime
,tim
))
155 if (reason
!= OCSP_REVOKED_STATUS_NOSTATUS
)
157 if (!(ri
->revocationReason
= ASN1_ENUMERATED_new()))
159 if (!(ASN1_ENUMERATED_set(ri
->revocationReason
,
166 if (cs
) OCSP_CERTSTATUS_free(cs
);
170 OCSP_REQUEST
*OCSP_request_new(X509_NAME
* name
,
171 STACK_OF(X509_EXTENSION
) *extensions
)
173 OCSP_REQUEST
*req
= NULL
;
175 if ((req
= OCSP_REQUEST_new()) == NULL
) goto err
;
176 if (name
) /* optional */
178 if (!(req
->tbsRequest
->requestorName
=GENERAL_NAME_new()))
180 req
->tbsRequest
->requestorName
->type
= GEN_DIRNAME
;
181 req
->tbsRequest
->requestorName
->d
.dirn
= X509_NAME_dup(name
);
183 if (!(req
->tbsRequest
->requestList
= sk_OCSP_ONEREQ_new(NULL
))) goto err
;
185 (!(req
->tbsRequest
->requestExtensions
= ext_dup(extensions
))))
189 if (req
) OCSP_REQUEST_free(req
);
193 int OCSP_request_add(OCSP_REQUEST
*req
,
195 STACK_OF(X509_EXTENSION
) *extensions
)
197 OCSP_ONEREQ
*one
= NULL
;
199 if (!(one
= OCSP_ONEREQ_new())) goto err
;
200 if (one
->reqCert
) OCSP_CERTID_free(one
->reqCert
);
201 if (!(one
->reqCert
= OCSP_CERTID_dup(cid
))) goto err
;
202 if (extensions
&&(!(one
->singleRequestExtensions
=ext_dup(extensions
))))
204 if (!sk_OCSP_ONEREQ_push(req
->tbsRequest
->requestList
, one
)) goto err
;
207 if (one
) OCSP_ONEREQ_free(one
);
211 int OCSP_request_sign(OCSP_REQUEST
*req
,
214 STACK_OF(X509
) *certs
)
219 if (!(req
->optionalSignature
= sig
= OCSP_SIGNATURE_new())) goto err
;
220 if (!OCSP_REQUEST_sign(req
, key
, dgst
)) goto err
;
223 if (!(sig
->certs
= sk_X509_dup(certs
))) goto err
;
224 for (i
= 0; i
< sk_X509_num(sig
->certs
); i
++)
226 sk_X509_set(sig
->certs
, i
,
227 X509_dup(sk_X509_value(certs
,i
)));
228 if (! sk_X509_value(sig
->certs
, i
))
234 if (req
->optionalSignature
)
236 OCSP_SIGNATURE_free(req
->optionalSignature
);
237 req
->optionalSignature
= NULL
;
242 OCSP_BASICRESP
*OCSP_basic_response_new(int tag
,
244 STACK_OF(X509_EXTENSION
) *extensions
)
249 OCSP_BASICRESP
*rsp
= NULL
;
250 unsigned char md
[SHA_DIGEST_LENGTH
];
252 if (!(rsp
= OCSP_BASICRESP_new())) goto err
;
253 rid
= rsp
->tbsResponseData
->responderId
;
254 switch (rid
->tag
= tag
)
256 case V_OCSP_RESPID_NAME
:
257 /* cert is user cert */
258 if (!(rid
->value
.byName
=
259 X509_NAME_dup(X509_get_subject_name(cert
))))
262 case V_OCSP_RESPID_KEY
:
263 /* cert is issuer cert */
264 /* SHA-1 hash of responder's public key
265 * (excluding the tag and length fields)
267 bs
= cert
->cert_info
->key
->public_key
;
268 SHA1(ASN1_STRING_data((ASN1_STRING
*)bs
),
269 ASN1_STRING_length((ASN1_STRING
*)bs
), md
);
270 if (!(rid
->value
.byKey
= ASN1_OCTET_STRING_new()))
272 if (!(ASN1_OCTET_STRING_set(rid
->value
.byKey
,
277 OCSPerr(OCSP_F_BASIC_RESPONSE_NEW
,OCSP_R_BAD_TAG
);
282 if (!(ASN1_GENERALIZEDTIME_set(rsp
->tbsResponseData
->producedAt
, t
)))
284 if (!(rsp
->tbsResponseData
->responses
= sk_OCSP_SINGLERESP_new(NULL
))) goto err
;
285 if (extensions
&& (!(rsp
->tbsResponseData
->responseExtensions
=
286 ext_dup(extensions
))))
290 if (rsp
) OCSP_BASICRESP_free(rsp
);
294 int OCSP_basic_response_add(OCSP_BASICRESP
*rsp
,
296 OCSP_CERTSTATUS
*cst
,
299 STACK_OF(X509_EXTENSION
) *extensions
)
301 OCSP_SINGLERESP
*single
= NULL
;
303 if (!(single
= OCSP_SINGLERESP_new())) goto err
;
304 if (single
->certId
) OCSP_CERTID_free(single
->certId
);
305 if (!(single
->certId
= OCSP_CERTID_dup(cid
))) goto err
;
306 if (single
->certStatus
) OCSP_CERTSTATUS_free(single
->certStatus
);
307 if (!(single
->certStatus
= OCSP_CERTSTATUS_dup(cst
))) goto err
;
308 if (!ASN1_GENERALIZEDTIME_set_string(single
->thisUpdate
,this))goto err
;
311 if (!(single
->nextUpdate
= ASN1_GENERALIZEDTIME_new()))
313 if (!ASN1_GENERALIZEDTIME_set_string(single
->nextUpdate
,next
))
316 if (extensions
&& (!(single
->singleExtensions
= ext_dup(extensions
))))
318 if (!sk_OCSP_SINGLERESP_push(rsp
->tbsResponseData
->responses
,single
)) goto err
;
321 if (single
) OCSP_SINGLERESP_free(single
);
325 int OCSP_basic_response_sign(OCSP_BASICRESP
*brsp
,
328 STACK_OF(X509
) *certs
)
332 /* Right now, I think that not doing double hashing is the right
333 thing. -- Richard Levitte */
334 if (!OCSP_BASICRESP_sign(brsp
, key
, dgst
, 0)) goto err
;
337 if (!(brsp
->certs
= sk_X509_dup(certs
))) goto err
;
338 for (i
= 0; i
< sk_X509_num(brsp
->certs
); i
++)
340 sk_X509_set(brsp
->certs
, i
,
341 X509_dup(sk_X509_value(certs
, i
)));
342 if (! sk_X509_value(brsp
->certs
, i
))
351 OCSP_RESPONSE
*OCSP_response_new(int status
,
356 OCSP_RESPONSE
*rsp
= NULL
;
358 if (!(rsp
= OCSP_RESPONSE_new())) goto err
;
359 if (!(ASN1_ENUMERATED_set(rsp
->responseStatus
, status
))) goto err
;
360 if (!(rsp
->responseBytes
= OCSP_RESPBYTES_new())) goto err
;
361 if (rsp
->responseBytes
->responseType
) ASN1_OBJECT_free(rsp
->responseBytes
->responseType
);
362 if (!(rsp
->responseBytes
->responseType
= OBJ_nid2obj(nid
))) goto err
;
363 if (!ASN1_STRING_encode((ASN1_STRING
*)rsp
->responseBytes
->response
,
364 i2d
, data
, NULL
)) goto err
;
367 if (rsp
) OCSP_RESPONSE_free(rsp
);
371 char* ocspResponseStatus2string(long s
)
373 static struct { long t
; char *m
; } ts
[6]= {
374 { OCSP_RESPONSE_STATUS_SUCCESSFULL
, "successful" },
375 { OCSP_RESPONSE_STATUS_MALFORMEDREQUEST
, "malformedrequest" },
376 { OCSP_RESPONSE_STATUS_INTERNALERROR
, "internalerror" },
377 { OCSP_RESPONSE_STATUS_TRYLATER
, "trylater" },
378 { OCSP_RESPONSE_STATUS_SIGREQUIRED
, "sigrequired" },
379 { OCSP_RESPONSE_STATUS_UNAUTHORIZED
, "unauthorized" } }, *p
;
380 for (p
=ts
; p
< &ts
[sizeof ts
/sizeof ts
[0]]; p
++)
386 char* ocspCertStatus2string(long s
)
388 static struct { long t
; char *m
; } ts
[3]= {
389 { V_OCSP_CERTSTATUS_GOOD
, "good" },
390 { V_OCSP_CERTSTATUS_REVOKED
, "revoked" },
391 { V_OCSP_CERTSTATUS_UNKNOWN
, "unknown" } }, *p
;
392 for (p
=ts
; p
< &ts
[sizeof ts
/sizeof ts
[0]]; p
++)
398 char * cRLReason2string(long s
)
400 static struct { long t
; char *m
; } ts
[8]= {
401 { OCSP_REVOKED_STATUS_UNSPECIFIED
, "unspecified" },
402 { OCSP_REVOKED_STATUS_KEYCOMPROMISE
, "keyCompromise" },
403 { OCSP_REVOKED_STATUS_CACOMPROMISE
, "cACompromise" },
404 { OCSP_REVOKED_STATUS_AFFILIATIONCHANGED
, "affiliationChanged" },
405 { OCSP_REVOKED_STATUS_SUPERSEDED
, "superseded" },
406 { OCSP_REVOKED_STATUS_CESSATIONOFOPERATION
, "cessationOfOperation" },
407 { OCSP_REVOKED_STATUS_CERTIFICATEHOLD
, "certificateHold" },
408 { OCSP_REVOKED_STATUS_REMOVEFROMCRL
, "removeFromCRL" } }, *p
;
409 for (p
=ts
; p
< &ts
[sizeof ts
/sizeof ts
[0]]; p
++)
415 static int i2a_GENERAL_NAME(bp
,n
)
422 if (n
== NULL
) return(0);
428 X509_NAME_print(bp
,n
->d
.dirn
,16);
435 p
=(char *)n
->d
.ip
->data
;
436 for (j
=n
->d
.ip
->length
;j
>0;j
--)
438 if ((*p
>= ' ') && (*p
<= '~'))
439 BIO_printf(bp
,"%c",*p
);
441 BIO_printf(bp
,"\\0x%02X",*p
);
442 else if ((unsigned char)*p
== 0xf7)
444 else BIO_printf(bp
,"^%c",*p
+'@');
450 i2a_ASN1_OBJECT(bp
, n
->d
.rid
);
453 /* XXX these are legit, need to support at some time... */
465 int OCSP_REQUEST_print(bp
, o
)
472 OCSP_CERTID
* cid
= NULL
;
473 OCSP_ONEREQ
*one
= NULL
;
474 OCSP_REQINFO
*inf
= o
->tbsRequest
;
475 OCSP_SIGNATURE
*sig
= o
->optionalSignature
;
477 if (BIO_write(bp
,"OCSP Request Data:\n",19) <= 0) goto err
;
478 l
=ASN1_INTEGER_get(inf
->version
);
479 if (BIO_printf(bp
,"%4sVersion: %lu (0x%lx)","",l
+1,l
) <= 0) goto err
;
480 if (inf
->requestorName
!= NULL
)
482 if (BIO_write(bp
,"\n Requestor Name: ",21) <= 0)
484 i2a_GENERAL_NAME(bp
, inf
->requestorName
);
486 if (BIO_write(bp
,"\n Requestor List:\n",21) <= 0) goto err
;
487 for (i
= 0; i
< sk_OCSP_ONEREQ_num(inf
->requestList
); i
++)
489 if (! sk_OCSP_ONEREQ_value(inf
->requestList
, i
)) continue;
490 one
= sk_OCSP_ONEREQ_value(inf
->requestList
, i
);
492 j
=OBJ_obj2nid(cid
->hashAlgorithm
->algorithm
);
493 if (BIO_printf(bp
,"%8sHash Algorithm: %s","",
494 (j
== NID_undef
)?"UNKNOWN":OBJ_nid2ln(j
)) <= 0)
496 if (BIO_write(bp
,"\n Issuer Name Hash: ",27) <= 0)
498 i2a_ASN1_STRING(bp
, cid
->issuerNameHash
, V_ASN1_OCTET_STRING
);
499 if (BIO_write(bp
,"\n Issuer Key Hash: ",26) <= 0)
501 i2a_ASN1_STRING(bp
, cid
->issuerKeyHash
, V_ASN1_OCTET_STRING
);
502 if (BIO_write(bp
,"\n Serial Number: ",24) <= 0)
504 if (!i2a_ASN1_INTEGER(bp
, cid
->serialNumber
))
506 if (!BIO_write(bp
,"\n",1)) goto err
;
507 if (!OCSP_extensions_print(bp
, one
->singleRequestExtensions
,
508 "Request Single Extensions"))
511 if (!OCSP_extensions_print(bp
, inf
->requestExtensions
,
512 "Request Extensions"))
516 i
=OBJ_obj2nid(sig
->signatureAlgorithm
->algorithm
);
517 if (BIO_printf(bp
,"OCSP Request Signature Algorithm: %s",
518 (i
== NID_undef
)?"UNKNOWN":OBJ_nid2ln(i
)) <= 0)
520 n
=sig
->signature
->length
;
521 s
=(char *)sig
->signature
->data
;
525 if (BIO_write(bp
,"\n ",9) <= 0) goto err
;
526 if (BIO_printf(bp
,"%02x%s",(unsigned char)s
[i
],
527 ((i
+1) == n
)?"":":") <= 0) goto err
;
529 if (BIO_write(bp
,"\n",1) != 1) goto err
;
532 for (i
=0; i
<sk_X509_num(sig
->certs
); i
++)
533 if (sk_X509_value(sig
->certs
,i
) != NULL
)
535 sk_X509_value(sig
->certs
,i
));
543 int OCSP_RESPONSE_print(BIO
*bp
, OCSP_RESPONSE
* o
)
549 OCSP_CERTID
*cid
= NULL
;
550 OCSP_BASICRESP
*br
= NULL
;
551 OCSP_RESPDATA
*rd
= NULL
;
552 OCSP_CERTSTATUS
*cst
= NULL
;
553 OCSP_REVOKEDINFO
*rev
= NULL
;
554 OCSP_SINGLERESP
*single
= NULL
;
555 OCSP_RESPBYTES
*rb
= o
->responseBytes
;
557 l
=ASN1_ENUMERATED_get(o
->responseStatus
);
558 if (BIO_printf(bp
,"OCSP Response Status: %s (0x%x)\n",
559 ocspResponseStatus2string(l
), l
) <= 0) goto err
;
560 if (rb
== NULL
) return 1;
561 i
=OBJ_obj2nid(rb
->responseType
);
562 if (BIO_printf(bp
,"OCSP Response Bytes Response Type: %s",
563 (i
== NID_undef
)?"UNKNOWN":OBJ_nid2sn(i
)) <= 0)
565 if (i
!= NID_id_pkix_OCSP_basic
)
567 BIO_printf(bp
," (unknown response type)\n");
570 p
= ASN1_STRING_data(rb
->response
);
571 i
= ASN1_STRING_length(rb
->response
);
572 if (!(d2i_OCSP_BASICRESP(&br
, &p
, i
))) goto err
;
573 rd
= br
->tbsResponseData
;
574 l
=ASN1_INTEGER_get(rd
->version
);
575 if (BIO_printf(bp
,"\nBasic Response Data Version: %lu (0x%lx)\n",
576 l
+1,l
) <= 0) goto err
;
577 if (BIO_printf(bp
,"Basic Response Data Responder Id: ") <= 0) goto err
;
578 i2a_OCSP_RESPID(bp
, rd
->responderId
);
579 if (BIO_printf(bp
,"\nBasic Response Data Produced At: ")<=0) goto err
;
580 if (!ASN1_GENERALIZEDTIME_print(bp
, rd
->producedAt
)) goto err
;
581 if (BIO_printf(bp
,"\nBasic Response Data Responses:\n") <= 0) goto err
;
582 for (i
= 0; i
< sk_OCSP_SINGLERESP_num(rd
->responses
); i
++)
584 if (! sk_OCSP_SINGLERESP_value(rd
->responses
, i
)) continue;
585 single
= sk_OCSP_SINGLERESP_value(rd
->responses
, i
);
586 cid
= single
->certId
;
587 j
=OBJ_obj2nid(cid
->hashAlgorithm
->algorithm
);
588 if (BIO_printf(bp
," Cert Id:") <= 0) goto err
;
589 if (BIO_printf(bp
,"\n%8sHash Algorithm: %s","",
590 (j
== NID_undef
)?"UNKNOWN":OBJ_nid2ln(j
)) <= 0)
592 if (BIO_write(bp
,"\n Issuer Name Hash: ",27) <= 0)
594 i2a_ASN1_STRING(bp
, cid
->issuerNameHash
, V_ASN1_OCTET_STRING
);
595 if (BIO_write(bp
,"\n Issuer Key Hash: ",26) <= 0)
597 i2a_ASN1_STRING(bp
, cid
->issuerKeyHash
, V_ASN1_OCTET_STRING
);
598 if (BIO_write(bp
,"\n Serial Number: ",24) <= 0)
600 if (!i2a_ASN1_INTEGER(bp
, cid
->serialNumber
))
602 cst
= single
->certStatus
;
603 if (BIO_printf(bp
,"\n Cert Status: %s (0x%x)",
604 ocspCertStatus2string(cst
->tag
), cst
->tag
) <= 0)
606 if (cst
->tag
== V_OCSP_CERTSTATUS_REVOKED
)
609 if (BIO_printf(bp
, "\n Revocation Time: ") <= 0)
611 if (!ASN1_GENERALIZEDTIME_print(bp
,
612 rev
->revocationTime
))
614 if (rev
->revocationReason
)
616 l
=ASN1_ENUMERATED_get(rev
->revocationReason
);
618 "\n Revocation Reason: %s (0x%x)",
619 cRLReason2string(l
), l
) <= 0)
623 if (BIO_printf(bp
,"\n This Update: ") <= 0) goto err
;
624 if (!ASN1_GENERALIZEDTIME_print(bp
, single
->thisUpdate
))
626 if (single
->nextUpdate
)
628 if (BIO_printf(bp
,"\n Next Update: ") <= 0)goto err
;
629 if (!ASN1_GENERALIZEDTIME_print(bp
,single
->nextUpdate
))
632 if (!BIO_write(bp
,"\n",1)) goto err
;
633 if (!OCSP_extensions_print(bp
, single
->singleExtensions
,
634 "Basic Response Single Extensions"))
637 if (!OCSP_extensions_print(bp
, rd
->responseExtensions
,
638 "Basic Response Extensions")) goto err
;
639 i
=OBJ_obj2nid(br
->signatureAlgorithm
->algorithm
);
640 if (BIO_printf(bp
,"Basic Response Signature Algorithm: %s",
641 (i
== NID_undef
)?"UNKNOWN":OBJ_nid2ln(i
)) <= 0)
643 n
=br
->signature
->length
;
644 s
=(char *)br
->signature
->data
;
648 if (BIO_write(bp
,"\n ",9) <= 0) goto err
;
649 if (BIO_printf(bp
,"%02x%s",(unsigned char)s
[i
],
650 ((i
+1) == n
)?"":":") <= 0) goto err
;
652 if (BIO_write(bp
,"\n",1) != 1) goto err
;
655 for (i
=0; i
<sk_X509_num(br
->certs
); i
++)
656 if (sk_X509_value(br
->certs
,i
) != NULL
) {
657 X509_print(bp
, sk_X509_value(br
->certs
,i
));
658 PEM_write_bio_X509(bp
,sk_X509_value(br
->certs
,i
));
666 int OCSP_CRLID_print(BIO
*bp
, OCSP_CRLID
*a
, int ind
)
670 if (!BIO_printf(bp
, "%*scrlUrl: ", ind
, "")) goto err
;
671 if (!ASN1_STRING_print(bp
, (ASN1_STRING
*)a
->crlUrl
)) goto err
;
672 if (!BIO_write(bp
, "\n", 1)) goto err
;
676 if (!BIO_printf(bp
, "%*scrlNum: ", ind
, "")) goto err
;
677 if (!i2a_ASN1_INTEGER(bp
, a
->crlNum
)) goto err
;
678 if (!BIO_write(bp
, "\n", 1)) goto err
;
682 if (!BIO_printf(bp
, "%*scrlTime: ", ind
, "")) goto err
;
683 if (!ASN1_GENERALIZEDTIME_print(bp
, a
->crlTime
)) goto err
;
684 if (!BIO_write(bp
, "\n", 1)) goto err
;
691 int OCSP_SERVICELOC_print(BIO
*bp
, OCSP_SERVICELOC
* a
, int ind
)
694 ACCESS_DESCRIPTION
*ad
;
696 if (BIO_printf(bp
, "%*sissuer: ", ind
, "") <= 0) goto err
;
697 if (X509_NAME_print(bp
, a
->issuer
, 16) <= 0) goto err
;
698 if (BIO_printf(bp
, "\n", 1) <= 0) goto err
;
700 /* Service locator is optional */
701 if (a
->locator
!= NULL
) {
702 if (BIO_printf(bp
, "%*slocator:\n", ind
, "") <= 0) goto err
;
703 for (i
= 0; i
< sk_ACCESS_DESCRIPTION_num(a
->locator
); i
++)
705 ad
= sk_ACCESS_DESCRIPTION_value(a
->locator
,i
);
706 if (BIO_printf(bp
, "%*smethod: ", (2*ind
), "") <= 0)
708 j
=OBJ_obj2nid(ad
->method
);
709 if (BIO_printf(bp
,"%s", (j
== NID_undef
)?"UNKNOWN":
712 if (BIO_printf(bp
, "\n%*sname: ", (2*ind
), "") <= 0)
714 if (i2a_GENERAL_NAME(bp
, ad
->location
) <= 0) goto err
;
715 if (BIO_write(bp
, "\n", 1) <= 0) goto err
;
723 /* XXX assumes certs in signature are sorted root to leaf XXX */
724 int OCSP_request_verify(OCSP_REQUEST
*req
, EVP_PKEY
*pkey
)
728 if (!req
->optionalSignature
) return 0;
731 if (!(sk
= req
->optionalSignature
->certs
)) return 0;
732 if (!(pkey
=X509_get_pubkey(sk_X509_value(sk
, sk_X509_num(sk
)-1))))
734 OCSPerr(OCSP_F_REQUEST_VERIFY
,OCSP_R_NO_PUBLIC_KEY
);
738 return OCSP_REQUEST_verify(req
, pkey
);
741 int OCSP_response_verify(OCSP_RESPONSE
*rsp
, EVP_PKEY
*pkey
)
746 OCSP_BASICRESP
*br
= NULL
;
748 if ((rb
= rsp
->responseBytes
) == NULL
)
750 OCSPerr(OCSP_F_RESPONSE_VERIFY
,OCSP_R_NO_RESPONSE_DATA
);
753 if (OBJ_obj2nid(rb
->responseType
) != NID_id_pkix_OCSP_basic
)
755 OCSPerr(OCSP_F_RESPONSE_VERIFY
,OCSP_R_BAD_TAG
);
758 p
= ASN1_STRING_data(rb
->response
);
759 i
= ASN1_STRING_length(rb
->response
);
760 if (!(d2i_OCSP_BASICRESP(&br
, &p
, i
))) return 0;
761 r
= OCSP_basic_response_verify(br
, pkey
);
762 OCSP_BASICRESP_free(br
);
766 int OCSP_basic_response_verify(OCSP_BASICRESP
*rsp
, EVP_PKEY
*pkey
)
773 OCSPerr(OCSP_F_BASIC_RESPONSE_VERIFY
,OCSP_R_NO_SIGNATURE
);
778 if (!(sk
= rsp
->certs
))
780 OCSPerr(OCSP_F_BASIC_RESPONSE_VERIFY
,OCSP_R_NO_CERTIFICATE
);
783 if (!(pkey
=X509_get_pubkey(sk_X509_value(sk
, sk_X509_num(sk
)-1))))
785 OCSPerr(OCSP_F_BASIC_RESPONSE_VERIFY
,OCSP_R_NO_PUBLIC_KEY
);
789 ret
= OCSP_BASICRESP_verify(rsp
, pkey
, 0);