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 namespace net { | 7 namespace net { |
8 | 8 |
9 namespace asn1 { | 9 namespace asn1 { |
10 | 10 |
11 bool ParseElement(base::StringPiece* in, | 11 bool ParseElement(base::StringPiece* in, |
12 unsigned tag_value, | 12 unsigned tag_value, |
13 base::StringPiece* out, | 13 base::StringPiece* out, |
14 unsigned *out_header_len) { | 14 unsigned* out_header_len) { |
15 const uint8* data = reinterpret_cast<const uint8*>(in->data()); | 15 const uint8* data = reinterpret_cast<const uint8*>(in->data()); |
16 | 16 |
17 // We don't support kAny and kOptional at the same time. | 17 // We don't support kAny and kOptional at the same time. |
18 if ((tag_value & kAny) && (tag_value & kOptional)) | 18 if ((tag_value & kAny) && (tag_value & kOptional)) |
19 return false; | 19 return false; |
20 | 20 |
21 if (in->empty() && (tag_value & kOptional)) { | 21 if (in->empty() && (tag_value & kOptional)) { |
22 if (out_header_len) | 22 if (out_header_len) |
23 *out_header_len = 0; | 23 *out_header_len = 0; |
24 if (out) | 24 if (out) |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 base::StringPiece algorithm; | 177 base::StringPiece algorithm; |
178 if (!asn1::GetElement(&spki_contents, asn1::kSEQUENCE, &algorithm)) | 178 if (!asn1::GetElement(&spki_contents, asn1::kSEQUENCE, &algorithm)) |
179 return false; | 179 return false; |
180 | 180 |
181 // Extract the subjectPublicKey field. | 181 // Extract the subjectPublicKey field. |
182 if (!asn1::GetElement(&spki_contents, asn1::kBITSTRING, spk_out)) | 182 if (!asn1::GetElement(&spki_contents, asn1::kBITSTRING, spk_out)) |
183 return false; | 183 return false; |
184 return true; | 184 return true; |
185 } | 185 } |
186 | 186 |
187 | |
188 bool ExtractCRLURLsFromDERCert(base::StringPiece cert, | 187 bool ExtractCRLURLsFromDERCert(base::StringPiece cert, |
189 std::vector<base::StringPiece>* urls_out) { | 188 std::vector<base::StringPiece>* urls_out) { |
190 urls_out->clear(); | 189 urls_out->clear(); |
191 std::vector<base::StringPiece> tmp_urls_out; | 190 std::vector<base::StringPiece> tmp_urls_out; |
192 | 191 |
193 if (!SeekToSPKI(&cert)) | 192 if (!SeekToSPKI(&cert)) |
194 return false; | 193 return false; |
195 | 194 |
196 // From RFC 5280, section 4.1 | 195 // From RFC 5280, section 4.1 |
197 // TBSCertificate ::= SEQUENCE { | 196 // TBSCertificate ::= SEQUENCE { |
198 // ... | 197 // ... |
199 // subjectPublicKeyInfo SubjectPublicKeyInfo, | 198 // subjectPublicKeyInfo SubjectPublicKeyInfo, |
200 // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, | 199 // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, |
201 // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, | 200 // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, |
202 // extensions [3] EXPLICIT Extensions OPTIONAL | 201 // extensions [3] EXPLICIT Extensions OPTIONAL |
203 | 202 |
204 // subjectPublicKeyInfo | 203 // subjectPublicKeyInfo |
205 if (!GetElement(&cert, kSEQUENCE, NULL)) | 204 if (!GetElement(&cert, kSEQUENCE, NULL)) |
206 return false; | 205 return false; |
207 // issuerUniqueID | 206 // issuerUniqueID |
208 if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 1, NULL)) | 207 if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 1, NULL)) |
209 return false; | 208 return false; |
210 // subjectUniqueID | 209 // subjectUniqueID |
211 if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 2, NULL)) | 210 if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 2, NULL)) |
212 return false; | 211 return false; |
213 | 212 |
214 base::StringPiece extensions_seq; | 213 base::StringPiece extensions_seq; |
215 if (!GetElement(&cert, kOptional | kConstructed | kContextSpecific | 3, | 214 if (!GetElement(&cert, |
| 215 kOptional | kConstructed | kContextSpecific | 3, |
216 &extensions_seq)) { | 216 &extensions_seq)) { |
217 return false; | 217 return false; |
218 } | 218 } |
219 | 219 |
220 if (extensions_seq.empty()) | 220 if (extensions_seq.empty()) |
221 return true; | 221 return true; |
222 | 222 |
223 // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension | 223 // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension |
224 // Extension ::= SEQUENCE { | 224 // Extension ::= SEQUENCE { |
225 // extnID OBJECT IDENTIFIER, | 225 // extnID OBJECT IDENTIFIER, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 base::StringPiece distribution_points; | 270 base::StringPiece distribution_points; |
271 if (!GetElement(&extension_value, kSEQUENCE, &distribution_points)) | 271 if (!GetElement(&extension_value, kSEQUENCE, &distribution_points)) |
272 return false; | 272 return false; |
273 | 273 |
274 while (distribution_points.size() > 0) { | 274 while (distribution_points.size() > 0) { |
275 base::StringPiece distrib_point; | 275 base::StringPiece distrib_point; |
276 if (!GetElement(&distribution_points, kSEQUENCE, &distrib_point)) | 276 if (!GetElement(&distribution_points, kSEQUENCE, &distrib_point)) |
277 return false; | 277 return false; |
278 | 278 |
279 base::StringPiece name; | 279 base::StringPiece name; |
280 if (!GetElement(&distrib_point, kContextSpecific | kConstructed | 0, | 280 if (!GetElement( |
281 &name)) { | 281 &distrib_point, kContextSpecific | kConstructed | 0, &name)) { |
282 // If it doesn't contain a name then we skip it. | 282 // If it doesn't contain a name then we skip it. |
283 continue; | 283 continue; |
284 } | 284 } |
285 | 285 |
286 if (GetElement(&distrib_point, kContextSpecific | 1, NULL)) { | 286 if (GetElement(&distrib_point, kContextSpecific | 1, NULL)) { |
287 // If it contains a subset of reasons then we skip it. We aren't | 287 // If it contains a subset of reasons then we skip it. We aren't |
288 // interested in subsets of CRLs and the RFC states that there MUST be | 288 // interested in subsets of CRLs and the RFC states that there MUST be |
289 // a CRL that covers all reasons. | 289 // a CRL that covers all reasons. |
290 continue; | 290 continue; |
291 } | 291 } |
292 | 292 |
293 if (GetElement(&distrib_point, | 293 if (GetElement( |
294 kContextSpecific | kConstructed | 2, NULL)) { | 294 &distrib_point, kContextSpecific | kConstructed | 2, NULL)) { |
295 // If it contains a alternative issuer, then we skip it. | 295 // If it contains a alternative issuer, then we skip it. |
296 continue; | 296 continue; |
297 } | 297 } |
298 | 298 |
299 // DistributionPointName ::= CHOICE { | 299 // DistributionPointName ::= CHOICE { |
300 // fullName [0] GeneralNames, | 300 // fullName [0] GeneralNames, |
301 // nameRelativeToCRLIssuer [1] RelativeDistinguishedName } | 301 // nameRelativeToCRLIssuer [1] RelativeDistinguishedName } |
302 base::StringPiece general_names; | 302 base::StringPiece general_names; |
303 if (!GetElement(&name, | 303 if (!GetElement( |
304 kContextSpecific | kConstructed | 0, &general_names)) { | 304 &name, kContextSpecific | kConstructed | 0, &general_names)) { |
305 continue; | 305 continue; |
306 } | 306 } |
307 | 307 |
308 // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName | 308 // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName |
309 // GeneralName ::= CHOICE { | 309 // GeneralName ::= CHOICE { |
310 // ... | 310 // ... |
311 // uniformResourceIdentifier [6] IA5String, | 311 // uniformResourceIdentifier [6] IA5String, |
312 // ... | 312 // ... |
313 while (general_names.size() > 0) { | 313 while (general_names.size() > 0) { |
314 base::StringPiece url; | 314 base::StringPiece url; |
315 if (GetElement(&general_names, kContextSpecific | 6, &url)) { | 315 if (GetElement(&general_names, kContextSpecific | 6, &url)) { |
316 tmp_urls_out.push_back(url); | 316 tmp_urls_out.push_back(url); |
317 } else { | 317 } else { |
318 if (!GetElement(&general_names, kAny, NULL)) | 318 if (!GetElement(&general_names, kAny, NULL)) |
319 return false; | 319 return false; |
320 } | 320 } |
321 } | 321 } |
322 } | 322 } |
323 } | 323 } |
324 | 324 |
325 urls_out->swap(tmp_urls_out); | 325 urls_out->swap(tmp_urls_out); |
326 return true; | 326 return true; |
327 } | 327 } |
328 | 328 |
329 } // namespace asn1 | 329 } // namespace asn1 |
330 | 330 |
331 } // namespace net | 331 } // namespace net |
OLD | NEW |