bug 857627 - 4/4: remove nickname-related APIs from nsIX509CertDB r?Cykesiopka,jcj draft
authorDavid Keeler <dkeeler@mozilla.com>
Fri, 18 Nov 2016 16:35:27 -0800
changeset 446748 3f36121f02944b3aad4cf5a046f1b56c5de9796c
parent 446747 c98c247f2fc94221a3a0f65db32b50c560e876a5
child 538847 45a0d225ff63ba407691238cec1b167f8b33856d
push id37861
push userdkeeler@mozilla.com
push dateThu, 01 Dec 2016 19:20:01 +0000
reviewersCykesiopka, jcj
bugs857627
milestone53.0a1
bug 857627 - 4/4: remove nickname-related APIs from nsIX509CertDB r?Cykesiopka,jcj This removes findCertByNickname, findEmailEncryptionCert, and findEmailSigningCert. MozReview-Commit-ID: KOxWHJm3GNX
security/manager/ssl/LocalCertService.cpp
security/manager/ssl/nsIX509CertDB.idl
security/manager/ssl/nsNSSCertificate.cpp
security/manager/ssl/nsNSSCertificateDB.cpp
--- a/security/manager/ssl/LocalCertService.cpp
+++ b/security/manager/ssl/LocalCertService.cpp
@@ -8,63 +8,87 @@
 #include "ScopedNSSTypes.h"
 #include "cert.h"
 #include "mozilla/Casting.h"
 #include "mozilla/ModuleUtils.h"
 #include "mozilla/RefPtr.h"
 #include "nsIPK11Token.h"
 #include "nsIPK11TokenDB.h"
 #include "nsIX509Cert.h"
-#include "nsIX509CertDB.h"
 #include "nsIX509CertValidity.h"
 #include "nsLiteralString.h"
 #include "nsProxyRelease.h"
 #include "nsServiceManagerUtils.h"
 #include "nsString.h"
 #include "pk11pub.h"
 
 namespace mozilla {
 
+// Given a name, searches the internal certificate/key database for a
+// self-signed certificate with subject and issuer distinguished name equal to
+// "CN={name}". This assumes that the user has already authenticated to the
+// internal DB if necessary.
+static nsresult
+FindLocalCertByName(const nsACString& aName,
+            /*out*/ UniqueCERTCertificate& aResult)
+{
+  aResult.reset(nullptr);
+  NS_NAMED_LITERAL_CSTRING(commonNamePrefix, "CN=");
+  nsAutoCString expectedDistinguishedName(commonNamePrefix + aName);
+  UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
+  if (!slot) {
+    return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
+  }
+  UniqueCERTCertList certList(PK11_ListCertsInSlot(slot.get()));
+  if (!certList) {
+    return NS_ERROR_UNEXPECTED;
+  }
+  for (const CERTCertListNode* node = CERT_LIST_HEAD(certList);
+       !CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node)) {
+    // If this isn't a self-signed cert, it's not what we're interested in.
+    if (!node->cert->isRoot) {
+      continue;
+    }
+    if (!expectedDistinguishedName.Equals(node->cert->subjectName)) {
+      continue; // Subject should match nickname
+    }
+    if (!expectedDistinguishedName.Equals(node->cert->issuerName)) {
+      continue; // Issuer should match nickname
+    }
+    // We found a match.
+    aResult.reset(CERT_DupCertificate(node->cert));
+    return NS_OK;
+  }
+  return NS_OK;
+}
+
 class LocalCertTask : public CryptoTask
 {
 protected:
   explicit LocalCertTask(const nsACString& aNickname)
     : mNickname(aNickname)
   {
   }
 
   nsresult RemoveExisting()
   {
-    // Search for any existing certs with this name and remove them
-    nsresult rv;
-
+    // Search for any existing self-signed certs with this name and remove them
     for (;;) {
-      UniqueCERTCertificate cert(
-        PK11_FindCertFromNickname(mNickname.get(), nullptr));
-      if (!cert) {
-        return NS_OK; // All done
+      UniqueCERTCertificate cert;
+      nsresult rv = FindLocalCertByName(mNickname, cert);
+      if (NS_FAILED(rv)) {
+        return rv;
       }
-
-      // Found a cert, check if generated by this service
-      if (!cert->isRoot) {
-        return NS_ERROR_UNEXPECTED; // Should be self-signed
+      // If we didn't find a match, we're done.
+      if (!cert) {
+        return NS_OK;
       }
-
-      NS_NAMED_LITERAL_CSTRING(commonNamePrefix, "CN=");
-      nsAutoCString subjectNameFromNickname(commonNamePrefix + mNickname);
-      if (!subjectNameFromNickname.Equals(cert->subjectName)) {
-        return NS_ERROR_UNEXPECTED; // Subject should match nickname
-      }
-      if (!subjectNameFromNickname.Equals(cert->issuerName)) {
-        return NS_ERROR_UNEXPECTED; // Issuer should match nickname
-      }
-
       rv = MapSECStatus(PK11_DeleteTokenCertAndKey(cert.get(), nullptr));
       if (NS_FAILED(rv)) {
-        return rv; // Some error, abort the loop
+        return rv;
       }
     }
   }
 
   nsCString mNickname;
 };
 
 class LocalCertGetTask final : public LocalCertTask
@@ -248,29 +272,25 @@ private:
     }
 
     // We should now have cert in the DB, read it back in nsIX509Cert form
     return GetFromDB();
   }
 
   nsresult GetFromDB()
   {
-    nsCOMPtr<nsIX509CertDB> certDB = do_GetService(NS_X509CERTDB_CONTRACTID);
-    if (!certDB) {
-      return NS_ERROR_FAILURE;
-    }
-
-    nsCOMPtr<nsIX509Cert> certFromDB;
-    nsresult rv;
-    rv = certDB->FindCertByNickname(NS_ConvertASCIItoUTF16(mNickname),
-                                    getter_AddRefs(certFromDB));
+    UniqueCERTCertificate cert;
+    nsresult rv = FindLocalCertByName(mNickname, cert);
     if (NS_FAILED(rv)) {
       return rv;
     }
-    mCert = certFromDB;
+    if (!cert) {
+      return NS_ERROR_FAILURE;
+    }
+    mCert = nsNSSCertificate::Create(cert.get());
     return NS_OK;
   }
 
   nsresult Validate()
   {
     // Verify cert is self-signed
     bool selfSigned;
     nsresult rv = mCert->GetIsSelfSigned(&selfSigned);
--- a/security/manager/ssl/nsIX509CertDB.idl
+++ b/security/manager/ssl/nsIX509CertDB.idl
@@ -70,57 +70,26 @@ interface nsIX509CertDB : nsISupports {
    *  is trusted for.
    */
   const unsigned long UNTRUSTED       =      0;
   const unsigned long TRUSTED_SSL     = 1 << 0;
   const unsigned long TRUSTED_EMAIL   = 1 << 1;
   const unsigned long TRUSTED_OBJSIGN = 1 << 2;
 
   /**
-   *  Given a nickname,
-   *  locate the matching certificate.
-   *
-   *  @param aNickname The nickname to be used as the key
-   *                   to find a certificate.
-   *
-   *  @return The matching certificate if found.
-   */
-  nsIX509Cert findCertByNickname(in AString aNickname);
-
-  /**
    *  Will find a certificate based on its dbkey
    *  retrieved by getting the dbKey attribute of
    *  the certificate.
    *
    *  @param aDBkey Database internal key, as obtained using
    *                attribute dbkey in nsIX509Cert.
    */
   nsIX509Cert findCertByDBKey(in string aDBkey);
 
   /**
-   *  Find user's own email encryption certificate by nickname.
-   *
-   *  @param aNickname The nickname to be used as the key
-   *                   to find the certificate.
-   *
-   *  @return The matching certificate if found.
-   */
-  nsIX509Cert findEmailEncryptionCert(in AString aNickname);
-
-  /**
-   *  Find user's own email signing certificate by nickname.
-   *
-   *  @param aNickname The nickname to be used as the key
-   *                   to find the certificate.
-   *
-   *  @return The matching certificate if found.
-   */
-  nsIX509Cert findEmailSigningCert(in AString aNickname);
-
-  /**
    *  Find a certificate by email address.
    *
    *  @param aEmailAddress The email address to be used as the key
    *                       to find the certificate.
    *
    *  @return The matching certificate if found.
    */
   nsIX509Cert findCertByEmailAddress(in string aEmailAddress);
--- a/security/manager/ssl/nsNSSCertificate.cpp
+++ b/security/manager/ssl/nsNSSCertificate.cpp
@@ -664,17 +664,16 @@ nsNSSCertificate::GetOrganizationalUnit(
 NS_IMETHODIMP
 nsNSSCertificate::GetChain(nsIArray** _rvChain)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return NS_ERROR_NOT_AVAILABLE;
 
   NS_ENSURE_ARG(_rvChain);
-  MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Getting chain for \"%s\"\n", mCert->nickname));
 
   mozilla::pkix::Time now(mozilla::pkix::Now());
 
   RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier());
   NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
 
   UniqueCERTCertList nssChain;
   // We want to test all usages, but we start with server because most of the
@@ -698,55 +697,47 @@ nsNSSCertificate::GetChain(nsIArray** _r
                                 certificateUsageObjectSigner |
                                 certificateUsageStatusResponder;
   for (int usage = certificateUsageSSLClient;
        usage < certificateUsageAnyCA && !nssChain;
        usage = usage << 1) {
     if ((usage & otherUsagesToTest) == 0) {
       continue;
     }
-    MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
-           ("pipnss: PKIX attempting chain(%d) for '%s'\n",
-            usage, mCert->nickname));
     if (certVerifier->VerifyCert(mCert.get(), usage, now,
                                  nullptr, /*XXX fixme*/
                                  nullptr, /*hostname*/
                                  nssChain,
                                  CertVerifier::FLAG_LOCAL_ONLY)
           != mozilla::pkix::Success) {
       nssChain = nullptr;
       // keep going
     }
   }
 
   if (!nssChain) {
     // There is not verified path for the chain, however we still want to
     // present to the user as much of a possible chain as possible, in the case
     // where there was a problem with the cert or the issuers.
-    MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
-           ("pipnss: getchain :CertVerify failed to get chain for '%s'\n",
-            mCert->nickname));
     nssChain = UniqueCERTCertList(
       CERT_GetCertChainFromCert(mCert.get(), PR_Now(), certUsageSSLClient));
   }
   if (!nssChain) {
     return NS_ERROR_FAILURE;
   }
 
   // enumerate the chain for scripting purposes
   nsCOMPtr<nsIMutableArray> array = nsArrayBase::Create();
   if (!array) {
     return NS_ERROR_FAILURE;
   }
   CERTCertListNode* node;
   for (node = CERT_LIST_HEAD(nssChain.get());
        !CERT_LIST_END(node, nssChain.get());
        node = CERT_LIST_NEXT(node)) {
-    MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
-           ("adding %s to chain\n", node->cert->nickname));
     nsCOMPtr<nsIX509Cert> cert = nsNSSCertificate::Create(node->cert);
     array->AppendElement(cert, false);
   }
   *_rvChain = array;
   NS_IF_ADDREF(*_rvChain);
   return NS_OK;
 }
 
@@ -758,17 +749,16 @@ nsNSSCertificate::GetAllTokenNames(uint3
     return NS_ERROR_NOT_AVAILABLE;
 
   NS_ENSURE_ARG(aLength);
   NS_ENSURE_ARG(aTokenNames);
   *aLength = 0;
   *aTokenNames = nullptr;
 
   // Get the slots from NSS
-  MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Getting slots for \"%s\"\n", mCert->nickname));
   UniquePK11SlotList slots(PK11_GetAllSlotsForCert(mCert.get(), nullptr));
   if (!slots) {
     if (PORT_GetError() == SEC_ERROR_NO_TOKEN) {
       return NS_OK; // List of slots is empty, return empty array
     }
     return NS_ERROR_FAILURE;
   }
 
--- a/security/manager/ssl/nsNSSCertificateDB.cpp
+++ b/security/manager/ssl/nsNSSCertificateDB.cpp
@@ -90,46 +90,16 @@ nsNSSCertificateDB::~nsNSSCertificateDB(
   if (isAlreadyShutDown()) {
     return;
   }
 
   shutdown(ShutdownCalledFrom::Object);
 }
 
 NS_IMETHODIMP
-nsNSSCertificateDB::FindCertByNickname(const nsAString& nickname,
-                                       nsIX509Cert** _rvCert)
-{
-  NS_ENSURE_ARG_POINTER(_rvCert);
-  *_rvCert = nullptr;
-
-  nsNSSShutDownPreventionLock locker;
-  if (isAlreadyShutDown()) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-  char *asciiname = nullptr;
-  NS_ConvertUTF16toUTF8 aUtf8Nickname(nickname);
-  asciiname = const_cast<char*>(aUtf8Nickname.get());
-  MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Getting \"%s\"\n", asciiname));
-  UniqueCERTCertificate cert(PK11_FindCertFromNickname(asciiname, nullptr));
-  if (!cert) {
-    cert.reset(CERT_FindCertByNickname(CERT_GetDefaultCertDB(), asciiname));
-  }
-  if (cert) {
-    MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("got it\n"));
-    nsCOMPtr<nsIX509Cert> pCert = nsNSSCertificate::Create(cert.get());
-    if (pCert) {
-      pCert.forget(_rvCert);
-      return NS_OK;
-    }
-  }
-  return NS_ERROR_FAILURE;
-}
-
-NS_IMETHODIMP
 nsNSSCertificateDB::FindCertByDBKey(const char* aDBKey,nsIX509Cert** _cert)
 {
   NS_ENSURE_ARG_POINTER(aDBKey);
   NS_ENSURE_ARG(aDBKey[0]);
   NS_ENSURE_ARG_POINTER(_cert);
   *_cert = nullptr;
 
   nsNSSShutDownPreventionLock locker;
@@ -1034,90 +1004,16 @@ nsNSSCertificateDB::ExportPKCS12File(nsI
   } else {
     localRef = do_QueryInterface(aToken);
   }
   blob.SetToken(localRef);
   return blob.ExportToFile(aFile, certs, count);
 }
 
 NS_IMETHODIMP
-nsNSSCertificateDB::FindEmailEncryptionCert(const nsAString& aNickname,
-                                            nsIX509Cert** _retval)
-{
-  NS_ENSURE_ARG_POINTER(_retval);
-  *_retval = nullptr;
-
-  if (aNickname.IsEmpty())
-    return NS_OK;
-
-  nsNSSShutDownPreventionLock locker;
-  if (isAlreadyShutDown()) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
-  char *asciiname = nullptr;
-  NS_ConvertUTF16toUTF8 aUtf8Nickname(aNickname);
-  asciiname = const_cast<char*>(aUtf8Nickname.get());
-
-  /* Find a good cert in the user's database */
-  UniqueCERTCertificate cert(CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
-                                                      asciiname,
-                                                      certUsageEmailRecipient,
-                                                      true, ctx));
-  if (!cert) {
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIX509Cert> nssCert = nsNSSCertificate::Create(cert.get());
-  if (!nssCert) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-  nssCert.forget(_retval);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsNSSCertificateDB::FindEmailSigningCert(const nsAString& aNickname,
-                                         nsIX509Cert** _retval)
-{
-  NS_ENSURE_ARG_POINTER(_retval);
-  *_retval = nullptr;
-
-  if (aNickname.IsEmpty())
-    return NS_OK;
-
-  nsNSSShutDownPreventionLock locker;
-  if (isAlreadyShutDown()) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
-  char *asciiname = nullptr;
-  NS_ConvertUTF16toUTF8 aUtf8Nickname(aNickname);
-  asciiname = const_cast<char*>(aUtf8Nickname.get());
-
-  /* Find a good cert in the user's database */
-  UniqueCERTCertificate cert(CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
-                                                      asciiname,
-                                                      certUsageEmailSigner,
-                                                      true, ctx));
-  if (!cert) {
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIX509Cert> nssCert = nsNSSCertificate::Create(cert.get());
-  if (!nssCert) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-  nssCert.forget(_retval);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsNSSCertificateDB::FindCertByEmailAddress(const char* aEmailAddress,
                                            nsIX509Cert** _retval)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }