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 | |
128 // TBSCertificate ::= SEQUENCE { | |
129 // ... | |
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 } | |
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) | 195 if (!present) |
157 return true; | 196 return true; |
158 | 197 |
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 | |
175 while (extensions_parser.HasMore()) { | 198 while (extensions_parser.HasMore()) { |
176 der::Parser extension_parser; | 199 der::Parser extension_parser; |
177 if (!extensions_parser.ReadSequence(&extension_parser)) | 200 if (!extensions_parser.ReadSequence(&extension_parser)) |
178 return false; | 201 return false; |
179 | 202 |
180 der::Input oid; | 203 der::Input oid; |
181 if (!extension_parser.ReadTag(der::kOid, &oid)) | 204 if (!extension_parser.ReadTag(der::kOid, &oid)) |
182 return false; | 205 return false; |
183 | 206 |
184 // kCRLDistributionPointsOID is the DER encoding of the OID for the X.509 | 207 // kCRLDistributionPointsOID is the DER encoding of the OID for the X.509 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 } | 305 } |
283 } | 306 } |
284 } | 307 } |
285 } | 308 } |
286 } | 309 } |
287 | 310 |
288 urls_out->swap(tmp_urls_out); | 311 urls_out->swap(tmp_urls_out); |
289 return true; | 312 return true; |
290 } | 313 } |
291 | 314 |
| 315 bool HasTLSFeatureExtension(base::StringPiece cert) { |
| 316 bool present; |
| 317 der::Parser extensions_parser; |
| 318 if (!SeekToExtensions(der::Input(cert), &present, &extensions_parser)) |
| 319 return false; |
| 320 if (!present) |
| 321 return false; |
| 322 |
| 323 while (extensions_parser.HasMore()) { |
| 324 der::Parser extension_parser; |
| 325 if (!extensions_parser.ReadSequence(&extension_parser)) |
| 326 return false; |
| 327 |
| 328 der::Input oid; |
| 329 if (!extension_parser.ReadTag(der::kOid, &oid)) |
| 330 return false; |
| 331 |
| 332 // kTLSFeatureExtensionOID is the DER encoding of the OID for the |
| 333 // X.509 TLS Feature Extension. |
| 334 static const uint8_t kTLSFeatureExtensionOID[] = {0x2B, 0x06, 0x01, 0x05, |
| 335 0x05, 0x07, 0x01, 0x18}; |
| 336 if (oid == der::Input(kTLSFeatureExtensionOID)) |
| 337 return true; |
| 338 } |
| 339 |
| 340 return false; |
| 341 } |
| 342 |
292 } // namespace asn1 | 343 } // namespace asn1 |
293 | 344 |
294 } // namespace net | 345 } // namespace net |
OLD | NEW |