1*25f6f224Stb /* $OpenBSD: ocsp_prn.c,v 1.11 2024/08/28 06:18:44 tb Exp $ */ 2da347917Sbeck /* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL 3da347917Sbeck * project. */ 4da347917Sbeck 5da347917Sbeck /* History: 6da347917Sbeck This file was originally part of ocsp.c and was transfered to Richard 7da347917Sbeck Levitte from CertCo by Kathy Weinhold in mid-spring 2000 to be included 8da347917Sbeck in OpenSSL or released as a patch kit. */ 9da347917Sbeck 10da347917Sbeck /* ==================================================================== 11da347917Sbeck * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 12da347917Sbeck * 13da347917Sbeck * Redistribution and use in source and binary forms, with or without 14da347917Sbeck * modification, are permitted provided that the following conditions 15da347917Sbeck * are met: 16da347917Sbeck * 17da347917Sbeck * 1. Redistributions of source code must retain the above copyright 18da347917Sbeck * notice, this list of conditions and the following disclaimer. 19da347917Sbeck * 20da347917Sbeck * 2. Redistributions in binary form must reproduce the above copyright 21da347917Sbeck * notice, this list of conditions and the following disclaimer in 22da347917Sbeck * the documentation and/or other materials provided with the 23da347917Sbeck * distribution. 24da347917Sbeck * 25da347917Sbeck * 3. All advertising materials mentioning features or use of this 26da347917Sbeck * software must display the following acknowledgment: 27da347917Sbeck * "This product includes software developed by the OpenSSL Project 28da347917Sbeck * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 29da347917Sbeck * 30da347917Sbeck * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 31da347917Sbeck * endorse or promote products derived from this software without 32da347917Sbeck * prior written permission. For written permission, please contact 33da347917Sbeck * openssl-core@openssl.org. 34da347917Sbeck * 35da347917Sbeck * 5. Products derived from this software may not be called "OpenSSL" 36da347917Sbeck * nor may "OpenSSL" appear in their names without prior written 37da347917Sbeck * permission of the OpenSSL Project. 38da347917Sbeck * 39da347917Sbeck * 6. Redistributions of any form whatsoever must retain the following 40da347917Sbeck * acknowledgment: 41da347917Sbeck * "This product includes software developed by the OpenSSL Project 42da347917Sbeck * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 43da347917Sbeck * 44da347917Sbeck * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 45da347917Sbeck * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 46da347917Sbeck * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 47da347917Sbeck * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 48da347917Sbeck * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 49da347917Sbeck * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50da347917Sbeck * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 51da347917Sbeck * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52da347917Sbeck * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 53da347917Sbeck * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 54da347917Sbeck * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 55da347917Sbeck * OF THE POSSIBILITY OF SUCH DAMAGE. 56da347917Sbeck * ==================================================================== 57da347917Sbeck * 58da347917Sbeck * This product includes cryptographic software written by Eric Young 59da347917Sbeck * (eay@cryptsoft.com). This product includes software written by Tim 60da347917Sbeck * Hudson (tjh@cryptsoft.com). 61da347917Sbeck * 62da347917Sbeck */ 63da347917Sbeck 64da347917Sbeck #include <openssl/bio.h> 65da347917Sbeck #include <openssl/err.h> 66da347917Sbeck #include <openssl/ocsp.h> 67da347917Sbeck #include <openssl/pem.h> 68*25f6f224Stb #include <openssl/x509.h> 69da347917Sbeck 709f44a700Stb #include "ocsp_local.h" 719f44a700Stb 722d2941d0Smiod static int 732d2941d0Smiod ocsp_certid_print(BIO *bp, OCSP_CERTID* a, int indent) 74da347917Sbeck { 75*25f6f224Stb const ASN1_OBJECT *aobj; 76*25f6f224Stb 77da347917Sbeck BIO_printf(bp, "%*sCertificate ID:\n", indent, ""); 78da347917Sbeck indent += 2; 79da347917Sbeck BIO_printf(bp, "%*sHash Algorithm: ", indent, ""); 80*25f6f224Stb X509_ALGOR_get0(&aobj, NULL, NULL, a->hashAlgorithm); 81*25f6f224Stb i2a_ASN1_OBJECT(bp, aobj); 82da347917Sbeck BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, ""); 83da347917Sbeck i2a_ASN1_STRING(bp, a->issuerNameHash, V_ASN1_OCTET_STRING); 84da347917Sbeck BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, ""); 85da347917Sbeck i2a_ASN1_STRING(bp, a->issuerKeyHash, V_ASN1_OCTET_STRING); 86da347917Sbeck BIO_printf(bp, "\n%*sSerial Number: ", indent, ""); 87da347917Sbeck i2a_ASN1_INTEGER(bp, a->serialNumber); 88da347917Sbeck BIO_printf(bp, "\n"); 89da347917Sbeck return 1; 90da347917Sbeck } 91da347917Sbeck 922d2941d0Smiod typedef struct { 93da347917Sbeck long t; 940a5d6edeSdjm const char *m; 95da347917Sbeck } OCSP_TBLSTR; 96da347917Sbeck 972d2941d0Smiod static const char * 982d2941d0Smiod table2string(long s, const OCSP_TBLSTR *ts, int len) 99da347917Sbeck { 1000a5d6edeSdjm const OCSP_TBLSTR *p; 1012d2941d0Smiod 102da347917Sbeck for (p = ts; p < ts + len; p++) 103da347917Sbeck if (p->t == s) 104da347917Sbeck return p->m; 105da347917Sbeck return "(UNKNOWN)"; 106da347917Sbeck } 107da347917Sbeck 1082d2941d0Smiod const char * 1092d2941d0Smiod OCSP_response_status_str(long s) 110da347917Sbeck { 1110a5d6edeSdjm static const OCSP_TBLSTR rstat_tbl[] = { 112da347917Sbeck { OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful" }, 113da347917Sbeck { OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest" }, 114da347917Sbeck { OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror" }, 115da347917Sbeck { OCSP_RESPONSE_STATUS_TRYLATER, "trylater" }, 116da347917Sbeck { OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired" }, 1172d2941d0Smiod { OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized" } 1182d2941d0Smiod }; 119da347917Sbeck return table2string(s, rstat_tbl, 6); 120da347917Sbeck } 121a1e92f6bSbeck LCRYPTO_ALIAS(OCSP_response_status_str); 122da347917Sbeck 1232d2941d0Smiod const char * 1242d2941d0Smiod OCSP_cert_status_str(long s) 125da347917Sbeck { 1260a5d6edeSdjm static const OCSP_TBLSTR cstat_tbl[] = { 127da347917Sbeck { V_OCSP_CERTSTATUS_GOOD, "good" }, 128da347917Sbeck { V_OCSP_CERTSTATUS_REVOKED, "revoked" }, 1292d2941d0Smiod { V_OCSP_CERTSTATUS_UNKNOWN, "unknown" } 1302d2941d0Smiod }; 131da347917Sbeck return table2string(s, cstat_tbl, 3); 132da347917Sbeck } 133a1e92f6bSbeck LCRYPTO_ALIAS(OCSP_cert_status_str); 134da347917Sbeck 1352d2941d0Smiod const char * 1362d2941d0Smiod OCSP_crl_reason_str(long s) 137da347917Sbeck { 1380a5d6edeSdjm static const OCSP_TBLSTR reason_tbl[] = { 139da347917Sbeck { OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified" }, 140da347917Sbeck { OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise" }, 141da347917Sbeck { OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise" }, 142da347917Sbeck { OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged" }, 143da347917Sbeck { OCSP_REVOKED_STATUS_SUPERSEDED, "superseded" }, 144da347917Sbeck { OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation" }, 145da347917Sbeck { OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold" }, 1462d2941d0Smiod { OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL" } 1472d2941d0Smiod }; 148da347917Sbeck return table2string(s, reason_tbl, 8); 149da347917Sbeck } 150a1e92f6bSbeck LCRYPTO_ALIAS(OCSP_crl_reason_str); 151da347917Sbeck 1522d2941d0Smiod int 1532d2941d0Smiod OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* o, unsigned long flags) 154da347917Sbeck { 155da347917Sbeck int i; 156da347917Sbeck long l; 157da347917Sbeck OCSP_CERTID* cid = NULL; 158da347917Sbeck OCSP_ONEREQ *one = NULL; 159da347917Sbeck OCSP_REQINFO *inf = o->tbsRequest; 160da347917Sbeck OCSP_SIGNATURE *sig = o->optionalSignature; 161da347917Sbeck 1622d2941d0Smiod if (BIO_write(bp, "OCSP Request Data:\n", 19) <= 0) 1632d2941d0Smiod goto err; 164da347917Sbeck l = ASN1_INTEGER_get(inf->version); 1652d2941d0Smiod if (BIO_printf(bp, " Version: %lu (0x%lx)", l+1, l) <= 0) 1662d2941d0Smiod goto err; 1672d2941d0Smiod if (inf->requestorName != NULL) { 168da347917Sbeck if (BIO_write(bp, "\n Requestor Name: ", 21) <= 0) 169da347917Sbeck goto err; 170da347917Sbeck GENERAL_NAME_print(bp, inf->requestorName); 171da347917Sbeck } 1722d2941d0Smiod if (BIO_write(bp, "\n Requestor List:\n", 21) <= 0) 1732d2941d0Smiod goto err; 1742d2941d0Smiod for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++) { 175da347917Sbeck one = sk_OCSP_ONEREQ_value(inf->requestList, i); 176da347917Sbeck cid = one->reqCert; 177da347917Sbeck ocsp_certid_print(bp, cid, 8); 1782d2941d0Smiod if (!X509V3_extensions_print(bp, "Request Single Extensions", 179da347917Sbeck one->singleRequestExtensions, flags, 8)) 180da347917Sbeck goto err; 181da347917Sbeck } 182da347917Sbeck if (!X509V3_extensions_print(bp, "Request Extensions", 183da347917Sbeck inf->requestExtensions, flags, 4)) 184da347917Sbeck goto err; 1852d2941d0Smiod if (sig) { 186965ef272Smiod if (X509_signature_print(bp, sig->signatureAlgorithm, 187965ef272Smiod sig->signature) == 0) 188965ef272Smiod goto err; 1892d2941d0Smiod for (i = 0; i < sk_X509_num(sig->certs); i++) { 190965ef272Smiod if (X509_print(bp, sk_X509_value(sig->certs, i)) == 0) 191965ef272Smiod goto err; 192965ef272Smiod if (PEM_write_bio_X509(bp, 193965ef272Smiod sk_X509_value(sig->certs, i)) == 0) 194965ef272Smiod goto err; 195da347917Sbeck } 196da347917Sbeck } 197da347917Sbeck return 1; 198bc775f6cSjsing 199da347917Sbeck err: 200da347917Sbeck return 0; 201da347917Sbeck } 202a1e92f6bSbeck LCRYPTO_ALIAS(OCSP_REQUEST_print); 203da347917Sbeck 2042d2941d0Smiod int 2052d2941d0Smiod OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags) 206da347917Sbeck { 207da347917Sbeck int i, ret = 0; 208da347917Sbeck long l; 209da347917Sbeck OCSP_CERTID *cid = NULL; 210da347917Sbeck OCSP_BASICRESP *br = NULL; 211da347917Sbeck OCSP_RESPID *rid = NULL; 212da347917Sbeck OCSP_RESPDATA *rd = NULL; 213da347917Sbeck OCSP_CERTSTATUS *cst = NULL; 214da347917Sbeck OCSP_REVOKEDINFO *rev = NULL; 215da347917Sbeck OCSP_SINGLERESP *single = NULL; 216da347917Sbeck OCSP_RESPBYTES *rb = o->responseBytes; 217da347917Sbeck 2182d2941d0Smiod if (BIO_puts(bp, "OCSP Response Data:\n") <= 0) 2192d2941d0Smiod goto err; 220da347917Sbeck l = ASN1_ENUMERATED_get(o->responseStatus); 2215650a0e1Sdjm if (BIO_printf(bp, " OCSP Response Status: %s (0x%lx)\n", 2222d2941d0Smiod OCSP_response_status_str(l), l) <= 0) 2232d2941d0Smiod goto err; 2242d2941d0Smiod if (rb == NULL) 2252d2941d0Smiod return 1; 226da347917Sbeck if (BIO_puts(bp, " Response Type: ") <= 0) 227da347917Sbeck goto err; 228da347917Sbeck if (i2a_ASN1_OBJECT(bp, rb->responseType) <= 0) 229da347917Sbeck goto err; 2302d2941d0Smiod if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) { 231da347917Sbeck BIO_puts(bp, " (unknown response type)\n"); 232da347917Sbeck return 1; 233da347917Sbeck } 234da347917Sbeck 235da347917Sbeck i = ASN1_STRING_length(rb->response); 2362d2941d0Smiod if (!(br = OCSP_response_get1_basic(o))) 2372d2941d0Smiod goto err; 238da347917Sbeck rd = br->tbsResponseData; 239da347917Sbeck l = ASN1_INTEGER_get(rd->version); 2402d2941d0Smiod if (BIO_printf(bp, "\n Version: %lu (0x%lx)\n", l+1, l) <= 0) 2412d2941d0Smiod goto err; 2422d2941d0Smiod if (BIO_puts(bp, " Responder Id: ") <= 0) 2432d2941d0Smiod goto err; 244da347917Sbeck 245da347917Sbeck rid = rd->responderId; 2462d2941d0Smiod switch (rid->type) { 247da347917Sbeck case V_OCSP_RESPID_NAME: 248da347917Sbeck X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE); 249da347917Sbeck break; 250da347917Sbeck case V_OCSP_RESPID_KEY: 251da347917Sbeck i2a_ASN1_STRING(bp, rid->value.byKey, V_ASN1_OCTET_STRING); 252da347917Sbeck break; 253da347917Sbeck } 254da347917Sbeck 2552d2941d0Smiod if (BIO_printf(bp, "\n Produced At: ")<=0) 2562d2941d0Smiod goto err; 2572d2941d0Smiod if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt)) 2582d2941d0Smiod goto err; 2592d2941d0Smiod if (BIO_printf(bp, "\n Responses:\n") <= 0) 2602d2941d0Smiod goto err; 2612d2941d0Smiod for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) { 2622d2941d0Smiod if (! sk_OCSP_SINGLERESP_value(rd->responses, i)) 2632d2941d0Smiod continue; 264da347917Sbeck single = sk_OCSP_SINGLERESP_value(rd->responses, i); 265da347917Sbeck cid = single->certId; 2662d2941d0Smiod if (ocsp_certid_print(bp, cid, 4) <= 0) 2672d2941d0Smiod goto err; 268da347917Sbeck cst = single->certStatus; 269da347917Sbeck if (BIO_printf(bp, " Cert Status: %s", 270da347917Sbeck OCSP_cert_status_str(cst->type)) <= 0) 271da347917Sbeck goto err; 2722d2941d0Smiod if (cst->type == V_OCSP_CERTSTATUS_REVOKED) { 273da347917Sbeck rev = cst->value.revoked; 274da347917Sbeck if (BIO_printf(bp, "\n Revocation Time: ") <= 0) 275da347917Sbeck goto err; 276da347917Sbeck if (!ASN1_GENERALIZEDTIME_print(bp, 277da347917Sbeck rev->revocationTime)) 278da347917Sbeck goto err; 2792d2941d0Smiod if (rev->revocationReason) { 280da347917Sbeck l = ASN1_ENUMERATED_get(rev->revocationReason); 281da347917Sbeck if (BIO_printf(bp, 2825650a0e1Sdjm "\n Revocation Reason: %s (0x%lx)", 283da347917Sbeck OCSP_crl_reason_str(l), l) <= 0) 284da347917Sbeck goto err; 285da347917Sbeck } 286da347917Sbeck } 2872d2941d0Smiod if (BIO_printf(bp, "\n This Update: ") <= 0) 2882d2941d0Smiod goto err; 289da347917Sbeck if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate)) 290da347917Sbeck goto err; 2912d2941d0Smiod if (single->nextUpdate) { 2922d2941d0Smiod if (BIO_printf(bp, "\n Next Update: ") <= 0) 2932d2941d0Smiod goto err; 294da347917Sbeck if (!ASN1_GENERALIZEDTIME_print(bp, single->nextUpdate)) 295da347917Sbeck goto err; 296da347917Sbeck } 2972d2941d0Smiod if (BIO_write(bp, "\n", 1) <= 0) 2982d2941d0Smiod goto err; 2992d2941d0Smiod if (!X509V3_extensions_print(bp, "Response Single Extensions", 300da347917Sbeck single->singleExtensions, flags, 8)) 301da347917Sbeck goto err; 3022d2941d0Smiod if (BIO_write(bp, "\n", 1) <= 0) 3032d2941d0Smiod goto err; 304da347917Sbeck } 305da347917Sbeck if (!X509V3_extensions_print(bp, "Response Extensions", 306da347917Sbeck rd->responseExtensions, flags, 4)) 3070a5d6edeSdjm goto err; 3082d2941d0Smiod if (X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 3092d2941d0Smiod 0) 310da347917Sbeck goto err; 311da347917Sbeck 3122d2941d0Smiod for (i = 0; i < sk_X509_num(br->certs); i++) { 313da347917Sbeck X509_print(bp, sk_X509_value(br->certs, i)); 314da347917Sbeck PEM_write_bio_X509(bp, sk_X509_value(br->certs, i)); 315da347917Sbeck } 316da347917Sbeck 317da347917Sbeck ret = 1; 318bc775f6cSjsing 319da347917Sbeck err: 320da347917Sbeck OCSP_BASICRESP_free(br); 321da347917Sbeck return ret; 322da347917Sbeck } 323a1e92f6bSbeck LCRYPTO_ALIAS(OCSP_RESPONSE_print); 324