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