OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "net/cert/asn1_util.h" | 5 #include "net/cert/asn1_util.h" |
6 | 6 |
7 #include "net/der/input.h" | 7 #include "net/der/input.h" |
8 #include "net/der/parser.h" | 8 #include "net/der/parser.h" |
9 | 9 |
10 namespace net { | 10 namespace net { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 return false; | 63 return false; |
64 // validity | 64 // validity |
65 if (!tbs_certificate->SkipTag(der::kSequence)) | 65 if (!tbs_certificate->SkipTag(der::kSequence)) |
66 return false; | 66 return false; |
67 // subject | 67 // subject |
68 if (!tbs_certificate->SkipTag(der::kSequence)) | 68 if (!tbs_certificate->SkipTag(der::kSequence)) |
69 return false; | 69 return false; |
70 return true; | 70 return true; |
71 } | 71 } |
72 | 72 |
73 // Parses input |in| which should point to the beginning of a | |
74 // Certificate. If parsing fails, this function returns false, with | |
75 // |*extensions_present| and |*extensions_parser| left in an undefined | |
76 // state. If parsing succeeds and extensions are present, this function | |
77 // sets |*extensions_present| to true and sets |*extensions_parser| | |
78 // ready to parse the Extensions. If extensions are not present, it sets | |
79 // |*extensions_present| to false and |*extensions_parser| is left in an | |
80 // undefined state. | |
81 bool SeekToExtensions(der::Input in, | |
82 bool* extensions_present, | |
83 der::Parser* extensions_parser) { | |
84 bool present; | |
85 der::Parser tbs_cert_parser; | |
86 if (!SeekToSPKI(in, &tbs_cert_parser)) | |
87 return false; | |
88 | |
89 // From RFC 5280, section 4.1 | |
90 // TBSCertificate ::= SEQUENCE { | |
91 // ... | |
92 // subjectPublicKeyInfo SubjectPublicKeyInfo, | |
93 // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, | |
94 // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, | |
95 // extensions [3] EXPLICIT Extensions OPTIONAL } | |
96 | |
97 // subjectPublicKeyInfo | |
98 if (!tbs_cert_parser.SkipTag(der::kSequence)) | |
99 return false; | |
100 // issuerUniqueID | |
101 if (!tbs_cert_parser.SkipOptionalTag( | |
102 der::kTagConstructed | der::kTagContextSpecific | 1, &present)) { | |
103 return false; | |
104 } | |
105 // subjectUniqueID | |
106 if (!tbs_cert_parser.SkipOptionalTag( | |
107 der::kTagConstructed | der::kTagContextSpecific | 2, &present)) { | |
108 return false; | |
109 } | |
110 | |
111 der::Input extensions; | |
112 if (!tbs_cert_parser.ReadOptionalTag( | |
113 der::kTagConstructed | der::kTagContextSpecific | 3, &extensions, | |
114 &present)) { | |
115 return false; | |
116 } | |
117 | |
118 if (!present) { | |
119 *extensions_present = false; | |
120 return true; | |
121 } | |
122 | |
123 // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension | |
124 // Extension ::= SEQUENCE { | |
125 // extnID OBJECT IDENTIFIER, | |
126 // critical BOOLEAN DEFAULT FALSE, | |
127 // extnValue OCTET STRING } | |
128 | |
129 // |extensions| was EXPLICITly tagged, so we still need to remove the | |
130 // ASN.1 SEQUENCE header. | |
131 der::Parser explicit_extensions_parser(extensions); | |
132 if (!explicit_extensions_parser.ReadSequence(extensions_parser)) | |
133 return false; | |
134 | |
135 if (explicit_extensions_parser.HasMore()) | |
136 return false; | |
137 | |
138 *extensions_present = true; | |
139 return true; | |
140 } | |
141 | |
73 } // namespace | 142 } // namespace |
74 | 143 |
75 bool ExtractSPKIFromDERCert(base::StringPiece cert, | 144 bool ExtractSPKIFromDERCert(base::StringPiece cert, |
76 base::StringPiece* spki_out) { | 145 base::StringPiece* spki_out) { |
77 der::Parser parser; | 146 der::Parser parser; |
78 if (!SeekToSPKI(der::Input(cert), &parser)) | 147 if (!SeekToSPKI(der::Input(cert), &parser)) |
79 return false; | 148 return false; |
80 der::Input spki; | 149 der::Input spki; |
81 if (!parser.ReadRawTLV(&spki)) | 150 if (!parser.ReadRawTLV(&spki)) |
82 return false; | 151 return false; |
(...skipping 28 matching lines...) Expand all Loading... | |
111 return false; | 180 return false; |
112 *spk_out = spk.AsStringPiece(); | 181 *spk_out = spk.AsStringPiece(); |
113 return true; | 182 return true; |
114 } | 183 } |
115 | 184 |
116 | 185 |
117 bool ExtractCRLURLsFromDERCert(base::StringPiece cert, | 186 bool ExtractCRLURLsFromDERCert(base::StringPiece cert, |
118 std::vector<base::StringPiece>* urls_out) { | 187 std::vector<base::StringPiece>* urls_out) { |
119 urls_out->clear(); | 188 urls_out->clear(); |
120 std::vector<base::StringPiece> tmp_urls_out; | 189 std::vector<base::StringPiece> tmp_urls_out; |
121 | |
122 bool present; | 190 bool present; |
123 der::Parser tbs_cert_parser; | 191 der::Parser extensions_parser; |
124 if (!SeekToSPKI(der::Input(cert), &tbs_cert_parser)) | 192 if (!SeekToExtensions(der::Input(cert), &present, &extensions_parser)) |
125 return false; | 193 return false; |
126 | 194 |
127 // From RFC 5280, section 4.1 | 195 if (!present) { |
128 // TBSCertificate ::= SEQUENCE { | 196 LOG(ERROR) << "No extensions!"; |
eroman
2016/10/21 01:49:22
nit: Why add the log statement?
estark
2016/10/21 02:11:29
Doh, sorry, thought I deleted that. It's gone now.
| |
129 // ... | 197 return true; |
130 // subjectPublicKeyInfo SubjectPublicKeyInfo, | |
131 // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, | |
132 // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, | |
133 // extensions [3] EXPLICIT Extensions OPTIONAL } | |
134 | |
135 // subjectPublicKeyInfo | |
136 if (!tbs_cert_parser.SkipTag(der::kSequence)) | |
137 return false; | |
138 // issuerUniqueID | |
139 if (!tbs_cert_parser.SkipOptionalTag( | |
140 der::kTagConstructed | der::kTagContextSpecific | 1, &present)) { | |
141 return false; | |
142 } | 198 } |
143 // subjectUniqueID | |
144 if (!tbs_cert_parser.SkipOptionalTag( | |
145 der::kTagConstructed | der::kTagContextSpecific | 2, &present)) { | |
146 return false; | |
147 } | |
148 | |
149 der::Input extensions; | |
150 if (!tbs_cert_parser.ReadOptionalTag( | |
151 der::kTagConstructed | der::kTagContextSpecific | 3, &extensions, | |
152 &present)) { | |
153 return false; | |
154 } | |
155 | |
156 if (!present) | |
157 return true; | |
158 | |
159 // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension | |
160 // Extension ::= SEQUENCE { | |
161 // extnID OBJECT IDENTIFIER, | |
162 // critical BOOLEAN DEFAULT FALSE, | |
163 // extnValue OCTET STRING } | |
164 | |
165 // |extensions| was EXPLICITly tagged, so we still need to remove the | |
166 // ASN.1 SEQUENCE header. | |
167 der::Parser explicit_extensions_parser(extensions); | |
168 der::Parser extensions_parser; | |
169 if (!explicit_extensions_parser.ReadSequence(&extensions_parser)) | |
170 return false; | |
171 | |
172 if (explicit_extensions_parser.HasMore()) | |
173 return false; | |
174 | 199 |
175 while (extensions_parser.HasMore()) { | 200 while (extensions_parser.HasMore()) { |
176 der::Parser extension_parser; | 201 der::Parser extension_parser; |
177 if (!extensions_parser.ReadSequence(&extension_parser)) | 202 if (!extensions_parser.ReadSequence(&extension_parser)) |
178 return false; | 203 return false; |
179 | 204 |
180 der::Input oid; | 205 der::Input oid; |
181 if (!extension_parser.ReadTag(der::kOid, &oid)) | 206 if (!extension_parser.ReadTag(der::kOid, &oid)) |
182 return false; | 207 return false; |
183 | 208 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
282 } | 307 } |
283 } | 308 } |
284 } | 309 } |
285 } | 310 } |
286 } | 311 } |
287 | 312 |
288 urls_out->swap(tmp_urls_out); | 313 urls_out->swap(tmp_urls_out); |
289 return true; | 314 return true; |
290 } | 315 } |
291 | 316 |
317 bool HasTLSFeatureExtension(base::StringPiece cert, | |
318 bool* has_tls_feature_extension) { | |
319 bool present; | |
320 der::Parser extensions_parser; | |
321 if (!SeekToExtensions(der::Input(cert), &present, &extensions_parser)) | |
322 return false; | |
323 if (!present) { | |
324 *has_tls_feature_extension = false; | |
325 return true; | |
326 } | |
327 | |
328 while (extensions_parser.HasMore()) { | |
329 der::Parser extension_parser; | |
330 if (!extensions_parser.ReadSequence(&extension_parser)) | |
331 return false; | |
332 | |
333 der::Input oid; | |
334 if (!extension_parser.ReadTag(der::kOid, &oid)) | |
335 return false; | |
336 | |
337 // kTLSFeatureExtensionOID is the DER encoding of the OID for the | |
338 // X.509 TLS Feature Extension. | |
339 static const uint8_t kTLSFeatureExtensionOID[] = {0x2B, 0x06, 0x01, 0x05, | |
340 0x05, 0x07, 0x01, 0x18}; | |
341 | |
342 if (oid == der::Input(kTLSFeatureExtensionOID)) { | |
343 *has_tls_feature_extension = true; | |
344 return true; | |
345 } | |
346 } | |
347 | |
348 *has_tls_feature_extension = false; | |
349 return true; | |
350 } | |
351 | |
292 } // namespace asn1 | 352 } // namespace asn1 |
293 | 353 |
294 } // namespace net | 354 } // namespace net |
OLD | NEW |