1 /* 2 * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #ifdef OPENSSL_NO_CT 11 # error "CT is disabled" 12 #endif 13 14 #include <openssl/asn1.h> 15 #include <openssl/bio.h> 16 17 #include "ct_local.h" 18 19 static void SCT_signature_algorithms_print(const SCT *sct, BIO *out) 20 { 21 int nid = SCT_get_signature_nid(sct); 22 23 if (nid == NID_undef) 24 BIO_printf(out, "%02X%02X", sct->hash_alg, sct->sig_alg); 25 else 26 BIO_printf(out, "%s", OBJ_nid2ln(nid)); 27 } 28 29 static void timestamp_print(uint64_t timestamp, BIO *out) 30 { 31 ASN1_GENERALIZEDTIME *gen = ASN1_GENERALIZEDTIME_new(); 32 char genstr[20]; 33 34 if (gen == NULL) 35 return; 36 ASN1_GENERALIZEDTIME_adj(gen, (time_t)0, 37 (int)(timestamp / 86400000), 38 (timestamp % 86400000) / 1000); 39 /* 40 * Note GeneralizedTime from ASN1_GENERALIZETIME_adj is always 15 41 * characters long with a final Z. Update it with fractional seconds. 42 */ 43 BIO_snprintf(genstr, sizeof(genstr), "%.14s.%03dZ", 44 ASN1_STRING_get0_data(gen), (unsigned int)(timestamp % 1000)); 45 if (ASN1_GENERALIZEDTIME_set_string(gen, genstr)) 46 ASN1_GENERALIZEDTIME_print(out, gen); 47 ASN1_GENERALIZEDTIME_free(gen); 48 } 49 50 const char *SCT_validation_status_string(const SCT *sct) 51 { 52 53 switch (SCT_get_validation_status(sct)) { 54 case SCT_VALIDATION_STATUS_NOT_SET: 55 return "not set"; 56 case SCT_VALIDATION_STATUS_UNKNOWN_VERSION: 57 return "unknown version"; 58 case SCT_VALIDATION_STATUS_UNKNOWN_LOG: 59 return "unknown log"; 60 case SCT_VALIDATION_STATUS_UNVERIFIED: 61 return "unverified"; 62 case SCT_VALIDATION_STATUS_INVALID: 63 return "invalid"; 64 case SCT_VALIDATION_STATUS_VALID: 65 return "valid"; 66 } 67 return "unknown status"; 68 } 69 70 void SCT_print(const SCT *sct, BIO *out, int indent, 71 const CTLOG_STORE *log_store) 72 { 73 const CTLOG *log = NULL; 74 75 if (log_store != NULL) { 76 log = CTLOG_STORE_get0_log_by_id(log_store, sct->log_id, 77 sct->log_id_len); 78 } 79 80 BIO_printf(out, "%*sSigned Certificate Timestamp:", indent, ""); 81 BIO_printf(out, "\n%*sVersion : ", indent + 4, ""); 82 83 if (sct->version != SCT_VERSION_V1) { 84 BIO_printf(out, "unknown\n%*s", indent + 16, ""); 85 BIO_hex_string(out, indent + 16, 16, sct->sct, sct->sct_len); 86 return; 87 } 88 89 BIO_printf(out, "v1 (0x0)"); 90 91 if (log != NULL) { 92 BIO_printf(out, "\n%*sLog : %s", indent + 4, "", 93 CTLOG_get0_name(log)); 94 } 95 96 BIO_printf(out, "\n%*sLog ID : ", indent + 4, ""); 97 BIO_hex_string(out, indent + 16, 16, sct->log_id, sct->log_id_len); 98 99 BIO_printf(out, "\n%*sTimestamp : ", indent + 4, ""); 100 timestamp_print(sct->timestamp, out); 101 102 BIO_printf(out, "\n%*sExtensions: ", indent + 4, ""); 103 if (sct->ext_len == 0) 104 BIO_printf(out, "none"); 105 else 106 BIO_hex_string(out, indent + 16, 16, sct->ext, sct->ext_len); 107 108 BIO_printf(out, "\n%*sSignature : ", indent + 4, ""); 109 SCT_signature_algorithms_print(sct, out); 110 BIO_printf(out, "\n%*s ", indent + 4, ""); 111 BIO_hex_string(out, indent + 16, 16, sct->sig, sct->sig_len); 112 } 113 114 void SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent, 115 const char *separator, const CTLOG_STORE *log_store) 116 { 117 int sct_count = sk_SCT_num(sct_list); 118 int i; 119 120 for (i = 0; i < sct_count; ++i) { 121 SCT *sct = sk_SCT_value(sct_list, i); 122 123 SCT_print(sct, out, indent, log_store); 124 if (i < sk_SCT_num(sct_list) - 1) 125 BIO_printf(out, "%s", separator); 126 } 127 } 128