1 /* $OpenBSD: ct_prn.c,v 1.6 2021/12/18 16:34:52 tb 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 */ 73 static int 74 BIO_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 99 static void 100 SCT_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 110 static void 111 timestamp_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 130 const char * 131 SCT_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 } 149 150 void 151 SCT_print(const SCT *sct, BIO *out, int indent, const CTLOG_STORE *log_store) 152 { 153 const CTLOG *log = NULL; 154 155 if (log_store != NULL) { 156 log = CTLOG_STORE_get0_log_by_id(log_store, sct->log_id, 157 sct->log_id_len); 158 } 159 160 BIO_printf(out, "%*sSigned Certificate Timestamp:", indent, ""); 161 BIO_printf(out, "\n%*sVersion : ", indent + 4, ""); 162 163 if (sct->version != SCT_VERSION_V1) { 164 BIO_printf(out, "unknown\n%*s", indent + 16, ""); 165 BIO_hex_string(out, indent + 16, 16, sct->sct, sct->sct_len); 166 return; 167 } 168 169 BIO_printf(out, "v1 (0x0)"); 170 171 if (log != NULL) { 172 BIO_printf(out, "\n%*sLog : %s", indent + 4, "", 173 CTLOG_get0_name(log)); 174 } 175 176 BIO_printf(out, "\n%*sLog ID : ", indent + 4, ""); 177 BIO_hex_string(out, indent + 16, 16, sct->log_id, sct->log_id_len); 178 179 BIO_printf(out, "\n%*sTimestamp : ", indent + 4, ""); 180 timestamp_print(sct->timestamp, out); 181 182 BIO_printf(out, "\n%*sExtensions: ", indent + 4, ""); 183 if (sct->ext_len == 0) 184 BIO_printf(out, "none"); 185 else 186 BIO_hex_string(out, indent + 16, 16, sct->ext, sct->ext_len); 187 188 BIO_printf(out, "\n%*sSignature : ", indent + 4, ""); 189 SCT_signature_algorithms_print(sct, out); 190 BIO_printf(out, "\n%*s ", indent + 4, ""); 191 BIO_hex_string(out, indent + 16, 16, sct->sig, sct->sig_len); 192 } 193 194 void 195 SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent, 196 const char *separator, const CTLOG_STORE *log_store) 197 { 198 int sct_count = sk_SCT_num(sct_list); 199 int i; 200 201 for (i = 0; i < sct_count; ++i) { 202 SCT *sct = sk_SCT_value(sct_list, i); 203 204 SCT_print(sct, out, indent, log_store); 205 if (i < sk_SCT_num(sct_list) - 1) 206 BIO_printf(out, "%s", separator); 207 } 208 } 209