| 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/base/cert_verify_proc_nss.h" | 5 #include "net/base/cert_verify_proc_nss.h" |
| 6 | 6 |
| 7 #include <string> |
| 8 #include <vector> |
| 9 |
| 7 #include <cert.h> | 10 #include <cert.h> |
| 8 #include <nss.h> | 11 #include <nss.h> |
| 9 #include <prerror.h> | 12 #include <prerror.h> |
| 10 #include <secerr.h> | 13 #include <secerr.h> |
| 11 #include <sechash.h> | 14 #include <sechash.h> |
| 12 #include <sslerr.h> | 15 #include <sslerr.h> |
| 13 | 16 |
| 14 #include "base/logging.h" | 17 #include "base/logging.h" |
| 15 #include "crypto/nss_util.h" | 18 #include "crypto/nss_util.h" |
| 16 #include "crypto/scoped_nss_types.h" | 19 #include "crypto/scoped_nss_types.h" |
| (...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 CERTPolicyInfo* policy_info = *policy_infos++; | 593 CERTPolicyInfo* policy_info = *policy_infos++; |
| 591 SECOidTag oid_tag = policy_info->oid; | 594 SECOidTag oid_tag = policy_info->oid; |
| 592 if (oid_tag == SEC_OID_UNKNOWN) | 595 if (oid_tag == SEC_OID_UNKNOWN) |
| 593 continue; | 596 continue; |
| 594 if (oid_tag == ev_policy_tag) | 597 if (oid_tag == ev_policy_tag) |
| 595 return true; | 598 return true; |
| 596 } | 599 } |
| 597 return false; | 600 return false; |
| 598 } | 601 } |
| 599 | 602 |
| 600 SHA1Fingerprint CertPublicKeyHash(CERTCertificate* cert) { | 603 HashValue CertPublicKeyHashSHA1(CERTCertificate* cert) { |
| 601 SHA1Fingerprint hash; | 604 HashValue hash; |
| 602 SECStatus rv = HASH_HashBuf(HASH_AlgSHA1, hash.data, | 605 hash.tag = HASH_VALUE_SHA1; |
| 606 SECStatus rv = HASH_HashBuf(HASH_AlgSHA1, hash.data(), |
| 607 cert->derPublicKey.data, cert->derPublicKey.len); |
| 608 DCHECK_EQ(rv, SECSuccess); |
| 609 return hash; |
| 610 } |
| 611 |
| 612 HashValue CertPublicKeyHashSHA256(CERTCertificate* cert) { |
| 613 HashValue hash; |
| 614 hash.tag = HASH_VALUE_SHA256; |
| 615 SECStatus rv = HASH_HashBuf(HASH_AlgSHA256, hash.data(), |
| 603 cert->derPublicKey.data, cert->derPublicKey.len); | 616 cert->derPublicKey.data, cert->derPublicKey.len); |
| 604 DCHECK_EQ(rv, SECSuccess); | 617 DCHECK_EQ(rv, SECSuccess); |
| 605 return hash; | 618 return hash; |
| 606 } | 619 } |
| 607 | 620 |
| 608 void AppendPublicKeyHashes(CERTCertList* cert_list, | 621 void AppendPublicKeyHashes(CERTCertList* cert_list, |
| 609 CERTCertificate* root_cert, | 622 CERTCertificate* root_cert, |
| 610 std::vector<SHA1Fingerprint>* hashes) { | 623 std::vector<HashValueVector>* hashes) { |
| 624 // TODO(palmer): Generalize this to handle any and all HashValueTags. |
| 611 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); | 625 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); |
| 612 !CERT_LIST_END(node, cert_list); | 626 !CERT_LIST_END(node, cert_list); |
| 613 node = CERT_LIST_NEXT(node)) { | 627 node = CERT_LIST_NEXT(node)) { |
| 614 hashes->push_back(CertPublicKeyHash(node->cert)); | 628 (*hashes)[HASH_VALUE_SHA1].push_back(CertPublicKeyHashSHA1(node->cert)); |
| 629 (*hashes)[HASH_VALUE_SHA256].push_back(CertPublicKeyHashSHA256(node->cert)); |
| 615 } | 630 } |
| 616 if (root_cert) | 631 if (root_cert) { |
| 617 hashes->push_back(CertPublicKeyHash(root_cert)); | 632 (*hashes)[HASH_VALUE_SHA1].push_back(CertPublicKeyHashSHA1(root_cert)); |
| 633 (*hashes)[HASH_VALUE_SHA256].push_back(CertPublicKeyHashSHA256(root_cert)); |
| 634 } |
| 618 } | 635 } |
| 619 | 636 |
| 620 // Studied Mozilla's code (esp. security/manager/ssl/src/nsIdentityChecking.cpp | 637 // Studied Mozilla's code (esp. security/manager/ssl/src/nsIdentityChecking.cpp |
| 621 // and nsNSSCertHelper.cpp) to learn how to verify EV certificate. | 638 // and nsNSSCertHelper.cpp) to learn how to verify EV certificate. |
| 622 // TODO(wtc): A possible optimization is that we get the trust anchor from | 639 // TODO(wtc): A possible optimization is that we get the trust anchor from |
| 623 // the first PKIXVerifyCert call. We look up the EV policy for the trust | 640 // the first PKIXVerifyCert call. We look up the EV policy for the trust |
| 624 // anchor. If the trust anchor has no EV policy, we know the cert isn't EV. | 641 // anchor. If the trust anchor has no EV policy, we know the cert isn't EV. |
| 625 // Otherwise, we pass just that EV policy (as opposed to all the EV policies) | 642 // Otherwise, we pass just that EV policy (as opposed to all the EV policies) |
| 626 // to the second PKIXVerifyCert call. | 643 // to the second PKIXVerifyCert call. |
| 627 bool VerifyEV(CERTCertificate* cert_handle, int flags, CRLSet* crl_set) { | 644 bool VerifyEV(CERTCertificate* cert_handle, int flags, CRLSet* crl_set) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 // the old path, might have been revoked. | 677 // the old path, might have been revoked. |
| 661 if (crl_set) { | 678 if (crl_set) { |
| 662 CRLSetResult crl_set_result = CheckRevocationWithCRLSet( | 679 CRLSetResult crl_set_result = CheckRevocationWithCRLSet( |
| 663 cvout[cvout_cert_list_index].value.pointer.chain, | 680 cvout[cvout_cert_list_index].value.pointer.chain, |
| 664 cvout[cvout_trust_anchor_index].value.pointer.cert, | 681 cvout[cvout_trust_anchor_index].value.pointer.cert, |
| 665 crl_set); | 682 crl_set); |
| 666 if (crl_set_result == kCRLSetRevoked) | 683 if (crl_set_result == kCRLSetRevoked) |
| 667 return false; | 684 return false; |
| 668 } | 685 } |
| 669 | 686 |
| 670 SHA1Fingerprint fingerprint = | 687 SHA1HashValue fingerprint = |
| 671 X509Certificate::CalculateFingerprint(root_ca); | 688 X509Certificate::CalculateFingerprint(root_ca); |
| 672 std::vector<SECOidTag> ev_policy_tags; | 689 std::vector<SECOidTag> ev_policy_tags; |
| 673 if (!metadata->GetPolicyOIDsForCA(fingerprint, &ev_policy_tags)) | 690 if (!metadata->GetPolicyOIDsForCA(fingerprint, &ev_policy_tags)) |
| 674 return false; | 691 return false; |
| 675 DCHECK(!ev_policy_tags.empty()); | 692 DCHECK(!ev_policy_tags.empty()); |
| 676 | 693 |
| 677 for (std::vector<SECOidTag>::const_iterator | 694 for (std::vector<SECOidTag>::const_iterator |
| 678 i = ev_policy_tags.begin(); i != ev_policy_tags.end(); ++i) { | 695 i = ev_policy_tags.begin(); i != ev_policy_tags.end(); ++i) { |
| 679 if (CheckCertPolicies(cert_handle, *i)) | 696 if (CheckCertPolicies(cert_handle, *i)) |
| 680 return true; | 697 return true; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 772 | 789 |
| 773 if ((flags & X509Certificate::VERIFY_EV_CERT) && | 790 if ((flags & X509Certificate::VERIFY_EV_CERT) && |
| 774 VerifyEV(cert_handle, flags, crl_set)) { | 791 VerifyEV(cert_handle, flags, crl_set)) { |
| 775 verify_result->cert_status |= CERT_STATUS_IS_EV; | 792 verify_result->cert_status |= CERT_STATUS_IS_EV; |
| 776 } | 793 } |
| 777 | 794 |
| 778 return OK; | 795 return OK; |
| 779 } | 796 } |
| 780 | 797 |
| 781 } // namespace net | 798 } // namespace net |
| OLD | NEW |