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

Side by Side Diff: extensions/common/cast/cast_cert_validator.cc

Issue 1890193003: Make Cast certificate verification enforce constraints specified in the trusted root certificate. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: list datafiles for ios (needed following the rebase) Created 4 years, 8 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 | extensions/common/cast/cast_root_ca_cert_der-inc.h » ('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 "extensions/common/cast/cast_cert_validator.h" 5 #include "extensions/common/cast/cast_cert_validator.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 #include <algorithm> 9 #include <algorithm>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/memory/singleton.h"
12 #include "net/cert/internal/certificate_policies.h" 13 #include "net/cert/internal/certificate_policies.h"
13 #include "net/cert/internal/extended_key_usage.h" 14 #include "net/cert/internal/extended_key_usage.h"
14 #include "net/cert/internal/parse_certificate.h" 15 #include "net/cert/internal/parse_certificate.h"
15 #include "net/cert/internal/parse_name.h" 16 #include "net/cert/internal/parse_name.h"
16 #include "net/cert/internal/signature_algorithm.h" 17 #include "net/cert/internal/signature_algorithm.h"
17 #include "net/cert/internal/signature_policy.h" 18 #include "net/cert/internal/signature_policy.h"
18 #include "net/cert/internal/verify_certificate_chain.h" 19 #include "net/cert/internal/verify_certificate_chain.h"
19 #include "net/cert/internal/verify_signed_data.h" 20 #include "net/cert/internal/verify_signed_data.h"
20 #include "net/der/input.h" 21 #include "net/der/input.h"
21 22
22 namespace extensions { 23 namespace extensions {
23 namespace api { 24 namespace api {
24 namespace cast_crypto { 25 namespace cast_crypto {
25 namespace { 26 namespace {
26 27
27 // ------------------------------------------------------------------------- 28 // -------------------------------------------------------------------------
28 // Cast trust anchors. 29 // Cast trust anchors.
29 // ------------------------------------------------------------------------- 30 // -------------------------------------------------------------------------
30 31
31 // There are two trusted roots for Cast certificate chains: 32 // There are two trusted roots for Cast certificate chains:
32 // 33 //
33 // (1) CN=Cast Root CA 34 // (1) CN=Cast Root CA (kCastRootCaDer)
34 // (2) CN=Eureka Root CA 35 // (2) CN=Eureka Root CA (kEurekaRootCaDer)
35 // 36 //
36 // Note that only the subject/spki are saved here, not the full certificate. 37 // These constants are defined by the files included next:
37 // See the TODO in CreateCastTrustStore().
38 38
39 unsigned char kCastRootCaSubjectDer[119] = { 39 #include "extensions/common/cast/cast_root_ca_cert_der-inc.h"
40 0x30, 0x75, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 40 #include "extensions/common/cast/eureka_root_ca_der-inc.h"
41 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 41
42 0x0C, 0x0A, 0x43, 0x61, 0x6C, 0x69, 0x66, 0x6F, 0x72, 0x6E, 0x69, 0x61, 42 // Singleton for the Cast trust store.
43 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x0D, 0x4D, 43 class CastTrustStore {
44 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x56, 0x69, 0x65, 0x77, 44 public:
45 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0A, 0x47, 45 static CastTrustStore* GetInstance() {
46 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x0D, 0x30, 46 return base::Singleton<CastTrustStore,
47 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x04, 0x43, 0x61, 0x73, 0x74, 47 base::LeakySingletonTraits<CastTrustStore>>::get();
48 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0C, 0x43, 48 }
49 0x61, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 49
50 static net::TrustStore& Get() { return GetInstance()->store_; }
51
52 private:
53 friend struct base::DefaultSingletonTraits<CastTrustStore>;
54
55 CastTrustStore() {
56 // Initialize the trust store with two root certificates.
57 CHECK(store_.AddTrustedCertificateWithoutCopying(kCastRootCaDer,
58 sizeof(kCastRootCaDer)));
59 CHECK(store_.AddTrustedCertificateWithoutCopying(kEurekaRootCaDer,
60 sizeof(kEurekaRootCaDer)));
61 }
62
63 net::TrustStore store_;
64 DISALLOW_COPY_AND_ASSIGN(CastTrustStore);
50 }; 65 };
51 66
52 unsigned char kCastRootCaSpkiDer[294] = {
53 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
54 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00,
55 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xBA, 0xD9, 0x65,
56 0x9D, 0xDA, 0x39, 0xD3, 0xC1, 0x77, 0xF6, 0xD4, 0xD0, 0xAE, 0x8F, 0x58,
57 0x08, 0x68, 0x39, 0x4A, 0x95, 0xED, 0x70, 0xCF, 0xFD, 0x79, 0x08, 0xA9,
58 0xAA, 0xE5, 0xE9, 0xB8, 0xA7, 0x2D, 0xA0, 0x67, 0x47, 0x8A, 0x9E, 0xC9,
59 0xCF, 0x70, 0xB3, 0x05, 0x87, 0x69, 0x11, 0xEC, 0x70, 0x98, 0x97, 0xC3,
60 0xE6, 0xC3, 0xC3, 0xEB, 0xBD, 0xC6, 0xB0, 0x3D, 0xFC, 0x4F, 0xC1, 0x5E,
61 0x38, 0x9F, 0xDA, 0xCF, 0x73, 0x30, 0x06, 0x5B, 0x79, 0x37, 0xC1, 0x5E,
62 0x8C, 0x87, 0x47, 0x94, 0x9A, 0x41, 0x92, 0x2A, 0xD6, 0x95, 0xC4, 0x71,
63 0x5C, 0x27, 0x5D, 0x08, 0xB1, 0x80, 0xC6, 0x92, 0xBD, 0x1B, 0xE3, 0x41,
64 0x97, 0xA1, 0xEC, 0x75, 0x9F, 0x55, 0x9E, 0x3E, 0x9F, 0x8F, 0x1C, 0xC7,
65 0x65, 0x64, 0x07, 0xD3, 0xB3, 0x96, 0xA1, 0x04, 0x9F, 0x91, 0xC4, 0xDE,
66 0x0A, 0x7B, 0x6C, 0xD9, 0xC8, 0xC0, 0x78, 0x31, 0xA0, 0x19, 0x42, 0xA9,
67 0xE8, 0x83, 0xE3, 0xCE, 0xFC, 0xF1, 0xCE, 0xC2, 0x2E, 0x24, 0x46, 0x95,
68 0x09, 0x19, 0xCA, 0xC0, 0x46, 0xB2, 0xE5, 0x01, 0xBA, 0xD7, 0x4F, 0xF3,
69 0xBF, 0xF6, 0x69, 0xAD, 0x99, 0x04, 0xFA, 0xA0, 0x07, 0x39, 0x0E, 0xE6,
70 0xDF, 0x51, 0x47, 0x07, 0xC0, 0xE4, 0xA9, 0x5C, 0x4B, 0x94, 0xC5, 0x2F,
71 0xB3, 0xA0, 0x30, 0x7F, 0xE7, 0x95, 0x6B, 0xB2, 0xAF, 0x32, 0x0D, 0xF1,
72 0x8C, 0xD5, 0x6D, 0xCB, 0x7B, 0x47, 0xA7, 0x08, 0xAB, 0xCB, 0x27, 0xA3,
73 0x4D, 0xCF, 0x4A, 0x5A, 0xF1, 0x05, 0xD1, 0xF8, 0x62, 0xC5, 0x10, 0x2A,
74 0x74, 0x69, 0xAA, 0xE6, 0x4B, 0x96, 0xFB, 0x9B, 0xD8, 0x63, 0xE4, 0x58,
75 0x66, 0xD3, 0xAD, 0x8A, 0x6E, 0xFF, 0x7B, 0x5E, 0xF9, 0xA5, 0x56, 0x1E,
76 0x2D, 0x82, 0x31, 0x5B, 0xF0, 0xE2, 0x24, 0xE6, 0x41, 0x4A, 0x1F, 0xAE,
77 0x13, 0x02, 0x03, 0x01, 0x00, 0x01,
78 };
79
80 unsigned char kEurekaRootCaSubjectDer[126] = {
81 0x30, 0x7C, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
82 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
83 0x0C, 0x0A, 0x43, 0x61, 0x6C, 0x69, 0x66, 0x6F, 0x72, 0x6E, 0x69, 0x61,
84 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x0D, 0x4D,
85 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x56, 0x69, 0x65, 0x77,
86 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0A, 0x47,
87 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x12, 0x30,
88 0x10, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x09, 0x47, 0x6F, 0x6F, 0x67,
89 0x6C, 0x65, 0x20, 0x54, 0x56, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55,
90 0x04, 0x03, 0x0C, 0x0E, 0x45, 0x75, 0x72, 0x65, 0x6B, 0x61, 0x20, 0x52,
91 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41,
92 };
93
94 unsigned char kEurekaRootCaSpkiDer[294] = {
95 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
96 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00,
97 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xB9, 0x11, 0xD0,
98 0xEA, 0x12, 0xDC, 0x32, 0xE1, 0xDF, 0x5C, 0x33, 0x6B, 0x19, 0x73, 0x1D,
99 0x9D, 0x9E, 0xD0, 0x39, 0x76, 0xBF, 0xA5, 0x84, 0x09, 0xA6, 0xFD, 0x6E,
100 0x6D, 0xE9, 0xDC, 0x8F, 0x36, 0x4E, 0xE9, 0x88, 0x02, 0xBD, 0x9F, 0xF4,
101 0xE8, 0x44, 0xFD, 0x4C, 0xF5, 0x9A, 0x02, 0x56, 0x6A, 0x47, 0x2A, 0x63,
102 0x6C, 0x58, 0x45, 0xCC, 0x7C, 0x66, 0x24, 0xDC, 0x79, 0x79, 0xC3, 0x2A,
103 0xA4, 0xB2, 0x8B, 0xA0, 0xF7, 0xA2, 0xB5, 0xCD, 0x06, 0x7E, 0xDB, 0xBE,
104 0xEC, 0x0C, 0x86, 0xF2, 0x0D, 0x24, 0x60, 0x74, 0x84, 0xCA, 0x29, 0x23,
105 0x84, 0x02, 0xD8, 0xA7, 0xED, 0x3B, 0xF1, 0xEC, 0x26, 0x47, 0x54, 0xE3,
106 0xB1, 0x2D, 0xE6, 0x64, 0x0F, 0xF6, 0x72, 0xC5, 0xE9, 0x98, 0x52, 0x17,
107 0xC0, 0xFC, 0xF2, 0x2C, 0x20, 0xC8, 0x40, 0xF8, 0x47, 0xC9, 0x32, 0x9E,
108 0x3B, 0x97, 0xB1, 0x8B, 0xF5, 0x98, 0x24, 0x70, 0x63, 0x66, 0x19, 0xC1,
109 0x52, 0xE8, 0x04, 0x05, 0x3D, 0x5F, 0x8D, 0xBC, 0xD8, 0x4B, 0xAF, 0x77,
110 0x98, 0x6F, 0x1F, 0x78, 0xD1, 0xB6, 0x50, 0x27, 0x4D, 0xE4, 0xEC, 0x14,
111 0x69, 0x67, 0x1F, 0x58, 0xAF, 0xA9, 0xA0, 0x11, 0x26, 0x3C, 0x94, 0x32,
112 0x07, 0x7F, 0xD7, 0xE9, 0x69, 0x1F, 0xAE, 0x3F, 0x4F, 0x63, 0x8A, 0x8F,
113 0x89, 0xD6, 0xF2, 0x19, 0x78, 0x5C, 0x21, 0x8E, 0xB1, 0xB6, 0x57, 0xD8,
114 0xC0, 0xE1, 0xEE, 0x7D, 0x6E, 0xDD, 0xF1, 0x3A, 0x0A, 0x6A, 0xF1, 0xBA,
115 0xFF, 0xF9, 0x83, 0x2F, 0xDC, 0xB5, 0xA4, 0x20, 0x17, 0x63, 0x36, 0xEF,
116 0xC8, 0x62, 0x19, 0xCC, 0x56, 0xCE, 0xB2, 0xEA, 0x31, 0x89, 0x4B, 0x78,
117 0x58, 0xC1, 0xBF, 0x03, 0x13, 0x99, 0xE0, 0x12, 0xF2, 0x88, 0xAA, 0x9B,
118 0x94, 0xDA, 0xDD, 0x76, 0x79, 0x17, 0x1E, 0x34, 0xD1, 0x0A, 0xC4, 0x07,
119 0x45, 0x02, 0x03, 0x01, 0x00, 0x01,
120 };
121
122 // Helper function that creates and initializes a TrustAnchor struct given
123 // arrays for the subject's DER and the SPKI's DER.
124 template <size_t SubjectSize, size_t SpkiSize>
125 net::TrustAnchor CreateTrustAnchor(const uint8_t (&subject)[SubjectSize],
126 const uint8_t (&spki)[SpkiSize]) {
127 net::TrustAnchor anchor;
128 anchor.name = std::string(subject, subject + SubjectSize);
129 anchor.spki = std::string(spki, spki + SpkiSize);
130 return anchor;
131 }
132
133 // Creates a trust store with the two Cast roots.
134 //
135 // TODO(eroman): The root certificates themselves are not included in the trust
136 // store (just their subject/SPKI). The problem with this approach is any
137 // restrictions encoded in their (like path length, or policy) are not known
138 // when verifying, and hence not enforced.
139 net::TrustStore CreateCastTrustStore() {
140 net::TrustStore store;
141 store.anchors.push_back(
142 CreateTrustAnchor(kEurekaRootCaSubjectDer, kEurekaRootCaSpkiDer));
143 store.anchors.push_back(
144 CreateTrustAnchor(kCastRootCaSubjectDer, kCastRootCaSpkiDer));
145 return store;
146 }
147
148 using ExtensionsMap = std::map<net::der::Input, net::ParsedExtension>; 67 using ExtensionsMap = std::map<net::der::Input, net::ParsedExtension>;
149 68
150 // Helper that looks up an extension by OID given a map of extensions. 69 // Helper that looks up an extension by OID given a map of extensions.
151 bool GetExtensionValue(const ExtensionsMap& extensions, 70 bool GetExtensionValue(const ExtensionsMap& extensions,
152 const net::der::Input& oid, 71 const net::der::Input& oid,
153 net::der::Input* value) { 72 net::der::Input* value) {
154 auto it = extensions.find(oid); 73 auto it = extensions.find(oid);
155 if (it == extensions.end()) 74 if (it == extensions.end())
156 return false; 75 return false;
157 *value = it->second.value; 76 *value = it->second.value;
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 result.seconds = exploded.second; 252 result.seconds = exploded.second;
334 return result; 253 return result;
335 } 254 }
336 255
337 } // namespace 256 } // namespace
338 257
339 bool VerifyDeviceCert(const std::vector<std::string>& certs, 258 bool VerifyDeviceCert(const std::vector<std::string>& certs,
340 const base::Time::Exploded& time, 259 const base::Time::Exploded& time,
341 scoped_ptr<CertVerificationContext>* context, 260 scoped_ptr<CertVerificationContext>* context,
342 CastDeviceCertPolicy* policy) { 261 CastDeviceCertPolicy* policy) {
343 // Initialize the trust store used for verifying Cast
344 // device certificates.
345 //
346 // Performance: This code is re-building a TrustStore object each
347 // time a chain needs to be verified rather than caching it, to
348 // avoid memory bloat.
349 auto trust_store = CreateCastTrustStore();
350
351 // The underlying verification function expects a sequence of 262 // The underlying verification function expects a sequence of
352 // der::Input, so wrap the data in it (cheap). 263 // der::Input, so wrap the data in it (cheap).
353 std::vector<net::der::Input> input_chain; 264 std::vector<net::der::Input> input_chain;
354 for (const auto& cert : certs) 265 for (const auto& cert : certs)
355 input_chain.push_back(net::der::Input(&cert)); 266 input_chain.push_back(net::der::Input(&cert));
356 267
357 // Use a signature policy compatible with Cast's PKI. 268 // Use a signature policy compatible with Cast's PKI.
358 auto signature_policy = CreateCastSignaturePolicy(); 269 auto signature_policy = CreateCastSignaturePolicy();
359 270
360 // Do RFC 5280 compatible certificate verification using the two Cast 271 // Do RFC 5280 compatible certificate verification using the two Cast
361 // trust anchors and Cast signature policy. 272 // trust anchors and Cast signature policy.
362 if (!net::VerifyCertificateChain(input_chain, trust_store, 273 if (!net::VerifyCertificateChain(input_chain, CastTrustStore::Get(),
363 signature_policy.get(), 274 signature_policy.get(),
364 ConvertExplodedTime(time))) { 275 ConvertExplodedTime(time))) {
365 return false; 276 return false;
366 } 277 }
367 278
368 // Check properties of the leaf certificate (key usage, policy), and construct 279 // Check properties of the leaf certificate (key usage, policy), and construct
369 // a CertVerificationContext that uses its public key. 280 // a CertVerificationContext that uses its public key.
370 return CheckTargetCertificate(input_chain[0], context, policy); 281 return CheckTargetCertificate(input_chain[0], context, policy);
371 } 282 }
372 283
373 scoped_ptr<CertVerificationContext> CertVerificationContextImplForTest( 284 scoped_ptr<CertVerificationContext> CertVerificationContextImplForTest(
374 const base::StringPiece& spki) { 285 const base::StringPiece& spki) {
375 // Use a bogus CommonName, since this is just exposed for testing signature 286 // Use a bogus CommonName, since this is just exposed for testing signature
376 // verification by unittests. 287 // verification by unittests.
377 return make_scoped_ptr( 288 return make_scoped_ptr(
378 new CertVerificationContextImpl(net::der::Input(spki), "CommonName")); 289 new CertVerificationContextImpl(net::der::Input(spki), "CommonName"));
379 } 290 }
380 291
381 } // namespace cast_crypto 292 } // namespace cast_crypto
382 } // namespace api 293 } // namespace api
383 } // namespace extensions 294 } // namespace extensions
OLDNEW
« no previous file with comments | « no previous file | extensions/common/cast/cast_root_ca_cert_der-inc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698