| OLD | NEW |
| 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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 for (const net::RelativeDistinguishedName& rdn : rdn_sequence) { | 153 for (const net::RelativeDistinguishedName& rdn : rdn_sequence) { |
| 154 for (const auto& atv : rdn) { | 154 for (const auto& atv : rdn) { |
| 155 if (atv.type == net::TypeCommonNameOid()) { | 155 if (atv.type == net::TypeCommonNameOid()) { |
| 156 return atv.ValueAsString(common_name); | 156 return atv.ValueAsString(common_name); |
| 157 } | 157 } |
| 158 } | 158 } |
| 159 } | 159 } |
| 160 return false; | 160 return false; |
| 161 } | 161 } |
| 162 | 162 |
| 163 // Returns true if the extended key usage list |ekus| contains client auth. | |
| 164 bool HasClientAuth(const std::vector<net::der::Input>& ekus) { | |
| 165 for (const auto& oid : ekus) { | |
| 166 if (oid == net::ClientAuth()) | |
| 167 return true; | |
| 168 } | |
| 169 return false; | |
| 170 } | |
| 171 | |
| 172 // Checks properties on the target certificate. | 163 // Checks properties on the target certificate. |
| 173 // | 164 // |
| 174 // * The Key Usage must include Digital Signature | 165 // * The Key Usage must include Digital Signature |
| 175 // * The Extended Key Usage must include TLS Client Auth | |
| 176 // * May have the policy 1.3.6.1.4.1.11129.2.5.2 to indicate it | 166 // * May have the policy 1.3.6.1.4.1.11129.2.5.2 to indicate it |
| 177 // is an audio-only device. | 167 // is an audio-only device. |
| 178 WARN_UNUSED_RESULT bool CheckTargetCertificate( | 168 WARN_UNUSED_RESULT bool CheckTargetCertificate( |
| 179 const net::ParsedCertificate* cert, | 169 const net::ParsedCertificate* cert, |
| 180 std::unique_ptr<CertVerificationContext>* context, | 170 std::unique_ptr<CertVerificationContext>* context, |
| 181 CastDeviceCertPolicy* policy) { | 171 CastDeviceCertPolicy* policy) { |
| 182 // Get the Key Usage extension. | 172 // Get the Key Usage extension. |
| 183 if (!cert->has_key_usage()) | 173 if (!cert->has_key_usage()) |
| 184 return false; | 174 return false; |
| 185 | 175 |
| 186 // Ensure Key Usage contains digitalSignature. | 176 // Ensure Key Usage contains digitalSignature. |
| 187 if (!cert->key_usage().AssertsBit(net::KEY_USAGE_BIT_DIGITAL_SIGNATURE)) | 177 if (!cert->key_usage().AssertsBit(net::KEY_USAGE_BIT_DIGITAL_SIGNATURE)) |
| 188 return false; | 178 return false; |
| 189 | 179 |
| 190 // Ensure Extended Key Usage contains client auth. | |
| 191 if (!cert->has_extended_key_usage() || | |
| 192 !HasClientAuth(cert->extended_key_usage())) | |
| 193 return false; | |
| 194 | |
| 195 // Check for an optional audio-only policy extension. | 180 // Check for an optional audio-only policy extension. |
| 196 *policy = CastDeviceCertPolicy::NONE; | 181 *policy = CastDeviceCertPolicy::NONE; |
| 197 if (cert->has_policy_oids()) { | 182 if (cert->has_policy_oids()) { |
| 198 const std::vector<net::der::Input>& policies = cert->policy_oids(); | 183 const std::vector<net::der::Input>& policies = cert->policy_oids(); |
| 199 // Look for an audio-only policy. Disregard any other policy found. | 184 // Look for an audio-only policy. Disregard any other policy found. |
| 200 if (std::find(policies.begin(), policies.end(), AudioOnlyPolicyOid()) != | 185 if (std::find(policies.begin(), policies.end(), AudioOnlyPolicyOid()) != |
| 201 policies.end()) { | 186 policies.end()) { |
| 202 *policy = CastDeviceCertPolicy::AUDIO_ONLY; | 187 *policy = CastDeviceCertPolicy::AUDIO_ONLY; |
| 203 } | 188 } |
| 204 } | 189 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 auto signature_policy = CreateCastSignaturePolicy(); | 261 auto signature_policy = CreateCastSignaturePolicy(); |
| 277 | 262 |
| 278 // Do path building and RFC 5280 compatible certificate verification using the | 263 // Do path building and RFC 5280 compatible certificate verification using the |
| 279 // two Cast trust anchors and Cast signature policy. | 264 // two Cast trust anchors and Cast signature policy. |
| 280 net::der::GeneralizedTime verification_time; | 265 net::der::GeneralizedTime verification_time; |
| 281 if (!net::der::EncodeTimeAsGeneralizedTime(time, &verification_time)) | 266 if (!net::der::EncodeTimeAsGeneralizedTime(time, &verification_time)) |
| 282 return false; | 267 return false; |
| 283 net::CertPathBuilder::Result result; | 268 net::CertPathBuilder::Result result; |
| 284 net::CertPathBuilder path_builder(target_cert.get(), trust_store, | 269 net::CertPathBuilder path_builder(target_cert.get(), trust_store, |
| 285 signature_policy.get(), verification_time, | 270 signature_policy.get(), verification_time, |
| 286 &result); | 271 net::KeyPurpose::CLIENT_AUTH, &result); |
| 287 path_builder.AddCertIssuerSource(&intermediate_cert_issuer_source); | 272 path_builder.AddCertIssuerSource(&intermediate_cert_issuer_source); |
| 288 path_builder.Run(); | 273 path_builder.Run(); |
| 289 if (!result.HasValidPath()) { | 274 if (!result.HasValidPath()) { |
| 290 // TODO(crbug.com/634443): Log error information. | 275 // TODO(crbug.com/634443): Log error information. |
| 291 return false; | 276 return false; |
| 292 } | 277 } |
| 293 | 278 |
| 294 // Check properties of the leaf certificate (key usage, policy), and construct | 279 // Check properties of the leaf certificate (key usage, policy), and construct |
| 295 // a CertVerificationContext that uses its public key. | 280 // a CertVerificationContext that uses its public key. |
| 296 if (!CheckTargetCertificate(target_cert.get(), context, policy)) | 281 if (!CheckTargetCertificate(target_cert.get(), context, policy)) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 311 | 296 |
| 312 std::unique_ptr<CertVerificationContext> CertVerificationContextImplForTest( | 297 std::unique_ptr<CertVerificationContext> CertVerificationContextImplForTest( |
| 313 const base::StringPiece& spki) { | 298 const base::StringPiece& spki) { |
| 314 // Use a bogus CommonName, since this is just exposed for testing signature | 299 // Use a bogus CommonName, since this is just exposed for testing signature |
| 315 // verification by unittests. | 300 // verification by unittests. |
| 316 return base::MakeUnique<CertVerificationContextImpl>(net::der::Input(spki), | 301 return base::MakeUnique<CertVerificationContextImpl>(net::der::Input(spki), |
| 317 "CommonName"); | 302 "CommonName"); |
| 318 } | 303 } |
| 319 | 304 |
| 320 } // namespace cast_certificate | 305 } // namespace cast_certificate |
| OLD | NEW |