Back out changeset a02ea85607a2 (bug 1038072) for widespread test failures (at least Linux, Android, and Mulet), on a CLOSED TREE.
authorL. David Baron <dbaron@dbaron.org>
Wed, 06 May 2015 09:58:55 +0200
changeset 242593 b7ed296c05adfa33ea8fc3aa29a28d96ce05a267
parent 242592 5ae4aaad2fe960ad4cd97a00198e84c32b081cfb
child 242594 aa884bc76a9d644bf82ef9410022e50d70eb0d2e
push id28701
push userryanvm@gmail.com
push dateWed, 06 May 2015 20:26:41 +0000
treeherdermozilla-central@5593ac626826 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1038072
milestone40.0a1
backs outa02ea85607a2c0989f057053858125fa5046763b
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Back out changeset a02ea85607a2 (bug 1038072) for widespread test failures (at least Linux, Android, and Mulet), on a CLOSED TREE.
security/apps/AppSignatureVerification.cpp
security/manager/ssl/public/nsIX509CertDB.idl
security/manager/ssl/tests/unit/test_signed_apps/sslcontrol.xpi
security/manager/ssl/tests/unit/test_signed_dir.js
security/manager/ssl/tests/unit/xpcshell.ini
--- a/security/apps/AppSignatureVerification.cpp
+++ b/security/apps/AppSignatureVerification.cpp
@@ -15,17 +15,16 @@
 #include "nsComponentManagerUtils.h"
 #include "nsCOMPtr.h"
 #include "nsDataSignatureVerifier.h"
 #include "nsHashKeys.h"
 #include "nsIFile.h"
 #include "nsIFileStreams.h"
 #include "nsIInputStream.h"
 #include "nsIStringEnumerator.h"
-#include "nsIDirectoryEnumerator.h"
 #include "nsIZipReader.h"
 #include "nsNetUtil.h"
 #include "nsNSSCertificate.h"
 #include "nsProxyRelease.h"
 #include "nssb64.h"
 #include "NSSCertDBTrustDomain.h"
 #include "nsString.h"
 #include "nsTHashtable.h"
@@ -94,17 +93,17 @@ ReadStream(const nsCOMPtr<nsIInputStream
     return NS_ERROR_FILE_CORRUPTED;
   }
 
   buf.data[buf.len - 1] = 0; // null-terminate
 
   return NS_OK;
 }
 
-// Finds exactly one (signature metadata) JAR entry that matches the given
+// Finds exactly one (signature metadata) entry that matches the given
 // search pattern, and then load it. Fails if there are no matches or if
 // there is more than one match. If bugDigest is not null then on success
 // bufDigest will contain the SHA-1 digeset of the entry.
 nsresult
 FindAndLoadOneEntry(nsIZipReader * zip,
                     const nsACString & searchPattern,
                     /*out*/ nsACString & filename,
                     /*out*/ SECItem & buf,
@@ -149,32 +148,37 @@ FindAndLoadOneEntry(nsIZipReader * zip,
 
   return NS_OK;
 }
 
 // Verify the digest of an entry. We avoid loading the entire entry into memory
 // at once, which would require memory in proportion to the size of the largest
 // entry. Instead, we require only a small, fixed amount of memory.
 //
-// @param stream  an input stream from a JAR entry or file depending on whether
-//                it is from a signed archive or unpacked into a directory
 // @param digestFromManifest The digest that we're supposed to check the file's
 //                           contents against, from the manifest
 // @param buf A scratch buffer that we use for doing the I/O, which must have
 //            already been allocated. The size of this buffer is the unit
 //            size of our I/O.
 nsresult
-VerifyStreamContentDigest(nsIInputStream* stream,
-                          const SECItem& digestFromManifest, SECItem& buf)
+VerifyEntryContentDigest(nsIZipReader * zip, const nsACString & aFilename,
+                         const SECItem & digestFromManifest, SECItem & buf)
 {
   MOZ_ASSERT(buf.len > 0);
   if (digestFromManifest.len != SHA1_LENGTH)
     return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
 
   nsresult rv;
+
+  nsCOMPtr<nsIInputStream> stream;
+  rv = zip->GetInputStream(aFilename, getter_AddRefs(stream));
+  if (NS_FAILED(rv)) {
+    return NS_ERROR_SIGNED_JAR_ENTRY_MISSING;
+  }
+
   uint64_t len64;
   rv = stream->Available(&len64);
   NS_ENSURE_SUCCESS(rv, rv);
   if (len64 > UINT32_MAX) {
     return NS_ERROR_SIGNED_JAR_ENTRY_TOO_LARGE;
   }
 
   ScopedPK11Context digestContext(PK11_CreateDigestContext(SEC_OID_SHA1));
@@ -217,91 +221,16 @@ VerifyStreamContentDigest(nsIInputStream
 
   if (SECITEM_CompareItem(&digestFromManifest, &digest.get()) != SECEqual) {
     return NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY;
   }
 
   return NS_OK;
 }
 
-nsresult
-VerifyEntryContentDigest(nsIZipReader* zip, const nsACString& aFilename,
-                         const SECItem& digestFromManifest, SECItem& buf)
-{
-  nsCOMPtr<nsIInputStream> stream;
-  nsresult rv = zip->GetInputStream(aFilename, getter_AddRefs(stream));
-  if (NS_FAILED(rv)) {
-    return NS_ERROR_SIGNED_JAR_ENTRY_MISSING;
-  }
-
-  return VerifyStreamContentDigest(stream, digestFromManifest, buf);
-}
-
-// @oaram aDir       directory containing the unpacked signed archive
-// @param aFilename  path of the target file relative to aDir
-// @param digestFromManifest The digest that we're supposed to check the file's
-//                           contents against, from the manifest
-// @param buf A scratch buffer that we use for doing the I/O
-nsresult
-VerifyFileContentDigest(nsIFile* aDir, const nsAString& aFilename,
-                        const SECItem& digestFromManifest, SECItem& buf)
-{
-  // Find the file corresponding to the manifest path
-  nsCOMPtr<nsIFile> file;
-  nsresult rv = aDir->Clone(getter_AddRefs(file));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  // We don't know how to handle JARs with signed directory entries.
-  // It's technically possible in the manifest but makes no sense on disk.
-  // Inside an archive we just ignore them, but here we have to treat it
-  // as an error because the signed bytes never got unpacked.
-  int32_t pos = 0;
-  int32_t slash;
-  int32_t namelen = aFilename.Length();
-  if (namelen == 0 || aFilename[namelen - 1] == '/') {
-    return NS_ERROR_SIGNED_JAR_ENTRY_INVALID;
-  }
-
-  // Append path segments one by one
-  do {
-    slash = aFilename.FindChar('/', pos);
-    int32_t segend = (slash == kNotFound) ? namelen : slash;
-    rv = file->Append(Substring(aFilename, pos, (segend - pos)));
-    if (NS_FAILED(rv)) {
-      return NS_ERROR_SIGNED_JAR_ENTRY_INVALID;
-    }
-    pos = slash + 1;
-  }  while (pos < namelen && slash != kNotFound);
-
-  bool exists;
-  rv = file->Exists(&exists);
-  if (NS_FAILED(rv) || !exists) {
-    return NS_ERROR_SIGNED_JAR_ENTRY_MISSING;
-  }
-
-  bool isDir;
-  rv = file->IsDirectory(&isDir);
-  if (NS_FAILED(rv) || isDir) {
-    // We only support signed files, not directory entries
-    return NS_ERROR_SIGNED_JAR_ENTRY_INVALID;
-  }
-
-  // Open an input stream for that file and verify it.
-  nsCOMPtr<nsIInputStream> stream;
-  rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file, -1, -1,
-                                  nsIFileInputStream::CLOSE_ON_EOF);
-  if (NS_FAILED(rv) || !stream) {
-    return NS_ERROR_SIGNED_JAR_ENTRY_MISSING;
-  }
-
-  return VerifyStreamContentDigest(stream, digestFromManifest, buf);
-}
-
 // On input, nextLineStart is the start of the current line. On output,
 // nextLineStart is the start of the next line.
 nsresult
 ReadLine(/*in/out*/ const char* & nextLineStart, /*out*/ nsCString & line,
          bool allowContinuations = true)
 {
   line.Truncate();
   size_t previousLength = 0;
@@ -352,17 +281,16 @@ ReadLine(/*in/out*/ const char* & nextLi
     ++nextLineStart; // skip space and keep appending
   }
 }
 
 // The header strings are defined in the JAR specification.
 #define JAR_MF_SEARCH_STRING "(M|/M)ETA-INF/(M|m)(ANIFEST|anifest).(MF|mf)$"
 #define JAR_SF_SEARCH_STRING "(M|/M)ETA-INF/*.(SF|sf)$"
 #define JAR_RSA_SEARCH_STRING "(M|/M)ETA-INF/*.(RSA|rsa)$"
-#define JAR_META_DIR "META-INF"
 #define JAR_MF_HEADER "Manifest-Version: 1.0"
 #define JAR_SF_HEADER "Signature-Version: 1.0"
 
 nsresult
 ParseAttribute(const nsAutoCString & curLine,
                /*out*/ nsAutoCString & attrName,
                /*out*/ nsAutoCString & attrValue)
 {
@@ -1016,502 +944,8 @@ nsNSSCertificateDB::VerifySignedManifest
   NS_ENSURE_ARG_POINTER(aSignatureStream);
   NS_ENSURE_ARG_POINTER(aCallback);
 
   RefPtr<VerifySignedmanifestTask> task(
     new VerifySignedmanifestTask(aTrustedRoot, aManifestStream,
                                  aSignatureStream, aCallback));
   return task->Dispatch("SignedManifest");
 }
-
-
-//
-// Signature verification for archives unpacked into a file structure
-//
-
-// Finds the "*.rsa" signature file in the META-INF directory and returns
-// the name. It is an error if there are none or more than one .rsa file
-nsresult
-FindSignatureFilename(nsIFile* aMetaDir,
-                      /*out*/ nsAString& aFilename)
-{
-  nsCOMPtr<nsISimpleEnumerator> entries;
-  nsresult rv = aMetaDir->GetDirectoryEntries(getter_AddRefs(entries));
-  nsCOMPtr<nsIDirectoryEnumerator> files = do_QueryInterface(entries);
-  if (NS_FAILED(rv) || !files) {
-    return NS_ERROR_SIGNED_JAR_NOT_SIGNED;
-  }
-
-  bool found = false;
-  nsCOMPtr<nsIFile> file;
-  rv = files->GetNextFile(getter_AddRefs(file));
-
-  while (NS_SUCCEEDED(rv) && file) {
-    nsAutoString leafname;
-    rv = file->GetLeafName(leafname);
-    if (NS_SUCCEEDED(rv)) {
-      if (StringEndsWith(leafname, NS_LITERAL_STRING(".rsa"))) {
-        if (!found) {
-          found = true;
-          aFilename = leafname;
-        } else {
-          // second signature file is an error
-          rv = NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-          break;
-        }
-      }
-      rv = files->GetNextFile(getter_AddRefs(file));
-    }
-  }
-
-  if (!found) {
-    rv = NS_ERROR_SIGNED_JAR_NOT_SIGNED;
-  }
-
-  files->Close();
-  return rv;
-}
-
-// Loads the signature metadata file that matches the given filename in
-// the passed-in Meta-inf directory. If bufDigest is not null then on
-// success bufDigest will contain the SHA-1 digest of the entry.
-nsresult
-LoadOneMetafile(nsIFile* aMetaDir,
-                const nsAString& aFilename,
-                /*out*/ SECItem& aBuf,
-                /*optional, out*/ Digest* aBufDigest)
-{
-  nsCOMPtr<nsIFile> metafile;
-  nsresult rv = aMetaDir->Clone(getter_AddRefs(metafile));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = metafile->Append(aFilename);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  bool exists;
-  rv = metafile->Exists(&exists);
-  if (NS_FAILED(rv) || !exists) {
-    // we can call a missing .rsa file "unsigned" but FindSignatureFilename()
-    // already found one: missing other metadata files means a broken signature.
-    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-  }
-
-  nsCOMPtr<nsIInputStream> stream;
-  rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), metafile);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = ReadStream(stream, aBuf);
-  stream->Close();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (aBufDigest) {
-    rv = aBufDigest->DigestBuf(SEC_OID_SHA1, aBuf.data, aBuf.len - 1);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  return NS_OK;
-}
-
-// Parses MANIFEST.MF and verifies the contents of the unpacked files
-// listed in the manifest.
-// The filenames of all entries will be returned in aMfItems. aBuf must
-// be a pre-allocated scratch buffer that is used for doing I/O.
-nsresult
-ParseMFUnpacked(const char* aFilebuf, nsIFile* aDir,
-                /*out*/ nsTHashtable<nsStringHashKey>& aMfItems,
-                ScopedAutoSECItem& aBuf)
-{
-  nsresult rv;
-
-  const char* nextLineStart = aFilebuf;
-
-  rv = CheckManifestVersion(nextLineStart, NS_LITERAL_CSTRING(JAR_MF_HEADER));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  // Skip the rest of the header section, which ends with a blank line.
-  {
-    nsAutoCString line;
-    do {
-      rv = ReadLine(nextLineStart, line);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-    } while (line.Length() > 0);
-
-    // Manifest containing no file entries is OK, though useless.
-    if (*nextLineStart == '\0') {
-      return NS_OK;
-    }
-  }
-
-  nsAutoString curItemName;
-  ScopedAutoSECItem digest;
-
-  for (;;) {
-    nsAutoCString curLine;
-    rv = ReadLine(nextLineStart, curLine);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-
-    if (curLine.Length() == 0) {
-      // end of section (blank line or end-of-file)
-
-      if (curItemName.Length() == 0) {
-        // '...Each section must start with an attribute with the name as
-        // "Name",...', so every section must have a Name attribute.
-        return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-      }
-
-      if (digest.len == 0) {
-        // We require every entry to have a digest, since we require every
-        // entry to be signed and we don't allow duplicate entries.
-        return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-      }
-
-      if (aMfItems.Contains(curItemName)) {
-        // Duplicate entry
-        return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-      }
-
-      // Verify that the file's content digest matches the digest from this
-      // MF section.
-      rv = VerifyFileContentDigest(aDir, curItemName, digest, aBuf);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      aMfItems.PutEntry(curItemName);
-
-      if (*nextLineStart == '\0') {
-        // end-of-file
-        break;
-      }
-
-      // reset so we know we haven't encountered either of these for the next
-      // item yet.
-      curItemName.Truncate();
-      digest.reset();
-
-      continue; // skip the rest of the loop below
-    }
-
-    nsAutoCString attrName;
-    nsAutoCString attrValue;
-    rv = ParseAttribute(curLine, attrName, attrValue);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-
-    // Lines to look for:
-
-    // (1) Digest:
-    if (attrName.LowerCaseEqualsLiteral("sha1-digest")) {
-      if (digest.len > 0) {
-        // multiple SHA1 digests in section
-        return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-      }
-
-      rv = MapSECStatus(ATOB_ConvertAsciiToItem(&digest, attrValue.get()));
-      if (NS_FAILED(rv)) {
-        return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-      }
-
-      continue;
-    }
-
-    // (2) Name: associates this manifest section with a file in the jar.
-    if (attrName.LowerCaseEqualsLiteral("name")) {
-      if (MOZ_UNLIKELY(curItemName.Length() > 0)) {
-        // multiple names in section
-        return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-      }
-
-      if (MOZ_UNLIKELY(attrValue.Length() == 0)) {
-        return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-      }
-
-      curItemName = NS_ConvertUTF8toUTF16(attrValue);
-
-      continue;
-    }
-
-    // (3) Magic: the only other must-understand attribute
-    if (attrName.LowerCaseEqualsLiteral("magic")) {
-      // We don't understand any magic, so we can't verify an entry that
-      // requires magic. Since we require every entry to have a valid
-      // signature, we have no choice but to reject the entry.
-      return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-    }
-
-    // unrecognized attributes must be ignored
-  }
-
-  return NS_OK;
-}
-
-// recursively check a directory tree for files not in the list of
-// verified files we found in the manifest. For each file we find
-// Check it against the files found in the manifest. If the file wasn't
-// in the manifest then it's unsigned and we can stop looking. Otherwise
-// remove it from the collection so we can check leftovers later.
-//
-// @param aDir   Directory to check
-// @param aPath  Relative path to that directory (to check against aItems)
-// @param aItems All the files found
-// @param *Filename  signature files that won't be in the manifest
-nsresult
-CheckDirForUnsignedFiles(nsIFile* aDir,
-                         const nsString& aPath,
-                         /* in/out */ nsTHashtable<nsStringHashKey>& aItems,
-                         const nsAString& sigFilename,
-                         const nsAString& sfFilename,
-                         const nsAString& mfFilename)
-{
-  nsCOMPtr<nsISimpleEnumerator> entries;
-  nsresult rv = aDir->GetDirectoryEntries(getter_AddRefs(entries));
-  nsCOMPtr<nsIDirectoryEnumerator> files = do_QueryInterface(entries);
-  if (NS_FAILED(rv) || !files) {
-    return NS_ERROR_SIGNED_JAR_ENTRY_MISSING;
-  }
-
-  bool inMeta = StringBeginsWith(aPath, NS_LITERAL_STRING(JAR_META_DIR));
-
-  while (NS_SUCCEEDED(rv)) {
-    nsCOMPtr<nsIFile> file;
-    rv = files->GetNextFile(getter_AddRefs(file));
-    if (NS_FAILED(rv) || !file) {
-      break;
-    }
-
-    nsAutoString leafname;
-    rv = file->GetLeafName(leafname);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-
-    nsAutoString curName(aPath + leafname);
-
-    bool isDir;
-    rv = file->IsDirectory(&isDir);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-
-    // if it's a directory we need to recurse
-    if (isDir) {
-      curName.Append(NS_LITERAL_STRING("/"));
-      rv = CheckDirForUnsignedFiles(file, curName, aItems,
-                                    sigFilename, sfFilename, mfFilename);
-    } else {
-      // The files that comprise the signature mechanism are not covered by the
-      // signature.
-      //
-      // XXX: This is OK for a single signature, but doesn't work for
-      // multiple signatures because the metadata for the other signatures
-      // is not signed either.
-      if (inMeta && ( leafname == sigFilename ||
-                      leafname == sfFilename ||
-                      leafname == mfFilename )) {
-        continue;
-      }
-
-      // make sure the current file was found in the manifest
-      nsStringHashKey* item = aItems.GetEntry(curName);
-      if (!item) {
-        return NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY;
-      }
-
-      // Remove the item so we can check for leftover items later
-      aItems.RemoveEntry(curName);
-    }
-  }
-  files->Close();
-  return rv;
-}
-
-/*
- * Verify the signature of a directory structure as if it were a
- * signed JAR file (used for unpacked JARs)
- */
-nsresult
-VerifySignedDirectory(AppTrustedRoot aTrustedRoot,
-                      nsIFile* aDirectory,
-                      /*out, optional */ nsIX509Cert** aSignerCert)
-{
-  NS_ENSURE_ARG_POINTER(aDirectory);
-
-  if (aSignerCert) {
-    *aSignerCert = nullptr;
-  }
-
-  // Make sure there's a META-INF directory
-
-  nsCOMPtr<nsIFile> metaDir;
-  nsresult rv = aDirectory->Clone(getter_AddRefs(metaDir));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  rv = metaDir->Append(NS_LITERAL_STRING(JAR_META_DIR));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  bool exists;
-  rv = metaDir->Exists(&exists);
-  if (NS_FAILED(rv) || !exists) {
-    return NS_ERROR_SIGNED_JAR_NOT_SIGNED;
-  }
-  bool isDirectory;
-  rv = metaDir->IsDirectory(&isDirectory);
-  if (NS_FAILED(rv) || !isDirectory) {
-    return NS_ERROR_SIGNED_JAR_NOT_SIGNED;
-  }
-
-  // Find and load the Signature (RSA) file
-
-  nsAutoString sigFilename;
-  rv = FindSignatureFilename(metaDir, sigFilename);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  ScopedAutoSECItem sigBuffer;
-  rv = LoadOneMetafile(metaDir, sigFilename, sigBuffer, nullptr);
-  if (NS_FAILED(rv)) {
-    return NS_ERROR_SIGNED_JAR_NOT_SIGNED;
-  }
-
-  // Load the signature (SF) file and verify the signature.
-  // The .sf and .rsa files must have the same name apart from the extension.
-
-  nsAutoString sfFilename(Substring(sigFilename, 0, sigFilename.Length() - 3)
-                          + NS_LITERAL_STRING("sf"));
-
-  ScopedAutoSECItem sfBuffer;
-  Digest sfCalculatedDigest;
-  rv = LoadOneMetafile(metaDir, sfFilename, sfBuffer, &sfCalculatedDigest);
-  if (NS_FAILED(rv)) {
-    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-  }
-
-  sigBuffer.type = siBuffer;
-  ScopedCERTCertList builtChain;
-  rv = VerifySignature(aTrustedRoot, sigBuffer, sfCalculatedDigest.get(),
-                       builtChain);
-  if (NS_FAILED(rv)) {
-    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-  }
-
-  // Get the expected manifest hash from the signed .sf file
-
-  ScopedAutoSECItem mfDigest;
-  rv = ParseSF(char_ptr_cast(sfBuffer.data), mfDigest);
-  if (NS_FAILED(rv)) {
-    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-  }
-
-  // Load manifest (MF) file and verify signature
-
-  nsAutoString mfFilename(NS_LITERAL_STRING("manifest.mf"));
-  ScopedAutoSECItem manifestBuffer;
-  Digest mfCalculatedDigest;
-  rv = LoadOneMetafile(metaDir, mfFilename, manifestBuffer, &mfCalculatedDigest);
-  if (NS_FAILED(rv)) {
-    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-  }
-
-  if (SECITEM_CompareItem(&mfDigest, &mfCalculatedDigest.get()) != SECEqual) {
-    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-  }
-
-  // Parse manifest and verify signed hash of all listed files
-
-  // Allocate the I/O buffer only once per JAR, instead of once per entry, in
-  // order to minimize malloc/free calls and in order to avoid fragmenting
-  // memory.
-  ScopedAutoSECItem buf(128 * 1024);
-
-  nsTHashtable<nsStringHashKey> items;
-  rv = ParseMFUnpacked(char_ptr_cast(manifestBuffer.data),
-                       aDirectory, items, buf);
-  if (NS_FAILED(rv)){
-    return rv;
-  }
-
-  // We've checked that everything listed in the manifest exists and is signed
-  // correctly. Now check on disk for extra (unsigned) files.
-  // Deletes found entries from items as it goes.
-  rv = CheckDirForUnsignedFiles(aDirectory, EmptyString(), items,
-                                sigFilename, sfFilename, mfFilename);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  // We verified that every entry that we require to be signed is signed. But,
-  // were there any missing entries--that is, entries that are mentioned in the
-  // manifest but missing from the directory tree? (There shouldn't be given
-  // ParseMFUnpacked() checking them all, but it's a cheap sanity check.)
-  if (items.Count() != 0) {
-    return NS_ERROR_SIGNED_JAR_ENTRY_MISSING;
-  }
-
-  // Return the signer's certificate to the reader if they want it.
-  // XXX: We should return an nsIX509CertList with the whole validated chain.
-  if (aSignerCert) {
-    MOZ_ASSERT(CERT_LIST_HEAD(builtChain));
-    nsCOMPtr<nsIX509Cert> signerCert =
-      nsNSSCertificate::Create(CERT_LIST_HEAD(builtChain)->cert);
-    NS_ENSURE_TRUE(signerCert, NS_ERROR_OUT_OF_MEMORY);
-    signerCert.forget(aSignerCert);
-  }
-
-  return NS_OK;
-}
-
-class VerifySignedDirectoryTask final : public CryptoTask
-{
-public:
-  VerifySignedDirectoryTask(AppTrustedRoot aTrustedRoot, nsIFile* aUnpackedJar,
-                            nsIVerifySignedDirectoryCallback* aCallback)
-    : mTrustedRoot(aTrustedRoot)
-    , mDirectory(aUnpackedJar)
-    , mCallback(new nsMainThreadPtrHolder<nsIVerifySignedDirectoryCallback>(aCallback))
-  {
-  }
-
-private:
-  virtual nsresult CalculateResult() override
-  {
-    return VerifySignedDirectory(mTrustedRoot,
-                                 mDirectory,
-                                 getter_AddRefs(mSignerCert));
-  }
-
-  // This class doesn't directly hold NSS resources so there's nothing that
-  // needs to be released
-  virtual void ReleaseNSSResources() override { }
-
-  virtual void CallCallback(nsresult rv) override
-  {
-    (void) mCallback->VerifySignedDirectoryFinished(rv, mSignerCert);
-  }
-
-  const AppTrustedRoot mTrustedRoot;
-  const nsCOMPtr<nsIFile> mDirectory;
-  nsMainThreadPtrHandle<nsIVerifySignedDirectoryCallback> mCallback;
-  nsCOMPtr<nsIX509Cert> mSignerCert; // out
-};
-
-NS_IMETHODIMP
-nsNSSCertificateDB::VerifySignedDirectoryAsync(
-  AppTrustedRoot aTrustedRoot, nsIFile* aUnpackedJar,
-  nsIVerifySignedDirectoryCallback* aCallback)
-{
-  NS_ENSURE_ARG_POINTER(aUnpackedJar);
-  NS_ENSURE_ARG_POINTER(aCallback);
-  RefPtr<VerifySignedDirectoryTask> task(new VerifySignedDirectoryTask(aTrustedRoot,
-                                                                       aUnpackedJar,
-                                                                       aCallback));
-  return task->Dispatch("UnpackedJar");
-}
--- a/security/manager/ssl/public/nsIX509CertDB.idl
+++ b/security/manager/ssl/public/nsIX509CertDB.idl
@@ -23,35 +23,28 @@ typedef uint32_t AppTrustedRoot;
 [scriptable, function, uuid(fc2b60e5-9a07-47c2-a2cd-b83b68a660ac)]
 interface nsIOpenSignedAppFileCallback : nsISupports
 {
   void openSignedAppFileFinished(in nsresult rv,
                                  in nsIZipReader aZipReader,
                                  in nsIX509Cert aSignerCert);
 };
 
-[scriptable, function, uuid(d5f97827-622a-488f-be08-d850432ac8ec)]
-interface nsIVerifySignedDirectoryCallback : nsISupports
-{
-  void verifySignedDirectoryFinished(in nsresult rv,
-                                     in nsIX509Cert aSignerCert);
-};
-
 [scriptable, function, uuid(3d6a9c87-5c5f-46fc-9410-96da6092f0f2)]
 interface nsIVerifySignedManifestCallback : nsISupports
 {
   void verifySignedManifestFinished(in nsresult rv,
                                     in nsIX509Cert aSignerCert);
 };
 
 /**
  * This represents a service to access and manipulate
  * X.509 certificates stored in a database.
  */
-[scriptable, uuid(6d27211b-7119-4777-9c62-f29310eeb262)]
+[scriptable, uuid(560bc9ac-3e71-472e-9b08-2270d0c71878)]
 interface nsIX509CertDB : nsISupports {
 
   /**
    *  Constants that define which usages a certificate
    *  is trusted for.
    */
   const unsigned long UNTRUSTED       =      0;
   const unsigned long TRUSTED_SSL     = 1 << 0;
@@ -320,32 +313,16 @@ interface nsIX509CertDB : nsISupports {
   const AppTrustedRoot TrustedHostedAppTestRoot = 8;
   const AppTrustedRoot AddonsPublicRoot = 9;
   const AppTrustedRoot AddonsStageRoot = 10;
   void openSignedAppFileAsync(in AppTrustedRoot trustedRoot,
                               in nsIFile aJarFile,
                               in nsIOpenSignedAppFileCallback callback);
 
   /**
-   *  Verifies the signature on a directory representing an unpacked signed
-   *  JAR file. To be considered valid, there must be exactly one signature
-   *  on the directory structure and that signature must have signed every
-   *  entry. Further, the signature must come from a certificate that
-   *  is trusted for code signing.
-   *
-   *  On success NS_OK and the trusted certificate that signed the
-   *  unpacked JAR are returned.
-   *
-   *  On failure, an error code is returned.
-   */
-  void verifySignedDirectoryAsync(in AppTrustedRoot trustedRoot,
-                                  in nsIFile aUnpackedDir,
-                                  in nsIVerifySignedDirectoryCallback callback);
-
-  /**
    * Given streams containing a signature and a manifest file, verifies
    * that the signature is valid for the manifest. The signature must
    * come from a certificate that is trusted for code signing and that
    * was issued by the given trusted root.
    *
    *  On success, NS_OK and the trusted certificate that signed the
    *  Manifest are returned.
    *
deleted file mode 100644
index c212c70eebb9e42088dd22e556964489667698f0..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
--- a/security/manager/ssl/tests/unit/test_signed_dir.js
+++ /dev/null
@@ -1,173 +0,0 @@
-"use strict";
-
-Components.utils.import("resource://gre/modules/ZipUtils.jsm");
-
-do_get_profile(); // must be called before getting nsIX509CertDB
-const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(Ci.nsIX509CertDB);
-
-var gSignedXPI = do_get_file("test_signed_apps/sslcontrol.xpi", false);
-var gTarget = FileUtils.getDir("TmpD", ["test_signed_dir"]);
-gTarget.createUnique(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
-
-
-// tamper data structure, each element is optional
-// { copy:    [[path,newname], [path2,newname2], ...],
-//   delete:  [path, path2, ...],
-//   corrupt: [path, path2, ...]
-// }
-
-function prepare(tamper) {
-  ZipUtils.extractFiles(gSignedXPI, gTarget);
-
-  // copy files
-  if (tamper.copy) {
-    tamper.copy.forEach(i => {
-      let f = gTarget.clone();
-      i[0].split('/').forEach(seg => {f.append(seg);});
-      f.copyTo(null, i[1]);
-    });
-  }
-
-  // delete files
-  if (tamper.delete) {
-    tamper.delete.forEach(i => {
-      let f = gTarget.clone();
-      i.split('/').forEach(seg => {f.append(seg);});
-      f.remove(true);
-    });
-  }
-
-  // corrupt files
-  if (tamper.corrupt) {
-    tamper.corrupt.forEach(i => {
-      let f = gTarget.clone();
-      i.split('/').forEach(seg => {f.append(seg);});
-      let s = FileUtils.openFileOutputStream(f, FileUtils.MODE_WRONLY);
-      const str = "Kilroy was here";
-      s.write(str, str.length);
-      s.close();
-    });
-  }
-
-  return gTarget;
-}
-
-
-function check_result(name, expectedRv, dir) {
-  return function verifySignedDirCallback(rv, aSignerCert) {
-    equal(rv, expectedRv, name + " rv:");
-    equal(aSignerCert != null, Components.isSuccessCode(expectedRv),
-          "expecting certificate:");
-    // cleanup and kick off next test
-    dir.remove(true);
-    run_next_test();
-  };
-}
-
-function verifyDirAsync(name, expectedRv, tamper) {
-  let targetDir = prepare(tamper);
-  certdb.verifySignedDirectoryAsync(
-    Ci.nsIX509CertDB.AddonsPublicRoot, targetDir,
-    check_result(name, expectedRv, targetDir));
-}
-
-
-//
-// the tests
-//
-
-add_test(function() {
-  verifyDirAsync("'valid'", Cr.NS_OK, {} /* no tampering */ );
-});
-
-add_test(function() {
-  verifyDirAsync("'no meta dir'", Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED,
-                 {delete: ["META-INF"]});
-});
-
-add_test(function() {
-  verifyDirAsync("'empty meta dir'", Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED,
-                 {delete: ["META-INF/mozilla.rsa",
-                           "META-INF/mozilla.sf",
-                           "META-INF/manifest.mf"]});
-});
-
-add_test(function() {
-  verifyDirAsync("'two rsa files'", Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID,
-                 {copy: [["META-INF/mozilla.rsa","extra.rsa"]]});
-});
-
-add_test(function() {
-  verifyDirAsync("'corrupt rsa file'", Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID,
-                 {corrupt: ["META-INF/mozilla.rsa"]});
-});
-
-add_test(function() {
-  verifyDirAsync("'missing sf file'", Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID,
-                 {delete: ["META-INF/mozilla.sf"]});
-});
-
-add_test(function() {
-  verifyDirAsync("'corrupt sf file'", Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID,
-                 {corrupt: ["META-INF/mozilla.sf"]});
-});
-
-add_test(function() {
-  verifyDirAsync("'extra .sf file (invalid)'", Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY,
-                 {copy: [["META-INF/mozilla.rsa","extra.sf"]]});
-});
-
-add_test(function() {
-  verifyDirAsync("'extra .sf file (valid)'", Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY,
-                 {copy: [["META-INF/mozilla.sf","extra.sf"]]});
-});
-
-add_test(function() {
-  verifyDirAsync("'missing manifest'", Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID,
-                 {delete: ["META-INF/manifest.mf"]});
-});
-
-add_test(function() {
-  verifyDirAsync("'corrupt manifest'", Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID,
-                 {corrupt: ["META-INF/manifest.mf"]});
-});
-
-add_test(function() {
-  verifyDirAsync("'missing file'", Cr.NS_ERROR_SIGNED_JAR_ENTRY_MISSING,
-                 {delete: ["bootstrap.js"]});
-});
-
-add_test(function() {
-  verifyDirAsync("'corrupt file'", Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY,
-                 {corrupt: ["bootstrap.js"]});
-});
-
-add_test(function() {
-  verifyDirAsync("'extra file'", Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY,
-                 {copy: [["bootstrap.js","extra"]]});
-});
-
-add_test(function() {
-  verifyDirAsync("'missing file in dir'", Cr.NS_ERROR_SIGNED_JAR_ENTRY_MISSING,
-                 {delete: ["content/options.xul"]});
-});
-
-add_test(function() {
-  verifyDirAsync("'corrupt file in dir'", Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY,
-                 {corrupt: ["content/options.xul"]});
-});
-
-add_test(function() {
-  verifyDirAsync("'extra file in dir'", Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY,
-                 {copy: [["content/options.xul","extra"]]});
-});
-
-do_register_cleanup(function() {
-  if (gTarget.exists()) {
-    gTarget.remove(true);
-  }
-});
-
-function run_test() {
-  run_next_test();
-}
\ No newline at end of file
--- a/security/manager/ssl/tests/unit/xpcshell.ini
+++ b/security/manager/ssl/tests/unit/xpcshell.ini
@@ -65,17 +65,16 @@ run-sequentially = hardcoded ports
 [test_cert_overrides.js]
 run-sequentially = hardcoded ports
 [test_intermediate_basic_usage_constraints.js]
 [test_name_constraints.js]
 [test_cert_trust.js]
 [test_cert_version.js]
 [test_signed_apps.js]
 [test_signed_apps-marketplace.js]
-[test_signed_dir.js]
 
 [test_cert_eku-CA_EP.js]
 [test_cert_eku-CA_EP_NS_OS_SA_TS.js]
 [test_cert_eku-CA.js]
 [test_cert_eku-CA_NS.js]
 [test_cert_eku-CA_OS.js]
 [test_cert_eku-CA_SA.js]
 [test_cert_eku-CA_TS.js]