1109998Smarkm/* ocsp_prn.c */ 2296465Sdelphij/* 3296465Sdelphij * Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL 4296465Sdelphij * project. 5296465Sdelphij */ 6109998Smarkm 7296465Sdelphij/* 8296465Sdelphij * History: This file was originally part of ocsp.c and was transfered to 9296465Sdelphij * Richard Levitte from CertCo by Kathy Weinhold in mid-spring 2000 to be 10296465Sdelphij * included in OpenSSL or released as a patch kit. 11296465Sdelphij */ 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 21296465Sdelphij * 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 72296465Sdelphijstatic int ocsp_certid_print(BIO *bp, OCSP_CERTID *a, int indent) 73296465Sdelphij{ 74296465Sdelphij BIO_printf(bp, "%*sCertificate ID:\n", indent, ""); 75296465Sdelphij indent += 2; 76296465Sdelphij BIO_printf(bp, "%*sHash Algorithm: ", indent, ""); 77296465Sdelphij i2a_ASN1_OBJECT(bp, a->hashAlgorithm->algorithm); 78296465Sdelphij BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, ""); 79296465Sdelphij i2a_ASN1_STRING(bp, a->issuerNameHash, V_ASN1_OCTET_STRING); 80296465Sdelphij BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, ""); 81296465Sdelphij i2a_ASN1_STRING(bp, a->issuerKeyHash, V_ASN1_OCTET_STRING); 82296465Sdelphij BIO_printf(bp, "\n%*sSerial Number: ", indent, ""); 83296465Sdelphij i2a_ASN1_INTEGER(bp, a->serialNumber); 84296465Sdelphij BIO_printf(bp, "\n"); 85296465Sdelphij return 1; 86296465Sdelphij} 87109998Smarkm 88296465Sdelphijtypedef struct { 89296465Sdelphij long t; 90296465Sdelphij char *m; 91296465Sdelphij} OCSP_TBLSTR; 92109998Smarkm 93109998Smarkmstatic char *table2string(long s, OCSP_TBLSTR *ts, int len) 94109998Smarkm{ 95296465Sdelphij OCSP_TBLSTR *p; 96296465Sdelphij for (p = ts; p < ts + len; p++) 97296465Sdelphij if (p->t == s) 98296465Sdelphij return p->m; 99296465Sdelphij return "(UNKNOWN)"; 100109998Smarkm} 101109998Smarkm 102109998Smarkmchar *OCSP_response_status_str(long s) 103296465Sdelphij{ 104296465Sdelphij static OCSP_TBLSTR rstat_tbl[] = { 105296465Sdelphij {OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful"}, 106296465Sdelphij {OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest"}, 107296465Sdelphij {OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror"}, 108296465Sdelphij {OCSP_RESPONSE_STATUS_TRYLATER, "trylater"}, 109296465Sdelphij {OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired"}, 110296465Sdelphij {OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized"} 111296465Sdelphij }; 112296465Sdelphij return table2string(s, rstat_tbl, 6); 113296465Sdelphij} 114109998Smarkm 115109998Smarkmchar *OCSP_cert_status_str(long s) 116296465Sdelphij{ 117296465Sdelphij static OCSP_TBLSTR cstat_tbl[] = { 118296465Sdelphij {V_OCSP_CERTSTATUS_GOOD, "good"}, 119296465Sdelphij {V_OCSP_CERTSTATUS_REVOKED, "revoked"}, 120296465Sdelphij {V_OCSP_CERTSTATUS_UNKNOWN, "unknown"} 121296465Sdelphij }; 122296465Sdelphij return table2string(s, cstat_tbl, 3); 123296465Sdelphij} 124109998Smarkm 125109998Smarkmchar *OCSP_crl_reason_str(long s) 126296465Sdelphij{ 127296465Sdelphij OCSP_TBLSTR reason_tbl[] = { 128296465Sdelphij {OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified"}, 129296465Sdelphij {OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise"}, 130296465Sdelphij {OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise"}, 131296465Sdelphij {OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged"}, 132296465Sdelphij {OCSP_REVOKED_STATUS_SUPERSEDED, "superseded"}, 133296465Sdelphij {OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation"}, 134296465Sdelphij {OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold"}, 135296465Sdelphij {OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL"} 136296465Sdelphij }; 137296465Sdelphij return table2string(s, reason_tbl, 8); 138296465Sdelphij} 139109998Smarkm 140296465Sdelphijint OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *o, unsigned long flags) 141296465Sdelphij{ 142296465Sdelphij int i; 143296465Sdelphij long l; 144296465Sdelphij OCSP_CERTID *cid = NULL; 145296465Sdelphij OCSP_ONEREQ *one = NULL; 146296465Sdelphij OCSP_REQINFO *inf = o->tbsRequest; 147296465Sdelphij OCSP_SIGNATURE *sig = o->optionalSignature; 148109998Smarkm 149296465Sdelphij if (BIO_write(bp, "OCSP Request Data:\n", 19) <= 0) 150296465Sdelphij goto err; 151296465Sdelphij l = ASN1_INTEGER_get(inf->version); 152296465Sdelphij if (BIO_printf(bp, " Version: %lu (0x%lx)", l + 1, l) <= 0) 153296465Sdelphij goto err; 154296465Sdelphij if (inf->requestorName != NULL) { 155296465Sdelphij if (BIO_write(bp, "\n Requestor Name: ", 21) <= 0) 156296465Sdelphij goto err; 157296465Sdelphij GENERAL_NAME_print(bp, inf->requestorName); 158296465Sdelphij } 159296465Sdelphij if (BIO_write(bp, "\n Requestor List:\n", 21) <= 0) 160296465Sdelphij goto err; 161296465Sdelphij for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++) { 162296465Sdelphij one = sk_OCSP_ONEREQ_value(inf->requestList, i); 163296465Sdelphij cid = one->reqCert; 164296465Sdelphij ocsp_certid_print(bp, cid, 8); 165296465Sdelphij if (!X509V3_extensions_print(bp, 166296465Sdelphij "Request Single Extensions", 167296465Sdelphij one->singleRequestExtensions, flags, 8)) 168296465Sdelphij goto err; 169296465Sdelphij } 170296465Sdelphij if (!X509V3_extensions_print(bp, "Request Extensions", 171296465Sdelphij inf->requestExtensions, flags, 4)) 172296465Sdelphij goto err; 173296465Sdelphij if (sig) { 174296465Sdelphij X509_signature_print(bp, sig->signatureAlgorithm, sig->signature); 175296465Sdelphij for (i = 0; i < sk_X509_num(sig->certs); i++) { 176296465Sdelphij X509_print(bp, sk_X509_value(sig->certs, i)); 177296465Sdelphij PEM_write_bio_X509(bp, sk_X509_value(sig->certs, i)); 178296465Sdelphij } 179296465Sdelphij } 180296465Sdelphij return 1; 181296465Sdelphij err: 182296465Sdelphij return 0; 183296465Sdelphij} 184109998Smarkm 185296465Sdelphijint OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags) 186296465Sdelphij{ 187296465Sdelphij int i, ret = 0; 188296465Sdelphij long l; 189296465Sdelphij OCSP_CERTID *cid = NULL; 190296465Sdelphij OCSP_BASICRESP *br = NULL; 191296465Sdelphij OCSP_RESPID *rid = NULL; 192296465Sdelphij OCSP_RESPDATA *rd = NULL; 193296465Sdelphij OCSP_CERTSTATUS *cst = NULL; 194296465Sdelphij OCSP_REVOKEDINFO *rev = NULL; 195296465Sdelphij OCSP_SINGLERESP *single = NULL; 196296465Sdelphij OCSP_RESPBYTES *rb = o->responseBytes; 197109998Smarkm 198296465Sdelphij if (BIO_puts(bp, "OCSP Response Data:\n") <= 0) 199296465Sdelphij goto err; 200296465Sdelphij l = ASN1_ENUMERATED_get(o->responseStatus); 201296465Sdelphij if (BIO_printf(bp, " OCSP Response Status: %s (0x%lx)\n", 202296465Sdelphij OCSP_response_status_str(l), l) <= 0) 203296465Sdelphij goto err; 204296465Sdelphij if (rb == NULL) 205296465Sdelphij return 1; 206296465Sdelphij if (BIO_puts(bp, " Response Type: ") <= 0) 207296465Sdelphij goto err; 208296465Sdelphij if (i2a_ASN1_OBJECT(bp, rb->responseType) <= 0) 209296465Sdelphij goto err; 210296465Sdelphij if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) { 211296465Sdelphij BIO_puts(bp, " (unknown response type)\n"); 212296465Sdelphij return 1; 213296465Sdelphij } 214109998Smarkm 215296465Sdelphij i = ASN1_STRING_length(rb->response); 216296465Sdelphij if (!(br = OCSP_response_get1_basic(o))) 217296465Sdelphij goto err; 218296465Sdelphij rd = br->tbsResponseData; 219296465Sdelphij l = ASN1_INTEGER_get(rd->version); 220296465Sdelphij if (BIO_printf(bp, "\n Version: %lu (0x%lx)\n", l + 1, l) <= 0) 221296465Sdelphij goto err; 222296465Sdelphij if (BIO_puts(bp, " Responder Id: ") <= 0) 223296465Sdelphij goto err; 224109998Smarkm 225296465Sdelphij rid = rd->responderId; 226296465Sdelphij switch (rid->type) { 227296465Sdelphij case V_OCSP_RESPID_NAME: 228296465Sdelphij X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE); 229296465Sdelphij break; 230296465Sdelphij case V_OCSP_RESPID_KEY: 231296465Sdelphij i2a_ASN1_STRING(bp, rid->value.byKey, V_ASN1_OCTET_STRING); 232296465Sdelphij break; 233296465Sdelphij } 234109998Smarkm 235296465Sdelphij if (BIO_printf(bp, "\n Produced At: ") <= 0) 236296465Sdelphij goto err; 237296465Sdelphij if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt)) 238296465Sdelphij goto err; 239296465Sdelphij if (BIO_printf(bp, "\n Responses:\n") <= 0) 240296465Sdelphij goto err; 241296465Sdelphij for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) { 242296465Sdelphij if (!sk_OCSP_SINGLERESP_value(rd->responses, i)) 243296465Sdelphij continue; 244296465Sdelphij single = sk_OCSP_SINGLERESP_value(rd->responses, i); 245296465Sdelphij cid = single->certId; 246296465Sdelphij if (ocsp_certid_print(bp, cid, 4) <= 0) 247296465Sdelphij goto err; 248296465Sdelphij cst = single->certStatus; 249296465Sdelphij if (BIO_printf(bp, " Cert Status: %s", 250296465Sdelphij OCSP_cert_status_str(cst->type)) <= 0) 251296465Sdelphij goto err; 252296465Sdelphij if (cst->type == V_OCSP_CERTSTATUS_REVOKED) { 253296465Sdelphij rev = cst->value.revoked; 254296465Sdelphij if (BIO_printf(bp, "\n Revocation Time: ") <= 0) 255296465Sdelphij goto err; 256296465Sdelphij if (!ASN1_GENERALIZEDTIME_print(bp, rev->revocationTime)) 257296465Sdelphij goto err; 258296465Sdelphij if (rev->revocationReason) { 259296465Sdelphij l = ASN1_ENUMERATED_get(rev->revocationReason); 260296465Sdelphij if (BIO_printf(bp, 261296465Sdelphij "\n Revocation Reason: %s (0x%lx)", 262296465Sdelphij OCSP_crl_reason_str(l), l) <= 0) 263296465Sdelphij goto err; 264296465Sdelphij } 265296465Sdelphij } 266296465Sdelphij if (BIO_printf(bp, "\n This Update: ") <= 0) 267296465Sdelphij goto err; 268296465Sdelphij if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate)) 269296465Sdelphij goto err; 270296465Sdelphij if (single->nextUpdate) { 271296465Sdelphij if (BIO_printf(bp, "\n Next Update: ") <= 0) 272296465Sdelphij goto err; 273296465Sdelphij if (!ASN1_GENERALIZEDTIME_print(bp, single->nextUpdate)) 274296465Sdelphij goto err; 275296465Sdelphij } 276296465Sdelphij if (BIO_write(bp, "\n", 1) <= 0) 277296465Sdelphij goto err; 278296465Sdelphij if (!X509V3_extensions_print(bp, 279296465Sdelphij "Response Single Extensions", 280296465Sdelphij single->singleExtensions, flags, 8)) 281296465Sdelphij goto err; 282296465Sdelphij if (BIO_write(bp, "\n", 1) <= 0) 283296465Sdelphij goto err; 284296465Sdelphij } 285296465Sdelphij if (!X509V3_extensions_print(bp, "Response Extensions", 286296465Sdelphij rd->responseExtensions, flags, 4)) 287296465Sdelphij goto err; 288296465Sdelphij if (X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0) 289296465Sdelphij goto err; 290109998Smarkm 291296465Sdelphij for (i = 0; i < sk_X509_num(br->certs); i++) { 292296465Sdelphij X509_print(bp, sk_X509_value(br->certs, i)); 293296465Sdelphij PEM_write_bio_X509(bp, sk_X509_value(br->certs, i)); 294296465Sdelphij } 295109998Smarkm 296296465Sdelphij ret = 1; 297296465Sdelphij err: 298296465Sdelphij OCSP_BASICRESP_free(br); 299296465Sdelphij return ret; 300296465Sdelphij} 301