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