From ad40b2190329c77463db06fb6982a0e26dc6ae05 Mon Sep 17 00:00:00 2001 From: "mattm@chromium.org" Date: Fri, 1 Jun 2012 05:59:56 +0000 Subject: Reland: Fix imported server certs being distrusted in NSS 3.13. Add support for intentionally distrusting certs. (Not exposed in the UI yet.) BUG=116411 TEST=CertDatabaseNSSTest TBR=stevenjb@chromium.org,jhawkins@chromium.org Review URL: https://chromiumcodereview.appspot.com/10458069 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@139979 0039d316-1c4b-4281-b951-d872f2087c98 --- .../mozilla_security_manager/nsNSSCertTrust.cpp | 378 --------------------- .../mozilla_security_manager/nsNSSCertTrust.h | 128 ------- .../nsNSSCertificateDB.cpp | 83 +++-- .../mozilla_security_manager/nsNSSCertificateDB.h | 1 + 4 files changed, 65 insertions(+), 525 deletions(-) delete mode 100644 net/third_party/mozilla_security_manager/nsNSSCertTrust.cpp delete mode 100644 net/third_party/mozilla_security_manager/nsNSSCertTrust.h (limited to 'net/third_party') diff --git a/net/third_party/mozilla_security_manager/nsNSSCertTrust.cpp b/net/third_party/mozilla_security_manager/nsNSSCertTrust.cpp deleted file mode 100644 index 408e55d..0000000 --- a/net/third_party/mozilla_security_manager/nsNSSCertTrust.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Ian McGreer - * Javier Delgadillo - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "net/third_party/mozilla_security_manager/nsNSSCertTrust.h" - -#if !defined(CERTDB_TERMINAL_RECORD) -/* NSS 3.13 renames CERTDB_VALID_PEER to CERTDB_TERMINAL_RECORD - * and marks CERTDB_VALID_PEER as deprecated. - * If we're using an older version, rename it ourselves. - */ -#define CERTDB_TERMINAL_RECORD CERTDB_VALID_PEER -#endif - -namespace mozilla_security_manager { - -void -nsNSSCertTrust::AddCATrust(PRBool ssl, PRBool email, PRBool objSign) -{ - if (ssl) { - addTrust(&mTrust.sslFlags, CERTDB_TRUSTED_CA); - addTrust(&mTrust.sslFlags, CERTDB_TRUSTED_CLIENT_CA); - } - if (email) { - addTrust(&mTrust.emailFlags, CERTDB_TRUSTED_CA); - addTrust(&mTrust.emailFlags, CERTDB_TRUSTED_CLIENT_CA); - } - if (objSign) { - addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED_CA); - addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED_CLIENT_CA); - } -} - -void -nsNSSCertTrust::AddPeerTrust(PRBool ssl, PRBool email, PRBool objSign) -{ - if (ssl) - addTrust(&mTrust.sslFlags, CERTDB_TRUSTED); - if (email) - addTrust(&mTrust.emailFlags, CERTDB_TRUSTED); - if (objSign) - addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED); -} - -nsNSSCertTrust::nsNSSCertTrust() -{ - memset(&mTrust, 0, sizeof(CERTCertTrust)); -} - -nsNSSCertTrust::nsNSSCertTrust(unsigned int ssl, - unsigned int email, - unsigned int objsign) -{ - memset(&mTrust, 0, sizeof(CERTCertTrust)); - addTrust(&mTrust.sslFlags, ssl); - addTrust(&mTrust.emailFlags, email); - addTrust(&mTrust.objectSigningFlags, objsign); -} - -nsNSSCertTrust::nsNSSCertTrust(CERTCertTrust *t) -{ - if (t) - memcpy(&mTrust, t, sizeof(CERTCertTrust)); - else - memset(&mTrust, 0, sizeof(CERTCertTrust)); -} - -nsNSSCertTrust::~nsNSSCertTrust() -{ -} - -void -nsNSSCertTrust::SetSSLTrust(PRBool peer, PRBool tPeer, - PRBool ca, PRBool tCA, PRBool tClientCA, - PRBool user, PRBool warn) -{ - mTrust.sslFlags = 0; - if (peer || tPeer) - addTrust(&mTrust.sslFlags, CERTDB_TERMINAL_RECORD); - if (tPeer) - addTrust(&mTrust.sslFlags, CERTDB_TRUSTED); - if (ca || tCA) - addTrust(&mTrust.sslFlags, CERTDB_VALID_CA); - if (tClientCA) - addTrust(&mTrust.sslFlags, CERTDB_TRUSTED_CLIENT_CA); - if (tCA) - addTrust(&mTrust.sslFlags, CERTDB_TRUSTED_CA); - if (user) - addTrust(&mTrust.sslFlags, CERTDB_USER); - if (warn) - addTrust(&mTrust.sslFlags, CERTDB_SEND_WARN); -} - -void -nsNSSCertTrust::SetEmailTrust(PRBool peer, PRBool tPeer, - PRBool ca, PRBool tCA, PRBool tClientCA, - PRBool user, PRBool warn) -{ - mTrust.emailFlags = 0; - if (peer || tPeer) - addTrust(&mTrust.emailFlags, CERTDB_TERMINAL_RECORD); - if (tPeer) - addTrust(&mTrust.emailFlags, CERTDB_TRUSTED); - if (ca || tCA) - addTrust(&mTrust.emailFlags, CERTDB_VALID_CA); - if (tClientCA) - addTrust(&mTrust.emailFlags, CERTDB_TRUSTED_CLIENT_CA); - if (tCA) - addTrust(&mTrust.emailFlags, CERTDB_TRUSTED_CA); - if (user) - addTrust(&mTrust.emailFlags, CERTDB_USER); - if (warn) - addTrust(&mTrust.emailFlags, CERTDB_SEND_WARN); -} - -void -nsNSSCertTrust::SetObjSignTrust(PRBool peer, PRBool tPeer, - PRBool ca, PRBool tCA, PRBool tClientCA, - PRBool user, PRBool warn) -{ - mTrust.objectSigningFlags = 0; - if (peer || tPeer) - addTrust(&mTrust.objectSigningFlags, CERTDB_TERMINAL_RECORD); - if (tPeer) - addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED); - if (ca || tCA) - addTrust(&mTrust.objectSigningFlags, CERTDB_VALID_CA); - if (tClientCA) - addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED_CLIENT_CA); - if (tCA) - addTrust(&mTrust.objectSigningFlags, CERTDB_TRUSTED_CA); - if (user) - addTrust(&mTrust.objectSigningFlags, CERTDB_USER); - if (warn) - addTrust(&mTrust.objectSigningFlags, CERTDB_SEND_WARN); -} - -void -nsNSSCertTrust::SetValidCA() -{ - SetSSLTrust(PR_FALSE, PR_FALSE, - PR_TRUE, PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE); - SetEmailTrust(PR_FALSE, PR_FALSE, - PR_TRUE, PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE); - SetObjSignTrust(PR_FALSE, PR_FALSE, - PR_TRUE, PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE); -} - -void -nsNSSCertTrust::SetTrustedServerCA() -{ - SetSSLTrust(PR_FALSE, PR_FALSE, - PR_TRUE, PR_TRUE, PR_FALSE, - PR_FALSE, PR_FALSE); - SetEmailTrust(PR_FALSE, PR_FALSE, - PR_TRUE, PR_TRUE, PR_FALSE, - PR_FALSE, PR_FALSE); - SetObjSignTrust(PR_FALSE, PR_FALSE, - PR_TRUE, PR_TRUE, PR_FALSE, - PR_FALSE, PR_FALSE); -} - -void -nsNSSCertTrust::SetTrustedCA() -{ - SetSSLTrust(PR_FALSE, PR_FALSE, - PR_TRUE, PR_TRUE, PR_TRUE, - PR_FALSE, PR_FALSE); - SetEmailTrust(PR_FALSE, PR_FALSE, - PR_TRUE, PR_TRUE, PR_TRUE, - PR_FALSE, PR_FALSE); - SetObjSignTrust(PR_FALSE, PR_FALSE, - PR_TRUE, PR_TRUE, PR_TRUE, - PR_FALSE, PR_FALSE); -} - -void -nsNSSCertTrust::SetValidPeer() -{ - SetSSLTrust(PR_TRUE, PR_FALSE, - PR_FALSE, PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE); - SetEmailTrust(PR_TRUE, PR_FALSE, - PR_FALSE, PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE); - SetObjSignTrust(PR_TRUE, PR_FALSE, - PR_FALSE, PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE); -} - -void -nsNSSCertTrust::SetValidServerPeer() -{ - SetSSLTrust(PR_TRUE, PR_FALSE, - PR_FALSE, PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE); - SetEmailTrust(PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE); - SetObjSignTrust(PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE); -} - -void -nsNSSCertTrust::SetTrustedPeer() -{ - SetSSLTrust(PR_TRUE, PR_TRUE, - PR_FALSE, PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE); - SetEmailTrust(PR_TRUE, PR_TRUE, - PR_FALSE, PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE); - SetObjSignTrust(PR_TRUE, PR_TRUE, - PR_FALSE, PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE); -} - -void -nsNSSCertTrust::SetUser() -{ - SetSSLTrust(PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE, PR_FALSE, - PR_TRUE, PR_FALSE); - SetEmailTrust(PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE, PR_FALSE, - PR_TRUE, PR_FALSE); - SetObjSignTrust(PR_FALSE, PR_FALSE, - PR_FALSE, PR_FALSE, PR_FALSE, - PR_TRUE, PR_FALSE); -} - -PRBool -nsNSSCertTrust::HasAnyCA() -{ - if (hasTrust(mTrust.sslFlags, CERTDB_VALID_CA) || - hasTrust(mTrust.emailFlags, CERTDB_VALID_CA) || - hasTrust(mTrust.objectSigningFlags, CERTDB_VALID_CA)) - return PR_TRUE; - return PR_FALSE; -} - -PRBool -nsNSSCertTrust::HasCA(PRBool checkSSL, - PRBool checkEmail, - PRBool checkObjSign) -{ - if (checkSSL && !hasTrust(mTrust.sslFlags, CERTDB_VALID_CA)) - return PR_FALSE; - if (checkEmail && !hasTrust(mTrust.emailFlags, CERTDB_VALID_CA)) - return PR_FALSE; - if (checkObjSign && !hasTrust(mTrust.objectSigningFlags, CERTDB_VALID_CA)) - return PR_FALSE; - return PR_TRUE; -} - -PRBool -nsNSSCertTrust::HasPeer(PRBool checkSSL, - PRBool checkEmail, - PRBool checkObjSign) -{ - if (checkSSL && !hasTrust(mTrust.sslFlags, CERTDB_TERMINAL_RECORD)) - return PR_FALSE; - if (checkEmail && !hasTrust(mTrust.emailFlags, CERTDB_TERMINAL_RECORD)) - return PR_FALSE; - if (checkObjSign && - !hasTrust(mTrust.objectSigningFlags, CERTDB_TERMINAL_RECORD)) - return PR_FALSE; - return PR_TRUE; -} - -PRBool -nsNSSCertTrust::HasAnyUser() -{ - if (hasTrust(mTrust.sslFlags, CERTDB_USER) || - hasTrust(mTrust.emailFlags, CERTDB_USER) || - hasTrust(mTrust.objectSigningFlags, CERTDB_USER)) - return PR_TRUE; - return PR_FALSE; -} - -PRBool -nsNSSCertTrust::HasUser(PRBool checkSSL, - PRBool checkEmail, - PRBool checkObjSign) -{ - if (checkSSL && !hasTrust(mTrust.sslFlags, CERTDB_USER)) - return PR_FALSE; - if (checkEmail && !hasTrust(mTrust.emailFlags, CERTDB_USER)) - return PR_FALSE; - if (checkObjSign && !hasTrust(mTrust.objectSigningFlags, CERTDB_USER)) - return PR_FALSE; - return PR_TRUE; -} - -PRBool -nsNSSCertTrust::HasTrustedCA(PRBool checkSSL, - PRBool checkEmail, - PRBool checkObjSign) -{ - if (checkSSL && !(hasTrust(mTrust.sslFlags, CERTDB_TRUSTED_CA) || - hasTrust(mTrust.sslFlags, CERTDB_TRUSTED_CLIENT_CA))) - return PR_FALSE; - if (checkEmail && !(hasTrust(mTrust.emailFlags, CERTDB_TRUSTED_CA) || - hasTrust(mTrust.emailFlags, CERTDB_TRUSTED_CLIENT_CA))) - return PR_FALSE; - if (checkObjSign && - !(hasTrust(mTrust.objectSigningFlags, CERTDB_TRUSTED_CA) || - hasTrust(mTrust.objectSigningFlags, CERTDB_TRUSTED_CLIENT_CA))) - return PR_FALSE; - return PR_TRUE; -} - -PRBool -nsNSSCertTrust::HasTrustedPeer(PRBool checkSSL, - PRBool checkEmail, - PRBool checkObjSign) -{ - if (checkSSL && !(hasTrust(mTrust.sslFlags, CERTDB_TRUSTED))) - return PR_FALSE; - if (checkEmail && !(hasTrust(mTrust.emailFlags, CERTDB_TRUSTED))) - return PR_FALSE; - if (checkObjSign && - !(hasTrust(mTrust.objectSigningFlags, CERTDB_TRUSTED))) - return PR_FALSE; - return PR_TRUE; -} - -void -nsNSSCertTrust::addTrust(unsigned int *t, unsigned int v) -{ - *t |= v; -} - -PRBool -nsNSSCertTrust::hasTrust(unsigned int t, unsigned int v) -{ - return !!(t & v); -} - -} // namespace mozilla_security_manager diff --git a/net/third_party/mozilla_security_manager/nsNSSCertTrust.h b/net/third_party/mozilla_security_manager/nsNSSCertTrust.h deleted file mode 100644 index bc42fd0..0000000 --- a/net/third_party/mozilla_security_manager/nsNSSCertTrust.h +++ /dev/null @@ -1,128 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Ian McGreer - * Javier Delgadillo - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef NET_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSNSSCERTTRUST_H_ -#define NET_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSNSSCERTTRUST_H_ - -#include -#include - -#include "net/base/net_export.h" - -namespace mozilla_security_manager { - -/* - * nsNSSCertTrust - * - * Class for maintaining trust flags for an NSS certificate. - */ -class NET_EXPORT nsNSSCertTrust -{ -public: - nsNSSCertTrust(); - nsNSSCertTrust(unsigned int ssl, unsigned int email, unsigned int objsign); - nsNSSCertTrust(CERTCertTrust *t); - virtual ~nsNSSCertTrust(); - - /* query */ - PRBool HasAnyCA(); - PRBool HasAnyUser(); - PRBool HasCA(PRBool checkSSL = PR_TRUE, - PRBool checkEmail = PR_TRUE, - PRBool checkObjSign = PR_TRUE); - PRBool HasPeer(PRBool checkSSL = PR_TRUE, - PRBool checkEmail = PR_TRUE, - PRBool checkObjSign = PR_TRUE); - PRBool HasUser(PRBool checkSSL = PR_TRUE, - PRBool checkEmail = PR_TRUE, - PRBool checkObjSign = PR_TRUE); - PRBool HasTrustedCA(PRBool checkSSL = PR_TRUE, - PRBool checkEmail = PR_TRUE, - PRBool checkObjSign = PR_TRUE); - PRBool HasTrustedPeer(PRBool checkSSL = PR_TRUE, - PRBool checkEmail = PR_TRUE, - PRBool checkObjSign = PR_TRUE); - - /* common defaults */ - /* equivalent to "c,c,c" */ - void SetValidCA(); - /* equivalent to "C,C,C" */ - void SetTrustedServerCA(); - /* equivalent to "CT,CT,CT" */ - void SetTrustedCA(); - /* equivalent to "p,," */ - void SetValidServerPeer(); - /* equivalent to "p,p,p" */ - void SetValidPeer(); - /* equivalent to "P,P,P" */ - void SetTrustedPeer(); - /* equivalent to "u,u,u" */ - void SetUser(); - - /* general setters */ - /* read: "p, P, c, C, T, u, w" */ - void SetSSLTrust(PRBool peer, PRBool tPeer, - PRBool ca, PRBool tCA, PRBool tClientCA, - PRBool user, PRBool warn); - - void SetEmailTrust(PRBool peer, PRBool tPeer, - PRBool ca, PRBool tCA, PRBool tClientCA, - PRBool user, PRBool warn); - - void SetObjSignTrust(PRBool peer, PRBool tPeer, - PRBool ca, PRBool tCA, PRBool tClientCA, - PRBool user, PRBool warn); - - /* set c <--> CT */ - void AddCATrust(PRBool ssl, PRBool email, PRBool objSign); - /* set p <--> P */ - void AddPeerTrust(PRBool ssl, PRBool email, PRBool objSign); - - /* get it (const?) (shallow?) */ - CERTCertTrust * GetTrust() { return &mTrust; } - -private: - void addTrust(unsigned int *t, unsigned int v); - void removeTrust(unsigned int *t, unsigned int v); - PRBool hasTrust(unsigned int t, unsigned int v); - CERTCertTrust mTrust; -}; - -} // namespace mozilla_security_manager - -#endif // NET_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSNSSCERTTRUST_H_ diff --git a/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp b/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp index 0cf430d..234c065 100644 --- a/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp +++ b/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp @@ -39,6 +39,7 @@ #include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h" #include +#include #include #include @@ -47,7 +48,14 @@ #include "crypto/scoped_nss_types.h" #include "net/base/net_errors.h" #include "net/base/x509_certificate.h" -#include "net/third_party/mozilla_security_manager/nsNSSCertTrust.h" + +#if !defined(CERTDB_TERMINAL_RECORD) +/* NSS 3.13 renames CERTDB_VALID_PEER to CERTDB_TERMINAL_RECORD + * and marks CERTDB_VALID_PEER as deprecated. + * If we're using an older version, rename it ourselves. + */ +#define CERTDB_TERMINAL_RECORD CERTDB_VALID_PEER +#endif namespace mozilla_security_manager { @@ -56,6 +64,9 @@ bool ImportCACerts(const net::CertificateList& certificates, net::X509Certificate* root, net::CertDatabase::TrustBits trustBits, net::CertDatabase::ImportCertFailureList* not_imported) { + if (certificates.empty() || !root) + return false; + crypto::ScopedPK11Slot slot(crypto::GetPublicNSSKeySlot()); if (!slot.get()) { LOG(ERROR) << "Couldn't get internal key slot!"; @@ -158,7 +169,11 @@ bool ImportCACerts(const net::CertificateList& certificates, // Based on nsNSSCertificateDB::ImportServerCertificate. bool ImportServerCert(const net::CertificateList& certificates, + net::CertDatabase::TrustBits trustBits, net::CertDatabase::ImportCertFailureList* not_imported) { + if (certificates.empty()) + return false; + crypto::ScopedPK11Slot slot(crypto::GetPublicNSSKeySlot()); if (!slot.get()) { LOG(ERROR) << "Couldn't get internal key slot!"; @@ -184,9 +199,7 @@ bool ImportServerCert(const net::CertificateList& certificates, } } - // Set as valid peer, but without any extra trust. - SetCertTrust(certificates[0].get(), net::SERVER_CERT, - net::CertDatabase::UNTRUSTED); + SetCertTrust(certificates[0].get(), net::SERVER_CERT, trustBits); // TODO(mattm): Report SetCertTrust result? Putting in not_imported // wouldn't quite match up since it was imported... @@ -200,25 +213,57 @@ SetCertTrust(const net::X509Certificate* cert, net::CertType type, net::CertDatabase::TrustBits trustBits) { + const unsigned kSSLTrustBits = net::CertDatabase::TRUSTED_SSL | + net::CertDatabase::DISTRUSTED_SSL; + const unsigned kEmailTrustBits = net::CertDatabase::TRUSTED_EMAIL | + net::CertDatabase::DISTRUSTED_EMAIL; + const unsigned kObjSignTrustBits = net::CertDatabase::TRUSTED_OBJ_SIGN | + net::CertDatabase::DISTRUSTED_OBJ_SIGN; + if ((trustBits & kSSLTrustBits) == kSSLTrustBits || + (trustBits & kEmailTrustBits) == kEmailTrustBits || + (trustBits & kObjSignTrustBits) == kObjSignTrustBits) { + LOG(ERROR) << "SetCertTrust called with conflicting trust bits " + << trustBits; + NOTREACHED(); + return false; + } + SECStatus srv; - nsNSSCertTrust trust; CERTCertificate *nsscert = cert->os_cert_handle(); if (type == net::CA_CERT) { - // always start with untrusted and move up - trust.SetValidCA(); - trust.AddCATrust(trustBits & net::CertDatabase::TRUSTED_SSL, - trustBits & net::CertDatabase::TRUSTED_EMAIL, - trustBits & net::CertDatabase::TRUSTED_OBJ_SIGN); - srv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), - nsscert, - trust.GetTrust()); + // Note that we start with CERTDB_VALID_CA for default trust and explicit + // trust, but explicitly distrusted usages will be set to + // CERTDB_TERMINAL_RECORD only. + CERTCertTrust trust = {CERTDB_VALID_CA, CERTDB_VALID_CA, CERTDB_VALID_CA}; + + if (trustBits & net::CertDatabase::DISTRUSTED_SSL) + trust.sslFlags = CERTDB_TERMINAL_RECORD; + else if (trustBits & net::CertDatabase::TRUSTED_SSL) + trust.sslFlags |= CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA; + + if (trustBits & net::CertDatabase::DISTRUSTED_EMAIL) + trust.emailFlags = CERTDB_TERMINAL_RECORD; + else if (trustBits & net::CertDatabase::TRUSTED_EMAIL) + trust.emailFlags |= CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA; + + if (trustBits & net::CertDatabase::DISTRUSTED_OBJ_SIGN) + trust.objectSigningFlags = CERTDB_TERMINAL_RECORD; + else if (trustBits & net::CertDatabase::TRUSTED_OBJ_SIGN) + trust.objectSigningFlags |= CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA; + + srv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nsscert, &trust); } else if (type == net::SERVER_CERT) { - // always start with untrusted and move up - trust.SetValidPeer(); - trust.AddPeerTrust(trustBits & net::CertDatabase::TRUSTED_SSL, 0, 0); - srv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), - nsscert, - trust.GetTrust()); + CERTCertTrust trust = {0}; + // We only modify the sslFlags, so copy the other flags. + CERT_GetCertTrust(nsscert, &trust); + trust.sslFlags = 0; + + if (trustBits & net::CertDatabase::DISTRUSTED_SSL) + trust.sslFlags |= CERTDB_TERMINAL_RECORD; + else if (trustBits & net::CertDatabase::TRUSTED_SSL) + trust.sslFlags |= CERTDB_TRUSTED | CERTDB_TERMINAL_RECORD; + + srv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nsscert, &trust); } else { // ignore user and email/unknown certs return true; diff --git a/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h b/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h index 29acaf9..e7a5a103 100644 --- a/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h +++ b/net/third_party/mozilla_security_manager/nsNSSCertificateDB.h @@ -58,6 +58,7 @@ bool ImportCACerts(const net::CertificateList& certificates, net::CertDatabase::ImportCertFailureList* not_imported); bool ImportServerCert(const net::CertificateList& certificates, + net::CertDatabase::TrustBits trustBits, net::CertDatabase::ImportCertFailureList* not_imported); bool SetCertTrust(const net::X509Certificate* cert, -- cgit v1.1