Bug 903135 - Multi platform MAR verification updater support. r=rstrong
authorBrian R. Bondy <netzen@gmail.com>
Wed, 22 Oct 2014 21:00:26 -0400
changeset 237691 aea7dfa2946416d2a8610e95ffcde908457ce31e
parent 237690 c19d11fe299702a7ef948b29e61b51b889c10b32
child 237692 40a318763f490eb9cc319987950f9cc9a3ceaf1f
push id28546
push usernetzen@gmail.com
push dateMon, 06 Apr 2015 16:08:39 +0000
treeherdermozilla-central@883e17fc475f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrstrong
bugs903135
milestone40.0a1
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
Bug 903135 - Multi platform MAR verification updater support. r=rstrong
toolkit/mozapps/update/updater/archivereader.cpp
toolkit/mozapps/update/updater/updater.cpp
--- a/toolkit/mozapps/update/updater/archivereader.cpp
+++ b/toolkit/mozapps/update/updater/archivereader.cpp
@@ -10,96 +10,88 @@
 #include "bzlib.h"
 #include "archivereader.h"
 #include "errors.h"
 #ifdef XP_WIN
 #include "nsAlgorithm.h" // Needed by nsVersionComparator.cpp
 #include "updatehelper.h"
 #endif
 
-#ifdef XP_WIN
 // These are generated at compile time based on the DER file for the channel
 // being used
 #include "primaryCert.h"
 #include "secondaryCert.h"
 #include "xpcshellCert.h"
-#endif
 
 #define UPDATER_NO_STRING_GLUE_STL
 #include "nsVersionComparator.cpp"
 #undef UPDATER_NO_STRING_GLUE_STL
 
 #if defined(XP_UNIX)
 # include <sys/types.h>
 #elif defined(XP_WIN)
 # include <io.h>
 #endif
 
 static int inbuf_size  = 262144;
 static int outbuf_size = 262144;
 static char *inbuf  = nullptr;
 static char *outbuf = nullptr;
 
-#ifdef XP_WIN
-#include "resource.h"
-
 /**
  * Performs a verification on the opened MAR file with the passed in
  * certificate name ID and type ID.
  *
  * @param  archive   The MAR file to verify the signature on.
  * @param  certData  The certificate data.
  * @return OK on success, CERT_VERIFY_ERROR on failure.
 */
 template<uint32_t SIZE>
 int
 VerifyLoadedCert(MarFile *archive, const uint8_t (&certData)[SIZE])
 {
   const uint32_t size = SIZE;
-  const uint8_t * const data = &certData[0];
-  if (mar_verify_signaturesW(archive, &data, &size, 1)) {
+  const uint8_t* const data = &certData[0];
+  if (mar_verify_signatures(archive, &data, &size, 1)) {
     return CERT_VERIFY_ERROR;
   }
 
   return OK;
 }
-#endif
-
 
 /**
  * Performs a verification on the opened MAR file.  Both the primary and backup 
  * keys stored are stored in the current process and at least the primary key 
  * will be tried.  Success will be returned as long as one of the two 
  * signatures verify.
  *
  * @return OK on success
 */
 int
 ArchiveReader::VerifySignature()
 {
   if (!mArchive) {
     return ARCHIVE_NOT_OPEN;
   }
 
-#ifdef XP_WIN
   // If the fallback key exists we're running an XPCShell test and we should
   // use the XPCShell specific cert for the signed MAR.
-  int rv;
+  int rv = OK;
+#ifdef XP_WIN
   if (DoesFallbackKeyExist()) {
     rv = VerifyLoadedCert(mArchive, xpcshellCertData);
-  } else {
+  } else
+#endif
+  {
     rv = VerifyLoadedCert(mArchive, primaryCertData);
     if (rv != OK) {
       rv = VerifyLoadedCert(mArchive, secondaryCertData);
     }
   }
   return rv;
-#else
-  return OK;
-#endif
 }
 
 /**
  * Verifies that the MAR file matches the current product, channel, and version
  * 
  * @param MARChannelID   The MAR channel name to use, only updates from MARs
  *                       with a matching MAR channel name will succeed.
  *                       If an empty string is passed, no check will be done
--- a/toolkit/mozapps/update/updater/updater.cpp
+++ b/toolkit/mozapps/update/updater/updater.cpp
@@ -111,16 +111,21 @@ static int ioprio_set(int which, int who
 #endif
 
 # define MAYBE_USE_HARD_LINKS 1
 static bool sUseHardLinks = true;
 #else
 # define MAYBE_USE_HARD_LINKS 0
 #endif
 
+#if defined(MOZ_VERIFY_MAR_SIGNATURE) && !defined(XP_WIN)
+#include "nss.h"
+#include "prerror.h"
+#endif
+
 #ifdef XP_WIN
 #include "updatehelper.h"
 
 // Closes the handle if valid and if the updater is elevated returns with the
 // return code specified. This prevents multiple launches of the callback
 // application by preventing the elevated process from launching the callback.
 #define EXIT_WHEN_ELEVATED(path, handle, retCode) \
   { \
@@ -2274,16 +2279,30 @@ int NS_main(int argc, NS_tchar **argv)
     // in the parent process, so we do it here.
     unsetenv("LD_PRELOAD");
     execv(argv[0], argv);
     __android_log_print(ANDROID_LOG_INFO, "updater",
                         "execve failed: errno: %d. Exiting...", errno);
     _exit(1);
   }
 #endif
+
+#if defined(MOZ_VERIFY_MAR_SIGNATURE) && !defined(XP_WIN)
+  // On Windows we rely on CyrptoAPI to do verifications so we don't need to
+  // initialize NSS at all there.
+  // Otherwise, minimize the amount of NSS we depend on by avoiding all the NSS
+  // databases.
+  if (NSS_NoDB_Init(NULL) != SECSuccess) {
+   PRErrorCode error = PR_GetError();
+   fprintf(stderr, "Could not initialize NSS: %s (%d)",
+           PR_ErrorToName(error), (int) error);
+    _exit(1);
+  }
+#endif
+
   InitProgressUI(&argc, &argv);
 
   // To process an update the updater command line must at a minimum have the
   // directory path containing the updater.mar file to process as the first
   // argument, the install directory as the second argument, and the directory
   // to apply the update to as the third argument. When the updater is launched
   // by another process the PID of the parent process should be provided in the
   // optional fourth argument and the updater will wait on the parent process to