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