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 #include "absl/strings/str_cat.h"
9 #include "absl/strings/string_view.h"
10
11 namespace quic {
12
AddCertAndKey(std::vector<std::string> server_hostnames,quiche::QuicheReferenceCountedPointer<Chain> chain,CertificatePrivateKey private_key)13 bool DefaultClientProofSource::AddCertAndKey(
14 std::vector<std::string> server_hostnames,
15 quiche::QuicheReferenceCountedPointer<Chain> chain,
16 CertificatePrivateKey private_key) {
17 if (!ValidateCertAndKey(chain, private_key)) {
18 return false;
19 }
20
21 auto cert_and_key =
22 std::make_shared<CertAndKey>(std::move(chain), std::move(private_key));
23 for (const std::string& domain : server_hostnames) {
24 cert_and_keys_[domain] = cert_and_key;
25 }
26 return true;
27 }
28
29 std::shared_ptr<const ClientProofSource::CertAndKey>
GetCertAndKey(absl::string_view hostname) const30 DefaultClientProofSource::GetCertAndKey(absl::string_view hostname) const {
31 if (std::shared_ptr<const CertAndKey> result = LookupExact(hostname);
32 result || hostname == "*") {
33 return result;
34 }
35
36 // Either a full or a wildcard domain lookup failed. In the former case,
37 // derive the wildcard domain and look it up.
38 if (hostname.size() > 1 && !absl::StartsWith(hostname, "*.")) {
39 auto dot_pos = hostname.find('.');
40 if (dot_pos != std::string::npos) {
41 std::string wildcard = absl::StrCat("*", hostname.substr(dot_pos));
42 std::shared_ptr<const CertAndKey> result = LookupExact(wildcard);
43 if (result != nullptr) {
44 return result;
45 }
46 }
47 }
48
49 // Return default cert, if any.
50 return LookupExact("*");
51 }
52
53 std::shared_ptr<const ClientProofSource::CertAndKey>
LookupExact(absl::string_view map_key) const54 DefaultClientProofSource::LookupExact(absl::string_view map_key) const {
55 const auto it = cert_and_keys_.find(map_key);
56 QUIC_DVLOG(1) << "LookupExact(" << map_key
57 << ") found:" << (it != cert_and_keys_.end());
58 if (it != cert_and_keys_.end()) {
59 return it->second;
60 }
61 return nullptr;
62 }
63
64 } // namespace quic
65