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

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: Addresses comments 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 necessary to fully enforce revocation.
34 // Flip this flag to true when the Cast certificate revocation feature
35 // is rolled out.
mark a. foltz 2016/10/08 04:44:33 Instead of a hard coded constant you'll probably w
ryanchung 2016/10/11 17:15:16 Sounds good. I've added a feature flag here. I wi
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 // |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 // |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& verification_time) {
140 // Verify the certificate 163 // Verify the certificate
141 std::unique_ptr<cast_crypto::CertVerificationContext> verification_context; 164 std::unique_ptr<cast_crypto::CertVerificationContext> verification_context;
142 165
143 // Build a single vector containing the certificate chain. 166 // Build a single vector containing the certificate chain.
144 std::vector<std::string> cert_chain; 167 std::vector<std::string> cert_chain;
145 cert_chain.push_back(response.client_auth_certificate()); 168 cert_chain.push_back(response.client_auth_certificate());
146 cert_chain.insert(cert_chain.end(), 169 cert_chain.insert(cert_chain.end(),
147 response.intermediate_certificate().begin(), 170 response.intermediate_certificate().begin(),
148 response.intermediate_certificate().end()); 171 response.intermediate_certificate().end());
149 172
150 // Use the current time when checking certificate validity. 173 // Parse the CRL.
151 base::Time now = base::Time::Now(); 174 std::unique_ptr<cast_crypto::CastCRL> crl =
152 175 cast_crypto::ParseAndVerifyCRLUsingCustomTrustStore(
153 // CRL should not be enforced until it is served. 176 response.crl(), verification_time, crl_trust_store);
154 cast_crypto::CastDeviceCertPolicy device_policy; 177 if (!crl && crl_policy == cast_crypto::CRLPolicy::CRL_REQUIRED) {
155 if (!cast_crypto::VerifyDeviceCert( 178 // CRL is invalid.
156 cert_chain, now, &verification_context, &device_policy, nullptr, 179 return AuthResult("Failed verifying Cast CRL.",
157 cast_certificate::CRLPolicy::CRL_OPTIONAL)) { 180 AuthResult::ERROR_CRL_INVALID);
158 // TODO(eroman): The error information was lost; this error is ambiguous.
159 return AuthResult("Failed verifying cast device certificate",
160 AuthResult::ERROR_CERT_NOT_SIGNED_BY_TRUSTED_CA);
161 } 181 }
162 182
183 cast_crypto::CastDeviceCertPolicy device_policy;
184 bool verification_success =
185 cast_crypto::VerifyDeviceCertUsingCustomTrustStore(
186 cert_chain, verification_time, &verification_context, &device_policy,
187 crl.get(), crl_policy, cast_trust_store);
188 if (!verification_success) {
189 // TODO(ryanchung): Once this feature is completely rolled-out, remove the
190 // reverification step and use error reporting to get verification errors
191 // for metrics.
192 bool verification_no_crl_success =
193 cast_crypto::VerifyDeviceCertUsingCustomTrustStore(
194 cert_chain, verification_time, &verification_context,
195 &device_policy, nullptr, cast_crypto::CRLPolicy::CRL_OPTIONAL,
196 cast_trust_store);
197 if (!verification_no_crl_success) {
198 // TODO(eroman): The error information was lost; this error is ambiguous.
199 return AuthResult("Failed verifying cast device certificate",
200 AuthResult::ERROR_CERT_NOT_SIGNED_BY_TRUSTED_CA);
201 }
202 if (crl_policy == cast_crypto::CRLPolicy::CRL_REQUIRED) {
203 // Device is revoked.
204 return AuthResult("Failed certificate revocation check.",
205 AuthResult::ERROR_CERT_REVOKED);
206 }
207 }
163 if (!verification_context->VerifySignatureOverData(response.signature(), 208 if (!verification_context->VerifySignatureOverData(response.signature(),
164 signature_input)) { 209 signature_input)) {
165 return AuthResult("Failed verifying signature over data", 210 return AuthResult("Failed verifying signature over data",
166 AuthResult::ERROR_SIGNED_BLOBS_MISMATCH); 211 AuthResult::ERROR_SIGNED_BLOBS_MISMATCH);
167 } 212 }
168 213
169 AuthResult success; 214 AuthResult success;
170 215
171 // Set the policy into the result. 216 // Set the policy into the result.
172 switch (device_policy) { 217 switch (device_policy) {
173 case cast_crypto::CastDeviceCertPolicy::AUDIO_ONLY: 218 case cast_crypto::CastDeviceCertPolicy::AUDIO_ONLY:
174 success.channel_policies = AuthResult::POLICY_AUDIO_ONLY; 219 success.channel_policies = AuthResult::POLICY_AUDIO_ONLY;
175 break; 220 break;
176 case cast_crypto::CastDeviceCertPolicy::NONE: 221 case cast_crypto::CastDeviceCertPolicy::NONE:
177 success.channel_policies = AuthResult::POLICY_NONE; 222 success.channel_policies = AuthResult::POLICY_NONE;
178 break; 223 break;
179 } 224 }
180 225
181 return success; 226 return success;
182 } 227 }
183 228
229 AuthResult VerifyCredentials(const AuthResponse& response,
230 const std::string& signature_input) {
231 base::Time now = base::Time::Now();
232 cast_crypto::CRLPolicy policy = cast_crypto::CRLPolicy::CRL_REQUIRED;
233 if (!kEnforceRevocationCheck) {
234 policy = cast_crypto::CRLPolicy::CRL_OPTIONAL;
235 }
236 return VerifyCredentialsImpl(response, signature_input, policy, nullptr,
237 nullptr, now);
238 }
239
240 AuthResult VerifyCredentialsForTest(const AuthResponse& response,
241 const std::string& signature_input,
242 const cast_crypto::CRLPolicy& crl_policy,
243 net::TrustStore* cast_trust_store,
244 net::TrustStore* crl_trust_store,
245 const base::Time& verification_time) {
246 return VerifyCredentialsImpl(response, signature_input, crl_policy,
247 cast_trust_store, crl_trust_store,
248 verification_time);
249 }
250
184 } // namespace cast_channel 251 } // namespace cast_channel
185 } // namespace api 252 } // namespace api
186 } // namespace extensions 253 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/api/cast_channel/cast_auth_util.h ('k') | extensions/browser/api/cast_channel/cast_auth_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698