Skip to content

Commit 4b00236

Browse files
vasilvvcopybara-github
authored andcommitted
Provide the certificate and the SPKI hash in WebTransportFingerprintProofVerifier.
This will be used to populate net::SSLInfo in Chromium. PiperOrigin-RevId: 867770493
1 parent 18573b8 commit 4b00236

File tree

5 files changed

+58
-14
lines changed

5 files changed

+58
-14
lines changed

quiche/quic/core/crypto/certificate_view.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ std::unique_ptr<CertificateView> CertificateView::ParseSingleCertificate(
375375
result->validity_start_ = *not_before_parsed;
376376
result->validity_end_ = *not_after_parsed;
377377

378+
result->spki_ = CbsToStringPiece(spki);
378379
result->public_key_.reset(EVP_parse_public_key(&spki));
379380
if (result->public_key_ == nullptr) {
380381
QUIC_DLOG(WARNING) << "Failed to parse the public key";

quiche/quic/core/crypto/certificate_view.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,16 @@ class QUICHE_EXPORT CertificateView {
8888
// Returns the type of the key used in the certificate's SPKI.
8989
PublicKeyType public_key_type() const;
9090

91+
// Returns the raw bytes of SubjectPublicKeyInfo.
92+
absl::string_view raw_spki() const { return spki_; }
93+
9194
private:
9295
CertificateView() = default;
9396

9497
QuicWallTime validity_start_ = QuicWallTime::Zero();
9598
QuicWallTime validity_end_ = QuicWallTime::Zero();
9699
absl::string_view subject_der_;
100+
absl::string_view spki_;
97101

98102
// Public key parsed from SPKI.
99103
bssl::UniquePtr<EVP_PKEY> public_key_;

quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.cc

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.h"
66

7+
#include <cstddef>
78
#include <cstdint>
89
#include <memory>
910
#include <string>
@@ -17,9 +18,11 @@
1718
#include "absl/strings/string_view.h"
1819
#include "openssl/sha.h"
1920
#include "quiche/quic/core/crypto/certificate_view.h"
21+
#include "quiche/quic/core/crypto/proof_verifier.h"
2022
#include "quiche/quic/core/quic_time.h"
2123
#include "quiche/quic/core/quic_types.h"
2224
#include "quiche/quic/core/quic_utils.h"
25+
#include "quiche/quic/core/quic_versions.h"
2326
#include "quiche/quic/platform/api/quic_bug_tracker.h"
2427
#include "quiche/quic/platform/api/quic_logging.h"
2528
#include "quiche/common/quiche_text_utils.h"
@@ -44,6 +47,12 @@ void NormalizeFingerprint(CertificateFingerprint& fingerprint) {
4447
constexpr char CertificateFingerprint::kSha256[];
4548
constexpr char WebTransportHash::kSha256[];
4649

50+
WebTransportFingerprintProofVerifier::Details::Details(
51+
Status status, absl::string_view cert, const CertificateView& parsed_cert)
52+
: status_(status),
53+
cert_(cert),
54+
spki_sha256_hash_(RawSha256(parsed_cert.raw_spki())) {}
55+
4756
ProofVerifyDetails* WebTransportFingerprintProofVerifier::Details::Clone()
4857
const {
4958
return new Details(*this);
@@ -140,12 +149,6 @@ QuicAsyncStatus WebTransportFingerprintProofVerifier::VerifyCertChain(
140149
return QUIC_FAILURE;
141150
}
142151

143-
if (!HasKnownFingerprint(certs[0])) {
144-
*details = std::make_unique<Details>(Status::kUnknownFingerprint);
145-
*error_details = "Certificate does not match any fingerprint";
146-
return QUIC_FAILURE;
147-
}
148-
149152
std::unique_ptr<CertificateView> view =
150153
CertificateView::ParseSingleCertificate(certs[0]);
151154
if (view == nullptr) {
@@ -154,30 +157,40 @@ QuicAsyncStatus WebTransportFingerprintProofVerifier::VerifyCertChain(
154157
return QUIC_FAILURE;
155158
}
156159

160+
if (!HasKnownFingerprint(certs[0])) {
161+
*details =
162+
std::make_unique<Details>(Status::kUnknownFingerprint, certs[0], *view);
163+
*error_details = "Certificate does not match any fingerprint";
164+
return QUIC_FAILURE;
165+
}
166+
157167
if (!HasValidExpiry(*view)) {
158-
*details = std::make_unique<Details>(Status::kExpiryTooLong);
168+
*details =
169+
std::make_unique<Details>(Status::kExpiryTooLong, certs[0], *view);
159170
*error_details =
160171
absl::StrCat("Certificate expiry exceeds the configured limit of ",
161172
max_validity_days_, " days");
162173
return QUIC_FAILURE;
163174
}
164175

165176
if (!IsWithinValidityPeriod(*view)) {
166-
*details = std::make_unique<Details>(Status::kExpired);
177+
*details = std::make_unique<Details>(Status::kExpired, certs[0], *view);
167178
*error_details =
168179
"Certificate has expired or has validity listed in the future";
169180
return QUIC_FAILURE;
170181
}
171182

172183
if (!IsKeyTypeAllowedByPolicy(*view)) {
173-
*details = std::make_unique<Details>(Status::kDisallowedKeyAlgorithm);
184+
*details = std::make_unique<Details>(Status::kDisallowedKeyAlgorithm,
185+
certs[0], *view);
174186
*error_details =
175187
absl::StrCat("Certificate uses a disallowed public key type (",
176188
PublicKeyTypeToString(view->public_key_type()), ")");
177189
return QUIC_FAILURE;
178190
}
179191

180-
*details = std::make_unique<Details>(Status::kValidCertificate);
192+
*details =
193+
std::make_unique<Details>(Status::kValidCertificate, certs[0], *view);
181194
return QUIC_SUCCESS;
182195
}
183196

quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,19 @@
55
#ifndef QUICHE_QUIC_CORE_CRYPTO_WEB_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
66
#define QUICHE_QUIC_CORE_CRYPTO_WEB_TRANSPORT_FINGERPRINT_PROOF_VERIFIER_H_
77

8+
#include <cstdint>
9+
#include <memory>
10+
#include <string>
811
#include <vector>
912

1013
#include "absl/strings/string_view.h"
1114
#include "quiche/quic/core/crypto/certificate_view.h"
1215
#include "quiche/quic/core/crypto/proof_verifier.h"
1316
#include "quiche/quic/core/quic_clock.h"
14-
#include "quiche/quic/platform/api/quic_export.h"
17+
#include "quiche/quic/core/quic_time.h"
18+
#include "quiche/quic/core/quic_types.h"
19+
#include "quiche/quic/core/quic_versions.h"
20+
#include "quiche/common/platform/api/quiche_export.h"
1521

1622
namespace quic {
1723

@@ -68,13 +74,21 @@ class QUICHE_EXPORT WebTransportFingerprintProofVerifier
6874

6975
class QUICHE_EXPORT Details : public ProofVerifyDetails {
7076
public:
77+
explicit Details(Status status, absl::string_view cert,
78+
const CertificateView& parsed_cert);
79+
// Used in failure states where a parsed certificate may not be available.
7180
explicit Details(Status status) : status_(status) {}
81+
7282
Status status() const { return status_; }
83+
absl::string_view cert() const { return cert_; }
84+
absl::string_view spki_sha256_hash() const { return spki_sha256_hash_; }
7385

7486
ProofVerifyDetails* Clone() const override;
7587

7688
private:
7789
const Status status_;
90+
const std::string cert_;
91+
const std::string spki_sha256_hash_;
7892
};
7993

8094
// |clock| is used to check if the certificate has expired. It is not owned

quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier_test.cc

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,16 @@
44

55
#include "quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.h"
66

7+
#include <cstdint>
78
#include <memory>
89
#include <string>
10+
#include <vector>
911

12+
#include "absl/memory/memory.h"
1013
#include "absl/strings/escaping.h"
1114
#include "absl/strings/string_view.h"
15+
#include "quiche/quic/core/crypto/proof_verifier.h"
16+
#include "quiche/quic/core/quic_time.h"
1217
#include "quiche/quic/core/quic_types.h"
1318
#include "quiche/quic/core/quic_utils.h"
1419
#include "quiche/quic/platform/api/quic_test.h"
@@ -27,6 +32,7 @@ constexpr QuicTime::Delta kValidTime = QuicTime::Delta::FromSeconds(1580560556);
2732
struct VerifyResult {
2833
QuicAsyncStatus status;
2934
WebTransportFingerprintProofVerifier::Status detailed_status;
35+
std::unique_ptr<WebTransportFingerprintProofVerifier::Details> details;
3036
std::string error;
3137
};
3238

@@ -51,10 +57,10 @@ class WebTransportFingerprintProofVerifierTest : public QuicTest {
5157
/*cert_sct=*/"",
5258
/*context=*/nullptr, &result.error, &details, &tls_alert,
5359
/*callback=*/nullptr);
54-
result.detailed_status =
60+
result.details = absl::WrapUnique(
5561
static_cast<WebTransportFingerprintProofVerifier::Details*>(
56-
details.get())
57-
->status();
62+
details.release()));
63+
result.detailed_status = result.details->status();
5864
return result;
5965
}
6066

@@ -79,6 +85,11 @@ TEST_F(WebTransportFingerprintProofVerifierTest, SimpleFingerprint) {
7985
EXPECT_EQ(result.status, QUIC_SUCCESS);
8086
EXPECT_EQ(result.detailed_status,
8187
WebTransportFingerprintProofVerifier::Status::kValidCertificate);
88+
EXPECT_EQ(result.details->cert(), kTestCertificate);
89+
// Hash manually computed from the test certificate by extracting the SPKI
90+
// using ascii2der/der2ascii.
91+
EXPECT_EQ(absl::BytesToHexString(result.details->spki_sha256_hash()),
92+
"dfbf620ab8c5c16acc9f1ce52bad06381095f157f9cc2ad8d28e71ecd6b0b8dd");
8293

8394
result = Verify(kWildcardCertificate);
8495
EXPECT_EQ(result.status, QUIC_FAILURE);
@@ -148,6 +159,7 @@ TEST_F(WebTransportFingerprintProofVerifierTest, InvalidCertificate) {
148159
EXPECT_EQ(
149160
result.detailed_status,
150161
WebTransportFingerprintProofVerifier::Status::kCertificateParseFailure);
162+
EXPECT_EQ(result.details->cert(), "");
151163
}
152164

153165
TEST_F(WebTransportFingerprintProofVerifierTest, AddCertificate) {

0 commit comments

Comments
 (0)