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

Side by Side Diff: components/cast_certificate/cast_cert_validator.cc

Issue 2918233002: Add tests for Cast certificate interpretation of policies. (Closed)
Patch Set: Add more tests, and use less restrictive approach Created 3 years, 6 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 | components/cast_certificate/cast_cert_validator_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 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 "components/cast_certificate/cast_cert_validator.h" 5 #include "components/cast_certificate/cast_cert_validator.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 for (const net::RelativeDistinguishedName& rdn : rdn_sequence) { 151 for (const net::RelativeDistinguishedName& rdn : rdn_sequence) {
152 for (const auto& atv : rdn) { 152 for (const auto& atv : rdn) {
153 if (atv.type == net::TypeCommonNameOid()) { 153 if (atv.type == net::TypeCommonNameOid()) {
154 return atv.ValueAsString(common_name); 154 return atv.ValueAsString(common_name);
155 } 155 }
156 } 156 }
157 } 157 }
158 return false; 158 return false;
159 } 159 }
160 160
161 // Cast device certificates use the policy 1.3.6.1.4.1.11129.2.5.2 to indicate
162 // it is *restricted* to an audio-only device whereas the absence of a policy
163 // means it is unrestricted.
164 //
165 // This is somewhat different than RFC 5280's notion of policies, so policies
166 // are checked separately outside of path building.
167 //
168 // See the unit-tests VerifyCastDeviceCertTest.Policies* for some
169 // concrete examples of how this works.
170 void DetermineDeviceCertificatePolicy(
171 const net::CertPathBuilder::ResultPath* result_path,
172 CastDeviceCertPolicy* policy) {
173 // Iterate over all the certificates, including the root certificate. If any
174 // certificate contains the audio-only policy, the whole chain is considered
175 // constrained to audio-only device certificates.
176 //
177 // Policy mappings are not accounted for. The expectation is that top-level
178 // intermediates issued with audio-only will have no mappings. If subsequent
179 // certificates in the chain do, it won't matter as the chain is already
180 // restricted to being audio-only.
181 bool audio_only = false;
182 for (const auto& cert : result_path->path.certs) {
183 if (cert->has_policy_oids()) {
184 const std::vector<net::der::Input>& policies = cert->policy_oids();
185 if (std::find(policies.begin(), policies.end(), AudioOnlyPolicyOid()) !=
186 policies.end()) {
187 audio_only = true;
188 break;
189 }
190 }
191 }
192
193 *policy = audio_only ? CastDeviceCertPolicy::AUDIO_ONLY
194 : CastDeviceCertPolicy::NONE;
195 }
196
161 // Checks properties on the target certificate. 197 // Checks properties on the target certificate.
162 // 198 //
163 // * The Key Usage must include Digital Signature 199 // * The Key Usage must include Digital Signature
164 // * May have the policy 1.3.6.1.4.1.11129.2.5.2 to indicate it
165 // is an audio-only device.
166 WARN_UNUSED_RESULT bool CheckTargetCertificate( 200 WARN_UNUSED_RESULT bool CheckTargetCertificate(
167 const net::ParsedCertificate* cert, 201 const net::ParsedCertificate* cert,
168 std::unique_ptr<CertVerificationContext>* context, 202 std::unique_ptr<CertVerificationContext>* context) {
169 CastDeviceCertPolicy* policy) {
170 // Get the Key Usage extension. 203 // Get the Key Usage extension.
171 if (!cert->has_key_usage()) 204 if (!cert->has_key_usage())
172 return false; 205 return false;
173 206
174 // Ensure Key Usage contains digitalSignature. 207 // Ensure Key Usage contains digitalSignature.
175 if (!cert->key_usage().AssertsBit(net::KEY_USAGE_BIT_DIGITAL_SIGNATURE)) 208 if (!cert->key_usage().AssertsBit(net::KEY_USAGE_BIT_DIGITAL_SIGNATURE))
176 return false; 209 return false;
177 210
178 // Check for an optional audio-only policy extension.
179 //
180 // TODO(eroman): Use |user_constrained_policy_set| that was output from
181 // verification instead. (Checking just the leaf certificate's policy
182 // assertion doesn't take into account policy restrictions on intermediates,
183 // policy constraints/inhibits, or policy re-mappings).
184 *policy = CastDeviceCertPolicy::NONE;
185 if (cert->has_policy_oids()) {
186 const std::vector<net::der::Input>& policies = cert->policy_oids();
187 // Look for an audio-only policy. Disregard any other policy found.
188 if (std::find(policies.begin(), policies.end(), AudioOnlyPolicyOid()) !=
189 policies.end()) {
190 *policy = CastDeviceCertPolicy::AUDIO_ONLY;
191 }
192 }
193
194 // Get the Common Name for the certificate. 211 // Get the Common Name for the certificate.
195 std::string common_name; 212 std::string common_name;
196 if (!GetCommonNameFromSubject(cert->tbs().subject_tlv, &common_name)) 213 if (!GetCommonNameFromSubject(cert->tbs().subject_tlv, &common_name))
197 return false; 214 return false;
198 215
199 context->reset( 216 context->reset(
200 new CertVerificationContextImpl(cert->tbs().spki_tlv, common_name)); 217 new CertVerificationContextImpl(cert->tbs().spki_tlv, common_name));
201 return true; 218 return true;
202 } 219 }
203 220
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 net::KeyPurpose::CLIENT_AUTH, net::InitialExplicitPolicy::kFalse, 291 net::KeyPurpose::CLIENT_AUTH, net::InitialExplicitPolicy::kFalse,
275 {net::AnyPolicy()}, net::InitialPolicyMappingInhibit::kFalse, 292 {net::AnyPolicy()}, net::InitialPolicyMappingInhibit::kFalse,
276 net::InitialAnyPolicyInhibit::kFalse, &result); 293 net::InitialAnyPolicyInhibit::kFalse, &result);
277 path_builder.AddCertIssuerSource(&intermediate_cert_issuer_source); 294 path_builder.AddCertIssuerSource(&intermediate_cert_issuer_source);
278 path_builder.Run(); 295 path_builder.Run();
279 if (!result.HasValidPath()) { 296 if (!result.HasValidPath()) {
280 // TODO(crbug.com/634443): Log error information. 297 // TODO(crbug.com/634443): Log error information.
281 return false; 298 return false;
282 } 299 }
283 300
284 // Check properties of the leaf certificate (key usage, policy), and construct 301 // Determine whether this device certificate is restricted to audio-only.
285 // a CertVerificationContext that uses its public key. 302 DetermineDeviceCertificatePolicy(result.GetBestValidPath(), policy);
286 if (!CheckTargetCertificate(target_cert.get(), context, policy)) 303
304 // Check properties of the leaf certificate not already verified by path
305 // building (key usage), and construct a CertVerificationContext that uses
306 // its public key.
307 if (!CheckTargetCertificate(target_cert.get(), context))
287 return false; 308 return false;
288 309
289 // Check if a CRL is available. 310 // Check if a CRL is available.
290 if (!crl) { 311 if (!crl) {
291 if (crl_policy == CRLPolicy::CRL_REQUIRED) { 312 if (crl_policy == CRLPolicy::CRL_REQUIRED) {
292 return false; 313 return false;
293 } 314 }
294 } else { 315 } else {
295 if (!crl->CheckRevocation(result.GetBestValidPath()->path, time)) { 316 if (!crl->CheckRevocation(result.GetBestValidPath()->path, time)) {
296 return false; 317 return false;
297 } 318 }
298 } 319 }
299 return true; 320 return true;
300 } 321 }
301 322
302 std::unique_ptr<CertVerificationContext> CertVerificationContextImplForTest( 323 std::unique_ptr<CertVerificationContext> CertVerificationContextImplForTest(
303 const base::StringPiece& spki) { 324 const base::StringPiece& spki) {
304 // Use a bogus CommonName, since this is just exposed for testing signature 325 // Use a bogus CommonName, since this is just exposed for testing signature
305 // verification by unittests. 326 // verification by unittests.
306 return base::MakeUnique<CertVerificationContextImpl>(net::der::Input(spki), 327 return base::MakeUnique<CertVerificationContextImpl>(net::der::Input(spki),
307 "CommonName"); 328 "CommonName");
308 } 329 }
309 330
310 } // namespace cast_certificate 331 } // namespace cast_certificate
OLDNEW
« no previous file with comments | « no previous file | components/cast_certificate/cast_cert_validator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698