// Copyright (c) 2014 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 "android_webview/browser/aw_ssl_host_state_delegate.h" #include "net/base/hash_value.h" using content::SSLHostStateDelegate; namespace android_webview { namespace internal { net::SHA256HashValue getChainFingerprint256(const net::X509Certificate& cert) { net::SHA256HashValue fingerprint = net::X509Certificate::CalculateChainFingerprint256( cert.os_cert_handle(), cert.GetIntermediateCertificates()); return fingerprint; } CertPolicy::CertPolicy() { } CertPolicy::~CertPolicy() { } // For an allowance, we consider a given |cert| to be a match to a saved // allowed cert if the |error| is an exact match to or subset of the errors // in the saved CertStatus. bool CertPolicy::Check(const net::X509Certificate& cert, net::CertStatus error) const { net::SHA256HashValue fingerprint = getChainFingerprint256(cert); std::map::const_iterator allowed_iter = allowed_.find(fingerprint); if ((allowed_iter != allowed_.end()) && (allowed_iter->second & error) && ((allowed_iter->second & error) == error)) { return true; } return false; } void CertPolicy::Allow(const net::X509Certificate& cert, net::CertStatus error) { // If this same cert had already been saved with a different error status, // this will replace it with the new error status. net::SHA256HashValue fingerprint = getChainFingerprint256(cert); allowed_[fingerprint] = error; } } // namespace internal AwSSLHostStateDelegate::AwSSLHostStateDelegate() { } AwSSLHostStateDelegate::~AwSSLHostStateDelegate() { } void AwSSLHostStateDelegate::HostRanInsecureContent(const std::string& host, int pid) { // Intentional no-op for Android WebView. } bool AwSSLHostStateDelegate::DidHostRunInsecureContent(const std::string& host, int pid) const { // Intentional no-op for Android WebView. return false; } void AwSSLHostStateDelegate::AllowCert(const std::string& host, const net::X509Certificate& cert, net::CertStatus error) { cert_policy_for_host_[host].Allow(cert, error); } void AwSSLHostStateDelegate::Clear() { cert_policy_for_host_.clear(); } SSLHostStateDelegate::CertJudgment AwSSLHostStateDelegate::QueryPolicy( const std::string& host, const net::X509Certificate& cert, net::CertStatus error, bool* expired_previous_decision) { return cert_policy_for_host_[host].Check(cert, error) ? SSLHostStateDelegate::ALLOWED : SSLHostStateDelegate::DENIED; } void AwSSLHostStateDelegate::RevokeUserAllowExceptions( const std::string& host) { cert_policy_for_host_.erase(host); } bool AwSSLHostStateDelegate::HasAllowException(const std::string& host) const { auto policy_iterator = cert_policy_for_host_.find(host); return policy_iterator != cert_policy_for_host_.end() && policy_iterator->second.HasAllowException(); } } // namespace android_webview