Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(291)

Side by Side Diff: chrome/browser/ssl/chrome_expect_ct_reporter.cc

Issue 2960163002: Revert of Update SCT serialization format in Expect-CT reports (Closed)
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ssl/chrome_expect_ct_reporter.h" 5 #include "chrome/browser/ssl/chrome_expect_ct_reporter.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/base64.h" 9 #include "base/base64.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/feature_list.h" 11 #include "base/feature_list.h"
12 #include "base/json/json_writer.h" 12 #include "base/json/json_writer.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/metrics/sparse_histogram.h" 15 #include "base/metrics/sparse_histogram.h"
16 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
18 #include "base/values.h" 18 #include "base/values.h"
19 #include "chrome/common/chrome_features.h" 19 #include "chrome/common/chrome_features.h"
20 #include "net/cert/ct_serialization.h"
21 #include "net/traffic_annotation/network_traffic_annotation.h" 20 #include "net/traffic_annotation/network_traffic_annotation.h"
22 #include "net/url_request/report_sender.h" 21 #include "net/url_request/report_sender.h"
23 22
24 namespace { 23 namespace {
25 24
26 std::string TimeToISO8601(const base::Time& t) { 25 std::string TimeToISO8601(const base::Time& t) {
27 base::Time::Exploded exploded; 26 base::Time::Exploded exploded;
28 t.UTCExplode(&exploded); 27 t.UTCExplode(&exploded);
29 return base::StringPrintf( 28 return base::StringPrintf(
30 "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", exploded.year, exploded.month, 29 "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", exploded.year, exploded.month,
(...skipping 14 matching lines...) Expand all
45 44
46 return result; 45 return result;
47 } 46 }
48 47
49 std::string SCTOriginToString( 48 std::string SCTOriginToString(
50 net::ct::SignedCertificateTimestamp::Origin origin) { 49 net::ct::SignedCertificateTimestamp::Origin origin) {
51 switch (origin) { 50 switch (origin) {
52 case net::ct::SignedCertificateTimestamp::SCT_EMBEDDED: 51 case net::ct::SignedCertificateTimestamp::SCT_EMBEDDED:
53 return "embedded"; 52 return "embedded";
54 case net::ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION: 53 case net::ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION:
55 return "tls-extension"; 54 return "from-tls-extension";
56 case net::ct::SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE: 55 case net::ct::SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE:
57 return "ocsp"; 56 return "from-ocsp-response";
58 case net::ct::SignedCertificateTimestamp::SCT_ORIGIN_MAX: 57 default:
59 NOTREACHED(); 58 NOTREACHED();
60 } 59 }
61 return ""; 60 return "";
62 } 61 }
63 62
64 void AddSCT(const net::SignedCertificateTimestampAndStatus& sct, 63 void AddUnknownSCT(
65 base::ListValue* list) { 64 const net::SignedCertificateTimestampAndStatus& sct_and_status,
65 base::ListValue* list) {
66 std::unique_ptr<base::DictionaryValue> list_item(new base::DictionaryValue()); 66 std::unique_ptr<base::DictionaryValue> list_item(new base::DictionaryValue());
67 // Chrome implements RFC6962, not 6962-bis, so the reports contain v1 SCTs. 67 list_item->SetString("origin", SCTOriginToString(sct_and_status.sct->origin));
68 list_item->SetInteger("version", 1);
69 std::string status;
70 switch (sct.status) {
71 case net::ct::SCT_STATUS_LOG_UNKNOWN:
72 status = "unknown";
73 break;
74 case net::ct::SCT_STATUS_INVALID_SIGNATURE:
75 case net::ct::SCT_STATUS_INVALID_TIMESTAMP:
76 status = "invalid";
77 break;
78 case net::ct::SCT_STATUS_OK:
79 status = "valid";
80 break;
81 case net::ct::SCT_STATUS_NONE:
82 NOTREACHED();
83 }
84 list_item->SetString("status", status);
85 list_item->SetString("source", SCTOriginToString(sct.sct->origin));
86 std::string serialized_sct;
87 net::ct::EncodeSignedCertificateTimestamp(sct.sct, &serialized_sct);
88 std::string encoded_serialized_sct;
89 base::Base64Encode(serialized_sct, &encoded_serialized_sct);
90 list_item->SetString("serialized_sct", encoded_serialized_sct);
91 list->Append(std::move(list_item)); 68 list->Append(std::move(list_item));
92 } 69 }
93 70
71 void AddInvalidSCT(
72 const net::SignedCertificateTimestampAndStatus& sct_and_status,
73 base::ListValue* list) {
74 std::unique_ptr<base::DictionaryValue> list_item(new base::DictionaryValue());
75 list_item->SetString("origin", SCTOriginToString(sct_and_status.sct->origin));
76 std::string log_id;
77 base::Base64Encode(sct_and_status.sct->log_id, &log_id);
78 list_item->SetString("id", log_id);
79 list->Append(std::move(list_item));
80 }
81
82 void AddValidSCT(const net::SignedCertificateTimestampAndStatus& sct_and_status,
83 base::ListValue* list) {
84 std::unique_ptr<base::DictionaryValue> list_item(new base::DictionaryValue());
85 list_item->SetString("origin", SCTOriginToString(sct_and_status.sct->origin));
86
87 // The structure of the SCT object is defined in
88 // http://tools.ietf.org/html/rfc6962#section-4.1.
89 std::unique_ptr<base::DictionaryValue> sct(new base::DictionaryValue());
90 sct->SetInteger("sct_version", sct_and_status.sct->version);
91 std::string log_id;
92 base::Base64Encode(sct_and_status.sct->log_id, &log_id);
93 sct->SetString("id", log_id);
94 base::TimeDelta timestamp =
95 sct_and_status.sct->timestamp - base::Time::UnixEpoch();
96 sct->SetString("timestamp", base::Int64ToString(timestamp.InMilliseconds()));
97 std::string extensions;
98 base::Base64Encode(sct_and_status.sct->extensions, &extensions);
99 sct->SetString("extensions", extensions);
100 std::string signature;
101 base::Base64Encode(sct_and_status.sct->signature.signature_data, &signature);
102 sct->SetString("signature", signature);
103
104 list_item->Set("sct", std::move(sct));
105 list->Append(std::move(list_item));
106 }
107
94 // Records an UMA histogram of the net errors when Expect CT reports 108 // Records an UMA histogram of the net errors when Expect CT reports
95 // fail to send. 109 // fail to send.
96 void RecordUMAOnFailure(const GURL& report_uri, 110 void RecordUMAOnFailure(const GURL& report_uri,
97 int net_error, 111 int net_error,
98 int http_response_code) { 112 int http_response_code) {
99 UMA_HISTOGRAM_SPARSE_SLOWLY("SSL.ExpectCTReportFailure2", -net_error); 113 UMA_HISTOGRAM_SPARSE_SLOWLY("SSL.ExpectCTReportFailure2", -net_error);
100 } 114 }
101 115
102 constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation = 116 constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
103 net::DefineNetworkTrafficAnnotation("chrome_expect_ct_reporter", R"( 117 net::DefineNetworkTrafficAnnotation("chrome_expect_ct_reporter", R"(
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 const net::X509Certificate* validated_certificate_chain, 154 const net::X509Certificate* validated_certificate_chain,
141 const net::X509Certificate* served_certificate_chain, 155 const net::X509Certificate* served_certificate_chain,
142 const net::SignedCertificateTimestampAndStatusList& 156 const net::SignedCertificateTimestampAndStatusList&
143 signed_certificate_timestamps) { 157 signed_certificate_timestamps) {
144 if (report_uri.is_empty()) 158 if (report_uri.is_empty())
145 return; 159 return;
146 160
147 if (!base::FeatureList::IsEnabled(features::kExpectCTReporting)) 161 if (!base::FeatureList::IsEnabled(features::kExpectCTReporting))
148 return; 162 return;
149 163
150 base::DictionaryValue outer_report; 164 base::DictionaryValue report;
151 base::DictionaryValue* report = outer_report.SetDictionary( 165 report.SetString("hostname", host_port_pair.host());
152 "expect-ct-report", base::MakeUnique<base::DictionaryValue>()); 166 report.SetInteger("port", host_port_pair.port());
153 report->SetString("hostname", host_port_pair.host()); 167 report.SetString("date-time", TimeToISO8601(base::Time::Now()));
154 report->SetInteger("port", host_port_pair.port()); 168 report.SetString("effective-expiration-date", TimeToISO8601(expiration));
155 report->SetString("date-time", TimeToISO8601(base::Time::Now())); 169 report.Set("served-certificate-chain",
156 report->SetString("effective-expiration-date", TimeToISO8601(expiration)); 170 GetPEMEncodedChainAsList(served_certificate_chain));
157 report->Set("served-certificate-chain", 171 report.Set("validated-certificate-chain",
158 GetPEMEncodedChainAsList(served_certificate_chain)); 172 GetPEMEncodedChainAsList(validated_certificate_chain));
159 report->Set("validated-certificate-chain",
160 GetPEMEncodedChainAsList(validated_certificate_chain));
161 173
162 std::unique_ptr<base::ListValue> scts(new base::ListValue()); 174 std::unique_ptr<base::ListValue> unknown_scts(new base::ListValue());
175 std::unique_ptr<base::ListValue> invalid_scts(new base::ListValue());
176 std::unique_ptr<base::ListValue> valid_scts(new base::ListValue());
177
163 for (const auto& sct_and_status : signed_certificate_timestamps) { 178 for (const auto& sct_and_status : signed_certificate_timestamps) {
164 AddSCT(sct_and_status, scts.get()); 179 switch (sct_and_status.status) {
180 case net::ct::SCT_STATUS_LOG_UNKNOWN:
181 AddUnknownSCT(sct_and_status, unknown_scts.get());
182 break;
183 case net::ct::SCT_STATUS_INVALID_SIGNATURE:
184 case net::ct::SCT_STATUS_INVALID_TIMESTAMP:
185 AddInvalidSCT(sct_and_status, invalid_scts.get());
186 break;
187 case net::ct::SCT_STATUS_OK:
188 AddValidSCT(sct_and_status, valid_scts.get());
189 break;
190 default:
191 NOTREACHED();
192 }
165 } 193 }
166 report->Set("scts", std::move(scts)); 194
195 report.Set("unknown-scts", std::move(unknown_scts));
196 report.Set("invalid-scts", std::move(invalid_scts));
197 report.Set("valid-scts", std::move(valid_scts));
167 198
168 std::string serialized_report; 199 std::string serialized_report;
169 if (!base::JSONWriter::Write(outer_report, &serialized_report)) { 200 if (!base::JSONWriter::Write(report, &serialized_report)) {
170 LOG(ERROR) << "Failed to serialize Expect CT report"; 201 LOG(ERROR) << "Failed to serialize Expect CT report";
171 return; 202 return;
172 } 203 }
173 204
174 UMA_HISTOGRAM_BOOLEAN("SSL.ExpectCTReportSendingAttempt", true); 205 UMA_HISTOGRAM_BOOLEAN("SSL.ExpectCTReportSendingAttempt", true);
175 206
176 report_sender_->Send(report_uri, "application/json; charset=utf-8", 207 report_sender_->Send(report_uri, "application/json; charset=utf-8",
177 serialized_report, base::Callback<void()>(), 208 serialized_report, base::Callback<void()>(),
178 base::Bind(RecordUMAOnFailure)); 209 base::Bind(RecordUMAOnFailure));
179 } 210 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698