Skip to content

Commit

Permalink
Introduce integrity block v2 (#890)
Browse files Browse the repository at this point in the history
  • Loading branch information
GrapeGreen authored Jul 9, 2024
1 parent 2011517 commit 4f468dc
Show file tree
Hide file tree
Showing 12 changed files with 264 additions and 89 deletions.
3 changes: 2 additions & 1 deletion js/sign/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules
lib
wbn-sign*.tgz
*.wbn
*.wbn
*.swbn
7 changes: 7 additions & 0 deletions js/sign/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ environment variable named `WEB_BUNDLE_SIGNING_PASSPHRASE`.

## Release Notes

### v0.2.0

- Add support for the v2 integrity block format. Now web-bundle-id is no longer
presumed to be a derivative of the first public key in the stack, but rather
acts as a separate entry in the integrity block attributes, and multiple
independent signatures are allowed to facilitate key rotation.

### v0.1.3

- Add support for ECDSA P-256 SHA-256 signatures
Expand Down
32 changes: 16 additions & 16 deletions js/sign/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions js/sign/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "wbn-sign",
"version": "0.1.3",
"version": "0.2.0",
"description": "Signing tool to sign a web bundle with integrity block",
"homepage": "https://github.com/WICG/webpackage/tree/main/js/sign",
"main": "./lib/wbn-sign.cjs",
Expand Down Expand Up @@ -40,7 +40,7 @@
"dependencies": {
"base32-encode": "^2.0.0",
"cborg": "^1.9.4",
"commander": "^4.0.1",
"commander": "^7.0.0",
"read": "^2.0.0"
},
"devDependencies": {
Expand Down
22 changes: 13 additions & 9 deletions js/sign/src/cli-dump-id.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import commander from 'commander';
import { Command } from 'commander';
import { WebBundleId } from './wbn-sign.js';
import * as fs from 'fs';
import { greenConsoleLog, parseMaybeEncryptedKey } from './utils/cli-utils.js';
import {
greenConsoleLog,
parseMaybeEncryptedKeyFromFile,
} from './utils/cli-utils.js';
import { KeyObject } from 'crypto';

const program = new commander.Command()
const program = new Command()
.name('wbn-dump-id')
.description(
'A simple CLI tool to dump the Web Bundle ID matching to the given private key.'
Expand All @@ -13,21 +16,22 @@ const program = new commander.Command()
function readOptions() {
return program
.requiredOption(
'-k, --privateKey <file>',
'Reads an ed25519 private key from the given path. (required)'
'-k, --private-key <file>',
'Reads an Ed25519 / ECDSA P-256 private key from the given path. (required)'
)
.option(
'-s, --withIwaScheme',
'-s, --with-iwa-scheme',
'Dumps the Web Bundle ID with isolated-app:// scheme. By default it only dumps the ID. (optional)',
/*defaultValue=*/ false
)
.parse(process.argv);
.parse(process.argv)
.opts();
}

export async function main() {
const options = readOptions();
const parsedPrivateKey: KeyObject = await parseMaybeEncryptedKey(
fs.readFileSync(options.privateKey)
const parsedPrivateKey: KeyObject = await parseMaybeEncryptedKeyFromFile(
options.privateKey
);

const webBundleId: string = options.withIwaScheme
Expand Down
65 changes: 54 additions & 11 deletions js/sign/src/cli-sign.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,91 @@
import commander from 'commander';
import { Command, Option } from 'commander';
import {
NodeCryptoSigningStrategy,
IntegrityBlockSigner,
WebBundleId,
} from './wbn-sign.js';
import * as fs from 'fs';
import { greenConsoleLog, parseMaybeEncryptedKey } from './utils/cli-utils.js';
import {
greenConsoleLog,
parseMaybeEncryptedKeyFromFile,
} from './utils/cli-utils.js';
import { KeyObject } from 'crypto';

const program = new commander.Command()
const program = new Command()
.name('wbn-sign')
.description(
'A simple CLI tool to sign the given web bundle with the given private key.'
);

function readOptions() {
return program
.addOption(
new Option('--version <version>').choices(['v1', 'v2']).default('v1')
)
.requiredOption(
'-i, --input <file>',
'input web bundle to be signed (required)'
)
.requiredOption(
'-k, --privateKey <file>',
'path to ed25519 private key (required)'
'-k, --private-key <file...>',
'paths to Ed25519 / ECDSA P-256 private key(s) (required)'
)
.option(
'-o, --output <file>',
'signed web bundle output file',
/*defaultValue=*/ 'signed.swbn'
)
.parse(process.argv);
.option('--web-bundle-id <web-bundle-id>', 'web bundle ID (only for v2)')
.action((options) => {
switch (options.version) {
case 'v1':
{
if (options.privateKey.length > 1) {
throw new Error(
`It's not allowed to specify more than one private key for v1 signing.`
);
}
if (options.webBundleId) {
throw new Error(
`It's not allowed to specify --web-bundle-id for v1 signing.`
);
}
}
break;
case 'v2':
{
if (options.privateKey.length > 1 && !options.webBundleId) {
throw new Error(
`--web-bundle-id must be specified if there's more than 1 signing key involved.`
);
}
}
break;
}
})
.parse(process.argv)
.opts();
}

export async function main() {
const options = readOptions();
const webBundle = fs.readFileSync(options.input);
const parsedPrivateKey: KeyObject = await parseMaybeEncryptedKey(
fs.readFileSync(options.privateKey)
);

const privateKeys = new Array<KeyObject>();
for (const privateKey of options.privateKey) {
privateKeys.push(await parseMaybeEncryptedKeyFromFile(privateKey));
}

const webBundleId = options.webBundleId
? options.webBundleId
: new WebBundleId(privateKeys[0]).serialize();
const signer = new IntegrityBlockSigner(
/*is_v2=*/ options.version === 'v2',
webBundle,
new NodeCryptoSigningStrategy(parsedPrivateKey)
webBundleId,
privateKeys.map((privateKey) => new NodeCryptoSigningStrategy(privateKey))
);
const { signedWebBundle } = await signer.sign();
greenConsoleLog(`${new WebBundleId(parsedPrivateKey)}`);
greenConsoleLog(`${webBundleId}`);
fs.writeFileSync(options.output, signedWebBundle);
}
Loading

0 comments on commit 4f468dc

Please sign in to comment.