mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 1178448 - Use imported CA in developer mode. r=keeler,valentin
This commit is contained in:
parent
4f4e1f466b
commit
e4b1f62b85
@ -24,7 +24,7 @@ interface nsIVerificationCallback;
|
||||
* https://wiki.mozilla.org/FirefoxOS/New_security_model/Packaging
|
||||
*/
|
||||
|
||||
[scriptable, uuid(cc245638-6a38-4f70-8d77-21c55aabd636)]
|
||||
[scriptable, uuid(edf91fee-ef4a-4479-9136-27eb3b7a6312)]
|
||||
interface nsIPackagedAppUtils : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -37,7 +37,8 @@ interface nsIPackagedAppUtils : nsISupports
|
||||
*/
|
||||
void verifyManifest(in ACString aHeader,
|
||||
in ACString aManifest,
|
||||
in nsIVerificationCallback aVerifier);
|
||||
in nsIVerificationCallback aVerifier,
|
||||
in boolean aDeveloperMode);
|
||||
|
||||
/**
|
||||
* @aFileName is the name of a resource in the package
|
||||
|
@ -29,7 +29,7 @@ PackagedAppUtils.prototype = {
|
||||
classDescription: "Packaged App Utils",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPackagedAppUtils]),
|
||||
|
||||
verifyManifest: function(aHeader, aManifest, aCallback) {
|
||||
verifyManifest: function(aHeader, aManifest, aCallback, aDeveloperMode) {
|
||||
debug("Manifest: " + aManifest);
|
||||
|
||||
// parse signature from header
|
||||
@ -83,8 +83,10 @@ PackagedAppUtils.prototype = {
|
||||
throw "CERTDB_ERROR";
|
||||
}
|
||||
|
||||
certDb.verifySignedManifestAsync(
|
||||
Ci.nsIX509CertDB.PrivilegedPackageRoot, manifestStream, signatureStream,
|
||||
let trustedRoot = aDeveloperMode ? Ci.nsIX509CertDB.DeveloperImportedRoot
|
||||
: Ci.nsIX509CertDB.PrivilegedPackageRoot;
|
||||
|
||||
certDb.verifySignedManifestAsync(trustedRoot, manifestStream, signatureStream,
|
||||
function(aRv, aCert) {
|
||||
aCallback.fireVerifiedEvent(true, Components.isSuccessCode(aRv));
|
||||
});
|
||||
|
@ -128,7 +128,7 @@ PackagedAppVerifier::WriteManifest(nsIInputStream* aStream,
|
||||
uint32_t* aWriteCount)
|
||||
{
|
||||
LOG(("WriteManifest: length %u", aCount));
|
||||
LOG(("%s", aFromRawSegment));
|
||||
LOG(("%s", nsCString(aFromRawSegment, aCount).get()));
|
||||
nsCString* manifest = static_cast<nsCString*>(aManifest);
|
||||
manifest->AppendASCII(aFromRawSegment, aCount);
|
||||
*aWriteCount = aCount;
|
||||
@ -277,7 +277,8 @@ PackagedAppVerifier::VerifyManifest(const ResourceCacheInfo* aInfo)
|
||||
|
||||
LOG(("Signature: length = %u\n%s", mSignature.Length(), mSignature.get()));
|
||||
LOG(("Manifest: length = %u\n%s", mManifest.Length(), mManifest.get()));
|
||||
nsresult rv = mPackagedAppUtils->VerifyManifest(mSignature, mManifest, this);
|
||||
nsresult rv = mPackagedAppUtils->VerifyManifest(mSignature, mManifest,
|
||||
this, gDeveloperMode);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("VerifyManifest FAILED rv = %u", (unsigned)rv));
|
||||
}
|
||||
@ -304,12 +305,6 @@ PackagedAppVerifier::VerifyResource(const ResourceCacheInfo* aInfo)
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
if (gDeveloperMode) {
|
||||
LOG(("Developer mode! Bypass integrity check."));
|
||||
FireVerifiedEvent(false, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSignature.IsEmpty()) {
|
||||
LOG(("No signature. No need to do resource integrity check."));
|
||||
FireVerifiedEvent(false, true);
|
||||
|
@ -5,33 +5,79 @@ var Cu = Components.utils;
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
response.setHeader("Content-Type", "application/package", false);
|
||||
response.write(octetStreamData.packageHeader + octetStreamData.getData());
|
||||
response.write(signedPackage);
|
||||
return;
|
||||
}
|
||||
|
||||
// The package content
|
||||
// getData formats it as described at http://www.w3.org/TR/web-packaging/#streamable-package-format
|
||||
var octetStreamData = {
|
||||
packageHeader: 'manifest-signature: dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk\r\n',
|
||||
|
||||
content: [
|
||||
{ headers: ["Content-Location: /index.html", "Content-Type: text/html"], data: "<html>\r\n <head>\r\n <script> alert('OK: hello'); alert('DONE'); </script>\r\n</head>\r\n Web Packaged App Index\r\n</html>\r\n", type: "text/html" },
|
||||
{ headers: ["Content-Location: /scripts/app.js", "Content-Type: text/javascript"], data: "module Math from '/scripts/helpers/math.js';\r\n...\r\n", type: "text/javascript" },
|
||||
{ headers: ["Content-Location: /scripts/helpers/math.js", "Content-Type: text/javascript"], data: "export function sum(nums) { ... }\r\n...\r\n", type: "text/javascript" }
|
||||
],
|
||||
token : "gc0pJq0M:08jU534c0p",
|
||||
getData: function() {
|
||||
var str = "";
|
||||
for (var i in this.content) {
|
||||
str += "--" + this.token + "\r\n";
|
||||
for (var j in this.content[i].headers) {
|
||||
str += this.content[i].headers[j] + "\r\n";
|
||||
}
|
||||
str += "\r\n";
|
||||
str += this.content[i].data + "\r\n";
|
||||
}
|
||||
|
||||
str += "--" + this.token + "--";
|
||||
return str;
|
||||
}
|
||||
}
|
||||
var signedPackage = [
|
||||
"manifest-signature: MIIF1AYJKoZIhvcNAQcCoIIFxTCCBcECAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCA54wggOaMIICgqADAgECAgECMA0GCSqGSIb3DQEBCwUAMHMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEkMCIGA1UEChMbRXhhbXBsZSBUcnVzdGVkIENvcnBvcmF0aW9uMRkwFwYDVQQDExBUcnVzdGVkIFZhbGlkIENBMB4XDTE1MDkxMDA4MDQzNVoXDTM1MDkxMDA4MDQzNVowdDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSQwIgYDVQQKExtFeGFtcGxlIFRydXN0ZWQgQ29ycG9yYXRpb24xGjAYBgNVBAMTEVRydXN0ZWQgQ29ycCBDZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAts8whjOzEbn/w1xkFJ67af7F/JPujBK91oyJekh2schIMzFau9pY8S1AiJQoJCulOJCJfUc8hBLKBZiGAkii+4Gpx6cVqMLe6C22MdD806Soxn8Dg4dQqbIvPuI4eeVKu5CEk80PW/BaFMmRvRHO62C7PILuH6yZeGHC4P7dTKpsk4CLxh/jRGXLC8jV2BCW0X+3BMbHBg53NoI9s1Gs7KGYnfOHbBP5wEFAa00RjHnubUaCdEBlC8Kl4X7p0S4RGb3rsB08wgFe9EmSZHIgcIm+SuVo7N4qqbI85qo2ulU6J8NN7ZtgMPHzrMhzgAgf/KnqPqwDIxnNmRNJmHTUYwIDAQABozgwNjAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMDMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAukH6cJUUj5faa8CuPCqrEa0PoLY4SYNnff9NI+TTAHkB9l+kOcFl5eo2EQOcWmZKYi7QLlWC4jy/KQYattO9FMaxiOQL4FAc6ZIbNyfwWBzZWyr5syYJTTTnkLq8A9pCKarN49+FqhJseycU+8EhJEJyP5pv5hLvDNTTHOQ6SXhASsiX8cjo3AY4bxA5pWeXuTZ459qDxOnQd+GrOe4dIeqflk0hA2xYKe3SfF+QlK8EO370B8Dj8RX230OATM1E3OtYyALe34KW3wM9Qm9rb0eViDnVyDiCWkhhQnw5yPg/XQfloug2itRYuCnfUoRt8xfeHgwz2Ymz8cUADn3KpTGCAf4wggH6AgEBMHgwczELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSQwIgYDVQQKExtFeGFtcGxlIFRydXN0ZWQgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFRydXN0ZWQgVmFsaWQgQ0ECAQIwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE1MTAwMTIxMTEwNlowIwYJKoZIhvcNAQkEMRYEFHAisUYrrt+gBxYFhZ5KQQusOmN3MA0GCSqGSIb3DQEBAQUABIIBACHW4V0BsPWOvWrGOTRj6mPpNbH/JI1bN2oyqQZrpUQoaBY+BbYxO7TY4Uwe+aeIR/TTPJznOMF/dl3Bna6TPabezU4ylg7TVFI6W7zC5f5DZKp+Xv6uTX6knUzbbW1fkJqMtE8hGUzYXc3/C++Ci6kuOzrpWOhk6DpJHeUO/ioV56H0+QK/oMAjYpEsOohaPqvTPNOBhMQ0OQP3bmuJ6HcjZ/oz96PpzXUPKT1tDe6VykIYkV5NvtC8Tu2lDbYvp9ug3gyDgdyNSV47y5i/iWkzEhsAJB+9Z50wKhplnkxxVHEXkB/6tmfvExvQ28gLd/VbaEGDX2ljCaTSUjhD0o0=\r",
|
||||
"--7B0MKBI3UH\r",
|
||||
"Content-Location: manifest.webapp\r",
|
||||
"Content-Type: application/x-web-app-manifest+json\r",
|
||||
"\r",
|
||||
"{",
|
||||
" \"name\": \"My App\",",
|
||||
" \"moz-resources\": [",
|
||||
" {",
|
||||
" \"src\": \"page2.html\",",
|
||||
" \"integrity\": \"JREF3JbXGvZ+I1KHtoz3f46ZkeIPrvXtG4VyFQrJ7II=\"",
|
||||
" },",
|
||||
" {",
|
||||
" \"src\": \"index.html\",",
|
||||
" \"integrity\": \"zEubR310nePwd30NThIuoCxKJdnz7Mf5z+dZHUbH1SE=\"",
|
||||
" },",
|
||||
" {",
|
||||
" \"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\"",
|
||||
" }",
|
||||
" }",
|
||||
" ],",
|
||||
" \"package-identifier\": \"611FC2FE-491D-4A47-B3B3-43FBDF6F404F\",",
|
||||
" \"moz-package-location\": \"https://example.com/myapp/app.pak\",",
|
||||
" \"description\": \"A great app!\"",
|
||||
"}\r",
|
||||
"--7B0MKBI3UH\r",
|
||||
"Content-Location: page2.html\r",
|
||||
"Content-Type: text/html\r",
|
||||
"\r",
|
||||
"<html>",
|
||||
" page2.html",
|
||||
"</html>",
|
||||
"\r",
|
||||
"--7B0MKBI3UH\r",
|
||||
"Content-Location: index.html\r",
|
||||
"Content-Type: text/html\r",
|
||||
"\r",
|
||||
"<html>",
|
||||
" Last updated: 2015/10/01 14:10 PST",
|
||||
"</html>",
|
||||
"\r",
|
||||
"--7B0MKBI3UH\r",
|
||||
"Content-Location: scripts/script.js\r",
|
||||
"Content-Type: text/javascript\r",
|
||||
"\r",
|
||||
"// script.js",
|
||||
"\r",
|
||||
"--7B0MKBI3UH\r",
|
||||
"Content-Location: scripts/library.js\r",
|
||||
"Content-Type: text/javascript\r",
|
||||
"\r",
|
||||
"// library.js",
|
||||
"\r",
|
||||
"--7B0MKBI3UH--"
|
||||
].join("\n");
|
||||
|
@ -21,7 +21,6 @@ var Cr = SpecialPowers.Cr;
|
||||
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ "set": [["network.http.enable-packaged-apps", true],
|
||||
["network.http.packaged-apps-developer-mode", true],
|
||||
["network.http.packaged-signed-apps-enabled", true],
|
||||
["dom.ipc.processPriorityManager.testMode", true],
|
||||
["dom.ipc.processPriorityManager.enabled", true],
|
||||
|
@ -51,7 +51,7 @@ Listener.prototype = {
|
||||
do_check_eq(this.available, count);
|
||||
// Need to consume stream to avoid assertion
|
||||
var str = new nsIBinaryInputStream(stream).readBytes(count);
|
||||
equal(str, "<html>\r\n <head>\r\n <script src=\"/scripts/app.js\"></script>\r\n ...\r\n </head>\r\n ...\r\n</html>\r\n", "check proper content");
|
||||
equal(str, "<html>\n Last updated: 2015/10/01 14:10 PST\n</html>\n", "check proper content");
|
||||
}
|
||||
catch (ex) {
|
||||
do_throw(ex);
|
||||
@ -74,7 +74,7 @@ Listener.prototype = {
|
||||
var testData = {
|
||||
packageHeader: "manifest-signature: dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk\r\n",
|
||||
content: [
|
||||
{ headers: ["Content-Location: /index.html", "Content-Type: text/html"], data: "<html>\r\n <head>\r\n <script src=\"/scripts/app.js\"></script>\r\n ...\r\n </head>\r\n ...\r\n</html>\r\n", type: "text/html" },
|
||||
{ headers: ["Content-Location: /index.html", "Content-Type: text/html"], data: "<html>\n Last updated: 2015/10/01 14:10 PST\n</html>\n", type: "text/html" },
|
||||
{ headers: ["Content-Location: /scripts/app.js", "Content-Type: text/javascript"], data: "module Math from '/scripts/helpers/math.js';\r\n...\r\n", type: "text/javascript" },
|
||||
{ headers: ["Content-Location: /scripts/helpers/math.js", "Content-Type: text/javascript"], data: "export function sum(nums) { ... }\r\n...\r\n", type: "text/javascript" }
|
||||
],
|
||||
@ -95,6 +95,79 @@ var testData = {
|
||||
}
|
||||
}
|
||||
|
||||
var badSignature = "manifest-signature: dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk\r\n";
|
||||
var goodSignature = "manifest-signature: MIIF1AYJKoZIhvcNAQcCoIIFxTCCBcECAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCA54wggOaMIICgqADAgECAgECMA0GCSqGSIb3DQEBCwUAMHMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEkMCIGA1UEChMbRXhhbXBsZSBUcnVzdGVkIENvcnBvcmF0aW9uMRkwFwYDVQQDExBUcnVzdGVkIFZhbGlkIENBMB4XDTE1MDkxMDA4MDQzNVoXDTM1MDkxMDA4MDQzNVowdDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSQwIgYDVQQKExtFeGFtcGxlIFRydXN0ZWQgQ29ycG9yYXRpb24xGjAYBgNVBAMTEVRydXN0ZWQgQ29ycCBDZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAts8whjOzEbn/w1xkFJ67af7F/JPujBK91oyJekh2schIMzFau9pY8S1AiJQoJCulOJCJfUc8hBLKBZiGAkii+4Gpx6cVqMLe6C22MdD806Soxn8Dg4dQqbIvPuI4eeVKu5CEk80PW/BaFMmRvRHO62C7PILuH6yZeGHC4P7dTKpsk4CLxh/jRGXLC8jV2BCW0X+3BMbHBg53NoI9s1Gs7KGYnfOHbBP5wEFAa00RjHnubUaCdEBlC8Kl4X7p0S4RGb3rsB08wgFe9EmSZHIgcIm+SuVo7N4qqbI85qo2ulU6J8NN7ZtgMPHzrMhzgAgf/KnqPqwDIxnNmRNJmHTUYwIDAQABozgwNjAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMDMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAukH6cJUUj5faa8CuPCqrEa0PoLY4SYNnff9NI+TTAHkB9l+kOcFl5eo2EQOcWmZKYi7QLlWC4jy/KQYattO9FMaxiOQL4FAc6ZIbNyfwWBzZWyr5syYJTTTnkLq8A9pCKarN49+FqhJseycU+8EhJEJyP5pv5hLvDNTTHOQ6SXhASsiX8cjo3AY4bxA5pWeXuTZ459qDxOnQd+GrOe4dIeqflk0hA2xYKe3SfF+QlK8EO370B8Dj8RX230OATM1E3OtYyALe34KW3wM9Qm9rb0eViDnVyDiCWkhhQnw5yPg/XQfloug2itRYuCnfUoRt8xfeHgwz2Ymz8cUADn3KpTGCAf4wggH6AgEBMHgwczELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSQwIgYDVQQKExtFeGFtcGxlIFRydXN0ZWQgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFRydXN0ZWQgVmFsaWQgQ0ECAQIwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE1MTAwMTIxMTEwNlowIwYJKoZIhvcNAQkEMRYEFHAisUYrrt+gBxYFhZ5KQQusOmN3MA0GCSqGSIb3DQEBAQUABIIBACHW4V0BsPWOvWrGOTRj6mPpNbH/JI1bN2oyqQZrpUQoaBY+BbYxO7TY4Uwe+aeIR/TTPJznOMF/dl3Bna6TPabezU4ylg7TVFI6W7zC5f5DZKp+Xv6uTX6knUzbbW1fkJqMtE8hGUzYXc3/C++Ci6kuOzrpWOhk6DpJHeUO/ioV56H0+QK/oMAjYpEsOohaPqvTPNOBhMQ0OQP3bmuJ6HcjZ/oz96PpzXUPKT1tDe6VykIYkV5NvtC8Tu2lDbYvp9ug3gyDgdyNSV47y5i/iWkzEhsAJB+9Z50wKhplnkxxVHEXkB/6tmfvExvQ28gLd/VbaEGDX2ljCaTSUjhD0o0=\r\n";
|
||||
|
||||
var packageContent = [
|
||||
"--7B0MKBI3UH\r",
|
||||
"Content-Location: manifest.webapp\r",
|
||||
"Content-Type: application/x-web-app-manifest+json\r",
|
||||
"\r",
|
||||
"{",
|
||||
" \"name\": \"My App\",",
|
||||
" \"moz-resources\": [",
|
||||
" {",
|
||||
" \"src\": \"page2.html\",",
|
||||
" \"integrity\": \"JREF3JbXGvZ+I1KHtoz3f46ZkeIPrvXtG4VyFQrJ7II=\"",
|
||||
" },",
|
||||
" {",
|
||||
" \"src\": \"index.html\",",
|
||||
" \"integrity\": \"zEubR310nePwd30NThIuoCxKJdnz7Mf5z+dZHUbH1SE=\"",
|
||||
" },",
|
||||
" {",
|
||||
" \"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\"",
|
||||
" }",
|
||||
" }",
|
||||
" ],",
|
||||
" \"package-identifier\": \"611FC2FE-491D-4A47-B3B3-43FBDF6F404F\",",
|
||||
" \"moz-package-location\": \"https://example.com/myapp/app.pak\",",
|
||||
" \"description\": \"A great app!\"",
|
||||
"}\r",
|
||||
"--7B0MKBI3UH\r",
|
||||
"Content-Location: page2.html\r",
|
||||
"Content-Type: text/html\r",
|
||||
"\r",
|
||||
"<html>",
|
||||
" page2.html",
|
||||
"</html>",
|
||||
"\r",
|
||||
"--7B0MKBI3UH\r",
|
||||
"Content-Location: index.html\r",
|
||||
"Content-Type: text/html\r",
|
||||
"\r",
|
||||
"<html>",
|
||||
" Last updated: 2015/10/01 14:10 PST",
|
||||
"</html>",
|
||||
"\r",
|
||||
"--7B0MKBI3UH\r",
|
||||
"Content-Location: scripts/script.js\r",
|
||||
"Content-Type: text/javascript\r",
|
||||
"\r",
|
||||
"// script.js",
|
||||
"\r",
|
||||
"--7B0MKBI3UH\r",
|
||||
"Content-Location: scripts/library.js\r",
|
||||
"Content-Type: text/javascript\r",
|
||||
"\r",
|
||||
"// library.js",
|
||||
"\r",
|
||||
"--7B0MKBI3UH--"
|
||||
].join("\n");
|
||||
|
||||
function contentHandler(metadata, response)
|
||||
{
|
||||
response.setHeader("Content-Type", 'application/package');
|
||||
@ -108,16 +181,22 @@ function regularContentHandler(metadata, response)
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
}
|
||||
|
||||
function contentHandlerWithSignature(metadata, response)
|
||||
function contentHandlerWithBadSignature(metadata, response)
|
||||
{
|
||||
response.setHeader("Content-Type", 'application/package');
|
||||
var body = testData.packageHeader + testData.getData();
|
||||
var body = badSignature + packageContent;
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
}
|
||||
|
||||
function contentHandlerWithGoodSignature(metadata, response)
|
||||
{
|
||||
response.setHeader("Content-Type", 'application/package');
|
||||
var body = goodSignature + packageContent;
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
}
|
||||
|
||||
var httpserver = null;
|
||||
var originalPref = false;
|
||||
var originalDevMode = false;
|
||||
var originalSignedAppEnabled = false;
|
||||
|
||||
function run_test()
|
||||
@ -126,15 +205,14 @@ function run_test()
|
||||
httpserver = new HttpServer();
|
||||
httpserver.registerPathHandler("/package", contentHandler);
|
||||
httpserver.registerPathHandler("/regular", regularContentHandler);
|
||||
httpserver.registerPathHandler("/package_with_signature", contentHandlerWithSignature);
|
||||
httpserver.registerPathHandler("/package_with_good_signature", contentHandlerWithGoodSignature);
|
||||
httpserver.registerPathHandler("/package_with_bad_signature", contentHandlerWithBadSignature);
|
||||
httpserver.start(-1);
|
||||
|
||||
// Enable the feature and save the original pref value
|
||||
originalPref = Services.prefs.getBoolPref("network.http.enable-packaged-apps");
|
||||
originalDevMode = Services.prefs.getBoolPref("network.http.packaged-apps-developer-mode");
|
||||
originalSignedAppEnabled = Services.prefs.getBoolPref("network.http.packaged-signed-apps-enabled");
|
||||
Services.prefs.setBoolPref("network.http.enable-packaged-apps", true);
|
||||
Services.prefs.setBoolPref("network.http.packaged-apps-developer-mode", false);
|
||||
Services.prefs.setBoolPref("network.http.packaged-signed-apps-enabled", true);
|
||||
do_register_cleanup(reset_pref);
|
||||
|
||||
@ -142,32 +220,27 @@ function run_test()
|
||||
add_test(test_channel_no_notificationCallbacks);
|
||||
add_test(test_channel_uris);
|
||||
|
||||
add_test(test_channel_with_signature);
|
||||
add_test(test_channel_with_signature_dev_mode);
|
||||
add_test(test_channel_with_bad_signature);
|
||||
add_test(test_channel_with_good_signature);
|
||||
|
||||
// run tests
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_channel_with_signature() {
|
||||
var channel = make_channel(uri+"/package_with_signature!//index.html");
|
||||
function test_channel_with_bad_signature() {
|
||||
var channel = make_channel(uri+"/package_with_bad_signature!//index.html");
|
||||
channel.notificationCallbacks = new LoadContextCallback(1024, false, false, false);
|
||||
channel.asyncOpen(new Listener(function(l) {
|
||||
// Since the manifest verification is not implemented yet, we should
|
||||
// get NS_ERROR_FILE_NOT_FOUND if the package has a signature while
|
||||
// not in developer mode.
|
||||
do_check_true(l.gotFileNotFound);
|
||||
run_next_test();
|
||||
}), null);
|
||||
}
|
||||
|
||||
function test_channel_with_signature_dev_mode() {
|
||||
Services.prefs.setBoolPref("network.http.packaged-apps-developer-mode", true);
|
||||
var channel = make_channel(uri+"/package_with_signature!//index.html");
|
||||
function test_channel_with_good_signature() {
|
||||
var channel = make_channel(uri+"/package_with_good_signature!//index.html");
|
||||
channel.notificationCallbacks = new LoadContextCallback(1024, false, false, false);
|
||||
channel.asyncOpen(new Listener(function(l) {
|
||||
do_check_true(l.gotStopRequestOK);
|
||||
Services.prefs.setBoolPref("network.http.packaged-apps-developer-mode", false);
|
||||
run_next_test();
|
||||
}), null);
|
||||
}
|
||||
@ -208,6 +281,5 @@ function check_regular_response(request, buffer) {
|
||||
function reset_pref() {
|
||||
// Set the pref to its original value
|
||||
Services.prefs.setBoolPref("network.http.enable-packaged-apps", originalPref);
|
||||
Services.prefs.setBoolPref("network.http.packaged-apps-developer-mode", originalDevMode);
|
||||
Services.prefs.setBoolPref("network.http.packaged-signed-apps-enabled", originalSignedAppEnabled);
|
||||
}
|
||||
|
@ -120,6 +120,77 @@ var testData = {
|
||||
}
|
||||
}
|
||||
|
||||
var signedPackage = [
|
||||
"manifest-signature: MIIF1AYJKoZIhvcNAQcCoIIFxTCCBcECAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCA54wggOaMIICgqADAgECAgECMA0GCSqGSIb3DQEBCwUAMHMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEkMCIGA1UEChMbRXhhbXBsZSBUcnVzdGVkIENvcnBvcmF0aW9uMRkwFwYDVQQDExBUcnVzdGVkIFZhbGlkIENBMB4XDTE1MDkxMDA4MDQzNVoXDTM1MDkxMDA4MDQzNVowdDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSQwIgYDVQQKExtFeGFtcGxlIFRydXN0ZWQgQ29ycG9yYXRpb24xGjAYBgNVBAMTEVRydXN0ZWQgQ29ycCBDZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAts8whjOzEbn/w1xkFJ67af7F/JPujBK91oyJekh2schIMzFau9pY8S1AiJQoJCulOJCJfUc8hBLKBZiGAkii+4Gpx6cVqMLe6C22MdD806Soxn8Dg4dQqbIvPuI4eeVKu5CEk80PW/BaFMmRvRHO62C7PILuH6yZeGHC4P7dTKpsk4CLxh/jRGXLC8jV2BCW0X+3BMbHBg53NoI9s1Gs7KGYnfOHbBP5wEFAa00RjHnubUaCdEBlC8Kl4X7p0S4RGb3rsB08wgFe9EmSZHIgcIm+SuVo7N4qqbI85qo2ulU6J8NN7ZtgMPHzrMhzgAgf/KnqPqwDIxnNmRNJmHTUYwIDAQABozgwNjAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMDMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAukH6cJUUj5faa8CuPCqrEa0PoLY4SYNnff9NI+TTAHkB9l+kOcFl5eo2EQOcWmZKYi7QLlWC4jy/KQYattO9FMaxiOQL4FAc6ZIbNyfwWBzZWyr5syYJTTTnkLq8A9pCKarN49+FqhJseycU+8EhJEJyP5pv5hLvDNTTHOQ6SXhASsiX8cjo3AY4bxA5pWeXuTZ459qDxOnQd+GrOe4dIeqflk0hA2xYKe3SfF+QlK8EO370B8Dj8RX230OATM1E3OtYyALe34KW3wM9Qm9rb0eViDnVyDiCWkhhQnw5yPg/XQfloug2itRYuCnfUoRt8xfeHgwz2Ymz8cUADn3KpTGCAf4wggH6AgEBMHgwczELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSQwIgYDVQQKExtFeGFtcGxlIFRydXN0ZWQgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFRydXN0ZWQgVmFsaWQgQ0ECAQIwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE1MTAwMTIxMTEwNlowIwYJKoZIhvcNAQkEMRYEFHAisUYrrt+gBxYFhZ5KQQusOmN3MA0GCSqGSIb3DQEBAQUABIIBACHW4V0BsPWOvWrGOTRj6mPpNbH/JI1bN2oyqQZrpUQoaBY+BbYxO7TY4Uwe+aeIR/TTPJznOMF/dl3Bna6TPabezU4ylg7TVFI6W7zC5f5DZKp+Xv6uTX6knUzbbW1fkJqMtE8hGUzYXc3/C++Ci6kuOzrpWOhk6DpJHeUO/ioV56H0+QK/oMAjYpEsOohaPqvTPNOBhMQ0OQP3bmuJ6HcjZ/oz96PpzXUPKT1tDe6VykIYkV5NvtC8Tu2lDbYvp9ug3gyDgdyNSV47y5i/iWkzEhsAJB+9Z50wKhplnkxxVHEXkB/6tmfvExvQ28gLd/VbaEGDX2ljCaTSUjhD0o0=\r",
|
||||
"--7B0MKBI3UH\r",
|
||||
"Content-Location: manifest.webapp\r",
|
||||
"Content-Type: application/x-web-app-manifest+json\r",
|
||||
"\r",
|
||||
"{",
|
||||
" \"name\": \"My App\",",
|
||||
" \"moz-resources\": [",
|
||||
" {",
|
||||
" \"src\": \"page2.html\",",
|
||||
" \"integrity\": \"JREF3JbXGvZ+I1KHtoz3f46ZkeIPrvXtG4VyFQrJ7II=\"",
|
||||
" },",
|
||||
" {",
|
||||
" \"src\": \"index.html\",",
|
||||
" \"integrity\": \"zEubR310nePwd30NThIuoCxKJdnz7Mf5z+dZHUbH1SE=\"",
|
||||
" },",
|
||||
" {",
|
||||
" \"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\"",
|
||||
" }",
|
||||
" }",
|
||||
" ],",
|
||||
" \"package-identifier\": \"611FC2FE-491D-4A47-B3B3-43FBDF6F404F\",",
|
||||
" \"moz-package-location\": \"https://example.com/myapp/app.pak\",",
|
||||
" \"description\": \"A great app!\"",
|
||||
"}\r",
|
||||
"--7B0MKBI3UH\r",
|
||||
"Content-Location: page2.html\r",
|
||||
"Content-Type: text/html\r",
|
||||
"\r",
|
||||
"<html>",
|
||||
" page2.html",
|
||||
"</html>",
|
||||
"\r",
|
||||
"--7B0MKBI3UH\r",
|
||||
"Content-Location: index.html\r",
|
||||
"Content-Type: text/html\r",
|
||||
"\r",
|
||||
"<html>",
|
||||
" Last updated: 2015/10/01 14:10 PST",
|
||||
"</html>",
|
||||
"\r",
|
||||
"--7B0MKBI3UH\r",
|
||||
"Content-Location: scripts/script.js\r",
|
||||
"Content-Type: text/javascript\r",
|
||||
"\r",
|
||||
"// script.js",
|
||||
"\r",
|
||||
"--7B0MKBI3UH\r",
|
||||
"Content-Location: scripts/library.js\r",
|
||||
"Content-Type: text/javascript\r",
|
||||
"\r",
|
||||
"// library.js",
|
||||
"\r",
|
||||
"--7B0MKBI3UH--"
|
||||
].join("\n");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "uri", function() {
|
||||
return "http://localhost:" + httpserver.identity.primaryPort;
|
||||
});
|
||||
@ -505,7 +576,7 @@ function test_worse_package_5() {
|
||||
function signedPackagedAppContentHandler(metadata, response)
|
||||
{
|
||||
response.setHeader("Content-Type", 'application/package');
|
||||
var body = testData.packageHeader + testData.getData();
|
||||
var body = signedPackage;
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
}
|
||||
|
||||
@ -523,9 +594,6 @@ var dummyCacheListener = {
|
||||
|
||||
function test_signed_package_callback()
|
||||
{
|
||||
// TODO: To be removed in Bug 1178518.
|
||||
gPrefs.setBoolPref("network.http.packaged-apps-developer-mode", true);
|
||||
|
||||
packagePath = "/signedPackage";
|
||||
let url = uri + packagePath + "!//index.html";
|
||||
let channel = getChannelForURL(url, {
|
||||
@ -544,6 +612,9 @@ function test_signed_package_callback()
|
||||
iid.equals(Ci.nsIPackagedAppChannelListener)) {
|
||||
return this;
|
||||
}
|
||||
if (iid.equals(Ci.nsILoadContext)) {
|
||||
return new LoadContextCallback(1024, false, false, false);
|
||||
}
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
});
|
||||
@ -570,6 +641,9 @@ function test_unsigned_package_callback()
|
||||
iid.equals(Ci.nsIPackagedAppChannelListener)) {
|
||||
return this;
|
||||
}
|
||||
if (iid.equals(Ci.nsILoadContext)) {
|
||||
return new LoadContextCallback(1024, false, false, false);
|
||||
}
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
});
|
||||
|
@ -98,7 +98,7 @@ function test_verify_manifest(aHeader, aManifest, aShouldSucceed) {
|
||||
run_next_test();
|
||||
}
|
||||
};
|
||||
packagedAppUtils.verifyManifest(aHeader, aManifest, fakeVerifier);
|
||||
packagedAppUtils.verifyManifest(aHeader, aManifest, fakeVerifier, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,18 +215,6 @@ function test_invalid_signature(aDeveloperMode) {
|
||||
feedResources(expectedCallbacks, signature);
|
||||
}
|
||||
|
||||
function test_no_signature_developer_mode()
|
||||
{
|
||||
enable_developer_mode()
|
||||
test_no_signature(true);
|
||||
}
|
||||
|
||||
function test_invalid_signature_developer_mode()
|
||||
{
|
||||
enable_developer_mode()
|
||||
test_invalid_signature(true);
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
ok(!!gVerifier);
|
||||
@ -235,10 +223,6 @@ function run_test()
|
||||
add_test(test_no_signature);
|
||||
add_test(test_invalid_signature);
|
||||
|
||||
// Test cases in developer mode.
|
||||
add_test(test_no_signature_developer_mode);
|
||||
add_test(test_invalid_signature_developer_mode);
|
||||
|
||||
// run tests
|
||||
run_next_test();
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,13 @@
|
||||
#include "certdb.h"
|
||||
#include "pkix/pkixnss.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIFileStreams.h"
|
||||
#include "nsIX509CertDB.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsNSSCertificate.h"
|
||||
#include "prerror.h"
|
||||
#include "secerr.h"
|
||||
@ -34,9 +40,15 @@ using namespace mozilla::pkix;
|
||||
extern PRLogModuleInfo* gPIPNSSLog;
|
||||
|
||||
static const unsigned int DEFAULT_MIN_RSA_BITS = 2048;
|
||||
static char kDevImportedDER[] =
|
||||
"network.http.packaged-apps-developer-trusted-root";
|
||||
|
||||
namespace mozilla { namespace psm {
|
||||
|
||||
StaticMutex AppTrustDomain::sMutex;
|
||||
nsAutoArrayPtr<unsigned char> AppTrustDomain::sDevImportedDERData(nullptr);
|
||||
unsigned int AppTrustDomain::sDevImportedDERLen = 0;
|
||||
|
||||
AppTrustDomain::AppTrustDomain(ScopedCERTCertList& certChain, void* pinArg)
|
||||
: mCertChain(certChain)
|
||||
, mPinArg(pinArg)
|
||||
@ -101,6 +113,53 @@ AppTrustDomain::SetTrustedRoot(AppTrustedRoot trustedRoot)
|
||||
trustedDER.len = mozilla::ArrayLength(privilegedPackageRoot);
|
||||
break;
|
||||
|
||||
case nsIX509CertDB::DeveloperImportedRoot: {
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
if (!sDevImportedDERData) {
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
nsCOMPtr<nsIFile> file(do_CreateInstance("@mozilla.org/file/local;1"));
|
||||
if (!file) {
|
||||
PR_SetError(SEC_ERROR_IO, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
nsresult rv = file->InitWithNativePath(
|
||||
Preferences::GetCString(kDevImportedDER));
|
||||
if (NS_FAILED(rv)) {
|
||||
PR_SetError(SEC_ERROR_IO, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> inputStream;
|
||||
NS_NewLocalFileInputStream(getter_AddRefs(inputStream), file, -1, -1,
|
||||
nsIFileInputStream::CLOSE_ON_EOF);
|
||||
if (!inputStream) {
|
||||
PR_SetError(SEC_ERROR_IO, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
uint64_t length;
|
||||
rv = inputStream->Available(&length);
|
||||
if (NS_FAILED(rv)) {
|
||||
PR_SetError(SEC_ERROR_IO, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
char* data = new char[length];
|
||||
rv = inputStream->Read(data, length, &sDevImportedDERLen);
|
||||
if (NS_FAILED(rv)) {
|
||||
PR_SetError(SEC_ERROR_IO, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(length == sDevImportedDERLen);
|
||||
sDevImportedDERData = reinterpret_cast<unsigned char*>(data);
|
||||
}
|
||||
|
||||
trustedDER.data = sDevImportedDERData;
|
||||
trustedDER.len = sDevImportedDERLen;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
|
||||
return SECFailure;
|
||||
|
@ -8,6 +8,8 @@
|
||||
#define mozilla_psm_AppsTrustDomain_h
|
||||
|
||||
#include "pkix/pkixtypes.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsIX509CertDB.h"
|
||||
#include "ScopedNSSTypes.h"
|
||||
@ -69,6 +71,10 @@ private:
|
||||
void* mPinArg; // non-owning!
|
||||
ScopedCERTCertificate mTrustedRoot;
|
||||
unsigned int mMinRSABits;
|
||||
|
||||
static StaticMutex sMutex;
|
||||
static nsAutoArrayPtr<unsigned char> sDevImportedDERData;
|
||||
static unsigned int sDevImportedDERLen;
|
||||
};
|
||||
|
||||
} } // namespace mozilla::psm
|
||||
|
@ -46,7 +46,7 @@ interface nsIVerifySignedManifestCallback : nsISupports
|
||||
* This represents a service to access and manipulate
|
||||
* X.509 certificates stored in a database.
|
||||
*/
|
||||
[scriptable, uuid(0a47571d-602c-4b21-9f52-c3d0e681d83a)]
|
||||
[scriptable, uuid(a36c45fb-f7b5-423e-a0f7-ea1eb4fd60b5)]
|
||||
interface nsIX509CertDB : nsISupports {
|
||||
|
||||
/**
|
||||
@ -319,6 +319,14 @@ interface nsIX509CertDB : nsISupports {
|
||||
const AppTrustedRoot AddonsPublicRoot = 7;
|
||||
const AppTrustedRoot AddonsStageRoot = 8;
|
||||
const AppTrustedRoot PrivilegedPackageRoot = 9;
|
||||
/*
|
||||
* If DeveloperImportedRoot is set as trusted root, a CA from local file
|
||||
* system will be imported. Only used when preference
|
||||
* "network.http.packaged-apps-developer-mode" is set.
|
||||
* The path of the CA is specified by preference
|
||||
* "network.http.packaged-apps-developer-trusted-root".
|
||||
*/
|
||||
const AppTrustedRoot DeveloperImportedRoot = 10;
|
||||
void openSignedAppFileAsync(in AppTrustedRoot trustedRoot,
|
||||
in nsIFile aJarFile,
|
||||
in nsIOpenSignedAppFileCallback callback);
|
||||
|
Loading…
Reference in New Issue
Block a user