Skip to content

Commit

Permalink
feat(compartment-mapper): parseArchive return hash
Browse files Browse the repository at this point in the history
  • Loading branch information
kriskowal committed Feb 19, 2022
1 parent 4204058 commit 1306c7d
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 10 deletions.
7 changes: 7 additions & 0 deletions packages/compartment-mapper/NEWS.md
@@ -1,5 +1,12 @@
User-visible changes to the compartment mapper:

# Next release

- The `parseArchive` function returns a promise for an archive. If provided a
`computeSha512`, regardless of whether provided `expectedSha512`, the archive
will have a `sha512` property computed from the parsed archive, for
the purpose of verifying integrity.

# 0.5.3 (2021-12-08)

- The `node-powers.js` module now exports `makeReadPowers` and
Expand Down
3 changes: 3 additions & 0 deletions packages/compartment-mapper/README.md
Expand Up @@ -116,6 +116,9 @@ Use `parseArchive` to construct a runner from the bytes of an archive.
The `loadArchive` and `parseArchive` functions return an `Application`
object with an `import({ globals?, modules? })` method.
`loadArchive` and `parseArchive` do not run the archived program,
so they can be used to check the hash of a program without running it.
# Package Descriptors
The compartment mapper uses [Compartments], one for each Node.js package your
Expand Down
9 changes: 6 additions & 3 deletions packages/compartment-mapper/src/import-archive.js
Expand Up @@ -150,13 +150,16 @@ export const parseArchive = async (
const archive = await readZip(archiveBytes, archiveLocation);
const compartmentMapBytes = await archive.read('compartment-map.json');

let sha512;
if (computeSha512 !== undefined) {
sha512 = computeSha512(compartmentMapBytes);
}
if (expectedSha512 !== undefined) {
if (computeSha512 === undefined) {
if (sha512 === undefined) {
throw new Error(
`Cannot verify expectedSha512 without also providing computeSha512, for archive ${archiveLocation}`,
);
}
const sha512 = computeSha512(compartmentMapBytes);
if (sha512 !== expectedSha512) {
throw new Error(
`Archive compartment map failed a SHA-512 integrity check, expected ${expectedSha512}, got ${sha512}, for archive ${archiveLocation}`,
Expand Down Expand Up @@ -205,7 +208,7 @@ export const parseArchive = async (
return compartment.import(moduleSpecifier);
};

return { import: execute };
return { import: execute, sha512 };
};

/**
Expand Down
20 changes: 13 additions & 7 deletions packages/compartment-mapper/test/scaffold.js
Expand Up @@ -184,7 +184,7 @@ export function scaffold(
});

test(`${name} / makeArchive / parseArchive / hashArchive consistency`, async t => {
t.plan(0);
t.plan(1);
await setup();

const expectedSha512 = await hashLocation(readPowers, fixture, {
Expand All @@ -198,12 +198,18 @@ export function scaffold(
});

const { computeSha512 } = readPowers;
await parseArchive(archiveBytes, 'memory:app.agar', {
modules,
dev: true,
computeSha512,
expectedSha512,
});
const { sha512: computedSha512 } = await parseArchive(
archiveBytes,
'memory:app.agar',
{
modules,
dev: true,
computeSha512,
expectedSha512,
},
);

t.is(computedSha512, expectedSha512);
});

test(`${name} / makeArchive / parseArchive, but with sha512 corruption of a compartment map`, async t => {
Expand Down

0 comments on commit 1306c7d

Please sign in to comment.