Bug 926219 - Relax the signature validation for locally installed apps. r=bsmith, r=fabrice

This commit is contained in:
Antonio M. Amaya 2013-11-19 20:41:54 +01:00
parent 196a737ae9
commit 80a43b3784

View File

@ -9,6 +9,28 @@ const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
// Possible errors thrown by the signature verifier.
const SEC_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SEC_ERROR_BASE;
const SEC_ERROR_EXPIRED_CERTIFICATE = (SEC_ERROR_BASE + 11);
// We need this to decide if we should accept or not files signed with expired
// certificates.
function buildIDToTime() {
let platformBuildID =
Cc["@mozilla.org/xre/app-info;1"]
.getService(Ci.nsIXULAppInfo).platformBuildID;
let platformBuildIDDate = new Date();
platformBuildIDDate.setUTCFullYear(platformBuildID.substr(0,4),
platformBuildID.substr(4,2) - 1,
platformBuildID.substr(6,2));
platformBuildIDDate.setUTCHours(platformBuildID.substr(8,2),
platformBuildID.substr(10,2),
platformBuildID.substr(12,2));
return platformBuildIDDate.getTime();
}
const PLATFORM_BUILD_ID_TIME = buildIDToTime();
this.EXPORTED_SYMBOLS = ["DOMApplicationRegistry"];
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@ -38,6 +60,10 @@ function debug(aMsg) {
#endif
}
function getNSPRErrorCode(err) {
return -1 * ((err) & 0xffff);
}
function supportUseCurrentProfile() {
return Services.prefs.getBoolPref("dom.webapps.useCurrentProfile");
}
@ -2485,6 +2511,10 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
// Check if it's a local file install (we've downloaded/sideloaded the
// package already or it did exist on the build).
// Note that this variable also controls whether files signed with expired
// certificates are accepted or not. If isLocalFileInstall is true and the
// device date is earlier than the build generation date, then the signature
// will be accepted even if the certificate is expired.
let isLocalFileInstall =
Services.io.extractScheme(fullPackagePath) === 'file';
@ -2837,7 +2867,8 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
let zipReader, isSigned, newManifest;
try {
[zipReader, isSigned] = yield this._openPackage(aZipFile, aOldApp);
[zipReader, isSigned] = yield this._openPackage(aZipFile, aOldApp,
aIsLocalFileInstall);
newManifest = yield this._readPackage(aOldApp, aNewApp,
aIsLocalFileInstall, aIsUpdate, aManifest, aRequestChannel,
aHash, zipReader, isSigned);
@ -2868,7 +2899,7 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
}).bind(this));
},
_openPackage: function(aZipFile, aApp) {
_openPackage: function(aZipFile, aApp, aIsLocalFileInstall) {
return Task.spawn((function*() {
let certDb;
try {
@ -2883,16 +2914,30 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
let [result, zipReader] = yield this._openSignedPackage(aZipFile, certDb);
// We cannot really know if the system date is correct or
// not. What we can know is if it's after the build date or not,
// and assume the build date is correct (which we cannot
// really know either).
let isLaterThanBuildTime = Date.now() > PLATFORM_BUILD_ID_TIME;
let isSigned;
if (Components.isSuccessCode(result)) {
isSigned = true;
} else if (result == Cr.NS_ERROR_FILE_CORRUPTED) {
throw "APP_PACKAGE_CORRUPTED";
} else if (result != Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED) {
} else if ((!aIsLocalFileInstall || isLaterThanBuildTime) &&
(result != Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED)) {
throw "INVALID_SIGNATURE";
} else {
isSigned = false;
// If it's a localFileInstall and the validation failed
// because of a expired certificate, just assume it was valid
// and that the error occurred because the system time has not
// been set yet.
isSigned = (aIsLocalFileInstall &&
(getNSPRErrorCode(result) ==
SEC_ERROR_EXPIRED_CERTIFICATE));
zipReader = Cc["@mozilla.org/libjar/zip-reader;1"]
.createInstance(Ci.nsIZipReader);
zipReader.open(aZipFile);