Commit 35d5d5d6 authored by agl@chromium.org's avatar agl@chromium.org

Mark untrusted certificates as such in Linux UI.

Some certificates are included in the certificate database in order to
explicitly mark them as untrusted. In our current UI this isn't
indicated and there's at least one, clearly fraudulent, CA in the list
that looks like all the rest.

This change causes these explicitly untrusted CAs to be marked with a
red badge next to them.

BUG=79549
TEST=Open the certificates dialog on Linux/ChromeOS and look for untrusted CA certificates.


Review URL: http://codereview.chromium.org/7272014

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@102402 0039d316-1c4b-4281-b951-d872f2087c98
parent 89fdca49
......@@ -3353,6 +3353,9 @@ are declared in build/common.gypi.
<message name="IDS_CERT_MANAGER_WRITE_ERROR_FORMAT" desc="The text in the error dialog for PKCS #12 file write errors.">
There was an error while trying to write the file: <ph name="ERROR_TEXT">$1<ex>Permission denied.</ex></ph>.
</message>
<message name="IDS_CERT_MANAGER_UNTRUSTED" desc="This text is displayed next to untrusted certificates in a red box. Untrusted certificates are sometimes added in order to explicitly distrust them. Thus, they will be listed but it's important that the user note that they serve a different purpose from the rest.">
Untrusted
</message>
<message name="IDS_CERT_MANAGER_PKCS12_IMPORT_ERROR_TITLE" desc="The title in the error dialog for PKCS #12 file import errors.">
PKCS #12 Import Error
</message>
......
span.certUntrusted {
background-color: pink;
border: 1px solid red;
border-radius: 3px;
margin-right: 3px;
padding-left: 1px;
padding-right: 1px;
}
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Copyright (c) 2011 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.
......@@ -24,6 +24,14 @@ cr.define('options', function() {
treeItem.icon = data.icon;
}
if (data.untrusted) {
var badge = document.createElement('span');
badge.setAttribute('class', 'certUntrusted');
badge.textContent = localStrings.getString("badgeCertUntrusted");
treeItem.labelElement.insertBefore(
badge, treeItem.labelElement.firstChild);
}
return treeItem;
}
......
......@@ -57,6 +57,7 @@
<if expr="not pp_ifdef('win32') and not pp_ifdef('darwin')">
<link rel="stylesheet" href="certificate_manager.css">
<link rel="stylesheet" href="certificate_tree.css">
</if>
<script src="chrome://resources/css/tree.css.js"></script>
......
......@@ -33,6 +33,7 @@ static const char kKeyId[] = "id";
static const char kSubNodesId[] = "subnodes";
static const char kNameId[] = "name";
static const char kReadOnlyId[] = "readonly";
static const char kUntrustedId[] = "untrusted";
static const char kIconId[] = "icon";
static const char kSecurityDeviceId[] = "device";
static const char kErrorId[] = "error";
......@@ -347,6 +348,10 @@ void CertificateManagerHandler::GetLocalizedValues(
localized_strings->SetString("certificateImportErrorFormat",
l10n_util::GetStringUTF16(IDS_CERT_MANAGER_IMPORT_ERROR_FORMAT));
// Badges next to certificates
localized_strings->SetString("badgeCertUntrusted",
l10n_util::GetStringUTF16(IDS_CERT_MANAGER_UNTRUSTED));
#if defined(OS_CHROMEOS)
localized_strings->SetString("importAndBindCertificate",
l10n_util::GetStringUTF16(IDS_CERT_MANAGER_IMPORT_AND_BIND_BUTTON));
......@@ -930,6 +935,9 @@ void CertificateManagerHandler::PopulateTree(const std::string& tab_name,
cert_dict->SetBoolean(
kReadOnlyId,
certificate_manager_model_->cert_db().IsReadOnly(cert));
cert_dict->SetBoolean(
kUntrustedId,
certificate_manager_model_->cert_db().IsUntrusted(cert));
// TODO(mattm): Other columns.
cert_dict->SetString(kIconId, "none");
subnodes->Append(cert_dict);
......
......@@ -162,6 +162,11 @@ class NET_EXPORT CertDatabase {
// Get trust bits for certificate.
TrustBits GetCertTrust(const X509Certificate* cert, CertType type) const;
// IsUntrusted returns true if |cert| is specifically untrusted. These
// certificates are stored in the database for the specific purpose of
// rejecting them.
bool IsUntrusted(const X509Certificate* cert) const;
// Set trust values for certificate.
// Returns true on success or false on failure.
bool SetCertTrust(const X509Certificate* cert,
......
......@@ -21,6 +21,12 @@
#include "net/third_party/mozilla_security_manager/nsNSSCertTrust.h"
#include "net/third_party/mozilla_security_manager/nsPKCS12Blob.h"
// In NSS 3.13, CERTDB_VALID_PEER was renamed CERTDB_TERMINAL_RECORD. So we use
// the new name of the macro.
#if !defined(CERTDB_TERMINAL_RECORD)
#define CERTDB_TERMINAL_RECORD CERTDB_VALID_PEER
#endif
// PSM = Mozilla's Personal Security Manager.
namespace psm = mozilla_security_manager;
......@@ -236,6 +242,59 @@ CertDatabase::TrustBits CertDatabase::GetCertTrust(const X509Certificate* cert,
}
}
bool CertDatabase::IsUntrusted(const X509Certificate* cert) const {
CERTCertTrust nsstrust;
SECStatus rv = CERT_GetCertTrust(cert->os_cert_handle(), &nsstrust);
if (rv != SECSuccess) {
LOG(ERROR) << "CERT_GetCertTrust failed with error " << PORT_GetError();
return false;
}
// The CERTCertTrust structure contains three trust records:
// sslFlags, emailFlags, and objectSigningFlags. The three
// trust records are independent of each other.
//
// If the CERTDB_TERMINAL_RECORD bit in a trust record is set,
// then that trust record is a terminal record. A terminal
// record is used for explicit trust and distrust of an
// end-entity or intermediate CA cert.
//
// In a terminal record, if neither CERTDB_TRUSTED_CA nor
// CERTDB_TRUSTED is set, then the terminal record means
// explicit distrust. On the other hand, if the terminal
// record has either CERTDB_TRUSTED_CA or CERTDB_TRUSTED bit
// set, then the terminal record means explicit trust.
//
// For a root CA, the trust record does not have
// the CERTDB_TERMINAL_RECORD bit set.
static const unsigned int kTrusted = CERTDB_TRUSTED_CA | CERTDB_TRUSTED;
if ((nsstrust.sslFlags & CERTDB_TERMINAL_RECORD) != 0 &&
(nsstrust.sslFlags & kTrusted) == 0) {
return true;
}
if ((nsstrust.emailFlags & CERTDB_TERMINAL_RECORD) != 0 &&
(nsstrust.emailFlags & kTrusted) == 0) {
return true;
}
if ((nsstrust.objectSigningFlags & CERTDB_TERMINAL_RECORD) != 0 &&
(nsstrust.objectSigningFlags & kTrusted) == 0) {
return true;
}
// Self-signed certificates that don't have any trust bits set are untrusted.
// Other certificates that don't have any trust bits set may still be trusted
// if they chain up to a trust anchor.
if (CERT_CompareName(&cert->os_cert_handle()->issuer,
&cert->os_cert_handle()->subject) == SECEqual) {
return (nsstrust.sslFlags & kTrusted) == 0 &&
(nsstrust.emailFlags & kTrusted) == 0 &&
(nsstrust.objectSigningFlags & kTrusted) == 0;
}
return false;
}
bool CertDatabase::SetCertTrust(const X509Certificate* cert,
CertType type,
TrustBits trust_bits) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment