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

Side by Side Diff: extensions/browser/api/cast_channel/cast_auth_util.cc

Issue 2303673004: Hook up Chrome Cast sender to Cast CRL. (Closed)
Patch Set: Cleaned up unused headers. Created 4 years, 3 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "extensions/browser/api/cast_channel/cast_auth_util.h" 5 #include "extensions/browser/api/cast_channel/cast_auth_util.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/stringprintf.h" 12 #include "base/strings/stringprintf.h"
13 #include "components/cast_certificate/cast_cert_validator.h" 13 #include "components/cast_certificate/cast_cert_validator.h"
14 #include "components/cast_certificate/cast_crl.h"
14 #include "extensions/browser/api/cast_channel/cast_message_util.h" 15 #include "extensions/browser/api/cast_channel/cast_message_util.h"
15 #include "extensions/common/api/cast_channel/cast_channel.pb.h" 16 #include "extensions/common/api/cast_channel/cast_channel.pb.h"
16 #include "net/cert/x509_certificate.h" 17 #include "net/cert/x509_certificate.h"
17 #include "net/der/parse_values.h" 18 #include "net/der/parse_values.h"
18 19
19 namespace extensions { 20 namespace extensions {
20 namespace api { 21 namespace api {
21 namespace cast_channel { 22 namespace cast_channel {
22 namespace { 23 namespace {
23 24
24 const char* const kParseErrorPrefix = "Failed to parse auth message: "; 25 const char* const kParseErrorPrefix = "Failed to parse auth message: ";
25 26
26 // The maximum number of days a cert can live for. 27 // The maximum number of days a cert can live for.
27 const int kMaxSelfSignedCertLifetimeInDays = 4; 28 const int kMaxSelfSignedCertLifetimeInDays = 4;
28 29
30 // Enforce certificate revocation when set to true.
31 // If set to false, then any revocation failures are ignored.
32 //
33 // This flag tracks the changes necesary to fully enforce revocation.
eroman 2016/09/17 00:44:41 typo: necessary
ryanchung 2016/09/22 21:38:51 Done.
34 // Flip this flag to true when the Cast certificate revocation feature
35 // is rolled out.
36 const bool kEnforceRevocationCheck = false;
37
29 namespace cast_crypto = ::cast_certificate; 38 namespace cast_crypto = ::cast_certificate;
30 39
31 // Extracts an embedded DeviceAuthMessage payload from an auth challenge reply 40 // Extracts an embedded DeviceAuthMessage payload from an auth challenge reply
32 // message. 41 // message.
33 AuthResult ParseAuthMessage(const CastMessage& challenge_reply, 42 AuthResult ParseAuthMessage(const CastMessage& challenge_reply,
34 DeviceAuthMessage* auth_message) { 43 DeviceAuthMessage* auth_message) {
35 if (challenge_reply.payload_type() != CastMessage_PayloadType_BINARY) { 44 if (challenge_reply.payload_type() != CastMessage_PayloadType_BINARY) {
36 return AuthResult::CreateWithParseError( 45 return AuthResult::CreateWithParseError(
37 "Wrong payload type in challenge reply", 46 "Wrong payload type in challenge reply",
38 AuthResult::ERROR_WRONG_PAYLOAD_TYPE); 47 AuthResult::ERROR_WRONG_PAYLOAD_TYPE);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 } 132 }
124 133
125 const AuthResponse& response = auth_message.response(); 134 const AuthResponse& response = auth_message.response();
126 return VerifyCredentials(response, peer_cert_der); 135 return VerifyCredentials(response, peer_cert_der);
127 } 136 }
128 137
129 // This function does the following 138 // This function does the following
130 // 139 //
131 // * Verifies that the certificate chain |response.client_auth_certificate| + 140 // * Verifies that the certificate chain |response.client_auth_certificate| +
132 // |response.intermediate_certificate| is valid and chains to a trusted 141 // |response.intermediate_certificate| is valid and chains to a trusted
133 // Cast root. 142 // Cast root. The list of trusted Cast roots can be overrided by providing a
143 // non-nullptr |cast_trust_store|. The certificate is verified at
144 // |cert_verification_time|.
145 //
146 // * Verifies that none of the certificates in the chain are revoked based on
147 // the CRL provided in the response |response.crl|. The CRL is verified to be
148 // valid and its issuer certificate chains to a trusted Cast CRL root. The
149 // list of trusted Cast CRL roots can be overrided by providing a non-nullptr
150 // |crl_trust_store|. If |crl_policy| is CRL_OPTIONAL then the result of
151 // revocation checking is ignored. The CRL is verified at
152 // |crl_verification_time|.
134 // 153 //
135 // * Verifies that |response.signature| matches the signature 154 // * Verifies that |response.signature| matches the signature
136 // of |signature_input| by |response.client_auth_certificate|'s public 155 // of |signature_input| by |response.client_auth_certificate|'s public
137 // key. 156 // key.
138 AuthResult VerifyCredentials(const AuthResponse& response, 157 AuthResult VerifyCredentialsImpl(const AuthResponse& response,
139 const std::string& signature_input) { 158 const std::string& signature_input,
159 const cast_crypto::CRLPolicy& crl_policy,
160 net::TrustStore* cast_trust_store,
161 net::TrustStore* crl_trust_store,
162 const base::Time& cert_verification_time,
eroman 2016/09/17 00:44:41 Are two timestamps necessary? I could only see th
ryanchung 2016/09/22 21:38:51 This mainly for use of a single test case. Every o
eroman 2016/09/22 22:02:50 I would omit this for now.
ryanchung 2016/09/22 22:43:35 Done.
163 const base::Time& crl_verification_time) {
140 // Verify the certificate 164 // Verify the certificate
141 std::unique_ptr<cast_crypto::CertVerificationContext> verification_context; 165 std::unique_ptr<cast_crypto::CertVerificationContext> verification_context;
142 166
143 // Build a single vector containing the certificate chain. 167 // Build a single vector containing the certificate chain.
144 std::vector<std::string> cert_chain; 168 std::vector<std::string> cert_chain;
145 cert_chain.push_back(response.client_auth_certificate()); 169 cert_chain.push_back(response.client_auth_certificate());
146 cert_chain.insert(cert_chain.end(), 170 cert_chain.insert(cert_chain.end(),
147 response.intermediate_certificate().begin(), 171 response.intermediate_certificate().begin(),
148 response.intermediate_certificate().end()); 172 response.intermediate_certificate().end());
149 173
150 // Use the current time when checking certificate validity. 174 // Parse the CRL.
151 base::Time now = base::Time::Now(); 175 std::unique_ptr<cast_crypto::CastCRL> crl;
152 176 if (crl_trust_store) {
153 // CRL should not be enforced until it is served. 177 crl = cast_crypto::ParseAndVerifyCRLUsingCustomTrustStore(
154 cast_crypto::CastDeviceCertPolicy device_policy; 178 response.crl(), crl_verification_time, crl_trust_store);
155 if (!cast_crypto::VerifyDeviceCert( 179 } else {
156 cert_chain, now, &verification_context, &device_policy, nullptr, 180 crl = cast_crypto::ParseAndVerifyCRL(response.crl(), crl_verification_time);
157 cast_certificate::CRLPolicy::CRL_OPTIONAL)) { 181 }
158 // TODO(eroman): The error information was lost; this error is ambiguous. 182 if (!crl && crl_policy == cast_crypto::CRLPolicy::CRL_REQUIRED) {
159 return AuthResult("Failed verifying cast device certificate", 183 // CRL is invalid.
160 AuthResult::ERROR_CERT_NOT_SIGNED_BY_TRUSTED_CA); 184 return AuthResult("Failed verifying Cast CRL.",
185 AuthResult::ERROR_CRL_INVALID);
161 } 186 }
162 187
188 cast_crypto::CastDeviceCertPolicy device_policy;
189 bool verification_success;
190 if (cast_trust_store) {
191 verification_success = cast_crypto::VerifyDeviceCertUsingCustomTrustStore(
192 cert_chain, cert_verification_time, &verification_context,
193 &device_policy, crl.get(), crl_policy, cast_trust_store);
194 } else {
195 verification_success = cast_crypto::VerifyDeviceCert(
196 cert_chain, cert_verification_time, &verification_context,
197 &device_policy, crl.get(), crl_policy);
198 }
199 if (!verification_success) {
200 // TODO(ryanchung): Once this feature is completely rolled-out, remove the
201 // reverification step and use error reporting to get verification errors
202 // for metrics.
203 bool verification_no_crl_success;
204 if (cast_trust_store) {
205 verification_no_crl_success =
206 cast_crypto::VerifyDeviceCertUsingCustomTrustStore(
eroman 2016/09/17 00:44:41 I may have been wrong when I suggested having a ri
ryanchung 2016/09/22 21:38:52 Done.
207 cert_chain, cert_verification_time, &verification_context,
208 &device_policy, nullptr, cast_crypto::CRLPolicy::CRL_OPTIONAL,
209 cast_trust_store);
210 } else {
211 verification_no_crl_success = cast_crypto::VerifyDeviceCert(
212 cert_chain, cert_verification_time, &verification_context,
213 &device_policy, nullptr, cast_crypto::CRLPolicy::CRL_OPTIONAL);
214 }
215 if (!verification_no_crl_success) {
216 // TODO(eroman): The error information was lost; this error is ambiguous.
217 return AuthResult("Failed verifying cast device certificate",
218 AuthResult::ERROR_CERT_NOT_SIGNED_BY_TRUSTED_CA);
219 }
220 if (crl_policy == cast_crypto::CRLPolicy::CRL_REQUIRED) {
221 // Device is revoked.
222 return AuthResult("Failed certificate revocation check.",
223 AuthResult::ERROR_CERT_REVOKED);
224 }
225 }
163 if (!verification_context->VerifySignatureOverData(response.signature(), 226 if (!verification_context->VerifySignatureOverData(response.signature(),
164 signature_input)) { 227 signature_input)) {
165 return AuthResult("Failed verifying signature over data", 228 return AuthResult("Failed verifying signature over data",
166 AuthResult::ERROR_SIGNED_BLOBS_MISMATCH); 229 AuthResult::ERROR_SIGNED_BLOBS_MISMATCH);
167 } 230 }
168 231
169 AuthResult success; 232 AuthResult success;
170 233
171 // Set the policy into the result. 234 // Set the policy into the result.
172 switch (device_policy) { 235 switch (device_policy) {
173 case cast_crypto::CastDeviceCertPolicy::AUDIO_ONLY: 236 case cast_crypto::CastDeviceCertPolicy::AUDIO_ONLY:
174 success.channel_policies = AuthResult::POLICY_AUDIO_ONLY; 237 success.channel_policies = AuthResult::POLICY_AUDIO_ONLY;
175 break; 238 break;
176 case cast_crypto::CastDeviceCertPolicy::NONE: 239 case cast_crypto::CastDeviceCertPolicy::NONE:
177 success.channel_policies = AuthResult::POLICY_NONE; 240 success.channel_policies = AuthResult::POLICY_NONE;
178 break; 241 break;
179 } 242 }
180 243
181 return success; 244 return success;
182 } 245 }
183 246
247 AuthResult VerifyCredentials(const AuthResponse& response,
248 const std::string& signature_input) {
249 base::Time now = base::Time::Now();
250 cast_crypto::CRLPolicy policy = cast_crypto::CRLPolicy::CRL_REQUIRED;
251 if (!kEnforceRevocationCheck) {
eroman 2016/09/17 00:44:41 [optional] Not sure on your next steps for rollout
ryanchung 2016/09/22 21:38:51 We should roll-out to users in stages and watch th
252 policy = cast_crypto::CRLPolicy::CRL_OPTIONAL;
253 }
254 return VerifyCredentialsImpl(response, signature_input, policy, nullptr,
255 nullptr, now, now);
256 }
257
258 AuthResult VerifyCredentialsForTest(const AuthResponse& response,
259 const std::string& signature_input,
260 const cast_crypto::CRLPolicy& crl_policy,
261 net::TrustStore* cast_trust_store,
262 net::TrustStore* crl_trust_store,
263 const base::Time& cert_verification_time,
264 const base::Time& crl_verification_time) {
265 return VerifyCredentialsImpl(response, signature_input, crl_policy,
266 cast_trust_store, crl_trust_store,
267 cert_verification_time, crl_verification_time);
268 }
269
184 } // namespace cast_channel 270 } // namespace cast_channel
185 } // namespace api 271 } // namespace api
186 } // namespace extensions 272 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698