1 // Copyright (c) 2021 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "quiche/quic/core/crypto/client_proof_source.h"
6
7 #include "absl/strings/match.h"
8
9 namespace quic {
10
AddCertAndKey(std::vector<std::string> server_hostnames,quiche::QuicheReferenceCountedPointer<Chain> chain,CertificatePrivateKey private_key)11 bool DefaultClientProofSource::AddCertAndKey(
12 std::vector<std::string> server_hostnames,
13 quiche::QuicheReferenceCountedPointer<Chain> chain,
14 CertificatePrivateKey private_key) {
15 if (!ValidateCertAndKey(chain, private_key)) {
16 return false;
17 }
18
19 auto cert_and_key =
20 std::make_shared<CertAndKey>(std::move(chain), std::move(private_key));
21 for (const std::string& domain : server_hostnames) {
22 cert_and_keys_[domain] = cert_and_key;
23 }
24 return true;
25 }
26
GetCertAndKey(absl::string_view hostname) const27 const ClientProofSource::CertAndKey* DefaultClientProofSource::GetCertAndKey(
28 absl::string_view hostname) const {
29 const CertAndKey* result = LookupExact(hostname);
30 if (result != nullptr || hostname == "*") {
31 return result;
32 }
33
34 // Either a full or a wildcard domain lookup failed. In the former case,
35 // derive the wildcard domain and look it up.
36 if (hostname.size() > 1 && !absl::StartsWith(hostname, "*.")) {
37 auto dot_pos = hostname.find('.');
38 if (dot_pos != std::string::npos) {
39 std::string wildcard = absl::StrCat("*", hostname.substr(dot_pos));
40 const CertAndKey* result = LookupExact(wildcard);
41 if (result != nullptr) {
42 return result;
43 }
44 }
45 }
46
47 // Return default cert, if any.
48 return LookupExact("*");
49 }
50
LookupExact(absl::string_view map_key) const51 const ClientProofSource::CertAndKey* DefaultClientProofSource::LookupExact(
52 absl::string_view map_key) const {
53 const auto it = cert_and_keys_.find(map_key);
54 QUIC_DVLOG(1) << "LookupExact(" << map_key
55 << ") found:" << (it != cert_and_keys_.end());
56 if (it != cert_and_keys_.end()) {
57 return it->second.get();
58 }
59 return nullptr;
60 }
61
62 } // namespace quic
63