Skip to content
Snippets Groups Projects
Verified Commit 9a95e213 authored by Kathleen Brade's avatar Kathleen Brade Committed by Pier Angelo Vendrame
Browse files

Bug 13379: Allow using NSS to sign and verify MAR signatures

Allow using NSS on all platforms for checking MAR signatures (instead
  of using OS-native APIs, the default on Mac OS and Windows).
  So that the NSS and NSPR libraries the updater depends on can be
  found at runtime, we add the firefox directory to the shared library
  search path on macOS.
  On Linux, rpath is used to solve that problem, but that approach
  won't work on macOS because the updater executable is copied during
  the update process to a location that can vary.
parent 9c1dd51f
Branches
No related tags found
1 merge request!585Bug 41668 (Base Browser): Port the updater changes to base browser
......@@ -65,7 +65,7 @@ static void print_usage() {
"signed_input_archive.mar base_64_encoded_signature_file "
"changed_signed_output.mar\n");
printf("(i) is the index of the certificate to extract\n");
# if defined(XP_MACOSX) || (defined(XP_WIN) && !defined(MAR_NSS))
# if (defined(XP_MACOSX) || defined(XP_WIN)) && !defined(MAR_NSS)
printf("Verify a MAR file:\n");
printf(" mar [-C workingDir] -D DERFilePath -v signed_archive.mar\n");
printf(
......@@ -149,7 +149,7 @@ int main(int argc, char** argv) {
memset((void*)certBuffers, 0, sizeof(certBuffers));
#endif
#if !defined(NO_SIGN_VERIFY) && \
((!defined(MAR_NSS) && defined(XP_WIN)) || defined(XP_MACOSX))
(!defined(MAR_NSS) && (defined(XP_WIN) || defined(XP_MACOSX)))
memset(DERFilePaths, 0, sizeof(DERFilePaths));
memset(fileSizes, 0, sizeof(fileSizes));
#endif
......@@ -181,7 +181,7 @@ int main(int argc, char** argv) {
argc -= 2;
}
#if !defined(NO_SIGN_VERIFY)
# if (!defined(MAR_NSS) && defined(XP_WIN)) || defined(XP_MACOSX)
# if (!defined(MAR_NSS) && (defined(XP_WIN) || defined(XP_MACOSX)))
/* -D DERFilePath, also matches -D[index] DERFilePath
We allow an index for verifying to be symmetric
with the import and export command line arguments. */
......
......
......@@ -43,15 +43,21 @@ if CONFIG["MOZ_BUILD_APP"] != "tools/update-packaging":
"verifymar",
]
if CONFIG["TOR_BROWSER_UPDATE"]:
DEFINES["MAR_NSS"] = True
if CONFIG["OS_ARCH"] == "WINNT":
USE_STATIC_LIBS = True
OS_LIBS += [
"ws2_32",
]
if not CONFIG["TOR_BROWSER_UPDATE"]:
OS_LIBS += [
"crypt32",
"advapi32",
]
elif CONFIG["OS_ARCH"] == "Darwin":
elif CONFIG["OS_ARCH"] == "Darwin" and not CONFIG["TOR_BROWSER_UPDATE"]:
OS_LIBS += [
"-framework CoreFoundation",
"-framework Security",
......
......
......@@ -16,15 +16,12 @@ FORCE_STATIC_LIB = True
if CONFIG["OS_ARCH"] == "WINNT":
USE_STATIC_LIBS = True
elif CONFIG["OS_ARCH"] == "Darwin":
UNIFIED_SOURCES += [
"MacVerifyCrypto.cpp",
]
OS_LIBS += [
"-framework Security",
USE_LIBS += [
"nspr",
"nss",
"signmar",
]
else:
DEFINES["MAR_NSS"] = True
LOCAL_INCLUDES += ["../sign"]
USE_LIBS += [
"nspr",
"nss",
......@@ -38,6 +35,9 @@ else:
"-Wl,-rpath=\\$$ORIGIN",
]
DEFINES["MAR_NSS"] = True
LOCAL_INCLUDES += ["../sign"]
LOCAL_INCLUDES += [
"../src",
]
......
......
......@@ -212,6 +212,13 @@ this.AppConstants = Object.freeze({
false,
#endif
MOZ_VERIFY_MAR_SIGNATURE:
#ifdef MOZ_VERIFY_MAR_SIGNATURE
true,
#else
false,
#endif
MOZ_MAINTENANCE_SERVICE:
#ifdef MOZ_MAINTENANCE_SERVICE
true,
......
......
......@@ -4,6 +4,10 @@
# 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/.
DEFINES["MAR_NSS"] = True
link_with_nss = DEFINES["MAR_NSS"] or (CONFIG["OS_ARCH"] == "Linux" and CONFIG["MOZ_VERIFY_MAR_SIGNATURE"])
srcs = [
"archivereader.cpp",
"updater.cpp",
......@@ -36,14 +40,18 @@ if CONFIG["OS_ARCH"] == "WINNT":
"ws2_32",
"shell32",
"shlwapi",
"crypt32",
"advapi32",
"gdi32",
"user32",
"userenv",
"uuid",
]
if not link_with_nss:
OS_LIBS += [
"crypt32",
"advapi32",
]
USE_LIBS += [
"bspatch",
"mar",
......@@ -51,6 +59,13 @@ USE_LIBS += [
"xz-embedded",
]
if link_with_nss:
USE_LIBS += [
"nspr",
"nss",
"signmar",
]
if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
have_progressui = 1
srcs += [
......@@ -65,9 +80,12 @@ if CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa":
]
OS_LIBS += [
"-framework Cocoa",
"-framework Security",
"-framework SystemConfiguration",
]
if not link_with_nss:
OS_LIBS += [
"-framework Security",
]
UNIFIED_SOURCES += [
"/toolkit/xre/updaterfileutils_osx.mm",
]
......
......
......@@ -106,10 +106,12 @@ struct UpdateServerThreadArgs {
# define stat64 stat
#endif
#if defined(MOZ_VERIFY_MAR_SIGNATURE) && !defined(XP_WIN) && !defined(XP_MACOSX)
#if defined(MOZ_VERIFY_MAR_SIGNATURE)
# if defined(MAR_NSS) || (!defined(XP_WIN) && !defined(XP_MACOSX))
# include "nss.h"
# include "prerror.h"
# endif
#endif
#include "crctable.h"
......@@ -2899,17 +2901,17 @@ int NS_main(int argc, NS_tchar** argv) {
if (!isDMGInstall) {
// Skip update-related code path for DMG installs.
#if defined(MOZ_VERIFY_MAR_SIGNATURE) && !defined(XP_WIN) && !defined(XP_MACOSX)
// On Windows and Mac we rely on native APIs 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 defined(MOZ_VERIFY_MAR_SIGNATURE)
# if defined(MAR_NSS) || (!defined(XP_WIN) && !defined(XP_MACOSX))
// If using NSS for signature verification, initialize NSS but minimize
// the portion we depend on by avoiding all of the NSS databases.
if (NSS_NoDB_Init(nullptr) != SECSuccess) {
PRErrorCode error = PR_GetError();
fprintf(stderr, "Could not initialize NSS: %s (%d)",
PR_ErrorToName(error), (int)error);
_exit(1);
}
# endif
#endif
// To process an update the updater command line must at a minimum have the
......
......
......@@ -232,6 +232,9 @@ for var in ("APP_VERSION", "APP_ID"):
if CONFIG["MOZ_BUILD_APP"] == "browser":
DEFINES["MOZ_BUILD_APP_IS_BROWSER"] = True
if CONFIG['TOR_BROWSER_UPDATE']:
DEFINES['MAR_NSS'] = True
LOCAL_INCLUDES += [
"../../other-licenses/nsis/Contrib/CityHash/cityhash",
"../components/find",
......
......
......@@ -293,6 +293,42 @@ static bool IsOlderVersion(nsIFile* versionFile, const char* appVersion) {
return mozilla::Version(appVersion) > buf;
}
#if defined(TOR_BROWSER_UPDATE) && defined(MOZ_VERIFY_MAR_SIGNATURE) && \
defined(MAR_NSS) && defined(XP_MACOSX)
/**
* Ideally we would save and restore the original library path value after
* the updater finishes its work (and before firefox is re-launched).
* Doing so would avoid potential problems like the following bug:
* https://bugzilla.mozilla.org/show_bug.cgi?id=1434033
*/
/**
* Appends the specified path to the library path.
* This is used so that the updater can find libnss3.dylib and other
* shared libs.
*
* @param pathToAppend A new library path to prepend to the dynamic linker's
* search path.
*/
# include "prprf.h"
# define PATH_SEPARATOR ":"
# define LD_LIBRARY_PATH_ENVVAR_NAME "DYLD_LIBRARY_PATH"
static void AppendToLibPath(const char* pathToAppend) {
char* pathValue = getenv(LD_LIBRARY_PATH_ENVVAR_NAME);
if (nullptr == pathValue || '\0' == *pathValue) {
// Leak the string because that is required by PR_SetEnv.
char* s =
Smprintf("%s=%s", LD_LIBRARY_PATH_ENVVAR_NAME, pathToAppend).release();
PR_SetEnv(s);
} else {
// Leak the string because that is required by PR_SetEnv.
char* s = Smprintf("%s=%s" PATH_SEPARATOR "%s", LD_LIBRARY_PATH_ENVVAR_NAME,
pathToAppend, pathValue)
.release();
PR_SetEnv(s);
}
}
#endif
/**
* Applies, switches, or stages an update.
*
......@@ -569,6 +605,20 @@ static void ApplyUpdate(nsIFile* greDir, nsIFile* updateDir, nsIFile* appDir,
PR_SetEnv("MOZ_SAFE_MODE_RESTART=1");
}
#if defined(TOR_BROWSER_UPDATE) && defined(MOZ_VERIFY_MAR_SIGNATURE) && \
defined(MAR_NSS) && defined(XP_MACOSX)
// On macOS, append the app directory to the shared library search path
// so the system can locate the shared libraries that are needed by the
// updater, e.g., libnss3.dylib).
nsAutoCString appPath;
nsresult rv2 = appDir->GetNativePath(appPath);
if (NS_SUCCEEDED(rv2)) {
AppendToLibPath(appPath.get());
} else {
LOG(("ApplyUpdate -- appDir->GetNativePath() failed (0x%x)\n", rv2));
}
#endif
LOG(("spawning updater process [%s]\n", updaterPath.get()));
#if defined(XP_UNIX) && !defined(XP_MACOSX)
......
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment