1// Copyright (c) 2014 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 "android_webview/browser/aw_ssl_host_state_delegate.h"
6
7#include "net/base/hash_value.h"
8
9using content::SSLHostStateDelegate;
10
11namespace android_webview {
12
13namespace internal {
14net::SHA256HashValue getChainFingerprint256(const net::X509Certificate& cert) {
15  net::SHA256HashValue fingerprint =
16      net::X509Certificate::CalculateChainFingerprint256(
17          cert.os_cert_handle(), cert.GetIntermediateCertificates());
18  return fingerprint;
19}
20
21CertPolicy::CertPolicy() {
22}
23CertPolicy::~CertPolicy() {
24}
25
26// For an allowance, we consider a given |cert| to be a match to a saved
27// allowed cert if the |error| is an exact match to or subset of the errors
28// in the saved CertStatus.
29bool CertPolicy::Check(const net::X509Certificate& cert,
30                       net::CertStatus error) const {
31  net::SHA256HashValue fingerprint = getChainFingerprint256(cert);
32  std::map<net::SHA256HashValue, net::CertStatus,
33           net::SHA256HashValueLessThan>::const_iterator allowed_iter =
34      allowed_.find(fingerprint);
35  if ((allowed_iter != allowed_.end()) && (allowed_iter->second & error) &&
36      ((allowed_iter->second & error) == error)) {
37    return true;
38  }
39  return false;
40}
41
42void CertPolicy::Allow(const net::X509Certificate& cert,
43                       net::CertStatus error) {
44  // If this same cert had already been saved with a different error status,
45  // this will replace it with the new error status.
46  net::SHA256HashValue fingerprint = getChainFingerprint256(cert);
47  allowed_[fingerprint] = error;
48}
49
50}  // namespace internal
51
52AwSSLHostStateDelegate::AwSSLHostStateDelegate() {
53}
54
55AwSSLHostStateDelegate::~AwSSLHostStateDelegate() {
56}
57
58void AwSSLHostStateDelegate::HostRanInsecureContent(const std::string& host,
59                                                    int pid) {
60  // Intentional no-op for Android WebView.
61}
62
63bool AwSSLHostStateDelegate::DidHostRunInsecureContent(const std::string& host,
64                                                       int pid) const {
65  // Intentional no-op for Android WebView.
66  return false;
67}
68
69void AwSSLHostStateDelegate::AllowCert(const std::string& host,
70                                       const net::X509Certificate& cert,
71                                       net::CertStatus error) {
72  cert_policy_for_host_[host].Allow(cert, error);
73}
74
75void AwSSLHostStateDelegate::Clear() {
76  cert_policy_for_host_.clear();
77}
78
79SSLHostStateDelegate::CertJudgment AwSSLHostStateDelegate::QueryPolicy(
80    const std::string& host,
81    const net::X509Certificate& cert,
82    net::CertStatus error,
83    bool* expired_previous_decision) {
84  return cert_policy_for_host_[host].Check(cert, error)
85             ? SSLHostStateDelegate::ALLOWED
86             : SSLHostStateDelegate::DENIED;
87}
88
89}  // namespace android_webview
90