summaryrefslogtreecommitdiff
path: root/chromium/content/browser/web_package/signed_exchange_signature_verifier.cc
diff options
context:
space:
mode:
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.cc107
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;
}