Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions task/codesigning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import tl = require("azure-pipelines-task-lib/task");
import { ToolRunner } from "azure-pipelines-task-lib/toolrunner";
import fs = require("fs");

async function sign(signToolPath: string, filePath: string, hashingAlgorithm: string, timeServer: string, signCertPassword: string, description: string): Promise<number> {
async function sign(signToolPath: string, filePath: string, hashingAlgorithm: string, timeServer: string, signCertPassword: string, description: string, enableDebugSwitch: boolean): Promise<number> {
const signToolRunner: ToolRunner = tl.tool(signToolPath);
let secureFilePath: string = tl.getTaskVariable("SECURE_FILE_PATH");
console.log("Signing file: " + filePath);
Expand All @@ -13,6 +13,10 @@ async function sign(signToolPath: string, filePath: string, hashingAlgorithm: st
signToolRunner.arg(["/t", timeServer]);
signToolRunner.arg(["/f", secureFilePath]);
signToolRunner.arg(["/p", signCertPassword]);
if(enableDebugSwitch){
signToolRunner.arg(["/debug"]);
signToolRunner.arg(["/v"]);
}
if(description) {
signToolRunner.arg(["/d", description]);
}
Expand All @@ -27,6 +31,7 @@ async function run(): Promise<void> {

let signCertPassword: string = tl.getInput("signCertPassword", true);
let timeServer: string = tl.getInput("timeServer", true);
let enableDebugSwitch: boolean = tl.getBoolInput("enableDebugSwitch", true);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this shouldn´t be required. Default value should be false. This should also fix the tests :)

let enableDebugSwitch: boolean = tl.getBoolInput("enableDebugSwitch", false);

let hashingAlgorithm: string = tl.getInput("hashingAlgorithm", true);
let filesPattern: string = tl.getInput("files", true);
let signToolLocationMethod: string = tl.getInput("signToolLocationMethod", false);
Expand All @@ -53,7 +58,7 @@ async function run(): Promise<void> {
throw new Error(tl.loc("NoMatchingFiles", filesPattern));
}
for (let filePath of filesToSign) {
await sign(signToolPath, filePath, hashingAlgorithm, timeServer, signCertPassword, description);
await sign(signToolPath, filePath, hashingAlgorithm, timeServer, signCertPassword, description, enableDebugSwitch);
console.log("Job Finished: Successfully signed file " + filePath + " with given certificate.");
}
} catch (err) {
Expand Down Expand Up @@ -96,4 +101,4 @@ function findFilesInDir(startPath: string, filter: string): string[] {
return results;
}

run();
run();
10 changes: 9 additions & 1 deletion task/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@
"defaultValue": "",
"helpMarkDown": "UAC will display this description when installing the signed file"
},
{
"name": "enableDebugSwitch",
"type": "boolean",
"label": "Enable debug output from signtool.exe",
"required": false,
"defaultValue": false,
"helpMarkDown": "Enable debug output from signtool.exe"
},
{
"name": "signToolLocationMethod",
"type": "radio",
Expand Down Expand Up @@ -110,4 +118,4 @@
"NoMatchingFiles": "No matching files were found with search pattern: %s",
"DeleteSecureFileFailed": "Failed to delete secure file downloaded from the server: %s"
}
}
}
38 changes: 38 additions & 0 deletions tests/L0CodeSigningSingleFileWithDebugSwitch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import mockanswer = require("azure-pipelines-task-lib/mock-answer");
import tmrm = require("azure-pipelines-task-lib/mock-run");
import path = require("path");

let taskPath: string = path.join(__dirname, "../task", "codesigning.js");
let tmr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath);

const secureFileId: string = "THESECUREFILEID";
const signCertPassword: string = "PASSWORD";
const timeServer: string = "http://timestamp.digicert.com";
const hashingAlgorithm: string = "SHA256";
const fileToSign: string = "DllToSign.dll";

const signToolPath: string = path.normalize(path.join(__dirname, "../task", "signtool.exe"));
const certificatePath: string = path.join(__dirname, "./test-files", "TestCertificate.pfx");
const filePaths: string = "DllToSign.dll";
tmr.setInput("secureFileId", secureFileId);
tmr.setInput("signCertPassword", signCertPassword);
tmr.setInput("timeServer", timeServer);
tmr.setInput("hashingAlgorithm", hashingAlgorithm);
tmr.setInput("files", filePaths);
tmr.setVariableName("SECURE_FILE_PATH", certificatePath);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depending on if we keep the ui option or switch to a system.variable, we should set the information in this test and check if the required flags are actually set.


let answers: mockanswer.TaskLibAnswers = <mockanswer.TaskLibAnswers>{
findMatch: {
"DllToSign.dll": [
"DllToSign.dll"
]
},
exec: {}
};
answers.exec[`${signToolPath} sign /fd ${hashingAlgorithm} /t ${timeServer} /f ${certificatePath} /p ${signCertPassword} ${fileToSign}`] = {
code: 0,
stdout: `Successfully signed ${fileToSign}`
};

tmr.setAnswers(answers);
tmr.run();