summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ssl/chrome_security_state_model_client.cc
blob: 412b89f3d547af090a0b9c59db8b1fdb7b13c9d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright 2015 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 "chrome/browser/ssl/chrome_security_state_model_client.h"

#include "base/command_line.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
#include "build/build_config.h"
#include "chrome/browser/chromeos/policy/policy_cert_service.h"
#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/cert_store.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/origin_util.h"
#include "content/public/common/ssl_status.h"
#include "net/cert/x509_certificate.h"

DEFINE_WEB_CONTENTS_USER_DATA_KEY(ChromeSecurityStateModelClient);

using security_state::SecurityStateModel;

namespace {

// Converts a content::SecurityStyle (an indicator of a request's
// overall security level computed by //content) into a
// SecurityStateModel::SecurityLevel (a finer-grained SecurityStateModel
// concept that can express all of SecurityStateModel's policies that
// //content doesn't necessarily know about).
SecurityStateModel::SecurityLevel GetSecurityLevelForSecurityStyle(
    content::SecurityStyle style) {
  switch (style) {
    case content::SECURITY_STYLE_UNKNOWN:
      NOTREACHED();
      return SecurityStateModel::NONE;
    case content::SECURITY_STYLE_UNAUTHENTICATED:
      return SecurityStateModel::NONE;
    case content::SECURITY_STYLE_AUTHENTICATION_BROKEN:
      return SecurityStateModel::SECURITY_ERROR;
    case content::SECURITY_STYLE_WARNING:
      // content currently doesn't use this style.
      NOTREACHED();
      return SecurityStateModel::SECURITY_WARNING;
    case content::SECURITY_STYLE_AUTHENTICATED:
      return SecurityStateModel::SECURE;
  }
  return SecurityStateModel::NONE;
}

}  // namespace

ChromeSecurityStateModelClient::ChromeSecurityStateModelClient(
    content::WebContents* web_contents)
    : web_contents_(web_contents),
      security_state_model_(new SecurityStateModel()) {
  security_state_model_->SetClient(this);
}

ChromeSecurityStateModelClient::~ChromeSecurityStateModelClient() {}

const SecurityStateModel::SecurityInfo&
ChromeSecurityStateModelClient::GetSecurityInfo() const {
  return security_state_model_->GetSecurityInfo();
}

bool ChromeSecurityStateModelClient::RetrieveCert(
    scoped_refptr<net::X509Certificate>* cert) {
  content::NavigationEntry* entry =
      web_contents_->GetController().GetVisibleEntry();
  if (!entry)
    return false;
  return content::CertStore::GetInstance()->RetrieveCert(
      entry->GetSSL().cert_id, cert);
}

bool ChromeSecurityStateModelClient::UsedPolicyInstalledCertificate() {
#if defined(OS_CHROMEOS)
  policy::PolicyCertService* service =
      policy::PolicyCertServiceFactory::GetForProfile(
          Profile::FromBrowserContext(web_contents_->GetBrowserContext()));
  if (service && service->UsedPolicyCertificates())
    return true;
#endif
  return false;
}

bool ChromeSecurityStateModelClient::IsOriginSecure(const GURL& url) {
  return content::IsOriginSecure(url);
}

void ChromeSecurityStateModelClient::GetVisibleSecurityState(
    SecurityStateModel::VisibleSecurityState* state) {
  content::NavigationEntry* entry =
      web_contents_->GetController().GetVisibleEntry();
  if (!entry ||
      entry->GetSSL().security_style == content::SECURITY_STYLE_UNKNOWN) {
    *state = SecurityStateModel::VisibleSecurityState();
    return;
  }

  state->initialized = true;
  state->url = entry->GetURL();
  const content::SSLStatus& ssl = entry->GetSSL();
  state->initial_security_level =
      GetSecurityLevelForSecurityStyle(ssl.security_style);
  state->cert_id = ssl.cert_id;
  state->cert_status = ssl.cert_status;
  state->connection_status = ssl.connection_status;
  state->security_bits = ssl.security_bits;
  state->sct_verify_statuses.clear();
  for (const auto& sct : ssl.signed_certificate_timestamp_ids)
    state->sct_verify_statuses.push_back(sct.status);
  state->displayed_mixed_content =
      (ssl.content_status & content::SSLStatus::DISPLAYED_INSECURE_CONTENT)
          ? true
          : false;
  state->ran_mixed_content =
      (ssl.content_status & content::SSLStatus::RAN_INSECURE_CONTENT) ? true
                                                                      : false;
}