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