Skip to content

Instantly share code, notes, and snippets.

@max24192

max24192/wine Secret

Created July 10, 2023 02:50
Show Gist options
  • Save max24192/3e3b5f4333a5167c4ce8072afb87aa02 to your computer and use it in GitHub Desktop.
Save max24192/3e3b5f4333a5167c4ce8072afb87aa02 to your computer and use it in GitHub Desktop.
A proxy that diverts a `wine signcode.exe` to a locally installed osslsigncode (intended for Apple Silicon)
#!/usr/bin/env node
const { spawn } = require("child_process");
const fs = require("fs");
const hashAlgorithms = ["sha1", "sha256"];
const args = process.argv.slice(2);
let cmd = args.shift();
const cwd = process.cwd();
let keyPath = "";
let password = "";
let filePath = "";
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function sign() {
for (let idx = 0; idx < hashAlgorithms.length; idx++) {
const hash = hashAlgorithms[idx];
let args = [
"-in",
filePath,
"-out",
filePath + ".signed",
"-pkcs12",
keyPath,
"-pass",
password,
"-nolegacy",
];
if (idx === 1) {
args.push("-nest"); // add instead of replace
}
args.push("-h", hash);
const command = "/opt/homebrew/bin/osslsigncode";
const commandArgs = args;
const childProcess = spawn(command, commandArgs);
// Call command
console.log("Call command:", command, commandArgs.join(" "));
childProcess.on("error", (error) => {
console.error(error);
process.exit(1);
});
const code = await new Promise((resolve) => {
childProcess.on("close", resolve);
});
if (code === 0) {
// Wait for result, max time = 5s
const maxWaitTime = 5 * 1000; // 5 seconds
const startTime = Date.now();
while (!fs.existsSync(filePath + ".signed")) {
if (Date.now() - startTime >= maxWaitTime) {
console.log("Signing", hash, "fail (overtime)");
break;
}
await wait(500);
}
if (fs.existsSync(filePath + ".signed")) {
// Check result
console.log("Signing", hash, "success");
try {
fs.unlinkSync(filePath);
fs.renameSync(filePath + ".signed", filePath);
} catch (error) {
console.error(error);
process.exit(1);
}
}
} else {
console.log("Signing", hash, "fail", code);
}
// Sleep for 500 milliseconds before the next iteration
await wait(1000);
}
}
if (cmd.endsWith("signtool.exe") || cmd.endsWith("signtool")) {
for (let idx = 0; idx < args.length; idx++) {
const param = args[idx];
if (param === "/f") {
keyPath = args[idx + 1];
}
if (param === "/p") {
password = args[idx + 1];
}
if (idx === args.length - 1) {
filePath = param;
}
}
if (keyPath === "") {
console.error("keyPath not set");
process.exit(1);
}
if (password === "") {
console.error("password not set");
process.exit(1);
}
if (filePath === "") {
console.error("exe file path not set");
process.exit(1);
}
sign().catch((error) => {
console.error(error);
process.exit(1);
});
} else {
// cannot use 'wine' loop
spawn("/opt/homebrew/bin/wine64", [cmd, ...args], { cwd });
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment