Files

51 lines
2.5 KiB
JavaScript

import assert from 'node:assert/strict'
import test from 'node:test'
import { parseKeyring, validateKeyringTransition, verifyRecoveryKeyring } from '../stage0/lib/keyring.mjs'
import { document, keyPair, keyring, signature } from './helpers.mjs'
test('accepts a Recovery-signed keyring with derived current and next IDs', () => {
const recovery = keyPair()
const value = keyring(1, keyPair(), keyPair())
const bytes = document(value)
assert.deepEqual(verifyRecoveryKeyring(bytes, signature(bytes, recovery), recovery.publicKey), value)
})
test('rejects a keyring signed by a non-Recovery key or modified after signing', () => {
const recovery = keyPair()
const other = keyPair()
const bytes = document(keyring(1, keyPair(), keyPair()))
assert.throws(() => verifyRecoveryKeyring(bytes, signature(bytes, other), recovery.publicKey), {
code: 'TRUST_UNKNOWN_KEY',
})
const signed = signature(bytes, recovery)
assert.throws(() => verifyRecoveryKeyring(Buffer.concat([bytes, Buffer.from(' ')]), signed, recovery.publicKey), {
code: 'TRUST_BAD_SIGNATURE',
})
})
test('rejects mismatched IDs, duplicate active keys, revoked active keys, and unknown algorithms', () => {
const current = keyPair()
const next = keyPair()
const cases = [
{ ...keyring(1, current, next), current: { ...keyring(1, current, next).current, keyId: next.keyId } },
{ ...keyring(1, current, next), next: { ...keyring(1, current, next).current } },
{ ...keyring(1, current, next), revokedKeyIds: [current.keyId] },
{ ...keyring(1, current, next), current: { ...keyring(1, current, next).current, algorithm: 'RSA' } },
]
for (const value of cases) assert.throws(() => parseKeyring(document(value)))
})
test('requires transitions to preserve revocations and revoke removed keys', () => {
const first = keyPair()
const second = keyPair()
const third = keyPair()
const fourth = keyPair()
const initial = parseKeyring(document(keyring(1, first, second)))
const rotated = parseKeyring(document(keyring(2, second, third, [first.keyId])))
assert.equal(validateKeyringTransition(initial, rotated), rotated)
assert.throws(() => validateKeyringTransition(initial, parseKeyring(document(keyring(2, second, third)))))
const next = parseKeyring(document(keyring(3, third, fourth, [first.keyId, second.keyId])))
assert.equal(validateKeyringTransition(rotated, next), next)
assert.throws(() => validateKeyringTransition(next, parseKeyring(document(keyring(4, first, fourth, [second.keyId, third.keyId])))))
})