Bug 704285 - Include certificates inside updater.exe and use them to verify MARs. r=rstrong

This commit is contained in:
Brian R. Bondy 2012-02-24 16:29:41 -05:00
Родитель 785c6ca5ee
Коммит adb8e1c40a
7 изменённых файлов: 129 добавлений и 2 удалений

Просмотреть файл

@ -56,6 +56,9 @@
#define UPDATER_QUOTED_PATH_MEM_ERROR 14
#define BAD_ACTION_ERROR 15
#define STRING_CONVERSION_ERROR 16
#define CERT_LOAD_ERROR 17
#define CERT_HANDLING_ERROR 18
#define CERT_VERIFY_ERROR 19
// The following error codes are only used by updater.exe
// when a fallback key exists and XPCShell tests are being run.

Просмотреть файл

@ -146,3 +146,12 @@ EXTRA_LIBS += $(call EXPAND_LIBNAME,advapi32)
endif
CXXFLAGS += $(BZ2_CFLAGS)
ifneq (,$(filter beta release esr,$(MOZ_UPDATE_CHANNEL)))
RCFLAGS += -DMAR_SIGNING_RELEASE_BETA=1
else
ifneq (,$(filter nightly aurora nightly-elm nightly-profiling nightly-oak,$(MOZ_UPDATE_CHANNEL)))
RCFLAGS += -DMAR_SIGNING_AURORA_NIGHTLY=1
endif
endif

Просмотреть файл

@ -54,6 +54,96 @@ static int outbuf_size = 262144;
static char *inbuf = NULL;
static char *outbuf = NULL;
#ifdef XP_WIN
#include "resource.h"
/**
* Obtains the data of the specified resource name and type.
*
* @param name The name ID of the resource
* @param type The type ID of the resource
* @param data Out parameter which sets the pointer to a buffer containing
* the needed data.
* @param size Out parameter which sets the size of the returned data buffer
* @return TRUE on success
*/
BOOL
LoadFileInResource(int name, int type, const char *&data, DWORD& size)
{
HMODULE handle = GetModuleHandle(NULL);
if (!handle) {
return FALSE;
}
HRSRC resourceInfoBlockHandle = FindResource(handle,
MAKEINTRESOURCE(name),
MAKEINTRESOURCE(type));
if (!resourceInfoBlockHandle) {
FreeLibrary(handle);
return FALSE;
}
HGLOBAL resourceHandle = LoadResource(handle, resourceInfoBlockHandle);
if (!resourceHandle) {
FreeLibrary(handle);
return FALSE;
}
size = SizeofResource(handle, resourceInfoBlockHandle);
data = static_cast<const char*>(::LockResource(resourceHandle));
FreeLibrary(handle);
return TRUE;
}
/**
* 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 name The name ID of the resource
* @param type THe type ID of the resource
* @return OK on success, CERT_LOAD_ERROR or CERT_VERIFY_ERROR on failure.
*/
int
VerifyLoadedCert(MarFile *archive, int name, int type)
{
DWORD size = 0;
const char *data = NULL;
if (!LoadFileInResource(name, type, data, size) || !data || !size) {
return CERT_LOAD_ERROR;
}
if (!archive || mar_verify_signatureW(archive, data, size)) {
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()
{
#ifdef XP_WIN
int rv = VerifyLoadedCert(mArchive, IDR_PRIMARY_CERT, TYPE_CERT);
if (rv != OK) {
rv = VerifyLoadedCert(mArchive, IDR_BACKUP_CERT, TYPE_CERT);
}
return rv;
#else
return OK;
#endif
}
int
ArchiveReader::Open(const NS_tchar *path)
{

Просмотреть файл

@ -56,6 +56,7 @@ public:
~ArchiveReader() { Close(); }
int Open(const NS_tchar *path);
int VerifySignature();
void Close();
int ExtractFile(const char *item, const NS_tchar *destination);

Просмотреть файл

@ -6,6 +6,9 @@
#define IDC_PROGRESS 1000
#define IDC_INFO 1002
#define IDI_DIALOG 1003
#define TYPE_CERT 512
#define IDR_PRIMARY_CERT 1004
#define IDR_BACKUP_CERT 1005
#define IDS_UPDATER_IDENTITY 1006
// Next default values for new objects

Просмотреть файл

@ -1535,11 +1535,15 @@ UpdateThreadFunc(void *param)
{
// open ZIP archive and process...
int rv;
NS_tchar dataFile[MAXPATHLEN];
NS_tsnprintf(dataFile, sizeof(dataFile)/sizeof(dataFile[0]),
NS_T("%s/update.mar"), gSourcePath);
int rv = gArchiveReader.Open(dataFile);
rv = gArchiveReader.Open(dataFile);
if (rv == OK) {
rv = gArchiveReader.VerifySignature();
}
if (rv == OK) {
rv = DoUpdate();
gArchiveReader.Close();
@ -2011,7 +2015,7 @@ int NS_main(int argc, NS_tchar **argv)
const int max_retries = 10;
int retries = 1;
do {
// By opening a file handle wihout FILE_SHARE_READ to the callback
// By opening a file handle without FILE_SHARE_READ to the callback
// executable, the OS will prevent launching the process while it is
// being updated.
callbackFile = CreateFileW(argv[callbackIndex],

Просмотреть файл

@ -36,6 +36,23 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
IDI_DIALOG ICON "updater.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Embedded certificates for allowed MARs
//
#if defined(MAR_SIGNING_RELEASE_BETA)
IDR_PRIMARY_CERT TYPE_CERT "release_primary.der"
IDR_BACKUP_CERT TYPE_CERT "release_secondary.der"
#elif defined(MAR_SIGNING_AURORA_NIGHTLY)
IDR_PRIMARY_CERT TYPE_CERT "nightly_aurora_level3_primary.der"
IDR_BACKUP_CERT TYPE_CERT "nightly_aurora_level3_secondary.der"
#else
IDR_PRIMARY_CERT TYPE_CERT "dep1.der"
IDR_BACKUP_CERT TYPE_CERT "dep2.der"
#endif
/////////////////////////////////////////////////////////////////////////////
//
// Embedded an identifier to uniquely identiy this as a Mozilla updater.