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

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

Issue 1849773002: Adding OCSP Verification Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix scoped_ptr. Created 4 years, 7 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 2016 The Chromium Authors. All rights reserved. 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 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/internal/ocsp.h"
6
5 #include <algorithm> 7 #include <algorithm>
6 8
7 #include "base/sha1.h" 9 #include "base/sha1.h"
8 #include "crypto/sha2.h" 10 #include "crypto/sha2.h"
9 #include "net/cert/internal/parse_ocsp.h" 11 #include "net/cert/internal/extended_key_usage.h"
12 #include "net/cert/internal/verify_name_match.h"
13 #include "net/cert/internal/verify_signed_data.h"
10 14
11 namespace net { 15 namespace net {
12 16
13 OCSPCertID::OCSPCertID() {} 17 OCSPCertID::OCSPCertID() {}
14 OCSPCertID::~OCSPCertID() {} 18 OCSPCertID::~OCSPCertID() {}
15 19
16 OCSPSingleResponse::OCSPSingleResponse() {} 20 OCSPSingleResponse::OCSPSingleResponse() {}
17 OCSPSingleResponse::~OCSPSingleResponse() {} 21 OCSPSingleResponse::~OCSPSingleResponse() {}
18 22
19 OCSPResponseData::OCSPResponseData() {} 23 OCSPResponseData::OCSPResponseData() {}
20 OCSPResponseData::~OCSPResponseData() {} 24 OCSPResponseData::~OCSPResponseData() {}
21 25
22 OCSPResponse::OCSPResponse() {} 26 OCSPResponse::OCSPResponse() {}
23 OCSPResponse::~OCSPResponse() {} 27 OCSPResponse::~OCSPResponse() {}
24 28
25 der::Input BasicOCSPResponseOid() { 29 WARN_UNUSED_RESULT der::Input BasicOCSPResponseOid() {
26 // From RFC 6960: 30 // From RFC 6960:
27 // 31 //
28 // id-pkix-ocsp OBJECT IDENTIFIER ::= { id-ad-ocsp } 32 // id-pkix-ocsp OBJECT IDENTIFIER ::= { id-ad-ocsp }
29 // id-pkix-ocsp-basic OBJECT IDENTIFIER ::= { id-pkix-ocsp 1 } 33 // id-pkix-ocsp-basic OBJECT IDENTIFIER ::= { id-pkix-ocsp 1 }
30 // 34 //
31 // In dotted notation: 1.3.6.1.5.5.7.48.1.1 35 // In dotted notation: 1.3.6.1.5.5.7.48.1.1
32 static const uint8_t oid[] = {0x2b, 0x06, 0x01, 0x05, 0x05, 36 static const uint8_t oid[] = {0x2b, 0x06, 0x01, 0x05, 0x05,
33 0x07, 0x30, 0x01, 0x01}; 37 0x07, 0x30, 0x01, 0x01};
34 return der::Input(oid); 38 return der::Input(oid);
35 } 39 }
36 40
37 // CertID ::= SEQUENCE { 41 // CertID ::= SEQUENCE {
38 // hashAlgorithm AlgorithmIdentifier, 42 // hashAlgorithm AlgorithmIdentifier,
39 // issuerNameHash OCTET STRING, -- Hash of issuer's DN 43 // issuerNameHash OCTET STRING, -- Hash of issuer's DN
40 // issuerKeyHash OCTET STRING, -- Hash of issuer's public key 44 // issuerKeyHash OCTET STRING, -- Hash of issuer's public key
41 // serialNumber CertificateSerialNumber 45 // serialNumber CertificateSerialNumber
42 // } 46 // }
43 bool ParseOCSPCertID(const der::Input& raw_tlv, OCSPCertID* out) { 47 WARN_UNUSED_RESULT bool ParseOCSPCertID(const der::Input& raw_tlv,
48 OCSPCertID* out) {
44 der::Parser outer_parser(raw_tlv); 49 der::Parser outer_parser(raw_tlv);
45 der::Parser parser; 50 der::Parser parser;
46 if (!outer_parser.ReadSequence(&parser)) 51 if (!outer_parser.ReadSequence(&parser))
47 return false; 52 return false;
48 if (outer_parser.HasMore()) 53 if (outer_parser.HasMore())
49 return false; 54 return false;
50 55
51 der::Input sigalg_tlv; 56 der::Input sigalg_tlv;
52 if (!parser.ReadRawTLV(&sigalg_tlv)) 57 if (!parser.ReadRawTLV(&sigalg_tlv))
53 return false; 58 return false;
(...skipping 14 matching lines...) Expand all
68 namespace { 73 namespace {
69 74
70 // Parses |raw_tlv| to extract an OCSP RevokedInfo (RFC 6960) and stores the 75 // Parses |raw_tlv| to extract an OCSP RevokedInfo (RFC 6960) and stores the
71 // result in the OCSPCertStatus |out|. Returns whether the parsing was 76 // result in the OCSPCertStatus |out|. Returns whether the parsing was
72 // successful. 77 // successful.
73 // 78 //
74 // RevokedInfo ::= SEQUENCE { 79 // RevokedInfo ::= SEQUENCE {
75 // revocationTime GeneralizedTime, 80 // revocationTime GeneralizedTime,
76 // revocationReason [0] EXPLICIT CRLReason OPTIONAL 81 // revocationReason [0] EXPLICIT CRLReason OPTIONAL
77 // } 82 // }
78 bool ParseRevokedInfo(const der::Input& raw_tlv, OCSPCertStatus* out) { 83 WARN_UNUSED_RESULT bool ParseRevokedInfo(const der::Input& raw_tlv,
84 OCSPCertStatus* out) {
79 der::Parser parser(raw_tlv); 85 der::Parser parser(raw_tlv);
80 if (!parser.ReadGeneralizedTime(&(out->revocation_time))) 86 if (!parser.ReadGeneralizedTime(&(out->revocation_time)))
81 return false; 87 return false;
82 88
83 der::Input reason_input; 89 der::Input reason_input;
84 if (!parser.ReadOptionalTag(der::ContextSpecificConstructed(0), &reason_input, 90 if (!parser.ReadOptionalTag(der::ContextSpecificConstructed(0), &reason_input,
85 &(out->has_reason))) { 91 &(out->has_reason))) {
86 return false; 92 return false;
87 } 93 }
88 if (out->has_reason) { 94 if (out->has_reason) {
(...skipping 22 matching lines...) Expand all
111 // result in the OCSPCertStatus |out|. Returns whether the parsing was 117 // result in the OCSPCertStatus |out|. Returns whether the parsing was
112 // successful. 118 // successful.
113 // 119 //
114 // CertStatus ::= CHOICE { 120 // CertStatus ::= CHOICE {
115 // good [0] IMPLICIT NULL, 121 // good [0] IMPLICIT NULL,
116 // revoked [1] IMPLICIT RevokedInfo, 122 // revoked [1] IMPLICIT RevokedInfo,
117 // unknown [2] IMPLICIT UnknownInfo 123 // unknown [2] IMPLICIT UnknownInfo
118 // } 124 // }
119 // 125 //
120 // UnknownInfo ::= NULL 126 // UnknownInfo ::= NULL
121 bool ParseCertStatus(const der::Input& raw_tlv, OCSPCertStatus* out) { 127 WARN_UNUSED_RESULT bool ParseCertStatus(const der::Input& raw_tlv,
128 OCSPCertStatus* out) {
122 der::Parser parser(raw_tlv); 129 der::Parser parser(raw_tlv);
123 der::Tag status_tag; 130 der::Tag status_tag;
124 der::Input status; 131 der::Input status;
125 if (!parser.ReadTagAndValue(&status_tag, &status)) 132 if (!parser.ReadTagAndValue(&status_tag, &status))
126 return false; 133 return false;
127 134
128 out->has_reason = false; 135 out->has_reason = false;
129 if (status_tag == der::ContextSpecificPrimitive(0)) { 136 if (status_tag == der::ContextSpecificPrimitive(0)) {
130 out->status = OCSPCertStatus::Status::GOOD; 137 out->status = OCSPCertStatus::Status::GOOD;
131 } else if (status_tag == der::ContextSpecificConstructed(1)) { 138 } else if (status_tag == der::ContextSpecificConstructed(1)) {
(...skipping 11 matching lines...) Expand all
143 150
144 } // namespace 151 } // namespace
145 152
146 // SingleResponse ::= SEQUENCE { 153 // SingleResponse ::= SEQUENCE {
147 // certID CertID, 154 // certID CertID,
148 // certStatus CertStatus, 155 // certStatus CertStatus,
149 // thisUpdate GeneralizedTime, 156 // thisUpdate GeneralizedTime,
150 // nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, 157 // nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
151 // singleExtensions [1] EXPLICIT Extensions OPTIONAL 158 // singleExtensions [1] EXPLICIT Extensions OPTIONAL
152 // } 159 // }
153 bool ParseOCSPSingleResponse(const der::Input& raw_tlv, 160 WARN_UNUSED_RESULT bool ParseOCSPSingleResponse(const der::Input& raw_tlv,
154 OCSPSingleResponse* out) { 161 OCSPSingleResponse* out) {
155 der::Parser outer_parser(raw_tlv); 162 der::Parser outer_parser(raw_tlv);
156 der::Parser parser; 163 der::Parser parser;
157 if (!outer_parser.ReadSequence(&parser)) 164 if (!outer_parser.ReadSequence(&parser))
158 return false; 165 return false;
159 if (outer_parser.HasMore()) 166 if (outer_parser.HasMore())
160 return false; 167 return false;
161 168
162 if (!parser.ReadRawTLV(&(out->cert_id_tlv))) 169 if (!parser.ReadRawTLV(&(out->cert_id_tlv)))
163 return false; 170 return false;
164 der::Input status_tlv; 171 der::Input status_tlv;
(...skipping 27 matching lines...) Expand all
192 199
193 namespace { 200 namespace {
194 201
195 // Parses |raw_tlv| to extract a ResponderID (RFC 6960) and stores the 202 // Parses |raw_tlv| to extract a ResponderID (RFC 6960) and stores the
196 // result in the ResponderID |out|. Returns whether the parsing was successful. 203 // result in the ResponderID |out|. Returns whether the parsing was successful.
197 // 204 //
198 // ResponderID ::= CHOICE { 205 // ResponderID ::= CHOICE {
199 // byName [1] Name, 206 // byName [1] Name,
200 // byKey [2] KeyHash 207 // byKey [2] KeyHash
201 // } 208 // }
202 bool ParseResponderID(const der::Input& raw_tlv, 209 WARN_UNUSED_RESULT bool ParseResponderID(const der::Input& raw_tlv,
203 OCSPResponseData::ResponderID* out) { 210 OCSPResponseData::ResponderID* out) {
204 der::Parser parser(raw_tlv); 211 der::Parser parser(raw_tlv);
205 der::Tag id_tag; 212 der::Tag id_tag;
206 der::Input id_input; 213 der::Input id_input;
207 if (!parser.ReadTagAndValue(&id_tag, &id_input)) 214 if (!parser.ReadTagAndValue(&id_tag, &id_input))
208 return false; 215 return false;
209 216
210 if (id_tag == der::ContextSpecificConstructed(1)) { 217 if (id_tag == der::ContextSpecificConstructed(1)) {
211 out->type = OCSPResponseData::ResponderType::NAME; 218 out->type = OCSPResponseData::ResponderType::NAME;
212 out->name = id_input; 219 out->name = id_input;
213 } else if (id_tag == der::ContextSpecificConstructed(2)) { 220 } else if (id_tag == der::ContextSpecificConstructed(2)) {
(...skipping 18 matching lines...) Expand all
232 239
233 } // namespace 240 } // namespace
234 241
235 // ResponseData ::= SEQUENCE { 242 // ResponseData ::= SEQUENCE {
236 // version [0] EXPLICIT Version DEFAULT v1, 243 // version [0] EXPLICIT Version DEFAULT v1,
237 // responderID ResponderID, 244 // responderID ResponderID,
238 // producedAt GeneralizedTime, 245 // producedAt GeneralizedTime,
239 // responses SEQUENCE OF SingleResponse, 246 // responses SEQUENCE OF SingleResponse,
240 // responseExtensions [1] EXPLICIT Extensions OPTIONAL 247 // responseExtensions [1] EXPLICIT Extensions OPTIONAL
241 // } 248 // }
242 bool ParseOCSPResponseData(const der::Input& raw_tlv, OCSPResponseData* out) { 249 WARN_UNUSED_RESULT bool ParseOCSPResponseData(const der::Input& raw_tlv,
250 OCSPResponseData* out) {
243 der::Parser outer_parser(raw_tlv); 251 der::Parser outer_parser(raw_tlv);
244 der::Parser parser; 252 der::Parser parser;
245 if (!outer_parser.ReadSequence(&parser)) 253 if (!outer_parser.ReadSequence(&parser))
246 return false; 254 return false;
247 if (outer_parser.HasMore()) 255 if (outer_parser.HasMore())
248 return false; 256 return false;
249 257
250 der::Input version_input; 258 der::Input version_input;
251 bool version_present; 259 bool version_present;
252 if (!parser.ReadOptionalTag(der::ContextSpecificConstructed(0), 260 if (!parser.ReadOptionalTag(der::ContextSpecificConstructed(0),
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 // Parses |raw_tlv| to extract a BasicOCSPResponse (RFC 6960) and stores the 310 // Parses |raw_tlv| to extract a BasicOCSPResponse (RFC 6960) and stores the
303 // result in the OCSPResponse |out|. Returns whether the parsing was 311 // result in the OCSPResponse |out|. Returns whether the parsing was
304 // successful. 312 // successful.
305 // 313 //
306 // BasicOCSPResponse ::= SEQUENCE { 314 // BasicOCSPResponse ::= SEQUENCE {
307 // tbsResponseData ResponseData, 315 // tbsResponseData ResponseData,
308 // signatureAlgorithm AlgorithmIdentifier, 316 // signatureAlgorithm AlgorithmIdentifier,
309 // signature BIT STRING, 317 // signature BIT STRING,
310 // certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL 318 // certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL
311 // } 319 // }
312 bool ParseBasicOCSPResponse(const der::Input& raw_tlv, OCSPResponse* out) { 320 WARN_UNUSED_RESULT bool ParseBasicOCSPResponse(const der::Input& raw_tlv,
321 OCSPResponse* out) {
313 der::Parser outer_parser(raw_tlv); 322 der::Parser outer_parser(raw_tlv);
314 der::Parser parser; 323 der::Parser parser;
315 if (!outer_parser.ReadSequence(&parser)) 324 if (!outer_parser.ReadSequence(&parser))
316 return false; 325 return false;
317 if (outer_parser.HasMore()) 326 if (outer_parser.HasMore())
318 return false; 327 return false;
319 328
320 if (!parser.ReadRawTLV(&(out->data))) 329 if (!parser.ReadRawTLV(&(out->data)))
321 return false; 330 return false;
322 der::Input sigalg_tlv; 331 der::Input sigalg_tlv;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 365
357 // OCSPResponse ::= SEQUENCE { 366 // OCSPResponse ::= SEQUENCE {
358 // responseStatus OCSPResponseStatus, 367 // responseStatus OCSPResponseStatus,
359 // responseBytes [0] EXPLICIT ResponseBytes OPTIONAL 368 // responseBytes [0] EXPLICIT ResponseBytes OPTIONAL
360 // } 369 // }
361 // 370 //
362 // ResponseBytes ::= SEQUENCE { 371 // ResponseBytes ::= SEQUENCE {
363 // responseType OBJECT IDENTIFIER, 372 // responseType OBJECT IDENTIFIER,
364 // response OCTET STRING 373 // response OCTET STRING
365 // } 374 // }
366 bool ParseOCSPResponse(const der::Input& raw_tlv, OCSPResponse* out) { 375 WARN_UNUSED_RESULT bool ParseOCSPResponse(const der::Input& raw_tlv,
376 OCSPResponse* out) {
367 der::Parser outer_parser(raw_tlv); 377 der::Parser outer_parser(raw_tlv);
368 der::Parser parser; 378 der::Parser parser;
369 if (!outer_parser.ReadSequence(&parser)) 379 if (!outer_parser.ReadSequence(&parser))
370 return false; 380 return false;
371 if (outer_parser.HasMore()) 381 if (outer_parser.HasMore())
372 return false; 382 return false;
373 383
374 der::Input response_status_input; 384 der::Input response_status_input;
375 uint8_t response_status; 385 uint8_t response_status;
376 if (!parser.ReadTag(der::kEnumerated, &response_status_input)) 386 if (!parser.ReadTag(der::kEnumerated, &response_status_input))
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 if (bytes_parser.HasMore()) 423 if (bytes_parser.HasMore())
414 return false; 424 return false;
415 } 425 }
416 426
417 return !parser.HasMore(); 427 return !parser.HasMore();
418 } 428 }
419 429
420 namespace { 430 namespace {
421 431
422 // Checks that the |type| hash of |value| is equal to |hash| 432 // Checks that the |type| hash of |value| is equal to |hash|
423 bool VerifyHash(HashValueTag type, 433 WARN_UNUSED_RESULT bool VerifyHash(HashValueTag type,
424 const der::Input& hash, 434 const der::Input& hash,
425 const der::Input& value) { 435 const der::Input& value) {
426 HashValue target(type); 436 HashValue target(type);
427 if (target.size() != hash.Length()) 437 if (target.size() != hash.Length())
428 return false; 438 return false;
429 memcpy(target.data(), hash.UnsafeData(), target.size()); 439 memcpy(target.data(), hash.UnsafeData(), target.size());
430 440
431 HashValue value_hash(type); 441 HashValue value_hash(type);
432 if (type == HASH_VALUE_SHA1) { 442 if (type == HASH_VALUE_SHA1) {
433 base::SHA1HashBytes(value.UnsafeData(), value.Length(), value_hash.data()); 443 base::SHA1HashBytes(value.UnsafeData(), value.Length(), value_hash.data());
434 } else if (type == HASH_VALUE_SHA256) { 444 } else if (type == HASH_VALUE_SHA256) {
435 std::string hash_string = crypto::SHA256HashString(value.AsString()); 445 std::string hash_string = crypto::SHA256HashString(value.AsString());
436 memcpy(value_hash.data(), hash_string.data(), value_hash.size()); 446 memcpy(value_hash.data(), hash_string.data(), value_hash.size());
437 } else { 447 } else {
438 return false; 448 return false;
439 } 449 }
440 450
441 return target.Equals(value_hash); 451 return target.Equals(value_hash);
442 } 452 }
443 453
444 // Checks that the input |id_tlv| parses to a valid CertID and matches the 454 // Checks that the input |id_tlv| parses to a valid CertID and matches the
445 // issuer |issuer| name and key, as well as the serial number |serial_number|. 455 // issuer |issuer| name and key, as well as the serial number |serial_number|.
446 bool CheckCertID(const der::Input& id_tlv, 456 WARN_UNUSED_RESULT bool CheckCertID(const der::Input& id_tlv,
447 const ParsedTbsCertificate& certificate, 457 const ParsedTbsCertificate& certificate,
448 const ParsedTbsCertificate& issuer, 458 const ParsedTbsCertificate& issuer,
449 const der::Input& serial_number) { 459 const der::Input& serial_number) {
450 OCSPCertID id; 460 OCSPCertID id;
451 if (!ParseOCSPCertID(id_tlv, &id)) 461 if (!ParseOCSPCertID(id_tlv, &id))
452 return false; 462 return false;
453 463
454 HashValueTag type = HASH_VALUE_SHA1; 464 HashValueTag type = HASH_VALUE_SHA1;
455 switch (id.hash_algorithm) { 465 switch (id.hash_algorithm) {
456 case DigestAlgorithm::Sha1: 466 case DigestAlgorithm::Sha1:
457 type = HASH_VALUE_SHA1; 467 type = HASH_VALUE_SHA1;
458 break; 468 break;
459 case DigestAlgorithm::Sha256: 469 case DigestAlgorithm::Sha256:
(...skipping 25 matching lines...) Expand all
485 return false; 495 return false;
486 der::Input key_tlv = key_bits.bytes(); 496 der::Input key_tlv = key_bits.bytes();
487 if (!VerifyHash(type, id.issuer_key_hash, key_tlv)) 497 if (!VerifyHash(type, id.issuer_key_hash, key_tlv))
488 return false; 498 return false;
489 499
490 return id.serial_number == serial_number; 500 return id.serial_number == serial_number;
491 } 501 }
492 502
493 } // namespace 503 } // namespace
494 504
495 bool GetOCSPCertStatus(const OCSPResponseData& response_data, 505 WARN_UNUSED_RESULT bool GetOCSPCertStatus(const OCSPResponseData& response_data,
496 const ParsedCertificate& issuer, 506 const ParsedCertificate& issuer,
497 const ParsedCertificate& cert, 507 const ParsedCertificate& cert,
498 OCSPCertStatus* out) { 508 OCSPCertStatus* out) {
499 out->status = OCSPCertStatus::Status::GOOD; 509 out->status = OCSPCertStatus::Status::GOOD;
500 510
501 ParsedTbsCertificate tbs_cert; 511 ParsedTbsCertificate tbs_cert;
502 if (!ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs_cert)) 512 if (!ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs_cert))
503 return false; 513 return false;
504 ParsedTbsCertificate issuer_tbs_cert; 514 ParsedTbsCertificate issuer_tbs_cert;
505 if (!ParseTbsCertificate(issuer.tbs_certificate_tlv, &issuer_tbs_cert)) 515 if (!ParseTbsCertificate(issuer.tbs_certificate_tlv, &issuer_tbs_cert))
506 return false; 516 return false;
507 517
508 bool found = false; 518 bool found = false;
(...skipping 13 matching lines...) Expand all
522 } 532 }
523 } 533 }
524 } 534 }
525 535
526 if (!found) 536 if (!found)
527 out->status = OCSPCertStatus::Status::UNKNOWN; 537 out->status = OCSPCertStatus::Status::UNKNOWN;
528 538
529 return found; 539 return found;
530 } 540 }
531 541
542 namespace {
543
544 // Checks that the ResponderID |id| matches the certificate |cert| either
545 // by verifying the name matches that of the certificate or that the hash
546 // matches the certificate's public key hash (RFC 6960, 4.2.2.3).
547 WARN_UNUSED_RESULT bool CheckResponder(const OCSPResponseData::ResponderID& id,
eroman 2016/05/31 19:12:46 Can you use a more specific name -- how about Resp
548 const ParsedTbsCertificate& cert) {
549 if (id.type == OCSPResponseData::ResponderType::NAME) {
550 der::Input name_rdn;
551 der::Input cert_rdn;
552 if (!der::Parser(id.name).ReadTag(der::kSequence, &name_rdn) ||
eroman 2016/05/31 19:12:46 Can you add documentation for ResponderID indicati
553 !der::Parser(cert.subject_tlv).ReadTag(der::kSequence, &cert_rdn))
554 return false;
555 return VerifyNameMatch(name_rdn, cert_rdn);
556 }
eroman 2016/05/31 19:12:46 For future proofing my preference is a switch(). B
557
558 // Otherwise we extract the SPKI and compare the public key hash to key
eroman 2016/05/31 19:12:46 avoid "we" in comments.
559 // in the ResponderID.
560 der::Parser parser(cert.spki_tlv);
561 der::Parser spki_parser;
562 der::BitString key_bits;
563 if (!parser.ReadSequence(&spki_parser))
564 return false;
565 if (!spki_parser.SkipTag(der::kSequence))
566 return false;
567 if (!spki_parser.ReadBitString(&key_bits))
568 return false;
569
570 der::Input key = key_bits.bytes();
571 HashValue key_hash(HASH_VALUE_SHA1);
572 base::SHA1HashBytes(key.UnsafeData(), key.Length(), key_hash.data());
573 return key_hash.Equals(id.key_hash);
574 }
575
576 } // namespace
577
578 WARN_UNUSED_RESULT bool VerifyOCSPResponse(
579 const OCSPResponse& response,
580 const ParsedCertificate& issuer_cert,
581 const SignaturePolicy& signature_policy) {
582 OCSPResponseData response_data;
583 if (!ParseOCSPResponseData(response.data, &response_data))
584 return false;
585
586 ParsedTbsCertificate issuer;
587 ParsedTbsCertificate responder;
588 if (!ParseTbsCertificate(issuer_cert.tbs_certificate_tlv, &issuer))
589 return false;
590
591 // In order to verify the OCSP signature, a valid responder matching the OCSP
592 // Responder ID must be located (RFC 6960, 4.2.2.2). The responder is allowed
593 // to be either the certificate issuer or a delegated authority directly
594 // signed by the issuer.
595 if (CheckResponder(response_data.responder_id, issuer)) {
596 responder = issuer;
597 } else {
598 bool found = false;
599 // If the authority to sign OCSP responses has been delegated to another
600 // authority, the OCSP Response will contain the responder certificate.
eroman 2016/05/31 19:12:46 Is there any normative reference for this logic?
601 for (const auto& responder_cert_tlv : response.certs) {
602 ParsedCertificate responder_cert;
603 ParsedTbsCertificate tbs_cert;
604 if (!ParseCertificate(responder_cert_tlv, &responder_cert))
605 return false;
606 if (!ParseTbsCertificate(responder_cert.tbs_certificate_tlv, &tbs_cert))
607 return false;
608
609 // The OCSP Responder ID is checked against each provided certificate to
610 // determine whether it is the correct Authorized Responder.
611 if (CheckResponder(response_data.responder_id, tbs_cert)) {
612 found = true;
613 responder = tbs_cert;
614
615 // The Authorized Responder must be directly signed by the issuer of the
616 // certificate being checked.
617 std::unique_ptr<SignatureAlgorithm> signature_algorithm =
618 SignatureAlgorithm::CreateFromDer(
619 responder_cert.signature_algorithm_tlv);
620 if (!signature_algorithm)
621 return false;
622 der::Input issuer_spki = issuer.spki_tlv;
623 if (!VerifySignedData(*signature_algorithm,
624 responder_cert.tbs_certificate_tlv,
625 responder_cert.signature_value, issuer_spki,
626 &signature_policy)) {
627 return false;
628 }
629
630 // The Authorized Responder must include the value id-kp-OCSPSigning as
631 // part of the extended key usage extension.
632 std::map<der::Input, ParsedExtension> extensions;
633 std::vector<der::Input> eku;
634 if (!ParseExtensions(responder.extensions_tlv, &extensions))
635 return false;
636 if (!ParseEKUExtension(extensions[ExtKeyUsageOid()].value, &eku))
637 return false;
638 if (std::find(eku.begin(), eku.end(), OCSPSigning()) == eku.end())
639 return false;
640
641 // TODO(svaldez): Add Revocation Checking of Authorized Responder.
642 break;
eroman 2016/05/31 19:12:46 Can you pull this out to a separate function inste
643 }
644 }
645 if (!found)
646 return false;
647 }
648 // Once a valid responder has been found, the signature of the OCSP
649 // response is verified against the public key of the responder.
650 return VerifySignedData(*(response.signature_algorithm), response.data,
651 response.signature, responder.spki_tlv,
652 &signature_policy);
653 }
654
532 } // namespace net 655 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698