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/ */
7 * This file tests signature extraction using Windows Authenticode APIs of
11 ////////////////////////////////////////////////////////////////////////////////
15 ChromeUtils
.defineESModuleGetters(this, {
16 FileTestUtils
: "resource://testing-common/FileTestUtils.sys.mjs",
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",
30 const TEST_FILE_NAME_1
= "test-backgroundfilesaver-1.txt";
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
);
41 * Waits for the given saver object to complete.
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.
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
) => {
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
)) {
64 reject(new Components
.Exception("Saver failed.", aStatus
));
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.
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
);
89 "@mozilla.org/network/async-stream-copier;1"
90 ].createInstance(Ci
.nsIAsyncStreamCopier
);
104 onStopRequest(aRequest
, aContext
, aStatusCode
) {
105 if (Components
.isSuccessCode(aStatusCode
)) {
108 reject(new Components
.Exception(aStatusCode
));
117 var gStillRunning
= true;
119 ////////////////////////////////////////////////////////////////////////////////
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 () {
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());
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
);
151 do_throw("Can't get signature before saver is complete.");
153 if (ex
.result
!= Cr
.NS_ERROR_NOT_AVAILABLE
) {
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(
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
);
195 destFile
.remove(false);
198 add_task(function test_teardown() {
199 gStillRunning
= false;