50 lines
1.5 KiB
JavaScript
50 lines
1.5 KiB
JavaScript
import { createHash, generateKeyPairSync } from 'node:crypto'
|
|
import { mkdirSync, rmSync, writeFileSync } from 'node:fs'
|
|
import { dirname, resolve } from 'node:path'
|
|
|
|
const args = process.argv.slice(2)
|
|
const privateKeyPath = resolve(option('--private-key'))
|
|
const publicKeyPath = resolve(option('--public-key'))
|
|
|
|
if (privateKeyPath === publicKeyPath) fail('Private and public key paths must differ.')
|
|
|
|
mkdirSync(dirname(privateKeyPath), { recursive: true })
|
|
mkdirSync(dirname(publicKeyPath), { recursive: true })
|
|
|
|
const { privateKey, publicKey } = generateKeyPairSync('ed25519')
|
|
const privatePem = privateKey.export({ type: 'pkcs8', format: 'pem' })
|
|
const publicPem = publicKey.export({ type: 'spki', format: 'pem' })
|
|
|
|
let privateCreated = false
|
|
try {
|
|
writeFileSync(privateKeyPath, privatePem, { flag: 'wx', mode: 0o600 })
|
|
privateCreated = true
|
|
writeFileSync(publicKeyPath, publicPem, { flag: 'wx', mode: 0o644 })
|
|
} catch (error) {
|
|
if (privateCreated) rmSync(privateKeyPath, { force: true })
|
|
throw error
|
|
}
|
|
|
|
const keyId = createHash('sha256')
|
|
.update(publicKey.export({ type: 'spki', format: 'der' }))
|
|
.digest('hex')
|
|
|
|
process.stdout.write(`${JSON.stringify({
|
|
ok: true,
|
|
algorithm: 'Ed25519',
|
|
keyId,
|
|
privateKeyPath,
|
|
publicKeyPath,
|
|
}, null, 2)}\n`)
|
|
|
|
function option(name) {
|
|
const index = args.indexOf(name)
|
|
const value = index === -1 ? undefined : args[index + 1]
|
|
if (!value || value.startsWith('--')) fail(`${name} is required.`)
|
|
return value
|
|
}
|
|
|
|
function fail(message) {
|
|
process.stderr.write(`[release-evidence-key] ${message}\n`)
|
|
process.exit(1)
|
|
}
|