Bug 853776, Part 2: Remove the SEC_PKCS7VerifyDetachedSignatureAtTime patch to NSS and replace the code that called it with a stub tha always fails, r=honzab, a=bbajaj
authorBrian Smith <bsmith@mozilla.com>
Sun, 31 Mar 2013 11:53:37 -0700
changeset 132523 e39e3947febb8327271f0b78e39cb8db7700b51a
parent 132522 7ba9d5f19980852268b35904b1fdac0b0521ff4c
child 132524 28ff0e110387aa0d6b4855f23f87bcf0200e6c4b
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershonzab, bbajaj
bugs853776
milestone21.0a2
Bug 853776, Part 2: Remove the SEC_PKCS7VerifyDetachedSignatureAtTime patch to NSS and replace the code that called it with a stub tha always fails, r=honzab, a=bbajaj
security/coreconf/coreconf.dep
security/manager/ssl/src/JARSignatureVerification.cpp
security/manager/ssl/tests/unit/test_signed_apps.js
security/manager/ssl/tests/unit/test_signed_apps/generate.sh
security/manager/ssl/tests/unit/test_signed_apps/nss_ctypes.py
security/manager/ssl/tests/unit/test_signed_apps/sign_b2g_app.py
security/manager/ssl/tests/unit/test_signed_apps/simple/icon-128.png
security/manager/ssl/tests/unit/test_signed_apps/simple/index.html
security/manager/ssl/tests/unit/test_signed_apps/simple/manifest.webapp
security/manager/ssl/tests/unit/test_signed_apps/trusted_ca1.der
security/manager/ssl/tests/unit/test_signed_apps/unknown_issuer.zip
security/manager/ssl/tests/unit/test_signed_apps/unsigned.zip
security/manager/ssl/tests/unit/test_signed_apps/untrusted/examplla-app-signing-root-ca-1.der
security/manager/ssl/tests/unit/test_signed_apps/valid.zip
security/manager/ssl/tests/unit/xpcshell.ini
security/nss/lib/pkcs7/p7decode.c
security/nss/lib/pkcs7/secpkcs7.h
security/nss/lib/smime/smime.def
security/patches/README
security/patches/bug-834091.patch
--- a/security/coreconf/coreconf.dep
+++ b/security/coreconf/coreconf.dep
@@ -5,9 +5,8 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
-
--- a/security/manager/ssl/src/JARSignatureVerification.cpp
+++ b/security/manager/ssl/src/JARSignatureVerification.cpp
@@ -1,767 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifdef MOZ_LOGGING
-#define FORCE_PR_LOG 1
-#endif
-
 #include "nsNSSCertificateDB.h"
 
-#include "mozilla/RefPtr.h"
-#include "CryptoTask.h"
-#include "nsComponentManagerUtils.h"
-#include "nsCOMPtr.h"
-#include "nsHashKeys.h"
-#include "nsIFile.h"
-#include "nsIInputStream.h"
-#include "nsIStringEnumerator.h"
-#include "nsIZipReader.h"
-#include "nsNSSCertificate.h"
-#include "nsString.h"
-#include "nsTHashtable.h"
-#include "ScopedNSSTypes.h"
-
-#include "base64.h"
-#include "secmime.h"
-#include "plstr.h"
-#include "prlog.h"
-
-using namespace mozilla;
-
-#ifdef MOZ_LOGGING
-extern PRLogModuleInfo* gPIPNSSLog;
-#endif
-
-namespace {
-
-// 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,
-                    /*optional, out*/ Digest * bufDigest)
-{
-  nsCOMPtr<nsIUTF8StringEnumerator> files;
-  nsresult rv = zip->FindEntries(searchPattern, getter_AddRefs(files));
-  if (NS_FAILED(rv) || !files) {
-    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-  }
-
-  bool more;
-  rv = files->HasMore(&more);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (!more) {
-    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-  }
-
-  rv = files->GetNext(filename);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Check if there is more than one match, if so then error!
-  rv = files->HasMore(&more);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (more) {
-    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-  }
-
-  nsCOMPtr<nsIInputStream> stream;
-  rv = zip->GetInputStream(filename, getter_AddRefs(stream));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // The size returned by Available() might be inaccurate so we need to check
-  // that Available() matches up with the actual length of the file.
-  uint64_t len64;
-  rv = stream->Available(&len64);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-
-  // Cap the maximum accepted size of signature-related files at 1MB (which is
-  // still crazily huge) to avoid OOM. The uncompressed length of an entry can be
-  // hundreds of times larger than the compressed version, especially if
-  // someone has speifically crafted the entry to cause OOM or to consume
-  // massive amounts of disk space.
-  //
-  // Also, keep in mind bug 164695 and that we must leave room for
-  // null-terminating the buffer.
-  static const uint32_t MAX_LENGTH = 1024 * 1024;
-  MOZ_STATIC_ASSERT(MAX_LENGTH < UINT32_MAX, "MAX_LENGTH < UINT32_MAX");
-  NS_ENSURE_TRUE(len64 < MAX_LENGTH, NS_ERROR_FILE_CORRUPTED);
-  NS_ENSURE_TRUE(len64 < UINT32_MAX, NS_ERROR_FILE_CORRUPTED); // bug 164695
-  SECITEM_AllocItem(buf, static_cast<uint32_t>(len64 + 1));
-
-  // buf.len == len64 + 1. We attempt to read len64 + 1 bytes instead of len64,
-  // so that we can check whether the metadata in the ZIP for the entry is
-  // incorrect.
-  uint32_t bytesRead;
-  rv = stream->Read(char_ptr_cast(buf.data), buf.len, &bytesRead);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (bytesRead != len64) {
-    return NS_ERROR_SIGNED_JAR_ENTRY_INVALID;
-  }
-
-  buf.data[buf.len - 1] = 0; // null-terminate
-
-  if (bufDigest) {
-    rv = bufDigest->DigestBuf(SEC_OID_SHA1, buf.data, buf.len - 1);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  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 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
-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));
-  if (!digestContext) {
-    return PRErrorCode_to_nsresult(PR_GetError());
-  }
-
-  rv = MapSECStatus(PK11_DigestBegin(digestContext));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  uint64_t totalBytesRead = 0;
-  for (;;) {
-    uint32_t bytesRead;
-    rv = stream->Read(char_ptr_cast(buf.data), buf.len, &bytesRead);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (bytesRead == 0) {
-      break; // EOF
-    }
-
-    totalBytesRead += bytesRead;
-    if (totalBytesRead >= UINT32_MAX) {
-      return NS_ERROR_SIGNED_JAR_ENTRY_TOO_LARGE;
-    }
-
-    rv = MapSECStatus(PK11_DigestOp(digestContext, buf.data, bytesRead));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  if (totalBytesRead != len64) {
-    // The metadata we used for Available() doesn't match the actual size of
-    // the entry.
-    return NS_ERROR_SIGNED_JAR_ENTRY_INVALID;
-  }
-
-  // Verify that the digests match.
-  Digest digest;
-  rv = digest.End(SEC_OID_SHA1, digestContext);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (SECITEM_CompareItem(&digestFromManifest, &digest.get()) != SECEqual) {
-    return NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY;
-  }
-
-  return NS_OK;
-}
-
-// 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();
-  for (;;) {
-    const char* eol = PL_strpbrk(nextLineStart, "\r\n");
-
-    if (!eol) { // Reached end of file before newline
-      eol = nextLineStart + PL_strlen(nextLineStart);
-    }
-
-    line.Append(nextLineStart, eol - nextLineStart);
-
-    if (*eol == '\r') {
-      ++eol;
-    }
-    if (*eol == '\n') {
-      ++eol;
-    }
-
-    nextLineStart = eol;
-
-    if (*eol != ' ') {
-      // not a continuation
-      return NS_OK;
-    }
-
-    // continuation
-    if (!allowContinuations) {
-      return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-    }
-
-    ++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_MF_HEADER (const char*)"Manifest-Version: 1.0"
-#define JAR_SF_HEADER (const char*)"Signature-Version: 1.0"
-
-nsresult
-ParseAttribute(const nsAutoCString & curLine,
-               /*out*/ nsAutoCString & attrName,
-               /*out*/ nsAutoCString & attrValue)
-{
-  nsAutoCString::size_type len = curLine.Length();
-  if (len > 72) {
-    // The spec says "No line may be longer than 72 bytes (not characters)"
-    // in its UTF8-encoded form. This check also ensures that len < INT32_MAX,
-    // which is required below.
-    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-  }
-
-  // Find the colon that separates the name from the value.
-  int32_t colonPos = curLine.FindChar(':');
-  if (colonPos == kNotFound) {
-    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-  }
-
-  // set attrName to the name, skipping spaces between the name and colon
-  int32_t nameEnd = colonPos;
-  for (;;) {
-    if (nameEnd == 0) {
-      return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID; // colon with no name
-    }
-    if (curLine[nameEnd - 1] != ' ')
-      break;
-    --nameEnd;
-  }
-  curLine.Left(attrName, nameEnd);
-
-  // Set attrValue to the value, skipping spaces between the colon and the
-  // value. The value may be empty.
-  int32_t valueStart = colonPos + 1;
-  int32_t curLineLength = curLine.Length();
-  while (valueStart != curLineLength && curLine[valueStart] == ' ') {
-    ++valueStart;
-  }
-  curLine.Right(attrValue, curLineLength - valueStart);
-
-  return NS_OK;
-}
-
-// Parses the version line of the MF or SF header.
-nsresult
-CheckManifestVersion(const char* & nextLineStart,
-                     const nsACString & expectedHeader)
-{
-  // The JAR spec says: "Manifest-Version and Signature-Version must be first,
-  // and in exactly that case (so that they can be recognized easily as magic
-  // strings)."
-  nsAutoCString curLine;
-  nsresult rv = ReadLine(nextLineStart, curLine, false);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  if (!curLine.Equals(expectedHeader)) {
-    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-  }
-  return NS_OK;
-}
-
-// Parses a signature file (SF) as defined in the JDK 8 JAR Specification.
-//
-// The SF file *must* contain exactly one SHA1-Digest-Manifest attribute in
-// the main section. All other sections are ignored. This means that this will
-// NOT parse old-style signature files that have separate digests per entry.
-// The JDK8 x-Digest-Manifest variant is better because:
-//
-//   (1) It allows us to follow the principle that we should minimize the
-//       processing of data that we do before we verify its signature. In
-//       particular, with the x-Digest-Manifest style, we can verify the digest
-//       of MANIFEST.MF before we parse it, which prevents malicious JARs
-//       exploiting our MANIFEST.MF parser.
-//   (2) It is more time-efficient and space-efficient to have one
-//       x-Digest-Manifest instead of multiple x-Digest values.
-//
-// In order to get benefit (1), we do NOT implement the fallback to the older
-// mechanism as the spec requires/suggests. Also, for simplity's sake, we only
-// support exactly one SHA1-Digest-Manifest attribute, and no other
-// algorithms.
-//
-// filebuf must be null-terminated. On output, mfDigest will contain the
-// decoded value of SHA1-Digest-Manifest.
-nsresult
-ParseSF(const char* filebuf, /*out*/ SECItem & mfDigest)
-{
-  nsresult rv;
-
-  const char* nextLineStart = filebuf;
-  rv = CheckManifestVersion(nextLineStart, nsLiteralCString(JAR_SF_HEADER));
-  if (NS_FAILED(rv))
-    return rv;
-
-  // Find SHA1-Digest-Manifest
-  for (;;) {
-    nsAutoCString curLine;
-    rv = ReadLine(nextLineStart, curLine);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-
-    if (curLine.Length() == 0) {
-      // End of main section (blank line or end-of-file), and no
-      // SHA1-Digest-Manifest found.
-      return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-    }
-
-    nsAutoCString attrName;
-    nsAutoCString attrValue;
-    rv = ParseAttribute(curLine, attrName, attrValue);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-
-    if (attrName.LowerCaseEqualsLiteral("sha1-digest-manifest")) {
-      rv = MapSECStatus(ATOB_ConvertAsciiToItem(&mfDigest, attrValue.get()));
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      // There could be multiple SHA1-Digest-Manifest attributes, which
-      // would be an error, but it's better to just skip any erroneous
-      // duplicate entries rather than trying to detect them, because:
-      //
-      //   (1) It's simpler, and simpler generally means more secure
-      //   (2) An attacker can't make us accept a JAR we would otherwise
-      //       reject just by adding additional SHA1-Digest-Manifest
-      //       attributes.
-      break;
-    }
-
-    // ignore unrecognized attributes
-  }
-
-  return NS_OK;
-}
-
-// Parses MANIFEST.MF. The filenames of all entries will be returned in
-// mfItems. buf must be a pre-allocated scratch buffer that is used for doing
-// I/O.
-nsresult
-ParseMF(const char* filebuf, nsIZipReader * zip,
-        /*out*/ nsTHashtable<nsCStringHashKey> & mfItems,
-        ScopedAutoSECItem & buf)
-{
-  nsresult rv;
-
-  const char* nextLineStart = filebuf;
-
-  rv = CheckManifestVersion(nextLineStart, nsLiteralCString(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;
-    }
-  }
-
-  nsAutoCString curItemName;
-  ScopedAutoSECItem digest;
-
-  for (;;) {
-    nsAutoCString curLine;
-    rv = ReadLine(nextLineStart, curLine);
-    NS_ENSURE_SUCCESS(rv, 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 (mfItems.Contains(curItemName)) {
-        // Duplicate entry
-        return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-      }
-
-      // Verify that the entry's content digest matches the digest from this
-      // MF section.
-      rv = VerifyEntryContentDigest(zip, curItemName, digest, buf);
-      if (NS_FAILED(rv))
-        return rv;
-
-      mfItems.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 = 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;
-}
-
-// Callback functions for decoder. For now, use empty/default functions.
-void
-ContentCallback(void *arg, const char *buf, unsigned long len)
-{
-}
-PK11SymKey *
-GetDecryptKeyCallback(void *, SECAlgorithmID *)
-{
-  return nullptr;
-}
-PRBool
-DecryptionAllowedCallback(SECAlgorithmID *algid, PK11SymKey *bulkkey)
-{
-  return false;
-}
-void *
-GetPasswordKeyCallback(void *arg, void *handle)
-{
-  return nullptr;
-}
-
-NS_IMETHODIMP
-OpenSignedJARFile(nsIFile * aJarFile,
-                  /*out, optional */ nsIZipReader ** aZipReader,
-                  /*out, optional */ nsIX509Cert3 ** aSignerCert)
-{
-  NS_ENSURE_ARG_POINTER(aJarFile);
-
-  if (aZipReader) {
-    *aZipReader = nullptr;
-  }
-
-  if (aSignerCert) {
-    *aSignerCert = nullptr;
-  }
-
-  nsresult rv;
-
-  static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
-  nsCOMPtr<nsIZipReader> zip = do_CreateInstance(kZipReaderCID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = zip->Open(aJarFile);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Signature (RSA) file
-  nsAutoCString sigFilename;
-  ScopedAutoSECItem sigBuffer;
-  rv = FindAndLoadOneEntry(zip, nsLiteralCString(JAR_RSA_SEARCH_STRING),
-                           sigFilename, sigBuffer, nullptr);
-  if (NS_FAILED(rv)) {
-    return NS_ERROR_SIGNED_JAR_NOT_SIGNED;
-  }
-
-  sigBuffer.type = siBuffer;
-  ScopedSEC_PKCS7ContentInfo p7_info(SEC_PKCS7DecodeItem(&sigBuffer,
-                                        ContentCallback, nullptr,
-                                        GetPasswordKeyCallback, nullptr,
-                                        GetDecryptKeyCallback, nullptr,
-                                        DecryptionAllowedCallback));
-  if (!p7_info) {
-    PRErrorCode error = PR_GetError();
-    const char * errorName = PR_ErrorToName(error);
-    PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Failed to decode PKCS#7 item: %s",
-           errorName));
-    return PRErrorCode_to_nsresult(error);
-  }
-
-  // Signature (SF) file
-  nsAutoCString sfFilename;
-  ScopedAutoSECItem sfBuffer;
-  Digest sfCalculatedDigest;
-  rv = FindAndLoadOneEntry(zip, NS_LITERAL_CSTRING(JAR_SF_SEARCH_STRING),
-                           sfFilename, sfBuffer, &sfCalculatedDigest);
-  if (NS_FAILED(rv)) {
-    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-  }
-
-  // Verify that the signature file is a valid signature of the SF file
-  if (!SEC_PKCS7VerifyDetachedSignatureAtTime(p7_info, certUsageObjectSigner,
-                                              &sfCalculatedDigest.get(),
-                                              HASH_AlgSHA1, false, PR_Now())) {
-    PRErrorCode error = PR_GetError();
-    const char * errorName = PR_ErrorToName(error);
-    PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Failed to verify detached signature: %s",
-           errorName));
-    rv = PRErrorCode_to_nsresult(error);
-    return rv;
-  }
-
-  ScopedAutoSECItem mfDigest;
-  rv = ParseSF(char_ptr_cast(sfBuffer.data), mfDigest);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  // Manifest (MF) file
-  nsAutoCString mfFilename;
-  ScopedAutoSECItem manifestBuffer;
-  Digest mfCalculatedDigest;
-  rv = FindAndLoadOneEntry(zip, NS_LITERAL_CSTRING(JAR_MF_SEARCH_STRING),
-                           mfFilename, manifestBuffer, &mfCalculatedDigest);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  if (SECITEM_CompareItem(&mfDigest, &mfCalculatedDigest.get()) != SECEqual) {
-    return NS_ERROR_SIGNED_JAR_MANIFEST_INVALID;
-  }
-
-  // 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<nsCStringHashKey> items;
-  items.Init();
-
-  rv = ParseMF(char_ptr_cast(manifestBuffer.data), zip, items, buf);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  // Verify every entry in the file.
-  nsCOMPtr<nsIUTF8StringEnumerator> entries;
-  rv = zip->FindEntries(NS_LITERAL_CSTRING(""), getter_AddRefs(entries));
-  if (NS_SUCCEEDED(rv) && !entries) {
-    rv = NS_ERROR_UNEXPECTED;
-  }
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  for (;;) {
-    bool hasMore;
-    rv = entries->HasMore(&hasMore);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (!hasMore) {
-      break;
-    }
-
-    nsAutoCString entryFilename;
-    rv = entries->GetNext(entryFilename);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Verifying digests for %s",
-           entryFilename.get()));
-
-    // 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 (entryFilename == mfFilename ||
-        entryFilename == sfFilename ||
-        entryFilename == sigFilename) {
-      continue;
-    }
-
-    if (entryFilename.Length() == 0) {
-      return NS_ERROR_SIGNED_JAR_ENTRY_INVALID;
-    }
-
-    // Entries with names that end in "/" are directory entries, which are not
-    // signed.
-    //
-    // XXX: As long as we don't unpack the JAR into the filesystem, the "/"
-    // entries are harmless. But, it is not clear what the security
-    // implications of directory entries are if/when we were to unpackage the
-    // JAR into the filesystem.
-    if (entryFilename[entryFilename.Length() - 1] == '/') {
-      continue;
-    }
-
-    nsCStringHashKey * item = items.GetEntry(entryFilename);
-    if (!item) {
-      return NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY;
-    }
-
-    // Remove the item so we can check for leftover items later
-    items.RemoveEntry(entryFilename);
-  }
-
-  // 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 archive?
-  if (items.Count() != 0) {
-    return NS_ERROR_SIGNED_JAR_ENTRY_MISSING;
-  }
-
-  // Return the reader to the caller if they want it
-  if (aZipReader) {
-    zip.forget(aZipReader);
-  }
-
-  // Return the signer's certificate to the reader if they want it.
-  // XXX: We should return an nsIX509CertList with the whole validated chain,
-  //      but we can't do that until we switch to libpkix.
-  if (aSignerCert) {
-    CERTCertificate *rawSignerCert
-      = p7_info->content.signedData->signerInfos[0]->cert;
-    NS_ENSURE_TRUE(rawSignerCert, NS_ERROR_UNEXPECTED);
-
-    nsCOMPtr<nsIX509Cert3> signerCert = nsNSSCertificate::Create(rawSignerCert);
-    NS_ENSURE_TRUE(signerCert, NS_ERROR_OUT_OF_MEMORY);
-
-    signerCert.forget(aSignerCert);
-  }
-
-  return NS_OK;
-}
-
-class OpenSignedJARFileTask MOZ_FINAL : public CryptoTask
-{
-public:
-  OpenSignedJARFileTask(nsIFile * aJarFile,
-                        nsIOpenSignedJARFileCallback * aCallback)
-    : mJarFile(aJarFile)
-    , mCallback(aCallback)
-  {
-  }
-
-private:
-  virtual nsresult CalculateResult() MOZ_OVERRIDE
-  {
-    return OpenSignedJARFile(mJarFile, getter_AddRefs(mZipReader),
-                             getter_AddRefs(mSignerCert));
-  }
-
-  // nsNSSCertificate implements nsNSSShutdownObject, so there's nothing that
-  // needs to be released
-  virtual void ReleaseNSSResources() { }
-
-  virtual void CallCallback(nsresult rv)
-  {
-    (void) mCallback->OpenSignedJARFileFinished(rv, mZipReader, mSignerCert);
-  }
-
-  const nsCOMPtr<nsIFile> mJarFile;
-  const nsCOMPtr<nsIOpenSignedJARFileCallback> mCallback;
-  nsCOMPtr<nsIZipReader> mZipReader; // out
-  nsCOMPtr<nsIX509Cert3> mSignerCert; // out
-};
-
-} // unnamed namespace
-
+// This functionality was disabled on mozilla-aurora because the implementation
+// used an NSS function that will not be part of the NSS release that Aurora
+// will ship with.
 NS_IMETHODIMP
 nsNSSCertificateDB::OpenSignedJARFileAsync(
   nsIFile * aJarFile, nsIOpenSignedJARFileCallback * aCallback)
 {
-  NS_ENSURE_ARG_POINTER(aJarFile);
-  NS_ENSURE_ARG_POINTER(aCallback);
-  RefPtr<OpenSignedJARFileTask> task(new OpenSignedJARFileTask(aJarFile,
-                                                               aCallback));
-  return task->Dispatch("SignedJAR");
+  return NS_ERROR_NOT_IMPLEMENTED;
 }
deleted file mode 100644
--- a/security/manager/ssl/tests/unit/test_signed_apps.js
+++ /dev/null
@@ -1,254 +0,0 @@
-"use strict";
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
-var Cr = Components.results;
-
-/* To regenerate the certificates and apps for this test:
-
-        cd security/manager/ssl/tests/unit/test_signed_apps
-        PATH=$NSS/bin:$NSS/lib:$PATH ./generate.sh
-        cd ../../../../../..
-        make -C $OBJDIR/security/manager/ssl/tests
-    
-   $NSS is the path to NSS binaries and libraries built for the host platform. 
-   If you get error messages about "CertUtil" on Windows, then it means that
-   the Windows CertUtil.exe is ahead of the NSS certutil.exe in $PATH.
-    
-   Check in the generated files. These steps are not done as part of the build
-   because we do not want to add a build-time dependency on the OpenSSL or NSS
-   tools or libraries built for the host platform.
-*/
-
-// XXX from prio.h
-const PR_RDWR        = 0x04; 
-const PR_CREATE_FILE = 0x08;
-const PR_TRUNCATE    = 0x20;
-
-let tempScope = {};
-Cu.import("resource://gre/modules/NetUtil.jsm", tempScope);
-let NetUtil = tempScope.NetUtil;
-
-Cu.import("resource://gre/modules/FileUtils.jsm"); // XXX: tempScope?
-Cu.import("resource://gre/modules/Services.jsm");  // XXX: tempScope?
-
-do_get_profile(); // must be called before getting nsIX509CertDB
-const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(Ci.nsIX509CertDB);
-
-// Creates a new app package based in the inFilePath package, with a set of
-// modifications (including possibly deletions) applied to the existing entries,
-// and/or a set of new entries to be included.
-function tamper(inFilePath, outFilePath, modifications, newEntries) {
-  var writer = Cc["@mozilla.org/zipwriter;1"].createInstance(Ci.nsIZipWriter);
-  writer.open(outFilePath, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE);
-  try {
-    var reader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance(Ci.nsIZipReader);
-    reader.open(inFilePath);
-    try {
-      var entries = reader.findEntries("");
-      while (entries.hasMore()) {
-        var entryName = entries.getNext();
-        var inEntry = reader.getEntry(entryName);
-        var entryInput = reader.getInputStream(entryName);
-        try {
-          var f = modifications[entryName];
-          var outEntry, outEntryInput;
-          if (f) {
-            [outEntry, outEntryInput] = f(inEntry, entryInput);
-            delete modifications[entryName];
-          } else {
-            [outEntry, outEntryInput] = [inEntry, entryInput];
-          }
-          // if f does not want the input entry to be copied to the output entry
-          // at all (i.e. it wants it to be deleted), it will return null.
-          if (outEntryInput) {
-            try {
-              writer.addEntryStream(entryName,
-                                    outEntry.lastModifiedTime,
-                                    outEntry.compression,
-                                    outEntryInput,
-                                    false);
-            } finally {
-              if (entryInput != outEntryInput)
-                outEntryInput.close();
-            }
-          }
-        } finally {
-          entryInput.close();
-        }
-      }
-    } finally {
-      reader.close();
-    }
-    
-    // Any leftover modification means that we were expecting to modify an entry
-    // in the input file that wasn't there.
-    for(var name in modifications) {
-      if (modifications.hasOwnProperty(name)) {
-        throw "input file was missing expected entries: " + name;
-      }
-    }
-    
-    // Now, append any new entries to the end
-    newEntries.forEach(function(newEntry) {
-      var sis = Cc["@mozilla.org/io/string-input-stream;1"]
-                  .createInstance(Ci.nsIStringInputStream);
-      try {
-        sis.setData(newEntry.content, newEntry.content.length);
-        writer.addEntryStream(newEntry.name,
-                              new Date(),
-                              Ci.nsIZipWriter.COMPRESSION_BEST,
-                              sis,
-                              false);
-      } finally {
-        sis.close();
-      }
-    });
-  } finally {
-    writer.close();
-  }
-}
-
-function removeEntry(entry, entryInput) { return [null, null]; }
-
-function truncateEntry(entry, entryInput) {
-  if (entryInput.available() == 0)
-    throw "Truncating already-zero length entry will result in identical entry.";
-
-  var content = Cc["@mozilla.org/io/string-input-stream;1"]
-                  .createInstance(Ci.nsIStringInputStream);
-  content.data = "";
-
-  return [entry, content]
-}
-
-function readFile(file) {
-  let fstream = Cc["@mozilla.org/network/file-input-stream;1"]
-                  .createInstance(Ci.nsIFileInputStream);
-  fstream.init(file, -1, 0, 0);
-  let data = NetUtil.readInputStreamToString(fstream, fstream.available());
-  fstream.close();
-  return data;
-}
-
-function run_test() {
-  var root_cert_der = 
-    do_get_file("test_signed_apps/trusted_ca1.der", false);
-  var der = readFile(root_cert_der);
-  certdb.addCert(der, ",,CTu", "test-root");
-  run_next_test();
-}
-
-function check_open_result(name, expectedRv) {
-  return function openSignedJARFileCallback(rv, aZipReader, aSignerCert) {
-    do_print("openSignedJARFileCallback called for " + name);
-    do_check_eq(rv, expectedRv);
-    do_check_eq(aZipReader != null,  Components.isSuccessCode(expectedRv));
-    do_check_eq(aSignerCert != null, Components.isSuccessCode(expectedRv));
-    run_next_test();
-  };
-}
-
-function original_app_path(test_name) {
-  return do_get_file("test_signed_apps/" + test_name + ".zip", false);
-}
-
-function tampered_app_path(test_name) {
-  return FileUtils.getFile("TmpD", ["test_signed_app-" + test_name + ".zip"]);
-}
-
-add_test(function () {
-  certdb.openSignedJARFileAsync(original_app_path("valid"),
-                                check_open_result("valid", Cr.NS_OK));
-});
-
-add_test(function () {
-  certdb.openSignedJARFileAsync(original_app_path("unsigned"),
-             check_open_result("unsigned", Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED));
-});
-
-add_test(function () {
-  // XXX: NSS has many possible error codes for this, e.g.
-  // SEC_ERROR_UNTRUSTED_ISSUER and others are also reasonable. Future versions
-  // of NSS may return one of these alternate errors; in that case, we need to
-  // update this test.
-  //
-  // XXX (bug 812089): Cr.NS_ERROR_SEC_ERROR_UNKNOWN_ISSUER is undefined.
-  //
-  // XXX: Cannot use operator| instead of operator+ to combine bits because
-  // bit 31 trigger's JavaScript's crazy interpretation of the numbers as
-  // two's complement negative integers.
-  const NS_ERROR_SEC_ERROR_UNKNOWN_ISSUER = 0x80000000 /* unsigned (1 << 31) */
-                                          + (    (0x45 + 21) << 16)
-                                          + (-(-0x2000 + 13)      );
-  certdb.openSignedJARFileAsync(original_app_path("unknown_issuer"),
-    check_open_result("unknown_issuer",
-                      /*Cr.*/NS_ERROR_SEC_ERROR_UNKNOWN_ISSUER));
-});
-
-// Sanity check to ensure a no-op tampering gives a valid result
-add_test(function () {
-  var tampered = tampered_app_path("identity_tampering");
-  tamper(original_app_path("valid"), tampered, { }, []);
-  certdb.openSignedJARFileAsync(original_app_path("valid"),
-    check_open_result("identity_tampering", Cr.NS_OK));
-});
-
-add_test(function () {
-  var tampered = tampered_app_path("missing_rsa");
-  tamper(original_app_path("valid"), tampered, { "META-INF/A.RSA" : removeEntry }, []);
-  certdb.openSignedJARFileAsync(tampered,
-    check_open_result("missing_rsa", Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED));
-});
-
-add_test(function () {
-  var tampered = tampered_app_path("missing_sf");
-  tamper(original_app_path("valid"), tampered, { "META-INF/A.SF" : removeEntry }, []);
-  certdb.openSignedJARFileAsync(tampered,
-    check_open_result("missing_sf", Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID));
-});
-
-add_test(function () {
-  var tampered = tampered_app_path("missing_manifest_mf");
-  tamper(original_app_path("valid"), tampered, { "META-INF/MANIFEST.MF" : removeEntry }, []);
-  certdb.openSignedJARFileAsync(tampered,
-    check_open_result("missing_manifest_mf",
-                      Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID));
-});
-
-add_test(function () {
-  var tampered = tampered_app_path("missing_entry");
-  tamper(original_app_path("valid"), tampered, { "manifest.webapp" : removeEntry }, []);
-  certdb.openSignedJARFileAsync(tampered,
-      check_open_result("missing_entry", Cr.NS_ERROR_SIGNED_JAR_ENTRY_MISSING));
-});
-
-add_test(function () {
-  var tampered = tampered_app_path("truncated_entry");
-  tamper(original_app_path("valid"), tampered, { "manifest.webapp" : truncateEntry }, []);
-  certdb.openSignedJARFileAsync(tampered,
-    check_open_result("truncated_entry", Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY));
-});
-
-add_test(function () {
-  var tampered = tampered_app_path("unsigned_entry");
-  tamper(original_app_path("valid"), tampered, {},
-    [ { "name": "unsigned.txt", "content": "unsigned content!" } ]);
-  certdb.openSignedJARFileAsync(tampered,
-    check_open_result("unsigned_entry", Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY));
-});
-
-add_test(function () {
-  var tampered = tampered_app_path("unsigned_metainf_entry");
-  tamper(original_app_path("valid"), tampered, {},
-    [ { name: "META-INF/unsigned.txt", content: "unsigned content!" } ]);
-  certdb.openSignedJARFileAsync(tampered,
-    check_open_result("unsigned_metainf_entry",
-                      Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY));
-});
-
-// TODO: tampered MF, tampered SF
-// TODO: too-large MF, too-large RSA, too-large SF
-// TODO: MF and SF that end immediately after the last main header
-//       (no CR nor LF)
-// TODO: broken headers to exercise the parser
deleted file mode 100644
--- a/security/manager/ssl/tests/unit/test_signed_apps/generate.sh
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/bin/bash
-# Usage:
-# export NSS_PREFIX=<path to NSS tools> \
-# PATH=$NSS_PREFIX/bin:$NSS_PREFIX/lib:$PATH ./generate.sh
-
-set -e
-
-srcdir=$PWD
-tmpdir=$TMP/test_signed_apps
-noisefile=$tmpdir/noise
-passwordfile=$tmpdir/passwordfile
-ca_responses=$tmpdir/ca_responses
-ee_responses=$tmpdir/ee_responses
-
-replace_zip()
-{
-  zip=$1 # must be an absolute path
-  new_contents_dir=$2
-
-  rm -f $zip
-  oldpwd=$PWD
-  cd $new_contents_dir && zip -9 -o -r $zip *
-  cd $oldpwd
-}
-
-sign_app_with_new_cert()
-{
-  label=$1
-  unsigned_zip=$2
-  out_signed_zip=$3
-
-  # XXX: We cannot give the trusted and untrusted versions of the certs the same
-  # subject names because otherwise we'll run into
-  # SEC_ERROR_REUSED_ISSUER_AND_SERIAL.
-  org="O=Examplla Corporation,L=Mountain View,ST=CA,C=US"
-  ca_subj="CN=Examplla Root CA $label,OU=Examplla CA,$org"
-  ee_subj="CN=Examplla Marketplace App Signing $label,OU=Examplla Marketplace App Signing,$org"
-
-  db=$tmpdir/$label
-  mkdir -p $db
-  certutil -d $db -N -f $passwordfile
-  make_cert="certutil -d $db -f $passwordfile -S -v 480 -g 2048 -Z SHA256 \
-                      -z $noisefile -y 3 -2 --extKeyUsage critical,codeSigning"
-  $make_cert -n ca1        -m 1 -s "$ca_subj" \
-             --keyUsage critical,certSigning      -t ",,CTu" -x < $ca_responses
-  $make_cert -n ee1 -c ca1 -m 2 -s "$ee_subj" \
-             --keyUsage critical,digitalSignature -t ",,,"      < $ee_responses
-
-  # In case we want to inspect the generated certs
-  certutil -d $db -L -n ca1 -r -o $db/ca1.der
-  certutil -d $db -L -n ee1 -r -o $db/ee1.der
-
-  python sign_b2g_app.py -d $db -f $passwordfile -k ee1 -i $unsigned_zip -o $out_signed_zip
-}
-
-rm -Rf $tmpdir
-mkdir $tmpdir
-
-echo password1 > $passwordfile
-head --bytes 32 /dev/urandom > $noisefile
-
-# XXX: certutil cannot generate basic constraints without interactive prompts,
-#      so we need to build response files to answer its questions
-# XXX: certutil cannot generate AKI/SKI without interactive prompts so we just
-#      skip them.
-echo y >  $ca_responses # Is this a CA?
-echo >>   $ca_responses # Accept default path length constraint (no constraint)
-echo y >> $ca_responses # Is this a critical constraint?
-echo n >  $ee_responses # Is this a CA?
-echo >>   $ee_responses # Accept default path length constraint (no constraint)
-echo y >> $ee_responses # Is this a critical constraint?
-
-replace_zip $srcdir/unsigned.zip $srcdir/simple
-
-sign_app_with_new_cert trusted   $srcdir/unsigned.zip $srcdir/valid.zip
-sign_app_with_new_cert untrusted $srcdir/unsigned.zip $srcdir/unknown_issuer.zip
-certutil -d $tmpdir/trusted -f $passwordfile -L -n ca1 -r -o $srcdir/trusted_ca1.der
deleted file mode 100644
--- a/security/manager/ssl/tests/unit/test_signed_apps/nss_ctypes.py
+++ /dev/null
@@ -1,125 +0,0 @@
-from ctypes import *
-import os
-import sys
-
-if sys.platform == 'darwin':
-  libprefix = "lib"
-  libsuffix = ".dylib"
-elif os.name == 'posix':
-  libprefix = "lib"
-  libsuffix = ".so"
-else: # assume windows
-  libprefix = ""
-  libsuffix = ".dll"
-
-plc   = cdll.LoadLibrary(libprefix + "plc4"   + libsuffix)
-nspr  = cdll.LoadLibrary(libprefix + "nspr4"  + libsuffix)
-nss   = cdll.LoadLibrary(libprefix + "nss3"   + libsuffix)
-smime = cdll.LoadLibrary(libprefix + "smime3" + libsuffix)
-
-nspr.PR_GetError.argtypes = []
-nspr.PR_GetError.restype = c_int32
-nspr.PR_ErrorToName.argtypes = [c_int32]
-nspr.PR_ErrorToName.restype = c_char_p
-
-def raise_if_not_SECSuccess(rv):
-  SECSuccess = 0
-  if (rv != SECSuccess):
-    raise ValueError(nspr.PR_ErrorToName(nspr.PR_GetError()))
-
-def raise_if_NULL(p):
-  if not p:
-    raise ValueError(nspr.PR_ErrorToName(nspr.PR_GetError()))
-  return p
-
-PRBool = c_int
-SECStatus = c_int
-
-# from secoidt.h
-SEC_OID_SHA1 = 4
-
-# from certt.h
-certUsageObjectSigner = 6
-
-class SECItem(Structure):
-  _fields_ = [("type", c_int),
-              ("data", c_char_p),
-              ("len", c_uint)]
-
-nss.NSS_Init.argtypes = [c_char_p]
-nss.NSS_Init.restype = SECStatus
-def NSS_Init(db_dir):
-  nss.NSS_Init.argtypes = [c_char_p]
-  nss.NSS_Init.restype = SECStatus
-  raise_if_not_SECSuccess(nss.NSS_Init(db_dir))
-
-nss.NSS_Shutdown.argtypes = []
-nss.NSS_Shutdown.restype = SECStatus
-def NSS_Shutdown():
-  raise_if_not_SECSuccess(nss.NSS_Shutdown())
-
-PK11PasswordFunc = CFUNCTYPE(c_char_p, c_void_p, PRBool, c_char_p)
-
-# pass the result of this as the wincx parameter when a wincx is required
-nss.PK11_SetPasswordFunc.argtypes = [PK11PasswordFunc]
-nss.PK11_SetPasswordFunc.restype = None
-def SetPasswordContext(password):
-  def callback(slot, retry, arg):
-    return plc.PL_strdup(password)
-  wincx = PK11PasswordFunc(callback)
-  nss.PK11_SetPasswordFunc(wincx)
-  return wincx
-
-nss.CERT_GetDefaultCertDB.argtypes = []
-nss.CERT_GetDefaultCertDB.restype = c_void_p
-def CERT_GetDefaultCertDB():
-  return raise_if_NULL(nss.CERT_GetDefaultCertDB())
-
-nss.PK11_FindCertFromNickname.argtypes = [c_char_p, c_void_p]
-nss.PK11_FindCertFromNickname.restype = c_void_p
-def PK11_FindCertFromNickname(nickname, wincx):
-  return raise_if_NULL(nss.PK11_FindCertFromNickname(nickname, wincx))
-
-nss.CERT_DestroyCertificate.argtypes = [c_void_p]
-nss.CERT_DestroyCertificate.restype = None
-def CERT_DestroyCertificate(cert):
-  nss.CERT_DestroyCertificate(cert)
-
-smime.SEC_PKCS7CreateSignedData.argtypes = [c_void_p, c_int, c_void_p,
-                                            c_int, c_void_p,
-                                            c_void_p, c_void_p]
-smime.SEC_PKCS7CreateSignedData.restype = c_void_p
-def SEC_PKCS7CreateSignedData(cert, certusage, certdb, digestalg, digest, wincx):
-  item = SECItem(0,  c_char_p(digest), len(digest))
-  return raise_if_NULL(smime.SEC_PKCS7CreateSignedData(cert, certusage, certdb,
-                                                       digestalg,
-                                                       pointer(item),
-                                                       None, wincx))
-
-smime.SEC_PKCS7AddSigningTime.argtypes = [c_void_p]
-smime.SEC_PKCS7AddSigningTime.restype = SECStatus
-def SEC_PKCS7AddSigningTime(p7):
-  raise_if_not_SECSuccess(smime.SEC_PKCS7AddSigningTime(p7))
-
-smime.SEC_PKCS7IncludeCertChain.argtypes = [c_void_p, c_void_p]
-smime.SEC_PKCS7IncludeCertChain.restype = SECStatus
-def SEC_PKCS7IncludeCertChain(p7, wincx):
-  raise_if_not_SECSuccess(smime.SEC_PKCS7IncludeCertChain(p7, wincx))
-
-SEC_PKCS7EncoderOutputCallback = CFUNCTYPE(None, c_void_p, c_void_p, c_long)
-smime.SEC_PKCS7Encode.argtypes = [c_void_p, SEC_PKCS7EncoderOutputCallback,
-                                  c_void_p, c_void_p, c_void_p, c_void_p]
-smime.SEC_PKCS7Encode.restype = SECStatus
-def SEC_PKCS7Encode(p7, bulkkey, wincx):
-  outputChunks = []
-  def callback(chunks, data, len):
-    outputChunks.append(string_at(data, len))
-  callbackWrapper = SEC_PKCS7EncoderOutputCallback(callback)
-  raise_if_not_SECSuccess(smime.SEC_PKCS7Encode(p7, callbackWrapper,
-                                                None, None, None, wincx))
-  return "".join(outputChunks)
-
-smime.SEC_PKCS7DestroyContentInfo.argtypes = [c_void_p]
-smime.SEC_PKCS7DestroyContentInfo.restype = None
-def SEC_PKCS7DestroyContentInfo(p7):
-  smime.SEC_PKCS7DestroyContentInfo(p7)
deleted file mode 100644
--- a/security/manager/ssl/tests/unit/test_signed_apps/sign_b2g_app.py
+++ /dev/null
@@ -1,144 +0,0 @@
-import argparse
-from base64 import b64encode
-from hashlib import sha1
-import sys
-import zipfile
-import ctypes
-
-import nss_ctypes
-
-def nss_load_cert(nss_db_dir, nss_password, cert_nickname):
-  nss_ctypes.NSS_Init(nss_db_dir)
-  try:
-    wincx = nss_ctypes.SetPasswordContext(nss_password)
-    cert = nss_ctypes.PK11_FindCertFromNickname(cert_nickname, wincx)
-    return (wincx, cert)
-  except:
-    nss_ctypes.NSS_Shutdown()
-    raise
-
-def nss_create_detached_signature(cert, dataToSign, wincx):
-  certdb = nss_ctypes.CERT_GetDefaultCertDB()
-  p7 = nss_ctypes.SEC_PKCS7CreateSignedData(cert,
-                                            nss_ctypes.certUsageObjectSigner,
-                                            certdb,
-                                            nss_ctypes.SEC_OID_SHA1,
-                                            sha1(dataToSign).digest(),
-                                            wincx       )
-  try:
-    nss_ctypes.SEC_PKCS7AddSigningTime(p7)
-    nss_ctypes.SEC_PKCS7IncludeCertChain(p7, wincx)
-    return nss_ctypes.SEC_PKCS7Encode(p7, None, wincx)
-  finally:
-    nss_ctypes.SEC_PKCS7DestroyContentInfo(p7)
-
-def sign_zip(in_zipfile_name, out_zipfile_name, cert, wincx):
-  mf_entries = []
-  seen_entries = set()
-
-  # Change the limits in JarSignatureVerification.cpp when you change the limits
-  # here.
-  max_entry_uncompressed_len = 100 * 1024 * 1024
-  max_total_uncompressed_len = 500 * 1024 * 1024
-  max_entry_count = 100 * 1000
-  max_entry_filename_len = 1024
-  max_mf_len = max_entry_count * 50
-  max_sf_len = 1024
-
-  total_uncompressed_len = 0
-  entry_count = 0
-  with zipfile.ZipFile(out_zipfile_name, 'w') as out_zip:
-    with zipfile.ZipFile(in_zipfile_name, 'r') as in_zip:
-      for entry_info in in_zip.infolist():
-        name = entry_info.filename
-
-        # Check for reserved and/or insane (potentially malicious) names
-        if name.endswith("/"):
-          pass
-          # Do nothing; we don't copy directory entries since they are just a
-          # waste of space.
-        elif name.lower().startswith("meta-inf/"):
-          # META-INF/* is reserved for our use
-          raise ValueError("META-INF entries are not allowed: %s" % (name))
-        elif len(name) > max_entry_filename_len:
-          raise ValueError("Entry's filename is too long: %s" % (name))
-        # TODO: elif name has invalid characters...
-        elif name in seen_entries:
-          # It is possible for a zipfile to have duplicate entries (with the exact
-          # same filenames). Python's zipfile module accepts them, but our zip
-          # reader in Gecko cannot do anything useful with them, and there's no
-          # sane reason for duplicate entries to exist, so reject them.
-          raise ValueError("Duplicate entry in input file: %s" % (name))
-        else:
-          entry_count += 1
-          if entry_count > max_entry_count:
-            raise ValueError("Too many entries in input archive")
-
-          seen_entries.add(name)
-
-          # Read in the input entry, but be careful to avoid going over the
-          # various limits we have, to minimize the likelihood that we'll run
-          # out of memory. Note that we can't use the length from entry_info
-          # because that might not be accurate if the input zip file is
-          # maliciously crafted to contain misleading metadata.
-          with in_zip.open(name, 'r') as entry_file:
-            contents = entry_file.read(max_entry_uncompressed_len + 1)
-          if len(contents) > max_entry_uncompressed_len:
-            raise ValueError("Entry is too large: %s" % (name))
-          total_uncompressed_len += len(contents)
-          if total_uncompressed_len > max_total_uncompressed_len:
-            raise ValueError("Input archive is too large")
-
-          # Copy the entry, using the same compression as used in the input file
-          out_zip.writestr(entry_info, contents)
-
-          # Add the entry to the manifest we're building
-          mf_entries.append('Name: %s\nSHA1-Digest: %s\n'
-                                % (name, b64encode(sha1(contents).digest())))
-
-    mf_contents = 'Manifest-Version: 1.0\n\n' + '\n'.join(mf_entries)
-    if len(mf_contents) > max_mf_len:
-      raise ValueError("Generated MANIFEST.MF is too large: %d" % (len(mf_contents)))
-
-    sf_contents = ('Signature-Version: 1.0\nSHA1-Digest-Manifest: %s\n'
-                                % (b64encode(sha1(mf_contents).digest())))
-    if len(sf_contents) > max_sf_len:
-      raise ValueError("Generated SIGNATURE.SF is too large: %d"
-                          % (len(mf_contents)))
-
-    p7 = nss_create_detached_signature(cert, sf_contents, wincx)
-
-    # write the signature, SF, and MF
-    out_zip.writestr("META-INF/A.RSA", p7, zipfile.ZIP_DEFLATED)
-    out_zip.writestr("META-INF/A.SF",  sf_contents, zipfile.ZIP_DEFLATED)
-    out_zip.writestr("META-INF/MANIFEST.MF", mf_contents, zipfile.ZIP_DEFLATED)
-
-def main():
-  parser = argparse.ArgumentParser(description='Sign a B2G app.')
-  parser.add_argument('-d', action='store',
-                            required=True, help='NSS database directory')
-  parser.add_argument('-f', action='store',
-                            type=argparse.FileType('rb'),
-                            required=True, help='password file')
-  parser.add_argument('-k', action='store',
-                            required=True, help="nickname of signing cert.")
-  parser.add_argument('-i', action='store', type=argparse.FileType('rb'),
-                            required=True, help="input JAR file (unsigned)")
-  parser.add_argument('-o', action='store', type=argparse.FileType('wb'),
-                            required=True, help="output JAR file (signed)")
-  args = parser.parse_args()
-
-  db_dir = args.d
-  password = args.f.readline().strip()
-  cert_nickname = args.k
-
-  (wincx, cert) = nss_load_cert(db_dir, password, cert_nickname)
-  try:
-    sign_zip(args.i, args.o, cert, wincx)
-    return 0
-  finally:
-    nss_ctypes.CERT_DestroyCertificate(cert)
-    nss_ctypes.NSS_Shutdown()
-
-if __name__ == "__main__":
-    sys.exit(main())
deleted file mode 100644
index d6fd07a4167d2f05a9a13a2eaca6a9981287dfb6..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
--- a/security/manager/ssl/tests/unit/test_signed_apps/simple/index.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!doctype html>
-<html lang=en>
-<head><meta charset=utf-8><title>Simple App</title></head>
-<body><p>This is a Simple App.</body>
-</html>
-
deleted file mode 100644
--- a/security/manager/ssl/tests/unit/test_signed_apps/simple/manifest.webapp
+++ /dev/null
@@ -1,6 +0,0 @@
-{ name: "Simple App"
-, description: "A Simple Open Web App"
-, launch_path: "/index.html"
-, icons: { "128" : "icon-128.png" }
-, installs_allowed_from: [ "https://marketplace.mozilla.com" ]
-}
deleted file mode 100644
index 9d4e30984dd62a275a5d4988d2c6c82f96d07674..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 9f63b0d751a9ca3158ce7ccbd767487460b76f6e..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 7ba7b45914783350fd83d14b21ae5369322c03cf..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index d98a88d1983fddbc7b850bcd17867c135f85b975..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index e00a301ef0c15c12bf5f99787145a4869c0e6f33..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/security/manager/ssl/tests/unit/xpcshell.ini
+++ b/security/manager/ssl/tests/unit/xpcshell.ini
@@ -1,13 +1,12 @@
 [DEFAULT]
 head = 
 tail = 
 
-[test_signed_apps.js]
 [test_datasignatureverifier.js]
 # Bug 676972: test hangs consistently on Android
 skip-if = os == "android"
 [test_hash_algorithms.js]
 # Bug 676972: test hangs consistently on Android
 skip-if = os == "android"
 [test_hmac.js]
 # Bug 676972: test hangs consistently on Android
--- a/security/nss/lib/pkcs7/p7decode.c
+++ b/security/nss/lib/pkcs7/p7decode.c
@@ -1276,18 +1276,17 @@ SEC_PKCS7ContentIsSigned(SEC_PKCS7Conten
  * there should be NO authenticatedAttributes (signerinfo->authAttr should
  * be NULL).
  */
 static PRBool
 sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
 			   SECCertUsage certusage,
 			   const SECItem *detached_digest,
 			   HASH_HashType digest_type,
-			   PRBool keepcerts,
-			   PRTime atTime)
+			   PRBool keepcerts)
 {
     SECAlgorithmID **digestalgs, *bulkid;
     const SECItem *digest;
     SECItem **digests;
     SECItem **rawcerts;
     CERTSignedCrl **crls;
     SEC_PKCS7SignerInfo **signerinfos, *signerinfo;
     CERTCertificate *cert, **certs;
@@ -1295,18 +1294,17 @@ sec_pkcs7_verify_signature(SEC_PKCS7Cont
     CERTCertDBHandle *certdb, *defaultdb; 
     SECOidTag encTag,digestTag;
     HASH_HashType found_type;
     int i, certcount;
     SECKEYPublicKey *publickey;
     SECItem *content_type;
     PK11SymKey *sigkey;
     SECItem *encoded_stime;
-    PRTime stime;
-    PRTime verificationTime;
+    int64 stime;
     SECStatus rv;
 
     /*
      * Everything needed in order to "goto done" safely.
      */
     goodsig = PR_FALSE;
     certcount = 0;
     cert = NULL;
@@ -1433,20 +1431,18 @@ sec_pkcs7_verify_signature(SEC_PKCS7Cont
     /*
      * XXX  This uses the signing time, if available.  Additionally, we
      * might want to, if there is no signing time, get the message time
      * from the mail header itself, and use that.  That would require
      * a change to our interface though, and for S/MIME callers to pass
      * in a time (and for non-S/MIME callers to pass in nothing, or
      * maybe make them pass in the current time, always?).
      */
-    verificationTime = atTime ? atTime
-			      : (encoded_stime ? stime : PR_Now());
     if (CERT_VerifyCert (certdb, cert, PR_TRUE, certusage,
-			 verificationTime,
+			 encoded_stime != NULL ? stime : PR_Now(),
 			 cinfo->pwfn_arg, NULL) != SECSuccess)
 	{
 	/*
 	 * XXX Give the user an option to check the signature anyway?
 	 * If we want to do this, need to give a way to leave and display
 	 * some dialog and get the answer and come back through (or do
 	 * the rest of what we do below elsewhere, maybe by putting it
 	 * in a function that we call below and could call from a dialog
@@ -1756,17 +1752,17 @@ done:
  *	into our local database.
  */
 PRBool
 SEC_PKCS7VerifySignature(SEC_PKCS7ContentInfo *cinfo,
 			 SECCertUsage certusage,
 			 PRBool keepcerts)
 {
     return sec_pkcs7_verify_signature (cinfo, certusage,
-				       NULL, HASH_AlgNULL, keepcerts, 0);
+				       NULL, HASH_AlgNULL, keepcerts);
 }
 
 /*
  * SEC_PKCS7VerifyDetachedSignature
  *	Look at a PKCS7 contentInfo and check if the signature matches
  *	a passed-in digest (calculated, supposedly, from detached contents).
  *	The verification checks that the signing cert is valid and trusted
  *	for the purpose specified by "certusage".
@@ -1778,44 +1774,19 @@ PRBool
 SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo,
 				 SECCertUsage certusage,
 				 const SECItem *detached_digest,
 				 HASH_HashType digest_type,
 				 PRBool keepcerts)
 {
     return sec_pkcs7_verify_signature (cinfo, certusage,
 				       detached_digest, digest_type,
-				       keepcerts, 0);
+				       keepcerts);
 }
 
-/*
- * SEC_PKCS7VerifyDetachedSignatureAtTime
- *      Look at a PKCS7 contentInfo and check if the signature matches
- *      a passed-in digest (calculated, supposedly, from detached contents).
- *      The verification checks that the signing cert is valid and trusted
- *      for the purpose specified by "certusage" at time "atTime"
- *      if "atTime" is non-zero, or at the current time (as returned by
- *      PR_Now) otherwise.
- */
-PRBool
-SEC_PKCS7VerifyDetachedSignatureAtTime(SEC_PKCS7ContentInfo *cinfo,
-				       SECCertUsage certusage,
-				       const SECItem *detached_digest,
-				       HASH_HashType digest_type,
-				       PRBool keepcerts,
-				       PRTime atTime)
-{
-    if (!atTime) {
-	atTime = PR_Now();
-    }
-
-    return sec_pkcs7_verify_signature (cinfo, certusage,
-				       detached_digest, digest_type,
-				       keepcerts, atTime);
-}
 
 /*
  * Return the asked-for portion of the name of the signer of a PKCS7
  * signed object.
  *
  * Returns a pointer to allocated memory, which must be freed.
  * A NULL return value is an error.
  */
@@ -1868,17 +1839,17 @@ sec_pkcs7_get_signer_cert_info(SEC_PKCS7
      */
     if (signercert == NULL) {
 	/*
 	 * The cert usage does not matter in this case, because we do not
 	 * actually care about the verification itself, but we have to pick
 	 * some valid usage to pass in.
 	 */
 	(void) sec_pkcs7_verify_signature (cinfo, certUsageEmailSigner,
-					   NULL, HASH_AlgNULL, PR_FALSE, 0);
+					   NULL, HASH_AlgNULL, PR_FALSE);
 	signercert = signerinfos[0]->cert;
 	if (signercert == NULL)
 	    return NULL;
     }
 
     switch (selector) {
       case sec_common_name:
 	container = CERT_GetCommonName (&signercert->subject);
--- a/security/nss/lib/pkcs7/secpkcs7.h
+++ b/security/nss/lib/pkcs7/secpkcs7.h
@@ -128,33 +128,16 @@ extern PRBool SEC_PKCS7VerifySignature(S
  *	into our local database.
  */
 extern PRBool SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo,
 					       SECCertUsage certusage,
 					       const SECItem *detached_digest,
 					       HASH_HashType digest_type,
 					       PRBool keepcerts);
 
-
-/*
- * SEC_PKCS7VerifyDetachedSignatureAtTime
- *      Look at a PKCS7 contentInfo and check if the signature matches
- *      a passed-in digest (calculated, supposedly, from detached contents).
- *      The verification checks that the signing cert is valid and trusted
- *      for the purpose specified by "certusage" at time "atTime"
- *      if "atTime" is non-zero, or at the current time (as returned by
- *      PR_Now) otherwise.
- */
-extern PRBool SEC_PKCS7VerifyDetachedSignatureAtTime(SEC_PKCS7ContentInfo *cinfo,
-						     SECCertUsage certusage,
-						     const SECItem *detached_digest,
-						     HASH_HashType digest_type,
-						     PRBool keepcerts,
-						     PRTime atTime);
-
 /*
  * SEC_PKCS7GetSignerCommonName, SEC_PKCS7GetSignerEmailAddress
  *      The passed-in contentInfo is espected to be Signed, and these
  *      functions return the specified portion of the full signer name.
  *
  *      Returns a pointer to allocated memory, which must be freed.
  *      A NULL return value is an error.
  */
--- a/security/nss/lib/smime/smime.def
+++ b/security/nss/lib/smime/smime.def
@@ -262,14 +262,8 @@ NSS_Get_NSS_PointerToCMSGenericWrapperDa
 ;+       *;
 ;+};
 ;+NSS_3.13 {    # NSS 3.13 release
 ;+    global:
 NSSSMIME_GetVersion;
 ;+    local:
 ;+       *;
 ;+};
-;+NSS_3.14.3 {    # NSS 3.14.3 release
-;+    global:
-SEC_PKCS7VerifyDetachedSignatureAtTime;
-;+    local:
-;+       *;
-;+};
--- a/security/patches/README
+++ b/security/patches/README
@@ -1,7 +1,4 @@
 This directory contains patches that were added locally
 on top of the NSS release.
 
-bug-834091.patch: Add SEC_PKCS7VerifyDetachedSignatureAtTime, which is needed
-                  for B2G 1.0. This patch is probably going to be modified
-                  before it can land in upstream NSS.
 bug-832942.patch: work around an ARMv6 code generation bug in gcc 4.6.
\ No newline at end of file
deleted file mode 100644
--- a/security/patches/bug-834091.patch
+++ /dev/null
@@ -1,216 +0,0 @@
-Index: security/nss/lib/pkcs7/p7decode.c
-===================================================================
-RCS file: /cvsroot/mozilla/security/nss/lib/pkcs7/p7decode.c,v
-retrieving revision 1.31
-diff -u -8 -p -r1.31 p7decode.c
---- security/nss/lib/pkcs7/p7decode.c	12 Dec 2012 19:25:36 -0000	1.31
-+++ security/nss/lib/pkcs7/p7decode.c	25 Jan 2013 23:22:54 -0000
-@@ -1276,17 +1276,18 @@ SEC_PKCS7ContentIsSigned(SEC_PKCS7Conten
-  * there should be NO authenticatedAttributes (signerinfo->authAttr should
-  * be NULL).
-  */
- static PRBool
- sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
- 			   SECCertUsage certusage,
- 			   const SECItem *detached_digest,
- 			   HASH_HashType digest_type,
--			   PRBool keepcerts)
-+			   PRBool keepcerts,
-+			   PRTime atTime)
- {
-     SECAlgorithmID **digestalgs, *bulkid;
-     const SECItem *digest;
-     SECItem **digests;
-     SECItem **rawcerts;
-     CERTSignedCrl **crls;
-     SEC_PKCS7SignerInfo **signerinfos, *signerinfo;
-     CERTCertificate *cert, **certs;
-@@ -1294,17 +1295,18 @@ sec_pkcs7_verify_signature(SEC_PKCS7Cont
-     CERTCertDBHandle *certdb, *defaultdb; 
-     SECOidTag encTag,digestTag;
-     HASH_HashType found_type;
-     int i, certcount;
-     SECKEYPublicKey *publickey;
-     SECItem *content_type;
-     PK11SymKey *sigkey;
-     SECItem *encoded_stime;
--    int64 stime;
-+    PRTime stime;
-+    PRTime verificationTime;
-     SECStatus rv;
- 
-     /*
-      * Everything needed in order to "goto done" safely.
-      */
-     goodsig = PR_FALSE;
-     certcount = 0;
-     cert = NULL;
-@@ -1431,18 +1433,20 @@ sec_pkcs7_verify_signature(SEC_PKCS7Cont
-     /*
-      * XXX  This uses the signing time, if available.  Additionally, we
-      * might want to, if there is no signing time, get the message time
-      * from the mail header itself, and use that.  That would require
-      * a change to our interface though, and for S/MIME callers to pass
-      * in a time (and for non-S/MIME callers to pass in nothing, or
-      * maybe make them pass in the current time, always?).
-      */
-+    verificationTime = atTime ? atTime
-+			      : (encoded_stime ? stime : PR_Now());
-     if (CERT_VerifyCert (certdb, cert, PR_TRUE, certusage,
--			 encoded_stime != NULL ? stime : PR_Now(),
-+			 verificationTime,
- 			 cinfo->pwfn_arg, NULL) != SECSuccess)
- 	{
- 	/*
- 	 * XXX Give the user an option to check the signature anyway?
- 	 * If we want to do this, need to give a way to leave and display
- 	 * some dialog and get the answer and come back through (or do
- 	 * the rest of what we do below elsewhere, maybe by putting it
- 	 * in a function that we call below and could call from a dialog
-@@ -1752,17 +1756,17 @@ done:
-  *	into our local database.
-  */
- PRBool
- SEC_PKCS7VerifySignature(SEC_PKCS7ContentInfo *cinfo,
- 			 SECCertUsage certusage,
- 			 PRBool keepcerts)
- {
-     return sec_pkcs7_verify_signature (cinfo, certusage,
--				       NULL, HASH_AlgNULL, keepcerts);
-+				       NULL, HASH_AlgNULL, keepcerts, 0);
- }
- 
- /*
-  * SEC_PKCS7VerifyDetachedSignature
-  *	Look at a PKCS7 contentInfo and check if the signature matches
-  *	a passed-in digest (calculated, supposedly, from detached contents).
-  *	The verification checks that the signing cert is valid and trusted
-  *	for the purpose specified by "certusage".
-@@ -1774,19 +1778,44 @@ PRBool
- SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo,
- 				 SECCertUsage certusage,
- 				 const SECItem *detached_digest,
- 				 HASH_HashType digest_type,
- 				 PRBool keepcerts)
- {
-     return sec_pkcs7_verify_signature (cinfo, certusage,
- 				       detached_digest, digest_type,
--				       keepcerts);
-+				       keepcerts, 0);
- }
- 
-+/*
-+ * SEC_PKCS7VerifyDetachedSignatureAtTime
-+ *      Look at a PKCS7 contentInfo and check if the signature matches
-+ *      a passed-in digest (calculated, supposedly, from detached contents).
-+ *      The verification checks that the signing cert is valid and trusted
-+ *      for the purpose specified by "certusage" at time "atTime"
-+ *      if "atTime" is non-zero, or at the current time (as returned by
-+ *      PR_Now) otherwise.
-+ */
-+PRBool
-+SEC_PKCS7VerifyDetachedSignatureAtTime(SEC_PKCS7ContentInfo *cinfo,
-+				       SECCertUsage certusage,
-+				       const SECItem *detached_digest,
-+				       HASH_HashType digest_type,
-+				       PRBool keepcerts,
-+				       PRTime atTime)
-+{
-+    if (!atTime) {
-+	atTime = PR_Now();
-+    }
-+
-+    return sec_pkcs7_verify_signature (cinfo, certusage,
-+				       detached_digest, digest_type,
-+				       keepcerts, atTime);
-+}
- 
- /*
-  * Return the asked-for portion of the name of the signer of a PKCS7
-  * signed object.
-  *
-  * Returns a pointer to allocated memory, which must be freed.
-  * A NULL return value is an error.
-  */
-@@ -1839,17 +1868,17 @@ sec_pkcs7_get_signer_cert_info(SEC_PKCS7
-      */
-     if (signercert == NULL) {
- 	/*
- 	 * The cert usage does not matter in this case, because we do not
- 	 * actually care about the verification itself, but we have to pick
- 	 * some valid usage to pass in.
- 	 */
- 	(void) sec_pkcs7_verify_signature (cinfo, certUsageEmailSigner,
--					   NULL, HASH_AlgNULL, PR_FALSE);
-+					   NULL, HASH_AlgNULL, PR_FALSE, 0);
- 	signercert = signerinfos[0]->cert;
- 	if (signercert == NULL)
- 	    return NULL;
-     }
- 
-     switch (selector) {
-       case sec_common_name:
- 	container = CERT_GetCommonName (&signercert->subject);
-Index: security/nss/lib/pkcs7/secpkcs7.h
-===================================================================
-RCS file: /cvsroot/mozilla/security/nss/lib/pkcs7/secpkcs7.h,v
-retrieving revision 1.10
-diff -u -8 -p -r1.10 secpkcs7.h
---- security/nss/lib/pkcs7/secpkcs7.h	27 Nov 2012 22:48:08 -0000	1.10
-+++ security/nss/lib/pkcs7/secpkcs7.h	25 Jan 2013 23:22:54 -0000
-@@ -128,16 +128,33 @@ extern PRBool SEC_PKCS7VerifySignature(S
-  *	into our local database.
-  */
- extern PRBool SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo,
- 					       SECCertUsage certusage,
- 					       const SECItem *detached_digest,
- 					       HASH_HashType digest_type,
- 					       PRBool keepcerts);
- 
-+
-+/*
-+ * SEC_PKCS7VerifyDetachedSignatureAtTime
-+ *      Look at a PKCS7 contentInfo and check if the signature matches
-+ *      a passed-in digest (calculated, supposedly, from detached contents).
-+ *      The verification checks that the signing cert is valid and trusted
-+ *      for the purpose specified by "certusage" at time "atTime"
-+ *      if "atTime" is non-zero, or at the current time (as returned by
-+ *      PR_Now) otherwise.
-+ */
-+extern PRBool SEC_PKCS7VerifyDetachedSignatureAtTime(SEC_PKCS7ContentInfo *cinfo,
-+						     SECCertUsage certusage,
-+						     const SECItem *detached_digest,
-+						     HASH_HashType digest_type,
-+						     PRBool keepcerts,
-+						     PRTime atTime);
-+
- /*
-  * SEC_PKCS7GetSignerCommonName, SEC_PKCS7GetSignerEmailAddress
-  *      The passed-in contentInfo is espected to be Signed, and these
-  *      functions return the specified portion of the full signer name.
-  *
-  *      Returns a pointer to allocated memory, which must be freed.
-  *      A NULL return value is an error.
-  */
-Index: security/nss/lib/smime/smime.def
-===================================================================
-RCS file: /cvsroot/mozilla/security/nss/lib/smime/smime.def,v
-retrieving revision 1.39
-diff -u -8 -p -r1.39 smime.def
---- security/nss/lib/smime/smime.def	25 Apr 2012 14:50:09 -0000	1.39
-+++ security/nss/lib/smime/smime.def	25 Jan 2013 23:22:54 -0000
-@@ -262,8 +262,14 @@ NSS_Get_NSS_PointerToCMSGenericWrapperDa
- ;+       *;
- ;+};
- ;+NSS_3.13 {    # NSS 3.13 release
- ;+    global:
- NSSSMIME_GetVersion;
- ;+    local:
- ;+       *;
- ;+};
-+;+NSS_3.14.3 {    # NSS 3.14.3 release
-+;+    global:
-+SEC_PKCS7VerifyDetachedSignatureAtTime;
-+;+    local:
-+;+       *;
-+;+};