diff options
Diffstat (limited to 'chromium/content/browser/web_package/signed_exchange_signature_verifier.cc')
-rw-r--r-- | chromium/content/browser/web_package/signed_exchange_signature_verifier.cc | 107 |
1 files changed, 64 insertions, 43 deletions
diff --git a/chromium/content/browser/web_package/signed_exchange_signature_verifier.cc b/chromium/content/browser/web_package/signed_exchange_signature_verifier.cc index bbc94fbeaf9..cf1322d96aa 100644 --- a/chromium/content/browser/web_package/signed_exchange_signature_verifier.cc +++ b/chromium/content/browser/web_package/signed_exchange_signature_verifier.cc @@ -20,6 +20,10 @@ #include "crypto/signature_verifier.h" #include "net/cert/asn1_util.h" #include "net/cert/x509_util.h" +#include "third_party/boringssl/src/include/openssl/bytestring.h" +#include "third_party/boringssl/src/include/openssl/ec.h" +#include "third_party/boringssl/src/include/openssl/ec_key.h" +#include "third_party/boringssl/src/include/openssl/evp.h" namespace content { @@ -138,48 +142,65 @@ base::Optional<cbor::CBORValue> GenerateSignedMessageCBOR( return cbor::CBORValue(map); } -bool VerifySignature( - base::span<const uint8_t> sig, - base::span<const uint8_t> msg, - scoped_refptr<net::X509Certificate> cert, - const signed_exchange_utils::LogCallback& error_message_callback) { +bool VerifySignature(base::span<const uint8_t> sig, + base::span<const uint8_t> msg, + scoped_refptr<net::X509Certificate> cert, + SignedExchangeDevToolsProxy* devtools_proxy) { TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"), "VerifySignature"); base::StringPiece spki; if (!net::asn1::ExtractSPKIFromDERCert( net::x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()), &spki)) { - signed_exchange_utils::RunErrorMessageCallbackAndEndTraceEvent( - "VerifySignature", error_message_callback, "Failed to extract SPKI."); + TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("loading"), "VerifySignature", + "error", "Failed to extract SPKI."); return false; } - size_t size_bits; - net::X509Certificate::PublicKeyType type; - net::X509Certificate::GetPublicKeyInfo(cert->cert_buffer(), &size_bits, - &type); - if (type != net::X509Certificate::kPublicKeyTypeRSA) { - // TODO(crbug.com/803774): Add support for ecdsa_secp256r1_sha256 and - // ecdsa_secp384r1_sha384. - signed_exchange_utils::RunErrorMessageCallbackAndEndTraceEvent( - "VerifySignature", error_message_callback, - base::StringPrintf("Unsupported public key type: %d", type)); + crypto::SignatureVerifier::SignatureAlgorithm algorithm; + CBS cbs; + CBS_init(&cbs, reinterpret_cast<const uint8_t*>(spki.data()), spki.size()); + bssl::UniquePtr<EVP_PKEY> pkey(EVP_parse_public_key(&cbs)); + if (!pkey || CBS_len(&cbs) != 0) { + signed_exchange_utils::ReportErrorAndEndTraceEvent( + devtools_proxy, "VerifySignature", "Failed to parse public key."); return false; } + switch (EVP_PKEY_id(pkey.get())) { + case EVP_PKEY_RSA: + algorithm = crypto::SignatureVerifier::RSA_PSS_SHA256; + break; + case EVP_PKEY_EC: { + const EC_GROUP* group = + EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey.get())); + switch (EC_GROUP_get_curve_name(group)) { + case NID_X9_62_prime256v1: + algorithm = crypto::SignatureVerifier::ECDSA_SHA256; + break; + default: + signed_exchange_utils::ReportErrorAndEndTraceEvent( + devtools_proxy, "VerifySignature", "Unsupported EC group."); + return false; + } + break; + } + default: + signed_exchange_utils::ReportErrorAndEndTraceEvent( + devtools_proxy, "VerifySignature", "Unsupported public key type."); + return false; + } - // TODO(crbug.com/803774): This is missing the digitalSignature key usage bit - // check. crypto::SignatureVerifier verifier; - if (!verifier.VerifyInit( - crypto::SignatureVerifier::RSA_PSS_SHA256, sig.data(), sig.size(), - reinterpret_cast<const uint8_t*>(spki.data()), spki.size())) { - signed_exchange_utils::RunErrorMessageCallbackAndEndTraceEvent( - "VerifySignature", error_message_callback, "VerifyInit failed."); + if (!net::x509_util::SignatureVerifierInitWithCertificate( + &verifier, algorithm, sig, cert->cert_buffer())) { + signed_exchange_utils::ReportErrorAndEndTraceEvent( + devtools_proxy, "VerifySignature", + "SignatureVerifierInitWithCertificate failed."); return false; } - verifier.VerifyUpdate(msg.data(), msg.size()); + verifier.VerifyUpdate(msg); if (!verifier.VerifyFinal()) { - signed_exchange_utils::RunErrorMessageCallbackAndEndTraceEvent( - "VerifySignature", error_message_callback, "VerifyFinal failed."); + signed_exchange_utils::ReportErrorAndEndTraceEvent( + devtools_proxy, "VerifySignature", "VerifyFinal failed."); return false; } TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"), "VerifySignature"); @@ -264,13 +285,13 @@ SignedExchangeSignatureVerifier::Result SignedExchangeSignatureVerifier::Verify( const SignedExchangeHeader& header, scoped_refptr<net::X509Certificate> certificate, const base::Time& verification_time, - const signed_exchange_utils::LogCallback& error_message_callback) { + SignedExchangeDevToolsProxy* devtools_proxy) { TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"), "SignedExchangeSignatureVerifier::Verify"); if (!VerifyTimestamps(header, verification_time)) { - signed_exchange_utils::RunErrorMessageCallbackAndEndTraceEvent( - "SignedExchangeSignatureVerifier::Verify", error_message_callback, + signed_exchange_utils::ReportErrorAndEndTraceEvent( + devtools_proxy, "SignedExchangeSignatureVerifier::Verify", base::StringPrintf( "Invalid timestamp. creation_time: %" PRIu64 ", expires_time: %" PRIu64 ", verification_time: %" PRIu64, @@ -280,15 +301,15 @@ SignedExchangeSignatureVerifier::Result SignedExchangeSignatureVerifier::Verify( } if (!certificate) { - signed_exchange_utils::RunErrorMessageCallbackAndEndTraceEvent( - "SignedExchangeSignatureVerifier::Verify", error_message_callback, + signed_exchange_utils::ReportErrorAndEndTraceEvent( + devtools_proxy, "SignedExchangeSignatureVerifier::Verify", "No certificate set."); return Result::kErrNoCertificate; } if (!header.signature().cert_sha256.has_value()) { - signed_exchange_utils::RunErrorMessageCallbackAndEndTraceEvent( - "SignedExchangeSignatureVerifier::Verify", error_message_callback, + signed_exchange_utils::ReportErrorAndEndTraceEvent( + devtools_proxy, "SignedExchangeSignatureVerifier::Verify", "No certSha256 set."); return Result::kErrNoCertificateSHA256; } @@ -297,16 +318,16 @@ SignedExchangeSignatureVerifier::Result SignedExchangeSignatureVerifier::Verify( if (*header.signature().cert_sha256 != net::X509Certificate::CalculateFingerprint256( certificate->cert_buffer())) { - signed_exchange_utils::RunErrorMessageCallbackAndEndTraceEvent( - "SignedExchangeSignatureVerifier::Verify", error_message_callback, + signed_exchange_utils::ReportErrorAndEndTraceEvent( + devtools_proxy, "SignedExchangeSignatureVerifier::Verify", "certSha256 mismatch."); return Result::kErrCertificateSHA256Mismatch; } auto message = GenerateSignedMessage(header); if (!message) { - signed_exchange_utils::RunErrorMessageCallbackAndEndTraceEvent( - "SignedExchangeSignatureVerifier::Verify", error_message_callback, + signed_exchange_utils::ReportErrorAndEndTraceEvent( + devtools_proxy, "SignedExchangeSignatureVerifier::Verify", "Failed to reconstruct signed message."); return Result::kErrInvalidSignatureFormat; } @@ -315,16 +336,16 @@ SignedExchangeSignatureVerifier::Result SignedExchangeSignatureVerifier::Verify( if (!VerifySignature( base::make_span(reinterpret_cast<const uint8_t*>(sig.data()), sig.size()), - *message, certificate, error_message_callback)) { - signed_exchange_utils::RunErrorMessageCallbackAndEndTraceEvent( - "SignedExchangeSignatureVerifier::Verify", error_message_callback, + *message, certificate, devtools_proxy)) { + signed_exchange_utils::ReportErrorAndEndTraceEvent( + devtools_proxy, "SignedExchangeSignatureVerifier::Verify", "Failed to verify signature \"sig\"."); return Result::kErrSignatureVerificationFailed; } if (!base::EqualsCaseInsensitiveASCII(header.signature().integrity, "mi")) { - signed_exchange_utils::RunErrorMessageCallbackAndEndTraceEvent( - "SignedExchangeSignatureVerifier::Verify", error_message_callback, + signed_exchange_utils::ReportErrorAndEndTraceEvent( + devtools_proxy, "SignedExchangeSignatureVerifier::Verify", "The current implemention only supports \"mi\" integrity scheme."); return Result::kErrInvalidSignatureIntegrity; } |