Skip to content
Merged
Changes from 7 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
115 changes: 114 additions & 1 deletion Herebyfile.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ let signCount = 0;
* @param {DDSignFileList} filelist
*/
async function sign(filelist) {
const data = JSON.stringify(filelist, undefined, 4);
let data = JSON.stringify(filelist, undefined, 4);
console.log("filelist:", data);

if (!process.env.MBSIGN_APPFOLDER) {
Expand Down Expand Up @@ -802,6 +802,70 @@ async function sign(filelist) {
return;
}

const signingWorkaround = true;

/** @type {{ source: string; target: string }[]} */
const signingWorkaroundFiles = [];

if (signingWorkaround) {
// DstPath is currently broken in the signing tool.
// Copy all of the files to a new tempdir and then leave DstPath unset
// so that it's overwritten, then move the file to the destination.
console.log("Working around DstPath bug");

/** @type {DDSignFileList} */
const newFileList = {
SignFileRecordList: filelist.SignFileRecordList.map(list => {
return {
Certs: list.Certs,
SignFileList: list.SignFileList.map(file => {
const dstPath = file.DstPath;
if (dstPath === null) {
return file;
}

const src = file.SrcPath;
// File extensions must be preserved; use a prefix.
const dstPathTemp = `${path.dirname(src)}/signing-temp-${path.basename(src)}`;

console.log(`Copying: ${src} -> ${dstPathTemp}`);
fs.cpSync(src, dstPathTemp);

signingWorkaroundFiles.push({ source: dstPathTemp, target: dstPath });

return {
SrcPath: dstPathTemp,
DstPath: null,
};
}),
};
}),
};

data = JSON.stringify(newFileList, undefined, 4);
console.log("new filelist:", data);
}

/** @type {Map<string, string>} */
const srcHashes = new Map();

for (const record of filelist.SignFileRecordList) {
for (const file of record.SignFileList) {
const src = file.SrcPath;
const dst = file.DstPath ?? src;

if (!fs.existsSync(src)) {
throw new Error(`Source file does not exist: ${src}`);
}

const hash = crypto.createHash("sha256").update(fs.readFileSync(src)).digest("hex");
srcHashes.set(src, hash);

console.log(`Will sign ${src} -> ${dst}`);
console.log(` sha256: ${hash}`);
}
}

const tmp = await getSignTempDir();
const filelistPath = path.resolve(tmp, `signing-filelist-${signCount++}.json`);
await fs.promises.writeFile(filelistPath, data);
Expand All @@ -814,6 +878,55 @@ async function sign(filelist) {
finally {
await fs.promises.unlink(filelistPath);
}

if (signingWorkaround) {
// Now, copy the files back.
for (const { source, target } of signingWorkaroundFiles) {
console.log(`Moving signed file: ${source} -> ${target}`);
await fs.promises.rename(source, target);
}
}

/** @type {string[]} */
let failures = [];

for (const record of filelist.SignFileRecordList) {
for (const file of record.SignFileList) {
const src = file.SrcPath;
const dst = file.DstPath ?? src;

if (!fs.existsSync(dst)) {
failures.push(`Signed file does not exist: ${dst}`);
const newSrcHash = crypto.createHash("sha256").update(fs.readFileSync(src)).digest("hex");
const oldSrcHash = srcHashes.get(src);
assert(oldSrcHash);
if (oldSrcHash !== newSrcHash) {
failures.push(` Source file changed during signing: ${src}\n before: ${oldSrcHash}\n after: ${newSrcHash}`);
}
continue;
}

const srcHash = srcHashes.get(src);
assert(srcHash);
const dstHash = crypto.createHash("sha256").update(fs.readFileSync(dst)).digest("hex");
if (srcHash === dstHash) {
failures.push(`Signed file is identical to source file (not signed?): ${src} -> ${dst}\n sha256: ${dstHash}`);
continue;
}

if (src === dst) {
console.log(`Signed ${src}`);
}
else {
console.log(`Signed ${src} -> ${dst}`);
}
console.log(` sha256: ${dstHash}`);
}
}

if (failures.length) {
throw new Error("Some files failed to sign:\n" + failures.map(f => " - " + f).join("\n"));
}
}

/**
Expand Down
Loading