1/* $OpenBSD: ct_prn.c,v 1.7 2023/07/08 07:22:58 beck Exp $ */ 2/* 3 * Written by Rob Stradling (rob@comodo.com) and Stephen Henson 4 * (steve@openssl.org) for the OpenSSL project 2014. 5 */ 6/* ==================================================================== 7 * Copyright (c) 2014 The OpenSSL Project. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. All advertising materials mentioning features or use of this 22 * software must display the following acknowledgment: 23 * "This product includes software developed by the OpenSSL Project 24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25 * 26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27 * endorse or promote products derived from this software without 28 * prior written permission. For written permission, please contact 29 * licensing@OpenSSL.org. 30 * 31 * 5. Products derived from this software may not be called "OpenSSL" 32 * nor may "OpenSSL" appear in their names without prior written 33 * permission of the OpenSSL Project. 34 * 35 * 6. Redistributions of any form whatsoever must retain the following 36 * acknowledgment: 37 * "This product includes software developed by the OpenSSL Project 38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51 * OF THE POSSIBILITY OF SUCH DAMAGE. 52 * ==================================================================== 53 * 54 * This product includes cryptographic software written by Eric Young 55 * (eay@cryptsoft.com). This product includes software written by Tim 56 * Hudson (tjh@cryptsoft.com). 57 * 58 */ 59 60#ifdef OPENSSL_NO_CT 61# error "CT is disabled" 62#endif 63 64#include <openssl/asn1.h> 65#include <openssl/bio.h> 66 67#include "ct_local.h" 68 69/* 70 * XXX public api in OpenSSL 1.1.0 but this is the only thing that uses it. 71 * so I am stuffing it here for the moment. 72 */ 73static int 74BIO_hex_string(BIO *out, int indent, int width, unsigned char *data, 75 int datalen) 76{ 77 int i, j = 0; 78 79 if (datalen < 1) 80 return 1; 81 82 for (i = 0; i < datalen - 1; i++) { 83 if (i && !j) 84 BIO_printf(out, "%*s", indent, ""); 85 86 BIO_printf(out, "%02X:", data[i]); 87 88 j = (j + 1) % width; 89 if (!j) 90 BIO_printf(out, "\n"); 91 } 92 93 if (i && !j) 94 BIO_printf(out, "%*s", indent, ""); 95 BIO_printf(out, "%02X", data[datalen - 1]); 96 return 1; 97} 98 99static void 100SCT_signature_algorithms_print(const SCT *sct, BIO *out) 101{ 102 int nid = SCT_get_signature_nid(sct); 103 104 if (nid == NID_undef) 105 BIO_printf(out, "%02X%02X", sct->hash_alg, sct->sig_alg); 106 else 107 BIO_printf(out, "%s", OBJ_nid2ln(nid)); 108} 109 110static void 111timestamp_print(uint64_t timestamp, BIO *out) 112{ 113 ASN1_GENERALIZEDTIME *gen = ASN1_GENERALIZEDTIME_new(); 114 char genstr[20]; 115 116 if (gen == NULL) 117 return; 118 ASN1_GENERALIZEDTIME_adj(gen, (time_t)0, (int)(timestamp / 86400000), 119 (timestamp % 86400000) / 1000); 120 /* 121 * Note GeneralizedTime from ASN1_GENERALIZETIME_adj is always 15 122 * characters long with a final Z. Update it with fractional seconds. 123 */ 124 snprintf(genstr, sizeof(genstr), "%.14sZ", ASN1_STRING_get0_data(gen)); 125 if (ASN1_GENERALIZEDTIME_set_string(gen, genstr)) 126 ASN1_GENERALIZEDTIME_print(out, gen); 127 ASN1_GENERALIZEDTIME_free(gen); 128} 129 130const char * 131SCT_validation_status_string(const SCT *sct) 132{ 133 switch (SCT_get_validation_status(sct)) { 134 case SCT_VALIDATION_STATUS_NOT_SET: 135 return "not set"; 136 case SCT_VALIDATION_STATUS_UNKNOWN_VERSION: 137 return "unknown version"; 138 case SCT_VALIDATION_STATUS_UNKNOWN_LOG: 139 return "unknown log"; 140 case SCT_VALIDATION_STATUS_UNVERIFIED: 141 return "unverified"; 142 case SCT_VALIDATION_STATUS_INVALID: 143 return "invalid"; 144 case SCT_VALIDATION_STATUS_VALID: 145 return "valid"; 146 } 147 return "unknown status"; 148} 149LCRYPTO_ALIAS(SCT_validation_status_string); 150 151void 152SCT_print(const SCT *sct, BIO *out, int indent, const CTLOG_STORE *log_store) 153{ 154 const CTLOG *log = NULL; 155 156 if (log_store != NULL) { 157 log = CTLOG_STORE_get0_log_by_id(log_store, sct->log_id, 158 sct->log_id_len); 159 } 160 161 BIO_printf(out, "%*sSigned Certificate Timestamp:", indent, ""); 162 BIO_printf(out, "\n%*sVersion : ", indent + 4, ""); 163 164 if (sct->version != SCT_VERSION_V1) { 165 BIO_printf(out, "unknown\n%*s", indent + 16, ""); 166 BIO_hex_string(out, indent + 16, 16, sct->sct, sct->sct_len); 167 return; 168 } 169 170 BIO_printf(out, "v1 (0x0)"); 171 172 if (log != NULL) { 173 BIO_printf(out, "\n%*sLog : %s", indent + 4, "", 174 CTLOG_get0_name(log)); 175 } 176 177 BIO_printf(out, "\n%*sLog ID : ", indent + 4, ""); 178 BIO_hex_string(out, indent + 16, 16, sct->log_id, sct->log_id_len); 179 180 BIO_printf(out, "\n%*sTimestamp : ", indent + 4, ""); 181 timestamp_print(sct->timestamp, out); 182 183 BIO_printf(out, "\n%*sExtensions: ", indent + 4, ""); 184 if (sct->ext_len == 0) 185 BIO_printf(out, "none"); 186 else 187 BIO_hex_string(out, indent + 16, 16, sct->ext, sct->ext_len); 188 189 BIO_printf(out, "\n%*sSignature : ", indent + 4, ""); 190 SCT_signature_algorithms_print(sct, out); 191 BIO_printf(out, "\n%*s ", indent + 4, ""); 192 BIO_hex_string(out, indent + 16, 16, sct->sig, sct->sig_len); 193} 194LCRYPTO_ALIAS(SCT_print); 195 196void 197SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent, 198 const char *separator, const CTLOG_STORE *log_store) 199{ 200 int sct_count = sk_SCT_num(sct_list); 201 int i; 202 203 for (i = 0; i < sct_count; ++i) { 204 SCT *sct = sk_SCT_value(sct_list, i); 205 206 SCT_print(sct, out, indent, log_store); 207 if (i < sk_SCT_num(sct_list) - 1) 208 BIO_printf(out, "%s", separator); 209 } 210} 211LCRYPTO_ALIAS(SCT_LIST_print); 212