Skip to content

Commit a1fb91c

Browse files
committed
fix: using specification algorithm for ECDSA signatures (IEEE-P1363 format)
1 parent f52b0ee commit a1fb91c

File tree

5 files changed

+44
-19
lines changed

5 files changed

+44
-19
lines changed

src/algorithm/index.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
VerifyPublicKeyInput,
1212
sign,
1313
verify,
14+
KeyObject,
1415
} from 'crypto';
1516
import { RSA_PKCS1_PADDING, RSA_PKCS1_PSS_PADDING } from 'constants';
1617
import { SigningKey, Algorithm, Verifier } from '../types';
@@ -50,10 +51,16 @@ export function createSigner(key: BinaryLike | KeyLike | SignKeyObjectInput | Si
5051
} as SignPrivateKeyInput);
5152
break;
5253
case 'ecdsa-p256-sha256':
53-
signer.sign = async (data: Buffer) => createSign('sha256').update(data).sign(key as KeyLike);
54+
signer.sign = async (data: Buffer) => createSign('sha256').update(data).sign({
55+
key: key as KeyObject,
56+
dsaEncoding: 'ieee-p1363',
57+
});
5458
break;
5559
case 'ecdsa-p384-sha384':
56-
signer.sign = async (data: Buffer) => createSign('sha384').update(data).sign(key as KeyLike);
60+
signer.sign = async (data: Buffer) => createSign('sha384').update(data).sign({
61+
key: key as KeyObject,
62+
dsaEncoding: 'ieee-p1363',
63+
});
5764
break;
5865
case 'ed25519':
5966
signer.sign = async (data: Buffer) => sign(null, data, key as KeyLike);
@@ -108,10 +115,16 @@ export function createVerifier(key: BinaryLike | KeyLike | VerifyKeyObjectInput
108115
} as VerifyPublicKeyInput, signature);
109116
break;
110117
case 'ecdsa-p256-sha256':
111-
verifier = async (data: Buffer, signature: Buffer) => createVerify('sha256').update(data).verify(key as KeyLike, signature);
118+
verifier = async (data: Buffer, signature: Buffer) => createVerify('sha256').update(data).verify({
119+
key: key as KeyObject,
120+
dsaEncoding: 'ieee-p1363',
121+
}, signature);
112122
break;
113123
case 'ecdsa-p384-sha384':
114-
verifier = async (data: Buffer, signature: Buffer) => createVerify('sha384').update(data).verify(key as KeyLike, signature);
124+
verifier = async (data: Buffer, signature: Buffer) => createVerify('sha384').update(data).verify({
125+
key: key as KeyObject,
126+
dsaEncoding: 'ieee-p1363',
127+
}, signature);
115128
break;
116129
case 'ed25519':
117130
verifier = async (data: Buffer, signature: Buffer) => verify(null, data, key as KeyLike, signature) as unknown as boolean;

src/types/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export type Signer = (data: Buffer) => Promise<Buffer>;
1313
export type Verifier = (data: Buffer, signature: Buffer, parameters?: SignatureParameters) => Promise<boolean | null>;
1414
export type VerifierFinder = (parameters: SignatureParameters) => Promise<VerifyingKey | null>;
1515

16-
export type Algorithm = 'rsa-v1_5-sha256' | 'ecdsa-p256-sha256' | 'hmac-sha256' | 'rsa-pss-sha512' | string;
16+
export type Algorithm = 'rsa-v1_5-sha256' | 'ecdsa-p256-sha256' | 'ecdsa-p384-sha384' | 'ed25519' | 'hmac-sha256' | 'rsa-pss-sha512' | string;
1717

1818
export interface SigningKey {
1919
/**

test/algorithm/ecdsa-p256-sha256.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,20 @@ describe('ecdsa-p256-sha256', () => {
2727
const data = Buffer.from('some random data');
2828
const sig = await signer.sign(data);
2929
expect(signer.alg).to.equal('ecdsa-p256-sha256');
30-
expect(sig).to.satisfy((arg: Buffer) => verify('sha256', data, ecdsaKeyPair.publicKey, arg));
30+
expect(sig).to.satisfy((arg: Buffer) => verify('sha256', data, {
31+
key: ecdsaKeyPair.publicKey,
32+
dsaEncoding: 'ieee-p1363',
33+
}, arg));
3134
});
3235
});
3336
describe('verifying', () => {
3437
it('verifies a signature', async () => {
3538
const verifier = createVerifier(ecdsaKeyPair.publicKey, 'ecdsa-p256-sha256');
3639
const data = Buffer.from('some random data');
37-
const sig = sign('sha256', data, ecdsaKeyPair.privateKey);
40+
const sig = sign('sha256', data, {
41+
key: ecdsaKeyPair.privateKey,
42+
dsaEncoding: 'ieee-p1363',
43+
});
3844
expect(sig).to.satisfy((arg: Buffer) => verifier(data, arg));
3945
});
4046
});
@@ -52,11 +58,12 @@ describe('ecdsa-p256-sha256', () => {
5258
'"@signature-params": ("@status" "content-type" "content-digest" "content-length");created=1618884473;keyid="test-key-ecc-p256"');
5359
it('successfully signs a payload', async () => {
5460
const sig = await (createSigner(ecKeyPem, 'ecdsa-p256-sha256').sign(data));
55-
expect(sig).to.satisfy((arg: Buffer) => verify('sha256', data, ecKeyPem, arg));
61+
expect(sig).to.satisfy((arg: Buffer) => verify('sha256', data, {
62+
key: ecKeyPem,
63+
dsaEncoding: 'ieee-p1363',
64+
}, arg));
5665
});
57-
// seems to be broken in node - Error: error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long
58-
// could be to do with https://stackoverflow.com/a/39575576
59-
it.skip('successfully verifies a signature', async () => {
66+
it('successfully verifies a signature', async () => {
6067
const sig = Buffer.from('wNmSUAhwb5LxtOtOpNa6W5xj067m5hFrj0XQ4fvpaCLx0NKocgPquLgyahnzDnDAUy5eCdlYUEkLIj+32oiasw==', 'base64');
6168
expect(await (createVerifier(ecKeyPem, 'ecdsa-p256-sha256')(data, sig))).to.equal(true);
6269
});

test/algorithm/ecdsa-p384-sha384.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,20 @@ describe('ecdsa-p384-sha384', () => {
2525
const data = Buffer.from('some random data');
2626
const sig = await signer.sign(data);
2727
expect(signer.alg).to.equal('ecdsa-p384-sha384');
28-
expect(sig).to.satisfy((arg: Buffer) => verify('sha384', data, ecdsaKeyPair.publicKey, arg));
28+
expect(sig).to.satisfy((arg: Buffer) => verify('sha384', data, {
29+
key: ecdsaKeyPair.publicKey,
30+
dsaEncoding: 'ieee-p1363',
31+
}, arg));
2932
});
3033
});
3134
describe('verifying', () => {
3235
it('verifies a signature', async () => {
3336
const verifier = createVerifier(ecdsaKeyPair.publicKey, 'ecdsa-p384-sha384');
3437
const data = Buffer.from('some random data');
35-
const sig = sign('sha384', data, ecdsaKeyPair.privateKey);
38+
const sig = sign('sha384', data, {
39+
key: ecdsaKeyPair.privateKey,
40+
dsaEncoding: 'ieee-p1363',
41+
});
3642
expect(sig).to.satisfy((arg: Buffer) => verifier(data, arg));
3743
});
3844
});

test/httpbis/httpbis.int.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ describe('httpbis', () => {
185185
res.setHeader('Content-Digest', 'sha-512=:mEWXIS7MaLRuGgxOBdODa3xqM1XdEvxoYhvlCFJ41QJgJc4GTsPp29l5oGX69wWdXymyU0rjJuahq4l5aGgfLQ==:');
186186
res.setHeader('Content-Length', '23');
187187
res.setHeader('Signature-Input', 'sig-b24=("@status" "content-type" "content-digest" "content-length");created=1618884473;keyid="test-key-ecc-p256"');
188-
res.setHeader('Signature', 'sig-b24=:MEYCIQDXrmWrcxKWLQQm0zlwbFr5/KAlB9oHkfMpNRVCuGVHjQIhAKtljVKRuRoWv5dCKuc+GgP3eqLAq+Eg0d3olyR67BYK:');
188+
res.setHeader('Signature', 'sig-b24=:wNmSUAhwb5LxtOtOpNa6W5xj067m5hFrj0XQ4fvpaCLx0NKocgPquLgyahnzDnDAUy5eCdlYUEkLIj+32oiasw==:');
189189
res.end('{"message": "good dog"}');
190190
});
191191
return server.start();
@@ -335,8 +335,7 @@ describe('httpbis', () => {
335335
});
336336
});
337337
describe('ecdsa-p256-sha256', () => {
338-
// There seems to be a problem in node in verifying ecdsa signatures from external sources
339-
it.skip('verifies a response', async () => {
338+
it('verifies a response', async () => {
340339
const response = await makeHttpRequest({
341340
method: 'POST',
342341
url: 'http://example.com/foo?param=Value&Pet=dog',
@@ -455,7 +454,7 @@ describe('httpbis', () => {
455454
'content-digest': 'sha-512=:mEWXIS7MaLRuGgxOBdODa3xqM1XdEvxoYhvlCFJ41QJgJc4GTsPp29l5oGX69wWdXymyU0rjJuahq4l5aGgfLQ==:',
456455
'content-length': '23',
457456
'signature-input': 'sig-b24=("@status" "content-type" "content-digest" "content-length");created=1618884473;keyid="test-key-ecc-p256"',
458-
'signature': 'sig-b24=:MEYCIQDXrmWrcxKWLQQm0zlwbFr5/KAlB9oHkfMpNRVCuGVHjQIhAKtljVKRuRoWv5dCKuc+GgP3eqLAq+Eg0d3olyR67BYK:',
457+
'signature': 'sig-b24=:wNmSUAhwb5LxtOtOpNa6W5xj067m5hFrj0XQ4fvpaCLx0NKocgPquLgyahnzDnDAUy5eCdlYUEkLIj+32oiasw==:',
459458
});
460459
stream.end('{"message": "good dog"}');
461460
stream.close();
@@ -610,8 +609,7 @@ describe('httpbis', () => {
610609
});
611610
});
612611
describe('ecdsa-p256-sha256', () => {
613-
// There seems to be a problem in node in verifying ecdsa signatures from external sources
614-
it.skip('verifies a response', async () => {
612+
it('verifies a response', async () => {
615613
const response = await makeHttp2Request({
616614
method: 'POST',
617615
url: 'http://example.com/foo?param=Value&Pet=dog',
@@ -634,6 +632,7 @@ describe('httpbis', () => {
634632
}
635633
return null;
636634
});
635+
console.log(response.headers);
637636
const valid = await httpbis.verifyMessage({
638637
keyLookup,
639638
}, {

0 commit comments

Comments
 (0)