1109998Smarkm/* ocsp_prn.c */ 2280297Sjkim/* 3280297Sjkim * Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL 4280297Sjkim * project. 5280297Sjkim */ 6109998Smarkm 7280297Sjkim/* 8280297Sjkim * History: This file was originally part of ocsp.c and was transfered to 9280297Sjkim * Richard Levitte from CertCo by Kathy Weinhold in mid-spring 2000 to be 10280297Sjkim * included in OpenSSL or released as a patch kit. 11280297Sjkim */ 12109998Smarkm 13109998Smarkm/* ==================================================================== 14109998Smarkm * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 15109998Smarkm * 16109998Smarkm * Redistribution and use in source and binary forms, with or without 17109998Smarkm * modification, are permitted provided that the following conditions 18109998Smarkm * are met: 19109998Smarkm * 20109998Smarkm * 1. Redistributions of source code must retain the above copyright 21280297Sjkim * notice, this list of conditions and the following disclaimer. 22109998Smarkm * 23109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 24109998Smarkm * notice, this list of conditions and the following disclaimer in 25109998Smarkm * the documentation and/or other materials provided with the 26109998Smarkm * distribution. 27109998Smarkm * 28109998Smarkm * 3. All advertising materials mentioning features or use of this 29109998Smarkm * software must display the following acknowledgment: 30109998Smarkm * "This product includes software developed by the OpenSSL Project 31109998Smarkm * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 32109998Smarkm * 33109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 34109998Smarkm * endorse or promote products derived from this software without 35109998Smarkm * prior written permission. For written permission, please contact 36109998Smarkm * openssl-core@openssl.org. 37109998Smarkm * 38109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 39109998Smarkm * nor may "OpenSSL" appear in their names without prior written 40109998Smarkm * permission of the OpenSSL Project. 41109998Smarkm * 42109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 43109998Smarkm * acknowledgment: 44109998Smarkm * "This product includes software developed by the OpenSSL Project 45109998Smarkm * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 46109998Smarkm * 47109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 48109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 50109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 51109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 52109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 53109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 54109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 56109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 57109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 58109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 59109998Smarkm * ==================================================================== 60109998Smarkm * 61109998Smarkm * This product includes cryptographic software written by Eric Young 62109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 63109998Smarkm * Hudson (tjh@cryptsoft.com). 64109998Smarkm * 65109998Smarkm */ 66109998Smarkm 67109998Smarkm#include <openssl/bio.h> 68109998Smarkm#include <openssl/err.h> 69109998Smarkm#include <openssl/ocsp.h> 70109998Smarkm#include <openssl/pem.h> 71109998Smarkm 72280297Sjkimstatic int ocsp_certid_print(BIO *bp, OCSP_CERTID *a, int indent) 73280297Sjkim{ 74280297Sjkim BIO_printf(bp, "%*sCertificate ID:\n", indent, ""); 75280297Sjkim indent += 2; 76280297Sjkim BIO_printf(bp, "%*sHash Algorithm: ", indent, ""); 77280297Sjkim i2a_ASN1_OBJECT(bp, a->hashAlgorithm->algorithm); 78280297Sjkim BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, ""); 79280297Sjkim i2a_ASN1_STRING(bp, a->issuerNameHash, V_ASN1_OCTET_STRING); 80280297Sjkim BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, ""); 81280297Sjkim i2a_ASN1_STRING(bp, a->issuerKeyHash, V_ASN1_OCTET_STRING); 82280297Sjkim BIO_printf(bp, "\n%*sSerial Number: ", indent, ""); 83280297Sjkim i2a_ASN1_INTEGER(bp, a->serialNumber); 84280297Sjkim BIO_printf(bp, "\n"); 85280297Sjkim return 1; 86280297Sjkim} 87109998Smarkm 88280297Sjkimtypedef struct { 89280297Sjkim long t; 90280297Sjkim const char *m; 91280297Sjkim} OCSP_TBLSTR; 92109998Smarkm 93238405Sjkimstatic const char *table2string(long s, const OCSP_TBLSTR *ts, int len) 94109998Smarkm{ 95280297Sjkim const OCSP_TBLSTR *p; 96280297Sjkim for (p = ts; p < ts + len; p++) 97280297Sjkim if (p->t == s) 98280297Sjkim return p->m; 99280297Sjkim return "(UNKNOWN)"; 100109998Smarkm} 101109998Smarkm 102238405Sjkimconst char *OCSP_response_status_str(long s) 103280297Sjkim{ 104280297Sjkim static const OCSP_TBLSTR rstat_tbl[] = { 105280297Sjkim {OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful"}, 106280297Sjkim {OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest"}, 107280297Sjkim {OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror"}, 108280297Sjkim {OCSP_RESPONSE_STATUS_TRYLATER, "trylater"}, 109280297Sjkim {OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired"}, 110280297Sjkim {OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized"} 111280297Sjkim }; 112280297Sjkim return table2string(s, rstat_tbl, 6); 113280297Sjkim} 114109998Smarkm 115238405Sjkimconst char *OCSP_cert_status_str(long s) 116280297Sjkim{ 117280297Sjkim static const OCSP_TBLSTR cstat_tbl[] = { 118280297Sjkim {V_OCSP_CERTSTATUS_GOOD, "good"}, 119280297Sjkim {V_OCSP_CERTSTATUS_REVOKED, "revoked"}, 120280297Sjkim {V_OCSP_CERTSTATUS_UNKNOWN, "unknown"} 121280297Sjkim }; 122280297Sjkim return table2string(s, cstat_tbl, 3); 123280297Sjkim} 124109998Smarkm 125238405Sjkimconst char *OCSP_crl_reason_str(long s) 126280297Sjkim{ 127280297Sjkim static const OCSP_TBLSTR reason_tbl[] = { 128280297Sjkim {OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified"}, 129280297Sjkim {OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise"}, 130280297Sjkim {OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise"}, 131280297Sjkim {OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged"}, 132280297Sjkim {OCSP_REVOKED_STATUS_SUPERSEDED, "superseded"}, 133280297Sjkim {OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation"}, 134280297Sjkim {OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold"}, 135280297Sjkim {OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL"} 136280297Sjkim }; 137280297Sjkim return table2string(s, reason_tbl, 8); 138280297Sjkim} 139109998Smarkm 140280297Sjkimint OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *o, unsigned long flags) 141280297Sjkim{ 142280297Sjkim int i; 143280297Sjkim long l; 144280297Sjkim OCSP_CERTID *cid = NULL; 145280297Sjkim OCSP_ONEREQ *one = NULL; 146280297Sjkim OCSP_REQINFO *inf = o->tbsRequest; 147280297Sjkim OCSP_SIGNATURE *sig = o->optionalSignature; 148109998Smarkm 149280297Sjkim if (BIO_write(bp, "OCSP Request Data:\n", 19) <= 0) 150280297Sjkim goto err; 151280297Sjkim l = ASN1_INTEGER_get(inf->version); 152280297Sjkim if (BIO_printf(bp, " Version: %lu (0x%lx)", l + 1, l) <= 0) 153280297Sjkim goto err; 154280297Sjkim if (inf->requestorName != NULL) { 155280297Sjkim if (BIO_write(bp, "\n Requestor Name: ", 21) <= 0) 156280297Sjkim goto err; 157280297Sjkim GENERAL_NAME_print(bp, inf->requestorName); 158280297Sjkim } 159280297Sjkim if (BIO_write(bp, "\n Requestor List:\n", 21) <= 0) 160280297Sjkim goto err; 161280297Sjkim for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++) { 162280297Sjkim one = sk_OCSP_ONEREQ_value(inf->requestList, i); 163280297Sjkim cid = one->reqCert; 164280297Sjkim ocsp_certid_print(bp, cid, 8); 165280297Sjkim if (!X509V3_extensions_print(bp, 166280297Sjkim "Request Single Extensions", 167280297Sjkim one->singleRequestExtensions, flags, 8)) 168280297Sjkim goto err; 169280297Sjkim } 170280297Sjkim if (!X509V3_extensions_print(bp, "Request Extensions", 171280297Sjkim inf->requestExtensions, flags, 4)) 172280297Sjkim goto err; 173280297Sjkim if (sig) { 174280297Sjkim X509_signature_print(bp, sig->signatureAlgorithm, sig->signature); 175280297Sjkim for (i = 0; i < sk_X509_num(sig->certs); i++) { 176280297Sjkim X509_print(bp, sk_X509_value(sig->certs, i)); 177280297Sjkim PEM_write_bio_X509(bp, sk_X509_value(sig->certs, i)); 178280297Sjkim } 179280297Sjkim } 180280297Sjkim return 1; 181280297Sjkim err: 182280297Sjkim return 0; 183280297Sjkim} 184109998Smarkm 185280297Sjkimint OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags) 186280297Sjkim{ 187280297Sjkim int i, ret = 0; 188280297Sjkim long l; 189280297Sjkim OCSP_CERTID *cid = NULL; 190280297Sjkim OCSP_BASICRESP *br = NULL; 191280297Sjkim OCSP_RESPID *rid = NULL; 192280297Sjkim OCSP_RESPDATA *rd = NULL; 193280297Sjkim OCSP_CERTSTATUS *cst = NULL; 194280297Sjkim OCSP_REVOKEDINFO *rev = NULL; 195280297Sjkim OCSP_SINGLERESP *single = NULL; 196280297Sjkim OCSP_RESPBYTES *rb = o->responseBytes; 197109998Smarkm 198280297Sjkim if (BIO_puts(bp, "OCSP Response Data:\n") <= 0) 199280297Sjkim goto err; 200280297Sjkim l = ASN1_ENUMERATED_get(o->responseStatus); 201280297Sjkim if (BIO_printf(bp, " OCSP Response Status: %s (0x%lx)\n", 202280297Sjkim OCSP_response_status_str(l), l) <= 0) 203280297Sjkim goto err; 204280297Sjkim if (rb == NULL) 205280297Sjkim return 1; 206280297Sjkim if (BIO_puts(bp, " Response Type: ") <= 0) 207280297Sjkim goto err; 208280297Sjkim if (i2a_ASN1_OBJECT(bp, rb->responseType) <= 0) 209280297Sjkim goto err; 210280297Sjkim if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) { 211280297Sjkim BIO_puts(bp, " (unknown response type)\n"); 212280297Sjkim return 1; 213280297Sjkim } 214109998Smarkm 215291719Sjkim if ((br = OCSP_response_get1_basic(o)) == NULL) 216280297Sjkim goto err; 217280297Sjkim rd = br->tbsResponseData; 218280297Sjkim l = ASN1_INTEGER_get(rd->version); 219280297Sjkim if (BIO_printf(bp, "\n Version: %lu (0x%lx)\n", l + 1, l) <= 0) 220280297Sjkim goto err; 221280297Sjkim if (BIO_puts(bp, " Responder Id: ") <= 0) 222280297Sjkim goto err; 223109998Smarkm 224280297Sjkim rid = rd->responderId; 225280297Sjkim switch (rid->type) { 226280297Sjkim case V_OCSP_RESPID_NAME: 227280297Sjkim X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE); 228280297Sjkim break; 229280297Sjkim case V_OCSP_RESPID_KEY: 230280297Sjkim i2a_ASN1_STRING(bp, rid->value.byKey, V_ASN1_OCTET_STRING); 231280297Sjkim break; 232280297Sjkim } 233109998Smarkm 234280297Sjkim if (BIO_printf(bp, "\n Produced At: ") <= 0) 235280297Sjkim goto err; 236280297Sjkim if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt)) 237280297Sjkim goto err; 238280297Sjkim if (BIO_printf(bp, "\n Responses:\n") <= 0) 239280297Sjkim goto err; 240280297Sjkim for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) { 241280297Sjkim if (!sk_OCSP_SINGLERESP_value(rd->responses, i)) 242280297Sjkim continue; 243280297Sjkim single = sk_OCSP_SINGLERESP_value(rd->responses, i); 244280297Sjkim cid = single->certId; 245280297Sjkim if (ocsp_certid_print(bp, cid, 4) <= 0) 246280297Sjkim goto err; 247280297Sjkim cst = single->certStatus; 248280297Sjkim if (BIO_printf(bp, " Cert Status: %s", 249280297Sjkim OCSP_cert_status_str(cst->type)) <= 0) 250280297Sjkim goto err; 251280297Sjkim if (cst->type == V_OCSP_CERTSTATUS_REVOKED) { 252280297Sjkim rev = cst->value.revoked; 253280297Sjkim if (BIO_printf(bp, "\n Revocation Time: ") <= 0) 254280297Sjkim goto err; 255280297Sjkim if (!ASN1_GENERALIZEDTIME_print(bp, rev->revocationTime)) 256280297Sjkim goto err; 257280297Sjkim if (rev->revocationReason) { 258280297Sjkim l = ASN1_ENUMERATED_get(rev->revocationReason); 259280297Sjkim if (BIO_printf(bp, 260280297Sjkim "\n Revocation Reason: %s (0x%lx)", 261280297Sjkim OCSP_crl_reason_str(l), l) <= 0) 262280297Sjkim goto err; 263280297Sjkim } 264280297Sjkim } 265280297Sjkim if (BIO_printf(bp, "\n This Update: ") <= 0) 266280297Sjkim goto err; 267280297Sjkim if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate)) 268280297Sjkim goto err; 269280297Sjkim if (single->nextUpdate) { 270280297Sjkim if (BIO_printf(bp, "\n Next Update: ") <= 0) 271280297Sjkim goto err; 272280297Sjkim if (!ASN1_GENERALIZEDTIME_print(bp, single->nextUpdate)) 273280297Sjkim goto err; 274280297Sjkim } 275280297Sjkim if (BIO_write(bp, "\n", 1) <= 0) 276280297Sjkim goto err; 277280297Sjkim if (!X509V3_extensions_print(bp, 278280297Sjkim "Response Single Extensions", 279280297Sjkim single->singleExtensions, flags, 8)) 280280297Sjkim goto err; 281280297Sjkim if (BIO_write(bp, "\n", 1) <= 0) 282280297Sjkim goto err; 283280297Sjkim } 284280297Sjkim if (!X509V3_extensions_print(bp, "Response Extensions", 285280297Sjkim rd->responseExtensions, flags, 4)) 286280297Sjkim goto err; 287280297Sjkim if (X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0) 288280297Sjkim goto err; 289109998Smarkm 290280297Sjkim for (i = 0; i < sk_X509_num(br->certs); i++) { 291280297Sjkim X509_print(bp, sk_X509_value(br->certs, i)); 292280297Sjkim PEM_write_bio_X509(bp, sk_X509_value(br->certs, i)); 293280297Sjkim } 294109998Smarkm 295280297Sjkim ret = 1; 296280297Sjkim err: 297280297Sjkim OCSP_BASICRESP_free(br); 298280297Sjkim return ret; 299280297Sjkim} 300