OLD | NEW |
| (Empty) |
1 /* ocsp_prn.c */ | |
2 /* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL | |
3 * project. */ | |
4 | |
5 /* History: | |
6 This file was originally part of ocsp.c and was transfered to Richard | |
7 Levitte from CertCo by Kathy Weinhold in mid-spring 2000 to be included | |
8 in OpenSSL or released as a patch kit. */ | |
9 | |
10 /* ==================================================================== | |
11 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. | |
12 * | |
13 * Redistribution and use in source and binary forms, with or without | |
14 * modification, are permitted provided that the following conditions | |
15 * are met: | |
16 * | |
17 * 1. Redistributions of source code must retain the above copyright | |
18 * notice, this list of conditions and the following disclaimer. | |
19 * | |
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 | |
23 * distribution. | |
24 * | |
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/)" | |
29 * | |
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. | |
34 * | |
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. | |
38 * | |
39 * 6. Redistributions of any form whatsoever must retain the following | |
40 * acknowledgment: | |
41 * "This product includes software developed by the OpenSSL Project | |
42 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | |
43 * | |
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 * ==================================================================== | |
57 * | |
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). | |
61 * | |
62 */ | |
63 | |
64 #include <openssl/bio.h> | |
65 #include <openssl/err.h> | |
66 #include <openssl/ocsp.h> | |
67 #include <openssl/pem.h> | |
68 | |
69 static int ocsp_certid_print(BIO *bp, OCSP_CERTID* a, int indent) | |
70 { | |
71 BIO_printf(bp, "%*sCertificate ID:\n", indent, ""); | |
72 indent += 2; | |
73 BIO_printf(bp, "%*sHash Algorithm: ", indent, ""); | |
74 i2a_ASN1_OBJECT(bp, a->hashAlgorithm->algorithm); | |
75 BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, ""); | |
76 i2a_ASN1_STRING(bp, a->issuerNameHash, V_ASN1_OCTET_STRING); | |
77 BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, ""); | |
78 i2a_ASN1_STRING(bp, a->issuerKeyHash, V_ASN1_OCTET_STRING); | |
79 BIO_printf(bp, "\n%*sSerial Number: ", indent, ""); | |
80 i2a_ASN1_INTEGER(bp, a->serialNumber); | |
81 BIO_printf(bp, "\n"); | |
82 return 1; | |
83 } | |
84 | |
85 typedef struct | |
86 { | |
87 long t; | |
88 const char *m; | |
89 } OCSP_TBLSTR; | |
90 | |
91 static const char *table2string(long s, const OCSP_TBLSTR *ts, int len) | |
92 { | |
93 const OCSP_TBLSTR *p; | |
94 for (p=ts; p < ts + len; p++) | |
95 if (p->t == s) | |
96 return p->m; | |
97 return "(UNKNOWN)"; | |
98 } | |
99 | |
100 const char *OCSP_response_status_str(long s) | |
101 { | |
102 static const OCSP_TBLSTR rstat_tbl[] = { | |
103 { OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful" }, | |
104 { OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest" }, | |
105 { OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror" }, | |
106 { OCSP_RESPONSE_STATUS_TRYLATER, "trylater" }, | |
107 { OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired" }, | |
108 { OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized" } }; | |
109 return table2string(s, rstat_tbl, 6); | |
110 } | |
111 | |
112 const char *OCSP_cert_status_str(long s) | |
113 { | |
114 static const OCSP_TBLSTR cstat_tbl[] = { | |
115 { V_OCSP_CERTSTATUS_GOOD, "good" }, | |
116 { V_OCSP_CERTSTATUS_REVOKED, "revoked" }, | |
117 { V_OCSP_CERTSTATUS_UNKNOWN, "unknown" } }; | |
118 return table2string(s, cstat_tbl, 3); | |
119 } | |
120 | |
121 const char *OCSP_crl_reason_str(long s) | |
122 { | |
123 static const OCSP_TBLSTR reason_tbl[] = { | |
124 { OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified" }, | |
125 { OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise" }, | |
126 { OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise" }, | |
127 { OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged" }, | |
128 { OCSP_REVOKED_STATUS_SUPERSEDED, "superseded" }, | |
129 { OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation" }, | |
130 { OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold" }, | |
131 { OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL" } }; | |
132 return table2string(s, reason_tbl, 8); | |
133 } | |
134 | |
135 int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* o, unsigned long flags) | |
136 { | |
137 int i; | |
138 long l; | |
139 OCSP_CERTID* cid = NULL; | |
140 OCSP_ONEREQ *one = NULL; | |
141 OCSP_REQINFO *inf = o->tbsRequest; | |
142 OCSP_SIGNATURE *sig = o->optionalSignature; | |
143 | |
144 if (BIO_write(bp,"OCSP Request Data:\n",19) <= 0) goto err; | |
145 l=ASN1_INTEGER_get(inf->version); | |
146 if (BIO_printf(bp," Version: %lu (0x%lx)",l+1,l) <= 0) goto err; | |
147 if (inf->requestorName != NULL) | |
148 { | |
149 if (BIO_write(bp,"\n Requestor Name: ",21) <= 0) | |
150 goto err; | |
151 GENERAL_NAME_print(bp, inf->requestorName); | |
152 } | |
153 if (BIO_write(bp,"\n Requestor List:\n",21) <= 0) goto err; | |
154 for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++) | |
155 { | |
156 one = sk_OCSP_ONEREQ_value(inf->requestList, i); | |
157 cid = one->reqCert; | |
158 ocsp_certid_print(bp, cid, 8); | |
159 if (!X509V3_extensions_print(bp, | |
160 "Request Single Extensions", | |
161 one->singleRequestExtensions, flags, 8)) | |
162 goto err; | |
163 } | |
164 if (!X509V3_extensions_print(bp, "Request Extensions", | |
165 inf->requestExtensions, flags, 4)) | |
166 goto err; | |
167 if (sig) | |
168 { | |
169 X509_signature_print(bp, sig->signatureAlgorithm, sig->signature
); | |
170 for (i=0; i<sk_X509_num(sig->certs); i++) | |
171 { | |
172 X509_print(bp, sk_X509_value(sig->certs,i)); | |
173 PEM_write_bio_X509(bp,sk_X509_value(sig->certs,i)); | |
174 } | |
175 } | |
176 return 1; | |
177 err: | |
178 return 0; | |
179 } | |
180 | |
181 int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags) | |
182 { | |
183 int i, ret = 0; | |
184 long l; | |
185 OCSP_CERTID *cid = NULL; | |
186 OCSP_BASICRESP *br = NULL; | |
187 OCSP_RESPID *rid = NULL; | |
188 OCSP_RESPDATA *rd = NULL; | |
189 OCSP_CERTSTATUS *cst = NULL; | |
190 OCSP_REVOKEDINFO *rev = NULL; | |
191 OCSP_SINGLERESP *single = NULL; | |
192 OCSP_RESPBYTES *rb = o->responseBytes; | |
193 | |
194 if (BIO_puts(bp,"OCSP Response Data:\n") <= 0) goto err; | |
195 l=ASN1_ENUMERATED_get(o->responseStatus); | |
196 if (BIO_printf(bp," OCSP Response Status: %s (0x%lx)\n", | |
197 OCSP_response_status_str(l), l) <= 0) goto err; | |
198 if (rb == NULL) return 1; | |
199 if (BIO_puts(bp," Response Type: ") <= 0) | |
200 goto err; | |
201 if(i2a_ASN1_OBJECT(bp, rb->responseType) <= 0) | |
202 goto err; | |
203 if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) | |
204 { | |
205 BIO_puts(bp," (unknown response type)\n"); | |
206 return 1; | |
207 } | |
208 | |
209 i = ASN1_STRING_length(rb->response); | |
210 if (!(br = OCSP_response_get1_basic(o))) goto err; | |
211 rd = br->tbsResponseData; | |
212 l=ASN1_INTEGER_get(rd->version); | |
213 if (BIO_printf(bp,"\n Version: %lu (0x%lx)\n", | |
214 l+1,l) <= 0) goto err; | |
215 if (BIO_puts(bp," Responder Id: ") <= 0) goto err; | |
216 | |
217 rid = rd->responderId; | |
218 switch (rid->type) | |
219 { | |
220 case V_OCSP_RESPID_NAME: | |
221 X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONE
LINE); | |
222 break; | |
223 case V_OCSP_RESPID_KEY: | |
224 i2a_ASN1_STRING(bp, rid->value.byKey, V_ASN1_OCTET_STRIN
G); | |
225 break; | |
226 } | |
227 | |
228 if (BIO_printf(bp,"\n Produced At: ")<=0) goto err; | |
229 if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt)) goto err; | |
230 if (BIO_printf(bp,"\n Responses:\n") <= 0) goto err; | |
231 for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) | |
232 { | |
233 if (! sk_OCSP_SINGLERESP_value(rd->responses, i)) continue; | |
234 single = sk_OCSP_SINGLERESP_value(rd->responses, i); | |
235 cid = single->certId; | |
236 if(ocsp_certid_print(bp, cid, 4) <= 0) goto err; | |
237 cst = single->certStatus; | |
238 if (BIO_printf(bp," Cert Status: %s", | |
239 OCSP_cert_status_str(cst->type)) <= 0) | |
240 goto err; | |
241 if (cst->type == V_OCSP_CERTSTATUS_REVOKED) | |
242 { | |
243 rev = cst->value.revoked; | |
244 if (BIO_printf(bp, "\n Revocation Time: ") <= 0) | |
245 goto err; | |
246 if (!ASN1_GENERALIZEDTIME_print(bp, | |
247 rev->revocationTime)) | |
248 goto err; | |
249 if (rev->revocationReason) | |
250 { | |
251 l=ASN1_ENUMERATED_get(rev->revocationReason); | |
252 if (BIO_printf(bp, | |
253 "\n Revocation Reason: %s (0x%lx)", | |
254 OCSP_crl_reason_str(l), l) <= 0) | |
255 goto err; | |
256 } | |
257 } | |
258 if (BIO_printf(bp,"\n This Update: ") <= 0) goto err; | |
259 if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate)) | |
260 goto err; | |
261 if (single->nextUpdate) | |
262 { | |
263 if (BIO_printf(bp,"\n Next Update: ") <= 0)goto err; | |
264 if (!ASN1_GENERALIZEDTIME_print(bp,single->nextUpdate)) | |
265 goto err; | |
266 } | |
267 if (BIO_write(bp,"\n",1) <= 0) goto err; | |
268 if (!X509V3_extensions_print(bp, | |
269 "Response Single Extensions", | |
270 single->singleExtensions, flags, 8)) | |
271 goto err; | |
272 if (BIO_write(bp,"\n",1) <= 0) goto err; | |
273 } | |
274 if (!X509V3_extensions_print(bp, "Response Extensions", | |
275 rd->responseExtensions, flags, 4)) | |
276 goto err; | |
277 if(X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0) | |
278 goto err; | |
279 | |
280 for (i=0; i<sk_X509_num(br->certs); i++) | |
281 { | |
282 X509_print(bp, sk_X509_value(br->certs,i)); | |
283 PEM_write_bio_X509(bp,sk_X509_value(br->certs,i)); | |
284 } | |
285 | |
286 ret = 1; | |
287 err: | |
288 OCSP_BASICRESP_free(br); | |
289 return ret; | |
290 } | |
OLD | NEW |