diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-22 23:54:36 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-22 23:54:36 +0000 |
commit | 35d5d5d6bcc213e12f073867f36aff082afc47ca (patch) | |
tree | f85bb274898e114f6c17a355c9286d54aa021d88 /net/base | |
parent | 89fdca49a4bb0cd18f6dde06e032482213aca299 (diff) | |
download | chromium_src-35d5d5d6bcc213e12f073867f36aff082afc47ca.zip chromium_src-35d5d5d6bcc213e12f073867f36aff082afc47ca.tar.gz chromium_src-35d5d5d6bcc213e12f073867f36aff082afc47ca.tar.bz2 |
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
Diffstat (limited to 'net/base')
-rw-r--r-- | net/base/cert_database.h | 5 | ||||
-rw-r--r-- | net/base/cert_database_nss.cc | 59 |
2 files changed, 64 insertions, 0 deletions
diff --git a/net/base/cert_database.h b/net/base/cert_database.h index 7f8c31c..4851a77 100644 --- a/net/base/cert_database.h +++ b/net/base/cert_database.h @@ -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, diff --git a/net/base/cert_database_nss.cc b/net/base/cert_database_nss.cc index e198e35..4fa877d 100644 --- a/net/base/cert_database_nss.cc +++ b/net/base/cert_database_nss.cc @@ -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) { |