| // 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 "absl/strings/match.h" | |
| #include "absl/strings/str_cat.h" | |
| #include "absl/strings/string_view.h" | |
| namespace quic { | |
| bool DefaultClientProofSource::AddCertAndKey( | |
| std::vector<std::string> server_hostnames, | |
| quiche::QuicheReferenceCountedPointer<Chain> chain, | |
| CertificatePrivateKey private_key) { | |
| if (!ValidateCertAndKey(chain, private_key)) { | |
| return false; | |
| } | |
| auto cert_and_key = | |
| std::make_shared<CertAndKey>(std::move(chain), std::move(private_key)); | |
| for (const std::string& domain : server_hostnames) { | |
| cert_and_keys_[domain] = cert_and_key; | |
| } | |
| return true; | |
| } | |
| const ClientProofSource::CertAndKey* DefaultClientProofSource::GetCertAndKey( | |
| absl::string_view hostname) const { | |
| if (const CertAndKey* const result = LookupExact(hostname); | |
| result || hostname == "*") { | |
| return result; | |
| } | |
| // Either a full or a wildcard domain lookup failed. In the former case, | |
| // derive the wildcard domain and look it up. | |
| if (hostname.size() > 1 && !absl::StartsWith(hostname, "*.")) { | |
| auto dot_pos = hostname.find('.'); | |
| if (dot_pos != std::string::npos) { | |
| std::string wildcard = absl::StrCat("*", hostname.substr(dot_pos)); | |
| const CertAndKey* const result = LookupExact(wildcard); | |
| if (result != nullptr) { | |
| return result; | |
| } | |
| } | |
| } | |
| // Return default cert, if any. | |
| return LookupExact("*"); | |
| } | |
| const ClientProofSource::CertAndKey* DefaultClientProofSource::LookupExact( | |
| absl::string_view map_key) const { | |
| const auto it = cert_and_keys_.find(map_key); | |
| QUIC_DVLOG(1) << "LookupExact(" << map_key | |
| << ") found:" << (it != cert_and_keys_.end()); | |
| if (it != cert_and_keys_.end()) { | |
| return it->second.get(); | |
| } | |
| return nullptr; | |
| } | |
| } // namespace quic |