mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1178518 - Packaged App Utils. r=valentin
This commit is contained in:
parent
50eb249b57
commit
ae5a452f5b
@ -410,6 +410,8 @@
|
|||||||
@RESPATH@/components/AlarmsManager.manifest
|
@RESPATH@/components/AlarmsManager.manifest
|
||||||
@RESPATH@/components/FeedProcessor.manifest
|
@RESPATH@/components/FeedProcessor.manifest
|
||||||
@RESPATH@/components/FeedProcessor.js
|
@RESPATH@/components/FeedProcessor.js
|
||||||
|
@RESPATH@/components/PackagedAppUtils.manifest
|
||||||
|
@RESPATH@/components/PackagedAppUtils.js
|
||||||
@RESPATH@/components/BrowserFeeds.manifest
|
@RESPATH@/components/BrowserFeeds.manifest
|
||||||
@RESPATH@/components/FeedConverter.js
|
@RESPATH@/components/FeedConverter.js
|
||||||
@RESPATH@/components/FeedWriter.js
|
@RESPATH@/components/FeedWriter.js
|
||||||
|
@ -369,6 +369,8 @@
|
|||||||
@RESPATH@/components/BrowserElementParent.js
|
@RESPATH@/components/BrowserElementParent.js
|
||||||
@RESPATH@/components/FeedProcessor.manifest
|
@RESPATH@/components/FeedProcessor.manifest
|
||||||
@RESPATH@/components/FeedProcessor.js
|
@RESPATH@/components/FeedProcessor.js
|
||||||
|
@RESPATH@/components/PackagedAppUtils.js
|
||||||
|
@RESPATH@/components/PackagedAppUtils.manifest
|
||||||
@RESPATH@/browser/components/BrowserFeeds.manifest
|
@RESPATH@/browser/components/BrowserFeeds.manifest
|
||||||
@RESPATH@/browser/components/FeedConverter.js
|
@RESPATH@/browser/components/FeedConverter.js
|
||||||
@RESPATH@/browser/components/FeedWriter.js
|
@RESPATH@/browser/components/FeedWriter.js
|
||||||
|
@ -308,6 +308,8 @@
|
|||||||
@BINPATH@/components/SettingsService.manifest
|
@BINPATH@/components/SettingsService.manifest
|
||||||
@BINPATH@/components/BrowserElementParent.manifest
|
@BINPATH@/components/BrowserElementParent.manifest
|
||||||
@BINPATH@/components/BrowserElementParent.js
|
@BINPATH@/components/BrowserElementParent.js
|
||||||
|
@BINPATH@/components/PackagedAppUtils.manifest
|
||||||
|
@BINPATH@/components/PackagedAppUtils.js
|
||||||
@BINPATH@/components/BrowserFeeds.manifest
|
@BINPATH@/components/BrowserFeeds.manifest
|
||||||
@BINPATH@/components/FeedConverter.js
|
@BINPATH@/components/FeedConverter.js
|
||||||
@BINPATH@/components/FeedWriter.js
|
@BINPATH@/components/FeedWriter.js
|
||||||
|
@ -311,6 +311,8 @@
|
|||||||
@BINPATH@/components/BrowserElementParent.js
|
@BINPATH@/components/BrowserElementParent.js
|
||||||
@BINPATH@/components/FeedProcessor.manifest
|
@BINPATH@/components/FeedProcessor.manifest
|
||||||
@BINPATH@/components/FeedProcessor.js
|
@BINPATH@/components/FeedProcessor.js
|
||||||
|
@BINPATH@/components/PackagedAppUtils.manifest
|
||||||
|
@BINPATH@/components/PackagedAppUtils.js
|
||||||
@BINPATH@/components/BrowserFeeds.manifest
|
@BINPATH@/components/BrowserFeeds.manifest
|
||||||
@BINPATH@/components/FeedConverter.js
|
@BINPATH@/components/FeedConverter.js
|
||||||
@BINPATH@/components/FeedWriter.js
|
@BINPATH@/components/FeedWriter.js
|
||||||
|
@ -70,6 +70,7 @@ XPIDL_SOURCES += [
|
|||||||
'nsINullChannel.idl',
|
'nsINullChannel.idl',
|
||||||
'nsIPACGenerator.idl',
|
'nsIPACGenerator.idl',
|
||||||
'nsIPackagedAppService.idl',
|
'nsIPackagedAppService.idl',
|
||||||
|
'nsIPackagedAppUtils.idl',
|
||||||
'nsIPackagedAppVerifier.idl',
|
'nsIPackagedAppVerifier.idl',
|
||||||
'nsIParentChannel.idl',
|
'nsIParentChannel.idl',
|
||||||
'nsIParentRedirectingChannel.idl',
|
'nsIParentRedirectingChannel.idl',
|
||||||
|
68
netwerk/base/nsIPackagedAppUtils.idl
Normal file
68
netwerk/base/nsIPackagedAppUtils.idl
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
#include "nsISupports.idl"
|
||||||
|
|
||||||
|
interface nsIVerificationCallback;
|
||||||
|
|
||||||
|
%{C++
|
||||||
|
#define NS_PACKAGEDAPPUTILS_CONTRACTID "@mozilla.org/network/packaged-app-utils;1"
|
||||||
|
%}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A package using privileged APIs should be signed by marketplace or trust-
|
||||||
|
* worthy developers. When Necko receives such a package, it has to
|
||||||
|
* extract the manifest and the signature and calls verifyManifest(...) to verify
|
||||||
|
* the manifest. nsIPackagedAppUtils will parse the manifest and
|
||||||
|
* store the hash values of each resource. When a resource is ready, Necko
|
||||||
|
* will calculate its hash value (including the header like Content-Location: xxx),
|
||||||
|
* and calls checkIntegrity(...) to verify the integrity.
|
||||||
|
*
|
||||||
|
* For more detail:
|
||||||
|
* https://wiki.mozilla.org/FirefoxOS/New_security_model/Packaging
|
||||||
|
*/
|
||||||
|
|
||||||
|
[scriptable, uuid(d0a98a69-a215-4cf9-abb3-7a0b9237cd27)]
|
||||||
|
interface nsIPackagedAppUtils : nsISupports
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @aHeader is the package's header including
|
||||||
|
* - "manifest-signature: xxxxxx" (base64 encoding)
|
||||||
|
* @aManifest is the manifest of the package
|
||||||
|
* - the multipart header is included
|
||||||
|
* - manifest must be the first resource of the package
|
||||||
|
* @aCallback is the callback, see comments of nsIVerificationCallback below
|
||||||
|
*/
|
||||||
|
void verifyManifest(in ACString aHeader,
|
||||||
|
in ACString aManifest,
|
||||||
|
in nsIVerificationCallback aVerifier);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @aFileName is the name of a resource in the package
|
||||||
|
* @aHashValue is the hash value of this resource named aFileName
|
||||||
|
* - aHashValue should be computed by the caller of this method
|
||||||
|
* @aCallback is the callback, see comments of nsIVerificationCallback below
|
||||||
|
*/
|
||||||
|
void checkIntegrity(in ACString aFileName,
|
||||||
|
in ACString aHashValue,
|
||||||
|
in nsIVerificationCallback aVerifier);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The callback passed to verifyManifest and checkIntegrity
|
||||||
|
*/
|
||||||
|
[scriptable, uuid(e1912028-93e5-4378-aa3f-a58702937169)]
|
||||||
|
interface nsIVerificationCallback : nsISupports
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @aForManifest
|
||||||
|
* - true if it's called by verifyManifest
|
||||||
|
* - false if it's called by checkIntegrity
|
||||||
|
* @aSuccess
|
||||||
|
* - true if the verification succeeds, false otherwise
|
||||||
|
*/
|
||||||
|
void fireVerifiedEvent(in boolean aForManifest,
|
||||||
|
in boolean aSuccess);
|
||||||
|
};
|
109
netwerk/protocol/http/PackagedAppUtils.js
Normal file
109
netwerk/protocol/http/PackagedAppUtils.js
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
|
||||||
|
const PACKAGEDAPPUTILS_CONTRACTID = "@mozilla.org/network/packaged-app-utils;1";
|
||||||
|
const PACKAGEDAPPUTILS_CID = Components.ID("{fe8f1c2e-3c13-11e5-9a3f-bbf47d1e6697}");
|
||||||
|
|
||||||
|
function PackagedAppUtils() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let DEBUG = 0
|
||||||
|
function debug(s) {
|
||||||
|
if (DEBUG) {
|
||||||
|
dump("-*- PackagedAppUtils: " + s + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PackagedAppUtils.prototype = {
|
||||||
|
classID: PACKAGEDAPPUTILS_CID,
|
||||||
|
contractID: PACKAGEDAPPUTILS_CONTRACTID,
|
||||||
|
classDescription: "Packaged App Utils",
|
||||||
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPackagedAppUtils]),
|
||||||
|
|
||||||
|
verifyManifest: function(aHeader, aManifest, aCallback) {
|
||||||
|
debug("Manifest: " + aManifest);
|
||||||
|
|
||||||
|
// parse signature from header
|
||||||
|
let signature;
|
||||||
|
const signatureField = "manifest-signature: ";
|
||||||
|
for (let item of aHeader.split('\r\n')) {
|
||||||
|
if (item.substr(0, signatureField.length) == signatureField) {
|
||||||
|
signature = item.substr(signatureField.length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!signature) {
|
||||||
|
debug("No signature in header");
|
||||||
|
aCallback.fireVerifiedEvent(true, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
debug("Signature: " + signature);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Base64 decode
|
||||||
|
signature = atob(signature);
|
||||||
|
|
||||||
|
// Remove header
|
||||||
|
let manifestBody = aManifest.substr(aManifest.indexOf('\r\n\r\n') + 4);
|
||||||
|
debug("manifestBody: " + manifestBody);
|
||||||
|
|
||||||
|
// Parse manifest, store resource hashes
|
||||||
|
this.resources = JSON.parse(manifestBody)["moz-resources"];
|
||||||
|
} catch (e) {
|
||||||
|
debug("JSON parsing failure");
|
||||||
|
aCallback.fireVerifiedEvent(true, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let manifestStream = Cc["@mozilla.org/io/string-input-stream;1"]
|
||||||
|
.createInstance(Ci.nsIStringInputStream);
|
||||||
|
let signatureStream = Cc["@mozilla.org/io/string-input-stream;1"]
|
||||||
|
.createInstance(Ci.nsIStringInputStream);
|
||||||
|
manifestStream.setData(aManifest, aManifest.length);
|
||||||
|
signatureStream.setData(signature, signature.length);
|
||||||
|
|
||||||
|
let certDb;
|
||||||
|
try {
|
||||||
|
certDb = Cc["@mozilla.org/security/x509certdb;1"]
|
||||||
|
.getService(Ci.nsIX509CertDB);
|
||||||
|
} catch (e) {
|
||||||
|
debug("nsIX509CertDB error: " + e);
|
||||||
|
// unrecoverable error, don't bug the user
|
||||||
|
throw "CERTDB_ERROR";
|
||||||
|
}
|
||||||
|
|
||||||
|
certDb.verifySignedManifestAsync(
|
||||||
|
Ci.nsIX509CertDB.PrivilegedPackageRoot, manifestStream, signatureStream,
|
||||||
|
function(aRv, aCert) {
|
||||||
|
aCallback.fireVerifiedEvent(true, Components.isSuccessCode(aRv));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
checkIntegrity: function(aFileName, aHashValue, aCallback) {
|
||||||
|
debug("checkIntegrity() " + aFileName + ": " + aHashValue + "\n");
|
||||||
|
if (!this.resources) {
|
||||||
|
debug("resource hashes not found");
|
||||||
|
aCallback.fireVerifiedEvent(false, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (let r of this.resources) {
|
||||||
|
if (r.src === aFileName) {
|
||||||
|
debug("found integrity = " + r.integrity);
|
||||||
|
aCallback.fireVerifiedEvent(false, r.integrity === aHashValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aCallback.fireVerifiedEvent(false, false);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PackagedAppUtils]);
|
3
netwerk/protocol/http/PackagedAppUtils.manifest
Normal file
3
netwerk/protocol/http/PackagedAppUtils.manifest
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# PackagedAppUtils.js
|
||||||
|
component {fe8f1c2e-3c13-11e5-9a3f-bbf47d1e6697} PackagedAppUtils.js
|
||||||
|
contract @mozilla.org/network/packaged-app-utils;1 {fe8f1c2e-3c13-11e5-9a3f-bbf47d1e6697}
|
@ -113,3 +113,8 @@ LOCAL_INCLUDES += [
|
|||||||
'/dom/base',
|
'/dom/base',
|
||||||
'/netwerk/base',
|
'/netwerk/base',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
EXTRA_COMPONENTS += [
|
||||||
|
'PackagedAppUtils.js',
|
||||||
|
'PackagedAppUtils.manifest',
|
||||||
|
]
|
||||||
|
135
netwerk/test/unit/test_packaged_app_utils.js
Normal file
135
netwerk/test/unit/test_packaged_app_utils.js
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
const header_missing_signature = "header1: content1";
|
||||||
|
const header_invalid_signature = "header1: content1\r\nmanifest-signature: invalid-signature\r\n";
|
||||||
|
const header = "manifest-signature: MIIF1AYJKoZIhvcNAQcCoIIFxTCCBcECAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCA54wggOaMIICgqADAgECAgECMA0GCSqGSIb3DQEBCwUAMHMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEkMCIGA1UEChMbRXhhbXBsZSBUcnVzdGVkIENvcnBvcmF0aW9uMRkwFwYDVQQDExBUcnVzdGVkIFZhbGlkIENBMB4XDTE1MDkxMDA4MDQzNVoXDTM1MDkxMDA4MDQzNVowdDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSQwIgYDVQQKExtFeGFtcGxlIFRydXN0ZWQgQ29ycG9yYXRpb24xGjAYBgNVBAMTEVRydXN0ZWQgQ29ycCBDZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAts8whjOzEbn/w1xkFJ67af7F/JPujBK91oyJekh2schIMzFau9pY8S1AiJQoJCulOJCJfUc8hBLKBZiGAkii+4Gpx6cVqMLe6C22MdD806Soxn8Dg4dQqbIvPuI4eeVKu5CEk80PW/BaFMmRvRHO62C7PILuH6yZeGHC4P7dTKpsk4CLxh/jRGXLC8jV2BCW0X+3BMbHBg53NoI9s1Gs7KGYnfOHbBP5wEFAa00RjHnubUaCdEBlC8Kl4X7p0S4RGb3rsB08wgFe9EmSZHIgcIm+SuVo7N4qqbI85qo2ulU6J8NN7ZtgMPHzrMhzgAgf/KnqPqwDIxnNmRNJmHTUYwIDAQABozgwNjAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMDMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAukH6cJUUj5faa8CuPCqrEa0PoLY4SYNnff9NI+TTAHkB9l+kOcFl5eo2EQOcWmZKYi7QLlWC4jy/KQYattO9FMaxiOQL4FAc6ZIbNyfwWBzZWyr5syYJTTTnkLq8A9pCKarN49+FqhJseycU+8EhJEJyP5pv5hLvDNTTHOQ6SXhASsiX8cjo3AY4bxA5pWeXuTZ459qDxOnQd+GrOe4dIeqflk0hA2xYKe3SfF+QlK8EO370B8Dj8RX230OATM1E3OtYyALe34KW3wM9Qm9rb0eViDnVyDiCWkhhQnw5yPg/XQfloug2itRYuCnfUoRt8xfeHgwz2Ymz8cUADn3KpTGCAf4wggH6AgEBMHgwczELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSQwIgYDVQQKExtFeGFtcGxlIFRydXN0ZWQgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFRydXN0ZWQgVmFsaWQgQ0ECAQIwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE1MDkxMDA4MDQ0M1owIwYJKoZIhvcNAQkEMRYEFNg6lGtV9bJbL2hA0c5DdOeuCQ6lMA0GCSqGSIb3DQEBAQUABIIBAKGziwzA5Q38rIvNUDHCjYVTR1FhALGZv677Tc2+pwd82W6O9q5GG9IfkF3ajb1fquUIpGPkf7r0oiO4udC8cSehA+lfhR94A8aCM9UhzvTtRI3tFB+TPSk1UcXlX8tB7dNkx4zC06ujlSaRKkmaZODVXQFEcsF6CKMApsBuUJrwzvbQqVi2KHXUO6oGlMEyt4tY+g2OY/vyxGajfAL49dAYOTtrV0arvJvoTYh+E0iSrsbuiuAxKAVjK/QnLJoV/dTaCqW4t3lzHrpE3+avqMXiewxu84VJSURxoryY89uAZS9+4MKrSOGlGCJy/8xDIAm9pi6lPJBP2pIRjaRt9r0=\r\n";
|
||||||
|
|
||||||
|
const manifest = "Content-Location: manifest.webapp\r\n" +
|
||||||
|
"Content-Type: application/x-web-app-manifest+json\r\n\r\n" +
|
||||||
|
`{
|
||||||
|
"name": "My App",
|
||||||
|
"moz-resources": [
|
||||||
|
{
|
||||||
|
"src": "page2.html",
|
||||||
|
"integrity": "JREF3JbXGvZ+I1KHtoz3f46ZkeIPrvXtG4VyFQrJ7II="
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "index.html",
|
||||||
|
"integrity": "B5Phw8L1tpyRBkI0gwg/evy1fgtMlMq3BIY3Q8X0rYU="
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "scripts/script.js",
|
||||||
|
"integrity": "6TqtNArQKrrsXEQWu3D9ZD8xvDRIkhyV6zVdTcmsT5Q="
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "scripts/library.js",
|
||||||
|
"integrity": "TN2ByXZiaBiBCvS4MeZ02UyNi44vED+KjdjLInUl4o8="
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"moz-permissions": [
|
||||||
|
{
|
||||||
|
"systemXHR": {
|
||||||
|
"description": "Needed to download stuff"
|
||||||
|
},
|
||||||
|
"devicestorage:pictures": {
|
||||||
|
"description": "Need to load pictures"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"moz-uuid": "some-uuid",
|
||||||
|
"moz-package-location": "https://example.com/myapp/app.pak",
|
||||||
|
"description": "A great app!"
|
||||||
|
}`;
|
||||||
|
|
||||||
|
const manifest_missing_moz_resources = "Content-Location: manifest.webapp\r\n" +
|
||||||
|
"Content-Type: application/x-web-app-manifest+json\r\n\r\n" +
|
||||||
|
`{
|
||||||
|
"name": "My App",
|
||||||
|
"moz-permissions": [
|
||||||
|
{
|
||||||
|
"systemXHR": {
|
||||||
|
"description": "Needed to download stuff"
|
||||||
|
},
|
||||||
|
"devicestorage:pictures": {
|
||||||
|
"description": "Need to load pictures"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"moz-uuid": "some-uuid",
|
||||||
|
"moz-package-location": "https://example.com/myapp/app.pak",
|
||||||
|
"description": "A great app!"
|
||||||
|
}`;
|
||||||
|
|
||||||
|
const manifest_malformed_json = "}";
|
||||||
|
|
||||||
|
let packagedAppUtils;
|
||||||
|
|
||||||
|
function run_test() {
|
||||||
|
add_test(test_verify_manifest(header_missing_signature, manifest, false));
|
||||||
|
add_test(test_verify_manifest(header_invalid_signature, manifest, false));
|
||||||
|
add_test(test_verify_manifest(header, manifest_malformed_json, false));
|
||||||
|
add_test(test_verify_manifest(header, manifest_missing_moz_resources, false));
|
||||||
|
add_test(test_verify_manifest(header, manifest, true));
|
||||||
|
|
||||||
|
// The last verification must succeed, because check_integrity use that object;
|
||||||
|
add_test(test_check_integrity_success);
|
||||||
|
add_test(test_check_integrity_filename_not_matched);
|
||||||
|
add_test(test_check_integrity_hashvalue_not_matched);
|
||||||
|
|
||||||
|
run_next_test();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_verify_manifest(aHeader, aManifest, aShouldSucceed) {
|
||||||
|
return function() {
|
||||||
|
do_test_pending();
|
||||||
|
packagedAppUtils = Cc["@mozilla.org/network/packaged-app-utils;1"].
|
||||||
|
createInstance(Ci.nsIPackagedAppUtils);
|
||||||
|
let fakeVerifier = {
|
||||||
|
fireVerifiedEvent: function(aForManifest, aSuccess) {
|
||||||
|
ok(aForManifest, "aForManifest should be true");
|
||||||
|
equal(aSuccess, aShouldSucceed, "Expected verification result: " + aShouldSucceed);
|
||||||
|
do_test_finished();
|
||||||
|
run_next_test();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
packagedAppUtils.verifyManifest(aHeader, aManifest, fakeVerifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_check_integrity_success() {
|
||||||
|
let manifestBody = manifest.substr(manifest.indexOf('\r\n\r\n') + 4);
|
||||||
|
fakeVerifier = {
|
||||||
|
fireVerifiedEvent: function(aForManifest, aSuccess) {
|
||||||
|
ok(!aForManifest && aSuccess, "checkIntegrity should succeed");
|
||||||
|
do_test_finished();
|
||||||
|
run_next_test();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (let resource of JSON.parse(manifestBody)["moz-resources"]) {
|
||||||
|
do_test_pending();
|
||||||
|
packagedAppUtils.checkIntegrity(resource.src, resource.integrity, fakeVerifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_check_integrity_filename_not_matched() {
|
||||||
|
fakeVerifier = {
|
||||||
|
fireVerifiedEvent: function(aForManifest, aSuccess) {
|
||||||
|
ok(!aForManifest && !aSuccess, "checkIntegrity should fail");
|
||||||
|
do_test_finished();
|
||||||
|
run_next_test();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
do_test_pending();
|
||||||
|
packagedAppUtils.checkIntegrity("/nosuchfile.html", "sha256-kass...eoirW-e", fakeVerifier);
|
||||||
|
run_next_test();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_check_integrity_hashvalue_not_matched() {
|
||||||
|
fakeVerifier = {
|
||||||
|
fireVerifiedEvent: function(aForManifest, aSuccess) {
|
||||||
|
ok(!aForManifest && !aSuccess, "checkIntegrity should fail");
|
||||||
|
do_test_finished();
|
||||||
|
run_next_test();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
do_test_pending();
|
||||||
|
packagedAppUtils.checkIntegrity("/index.html", "kass...eoirW-e", fakeVerifier);
|
||||||
|
}
|
@ -323,6 +323,7 @@ skip-if = os == "android"
|
|||||||
[test_safeoutputstream_append.js]
|
[test_safeoutputstream_append.js]
|
||||||
[test_packaged_app_service.js]
|
[test_packaged_app_service.js]
|
||||||
[test_packaged_app_verifier.js]
|
[test_packaged_app_verifier.js]
|
||||||
|
[test_packaged_app_utils.js]
|
||||||
[test_suspend_channel_before_connect.js]
|
[test_suspend_channel_before_connect.js]
|
||||||
[test_inhibit_caching.js]
|
[test_inhibit_caching.js]
|
||||||
[test_dns_disable_ipv4.js]
|
[test_dns_disable_ipv4.js]
|
||||||
|
Loading…
Reference in New Issue
Block a user