diff options
Diffstat (limited to 'chromium/net/cert')
196 files changed, 2632 insertions, 2279 deletions
diff --git a/chromium/net/cert/asn1_util.cc b/chromium/net/cert/asn1_util.cc index ffafe1ce416..15393d933f4 100644 --- a/chromium/net/cert/asn1_util.cc +++ b/chromium/net/cert/asn1_util.cc @@ -4,14 +4,12 @@ #include "net/cert/asn1_util.h" -#include "net/cert/internal/parse_certificate.h" +#include "net/cert/pki/parse_certificate.h" #include "net/der/input.h" #include "net/der/parser.h" #include "third_party/abseil-cpp/absl/types/optional.h" -namespace net { - -namespace asn1 { +namespace net::asn1 { namespace { @@ -330,6 +328,4 @@ bool ExtractExtensionFromDERCert(base::StringPiece cert, return true; } -} // namespace asn1 - -} // namespace net +} // namespace net::asn1 diff --git a/chromium/net/cert/asn1_util.h b/chromium/net/cert/asn1_util.h index ec59393e70c..349b554b39a 100644 --- a/chromium/net/cert/asn1_util.h +++ b/chromium/net/cert/asn1_util.h @@ -8,9 +8,7 @@ #include "base/strings/string_piece.h" #include "net/base/net_export.h" -namespace net { - -namespace asn1 { +namespace net::asn1 { // ExtractSubjectFromDERCert parses the DER encoded certificate in |cert| and // extracts the bytes of the X.501 Subject. On successful return, |subject_out| @@ -70,8 +68,6 @@ NET_EXPORT bool ExtractExtensionFromDERCert(base::StringPiece cert, bool* out_extension_critical, base::StringPiece* out_contents); -} // namespace asn1 - -} // namespace net +} // namespace net::asn1 #endif // NET_CERT_ASN1_UTIL_H_ diff --git a/chromium/net/cert/cert_and_ct_verifier_unittest.cc b/chromium/net/cert/cert_and_ct_verifier_unittest.cc index 7771312b9e0..858a95250cd 100644 --- a/chromium/net/cert/cert_and_ct_verifier_unittest.cc +++ b/chromium/net/cert/cert_and_ct_verifier_unittest.cc @@ -70,7 +70,7 @@ class FakeCTVerifier : public CTVerifier { class CertAndCTVerifierTest : public TestWithTaskEnvironment { public: - CertAndCTVerifierTest() {} + CertAndCTVerifierTest() = default; ~CertAndCTVerifierTest() override = default; }; diff --git a/chromium/net/cert/cert_database.cc b/chromium/net/cert/cert_database.cc index 99f5dea5695..7e8220b4c14 100644 --- a/chromium/net/cert/cert_database.cc +++ b/chromium/net/cert/cert_database.cc @@ -39,7 +39,8 @@ void CertDatabase::NotifyObserversCertDBChanged() { } CertDatabase::CertDatabase() - : observer_list_(new base::ObserverListThreadSafe<Observer>) {} + : observer_list_( + base::MakeRefCounted<base::ObserverListThreadSafe<Observer>>()) {} CertDatabase::~CertDatabase() { #if BUILDFLAG(IS_MAC) diff --git a/chromium/net/cert/cert_database.h b/chromium/net/cert/cert_database.h index a56d1880d18..0ffb928c9da 100644 --- a/chromium/net/cert/cert_database.h +++ b/chromium/net/cert/cert_database.h @@ -5,6 +5,7 @@ #ifndef NET_CERT_CERT_DATABASE_H_ #define NET_CERT_CERT_DATABASE_H_ +#include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" #include "build/build_config.h" #include "net/base/net_export.h" @@ -39,7 +40,7 @@ class NET_EXPORT CertDatabase { Observer(const Observer&) = delete; Observer& operator=(const Observer&) = delete; - virtual ~Observer() {} + virtual ~Observer() = default; // Called whenever the Cert Database is known to have changed. // Typically, this will be in response to a CA certificate being added, @@ -48,7 +49,7 @@ class NET_EXPORT CertDatabase { virtual void OnCertDBChanged() {} protected: - Observer() {} + Observer() = default; }; // Returns the CertDatabase singleton. @@ -91,7 +92,7 @@ class NET_EXPORT CertDatabase { class Notifier; friend class Notifier; - Notifier* notifier_ = nullptr; + raw_ptr<Notifier> notifier_ = nullptr; #endif }; diff --git a/chromium/net/cert/cert_database_mac.cc b/chromium/net/cert/cert_database_mac.cc index 1cd7809ccc4..f561550305f 100644 --- a/chromium/net/cert/cert_database_mac.cc +++ b/chromium/net/cert/cert_database_mac.cc @@ -10,6 +10,7 @@ #include "base/check.h" #include "base/location.h" #include "base/mac/mac_logging.h" +#include "base/memory/raw_ptr.h" #include "base/notreached.h" #include "base/process/process_handle.h" #include "base/synchronization/lock.h" @@ -39,6 +40,12 @@ class CertDatabase::Notifier { FROM_HERE, base::BindOnce(&Notifier::Init, base::Unretained(this))); } +// Much of the Keychain API was marked deprecated as of the macOS 13 SDK. +// Removal of its use is tracked in https://crbug.com/1348251 but deprecation +// warnings are disabled in the meanwhile. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + // Should be called from the |task_runner_|'s sequence. Use Shutdown() // to shutdown on arbitrary sequence. ~Notifier() { @@ -48,6 +55,8 @@ class CertDatabase::Notifier { SecKeychainRemoveCallback(&Notifier::KeychainCallback); } +#pragma clang diagnostic pop + void Shutdown() { called_shutdown_ = true; if (!task_runner_->DeleteSoon(FROM_HERE, this)) { @@ -58,6 +67,12 @@ class CertDatabase::Notifier { } } +// Much of the Keychain API was marked deprecated as of the macOS 13 SDK. +// Removal of its use is tracked in https://crbug.com/1348251 but deprecation +// warnings are disabled in the meanwhile. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + private: void Init() { SecKeychainEventMask event_mask = @@ -68,13 +83,15 @@ class CertDatabase::Notifier { registered_ = true; } +#pragma clang diagnostic pop + // SecKeychainCallback function that receives notifications from securityd // and forwards them to the |cert_db_|. static OSStatus KeychainCallback(SecKeychainEvent keychain_event, SecKeychainCallbackInfo* info, void* context); - CertDatabase* const cert_db_; + const raw_ptr<CertDatabase> cert_db_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; bool registered_ = false; bool called_shutdown_ = false; diff --git a/chromium/net/cert/cert_net_fetcher.h b/chromium/net/cert/cert_net_fetcher.h index e29167fee99..3ac71321b22 100644 --- a/chromium/net/cert/cert_net_fetcher.h +++ b/chromium/net/cert/cert_net_fetcher.h @@ -31,7 +31,7 @@ class NET_EXPORT CertNetFetcher public: class Request { public: - virtual ~Request() {} + virtual ~Request() = default; // WaitForResult() can be called at most once. // @@ -43,7 +43,7 @@ class NET_EXPORT CertNetFetcher // This value can be used in place of timeout or max size limits. enum { DEFAULT = -1 }; - CertNetFetcher() {} + CertNetFetcher() = default; CertNetFetcher(const CertNetFetcher&) = delete; CertNetFetcher& operator=(const CertNetFetcher&) = delete; @@ -83,7 +83,7 @@ class NET_EXPORT CertNetFetcher int max_response_bytes) = 0; protected: - virtual ~CertNetFetcher() {} + virtual ~CertNetFetcher() = default; private: friend class base::RefCountedThreadSafe<CertNetFetcher>; diff --git a/chromium/net/cert/cert_verifier.h b/chromium/net/cert/cert_verifier.h index 589b03554e2..cc03c8dc133 100644 --- a/chromium/net/cert/cert_verifier.h +++ b/chromium/net/cert/cert_verifier.h @@ -76,13 +76,13 @@ class NET_EXPORT CertVerifier { class Request { public: - Request() {} + Request() = default; Request(const Request&) = delete; Request& operator=(const Request&) = delete; // Destruction of the Request cancels it. - virtual ~Request() {} + virtual ~Request() = default; }; enum VerifyFlags { @@ -155,7 +155,7 @@ class NET_EXPORT CertVerifier { // When the verifier is destroyed, all certificate verification requests are // canceled, and their completion callbacks will not be called. - virtual ~CertVerifier() {} + virtual ~CertVerifier() = default; // Verifies the given certificate against the given hostname as an SSL server. // Returns OK if successful or an error code upon failure. diff --git a/chromium/net/cert/cert_verify_proc.cc b/chromium/net/cert/cert_verify_proc.cc index cb40c44e7fc..eaeb8416f8b 100644 --- a/chromium/net/cert/cert_verify_proc.cc +++ b/chromium/net/cert/cert_verify_proc.cc @@ -31,15 +31,15 @@ #include "net/cert/cert_verifier.h" #include "net/cert/cert_verify_result.h" #include "net/cert/crl_set.h" -#include "net/cert/internal/extended_key_usage.h" -#include "net/cert/internal/ocsp.h" -#include "net/cert/internal/parse_certificate.h" #include "net/cert/internal/revocation_checker.h" -#include "net/cert/internal/signature_algorithm.h" #include "net/cert/internal/system_trust_store.h" #include "net/cert/known_roots.h" #include "net/cert/ocsp_revocation_status.h" #include "net/cert/pem.h" +#include "net/cert/pki/extended_key_usage.h" +#include "net/cert/pki/ocsp.h" +#include "net/cert/pki/parse_certificate.h" +#include "net/cert/pki/signature_algorithm.h" #include "net/cert/symantec_certs.h" #include "net/cert/x509_certificate.h" #include "net/cert/x509_certificate_net_log_param.h" @@ -358,29 +358,6 @@ bool AreSHA1IntermediatesAllowed() { #endif } -// Validate if a digest hash algorithm is acceptable in a certificate. -// -// Sets as a side effect the "has_*" boolean members in -// |verify_result| that correspond with the the presence of |hash| -// somewhere in the certificate chain (excluding the trust anchor). -bool ValidateHashAlgorithm(DigestAlgorithm hash, - CertVerifyResult* verify_result) { - switch (hash) { - case DigestAlgorithm::Sha1: - verify_result->has_sha1 = true; - return true; // For now. - case DigestAlgorithm::Sha256: - case DigestAlgorithm::Sha384: - case DigestAlgorithm::Sha512: - return true; - case DigestAlgorithm::Md2: - case DigestAlgorithm::Md4: - case DigestAlgorithm::Md5: - return false; - } - NOTREACHED(); -} - // Inspects the signature algorithms in a single certificate |cert|. // // * Sets |verify_result->has_sha1| to true if the certificate uses SHA1. @@ -399,37 +376,43 @@ bool ValidateHashAlgorithm(DigestAlgorithm hash, return false; } - if (!SignatureAlgorithm::IsEquivalent(der::Input(cert_algorithm_sequence), - der::Input(tbs_algorithm_sequence))) { + absl::optional<SignatureAlgorithm> cert_algorithm = + ParseSignatureAlgorithm(der::Input(cert_algorithm_sequence), nullptr); + absl::optional<SignatureAlgorithm> tbs_algorithm = + ParseSignatureAlgorithm(der::Input(tbs_algorithm_sequence), nullptr); + if (!cert_algorithm || !tbs_algorithm || *cert_algorithm != *tbs_algorithm) { return false; } - std::unique_ptr<SignatureAlgorithm> algorithm = - SignatureAlgorithm::Create(der::Input(cert_algorithm_sequence), nullptr); - if (!algorithm) { - return false; - } + switch (*cert_algorithm) { + case SignatureAlgorithm::kRsaPkcs1Sha1: + case SignatureAlgorithm::kEcdsaSha1: + case SignatureAlgorithm::kDsaSha1: + verify_result->has_sha1 = true; + return true; // For now. - if (!ValidateHashAlgorithm(algorithm->digest(), verify_result)) { - return false; - } + case SignatureAlgorithm::kRsaPkcs1Md2: + case SignatureAlgorithm::kRsaPkcs1Md4: + case SignatureAlgorithm::kRsaPkcs1Md5: + // TODO(https://crbug.com/1321688): Remove these from the parser + // altogether. + return false; - // Check algorithm-specific parameters. - switch (algorithm->algorithm()) { - case SignatureAlgorithmId::Dsa: - case SignatureAlgorithmId::RsaPkcs1: - case SignatureAlgorithmId::Ecdsa: - DCHECK(!algorithm->has_params()); - break; - case SignatureAlgorithmId::RsaPss: - if (!ValidateHashAlgorithm(algorithm->ParamsForRsaPss()->mgf1_hash(), - verify_result)) { - return false; - } - break; + case SignatureAlgorithm::kRsaPkcs1Sha256: + case SignatureAlgorithm::kRsaPkcs1Sha384: + case SignatureAlgorithm::kRsaPkcs1Sha512: + case SignatureAlgorithm::kEcdsaSha256: + case SignatureAlgorithm::kEcdsaSha384: + case SignatureAlgorithm::kEcdsaSha512: + case SignatureAlgorithm::kRsaPssSha256: + case SignatureAlgorithm::kRsaPssSha384: + case SignatureAlgorithm::kRsaPssSha512: + case SignatureAlgorithm::kDsaSha256: + return true; } - return true; + NOTREACHED(); + return false; } // InspectSignatureAlgorithmsInChain() sets |verify_result->has_*| based on @@ -532,13 +515,14 @@ base::Value CertVerifyParams(X509Certificate* cert, scoped_refptr<CertVerifyProc> CertVerifyProc::CreateSystemVerifyProc( scoped_refptr<CertNetFetcher> cert_net_fetcher) { #if BUILDFLAG(IS_ANDROID) - return new CertVerifyProcAndroid(std::move(cert_net_fetcher)); + return base::MakeRefCounted<CertVerifyProcAndroid>( + std::move(cert_net_fetcher)); #elif BUILDFLAG(IS_IOS) - return new CertVerifyProcIOS(); + return base::MakeRefCounted<CertVerifyProcIOS>(); #elif BUILDFLAG(IS_MAC) - return new CertVerifyProcMac(); + return base::MakeRefCounted<CertVerifyProcMac>(); #elif BUILDFLAG(IS_WIN) - return new CertVerifyProcWin(); + return base::MakeRefCounted<CertVerifyProcWin>(); #else #error Unsupported platform #endif @@ -554,7 +538,7 @@ scoped_refptr<CertVerifyProc> CertVerifyProc::CreateBuiltinVerifyProc( } #endif -CertVerifyProc::CertVerifyProc() {} +CertVerifyProc::CertVerifyProc() = default; CertVerifyProc::~CertVerifyProc() = default; diff --git a/chromium/net/cert/cert_verify_proc_android.cc b/chromium/net/cert/cert_verify_proc_android.cc index 550661305d6..95ec17f5ff2 100644 --- a/chromium/net/cert/cert_verify_proc_android.cc +++ b/chromium/net/cert/cert_verify_proc_android.cc @@ -22,9 +22,9 @@ #include "net/cert/cert_net_fetcher.h" #include "net/cert/cert_status_flags.h" #include "net/cert/cert_verify_result.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parsed_certificate.h" #include "net/cert/known_roots.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/parsed_certificate.h" #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" #include "url/gurl.h" @@ -341,7 +341,7 @@ CertVerifyProcAndroid::CertVerifyProcAndroid( scoped_refptr<CertNetFetcher> cert_net_fetcher) : cert_net_fetcher_(std::move(cert_net_fetcher)) {} -CertVerifyProcAndroid::~CertVerifyProcAndroid() {} +CertVerifyProcAndroid::~CertVerifyProcAndroid() = default; bool CertVerifyProcAndroid::SupportsAdditionalTrustAnchors() const { return false; diff --git a/chromium/net/cert/cert_verify_proc_android_unittest.cc b/chromium/net/cert/cert_verify_proc_android_unittest.cc index 84dd80e68b4..2b3e37f544b 100644 --- a/chromium/net/cert/cert_verify_proc_android_unittest.cc +++ b/chromium/net/cert/cert_verify_proc_android_unittest.cc @@ -11,8 +11,8 @@ #include "net/cert/cert_verify_proc_android.h" #include "net/cert/cert_verify_result.h" #include "net/cert/crl_set.h" -#include "net/cert/internal/test_helpers.h" #include "net/cert/mock_cert_net_fetcher.h" +#include "net/cert/pki/test_helpers.h" #include "net/cert/test_root_certs.h" #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" diff --git a/chromium/net/cert/cert_verify_proc_builtin.cc b/chromium/net/cert/cert_verify_proc_builtin.cc index e63df98b015..afe1bc86066 100644 --- a/chromium/net/cert/cert_verify_proc_builtin.cc +++ b/chromium/net/cert/cert_verify_proc_builtin.cc @@ -20,18 +20,18 @@ #include "net/cert/cert_verify_proc.h" #include "net/cert/cert_verify_result.h" #include "net/cert/ev_root_ca_metadata.h" -#include "net/cert/internal/cert_errors.h" #include "net/cert/internal/cert_issuer_source_aia.h" -#include "net/cert/internal/cert_issuer_source_static.h" -#include "net/cert/internal/common_cert_errors.h" -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/path_builder.h" #include "net/cert/internal/revocation_checker.h" -#include "net/cert/internal/simple_path_builder_delegate.h" #include "net/cert/internal/system_trust_store.h" -#include "net/cert/internal/trust_store_collection.h" -#include "net/cert/internal/trust_store_in_memory.h" #include "net/cert/known_roots.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/cert_issuer_source_static.h" +#include "net/cert/pki/common_cert_errors.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/path_builder.h" +#include "net/cert/pki/simple_path_builder_delegate.h" +#include "net/cert/pki/trust_store_collection.h" +#include "net/cert/pki/trust_store_in_memory.h" #include "net/cert/test_root_certs.h" #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" @@ -58,19 +58,19 @@ const void* kResultDebugDataKey = &kResultDebugDataKey; base::Value NetLogCertParams(const CRYPTO_BUFFER* cert_handle, const CertErrors& errors) { - base::Value results(base::Value::Type::DICTIONARY); + base::Value::Dict results; std::string pem_encoded; if (X509Certificate::GetPEMEncodedFromDER( x509_util::CryptoBufferAsStringPiece(cert_handle), &pem_encoded)) { - results.GetDict().Set("certificate", pem_encoded); + results.Set("certificate", pem_encoded); } std::string errors_string = errors.ToDebugString(); if (!errors_string.empty()) - results.GetDict().Set("errors", errors_string); + results.Set("errors", errors_string); - return results; + return base::Value(std::move(results)); } #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) @@ -124,6 +124,7 @@ RevocationPolicy NoRevocationChecking() { RevocationPolicy policy; policy.check_revocation = false; policy.networking_allowed = false; + policy.crl_allowed = false; policy.allow_missing_info = true; policy.allow_unable_to_check = true; return policy; @@ -275,11 +276,8 @@ class PathBuilderDelegateImpl : public SimplePathBuilderDelegate { } // Select an appropriate revocation policy for this chain based on the - // verifier flags and root, and whether this is an EV or DV path building - // attempt. - bool crlset_leaf_coverage_sufficient; - RevocationPolicy policy = - ChooseRevocationPolicy(path->certs, &crlset_leaf_coverage_sufficient); + // verifier flags and root. + RevocationPolicy policy = ChooseRevocationPolicy(path->certs); // Check for revocations using the CRLSet. switch ( @@ -287,12 +285,6 @@ class PathBuilderDelegateImpl : public SimplePathBuilderDelegate { case CRLSet::Result::REVOKED: return; case CRLSet::Result::GOOD: - if (crlset_leaf_coverage_sufficient) { - // Weaken the revocation checking requirement as it has been - // satisfied. (Don't early-return, since still want to consult - // cached OCSP/CRL if available). - policy = NoRevocationChecking(); - } break; case CRLSet::Result::UNKNOWN: // CRLSet was inconclusive. @@ -316,12 +308,7 @@ class PathBuilderDelegateImpl : public SimplePathBuilderDelegate { private: // Selects a revocation policy based on the CertVerifier flags and the given // certificate chain. - RevocationPolicy ChooseRevocationPolicy( - const ParsedCertificateList& certs, - bool* crlset_leaf_coverage_sufficient) { - // The only case this is set to true is for EV. - *crlset_leaf_coverage_sufficient = false; - + RevocationPolicy ChooseRevocationPolicy(const ParsedCertificateList& certs) { // Use hard-fail revocation checking for local trust anchors, if requested // by the load flag and the chain uses a non-public root. if ((flags_ & CertVerifyProc::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS) && @@ -329,19 +316,7 @@ class PathBuilderDelegateImpl : public SimplePathBuilderDelegate { RevocationPolicy policy; policy.check_revocation = true; policy.networking_allowed = true; - policy.allow_missing_info = false; - policy.allow_unable_to_check = false; - return policy; - } - - // Use hard-fail revocation checking for EV certificates. - if (verification_type_ == VerificationType::kEV) { - // For EV verification leaf coverage is considered sufficient. - *crlset_leaf_coverage_sufficient = true; - - RevocationPolicy policy; - policy.check_revocation = true; - policy.networking_allowed = true; + policy.crl_allowed = true; policy.allow_missing_info = false; policy.allow_unable_to_check = false; return policy; @@ -352,6 +327,11 @@ class PathBuilderDelegateImpl : public SimplePathBuilderDelegate { RevocationPolicy policy; policy.check_revocation = true; policy.networking_allowed = true; + // Publicly trusted certs are required to have OCSP by the Baseline + // Requirements and CRLs can be quite large, so disable the fallback to + // CRLs for chains to known roots. + policy.crl_allowed = + !certs.empty() && !trust_store_->IsKnownRoot(certs.back().get()); policy.allow_missing_info = true; policy.allow_unable_to_check = true; return policy; @@ -734,6 +714,7 @@ int CertVerifyProcBuiltin::VerifyInternal( verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID; return ERR_CERT_AUTHORITY_INVALID; } + absl::optional<int64_t> chrome_root_store_version_opt = absl::nullopt; #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) int64_t chrome_root_store_version = system_trust_store_->chrome_root_store_version(); @@ -742,11 +723,13 @@ int CertVerifyProcBuiltin::VerifyInternal( NetLogEventType::CERT_VERIFY_PROC_CHROME_ROOT_STORE_VERSION, [&] { return NetLogChromeRootStoreVersion(chrome_root_store_version); }); + chrome_root_store_version_opt = chrome_root_store_version; } #endif CertVerifyProcBuiltinResultDebugData::Create(verify_result, verification_time, - der_verification_time); + der_verification_time, + chrome_root_store_version_opt); // Parse the target certificate. scoped_refptr<ParsedCertificate> target; @@ -820,12 +803,12 @@ int CertVerifyProcBuiltin::VerifyInternal( verification_type = cur_attempt.verification_type; net_log.BeginEvent( NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT, [&] { - base::Value results(base::Value::Type::DICTIONARY); + base::Value::Dict results; if (verification_type == VerificationType::kEV) - results.GetDict().Set("is_ev_attempt", true); - results.GetDict().Set("digest_policy", - static_cast<int>(cur_attempt.digest_policy)); - return results; + results.Set("is_ev_attempt", true); + results.Set("digest_policy", + static_cast<int>(cur_attempt.digest_policy)); + return base::Value(std::move(results)); }); // If a previous attempt used up most/all of the deadline, extend the @@ -855,16 +838,7 @@ int CertVerifyProcBuiltin::VerifyInternal( break; if (result.exceeded_deadline) { - if (verification_type == VerificationType::kEV && - result.AnyPathContainsError(cert_errors::kUnableToCheckRevocation)) { - // EV verification failed due to deadline exceeded and unable to check - // revocation. Try the non-EV attempt even though the deadline has been - // reached, since a revocation checking failure on EV should be a - // soft-fail. (Since the non-EV attempt generally will not be using - // revocation checking it hopefully won't hit the deadline too.) - continue; - } - // Otherwise, stop immediately if an attempt exceeds the deadline. + // Stop immediately if an attempt exceeds the deadline. break; } @@ -903,9 +877,11 @@ int CertVerifyProcBuiltin::VerifyInternal( CertVerifyProcBuiltinResultDebugData::CertVerifyProcBuiltinResultDebugData( base::Time verification_time, - const der::GeneralizedTime& der_verification_time) + const der::GeneralizedTime& der_verification_time, + absl::optional<int64_t> chrome_root_store_version) : verification_time_(verification_time), - der_verification_time_(der_verification_time) {} + der_verification_time_(der_verification_time), + chrome_root_store_version_(chrome_root_store_version) {} // static const CertVerifyProcBuiltinResultDebugData* @@ -919,11 +895,12 @@ CertVerifyProcBuiltinResultDebugData::Get( void CertVerifyProcBuiltinResultDebugData::Create( base::SupportsUserData* debug_data, base::Time verification_time, - const der::GeneralizedTime& der_verification_time) { + const der::GeneralizedTime& der_verification_time, + absl::optional<int64_t> chrome_root_store_version) { debug_data->SetUserData( kResultDebugDataKey, std::make_unique<CertVerifyProcBuiltinResultDebugData>( - verification_time, der_verification_time)); + verification_time, der_verification_time, chrome_root_store_version)); } std::unique_ptr<base::SupportsUserData::Data> diff --git a/chromium/net/cert/cert_verify_proc_builtin.h b/chromium/net/cert/cert_verify_proc_builtin.h index d0a88f66ec2..74400831b98 100644 --- a/chromium/net/cert/cert_verify_proc_builtin.h +++ b/chromium/net/cert/cert_verify_proc_builtin.h @@ -12,6 +12,7 @@ #include "base/time/time.h" #include "net/base/net_export.h" #include "net/der/parse_values.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace net { @@ -24,13 +25,15 @@ class NET_EXPORT CertVerifyProcBuiltinResultDebugData public: CertVerifyProcBuiltinResultDebugData( base::Time verification_time, - const der::GeneralizedTime& der_verification_time); + const der::GeneralizedTime& der_verification_time, + absl::optional<int64_t> chrome_root_store_version); static const CertVerifyProcBuiltinResultDebugData* Get( const base::SupportsUserData* debug_data); static void Create(base::SupportsUserData* debug_data, base::Time verification_time, - const der::GeneralizedTime& der_verification_time); + const der::GeneralizedTime& der_verification_time, + absl::optional<int64_t> chrome_root_store_version); // base::SupportsUserData::Data implementation: std::unique_ptr<Data> Clone() override; @@ -39,10 +42,14 @@ class NET_EXPORT CertVerifyProcBuiltinResultDebugData const der::GeneralizedTime& der_verification_time() const { return der_verification_time_; } + absl::optional<int64_t> chrome_root_store_version() const { + return chrome_root_store_version_; + } private: base::Time verification_time_; der::GeneralizedTime der_verification_time_; + absl::optional<int64_t> chrome_root_store_version_; }; // TODO(crbug.com/649017): This is not how other cert_verify_proc_*.h are diff --git a/chromium/net/cert/cert_verify_proc_builtin_unittest.cc b/chromium/net/cert/cert_verify_proc_builtin_unittest.cc index c864606223c..a69e47a46e5 100644 --- a/chromium/net/cert/cert_verify_proc_builtin_unittest.cc +++ b/chromium/net/cert/cert_verify_proc_builtin_unittest.cc @@ -16,9 +16,9 @@ #include "net/cert/crl_set.h" #include "net/cert/ev_root_ca_metadata.h" #include "net/cert/internal/system_trust_store.h" -#include "net/cert/internal/trust_store.h" -#include "net/cert/internal/trust_store_collection.h" -#include "net/cert/internal/trust_store_in_memory.h" +#include "net/cert/pki/trust_store.h" +#include "net/cert/pki/trust_store_collection.h" +#include "net/cert/pki/trust_store_in_memory.h" #include "net/cert_net/cert_net_fetcher_url_request.h" #include "net/der/encode_values.h" #include "net/log/net_log_with_source.h" @@ -30,6 +30,7 @@ #include "net/test/embedded_test_server/http_response.h" #include "net/test/embedded_test_server/request_handler_util.h" #include "net/test/gtest_util.h" +#include "net/test/revocation_builder.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_builder.h" #include "net/url_request/url_request_test_util.h" @@ -63,6 +64,31 @@ std::unique_ptr<test_server::HttpResponse> FailRequestAndFailTest( return response; } +std::unique_ptr<test_server::HttpResponse> ServeResponse( + HttpStatusCode status_code, + const std::string& content_type, + const std::string& content, + const test_server::HttpRequest& request) { + auto http_response = std::make_unique<test_server::BasicHttpResponse>(); + + http_response->set_code(status_code); + http_response->set_content_type(content_type); + http_response->set_content(content); + return http_response; +} + +std::string MakeRandomHexString(size_t num_bytes) { + std::vector<char> rand_bytes; + rand_bytes.resize(num_bytes); + + base::RandBytes(rand_bytes.data(), rand_bytes.size()); + return base::HexEncode(rand_bytes.data(), rand_bytes.size()); +} + +static std::string MakeRandomPath(base::StringPiece suffix) { + return "/" + MakeRandomHexString(12) + std::string(suffix); +} + int VerifyOnWorkerThread(const scoped_refptr<CertVerifyProc>& verify_proc, scoped_refptr<X509Certificate> cert, const std::string& hostname, @@ -91,17 +117,22 @@ class MockSystemTrustStore : public SystemTrustStore { bool UsesSystemTrustStore() const override { return false; } bool IsKnownRoot(const ParsedCertificate* trust_anchor) const override { - return false; + return mock_is_known_root_; } void AddTrustStore(TrustStore* store) { trust_store_.AddTrustStore(store); } + void SetMockIsKnownRoot(bool is_known_root) { + mock_is_known_root_ = is_known_root; + } + #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) int64_t chrome_root_store_version() override { return 0; } #endif private: TrustStoreCollection trust_store_; + bool mock_is_known_root_ = false; }; class BlockingTrustStore : public TrustStore { @@ -164,6 +195,18 @@ class CertVerifyProcBuiltinTest : public ::testing::Test { base::test::TaskEnvironment& task_environment() { return task_environment_; } void CreateChain(std::unique_ptr<CertBuilder>* out_leaf, + std::unique_ptr<CertBuilder>* out_root) { + CertBuilder::CreateSimpleChain(out_leaf, out_root); + ASSERT_TRUE(*out_leaf && *out_root); + // This test uses MOCK_TIME, so need to set the cert validity dates based + // on whatever the mock time happens to start at. + base::Time not_before = base::Time::Now() - base::Days(1); + base::Time not_after = base::Time::Now() + base::Days(10); + (*out_leaf)->SetValidity(not_before, not_after); + (*out_root)->SetValidity(not_before, not_after); + } + + void CreateChain(std::unique_ptr<CertBuilder>* out_leaf, std::unique_ptr<CertBuilder>* out_intermediate, std::unique_ptr<CertBuilder>* out_root) { CertBuilder::CreateSimpleChain(out_leaf, out_intermediate, out_root); @@ -177,10 +220,32 @@ class CertVerifyProcBuiltinTest : public ::testing::Test { (*out_root)->SetValidity(not_before, not_after); } + // Creates a CRL issued and signed by |crl_issuer|, marking |revoked_serials| + // as revoked, and registers it to be served by the test server. + // Returns the full URL to retrieve the CRL from the test server. + GURL CreateAndServeCrl( + EmbeddedTestServer* test_server, + CertBuilder* crl_issuer, + const std::vector<uint64_t>& revoked_serials, + absl::optional<SignatureAlgorithm> signature_algorithm = absl::nullopt) { + std::string crl = BuildCrl(crl_issuer->GetSubject(), crl_issuer->GetKey(), + revoked_serials, signature_algorithm); + std::string crl_path = MakeRandomPath(".crl"); + test_server->RegisterRequestHandler( + base::BindRepeating(&test_server::HandlePrefixedRequest, crl_path, + base::BindRepeating(ServeResponse, HTTP_OK, + "application/pkix-crl", crl))); + return test_server->GetURL(crl_path); + } + void AddTrustStore(TrustStore* store) { mock_system_trust_store_->AddTrustStore(store); } + void SetMockIsKnownRoot(bool is_known_root) { + mock_system_trust_store_->SetMockIsKnownRoot(is_known_root); + } + private: base::test::TaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME, @@ -213,6 +278,56 @@ TEST_F(CertVerifyProcBuiltinTest, SimpleSuccess) { EXPECT_THAT(error, IsOk()); } +TEST_F(CertVerifyProcBuiltinTest, CRLNotCheckedForKnownRoots) { + std::unique_ptr<CertBuilder> leaf, root; + CreateChain(&leaf, &root); + ASSERT_TRUE(leaf && root); + + EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP); + ASSERT_TRUE(test_server.InitializeAndListen()); + + // CRL that marks leaf as revoked. + leaf->SetCrlDistributionPointUrl( + CreateAndServeCrl(&test_server, root.get(), {leaf->GetSerialNumber()})); + + test_server.StartAcceptingConnections(); + + scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain(); + ASSERT_TRUE(chain.get()); + + NetLogSource verify_net_log_source; + + { + CertVerifyResult verify_result; + TestCompletionCallback verify_callback; + Verify(chain.get(), "www.example.com", + CertVerifyProc::VERIFY_REV_CHECKING_ENABLED, + /*additional_trust_anchors=*/{root->GetX509Certificate()}, + &verify_result, &verify_net_log_source, verify_callback.callback()); + + int error = verify_callback.WaitForResult(); + EXPECT_THAT(error, IsError(ERR_CERT_REVOKED)); + EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED); + } + + { + // Pretend the root is a known root. + SetMockIsKnownRoot(true); + CertVerifyResult verify_result; + TestCompletionCallback verify_callback; + Verify(chain.get(), "www.example.com", + CertVerifyProc::VERIFY_REV_CHECKING_ENABLED, + /*additional_trust_anchors=*/{root->GetX509Certificate()}, + &verify_result, &verify_net_log_source, verify_callback.callback()); + + int error = verify_callback.WaitForResult(); + // CRLs are not checked for chains issued by known roots, so verification + // should be successful. + EXPECT_THAT(error, IsOk()); + EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED); + } +} + // Tests that if the verification deadline is exceeded during revocation // checking, additional CRL fetches will not be attempted. TEST_F(CertVerifyProcBuiltinTest, RevocationCheckDeadlineCRL) { @@ -360,9 +475,9 @@ TEST_F(CertVerifyProcBuiltinTest, RevocationCheckDeadlineOCSP) { } #if defined(PLATFORM_USES_CHROMIUM_EV_METADATA) -// Tests that if the verification deadline is exceeded during EV revocation -// checking, the certificate is verified as non-EV. -TEST_F(CertVerifyProcBuiltinTest, EVRevocationCheckDeadline) { +// Tests that if we're doing EV verification, that no OCSP revocation checking +// is done. +TEST_F(CertVerifyProcBuiltinTest, EVNoOCSPRevocationChecks) { std::unique_ptr<CertBuilder> leaf, intermediate, root; CreateChain(&leaf, &intermediate, &root); ASSERT_TRUE(leaf && intermediate && root); @@ -372,31 +487,20 @@ TEST_F(CertVerifyProcBuiltinTest, EVRevocationCheckDeadline) { leaf->SetCertificatePolicies({kEVTestCertPolicy}); intermediate->SetCertificatePolicies({kEVTestCertPolicy}); - const base::TimeDelta timeout_increment = - CertNetFetcherURLRequest::GetDefaultTimeoutForTesting() + - base::Milliseconds(1); - const int expected_request_count = - base::ClampFloor(GetCertVerifyProcBuiltinTimeLimitForTesting() / - timeout_increment) + - 1; - EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP); ASSERT_TRUE(test_server.InitializeAndListen()); - // Set up the test intermediate to have enough OCSP urls that if all the - // requests hang the deadline will be exceeded. + // Set up the test intermediate to have an OCSP url that fails the test if + // called. std::vector<GURL> ocsp_urls; - std::vector<base::RunLoop> runloops(expected_request_count); - for (int i = 0; i < expected_request_count; ++i) { - std::string path = base::StringPrintf("/hung/%i", i); - ocsp_urls.emplace_back(test_server.GetURL(path)); - test_server.RegisterRequestHandler( - base::BindRepeating(&test_server::HandlePrefixedRequest, path, - base::BindRepeating(&HangRequestAndCallback, - runloops[i].QuitClosure()))); - } + std::string path = "/failtest"; + ocsp_urls.emplace_back(test_server.GetURL(path)); + test_server.RegisterRequestHandler(base::BindRepeating( + &test_server::HandlePrefixedRequest, path, + base::BindRepeating(FailRequestAndFailTest, + "no OCSP requests should be sent", + base::SequencedTaskRunnerHandle::Get()))); intermediate->SetCaIssuersAndOCSPUrls({}, ocsp_urls); - test_server.StartAcceptingConnections(); // Consider the root of the test chain a valid EV root for the test policy. @@ -417,22 +521,12 @@ TEST_F(CertVerifyProcBuiltinTest, EVRevocationCheckDeadline) { /*additional_trust_anchors=*/{root->GetX509Certificate()}, &verify_result, &verify_net_log_source, verify_callback.callback()); - for (int i = 0; i < expected_request_count; i++) { - // Wait for request #|i| to be made. - runloops[i].Run(); - // Advance virtual time to cause the timeout task to become runnable. - task_environment().AdvanceClock(timeout_increment); - } - - // Once |expected_request_count| requests have been made and timed out, the - // overall deadline should be reached, causing the EV verification attempt to - // fail. + // EV doesn't do revocation checking, therefore verification result + // should be OK and EV. int error = verify_callback.WaitForResult(); - // EV uses soft-fail revocation checking, therefore verification result - // should be OK but not EV. EXPECT_THAT(error, IsOk()); - EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_IS_EV); - EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED); + EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV); + EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED); auto events = net_log_observer.GetEntriesForSource(verify_net_log_source); @@ -450,35 +544,6 @@ TEST_F(CertVerifyProcBuiltinTest, EVRevocationCheckDeadline) { ASSERT_NE(event, events.end()); EXPECT_EQ(net::NetLogEventPhase::NONE, event->phase); ASSERT_TRUE(event->params.is_dict()); - const std::string* errors = event->params.FindStringKey("errors"); - ASSERT_TRUE(errors); - EXPECT_EQ("----- Certificate i=1 (CN=" + - intermediate->GetX509Certificate()->subject().common_name + - ") -----\nERROR: Unable to check revocation\n\n", - *errors); - - event = std::find_if(++event, events.end(), [](const auto& e) { - return e.type == NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT; - }); - ASSERT_NE(event, events.end()); - EXPECT_EQ(net::NetLogEventPhase::END, event->phase); - ASSERT_TRUE(event->params.is_dict()); - EXPECT_EQ(false, event->params.FindBoolKey("has_valid_path")); - - event = std::find_if(++event, events.end(), [](const auto& e) { - return e.type == NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT; - }); - ASSERT_NE(event, events.end()); - EXPECT_EQ(net::NetLogEventPhase::BEGIN, event->phase); - ASSERT_TRUE(event->params.is_dict()); - EXPECT_EQ(absl::nullopt, event->params.FindBoolKey("is_ev_attempt")); - - event = std::find_if(++event, events.end(), [](const auto& e) { - return e.type == NetLogEventType::CERT_VERIFY_PROC_PATH_BUILT; - }); - ASSERT_NE(event, events.end()); - EXPECT_EQ(net::NetLogEventPhase::NONE, event->phase); - ASSERT_TRUE(event->params.is_dict()); EXPECT_FALSE(event->params.FindStringKey("errors")); event = std::find_if(++event, events.end(), [](const auto& e) { @@ -573,4 +638,110 @@ TEST_F(CertVerifyProcBuiltinTest, DebugData) { (time - der_verification_time_converted_back_to_base_time).InSeconds()); } +namespace { + +// Returns a TLV to use as an invalid signature algorithm when building a cert. +// This is a SEQUENCE so that it will pass the ParseCertificate code +// and fail inside ParseSignatureAlgorithm. +// SEQUENCE { +// INTEGER { 42 } +// } +std::string InvalidSignatureAlgorithmTLV() { + const uint8_t kInvalidSignatureAlgorithmTLV[] = {0x30, 0x03, 0x02, 0x01, + 0x2a}; + return std::string(std::begin(kInvalidSignatureAlgorithmTLV), + std::end(kInvalidSignatureAlgorithmTLV)); +} + +} // namespace + +TEST_F(CertVerifyProcBuiltinTest, + UnparsableMismatchedTBSSignatureAlgorithmTarget) { + std::unique_ptr<CertBuilder> leaf, root; + CreateChain(&leaf, &root); + ASSERT_TRUE(leaf && root); + // Set only the tbsCertificate signature to an invalid value. + leaf->SetTBSSignatureAlgorithmTLV(InvalidSignatureAlgorithmTLV()); + + // Trust the root and build a chain to verify. + ScopedTestRoot scoped_root(root->GetX509Certificate().get()); + scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain(); + ASSERT_TRUE(chain.get()); + + int flags = 0; + CertVerifyResult verify_result; + NetLogSource verify_net_log_source; + TestCompletionCallback callback; + Verify(chain.get(), "www.example.com", flags, CertificateList(), + &verify_result, &verify_net_log_source, callback.callback()); + int error = callback.WaitForResult(); + // Invalid signature algorithm in the leaf cert should result in the + // cert being invalid. + EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID); + EXPECT_THAT(error, IsError(ERR_CERT_INVALID)); +} + +TEST_F(CertVerifyProcBuiltinTest, + UnparsableMismatchedTBSSignatureAlgorithmIntermediate) { + std::unique_ptr<CertBuilder> leaf, intermediate, root; + CreateChain(&leaf, &intermediate, &root); + ASSERT_TRUE(leaf && intermediate && root); + // Set only the tbsCertificate signature to an invalid value. + intermediate->SetTBSSignatureAlgorithmTLV(InvalidSignatureAlgorithmTLV()); + + // Trust the root and build a chain to verify that includes the intermediate. + ScopedTestRoot scoped_root(root->GetX509Certificate().get()); + scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain(); + ASSERT_TRUE(chain.get()); + ASSERT_EQ(chain->intermediate_buffers().size(), 1U); + + int flags = 0; + CertVerifyResult verify_result; + NetLogSource verify_net_log_source; + TestCompletionCallback callback; + Verify(chain.get(), "www.example.com", flags, CertificateList(), + &verify_result, &verify_net_log_source, callback.callback()); + int error = callback.WaitForResult(); + // Invalid signature algorithm in the intermediate cert should result in the + // cert being invalid. + EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID); + EXPECT_THAT(error, IsError(ERR_CERT_INVALID)); +} + +// This test is disabled on Android as adding the invalid root through +// ScopedTestRoot causes it to be parsed by the Java X509 code which barfs. We +// could re-enable if Chrome on Android has fully switched to the +// builtin-verifier and ScopedTestRoot no longer has Android-specific code. +#if BUILDFLAG(IS_ANDROID) +#define MAYBE_UnparsableMismatchedTBSSignatureAlgorithmRoot \ + DISABLED_UnparsableMismatchedTBSSignatureAlgorithmRoot +#else +#define MAYBE_UnparsableMismatchedTBSSignatureAlgorithmRoot \ + UnparsableMismatchedTBSSignatureAlgorithmRoot +#endif +TEST_F(CertVerifyProcBuiltinTest, + MAYBE_UnparsableMismatchedTBSSignatureAlgorithmRoot) { + std::unique_ptr<CertBuilder> leaf, intermediate, root; + CreateChain(&leaf, &intermediate, &root); + ASSERT_TRUE(leaf && intermediate && root); + // Set only the tbsCertificate signature to an invalid value. + root->SetTBSSignatureAlgorithmTLV(InvalidSignatureAlgorithmTLV()); + + // Trust the root and build a chain to verify that includes the intermediate. + ScopedTestRoot scoped_root(root->GetX509Certificate().get()); + scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain(); + ASSERT_TRUE(chain.get()); + + int flags = 0; + CertVerifyResult verify_result; + NetLogSource verify_net_log_source; + TestCompletionCallback callback; + Verify(chain.get(), "www.example.com", flags, CertificateList(), + &verify_result, &verify_net_log_source, callback.callback()); + int error = callback.WaitForResult(); + // Invalid signature algorithm in the root cert should have no effect on + // verification. + EXPECT_THAT(error, IsOk()); +} + } // namespace net diff --git a/chromium/net/cert/cert_verify_proc_ios.cc b/chromium/net/cert/cert_verify_proc_ios.cc index ff02587d1b8..634266c003b 100644 --- a/chromium/net/cert/cert_verify_proc_ios.cc +++ b/chromium/net/cert/cert_verify_proc_ios.cc @@ -228,17 +228,9 @@ int BuildAndEvaluateSecTrustRef(CFArrayRef cert_array, #endif } - ScopedCFTypeRef<CFMutableArrayRef> tmp_verified_chain( - CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); - const CFIndex chain_length = SecTrustGetCertificateCount(tmp_trust); - for (CFIndex i = 0; i < chain_length; ++i) { - SecCertificateRef chain_cert = SecTrustGetCertificateAtIndex(tmp_trust, i); - CFArrayAppendValue(tmp_verified_chain, chain_cert); - } - trust_ref->swap(scoped_tmp_trust); trust_error->swap(tmp_error); - verified_chain->reset(tmp_verified_chain.release()); + *verified_chain = x509_util::CertificateChainFromSecTrust(tmp_trust); *is_trusted = tmp_is_trusted; return OK; } diff --git a/chromium/net/cert/cert_verify_proc_mac.cc b/chromium/net/cert/cert_verify_proc_mac.cc index 2da63bd1b5c..395c467be7e 100644 --- a/chromium/net/cert/cert_verify_proc_mac.cc +++ b/chromium/net/cert/cert_verify_proc_mac.cc @@ -29,10 +29,10 @@ #include "net/cert/crl_set.h" #include "net/cert/ct_serialization.h" #include "net/cert/ev_root_ca_metadata.h" -#include "net/cert/internal/certificate_policies.h" -#include "net/cert/internal/parsed_certificate.h" #include "net/cert/known_roots.h" #include "net/cert/known_roots_mac.h" +#include "net/cert/pki/certificate_policies.h" +#include "net/cert/pki/parsed_certificate.h" #include "net/cert/test_keychain_search_list_mac.h" #include "net/cert/test_root_certs.h" #include "net/cert/x509_certificate.h" @@ -572,7 +572,7 @@ int BuildAndEvaluateSecTrustRef(CFArrayRef cert_array, SecTrustResultType* trust_result, ScopedCFTypeRef<CFArrayRef>* verified_chain, std::vector<CertEvidenceInfo>* chain_info) { - SecTrustRef tmp_trust = NULL; + SecTrustRef tmp_trust = nullptr; OSStatus status = SecTrustCreateWithCertificates(cert_array, trust_policies, &tmp_trust); if (status) @@ -656,7 +656,7 @@ int BuildAndEvaluateSecTrustRef(CFArrayRef cert_array, status = SecTrustEvaluate(tmp_trust, &tmp_trust_result); if (status) return NetErrorFromOSStatus(status); - CFArrayRef tmp_verified_chain = NULL; + CFArrayRef tmp_verified_chain = nullptr; CSSM_TP_APPLE_EVIDENCE_INFO* tmp_chain_info; status = SecTrustGetResult(tmp_trust, &tmp_trust_result, &tmp_verified_chain, &tmp_chain_info); @@ -1143,44 +1143,10 @@ int CertVerifyProcMac::VerifyInternal( if (!candidate_ev_policy_oid.empty() && CheckCertChainEV(verify_result->verified_cert.get(), candidate_ev_policy_oid)) { - // EV policies check out and the verification succeeded. See if revocation - // checking still needs to be done before it can be marked as EV. Even if - // the first verification had VERIFY_REV_CHECKING_ENABLED, verification - // must be repeated since the previous verification was done with soft-fail - // revocation checking. - if (completed_chain_crl_result == kCRLSetUnknown) { - // If this is an EV cert and it wasn't covered by CRLSets and revocation - // checking wasn't already on, try again with revocation forced on. - // - // Restore the input state of |*verify_result|, so that the - // re-verification starts with a clean slate. - CertVerifyResult ev_verify_result = input_verify_result; - int tmp_rv = VerifyWithGivenFlags( - verify_result->verified_cert.get(), hostname, ocsp_response, sct_list, - flags | VERIFY_REV_CHECKING_ENABLED, - /*rev_checking_soft_fail=*/false, crl_set, &ev_verify_result, - &completed_chain_crl_result); - if (tmp_rv == OK) { - // If EV re-verification succeeded, mark as EV and return those results. - *verify_result = ev_verify_result; - verify_result->cert_status |= CERT_STATUS_IS_EV; - } else if (tmp_rv == ERR_CERT_REVOKED) { - // This matches the historical behavior of cert_verify_proc_mac where a - // revoked result from the EV verification attempt results in revoked - // result overall. (Technically this may not be correct if there was a - // different non-revoked, non-EV path that could have been built.) - *verify_result = ev_verify_result; - return tmp_rv; - } else { - // If EV was attempted, set CERT_STATUS_REV_CHECKING_ENABLED even if the - // EV result wasn't used. This is a little weird but matches the - // behavior of the other verifiers. - verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; - } - } else { - // EV cert and it was covered by CRLSets. - verify_result->cert_status |= CERT_STATUS_IS_EV; - } + // EV policies check out and the verification succeeded. Revocation checking + // may have been done, but revocation checking is not required for EV certs + // (see https://crbug.com/705285). + verify_result->cert_status |= CERT_STATUS_IS_EV; } LogNameNormalizationMetrics(".Mac", verify_result->verified_cert.get(), diff --git a/chromium/net/cert/cert_verify_proc_mac_unittest.cc b/chromium/net/cert/cert_verify_proc_mac_unittest.cc index b3dfd6b3743..908d5fccd15 100644 --- a/chromium/net/cert/cert_verify_proc_mac_unittest.cc +++ b/chromium/net/cert/cert_verify_proc_mac_unittest.cc @@ -84,6 +84,12 @@ TEST(CertVerifyProcMacTest, DISABLED_MacCRLIntermediate) { TestKeychainSearchList::Create()); ASSERT_TRUE(test_keychain_search_list); +// Much of the Keychain API was marked deprecated as of the macOS 13 SDK. +// Removal of its use is tracked in https://crbug.com/1348251 but deprecation +// warnings are disabled in the meanwhile. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + base::FilePath keychain_path( GetTestCertsDirectory().AppendASCII("multi-root-BFE.keychain")); // SecKeychainOpen does not fail if the file doesn't exist, so assert it here @@ -97,6 +103,8 @@ TEST(CertVerifyProcMacTest, DISABLED_MacCRLIntermediate) { base::ScopedCFTypeRef<SecKeychainRef> scoped_keychain(keychain); test_keychain_search_list->AddKeychain(keychain); +#pragma clang diagnostic pop + scoped_refptr<CRLSet> crl_set; std::string crl_set_bytes; // CRL which blocks C by SPKI. @@ -147,6 +155,12 @@ TEST(CertVerifyProcMacTest, DISABLED_MacKeychainReordering) { X509Certificate::FORMAT_AUTO); ASSERT_TRUE(cert); +// Much of the Keychain API was marked deprecated as of the macOS 13 SDK. +// Removal of its use is tracked in https://crbug.com/1348251 but deprecation +// warnings are disabled in the meanwhile. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + // Create a test keychain search list that will Always Trust the SHA1 // cross-signed VeriSign Class 3 Public Primary Certification Authority - G5 std::unique_ptr<TestKeychainSearchList> test_keychain_search_list( @@ -166,6 +180,8 @@ TEST(CertVerifyProcMacTest, DISABLED_MacKeychainReordering) { base::ScopedCFTypeRef<SecKeychainRef> scoped_keychain(keychain); test_keychain_search_list->AddKeychain(keychain); +#pragma clang diagnostic pop + int flags = 0; CertVerifyResult verify_result; scoped_refptr<CertVerifyProc> verify_proc = @@ -184,6 +200,12 @@ TEST(CertVerifyProcMacTest, DISABLED_MacKeychainReordering) { ASSERT_EQ(2U, verified_intermediates.size()); } +// Much of the Keychain API was marked deprecated as of the macOS 13 SDK. +// Removal of its use is tracked in https://crbug.com/1348251 but deprecation +// warnings are disabled in the meanwhile. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + // Test that the system root certificate keychain is in the expected location // and can be opened. Other tests would fail if this was not true, but this // test makes the reason for the failure obvious. @@ -198,6 +220,8 @@ TEST(CertVerifyProcMacTest, MacSystemRootCertificateKeychainLocation) { CFRelease(keychain); } +#pragma clang diagnostic pop + // Test that CertVerifyProcMac reacts appropriately when Apple's certificate // verifier rejects a certificate with a fatal error. This is a regression // test for https://crbug.com/472291. diff --git a/chromium/net/cert/cert_verify_proc_unittest.cc b/chromium/net/cert/cert_verify_proc_unittest.cc index 19608b63a5c..edbe04abeda 100644 --- a/chromium/net/cert/cert_verify_proc_unittest.cc +++ b/chromium/net/cert/cert_verify_proc_unittest.cc @@ -34,12 +34,12 @@ #include "net/cert/cert_verify_result.h" #include "net/cert/crl_set.h" #include "net/cert/ev_root_ca_metadata.h" -#include "net/cert/internal/extended_key_usage.h" -#include "net/cert/internal/parse_certificate.h" -#include "net/cert/internal/signature_algorithm.h" #include "net/cert/internal/system_trust_store.h" #include "net/cert/ocsp_revocation_status.h" #include "net/cert/pem.h" +#include "net/cert/pki/extended_key_usage.h" +#include "net/cert/pki/parse_certificate.h" +#include "net/cert/pki/signature_algorithm.h" #include "net/cert/test_root_certs.h" #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" @@ -191,16 +191,17 @@ scoped_refptr<CertVerifyProc> CreateCertVerifyProc( switch (type) { #if BUILDFLAG(IS_ANDROID) case CERT_VERIFY_PROC_ANDROID: - return new CertVerifyProcAndroid(std::move(cert_net_fetcher)); + return base::MakeRefCounted<CertVerifyProcAndroid>( + std::move(cert_net_fetcher)); #elif BUILDFLAG(IS_IOS) case CERT_VERIFY_PROC_IOS: - return new CertVerifyProcIOS(); + return base::MakeRefCounted<CertVerifyProcIOS>(); #elif BUILDFLAG(IS_MAC) case CERT_VERIFY_PROC_MAC: - return new CertVerifyProcMac(); + return base::MakeRefCounted<CertVerifyProcMac>(); #elif BUILDFLAG(IS_WIN) case CERT_VERIFY_PROC_WIN: - return new CertVerifyProcWin(); + return base::MakeRefCounted<CertVerifyProcWin>(); #endif case CERT_VERIFY_PROC_BUILTIN: return CreateCertVerifyProcBuiltin(std::move(cert_net_fetcher), @@ -229,9 +230,15 @@ const std::vector<CertVerifyProcType> kAllCertVerifiers = { #elif BUILDFLAG(IS_IOS) CERT_VERIFY_PROC_IOS #elif BUILDFLAG(IS_MAC) - CERT_VERIFY_PROC_MAC, CERT_VERIFY_PROC_BUILTIN + CERT_VERIFY_PROC_MAC, CERT_VERIFY_PROC_BUILTIN, +#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) + CERT_VERIFY_PROC_BUILTIN_CHROME_ROOTS +#endif #elif BUILDFLAG(IS_WIN) - CERT_VERIFY_PROC_WIN, CERT_VERIFY_PROC_BUILTIN_CHROME_ROOTS + CERT_VERIFY_PROC_WIN, +#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) + CERT_VERIFY_PROC_BUILTIN_CHROME_ROOTS +#endif #elif BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) CERT_VERIFY_PROC_BUILTIN #else @@ -622,11 +629,19 @@ TEST_P(CertVerifyProcInternalTest, TrustedIntermediateCertWithEVPolicy) { ASSERT_EQ(3U, orig_certs.size()); for (bool trust_the_intermediate : {false, true}) { + SCOPED_TRACE(trust_the_intermediate); + // Need to build unique certs for each try otherwise caching can break // things. CertBuilder root(orig_certs[2]->cert_buffer(), nullptr); + root.SetSignatureAlgorithm(SignatureAlgorithm::kEcdsaSha256); + root.GenerateECKey(); CertBuilder intermediate(orig_certs[1]->cert_buffer(), &root); + intermediate.SetSignatureAlgorithm(SignatureAlgorithm::kEcdsaSha256); + intermediate.GenerateECKey(); CertBuilder leaf(orig_certs[0]->cert_buffer(), &intermediate); + leaf.SetSignatureAlgorithm(SignatureAlgorithm::kEcdsaSha256); + leaf.GenerateECKey(); // The policy that "explicit-policy-chain.pem" target certificate asserts. static const char kEVTestCertPolicy[] = "1.2.3.4"; @@ -1192,8 +1207,7 @@ class CertVerifyProcInspectSignatureAlgorithmsTest : public ::testing::Test { CertVerifyResult dummy_result; CertVerifyResult verify_result; - scoped_refptr<CertVerifyProc> verify_proc = - new MockCertVerifyProc(dummy_result); + auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(dummy_result); return verify_proc->Verify( chain.get(), "test.example.com", /*ocsp_response=*/std::string(), @@ -1621,7 +1635,7 @@ TEST_P(CertVerifyProcInternalTest, TestKnownRoot) { << "against mattm."; EXPECT_TRUE(verify_result.is_issued_by_known_root); #if BUILDFLAG(IS_MAC) - if (VerifyProcTypeIsBuiltin()) { + if (verify_proc_type() == CERT_VERIFY_PROC_BUILTIN) { auto* mac_trust_debug_info = net::TrustStoreMac::ResultDebugData::Get(&verify_result); ASSERT_TRUE(mac_trust_debug_info); @@ -1848,8 +1862,7 @@ TEST(CertVerifyProcTest, IntranetHostsRejected) { // Intranet names for public CAs should be flagged: CertVerifyResult dummy_result; dummy_result.is_issued_by_known_root = true; - scoped_refptr<CertVerifyProc> verify_proc = - new MockCertVerifyProc(dummy_result); + auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(dummy_result); error = verify_proc->Verify( cert.get(), "webmail", /*ocsp_response=*/std::string(), /*sct_list=*/std::string(), 0, CRLSet::BuiltinCRLSet().get(), @@ -3114,11 +3127,12 @@ class CertVerifyProcInternalWithNetFetchingTest // Creates a CRL issued and signed by |crl_issuer|, marking |revoked_serials| // as revoked, and registers it to be served by the test server. // Returns the full URL to retrieve the CRL from the test server. - GURL CreateAndServeCrl(CertBuilder* crl_issuer, - const std::vector<uint64_t>& revoked_serials, - DigestAlgorithm digest = DigestAlgorithm::Sha256) { + GURL CreateAndServeCrl( + CertBuilder* crl_issuer, + const std::vector<uint64_t>& revoked_serials, + absl::optional<SignatureAlgorithm> signature_algorithm = absl::nullopt) { std::string crl = BuildCrl(crl_issuer->GetSubject(), crl_issuer->GetKey(), - revoked_serials, digest); + revoked_serials, signature_algorithm); std::string crl_path = MakeRandomPath(".crl"); return RegisterSimpleTestServerHandler(crl_path, HTTP_OK, "application/pkix-crl", crl); @@ -3428,8 +3442,13 @@ TEST_P(CertVerifyProcInternalWithNetFetchingTest, // Build slightly modified variants of |orig_certs|. CertBuilder root(orig_certs[2]->cert_buffer(), nullptr); + root.SetSignatureAlgorithm(SignatureAlgorithm::kEcdsaSha256); + root.GenerateECKey(); CertBuilder intermediate(orig_certs[1]->cert_buffer(), &root); + intermediate.GenerateECKey(); CertBuilder leaf(orig_certs[0]->cert_buffer(), &intermediate); + leaf.SetSignatureAlgorithm(SignatureAlgorithm::kEcdsaSha256); + leaf.GenerateECKey(); // Make the leaf certificate have an AIA (CA Issuers) that points to the // embedded test server. This uses a random URL for predictable behavior in @@ -3443,11 +3462,11 @@ TEST_P(CertVerifyProcInternalWithNetFetchingTest, // that is SHA1 signed. Note that the subjectKeyIdentifier for `intermediate` // is intentionally not changed, so that path building will consider both // certificate paths. - intermediate.SetSignatureAlgorithmRsaPkca1(DigestAlgorithm::Sha256); + intermediate.SetSignatureAlgorithm(SignatureAlgorithm::kEcdsaSha256); intermediate.SetRandomSerialNumber(); auto intermediate_sha256 = intermediate.DupCertBuffer(); - intermediate.SetSignatureAlgorithmRsaPkca1(DigestAlgorithm::Sha1); + intermediate.SetSignatureAlgorithm(SignatureAlgorithm::kEcdsaSha1); intermediate.SetRandomSerialNumber(); auto intermediate_sha1 = intermediate.DupCertBuffer(); @@ -3998,9 +4017,10 @@ TEST_P(CertVerifyProcInternalWithNetFetchingTest, intermediate->SetCrlDistributionPointUrl(CreateAndServeCrl(root.get(), {})); // Leaf is revoked by intermediate issued CRL which is signed with - // sha1WithRSAEncryption. - leaf->SetCrlDistributionPointUrl(CreateAndServeCrl( - intermediate.get(), {leaf->GetSerialNumber()}, DigestAlgorithm::Sha1)); + // ecdsaWithSha256. + leaf->SetCrlDistributionPointUrl( + CreateAndServeCrl(intermediate.get(), {leaf->GetSerialNumber()}, + SignatureAlgorithm::kEcdsaSha1)); // Trust the root and build a chain to verify that includes the intermediate. ScopedTestRoot scoped_root(root->GetX509Certificate().get()); @@ -4040,11 +4060,17 @@ TEST_P(CertVerifyProcInternalWithNetFetchingTest, // Root-issued CRL which does not revoke intermediate. intermediate->SetCrlDistributionPointUrl(CreateAndServeCrl(root.get(), {})); + // This test wants to check handling of MD5 CRLs, but ecdsa-with-md5 + // signatureAlgorithm does not exist. Use an RSA private key for intermediate + // so that the CRL will be signed with the md5WithRSAEncryption algorithm. + intermediate->GenerateRSAKey(); + leaf->SetSignatureAlgorithm(SignatureAlgorithm::kRsaPkcs1Sha256); // Leaf is revoked by intermediate issued CRL which is signed with // md5WithRSAEncryption. - leaf->SetCrlDistributionPointUrl(CreateAndServeCrl( - intermediate.get(), {leaf->GetSerialNumber()}, DigestAlgorithm::Md5)); + leaf->SetCrlDistributionPointUrl( + CreateAndServeCrl(intermediate.get(), {leaf->GetSerialNumber()}, + SignatureAlgorithm::kRsaPkcs1Md5)); // Trust the root and build a chain to verify that includes the intermediate. ScopedTestRoot scoped_root(root->GetX509Certificate().get()); @@ -4191,11 +4217,11 @@ TEST_P(CertVerifyProcInternalWithNetFetchingTest, CRLSet::BuiltinCRLSet().get(), CertificateList(), &verify_result); EXPECT_THAT(error, IsOk()); EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV); - EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED); + EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } // Tests that an EV cert verification with that could not retrieve online OCSP -// revocation information is verified but not marked as CERT_STATUS_IS_EV. +// revocation information is verified but still marked as CERT_STATUS_IS_EV. TEST_P(CertVerifyProcInternalWithNetFetchingTest, EVOnlineOCSPRevocationCheckingSoftFail) { if (!SupportsEV()) { @@ -4233,12 +4259,12 @@ TEST_P(CertVerifyProcInternalWithNetFetchingTest, Verify(chain.get(), ocsp_test_server.host_port_pair().host(), flags, CRLSet::BuiltinCRLSet().get(), CertificateList(), &verify_result); EXPECT_THAT(error, IsOk()); - EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_IS_EV); + EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV); + EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } // Tests that an EV cert verification with online OCSP returning affirmatively -// revoked is not marked as CERT_STATUS_IS_EV. On some platforms verification -// will fail with ERR_CERT_REVOKED. +// revoked is marked as CERT_STATUS_IS_EV. TEST_P(CertVerifyProcInternalWithNetFetchingTest, EVOnlineOCSPRevocationCheckingRevoked) { if (!SupportsEV()) { @@ -4275,11 +4301,9 @@ TEST_P(CertVerifyProcInternalWithNetFetchingTest, int error = Verify(chain.get(), ocsp_test_server.host_port_pair().host(), flags, CRLSet::BuiltinCRLSet().get(), CertificateList(), &verify_result); - if (VerifyProcTypeIsBuiltin()) - EXPECT_THAT(error, IsOk()); - else - EXPECT_THAT(error, IsError(ERR_CERT_REVOKED)); - EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_IS_EV); + EXPECT_THAT(error, IsOk()); + EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV); + EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED); } TEST(CertVerifyProcTest, RejectsPublicSHA1Leaves) { @@ -4291,7 +4315,7 @@ TEST(CertVerifyProcTest, RejectsPublicSHA1Leaves) { result.has_sha1 = true; result.has_sha1_leaf = true; result.is_issued_by_known_root = true; - scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); + auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result); int flags = 0; CertVerifyResult verify_result; @@ -4312,7 +4336,7 @@ TEST(CertVerifyProcTest, RejectsPublicSHA1IntermediatesUnlessAllowed) { result.has_sha1 = true; result.has_sha1_leaf = false; result.is_issued_by_known_root = true; - scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); + auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result); int flags = 0; CertVerifyResult verify_result; @@ -4339,7 +4363,7 @@ TEST(CertVerifyProcTest, RejectsPrivateSHA1UnlessFlag) { result.has_sha1 = true; result.has_sha1_leaf = true; result.is_issued_by_known_root = false; - scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); + auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result); // SHA-1 should be rejected by default for private roots... int flags = 0; @@ -4396,7 +4420,7 @@ class CertVerifyProcWeakDigestTest : public testing::TestWithParam<WeakDigestTestData> { public: CertVerifyProcWeakDigestTest() = default; - virtual ~CertVerifyProcWeakDigestTest() = default; + ~CertVerifyProcWeakDigestTest() override = default; }; // Tests that the CertVerifyProc::Verify() properly surfaces the (weak) hash @@ -4438,8 +4462,7 @@ TEST_P(CertVerifyProcWeakDigestTest, VerifyDetectsAlgorithm) { // // This is sufficient for the purposes of this test, as the checking for weak // hash algorithms is done by CertVerifyProc::Verify(). - scoped_refptr<CertVerifyProc> proc = - new MockCertVerifyProc(CertVerifyResult()); + auto proc = base::MakeRefCounted<MockCertVerifyProc>(CertVerifyResult()); int error = proc->Verify(ee_chain.get(), "127.0.0.1", /*ocsp_response=*/std::string(), /*sct_list=*/std::string(), flags, @@ -4569,7 +4592,7 @@ class CertVerifyProcNameTest : public ::testing::Test { ASSERT_TRUE(cert); CertVerifyResult result; result.is_issued_by_known_root = false; - scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); + auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result); CertVerifyResult verify_result; int error = verify_proc->Verify( @@ -4678,7 +4701,7 @@ TEST(CertVerifyProcTest, HasTrustAnchorVerifyUMA) { const base::HistogramBase::Sample kGTSRootR4HistogramID = 486; - scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); + auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result); histograms.ExpectTotalCount(kTrustAnchorVerifyHistogram, 0); @@ -4726,7 +4749,7 @@ TEST(CertVerifyProcTest, LogsOnlyMostSpecificTrustAnchorUMA) { const base::HistogramBase::Sample kGTSRootR3HistogramID = 485; - scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); + auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result); histograms.ExpectTotalCount(kTrustAnchorVerifyHistogram, 0); @@ -4764,7 +4787,7 @@ TEST(CertVerifyProcTest, HasTrustAnchorVerifyOutOfDateUMA) { result.public_key_hashes.push_back(HashValue(root_hash)); result.is_issued_by_known_root = true; - scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); + auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result); histograms.ExpectTotalCount(kTrustAnchorVerifyHistogram, 0); histograms.ExpectTotalCount(kTrustAnchorVerifyOutOfDateHistogram, 0); @@ -4797,7 +4820,7 @@ TEST(CertVerifyProcTest, DoesNotRecalculateStapledOCSPResult) { result.ocsp_result.response_status = OCSPVerifyResult::PROVIDED; result.ocsp_result.revocation_status = OCSPRevocationStatus::GOOD; - scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); + auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result); int flags = 0; CertVerifyResult verify_result; @@ -4828,7 +4851,7 @@ TEST(CertVerifyProcTest, CalculateStapledOCSPResultIfNotAlreadyDone) { EXPECT_EQ(OCSPRevocationStatus::UNKNOWN, result.ocsp_result.revocation_status); - scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); + auto verify_proc = base::MakeRefCounted<MockCertVerifyProc>(result); int flags = 0; CertVerifyResult verify_result; diff --git a/chromium/net/cert/cert_verify_proc_win.cc b/chromium/net/cert/cert_verify_proc_win.cc index 3ab050f51f1..9d767d0e216 100644 --- a/chromium/net/cert/cert_verify_proc_win.cc +++ b/chromium/net/cert/cert_verify_proc_win.cc @@ -285,7 +285,7 @@ void GetCertChainInfo(PCCERT_CHAIN_CONTEXT chain_context, NULL, X509_ASN_ENCODING, CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT, const_cast<PCERT_CONTEXT>(cert), CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT, - const_cast<PCERT_CONTEXT>(issuer), 0, NULL)) { + const_cast<PCERT_CONTEXT>(issuer), 0, nullptr)) { verify_result->cert_status |= CERT_STATUS_INVALID; break; } @@ -453,7 +453,7 @@ CRLSetResult CheckRevocationWithCRLSet(CRLSet* crl_set, // Compute the subject's serial. const CRYPT_INTEGER_BLOB* serial_blob = &subject_cert->pCertInfo->SerialNumber; - std::unique_ptr<uint8_t[]> serial_bytes(new uint8_t[serial_blob->cbData]); + auto serial_bytes = std::make_unique<uint8_t[]>(serial_blob->cbData); // The bytes of the serial number are stored little-endian. // Note: While MSDN implies that bytes are stripped from this serial, // they are not - only CertCompareIntegerBlob actually removes bytes. @@ -1055,9 +1055,9 @@ CertVerifyProcWin::ResultDebugData::Clone() { return std::make_unique<ResultDebugData>(*this); } -CertVerifyProcWin::CertVerifyProcWin() {} +CertVerifyProcWin::CertVerifyProcWin() = default; -CertVerifyProcWin::~CertVerifyProcWin() {} +CertVerifyProcWin::~CertVerifyProcWin() = default; bool CertVerifyProcWin::SupportsAdditionalTrustAnchors() const { return false; @@ -1250,26 +1250,11 @@ int CertVerifyProcWin::VerifyInternal( if (crl_set_result == kCRLSetRevoked) { verify_result->cert_status |= CERT_STATUS_REVOKED; - } else if (crl_set_result == kCRLSetUnknown && !rev_checking_enabled && - ev_policy_oid) { - // We don't have fresh information about this chain from the CRLSet and - // it's probably an EV certificate. Retry with online revocation checking. - rev_checking_enabled = true; - chain_flags &= ~CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY; - verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; - - CertFreeCertificateChain(chain_context); - if (!CertGetCertificateChain(chain_engine.get(), cert_list.get(), - nullptr, // current system time - cert_list->hCertStore, &chain_para, - chain_flags, - nullptr, // reserved - &chain_context)) { - verify_result->cert_status |= CERT_STATUS_INVALID; - return MapSecurityError(GetLastError()); - } } + // Even if the cert is possibly EV and crl_set_result == kCRLSetUnknown, we + // don't check with online revocation checking enabled. See crbug.com/1268848. + if (chain_context->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE) { // Could not verify the cert with the EV policy. Remove the EV policy and diff --git a/chromium/net/cert/client_cert_verifier.h b/chromium/net/cert/client_cert_verifier.h index 8c49a63232f..b29d61875ba 100644 --- a/chromium/net/cert/client_cert_verifier.h +++ b/chromium/net/cert/client_cert_verifier.h @@ -19,16 +19,16 @@ class NET_EXPORT ClientCertVerifier { public: class Request { public: - Request() {} + Request() = default; Request(const Request&) = delete; Request& operator=(const Request&) = delete; // Destruction of the Request cancels it. - virtual ~Request() {} + virtual ~Request() = default; }; - virtual ~ClientCertVerifier() {} + virtual ~ClientCertVerifier() = default; // Verifies the given certificate as a client certificate. // Returns OK if successful or an error code upon failure. diff --git a/chromium/net/cert/crl_set.cc b/chromium/net/cert/crl_set.cc index cc9e6c50f6c..d60b386396f 100644 --- a/chromium/net/cert/crl_set.cc +++ b/chromium/net/cert/crl_set.cc @@ -177,7 +177,7 @@ bool CopyHashToHashesMapFromHeader( std::vector<std::string> allowed_spkis; for (const auto& j : i.second.GetList()) { - allowed_spkis.push_back(std::string()); + allowed_spkis.emplace_back(); if (!j.is_string() || !base::Base64Decode(j.GetString(), &allowed_spkis.back())) { return false; @@ -236,7 +236,7 @@ bool CRLSet::Parse(base::StringPiece data, scoped_refptr<CRLSet>* out_crl_set) { if (not_after < 0) return false; - scoped_refptr<CRLSet> crl_set(new CRLSet()); + auto crl_set = base::WrapRefCounted(new CRLSet()); crl_set->sequence_ = static_cast<uint32_t>(*sequence); crl_set->not_after_ = static_cast<uint64_t>(not_after); crl_set->crls_.reserve(64); // Value observed experimentally. @@ -276,13 +276,13 @@ bool CRLSet::Parse(base::StringPiece data, scoped_refptr<CRLSet>* out_crl_set) { // Defines kSPKIBlockList and kKnownInterceptionList #include "net/cert/cert_verify_proc_blocklist.inc" for (const auto& hash : kSPKIBlockList) { - crl_set->blocked_spkis_.push_back(std::string( - reinterpret_cast<const char*>(hash), crypto::kSHA256Length)); + crl_set->blocked_spkis_.emplace_back(reinterpret_cast<const char*>(hash), + crypto::kSHA256Length); } for (const auto& hash : kKnownInterceptionList) { - crl_set->known_interception_spkis_.push_back(std::string( - reinterpret_cast<const char*>(hash), crypto::kSHA256Length)); + crl_set->known_interception_spkis_.emplace_back( + reinterpret_cast<const char*>(hash), crypto::kSHA256Length); } // Sort, as these will be std::binary_search()'d. @@ -435,7 +435,7 @@ scoped_refptr<CRLSet> CRLSet::ForTesting( OPENSSL_free(x501_data); } - scoped_refptr<CRLSet> crl_set(new CRLSet); + auto crl_set = base::WrapRefCounted(new CRLSet()); crl_set->sequence_ = 0; if (is_expired) crl_set->not_after_ = 1; diff --git a/chromium/net/cert/ct_log_response_parser.cc b/chromium/net/cert/ct_log_response_parser.cc index 1d92485a1e3..614a56b252f 100644 --- a/chromium/net/cert/ct_log_response_parser.cc +++ b/chromium/net/cert/ct_log_response_parser.cc @@ -15,9 +15,7 @@ #include "net/cert/ct_serialization.h" #include "net/cert/signed_tree_head.h" -namespace net { - -namespace ct { +namespace net::ct { namespace { @@ -128,6 +126,4 @@ bool FillConsistencyProof(const base::Value& json_consistency_proof, return true; } -} // namespace ct - -} // namespace net +} // namespace net::ct diff --git a/chromium/net/cert/ct_log_response_parser.h b/chromium/net/cert/ct_log_response_parser.h index 403f8bfb050..c5ece4ef53a 100644 --- a/chromium/net/cert/ct_log_response_parser.h +++ b/chromium/net/cert/ct_log_response_parser.h @@ -15,9 +15,7 @@ namespace base { class Value; } // namespace base -namespace net { - -namespace ct { +namespace net::ct { struct SignedTreeHead; // Fills in |signed_tree_head| from its JSON representation in @@ -31,7 +29,5 @@ NET_EXPORT bool FillConsistencyProof( const base::Value& json_signed_tree_head, std::vector<std::string>* consistency_proof); -} // namespace ct - -} // namespace net +} // namespace net::ct #endif // NET_CERT_CT_LOG_RESPONSE_PARSER_H_ diff --git a/chromium/net/cert/ct_log_response_parser_unittest.cc b/chromium/net/cert/ct_log_response_parser_unittest.cc index b3ed665947a..ce479ef99ad 100644 --- a/chromium/net/cert/ct_log_response_parser_unittest.cc +++ b/chromium/net/cert/ct_log_response_parser_unittest.cc @@ -16,9 +16,7 @@ #include "net/test/ct_test_util.h" #include "testing/gtest/include/gtest/gtest.h" -namespace net { - -namespace ct { +namespace net::ct { TEST(CTLogResponseParserTest, ParsesValidJsonSTH) { absl::optional<base::Value> sample_sth_json = @@ -154,6 +152,4 @@ TEST(CTLogResponseParserTest, ParsesProofJsonWithExtraFields) { EXPECT_TRUE(FillConsistencyProof(*badly_encoded, &output)); } -} // namespace ct - -} // namespace net +} // namespace net::ct diff --git a/chromium/net/cert/ct_log_verifier.cc b/chromium/net/cert/ct_log_verifier.cc index 7d6fcca74fd..f231491fa81 100644 --- a/chromium/net/cert/ct_log_verifier.cc +++ b/chromium/net/cert/ct_log_verifier.cc @@ -59,8 +59,7 @@ const EVP_MD* GetEvpAlg(ct::DigitallySigned::HashAlgorithm alg) { scoped_refptr<const CTLogVerifier> CTLogVerifier::Create( const base::StringPiece& public_key, std::string description) { - scoped_refptr<CTLogVerifier> result( - new CTLogVerifier(std::move(description))); + auto result = base::WrapRefCounted(new CTLogVerifier(std::move(description))); if (!result->Init(public_key)) return nullptr; return result; @@ -284,7 +283,7 @@ bool CTLogVerifier::Init(const base::StringPiece& public_key) { // Right now, only RSASSA-PKCS1v15 with SHA-256 and ECDSA with SHA-256 are // supported. - switch (EVP_PKEY_type(public_key_->type)) { + switch (EVP_PKEY_id(public_key_)) { case EVP_PKEY_RSA: hash_algorithm_ = ct::DigitallySigned::HASH_ALGO_SHA256; signature_algorithm_ = ct::DigitallySigned::SIG_ALGO_RSA; diff --git a/chromium/net/cert/ct_log_verifier_unittest.cc b/chromium/net/cert/ct_log_verifier_unittest.cc index f54e071d2b5..2faf373297c 100644 --- a/chromium/net/cert/ct_log_verifier_unittest.cc +++ b/chromium/net/cert/ct_log_verifier_unittest.cc @@ -256,7 +256,7 @@ void CheckVerifyAuditProof(const CTLogVerifier& log, } wrong_proof = proof; - wrong_proof.push_back(std::string()); + wrong_proof.emplace_back(); EXPECT_FALSE( VerifyAuditProof(log, leaf, tree_size, wrong_proof, root_hash, leaf_hash)) << "proof passed verification with an empty node appended"; @@ -275,7 +275,7 @@ void CheckVerifyAuditProof(const CTLogVerifier& log, } wrong_proof.clear(); - wrong_proof.push_back(std::string()); + wrong_proof.emplace_back(); wrong_proof.insert(wrong_proof.end(), proof.begin(), proof.end()); EXPECT_FALSE( VerifyAuditProof(log, leaf, tree_size, wrong_proof, root_hash, leaf_hash)) @@ -355,7 +355,7 @@ void CheckVerifyConsistencyProof(const CTLogVerifier& log, } wrong_proof = proof; - wrong_proof.push_back(std::string()); + wrong_proof.emplace_back(); EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size, old_root, new_tree_size, new_root, wrong_proof)) << "proof passed verification with empty node appended"; @@ -372,7 +372,7 @@ void CheckVerifyConsistencyProof(const CTLogVerifier& log, << "proof passed verification with last node missing"; wrong_proof.clear(); - wrong_proof.push_back(std::string()); + wrong_proof.emplace_back(); wrong_proof.insert(wrong_proof.end(), proof.begin(), proof.end()); EXPECT_FALSE(VerifyConsistencyProof(log, old_tree_size, old_root, new_tree_size, new_root, wrong_proof)) diff --git a/chromium/net/cert/ct_log_verifier_util.cc b/chromium/net/cert/ct_log_verifier_util.cc index 402fd0c59f3..0a74dac7b32 100644 --- a/chromium/net/cert/ct_log_verifier_util.cc +++ b/chromium/net/cert/ct_log_verifier_util.cc @@ -10,11 +10,7 @@ #include "crypto/secure_hash.h" #include "crypto/sha2.h" -namespace net { - -namespace ct { - -namespace internal { +namespace net::ct::internal { std::string HashNodes(const std::string& lh, const std::string& rh) { std::unique_ptr<crypto::SecureHash> hash( @@ -30,8 +26,4 @@ std::string HashNodes(const std::string& lh, const std::string& rh) { return result; } -} // namespace internal - -} // namespace ct - -} // namespace net +} // namespace net::ct::internal diff --git a/chromium/net/cert/ct_log_verifier_util.h b/chromium/net/cert/ct_log_verifier_util.h index 2e62d1a7a3d..2149e942cff 100644 --- a/chromium/net/cert/ct_log_verifier_util.h +++ b/chromium/net/cert/ct_log_verifier_util.h @@ -11,20 +11,12 @@ #include "net/base/net_export.h" -namespace net { - -namespace ct { - -namespace internal { +namespace net::ct::internal { // Hash |lh| and |rh| to produce a node hash according to // http://tools.ietf.org/html/rfc6962#section-2.1 NET_EXPORT std::string HashNodes(const std::string& lh, const std::string& rh); -} // namespace internal - -} // namespace ct - -} // namespace net +} // namespace net::ct::internal #endif // NET_CERT_CT_LOG_VERIFIER_UTIL_H_ diff --git a/chromium/net/cert/ct_objects_extractor.cc b/chromium/net/cert/ct_objects_extractor.cc index 4021ec7a524..25ccf2d2986 100644 --- a/chromium/net/cert/ct_objects_extractor.cc +++ b/chromium/net/cert/ct_objects_extractor.cc @@ -17,9 +17,7 @@ #include "third_party/boringssl/src/include/openssl/bytestring.h" #include "third_party/boringssl/src/include/openssl/mem.h" -namespace net { - -namespace ct { +namespace net::ct { namespace { @@ -425,6 +423,4 @@ bool ExtractSCTListFromOCSPResponse(const CRYPTO_BUFFER* issuer, sizeof(kOCSPExtensionOid), sct_list); } -} // namespace ct - -} // namespace net +} // namespace net::ct diff --git a/chromium/net/cert/ct_objects_extractor.h b/chromium/net/cert/ct_objects_extractor.h index e18a84a5ac5..d51ddbaf103 100644 --- a/chromium/net/cert/ct_objects_extractor.h +++ b/chromium/net/cert/ct_objects_extractor.h @@ -11,9 +11,7 @@ #include "net/base/net_export.h" #include "net/cert/x509_certificate.h" -namespace net { - -namespace ct { +namespace net::ct { struct SignedEntryData; @@ -57,8 +55,6 @@ NET_EXPORT_PRIVATE bool ExtractSCTListFromOCSPResponse( base::StringPiece ocsp_response, std::string* sct_list); -} // namespace ct - -} // namespace net +} // namespace net::ct #endif // NET_CERT_CT_OBJECTS_EXTRACTOR_H_ diff --git a/chromium/net/cert/ct_objects_extractor_unittest.cc b/chromium/net/cert/ct_objects_extractor_unittest.cc index aee5b069f83..56e42cedd19 100644 --- a/chromium/net/cert/ct_objects_extractor_unittest.cc +++ b/chromium/net/cert/ct_objects_extractor_unittest.cc @@ -14,9 +14,7 @@ #include "net/test/test_data_directory.h" #include "testing/gtest/include/gtest/gtest.h" -namespace net { - -namespace ct { +namespace net::ct { class CTObjectsExtractorTest : public ::testing::Test { public: @@ -191,6 +189,4 @@ TEST_F(CTObjectsExtractorTest, ExtractSCTListFromOCSPResponseMatchesIssuer) { &extracted_sct_list)); } -} // namespace ct - -} // namespace net +} // namespace net::ct diff --git a/chromium/net/cert/ct_policy_status.h b/chromium/net/cert/ct_policy_status.h index c67269724df..bb077c226db 100644 --- a/chromium/net/cert/ct_policy_status.h +++ b/chromium/net/cert/ct_policy_status.h @@ -5,9 +5,7 @@ #ifndef NET_CERT_CT_POLICY_STATUS_H_ #define NET_CERT_CT_POLICY_STATUS_H_ -namespace net { - -namespace ct { +namespace net::ct { // Information about the connection's compliance with the CT policy. This value // is histogrammed, so do not re-order or change values, and add new values at @@ -30,8 +28,6 @@ enum class CTPolicyCompliance { CT_POLICY_COUNT }; -} // namespace ct - -} // namespace net +} // namespace net::ct #endif // NET_CERT_CT_POLICY_STATUS_H_ diff --git a/chromium/net/cert/ct_sct_to_string.cc b/chromium/net/cert/ct_sct_to_string.cc index 211f7ea264a..43d863466ba 100644 --- a/chromium/net/cert/ct_sct_to_string.cc +++ b/chromium/net/cert/ct_sct_to_string.cc @@ -7,9 +7,7 @@ #include "base/logging.h" #include "base/notreached.h" -namespace net { - -namespace ct { +namespace net::ct { const std::string HashAlgorithmToString( DigitallySigned::HashAlgorithm hashAlgorithm) { @@ -77,6 +75,4 @@ const std::string StatusToString(SCTVerifyStatus status) { return "Unknown"; } -} // namespace ct - -} // namespace net +} // namespace net::ct diff --git a/chromium/net/cert/ct_sct_to_string.h b/chromium/net/cert/ct_sct_to_string.h index 5dc77962190..d22ecec7487 100644 --- a/chromium/net/cert/ct_sct_to_string.h +++ b/chromium/net/cert/ct_sct_to_string.h @@ -11,12 +11,10 @@ #include "net/cert/sct_status_flags.h" #include "net/cert/signed_certificate_timestamp.h" -namespace net { - // Functions for converting non-string attributes of // net::ct::SignedCertificateTimestamp and net::ct::SCTVerifyStatus values to // strings. -namespace ct { +namespace net::ct { // Returns a textual representation of |hash_algorithm|. NET_EXPORT const std::string HashAlgorithmToString( @@ -33,8 +31,6 @@ NET_EXPORT const std::string SignatureAlgorithmToString( // Returns a textual representation of |status|. NET_EXPORT const std::string StatusToString(SCTVerifyStatus status); -} // namespace ct - -} // namespace net +} // namespace net::ct #endif // NET_CERT_CT_SCT_TO_STRING_H_ diff --git a/chromium/net/cert/ct_serialization.cc b/chromium/net/cert/ct_serialization.cc index 0059979ed54..1147a3785fc 100644 --- a/chromium/net/cert/ct_serialization.cc +++ b/chromium/net/cert/ct_serialization.cc @@ -12,9 +12,7 @@ #include "net/cert/signed_tree_head.h" #include "third_party/boringssl/src/include/openssl/bytestring.h" -namespace net { - -namespace ct { +namespace net::ct { namespace { @@ -320,8 +318,7 @@ bool DecodeSCTList(base::StringPiece input, bool DecodeSignedCertificateTimestamp( base::StringPiece* input, scoped_refptr<SignedCertificateTimestamp>* output) { - scoped_refptr<SignedCertificateTimestamp> result( - new SignedCertificateTimestamp()); + auto result = base::MakeRefCounted<SignedCertificateTimestamp>(); uint8_t version; CBS input_cbs; CBS_init(&input_cbs, reinterpret_cast<const uint8_t*>(input->data()), @@ -401,6 +398,4 @@ bool EncodeSCTListForTesting(const base::StringPiece& sct, return true; } -} // namespace ct - -} // namespace net +} // namespace net::ct diff --git a/chromium/net/cert/ct_serialization.h b/chromium/net/cert/ct_serialization.h index dcfa3fca9e4..37003245209 100644 --- a/chromium/net/cert/ct_serialization.h +++ b/chromium/net/cert/ct_serialization.h @@ -13,11 +13,9 @@ #include "base/time/time.h" #include "net/base/net_export.h" -namespace net { - // Utility functions for encoding/decoding structures used by Certificate // Transparency to/from the TLS wire format encoding. -namespace ct { +namespace net::ct { struct DigitallySigned; struct MerkleTreeLeaf; @@ -97,8 +95,6 @@ NET_EXPORT bool EncodeSignedCertificateTimestamp( // Writes an SCTList into |output|, containing a single |sct|. NET_EXPORT_PRIVATE bool EncodeSCTListForTesting(const base::StringPiece& sct, std::string* output); -} // namespace ct - -} // namespace net +} // namespace net::ct #endif // NET_CERT_CT_SERIALIZATION_H_ diff --git a/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc b/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc index 1ada1a9b7a6..5721f68f589 100644 --- a/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc +++ b/chromium/net/cert/ct_signed_certificate_timestamp_log_param.cc @@ -73,11 +73,11 @@ base::Value SCTListToPrintableValues( base::Value NetLogSignedCertificateTimestampParams( const SignedCertificateTimestampAndStatusList* scts) { - base::Value dict(base::Value::Type::DICTIONARY); + base::Value::Dict dict; - dict.GetDict().Set("scts", SCTListToPrintableValues(*scts)); + dict.Set("scts", SCTListToPrintableValues(*scts)); - return dict; + return base::Value(std::move(dict)); } base::Value NetLogRawSignedCertificateTimestampParams( diff --git a/chromium/net/cert/ct_verifier.h b/chromium/net/cert/ct_verifier.h index 63c0923bc43..a0103c9e9f9 100644 --- a/chromium/net/cert/ct_verifier.h +++ b/chromium/net/cert/ct_verifier.h @@ -17,7 +17,7 @@ class X509Certificate; // Interface for verifying Signed Certificate Timestamps over a certificate. class NET_EXPORT CTVerifier { public: - virtual ~CTVerifier() {} + virtual ~CTVerifier() = default; // Verifies SCTs embedded in the certificate itself, SCTs embedded in a // stapled OCSP response, and SCTs obtained via the diff --git a/chromium/net/cert/internal/cert_issuer_source_aia.cc b/chromium/net/cert/internal/cert_issuer_source_aia.cc index d7c07c18d0c..22411efff84 100644 --- a/chromium/net/cert/internal/cert_issuer_source_aia.cc +++ b/chromium/net/cert/internal/cert_issuer_source_aia.cc @@ -8,8 +8,8 @@ #include "base/logging.h" #include "base/strings/string_piece.h" #include "net/cert/cert_net_fetcher.h" -#include "net/cert/internal/cert_errors.h" #include "net/cert/pem.h" +#include "net/cert/pki/cert_errors.h" #include "net/cert/x509_util.h" #include "url/gurl.h" @@ -195,7 +195,7 @@ void CertIssuerSourceAia::AsyncGetIssuersOf(const ParsedCertificate* cert, if (urls.empty()) return; - std::unique_ptr<AiaRequest> aia_request(new AiaRequest()); + auto aia_request = std::make_unique<AiaRequest>(); for (const auto& url : urls) { // TODO(mattm): add synchronous failure mode to FetchCaIssuers interface so diff --git a/chromium/net/cert/internal/cert_issuer_source_aia.h b/chromium/net/cert/internal/cert_issuer_source_aia.h index 1503d435de1..4247bc50a73 100644 --- a/chromium/net/cert/internal/cert_issuer_source_aia.h +++ b/chromium/net/cert/internal/cert_issuer_source_aia.h @@ -7,7 +7,7 @@ #include "base/strings/string_piece.h" #include "net/base/net_export.h" -#include "net/cert/internal/cert_issuer_source.h" +#include "net/cert/pki/cert_issuer_source.h" namespace net { diff --git a/chromium/net/cert/internal/cert_issuer_source_aia_unittest.cc b/chromium/net/cert/internal/cert_issuer_source_aia_unittest.cc index 67d7eeeebb5..344ad413f84 100644 --- a/chromium/net/cert/internal/cert_issuer_source_aia_unittest.cc +++ b/chromium/net/cert/internal/cert_issuer_source_aia_unittest.cc @@ -7,10 +7,10 @@ #include <memory> #include "base/files/file_util.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/test_helpers.h" #include "net/cert/mock_cert_net_fetcher.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/test_helpers.h" #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" #include "net/test/test_data_directory.h" @@ -194,8 +194,7 @@ TEST(CertIssuerSourceAiaTest, OneInvalidOneHttpAia) { scoped_refptr<ParsedCertificate> intermediate_cert; ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert)); - scoped_refptr<StrictMock<MockCertNetFetcher>> mock_fetcher( - new StrictMock<MockCertNetFetcher>()); + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); EXPECT_CALL(*mock_fetcher, FetchCaIssuers(GURL("http://url-for-aia2/I2.foo"), _, _)) @@ -229,8 +228,7 @@ TEST(CertIssuerSourceAiaTest, TwoAiaCompletedInSeries) { scoped_refptr<ParsedCertificate> intermediate_cert2; ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert2)); - scoped_refptr<StrictMock<MockCertNetFetcher>> mock_fetcher( - new StrictMock<MockCertNetFetcher>()); + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); EXPECT_CALL(*mock_fetcher, FetchCaIssuers(GURL("http://url-for-aia/I.cer"), _, _)) @@ -271,8 +269,7 @@ TEST(CertIssuerSourceAiaTest, OneAiaHttpError) { scoped_refptr<ParsedCertificate> cert; ASSERT_TRUE(ReadTestCert("target_one_aia.pem", &cert)); - scoped_refptr<StrictMock<MockCertNetFetcher>> mock_fetcher( - new StrictMock<MockCertNetFetcher>()); + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); // HTTP request returns with an error. EXPECT_CALL(*mock_fetcher, @@ -296,8 +293,7 @@ TEST(CertIssuerSourceAiaTest, OneAiaParseError) { scoped_refptr<ParsedCertificate> cert; ASSERT_TRUE(ReadTestCert("target_one_aia.pem", &cert)); - scoped_refptr<StrictMock<MockCertNetFetcher>> mock_fetcher( - new StrictMock<MockCertNetFetcher>()); + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); // HTTP request returns invalid certificate data. EXPECT_CALL(*mock_fetcher, @@ -324,8 +320,7 @@ TEST(CertIssuerSourceAiaTest, TwoAiaCompletedInSeriesFirstFails) { scoped_refptr<ParsedCertificate> intermediate_cert2; ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert2)); - scoped_refptr<StrictMock<MockCertNetFetcher>> mock_fetcher( - new StrictMock<MockCertNetFetcher>()); + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); // Request for I.cer completes first, but fails. EXPECT_CALL(*mock_fetcher, @@ -364,8 +359,7 @@ TEST(CertIssuerSourceAiaTest, TwoAiaCompletedInSeriesSecondFails) { scoped_refptr<ParsedCertificate> intermediate_cert; ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert)); - scoped_refptr<StrictMock<MockCertNetFetcher>> mock_fetcher( - new StrictMock<MockCertNetFetcher>()); + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); // Request for I.cer completes first. EXPECT_CALL(*mock_fetcher, @@ -402,8 +396,7 @@ TEST(CertIssuerSourceAiaTest, MaxFetchesPerCert) { scoped_refptr<ParsedCertificate> cert; ASSERT_TRUE(ReadTestCert("target_six_aia.pem", &cert)); - scoped_refptr<StrictMock<MockCertNetFetcher>> mock_fetcher( - new StrictMock<MockCertNetFetcher>()); + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); std::vector<uint8_t> bad_der({1, 2, 3, 4, 5}); diff --git a/chromium/net/cert/internal/cert_issuer_source_sync_unittest.cc b/chromium/net/cert/internal/cert_issuer_source_sync_unittest.cc index 94ee55c6685..da758ca71d9 100644 --- a/chromium/net/cert/internal/cert_issuer_source_sync_unittest.cc +++ b/chromium/net/cert/internal/cert_issuer_source_sync_unittest.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/cert_issuer_source_sync_unittest.h" +#include "net/cert/pki/cert_issuer_source_sync_unittest.h" namespace net { diff --git a/chromium/net/cert/internal/crl_getcrlstatusforcert_fuzzer.cc b/chromium/net/cert/internal/crl_getcrlstatusforcert_fuzzer.cc index 56bb3bf05ad..06a1321bfdd 100644 --- a/chromium/net/cert/internal/crl_getcrlstatusforcert_fuzzer.cc +++ b/chromium/net/cert/internal/crl_getcrlstatusforcert_fuzzer.cc @@ -6,7 +6,7 @@ #include <stdint.h> #include "crypto/sha2.h" -#include "net/cert/internal/crl.h" +#include "net/cert/pki/crl.h" #include "net/der/input.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { diff --git a/chromium/net/cert/internal/crl_parse_crl_certificatelist_fuzzer.cc b/chromium/net/cert/internal/crl_parse_crl_certificatelist_fuzzer.cc index e8f0724516e..b90164de4b3 100644 --- a/chromium/net/cert/internal/crl_parse_crl_certificatelist_fuzzer.cc +++ b/chromium/net/cert/internal/crl_parse_crl_certificatelist_fuzzer.cc @@ -7,7 +7,7 @@ #include <tuple> -#include "net/cert/internal/crl.h" +#include "net/cert/pki/crl.h" #include "net/der/input.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { diff --git a/chromium/net/cert/internal/crl_parse_crl_tbscertlist_fuzzer.cc b/chromium/net/cert/internal/crl_parse_crl_tbscertlist_fuzzer.cc index df64f7b8703..4a82b035e43 100644 --- a/chromium/net/cert/internal/crl_parse_crl_tbscertlist_fuzzer.cc +++ b/chromium/net/cert/internal/crl_parse_crl_tbscertlist_fuzzer.cc @@ -7,7 +7,7 @@ #include <tuple> -#include "net/cert/internal/crl.h" +#include "net/cert/pki/crl.h" #include "net/der/input.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { diff --git a/chromium/net/cert/internal/crl_parse_issuing_distribution_point_fuzzer.cc b/chromium/net/cert/internal/crl_parse_issuing_distribution_point_fuzzer.cc index 24bce9866f8..e4aaeb00308 100644 --- a/chromium/net/cert/internal/crl_parse_issuing_distribution_point_fuzzer.cc +++ b/chromium/net/cert/internal/crl_parse_issuing_distribution_point_fuzzer.cc @@ -5,7 +5,7 @@ #include <stddef.h> #include <stdint.h> -#include "net/cert/internal/crl.h" +#include "net/cert/pki/crl.h" #include "net/der/input.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { diff --git a/chromium/net/cert/internal/crl_unittest.cc b/chromium/net/cert/internal/crl_unittest.cc index c80de5708eb..b1f9ee7ca98 100644 --- a/chromium/net/cert/internal/crl_unittest.cc +++ b/chromium/net/cert/internal/crl_unittest.cc @@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/crl.h" +#include "net/cert/pki/crl.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/test_helpers.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/test_helpers.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/boringssl/src/include/openssl/pool.h" diff --git a/chromium/net/cert/internal/general_names_unittest.cc b/chromium/net/cert/internal/general_names_unittest.cc index 41cf5ba249f..927b4f574c5 100644 --- a/chromium/net/cert/internal/general_names_unittest.cc +++ b/chromium/net/cert/internal/general_names_unittest.cc @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/general_names.h" +#include "net/cert/pki/general_names.h" #include "base/strings/string_util.h" -#include "net/cert/internal/test_helpers.h" +#include "net/cert/pki/test_helpers.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { diff --git a/chromium/net/cert/internal/parse_authority_key_identifier_fuzzer.cc b/chromium/net/cert/internal/parse_authority_key_identifier_fuzzer.cc index 8448bb29c4a..e3deecab6e1 100644 --- a/chromium/net/cert/internal/parse_authority_key_identifier_fuzzer.cc +++ b/chromium/net/cert/internal/parse_authority_key_identifier_fuzzer.cc @@ -7,7 +7,7 @@ #include <tuple> -#include "net/cert/internal/parse_certificate.h" +#include "net/cert/pki/parse_certificate.h" #include "net/der/input.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { diff --git a/chromium/net/cert/internal/revocation_checker.cc b/chromium/net/cert/internal/revocation_checker.cc index 9d215ee47a9..174c2287c2f 100644 --- a/chromium/net/cert/internal/revocation_checker.cc +++ b/chromium/net/cert/internal/revocation_checker.cc @@ -10,12 +10,12 @@ #include "base/strings/string_piece.h" #include "crypto/sha2.h" #include "net/cert/cert_net_fetcher.h" -#include "net/cert/internal/common_cert_errors.h" -#include "net/cert/internal/crl.h" -#include "net/cert/internal/ocsp.h" -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/trust_store.h" #include "net/cert/ocsp_verify_result.h" +#include "net/cert/pki/common_cert_errors.h" +#include "net/cert/pki/crl.h" +#include "net/cert/pki/ocsp.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/trust_store.h" #include "url/gurl.h" namespace net { @@ -154,7 +154,8 @@ bool CheckCertRevocation(const ParsedCertificateList& certs, // Check CRLs. ParsedExtension crl_dp_extension; - if (cert->GetExtension(der::Input(kCrlDistributionPointsOid), + if (policy.crl_allowed && + cert->GetExtension(der::Input(kCrlDistributionPointsOid), &crl_dp_extension)) { std::vector<ParsedDistributionPoint> distribution_points; if (ParseCrlDistributionPoints(crl_dp_extension.value, diff --git a/chromium/net/cert/internal/revocation_checker.h b/chromium/net/cert/internal/revocation_checker.h index 6da6b17008b..78ae5aa9a68 100644 --- a/chromium/net/cert/internal/revocation_checker.h +++ b/chromium/net/cert/internal/revocation_checker.h @@ -9,7 +9,7 @@ #include "base/time/time.h" #include "net/base/net_export.h" #include "net/cert/crl_set.h" -#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/pki/parsed_certificate.h" namespace net { @@ -73,6 +73,10 @@ struct NET_EXPORT_PRIVATE RevocationPolicy { // networking is not permitted in the course of revocation checking. bool networking_allowed : 1; + // If |crl_allowed| is true then CRLs will be checked as a fallback when an + // OCSP URL is not present or OCSP results are indeterminate. + bool crl_allowed : 1; + // If set to true, considers certificates lacking URLs for OCSP/CRL to be // unrevoked. Otherwise will fail for certificates lacking revocation // mechanisms. diff --git a/chromium/net/cert/internal/revocation_checker_unittest.cc b/chromium/net/cert/internal/revocation_checker_unittest.cc index 5cbeaa32cdc..1ad965057da 100644 --- a/chromium/net/cert/internal/revocation_checker_unittest.cc +++ b/chromium/net/cert/internal/revocation_checker_unittest.cc @@ -5,11 +5,11 @@ #include "net/cert/internal/revocation_checker.h" #include "base/time/time.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/common_cert_errors.h" -#include "net/cert/internal/parse_certificate.h" -#include "net/cert/internal/parsed_certificate.h" #include "net/cert/mock_cert_net_fetcher.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/common_cert_errors.h" +#include "net/cert/pki/parse_certificate.h" +#include "net/cert/pki/parsed_certificate.h" #include "net/test/cert_builder.h" #include "net/test/revocation_builder.h" #include "testing/gmock/include/gmock/gmock.h" @@ -47,6 +47,7 @@ TEST(RevocationChecker, NoRevocationMechanism) { RevocationPolicy policy; policy.check_revocation = true; policy.networking_allowed = true; + policy.crl_allowed = true; policy.allow_unable_to_check = false; { @@ -119,12 +120,13 @@ TEST(RevocationChecker, ValidCRL) { std::string crl_data_as_string_for_some_reason = BuildCrl(root->GetSubject(), root->GetKey(), - /*revoked_serials=*/{}, DigestAlgorithm::Sha256); + /*revoked_serials=*/{}); std::vector<uint8_t> crl_data(crl_data_as_string_for_some_reason.begin(), crl_data_as_string_for_some_reason.end()); { policy.networking_allowed = true; + policy.crl_allowed = true; auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); EXPECT_CALL(*mock_fetcher, FetchCrl(kTestCrlUrl, _, _)) @@ -141,6 +143,7 @@ TEST(RevocationChecker, ValidCRL) { { policy.networking_allowed = false; + policy.crl_allowed = true; // No methods on |mock_fetcher| should be called. auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); @@ -154,6 +157,25 @@ TEST(RevocationChecker, ValidCRL) { EXPECT_TRUE(errors.ContainsHighSeverityErrors()); EXPECT_TRUE(errors.ContainsError(cert_errors::kUnableToCheckRevocation)); } + + { + policy.networking_allowed = true; + policy.crl_allowed = false; + + // No methods on |mock_fetcher| should be called. + auto mock_fetcher = base::MakeRefCounted<StrictMock<MockCertNetFetcher>>(); + + CertPathErrors errors; + CheckValidatedChainRevocation( + chain, policy, /*deadline=*/base::TimeTicks(), + /*stapled_leaf_ocsp_response=*/base::StringPiece(), mock_fetcher.get(), + &errors, /*stapled_ocsp_verify_result=*/nullptr); + + EXPECT_TRUE(errors.ContainsHighSeverityErrors()); + // Since CRLs were not considered, the error should be "no revocation + // mechanism". + EXPECT_TRUE(errors.ContainsError(cert_errors::kNoRevocationMechanism)); + } } TEST(RevocationChecker, RevokedCRL) { @@ -169,10 +191,11 @@ TEST(RevocationChecker, RevokedCRL) { RevocationPolicy policy; policy.check_revocation = true; policy.networking_allowed = true; + policy.crl_allowed = true; - std::string crl_data_as_string_for_some_reason = BuildCrl( - root->GetSubject(), root->GetKey(), - /*revoked_serials=*/{leaf->GetSerialNumber()}, DigestAlgorithm::Sha256); + std::string crl_data_as_string_for_some_reason = + BuildCrl(root->GetSubject(), root->GetKey(), + /*revoked_serials=*/{leaf->GetSerialNumber()}); std::vector<uint8_t> crl_data(crl_data_as_string_for_some_reason.begin(), crl_data_as_string_for_some_reason.end()); @@ -228,6 +251,7 @@ TEST(RevocationChecker, CRLRequestFails) { RevocationPolicy policy; policy.check_revocation = true; policy.networking_allowed = true; + policy.crl_allowed = true; { policy.allow_unable_to_check = false; @@ -299,6 +323,7 @@ TEST(RevocationChecker, CRLNonHttpUrl) { RevocationPolicy policy; policy.check_revocation = true; policy.networking_allowed = true; + policy.crl_allowed = true; policy.allow_unable_to_check = false; policy.allow_missing_info = false; @@ -359,12 +384,13 @@ TEST(RevocationChecker, SkipEntireInvalidCRLDistributionPoints) { RevocationPolicy policy; policy.check_revocation = true; policy.networking_allowed = true; + policy.crl_allowed = true; policy.allow_unable_to_check = false; policy.allow_missing_info = false; std::string crl_data_as_string_for_some_reason = BuildCrl(root->GetSubject(), root->GetKey(), - /*revoked_serials=*/{}, DigestAlgorithm::Sha256); + /*revoked_serials=*/{}); std::vector<uint8_t> crl_data(crl_data_as_string_for_some_reason.begin(), crl_data_as_string_for_some_reason.end()); @@ -444,12 +470,13 @@ TEST(RevocationChecker, SkipUnsupportedCRLDistPointWithNonUriFullname) { RevocationPolicy policy; policy.check_revocation = true; policy.networking_allowed = true; + policy.crl_allowed = true; policy.allow_unable_to_check = false; policy.allow_missing_info = false; std::string crl_data_as_string_for_some_reason = BuildCrl(root->GetSubject(), root->GetKey(), - /*revoked_serials=*/{}, DigestAlgorithm::Sha256); + /*revoked_serials=*/{}); std::vector<uint8_t> crl_data(crl_data_as_string_for_some_reason.begin(), crl_data_as_string_for_some_reason.end()); @@ -513,12 +540,13 @@ TEST(RevocationChecker, SkipUnsupportedCRLDistPointWithReasons) { RevocationPolicy policy; policy.check_revocation = true; policy.networking_allowed = true; + policy.crl_allowed = true; policy.allow_unable_to_check = false; policy.allow_missing_info = false; std::string crl_data_as_string_for_some_reason = BuildCrl(root->GetSubject(), root->GetKey(), - /*revoked_serials=*/{}, DigestAlgorithm::Sha256); + /*revoked_serials=*/{}); std::vector<uint8_t> crl_data(crl_data_as_string_for_some_reason.begin(), crl_data_as_string_for_some_reason.end()); @@ -614,12 +642,13 @@ TEST(RevocationChecker, SkipUnsupportedCRLDistPointWithCrlIssuer) { RevocationPolicy policy; policy.check_revocation = true; policy.networking_allowed = true; + policy.crl_allowed = true; policy.allow_unable_to_check = false; policy.allow_missing_info = false; std::string crl_data_as_string_for_some_reason = BuildCrl(root->GetSubject(), root->GetKey(), - /*revoked_serials=*/{}, DigestAlgorithm::Sha256); + /*revoked_serials=*/{}); std::vector<uint8_t> crl_data(crl_data_as_string_for_some_reason.begin(), crl_data_as_string_for_some_reason.end()); diff --git a/chromium/net/cert/internal/revocation_util_unittest.cc b/chromium/net/cert/internal/revocation_util_unittest.cc index ead9c9a70b1..fd1b0389748 100644 --- a/chromium/net/cert/internal/revocation_util_unittest.cc +++ b/chromium/net/cert/internal/revocation_util_unittest.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/revocation_util.h" +#include "net/cert/pki/revocation_util.h" #include "base/time/time.h" #include "net/der/encode_values.h" diff --git a/chromium/net/cert/internal/signature_algorithm.h b/chromium/net/cert/internal/signature_algorithm.h deleted file mode 100644 index 6d209ff2a23..00000000000 --- a/chromium/net/cert/internal/signature_algorithm.h +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_CERT_INTERNAL_SIGNATURE_ALGORITHM_H_ -#define NET_CERT_INTERNAL_SIGNATURE_ALGORITHM_H_ - -#include <stdint.h> - -#include <memory> - -#include "net/base/net_export.h" - -namespace net { - -class CertErrors; - -namespace der { -class Input; -} // namespace der - -// The digest algorithm used within a signature. -enum class DigestAlgorithm { - Md2, - Md4, - Md5, - Sha1, - Sha256, - Sha384, - Sha512, -}; - -// The signature scheme used within a signature. Parameters are specified -// separately. -enum class SignatureAlgorithmId { - RsaPkcs1, // RSA PKCS#1 v1.5 - RsaPss, // RSASSA-PSS - Ecdsa, // ECDSA - Dsa, // DSA -}; - -// Parses AlgorithmIdentifier as defined by RFC 5280 section 4.1.1.2: -// -// AlgorithmIdentifier ::= SEQUENCE { -// algorithm OBJECT IDENTIFIER, -// parameters ANY DEFINED BY algorithm OPTIONAL } -[[nodiscard]] NET_EXPORT bool ParseAlgorithmIdentifier(const der::Input& input, - der::Input* algorithm, - der::Input* parameters); - -// Parses a HashAlgorithm as defined by RFC 5912: -// -// HashAlgorithm ::= AlgorithmIdentifier{DIGEST-ALGORITHM, -// {HashAlgorithms}} -// -// HashAlgorithms DIGEST-ALGORITHM ::= { -// { IDENTIFIER id-sha1 PARAMS TYPE NULL ARE preferredPresent } | -// { IDENTIFIER id-sha224 PARAMS TYPE NULL ARE preferredPresent } | -// { IDENTIFIER id-sha256 PARAMS TYPE NULL ARE preferredPresent } | -// { IDENTIFIER id-sha384 PARAMS TYPE NULL ARE preferredPresent } | -// { IDENTIFIER id-sha512 PARAMS TYPE NULL ARE preferredPresent } -// } -[[nodiscard]] bool ParseHashAlgorithm(const der::Input& input, - DigestAlgorithm* out); - -// Base class for describing algorithm parameters. -class NET_EXPORT SignatureAlgorithmParameters { - public: - SignatureAlgorithmParameters() {} - - SignatureAlgorithmParameters(const SignatureAlgorithmParameters&) = delete; - SignatureAlgorithmParameters& operator=(const SignatureAlgorithmParameters&) = - delete; - - virtual ~SignatureAlgorithmParameters() {} -}; - -// Parameters for an RSASSA-PSS signature algorithm. -// -// The trailer is assumed to be 1 and the mask generation algorithm to be MGF1, -// as that is all that is implemented, and any other values while parsing the -// AlgorithmIdentifier will thus be rejected. -class NET_EXPORT RsaPssParameters : public SignatureAlgorithmParameters { - public: - RsaPssParameters(DigestAlgorithm mgf1_hash, uint32_t salt_length); - - DigestAlgorithm mgf1_hash() const { return mgf1_hash_; } - uint32_t salt_length() const { return salt_length_; } - - private: - const DigestAlgorithm mgf1_hash_; - const uint32_t salt_length_; -}; - -// SignatureAlgorithm describes a signature algorithm and its parameters. This -// corresponds to "AlgorithmIdentifier" from RFC 5280. -// -// TODO(crbug.com/1321691): Replace this with a simple enum. -class NET_EXPORT SignatureAlgorithm { - public: - SignatureAlgorithm(const SignatureAlgorithm&) = delete; - SignatureAlgorithm& operator=(const SignatureAlgorithm&) = delete; - - ~SignatureAlgorithm(); - - SignatureAlgorithmId algorithm() const { return algorithm_; } - DigestAlgorithm digest() const { return digest_; } - - // Creates a SignatureAlgorithm by parsing a DER-encoded "AlgorithmIdentifier" - // (RFC 5280). Returns nullptr on failure. If |errors| was non-null then - // error/warning information is output to it. - static std::unique_ptr<SignatureAlgorithm> Create( - const der::Input& algorithm_identifier, - CertErrors* errors); - - // Creates a new SignatureAlgorithm with the given type and parameters. - // Guaranteed to return non-null result. - static std::unique_ptr<SignatureAlgorithm> CreateRsaPkcs1( - DigestAlgorithm digest); - static std::unique_ptr<SignatureAlgorithm> CreateDsa(DigestAlgorithm digest); - static std::unique_ptr<SignatureAlgorithm> CreateEcdsa( - DigestAlgorithm digest); - static std::unique_ptr<SignatureAlgorithm> CreateRsaPss( - DigestAlgorithm digest, - DigestAlgorithm mgf1_hash, - uint32_t salt_length); - - // The following methods retrieve the parameters for the signature algorithm. - // - // The correct parameters should be chosen based on the algorithm ID. For - // instance a SignatureAlgorithm with |algorithm() == RsaPss| should retrieve - // parameters via ParametersForRsaPss(). - // - // The returned pointer is non-owned, and has the same lifetime as |this|. - const RsaPssParameters* ParamsForRsaPss() const; - - bool has_params() const { return !!params_; } - - // Returns true if |alg1_tlv| and |alg2_tlv| represent an equivalent - // AlgorithmIdentifier once parsed. - static bool IsEquivalent(const der::Input& alg1_tlv, - const der::Input& alg2_tlv); - - private: - SignatureAlgorithm(SignatureAlgorithmId algorithm, - DigestAlgorithm digest, - std::unique_ptr<SignatureAlgorithmParameters> params); - - const SignatureAlgorithmId algorithm_; - const DigestAlgorithm digest_; - const std::unique_ptr<SignatureAlgorithmParameters> params_; -}; - -} // namespace net - -#endif // NET_CERT_INTERNAL_SIGNATURE_ALGORITHM_H_ diff --git a/chromium/net/cert/internal/system_trust_store.cc b/chromium/net/cert/internal/system_trust_store.cc index c5ba97fb5b0..fc21d3633a2 100644 --- a/chromium/net/cert/internal/system_trust_store.cc +++ b/chromium/net/cert/internal/system_trust_store.cc @@ -4,6 +4,7 @@ #include "net/cert/internal/system_trust_store.h" +#include "base/memory/ptr_util.h" #include "build/build_config.h" #include "crypto/crypto_buildflags.h" @@ -27,10 +28,10 @@ #include "base/task/task_traits.h" #include "base/task/thread_pool.h" #include "build/build_config.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/trust_store_collection.h" -#include "net/cert/internal/trust_store_in_memory.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/trust_store_collection.h" +#include "net/cert/pki/trust_store_in_memory.h" #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" @@ -78,15 +79,18 @@ class DummySystemTrustStore : public SystemTrustStore { } // namespace #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) -class SystemTrustStoreChrome : public SystemTrustStore { +class SystemTrustStoreChromeWithUnOwnedSystemStore : public SystemTrustStore { public: - explicit SystemTrustStoreChrome( + // Creates a SystemTrustStore that gets publicly trusted roots from + // |trust_store_chrome| and local trust settings from |trust_store_system|. + // Does not take ownership of |trust_store_system|, which must outlive this + // object. + explicit SystemTrustStoreChromeWithUnOwnedSystemStore( std::unique_ptr<TrustStoreChrome> trust_store_chrome, - std::unique_ptr<TrustStore> trust_store_system) - : trust_store_chrome_(std::move(trust_store_chrome)), - trust_store_system_(std::move(trust_store_system)) { + TrustStore* trust_store_system) + : trust_store_chrome_(std::move(trust_store_chrome)) { trust_store_collection_.AddTrustStore(trust_store_chrome_.get()); - trust_store_collection_.AddTrustStore(trust_store_system_.get()); + trust_store_collection_.AddTrustStore(trust_store_system); } TrustStore* GetTrustStore() override { return &trust_store_collection_; } @@ -105,17 +109,32 @@ class SystemTrustStoreChrome : public SystemTrustStore { private: std::unique_ptr<TrustStoreChrome> trust_store_chrome_; - std::unique_ptr<TrustStore> trust_store_system_; TrustStoreCollection trust_store_collection_; }; +class SystemTrustStoreChrome + : public SystemTrustStoreChromeWithUnOwnedSystemStore { + public: + // Creates a SystemTrustStore that gets publicly trusted roots from + // |trust_store_chrome| and local trust settings from |trust_store_system|. + explicit SystemTrustStoreChrome( + std::unique_ptr<TrustStoreChrome> trust_store_chrome, + std::unique_ptr<TrustStore> trust_store_system) + : SystemTrustStoreChromeWithUnOwnedSystemStore( + std::move(trust_store_chrome), + trust_store_system.get()), + trust_store_system_(std::move(trust_store_system)) {} + + private: + std::unique_ptr<TrustStore> trust_store_system_; +}; + std::unique_ptr<SystemTrustStore> CreateSystemTrustStoreChromeForTesting( std::unique_ptr<TrustStoreChrome> trust_store_chrome, std::unique_ptr<TrustStore> trust_store_system) { return std::make_unique<SystemTrustStoreChrome>( std::move(trust_store_chrome), std::move(trust_store_system)); } - #endif // CHROME_ROOT_STORE_SUPPORTED #if BUILDFLAG(USE_NSS_CERTS) @@ -163,35 +182,100 @@ class SystemTrustStoreNSS : public SystemTrustStore { } // namespace std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() { - return std::make_unique<SystemTrustStoreNSS>( - std::make_unique<TrustStoreNSS>(trustSSL)); + return std::make_unique<SystemTrustStoreNSS>(std::make_unique<TrustStoreNSS>( + trustSSL, TrustStoreNSS::kUseSystemTrust, + TrustStoreNSS::UseTrustFromAllUserSlots())); } #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot( std::unique_ptr<TrustStoreChrome> chrome_root) { return std::make_unique<SystemTrustStoreChrome>( - std::move(chrome_root), - std::make_unique<TrustStoreNSS>( - trustSSL, TrustStoreNSS::IgnoreSystemTrustSettings())); + std::move(chrome_root), std::make_unique<TrustStoreNSS>( + trustSSL, TrustStoreNSS::kIgnoreSystemTrust, + TrustStoreNSS::UseTrustFromAllUserSlots())); +} + +std::unique_ptr<SystemTrustStore> +CreateSslSystemTrustStoreChromeRootWithUserSlotRestriction( + std::unique_ptr<TrustStoreChrome> chrome_root, + crypto::ScopedPK11Slot user_slot_restriction) { + return std::make_unique<SystemTrustStoreChrome>( + std::move(chrome_root), std::make_unique<TrustStoreNSS>( + trustSSL, TrustStoreNSS::kIgnoreSystemTrust, + std::move(user_slot_restriction))); } #endif // CHROME_ROOT_STORE_SUPPORTED std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreNSSWithUserSlotRestriction( - crypto::ScopedPK11Slot user_slot) { + crypto::ScopedPK11Slot user_slot_restriction) { return std::make_unique<SystemTrustStoreNSS>( - std::make_unique<TrustStoreNSS>(trustSSL, std::move(user_slot))); + std::make_unique<TrustStoreNSS>(trustSSL, TrustStoreNSS::kUseSystemTrust, + std::move(user_slot_restriction))); } -std::unique_ptr<SystemTrustStore> -CreateSslSystemTrustStoreNSSWithNoUserSlots() { - return std::make_unique<SystemTrustStoreNSS>(std::make_unique<TrustStoreNSS>( - trustSSL, TrustStoreNSS::DisallowTrustForCertsOnUserSlots())); +#elif BUILDFLAG(IS_MAC) + +namespace { + +TrustStoreMac::TrustImplType ParamToTrustImplType( + int param, + TrustStoreMac::TrustImplType default_impl) { + // These values are used in experiment configs, do not change or reuse the + // numbers. + switch (param) { + case 1: + return TrustStoreMac::TrustImplType::kDomainCache; + case 2: + return TrustStoreMac::TrustImplType::kSimple; + case 3: + return TrustStoreMac::TrustImplType::kLruCache; + case 4: + return TrustStoreMac::TrustImplType::kDomainCacheFullCerts; + default: + return default_impl; + } } -#elif BUILDFLAG(IS_MAC) +TrustStoreMac::TrustImplType GetTrustStoreImplParam( + TrustStoreMac::TrustImplType default_impl) { + // TODO(https://crbug.com/1327433): A limitation of this approach is that if + // the primary verifier is being set to use the builtin verifier via a + // feature flag, it isn't possible to run dual verifier trial comparing that + // to the builtin verifier with different flags, since this method can't tell + // which flags to use for which verifier. + // If handling that becomes necessary, the flags should be checked in the + // higher level code (maybe in cert_verifier_creation.cc) so that each + // type of CertVerifyProc could be created with the appropriate flags. + if (base::FeatureList::IsEnabled(features::kCertVerifierBuiltinFeature)) { + return ParamToTrustImplType(features::kCertVerifierBuiltinImpl.Get(), + default_impl); + } + if (base::FeatureList::IsEnabled( + features::kCertDualVerificationTrialFeature)) { + return ParamToTrustImplType(features::kCertDualVerificationTrialImpl.Get(), + default_impl); + } + return default_impl; +} + +size_t GetTrustStoreCacheSize() { + if (base::FeatureList::IsEnabled(features::kCertVerifierBuiltinFeature) && + features::kCertVerifierBuiltinCacheSize.Get() > 0) { + return features::kCertVerifierBuiltinCacheSize.Get(); + } + if (base::FeatureList::IsEnabled( + features::kCertDualVerificationTrialFeature) && + features::kCertDualVerificationTrialCacheSize.Get() > 0) { + return features::kCertDualVerificationTrialCacheSize.Get(); + } + constexpr size_t kDefaultCacheSize = 512; + return kDefaultCacheSize; +} + +} // namespace class SystemTrustStoreMac : public SystemTrustStore { public: @@ -211,50 +295,18 @@ class SystemTrustStoreMac : public SystemTrustStore { GetGlobalTrustStoreMac()->InitializeTrustCache(); } +#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) + int64_t chrome_root_store_version() override { return 0; } +#endif + private: static constexpr TrustStoreMac::TrustImplType kDefaultTrustImpl = TrustStoreMac::TrustImplType::kLruCache; - static TrustStoreMac::TrustImplType ParamToTrustImplType(int param) { - switch (param) { - case 1: - return TrustStoreMac::TrustImplType::kDomainCache; - case 2: - return TrustStoreMac::TrustImplType::kSimple; - case 3: - return TrustStoreMac::TrustImplType::kLruCache; - default: - return kDefaultTrustImpl; - } - } - - static TrustStoreMac::TrustImplType GetTrustStoreImplParam() { - if (base::FeatureList::IsEnabled(features::kCertVerifierBuiltinFeature)) - return ParamToTrustImplType(features::kCertVerifierBuiltinImpl.Get()); - if (base::FeatureList::IsEnabled( - features::kCertDualVerificationTrialFeature)) - return ParamToTrustImplType( - features::kCertDualVerificationTrialImpl.Get()); - return kDefaultTrustImpl; - } - - static size_t GetTrustStoreCacheSize() { - if (base::FeatureList::IsEnabled(features::kCertVerifierBuiltinFeature) && - features::kCertVerifierBuiltinCacheSize.Get() > 0) { - return features::kCertVerifierBuiltinCacheSize.Get(); - } - if (base::FeatureList::IsEnabled( - features::kCertDualVerificationTrialFeature) && - features::kCertDualVerificationTrialCacheSize.Get() > 0) { - return features::kCertDualVerificationTrialCacheSize.Get(); - } - constexpr size_t kDefaultCacheSize = 512; - return kDefaultCacheSize; - } - static TrustStoreMac* GetGlobalTrustStoreMac() { static base::NoDestructor<TrustStoreMac> static_trust_store_mac( - kSecPolicyAppleSSL, GetTrustStoreImplParam(), GetTrustStoreCacheSize()); + kSecPolicyAppleSSL, GetTrustStoreImplParam(kDefaultTrustImpl), + GetTrustStoreCacheSize(), TrustStoreMac::TrustDomains::kAll); return static_trust_store_mac.get(); } }; @@ -263,11 +315,50 @@ std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() { return std::make_unique<SystemTrustStoreMac>(); } +#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) +namespace { + +TrustStoreMac* GetGlobalTrustStoreMacForCRS() { + constexpr TrustStoreMac::TrustImplType kDefaultMacTrustImplForCRS = + TrustStoreMac::TrustImplType::kDomainCacheFullCerts; + static base::NoDestructor<TrustStoreMac> static_trust_store_mac( + kSecPolicyAppleSSL, GetTrustStoreImplParam(kDefaultMacTrustImplForCRS), + GetTrustStoreCacheSize(), TrustStoreMac::TrustDomains::kUserAndAdmin); + return static_trust_store_mac.get(); +} + +void InitializeTrustCacheForCRSOnWorkerThread() { + GetGlobalTrustStoreMacForCRS()->InitializeTrustCache(); +} + +} // namespace + +std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot( + std::unique_ptr<TrustStoreChrome> chrome_root) { + return std::make_unique<SystemTrustStoreChromeWithUnOwnedSystemStore>( + std::move(chrome_root), GetGlobalTrustStoreMacForCRS()); +} +#endif // CHROME_ROOT_STORE_SUPPORTED + void InitializeTrustStoreMacCache() { - base::ThreadPool::PostTask( - FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - base::BindOnce(&SystemTrustStoreMac::InitializeTrustCacheOnWorkerThread)); +#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) + if (base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed)) { + base::ThreadPool::PostTask( + FROM_HERE, + {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::BindOnce(&InitializeTrustCacheForCRSOnWorkerThread)); + return; + } +#endif // CHROME_ROOT_STORE_SUPPORTED + if (base::FeatureList::IsEnabled( + net::features::kCertVerifierBuiltinFeature)) { + base::ThreadPool::PostTask( + FROM_HERE, + {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + base::BindOnce( + &SystemTrustStoreMac::InitializeTrustCacheOnWorkerThread)); + return; + } } #elif BUILDFLAG(IS_FUCHSIA) diff --git a/chromium/net/cert/internal/system_trust_store.h b/chromium/net/cert/internal/system_trust_store.h index 9cbf4da0289..9a965013ffe 100644 --- a/chromium/net/cert/internal/system_trust_store.h +++ b/chromium/net/cert/internal/system_trust_store.h @@ -10,7 +10,7 @@ #include "base/memory/ref_counted.h" #include "build/build_config.h" #include "net/base/net_export.h" -#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/pki/parsed_certificate.h" #include "net/net_buildflags.h" namespace net { @@ -99,7 +99,8 @@ CreateSystemTrustStoreChromeForTesting( NET_EXPORT std::unique_ptr<SystemTrustStore> CreateEmptySystemTrustStore(); #if BUILDFLAG(IS_MAC) -// Initializes trust cache on a worker thread. +// Initializes trust cache on a worker thread, if the builtin verifier is +// enabled. NET_EXPORT void InitializeTrustStoreMacCache(); #endif diff --git a/chromium/net/cert/internal/system_trust_store_nss.h b/chromium/net/cert/internal/system_trust_store_nss.h index 8210258ffd6..70b3052d444 100644 --- a/chromium/net/cert/internal/system_trust_store_nss.h +++ b/chromium/net/cert/internal/system_trust_store_nss.h @@ -13,16 +13,20 @@ namespace net { // Create a SystemTrustStore that will accept trust for: // (*) built-in certificates -// (*) certificates stored on the |user_slot|. +// (*) certificates stored on the |user_slot_restriction|, if non-null. NET_EXPORT std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreNSSWithUserSlotRestriction( - crypto::ScopedPK11Slot user_slot); + crypto::ScopedPK11Slot user_slot_restriction); +#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) // Create a SystemTrustStore that will accept trust for: -// (*) built-in certificates -// It will not accept trust for certificates stored on other slots. +// (*) Chrome Root Store certificates +// (*) certificates stored on the |user_slot_restriction|, if non-null. NET_EXPORT std::unique_ptr<SystemTrustStore> -CreateSslSystemTrustStoreNSSWithNoUserSlots(); +CreateSslSystemTrustStoreChromeRootWithUserSlotRestriction( + std::unique_ptr<TrustStoreChrome> chrome_root, + crypto::ScopedPK11Slot user_slot_restriction); +#endif } // namespace net diff --git a/chromium/net/cert/internal/system_trust_store_nss_unittest.cc b/chromium/net/cert/internal/system_trust_store_nss_unittest.cc index efea095da41..ae343e796aa 100644 --- a/chromium/net/cert/internal/system_trust_store_nss_unittest.cc +++ b/chromium/net/cert/internal/system_trust_store_nss_unittest.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/memory/raw_ptr.h" #include "net/cert/internal/system_trust_store.h" #include <cert.h> @@ -11,9 +12,9 @@ #include "crypto/scoped_nss_types.h" #include "crypto/scoped_test_nss_db.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parsed_certificate.h" #include "net/cert/internal/system_trust_store_nss.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/parsed_certificate.h" #include "net/cert/test_root_certs.h" #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" @@ -89,7 +90,7 @@ class SystemTrustStoreNSSTest : public ::testing::Test { crypto::ScopedTestNSSDB test_nssdb_; crypto::ScopedTestNSSDB other_test_nssdb_; - TestRootCerts* test_root_certs_; + raw_ptr<TestRootCerts> test_root_certs_; scoped_refptr<X509Certificate> root_cert_; scoped_refptr<ParsedCertificate> parsed_root_cert_; @@ -131,7 +132,7 @@ TEST_F(SystemTrustStoreNSSTest, UserSlotRestrictionDisallows) { // certificate stored on user slots. TEST_F(SystemTrustStoreNSSTest, NoUserSlots) { std::unique_ptr<SystemTrustStore> system_trust_store = - CreateSslSystemTrustStoreNSSWithNoUserSlots(); + CreateSslSystemTrustStoreNSSWithUserSlotRestriction(nullptr); ASSERT_NO_FATAL_FAILURE(ImportRootCertAsTrusted(test_nssdb_.slot())); diff --git a/chromium/net/cert/internal/system_trust_store_unittest.cc b/chromium/net/cert/internal/system_trust_store_unittest.cc index 51308b77b09..902b40b3c8f 100644 --- a/chromium/net/cert/internal/system_trust_store_unittest.cc +++ b/chromium/net/cert/internal/system_trust_store_unittest.cc @@ -4,7 +4,7 @@ #include "net/cert/internal/system_trust_store.h" -#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/pki/parsed_certificate.h" #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" #include "net/net_buildflags.h" diff --git a/chromium/net/cert/internal/trust_store_chrome.cc b/chromium/net/cert/internal/trust_store_chrome.cc index 926c1207d66..56f9d497f0f 100644 --- a/chromium/net/cert/internal/trust_store_chrome.cc +++ b/chromium/net/cert/internal/trust_store_chrome.cc @@ -6,8 +6,8 @@ #include "base/containers/span.h" #include "base/logging.h" #include "base/memory/ptr_util.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/parsed_certificate.h" #include "net/cert/root_store_proto_lite/root_store.pb.h" #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" @@ -73,10 +73,12 @@ TrustStoreChrome::TrustStoreChrome(base::span<const ChromeRootCertInfo> certs, for (const auto& cert_info : certs) { bssl::UniquePtr<CRYPTO_BUFFER> cert; if (certs_are_static) { - // TODO(mattm,hchao): When the component updater is implemented, ensure - // the static data crypto_buffers for the compiled-in roots are kept - // alive, so that roots from the component updater data will de-dupe - // against them. + // TODO(mattm,hchao): Ensure the static data crypto_buffers for the + // compiled-in roots are kept alive, so that roots from the component + // updater data will de-dupe against them. This currently works if the + // new components roots are the same as the compiled in roots, but + // fails if a component update drops a root and then the next component + // update readds the root without a restart. cert = x509_util::CreateCryptoBufferFromStaticDataUnsafe( cert_info.root_cert_der); } else { @@ -86,8 +88,6 @@ TrustStoreChrome::TrustStoreChrome(base::span<const ChromeRootCertInfo> certs, auto parsed = ParsedCertificate::Create( std::move(cert), x509_util::DefaultParseCertificateOptions(), &errors); DCHECK(parsed); - // TODO(hchao): Figure out how to fail gracefully when the Chrome Root Store - // gets a bad component update. trust_store_.AddTrustAnchor(parsed); } version_ = version; @@ -130,4 +130,20 @@ int64_t CompiledChromeRootStoreVersion() { return kRootStoreVersion; } +ParsedCertificateList CompiledChromeRootStoreAnchors() { + ParsedCertificateList parsed_cert_list; + for (const auto& cert_info : kChromeRootCertList) { + bssl::UniquePtr<CRYPTO_BUFFER> cert = + x509_util::CreateCryptoBufferFromStaticDataUnsafe( + cert_info.root_cert_der); + CertErrors errors; + auto parsed = ParsedCertificate::Create( + std::move(cert), x509_util::DefaultParseCertificateOptions(), &errors); + DCHECK(parsed); + parsed_cert_list.push_back(parsed); + } + + return parsed_cert_list; +} + } // namespace net diff --git a/chromium/net/cert/internal/trust_store_chrome.h b/chromium/net/cert/internal/trust_store_chrome.h index 5f59e2ce9bf..0d7acc591a5 100644 --- a/chromium/net/cert/internal/trust_store_chrome.h +++ b/chromium/net/cert/internal/trust_store_chrome.h @@ -7,8 +7,8 @@ #include "base/containers/span.h" #include "net/base/net_export.h" -#include "net/cert/internal/trust_store.h" -#include "net/cert/internal/trust_store_in_memory.h" +#include "net/cert/pki/trust_store.h" +#include "net/cert/pki/trust_store_in_memory.h" #include "net/cert/root_store_proto_lite/root_store.pb.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -89,6 +89,10 @@ class NET_EXPORT TrustStoreChrome : public TrustStore { // binary. NET_EXPORT int64_t CompiledChromeRootStoreVersion(); +// Returns the anchors of the Chrome Root Store that were compiled into the +// binary. +NET_EXPORT ParsedCertificateList CompiledChromeRootStoreAnchors(); + } // namespace net #endif // NET_CERT_INTERNAL_TRUST_STORE_CHROME_H_ diff --git a/chromium/net/cert/internal/trust_store_chrome_unittest.cc b/chromium/net/cert/internal/trust_store_chrome_unittest.cc index 1734cf9b9cf..7ba40227386 100644 --- a/chromium/net/cert/internal/trust_store_chrome_unittest.cc +++ b/chromium/net/cert/internal/trust_store_chrome_unittest.cc @@ -5,8 +5,8 @@ #include "net/cert/internal/trust_store_chrome.h" #include "base/containers/span.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/parsed_certificate.h" #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" #include "net/test/cert_test_util.h" diff --git a/chromium/net/cert/internal/trust_store_mac.cc b/chromium/net/cert/internal/trust_store_mac.cc index fed6c8ed3c6..f3b6e2a53d5 100644 --- a/chromium/net/cert/internal/trust_store_mac.cc +++ b/chromium/net/cert/internal/trust_store_mac.cc @@ -14,15 +14,18 @@ #include "base/logging.h" #include "base/mac/foundation_util.h" #include "base/mac/mac_logging.h" +#include "base/metrics/histogram_functions.h" #include "base/no_destructor.h" +#include "base/strings/strcat.h" #include "base/synchronization/lock.h" #include "crypto/mac_security_services_lock.h" #include "net/base/hash_value.h" #include "net/base/network_notification_thread_mac.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parse_name.h" -#include "net/cert/internal/parsed_certificate.h" #include "net/cert/known_roots_mac.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/cert_issuer_source_static.h" +#include "net/cert/pki/parse_name.h" +#include "net/cert/pki/parsed_certificate.h" #include "net/cert/test_keychain_search_list_mac.h" #include "net/cert/x509_util.h" #include "net/cert/x509_util_apple.h" @@ -288,6 +291,7 @@ KnownRootStatus IsCertificateKnownRoot(const ParsedCertificate* cert) { TrustStatus IsCertificateTrustedForPolicy(const ParsedCertificate* cert, const CFStringRef policy_oid, + TrustStoreMac::TrustDomains domains, int* debug_info, KnownRootStatus* out_is_known_root) { // |*out_is_known_root| is intentionally not cleared before starting, as @@ -309,6 +313,10 @@ TrustStatus IsCertificateTrustedForPolicy(const ParsedCertificate* cert, for (const auto& trust_domain : {kSecTrustSettingsDomainUser, kSecTrustSettingsDomainAdmin, kSecTrustSettingsDomainSystem}) { + if (domains == TrustStoreMac::TrustDomains::kUserAndAdmin && + trust_domain == kSecTrustSettingsDomainSystem) { + continue; + } base::ScopedCFTypeRef<CFArrayRef> trust_settings; OSStatus err; { @@ -442,6 +450,139 @@ class TrustDomainCache { base::flat_map<SHA256HashValue, TrustStatusDetails> trust_status_cache_; }; +// Caches certificates and calculated trust status for certificates present in +// a single trust domain. +class TrustDomainCacheFullCerts { + public: + struct TrustStatusDetails { + TrustStatus trust_status = TrustStatus::UNKNOWN; + int debug_info = 0; + }; + + TrustDomainCacheFullCerts(SecTrustSettingsDomain domain, + CFStringRef policy_oid) + : domain_(domain), policy_oid_(policy_oid) { + DCHECK(policy_oid_); + } + + TrustDomainCacheFullCerts(const TrustDomainCacheFullCerts&) = delete; + TrustDomainCacheFullCerts& operator=(const TrustDomainCacheFullCerts&) = + delete; + + // (Re-)Initializes the cache with the certs in |domain_| set to UNKNOWN trust + // status. + void Initialize() { + trust_status_cache_.clear(); + cert_issuer_source_.Clear(); + + base::ScopedCFTypeRef<CFArrayRef> cert_array; + OSStatus rv; + { + base::AutoLock lock(crypto::GetMacSecurityServicesLock()); + rv = SecTrustSettingsCopyCertificates(domain_, + cert_array.InitializeInto()); + } + if (rv != noErr) { + // Note: SecTrustSettingsCopyCertificates can legitimately return + // errSecNoTrustSettings if there are no trust settings in |domain_|. + HistogramTrustDomainCertCount(0U); + return; + } + std::vector<std::pair<SHA256HashValue, TrustStatusDetails>> + trust_status_vector; + for (CFIndex i = 0, size = CFArrayGetCount(cert_array); i < size; ++i) { + SecCertificateRef cert = reinterpret_cast<SecCertificateRef>( + const_cast<void*>(CFArrayGetValueAtIndex(cert_array, i))); + base::ScopedCFTypeRef<CFDataRef> der_data(SecCertificateCopyData(cert)); + if (!der_data) { + LOG(ERROR) << "SecCertificateCopyData error"; + continue; + } + auto buffer = x509_util::CreateCryptoBuffer(base::make_span( + CFDataGetBytePtr(der_data.get()), CFDataGetLength(der_data.get()))); + CertErrors errors; + ParseCertificateOptions options; + options.allow_invalid_serial_numbers = true; + scoped_refptr<ParsedCertificate> parsed_cert = + ParsedCertificate::Create(std::move(buffer), options, &errors); + if (!parsed_cert) { + LOG(ERROR) << "Error parsing certificate:\n" << errors.ToDebugString(); + continue; + } + cert_issuer_source_.AddCert(parsed_cert); + trust_status_vector.emplace_back(x509_util::CalculateFingerprint256(cert), + TrustStatusDetails()); + } + HistogramTrustDomainCertCount(trust_status_vector.size()); + trust_status_cache_ = base::flat_map<SHA256HashValue, TrustStatusDetails>( + std::move(trust_status_vector)); + } + + // Returns the trust status for |cert| in |domain_|. + TrustStatus IsCertTrusted(const ParsedCertificate* cert, + const SHA256HashValue& cert_hash, + base::SupportsUserData* debug_data) { + auto cache_iter = trust_status_cache_.find(cert_hash); + if (cache_iter == trust_status_cache_.end()) { + // Cert does not have trust settings in this domain, return UNSPECIFIED. + UpdateUserData(0, debug_data, + TrustStoreMac::TrustImplType::kDomainCacheFullCerts); + return TrustStatus::UNSPECIFIED; + } + + if (cache_iter->second.trust_status != TrustStatus::UNKNOWN) { + // Cert has trust settings and trust has already been calculated, return + // the cached value. + UpdateUserData(cache_iter->second.debug_info, debug_data, + TrustStoreMac::TrustImplType::kDomainCacheFullCerts); + return cache_iter->second.trust_status; + } + + // Cert has trust settings but trust has not been calculated yet. + // Calculate it now, insert into cache, and return. + TrustStatus cert_trust = IsCertificateTrustedForPolicyInDomain( + cert, policy_oid_, domain_, &cache_iter->second.debug_info); + cache_iter->second.trust_status = cert_trust; + UpdateUserData(cache_iter->second.debug_info, debug_data, + TrustStoreMac::TrustImplType::kDomainCacheFullCerts); + return cert_trust; + } + + // Returns true if the certificate with |cert_hash| is present in |domain_|. + bool ContainsCert(const SHA256HashValue& cert_hash) const { + return trust_status_cache_.find(cert_hash) != trust_status_cache_.end(); + } + + // Returns a CertIssuerSource containing all the certificates that are + // present in |domain_|. + CertIssuerSource& cert_issuer_source() { return cert_issuer_source_; } + + private: + void HistogramTrustDomainCertCount(size_t count) const { + base::StringPiece domain_name; + switch (domain_) { + case kSecTrustSettingsDomainUser: + domain_name = "User"; + break; + case kSecTrustSettingsDomainAdmin: + domain_name = "Admin"; + break; + case kSecTrustSettingsDomainSystem: + domain_name = "System"; + break; + } + base::UmaHistogramCounts1000( + base::StrCat( + {"Net.CertVerifier.MacTrustDomainCertCount.", domain_name}), + count); + } + + const SecTrustSettingsDomain domain_; + const CFStringRef policy_oid_; + base::flat_map<SHA256HashValue, TrustStatusDetails> trust_status_cache_; + CertIssuerSourceStatic cert_issuer_source_; +}; + SHA256HashValue CalculateFingerprint256(const der::Input& buffer) { SHA256HashValue sha256; SHA256(buffer.UnsafeData(), buffer.Length(), sha256.data); @@ -473,6 +614,12 @@ class KeychainTrustSettingsChangedNotifier { private: friend base::NoDestructor<KeychainTrustSettingsChangedNotifier>; +// Much of the Keychain API was marked deprecated as of the macOS 13 SDK. +// Removal of its use is tracked in https://crbug.com/1348251 but deprecation +// warnings are disabled in the meanwhile. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + KeychainTrustSettingsChangedNotifier() { DCHECK(GetNetworkNotificationThreadMac()->RunsTasksInCurrentSequence()); OSStatus status = SecKeychainAddCallback( @@ -482,6 +629,8 @@ class KeychainTrustSettingsChangedNotifier { OSSTATUS_LOG(ERROR, status) << "SecKeychainAddCallback failed"; } +#pragma clang diagnostic pop + ~KeychainTrustSettingsChangedNotifier() = delete; static OSStatus KeychainCallback(SecKeychainEvent keychain_event, @@ -587,6 +736,9 @@ class TrustStoreMac::TrustImpl { virtual bool IsKnownRoot(const ParsedCertificate* cert) = 0; virtual TrustStatus IsCertTrusted(const ParsedCertificate* cert, base::SupportsUserData* debug_data) = 0; + virtual bool ImplementsSyncGetIssuersOf() const { return false; } + virtual void SyncGetIssuersOf(const ParsedCertificate* cert, + ParsedCertificateList* issuers) {} virtual void InitializeTrustCache() = 0; }; @@ -596,10 +748,14 @@ class TrustStoreMac::TrustImpl { // modified. class TrustStoreMac::TrustImplDomainCache : public TrustStoreMac::TrustImpl { public: - explicit TrustImplDomainCache(CFStringRef policy_oid) - : system_domain_cache_(kSecTrustSettingsDomainSystem, policy_oid), + explicit TrustImplDomainCache(CFStringRef policy_oid, TrustDomains domains) + : use_system_domain_cache_(domains == TrustDomains::kAll), admin_domain_cache_(kSecTrustSettingsDomainAdmin, policy_oid), user_domain_cache_(kSecTrustSettingsDomainUser, policy_oid) { + if (use_system_domain_cache_) { + system_domain_cache_ = std::make_unique<TrustDomainCache>( + kSecTrustSettingsDomainSystem, policy_oid); + } keychain_observer_ = std::make_unique<KeychainTrustObserver>(); } @@ -613,11 +769,13 @@ class TrustStoreMac::TrustImplDomainCache : public TrustStoreMac::TrustImpl { // Returns true if |cert| is present in kSecTrustSettingsDomainSystem. bool IsKnownRoot(const ParsedCertificate* cert) override { + if (!use_system_domain_cache_) + return false; SHA256HashValue cert_hash = CalculateFingerprint256(cert->der_cert()); base::AutoLock lock(cache_lock_); MaybeInitializeCache(); - return system_domain_cache_.ContainsCert(cert_hash); + return system_domain_cache_->ContainsCert(cert_hash); } // Returns the trust status for |cert|. @@ -632,12 +790,15 @@ class TrustStoreMac::TrustImplDomainCache : public TrustStoreMac::TrustImpl { // override system ones, and user settings can override both admin and // system. for (TrustDomainCache* trust_domain_cache : - {&user_domain_cache_, &admin_domain_cache_, &system_domain_cache_}) { + {&user_domain_cache_, &admin_domain_cache_}) { TrustStatus ts = trust_domain_cache->IsCertTrusted(cert, cert_hash, debug_data); if (ts != TrustStatus::UNSPECIFIED) return ts; } + if (use_system_domain_cache_) { + return system_domain_cache_->IsCertTrusted(cert, cert_hash, debug_data); + } // Cert did not have trust settings in any domain. return TrustStatus::UNSPECIFIED; @@ -661,31 +822,158 @@ class TrustStoreMac::TrustImplDomainCache : public TrustStoreMac::TrustImpl { iteration_ = keychain_iteration; user_domain_cache_.Initialize(); admin_domain_cache_.Initialize(); - if (!system_domain_initialized_) { + if (use_system_domain_cache_ && !system_domain_initialized_) { // In practice, the system trust domain does not change during runtime, // and SecTrustSettingsCopyCertificates on the system domain is quite // slow, so the system domain cache is not reset on keychain changes. - system_domain_cache_.Initialize(); + system_domain_cache_->Initialize(); system_domain_initialized_ = true; } } std::unique_ptr<KeychainTrustObserver> keychain_observer_; + // Store whether to use the system domain in a const bool that is initialized + // in constructor so it is safe to read without having to lock first. + const bool use_system_domain_cache_; base::Lock cache_lock_; // |cache_lock_| must be held while accessing any following members. int64_t iteration_ GUARDED_BY(cache_lock_) = -1; bool system_domain_initialized_ GUARDED_BY(cache_lock_) = false; - TrustDomainCache system_domain_cache_ GUARDED_BY(cache_lock_); + std::unique_ptr<TrustDomainCache> system_domain_cache_ + GUARDED_BY(cache_lock_); TrustDomainCache admin_domain_cache_ GUARDED_BY(cache_lock_); TrustDomainCache user_domain_cache_ GUARDED_BY(cache_lock_); }; +// TrustImplDomainCacheFullCerts uses SecTrustSettingsCopyCertificates to get +// the list of certs in each trust domain and caches the full certificates so +// that pathbuilding does not need to touch any Mac APIs unless one of those +// certificates is encountered, at which point the calculated trust status of +// that cert is cached. The cache is reset if trust settings are modified. +class TrustStoreMac::TrustImplDomainCacheFullCerts + : public TrustStoreMac::TrustImpl { + public: + explicit TrustImplDomainCacheFullCerts(CFStringRef policy_oid, + TrustDomains domains) + : use_system_domain_cache_(domains == TrustDomains::kAll), + admin_domain_cache_(kSecTrustSettingsDomainAdmin, policy_oid), + user_domain_cache_(kSecTrustSettingsDomainUser, policy_oid) { + if (use_system_domain_cache_) { + system_domain_cache_ = std::make_unique<TrustDomainCacheFullCerts>( + kSecTrustSettingsDomainSystem, policy_oid); + } + keychain_observer_ = std::make_unique<KeychainTrustObserver>(); + } + + TrustImplDomainCacheFullCerts(const TrustImplDomainCacheFullCerts&) = delete; + TrustImplDomainCacheFullCerts& operator=( + const TrustImplDomainCacheFullCerts&) = delete; + + ~TrustImplDomainCacheFullCerts() override { + GetNetworkNotificationThreadMac()->DeleteSoon( + FROM_HERE, std::move(keychain_observer_)); + } + + // Returns true if |cert| is present in kSecTrustSettingsDomainSystem. + bool IsKnownRoot(const ParsedCertificate* cert) override { + if (!use_system_domain_cache_) + return false; + SHA256HashValue cert_hash = CalculateFingerprint256(cert->der_cert()); + + base::AutoLock lock(cache_lock_); + MaybeInitializeCache(); + return system_domain_cache_->ContainsCert(cert_hash); + } + + // Returns the trust status for |cert|. + TrustStatus IsCertTrusted(const ParsedCertificate* cert, + base::SupportsUserData* debug_data) override { + SHA256HashValue cert_hash = CalculateFingerprint256(cert->der_cert()); + + base::AutoLock lock(cache_lock_); + MaybeInitializeCache(); + + // Evaluate trust domains in user, admin, system order. Admin settings can + // override system ones, and user settings can override both admin and + // system. + for (TrustDomainCacheFullCerts* trust_domain_cache : + {&user_domain_cache_, &admin_domain_cache_}) { + TrustStatus ts = + trust_domain_cache->IsCertTrusted(cert, cert_hash, debug_data); + if (ts != TrustStatus::UNSPECIFIED) + return ts; + } + if (use_system_domain_cache_) { + return system_domain_cache_->IsCertTrusted(cert, cert_hash, debug_data); + } + + // Cert did not have trust settings in any domain. + return TrustStatus::UNSPECIFIED; + } + + bool ImplementsSyncGetIssuersOf() const override { return true; } + + void SyncGetIssuersOf(const ParsedCertificate* cert, + ParsedCertificateList* issuers) override { + base::AutoLock lock(cache_lock_); + MaybeInitializeCache(); + user_domain_cache_.cert_issuer_source().SyncGetIssuersOf(cert, issuers); + admin_domain_cache_.cert_issuer_source().SyncGetIssuersOf(cert, issuers); + if (system_domain_cache_) { + system_domain_cache_->cert_issuer_source().SyncGetIssuersOf(cert, + issuers); + } + } + + // Initializes the cache, if it isn't already initialized. + void InitializeTrustCache() override { + base::AutoLock lock(cache_lock_); + MaybeInitializeCache(); + } + + private: + // (Re-)Initialize the cache if necessary. Must be called after acquiring + // |cache_lock_| and before accessing any of the |*_domain_cache_| members. + void MaybeInitializeCache() EXCLUSIVE_LOCKS_REQUIRED(cache_lock_) { + cache_lock_.AssertAcquired(); + int64_t keychain_iteration = keychain_observer_->Iteration(); + if (iteration_ == keychain_iteration) + return; + + iteration_ = keychain_iteration; + user_domain_cache_.Initialize(); + admin_domain_cache_.Initialize(); + if (use_system_domain_cache_ && !system_domain_initialized_) { + // In practice, the system trust domain does not change during runtime, + // and SecTrustSettingsCopyCertificates on the system domain is quite + // slow, so the system domain cache is not reset on keychain changes. + system_domain_cache_->Initialize(); + system_domain_initialized_ = true; + } + } + + std::unique_ptr<KeychainTrustObserver> keychain_observer_; + // Store whether to use the system domain in a const bool that is initialized + // in constructor so it is safe to read without having to lock first. + const bool use_system_domain_cache_; + + base::Lock cache_lock_; + // |cache_lock_| must be held while accessing any following members. + int64_t iteration_ GUARDED_BY(cache_lock_) = -1; + bool system_domain_initialized_ GUARDED_BY(cache_lock_) = false; + std::unique_ptr<TrustDomainCacheFullCerts> system_domain_cache_ + GUARDED_BY(cache_lock_); + TrustDomainCacheFullCerts admin_domain_cache_ GUARDED_BY(cache_lock_); + TrustDomainCacheFullCerts user_domain_cache_ GUARDED_BY(cache_lock_); +}; + // TrustImplNoCache is the simplest approach which calls // SecTrustSettingsCopyTrustSettings on every cert checked, with no caching. class TrustStoreMac::TrustImplNoCache : public TrustStoreMac::TrustImpl { public: - explicit TrustImplNoCache(CFStringRef policy_oid) : policy_oid_(policy_oid) {} + explicit TrustImplNoCache(CFStringRef policy_oid, TrustDomains domains) + : policy_oid_(policy_oid), domains_(domains) {} TrustImplNoCache(const TrustImplNoCache&) = delete; TrustImplNoCache& operator=(const TrustImplNoCache&) = delete; @@ -694,6 +982,8 @@ class TrustStoreMac::TrustImplNoCache : public TrustStoreMac::TrustImpl { // Returns true if |cert| is present in kSecTrustSettingsDomainSystem. bool IsKnownRoot(const ParsedCertificate* cert) override { + if (domains_ == TrustDomains::kUserAndAdmin) + return false; HashValue cert_hash(CalculateFingerprint256(cert->der_cert())); base::AutoLock lock(crypto::GetMacSecurityServicesLock()); return net::IsKnownRoot(cert_hash); @@ -703,8 +993,9 @@ class TrustStoreMac::TrustImplNoCache : public TrustStoreMac::TrustImpl { TrustStatus IsCertTrusted(const ParsedCertificate* cert, base::SupportsUserData* debug_data) override { int debug_info = 0; - TrustStatus result = IsCertificateTrustedForPolicy( - cert, policy_oid_, &debug_info, /*out_is_known_root=*/nullptr); + TrustStatus result = + IsCertificateTrustedForPolicy(cert, policy_oid_, domains_, &debug_info, + /*out_is_known_root=*/nullptr); UpdateUserData(debug_info, debug_data, TrustStoreMac::TrustImplType::kSimple); return result; @@ -716,6 +1007,7 @@ class TrustStoreMac::TrustImplNoCache : public TrustStoreMac::TrustImpl { private: const CFStringRef policy_oid_; + const TrustDomains domains_; }; // TrustImplLRUCache is calls SecTrustSettingsCopyTrustSettings on every cert @@ -723,8 +1015,12 @@ class TrustStoreMac::TrustImplNoCache : public TrustStoreMac::TrustImpl { // keychain updates. class TrustStoreMac::TrustImplLRUCache : public TrustStoreMac::TrustImpl { public: - TrustImplLRUCache(CFStringRef policy_oid, size_t cache_size) - : policy_oid_(policy_oid), trust_status_cache_(cache_size) { + TrustImplLRUCache(CFStringRef policy_oid, + size_t cache_size, + TrustDomains domains) + : policy_oid_(policy_oid), + domains_(domains), + trust_status_cache_(cache_size) { keychain_observer_ = std::make_unique<KeychainTrustObserver>(); } @@ -738,6 +1034,8 @@ class TrustStoreMac::TrustImplLRUCache : public TrustStoreMac::TrustImpl { // Returns true if |cert| has trust settings in kSecTrustSettingsDomainSystem. bool IsKnownRoot(const ParsedCertificate* cert) override { + if (domains_ == TrustDomains::kUserAndAdmin) + return false; return GetKnownRootStatus(cert) == KnownRootStatus::IS_KNOWN_ROOT; } @@ -818,7 +1116,7 @@ class TrustStoreMac::TrustImplLRUCache : public TrustStoreMac::TrustImpl { } trust_details.trust_status = IsCertificateTrustedForPolicy( - cert, policy_oid_, &trust_details.debug_info, + cert, policy_oid_, domains_, &trust_details.debug_info, &trust_details.is_known_root); { @@ -841,6 +1139,7 @@ class TrustStoreMac::TrustImplLRUCache : public TrustStoreMac::TrustImpl { } const CFStringRef policy_oid_; + const TrustDomains domains_; std::unique_ptr<KeychainTrustObserver> keychain_observer_; base::Lock cache_lock_; @@ -858,20 +1157,27 @@ class TrustStoreMac::TrustImplLRUCache : public TrustStoreMac::TrustImpl { TrustStoreMac::TrustStoreMac(CFStringRef policy_oid, TrustImplType impl, - size_t cache_size) { + size_t cache_size, + TrustDomains domains) + : domains_(domains) { switch (impl) { case TrustImplType::kUnknown: DCHECK(false); break; case TrustImplType::kDomainCache: - trust_cache_ = std::make_unique<TrustImplDomainCache>(policy_oid); + trust_cache_ = + std::make_unique<TrustImplDomainCache>(policy_oid, domains); break; case TrustImplType::kSimple: - trust_cache_ = std::make_unique<TrustImplNoCache>(policy_oid); + trust_cache_ = std::make_unique<TrustImplNoCache>(policy_oid, domains); break; case TrustImplType::kLruCache: trust_cache_ = - std::make_unique<TrustImplLRUCache>(policy_oid, cache_size); + std::make_unique<TrustImplLRUCache>(policy_oid, cache_size, domains); + break; + case TrustImplType::kDomainCacheFullCerts: + trust_cache_ = + std::make_unique<TrustImplDomainCacheFullCerts>(policy_oid, domains); break; } } @@ -888,12 +1194,17 @@ bool TrustStoreMac::IsKnownRoot(const ParsedCertificate* cert) const { void TrustStoreMac::SyncGetIssuersOf(const ParsedCertificate* cert, ParsedCertificateList* issuers) { + if (trust_cache_->ImplementsSyncGetIssuersOf()) { + trust_cache_->SyncGetIssuersOf(cert, issuers); + return; + } + base::ScopedCFTypeRef<CFDataRef> name_data = GetMacNormalizedIssuer(cert); if (!name_data) return; std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> matching_cert_buffers = - FindMatchingCertificatesForMacNormalizedSubject(name_data); + FindMatchingCertificatesForMacNormalizedSubject(name_data, domains_); // Convert to ParsedCertificate. for (auto& buffer : matching_cert_buffers) { @@ -937,7 +1248,8 @@ CertificateTrust TrustStoreMac::GetTrust( // static std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( - CFDataRef name_data) { + CFDataRef name_data, + TrustDomains domains) { std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> matching_cert_buffers; base::ScopedCFTypeRef<CFMutableDictionaryRef> query( CFDictionaryCreateMutable(nullptr, 0, &kCFTypeDictionaryKeyCallBacks, @@ -961,43 +1273,56 @@ TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( } } - // If a TestKeychainSearchList is present, it will have already set - // |scoped_alternate_keychain_search_list|, which will be used as the - // basis for reordering the keychain. Otherwise, get the current keychain - // search list and use that. - if (!scoped_alternate_keychain_search_list) { - OSStatus status = SecKeychainCopySearchList( - scoped_alternate_keychain_search_list.InitializeInto()); +// Much of the Keychain API was marked deprecated as of the macOS 13 SDK. +// Removal of its use is tracked in https://crbug.com/1348251 but deprecation +// warnings are disabled in the meanwhile. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + + if (domains == TrustDomains::kAll) { + // If a TestKeychainSearchList is present, it will have already set + // |scoped_alternate_keychain_search_list|, which will be used as the + // basis for reordering the keychain. Otherwise, get the current keychain + // search list and use that. + if (!scoped_alternate_keychain_search_list) { + OSStatus status = SecKeychainCopySearchList( + scoped_alternate_keychain_search_list.InitializeInto()); + if (status) { + OSSTATUS_LOG(ERROR, status) << "SecKeychainCopySearchList error"; + return matching_cert_buffers; + } + } + + CFMutableArrayRef mutable_keychain_search_list = CFArrayCreateMutableCopy( + kCFAllocatorDefault, + CFArrayGetCount(scoped_alternate_keychain_search_list.get()) + 1, + scoped_alternate_keychain_search_list.get()); + if (!mutable_keychain_search_list) { + LOG(ERROR) << "CFArrayCreateMutableCopy"; + return matching_cert_buffers; + } + scoped_alternate_keychain_search_list.reset(mutable_keychain_search_list); + + base::ScopedCFTypeRef<SecKeychainRef> roots_keychain; + // The System Roots keychain is not normally searched by + // SecItemCopyMatching. Get a reference to it and include in the keychain + // search list. + OSStatus status = SecKeychainOpen( + "/System/Library/Keychains/SystemRootCertificates.keychain", + roots_keychain.InitializeInto()); if (status) { - OSSTATUS_LOG(ERROR, status) << "SecKeychainCopySearchList error"; + OSSTATUS_LOG(ERROR, status) << "SecKeychainOpen error"; return matching_cert_buffers; } + CFArrayAppendValue(mutable_keychain_search_list, roots_keychain); } - CFMutableArrayRef mutable_keychain_search_list = CFArrayCreateMutableCopy( - kCFAllocatorDefault, - CFArrayGetCount(scoped_alternate_keychain_search_list.get()) + 1, - scoped_alternate_keychain_search_list.get()); - if (!mutable_keychain_search_list) { - LOG(ERROR) << "CFArrayCreateMutableCopy"; - return matching_cert_buffers; - } - scoped_alternate_keychain_search_list.reset(mutable_keychain_search_list); +#pragma clang diagnostic pop - base::ScopedCFTypeRef<SecKeychainRef> roots_keychain; - // The System Roots keychain is not normally searched by SecItemCopyMatching. - // Get a reference to it and include in the keychain search list. - OSStatus status = SecKeychainOpen( - "/System/Library/Keychains/SystemRootCertificates.keychain", - roots_keychain.InitializeInto()); - if (status) { - OSSTATUS_LOG(ERROR, status) << "SecKeychainOpen error"; - return matching_cert_buffers; + if (scoped_alternate_keychain_search_list) { + CFDictionarySetValue(query, kSecMatchSearchList, + scoped_alternate_keychain_search_list.get()); } - CFArrayAppendValue(mutable_keychain_search_list, roots_keychain); - - CFDictionarySetValue(query, kSecMatchSearchList, - scoped_alternate_keychain_search_list.get()); base::ScopedCFTypeRef<CFArrayRef> matching_items; OSStatus err = SecItemCopyMatching( diff --git a/chromium/net/cert/internal/trust_store_mac.h b/chromium/net/cert/internal/trust_store_mac.h index 02c39fc21b5..e7f9a964cb0 100644 --- a/chromium/net/cert/internal/trust_store_mac.h +++ b/chromium/net/cert/internal/trust_store_mac.h @@ -11,7 +11,7 @@ #include "base/mac/scoped_cftyperef.h" #include "base/memory/ref_counted.h" #include "net/base/net_export.h" -#include "net/cert/internal/trust_store.h" +#include "net/cert/pki/trust_store.h" namespace net { @@ -74,11 +74,25 @@ class NET_EXPORT TrustStoreMac : public TrustStore { COPY_TRUST_SETTINGS_ERROR = 1 << 11, }; + // NOTE: When updating this enum, also update ParamToTrustImplType in + // system_trust_store.cc enum class TrustImplType { kUnknown = 0, kDomainCache = 1, kSimple = 2, kLruCache = 3, + kDomainCacheFullCerts = 4, + }; + + enum class TrustDomains { + // Load trust settings and certificates from all three trust domains + // (user, admin, system). + kAll = 0, + + // Load trust settings and certificates from only the user and admin trust + // domains. This will find trust settings that have been set locally or by + // an enterprise, but not those distributed with the OS. + kUserAndAdmin = 1, }; class ResultDebugData : public base::SupportsUserData::Data { @@ -111,7 +125,10 @@ class NET_EXPORT TrustStoreMac : public TrustStore { // |impl| selects which internal implementation is used for checking trust // settings, and the interpretation of |cache_size| varies depending on // |impl|. - TrustStoreMac(CFStringRef policy_oid, TrustImplType impl, size_t cache_size); + TrustStoreMac(CFStringRef policy_oid, + TrustImplType impl, + size_t cache_size, + TrustDomains domains); TrustStoreMac(const TrustStoreMac&) = delete; TrustStoreMac& operator=(const TrustStoreMac&) = delete; @@ -134,6 +151,7 @@ class NET_EXPORT TrustStoreMac : public TrustStore { private: class TrustImpl; class TrustImplDomainCache; + class TrustImplDomainCacheFullCerts; class TrustImplNoCache; class TrustImplLRUCache; @@ -143,7 +161,8 @@ class NET_EXPORT TrustStoreMac : public TrustStore { // The result is an array of CRYPTO_BUFFERs containing the DER certificate // data. static std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> - FindMatchingCertificatesForMacNormalizedSubject(CFDataRef name_data); + FindMatchingCertificatesForMacNormalizedSubject(CFDataRef name_data, + TrustDomains domains); // Returns the OS-normalized issuer of |cert|. // macOS internally uses a normalized form of subject/issuer names for @@ -152,6 +171,7 @@ class NET_EXPORT TrustStoreMac : public TrustStore { static base::ScopedCFTypeRef<CFDataRef> GetMacNormalizedIssuer( const ParsedCertificate* cert); + TrustDomains domains_; std::unique_ptr<TrustImpl> trust_cache_; }; diff --git a/chromium/net/cert/internal/trust_store_mac_unittest.cc b/chromium/net/cert/internal/trust_store_mac_unittest.cc index 095b90df72f..92383414d74 100644 --- a/chromium/net/cert/internal/trust_store_mac_unittest.cc +++ b/chromium/net/cert/internal/trust_store_mac_unittest.cc @@ -4,19 +4,25 @@ #include "net/cert/internal/trust_store_mac.h" +#include <algorithm> +#include <set> + #include "base/base_paths.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/logging.h" #include "base/path_service.h" #include "base/process/launch.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/synchronization/lock.h" +#include "base/test/metrics/histogram_tester.h" #include "crypto/mac_security_services_lock.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/test_helpers.h" +#include "crypto/sha2.h" #include "net/cert/known_roots_mac.h" #include "net/cert/pem.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/test_helpers.h" #include "net/cert/test_keychain_search_list_mac.h" #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" @@ -83,6 +89,28 @@ std::vector<std::string> ParsedCertificateListAsDER( return result; } +std::set<std::string> ParseFindCertificateOutputToDerCerts(std::string output) { + std::set<std::string> certs; + for (const std::string& hash_and_pem_partial : base::SplitStringUsingSubstr( + output, "-----END CERTIFICATE-----", base::TRIM_WHITESPACE, + base::SPLIT_WANT_NONEMPTY)) { + // Re-add the PEM ending mark, since SplitStringUsingSubstr eats it. + const std::string hash_and_pem = + hash_and_pem_partial + "\n-----END CERTIFICATE-----\n"; + + // Parse the PEM encoded text to DER bytes. + PEMTokenizer pem_tokenizer(hash_and_pem, {kCertificateHeader}); + if (!pem_tokenizer.GetNext()) { + ADD_FAILURE() << "!pem_tokenizer.GetNext()"; + continue; + } + std::string cert_der(pem_tokenizer.data()); + EXPECT_FALSE(pem_tokenizer.GetNext()); + certs.insert(cert_der); + } + return certs; +} + class DebugData : public base::SupportsUserData { public: ~DebugData() override = default; @@ -96,8 +124,15 @@ enum IsKnownRootTestOrder { } // namespace class TrustStoreMacImplTest - : public testing::TestWithParam< - std::tuple<TrustStoreMac::TrustImplType, IsKnownRootTestOrder>> {}; + : public testing::TestWithParam<std::tuple<TrustStoreMac::TrustImplType, + IsKnownRootTestOrder, + TrustStoreMac::TrustDomains>> {}; + +// Much of the Keychain API was marked deprecated as of the macOS 13 SDK. +// Removal of its use is tracked in https://crbug.com/1348251 but deprecation +// warnings are disabled in the meanwhile. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" // Test the trust store using known test certificates in a keychain. Tests // that issuer searching returns the expected certificates, and that none of @@ -118,9 +153,13 @@ TEST_P(TrustStoreMacImplTest, MultiRootNotTrusted) { ASSERT_TRUE(keychain); test_keychain_search_list->AddKeychain(keychain); +#pragma clang diagnostic pop + const TrustStoreMac::TrustImplType trust_impl = std::get<0>(GetParam()); const IsKnownRootTestOrder is_known_root_test_order = std::get<1>(GetParam()); - TrustStoreMac trust_store(kSecPolicyAppleSSL, trust_impl, kDefaultCacheSize); + const TrustStoreMac::TrustDomains trust_domains = std::get<2>(GetParam()); + TrustStoreMac trust_store(kSecPolicyAppleSSL, trust_impl, kDefaultCacheSize, + trust_domains); scoped_refptr<ParsedCertificate> a_by_b, b_by_c, b_by_f, c_by_d, c_by_e, f_by_e, d_by_d, e_by_e; @@ -155,7 +194,7 @@ TEST_P(TrustStoreMacImplTest, MultiRootNotTrusted) { { std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> scoped_matching_items = TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( - normalized_name_b.get()); + normalized_name_b.get(), trust_domains); EXPECT_THAT(CryptoBufferVectorAsStringVector(scoped_matching_items), UnorderedElementsAreArray( @@ -165,7 +204,7 @@ TEST_P(TrustStoreMacImplTest, MultiRootNotTrusted) { { std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> scoped_matching_items = TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( - normalized_name_c.get()); + normalized_name_c.get(), trust_domains); EXPECT_THAT(CryptoBufferVectorAsStringVector(scoped_matching_items), UnorderedElementsAreArray( ParsedCertificateListAsDER({c_by_d, c_by_e}))); @@ -174,7 +213,7 @@ TEST_P(TrustStoreMacImplTest, MultiRootNotTrusted) { { std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> scoped_matching_items = TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( - normalized_name_f.get()); + normalized_name_f.get(), trust_domains); EXPECT_THAT( CryptoBufferVectorAsStringVector(scoped_matching_items), UnorderedElementsAreArray(ParsedCertificateListAsDER({f_by_e}))); @@ -183,7 +222,7 @@ TEST_P(TrustStoreMacImplTest, MultiRootNotTrusted) { { std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> scoped_matching_items = TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( - normalized_name_d.get()); + normalized_name_d.get(), trust_domains); EXPECT_THAT( CryptoBufferVectorAsStringVector(scoped_matching_items), UnorderedElementsAreArray(ParsedCertificateListAsDER({d_by_d}))); @@ -192,7 +231,7 @@ TEST_P(TrustStoreMacImplTest, MultiRootNotTrusted) { { std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> scoped_matching_items = TrustStoreMac::FindMatchingCertificatesForMacNormalizedSubject( - normalized_name_e.get()); + normalized_name_e.get(), trust_domains); EXPECT_THAT( CryptoBufferVectorAsStringVector(scoped_matching_items), UnorderedElementsAreArray(ParsedCertificateListAsDER({e_by_e}))); @@ -242,43 +281,33 @@ TEST_P(TrustStoreMacImplTest, SystemCerts) { "/System/Library/Keychains/SystemRootCertificates.keychain"}, &find_certificate_system_roots_output)); + std::set<std::string> find_certificate_default_search_list_certs = + ParseFindCertificateOutputToDerCerts( + find_certificate_default_search_list_output); + std::set<std::string> find_certificate_system_roots_certs = + ParseFindCertificateOutputToDerCerts( + find_certificate_system_roots_output); + const TrustStoreMac::TrustImplType trust_impl = std::get<0>(GetParam()); const IsKnownRootTestOrder is_known_root_test_order = std::get<1>(GetParam()); + const TrustStoreMac::TrustDomains trust_domains = std::get<2>(GetParam()); + + base::HistogramTester histogram_tester; TrustStoreMac trust_store(kSecPolicyAppleX509Basic, trust_impl, - kDefaultCacheSize); + kDefaultCacheSize, trust_domains); base::ScopedCFTypeRef<SecPolicyRef> sec_policy(SecPolicyCreateBasicX509()); ASSERT_TRUE(sec_policy); - for (const std::string& hash_and_pem_partial : base::SplitStringUsingSubstr( - find_certificate_system_roots_output + - find_certificate_default_search_list_output, - "-----END CERTIFICATE-----", base::TRIM_WHITESPACE, - base::SPLIT_WANT_NONEMPTY)) { - // Re-add the PEM ending mark, since SplitStringUsingSubstr eats it. - const std::string hash_and_pem = - hash_and_pem_partial + "\n-----END CERTIFICATE-----\n"; - - // Use the first hash value found in the text. This might be SHA-256 or - // SHA-1, but it's only for debugging purposes so it doesn't matter as long - // as one exists. - std::string::size_type hash_pos = hash_and_pem.find("hash: "); - ASSERT_NE(std::string::npos, hash_pos); - hash_pos += 6; - std::string::size_type eol_pos = hash_and_pem.find_first_of("\r\n"); - ASSERT_NE(std::string::npos, eol_pos); - // Extract the hash of the certificate. This isn't necessary for the - // test, but is a convenient identifier to use in any error messages. - std::string hash_text = hash_and_pem.substr(hash_pos, eol_pos - hash_pos); - + std::vector<std::string> all_certs; + std::set_union(find_certificate_default_search_list_certs.begin(), + find_certificate_default_search_list_certs.end(), + find_certificate_system_roots_certs.begin(), + find_certificate_system_roots_certs.end(), + std::back_inserter(all_certs)); + for (const std::string& cert_der : all_certs) { + std::string hash = crypto::SHA256HashString(cert_der); + std::string hash_text = base::HexEncode(hash.data(), hash.size()); SCOPED_TRACE(hash_text); - // TODO(mattm): The same cert might exist in both lists, could de-dupe - // before testing? - - // Parse the PEM encoded text to DER bytes. - PEMTokenizer pem_tokenizer(hash_and_pem, {kCertificateHeader}); - ASSERT_TRUE(pem_tokenizer.GetNext()); - std::string cert_der(pem_tokenizer.data()); - ASSERT_FALSE(pem_tokenizer.GetNext()); CertErrors errors; // Note: don't actually need to make a ParsedCertificate here, just need @@ -307,9 +336,11 @@ TEST_P(TrustStoreMacImplTest, SystemCerts) { if (is_known_root_test_order == TEST_IS_KNOWN_ROOT_BEFORE) { bool trust_store_is_known_root = trust_store.IsKnownRoot(cert.get()); - { + if (trust_domains == TrustStoreMac::TrustDomains::kAll) { base::AutoLock lock(crypto::GetMacSecurityServicesLock()); EXPECT_EQ(net::IsKnownRoot(cert_handle), trust_store_is_known_root); + } else { + EXPECT_FALSE(trust_store_is_known_root); } } @@ -334,13 +365,26 @@ TEST_P(TrustStoreMacImplTest, SystemCerts) { kSecTrustOptionAllowExpired | kSecTrustOptionAllowExpiredRoot)); - SecTrustResultType trust_result; - ASSERT_EQ(noErr, SecTrustEvaluate(trust, &trust_result)); - bool expected_trust_anchor = - ((trust_result == kSecTrustResultProceed) || - (trust_result == kSecTrustResultUnspecified)) && - (SecTrustGetCertificateCount(trust) == 1); - EXPECT_EQ(expected_trust_anchor, is_trust_anchor); + if (trust_domains == TrustStoreMac::TrustDomains::kUserAndAdmin && + find_certificate_default_search_list_certs.count(cert_der) && + find_certificate_system_roots_certs.count(cert_der)) { + // If the same certificate is present in both the System and User/Admin + // domains, and TrustStoreMac is only using trust settings from + // User/Admin, then it's not possible for this test to know whether the + // result from SecTrustEvaluate should match the TrustStoreMac result. + // Just ignore such certificates. + } else if (trust_domains == TrustStoreMac::TrustDomains::kUserAndAdmin && + !find_certificate_default_search_list_certs.count(cert_der)) { + EXPECT_FALSE(is_trust_anchor); + } else { + SecTrustResultType trust_result; + ASSERT_EQ(noErr, SecTrustEvaluate(trust, &trust_result)); + bool expected_trust_anchor = + ((trust_result == kSecTrustResultProceed) || + (trust_result == kSecTrustResultUnspecified)) && + (SecTrustGetCertificateCount(trust) == 1); + EXPECT_EQ(expected_trust_anchor, is_trust_anchor); + } auto* trust_debug_data = TrustStoreMac::ResultDebugData::Get(&debug_data); ASSERT_TRUE(trust_debug_data); if (is_trust_anchor) { @@ -355,9 +399,11 @@ TEST_P(TrustStoreMacImplTest, SystemCerts) { if (is_known_root_test_order == TEST_IS_KNOWN_ROOT_AFTER) { bool trust_store_is_known_root = trust_store.IsKnownRoot(cert.get()); - { + if (trust_domains == TrustStoreMac::TrustDomains::kAll) { base::AutoLock lock(crypto::GetMacSecurityServicesLock()); EXPECT_EQ(net::IsKnownRoot(cert_handle), trust_store_is_known_root); + } else { + EXPECT_FALSE(trust_store_is_known_root); } } @@ -375,6 +421,20 @@ TEST_P(TrustStoreMacImplTest, SystemCerts) { trust_debug_data2->combined_trust_debug_info()); EXPECT_EQ(trust_debug_data->trust_impl(), trust_debug_data2->trust_impl()); } + + if (trust_impl == TrustStoreMac::TrustImplType::kDomainCacheFullCerts) { + // Since this is testing the actual platform trust settings, we don't know + // what values the histogram should be for each domain, so just verify that + // the histogram is recorded (or not) depending on the requested trust + // domains. + histogram_tester.ExpectTotalCount( + "Net.CertVerifier.MacTrustDomainCertCount.User", 1); + histogram_tester.ExpectTotalCount( + "Net.CertVerifier.MacTrustDomainCertCount.Admin", 1); + histogram_tester.ExpectTotalCount( + "Net.CertVerifier.MacTrustDomainCertCount.System", + (trust_domains == TrustStoreMac::TrustDomains::kAll) ? 1 : 0); + } } INSTANTIATE_TEST_SUITE_P( @@ -383,11 +443,14 @@ INSTANTIATE_TEST_SUITE_P( testing::Combine( testing::Values(TrustStoreMac::TrustImplType::kDomainCache, TrustStoreMac::TrustImplType::kSimple, - TrustStoreMac::TrustImplType::kLruCache), + TrustStoreMac::TrustImplType::kLruCache, + TrustStoreMac::TrustImplType::kDomainCacheFullCerts), // Some TrustImpls may calculate/cache IsKnownRoot values and trust // values independently, so test with calling IsKnownRoot both before // and after GetTrust to try to ensure there is no ordering issue with // which one initializes the cache first. - testing::Values(TEST_IS_KNOWN_ROOT_BEFORE, TEST_IS_KNOWN_ROOT_AFTER))); + testing::Values(TEST_IS_KNOWN_ROOT_BEFORE, TEST_IS_KNOWN_ROOT_AFTER), + testing::Values(TrustStoreMac::TrustDomains::kAll, + TrustStoreMac::TrustDomains::kUserAndAdmin))); } // namespace net diff --git a/chromium/net/cert/internal/trust_store_nss.cc b/chromium/net/cert/internal/trust_store_nss.cc index 07687377dcb..f9d616119a4 100644 --- a/chromium/net/cert/internal/trust_store_nss.cc +++ b/chromium/net/cert/internal/trust_store_nss.cc @@ -9,39 +9,22 @@ #include "base/logging.h" #include "crypto/nss_util.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/trust_store.h" #include "net/cert/known_roots_nss.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/trust_store.h" #include "net/cert/scoped_nss_types.h" -#include "net/cert/test_root_certs.h" #include "net/cert/x509_util.h" #include "net/cert/x509_util_nss.h" namespace net { -TrustStoreNSS::TrustStoreNSS(SECTrustType trust_type) - : trust_type_(trust_type), filter_trusted_certs_by_slot_(false) {} - TrustStoreNSS::TrustStoreNSS(SECTrustType trust_type, - crypto::ScopedPK11Slot user_slot) - : trust_type_(trust_type), - filter_trusted_certs_by_slot_(true), - user_slot_(std::move(user_slot)) { - DCHECK(user_slot_); -} - -TrustStoreNSS::TrustStoreNSS( - SECTrustType trust_type, - DisallowTrustForCertsOnUserSlots disallow_trust_for_certs_on_user_slots) - : trust_type_(trust_type), filter_trusted_certs_by_slot_(true) {} - -TrustStoreNSS::TrustStoreNSS( - SECTrustType trust_type, - IgnoreSystemTrustSettings ignore_system_trust_settings) + SystemTrustSetting system_trust_setting, + UserSlotTrustSetting user_slot_trust_setting) : trust_type_(trust_type), - ignore_system_trust_settings_(true), - filter_trusted_certs_by_slot_(false) {} + ignore_system_trust_settings_(system_trust_setting == kIgnoreSystemTrust), + user_slot_trust_setting_(std::move(user_slot_trust_setting)) {} TrustStoreNSS::~TrustStoreNSS() = default; @@ -148,10 +131,10 @@ CertificateTrust TrustStoreNSS::GetTrust( } bool TrustStoreNSS::IsCertAllowedForTrust(CERTCertificate* cert) const { - // If |filter_trusted_certs_by_slot_| is false, allow trust for any - // certificate, no matter which slot it is stored on. - if (!filter_trusted_certs_by_slot_) + if (absl::holds_alternative<UseTrustFromAllUserSlots>( + user_slot_trust_setting_)) { return true; + } crypto::ScopedPK11SlotList slots_for_cert( PK11_GetAllSlotsForCert(cert, nullptr)); @@ -169,8 +152,11 @@ bool TrustStoreNSS::IsCertAllowedForTrust(CERTCertificate* cert) const { PK11_HasRootCerts(slot) || // Allow read-only internal slots. (PK11_IsInternal(slot) && !PK11_IsRemovable(slot)) || - // Allow |user_slot_| if specified. - (user_slot_ && slot == user_slot_.get()); + // Allow configured user slot if specified. + (absl::holds_alternative<crypto::ScopedPK11Slot>( + user_slot_trust_setting_) && + slot == + absl::get<crypto::ScopedPK11Slot>(user_slot_trust_setting_).get()); if (allow_slot) { PK11_FreeSlotListElement(slots_for_cert.get(), slot_element); diff --git a/chromium/net/cert/internal/trust_store_nss.h b/chromium/net/cert/internal/trust_store_nss.h index 794fedc9604..2eebd88e2bd 100644 --- a/chromium/net/cert/internal/trust_store_nss.h +++ b/chromium/net/cert/internal/trust_store_nss.h @@ -8,10 +8,10 @@ #include <cert.h> #include <certt.h> -#include "base/memory/ref_counted.h" #include "crypto/scoped_nss_types.h" #include "net/base/net_export.h" -#include "net/cert/internal/trust_store.h" +#include "net/cert/pki/trust_store.h" +#include "third_party/abseil-cpp/absl/types/variant.h" namespace net { @@ -19,44 +19,29 @@ namespace net { // anchors for path building. This TrustStore is thread-safe. class NET_EXPORT TrustStoreNSS : public TrustStore { public: - // TODO(hchao): this won't work when we try to get this working for ChromeOS - // as we will likely need to be able to specify multiple options (trust_type, - // user_slot, ignoring_system_certs_unless_distrusted), so we'll need to - // re-engineer to not get combinatorial explosion for constructors. - struct DisallowTrustForCertsOnUserSlots {}; - struct IgnoreSystemTrustSettings {}; + enum SystemTrustSetting { + kUseSystemTrust, + kIgnoreSystemTrust, + }; - // Creates a TrustStoreNSS which will find anchors that are trusted for - // |trust_type|. - // The created TrustStoreNSS will not perform any filtering based on the slot - // certificates are stored on. - explicit TrustStoreNSS(SECTrustType trust_type); - - // Creates a TrustStoreNSS which will find anchors that are trusted for - // |trust_type|. - // The created TrustStoreNSS will allow trust for certificates that: - // (*) are built-in certificates - // (*) are stored on a read-only internal slot - // (*) are stored on the |user_slot|. - TrustStoreNSS(SECTrustType trust_type, crypto::ScopedPK11Slot user_slot); + struct UseTrustFromAllUserSlots : absl::monostate {}; + using UserSlotTrustSetting = + absl::variant<UseTrustFromAllUserSlots, crypto::ScopedPK11Slot>; // Creates a TrustStoreNSS which will find anchors that are trusted for // |trust_type|. - // The created TrustStoreNSS will allow trust for certificates that: - // (*) are built-in certificates - // (*) are stored on a read-only internal slot - TrustStoreNSS( - SECTrustType trust_type, - DisallowTrustForCertsOnUserSlots disallow_trust_for_certs_on_user_slots); - - // Creates a TrustStoreNSS which will find anchors that are trusted for - // |trust_type|. - // The created TrustStoreNSS will ignore system trust settings (but will - // respect user-added certs). // - // TODO(hchao, sleevi): Only ignore builtin trust settings for these certs. + // |system_trust_setting| configures the use of trust from the builtin roots. + // If |system_trust_setting| is kIgnoreSystemTrust, trust settings from the + // builtin roots slot with the Mozilla CA Policy attribute will not be used. + // + // |user_slot_trust_setting| configures the use of trust from user slots: + // * UseTrustFromAllUserSlots: all user slots will be allowed. + // * nullptr: no user slots will be allowed. + // * non-null PK11Slot: the specified slot will be allowed. TrustStoreNSS(SECTrustType trust_type, - IgnoreSystemTrustSettings ignore_system_trust_settings); + SystemTrustSetting system_trust_setting, + UserSlotTrustSetting user_slot_trust_setting); TrustStoreNSS(const TrustStoreNSS&) = delete; TrustStoreNSS& operator=(const TrustStoreNSS&) = delete; @@ -83,25 +68,16 @@ class NET_EXPORT TrustStoreNSS : public TrustStore { // while respecting user-configured trust settings, for these certificates. const bool ignore_system_trust_settings_ = false; - // |filter_trusted_certs_by_slot_| and |user_slot_| together specify which - // slots certificates must be stored on to be allowed to be trusted. The - // possible combinations are: - // - // |filter_trusted_certs_by_slot_| == false: Allow any certificate to be - // trusted, don't filter by slot. |user_slot_| is ignored in this case. + // |user_slot_trust_setting_| specifies which slots certificates must be + // stored on to be allowed to be trusted. The possible values are: // - // |filter_trusted_certs_by_slot_| == true and |user_slot_| = nullptr: Allow - // certificates to be trusted if they - // (*) are built-in certificates or - // (*) are stored on a read-only internal slot. + // |user_slot_trust_setting_| is UseTrustFromAllUserSlots: Allow trust + // settings from any user slots. // - // |filter_trusted_certs_by_slot_| == true and |user_slot_| != nullptr: Allow - // certificates to be trusted if they - // (*) are built-in certificates or - // (*) are stored on a read-only internal slot or - // (*) are stored on |user_slot_|. - const bool filter_trusted_certs_by_slot_; - crypto::ScopedPK11Slot user_slot_; + // |user_slot_trust_setting_| is a ScopedPK11Slot: Allow + // certificates from the specified slot to be trusted. If the slot is nullptr, + // trust from user slots will not be used. + const UserSlotTrustSetting user_slot_trust_setting_; }; } // namespace net diff --git a/chromium/net/cert/internal/trust_store_nss_unittest.cc b/chromium/net/cert/internal/trust_store_nss_unittest.cc index 1d3b4481f69..6bdd0c01a2e 100644 --- a/chromium/net/cert/internal/trust_store_nss_unittest.cc +++ b/chromium/net/cert/internal/trust_store_nss_unittest.cc @@ -13,10 +13,10 @@ #include "base/strings/string_number_conversions.h" #include "crypto/nss_util_internal.h" #include "crypto/scoped_test_nss_db.h" -#include "net/cert/internal/cert_issuer_source_sync_unittest.h" -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/test_helpers.h" #include "net/cert/known_roots_nss.h" +#include "net/cert/pki/cert_issuer_source_sync_unittest.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/test_helpers.h" #include "net/cert/scoped_nss_types.h" #include "net/cert/test_root_certs.h" #include "net/cert/x509_util.h" @@ -51,7 +51,7 @@ bool IsBuiltInRootSlot(PK11SlotInfo* slot) { crypto::ScopedPK11Slot GetBuiltInRootCertsSlot() { crypto::AutoSECMODListReadLock auto_lock; SECMODModuleList* head = SECMOD_GetDefaultModuleList(); - for (SECMODModuleList* item = head; item != NULL; item = item->next) { + for (SECMODModuleList* item = head; item != nullptr; item = item->next) { int slot_count = item->module->loaded ? item->module->slotCount : 0; for (int i = 0; i < slot_count; i++) { PK11SlotInfo* slot = item->module->slots[i]; @@ -298,13 +298,16 @@ class TrustStoreNSSTestWithSlotFilterType std::unique_ptr<TrustStoreNSS> CreateTrustStoreNSS() override { switch (GetParam()) { case SlotFilterType::kDontFilter: - return std::make_unique<TrustStoreNSS>(trustSSL); + return std::make_unique<TrustStoreNSS>( + trustSSL, TrustStoreNSS::kUseSystemTrust, + TrustStoreNSS::UseTrustFromAllUserSlots()); case SlotFilterType::kDoNotAllowUserSlots: return std::make_unique<TrustStoreNSS>( - trustSSL, TrustStoreNSS::DisallowTrustForCertsOnUserSlots()); + trustSSL, TrustStoreNSS::kUseSystemTrust, + /*user_slot_trust_setting=*/nullptr); case SlotFilterType::kAllowSpecifiedUserSlot: return std::make_unique<TrustStoreNSS>( - trustSSL, + trustSSL, TrustStoreNSS::kUseSystemTrust, crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_nssdb_.slot()))); } } @@ -345,7 +348,7 @@ INSTANTIATE_TEST_SUITE_P( SlotFilterType::kDoNotAllowUserSlots, SlotFilterType::kAllowSpecifiedUserSlot)); -// Tests a TrustStoreNSS that ignores root certs +// Tests a TrustStoreNSS that ignores system root certs. class TrustStoreNSSTestIgnoreSystemCerts : public TrustStoreNSSTestBase { public: TrustStoreNSSTestIgnoreSystemCerts() = default; @@ -353,7 +356,8 @@ class TrustStoreNSSTestIgnoreSystemCerts : public TrustStoreNSSTestBase { std::unique_ptr<TrustStoreNSS> CreateTrustStoreNSS() override { return std::make_unique<TrustStoreNSS>( - trustSSL, TrustStoreNSS::IgnoreSystemTrustSettings()); + trustSSL, TrustStoreNSS::kIgnoreSystemTrust, + TrustStoreNSS::UseTrustFromAllUserSlots()); } }; @@ -382,7 +386,9 @@ class TrustStoreNSSTestWithoutSlotFilter : public TrustStoreNSSTestBase { ~TrustStoreNSSTestWithoutSlotFilter() override = default; std::unique_ptr<TrustStoreNSS> CreateTrustStoreNSS() override { - return std::make_unique<TrustStoreNSS>(trustSSL); + return std::make_unique<TrustStoreNSS>( + trustSSL, TrustStoreNSS::kUseSystemTrust, + TrustStoreNSS::UseTrustFromAllUserSlots()); } }; @@ -494,8 +500,9 @@ class TrustStoreNSSTestDoNotAllowUserSlots : public TrustStoreNSSTestBase { ~TrustStoreNSSTestDoNotAllowUserSlots() override = default; std::unique_ptr<TrustStoreNSS> CreateTrustStoreNSS() override { - return std::make_unique<TrustStoreNSS>( - trustSSL, TrustStoreNSS::DisallowTrustForCertsOnUserSlots()); + return std::make_unique<TrustStoreNSS>(trustSSL, + TrustStoreNSS::kUseSystemTrust, + /*user_slot_trust_setting=*/nullptr); } }; @@ -516,7 +523,7 @@ class TrustStoreNSSTestAllowSpecifiedUserSlot : public TrustStoreNSSTestBase { std::unique_ptr<TrustStoreNSS> CreateTrustStoreNSS() override { return std::make_unique<TrustStoreNSS>( - trustSSL, + trustSSL, TrustStoreNSS::kUseSystemTrust, crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_nssdb_.slot()))); } }; @@ -544,7 +551,10 @@ TEST_F(TrustStoreNSSTestAllowSpecifiedUserSlot, CertOnOtherUserSlot) { class TrustStoreNSSTestDelegate { public: - TrustStoreNSSTestDelegate() : trust_store_nss_(trustSSL) {} + TrustStoreNSSTestDelegate() + : trust_store_nss_(trustSSL, + TrustStoreNSS::kUseSystemTrust, + TrustStoreNSS::UseTrustFromAllUserSlots()) {} void AddCert(scoped_refptr<ParsedCertificate> cert) { ASSERT_TRUE(test_nssdb_.is_open()); diff --git a/chromium/net/cert/internal/trust_store_win.cc b/chromium/net/cert/internal/trust_store_win.cc index b1649620e6f..85159c87fa5 100644 --- a/chromium/net/cert/internal/trust_store_win.cc +++ b/chromium/net/cert/internal/trust_store_win.cc @@ -9,8 +9,8 @@ #include "base/memory/ptr_util.h" #include "base/ranges/algorithm.h" #include "base/strings/string_number_conversions.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/parsed_certificate.h" #include "net/cert/x509_util.h" #include "net/third_party/mozilla_win/cert/win_util.h" @@ -43,7 +43,7 @@ namespace { bool IsCertTrustedForServerAuth(PCCERT_CONTEXT cert) { DWORD usage_size = 0; - if (!CertGetEnhancedKeyUsage(cert, 0, NULL, &usage_size)) { + if (!CertGetEnhancedKeyUsage(cert, 0, nullptr, &usage_size)) { return false; } diff --git a/chromium/net/cert/internal/trust_store_win.h b/chromium/net/cert/internal/trust_store_win.h index 833e205e585..4d2fe96e7e6 100644 --- a/chromium/net/cert/internal/trust_store_win.h +++ b/chromium/net/cert/internal/trust_store_win.h @@ -10,7 +10,7 @@ #include "base/win/wincrypt_shim.h" #include "crypto/scoped_capi_types.h" #include "net/base/net_export.h" -#include "net/cert/internal/trust_store.h" +#include "net/cert/pki/trust_store.h" namespace net { diff --git a/chromium/net/cert/internal/trust_store_win_unittest.cc b/chromium/net/cert/internal/trust_store_win_unittest.cc index a01bb8f215c..b1b73c4a92d 100644 --- a/chromium/net/cert/internal/trust_store_win_unittest.cc +++ b/chromium/net/cert/internal/trust_store_win_unittest.cc @@ -13,9 +13,9 @@ #include "base/win/wincrypt_shim.h" #include "crypto/scoped_capi_types.h" #include "net/cert/cert_net_fetcher.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/test_helpers.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/test_helpers.h" #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" #include "net/cert/x509_util_win.h" @@ -65,7 +65,7 @@ bool AddToStore(HCERTSTORE store, const std::string file_name) { X509_ASN_ENCODING, CRYPTO_BUFFER_data(cert->cert_buffer()), CRYPTO_BUFFER_len(cert->cert_buffer()))); return CertAddCertificateContextToStore(store, os_cert.get(), - CERT_STORE_ADD_ALWAYS, NULL); + CERT_STORE_ADD_ALWAYS, nullptr); } // Returns true if cert at file_name successfully added to store with @@ -93,7 +93,7 @@ bool AddToStoreWithEKURestriction(HCERTSTORE store, } } return !!CertAddCertificateContextToStore(store, os_cert.get(), - CERT_STORE_ADD_ALWAYS, NULL); + CERT_STORE_ADD_ALWAYS, nullptr); } // TrustStoreWin isset up as follows: diff --git a/chromium/net/cert/known_roots_mac.cc b/chromium/net/cert/known_roots_mac.cc index 7f105d1468d..383c576f8a3 100644 --- a/chromium/net/cert/known_roots_mac.cc +++ b/chromium/net/cert/known_roots_mac.cc @@ -53,7 +53,7 @@ class OSXKnownRootHelper { OSXKnownRootHelper() { crypto::GetMacSecurityServicesLock().AssertAcquired(); - CFArrayRef cert_array = NULL; + CFArrayRef cert_array = nullptr; OSStatus rv = SecTrustSettingsCopyCertificates( kSecTrustSettingsDomainSystem, &cert_array); if (rv != noErr) { @@ -72,7 +72,7 @@ class OSXKnownRootHelper { std::sort(known_roots_.begin(), known_roots_.end()); } - ~OSXKnownRootHelper() {} + ~OSXKnownRootHelper() = default; std::vector<SHA256HashValue> known_roots_; }; diff --git a/chromium/net/cert/known_roots_nss.cc b/chromium/net/cert/known_roots_nss.cc index edcc608d97e..ab3848b5cc4 100644 --- a/chromium/net/cert/known_roots_nss.cc +++ b/chromium/net/cert/known_roots_nss.cc @@ -64,8 +64,7 @@ bool IsKnownRoot(CERTCertificate* root) { if (PK11_IsPresent(slot) && PK11_HasRootCerts(slot)) { CK_OBJECT_HANDLE handle = PK11_FindCertInSlot(slot, root, nullptr); if (handle != CK_INVALID_HANDLE && - pk11_has_attribute_set(root->slot, handle, - CKA_NSS_MOZILLA_CA_POLICY, + pk11_has_attribute_set(slot, handle, CKA_NSS_MOZILLA_CA_POLICY, PR_FALSE) == CK_TRUE) { return true; } diff --git a/chromium/net/cert/merkle_audit_proof.cc b/chromium/net/cert/merkle_audit_proof.cc index 585ffbbe2b7..46e9f32a05b 100644 --- a/chromium/net/cert/merkle_audit_proof.cc +++ b/chromium/net/cert/merkle_audit_proof.cc @@ -6,8 +6,7 @@ #include "base/check_op.h" -namespace net { -namespace ct { +namespace net::ct { uint64_t CalculateAuditPathLength(uint64_t leaf_index, uint64_t tree_size) { // RFC6962, section 2.1.1, describes audit paths. @@ -39,5 +38,4 @@ MerkleAuditProof::MerkleAuditProof(uint64_t leaf_index, MerkleAuditProof::~MerkleAuditProof() = default; -} // namespace ct -} // namespace net +} // namespace net::ct diff --git a/chromium/net/cert/merkle_audit_proof.h b/chromium/net/cert/merkle_audit_proof.h index 69f2b9c82cf..6aa36205716 100644 --- a/chromium/net/cert/merkle_audit_proof.h +++ b/chromium/net/cert/merkle_audit_proof.h @@ -12,8 +12,7 @@ #include "net/base/net_export.h" -namespace net { -namespace ct { +namespace net::ct { // Returns the length of the audit path for a leaf at |leaf_index| in a Merkle // tree containing |tree_size| leaves. @@ -44,7 +43,6 @@ struct NET_EXPORT MerkleAuditProof { std::vector<std::string> nodes; }; -} // namespace ct -} // namespace net +} // namespace net::ct #endif // NET_CERT_MERKLE_AUDIT_PROOF_H_ diff --git a/chromium/net/cert/merkle_audit_proof_unittest.cc b/chromium/net/cert/merkle_audit_proof_unittest.cc index d4b988029d7..602a58494fc 100644 --- a/chromium/net/cert/merkle_audit_proof_unittest.cc +++ b/chromium/net/cert/merkle_audit_proof_unittest.cc @@ -8,8 +8,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -namespace net { -namespace ct { +namespace net::ct { namespace { TEST(MerkleAuditProofTest, CalculatesAuditPathLengthCorrectly) { @@ -49,5 +48,4 @@ TEST(MerkleAuditProofDeathTest, DiesIfLeafIndexIsGreaterThanOrEqualToTreeSize) { } } // namespace -} // namespace ct -} // namespace net +} // namespace net::ct diff --git a/chromium/net/cert/merkle_consistency_proof.cc b/chromium/net/cert/merkle_consistency_proof.cc index 12ec9366e89..a6ac1bb173c 100644 --- a/chromium/net/cert/merkle_consistency_proof.cc +++ b/chromium/net/cert/merkle_consistency_proof.cc @@ -4,9 +4,7 @@ #include "net/cert/merkle_consistency_proof.h" -namespace net { - -namespace ct { +namespace net::ct { MerkleConsistencyProof::MerkleConsistencyProof() = default; @@ -22,6 +20,4 @@ MerkleConsistencyProof::MerkleConsistencyProof( MerkleConsistencyProof::~MerkleConsistencyProof() = default; -} // namespace ct - -} // namespace net +} // namespace net::ct diff --git a/chromium/net/cert/merkle_consistency_proof.h b/chromium/net/cert/merkle_consistency_proof.h index 48a70dc5eaa..457ed5284dd 100644 --- a/chromium/net/cert/merkle_consistency_proof.h +++ b/chromium/net/cert/merkle_consistency_proof.h @@ -12,9 +12,7 @@ #include "net/base/net_export.h" -namespace net { - -namespace ct { +namespace net::ct { // Consistency proof between two STHs as defined in section 2.1.2. of RFC6962. struct NET_EXPORT MerkleConsistencyProof { @@ -38,8 +36,6 @@ struct NET_EXPORT MerkleConsistencyProof { uint64_t second_tree_size = 0; }; -} // namespace ct - -} // namespace net +} // namespace net::ct #endif // NET_CERT_MERKLE_CONSISTENCY_PROOF_H_ diff --git a/chromium/net/cert/merkle_tree_leaf.cc b/chromium/net/cert/merkle_tree_leaf.cc index 1030213ac25..70ada09872b 100644 --- a/chromium/net/cert/merkle_tree_leaf.cc +++ b/chromium/net/cert/merkle_tree_leaf.cc @@ -9,9 +9,7 @@ #include "net/cert/ct_serialization.h" #include "net/cert/x509_certificate.h" -namespace net { - -namespace ct { +namespace net::ct { MerkleTreeLeaf::MerkleTreeLeaf() = default; @@ -53,6 +51,4 @@ bool GetMerkleTreeLeaf(const X509Certificate* cert, return true; } -} // namespace ct - -} // namespace net +} // namespace net::ct diff --git a/chromium/net/cert/merkle_tree_leaf_unittest.cc b/chromium/net/cert/merkle_tree_leaf_unittest.cc index b2bd82010d5..ed9feace299 100644 --- a/chromium/net/cert/merkle_tree_leaf_unittest.cc +++ b/chromium/net/cert/merkle_tree_leaf_unittest.cc @@ -16,9 +16,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -namespace net { - -namespace ct { +namespace net::ct { namespace { @@ -129,6 +127,4 @@ TEST_F(MerkleTreeLeafTest, HashForPrecert) { } // namespace -} // namespace ct - -} // namespace net +} // namespace net::ct diff --git a/chromium/net/cert/nss_cert_database.cc b/chromium/net/cert/nss_cert_database.cc index 135e0f1a489..7f1c1290f3b 100644 --- a/chromium/net/cert/nss_cert_database.cc +++ b/chromium/net/cert/nss_cert_database.cc @@ -17,6 +17,7 @@ #include "base/bind.h" #include "base/callback.h" #include "base/logging.h" +#include "base/memory/raw_ptr.h" #include "base/observer_list_threadsafe.h" #include "base/task/thread_pool.h" #include "base/threading/scoped_blocking_call.h" @@ -65,7 +66,7 @@ class CertNotificationForwarder : public NSSCertDatabase::Observer { void OnCertDBChanged() override { cert_db_->NotifyObserversCertDBChanged(); } private: - CertDatabase* cert_db_; + raw_ptr<CertDatabase> cert_db_; }; } // namespace @@ -90,7 +91,8 @@ NSSCertDatabase::NSSCertDatabase(crypto::ScopedPK11Slot public_slot, crypto::ScopedPK11Slot private_slot) : public_slot_(std::move(public_slot)), private_slot_(std::move(private_slot)), - observer_list_(new base::ObserverListThreadSafe<Observer>) { + observer_list_( + base::MakeRefCounted<base::ObserverListThreadSafe<Observer>>()) { CHECK(public_slot_); CertDatabase* cert_db = CertDatabase::GetInstance(); diff --git a/chromium/net/cert/nss_cert_database.h b/chromium/net/cert/nss_cert_database.h index cfc4f176808..e8d45d7bbdc 100644 --- a/chromium/net/cert/nss_cert_database.h +++ b/chromium/net/cert/nss_cert_database.h @@ -40,14 +40,14 @@ class NET_EXPORT NSSCertDatabase { Observer(const Observer&) = delete; Observer& operator=(const Observer&) = delete; - virtual ~Observer() {} + virtual ~Observer() = default; // Will be called when a certificate is added, removed, or trust settings // are changed. virtual void OnCertDBChanged() {} protected: - Observer() {} + Observer() = default; }; // Holds an NSS certificate along with additional information. diff --git a/chromium/net/cert/nss_profile_filter_chromeos.cc b/chromium/net/cert/nss_profile_filter_chromeos.cc index 85dc7b6e930..d85ac42b13b 100644 --- a/chromium/net/cert/nss_profile_filter_chromeos.cc +++ b/chromium/net/cert/nss_profile_filter_chromeos.cc @@ -18,28 +18,30 @@ NSSProfileFilterChromeOS::NSSProfileFilterChromeOS() = default; NSSProfileFilterChromeOS::NSSProfileFilterChromeOS( const NSSProfileFilterChromeOS& other) { - public_slot_.reset(other.public_slot_ ? - PK11_ReferenceSlot(other.public_slot_.get()) : - NULL); - private_slot_.reset(other.private_slot_ ? - PK11_ReferenceSlot(other.private_slot_.get()) : - NULL); - system_slot_.reset( - other.system_slot_ ? PK11_ReferenceSlot(other.system_slot_.get()) : NULL); + public_slot_.reset(other.public_slot_ + ? PK11_ReferenceSlot(other.public_slot_.get()) + : nullptr); + private_slot_.reset(other.private_slot_ + ? PK11_ReferenceSlot(other.private_slot_.get()) + : nullptr); + system_slot_.reset(other.system_slot_ + ? PK11_ReferenceSlot(other.system_slot_.get()) + : nullptr); } NSSProfileFilterChromeOS::~NSSProfileFilterChromeOS() = default; NSSProfileFilterChromeOS& NSSProfileFilterChromeOS::operator=( const NSSProfileFilterChromeOS& other) { - public_slot_.reset(other.public_slot_ ? - PK11_ReferenceSlot(other.public_slot_.get()) : - NULL); - private_slot_.reset(other.private_slot_ ? - PK11_ReferenceSlot(other.private_slot_.get()) : - NULL); - system_slot_.reset( - other.system_slot_ ? PK11_ReferenceSlot(other.system_slot_.get()) : NULL); + public_slot_.reset(other.public_slot_ + ? PK11_ReferenceSlot(other.public_slot_.get()) + : nullptr); + private_slot_.reset(other.private_slot_ + ? PK11_ReferenceSlot(other.private_slot_.get()) + : nullptr); + system_slot_.reset(other.system_slot_ + ? PK11_ReferenceSlot(other.system_slot_.get()) + : nullptr); return *this; } @@ -94,7 +96,7 @@ bool NSSProfileFilterChromeOS::IsModuleAllowed(PK11SlotInfo* slot) const { bool NSSProfileFilterChromeOS::IsCertAllowed(CERTCertificate* cert) const { crypto::ScopedPK11SlotList slots_for_cert( - PK11_GetAllSlotsForCert(cert, NULL)); + PK11_GetAllSlotsForCert(cert, nullptr)); if (!slots_for_cert) return false; diff --git a/chromium/net/cert/nss_profile_filter_chromeos_unittest.cc b/chromium/net/cert/nss_profile_filter_chromeos_unittest.cc index 7a4b8024928..0a21f961ce9 100644 --- a/chromium/net/cert/nss_profile_filter_chromeos_unittest.cc +++ b/chromium/net/cert/nss_profile_filter_chromeos_unittest.cc @@ -28,7 +28,7 @@ namespace { crypto::ScopedPK11Slot GetRootCertsSlot() { crypto::AutoSECMODListReadLock auto_lock; SECMODModuleList* head = SECMOD_GetDefaultModuleList(); - for (SECMODModuleList* item = head; item != NULL; item = item->next) { + for (SECMODModuleList* item = head; item != nullptr; item = item->next) { int slot_count = item->module->loaded ? item->module->slotCount : 0; for (int i = 0; i < slot_count; i++) { PK11SlotInfo* slot = item->module->slots[i]; @@ -121,7 +121,7 @@ class NSSProfileFilterChromeOSTest : public testing::Test { }; TEST_F(NSSProfileFilterChromeOSTest, TempCertNotAllowed) { - EXPECT_EQ(NULL, certs_[0]->slot); + EXPECT_EQ(nullptr, certs_[0]->slot); EXPECT_FALSE(no_slots_profile_filter_.IsCertAllowed(certs_[0].get())); EXPECT_FALSE(profile_filter_1_.IsCertAllowed(certs_[0].get())); EXPECT_FALSE(profile_filter_1_copy_.IsCertAllowed(certs_[0].get())); diff --git a/chromium/net/cert/pem.cc b/chromium/net/cert/pem.cc index cc2e48b6542..fe37b197b07 100644 --- a/chromium/net/cert/pem.cc +++ b/chromium/net/cert/pem.cc @@ -90,12 +90,13 @@ void PEMTokenizer::Init(const StringPiece& str, // Construct PEM header/footer strings for all the accepted types, to // reduce parsing later. - for (auto it = allowed_block_types.begin(); it != allowed_block_types.end(); - ++it) { + for (const auto& allowed_block_type : allowed_block_types) { PEMType allowed_type; - allowed_type.type = *it; - allowed_type.header = base::StringPrintf(kPEMBeginBlock, it->c_str()); - allowed_type.footer = base::StringPrintf(kPEMEndBlock, it->c_str()); + allowed_type.type = allowed_block_type; + allowed_type.header = + base::StringPrintf(kPEMBeginBlock, allowed_block_type.c_str()); + allowed_type.footer = + base::StringPrintf(kPEMEndBlock, allowed_block_type.c_str()); block_types_.push_back(allowed_type); } } diff --git a/chromium/net/cert/pki/README.md b/chromium/net/cert/pki/README.md new file mode 100644 index 00000000000..9e936b61b99 --- /dev/null +++ b/chromium/net/cert/pki/README.md @@ -0,0 +1,11 @@ +# Web PKI Certificate path building and verification + +This directory contains the core internal code used for path building +and verifying certificates. This is existing temporarily in this +directory while changes are made to remove chromium specific +dependencies. This code will be moving to it's own separate library +in boringssl (Issue 1322914). + +Please do not depend on this directory continuing to exist, and please +try to avoid adding dependencies on anything in this directory from +outside of //net/cert. diff --git a/chromium/net/cert/internal/cert_error_id.cc b/chromium/net/cert/pki/cert_error_id.cc index 80ab4f4f214..793b92ffb2c 100644 --- a/chromium/net/cert/internal/cert_error_id.cc +++ b/chromium/net/cert/pki/cert_error_id.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/cert_error_id.h" +#include "net/cert/pki/cert_error_id.h" namespace net { diff --git a/chromium/net/cert/internal/cert_error_id.h b/chromium/net/cert/pki/cert_error_id.h index 63a01679816..1c0e4ec947b 100644 --- a/chromium/net/cert/internal/cert_error_id.h +++ b/chromium/net/cert/pki/cert_error_id.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_CERT_ERROR_ID_H_ -#define NET_CERT_INTERNAL_CERT_ERROR_ID_H_ +#ifndef NET_CERT_PKI_CERT_ERROR_ID_H_ +#define NET_CERT_PKI_CERT_ERROR_ID_H_ #include "net/base/net_export.h" @@ -34,4 +34,4 @@ NET_EXPORT const char* CertErrorIdToDebugString(CertErrorId id); } // namespace net -#endif // NET_CERT_INTERNAL_CERT_ERROR_ID_H_ +#endif // NET_CERT_PKI_CERT_ERROR_ID_H_ diff --git a/chromium/net/cert/internal/cert_error_params.cc b/chromium/net/cert/pki/cert_error_params.cc index eff1dbfcf0c..0d4f2b61d83 100644 --- a/chromium/net/cert/internal/cert_error_params.cc +++ b/chromium/net/cert/pki/cert_error_params.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/cert_error_params.h" +#include "net/cert/pki/cert_error_params.h" #include <memory> diff --git a/chromium/net/cert/internal/cert_error_params.h b/chromium/net/cert/pki/cert_error_params.h index dc696e78afd..b00d0f2e8a4 100644 --- a/chromium/net/cert/internal/cert_error_params.h +++ b/chromium/net/cert/pki/cert_error_params.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_CERT_ERROR_PARAMS_H_ -#define NET_CERT_INTERNAL_CERT_ERROR_PARAMS_H_ +#ifndef NET_CERT_PKI_CERT_ERROR_PARAMS_H_ +#define NET_CERT_PKI_CERT_ERROR_PARAMS_H_ #include <memory> #include <string> @@ -64,4 +64,4 @@ NET_EXPORT std::unique_ptr<CertErrorParams> CreateCertErrorParams2SizeT( } // namespace net -#endif // NET_CERT_INTERNAL_CERT_ERROR_PARAMS_H_ +#endif // NET_CERT_PKI_CERT_ERROR_PARAMS_H_ diff --git a/chromium/net/cert/internal/cert_errors.cc b/chromium/net/cert/pki/cert_errors.cc index cea2115ee8e..833fb1d3638 100644 --- a/chromium/net/cert/internal/cert_errors.cc +++ b/chromium/net/cert/pki/cert_errors.cc @@ -2,14 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/cert_errors.h" +#include "net/cert/pki/cert_errors.h" -#include "base/strings/strcat.h" -#include "base/strings/string_split.h" -#include "base/strings/stringprintf.h" -#include "net/cert/internal/cert_error_params.h" -#include "net/cert/internal/parse_name.h" -#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/pki/cert_error_params.h" +#include "net/cert/pki/parse_name.h" +#include "net/cert/pki/parsed_certificate.h" + +#include <sstream> namespace net { @@ -18,11 +17,11 @@ namespace { void AppendLinesWithIndentation(const std::string& text, const std::string& indentation, std::string* out) { - std::vector<base::StringPiece> lines = base::SplitStringPieceUsingSubstr( - text, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); - - for (const auto& line : lines) { - base::StrAppend(out, {indentation, line, "\n"}); + std::istringstream stream(text); + for (std::string line; std::getline(stream, line, '\n');) { + out->append(indentation); + out->append(line); + out->append("\n"); } } @@ -68,7 +67,7 @@ CertErrors::~CertErrors() = default; void CertErrors::Add(CertError::Severity severity, CertErrorId id, std::unique_ptr<CertErrorParams> params) { - nodes_.push_back(CertError(severity, id, std::move(params))); + nodes_.emplace_back(severity, id, std::move(params)); } void CertErrors::AddError(CertErrorId id, @@ -164,7 +163,7 @@ bool CertPathErrors::ContainsAnyErrorWithSeverity( std::string CertPathErrors::ToDebugString( const ParsedCertificateList& certs) const { - std::string result; + std::ostringstream result; for (size_t i = 0; i < cert_errors_.size(); ++i) { // Pretty print the current CertErrors. If there were no errors/warnings, @@ -184,25 +183,19 @@ std::string CertPathErrors::ToDebugString( cert_name_debug_str = " (" + cert_name_debug_str + ")"; } } - - result += - base::StringPrintf("----- Certificate i=%d%s -----\n", - static_cast<int>(i), cert_name_debug_str.c_str()); - - result += cert_errors_string; - result += "\n"; + result << "----- Certificate i=" << i << cert_name_debug_str << " -----\n"; + result << cert_errors_string << "\n"; } // Print any other errors that aren't associated with a particular certificate // in the chain. std::string other_errors = other_errors_.ToDebugString(); if (!other_errors.empty()) { - result += "----- Other errors (not certificate specific) -----\n"; - result += other_errors; - result += "\n"; + result << "----- Other errors (not certificate specific) -----\n"; + result << other_errors << "\n"; } - return result; + return result.str(); } } // namespace net diff --git a/chromium/net/cert/internal/cert_errors.h b/chromium/net/cert/pki/cert_errors.h index 05bc02b68b6..98f635da34b 100644 --- a/chromium/net/cert/internal/cert_errors.h +++ b/chromium/net/cert/pki/cert_errors.h @@ -43,16 +43,16 @@ // Error IDs are in truth string literals, whose pointer value will be unique // per process. -#ifndef NET_CERT_INTERNAL_CERT_ERRORS_H_ -#define NET_CERT_INTERNAL_CERT_ERRORS_H_ +#ifndef NET_CERT_PKI_CERT_ERRORS_H_ +#define NET_CERT_PKI_CERT_ERRORS_H_ #include <memory> #include <vector> #include "base/compiler_specific.h" #include "net/base/net_export.h" -#include "net/cert/internal/cert_error_id.h" -#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/pki/cert_error_id.h" +#include "net/cert/pki/parsed_certificate.h" namespace net { @@ -165,4 +165,4 @@ class NET_EXPORT CertPathErrors { } // namespace net -#endif // NET_CERT_INTERNAL_CERT_ERRORS_H_ +#endif // NET_CERT_PKI_CERT_ERRORS_H_ diff --git a/chromium/net/cert/internal/cert_issuer_source.h b/chromium/net/cert/pki/cert_issuer_source.h index 8127203cede..1568cd058f3 100644 --- a/chromium/net/cert/internal/cert_issuer_source.h +++ b/chromium/net/cert/pki/cert_issuer_source.h @@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_CERT_ISSUER_SOURCE_H_ -#define NET_CERT_INTERNAL_CERT_ISSUER_SOURCE_H_ +#ifndef NET_CERT_PKI_CERT_ISSUER_SOURCE_H_ +#define NET_CERT_PKI_CERT_ISSUER_SOURCE_H_ #include <memory> #include <vector> #include "net/base/net_export.h" -#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/pki/parsed_certificate.h" namespace net { @@ -64,4 +64,4 @@ class NET_EXPORT CertIssuerSource { } // namespace net -#endif // NET_CERT_INTERNAL_CERT_ISSUER_SOURCE_H_ +#endif // NET_CERT_PKI_CERT_ISSUER_SOURCE_H_ diff --git a/chromium/net/cert/internal/cert_issuer_source_static.cc b/chromium/net/cert/pki/cert_issuer_source_static.cc index e6ddb27b39f..c41aede9d6f 100644 --- a/chromium/net/cert/internal/cert_issuer_source_static.cc +++ b/chromium/net/cert/pki/cert_issuer_source_static.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/cert_issuer_source_static.h" +#include "net/cert/pki/cert_issuer_source_static.h" namespace net { @@ -14,6 +14,10 @@ void CertIssuerSourceStatic::AddCert(scoped_refptr<ParsedCertificate> cert) { cert->normalized_subject().AsStringPiece(), std::move(cert))); } +void CertIssuerSourceStatic::Clear() { + intermediates_.clear(); +} + void CertIssuerSourceStatic::SyncGetIssuersOf(const ParsedCertificate* cert, ParsedCertificateList* issuers) { auto range = diff --git a/chromium/net/cert/internal/cert_issuer_source_static.h b/chromium/net/cert/pki/cert_issuer_source_static.h index 39d3187c8e3..c3be882d023 100644 --- a/chromium/net/cert/internal/cert_issuer_source_static.h +++ b/chromium/net/cert/pki/cert_issuer_source_static.h @@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_CERT_ISSUER_SOURCE_STATIC_H_ -#define NET_CERT_INTERNAL_CERT_ISSUER_SOURCE_STATIC_H_ +#ifndef NET_CERT_PKI_CERT_ISSUER_SOURCE_STATIC_H_ +#define NET_CERT_PKI_CERT_ISSUER_SOURCE_STATIC_H_ #include <unordered_map> #include "base/strings/string_piece.h" #include "net/base/net_export.h" -#include "net/cert/internal/cert_issuer_source.h" +#include "net/cert/pki/cert_issuer_source.h" namespace net { @@ -27,6 +27,9 @@ class NET_EXPORT CertIssuerSourceStatic : public CertIssuerSource { // provide. void AddCert(scoped_refptr<ParsedCertificate> cert); + // Clears the set of certificates. + void Clear(); + // CertIssuerSource implementation: void SyncGetIssuersOf(const ParsedCertificate* cert, ParsedCertificateList* issuers) override; @@ -44,4 +47,4 @@ class NET_EXPORT CertIssuerSourceStatic : public CertIssuerSource { } // namespace net -#endif // NET_CERT_INTERNAL_CERT_ISSUER_SOURCE_STATIC_H_ +#endif // NET_CERT_PKI_CERT_ISSUER_SOURCE_STATIC_H_ diff --git a/chromium/net/cert/internal/cert_issuer_source_static_unittest.cc b/chromium/net/cert/pki/cert_issuer_source_static_unittest.cc index 9dd45d0c9b0..02727cc6724 100644 --- a/chromium/net/cert/internal/cert_issuer_source_static_unittest.cc +++ b/chromium/net/cert/pki/cert_issuer_source_static_unittest.cc @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/cert_issuer_source_static.h" +#include "net/cert/pki/cert_issuer_source_static.h" -#include "net/cert/internal/cert_issuer_source_sync_unittest.h" -#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/pki/cert_issuer_source_sync_unittest.h" +#include "net/cert/pki/parsed_certificate.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { diff --git a/chromium/net/cert/internal/cert_issuer_source_sync_unittest.h b/chromium/net/cert/pki/cert_issuer_source_sync_unittest.h index 7d4548b1f0b..e3f165036db 100644 --- a/chromium/net/cert/internal/cert_issuer_source_sync_unittest.h +++ b/chromium/net/cert/pki/cert_issuer_source_sync_unittest.h @@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_CERT_ISSUER_SOURCE_SYNC_UNITTEST_H_ -#define NET_CERT_INTERNAL_CERT_ISSUER_SOURCE_SYNC_UNITTEST_H_ +#ifndef NET_CERT_PKI_CERT_ISSUER_SOURCE_SYNC_UNITTEST_H_ +#define NET_CERT_PKI_CERT_ISSUER_SOURCE_SYNC_UNITTEST_H_ #include <algorithm> -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/cert_issuer_source.h" -#include "net/cert/internal/test_helpers.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/cert_issuer_source.h" +#include "net/cert/pki/test_helpers.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/boringssl/src/include/openssl/pool.h" @@ -213,4 +213,4 @@ REGISTER_TYPED_TEST_SUITE_P(CertIssuerSourceSyncNotNormalizedTest, } // namespace net -#endif // NET_CERT_INTERNAL_CERT_ISSUER_SOURCE_SYNC_UNITTEST_H_ +#endif // NET_CERT_PKI_CERT_ISSUER_SOURCE_SYNC_UNITTEST_H_ diff --git a/chromium/net/cert/internal/certificate_policies.cc b/chromium/net/cert/pki/certificate_policies.cc index be5240f6bbd..e7a3c17e435 100644 --- a/chromium/net/cert/internal/certificate_policies.cc +++ b/chromium/net/cert/pki/certificate_policies.cc @@ -4,10 +4,10 @@ #include <algorithm> -#include "net/cert/internal/certificate_policies.h" +#include "net/cert/pki/certificate_policies.h" -#include "net/cert/internal/cert_error_params.h" -#include "net/cert/internal/cert_errors.h" +#include "net/cert/pki/cert_error_params.h" +#include "net/cert/pki/cert_errors.h" #include "net/der/input.h" #include "net/der/parse_values.h" #include "net/der/parser.h" diff --git a/chromium/net/cert/internal/certificate_policies.h b/chromium/net/cert/pki/certificate_policies.h index 7ca38f9bd3e..182bf9a82f5 100644 --- a/chromium/net/cert/internal/certificate_policies.h +++ b/chromium/net/cert/pki/certificate_policies.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_CERTIFICATE_POLICIES_H_ -#define NET_CERT_INTERNAL_CERTIFICATE_POLICIES_H_ +#ifndef NET_CERT_PKI_CERTIFICATE_POLICIES_H_ +#define NET_CERT_PKI_CERTIFICATE_POLICIES_H_ #include <stdint.h> @@ -132,4 +132,4 @@ struct ParsedPolicyMapping { } // namespace net -#endif // NET_CERT_INTERNAL_CERTIFICATE_POLICIES_H_ +#endif // NET_CERT_PKI_CERTIFICATE_POLICIES_H_ diff --git a/chromium/net/cert/internal/certificate_policies_unittest.cc b/chromium/net/cert/pki/certificate_policies_unittest.cc index 92267559e0e..b38aff49a73 100644 --- a/chromium/net/cert/internal/certificate_policies_unittest.cc +++ b/chromium/net/cert/pki/certificate_policies_unittest.cc @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/certificate_policies.h" +#include "net/cert/pki/certificate_policies.h" -#include "net/cert/internal/test_helpers.h" +#include "net/cert/pki/test_helpers.h" #include "net/der/input.h" #include "net/der/parser.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chromium/net/cert/internal/common_cert_errors.cc b/chromium/net/cert/pki/common_cert_errors.cc index 3aa4cefa214..d282999c472 100644 --- a/chromium/net/cert/internal/common_cert_errors.cc +++ b/chromium/net/cert/pki/common_cert_errors.cc @@ -2,11 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/common_cert_errors.h" +#include "net/cert/pki/common_cert_errors.h" -namespace net { - -namespace cert_errors { +namespace net::cert_errors { DEFINE_CERT_ERROR_ID(kInternalError, "Internal error"); DEFINE_CERT_ERROR_ID(kValidityFailedNotAfter, "Time is after notAfter"); @@ -65,6 +63,4 @@ DEFINE_CERT_ERROR_ID(kDeadlineExceeded, "Deadline exceeded"); DEFINE_CERT_ERROR_ID(kIterationLimitExceeded, "Iteration limit exceeded"); DEFINE_CERT_ERROR_ID(kDepthLimitExceeded, "Depth limit exceeded"); -} // namespace cert_errors - -} // namespace net +} // namespace net::cert_errors diff --git a/chromium/net/cert/internal/common_cert_errors.h b/chromium/net/cert/pki/common_cert_errors.h index 46625962ba9..2819671f4c9 100644 --- a/chromium/net/cert/internal/common_cert_errors.h +++ b/chromium/net/cert/pki/common_cert_errors.h @@ -2,19 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_COMMON_CERT_ERRORS_H_ -#define NET_CERT_INTERNAL_COMMON_CERT_ERRORS_H_ +#ifndef NET_CERT_PKI_COMMON_CERT_ERRORS_H_ +#define NET_CERT_PKI_COMMON_CERT_ERRORS_H_ #include "net/base/net_export.h" -#include "net/cert/internal/cert_errors.h" +#include "net/cert/pki/cert_errors.h" // This file contains the set of "default" certificate errors (those // defined by the core verification/path building code). // // Errors may be defined for other domains. -namespace net { - -namespace cert_errors { +namespace net::cert_errors { // An internal error occurred which prevented path building or verification // from finishing. @@ -142,8 +140,6 @@ NET_EXPORT extern const CertErrorId kIterationLimitExceeded; // Depth limit was reached during path building. NET_EXPORT extern const CertErrorId kDepthLimitExceeded; -} // namespace cert_errors - -} // namespace net +} // namespace net::cert_errors -#endif // NET_CERT_INTERNAL_COMMON_CERT_ERRORS_H_ +#endif // NET_CERT_PKI_COMMON_CERT_ERRORS_H_ diff --git a/chromium/net/cert/internal/crl.cc b/chromium/net/cert/pki/crl.cc index 450b452b15b..c3a0c9dc5fa 100644 --- a/chromium/net/cert/internal/crl.cc +++ b/chromium/net/cert/pki/crl.cc @@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/crl.h" +#include "net/cert/pki/crl.h" #include "base/stl_util.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/revocation_util.h" -#include "net/cert/internal/signature_algorithm.h" -#include "net/cert/internal/verify_name_match.h" -#include "net/cert/internal/verify_signed_data.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/revocation_util.h" +#include "net/cert/pki/signature_algorithm.h" +#include "net/cert/pki/verify_name_match.h" +#include "net/cert/pki/verify_signed_data.h" #include "net/der/input.h" #include "net/der/parse_values.h" #include "net/der/parser.h" @@ -401,18 +401,24 @@ CRLRevocationStatus CheckCRL(base::StringPiece raw_crl, return CRLRevocationStatus::UNKNOWN; // 5.1.1.2 signatureAlgorithm + // + // TODO(https://crbug.com/749276): Check the signature algorithm against + // policy. + absl::optional<SignatureAlgorithm> signature_algorithm = + ParseSignatureAlgorithm(signature_algorithm_tlv, + /*errors=*/nullptr); + if (!signature_algorithm) { + return CRLRevocationStatus::UNKNOWN; + } + // This field MUST contain the same algorithm identifier as the // signature field in the sequence tbsCertList (Section 5.1.2.2). - if (!SignatureAlgorithm::IsEquivalent( - signature_algorithm_tlv, tbs_cert_list.signature_algorithm_tlv)) { + absl::optional<SignatureAlgorithm> tbs_alg = + ParseSignatureAlgorithm(tbs_cert_list.signature_algorithm_tlv, + /*errors=*/nullptr); + if (!tbs_alg || *signature_algorithm != *tbs_alg) { return CRLRevocationStatus::UNKNOWN; } - // TODO(https://crbug.com/749276): Check the signature algorithm against - // policy. - std::unique_ptr<SignatureAlgorithm> signature_algorithm = - SignatureAlgorithm::Create(signature_algorithm_tlv, /*errors=*/nullptr); - if (!signature_algorithm) - return CRLRevocationStatus::UNKNOWN; // Check CRL dates. Roughly corresponds to 6.3.3 (a) (1) but does not attempt // to update the CRL if it is out of date. diff --git a/chromium/net/cert/internal/crl.h b/chromium/net/cert/pki/crl.h index 3b433acfd94..e6add49add4 100644 --- a/chromium/net/cert/internal/crl.h +++ b/chromium/net/cert/pki/crl.h @@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_CRL_H_ -#define NET_CERT_INTERNAL_CRL_H_ +#ifndef NET_CERT_PKI_CRL_H_ +#define NET_CERT_PKI_CRL_H_ #include "base/strings/string_piece_forward.h" #include "base/time/time.h" #include "net/base/net_export.h" -#include "net/cert/internal/general_names.h" -#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/pki/general_names.h" +#include "net/cert/pki/parsed_certificate.h" #include "net/der/input.h" #include "net/der/parse_values.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -221,4 +221,4 @@ CheckCRL(base::StringPiece raw_crl, } // namespace net -#endif // NET_CERT_INTERNAL_CRL_H_ +#endif // NET_CERT_PKI_CRL_H_ diff --git a/chromium/net/cert/internal/extended_key_usage.cc b/chromium/net/cert/pki/extended_key_usage.cc index c7838737bfd..e4e97b30175 100644 --- a/chromium/net/cert/internal/extended_key_usage.cc +++ b/chromium/net/cert/pki/extended_key_usage.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/extended_key_usage.h" +#include "net/cert/pki/extended_key_usage.h" #include "net/der/input.h" #include "net/der/parser.h" diff --git a/chromium/net/cert/internal/extended_key_usage.h b/chromium/net/cert/pki/extended_key_usage.h index 363c8afcdbf..f2ce9eb3e36 100644 --- a/chromium/net/cert/internal/extended_key_usage.h +++ b/chromium/net/cert/pki/extended_key_usage.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_EXTENDED_KEY_USAGE_H_ -#define NET_CERT_INTERNAL_EXTENDED_KEY_USAGE_H_ +#ifndef NET_CERT_PKI_EXTENDED_KEY_USAGE_H_ +#define NET_CERT_PKI_EXTENDED_KEY_USAGE_H_ #include <vector> @@ -85,4 +85,4 @@ NET_EXPORT bool ParseEKUExtension(const der::Input& extension_value, } // namespace net -#endif // NET_CERT_INTERNAL_EXTENDED_KEY_USAGE_H_ +#endif // NET_CERT_PKI_EXTENDED_KEY_USAGE_H_ diff --git a/chromium/net/cert/internal/extended_key_usage_unittest.cc b/chromium/net/cert/pki/extended_key_usage_unittest.cc index a8bd055938d..f98ad799882 100644 --- a/chromium/net/cert/internal/extended_key_usage_unittest.cc +++ b/chromium/net/cert/pki/extended_key_usage_unittest.cc @@ -4,7 +4,7 @@ #include <algorithm> -#include "net/cert/internal/extended_key_usage.h" +#include "net/cert/pki/extended_key_usage.h" #include "net/der/input.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chromium/net/cert/internal/general_names.cc b/chromium/net/cert/pki/general_names.cc index b8d6b9a630e..0a598dd24fe 100644 --- a/chromium/net/cert/internal/general_names.cc +++ b/chromium/net/cert/pki/general_names.cc @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/general_names.h" +#include "net/cert/pki/general_names.h" #include "base/check_op.h" #include "base/strings/string_util.h" -#include "net/cert/internal/cert_error_params.h" -#include "net/cert/internal/cert_errors.h" +#include "net/cert/pki/cert_error_params.h" +#include "net/cert/pki/cert_errors.h" #include "net/der/input.h" #include "net/der/parser.h" #include "net/der/tag.h" @@ -85,7 +85,7 @@ std::unique_ptr<GeneralNames> GeneralNames::CreateFromValue( CertErrors* errors) { DCHECK(errors); - std::unique_ptr<GeneralNames> general_names(new GeneralNames()); + auto general_names = std::make_unique<GeneralNames>(); der::Parser sequence_parser(general_names_value); // The GeneralNames sequence should have at least 1 element. @@ -190,8 +190,7 @@ std::unique_ptr<GeneralNames> GeneralNames::CreateFromValue( errors->AddError(kFailedParsingIp); return false; } - subtrees->ip_addresses.push_back( - IPAddress(value.UnsafeData(), value.Length())); + subtrees->ip_addresses.emplace_back(value.UnsafeData(), value.Length()); } else { DCHECK_EQ(ip_address_type, GeneralNames::IP_ADDRESS_AND_NETMASK); // RFC 5280 section 4.2.1.10: @@ -216,9 +215,9 @@ std::unique_ptr<GeneralNames> GeneralNames::CreateFromValue( errors->AddError(kFailedParsingIp); return false; } - subtrees->ip_address_ranges.push_back( - std::make_pair(IPAddress(value.UnsafeData(), value.Length() / 2), - mask_prefix_length)); + subtrees->ip_address_ranges.emplace_back( + IPAddress(value.UnsafeData(), value.Length() / 2), + mask_prefix_length); } } else if (tag == der::ContextSpecificPrimitive(8)) { // registeredID [8] OBJECT IDENTIFIER } diff --git a/chromium/net/cert/internal/general_names.h b/chromium/net/cert/pki/general_names.h index 87ef0756407..0bacddfe98e 100644 --- a/chromium/net/cert/internal/general_names.h +++ b/chromium/net/cert/pki/general_names.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_GENERAL_NAMES_H_ -#define NET_CERT_INTERNAL_GENERAL_NAMES_H_ +#ifndef NET_CERT_PKI_GENERAL_NAMES_H_ +#define NET_CERT_PKI_GENERAL_NAMES_H_ #include <memory> #include <vector> @@ -11,7 +11,7 @@ #include "base/strings/string_piece_forward.h" #include "net/base/ip_address.h" #include "net/base/net_export.h" -#include "net/cert/internal/cert_error_id.h" +#include "net/cert/pki/cert_error_id.h" namespace net { @@ -121,4 +121,4 @@ struct NET_EXPORT GeneralNames { } // namespace net -#endif // NET_CERT_INTERNAL_GENERAL_NAMES_H_ +#endif // NET_CERT_PKI_GENERAL_NAMES_H_ diff --git a/chromium/net/cert/internal/name_constraints.cc b/chromium/net/cert/pki/name_constraints.cc index 72f21c1f3b1..b66abdbef6c 100644 --- a/chromium/net/cert/internal/name_constraints.cc +++ b/chromium/net/cert/pki/name_constraints.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/name_constraints.h" +#include "net/cert/pki/name_constraints.h" #include <limits.h> @@ -11,9 +11,9 @@ #include "base/check.h" #include "base/numerics/clamped_math.h" #include "base/strings/string_util.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/common_cert_errors.h" -#include "net/cert/internal/verify_name_match.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/common_cert_errors.h" +#include "net/cert/pki/verify_name_match.h" #include "net/der/input.h" #include "net/der/parser.h" #include "net/der/tag.h" @@ -138,9 +138,9 @@ bool DNSNameMatches(base::StringPiece name, if (!subtree_sequence.ReadRawTLV(&raw_general_name)) return false; - if (!ParseGeneralName( - raw_general_name, - GeneralNames::IP_ADDRESS_AND_NETMASK, subtrees, errors)) { + if (!ParseGeneralName(raw_general_name, + GeneralNames::IP_ADDRESS_AND_NETMASK, subtrees, + errors)) { errors->AddError(kFailedParsingGeneralName); return false; } @@ -174,7 +174,7 @@ std::unique_ptr<NameConstraints> NameConstraints::Create( CertErrors* errors) { DCHECK(errors); - std::unique_ptr<NameConstraints> name_constraints(new NameConstraints()); + auto name_constraints = std::make_unique<NameConstraints>(); if (!name_constraints->Parse(extension_value, is_critical, errors)) return nullptr; return name_constraints; diff --git a/chromium/net/cert/internal/name_constraints.h b/chromium/net/cert/pki/name_constraints.h index 5a64640e0cd..0fe0452da51 100644 --- a/chromium/net/cert/internal/name_constraints.h +++ b/chromium/net/cert/pki/name_constraints.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_NAME_CONSTRAINTS_H_ -#define NET_CERT_INTERNAL_NAME_CONSTRAINTS_H_ +#ifndef NET_CERT_PKI_NAME_CONSTRAINTS_H_ +#define NET_CERT_PKI_NAME_CONSTRAINTS_H_ #include <stdint.h> @@ -12,7 +12,7 @@ #include "base/strings/string_piece_forward.h" #include "net/base/ip_address.h" #include "net/base/net_export.h" -#include "net/cert/internal/general_names.h" +#include "net/cert/pki/general_names.h" namespace net { @@ -97,4 +97,4 @@ class NET_EXPORT NameConstraints { } // namespace net -#endif // NET_CERT_INTERNAL_NAME_CONSTRAINTS_H_ +#endif // NET_CERT_PKI_NAME_CONSTRAINTS_H_ diff --git a/chromium/net/cert/internal/name_constraints_unittest.cc b/chromium/net/cert/pki/name_constraints_unittest.cc index c5c556ec957..32a97af4f4b 100644 --- a/chromium/net/cert/internal/name_constraints_unittest.cc +++ b/chromium/net/cert/pki/name_constraints_unittest.cc @@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/name_constraints.h" +#include "net/cert/pki/name_constraints.h" #include <memory> #include "net/base/ip_address.h" -#include "net/cert/internal/common_cert_errors.h" -#include "net/cert/internal/test_helpers.h" +#include "net/cert/pki/common_cert_errors.h" +#include "net/cert/pki/test_helpers.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chromium/net/cert/internal/nist_pkits_unittest.cc b/chromium/net/cert/pki/nist_pkits_unittest.cc index c50a0ac546b..f2309349fba 100644 --- a/chromium/net/cert/internal/nist_pkits_unittest.cc +++ b/chromium/net/cert/pki/nist_pkits_unittest.cc @@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/nist_pkits_unittest.h" +#include "net/cert/pki/nist_pkits_unittest.h" -#include "base/strings/string_split.h" -#include "net/cert/internal/certificate_policies.h" +#include "net/cert/pki/certificate_policies.h" + +#include <sstream> namespace net { @@ -30,9 +31,21 @@ const uint8_t kTestPolicy6[] = {0x60, 0x86, 0x48, 0x01, 0x65, void SetPolicySetFromString(const char* const policy_names, std::set<der::Input>* out) { out->clear(); - std::vector<std::string> names = base::SplitString( - policy_names, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - for (const std::string& policy_name : names) { + std::istringstream stream(policy_names); + for (std::string line; std::getline(stream, line, ',');) { + size_t start = line.find_first_not_of(" \n\t\r\f\v"); + if (start == std::string::npos) { + continue; + } + size_t end = line.find_last_not_of(" \n\t\r\f\v"); + if (end == std::string::npos) { + continue; + } + std::string policy_name = line.substr(start, end + 1); + if (policy_name.empty()) { + continue; + } + if (policy_name == "anyPolicy") { out->insert(der::Input(kAnyPolicyOid)); } else if (policy_name == "NIST-test-policy-1") { diff --git a/chromium/net/cert/internal/nist_pkits_unittest.h b/chromium/net/cert/pki/nist_pkits_unittest.h index 4202e9da770..bf4d16485c9 100644 --- a/chromium/net/cert/internal/nist_pkits_unittest.h +++ b/chromium/net/cert/pki/nist_pkits_unittest.h @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_NIST_PKITS_UNITTEST_H_ -#define NET_CERT_INTERNAL_NIST_PKITS_UNITTEST_H_ +#ifndef NET_CERT_PKI_NIST_PKITS_UNITTEST_H_ +#define NET_CERT_PKI_NIST_PKITS_UNITTEST_H_ #include <set> -#include "net/cert/internal/test_helpers.h" +#include "net/cert/pki/test_helpers.h" #include "net/der/parse_values.h" #include "testing/gtest/include/gtest/gtest.h" @@ -154,4 +154,4 @@ class PkitsTest : public ::testing::Test { } // namespace net -#endif // NET_CERT_INTERNAL_NIST_PKITS_UNITTEST_H_ +#endif // NET_CERT_PKI_NIST_PKITS_UNITTEST_H_ diff --git a/chromium/net/cert/internal/ocsp.cc b/chromium/net/cert/pki/ocsp.cc index 4e316f35725..46fd72f7109 100644 --- a/chromium/net/cert/internal/ocsp.cc +++ b/chromium/net/cert/pki/ocsp.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/ocsp.h" +#include "net/cert/pki/ocsp.h" #include <algorithm> @@ -10,12 +10,12 @@ #include "base/strings/string_util.h" #include "base/time/time.h" #include "net/cert/asn1_util.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/extended_key_usage.h" -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/revocation_util.h" -#include "net/cert/internal/verify_name_match.h" -#include "net/cert/internal/verify_signed_data.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/extended_key_usage.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/revocation_util.h" +#include "net/cert/pki/verify_name_match.h" +#include "net/cert/pki/verify_signed_data.h" #include "net/cert/x509_util.h" #include "third_party/boringssl/src/include/openssl/bytestring.h" #include "third_party/boringssl/src/include/openssl/digest.h" @@ -340,10 +340,11 @@ bool ParseBasicOCSPResponse(const der::Input& raw_tlv, OCSPResponse* out) { if (!parser.ReadRawTLV(&sigalg_tlv)) return false; // TODO(crbug.com/634443): Propagate the errors. - CertErrors errors; - out->signature_algorithm = SignatureAlgorithm::Create(sigalg_tlv, &errors); - if (!out->signature_algorithm) + absl::optional<SignatureAlgorithm> sigalg = + ParseSignatureAlgorithm(sigalg_tlv, /*errors=*/nullptr); + if (!sigalg) return false; + out->signature_algorithm = sigalg.value(); absl::optional<der::BitString> signature = parser.ReadBitString(); if (!signature) return false; @@ -602,7 +603,7 @@ scoped_refptr<ParsedCertificate> OCSPParseCertificate(base::StringPiece der) { const OCSPResponse& response, const ParsedCertificate* cert) { // TODO(eroman): Must check the signature algorithm against policy. - return VerifySignedData(*(response.signature_algorithm), response.data, + return VerifySignedData(response.signature_algorithm, response.data, response.signature, cert->tbs().spki_tlv); } diff --git a/chromium/net/cert/internal/ocsp.h b/chromium/net/cert/pki/ocsp.h index dbbf68bb871..6a2a5e5b7d3 100644 --- a/chromium/net/cert/internal/ocsp.h +++ b/chromium/net/cert/pki/ocsp.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_OCSP_H_ -#define NET_CERT_INTERNAL_OCSP_H_ +#ifndef NET_CERT_PKI_OCSP_H_ +#define NET_CERT_PKI_OCSP_H_ #include <memory> #include <vector> @@ -11,10 +11,10 @@ #include "base/strings/string_piece_forward.h" #include "base/time/time.h" #include "net/base/net_export.h" -#include "net/cert/internal/parse_certificate.h" -#include "net/cert/internal/signature_algorithm.h" #include "net/cert/ocsp_revocation_status.h" #include "net/cert/ocsp_verify_result.h" +#include "net/cert/pki/parse_certificate.h" +#include "net/cert/pki/signature_algorithm.h" #include "net/der/input.h" #include "net/der/parse_values.h" #include "net/der/parser.h" @@ -218,7 +218,7 @@ struct NET_EXPORT OCSPResponse { ResponseStatus status; der::Input data; - std::unique_ptr<SignatureAlgorithm> signature_algorithm; + SignatureAlgorithm signature_algorithm; der::BitString signature; bool has_certs; std::vector<der::Input> certs; @@ -325,4 +325,4 @@ NET_EXPORT GURL CreateOCSPGetURL(const ParsedCertificate* cert, } // namespace net -#endif // NET_CERT_INTERNAL_OCSP_H_ +#endif // NET_CERT_PKI_OCSP_H_ diff --git a/chromium/net/cert/internal/ocsp_parse_ocsp_cert_id_fuzzer.cc b/chromium/net/cert/pki/ocsp_parse_ocsp_cert_id_fuzzer.cc index 855908dceb1..1d23453d0b5 100644 --- a/chromium/net/cert/internal/ocsp_parse_ocsp_cert_id_fuzzer.cc +++ b/chromium/net/cert/pki/ocsp_parse_ocsp_cert_id_fuzzer.cc @@ -5,7 +5,7 @@ #include <stddef.h> #include <stdint.h> -#include "net/cert/internal/ocsp.h" +#include "net/cert/pki/ocsp.h" #include "net/der/input.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { diff --git a/chromium/net/cert/internal/ocsp_parse_ocsp_response_data_fuzzer.cc b/chromium/net/cert/pki/ocsp_parse_ocsp_response_data_fuzzer.cc index 4d7ca7558fc..d312f0fae1b 100644 --- a/chromium/net/cert/internal/ocsp_parse_ocsp_response_data_fuzzer.cc +++ b/chromium/net/cert/pki/ocsp_parse_ocsp_response_data_fuzzer.cc @@ -5,7 +5,7 @@ #include <stddef.h> #include <stdint.h> -#include "net/cert/internal/ocsp.h" +#include "net/cert/pki/ocsp.h" #include "net/der/input.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { diff --git a/chromium/net/cert/internal/ocsp_parse_ocsp_response_fuzzer.cc b/chromium/net/cert/pki/ocsp_parse_ocsp_response_fuzzer.cc index f5dae65bd16..f3673aeec7a 100644 --- a/chromium/net/cert/internal/ocsp_parse_ocsp_response_fuzzer.cc +++ b/chromium/net/cert/pki/ocsp_parse_ocsp_response_fuzzer.cc @@ -5,7 +5,7 @@ #include <stddef.h> #include <stdint.h> -#include "net/cert/internal/ocsp.h" +#include "net/cert/pki/ocsp.h" #include "net/der/input.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { diff --git a/chromium/net/cert/internal/ocsp_parse_ocsp_single_response_fuzzer.cc b/chromium/net/cert/pki/ocsp_parse_ocsp_single_response_fuzzer.cc index 9eddfec433c..872e2680a4e 100644 --- a/chromium/net/cert/internal/ocsp_parse_ocsp_single_response_fuzzer.cc +++ b/chromium/net/cert/pki/ocsp_parse_ocsp_single_response_fuzzer.cc @@ -5,7 +5,7 @@ #include <stddef.h> #include <stdint.h> -#include "net/cert/internal/ocsp.h" +#include "net/cert/pki/ocsp.h" #include "net/der/input.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { diff --git a/chromium/net/cert/internal/ocsp_unittest.cc b/chromium/net/cert/pki/ocsp_unittest.cc index 5a7d0141c0e..6b3ae13a68d 100644 --- a/chromium/net/cert/internal/ocsp_unittest.cc +++ b/chromium/net/cert/pki/ocsp_unittest.cc @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/ocsp.h" +#include "net/cert/pki/ocsp.h" #include "base/base64.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" -#include "net/cert/internal/test_helpers.h" +#include "net/cert/pki/test_helpers.h" #include "net/der/encode_values.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/boringssl/src/include/openssl/pool.h" @@ -179,7 +179,8 @@ TEST_P(CheckOCSPTest, FromFile) { } base::StringPiece kGetURLTestParams[] = { - "http://www.example.com/", "http://www.example.com/path/", + "http://www.example.com/", + "http://www.example.com/path/", "http://www.example.com/path", "http://www.example.com/path?query" "http://user:pass@www.example.com/path?query", diff --git a/chromium/net/cert/internal/parse_certificate.cc b/chromium/net/cert/pki/parse_certificate.cc index 2dddf9d22f6..d206ec897e6 100644 --- a/chromium/net/cert/internal/parse_certificate.cc +++ b/chromium/net/cert/pki/parse_certificate.cc @@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/parse_certificate.h" +#include "net/cert/pki/parse_certificate.h" #include <utility> #include "base/strings/string_util.h" -#include "net/cert/internal/cert_error_params.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/general_names.h" +#include "net/cert/pki/cert_error_params.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/general_names.h" #include "net/der/input.h" #include "net/der/parse_values.h" #include "net/der/parser.h" @@ -236,6 +236,9 @@ bool ParseAndAddDistributionPoint( ParsedTbsCertificate::ParsedTbsCertificate() = default; +ParsedTbsCertificate::ParsedTbsCertificate(ParsedTbsCertificate&& other) = + default; + ParsedTbsCertificate::~ParsedTbsCertificate() = default; bool VerifySerialNumber(const der::Input& value, diff --git a/chromium/net/cert/internal/parse_certificate.h b/chromium/net/cert/pki/parse_certificate.h index ea03bf8fce7..d71dda139b5 100644 --- a/chromium/net/cert/internal/parse_certificate.h +++ b/chromium/net/cert/pki/parse_certificate.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_PARSE_CERTIFICATE_H_ -#define NET_CERT_INTERNAL_PARSE_CERTIFICATE_H_ +#ifndef NET_CERT_PKI_PARSE_CERTIFICATE_H_ +#define NET_CERT_PKI_PARSE_CERTIFICATE_H_ #include <stdint.h> @@ -12,7 +12,7 @@ #include <vector> #include "net/base/net_export.h" -#include "net/cert/internal/general_names.h" +#include "net/cert/pki/general_names.h" #include "net/der/input.h" #include "net/der/parse_values.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -190,6 +190,8 @@ enum class CertificateVersion { // sets. struct NET_EXPORT ParsedTbsCertificate { ParsedTbsCertificate(); + ParsedTbsCertificate(ParsedTbsCertificate&& other); + ParsedTbsCertificate& operator=(ParsedTbsCertificate&& other) = default; ~ParsedTbsCertificate(); // Corresponds with "version" from RFC 5280: @@ -616,4 +618,4 @@ struct NET_EXPORT ParsedAuthorityKeyIdentifier { } // namespace net -#endif // NET_CERT_INTERNAL_PARSE_CERTIFICATE_H_ +#endif // NET_CERT_PKI_PARSE_CERTIFICATE_H_ diff --git a/chromium/net/cert/internal/parse_certificate_fuzzer.cc b/chromium/net/cert/pki/parse_certificate_fuzzer.cc index 578a9a64008..b73eb018a24 100644 --- a/chromium/net/cert/internal/parse_certificate_fuzzer.cc +++ b/chromium/net/cert/pki/parse_certificate_fuzzer.cc @@ -6,8 +6,8 @@ #include <stdint.h> #include "base/check_op.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/parsed_certificate.h" #include "net/cert/x509_util.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { diff --git a/chromium/net/cert/internal/parse_certificate_unittest.cc b/chromium/net/cert/pki/parse_certificate_unittest.cc index 13e881fa538..7f5c48efe3e 100644 --- a/chromium/net/cert/internal/parse_certificate_unittest.cc +++ b/chromium/net/cert/pki/parse_certificate_unittest.cc @@ -2,13 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/parse_certificate.h" +#include "net/cert/pki/parse_certificate.h" -#include "base/strings/stringprintf.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/general_names.h" -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/test_helpers.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/general_names.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/test_helpers.h" #include "net/der/input.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/boringssl/src/include/openssl/pool.h" @@ -21,9 +20,12 @@ namespace { // expectations (it is more readable to specify the expected results as a // string). std::string ToString(const der::GeneralizedTime& time) { - return base::StringPrintf( - "year=%d, month=%d, day=%d, hours=%d, minutes=%d, seconds=%d", time.year, - time.month, time.day, time.hours, time.minutes, time.seconds); + std::ostringstream pretty_time; + pretty_time << "year=" << int{time.year} << ", month=" << int{time.month} + << ", day=" << int{time.day} << ", hours=" << int{time.hours} + << ", minutes=" << int{time.minutes} + << ", seconds=" << int{time.seconds}; + return pretty_time.str(); } std::string GetFilePath(const std::string& file_name) { diff --git a/chromium/net/cert/internal/parse_name.cc b/chromium/net/cert/pki/parse_name.cc index 3d8bfea98e4..5cd4516890c 100644 --- a/chromium/net/cert/internal/parse_name.cc +++ b/chromium/net/cert/pki/parse_name.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/parse_name.h" +#include "net/cert/pki/parse_name.h" #include "base/check_op.h" #include "base/notreached.h" diff --git a/chromium/net/cert/internal/parse_name.h b/chromium/net/cert/pki/parse_name.h index 357f3ebf5d6..e44833a9b30 100644 --- a/chromium/net/cert/internal/parse_name.h +++ b/chromium/net/cert/pki/parse_name.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_PARSE_NAME_H_ -#define NET_CERT_INTERNAL_PARSE_NAME_H_ +#ifndef NET_CERT_PKI_PARSE_NAME_H_ +#define NET_CERT_PKI_PARSE_NAME_H_ #include <vector> @@ -154,4 +154,4 @@ typedef std::vector<RelativeDistinguishedName> RDNSequence; std::string* out); } // namespace net -#endif // NET_CERT_INTERNAL_PARSE_NAME_H_ +#endif // NET_CERT_PKI_PARSE_NAME_H_ diff --git a/chromium/net/cert/internal/parse_name_unittest.cc b/chromium/net/cert/pki/parse_name_unittest.cc index 239f56cfcd5..3e29b808c4e 100644 --- a/chromium/net/cert/internal/parse_name_unittest.cc +++ b/chromium/net/cert/pki/parse_name_unittest.cc @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/parse_name.h" +#include "net/cert/pki/parse_name.h" -#include "net/cert/internal/test_helpers.h" +#include "net/cert/pki/test_helpers.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { diff --git a/chromium/net/cert/internal/parsed_certificate.cc b/chromium/net/cert/pki/parsed_certificate.cc index 5253a7db51d..a1268a127b6 100644 --- a/chromium/net/cert/internal/parsed_certificate.cc +++ b/chromium/net/cert/pki/parsed_certificate.cc @@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/parsed_certificate.h" - -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/certificate_policies.h" -#include "net/cert/internal/extended_key_usage.h" -#include "net/cert/internal/name_constraints.h" -#include "net/cert/internal/signature_algorithm.h" -#include "net/cert/internal/verify_name_match.h" +#include "net/cert/pki/parsed_certificate.h" + +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/certificate_policies.h" +#include "net/cert/pki/extended_key_usage.h" +#include "net/cert/pki/name_constraints.h" +#include "net/cert/pki/signature_algorithm.h" +#include "net/cert/pki/verify_name_match.h" #include "net/der/parser.h" #include "third_party/boringssl/src/include/openssl/pool.h" @@ -87,7 +87,7 @@ scoped_refptr<ParsedCertificate> ParsedCertificate::Create( if (!errors) errors = &unused_errors; - scoped_refptr<ParsedCertificate> result(new ParsedCertificate); + auto result = base::WrapRefCounted(new ParsedCertificate); result->cert_data_ = std::move(backing_data); result->cert_ = der::Input(CRYPTO_BUFFER_data(result->cert_data_.get()), CRYPTO_BUFFER_len(result->cert_data_.get())); @@ -106,12 +106,13 @@ scoped_refptr<ParsedCertificate> ParsedCertificate::Create( } // Attempt to parse the signature algorithm contained in the Certificate. - result->signature_algorithm_ = - SignatureAlgorithm::Create(result->signature_algorithm_tlv_, errors); - if (!result->signature_algorithm_) { + absl::optional<SignatureAlgorithm> sigalg = + ParseSignatureAlgorithm(result->signature_algorithm_tlv_, errors); + if (!sigalg) { errors->AddError(kFailedParsingSignatureAlgorithm); return nullptr; } + result->signature_algorithm_ = *sigalg; der::Input subject_value; if (!GetSequenceValue(result->tbs_.subject_tlv, &subject_value)) { diff --git a/chromium/net/cert/internal/parsed_certificate.h b/chromium/net/cert/pki/parsed_certificate.h index 55457178afb..d02c4bf5129 100644 --- a/chromium/net/cert/internal/parsed_certificate.h +++ b/chromium/net/cert/pki/parsed_certificate.h @@ -3,8 +3,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_PARSED_CERTIFICATE_H_ -#define NET_CERT_INTERNAL_PARSED_CERTIFICATE_H_ +#ifndef NET_CERT_PKI_PARSED_CERTIFICATE_H_ +#define NET_CERT_PKI_PARSED_CERTIFICATE_H_ #include <map> #include <memory> @@ -13,8 +13,9 @@ #include "base/check.h" #include "base/memory/ref_counted.h" #include "net/base/net_export.h" -#include "net/cert/internal/certificate_policies.h" -#include "net/cert/internal/parse_certificate.h" +#include "net/cert/pki/certificate_policies.h" +#include "net/cert/pki/parse_certificate.h" +#include "net/cert/pki/signature_algorithm.h" #include "net/der/input.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/boringssl/src/include/openssl/base.h" @@ -24,7 +25,6 @@ namespace net { struct GeneralNames; class NameConstraints; class ParsedCertificate; -class SignatureAlgorithm; class CertErrors; using ParsedCertificateList = std::vector<scoped_refptr<ParsedCertificate>>; @@ -86,9 +86,8 @@ class NET_EXPORT ParsedCertificate const ParsedTbsCertificate& tbs() const { return tbs_; } // Returns the signatureAlgorithm of the Certificate (not the tbsCertificate). - const SignatureAlgorithm& signature_algorithm() const { - DCHECK(signature_algorithm_); - return *signature_algorithm_; + SignatureAlgorithm signature_algorithm() const { + return signature_algorithm_; } // Returns the DER-encoded raw subject value (including the outer sequence @@ -262,7 +261,14 @@ class NET_EXPORT ParsedCertificate ParsedTbsCertificate tbs_; // The signatureAlgorithm from the Certificate. - std::unique_ptr<SignatureAlgorithm> signature_algorithm_; + // + // TODO(crbug.com/1321688): This class requires that we recognize the + // signature algorithm, but there are some self-signed root certificates with + // weak signature algorithms like MD2. We never verify those signatures, but + // this means we must include MD2, etc., in the `SignatureAlgorithm` enum. + // Instead, make this an `absl::optional<SignatureAlgorithm>` and make the + // call sites handle recognized and unrecognized algorithms. + SignatureAlgorithm signature_algorithm_; // Normalized DER-encoded Subject (not including outer Sequence tag). std::string normalized_subject_; @@ -326,4 +332,4 @@ class NET_EXPORT ParsedCertificate } // namespace net -#endif // NET_CERT_INTERNAL_PARSED_CERTIFICATE_H_ +#endif // NET_CERT_PKI_PARSED_CERTIFICATE_H_ diff --git a/chromium/net/cert/internal/parsed_certificate_unittest.cc b/chromium/net/cert/pki/parsed_certificate_unittest.cc index 2d8032fcdca..b33520910b3 100644 --- a/chromium/net/cert/internal/parsed_certificate_unittest.cc +++ b/chromium/net/cert/pki/parsed_certificate_unittest.cc @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/pki/parsed_certificate.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parse_certificate.h" -#include "net/cert/internal/test_helpers.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/parse_certificate.h" +#include "net/cert/pki/test_helpers.h" #include "net/der/input.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/boringssl/src/include/openssl/pool.h" @@ -33,7 +33,8 @@ scoped_refptr<ParsedCertificate> ParseCertificateFromFile( // Read the certificate data and error expectations from a single PEM file. const PemBlockMapping mappings[] = { - {"CERTIFICATE", &data}, {"ERRORS", &expected_errors, true /*optional*/}, + {"CERTIFICATE", &data}, + {"ERRORS", &expected_errors, true /*optional*/}, }; std::string test_file_path = GetFilePath(file_name); EXPECT_TRUE(ReadTestDataFromPemFile(test_file_path, mappings)); diff --git a/chromium/net/cert/internal/path_builder.cc b/chromium/net/cert/pki/path_builder.cc index 82702755a8e..cdb9ede48dd 100644 --- a/chromium/net/cert/internal/path_builder.cc +++ b/chromium/net/cert/pki/path_builder.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/path_builder.h" +#include "net/cert/pki/path_builder.h" #include <memory> #include <set> @@ -15,14 +15,14 @@ #include "base/strings/string_number_conversions.h" #include "crypto/sha2.h" #include "net/base/net_errors.h" -#include "net/cert/internal/cert_issuer_source.h" -#include "net/cert/internal/certificate_policies.h" -#include "net/cert/internal/common_cert_errors.h" -#include "net/cert/internal/parse_certificate.h" -#include "net/cert/internal/parse_name.h" // For CertDebugString. -#include "net/cert/internal/trust_store.h" -#include "net/cert/internal/verify_certificate_chain.h" -#include "net/cert/internal/verify_name_match.h" +#include "net/cert/pki/cert_issuer_source.h" +#include "net/cert/pki/certificate_policies.h" +#include "net/cert/pki/common_cert_errors.h" +#include "net/cert/pki/parse_certificate.h" +#include "net/cert/pki/parse_name.h" // For CertDebugString. +#include "net/cert/pki/trust_store.h" +#include "net/cert/pki/verify_certificate_chain.h" +#include "net/cert/pki/verify_name_match.h" #include "net/der/parser.h" #include "net/der/tag.h" @@ -715,9 +715,10 @@ CertPathBuilder::CertPathBuilder( const std::set<der::Input>& user_initial_policy_set, InitialPolicyMappingInhibit initial_policy_mapping_inhibit, InitialAnyPolicyInhibit initial_any_policy_inhibit) - : cert_path_iter_(new CertPathIter(std::move(cert), - trust_store, - /*debug_data=*/&out_result_)), + : cert_path_iter_( + std::make_unique<CertPathIter>(std::move(cert), + trust_store, + /*debug_data=*/&out_result_)), delegate_(delegate), time_(time), key_purpose_(key_purpose), @@ -782,6 +783,7 @@ CertPathBuilder::Result CertPathBuilder::Run() { } AddResultPath(std::move(result_path)); } + out_result_.iteration_count = iteration_count; RecordIterationCountHistogram(iteration_count); return std::move(out_result_); } @@ -813,6 +815,7 @@ CertPathBuilder::Result CertPathBuilder::Run() { AddResultPath(std::move(result_path)); if (path_is_good && !explore_all_paths_) { + out_result_.iteration_count = iteration_count; RecordIterationCountHistogram(iteration_count); // Found a valid path, return immediately. return std::move(out_result_); @@ -839,6 +842,9 @@ void CertPathBuilder::AddResultPath( out_result_.best_result_index = out_result_.paths.size(); } } + if (result_path->certs.size() > out_result_.max_depth_seen) { + out_result_.max_depth_seen = result_path->certs.size(); + } out_result_.paths.push_back(std::move(result_path)); } diff --git a/chromium/net/cert/internal/path_builder.h b/chromium/net/cert/pki/path_builder.h index 99aac4a43ff..c4bd8a72581 100644 --- a/chromium/net/cert/internal/path_builder.h +++ b/chromium/net/cert/pki/path_builder.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_PATH_BUILDER_H_ -#define NET_CERT_INTERNAL_PATH_BUILDER_H_ +#ifndef NET_CERT_PKI_PATH_BUILDER_H_ +#define NET_CERT_PKI_PATH_BUILDER_H_ #include <memory> #include <vector> @@ -12,10 +12,10 @@ #include "base/supports_user_data.h" #include "base/time/time.h" #include "net/base/net_export.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/trust_store.h" -#include "net/cert/internal/verify_certificate_chain.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/trust_store.h" +#include "net/cert/pki/verify_certificate_chain.h" #include "net/der/input.h" #include "net/der/parse_values.h" @@ -32,7 +32,7 @@ class CertIssuerSource; // Base class for custom data that CertPathBuilderDelegate can attach to paths. class NET_EXPORT CertPathBuilderDelegateData { public: - virtual ~CertPathBuilderDelegateData() {} + virtual ~CertPathBuilderDelegateData() = default; }; // Represents a single candidate path that was built or is being processed. @@ -139,6 +139,12 @@ class NET_EXPORT CertPathBuilder { // better than invalid, but otherwise nothing is guaranteed. size_t best_result_index = 0; + // The iteration count reached by path building. + uint32_t iteration_count = 0; + + // The max depth seen while path building. + uint32_t max_depth_seen = 0; + // True if the search stopped because it exceeded the iteration limit // configured with |SetIterationLimit|. bool exceeded_iteration_limit = false; @@ -238,4 +244,4 @@ class NET_EXPORT CertPathBuilder { } // namespace net -#endif // NET_CERT_INTERNAL_PATH_BUILDER_H_ +#endif // NET_CERT_PKI_PATH_BUILDER_H_ diff --git a/chromium/net/cert/internal/path_builder_pkits_unittest.cc b/chromium/net/cert/pki/path_builder_pkits_unittest.cc index 57680c769b0..e082f7d55fc 100644 --- a/chromium/net/cert/internal/path_builder_pkits_unittest.cc +++ b/chromium/net/cert/pki/path_builder_pkits_unittest.cc @@ -2,23 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/path_builder.h" +#include "net/cert/pki/path_builder.h" #include "base/time/time.h" #include "net/base/net_errors.h" -#include "net/cert/internal/cert_issuer_source_static.h" -#include "net/cert/internal/common_cert_errors.h" -#include "net/cert/internal/crl.h" -#include "net/cert/internal/parse_certificate.h" -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/simple_path_builder_delegate.h" -#include "net/cert/internal/trust_store_in_memory.h" -#include "net/cert/internal/verify_certificate_chain.h" +#include "net/cert/pki/cert_issuer_source_static.h" +#include "net/cert/pki/common_cert_errors.h" +#include "net/cert/pki/crl.h" +#include "net/cert/pki/parse_certificate.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/simple_path_builder_delegate.h" +#include "net/cert/pki/trust_store_in_memory.h" +#include "net/cert/pki/verify_certificate_chain.h" #include "net/der/encode_values.h" #include "net/der/input.h" #include "third_party/boringssl/src/include/openssl/pool.h" -#include "net/cert/internal/nist_pkits_unittest.h" +#include "net/cert/pki/nist_pkits_unittest.h" namespace net { diff --git a/chromium/net/cert/internal/path_builder_unittest.cc b/chromium/net/cert/pki/path_builder_unittest.cc index 545a5157b0a..80c5baa5eae 100644 --- a/chromium/net/cert/internal/path_builder_unittest.cc +++ b/chromium/net/cert/pki/path_builder_unittest.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/path_builder.h" +#include "net/cert/pki/path_builder.h" #include "base/base_paths.h" #include "base/callback_forward.h" @@ -14,16 +14,16 @@ #include "base/test/task_environment.h" #include "base/time/time.h" #include "build/build_config.h" -#include "net/cert/internal/cert_error_params.h" -#include "net/cert/internal/cert_issuer_source_static.h" -#include "net/cert/internal/common_cert_errors.h" -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/simple_path_builder_delegate.h" -#include "net/cert/internal/test_helpers.h" -#include "net/cert/internal/trust_store_collection.h" -#include "net/cert/internal/trust_store_in_memory.h" -#include "net/cert/internal/verify_certificate_chain.h" #include "net/cert/pem.h" +#include "net/cert/pki/cert_error_params.h" +#include "net/cert/pki/cert_issuer_source_static.h" +#include "net/cert/pki/common_cert_errors.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/simple_path_builder_delegate.h" +#include "net/cert/pki/test_helpers.h" +#include "net/cert/pki/trust_store_collection.h" +#include "net/cert/pki/trust_store_in_memory.h" +#include "net/cert/pki/verify_certificate_chain.h" #include "net/der/input.h" #include "net/net_buildflags.h" #include "net/test/test_certificate_data.h" @@ -93,8 +93,7 @@ class AsyncCertIssuerSourceStatic : public CertIssuerSource { num_async_gets_++; ParsedCertificateList issuers; static_cert_issuer_source_.SyncGetIssuersOf(cert, &issuers); - std::unique_ptr<StaticAsyncRequest> req( - new StaticAsyncRequest(std::move(issuers))); + auto req = std::make_unique<StaticAsyncRequest>(std::move(issuers)); *out_req = std::move(req); if (!async_get_callback_.is_null()) async_get_callback_.Run(); @@ -257,6 +256,7 @@ TEST_F(PathBuilderMultiRootTest, TargetWithSameNameAsTrustAnchorFails) { auto result = path_builder.Run(); EXPECT_FALSE(result.HasValidPath()); + EXPECT_EQ(1U, result.max_depth_seen); } // Test a failed path building when the trust anchor is provided as a @@ -682,10 +682,12 @@ TEST_F(PathBuilderMultiRootTest, TestIterationLimit) { EXPECT_EQ(insufficient_limit, result.exceeded_iteration_limit); if (insufficient_limit) { + EXPECT_EQ(2U, result.iteration_count); EXPECT_THAT(histogram_tester.GetAllSamples( "Net.CertVerifier.PathBuilderIterationCount"), ElementsAre(base::Bucket(/*sample=*/2, /*count=*/1))); } else { + EXPECT_EQ(3U, result.iteration_count); EXPECT_THAT(histogram_tester.GetAllSamples( "Net.CertVerifier.PathBuilderIterationCount"), ElementsAre(base::Bucket(/*sample=*/3, /*count=*/1))); @@ -828,6 +830,11 @@ TEST_F(PathBuilderMultiRootTest, TestDepthLimit) { EXPECT_EQ(!insufficient_limit, result.HasValidPath()); EXPECT_EQ(insufficient_limit, result.AnyPathContainsError(cert_errors::kDepthLimitExceeded)); + if (insufficient_limit) { + EXPECT_EQ(2U, result.max_depth_seen); + } else { + EXPECT_EQ(4U, result.max_depth_seen); + } } } @@ -901,7 +908,7 @@ void AddToStoreWithEKURestriction(HCERTSTORE store, CertAddEnhancedKeyUsageIdentifier(os_cert.get(), usage_identifier); } CertAddCertificateContextToStore(store, os_cert.get(), CERT_STORE_ADD_ALWAYS, - NULL); + nullptr); } bool AreCertsEq(const scoped_refptr<ParsedCertificate> cert_1, @@ -1384,6 +1391,7 @@ TEST_F(PathBuilderKeyRolloverTest, ExploreAllPathsWithIterationLimit) { EXPECT_EQ(target_, path0.certs[0]); EXPECT_EQ(newintermediate_, path0.certs[1]); EXPECT_EQ(newroot_, path0.certs[2]); + EXPECT_EQ(3U, result.max_depth_seen); } if (expectation.expected_num_paths > 1) { @@ -1394,6 +1402,7 @@ TEST_F(PathBuilderKeyRolloverTest, ExploreAllPathsWithIterationLimit) { EXPECT_EQ(target_, path1.certs[0]); EXPECT_EQ(newintermediate_, path1.certs[1]); EXPECT_EQ(oldroot_, path1.certs[2]); + EXPECT_EQ(3U, result.max_depth_seen); } if (expectation.expected_num_paths > 2) { @@ -1404,6 +1413,7 @@ TEST_F(PathBuilderKeyRolloverTest, ExploreAllPathsWithIterationLimit) { EXPECT_EQ(target_, path2.certs[0]); EXPECT_EQ(oldintermediate_, path2.certs[1]); EXPECT_EQ(oldroot_, path2.certs[2]); + EXPECT_EQ(3U, result.max_depth_seen); } if (expectation.expected_num_paths > 3) { @@ -1414,6 +1424,7 @@ TEST_F(PathBuilderKeyRolloverTest, ExploreAllPathsWithIterationLimit) { EXPECT_EQ(target_, path3.certs[0]); EXPECT_EQ(oldintermediate_, path3.certs[1]); EXPECT_EQ(newroot_, path3.certs[2]); + EXPECT_EQ(3U, result.max_depth_seen); } } } @@ -1620,7 +1631,8 @@ class MockCertIssuerSource : public CertIssuerSource { // only be used with Return, not SetArgPointee.) class CertIssuerSourceRequestMover { public: - CertIssuerSourceRequestMover(std::unique_ptr<CertIssuerSource::Request> req) + explicit CertIssuerSourceRequestMover( + std::unique_ptr<CertIssuerSource::Request> req) : request_(std::move(req)) {} void MoveIt(const ParsedCertificate* cert, std::unique_ptr<CertIssuerSource::Request>* out_req) { @@ -1661,8 +1673,8 @@ TEST_F(PathBuilderKeyRolloverTest, TestMultipleAsyncIssuersFromSingleSource) { path_builder.AddCertIssuerSource(&cert_issuer_source); // Create the mock CertIssuerSource::Request... - std::unique_ptr<StrictMock<MockCertIssuerSourceRequest>> - target_issuers_req_owner(new StrictMock<MockCertIssuerSourceRequest>()); + auto target_issuers_req_owner = + std::make_unique<StrictMock<MockCertIssuerSourceRequest>>(); // Keep a raw pointer to the Request... StrictMock<MockCertIssuerSourceRequest>* target_issuers_req = target_issuers_req_owner.get(); @@ -1741,8 +1753,8 @@ TEST_F(PathBuilderKeyRolloverTest, TestDuplicateAsyncIntermediates) { path_builder.AddCertIssuerSource(&cert_issuer_source); // Create the mock CertIssuerSource::Request... - std::unique_ptr<StrictMock<MockCertIssuerSourceRequest>> - target_issuers_req_owner(new StrictMock<MockCertIssuerSourceRequest>()); + auto target_issuers_req_owner = + std::make_unique<StrictMock<MockCertIssuerSourceRequest>>(); // Keep a raw pointer to the Request... StrictMock<MockCertIssuerSourceRequest>* target_issuers_req = target_issuers_req_owner.get(); diff --git a/chromium/net/cert/internal/path_builder_verify_certificate_chain_unittest.cc b/chromium/net/cert/pki/path_builder_verify_certificate_chain_unittest.cc index 6710dd1dd39..1db806bb67a 100644 --- a/chromium/net/cert/internal/path_builder_verify_certificate_chain_unittest.cc +++ b/chromium/net/cert/pki/path_builder_verify_certificate_chain_unittest.cc @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/path_builder.h" +#include "net/cert/pki/path_builder.h" -#include "net/cert/internal/cert_issuer_source_static.h" -#include "net/cert/internal/simple_path_builder_delegate.h" -#include "net/cert/internal/trust_store_in_memory.h" -#include "net/cert/internal/verify_certificate_chain_typed_unittest.h" +#include "net/cert/pki/cert_issuer_source_static.h" +#include "net/cert/pki/simple_path_builder_delegate.h" +#include "net/cert/pki/trust_store_in_memory.h" +#include "net/cert/pki/verify_certificate_chain_typed_unittest.h" namespace net { diff --git a/chromium/net/cert/internal/revocation_util.cc b/chromium/net/cert/pki/revocation_util.cc index 786ec8697ac..17a75b03c8e 100644 --- a/chromium/net/cert/internal/revocation_util.cc +++ b/chromium/net/cert/pki/revocation_util.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/revocation_util.h" +#include "net/cert/pki/revocation_util.h" #include "base/time/time.h" #include "net/der/encode_values.h" diff --git a/chromium/net/cert/internal/revocation_util.h b/chromium/net/cert/pki/revocation_util.h index 4b71f03825b..2966a0542de 100644 --- a/chromium/net/cert/internal/revocation_util.h +++ b/chromium/net/cert/pki/revocation_util.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_REVOCATION_UTIL_H_ -#define NET_CERT_INTERNAL_REVOCATION_UTIL_H_ +#ifndef NET_CERT_PKI_REVOCATION_UTIL_H_ +#define NET_CERT_PKI_REVOCATION_UTIL_H_ #include "net/base/net_export.h" @@ -30,4 +30,4 @@ struct GeneralizedTime; } // namespace net -#endif // NET_CERT_INTERNAL_REVOCATION_UTIL_H_ +#endif // NET_CERT_PKI_REVOCATION_UTIL_H_ diff --git a/chromium/net/cert/internal/signature_algorithm.cc b/chromium/net/cert/pki/signature_algorithm.cc index b733b8ebf03..a7ff1852587 100644 --- a/chromium/net/cert/internal/signature_algorithm.cc +++ b/chromium/net/cert/pki/signature_algorithm.cc @@ -2,14 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/signature_algorithm.h" +#include "net/cert/pki/signature_algorithm.h" -#include <memory> -#include <utility> - -#include "base/memory/ptr_util.h" -#include "net/cert/internal/cert_error_params.h" -#include "net/cert/internal/cert_errors.h" +#include "base/check.h" +#include "net/cert/pki/cert_error_params.h" +#include "net/cert/pki/cert_errors.h" #include "net/der/input.h" #include "net/der/parse_values.h" #include "net/der/parser.h" @@ -42,8 +39,8 @@ const uint8_t kOidMd5WithRsaEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, // pkcs-1(1) 5 } // // In dotted notation: 1.2.840.113549.1.1.5 -const uint8_t kOidSha1WithRsaEncryption[] = - {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05}; +const uint8_t kOidSha1WithRsaEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x05}; // sha1WithRSASignature is a deprecated equivalent of // sha1WithRSAEncryption. @@ -69,24 +66,24 @@ const uint8_t kOidSha1WithRsaSignature[] = {0x2b, 0x0e, 0x03, 0x02, 0x1d}; // sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 } // // In dotted notation: 1.2.840.113549.1.1.11 -const uint8_t kOidSha256WithRsaEncryption[] = - {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b}; +const uint8_t kOidSha256WithRsaEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b}; // From RFC 5912: // // sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 } // // In dotted notation: 1.2.840.113549.1.1.11 -const uint8_t kOidSha384WithRsaEncryption[] = - {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0c}; +const uint8_t kOidSha384WithRsaEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0c}; // From RFC 5912: // // sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 } // // In dotted notation: 1.2.840.113549.1.1.13 -const uint8_t kOidSha512WithRsaEncryption[] = - {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d}; +const uint8_t kOidSha512WithRsaEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0d}; // From RFC 5912: // @@ -104,8 +101,8 @@ const uint8_t kOidEcdsaWithSha1[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01}; // ecdsa-with-SHA2(3) 2 } // // In dotted notation: 1.2.840.10045.4.3.2 -const uint8_t kOidEcdsaWithSha256[] = - {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02}; +const uint8_t kOidEcdsaWithSha256[] = {0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x04, 0x03, 0x02}; // From RFC 5912: // @@ -114,8 +111,8 @@ const uint8_t kOidEcdsaWithSha256[] = // ecdsa-with-SHA2(3) 3 } // // In dotted notation: 1.2.840.10045.4.3.3 -const uint8_t kOidEcdsaWithSha384[] = - {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03}; +const uint8_t kOidEcdsaWithSha384[] = {0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x04, 0x03, 0x03}; // From RFC 5912: // @@ -124,8 +121,8 @@ const uint8_t kOidEcdsaWithSha384[] = // ecdsa-with-SHA2(3) 4 } // // In dotted notation: 1.2.840.10045.4.3.4 -const uint8_t kOidEcdsaWithSha512[] = - {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04}; +const uint8_t kOidEcdsaWithSha512[] = {0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x04, 0x03, 0x04}; // From RFC 5912: // @@ -181,122 +178,8 @@ const uint8_t kOidMgf1[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, return !parser.HasMore(); } -// Parses an RSA PKCS#1 v1.5 signature algorithm given the DER-encoded -// "parameters" from the parsed AlgorithmIdentifier, and the hash algorithm -// that was implied by the AlgorithmIdentifier's OID. -// -// Returns a nullptr on failure. -// -// RFC 5912 requires that the parameters for RSA PKCS#1 v1.5 algorithms be NULL -// ("PARAMS TYPE NULL ARE required"), however an empty parameter is also -// allowed for compatibility with non-compliant OCSP responders: -// -// sa-rsaWithSHA1 SIGNATURE-ALGORITHM ::= { -// IDENTIFIER sha1WithRSAEncryption -// PARAMS TYPE NULL ARE required -// HASHES { mda-sha1 } -// PUBLIC-KEYS { pk-rsa } -// SMIME-CAPS {IDENTIFIED BY sha1WithRSAEncryption } -// } -// -// sa-sha256WithRSAEncryption SIGNATURE-ALGORITHM ::= { -// IDENTIFIER sha256WithRSAEncryption -// PARAMS TYPE NULL ARE required -// HASHES { mda-sha256 } -// PUBLIC-KEYS { pk-rsa } -// SMIME-CAPS { IDENTIFIED BY sha256WithRSAEncryption } -// } -// -// sa-sha384WithRSAEncryption SIGNATURE-ALGORITHM ::= { -// IDENTIFIER sha384WithRSAEncryption -// PARAMS TYPE NULL ARE required -// HASHES { mda-sha384 } -// PUBLIC-KEYS { pk-rsa } -// SMIME-CAPS { IDENTIFIED BY sha384WithRSAEncryption } -// } -// -// sa-sha512WithRSAEncryption SIGNATURE-ALGORITHM ::= { -// IDENTIFIER sha512WithRSAEncryption -// PARAMS TYPE NULL ARE required -// HASHES { mda-sha512 } -// PUBLIC-KEYS { pk-rsa } -// SMIME-CAPS { IDENTIFIED BY sha512WithRSAEncryption } -// } -std::unique_ptr<SignatureAlgorithm> ParseRsaPkcs1(DigestAlgorithm digest, - const der::Input& params) { - // TODO(svaldez): Add warning about non-strict parsing. - if (!IsNull(params) && !IsEmpty(params)) - return nullptr; - - return SignatureAlgorithm::CreateRsaPkcs1(digest); -} - -// Parses a DSA signature algorithm given the DER-encoded -// "parameters" from the parsed AlgorithmIdentifier, and the hash algorithm -// that was implied by the AlgorithmIdentifier's OID. -// -// Returns a nullptr on failure. -// -// RFC 5912 requires that the parameters for DSA algorithms be absent. -std::unique_ptr<SignatureAlgorithm> ParseDsa(DigestAlgorithm digest, - const der::Input& params) { - // TODO(svaldez): Add warning about non-strict parsing. - if (!IsNull(params) && !IsEmpty(params)) - return nullptr; - - return SignatureAlgorithm::CreateDsa(digest); -} - -// Parses an ECDSA signature algorithm given the DER-encoded "parameters" from -// the parsed AlgorithmIdentifier, and the hash algorithm that was implied by -// the AlgorithmIdentifier's OID. -// -// On failure returns a nullptr. -// -// RFC 5912 requires that the parameters for ECDSA algorithms be absent -// ("PARAMS TYPE NULL ARE absent"): -// -// sa-ecdsaWithSHA1 SIGNATURE-ALGORITHM ::= { -// IDENTIFIER ecdsa-with-SHA1 -// VALUE ECDSA-Sig-Value -// PARAMS TYPE NULL ARE absent -// HASHES { mda-sha1 } -// PUBLIC-KEYS { pk-ec } -// SMIME-CAPS {IDENTIFIED BY ecdsa-with-SHA1 } -// } -// -// sa-ecdsaWithSHA256 SIGNATURE-ALGORITHM ::= { -// IDENTIFIER ecdsa-with-SHA256 -// VALUE ECDSA-Sig-Value -// PARAMS TYPE NULL ARE absent -// HASHES { mda-sha256 } -// PUBLIC-KEYS { pk-ec } -// SMIME-CAPS { IDENTIFIED BY ecdsa-with-SHA256 } -// } -// -// sa-ecdsaWithSHA384 SIGNATURE-ALGORITHM ::= { -// IDENTIFIER ecdsa-with-SHA384 -// VALUE ECDSA-Sig-Value -// PARAMS TYPE NULL ARE absent -// HASHES { mda-sha384 } -// PUBLIC-KEYS { pk-ec } -// SMIME-CAPS { IDENTIFIED BY ecdsa-with-SHA384 } -// } -// -// sa-ecdsaWithSHA512 SIGNATURE-ALGORITHM ::= { -// IDENTIFIER ecdsa-with-SHA512 -// VALUE ECDSA-Sig-Value -// PARAMS TYPE NULL ARE absent -// HASHES { mda-sha512 } -// PUBLIC-KEYS { pk-ec } -// SMIME-CAPS { IDENTIFIED BY ecdsa-with-SHA512 } -// } -std::unique_ptr<SignatureAlgorithm> ParseEcdsa(DigestAlgorithm digest, - const der::Input& params) { - if (!IsEmpty(params)) - return nullptr; - - return SignatureAlgorithm::CreateEcdsa(digest); +[[nodiscard]] bool IsNullOrEmpty(const der::Input& input) { + return IsNull(input) || IsEmpty(input); } // Parses a MaskGenAlgorithm as defined by RFC 5912: @@ -364,16 +247,16 @@ std::unique_ptr<SignatureAlgorithm> ParseEcdsa(DigestAlgorithm digest, // Note also that DER encoding (ITU-T X.690 section 11.5) prohibits // specifying default values explicitly. The parameter should instead be // omitted to indicate a default value. -std::unique_ptr<SignatureAlgorithm> ParseRsaPss(const der::Input& params) { +absl::optional<SignatureAlgorithm> ParseRsaPss(const der::Input& params) { der::Parser parser(params); der::Parser params_parser; if (!parser.ReadSequence(¶ms_parser)) - return nullptr; + return absl::nullopt; // There shouldn't be anything after the sequence (by definition the // parameters is a single sequence). if (parser.HasMore()) - return nullptr; + return absl::nullopt; // The default values for hashAlgorithm, maskGenAlgorithm, and saltLength // correspond to SHA-1, which we do not support with RSA-PSS, so treat them as @@ -397,25 +280,28 @@ std::unique_ptr<SignatureAlgorithm> ParseRsaPss(const der::Input& params) { &salt_length_parser) || !salt_length_parser.ReadUint64(&salt_length) || salt_length_parser.HasMore() || params_parser.HasMore()) { - return nullptr; + return absl::nullopt; } // Only combinations of RSASSA-PSS-params specified by TLS 1.3 (RFC 8446) are // supported. - if ((hash == DigestAlgorithm::Sha256 && - mgf1_hash == DigestAlgorithm::Sha256 && salt_length == 32) || - (hash == DigestAlgorithm::Sha384 && - mgf1_hash == DigestAlgorithm::Sha384 && salt_length == 48) || - (hash == DigestAlgorithm::Sha512 && - mgf1_hash == DigestAlgorithm::Sha512 && salt_length == 64)) { - return SignatureAlgorithm::CreateRsaPss(hash, mgf1_hash, salt_length); + if (hash != mgf1_hash) { + return absl::nullopt; // TLS 1.3 always matches MGF-1 and message hash. + } + if (hash == DigestAlgorithm::Sha256 && salt_length == 32) { + return SignatureAlgorithm::kRsaPssSha256; + } + if (hash == DigestAlgorithm::Sha384 && salt_length == 48) { + return SignatureAlgorithm::kRsaPssSha384; + } + if (hash == DigestAlgorithm::Sha512 && salt_length == 64) { + return SignatureAlgorithm::kRsaPssSha512; } - return nullptr; + return absl::nullopt; } -DEFINE_CERT_ERROR_ID(kUnknownAlgorithmIdentifierOid, - "Unknown AlgorithmIdentifier OID"); +DEFINE_CERT_ERROR_ID(kUnknownSignatureAlgorithm, "Unknown signature algorithm"); } // namespace @@ -474,148 +360,128 @@ DEFINE_CERT_ERROR_ID(kUnknownAlgorithmIdentifierOid, return true; } -RsaPssParameters::RsaPssParameters(DigestAlgorithm mgf1_hash, - uint32_t salt_length) - : mgf1_hash_(mgf1_hash), salt_length_(salt_length) { -} - -SignatureAlgorithm::~SignatureAlgorithm() = default; - -std::unique_ptr<SignatureAlgorithm> SignatureAlgorithm::Create( +absl::optional<SignatureAlgorithm> ParseSignatureAlgorithm( const der::Input& algorithm_identifier, CertErrors* errors) { der::Input oid; der::Input params; if (!ParseAlgorithmIdentifier(algorithm_identifier, &oid, ¶ms)) - return nullptr; + return absl::nullopt; // TODO(eroman): Each OID is tested for equality in order, which is not // particularly efficient. - if (oid == der::Input(kOidSha1WithRsaEncryption)) - return ParseRsaPkcs1(DigestAlgorithm::Sha1, params); - - if (oid == der::Input(kOidSha256WithRsaEncryption)) - return ParseRsaPkcs1(DigestAlgorithm::Sha256, params); - - if (oid == der::Input(kOidSha384WithRsaEncryption)) - return ParseRsaPkcs1(DigestAlgorithm::Sha384, params); - - if (oid == der::Input(kOidSha512WithRsaEncryption)) - return ParseRsaPkcs1(DigestAlgorithm::Sha512, params); - - if (oid == der::Input(kOidEcdsaWithSha1)) - return ParseEcdsa(DigestAlgorithm::Sha1, params); - - if (oid == der::Input(kOidEcdsaWithSha256)) - return ParseEcdsa(DigestAlgorithm::Sha256, params); - - if (oid == der::Input(kOidEcdsaWithSha384)) - return ParseEcdsa(DigestAlgorithm::Sha384, params); + // RFC 5912 requires that the parameters for RSA PKCS#1 v1.5 algorithms be + // NULL ("PARAMS TYPE NULL ARE required"), however an empty parameter is also + // allowed for compatibility with non-compliant OCSP responders. + // + // TODO(svaldez): Add warning about non-strict parsing. + if (oid == der::Input(kOidSha1WithRsaEncryption) && IsNullOrEmpty(params)) { + return SignatureAlgorithm::kRsaPkcs1Sha1; + } + if (oid == der::Input(kOidSha256WithRsaEncryption) && IsNullOrEmpty(params)) { + return SignatureAlgorithm::kRsaPkcs1Sha256; + } + if (oid == der::Input(kOidSha384WithRsaEncryption) && IsNullOrEmpty(params)) { + return SignatureAlgorithm::kRsaPkcs1Sha384; + } + if (oid == der::Input(kOidSha512WithRsaEncryption) && IsNullOrEmpty(params)) { + return SignatureAlgorithm::kRsaPkcs1Sha512; + } + if (oid == der::Input(kOidSha1WithRsaSignature) && IsNullOrEmpty(params)) { + return SignatureAlgorithm::kRsaPkcs1Sha1; + } + if (oid == der::Input(kOidMd2WithRsaEncryption) && IsNullOrEmpty(params)) { + return SignatureAlgorithm::kRsaPkcs1Md2; + } + if (oid == der::Input(kOidMd4WithRsaEncryption) && IsNullOrEmpty(params)) { + return SignatureAlgorithm::kRsaPkcs1Md4; + } + if (oid == der::Input(kOidMd5WithRsaEncryption) && IsNullOrEmpty(params)) { + return SignatureAlgorithm::kRsaPkcs1Md5; + } - if (oid == der::Input(kOidEcdsaWithSha512)) - return ParseEcdsa(DigestAlgorithm::Sha512, params); + // RFC 5912 requires that the parameters for ECDSA algorithms be absent + // ("PARAMS TYPE NULL ARE absent"): + if (oid == der::Input(kOidEcdsaWithSha1) && IsEmpty(params)) { + return SignatureAlgorithm::kEcdsaSha1; + } + if (oid == der::Input(kOidEcdsaWithSha256) && IsEmpty(params)) { + return SignatureAlgorithm::kEcdsaSha256; + } + if (oid == der::Input(kOidEcdsaWithSha384) && IsEmpty(params)) { + return SignatureAlgorithm::kEcdsaSha384; + } + if (oid == der::Input(kOidEcdsaWithSha512) && IsEmpty(params)) { + return SignatureAlgorithm::kEcdsaSha512; + } - if (oid == der::Input(kOidRsaSsaPss)) + if (oid == der::Input(kOidRsaSsaPss)) { return ParseRsaPss(params); + } - if (oid == der::Input(kOidSha1WithRsaSignature)) - return ParseRsaPkcs1(DigestAlgorithm::Sha1, params); - - if (oid == der::Input(kOidMd2WithRsaEncryption)) - return ParseRsaPkcs1(DigestAlgorithm::Md2, params); - - if (oid == der::Input(kOidMd4WithRsaEncryption)) - return ParseRsaPkcs1(DigestAlgorithm::Md4, params); - - if (oid == der::Input(kOidMd5WithRsaEncryption)) - return ParseRsaPkcs1(DigestAlgorithm::Md5, params); - - if (oid == der::Input(kOidDsaWithSha1)) - return ParseDsa(DigestAlgorithm::Sha1, params); - - if (oid == der::Input(kOidDsaWithSha256)) - return ParseDsa(DigestAlgorithm::Sha256, params); + // RFC 5912 requires that the parameters for DSA algorithms be absent. + // + // TODO(svaldez): Add warning about non-strict parsing. + if (oid == der::Input(kOidDsaWithSha1) && IsNullOrEmpty(params)) { + return SignatureAlgorithm::kDsaSha1; + } + if (oid == der::Input(kOidDsaWithSha256) && IsNullOrEmpty(params)) { + return SignatureAlgorithm::kDsaSha256; + } - // Unknown OID. + // Unknown signature algorithm. if (errors) { - errors->AddError(kUnknownAlgorithmIdentifierOid, + errors->AddError(kUnknownSignatureAlgorithm, CreateCertErrorParams2Der("oid", oid, "params", params)); } - return nullptr; -} - -std::unique_ptr<SignatureAlgorithm> SignatureAlgorithm::CreateRsaPkcs1( - DigestAlgorithm digest) { - return base::WrapUnique( - new SignatureAlgorithm(SignatureAlgorithmId::RsaPkcs1, digest, nullptr)); + return absl::nullopt; } -std::unique_ptr<SignatureAlgorithm> SignatureAlgorithm::CreateDsa( - DigestAlgorithm digest) { - return base::WrapUnique( - new SignatureAlgorithm(SignatureAlgorithmId::Dsa, digest, nullptr)); -} - -std::unique_ptr<SignatureAlgorithm> SignatureAlgorithm::CreateEcdsa( - DigestAlgorithm digest) { - return base::WrapUnique( - new SignatureAlgorithm(SignatureAlgorithmId::Ecdsa, digest, nullptr)); -} - -std::unique_ptr<SignatureAlgorithm> SignatureAlgorithm::CreateRsaPss( - DigestAlgorithm digest, - DigestAlgorithm mgf1_hash, - uint32_t salt_length) { - return base::WrapUnique(new SignatureAlgorithm( - SignatureAlgorithmId::RsaPss, digest, - std::make_unique<RsaPssParameters>(mgf1_hash, salt_length))); -} - -const RsaPssParameters* SignatureAlgorithm::ParamsForRsaPss() const { - if (algorithm_ == SignatureAlgorithmId::RsaPss) - return static_cast<RsaPssParameters*>(params_.get()); - return nullptr; -} - -bool SignatureAlgorithm::IsEquivalent(const der::Input& alg1_tlv, - const der::Input& alg2_tlv) { - if (alg1_tlv == alg2_tlv) - return true; - - std::unique_ptr<SignatureAlgorithm> alg1 = Create(alg1_tlv, nullptr); - std::unique_ptr<SignatureAlgorithm> alg2 = Create(alg2_tlv, nullptr); - - // Do checks that apply to all algorithms. - if (!alg1 || !alg2 || (alg1->algorithm() != alg2->algorithm()) || - (alg1->digest() != alg2->digest())) { - return false; - } - - // Check algorithm-specific parameters for equality. - switch (alg1->algorithm()) { - case SignatureAlgorithmId::RsaPkcs1: - case SignatureAlgorithmId::Ecdsa: - case SignatureAlgorithmId::Dsa: - DCHECK(!alg1->has_params()); - DCHECK(!alg2->has_params()); - return true; - case SignatureAlgorithmId::RsaPss: { - const RsaPssParameters* params1 = alg1->ParamsForRsaPss(); - const RsaPssParameters* params2 = alg2->ParamsForRsaPss(); - return params1 && params2 && - (params1->salt_length() == params2->salt_length()) && - (params1->mgf1_hash() == params2->mgf1_hash()); - } +absl::optional<DigestAlgorithm> GetTlsServerEndpointDigestAlgorithm( + SignatureAlgorithm alg) { + // See RFC 5929, section 4.1. RFC 5929 breaks the signature algorithm + // abstraction by trying to extract individual digest algorithms. (While + // common, this is not a universal property of signature algorithms.) We + // implement this within the library, so callers do not need to condition over + // all algorithms. + switch (alg) { + // If the single digest algorithm is MD5 or SHA-1, use SHA-256. + case SignatureAlgorithm::kRsaPkcs1Md5: + case SignatureAlgorithm::kRsaPkcs1Sha1: + case SignatureAlgorithm::kEcdsaSha1: + return DigestAlgorithm::Sha256; + + case SignatureAlgorithm::kRsaPkcs1Sha256: + case SignatureAlgorithm::kEcdsaSha256: + return DigestAlgorithm::Sha256; + + case SignatureAlgorithm::kRsaPkcs1Sha384: + case SignatureAlgorithm::kEcdsaSha384: + return DigestAlgorithm::Sha384; + + case SignatureAlgorithm::kRsaPkcs1Sha512: + case SignatureAlgorithm::kEcdsaSha512: + return DigestAlgorithm::Sha512; + + // It is ambiguous whether hash-matching RSASSA-PSS instantiations count as + // using one or multiple digests, but the corresponding digest is the only + // reasonable interpretation. + case SignatureAlgorithm::kRsaPssSha256: + return DigestAlgorithm::Sha256; + case SignatureAlgorithm::kRsaPssSha384: + return DigestAlgorithm::Sha384; + case SignatureAlgorithm::kRsaPssSha512: + return DigestAlgorithm::Sha512; + + // Do not return anything for these legacy algorithms. + case SignatureAlgorithm::kDsaSha1: + case SignatureAlgorithm::kDsaSha256: + case SignatureAlgorithm::kRsaPkcs1Md2: + case SignatureAlgorithm::kRsaPkcs1Md4: + return absl::nullopt; } - - return false; + return absl::nullopt; } -SignatureAlgorithm::SignatureAlgorithm( - SignatureAlgorithmId algorithm, - DigestAlgorithm digest, - std::unique_ptr<SignatureAlgorithmParameters> params) - : algorithm_(algorithm), digest_(digest), params_(std::move(params)) {} - } // namespace net diff --git a/chromium/net/cert/pki/signature_algorithm.h b/chromium/net/cert/pki/signature_algorithm.h new file mode 100644 index 00000000000..e6e2569bbae --- /dev/null +++ b/chromium/net/cert/pki/signature_algorithm.h @@ -0,0 +1,95 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_CERT_PKI_SIGNATURE_ALGORITHM_H_ +#define NET_CERT_PKI_SIGNATURE_ALGORITHM_H_ + +#include <stdint.h> + +#include "net/base/net_export.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace net { + +class CertErrors; + +namespace der { +class Input; +} // namespace der + +// The digest algorithm used within a signature. +enum class DigestAlgorithm { + Md2, + Md4, + Md5, + Sha1, + Sha256, + Sha384, + Sha512, +}; + +// The signature algorithm used within a certificate. +enum class SignatureAlgorithm { + kRsaPkcs1Sha1, + kRsaPkcs1Sha256, + kRsaPkcs1Sha384, + kRsaPkcs1Sha512, + kEcdsaSha1, + kEcdsaSha256, + kEcdsaSha384, + kEcdsaSha512, + // These RSA-PSS constants match RFC 8446 and refer to RSASSA-PSS with MGF-1, + // using the specified hash as both the signature and MGF-1 hash, and the hash + // length as the salt length. + kRsaPssSha256, + kRsaPssSha384, + kRsaPssSha512, + // These algorithms can be parsed but are not supported. + // TODO(https://crbug.com/1321688): Remove these. + kRsaPkcs1Md2, + kRsaPkcs1Md4, + kRsaPkcs1Md5, + kDsaSha1, + kDsaSha256, +}; + +// Parses AlgorithmIdentifier as defined by RFC 5280 section 4.1.1.2: +// +// AlgorithmIdentifier ::= SEQUENCE { +// algorithm OBJECT IDENTIFIER, +// parameters ANY DEFINED BY algorithm OPTIONAL } +[[nodiscard]] NET_EXPORT bool ParseAlgorithmIdentifier(const der::Input& input, + der::Input* algorithm, + der::Input* parameters); + +// Parses a HashAlgorithm as defined by RFC 5912: +// +// HashAlgorithm ::= AlgorithmIdentifier{DIGEST-ALGORITHM, +// {HashAlgorithms}} +// +// HashAlgorithms DIGEST-ALGORITHM ::= { +// { IDENTIFIER id-sha1 PARAMS TYPE NULL ARE preferredPresent } | +// { IDENTIFIER id-sha224 PARAMS TYPE NULL ARE preferredPresent } | +// { IDENTIFIER id-sha256 PARAMS TYPE NULL ARE preferredPresent } | +// { IDENTIFIER id-sha384 PARAMS TYPE NULL ARE preferredPresent } | +// { IDENTIFIER id-sha512 PARAMS TYPE NULL ARE preferredPresent } +// } +[[nodiscard]] bool ParseHashAlgorithm(const der::Input& input, + DigestAlgorithm* out); + +// Parses an AlgorithmIdentifier into a signature algorithm and returns it, or +// returns `absl::nullopt` if `algorithm_identifer` either cannot be parsed or +// is not a recognized signature algorithm. +NET_EXPORT absl::optional<SignatureAlgorithm> ParseSignatureAlgorithm( + const der::Input& algorithm_identifier, + CertErrors* errors); + +// Returns the hash to be used with the tls-server-end-point channel binding +// (RFC 5929) or `absl::nullopt`, if not supported for this signature algorithm. +absl::optional<DigestAlgorithm> GetTlsServerEndpointDigestAlgorithm( + SignatureAlgorithm alg); + +} // namespace net + +#endif // NET_CERT_PKI_SIGNATURE_ALGORITHM_H_ diff --git a/chromium/net/cert/internal/signature_algorithm_unittest.cc b/chromium/net/cert/pki/signature_algorithm_unittest.cc index c721eb34836..2247675ca76 100644 --- a/chromium/net/cert/internal/signature_algorithm_unittest.cc +++ b/chromium/net/cert/pki/signature_algorithm_unittest.cc @@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/signature_algorithm.h" +#include "net/cert/pki/signature_algorithm.h" #include <memory> #include "base/containers/span.h" #include "base/files/file_util.h" #include "base/strings/string_number_conversions.h" -#include "net/cert/internal/cert_errors.h" #include "net/cert/pem.h" +#include "net/cert/pki/cert_errors.h" #include "net/der/input.h" #include "net/der/parser.h" #include "testing/gtest/include/gtest/gtest.h" @@ -19,23 +19,10 @@ namespace net { namespace { -// Creates a SignatureAlgorithm given the DER as a byte array. Returns true on -// success and fills |*out| with a non-null pointer. -bool ParseDer(base::span<const uint8_t> data, - std::unique_ptr<SignatureAlgorithm>* out) { - *out = - SignatureAlgorithm::Create(der::Input(data.data(), data.size()), nullptr); - bool success = !!*out; - - return success; -} - // Parses a SignatureAlgorithm given an empty DER input. TEST(SignatureAlgorithmTest, ParseDerEmpty) { CertErrors errors; - std::unique_ptr<SignatureAlgorithm> algorithm = - SignatureAlgorithm::Create(der::Input(), &errors); - ASSERT_FALSE(algorithm); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(), &errors)); // TODO(crbug.com/634443): Test the errors. // EXPECT_FALSE(errors.empty()); } @@ -43,8 +30,7 @@ TEST(SignatureAlgorithmTest, ParseDerEmpty) { // Parses a SignatureAlgorithm given invalid DER input. TEST(SignatureAlgorithmTest, ParseDerBogus) { const uint8_t kData[] = {0x00}; - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a SignatureAlgorithm with an unsupported algorithm OID. @@ -59,8 +45,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssUnsupportedAlgorithmOid) { 0x42, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a sha1WithRSAEncryption which contains a NULL parameters field. @@ -77,11 +62,8 @@ TEST(SignatureAlgorithmTest, ParseDerSha1WithRSAEncryptionNullParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::RsaPkcs1, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha1, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kRsaPkcs1Sha1); } // Parses a sha1WithRSAEncryption which contains no parameters field. @@ -96,11 +78,8 @@ TEST(SignatureAlgorithmTest, ParseDerSha1WithRSAEncryptionNoParams) { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::RsaPkcs1, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha1, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kRsaPkcs1Sha1); } // Parses a sha1WithRSAEncryption which contains an unexpected parameters @@ -118,8 +97,7 @@ TEST(SignatureAlgorithmTest, ParseDerSha1WithRSAEncryptionNonNullParams) { 0x02, 0x01, 0x00, // INTEGER (1 byte) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a sha1WithRSASignature which contains a NULL parameters field. @@ -136,11 +114,8 @@ TEST(SignatureAlgorithmTest, ParseDerSha1WithRSASignatureNullParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::RsaPkcs1, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha1, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kRsaPkcs1Sha1); } // Parses a sha1WithRSASignature which contains no parameters field. @@ -155,11 +130,8 @@ TEST(SignatureAlgorithmTest, ParseDerSha1WithRSASignatureNoParams) { 0x2b, 0x0e, 0x03, 0x02, 0x1d, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::RsaPkcs1, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha1, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kRsaPkcs1Sha1); } // Parses a sha1WithRSAEncryption which contains values after the sequence. @@ -178,8 +150,7 @@ TEST(SignatureAlgorithmTest, ParseDerSha1WithRsaEncryptionDataAfterSequence) { 0x02, 0x01, 0x00, // INTEGER (1 byte) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a sha1WithRSAEncryption which contains a bad NULL parameters field. @@ -198,8 +169,7 @@ TEST(SignatureAlgorithmTest, ParseDerSha1WithRSAEncryptionBadNullParams) { 0x05, 0x01, 0x09, // NULL (1 byte) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a sha1WithRSAEncryption which contains a NULL parameters field, @@ -220,8 +190,7 @@ TEST(SignatureAlgorithmTest, 0x02, 0x01, 0x00, // INTEGER (1 byte) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a SignatureAlgorithm given DER which does not encode a sequence. @@ -233,8 +202,7 @@ TEST(SignatureAlgorithmTest, ParseDerNotASequence) { 0x02, 0x01, 0x00, // INTEGER (1 byte) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a sha256WithRSAEncryption which contains a NULL parameters field. @@ -251,11 +219,8 @@ TEST(SignatureAlgorithmTest, ParseDerSha256WithRSAEncryptionNullParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::RsaPkcs1, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha256, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kRsaPkcs1Sha256); } // Parses a sha256WithRSAEncryption which contains no parameters field. @@ -270,11 +235,8 @@ TEST(SignatureAlgorithmTest, ParseDerSha256WithRSAEncryptionNoParams) { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::RsaPkcs1, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha256, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kRsaPkcs1Sha256); } // Parses a sha384WithRSAEncryption which contains a NULL parameters field. @@ -291,11 +253,8 @@ TEST(SignatureAlgorithmTest, ParseDerSha384WithRSAEncryptionNullParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::RsaPkcs1, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha384, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kRsaPkcs1Sha384); } // Parses a sha384WithRSAEncryption which contains no parameters field. @@ -310,11 +269,8 @@ TEST(SignatureAlgorithmTest, ParseDerSha384WithRSAEncryptionNoParams) { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0c, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::RsaPkcs1, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha384, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kRsaPkcs1Sha384); } // Parses a sha512WithRSAEncryption which contains a NULL parameters field. @@ -331,11 +287,8 @@ TEST(SignatureAlgorithmTest, ParseDerSha512WithRSAEncryptionNullParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::RsaPkcs1, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha512, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kRsaPkcs1Sha512); } // Parses a sha512WithRSAEncryption which contains no parameters field. @@ -350,11 +303,8 @@ TEST(SignatureAlgorithmTest, ParseDerSha512WithRSAEncryptionNoParams) { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::RsaPkcs1, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha512, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kRsaPkcs1Sha512); } // Parses a sha224WithRSAEncryption which contains a NULL parameters field. @@ -373,8 +323,7 @@ TEST(SignatureAlgorithmTest, ParseDerSha224WithRSAEncryptionNullParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a ecdsa-with-SHA1 which contains no parameters field. @@ -389,11 +338,8 @@ TEST(SignatureAlgorithmTest, ParseDerEcdsaWithSHA1NoParams) { 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::Ecdsa, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha1, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kEcdsaSha1); } // Parses a ecdsa-with-SHA1 which contains a NULL parameters field. @@ -410,8 +356,7 @@ TEST(SignatureAlgorithmTest, ParseDerEcdsaWithSHA1NullParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a ecdsa-with-SHA256 which contains no parameters field. @@ -426,11 +371,8 @@ TEST(SignatureAlgorithmTest, ParseDerEcdsaWithSHA256NoParams) { 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::Ecdsa, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha256, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kEcdsaSha256); } // Parses a ecdsa-with-SHA256 which contains a NULL parameters field. @@ -447,8 +389,7 @@ TEST(SignatureAlgorithmTest, ParseDerEcdsaWithSHA256NullParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a ecdsa-with-SHA384 which contains no parameters field. @@ -463,11 +404,8 @@ TEST(SignatureAlgorithmTest, ParseDerEcdsaWithSHA384NoParams) { 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::Ecdsa, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha384, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kEcdsaSha384); } // Parses a ecdsa-with-SHA384 which contains a NULL parameters field. @@ -484,8 +422,7 @@ TEST(SignatureAlgorithmTest, ParseDerEcdsaWithSHA384NullParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a ecdsa-with-SHA512 which contains no parameters field. @@ -500,11 +437,8 @@ TEST(SignatureAlgorithmTest, ParseDerEcdsaWithSHA512NoParams) { 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::Ecdsa, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha512, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kEcdsaSha512); } // Parses a ecdsa-with-SHA512 which contains a NULL parameters field. @@ -521,26 +455,7 @@ TEST(SignatureAlgorithmTest, ParseDerEcdsaWithSHA512NullParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); -} - -// Tests that the parmeters returned for an ECDSA algorithm are null for -// non-ECDSA algorithms. -TEST(SignatureAlgorithmTest, ParamsAreNullForWrongTypeEcdsa) { - std::unique_ptr<SignatureAlgorithm> alg1 = - SignatureAlgorithm::CreateEcdsa(DigestAlgorithm::Sha1); - - EXPECT_FALSE(alg1->ParamsForRsaPss()); -} - -// Tests that the parmeters returned for an RSA PKCS#1 v1.5 algorithm are null -// for non-RSA PKCS#1 v1.5 algorithms. -TEST(SignatureAlgorithmTest, ParamsAreNullForWrongTypeRsaPkcs1) { - std::unique_ptr<SignatureAlgorithm> alg1 = - SignatureAlgorithm::CreateRsaPkcs1(DigestAlgorithm::Sha1); - - EXPECT_FALSE(alg1->ParamsForRsaPss()); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that uses SHA256 and a salt length of 32. @@ -586,17 +501,8 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPss) { }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - ASSERT_EQ(SignatureAlgorithmId::RsaPss, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha256, algorithm->digest()); - - const RsaPssParameters* params = algorithm->ParamsForRsaPss(); - - ASSERT_TRUE(params); - EXPECT_EQ(DigestAlgorithm::Sha256, params->mgf1_hash()); - EXPECT_EQ(32u, params->salt_length()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kRsaPssSha256); } // Parses a rsaPss algorithm that has an empty parameters. This encodes the @@ -614,8 +520,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssEmptyParams) { 0x30, 0x00, // SEQUENCE (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - EXPECT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that has NULL parameters. This fails. @@ -632,8 +537,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssNullParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that has no parameters. This fails. @@ -648,8 +552,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssNoParams) { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0A, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that has data after the parameters sequence. @@ -668,8 +571,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssDataAfterParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that has unrecognized data (NULL) within the @@ -694,8 +596,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssNullInsideParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that has an unsupported trailer value (2). Only @@ -718,8 +619,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssUnsupportedTrailer) { 0x02, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that has extra data appearing after the trailer in @@ -744,8 +644,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssBadTrailer) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that uses SHA384 for the hash, and leaves the rest @@ -773,8 +672,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssNonDefaultHash) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - EXPECT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that uses an invalid hash algorithm (twiddled the @@ -799,8 +697,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssUnsupportedHashOid) { 0x60, 0x86, 0x48, 0x02, 0x67, 0x13, 0x04, 0x02, 0x02, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that uses SHA512 MGF1 for the mask gen, and @@ -833,8 +730,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssNonDefaultMaskGen) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - EXPECT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that uses a mask gen with an unrecognized OID @@ -866,8 +762,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssUnsupportedMaskGen) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that uses SHA256 for the hash, and SHA512 for the @@ -908,8 +803,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssNonDefaultHashAndMaskGen) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - EXPECT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that uses SHA256 for the hash, and SHA256 for the @@ -956,8 +850,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssNonDefaultHashAndMaskGenAndSalt) { 0x0A, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - EXPECT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that specifies default hash (SHA1). @@ -984,8 +877,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssSpecifiedDefaultHash) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that specifies default mask gen algorithm (SHA1). @@ -1017,8 +909,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssSpecifiedDefaultMaskGen) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that specifies default salt length. @@ -1041,8 +932,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssSpecifiedDefaultSaltLength) { 0x14, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that specifies default trailer field. @@ -1085,8 +975,7 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssSpecifiedDefaultTrailerField) { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x20, 0xa3, 0x03, 0x02, 0x01, 0x01}; - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } // Parses a rsaPss algorithm that specifies multiple default parameter values. @@ -1137,17 +1026,14 @@ TEST(SignatureAlgorithmTest, ParseDerRsaPssMultipleDefaultParameterValues) { 0x01, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_FALSE(ParseDer(kData, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm(der::Input(kData), nullptr)); } TEST(SignatureAlgorithmTest, ParseRsaPss) { // Test data generated with https://github.com/google/der-ascii. struct { std::vector<uint8_t> data; - DigestAlgorithm expected_digest; - DigestAlgorithm expected_mgf1_hash; - uint32_t expected_salt_length; + SignatureAlgorithm expected; } kValidTests[] = { // SEQUENCE { // # rsassa-pss @@ -1182,9 +1068,7 @@ TEST(SignatureAlgorithmTest, ParseRsaPss) { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x20}, - DigestAlgorithm::Sha256, - DigestAlgorithm::Sha256, - 32}, + SignatureAlgorithm::kRsaPssSha256}, // SEQUENCE { // # rsassa-pss // OBJECT_IDENTIFIER { 1.2.840.113549.1.1.10 } @@ -1218,9 +1102,7 @@ TEST(SignatureAlgorithmTest, ParseRsaPss) { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x30}, - DigestAlgorithm::Sha384, - DigestAlgorithm::Sha384, - 48}, + SignatureAlgorithm::kRsaPssSha384}, // SEQUENCE { // # rsassa-pss // OBJECT_IDENTIFIER { 1.2.840.113549.1.1.10 } @@ -1254,9 +1136,7 @@ TEST(SignatureAlgorithmTest, ParseRsaPss) { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x40}, - DigestAlgorithm::Sha512, - DigestAlgorithm::Sha512, - 64}, + SignatureAlgorithm::kRsaPssSha512}, // The same inputs as above, but the NULLs in the digest algorithms are // omitted. @@ -1266,35 +1146,25 @@ TEST(SignatureAlgorithmTest, ParseRsaPss) { 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20}, - DigestAlgorithm::Sha256, - DigestAlgorithm::Sha256, - 32}, + SignatureAlgorithm::kRsaPssSha256}, {{0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0xa2, 0x03, 0x02, 0x01, 0x30}, - DigestAlgorithm::Sha384, - DigestAlgorithm::Sha384, - 48}, + SignatureAlgorithm::kRsaPssSha384}, {{0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0xa2, 0x03, 0x02, 0x01, 0x40}, - DigestAlgorithm::Sha512, - DigestAlgorithm::Sha512, - 64}}; + SignatureAlgorithm::kRsaPssSha512}}; for (const auto& t : kValidTests) { - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(t.data, &algorithm)); - ASSERT_EQ(SignatureAlgorithmId::RsaPss, algorithm->algorithm()); - EXPECT_EQ(t.expected_digest, algorithm->digest()); - EXPECT_EQ(t.expected_mgf1_hash, algorithm->ParamsForRsaPss()->mgf1_hash()); - EXPECT_EQ(t.expected_salt_length, - algorithm->ParamsForRsaPss()->salt_length()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(t.data.data(), t.data.size()), + nullptr), + t.expected); } struct { @@ -1484,8 +1354,8 @@ TEST(SignatureAlgorithmTest, ParseRsaPss) { 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x41}}, }; for (const auto& t : kInvalidTests) { - std::unique_ptr<SignatureAlgorithm> algorithm; - EXPECT_FALSE(ParseDer(t.data, &algorithm)); + EXPECT_FALSE(ParseSignatureAlgorithm( + der::Input(t.data.data(), t.data.size()), nullptr)); } } @@ -1503,11 +1373,8 @@ TEST(SignatureAlgorithmTest, ParseDerMd5WithRsaEncryptionNullParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::RsaPkcs1, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Md5, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kRsaPkcs1Md5); } // Parses a md4WithRSAEncryption which contains a NULL parameters field. @@ -1524,11 +1391,8 @@ TEST(SignatureAlgorithmTest, ParseDerMd4WithRsaEncryptionNullParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::RsaPkcs1, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Md4, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kRsaPkcs1Md4); } // Parses a md2WithRSAEncryption which contains a NULL parameters field. @@ -1545,11 +1409,8 @@ TEST(SignatureAlgorithmTest, ParseDerMd2WithRsaEncryptionNullParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::RsaPkcs1, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Md2, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kRsaPkcs1Md2); } // Parses a dsaWithSha1 which contains no parameters field. @@ -1564,11 +1425,8 @@ TEST(SignatureAlgorithmTest, ParseDerDsaWithSha1NoParams) { 0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x03, }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::Dsa, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha1, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kDsaSha1); } // Parses a dsaWithSha1 which contains a NULL parameters field. @@ -1585,11 +1443,8 @@ TEST(SignatureAlgorithmTest, ParseDerDsaWithSha1NullParams) { 0x05, 0x00, // NULL (0 bytes) }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::Dsa, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha1, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kDsaSha1); } // Parses a dsaWithSha256 which contains no parameters field. @@ -1604,11 +1459,8 @@ TEST(SignatureAlgorithmTest, ParseDerDsaWithSha256NoParams) { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x02 }; // clang-format on - std::unique_ptr<SignatureAlgorithm> algorithm; - ASSERT_TRUE(ParseDer(kData, &algorithm)); - - EXPECT_EQ(SignatureAlgorithmId::Dsa, algorithm->algorithm()); - EXPECT_EQ(DigestAlgorithm::Sha256, algorithm->digest()); + EXPECT_EQ(ParseSignatureAlgorithm(der::Input(kData), nullptr), + SignatureAlgorithm::kDsaSha256); } } // namespace diff --git a/chromium/net/cert/internal/simple_path_builder_delegate.cc b/chromium/net/cert/pki/simple_path_builder_delegate.cc index e4259ee6eb3..aa961254d3a 100644 --- a/chromium/net/cert/internal/simple_path_builder_delegate.cc +++ b/chromium/net/cert/pki/simple_path_builder_delegate.cc @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/simple_path_builder_delegate.h" +#include "net/cert/pki/simple_path_builder_delegate.h" -#include "net/cert/internal/cert_error_params.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/signature_algorithm.h" -#include "net/cert/internal/verify_signed_data.h" +#include "net/cert/pki/cert_error_params.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/signature_algorithm.h" +#include "net/cert/pki/verify_signed_data.h" #include "third_party/boringssl/src/include/openssl/bn.h" #include "third_party/boringssl/src/include/openssl/bytestring.h" #include "third_party/boringssl/src/include/openssl/digest.h" @@ -53,25 +53,34 @@ void SimplePathBuilderDelegate::CheckPathAfterVerification( } bool SimplePathBuilderDelegate::IsSignatureAlgorithmAcceptable( - const SignatureAlgorithm& algorithm, + SignatureAlgorithm algorithm, CertErrors* errors) { - // Restrict default permitted signature algorithms to: - // - // RSA PKCS#1 v1.5 - // RSASSA-PSS - // ECDSA - switch (algorithm.algorithm()) { - case SignatureAlgorithmId::Dsa: + switch (algorithm) { + case SignatureAlgorithm::kRsaPkcs1Sha1: + case SignatureAlgorithm::kEcdsaSha1: + return digest_policy_ == DigestPolicy::kWeakAllowSha1; + + case SignatureAlgorithm::kRsaPkcs1Sha256: + case SignatureAlgorithm::kRsaPkcs1Sha384: + case SignatureAlgorithm::kRsaPkcs1Sha512: + case SignatureAlgorithm::kEcdsaSha256: + case SignatureAlgorithm::kEcdsaSha384: + case SignatureAlgorithm::kEcdsaSha512: + case SignatureAlgorithm::kRsaPssSha256: + case SignatureAlgorithm::kRsaPssSha384: + case SignatureAlgorithm::kRsaPssSha512: + return true; + + case SignatureAlgorithm::kRsaPkcs1Md2: + case SignatureAlgorithm::kRsaPkcs1Md4: + case SignatureAlgorithm::kRsaPkcs1Md5: + case SignatureAlgorithm::kDsaSha1: + case SignatureAlgorithm::kDsaSha256: + // TODO(https://crbug.com/1321688): We do not implement DSA, MD2, MD4, or + // MD5 anyway. Remove them from the parser altogether, so code does not + // need to handle them. return false; - case SignatureAlgorithmId::Ecdsa: - case SignatureAlgorithmId::RsaPkcs1: - return IsAcceptableDigest(algorithm.digest()); - case SignatureAlgorithmId::RsaPss: - return IsAcceptableDigest(algorithm.digest()) && - IsAcceptableDigest(algorithm.ParamsForRsaPss()->mgf1_hash()); } - - return false; } bool SimplePathBuilderDelegate::IsPublicKeyAcceptable(EVP_PKEY* public_key, @@ -82,7 +91,7 @@ bool SimplePathBuilderDelegate::IsPublicKeyAcceptable(EVP_PKEY* public_key, RSA* rsa = EVP_PKEY_get0_RSA(public_key); if (!rsa) return false; - unsigned int modulus_length_bits = BN_num_bits(rsa->n); + unsigned int modulus_length_bits = RSA_bits(rsa); if (modulus_length_bits < min_rsa_modulus_length_bits_) { errors->AddError( @@ -114,30 +123,4 @@ bool SimplePathBuilderDelegate::IsPublicKeyAcceptable(EVP_PKEY* public_key, return false; } -// Restricted signature digest algorithms to: -// -// SHA1 (if digest_policy_ == kWeakAllowSha1) -// SHA256 -// SHA384 -// SHA512 -bool SimplePathBuilderDelegate::IsAcceptableDigest( - DigestAlgorithm digest) const { - switch (digest) { - case DigestAlgorithm::Md2: - case DigestAlgorithm::Md4: - case DigestAlgorithm::Md5: - return false; - - case DigestAlgorithm::Sha1: - return digest_policy_ == - SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1; - case DigestAlgorithm::Sha256: - case DigestAlgorithm::Sha384: - case DigestAlgorithm::Sha512: - return true; - } - - return false; -} - } // namespace net diff --git a/chromium/net/cert/internal/simple_path_builder_delegate.h b/chromium/net/cert/pki/simple_path_builder_delegate.h index bd6ccf733d9..db1b368c215 100644 --- a/chromium/net/cert/internal/simple_path_builder_delegate.h +++ b/chromium/net/cert/pki/simple_path_builder_delegate.h @@ -2,19 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_SIMPLE_PATH_BUILDER_DELEGATE_H_ -#define NET_CERT_INTERNAL_SIMPLE_PATH_BUILDER_DELEGATE_H_ +#ifndef NET_CERT_PKI_SIMPLE_PATH_BUILDER_DELEGATE_H_ +#define NET_CERT_PKI_SIMPLE_PATH_BUILDER_DELEGATE_H_ #include <stddef.h> #include "net/base/net_export.h" -#include "net/cert/internal/path_builder.h" -#include "net/cert/internal/signature_algorithm.h" +#include "net/cert/pki/path_builder.h" +#include "net/cert/pki/signature_algorithm.h" namespace net { class CertErrors; -class SignatureAlgorithm; // SimplePathBuilderDelegate is an implementation of CertPathBuilderDelegate // that uses some default policies: @@ -46,9 +45,8 @@ class NET_EXPORT SimplePathBuilderDelegate : public CertPathBuilderDelegate { // Accepts RSA PKCS#1, RSASSA-PSS or ECDA using any of the SHA* digests // (including SHA1). - bool IsSignatureAlgorithmAcceptable( - const SignatureAlgorithm& signature_algorithm, - CertErrors* errors) override; + bool IsSignatureAlgorithmAcceptable(SignatureAlgorithm signature_algorithm, + CertErrors* errors) override; // Requires RSA keys be >= |min_rsa_modulus_length_bits_|. bool IsPublicKeyAcceptable(EVP_PKEY* public_key, CertErrors* errors) override; @@ -58,12 +56,10 @@ class NET_EXPORT SimplePathBuilderDelegate : public CertPathBuilderDelegate { CertPathBuilderResultPath* path) override; private: - [[nodiscard]] bool IsAcceptableDigest(DigestAlgorithm digest) const; - const size_t min_rsa_modulus_length_bits_; const DigestPolicy digest_policy_; }; } // namespace net -#endif // NET_CERT_INTERNAL_SIMPLE_PATH_BUILDER_DELEGATE_H_ +#endif // NET_CERT_PKI_SIMPLE_PATH_BUILDER_DELEGATE_H_ diff --git a/chromium/net/cert/internal/simple_path_builder_delegate_unittest.cc b/chromium/net/cert/pki/simple_path_builder_delegate_unittest.cc index e89e0b4e312..e9613a1e61f 100644 --- a/chromium/net/cert/internal/simple_path_builder_delegate_unittest.cc +++ b/chromium/net/cert/pki/simple_path_builder_delegate_unittest.cc @@ -1,15 +1,15 @@ // Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/simple_path_builder_delegate.h" +#include "net/cert/pki/simple_path_builder_delegate.h" #include <memory> #include <set> -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/signature_algorithm.h" -#include "net/cert/internal/test_helpers.h" -#include "net/cert/internal/verify_signed_data.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/signature_algorithm.h" +#include "net/cert/pki/test_helpers.h" +#include "net/cert/pki/verify_signed_data.h" #include "net/der/input.h" #include "net/der/parse_values.h" #include "net/der/parser.h" @@ -22,7 +22,7 @@ namespace { // Reads the public key and algorithm from the test data at |file_name|. void ReadTestCase(const char* file_name, - std::unique_ptr<SignatureAlgorithm>* signature_algorithm, + SignatureAlgorithm* signature_algorithm, bssl::UniquePtr<EVP_PKEY>* public_key) { std::string path = std::string("net/data/verify_signed_data_unittest/") + file_name; @@ -31,15 +31,17 @@ void ReadTestCase(const char* file_name, std::string algorithm_str; const PemBlockMapping mappings[] = { - {"PUBLIC KEY", &public_key_str}, {"ALGORITHM", &algorithm_str}, + {"PUBLIC KEY", &public_key_str}, + {"ALGORITHM", &algorithm_str}, }; ASSERT_TRUE(ReadTestDataFromPemFile(path, mappings)); CertErrors algorithm_errors; - *signature_algorithm = - SignatureAlgorithm::Create(der::Input(&algorithm_str), &algorithm_errors); - ASSERT_TRUE(*signature_algorithm) << algorithm_errors.ToDebugString(); + absl::optional<SignatureAlgorithm> sigalg_opt = + ParseSignatureAlgorithm(der::Input(&algorithm_str), &algorithm_errors); + ASSERT_TRUE(sigalg_opt) << algorithm_errors.ToDebugString(); + *signature_algorithm = *sigalg_opt; ASSERT_TRUE(ParsePublicKey(der::Input(&public_key_str), public_key)); } @@ -59,10 +61,10 @@ INSTANTIATE_TEST_SUITE_P(All, ::testing::ValuesIn(kSuccess1024Filenames)); TEST_P(SimplePathBuilderDelegate1024SuccessTest, IsAcceptableSignatureAndKey) { - std::unique_ptr<SignatureAlgorithm> signature_algorithm; + SignatureAlgorithm signature_algorithm; bssl::UniquePtr<EVP_PKEY> public_key; - ReadTestCase(GetParam(), &signature_algorithm, &public_key); - ASSERT_TRUE(signature_algorithm); + ASSERT_NO_FATAL_FAILURE( + ReadTestCase(GetParam(), &signature_algorithm, &public_key)); ASSERT_TRUE(public_key); CertErrors errors; @@ -70,7 +72,7 @@ TEST_P(SimplePathBuilderDelegate1024SuccessTest, IsAcceptableSignatureAndKey) { 1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1); EXPECT_TRUE( - delegate.IsSignatureAlgorithmAcceptable(*signature_algorithm, &errors)); + delegate.IsSignatureAlgorithmAcceptable(signature_algorithm, &errors)); EXPECT_TRUE(delegate.IsPublicKeyAcceptable(public_key.get(), &errors)); } @@ -86,10 +88,10 @@ INSTANTIATE_TEST_SUITE_P(All, ::testing::ValuesIn(kFail2048Filenames)); TEST_P(SimplePathBuilderDelegate2048FailTest, RsaKeySmallerThan2048) { - std::unique_ptr<SignatureAlgorithm> signature_algorithm; + SignatureAlgorithm signature_algorithm; bssl::UniquePtr<EVP_PKEY> public_key; - ReadTestCase(GetParam(), &signature_algorithm, &public_key); - ASSERT_TRUE(signature_algorithm); + ASSERT_NO_FATAL_FAILURE( + ReadTestCase(GetParam(), &signature_algorithm, &public_key)); ASSERT_TRUE(public_key); CertErrors errors; @@ -97,7 +99,7 @@ TEST_P(SimplePathBuilderDelegate2048FailTest, RsaKeySmallerThan2048) { 2048, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1); EXPECT_TRUE( - delegate.IsSignatureAlgorithmAcceptable(*signature_algorithm, &errors)); + delegate.IsSignatureAlgorithmAcceptable(signature_algorithm, &errors)); EXPECT_FALSE(delegate.IsPublicKeyAcceptable(public_key.get(), &errors)); } diff --git a/chromium/net/cert/internal/test_helpers.cc b/chromium/net/cert/pki/test_helpers.cc index 502d708ebee..914b6a3921a 100644 --- a/chromium/net/cert/internal/test_helpers.cc +++ b/chromium/net/cert/pki/test_helpers.cc @@ -2,22 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/test_helpers.h" +#include "net/cert/pki/test_helpers.h" #include "base/base64.h" #include "base/base_paths.h" #include "base/files/file_util.h" #include "base/path_service.h" #include "base/strings/string_piece.h" -#include "base/strings/string_split.h" #include "base/strings/string_util.h" -#include "net/cert/internal/cert_error_params.h" -#include "net/cert/internal/cert_errors.h" #include "net/cert/pem.h" +#include "net/cert/pki/cert_error_params.h" +#include "net/cert/pki/cert_errors.h" #include "net/der/parser.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/boringssl/src/include/openssl/pool.h" +#include <sstream> + namespace net { namespace { @@ -195,9 +196,6 @@ bool ReadVerifyCertChainTestFromFile(const std::string& file_path_ascii, if (file_data.empty()) return false; - std::vector<std::string> lines = base::SplitString( - file_data, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - bool has_chain = false; bool has_trust = false; bool has_time = false; @@ -206,7 +204,20 @@ bool ReadVerifyCertChainTestFromFile(const std::string& file_path_ascii, base::StringPiece kExpectedErrors = "expected_errors:"; - for (const std::string& line : lines) { + std::istringstream stream(file_data); + for (std::string line; std::getline(stream, line, '\n');) { + size_t start = line.find_first_not_of(" \n\t\r\f\v"); + if (start == std::string::npos) { + continue; + } + size_t end = line.find_last_not_of(" \n\t\r\f\v"); + if (end == std::string::npos) { + continue; + } + line = line.substr(start, end + 1); + if (line.empty()) { + continue; + } base::StringPiece line_piece(line); std::string value; diff --git a/chromium/net/cert/internal/test_helpers.h b/chromium/net/cert/pki/test_helpers.h index 864d424f124..0fe301af316 100644 --- a/chromium/net/cert/internal/test_helpers.h +++ b/chromium/net/cert/pki/test_helpers.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_TEST_HELPERS_H_ -#define NET_CERT_INTERNAL_TEST_HELPERS_H_ +#ifndef NET_CERT_PKI_TEST_HELPERS_H_ +#define NET_CERT_PKI_TEST_HELPERS_H_ #include <stddef.h> @@ -12,9 +12,9 @@ #include <vector> #include "base/memory/raw_ptr.h" -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/trust_store.h" -#include "net/cert/internal/verify_certificate_chain.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/trust_store.h" +#include "net/cert/pki/verify_certificate_chain.h" #include "net/der/input.h" #include "testing/gtest/include/gtest/gtest.h" @@ -74,7 +74,7 @@ struct PemBlockMapping { template <size_t N> ::testing::AssertionResult ReadTestDataFromPemFile( const std::string& file_path_ascii, - const PemBlockMapping(&mappings)[N]) { + const PemBlockMapping (&mappings)[N]) { return ReadTestDataFromPemFile(file_path_ascii, mappings, N); } @@ -152,4 +152,4 @@ void VerifyCertErrors(const std::string& expected_errors_str, } // namespace net -#endif // NET_CERT_INTERNAL_TEST_HELPERS_H_ +#endif // NET_CERT_PKI_TEST_HELPERS_H_ diff --git a/chromium/net/cert/internal/trust_store.cc b/chromium/net/cert/pki/trust_store.cc index 5266521dd12..ee504bff53f 100644 --- a/chromium/net/cert/internal/trust_store.cc +++ b/chromium/net/cert/pki/trust_store.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/trust_store.h" +#include "net/cert/pki/trust_store.h" #include "base/notreached.h" diff --git a/chromium/net/cert/internal/trust_store.h b/chromium/net/cert/pki/trust_store.h index e84fc082d5c..1c3a721ea29 100644 --- a/chromium/net/cert/internal/trust_store.h +++ b/chromium/net/cert/pki/trust_store.h @@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_TRUST_STORE_H_ -#define NET_CERT_INTERNAL_TRUST_STORE_H_ +#ifndef NET_CERT_PKI_TRUST_STORE_H_ +#define NET_CERT_PKI_TRUST_STORE_H_ #include <vector> #include "base/memory/ref_counted.h" #include "base/supports_user_data.h" #include "net/base/net_export.h" -#include "net/cert/internal/cert_issuer_source.h" -#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/pki/cert_issuer_source.h" +#include "net/cert/pki/parsed_certificate.h" namespace net { @@ -87,4 +87,4 @@ class NET_EXPORT TrustStore : public CertIssuerSource { } // namespace net -#endif // NET_CERT_INTERNAL_TRUST_STORE_H_ +#endif // NET_CERT_PKI_TRUST_STORE_H_ diff --git a/chromium/net/cert/internal/trust_store_collection.cc b/chromium/net/cert/pki/trust_store_collection.cc index abeed9aac61..03657c4d4a0 100644 --- a/chromium/net/cert/internal/trust_store_collection.cc +++ b/chromium/net/cert/pki/trust_store_collection.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/trust_store_collection.h" +#include "net/cert/pki/trust_store_collection.h" namespace net { diff --git a/chromium/net/cert/internal/trust_store_collection.h b/chromium/net/cert/pki/trust_store_collection.h index f16f28e945e..4d168aa6cfb 100644 --- a/chromium/net/cert/internal/trust_store_collection.h +++ b/chromium/net/cert/pki/trust_store_collection.h @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_TRUST_STORE_COLLECTION_H_ -#define NET_CERT_INTERNAL_TRUST_STORE_COLLECTION_H_ +#ifndef NET_CERT_PKI_TRUST_STORE_COLLECTION_H_ +#define NET_CERT_PKI_TRUST_STORE_COLLECTION_H_ #include "base/memory/ref_counted.h" #include "net/base/net_export.h" -#include "net/cert/internal/trust_store.h" +#include "net/cert/pki/trust_store.h" namespace net { @@ -41,4 +41,4 @@ class NET_EXPORT TrustStoreCollection : public TrustStore { } // namespace net -#endif // NET_CERT_INTERNAL_TRUST_STORE_COLLECTION_H_ +#endif // NET_CERT_PKI_TRUST_STORE_COLLECTION_H_ diff --git a/chromium/net/cert/internal/trust_store_collection_unittest.cc b/chromium/net/cert/pki/trust_store_collection_unittest.cc index d7f7caa8561..8b17c5a8d8d 100644 --- a/chromium/net/cert/internal/trust_store_collection_unittest.cc +++ b/chromium/net/cert/pki/trust_store_collection_unittest.cc @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/trust_store_collection.h" +#include "net/cert/pki/trust_store_collection.h" -#include "net/cert/internal/test_helpers.h" -#include "net/cert/internal/trust_store_in_memory.h" +#include "net/cert/pki/test_helpers.h" +#include "net/cert/pki/trust_store_in_memory.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { diff --git a/chromium/net/cert/internal/trust_store_in_memory.cc b/chromium/net/cert/pki/trust_store_in_memory.cc index 7b64ff1f0fe..7769b992429 100644 --- a/chromium/net/cert/internal/trust_store_in_memory.cc +++ b/chromium/net/cert/pki/trust_store_in_memory.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/trust_store_in_memory.h" +#include "net/cert/pki/trust_store_in_memory.h" namespace net { diff --git a/chromium/net/cert/internal/trust_store_in_memory.h b/chromium/net/cert/pki/trust_store_in_memory.h index 296e87b7119..1d6a7c69257 100644 --- a/chromium/net/cert/internal/trust_store_in_memory.h +++ b/chromium/net/cert/pki/trust_store_in_memory.h @@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_TRUST_STORE_IN_MEMORY_H_ -#define NET_CERT_INTERNAL_TRUST_STORE_IN_MEMORY_H_ +#ifndef NET_CERT_PKI_TRUST_STORE_IN_MEMORY_H_ +#define NET_CERT_PKI_TRUST_STORE_IN_MEMORY_H_ #include <unordered_map> #include "base/memory/ref_counted.h" #include "base/strings/string_piece.h" #include "net/base/net_export.h" -#include "net/cert/internal/trust_store.h" +#include "net/cert/pki/trust_store.h" namespace net { @@ -88,4 +88,4 @@ class NET_EXPORT TrustStoreInMemory : public TrustStore { } // namespace net -#endif // NET_CERT_INTERNAL_TRUST_STORE_IN_MEMORY_H_ +#endif // NET_CERT_PKI_TRUST_STORE_IN_MEMORY_H_ diff --git a/chromium/net/cert/internal/verify_certificate_chain.cc b/chromium/net/cert/pki/verify_certificate_chain.cc index 28ed816948b..5fea3878087 100644 --- a/chromium/net/cert/internal/verify_certificate_chain.cc +++ b/chromium/net/cert/pki/verify_certificate_chain.cc @@ -2,21 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/verify_certificate_chain.h" +#include "net/cert/pki/verify_certificate_chain.h" #include <algorithm> #include "base/check.h" #include "base/memory/raw_ptr.h" -#include "net/cert/internal/cert_error_params.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/common_cert_errors.h" -#include "net/cert/internal/extended_key_usage.h" -#include "net/cert/internal/name_constraints.h" -#include "net/cert/internal/parse_certificate.h" -#include "net/cert/internal/signature_algorithm.h" -#include "net/cert/internal/trust_store.h" -#include "net/cert/internal/verify_signed_data.h" +#include "net/cert/pki/cert_error_params.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/common_cert_errors.h" +#include "net/cert/pki/extended_key_usage.h" +#include "net/cert/pki/name_constraints.h" +#include "net/cert/pki/parse_certificate.h" +#include "net/cert/pki/signature_algorithm.h" +#include "net/cert/pki/trust_store.h" +#include "net/cert/pki/verify_signed_data.h" #include "net/der/input.h" #include "net/der/parser.h" @@ -145,7 +145,20 @@ bool VerifySignatureAlgorithmsMatch(const ParsedCertificate& cert, // But make a compatibility concession if alternate encodings are used // TODO(eroman): Turn this warning into an error. // TODO(eroman): Add a unit-test that exercises this case. - if (SignatureAlgorithm::IsEquivalent(alg1_tlv, alg2_tlv)) { + absl::optional<SignatureAlgorithm> alg1 = + ParseSignatureAlgorithm(alg1_tlv, errors); + if (!alg1) { + errors->AddError(cert_errors::kUnacceptableSignatureAlgorithm); + return false; + } + absl::optional<SignatureAlgorithm> alg2 = + ParseSignatureAlgorithm(alg2_tlv, errors); + if (!alg2) { + errors->AddError(cert_errors::kUnacceptableSignatureAlgorithm); + return false; + } + + if (*alg1 == *alg2) { errors->AddWarning( cert_errors::kSignatureAlgorithmsDifferentEncoding, CreateCertErrorParams2Der("Certificate.algorithm", alg1_tlv, @@ -207,9 +220,7 @@ void VerifyExtendedKeyUsage(const ParsedCertificate& cert, // equivalence between builtin verifier and platform verifier is less // important. if ((cert.has_basic_constraints() && cert.basic_constraints().is_ca) && - (cert.signature_algorithm().algorithm() == - SignatureAlgorithmId::RsaPkcs1) && - (cert.signature_algorithm().digest() == DigestAlgorithm::Sha1)) { + cert.signature_algorithm() == SignatureAlgorithm::kRsaPkcs1Sha1) { return; } } @@ -795,8 +806,10 @@ void PathVerifier::BasicCertificateProcessing( // Check that the signature algorithms in Certificate vs TBSCertificate // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by // sections 4.1.1.2 and 4.1.2.3. - if (!VerifySignatureAlgorithmsMatch(cert, errors)) + if (!VerifySignatureAlgorithmsMatch(cert, errors)) { + CHECK(errors->ContainsAnyErrorWithSeverity(CertError::SEVERITY_HIGH)); *shortcircuit_chain_validation = true; + } // Check whether this signature algorithm is allowed. if (!delegate_->IsSignatureAlgorithmAcceptable(cert.signature_algorithm(), @@ -1274,7 +1287,7 @@ void PathVerifier::Run( // Chains that don't start from a trusted root should short-circuit the // rest of the verification, as accumulating more errors from untrusted // certificates would not be meaningful. - DCHECK(cert_errors->ContainsAnyErrorWithSeverity( + CHECK(cert_errors->ContainsAnyErrorWithSeverity( CertError::SEVERITY_HIGH)); return; } @@ -1295,7 +1308,7 @@ void PathVerifier::Run( // Signature errors should short-circuit the rest of the verification, as // accumulating more errors from untrusted certificates would not be // meaningful. - DCHECK( + CHECK( cert_errors->ContainsAnyErrorWithSeverity(CertError::SEVERITY_HIGH)); return; } diff --git a/chromium/net/cert/internal/verify_certificate_chain.h b/chromium/net/cert/pki/verify_certificate_chain.h index 378a52d2667..3dd187e6ff2 100644 --- a/chromium/net/cert/internal/verify_certificate_chain.h +++ b/chromium/net/cert/pki/verify_certificate_chain.h @@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_VERIFY_CERTIFICATE_CHAIN_H_ -#define NET_CERT_INTERNAL_VERIFY_CERTIFICATE_CHAIN_H_ +#ifndef NET_CERT_PKI_VERIFY_CERTIFICATE_CHAIN_H_ +#define NET_CERT_PKI_VERIFY_CERTIFICATE_CHAIN_H_ #include <set> #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "net/base/net_export.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/parsed_certificate.h" #include "net/der/input.h" #include "third_party/boringssl/src/include/openssl/evp.h" @@ -54,7 +54,7 @@ class NET_EXPORT VerifyCertificateChainDelegate { // can optionally add high-severity errors to |errors| with details on why it // was rejected. virtual bool IsSignatureAlgorithmAcceptable( - const SignatureAlgorithm& signature_algorithm, + SignatureAlgorithm signature_algorithm, CertErrors* errors) = 0; // Implementations should return true if |public_key| is acceptable. This is @@ -245,4 +245,4 @@ NET_EXPORT void VerifyCertificateChain( } // namespace net -#endif // NET_CERT_INTERNAL_VERIFY_CERTIFICATE_CHAIN_H_ +#endif // NET_CERT_PKI_VERIFY_CERTIFICATE_CHAIN_H_ diff --git a/chromium/net/cert/internal/verify_certificate_chain_pkits_unittest.cc b/chromium/net/cert/pki/verify_certificate_chain_pkits_unittest.cc index f262f51eb1e..7a2a4aa32ec 100644 --- a/chromium/net/cert/internal/verify_certificate_chain_pkits_unittest.cc +++ b/chromium/net/cert/pki/verify_certificate_chain_pkits_unittest.cc @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/verify_certificate_chain.h" +#include "net/cert/pki/verify_certificate_chain.h" -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/simple_path_builder_delegate.h" -#include "net/cert/internal/trust_store.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/simple_path_builder_delegate.h" +#include "net/cert/pki/trust_store.h" #include "net/der/input.h" #include "third_party/boringssl/src/include/openssl/pool.h" @@ -17,7 +17,7 @@ #define Section7InvalidkeyUsageNotCriticalcRLSignFalseTest5 \ DISABLED_Section7InvalidkeyUsageNotCriticalcRLSignFalseTest5 -#include "net/cert/internal/nist_pkits_unittest.h" +#include "net/cert/pki/nist_pkits_unittest.h" namespace net { diff --git a/chromium/net/cert/internal/verify_certificate_chain_typed_unittest.h b/chromium/net/cert/pki/verify_certificate_chain_typed_unittest.h index 31a7922a931..c563f17ffa0 100644 --- a/chromium/net/cert/internal/verify_certificate_chain_typed_unittest.h +++ b/chromium/net/cert/pki/verify_certificate_chain_typed_unittest.h @@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_VERIFY_CERTIFICATE_CHAIN_TYPED_UNITTEST_H_ -#define NET_CERT_INTERNAL_VERIFY_CERTIFICATE_CHAIN_TYPED_UNITTEST_H_ +#ifndef NET_CERT_PKI_VERIFY_CERTIFICATE_CHAIN_TYPED_UNITTEST_H_ +#define NET_CERT_PKI_VERIFY_CERTIFICATE_CHAIN_TYPED_UNITTEST_H_ -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/test_helpers.h" -#include "net/cert/internal/trust_store.h" -#include "net/cert/internal/verify_certificate_chain.h" #include "net/cert/pem.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/test_helpers.h" +#include "net/cert/pki/trust_store.h" +#include "net/cert/pki/verify_certificate_chain.h" #include "net/der/input.h" #include "testing/gtest/include/gtest/gtest.h" @@ -225,4 +225,4 @@ REGISTER_TYPED_TEST_SUITE_P(VerifyCertificateChainSingleRootTest, } // namespace net -#endif // NET_CERT_INTERNAL_VERIFY_CERTIFICATE_CHAIN_TYPED_UNITTEST_H_ +#endif // NET_CERT_PKI_VERIFY_CERTIFICATE_CHAIN_TYPED_UNITTEST_H_ diff --git a/chromium/net/cert/internal/verify_certificate_chain_unittest.cc b/chromium/net/cert/pki/verify_certificate_chain_unittest.cc index e82f1d88dd2..a98532ebc0a 100644 --- a/chromium/net/cert/internal/verify_certificate_chain_unittest.cc +++ b/chromium/net/cert/pki/verify_certificate_chain_unittest.cc @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/verify_certificate_chain.h" +#include "net/cert/pki/verify_certificate_chain.h" -#include "net/cert/internal/simple_path_builder_delegate.h" -#include "net/cert/internal/test_helpers.h" -#include "net/cert/internal/trust_store.h" -#include "net/cert/internal/verify_certificate_chain_typed_unittest.h" +#include "net/cert/pki/simple_path_builder_delegate.h" +#include "net/cert/pki/test_helpers.h" +#include "net/cert/pki/trust_store.h" +#include "net/cert/pki/verify_certificate_chain_typed_unittest.h" namespace net { diff --git a/chromium/net/cert/internal/verify_name_match.cc b/chromium/net/cert/pki/verify_name_match.cc index a606d53ce14..b17ab7e2296 100644 --- a/chromium/net/cert/internal/verify_name_match.cc +++ b/chromium/net/cert/pki/verify_name_match.cc @@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/verify_name_match.h" +#include "net/cert/pki/verify_name_match.h" #include "base/check.h" #include "base/notreached.h" #include "base/strings/string_util.h" -#include "net/cert/internal/cert_error_params.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parse_name.h" +#include "net/cert/pki/cert_error_params.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/parse_name.h" #include "net/der/input.h" #include "net/der/parser.h" #include "net/der/tag.h" @@ -352,9 +352,10 @@ bool NormalizeName(const der::Input& name_rdn_sequence, return false; if (!CBB_add_asn1(&attribute_type_and_value_cbb, &value_cbb, CBS_ASN1_UTF8STRING) || - !CBB_add_bytes(&value_cbb, reinterpret_cast<const uint8_t*>( - normalized_value.data()), - normalized_value.size())) + !CBB_add_bytes( + &value_cbb, + reinterpret_cast<const uint8_t*>(normalized_value.data()), + normalized_value.size())) return false; } else { if (!CBB_add_asn1(&attribute_type_and_value_cbb, &value_cbb, diff --git a/chromium/net/cert/internal/verify_name_match.h b/chromium/net/cert/pki/verify_name_match.h index 919effd6a88..4e49d435df5 100644 --- a/chromium/net/cert/internal/verify_name_match.h +++ b/chromium/net/cert/pki/verify_name_match.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_VERIFY_NAME_MATCH_H_ -#define NET_CERT_INTERNAL_VERIFY_NAME_MATCH_H_ +#ifndef NET_CERT_PKI_VERIFY_NAME_MATCH_H_ +#define NET_CERT_PKI_VERIFY_NAME_MATCH_H_ #include <string> @@ -54,4 +54,4 @@ NET_EXPORT bool VerifyNameInSubtree(const der::Input& name_rdn_sequence, } // namespace net -#endif // NET_CERT_INTERNAL_VERIFY_NAME_MATCH_H_ +#endif // NET_CERT_PKI_VERIFY_NAME_MATCH_H_ diff --git a/chromium/net/cert/internal/verify_name_match_fuzzer.cc b/chromium/net/cert/pki/verify_name_match_fuzzer.cc index 6522387c0fc..02ae46f62bd 100644 --- a/chromium/net/cert/internal/verify_name_match_fuzzer.cc +++ b/chromium/net/cert/pki/verify_name_match_fuzzer.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/verify_name_match.h" +#include "net/cert/pki/verify_name_match.h" #include <stddef.h> #include <stdint.h> diff --git a/chromium/net/cert/internal/verify_name_match_normalizename_fuzzer.cc b/chromium/net/cert/pki/verify_name_match_normalizename_fuzzer.cc index c65d4ee521e..dc5c810c501 100644 --- a/chromium/net/cert/internal/verify_name_match_normalizename_fuzzer.cc +++ b/chromium/net/cert/pki/verify_name_match_normalizename_fuzzer.cc @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/verify_name_match.h" +#include "net/cert/pki/verify_name_match.h" -#include "net/cert/internal/cert_errors.h" +#include "net/cert/pki/cert_errors.h" #include "net/der/input.h" // Entry point for LibFuzzer. diff --git a/chromium/net/cert/internal/verify_name_match_unittest.cc b/chromium/net/cert/pki/verify_name_match_unittest.cc index e7a61174323..59660c0c936 100644 --- a/chromium/net/cert/internal/verify_name_match_unittest.cc +++ b/chromium/net/cert/pki/verify_name_match_unittest.cc @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/verify_name_match.h" +#include "net/cert/pki/verify_name_match.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" -#include "net/cert/internal/test_helpers.h" +#include "net/cert/pki/test_helpers.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { diff --git a/chromium/net/cert/internal/verify_name_match_verifynameinsubtree_fuzzer.cc b/chromium/net/cert/pki/verify_name_match_verifynameinsubtree_fuzzer.cc index 4b981c9a676..996a6353342 100644 --- a/chromium/net/cert/internal/verify_name_match_verifynameinsubtree_fuzzer.cc +++ b/chromium/net/cert/pki/verify_name_match_verifynameinsubtree_fuzzer.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/verify_name_match.h" +#include "net/cert/pki/verify_name_match.h" #include <stddef.h> #include <stdint.h> diff --git a/chromium/net/cert/internal/verify_signed_data.cc b/chromium/net/cert/pki/verify_signed_data.cc index 6fb34a18df6..5dc399129a2 100644 --- a/chromium/net/cert/internal/verify_signed_data.cc +++ b/chromium/net/cert/pki/verify_signed_data.cc @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/verify_signed_data.h" +#include "net/cert/pki/verify_signed_data.h" #include "base/numerics/safe_math.h" #include "crypto/openssl_util.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/signature_algorithm.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/signature_algorithm.h" #include "net/der/input.h" #include "net/der/parse_values.h" #include "net/der/parser.h" @@ -18,56 +18,6 @@ namespace net { -namespace { - -// Converts a DigestAlgorithm to an equivalent EVP_MD*. -[[nodiscard]] bool GetDigest(DigestAlgorithm digest, const EVP_MD** out) { - *out = nullptr; - - switch (digest) { - case DigestAlgorithm::Md2: - case DigestAlgorithm::Md4: - case DigestAlgorithm::Md5: - // Unsupported. - break; - case DigestAlgorithm::Sha1: - *out = EVP_sha1(); - break; - case DigestAlgorithm::Sha256: - *out = EVP_sha256(); - break; - case DigestAlgorithm::Sha384: - *out = EVP_sha384(); - break; - case DigestAlgorithm::Sha512: - *out = EVP_sha512(); - break; - } - - return *out != nullptr; -} - -// Sets the RSASSA-PSS parameters on |pctx|. Returns true on success. -[[nodiscard]] bool ApplyRsaPssOptions(const RsaPssParameters* params, - EVP_PKEY_CTX* pctx) { - // BoringSSL takes a signed int for the salt length, and interprets - // negative values in a special manner. Make sure not to silently underflow. - base::CheckedNumeric<int> salt_length_bytes_int(params->salt_length()); - if (!salt_length_bytes_int.IsValid()) - return false; - - const EVP_MD* mgf1_hash; - if (!GetDigest(params->mgf1_hash(), &mgf1_hash)) - return false; - - return EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) && - EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1_hash) && - EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, - salt_length_bytes_int.ValueOrDie()); -} - -} // namespace - // Parses an RSA public key or EC public key from SPKI to an EVP_PKEY. Returns // true on success. // @@ -148,23 +98,72 @@ bool ParsePublicKey(const der::Input& public_key_spki, return true; } -bool VerifySignedData(const SignatureAlgorithm& algorithm, +bool VerifySignedData(SignatureAlgorithm algorithm, const der::Input& signed_data, const der::BitString& signature_value, EVP_PKEY* public_key) { - // Check that the key type matches the signature algorithm. - int expected_pkey_id = -1; - switch (algorithm.algorithm()) { - case SignatureAlgorithmId::Dsa: - // DSA is not supported. - return false; - case SignatureAlgorithmId::RsaPkcs1: - case SignatureAlgorithmId::RsaPss: + int expected_pkey_id = 1; + const EVP_MD* digest = nullptr; + bool is_rsa_pss = false; + switch (algorithm) { + case SignatureAlgorithm::kRsaPkcs1Sha1: + expected_pkey_id = EVP_PKEY_RSA; + digest = EVP_sha1(); + break; + case SignatureAlgorithm::kRsaPkcs1Sha256: + expected_pkey_id = EVP_PKEY_RSA; + digest = EVP_sha256(); + break; + case SignatureAlgorithm::kRsaPkcs1Sha384: expected_pkey_id = EVP_PKEY_RSA; + digest = EVP_sha384(); break; - case SignatureAlgorithmId::Ecdsa: + case SignatureAlgorithm::kRsaPkcs1Sha512: + expected_pkey_id = EVP_PKEY_RSA; + digest = EVP_sha512(); + break; + + case SignatureAlgorithm::kEcdsaSha1: expected_pkey_id = EVP_PKEY_EC; + digest = EVP_sha1(); + break; + case SignatureAlgorithm::kEcdsaSha256: + expected_pkey_id = EVP_PKEY_EC; + digest = EVP_sha256(); + break; + case SignatureAlgorithm::kEcdsaSha384: + expected_pkey_id = EVP_PKEY_EC; + digest = EVP_sha384(); + break; + case SignatureAlgorithm::kEcdsaSha512: + expected_pkey_id = EVP_PKEY_EC; + digest = EVP_sha512(); + break; + + case SignatureAlgorithm::kRsaPssSha256: + expected_pkey_id = EVP_PKEY_RSA; + digest = EVP_sha256(); + is_rsa_pss = true; + break; + case SignatureAlgorithm::kRsaPssSha384: + expected_pkey_id = EVP_PKEY_RSA; + digest = EVP_sha384(); + is_rsa_pss = true; break; + case SignatureAlgorithm::kRsaPssSha512: + expected_pkey_id = EVP_PKEY_RSA; + digest = EVP_sha512(); + is_rsa_pss = true; + break; + + case SignatureAlgorithm::kDsaSha1: + case SignatureAlgorithm::kDsaSha256: + case SignatureAlgorithm::kRsaPkcs1Md2: + case SignatureAlgorithm::kRsaPkcs1Md4: + case SignatureAlgorithm::kRsaPkcs1Md5: + // DSA, MD2, MD4, and MD5 are not supported. See + // https://crbug.com/1321688. + return false; } if (expected_pkey_id != EVP_PKEY_id(public_key)) @@ -181,17 +180,17 @@ bool VerifySignedData(const SignatureAlgorithm& algorithm, bssl::ScopedEVP_MD_CTX ctx; EVP_PKEY_CTX* pctx = nullptr; // Owned by |ctx|. - const EVP_MD* digest; - if (!GetDigest(algorithm.digest(), &digest)) - return false; - if (!EVP_DigestVerifyInit(ctx.get(), &pctx, digest, nullptr, public_key)) return false; - // Set the RSASSA-PSS specific options. - if (algorithm.algorithm() == SignatureAlgorithmId::RsaPss && - !ApplyRsaPssOptions(algorithm.ParamsForRsaPss(), pctx)) { - return false; + if (is_rsa_pss) { + // All supported RSASSA-PSS algorithms match signing and MGF-1 digest. They + // also use the digest length as the salt length, which is specified with -1 + // in OpenSSL's API. + if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) { + return false; + } } if (!EVP_DigestVerifyUpdate(ctx.get(), signed_data.UnsafeData(), @@ -204,7 +203,7 @@ bool VerifySignedData(const SignatureAlgorithm& algorithm, signature_value_bytes.Length()); } -bool VerifySignedData(const SignatureAlgorithm& algorithm, +bool VerifySignedData(SignatureAlgorithm algorithm, const der::Input& signed_data, const der::BitString& signature_value, const der::Input& public_key_spki) { diff --git a/chromium/net/cert/internal/verify_signed_data.h b/chromium/net/cert/pki/verify_signed_data.h index 3f97c95e858..b904992dc1c 100644 --- a/chromium/net/cert/internal/verify_signed_data.h +++ b/chromium/net/cert/pki/verify_signed_data.h @@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef NET_CERT_INTERNAL_VERIFY_SIGNED_DATA_H_ -#define NET_CERT_INTERNAL_VERIFY_SIGNED_DATA_H_ +#ifndef NET_CERT_PKI_VERIFY_SIGNED_DATA_H_ +#define NET_CERT_PKI_VERIFY_SIGNED_DATA_H_ #include "crypto/openssl_util.h" #include "net/base/net_export.h" +#include "net/cert/pki/signature_algorithm.h" #include "third_party/boringssl/src/include/openssl/evp.h" namespace net { @@ -16,8 +17,6 @@ class BitString; class Input; } // namespace der -class SignatureAlgorithm; - // Verifies that |signature_value| is a valid signature of |signed_data| using // the algorithm |algorithm| and the public key |public_key|. // @@ -28,7 +27,7 @@ class SignatureAlgorithm; // // Returns true if verification was successful. [[nodiscard]] NET_EXPORT bool VerifySignedData( - const SignatureAlgorithm& algorithm, + SignatureAlgorithm algorithm, const der::Input& signed_data, const der::BitString& signature_value, EVP_PKEY* public_key); @@ -36,7 +35,7 @@ class SignatureAlgorithm; // Same as above overload, only the public key is inputted as an SPKI and will // be parsed internally. [[nodiscard]] NET_EXPORT bool VerifySignedData( - const SignatureAlgorithm& algorithm, + SignatureAlgorithm algorithm, const der::Input& signed_data, const der::BitString& signature_value, const der::Input& public_key_spki); @@ -47,4 +46,4 @@ class SignatureAlgorithm; } // namespace net -#endif // NET_CERT_INTERNAL_VERIFY_SIGNED_DATA_H_ +#endif // NET_CERT_PKI_VERIFY_SIGNED_DATA_H_ diff --git a/chromium/net/cert/internal/verify_signed_data_unittest.cc b/chromium/net/cert/pki/verify_signed_data_unittest.cc index 62bf85f161b..8a0a26e9cb0 100644 --- a/chromium/net/cert/internal/verify_signed_data_unittest.cc +++ b/chromium/net/cert/pki/verify_signed_data_unittest.cc @@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/cert/internal/verify_signed_data.h" +#include "net/cert/pki/verify_signed_data.h" #include <memory> #include <set> -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/signature_algorithm.h" -#include "net/cert/internal/test_helpers.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/signature_algorithm.h" +#include "net/cert/pki/test_helpers.h" #include "net/der/input.h" #include "net/der/parse_values.h" #include "net/der/parser.h" @@ -52,8 +52,8 @@ void RunTestCase(VerifyResult expected_result, const char* file_name) { ASSERT_TRUE(ReadTestDataFromPemFile(path, mappings)); CertErrors algorithm_errors; - std::unique_ptr<SignatureAlgorithm> signature_algorithm = - SignatureAlgorithm::Create(der::Input(&algorithm), &algorithm_errors); + absl::optional<SignatureAlgorithm> signature_algorithm = + ParseSignatureAlgorithm(der::Input(&algorithm), &algorithm_errors); ASSERT_TRUE(signature_algorithm) << algorithm_errors.ToDebugString(); der::Parser signature_value_parser((der::Input(&signature_value))); diff --git a/chromium/net/cert/root_cert_list_generated.h b/chromium/net/cert/root_cert_list_generated.h index 354469a69ca..8f5f7591d1c 100644 --- a/chromium/net/cert/root_cert_list_generated.h +++ b/chromium/net/cert/root_cert_list_generated.h @@ -1004,6 +1004,13 @@ const struct RootCertData { 187, false}, {{ + 0x42, 0x43, 0x16, 0x27, 0xEA, 0x76, 0xCC, 0x78, 0x69, 0x7F, 0x91, + 0x5E, 0x34, 0x55, 0xB1, 0xB2, 0xEC, 0x82, 0xFF, 0x2F, 0x63, 0x80, + 0xEE, 0x64, 0x23, 0xEF, 0x3C, 0x08, 0x40, 0xB7, 0xE6, 0x31, + }, + 521, + false}, + {{ 0x42, 0xA7, 0x09, 0x84, 0xFF, 0xD3, 0x99, 0xC4, 0xEA, 0xF0, 0xE7, 0x02, 0xA4, 0x4B, 0xEF, 0x2A, 0xD8, 0xA7, 0x9B, 0x8B, 0xF4, 0x64, 0x8F, 0x6B, 0xB2, 0x10, 0xE1, 0x23, 0xFD, 0x07, 0x57, 0x93, diff --git a/chromium/net/cert/sct_status_flags.cc b/chromium/net/cert/sct_status_flags.cc index a8f070a7298..92042fa6429 100644 --- a/chromium/net/cert/sct_status_flags.cc +++ b/chromium/net/cert/sct_status_flags.cc @@ -4,9 +4,7 @@ #include "net/cert/sct_status_flags.h" -namespace net { - -namespace ct { +namespace net::ct { bool IsValidSCTStatus(uint32_t status) { switch (status) { @@ -22,6 +20,4 @@ bool IsValidSCTStatus(uint32_t status) { return false; } -} // namespace ct - -} // namespace net +} // namespace net::ct diff --git a/chromium/net/cert/sct_status_flags.h b/chromium/net/cert/sct_status_flags.h index 86daa0c5925..0957cdcbf6c 100644 --- a/chromium/net/cert/sct_status_flags.h +++ b/chromium/net/cert/sct_status_flags.h @@ -9,9 +9,7 @@ #include "net/base/net_export.h" -namespace net { - -namespace ct { +namespace net::ct { // The possible verification statuses for a SignedCertificateTimestamp. // Note: The numeric values are used within histograms and should not change @@ -46,8 +44,6 @@ enum SCTVerifyStatus : uint32_t { // is all current values in the enum except SCT_STATUS_NONE. NET_EXPORT bool IsValidSCTStatus(uint32_t status); -} // namespace ct - -} // namespace net +} // namespace net::ct #endif // NET_CERT_SCT_STATUS_FLAGS_H_ diff --git a/chromium/net/cert/signed_certificate_timestamp.cc b/chromium/net/cert/signed_certificate_timestamp.cc index aa3308985d9..da6e2c967b9 100644 --- a/chromium/net/cert/signed_certificate_timestamp.cc +++ b/chromium/net/cert/signed_certificate_timestamp.cc @@ -6,9 +6,7 @@ #include "base/pickle.h" -namespace net { - -namespace ct { +namespace net::ct { bool SignedCertificateTimestamp::LessThan::operator()( const scoped_refptr<SignedCertificateTimestamp>& lhs, @@ -51,8 +49,7 @@ SignedCertificateTimestamp::CreateFromPickle(base::PickleIterator* iter) { int64_t timestamp; int hash_algorithm; int sig_algorithm; - scoped_refptr<SignedCertificateTimestamp> sct( - new SignedCertificateTimestamp()); + auto sct = base::MakeRefCounted<SignedCertificateTimestamp>(); int origin; // string values are set directly if (!(iter->ReadInt(&version) && @@ -97,6 +94,4 @@ bool DigitallySigned::SignatureParametersMatch( return (hash_algorithm == other_hash_algorithm) && (signature_algorithm == other_signature_algorithm); } -} // namespace ct - -} // namespace net +} // namespace net::ct diff --git a/chromium/net/cert/signed_certificate_timestamp.h b/chromium/net/cert/signed_certificate_timestamp.h index 50d5a02a8bb..a877ee724ec 100644 --- a/chromium/net/cert/signed_certificate_timestamp.h +++ b/chromium/net/cert/signed_certificate_timestamp.h @@ -18,10 +18,8 @@ class Pickle; class PickleIterator; } -namespace net { - // Structures related to Certificate Transparency (RFC6962). -namespace ct { +namespace net::ct { // Contains the data necessary to reconstruct the signed_entry of a // SignedCertificateTimestamp, from RFC 6962, Section 3.2. @@ -148,8 +146,6 @@ struct NET_EXPORT SignedCertificateTimestamp using SCTList = std::vector<scoped_refptr<ct::SignedCertificateTimestamp>>; -} // namespace ct - -} // namespace net +} // namespace net::ct #endif // NET_CERT_SIGNED_CERTIFICATE_TIMESTAMP_H_ diff --git a/chromium/net/cert/signed_certificate_timestamp_unittest.cc b/chromium/net/cert/signed_certificate_timestamp_unittest.cc index 90b4ab740e3..0b9a7d96b88 100644 --- a/chromium/net/cert/signed_certificate_timestamp_unittest.cc +++ b/chromium/net/cert/signed_certificate_timestamp_unittest.cc @@ -10,9 +10,7 @@ #include "net/test/ct_test_util.h" #include "testing/gtest/include/gtest/gtest.h" -namespace net { - -namespace ct { +namespace net::ct { namespace { @@ -60,6 +58,4 @@ TEST_F(SignedCertificateTimestampTest, SCTsWithDifferentOriginsNotEqual) { } // namespace -} // namespace ct - -} // namespace net +} // namespace net::ct diff --git a/chromium/net/cert/signed_tree_head.cc b/chromium/net/cert/signed_tree_head.cc index a2dc9efbfb6..9640b135a5d 100644 --- a/chromium/net/cert/signed_tree_head.cc +++ b/chromium/net/cert/signed_tree_head.cc @@ -10,8 +10,7 @@ #include "base/strings/string_number_conversions.h" -namespace net { -namespace ct { +namespace net::ct { SignedTreeHead::SignedTreeHead() = default; @@ -59,5 +58,4 @@ bool operator!=(const SignedTreeHead& lhs, const SignedTreeHead& rhs) { return !(lhs == rhs); } -} // namespace ct -} // namespace net +} // namespace net::ct diff --git a/chromium/net/cert/signed_tree_head.h b/chromium/net/cert/signed_tree_head.h index 2b97f744506..13248888314 100644 --- a/chromium/net/cert/signed_tree_head.h +++ b/chromium/net/cert/signed_tree_head.h @@ -16,9 +16,7 @@ #include "net/base/net_export.h" #include "net/cert/signed_certificate_timestamp.h" -namespace net { - -namespace ct { +namespace net::ct { static const uint8_t kSthRootHashLength = 32; @@ -57,8 +55,6 @@ NET_EXPORT bool operator==(const SignedTreeHead& lhs, NET_EXPORT bool operator!=(const SignedTreeHead& lhs, const SignedTreeHead& rhs); -} // namespace ct - -} // namespace net +} // namespace net::ct #endif // NET_CERT_SIGNED_TREE_HEAD_H_ diff --git a/chromium/net/cert/test_root_certs.cc b/chromium/net/cert/test_root_certs.cc index 10adc528919..fd158a06352 100644 --- a/chromium/net/cert/test_root_certs.cc +++ b/chromium/net/cert/test_root_certs.cc @@ -7,11 +7,7 @@ #include <string> #include <utility> -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/threading/thread_restrictions.h" -#include "net/cert/internal/cert_errors.h" +#include "net/cert/pki/cert_errors.h" #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" #include "third_party/boringssl/src/include/openssl/pool.h" @@ -25,17 +21,6 @@ bool g_has_instance = false; base::LazyInstance<TestRootCerts>::Leaky g_test_root_certs = LAZY_INSTANCE_INITIALIZER; -CertificateList LoadCertificates(const base::FilePath& filename) { - std::string raw_cert; - if (!base::ReadFileToString(filename, &raw_cert)) { - LOG(ERROR) << "Can't load certificate " << filename.value(); - return CertificateList(); - } - - return X509Certificate::CreateCertificateListFromBytes( - base::as_bytes(base::make_span(raw_cert)), X509Certificate::FORMAT_AUTO); -} - } // namespace // static @@ -60,15 +45,6 @@ bool TestRootCerts::Add(X509Certificate* certificate) { return AddImpl(certificate); } -bool TestRootCerts::AddFromFile(const base::FilePath& file) { - base::ThreadRestrictions::ScopedAllowIO allow_io_for_loading_test_certs; - CertificateList root_certs = LoadCertificates(file); - if (root_certs.empty() || root_certs.size() > 1) - return false; - - return Add(root_certs.front().get()); -} - void TestRootCerts::Clear() { ClearImpl(); test_trust_store_.Clear(); @@ -93,6 +69,17 @@ ScopedTestRoot::ScopedTestRoot(CertificateList certs) { Reset(std::move(certs)); } +ScopedTestRoot::ScopedTestRoot(ScopedTestRoot&& other) { + *this = std::move(other); +} + +ScopedTestRoot& ScopedTestRoot::operator=(ScopedTestRoot&& other) { + CertificateList tmp_certs; + tmp_certs.swap(other.certs_); + Reset(std::move(tmp_certs)); + return *this; +} + ScopedTestRoot::~ScopedTestRoot() { Reset({}); } diff --git a/chromium/net/cert/test_root_certs.h b/chromium/net/cert/test_root_certs.h index f2251dd1e78..c299b3c6d3b 100644 --- a/chromium/net/cert/test_root_certs.h +++ b/chromium/net/cert/test_root_certs.h @@ -6,10 +6,9 @@ #define NET_CERT_TEST_ROOT_CERTS_H_ #include "base/lazy_instance.h" -#include "base/memory/ref_counted.h" #include "build/build_config.h" #include "net/base/net_export.h" -#include "net/cert/internal/trust_store_in_memory.h" +#include "net/cert/pki/trust_store_in_memory.h" #if BUILDFLAG(IS_WIN) #include <windows.h> @@ -21,10 +20,6 @@ #include "base/mac/scoped_cftyperef.h" #endif -namespace base { -class FilePath; -} - namespace net { class X509Certificate; @@ -33,6 +28,9 @@ typedef std::vector<scoped_refptr<X509Certificate>> CertificateList; // TestRootCerts is a helper class for unit tests that is used to // artificially mark a certificate as trusted, independent of the local // machine configuration. +// +// Test roots can be added using the ScopedTestRoot class below. See the +// class documentation for usage and limitations. class NET_EXPORT TestRootCerts { public: // Obtains the Singleton instance to the trusted certificates. @@ -44,16 +42,6 @@ class NET_EXPORT TestRootCerts { // Returns true if an instance exists, without forcing an initialization. static bool HasInstance(); - // Marks |certificate| as trusted in the effective trust store - // used by CertVerifier::Verify(). Returns false if the - // certificate could not be marked trusted. - bool Add(X509Certificate* certificate); - - // Reads a single certificate from |file| and marks it as trusted. Returns - // false if an error is encountered, such as being unable to read |file| - // or more than one certificate existing in |file|. - bool AddFromFile(const base::FilePath& file); - // Clears the trusted status of any certificates that were previously // marked trusted via Add(). void Clear(); @@ -81,10 +69,16 @@ class NET_EXPORT TestRootCerts { private: friend struct base::LazyInstanceTraitsBase<TestRootCerts>; + friend class ScopedTestRoot; TestRootCerts(); ~TestRootCerts(); + // Marks |certificate| as trusted in the effective trust store + // used by CertVerifier::Verify(). Returns false if the + // certificate could not be marked trusted. + bool Add(X509Certificate* certificate); + // Performs platform-dependent operations. void Init(); bool AddImpl(X509Certificate* certificate); @@ -100,21 +94,27 @@ class NET_EXPORT TestRootCerts { }; // Scoped helper for unittests to handle safely managing trusted roots. -class NET_EXPORT_PRIVATE ScopedTestRoot { +// +// Limitations: +// Multiple instances of ScopedTestRoot may be created at once, which will +// trust the union of the certs provided. However, when one of the +// ScopedTestRoot instances removes its trust, either by going out of scope, or +// by Reset() being called, *all* test root certs will be untrusted. (This +// limitation could be removed if a reason arises.) +class NET_EXPORT ScopedTestRoot { public: ScopedTestRoot(); - // Creates a ScopedTestRoot that sets |cert| as the single root in the - // TestRootCerts store (if there were existing roots they are - // cleared). + // Creates a ScopedTestRoot that adds |cert| to the TestRootCerts store. explicit ScopedTestRoot(X509Certificate* cert); - // Creates a ScopedTestRoot that sets |certs| as the only roots in the - // TestRootCerts store (if there were existing roots they are - // cleared). + // Creates a ScopedTestRoot that adds |certs| to the TestRootCerts store. explicit ScopedTestRoot(CertificateList certs); ScopedTestRoot(const ScopedTestRoot&) = delete; ScopedTestRoot& operator=(const ScopedTestRoot&) = delete; + ScopedTestRoot(ScopedTestRoot&& other); + ScopedTestRoot& operator=(ScopedTestRoot&& other); + ~ScopedTestRoot(); // Assigns |certs| to be the new test root certs. If |certs| is empty, undoes @@ -124,6 +124,9 @@ class NET_EXPORT_PRIVATE ScopedTestRoot { // cleared. void Reset(CertificateList certs); + // Returns true if this ScopedTestRoot has no certs assigned. + bool IsEmpty() const { return certs_.empty(); } + private: CertificateList certs_; }; diff --git a/chromium/net/cert/test_root_certs_android.cc b/chromium/net/cert/test_root_certs_android.cc index 308c081d82a..ce1bca56018 100644 --- a/chromium/net/cert/test_root_certs_android.cc +++ b/chromium/net/cert/test_root_certs_android.cc @@ -25,7 +25,7 @@ void TestRootCerts::ClearImpl() { android::ClearTestRootCertificates(); } -TestRootCerts::~TestRootCerts() {} +TestRootCerts::~TestRootCerts() = default; void TestRootCerts::Init() {} diff --git a/chromium/net/cert/test_root_certs_builtin.cc b/chromium/net/cert/test_root_certs_builtin.cc index aae6e0ceafd..c26eb4a290e 100644 --- a/chromium/net/cert/test_root_certs_builtin.cc +++ b/chromium/net/cert/test_root_certs_builtin.cc @@ -12,7 +12,7 @@ bool TestRootCerts::AddImpl(X509Certificate* certificate) { void TestRootCerts::ClearImpl() {} -TestRootCerts::~TestRootCerts() {} +TestRootCerts::~TestRootCerts() = default; void TestRootCerts::Init() {} diff --git a/chromium/net/cert/test_root_certs_mac.cc b/chromium/net/cert/test_root_certs_mac.cc index f57ad926459..d5023728e2c 100644 --- a/chromium/net/cert/test_root_certs_mac.cc +++ b/chromium/net/cert/test_root_certs_mac.cc @@ -7,7 +7,7 @@ #include <Security/Security.h> #include "build/build_config.h" -#include "net/cert/internal/cert_errors.h" +#include "net/cert/pki/cert_errors.h" #include "net/cert/x509_certificate.h" #include "net/cert/x509_util.h" #include "net/cert/x509_util_apple.h" @@ -44,7 +44,7 @@ OSStatus TestRootCerts::FixupSecTrustRef(SecTrustRef trust_ref) const { return SecTrustSetAnchorCertificatesOnly(trust_ref, false); } -TestRootCerts::~TestRootCerts() {} +TestRootCerts::~TestRootCerts() = default; void TestRootCerts::Init() { temporary_roots_.reset( diff --git a/chromium/net/cert/test_root_certs_unittest.cc b/chromium/net/cert/test_root_certs_unittest.cc index 36b14065675..f430c590623 100644 --- a/chromium/net/cert/test_root_certs_unittest.cc +++ b/chromium/net/cert/test_root_certs_unittest.cc @@ -59,26 +59,10 @@ TEST(TestRootCertsTest, AddFromPointer) { ASSERT_NE(static_cast<TestRootCerts*>(nullptr), test_roots); EXPECT_TRUE(test_roots->IsEmpty()); - EXPECT_TRUE(test_roots->Add(root_cert.get())); - EXPECT_FALSE(test_roots->IsEmpty()); - - test_roots->Clear(); - EXPECT_TRUE(test_roots->IsEmpty()); -} - -// Test basic functionality when adding directly from a file, which should -// behave the same as when adding from an existing certificate. -TEST(TestRootCertsTest, AddFromFile) { - TestRootCerts* test_roots = TestRootCerts::GetInstance(); - ASSERT_NE(static_cast<TestRootCerts*>(nullptr), test_roots); - EXPECT_TRUE(test_roots->IsEmpty()); - - base::FilePath cert_path = - GetTestCertsDirectory().AppendASCII(kRootCertificateFile); - EXPECT_TRUE(test_roots->AddFromFile(cert_path)); - EXPECT_FALSE(test_roots->IsEmpty()); - - test_roots->Clear(); + { + ScopedTestRoot scoped_root(root_cert.get()); + EXPECT_FALSE(test_roots->IsEmpty()); + } EXPECT_TRUE(test_roots->IsEmpty()); } @@ -109,8 +93,10 @@ TEST(TestRootCertsTest, OverrideTrust) { EXPECT_NE(0u, bad_verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID); // Add the root certificate and mark it as trusted. - EXPECT_TRUE(test_roots->AddFromFile( - GetTestCertsDirectory().AppendASCII(kRootCertificateFile))); + scoped_refptr<X509Certificate> root_cert = + ImportCertFromFile(GetTestCertsDirectory(), kRootCertificateFile); + ASSERT_TRUE(root_cert); + ScopedTestRoot scoped_root(root_cert.get()); EXPECT_FALSE(test_roots->IsEmpty()); // Test that the certificate verification now succeeds, because the @@ -141,6 +127,91 @@ TEST(TestRootCertsTest, OverrideTrust) { EXPECT_EQ(bad_verify_result.cert_status, restored_verify_result.cert_status); } +TEST(TestRootCertsTest, Moveable) { + TestRootCerts* test_roots = TestRootCerts::GetInstance(); + ASSERT_NE(static_cast<TestRootCerts*>(nullptr), test_roots); + EXPECT_TRUE(test_roots->IsEmpty()); + + scoped_refptr<X509Certificate> test_cert = + ImportCertFromFile(GetTestCertsDirectory(), kGoodCertificateFile); + ASSERT_NE(static_cast<X509Certificate*>(nullptr), test_cert.get()); + + int flags = 0; + CertVerifyResult bad_verify_result; + int bad_status; + scoped_refptr<CertVerifyProc> verify_proc(CreateCertVerifyProc()); + { + // Empty ScopedTestRoot at outer scope has no effect. + ScopedTestRoot scoped_root_outer; + EXPECT_TRUE(test_roots->IsEmpty()); + + // Test that the good certificate fails verification, because the root + // certificate should not yet be trusted. + bad_status = verify_proc->Verify( + test_cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(), + /*sct_list=*/std::string(), flags, net::CRLSet::BuiltinCRLSet().get(), + CertificateList(), &bad_verify_result, NetLogWithSource()); + EXPECT_NE(OK, bad_status); + EXPECT_NE(0u, + bad_verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID); + + { + // Add the root certificate and mark it as trusted. + scoped_refptr<X509Certificate> root_cert = + ImportCertFromFile(GetTestCertsDirectory(), kRootCertificateFile); + ASSERT_TRUE(root_cert); + ScopedTestRoot scoped_root_inner(root_cert.get()); + EXPECT_FALSE(test_roots->IsEmpty()); + + // Test that the certificate verification now succeeds, because the + // TestRootCerts is successfully imbuing trust. + CertVerifyResult good_verify_result; + int good_status = verify_proc->Verify( + test_cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(), + /*sct_list=*/std::string(), flags, CRLSet::BuiltinCRLSet().get(), + CertificateList(), &good_verify_result, NetLogWithSource()); + EXPECT_THAT(good_status, IsOk()); + EXPECT_EQ(0u, good_verify_result.cert_status); + + EXPECT_FALSE(scoped_root_inner.IsEmpty()); + EXPECT_TRUE(scoped_root_outer.IsEmpty()); + // Move from inner scoped root to outer + scoped_root_outer = std::move(scoped_root_inner); + EXPECT_FALSE(test_roots->IsEmpty()); + EXPECT_FALSE(scoped_root_outer.IsEmpty()); + } + // After inner scoper was freed, test root is still trusted since ownership + // was moved to the outer scoper. + EXPECT_FALSE(test_roots->IsEmpty()); + EXPECT_FALSE(scoped_root_outer.IsEmpty()); + + // Test that the certificate verification still succeeds, because the + // TestRootCerts is successfully imbuing trust. + CertVerifyResult good_verify_result; + int good_status = verify_proc->Verify( + test_cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(), + /*sct_list=*/std::string(), flags, CRLSet::BuiltinCRLSet().get(), + CertificateList(), &good_verify_result, NetLogWithSource()); + EXPECT_THAT(good_status, IsOk()); + EXPECT_EQ(0u, good_verify_result.cert_status); + } + EXPECT_TRUE(test_roots->IsEmpty()); + + // Ensure that when the TestRootCerts is cleared, the trust settings + // revert to their original state, and don't linger. If trust status + // lingers, it will likely break other tests in net_unittests. + CertVerifyResult restored_verify_result; + int restored_status = verify_proc->Verify( + test_cert.get(), "127.0.0.1", /*ocsp_response=*/std::string(), + /*sct_list=*/std::string(), flags, CRLSet::BuiltinCRLSet().get(), + CertificateList(), &restored_verify_result, NetLogWithSource()); + EXPECT_NE(OK, restored_status); + EXPECT_NE(0u, + restored_verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID); + EXPECT_EQ(bad_status, restored_status); + EXPECT_EQ(bad_verify_result.cert_status, restored_verify_result.cert_status); +} + // TODO(rsleevi): Add tests for revocation checking via CRLs, ensuring that // TestRootCerts properly injects itself into the validation process. See // http://crbug.com/63958 diff --git a/chromium/net/cert/trial_comparison_cert_verifier.cc b/chromium/net/cert/trial_comparison_cert_verifier.cc index a1d93edec27..963677c5ed0 100644 --- a/chromium/net/cert/trial_comparison_cert_verifier.cc +++ b/chromium/net/cert/trial_comparison_cert_verifier.cc @@ -30,9 +30,9 @@ namespace net { namespace { base::Value JobResultParams(bool trial_success) { - base::Value results(base::Value::Type::DICTIONARY); - results.GetDict().Set("trial_success", trial_success); - return results; + base::Value::Dict results; + results.Set("trial_success", trial_success); + return base::Value(std::move(results)); } } // namespace diff --git a/chromium/net/cert/trial_comparison_cert_verifier_util.cc b/chromium/net/cert/trial_comparison_cert_verifier_util.cc index d08d51bb566..b51d4306286 100644 --- a/chromium/net/cert/trial_comparison_cert_verifier_util.cc +++ b/chromium/net/cert/trial_comparison_cert_verifier_util.cc @@ -10,8 +10,8 @@ #include "net/base/net_errors.h" #include "net/cert/cert_status_flags.h" #include "net/cert/ev_root_ca_metadata.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/parsed_certificate.h" #include "net/cert/x509_util.h" namespace net { diff --git a/chromium/net/cert/x509_cert_types.cc b/chromium/net/cert/x509_cert_types.cc index daca1dd686e..202181d7e00 100644 --- a/chromium/net/cert/x509_cert_types.cc +++ b/chromium/net/cert/x509_cert_types.cc @@ -4,7 +4,7 @@ #include "net/cert/x509_cert_types.h" -#include "net/cert/internal/parse_name.h" +#include "net/cert/pki/parse_name.h" #include "net/der/input.h" namespace net { diff --git a/chromium/net/cert/x509_certificate.cc b/chromium/net/cert/x509_certificate.cc index 17d93695034..1dac369039a 100644 --- a/chromium/net/cert/x509_certificate.cc +++ b/chromium/net/cert/x509_certificate.cc @@ -27,13 +27,13 @@ #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/base/url_util.h" #include "net/cert/asn1_util.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/name_constraints.h" -#include "net/cert/internal/parsed_certificate.h" -#include "net/cert/internal/signature_algorithm.h" -#include "net/cert/internal/verify_name_match.h" -#include "net/cert/internal/verify_signed_data.h" #include "net/cert/pem.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/name_constraints.h" +#include "net/cert/pki/parsed_certificate.h" +#include "net/cert/pki/signature_algorithm.h" +#include "net/cert/pki/verify_name_match.h" +#include "net/cert/pki/verify_signed_data.h" #include "net/cert/x509_util.h" #include "net/der/encode_values.h" #include "net/der/parser.h" @@ -118,7 +118,7 @@ scoped_refptr<X509Certificate> X509Certificate::CreateFromBuffer( bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer, std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates) { DCHECK(cert_buffer); - scoped_refptr<X509Certificate> cert( + auto cert = base::WrapRefCounted( new X509Certificate(std::move(cert_buffer), std::move(intermediates))); if (!cert->cert_buffer()) return nullptr; // Initialize() failed. @@ -131,7 +131,7 @@ scoped_refptr<X509Certificate> X509Certificate::CreateFromBufferUnsafeOptions( std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates, UnsafeCreateOptions options) { DCHECK(cert_buffer); - scoped_refptr<X509Certificate> cert(new X509Certificate( + auto cert = base::WrapRefCounted(new X509Certificate( std::move(cert_buffer), std::move(intermediates), options)); if (!cert->cert_buffer()) return nullptr; // Initialize() failed. @@ -205,17 +205,17 @@ scoped_refptr<X509Certificate> X509Certificate::CreateFromPickle( scoped_refptr<X509Certificate> X509Certificate::CreateFromPickleUnsafeOptions( base::PickleIterator* pickle_iter, UnsafeCreateOptions options) { - int chain_length = 0; + size_t chain_length = 0; if (!pickle_iter->ReadLength(&chain_length)) return nullptr; std::vector<base::StringPiece> cert_chain; const char* data = nullptr; - int data_length = 0; - for (int i = 0; i < chain_length; ++i) { + size_t data_length = 0; + for (size_t i = 0; i < chain_length; ++i) { if (!pickle_iter->ReadData(&data, &data_length)) return nullptr; - cert_chain.push_back(base::StringPiece(data, data_length)); + cert_chain.emplace_back(data, data_length); } return CreateFromDERCertChainUnsafeOptions(cert_chain, options); } @@ -588,8 +588,8 @@ bool X509Certificate::GetPEMEncodedChain( if (!GetPEMEncoded(cert_buffer(), &pem_data)) return false; encoded_chain.push_back(pem_data); - for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { - if (!GetPEMEncoded(intermediate_ca_certs_[i].get(), &pem_data)) + for (const auto& intermediate_ca_cert : intermediate_ca_certs_) { + if (!GetPEMEncoded(intermediate_ca_cert.get(), &pem_data)) return false; encoded_chain.push_back(pem_data); } @@ -621,7 +621,7 @@ void X509Certificate::GetPublicKeyInfo(const CRYPTO_BUFFER* cert_buffer, if (!pkey) return; - switch (pkey->type) { + switch (EVP_PKEY_id(pkey.get())) { case EVP_PKEY_RSA: *type = kPublicKeyTypeRSA; break; @@ -743,8 +743,9 @@ bool X509Certificate::IsSelfSigned(const CRYPTO_BUFFER* cert_buffer) { if (normalized_subject != normalized_issuer) return false; - std::unique_ptr<SignatureAlgorithm> signature_algorithm = - SignatureAlgorithm::Create(signature_algorithm_tlv, nullptr /* errors */); + absl::optional<SignatureAlgorithm> signature_algorithm = + ParseSignatureAlgorithm(signature_algorithm_tlv, + /*errors=*/nullptr); if (!signature_algorithm) return false; diff --git a/chromium/net/cert/x509_certificate_unittest.cc b/chromium/net/cert/x509_certificate_unittest.cc index 50d55a81739..a32ba859784 100644 --- a/chromium/net/cert/x509_certificate_unittest.cc +++ b/chromium/net/cert/x509_certificate_unittest.cc @@ -19,8 +19,8 @@ #include "crypto/rsa_private_key.h" #include "net/base/net_errors.h" #include "net/cert/asn1_util.h" -#include "net/cert/internal/parse_certificate.h" #include "net/cert/pem.h" +#include "net/cert/pki/parse_certificate.h" #include "net/cert/x509_util.h" #include "net/test/cert_test_util.h" #include "net/test/test_certificate_data.h" @@ -1092,7 +1092,7 @@ const struct CertificateFormatTestData { class X509CertificateParseTest : public testing::TestWithParam<CertificateFormatTestData> { public: - virtual ~X509CertificateParseTest() = default; + ~X509CertificateParseTest() override = default; void SetUp() override { test_data_ = GetParam(); } void TearDown() override {} @@ -1324,13 +1324,13 @@ TEST_P(X509CertificateNameVerifyTest, VerifyHostname) { ip_addressses.push_back(std::move(bytes)); ASSERT_EQ(16U, ip_addressses.back().size()) << i; } else { // Decimal groups - std::vector<std::string> decimals_ascii = base::SplitString( + std::vector<std::string> decimals_ascii_list = base::SplitString( addr_ascii, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - EXPECT_EQ(4U, decimals_ascii.size()) << i; + EXPECT_EQ(4U, decimals_ascii_list.size()) << i; std::string addr_bytes; - for (size_t j = 0; j < decimals_ascii.size(); ++j) { + for (const auto& decimals_ascii : decimals_ascii_list) { int decimal_value; - EXPECT_TRUE(base::StringToInt(decimals_ascii[j], &decimal_value)); + EXPECT_TRUE(base::StringToInt(decimals_ascii, &decimal_value)); EXPECT_GE(decimal_value, 0); EXPECT_LE(decimal_value, 255); addr_bytes.push_back(static_cast<char>(decimal_value)); diff --git a/chromium/net/cert/x509_util.cc b/chromium/net/cert/x509_util.cc index a1a9ddc6cc2..310742ec97a 100644 --- a/chromium/net/cert/x509_util.cc +++ b/chromium/net/cert/x509_util.cc @@ -21,11 +21,11 @@ #include "crypto/sha2.h" #include "net/base/hash_value.h" #include "net/cert/asn1_util.h" -#include "net/cert/internal/cert_errors.h" -#include "net/cert/internal/name_constraints.h" -#include "net/cert/internal/parse_certificate.h" -#include "net/cert/internal/parse_name.h" -#include "net/cert/internal/signature_algorithm.h" +#include "net/cert/pki/cert_errors.h" +#include "net/cert/pki/name_constraints.h" +#include "net/cert/pki/parse_certificate.h" +#include "net/cert/pki/parse_name.h" +#include "net/cert/pki/signature_algorithm.h" #include "net/cert/x509_certificate.h" #include "net/der/encode_values.h" #include "net/der/input.h" @@ -38,9 +38,7 @@ #include "third_party/boringssl/src/include/openssl/pool.h" #include "third_party/boringssl/src/include/openssl/stack.h" -namespace net { - -namespace x509_util { +namespace net::x509_util { namespace { @@ -196,25 +194,32 @@ bool GetTLSServerEndPointChannelBinding(const X509Certificate& certificate, der::BitString signature_value; if (!ParseCertificate(der::Input(der_encoded_certificate), &tbs_certificate_tlv, &signature_algorithm_tlv, - &signature_value, nullptr)) + &signature_value, nullptr)) { return false; - - std::unique_ptr<SignatureAlgorithm> signature_algorithm = - SignatureAlgorithm::Create(signature_algorithm_tlv, nullptr); - if (!signature_algorithm) + } + absl::optional<SignatureAlgorithm> signature_algorithm = + ParseSignatureAlgorithm(signature_algorithm_tlv, nullptr); + if (!signature_algorithm) { return false; + } + absl::optional<net::DigestAlgorithm> binding_digest = + GetTlsServerEndpointDigestAlgorithm(*signature_algorithm); + if (!binding_digest) { + return false; + } const EVP_MD* digest_evp_md = nullptr; - switch (signature_algorithm->digest()) { + switch (binding_digest.value()) { case net::DigestAlgorithm::Md2: case net::DigestAlgorithm::Md4: - // Shouldn't be reachable. - digest_evp_md = nullptr; - break; - - // Per RFC 5929 section 4.1, MD5 and SHA1 map to SHA256. case net::DigestAlgorithm::Md5: case net::DigestAlgorithm::Sha1: + // Legacy digests are not supported, and + // `GetTlsServerEndpointDigestAlgorithm` internally maps MD5 and SHA-1 to + // SHA-256. + NOTREACHED(); + break; + case net::DigestAlgorithm::Sha256: digest_evp_md = EVP_sha256(); break; @@ -273,7 +278,7 @@ Extension::Extension(base::span<const uint8_t> in_oid, bool in_critical, base::span<const uint8_t> in_contents) : oid(in_oid), critical(in_critical), contents(in_contents) {} -Extension::~Extension() {} +Extension::~Extension() = default; Extension::Extension(const Extension&) = default; bool CreateSelfSignedCert(EVP_PKEY* key, @@ -511,7 +516,7 @@ bool SignatureVerifierInitWithCertificate( base::make_span(tbs.spki_tlv.UnsafeData(), tbs.spki_tlv.Length())); } -bool HasSHA1Signature(const CRYPTO_BUFFER* cert_buffer) { +bool HasRsaPkcs1Sha1Signature(const CRYPTO_BUFFER* cert_buffer) { der::Input tbs_certificate_tlv; der::Input signature_algorithm_tlv; der::BitString signature_value; @@ -522,14 +527,12 @@ bool HasSHA1Signature(const CRYPTO_BUFFER* cert_buffer) { return false; } - std::unique_ptr<SignatureAlgorithm> signature_algorithm = - SignatureAlgorithm::Create(signature_algorithm_tlv, /*errors=*/nullptr); - if (!signature_algorithm) - return false; + absl::optional<SignatureAlgorithm> signature_algorithm = + ParseSignatureAlgorithm(signature_algorithm_tlv, + /*errors=*/nullptr); - return signature_algorithm->digest() == net::DigestAlgorithm::Sha1; + return signature_algorithm && + *signature_algorithm == SignatureAlgorithm::kRsaPkcs1Sha1; } -} // namespace x509_util - -} // namespace net +} // namespace net::x509_util diff --git a/chromium/net/cert/x509_util.h b/chromium/net/cert/x509_util.h index 2344aa8fa90..f86c7cd9a99 100644 --- a/chromium/net/cert/x509_util.h +++ b/chromium/net/cert/x509_util.h @@ -169,8 +169,10 @@ NET_EXPORT bool SignatureVerifierInitWithCertificate( base::span<const uint8_t> signature, const CRYPTO_BUFFER* certificate); -// Returns true if the signature on the certificate uses SHA-1. -NET_EXPORT_PRIVATE bool HasSHA1Signature(const CRYPTO_BUFFER* cert_buffer); +// Returns true if the signature on the certificate is RSASSA-PKCS1-v1_5 with +// SHA-1. +NET_EXPORT_PRIVATE bool HasRsaPkcs1Sha1Signature( + const CRYPTO_BUFFER* cert_buffer); } // namespace x509_util diff --git a/chromium/net/cert/x509_util_apple.cc b/chromium/net/cert/x509_util_apple.cc index 4d8c6b27ad5..979e84f2d82 100644 --- a/chromium/net/cert/x509_util_apple.cc +++ b/chromium/net/cert/x509_util_apple.cc @@ -137,5 +137,21 @@ SHA256HashValue CalculateFingerprint256(SecCertificateRef cert) { return sha256; } +base::ScopedCFTypeRef<CFArrayRef> CertificateChainFromSecTrust( + SecTrustRef trust) { + if (__builtin_available(macOS 12.0, iOS 15.0, *)) { + return base::ScopedCFTypeRef<CFArrayRef>( + SecTrustCopyCertificateChain(trust)); + } + + base::ScopedCFTypeRef<CFMutableArrayRef> chain( + CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); + const CFIndex chain_length = SecTrustGetCertificateCount(trust); + for (CFIndex i = 0; i < chain_length; ++i) { + CFArrayAppendValue(chain, SecTrustGetCertificateAtIndex(trust, i)); + } + return base::ScopedCFTypeRef<CFArrayRef>(chain.release()); +} + } // namespace x509_util } // namespace net diff --git a/chromium/net/cert/x509_util_apple.h b/chromium/net/cert/x509_util_apple.h index 080565905ec..1348a2ef5f3 100644 --- a/chromium/net/cert/x509_util_apple.h +++ b/chromium/net/cert/x509_util_apple.h @@ -69,6 +69,10 @@ CreateX509CertificateFromSecCertificate( // (all zero) fingerprint on failure. NET_EXPORT SHA256HashValue CalculateFingerprint256(SecCertificateRef cert); +// Returns a new CFArrayRef containing the certificate chain built in |trust|. +base::ScopedCFTypeRef<CFArrayRef> CertificateChainFromSecTrust( + SecTrustRef trust); + } // namespace x509_util } // namespace net diff --git a/chromium/net/cert/x509_util_mac.cc b/chromium/net/cert/x509_util_mac.cc index d72bc82da29..bb675db0715 100644 --- a/chromium/net/cert/x509_util_mac.cc +++ b/chromium/net/cert/x509_util_mac.cc @@ -16,10 +16,7 @@ namespace net { namespace x509_util { CSSMFieldValue::CSSMFieldValue() - : cl_handle_(CSSM_INVALID_HANDLE), - oid_(NULL), - field_(NULL) { -} + : cl_handle_(CSSM_INVALID_HANDLE), oid_(nullptr), field_(nullptr) {} CSSMFieldValue::CSSMFieldValue(CSSM_CL_HANDLE cl_handle, const CSSM_OID* oid, CSSM_DATA_PTR field) @@ -29,7 +26,7 @@ CSSMFieldValue::CSSMFieldValue(CSSM_CL_HANDLE cl_handle, } CSSMFieldValue::~CSSMFieldValue() { - Reset(CSSM_INVALID_HANDLE, NULL, NULL); + Reset(CSSM_INVALID_HANDLE, nullptr, nullptr); } void CSSMFieldValue::Reset(CSSM_CL_HANDLE cl_handle, @@ -76,7 +73,7 @@ OSStatus CSSMCachedCertificate::GetField(const CSSM_OID* field_oid, DCHECK(cached_cert_handle_); CSSM_OID_PTR oid = const_cast<CSSM_OID_PTR>(field_oid); - CSSM_DATA_PTR field_ptr = NULL; + CSSM_DATA_PTR field_ptr = nullptr; CSSM_HANDLE results_handle = CSSM_INVALID_HANDLE; uint32_t field_value_count = 0; CSSM_RETURN status = CSSM_CL_CertGetFirstCachedFieldValue( diff --git a/chromium/net/cert/x509_util_mac.h b/chromium/net/cert/x509_util_mac.h index d2eb69eff6d..d95f21af267 100644 --- a/chromium/net/cert/x509_util_mac.h +++ b/chromium/net/cert/x509_util_mac.h @@ -7,8 +7,7 @@ #include <Security/Security.h> -namespace net { -namespace x509_util { +namespace net::x509_util { // CSSM functions are deprecated as of OSX 10.7, but have no replacement. // https://bugs.chromium.org/p/chromium/issues/detail?id=590914#c1 @@ -40,7 +39,7 @@ class CSSMFieldValue { // enough to actually contain the requested type. template <typename T> const T* GetAs() const { if (!field_ || field_->Length < sizeof(T)) - return NULL; + return nullptr; return reinterpret_cast<const T*>(field_->Data); } @@ -100,7 +99,6 @@ inline bool CSSMOIDEqual(const CSSM_OID* oid1, const CSSM_OID* oid2) { #pragma clang diagnostic pop // "-Wdeprecated-declarations" -} // namespace x509_util -} // namespace net +} // namespace net::x509_util #endif // NET_CERT_X509_UTIL_MAC_H_ diff --git a/chromium/net/cert/x509_util_nss.cc b/chromium/net/cert/x509_util_nss.cc index 98827784394..d52282832e5 100644 --- a/chromium/net/cert/x509_util_nss.cc +++ b/chromium/net/cert/x509_util_nss.cc @@ -22,9 +22,7 @@ #include "crypto/scoped_nss_types.h" #include "third_party/boringssl/src/include/openssl/pool.h" -namespace net { - -namespace x509_util { +namespace net::x509_util { namespace { @@ -85,8 +83,8 @@ std::string GetDefaultNickname(CERTCertificate* nss_cert, CertType type) { // Find the private key for this certificate and see if it has a // nickname. If there is a private key, and it has a nickname, then // return that nickname. - SECKEYPrivateKey* private_key = - PK11_FindPrivateKeyFromCert(nss_cert->slot, nss_cert, NULL /*wincx*/); + SECKEYPrivateKey* private_key = PK11_FindPrivateKeyFromCert( + nss_cert->slot, nss_cert, nullptr /*wincx*/); if (private_key) { char* private_key_nickname = PK11_GetPrivateKeyNickname(private_key); if (private_key_nickname) { @@ -155,7 +153,7 @@ ScopedCERTCertificate CreateCERTCertificateFromBytes(const uint8_t* data, crypto::EnsureNSSInit(); if (!NSS_IsInitialized()) - return NULL; + return nullptr; SECItem der_cert; der_cert.data = const_cast<uint8_t*>(data); @@ -309,7 +307,7 @@ bool GetPEMEncoded(CERTCertificate* cert, std::string* pem_encoded) { void GetRFC822SubjectAltNames(CERTCertificate* cert_handle, std::vector<std::string>* names) { - crypto::ScopedSECItem alt_name(SECITEM_AllocItem(NULL, NULL, 0)); + crypto::ScopedSECItem alt_name(SECITEM_AllocItem(nullptr, nullptr, 0)); DCHECK(alt_name.get()); names->clear(); @@ -339,7 +337,7 @@ void GetRFC822SubjectAltNames(CERTCertificate* cert_handle, void GetUPNSubjectAltNames(CERTCertificate* cert_handle, std::vector<std::string>* names) { - crypto::ScopedSECItem alt_name(SECITEM_AllocItem(NULL, NULL, 0)); + crypto::ScopedSECItem alt_name(SECITEM_AllocItem(nullptr, nullptr, 0)); DCHECK(alt_name.get()); names->clear(); @@ -389,7 +387,7 @@ std::string GetCERTNameDisplayName(CERTName* name) { CERTRDN** rdns = name->rdns; for (size_t rdn = 0; rdns[rdn]; ++rdn) { CERTAVA** avas = rdns[rdn]->avas; - for (size_t pair = 0; avas[pair] != 0; ++pair) { + for (size_t pair = 0; avas[pair] != nullptr; ++pair) { SECOidTag tag = CERT_GetAVATag(avas[pair]); if (tag == SEC_OID_AVA_COMMON_NAME) { // If CN is found, return immediately. @@ -438,6 +436,4 @@ SHA256HashValue CalculateFingerprint256(CERTCertificate* cert) { return sha256; } -} // namespace x509_util - -} // namespace net +} // namespace net::x509_util diff --git a/chromium/net/cert/x509_util_nss.h b/chromium/net/cert/x509_util_nss.h index 8c54996dae0..c9cb113a88d 100644 --- a/chromium/net/cert/x509_util_nss.h +++ b/chromium/net/cert/x509_util_nss.h @@ -20,9 +20,7 @@ typedef struct CERTNameStr CERTName; typedef struct PK11SlotInfoStr PK11SlotInfo; typedef struct SECItemStr SECItem; -namespace net { - -namespace x509_util { +namespace net::x509_util { // Returns true if two certificate handles refer to identical certificates. NET_EXPORT bool IsSameCertificate(CERTCertificate* a, CERTCertificate* b); @@ -159,8 +157,6 @@ NET_EXPORT bool GetValidityTimes(CERTCertificate* cert, // (all zero) fingerprint on failure. NET_EXPORT SHA256HashValue CalculateFingerprint256(CERTCertificate* cert); -} // namespace x509_util - -} // namespace net +} // namespace net::x509_util #endif // NET_CERT_X509_UTIL_NSS_H_ diff --git a/chromium/net/cert/x509_util_unittest.cc b/chromium/net/cert/x509_util_unittest.cc index d89ff5069b6..00d5d281297 100644 --- a/chromium/net/cert/x509_util_unittest.cc +++ b/chromium/net/cert/x509_util_unittest.cc @@ -19,9 +19,7 @@ #include "third_party/boringssl/src/include/openssl/evp.h" #include "third_party/boringssl/src/include/openssl/rsa.h" -namespace net { - -namespace x509_util { +namespace net::x509_util { // This test creates a self-signed cert and a private key and then verifies the // content of the certificate. @@ -790,20 +788,18 @@ TEST(X509UtilTest, SignatureVerifierInitWithCertificate) { } } -TEST(X509UtilTest, HasSHA1Signature) { +TEST(X509UtilTest, HasRsaPkcs1Sha1Signature) { base::FilePath certs_dir = GetTestCertsDirectory(); scoped_refptr<X509Certificate> sha1_leaf = ImportCertFromFile(certs_dir, "sha1_leaf.pem"); ASSERT_TRUE(sha1_leaf); - EXPECT_TRUE(HasSHA1Signature(sha1_leaf->cert_buffer())); + EXPECT_TRUE(HasRsaPkcs1Sha1Signature(sha1_leaf->cert_buffer())); scoped_refptr<X509Certificate> ok_cert = ImportCertFromFile(certs_dir, "ok_cert.pem"); ASSERT_TRUE(ok_cert); - EXPECT_FALSE(HasSHA1Signature(ok_cert->cert_buffer())); + EXPECT_FALSE(HasRsaPkcs1Sha1Signature(ok_cert->cert_buffer())); } -} // namespace x509_util - -} // namespace net +} // namespace net::x509_util diff --git a/chromium/net/cert/x509_util_win.h b/chromium/net/cert/x509_util_win.h index 7d667797594..02f52cdaee1 100644 --- a/chromium/net/cert/x509_util_win.h +++ b/chromium/net/cert/x509_util_win.h @@ -17,9 +17,7 @@ #include "net/base/net_export.h" #include "net/cert/x509_certificate.h" -namespace net { - -namespace x509_util { +namespace net::x509_util { // Creates an X509Certificate representing |os_cert| with intermediates // |os_chain|. @@ -64,8 +62,6 @@ NET_EXPORT SHA256HashValue CalculateFingerprint256(PCCERT_CONTEXT cert); // Returns true if the certificate is self-signed. NET_EXPORT bool IsSelfSigned(PCCERT_CONTEXT cert_handle); -} // namespace x509_util - -} // namespace net +} // namespace net::x509_util #endif // NET_CERT_X509_UTIL_WIN_H_ |