ocsp_prn.c revision 296465
1/* ocsp_prn.c */ 2/* 3 * Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL 4 * project. 5 */ 6 7/* 8 * History: This file was originally part of ocsp.c and was transfered to 9 * Richard Levitte from CertCo by Kathy Weinhold in mid-spring 2000 to be 10 * included in OpenSSL or released as a patch kit. 11 */ 12 13/* ==================================================================== 14 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 20 * 1. Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 23 * 2. Redistributions in binary form must reproduce the above copyright 24 * notice, this list of conditions and the following disclaimer in 25 * the documentation and/or other materials provided with the 26 * distribution. 27 * 28 * 3. All advertising materials mentioning features or use of this 29 * software must display the following acknowledgment: 30 * "This product includes software developed by the OpenSSL Project 31 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 32 * 33 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 34 * endorse or promote products derived from this software without 35 * prior written permission. For written permission, please contact 36 * openssl-core@openssl.org. 37 * 38 * 5. Products derived from this software may not be called "OpenSSL" 39 * nor may "OpenSSL" appear in their names without prior written 40 * permission of the OpenSSL Project. 41 * 42 * 6. Redistributions of any form whatsoever must retain the following 43 * acknowledgment: 44 * "This product includes software developed by the OpenSSL Project 45 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 46 * 47 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 48 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 50 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 51 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 52 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 53 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 54 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 56 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 57 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 58 * OF THE POSSIBILITY OF SUCH DAMAGE. 59 * ==================================================================== 60 * 61 * This product includes cryptographic software written by Eric Young 62 * (eay@cryptsoft.com). This product includes software written by Tim 63 * Hudson (tjh@cryptsoft.com). 64 * 65 */ 66 67#include <openssl/bio.h> 68#include <openssl/err.h> 69#include <openssl/ocsp.h> 70#include <openssl/pem.h> 71 72static int ocsp_certid_print(BIO *bp, OCSP_CERTID *a, int indent) 73{ 74 BIO_printf(bp, "%*sCertificate ID:\n", indent, ""); 75 indent += 2; 76 BIO_printf(bp, "%*sHash Algorithm: ", indent, ""); 77 i2a_ASN1_OBJECT(bp, a->hashAlgorithm->algorithm); 78 BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, ""); 79 i2a_ASN1_STRING(bp, a->issuerNameHash, V_ASN1_OCTET_STRING); 80 BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, ""); 81 i2a_ASN1_STRING(bp, a->issuerKeyHash, V_ASN1_OCTET_STRING); 82 BIO_printf(bp, "\n%*sSerial Number: ", indent, ""); 83 i2a_ASN1_INTEGER(bp, a->serialNumber); 84 BIO_printf(bp, "\n"); 85 return 1; 86} 87 88typedef struct { 89 long t; 90 char *m; 91} OCSP_TBLSTR; 92 93static char *table2string(long s, OCSP_TBLSTR *ts, int len) 94{ 95 OCSP_TBLSTR *p; 96 for (p = ts; p < ts + len; p++) 97 if (p->t == s) 98 return p->m; 99 return "(UNKNOWN)"; 100} 101 102char *OCSP_response_status_str(long s) 103{ 104 static OCSP_TBLSTR rstat_tbl[] = { 105 {OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful"}, 106 {OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest"}, 107 {OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror"}, 108 {OCSP_RESPONSE_STATUS_TRYLATER, "trylater"}, 109 {OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired"}, 110 {OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized"} 111 }; 112 return table2string(s, rstat_tbl, 6); 113} 114 115char *OCSP_cert_status_str(long s) 116{ 117 static OCSP_TBLSTR cstat_tbl[] = { 118 {V_OCSP_CERTSTATUS_GOOD, "good"}, 119 {V_OCSP_CERTSTATUS_REVOKED, "revoked"}, 120 {V_OCSP_CERTSTATUS_UNKNOWN, "unknown"} 121 }; 122 return table2string(s, cstat_tbl, 3); 123} 124 125char *OCSP_crl_reason_str(long s) 126{ 127 OCSP_TBLSTR reason_tbl[] = { 128 {OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified"}, 129 {OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise"}, 130 {OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise"}, 131 {OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged"}, 132 {OCSP_REVOKED_STATUS_SUPERSEDED, "superseded"}, 133 {OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation"}, 134 {OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold"}, 135 {OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL"} 136 }; 137 return table2string(s, reason_tbl, 8); 138} 139 140int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *o, unsigned long flags) 141{ 142 int i; 143 long l; 144 OCSP_CERTID *cid = NULL; 145 OCSP_ONEREQ *one = NULL; 146 OCSP_REQINFO *inf = o->tbsRequest; 147 OCSP_SIGNATURE *sig = o->optionalSignature; 148 149 if (BIO_write(bp, "OCSP Request Data:\n", 19) <= 0) 150 goto err; 151 l = ASN1_INTEGER_get(inf->version); 152 if (BIO_printf(bp, " Version: %lu (0x%lx)", l + 1, l) <= 0) 153 goto err; 154 if (inf->requestorName != NULL) { 155 if (BIO_write(bp, "\n Requestor Name: ", 21) <= 0) 156 goto err; 157 GENERAL_NAME_print(bp, inf->requestorName); 158 } 159 if (BIO_write(bp, "\n Requestor List:\n", 21) <= 0) 160 goto err; 161 for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++) { 162 one = sk_OCSP_ONEREQ_value(inf->requestList, i); 163 cid = one->reqCert; 164 ocsp_certid_print(bp, cid, 8); 165 if (!X509V3_extensions_print(bp, 166 "Request Single Extensions", 167 one->singleRequestExtensions, flags, 8)) 168 goto err; 169 } 170 if (!X509V3_extensions_print(bp, "Request Extensions", 171 inf->requestExtensions, flags, 4)) 172 goto err; 173 if (sig) { 174 X509_signature_print(bp, sig->signatureAlgorithm, sig->signature); 175 for (i = 0; i < sk_X509_num(sig->certs); i++) { 176 X509_print(bp, sk_X509_value(sig->certs, i)); 177 PEM_write_bio_X509(bp, sk_X509_value(sig->certs, i)); 178 } 179 } 180 return 1; 181 err: 182 return 0; 183} 184 185int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags) 186{ 187 int i, ret = 0; 188 long l; 189 OCSP_CERTID *cid = NULL; 190 OCSP_BASICRESP *br = NULL; 191 OCSP_RESPID *rid = NULL; 192 OCSP_RESPDATA *rd = NULL; 193 OCSP_CERTSTATUS *cst = NULL; 194 OCSP_REVOKEDINFO *rev = NULL; 195 OCSP_SINGLERESP *single = NULL; 196 OCSP_RESPBYTES *rb = o->responseBytes; 197 198 if (BIO_puts(bp, "OCSP Response Data:\n") <= 0) 199 goto err; 200 l = ASN1_ENUMERATED_get(o->responseStatus); 201 if (BIO_printf(bp, " OCSP Response Status: %s (0x%lx)\n", 202 OCSP_response_status_str(l), l) <= 0) 203 goto err; 204 if (rb == NULL) 205 return 1; 206 if (BIO_puts(bp, " Response Type: ") <= 0) 207 goto err; 208 if (i2a_ASN1_OBJECT(bp, rb->responseType) <= 0) 209 goto err; 210 if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) { 211 BIO_puts(bp, " (unknown response type)\n"); 212 return 1; 213 } 214 215 i = ASN1_STRING_length(rb->response); 216 if (!(br = OCSP_response_get1_basic(o))) 217 goto err; 218 rd = br->tbsResponseData; 219 l = ASN1_INTEGER_get(rd->version); 220 if (BIO_printf(bp, "\n Version: %lu (0x%lx)\n", l + 1, l) <= 0) 221 goto err; 222 if (BIO_puts(bp, " Responder Id: ") <= 0) 223 goto err; 224 225 rid = rd->responderId; 226 switch (rid->type) { 227 case V_OCSP_RESPID_NAME: 228 X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE); 229 break; 230 case V_OCSP_RESPID_KEY: 231 i2a_ASN1_STRING(bp, rid->value.byKey, V_ASN1_OCTET_STRING); 232 break; 233 } 234 235 if (BIO_printf(bp, "\n Produced At: ") <= 0) 236 goto err; 237 if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt)) 238 goto err; 239 if (BIO_printf(bp, "\n Responses:\n") <= 0) 240 goto err; 241 for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) { 242 if (!sk_OCSP_SINGLERESP_value(rd->responses, i)) 243 continue; 244 single = sk_OCSP_SINGLERESP_value(rd->responses, i); 245 cid = single->certId; 246 if (ocsp_certid_print(bp, cid, 4) <= 0) 247 goto err; 248 cst = single->certStatus; 249 if (BIO_printf(bp, " Cert Status: %s", 250 OCSP_cert_status_str(cst->type)) <= 0) 251 goto err; 252 if (cst->type == V_OCSP_CERTSTATUS_REVOKED) { 253 rev = cst->value.revoked; 254 if (BIO_printf(bp, "\n Revocation Time: ") <= 0) 255 goto err; 256 if (!ASN1_GENERALIZEDTIME_print(bp, rev->revocationTime)) 257 goto err; 258 if (rev->revocationReason) { 259 l = ASN1_ENUMERATED_get(rev->revocationReason); 260 if (BIO_printf(bp, 261 "\n Revocation Reason: %s (0x%lx)", 262 OCSP_crl_reason_str(l), l) <= 0) 263 goto err; 264 } 265 } 266 if (BIO_printf(bp, "\n This Update: ") <= 0) 267 goto err; 268 if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate)) 269 goto err; 270 if (single->nextUpdate) { 271 if (BIO_printf(bp, "\n Next Update: ") <= 0) 272 goto err; 273 if (!ASN1_GENERALIZEDTIME_print(bp, single->nextUpdate)) 274 goto err; 275 } 276 if (BIO_write(bp, "\n", 1) <= 0) 277 goto err; 278 if (!X509V3_extensions_print(bp, 279 "Response Single Extensions", 280 single->singleExtensions, flags, 8)) 281 goto err; 282 if (BIO_write(bp, "\n", 1) <= 0) 283 goto err; 284 } 285 if (!X509V3_extensions_print(bp, "Response Extensions", 286 rd->responseExtensions, flags, 4)) 287 goto err; 288 if (X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0) 289 goto err; 290 291 for (i = 0; i < sk_X509_num(br->certs); i++) { 292 X509_print(bp, sk_X509_value(br->certs, i)); 293 PEM_write_bio_X509(bp, sk_X509_value(br->certs, i)); 294 } 295 296 ret = 1; 297 err: 298 OCSP_BASICRESP_free(br); 299 return ret; 300} 301