ocsp_prn.c revision 291721
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 const char *m; 91} OCSP_TBLSTR; 92 93static const char *table2string(long s, const OCSP_TBLSTR *ts, int len) 94{ 95 const 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 102const char *OCSP_response_status_str(long s) 103{ 104 static const 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 115const char *OCSP_cert_status_str(long s) 116{ 117 static const 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 125const char *OCSP_crl_reason_str(long s) 126{ 127 static const 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 if ((br = OCSP_response_get1_basic(o)) == NULL) 216 goto err; 217 rd = br->tbsResponseData; 218 l = ASN1_INTEGER_get(rd->version); 219 if (BIO_printf(bp, "\n Version: %lu (0x%lx)\n", l + 1, l) <= 0) 220 goto err; 221 if (BIO_puts(bp, " Responder Id: ") <= 0) 222 goto err; 223 224 rid = rd->responderId; 225 switch (rid->type) { 226 case V_OCSP_RESPID_NAME: 227 X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE); 228 break; 229 case V_OCSP_RESPID_KEY: 230 i2a_ASN1_STRING(bp, rid->value.byKey, V_ASN1_OCTET_STRING); 231 break; 232 } 233 234 if (BIO_printf(bp, "\n Produced At: ") <= 0) 235 goto err; 236 if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt)) 237 goto err; 238 if (BIO_printf(bp, "\n Responses:\n") <= 0) 239 goto err; 240 for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) { 241 if (!sk_OCSP_SINGLERESP_value(rd->responses, i)) 242 continue; 243 single = sk_OCSP_SINGLERESP_value(rd->responses, i); 244 cid = single->certId; 245 if (ocsp_certid_print(bp, cid, 4) <= 0) 246 goto err; 247 cst = single->certStatus; 248 if (BIO_printf(bp, " Cert Status: %s", 249 OCSP_cert_status_str(cst->type)) <= 0) 250 goto err; 251 if (cst->type == V_OCSP_CERTSTATUS_REVOKED) { 252 rev = cst->value.revoked; 253 if (BIO_printf(bp, "\n Revocation Time: ") <= 0) 254 goto err; 255 if (!ASN1_GENERALIZEDTIME_print(bp, rev->revocationTime)) 256 goto err; 257 if (rev->revocationReason) { 258 l = ASN1_ENUMERATED_get(rev->revocationReason); 259 if (BIO_printf(bp, 260 "\n Revocation Reason: %s (0x%lx)", 261 OCSP_crl_reason_str(l), l) <= 0) 262 goto err; 263 } 264 } 265 if (BIO_printf(bp, "\n This Update: ") <= 0) 266 goto err; 267 if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate)) 268 goto err; 269 if (single->nextUpdate) { 270 if (BIO_printf(bp, "\n Next Update: ") <= 0) 271 goto err; 272 if (!ASN1_GENERALIZEDTIME_print(bp, single->nextUpdate)) 273 goto err; 274 } 275 if (BIO_write(bp, "\n", 1) <= 0) 276 goto err; 277 if (!X509V3_extensions_print(bp, 278 "Response Single Extensions", 279 single->singleExtensions, flags, 8)) 280 goto err; 281 if (BIO_write(bp, "\n", 1) <= 0) 282 goto err; 283 } 284 if (!X509V3_extensions_print(bp, "Response Extensions", 285 rd->responseExtensions, flags, 4)) 286 goto err; 287 if (X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0) 288 goto err; 289 290 for (i = 0; i < sk_X509_num(br->certs); i++) { 291 X509_print(bp, sk_X509_value(br->certs, i)); 292 PEM_write_bio_X509(bp, sk_X509_value(br->certs, i)); 293 } 294 295 ret = 1; 296 err: 297 OCSP_BASICRESP_free(br); 298 return ret; 299} 300