1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "net/cert/ct_signed_certificate_timestamp_log_param.h" 6 7#include <algorithm> 8#include <string> 9 10#include "base/base64.h" 11#include "base/strings/string_number_conversions.h" 12#include "base/strings/stringprintf.h" 13#include "base/values.h" 14#include "net/cert/ct_verify_result.h" 15#include "net/cert/signed_certificate_timestamp.h" 16 17namespace net { 18 19namespace { 20 21// Converts a numeric |origin| to text describing the SCT's origin 22const char* OriginToString(ct::SignedCertificateTimestamp::Origin origin) { 23 switch (origin) { 24 case ct::SignedCertificateTimestamp::SCT_EMBEDDED: 25 return "embedded_in_certificate"; 26 case ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION: 27 return "tls_extension"; 28 case ct::SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE: 29 return "ocsp"; 30 case ct::SignedCertificateTimestamp::SCT_ORIGIN_MAX: 31 break; 32 } 33 34 return "unknown"; 35} 36 37// Converts a numeric |hash_algorithm| to its textual representation 38const char* HashAlgorithmToString( 39 ct::DigitallySigned::HashAlgorithm hash_algorithm) { 40 switch (hash_algorithm) { 41 case ct::DigitallySigned::HASH_ALGO_NONE: 42 return "NONE"; 43 case ct::DigitallySigned::HASH_ALGO_MD5: 44 return "MD5"; 45 case ct::DigitallySigned::HASH_ALGO_SHA1: 46 return "SHA1"; 47 case ct::DigitallySigned::HASH_ALGO_SHA224: 48 return "SHA224"; 49 case ct::DigitallySigned::HASH_ALGO_SHA256: 50 return "SHA256"; 51 case ct::DigitallySigned::HASH_ALGO_SHA384: 52 return "SHA384"; 53 case ct::DigitallySigned::HASH_ALGO_SHA512: 54 return "SHA512"; 55 } 56 57 return "unknown"; 58} 59 60// Converts a numeric |signature_algorithm| to its textual representation 61const char* SignatureAlgorithmToString( 62 ct::DigitallySigned::SignatureAlgorithm signature_algorithm) { 63 switch (signature_algorithm) { 64 case ct::DigitallySigned::SIG_ALGO_ANONYMOUS: 65 return "ANONYMOUS"; 66 case ct::DigitallySigned::SIG_ALGO_RSA: 67 return "RSA"; 68 case ct::DigitallySigned::SIG_ALGO_DSA: 69 return "DSA"; 70 case ct::DigitallySigned::SIG_ALGO_ECDSA: 71 return "ECDSA"; 72 } 73 74 return "unknown"; 75} 76 77// Base64 encode the given |value| string and put it in |dict| with the 78// description |key|. 79void SetBinaryData( 80 const char* key, 81 const std::string& value, 82 base::DictionaryValue* dict) { 83 std::string b64_value; 84 base::Base64Encode(value, &b64_value); 85 86 dict->SetString(key, b64_value); 87} 88 89// Returns a dictionary where each key is a field of the SCT and its value 90// is this field's value in the SCT. This dictionary is meant to be used for 91// outputting a de-serialized SCT to the NetLog. 92base::DictionaryValue* SCTToDictionary( 93 const ct::SignedCertificateTimestamp& sct) { 94 base::DictionaryValue* out = new base::DictionaryValue(); 95 96 out->SetString("origin", OriginToString(sct.origin)); 97 out->SetInteger("version", sct.version); 98 99 SetBinaryData("log_id", sct.log_id, out); 100 base::TimeDelta time_since_unix_epoch = 101 sct.timestamp - base::Time::UnixEpoch(); 102 out->SetString("timestamp", 103 base::Int64ToString(time_since_unix_epoch.InMilliseconds())); 104 SetBinaryData("extensions", sct.extensions, out); 105 106 out->SetString("hash_algorithm", 107 HashAlgorithmToString(sct.signature.hash_algorithm)); 108 out->SetString("signature_algorithm", 109 SignatureAlgorithmToString(sct.signature.signature_algorithm)); 110 SetBinaryData( 111 "signature_data", sct.signature.signature_data, out); 112 113 return out; 114} 115 116// Given a list of SCTs, return a ListValue instance where each item in the 117// list is a dictionary created by SCTToDictionary. 118base::ListValue* SCTListToPrintableValues( 119 const ct::SCTList& sct_list) { 120 base::ListValue* output_scts = new base::ListValue(); 121 for (ct::SCTList::const_iterator it = sct_list.begin(); 122 it != sct_list.end(); 123 ++it) 124 output_scts->Append(SCTToDictionary(*(it->get()))); 125 126 return output_scts; 127} 128 129} // namespace 130 131base::Value* NetLogSignedCertificateTimestampCallback( 132 const ct::CTVerifyResult* ct_result, NetLog::LogLevel log_level) { 133 base::DictionaryValue* dict = new base::DictionaryValue(); 134 135 dict->Set("verified_scts", 136 SCTListToPrintableValues(ct_result->verified_scts)); 137 138 dict->Set("invalid_scts", 139 SCTListToPrintableValues(ct_result->invalid_scts)); 140 141 dict->Set("unknown_logs_scts", 142 SCTListToPrintableValues(ct_result->unknown_logs_scts)); 143 144 return dict; 145} 146 147base::Value* NetLogRawSignedCertificateTimestampCallback( 148 const std::string* embedded_scts, 149 const std::string* sct_list_from_ocsp, 150 const std::string* sct_list_from_tls_extension, 151 NetLog::LogLevel log_level) { 152 base::DictionaryValue* dict = new base::DictionaryValue(); 153 154 SetBinaryData("embedded_scts", *embedded_scts, dict); 155 SetBinaryData("scts_from_ocsp_response", *sct_list_from_ocsp, dict); 156 SetBinaryData("scts_from_tls_extension", *sct_list_from_tls_extension, dict); 157 158 return dict; 159} 160 161} // namespace net 162