Index: net/base/cert_database_nss.cc |
diff --git a/net/base/cert_database_nss.cc b/net/base/cert_database_nss.cc |
index e198e3504be82298c9b3354b0ae08e81be425a1f..4fa877dbb7dd35a900c3cb70d42bbbb5291c10dd 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) { |