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

Side by Side Diff: net/cert/internal/parsed_certificate.cc

Issue 1976433002: Add new ParsedCertificate class, move TrustStore to own file. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cert-parsing-remove-old-parsedcertificate
Patch Set: ScopedCheckUnreferencedCerts Created 4 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
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/cert/internal/parsed_certificate.h"
6
7 #include "net/cert/internal/name_constraints.h"
8 #include "net/cert/internal/signature_algorithm.h"
9 #include "net/cert/internal/verify_name_match.h"
10 #include "net/der/parser.h"
11
12 namespace net {
13
14 namespace {
15
16 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv,
17 der::Input* value) {
18 der::Parser parser(tlv);
19 return parser.ReadTag(der::kSequence, value) && !parser.HasMore();
20 }
21
22 } // namespace
23
24 ParsedCertificate::ParsedCertificate() {}
25 ParsedCertificate::~ParsedCertificate() {}
26
27 scoped_refptr<ParsedCertificate> ParsedCertificate::CreateFromCertificateData(
28 const uint8_t* data,
29 size_t length,
30 DataSource source) {
31 scoped_refptr<ParsedCertificate> result(new ParsedCertificate);
32
33 switch (source) {
34 case DataSource::INTERNAL_COPY:
35 result->cert_data_.assign(data, data + length);
36 result->cert_ =
37 der::Input(result->cert_data_.data(), result->cert_data_.size());
38 break;
39 case DataSource::EXTERNAL_REFERENCE:
40 result->cert_ = der::Input(data, length);
41 break;
42 }
43
44 if (!ParseCertificate(result->cert_, &result->tbs_certificate_tlv_,
45 &result->signature_algorithm_tlv_,
46 &result->signature_value_)) {
47 return nullptr;
48 }
49
50 if (!ParseTbsCertificate(result->tbs_certificate_tlv_, &result->tbs_))
51 return nullptr;
52
53 // Attempt to parse the signature algorithm contained in the Certificate.
54 // Do not give up on failure here, since SignatureAlgorithm::CreateFromDer
55 // will fail on valid but unsupported signature algorithms.
56 // TODO(mattm): should distinguish between unsupported algorithms and parsing
57 // errors.
58 result->signature_algorithm_ =
59 SignatureAlgorithm::CreateFromDer(result->signature_algorithm_tlv_);
60
61 der::Input subject_value;
62 if (!GetSequenceValue(result->tbs_.subject_tlv, &subject_value) ||
63 !NormalizeName(subject_value, &result->normalized_subject_)) {
64 return nullptr;
65 }
66 der::Input issuer_value;
67 if (!GetSequenceValue(result->tbs_.issuer_tlv, &issuer_value) ||
68 !NormalizeName(issuer_value, &result->normalized_issuer_)) {
69 return nullptr;
70 }
71
72 // Parse the standard X.509 extensions and remove them from
73 // |unparsed_extensions|.
74 if (result->tbs_.has_extensions) {
75 // ParseExtensions() ensures there are no duplicates, and maps the (unique)
76 // OID to the extension value.
77 if (!ParseExtensions(result->tbs_.extensions_tlv,
78 &result->unparsed_extensions_)) {
79 return nullptr;
80 }
81
82 ParsedExtension extension;
83
84 // Basic constraints.
85 if (ConsumeExtension(BasicConstraintsOid(), &result->unparsed_extensions_,
86 &extension)) {
87 result->has_basic_constraints_ = true;
88 if (!ParseBasicConstraints(extension.value, &result->basic_constraints_))
89 return nullptr;
90 }
91
92 // KeyUsage.
93 if (ConsumeExtension(KeyUsageOid(), &result->unparsed_extensions_,
94 &extension)) {
95 result->has_key_usage_ = true;
96 if (!ParseKeyUsage(extension.value, &result->key_usage_))
97 return nullptr;
98 }
99
100 // Subject alternative name.
101 if (ConsumeExtension(SubjectAltNameOid(), &result->unparsed_extensions_,
102 &result->subject_alt_names_extension_)) {
103 // RFC 5280 section 4.2.1.6:
104 // SubjectAltName ::= GeneralNames
105 result->subject_alt_names_ = GeneralNames::CreateFromDer(
106 result->subject_alt_names_extension_.value);
107 if (!result->subject_alt_names_)
108 return nullptr;
109 // RFC 5280 section 4.1.2.6:
110 // If subject naming information is present only in the subjectAltName
111 // extension (e.g., a key bound only to an email address or URI), then the
112 // subject name MUST be an empty sequence and the subjectAltName extension
113 // MUST be critical.
114 if (subject_value.Length() == 0 &&
115 !result->subject_alt_names_extension_.critical) {
116 return nullptr;
117 }
118 }
119
120 // Name constraints.
121 if (ConsumeExtension(NameConstraintsOid(), &result->unparsed_extensions_,
122 &extension)) {
123 result->name_constraints_ =
124 NameConstraints::CreateFromDer(extension.value, extension.critical);
125 if (!result->name_constraints_)
126 return nullptr;
127 }
128
129 // NOTE: if additional extensions are consumed here, the verification code
130 // must be updated to process those extensions, since the
131 // VerifyNoUnconsumedCriticalExtensions uses the unparsed_extensions_
132 // variable to tell which extensions were processed.
133 }
134
135 return result;
136 }
137
138 scoped_refptr<ParsedCertificate> ParsedCertificate::CreateFromCertificateCopy(
139 const base::StringPiece& data) {
140 return ParsedCertificate::CreateFromCertificateData(
141 reinterpret_cast<const uint8_t*>(data.data()), data.size(),
142 DataSource::INTERNAL_COPY);
143 }
144
145 bool ParsedCertificate::CreateAndAddToVector(
146 const uint8_t* data,
147 size_t length,
148 DataSource source,
149 std::vector<scoped_refptr<ParsedCertificate>>* chain) {
150 scoped_refptr<ParsedCertificate> cert(
151 CreateFromCertificateData(data, length, source));
152 if (!cert)
153 return false;
154 chain->push_back(std::move(cert));
155 return true;
156 }
157
158 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698