mirror of
https://github.com/danbulant/jose
synced 2026-05-25 04:51:47 +00:00
149 lines
4.5 KiB
JavaScript
149 lines
4.5 KiB
JavaScript
import test from 'ava';
|
||
import * as crypto from 'crypto';
|
||
|
||
const root = !('WEBCRYPTO' in process.env) ? '#dist' : '#dist/webcrypto';
|
||
Promise.all([import(`${root}/jws/general/sign`), import(`${root}/jws/general/verify`)]).then(
|
||
([{ GeneralSign }, { generalVerify }]) => {
|
||
test.before(async (t) => {
|
||
const encode = TextEncoder.prototype.encode.bind(new TextEncoder());
|
||
t.context.plaintext = encode('It’s a dangerous business, Frodo, going out your door.');
|
||
t.context.secret = crypto.randomFillSync(new Uint8Array(48));
|
||
});
|
||
|
||
test('General JWS signing', async (t) => {
|
||
const sig = new GeneralSign(t.context.plaintext);
|
||
|
||
sig
|
||
.addSignature(t.context.secret)
|
||
.setProtectedHeader({ bar: 'baz' })
|
||
.setUnprotectedHeader({ alg: 'HS256' });
|
||
|
||
sig
|
||
.addSignature(t.context.secret)
|
||
.setProtectedHeader({ bar: 'baz' })
|
||
.setUnprotectedHeader({ alg: 'HS384' });
|
||
|
||
const generalJws = await sig.sign();
|
||
|
||
t.is(
|
||
generalJws.payload,
|
||
'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4',
|
||
);
|
||
t.is(generalJws.signatures.length, 2);
|
||
});
|
||
|
||
test('General JWS signing b64:false', async (t) => {
|
||
const sig = new GeneralSign(t.context.plaintext);
|
||
|
||
sig
|
||
.addSignature(t.context.secret)
|
||
.setProtectedHeader({ bar: 'baz', b64: false, crit: ['b64'] })
|
||
.setUnprotectedHeader({ alg: 'HS256' });
|
||
|
||
sig
|
||
.addSignature(t.context.secret)
|
||
.setProtectedHeader({ bar: 'baz', b64: false, crit: ['b64'] })
|
||
.setUnprotectedHeader({ alg: 'HS384' });
|
||
|
||
const generalJws = await sig.sign();
|
||
|
||
t.is(generalJws.payload, '');
|
||
t.is(generalJws.signatures.length, 2);
|
||
});
|
||
|
||
test('General JWS signing validations', async (t) => {
|
||
const sig = new GeneralSign(t.context.plaintext);
|
||
|
||
t.throws(
|
||
() => {
|
||
sig
|
||
.addSignature(t.context.secret)
|
||
.setProtectedHeader({ bar: 'baz', crit: ['b64'], b64: false, alg: 'HS256' })
|
||
.setProtectedHeader({ bar: 'baz', crit: ['b64'], b64: false, alg: 'HS256' });
|
||
},
|
||
{ instanceOf: TypeError, message: 'setProtectedHeader can only be called once' },
|
||
);
|
||
|
||
t.throws(
|
||
() => {
|
||
sig
|
||
.addSignature(t.context.secret)
|
||
.setProtectedHeader({ bar: 'baz', crit: ['b64'], b64: true, alg: 'HS384' })
|
||
.setUnprotectedHeader({ foo: 'bar' })
|
||
.setUnprotectedHeader({ foo: 'bar' });
|
||
},
|
||
{ instanceOf: TypeError, message: 'setUnprotectedHeader can only be called once' },
|
||
);
|
||
|
||
await t.throwsAsync(sig.sign(), {
|
||
message: 'inconsistent use of JWS Unencoded Payload Option (RFC7797)',
|
||
code: 'ERR_JWS_INVALID',
|
||
});
|
||
});
|
||
|
||
test('General JWS verify format validation', async (t) => {
|
||
const sig = new GeneralSign(t.context.plaintext);
|
||
|
||
sig
|
||
.addSignature(t.context.secret)
|
||
.setProtectedHeader({ bar: 'baz' })
|
||
.setUnprotectedHeader({ alg: 'HS256' });
|
||
|
||
const generalJws = await sig.sign();
|
||
|
||
{
|
||
await t.throwsAsync(generalVerify(null, t.context.secret), {
|
||
message: 'General JWS must be an object',
|
||
code: 'ERR_JWS_INVALID',
|
||
});
|
||
}
|
||
|
||
{
|
||
await t.throwsAsync(generalVerify({ signatures: null }, t.context.secret), {
|
||
message: 'JWS Signatures missing or incorrect type',
|
||
code: 'ERR_JWS_INVALID',
|
||
});
|
||
}
|
||
|
||
{
|
||
await t.throwsAsync(generalVerify({ signatures: [null] }, t.context.secret), {
|
||
message: 'JWS Signatures missing or incorrect type',
|
||
code: 'ERR_JWS_INVALID',
|
||
});
|
||
}
|
||
|
||
{
|
||
const jws = { payload: generalJws.payload, signatures: [] };
|
||
|
||
await t.throwsAsync(generalVerify(jws, t.context.secret), {
|
||
message: 'signature verification failed',
|
||
code: 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED',
|
||
});
|
||
}
|
||
|
||
{
|
||
await t.notThrowsAsync(generalVerify(generalJws, t.context.secret));
|
||
}
|
||
|
||
{
|
||
const { payload, signatures } = generalJws;
|
||
const jws = { payload, signatures: [...signatures, {}] };
|
||
|
||
await t.notThrowsAsync(generalVerify(jws, t.context.secret));
|
||
}
|
||
|
||
{
|
||
const { payload, signatures } = generalJws;
|
||
const jws = { payload, signatures: [{}, ...signatures] };
|
||
|
||
await t.notThrowsAsync(generalVerify(jws, t.context.secret));
|
||
}
|
||
});
|
||
},
|
||
(err) => {
|
||
test('failed to import', (t) => {
|
||
console.error(err);
|
||
t.fail();
|
||
});
|
||
},
|
||
);
|