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/cert_verify_proc_nss.h" | 5 #include "net/cert/cert_verify_proc_nss.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include <cert.h> | 10 #include <cert.h> |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
108 case SEC_ERROR_UNKNOWN_ISSUER: | 108 case SEC_ERROR_UNKNOWN_ISSUER: |
109 case SEC_ERROR_UNTRUSTED_ISSUER: | 109 case SEC_ERROR_UNTRUSTED_ISSUER: |
110 case SEC_ERROR_CA_CERT_INVALID: | 110 case SEC_ERROR_CA_CERT_INVALID: |
111 return ERR_CERT_AUTHORITY_INVALID; | 111 return ERR_CERT_AUTHORITY_INVALID; |
112 // TODO(port): map ERR_CERT_NO_REVOCATION_MECHANISM. | 112 // TODO(port): map ERR_CERT_NO_REVOCATION_MECHANISM. |
113 case SEC_ERROR_OCSP_BAD_HTTP_RESPONSE: | 113 case SEC_ERROR_OCSP_BAD_HTTP_RESPONSE: |
114 case SEC_ERROR_OCSP_SERVER_ERROR: | 114 case SEC_ERROR_OCSP_SERVER_ERROR: |
115 return ERR_CERT_UNABLE_TO_CHECK_REVOCATION; | 115 return ERR_CERT_UNABLE_TO_CHECK_REVOCATION; |
116 case SEC_ERROR_REVOKED_CERTIFICATE: | 116 case SEC_ERROR_REVOKED_CERTIFICATE: |
117 case SEC_ERROR_UNTRUSTED_CERT: // Treat as revoked. | 117 case SEC_ERROR_UNTRUSTED_CERT: // Treat as revoked. |
118 case SEC_ERROR_APPLICATION_CALLBACK_ERROR: // Rejected by | |
119 // chain_verify_callback. | |
Ryan Sleevi
2014/01/25 01:50:17
wrong mapping
mattm
2014/01/28 04:36:44
Done.
| |
118 return ERR_CERT_REVOKED; | 120 return ERR_CERT_REVOKED; |
119 case SEC_ERROR_CERT_NOT_IN_NAME_SPACE: | 121 case SEC_ERROR_CERT_NOT_IN_NAME_SPACE: |
120 return ERR_CERT_NAME_CONSTRAINT_VIOLATION; | 122 return ERR_CERT_NAME_CONSTRAINT_VIOLATION; |
121 case SEC_ERROR_BAD_DER: | 123 case SEC_ERROR_BAD_DER: |
122 case SEC_ERROR_BAD_SIGNATURE: | 124 case SEC_ERROR_BAD_SIGNATURE: |
123 case SEC_ERROR_CERT_NOT_VALID: | 125 case SEC_ERROR_CERT_NOT_VALID: |
124 // TODO(port): add an ERR_CERT_WRONG_USAGE error code. | 126 // TODO(port): add an ERR_CERT_WRONG_USAGE error code. |
125 case SEC_ERROR_CERT_USAGES_INVALID: | 127 case SEC_ERROR_CERT_USAGES_INVALID: |
126 case SEC_ERROR_INADEQUATE_KEY_USAGE: // Key usage. | 128 case SEC_ERROR_INADEQUATE_KEY_USAGE: // Key usage. |
127 case SEC_ERROR_INADEQUATE_CERT_TYPE: // Extended key usage and whether | 129 case SEC_ERROR_INADEQUATE_CERT_TYPE: // Extended key usage and whether |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
342 // additional_trust_anchors is an optional list of certificates that can be | 344 // additional_trust_anchors is an optional list of certificates that can be |
343 // trusted as anchors when building a certificate chain. | 345 // trusted as anchors when building a certificate chain. |
344 // Caller must initialize cvout before calling this function. | 346 // Caller must initialize cvout before calling this function. |
345 SECStatus PKIXVerifyCert(CERTCertificate* cert_handle, | 347 SECStatus PKIXVerifyCert(CERTCertificate* cert_handle, |
346 bool check_revocation, | 348 bool check_revocation, |
347 bool hard_fail, | 349 bool hard_fail, |
348 bool cert_io_enabled, | 350 bool cert_io_enabled, |
349 const SECOidTag* policy_oids, | 351 const SECOidTag* policy_oids, |
350 int num_policy_oids, | 352 int num_policy_oids, |
351 CERTCertList* additional_trust_anchors, | 353 CERTCertList* additional_trust_anchors, |
354 CERTChainVerifyCallback* chain_verify_callback, | |
352 CERTValOutParam* cvout) { | 355 CERTValOutParam* cvout) { |
353 bool use_crl = check_revocation; | 356 bool use_crl = check_revocation; |
354 bool use_ocsp = check_revocation; | 357 bool use_ocsp = check_revocation; |
355 | 358 |
356 PRUint64 revocation_method_flags = | 359 PRUint64 revocation_method_flags = |
357 CERT_REV_M_DO_NOT_TEST_USING_THIS_METHOD | | 360 CERT_REV_M_DO_NOT_TEST_USING_THIS_METHOD | |
358 CERT_REV_M_ALLOW_NETWORK_FETCHING | | 361 CERT_REV_M_ALLOW_NETWORK_FETCHING | |
359 CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE | | 362 CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE | |
360 CERT_REV_M_IGNORE_MISSING_FRESH_INFO | | 363 CERT_REV_M_IGNORE_MISSING_FRESH_INFO | |
361 CERT_REV_M_STOP_TESTING_ON_FRESH_INFO; | 364 CERT_REV_M_STOP_TESTING_ON_FRESH_INFO; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
431 cvin.push_back(in_param); | 434 cvin.push_back(in_param); |
432 } | 435 } |
433 if (additional_trust_anchors) { | 436 if (additional_trust_anchors) { |
434 in_param.type = cert_pi_trustAnchors; | 437 in_param.type = cert_pi_trustAnchors; |
435 in_param.value.pointer.chain = additional_trust_anchors; | 438 in_param.value.pointer.chain = additional_trust_anchors; |
436 cvin.push_back(in_param); | 439 cvin.push_back(in_param); |
437 in_param.type = cert_pi_useOnlyTrustAnchors; | 440 in_param.type = cert_pi_useOnlyTrustAnchors; |
438 in_param.value.scalar.b = PR_FALSE; | 441 in_param.value.scalar.b = PR_FALSE; |
439 cvin.push_back(in_param); | 442 cvin.push_back(in_param); |
440 } | 443 } |
444 if (chain_verify_callback) { | |
445 in_param.type = cert_pi_chainVerifyCallback; | |
446 in_param.value.pointer.chainVerifyCallback = chain_verify_callback; | |
447 cvin.push_back(in_param); | |
448 } | |
441 in_param.type = cert_pi_end; | 449 in_param.type = cert_pi_end; |
442 cvin.push_back(in_param); | 450 cvin.push_back(in_param); |
443 | 451 |
444 SECStatus rv = CERT_PKIXVerifyCert(cert_handle, certificateUsageSSLServer, | 452 SECStatus rv = CERT_PKIXVerifyCert(cert_handle, certificateUsageSSLServer, |
445 &cvin[0], cvout, NULL); | 453 &cvin[0], cvout, NULL); |
446 if (rv != SECSuccess) { | 454 if (rv != SECSuccess) { |
447 rv = RetryPKIXVerifyCertWithWorkarounds(cert_handle, num_policy_oids, | 455 rv = RetryPKIXVerifyCertWithWorkarounds(cert_handle, num_policy_oids, |
448 cert_io_enabled, &cvin, cvout); | 456 cert_io_enabled, &cvin, cvout); |
449 } | 457 } |
450 return rv; | 458 return rv; |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
651 // the first PKIXVerifyCert call. We look up the EV policy for the trust | 659 // the first PKIXVerifyCert call. We look up the EV policy for the trust |
652 // anchor. If the trust anchor has no EV policy, we know the cert isn't EV. | 660 // anchor. If the trust anchor has no EV policy, we know the cert isn't EV. |
653 // Otherwise, we pass just that EV policy (as opposed to all the EV policies) | 661 // Otherwise, we pass just that EV policy (as opposed to all the EV policies) |
654 // to the second PKIXVerifyCert call. | 662 // to the second PKIXVerifyCert call. |
655 bool VerifyEV(CERTCertificate* cert_handle, | 663 bool VerifyEV(CERTCertificate* cert_handle, |
656 int flags, | 664 int flags, |
657 CRLSet* crl_set, | 665 CRLSet* crl_set, |
658 bool rev_checking_enabled, | 666 bool rev_checking_enabled, |
659 EVRootCAMetadata* metadata, | 667 EVRootCAMetadata* metadata, |
660 SECOidTag ev_policy_oid, | 668 SECOidTag ev_policy_oid, |
661 CERTCertList* additional_trust_anchors) { | 669 CERTCertList* additional_trust_anchors, |
670 CERTChainVerifyCallback* chain_verify_callback) { | |
662 CERTValOutParam cvout[3]; | 671 CERTValOutParam cvout[3]; |
663 int cvout_index = 0; | 672 int cvout_index = 0; |
664 cvout[cvout_index].type = cert_po_certList; | 673 cvout[cvout_index].type = cert_po_certList; |
665 cvout[cvout_index].value.pointer.chain = NULL; | 674 cvout[cvout_index].value.pointer.chain = NULL; |
666 int cvout_cert_list_index = cvout_index; | 675 int cvout_cert_list_index = cvout_index; |
667 cvout_index++; | 676 cvout_index++; |
668 cvout[cvout_index].type = cert_po_trustAnchor; | 677 cvout[cvout_index].type = cert_po_trustAnchor; |
669 cvout[cvout_index].value.pointer.cert = NULL; | 678 cvout[cvout_index].value.pointer.cert = NULL; |
670 int cvout_trust_anchor_index = cvout_index; | 679 int cvout_trust_anchor_index = cvout_index; |
671 cvout_index++; | 680 cvout_index++; |
672 cvout[cvout_index].type = cert_po_end; | 681 cvout[cvout_index].type = cert_po_end; |
673 ScopedCERTValOutParam scoped_cvout(cvout); | 682 ScopedCERTValOutParam scoped_cvout(cvout); |
674 | 683 |
675 SECStatus status = PKIXVerifyCert( | 684 SECStatus status = PKIXVerifyCert( |
676 cert_handle, | 685 cert_handle, |
677 rev_checking_enabled, | 686 rev_checking_enabled, |
678 true, /* hard fail is implied in EV. */ | 687 true, /* hard fail is implied in EV. */ |
679 flags & CertVerifier::VERIFY_CERT_IO_ENABLED, | 688 flags & CertVerifier::VERIFY_CERT_IO_ENABLED, |
680 &ev_policy_oid, | 689 &ev_policy_oid, |
681 1, | 690 1, |
682 additional_trust_anchors, | 691 additional_trust_anchors, |
692 chain_verify_callback, | |
683 cvout); | 693 cvout); |
684 if (status != SECSuccess) | 694 if (status != SECSuccess) |
685 return false; | 695 return false; |
686 | 696 |
687 CERTCertificate* root_ca = | 697 CERTCertificate* root_ca = |
688 cvout[cvout_trust_anchor_index].value.pointer.cert; | 698 cvout[cvout_trust_anchor_index].value.pointer.cert; |
689 if (root_ca == NULL) | 699 if (root_ca == NULL) |
690 return false; | 700 return false; |
691 | 701 |
692 // This second PKIXVerifyCert call could have found a different certification | 702 // This second PKIXVerifyCert call could have found a different certification |
(...skipping 28 matching lines...) Expand all Loading... | |
721 #else | 731 #else |
722 CERTCertificate* cert = list[i]->os_cert_handle(); | 732 CERTCertificate* cert = list[i]->os_cert_handle(); |
723 #endif | 733 #endif |
724 CERT_AddCertToListTail(result, CERT_DupCertificate(cert)); | 734 CERT_AddCertToListTail(result, CERT_DupCertificate(cert)); |
725 } | 735 } |
726 return result; | 736 return result; |
727 } | 737 } |
728 | 738 |
729 } // namespace | 739 } // namespace |
730 | 740 |
731 CertVerifyProcNSS::CertVerifyProcNSS() {} | 741 CertVerifyProcNSS::CertVerifyProcNSS() : chain_verify_callback_(NULL) {} |
742 | |
743 CertVerifyProcNSS::CertVerifyProcNSS( | |
744 CERTChainVerifyCallback* chain_verify_callback) | |
745 : chain_verify_callback_(chain_verify_callback) {} | |
732 | 746 |
733 CertVerifyProcNSS::~CertVerifyProcNSS() {} | 747 CertVerifyProcNSS::~CertVerifyProcNSS() {} |
734 | 748 |
735 bool CertVerifyProcNSS::SupportsAdditionalTrustAnchors() const { | 749 bool CertVerifyProcNSS::SupportsAdditionalTrustAnchors() const { |
736 return true; | 750 return true; |
737 } | 751 } |
738 | 752 |
739 int CertVerifyProcNSS::VerifyInternal( | 753 int CertVerifyProcNSS::VerifyInternal( |
740 X509Certificate* cert, | 754 X509Certificate* cert, |
741 const std::string& hostname, | 755 const std::string& hostname, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
787 (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED); | 801 (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED); |
788 if (check_revocation) | 802 if (check_revocation) |
789 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; | 803 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; |
790 | 804 |
791 ScopedCERTCertList trust_anchors; | 805 ScopedCERTCertList trust_anchors; |
792 if (!additional_trust_anchors.empty()) { | 806 if (!additional_trust_anchors.empty()) { |
793 trust_anchors.reset( | 807 trust_anchors.reset( |
794 CertificateListToCERTCertList(additional_trust_anchors)); | 808 CertificateListToCERTCertList(additional_trust_anchors)); |
795 } | 809 } |
796 | 810 |
797 SECStatus status = PKIXVerifyCert(cert_handle, check_revocation, false, | 811 SECStatus status = PKIXVerifyCert(cert_handle, |
798 cert_io_enabled, NULL, 0, | 812 check_revocation, |
799 trust_anchors.get(), cvout); | 813 false, |
814 cert_io_enabled, | |
815 NULL, | |
816 0, | |
817 trust_anchors.get(), | |
818 chain_verify_callback_, | |
819 cvout); | |
800 | 820 |
801 if (status == SECSuccess && | 821 if (status == SECSuccess && |
802 (flags & CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS) && | 822 (flags & CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS) && |
803 !IsKnownRoot(cvout[cvout_trust_anchor_index].value.pointer.cert)) { | 823 !IsKnownRoot(cvout[cvout_trust_anchor_index].value.pointer.cert)) { |
804 // TODO(rsleevi): Optimize this by supplying the constructed chain to | 824 // TODO(rsleevi): Optimize this by supplying the constructed chain to |
805 // libpkix via cvin. Omitting for now, due to lack of coverage in upstream | 825 // libpkix via cvin. Omitting for now, due to lack of coverage in upstream |
806 // NSS tests for that feature. | 826 // NSS tests for that feature. |
807 scoped_cvout.Clear(); | 827 scoped_cvout.Clear(); |
808 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; | 828 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; |
809 status = PKIXVerifyCert(cert_handle, true, true, | 829 status = PKIXVerifyCert(cert_handle, |
810 cert_io_enabled, NULL, 0, trust_anchors.get(), | 830 true, |
831 true, | |
832 cert_io_enabled, | |
833 NULL, | |
834 0, | |
835 trust_anchors.get(), | |
836 chain_verify_callback_, | |
811 cvout); | 837 cvout); |
812 } | 838 } |
813 | 839 |
814 if (status == SECSuccess) { | 840 if (status == SECSuccess) { |
815 AppendPublicKeyHashes(cvout[cvout_cert_list_index].value.pointer.chain, | 841 AppendPublicKeyHashes(cvout[cvout_cert_list_index].value.pointer.chain, |
816 cvout[cvout_trust_anchor_index].value.pointer.cert, | 842 cvout[cvout_trust_anchor_index].value.pointer.cert, |
817 &verify_result->public_key_hashes); | 843 &verify_result->public_key_hashes); |
818 | 844 |
819 verify_result->is_issued_by_known_root = | 845 verify_result->is_issued_by_known_root = |
820 IsKnownRoot(cvout[cvout_trust_anchor_index].value.pointer.cert); | 846 IsKnownRoot(cvout[cvout_trust_anchor_index].value.pointer.cert); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
863 | 889 |
864 if ((flags & CertVerifier::VERIFY_EV_CERT) && is_ev_candidate) { | 890 if ((flags & CertVerifier::VERIFY_EV_CERT) && is_ev_candidate) { |
865 check_revocation |= | 891 check_revocation |= |
866 crl_set_result != kCRLSetOk && | 892 crl_set_result != kCRLSetOk && |
867 cert_io_enabled && | 893 cert_io_enabled && |
868 (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY); | 894 (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY); |
869 if (check_revocation) | 895 if (check_revocation) |
870 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; | 896 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; |
871 | 897 |
872 if (VerifyEV(cert_handle, flags, crl_set, check_revocation, metadata, | 898 if (VerifyEV(cert_handle, flags, crl_set, check_revocation, metadata, |
873 ev_policy_oid, trust_anchors.get())) { | 899 ev_policy_oid, trust_anchors.get(), chain_verify_callback_)) { |
874 verify_result->cert_status |= CERT_STATUS_IS_EV; | 900 verify_result->cert_status |= CERT_STATUS_IS_EV; |
875 } | 901 } |
876 } | 902 } |
877 | 903 |
878 return OK; | 904 return OK; |
879 } | 905 } |
880 | 906 |
881 } // namespace net | 907 } // namespace net |
OLD | NEW |