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

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: fix 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
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
mattm 2016/04/16 02:40:29 Add "(kCastRootCaDer)" ? Or maybe just combine the
eroman 2016/04/18 20:43:03 Done.
34 // (2) CN=Eureka Root CA 35 // (2) CN=Eureka Root CA (kEurekaRootCaDer)
35 //
36 // Note that only the subject/spki are saved here, not the full certificate.
37 // See the TODO in CreateCastTrustStore().
38 36
39 unsigned char kCastRootCaSubjectDer[119] = { 37 // Define kCastRootCaDer.
40 0x30, 0x75, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 38 #include "extensions/common/cast/cast_root_ca_cert_der-inc.h"
41 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 39
42 0x0C, 0x0A, 0x43, 0x61, 0x6C, 0x69, 0x66, 0x6F, 0x72, 0x6E, 0x69, 0x61, 40 // Define kEurekaRootCaDer
43 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x0D, 0x4D, 41 #include "extensions/common/cast/eureka_root_ca_der-inc.h"
44 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x56, 0x69, 0x65, 0x77, 42
45 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x0A, 0x47, 43 // Singleton for the Cast trust store.
46 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x20, 0x49, 0x6E, 0x63, 0x31, 0x0D, 0x30, 44 class CastTrustStore {
47 0x0B, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x04, 0x43, 0x61, 0x73, 0x74, 45 public:
48 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0C, 0x43, 46 static CastTrustStore* GetInstance() {
49 0x61, 0x73, 0x74, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 47 return base::Singleton<CastTrustStore,
48 base::LeakySingletonTraits<CastTrustStore>>::get();
49 }
50
51 static net::TrustStore& Get() {
52 return GetInstance()->store_;
53 }
54
55 private:
56
57 friend struct base::DefaultSingletonTraits<CastTrustStore>;
58
59 CastTrustStore() {
60 // Initialize the trust store with two root certificates.
61 CHECK(store_.AddTrustedCertificateWithoutCopying(kCastRootCaDer,
62 sizeof(kCastRootCaDer)));
63 CHECK(store_.AddTrustedCertificateWithoutCopying(kEurekaRootCaDer,
64 sizeof(kEurekaRootCaDer)));
65 }
66
67 net::TrustStore store_;
68 DISALLOW_COPY_AND_ASSIGN(CastTrustStore);
50 }; 69 };
51 70
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>; 71 using ExtensionsMap = std::map<net::der::Input, net::ParsedExtension>;
149 72
150 // Helper that looks up an extension by OID given a map of extensions. 73 // Helper that looks up an extension by OID given a map of extensions.
151 bool GetExtensionValue(const ExtensionsMap& extensions, 74 bool GetExtensionValue(const ExtensionsMap& extensions,
152 const net::der::Input& oid, 75 const net::der::Input& oid,
153 net::der::Input* value) { 76 net::der::Input* value) {
154 auto it = extensions.find(oid); 77 auto it = extensions.find(oid);
155 if (it == extensions.end()) 78 if (it == extensions.end())
156 return false; 79 return false;
157 *value = it->second.value; 80 *value = it->second.value;
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 result.seconds = exploded.second; 256 result.seconds = exploded.second;
334 return result; 257 return result;
335 } 258 }
336 259
337 } // namespace 260 } // namespace
338 261
339 bool VerifyDeviceCert(const std::vector<std::string>& certs, 262 bool VerifyDeviceCert(const std::vector<std::string>& certs,
340 const base::Time::Exploded& time, 263 const base::Time::Exploded& time,
341 scoped_ptr<CertVerificationContext>* context, 264 scoped_ptr<CertVerificationContext>* context,
342 CastDeviceCertPolicy* policy) { 265 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 266 // The underlying verification function expects a sequence of
352 // der::Input, so wrap the data in it (cheap). 267 // der::Input, so wrap the data in it (cheap).
353 std::vector<net::der::Input> input_chain; 268 std::vector<net::der::Input> input_chain;
354 for (const auto& cert : certs) 269 for (const auto& cert : certs)
355 input_chain.push_back(net::der::Input(&cert)); 270 input_chain.push_back(net::der::Input(&cert));
356 271
357 // Use a signature policy compatible with Cast's PKI. 272 // Use a signature policy compatible with Cast's PKI.
358 auto signature_policy = CreateCastSignaturePolicy(); 273 auto signature_policy = CreateCastSignaturePolicy();
359 274
360 // Do RFC 5280 compatible certificate verification using the two Cast 275 // Do RFC 5280 compatible certificate verification using the two Cast
361 // trust anchors and Cast signature policy. 276 // trust anchors and Cast signature policy.
362 if (!net::VerifyCertificateChain(input_chain, trust_store, 277 if (!net::VerifyCertificateChain(input_chain, CastTrustStore::Get(),
363 signature_policy.get(), 278 signature_policy.get(),
364 ConvertExplodedTime(time))) { 279 ConvertExplodedTime(time))) {
365 return false; 280 return false;
366 } 281 }
367 282
368 // Check properties of the leaf certificate (key usage, policy), and construct 283 // Check properties of the leaf certificate (key usage, policy), and construct
369 // a CertVerificationContext that uses its public key. 284 // a CertVerificationContext that uses its public key.
370 return CheckTargetCertificate(input_chain[0], context, policy); 285 return CheckTargetCertificate(input_chain[0], context, policy);
371 } 286 }
372 287
373 scoped_ptr<CertVerificationContext> CertVerificationContextImplForTest( 288 scoped_ptr<CertVerificationContext> CertVerificationContextImplForTest(
374 const base::StringPiece& spki) { 289 const base::StringPiece& spki) {
375 // Use a bogus CommonName, since this is just exposed for testing signature 290 // Use a bogus CommonName, since this is just exposed for testing signature
376 // verification by unittests. 291 // verification by unittests.
377 return make_scoped_ptr( 292 return make_scoped_ptr(
378 new CertVerificationContextImpl(net::der::Input(spki), "CommonName")); 293 new CertVerificationContextImpl(net::der::Input(spki), "CommonName"));
379 } 294 }
380 295
381 } // namespace cast_crypto 296 } // namespace cast_crypto
382 } // namespace api 297 } // namespace api
383 } // namespace extensions 298 } // namespace extensions
OLDNEW
« no previous file with comments | « no previous file | extensions/common/cast/cast_root_ca_cert_der-inc.h » ('j') | net/cert/internal/verify_certificate_chain.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698