| // Copyright 2018 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 "services/network/ssl_config_service_mojo.h" |
| |
| #include "base/strings/string_piece.h" |
| #include "mojo/public/cpp/bindings/type_converter.h" |
| #include "services/network/cert_verifier_config_type_converter.h" |
| #include "services/network/ssl_config_type_converter.h" |
| |
| namespace network { |
| |
| namespace { |
| |
| // Returns true if |hostname| is a subdomain of |pattern| (including if they are |
| // equal). |
| bool IsSubdomain(const base::StringPiece hostname, |
| const base::StringPiece pattern) { |
| if (hostname == pattern) { |
| return true; |
| } |
| if (hostname.length() <= (pattern.length() + 1)) { |
| return false; |
| } |
| if (!hostname.ends_with(pattern)) { |
| return false; |
| } |
| return hostname[hostname.length() - pattern.length() - 1] == '.'; |
| } |
| |
| } // namespace |
| |
| SSLConfigServiceMojo::SSLConfigServiceMojo( |
| mojom::SSLConfigPtr initial_config, |
| mojom::SSLConfigClientRequest ssl_config_client_request, |
| CRLSetDistributor* crl_set_distributor) |
| : binding_(this), |
| crl_set_distributor_(crl_set_distributor), |
| client_cert_pooling_policy_( |
| initial_config ? initial_config->client_cert_pooling_policy |
| : std::vector<std::string>()) { |
| if (initial_config) { |
| cert_verifier_config_ = |
| mojo::ConvertTo<net::CertVerifier::Config>(initial_config->Clone()); |
| ssl_config_ = mojo::ConvertTo<net::SSLConfig>(std::move(initial_config)); |
| } |
| |
| if (ssl_config_client_request) |
| binding_.Bind(std::move(ssl_config_client_request)); |
| |
| crl_set_distributor_->AddObserver(this); |
| cert_verifier_config_.crl_set = crl_set_distributor_->crl_set(); |
| } |
| |
| SSLConfigServiceMojo::~SSLConfigServiceMojo() { |
| crl_set_distributor_->RemoveObserver(this); |
| } |
| |
| void SSLConfigServiceMojo::SetCertVerifierForConfiguring( |
| net::CertVerifier* cert_verifier) { |
| cert_verifier_ = cert_verifier; |
| if (cert_verifier_) { |
| cert_verifier_->SetConfig(cert_verifier_config_); |
| } |
| } |
| |
| void SSLConfigServiceMojo::OnSSLConfigUpdated(mojom::SSLConfigPtr ssl_config) { |
| bool force_notification = |
| client_cert_pooling_policy_ != ssl_config->client_cert_pooling_policy; |
| client_cert_pooling_policy_ = ssl_config->client_cert_pooling_policy; |
| |
| net::SSLConfig old_config = ssl_config_; |
| ssl_config_ = mojo::ConvertTo<net::SSLConfig>(ssl_config->Clone()); |
| ProcessConfigUpdate(old_config, ssl_config_, force_notification); |
| |
| net::CertVerifier::Config old_cert_verifier_config = cert_verifier_config_; |
| cert_verifier_config_ = |
| mojo::ConvertTo<net::CertVerifier::Config>(std::move(ssl_config)); |
| cert_verifier_config_.crl_set = old_cert_verifier_config.crl_set; |
| if (cert_verifier_ && (old_cert_verifier_config != cert_verifier_config_)) { |
| cert_verifier_->SetConfig(cert_verifier_config_); |
| } |
| } |
| |
| void SSLConfigServiceMojo::GetSSLConfig(net::SSLConfig* ssl_config) { |
| *ssl_config = ssl_config_; |
| } |
| |
| bool SSLConfigServiceMojo::CanShareConnectionWithClientCerts( |
| const std::string& hostname) const { |
| // Hostnames (and the patterns configured for this class) must be |
| // canonicalized before comparison, or the comparison will fail. |
| for (const std::string& pattern : client_cert_pooling_policy_) { |
| if (pattern.empty()) { |
| continue; |
| } |
| // If the pattern starts with a '.', |hostname| must match it exactly |
| // (except for the leading dot) for the pattern to be a match. |
| if (pattern[0] == '.') { |
| if (pattern.compare(1, std::string::npos, hostname) == 0) { |
| return true; |
| } else { |
| continue; |
| } |
| } |
| // Patterns that don't start with a dot match subdomains as well as an exact |
| // pattern match. For example, a pattern of "example.com" should match a |
| // hostname of "example.com", "sub.example.com", but not "notexample.com". |
| if (IsSubdomain(hostname, pattern)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| void SSLConfigServiceMojo::OnNewCRLSet(scoped_refptr<net::CRLSet> crl_set) { |
| cert_verifier_config_.crl_set = crl_set; |
| if (cert_verifier_) |
| cert_verifier_->SetConfig(cert_verifier_config_); |
| } |
| |
| } // namespace network |