summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/client_proof_source_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/third_party/quiche/src/quiche/quic/core/crypto/client_proof_source_test.cc')
-rw-r--r--chromium/net/third_party/quiche/src/quiche/quic/core/crypto/client_proof_source_test.cc215
1 files changed, 215 insertions, 0 deletions
diff --git a/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/client_proof_source_test.cc b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/client_proof_source_test.cc
new file mode 100644
index 00000000000..a35e0aa87a2
--- /dev/null
+++ b/chromium/net/third_party/quiche/src/quiche/quic/core/crypto/client_proof_source_test.cc
@@ -0,0 +1,215 @@
+// Copyright (c) 2021 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 "quiche/quic/core/crypto/client_proof_source.h"
+
+#include "quiche/quic/platform/api/quic_expect_bug.h"
+#include "quiche/quic/platform/api/quic_test.h"
+#include "quiche/quic/test_tools/test_certificates.h"
+
+namespace quic {
+namespace test {
+
+quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>
+TestCertChain() {
+ return quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>(
+ new ClientProofSource::Chain({std::string(kTestCertificate)}));
+}
+
+CertificatePrivateKey TestPrivateKey() {
+ CBS private_key_cbs;
+ CBS_init(&private_key_cbs,
+ reinterpret_cast<const uint8_t*>(kTestCertificatePrivateKey.data()),
+ kTestCertificatePrivateKey.size());
+
+ return CertificatePrivateKey(
+ bssl::UniquePtr<EVP_PKEY>(EVP_parse_private_key(&private_key_cbs)));
+}
+
+const ClientProofSource::CertAndKey* TestCertAndKey() {
+ static const ClientProofSource::CertAndKey cert_and_key(TestCertChain(),
+ TestPrivateKey());
+ return &cert_and_key;
+}
+
+quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>
+NullCertChain() {
+ return quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>();
+}
+
+quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>
+EmptyCertChain() {
+ return quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>(
+ new ClientProofSource::Chain(std::vector<std::string>()));
+}
+
+quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain> BadCertChain() {
+ return quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>(
+ new ClientProofSource::Chain({"This is the content of a bad cert."}));
+}
+
+CertificatePrivateKey EmptyPrivateKey() {
+ return CertificatePrivateKey(bssl::UniquePtr<EVP_PKEY>(EVP_PKEY_new()));
+}
+
+#define VERIFY_CERT_AND_KEY_MATCHES(lhs, rhs) \
+ do { \
+ SCOPED_TRACE(testing::Message()); \
+ VerifyCertAndKeyMatches(lhs, rhs); \
+ } while (0)
+
+void VerifyCertAndKeyMatches(const ClientProofSource::CertAndKey* lhs,
+ const ClientProofSource::CertAndKey* rhs) {
+ if (lhs == rhs) {
+ return;
+ }
+
+ if (lhs == nullptr) {
+ ADD_FAILURE() << "lhs is nullptr, but rhs is not";
+ return;
+ }
+
+ if (rhs == nullptr) {
+ ADD_FAILURE() << "rhs is nullptr, but lhs is not";
+ return;
+ }
+
+ if (1 != EVP_PKEY_cmp(lhs->private_key.private_key(),
+ rhs->private_key.private_key())) {
+ ADD_FAILURE() << "Private keys mismatch";
+ return;
+ }
+
+ const ClientProofSource::Chain* lhs_chain = lhs->chain.get();
+ const ClientProofSource::Chain* rhs_chain = rhs->chain.get();
+
+ if (lhs_chain == rhs_chain) {
+ return;
+ }
+
+ if (lhs_chain == nullptr) {
+ ADD_FAILURE() << "lhs->chain is nullptr, but rhs->chain is not";
+ return;
+ }
+
+ if (rhs_chain == nullptr) {
+ ADD_FAILURE() << "rhs->chain is nullptr, but lhs->chain is not";
+ return;
+ }
+
+ if (lhs_chain->certs.size() != rhs_chain->certs.size()) {
+ ADD_FAILURE() << "Cert chain length differ. lhs:" << lhs_chain->certs.size()
+ << ", rhs:" << rhs_chain->certs.size();
+ return;
+ }
+
+ for (size_t i = 0; i < lhs_chain->certs.size(); ++i) {
+ if (lhs_chain->certs[i] != rhs_chain->certs[i]) {
+ ADD_FAILURE() << "The " << i << "-th certs differ.";
+ return;
+ }
+ }
+
+ // All good.
+}
+
+TEST(DefaultClientProofSource, FullDomain) {
+ DefaultClientProofSource proof_source;
+ ASSERT_TRUE(proof_source.AddCertAndKey({"www.google.com"}, TestCertChain(),
+ TestPrivateKey()));
+ VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
+ TestCertAndKey());
+ EXPECT_EQ(proof_source.GetCertAndKey("*.google.com"), nullptr);
+ EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+TEST(DefaultClientProofSource, WildcardDomain) {
+ DefaultClientProofSource proof_source;
+ ASSERT_TRUE(proof_source.AddCertAndKey({"*.google.com"}, TestCertChain(),
+ TestPrivateKey()));
+ VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
+ TestCertAndKey());
+ VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*.google.com"),
+ TestCertAndKey());
+ EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+TEST(DefaultClientProofSource, DefaultDomain) {
+ DefaultClientProofSource proof_source;
+ ASSERT_TRUE(
+ proof_source.AddCertAndKey({"*"}, TestCertChain(), TestPrivateKey()));
+ VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
+ TestCertAndKey());
+ VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*.google.com"),
+ TestCertAndKey());
+ VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*"),
+ TestCertAndKey());
+}
+
+TEST(DefaultClientProofSource, FullAndWildcard) {
+ DefaultClientProofSource proof_source;
+ ASSERT_TRUE(proof_source.AddCertAndKey({"www.google.com", "*.google.com"},
+ TestCertChain(), TestPrivateKey()));
+ VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
+ TestCertAndKey());
+ VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("foo.google.com"),
+ TestCertAndKey());
+ EXPECT_EQ(proof_source.GetCertAndKey("www.example.com"), nullptr);
+ EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+TEST(DefaultClientProofSource, FullWildcardAndDefault) {
+ DefaultClientProofSource proof_source;
+ ASSERT_TRUE(
+ proof_source.AddCertAndKey({"www.google.com", "*.google.com", "*"},
+ TestCertChain(), TestPrivateKey()));
+ VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.google.com"),
+ TestCertAndKey());
+ VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("foo.google.com"),
+ TestCertAndKey());
+ VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("www.example.com"),
+ TestCertAndKey());
+ VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*.google.com"),
+ TestCertAndKey());
+ VERIFY_CERT_AND_KEY_MATCHES(proof_source.GetCertAndKey("*"),
+ TestCertAndKey());
+}
+
+TEST(DefaultClientProofSource, EmptyCerts) {
+ DefaultClientProofSource proof_source;
+ bool ok;
+ EXPECT_QUIC_BUG(
+ ok = proof_source.AddCertAndKey({"*"}, NullCertChain(), TestPrivateKey()),
+ "Certificate chain is empty");
+ ASSERT_FALSE(ok);
+
+ EXPECT_QUIC_BUG(ok = proof_source.AddCertAndKey({"*"}, EmptyCertChain(),
+ TestPrivateKey()),
+ "Certificate chain is empty");
+ ASSERT_FALSE(ok);
+ EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+TEST(DefaultClientProofSource, BadCerts) {
+ DefaultClientProofSource proof_source;
+ bool ok;
+ EXPECT_QUIC_BUG(
+ ok = proof_source.AddCertAndKey({"*"}, BadCertChain(), TestPrivateKey()),
+ "Unabled to parse leaf certificate");
+ ASSERT_FALSE(ok);
+ EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+TEST(DefaultClientProofSource, KeyMismatch) {
+ DefaultClientProofSource proof_source;
+ bool ok;
+ EXPECT_QUIC_BUG(ok = proof_source.AddCertAndKey(
+ {"www.google.com"}, TestCertChain(), EmptyPrivateKey()),
+ "Private key does not match the leaf certificate");
+ ASSERT_FALSE(ok);
+ EXPECT_EQ(proof_source.GetCertAndKey("*"), nullptr);
+}
+
+} // namespace test
+} // namespace quic