@oada/certs
Version:
Generate and verify JWT signatures (OAuth dynamic client registration certificates and Trellis document integrity signatures) in the Open Ag Data Alliance (OADA) and Trellis ecosystems
99 lines • 4 kB
JavaScript
import { readFile, unlink, writeFile } from 'node:fs/promises';
import fs from 'node:fs';
import path from 'node:path';
import url from 'node:url';
import debug from 'debug';
import minimist from 'minimist';
import pemjwk from 'pem-jwk';
import { keys, sign, validate } from '.';
const argv = minimist(process.argv.slice(2));
const error = debug('oada-certs:error');
if (argv.validate) {
let signedcertpath = './signed_software_statement.js';
if (argv.validate &&
argv.validate.length > 0 &&
!fs.existsSync(argv.validate)) {
signedcertpath = argv.validate;
}
const file = await readFile(signedcertpath);
let signedcert = file.toString();
if (signedcert.includes('module.exports')) {
signedcert = eval(signedcert);
}
else {
try {
signedcert = JSON.parse(signedcert);
}
catch { }
}
const { payload, trusted, valid, details } = await validate.validate(signedcert);
console.log('trusted:', trusted);
console.log('valid:', valid);
console.log('decoded payload:', payload);
console.log('details on validation:', details);
}
if (argv['create-keys']) {
if (argv.force) {
console.log('You asked for --force, removing key files');
try {
await unlink('./private_key.pem');
await unlink('./public_key.pem');
await unlink('./public_key.jwk');
}
catch {
}
}
console.log('Creating keys ./private_key.pem and ./public_key.pem...');
if (fs.existsSync('./private_key.pem')) {
throw new Error('ERROR: ./private_key.pem already exists, refusing to overwrite. force with --force');
}
if (fs.existsSync('./private_key.jwk')) {
throw new Error('ERROR: ./private_key.jwk already exists, refusing to overwrite. force with --force');
}
if (fs.existsSync('./public_key.pem')) {
throw new Error('ERROR: ./public_key.pem already exists, refusing to overwrite. force with --force');
}
if (fs.existsSync('./public_key.jwk')) {
throw new Error('ERROR: ./public_key.jwk already exists, refusing to overwrite. force with --force');
}
console.log('You could use "openssl genrsa -out private_key.pem 2048" to sign keys, but this will use built-in library');
const result = await keys.create();
console.log('Keys created, converting to PEM and writing output');
await Promise.all([
writeFile('./public_key.pem', pemjwk.jwk2pem(result.public)),
writeFile('./public_key.jwk', JSON.stringify(result.public)),
writeFile('./private_key.pem', pemjwk.jwk2pem(result.private)),
writeFile('./private_key.jwk', JSON.stringify(result.private)),
]);
console.log('Done creating ./public_key.pem, ./private_key.pem, ./public_key.jwk, and ./private_key.jwk');
console.log('IMPORTANT: for now, you have to put the jwk from ./public_key.jwk into your unsigned_clientcert.js manually as your signing key for OAuth2 requests');
}
const signkeypath = argv.signkey ||
`${path.dirname(url.fileURLToPath(import.meta.url))}/test/dev_privatekey.pem`;
const file = await readFile(signkeypath);
const signkey = {
kty: 'PEM',
pem: file.toString(),
kid: argv.signkid || 'dev1',
};
const unsignedcertpath = argv.sign || './unsigned_software_statement.js';
let unsignedcert;
try {
const cert = await readFile(unsignedcertpath);
unsignedcert = eval(cert.toString());
}
catch (error_) {
error('Failed to read unsigned cert ', unsignedcertpath, '. Error was: ', error_);
throw error_;
}
const options = { header: {} };
if (argv.signjku) {
options.header.jku = argv.signjku;
}
if (argv.signkid) {
options.header.kid = argv.signkid;
}
const signedcert = await sign(unsignedcert, signkey, options);
await writeFile('./signed_software_statement.js', `module.exports = ${JSON.stringify(signedcert)};`);
console.log('Wrote JWT to ./signed_software_statement.js');
//# sourceMappingURL=cli.mjs.map