• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4
5if (!common.hasCrypto)
6  common.skip('missing crypto');
7
8const assert = require('assert');
9const { subtle } = require('crypto').webcrypto;
10
11const vectors = require('../fixtures/crypto/eddsa')();
12
13async function testVerify({ name,
14                            publicKeyBuffer,
15                            privateKeyBuffer,
16                            signature,
17                            data }) {
18  const [
19    publicKey,
20    noVerifyPublicKey,
21    privateKey,
22    hmacKey,
23    rsaKeys,
24    ecKeys,
25  ] = await Promise.all([
26    subtle.importKey(
27      'spki',
28      publicKeyBuffer,
29      { name },
30      false,
31      ['verify']),
32    subtle.importKey(
33      'spki',
34      publicKeyBuffer,
35      { name },
36      false,
37      [ /* No usages */ ]),
38    subtle.importKey(
39      'pkcs8',
40      privateKeyBuffer,
41      { name },
42      false,
43      ['sign']),
44    subtle.generateKey(
45      { name: 'HMAC', hash: 'SHA-256' },
46      false,
47      ['sign']),
48    subtle.generateKey(
49      {
50        name: 'RSA-PSS',
51        modulusLength: 1024,
52        publicExponent: new Uint8Array([1, 0, 1]),
53        hash: 'SHA-256',
54      },
55      false,
56      ['sign']),
57    subtle.generateKey(
58      {
59        name: 'ECDSA',
60        namedCurve: 'P-256'
61      },
62      false,
63      ['sign']),
64  ]);
65
66  assert(await subtle.verify({ name }, publicKey, signature, data));
67
68  // Test verification with altered buffers
69  const copy = Buffer.from(data);
70  const sigcopy = Buffer.from(signature);
71  const p = subtle.verify({ name }, publicKey, sigcopy, copy);
72  copy[0] = 255 - copy[0];
73  sigcopy[0] = 255 - sigcopy[0];
74  assert(await p);
75
76  // Test failure when using wrong key
77  await assert.rejects(
78    subtle.verify({ name }, privateKey, signature, data), {
79      message: /Unable to use this key to verify/
80    });
81
82  await assert.rejects(
83    subtle.verify({ name }, noVerifyPublicKey, signature, data), {
84      message: /Unable to use this key to verify/
85    });
86
87  // Test failure when using the wrong algorithms
88  await assert.rejects(
89    subtle.verify({ name }, hmacKey, signature, data), {
90      message: /Unable to use this key to verify/
91    });
92
93  await assert.rejects(
94    subtle.verify({ name }, rsaKeys.publicKey, signature, data), {
95      message: /Unable to use this key to verify/
96    });
97
98  await assert.rejects(
99    subtle.verify({ name }, ecKeys.publicKey, signature, data), {
100      message: /Unable to use this key to verify/
101    });
102
103  // Test failure when signature is altered
104  {
105    const copy = Buffer.from(signature);
106    copy[0] = 255 - copy[0];
107    assert(!(await subtle.verify(
108      { name },
109      publicKey,
110      copy,
111      data)));
112    assert(!(await subtle.verify(
113      { name },
114      publicKey,
115      copy.slice(1),
116      data)));
117  }
118
119  // Test failure when data is altered
120  {
121    const copy = Buffer.from(data);
122    copy[0] = 255 - copy[0];
123    assert(!(await subtle.verify({ name }, publicKey, signature, copy)));
124  }
125}
126
127async function testSign({ name,
128                          publicKeyBuffer,
129                          privateKeyBuffer,
130                          signature,
131                          data }) {
132  const [
133    publicKey,
134    privateKey,
135    hmacKey,
136    rsaKeys,
137    ecKeys,
138  ] = await Promise.all([
139    subtle.importKey(
140      'spki',
141      publicKeyBuffer,
142      { name },
143      false,
144      ['verify']),
145    subtle.importKey(
146      'pkcs8',
147      privateKeyBuffer,
148      { name },
149      false,
150      ['sign']),
151    subtle.generateKey(
152      { name: 'HMAC', hash: 'SHA-256' },
153      false,
154      ['sign']),
155    subtle.generateKey(
156      {
157        name: 'RSA-PSS',
158        modulusLength: 1024,
159        publicExponent: new Uint8Array([1, 0, 1]),
160        hash: 'SHA-256',
161      },
162      false,
163      ['sign']),
164    subtle.generateKey(
165      {
166        name: 'ECDSA',
167        namedCurve: 'P-256'
168      },
169      false,
170      ['sign']),
171  ]);
172
173  {
174    const sig = await subtle.sign({ name }, privateKey, data);
175    assert.strictEqual(sig.byteLength, signature.byteLength);
176    assert(await subtle.verify({ name }, publicKey, sig, data));
177  }
178
179  {
180    const copy = Buffer.from(data);
181    const p = subtle.sign({ name }, privateKey, copy);
182    copy[0] = 255 - copy[0];
183    const sig = await p;
184    assert(await subtle.verify({ name }, publicKey, sig, data));
185  }
186
187  // Test failure when using wrong key
188  await assert.rejects(
189    subtle.sign({ name }, publicKey, data), {
190      message: /Unable to use this key to sign/
191    });
192
193  // Test failure when using the wrong algorithms
194  await assert.rejects(
195    subtle.sign({ name }, hmacKey, data), {
196      message: /Unable to use this key to sign/
197    });
198
199  await assert.rejects(
200    subtle.sign({ name }, rsaKeys.privateKey, data), {
201      message: /Unable to use this key to sign/
202    });
203
204  await assert.rejects(
205    subtle.sign({ name }, ecKeys.privateKey, data), {
206      message: /Unable to use this key to sign/
207    });
208}
209
210(async function() {
211  const variations = [];
212
213  vectors.forEach((vector) => {
214    variations.push(testVerify(vector));
215    variations.push(testSign(vector));
216  });
217
218  await Promise.all(variations);
219})().then(common.mustCall());
220
221// Ed448 context
222{
223  const vector = vectors.find(({ name }) => name === 'Ed448');
224  Promise.all([
225    subtle.importKey(
226      'pkcs8',
227      vector.privateKeyBuffer,
228      { name: 'Ed448' },
229      false,
230      ['sign']),
231    subtle.importKey(
232      'spki',
233      vector.publicKeyBuffer,
234      { name: 'Ed448' },
235      false,
236      ['verify']),
237  ]).then(async ([privateKey, publicKey]) => {
238    const sig = await subtle.sign({ name: 'Ed448', context: Buffer.alloc(0) }, privateKey, vector.data);
239    assert.deepStrictEqual(Buffer.from(sig), vector.signature);
240    assert.strictEqual(
241      await subtle.verify({ name: 'Ed448', context: Buffer.alloc(0) }, publicKey, sig, vector.data), true);
242
243    await assert.rejects(subtle.sign({ name: 'Ed448', context: Buffer.alloc(1) }, privateKey, vector.data), {
244      message: /Non zero-length context is not yet supported/
245    });
246    await assert.rejects(subtle.verify({ name: 'Ed448', context: Buffer.alloc(1) }, publicKey, sig, vector.data), {
247      message: /Non zero-length context is not yet supported/
248    });
249  }).then(common.mustCall());
250}
251