Backed out changeset b71c8c052463 (bug 1943846) for causing mass failures. CLOSED...
[gecko.git] / netwerk / test / unit / test_signature_extraction.js
blobe179051e9237fe37e0075b003f965a145d67e8eb
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* Any copyright is dedicated to the Public Domain.
4 * http://creativecommons.org/publicdomain/zero/1.0/ */
6 /**
7 * This file tests signature extraction using Windows Authenticode APIs of
8 * downloaded files.
9 */
11 ////////////////////////////////////////////////////////////////////////////////
12 //// Globals
13 "use strict";
15 ChromeUtils.defineESModuleGetters(this, {
16 FileTestUtils: "resource://testing-common/FileTestUtils.sys.mjs",
17 });
19 const BackgroundFileSaverOutputStream = Components.Constructor(
20 "@mozilla.org/network/background-file-saver;1?mode=outputstream",
21 "nsIBackgroundFileSaver"
24 const StringInputStream = Components.Constructor(
25 "@mozilla.org/io/string-input-stream;1",
26 "nsIStringInputStream",
27 "setByteStringData"
30 const TEST_FILE_NAME_1 = "test-backgroundfilesaver-1.txt";
32 /**
33 * Returns a reference to a temporary file that is guaranteed not to exist and
34 * is cleaned up later. See FileTestUtils.getTempFile for details.
36 function getTempFile(leafName) {
37 return FileTestUtils.getTempFile(leafName);
40 /**
41 * Waits for the given saver object to complete.
43 * @param aSaver
44 * The saver, with the output stream or a stream listener implementation.
45 * @param aOnTargetChangeFn
46 * Optional callback invoked with the target file name when it changes.
48 * @return {Promise}
49 * @resolves When onSaveComplete is called with a success code.
50 * @rejects With an exception, if onSaveComplete is called with a failure code.
52 function promiseSaverComplete(aSaver, aOnTargetChangeFn) {
53 return new Promise((resolve, reject) => {
54 aSaver.observer = {
55 onTargetChange: function BFSO_onSaveComplete(saver, aTarget) {
56 if (aOnTargetChangeFn) {
57 aOnTargetChangeFn(aTarget);
60 onSaveComplete: function BFSO_onSaveComplete(saver, aStatus) {
61 if (Components.isSuccessCode(aStatus)) {
62 resolve();
63 } else {
64 reject(new Components.Exception("Saver failed.", aStatus));
68 });
71 /**
72 * Feeds a string to a BackgroundFileSaverOutputStream.
74 * @param aSourceString
75 * The source data to copy.
76 * @param aSaverOutputStream
77 * The BackgroundFileSaverOutputStream to feed.
78 * @param aCloseWhenDone
79 * If true, the output stream will be closed when the copy finishes.
81 * @return {Promise}
82 * @resolves When the copy completes with a success code.
83 * @rejects With an exception, if the copy fails.
85 function promiseCopyToSaver(aSourceString, aSaverOutputStream, aCloseWhenDone) {
86 return new Promise((resolve, reject) => {
87 let inputStream = new StringInputStream(aSourceString);
88 let copier = Cc[
89 "@mozilla.org/network/async-stream-copier;1"
90 ].createInstance(Ci.nsIAsyncStreamCopier);
91 copier.init(
92 inputStream,
93 aSaverOutputStream,
94 null,
95 false,
96 true,
97 0x8000,
98 true,
99 aCloseWhenDone
101 copier.asyncCopy(
103 onStartRequest() {},
104 onStopRequest(aRequest, aContext, aStatusCode) {
105 if (Components.isSuccessCode(aStatusCode)) {
106 resolve();
107 } else {
108 reject(new Components.Exception(aStatusCode));
112 null
117 var gStillRunning = true;
119 ////////////////////////////////////////////////////////////////////////////////
120 //// Tests
122 add_task(function test_setup() {
123 // Wait 10 minutes, that is half of the external xpcshell timeout.
124 do_timeout(10 * 60 * 1000, function () {
125 if (gStillRunning) {
126 do_throw("Test timed out.");
131 function readFileToString(aFilename) {
132 let f = do_get_file(aFilename);
133 let stream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
134 Ci.nsIFileInputStream
136 stream.init(f, -1, 0, 0);
137 let buf = NetUtil.readInputStreamToString(stream, stream.available());
138 return buf;
141 add_task(async function test_signature() {
142 // Check that we get a signature if the saver is finished on Windows.
143 let destFile = getTempFile(TEST_FILE_NAME_1);
145 let data = readFileToString("data/signed_win.exe");
146 let saver = new BackgroundFileSaverOutputStream();
147 let completionPromise = promiseSaverComplete(saver);
149 try {
150 saver.signatureInfo;
151 do_throw("Can't get signature before saver is complete.");
152 } catch (ex) {
153 if (ex.result != Cr.NS_ERROR_NOT_AVAILABLE) {
154 throw ex;
158 saver.enableSignatureInfo();
159 saver.setTarget(destFile, false);
160 await promiseCopyToSaver(data, saver, true);
162 saver.finish(Cr.NS_OK);
163 await completionPromise;
165 // There's only one Array of certs(raw bytes) in the signature array.
166 Assert.equal(1, saver.signatureInfo.length);
167 let certLists = saver.signatureInfo;
168 Assert.ok(certLists.length === 1);
170 // Check that it has 3 certs(raw bytes).
171 let certs = certLists[0];
172 Assert.ok(certs.length === 3);
174 const certDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
175 Ci.nsIX509CertDB
177 let signer = certDB.constructX509(certs[0]);
178 let issuer = certDB.constructX509(certs[1]);
179 let root = certDB.constructX509(certs[2]);
181 let organization = "Microsoft Corporation";
182 Assert.equal("Microsoft Corporation", signer.commonName);
183 Assert.equal(organization, signer.organization);
184 Assert.equal("Copyright (c) 2002 Microsoft Corp.", signer.organizationalUnit);
186 Assert.equal("Microsoft Code Signing PCA", issuer.commonName);
187 Assert.equal(organization, issuer.organization);
188 Assert.equal("Copyright (c) 2000 Microsoft Corp.", issuer.organizationalUnit);
190 Assert.equal("Microsoft Root Authority", root.commonName);
191 Assert.ok(!root.organization);
192 Assert.equal("Copyright (c) 1997 Microsoft Corp.", root.organizationalUnit);
194 // Clean up.
195 destFile.remove(false);
198 add_task(function test_teardown() {
199 gStillRunning = false;