• 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/hmac')();
12
13async function testVerify({ hash,
14                            keyBuffer,
15                            signature,
16                            plaintext }) {
17  const name = 'HMAC';
18  const [
19    key,
20    noVerifyKey,
21    rsaKeys,
22  ] = await Promise.all([
23    subtle.importKey(
24      'raw',
25      keyBuffer,
26      { name, hash },
27      false,
28      ['verify']),
29    subtle.importKey(
30      'raw',
31      keyBuffer,
32      { name, hash },
33      false,
34      ['sign']),
35    subtle.generateKey(
36      {
37        name: 'RSA-PSS',
38        modulusLength: 1024,
39        publicExponent: new Uint8Array([1, 0, 1]),
40        hash: 'SHA-256',
41      },
42      false,
43      ['sign']),
44  ]);
45
46  assert(await subtle.verify({ name, hash }, key, signature, plaintext));
47
48  // Test verification with altered buffers
49  const copy = Buffer.from(plaintext);
50  const sigcopy = Buffer.from(signature);
51  const p = subtle.verify({ name, hash }, key, sigcopy, copy);
52  copy[0] = 255 - copy[0];
53  sigcopy[0] = 255 - sigcopy[0];
54  assert(await p);
55
56  // Test failure when using wrong key
57  await assert.rejects(
58    subtle.verify({ name, hash }, noVerifyKey, signature, plaintext), {
59      message: /Unable to use this key to verify/
60    });
61
62  // Test failure when using the wrong algorithms
63  await assert.rejects(
64    subtle.verify({ name, hash }, rsaKeys.publicKey, signature, plaintext), {
65      message: /Unable to use this key to verify/
66    });
67
68  // Test failure when signature is altered
69  {
70    const copy = Buffer.from(signature);
71    copy[0] = 255 - copy[0];
72    assert(!(await subtle.verify(
73      { name, hash },
74      key,
75      copy,
76      plaintext)));
77    assert(!(await subtle.verify(
78      { name, hash },
79      key,
80      copy.slice(1),
81      plaintext)));
82  }
83
84  // Test failure when data is altered
85  {
86    const copy = Buffer.from(plaintext);
87    copy[0] = 255 - copy[0];
88    assert(!(await subtle.verify({ name, hash }, key, signature, copy)));
89  }
90
91  // Test failure when wrong hash is used
92  {
93    const otherhash = hash === 'SHA-1' ? 'SHA-256' : 'SHA-1';
94    const keyWithOtherHash = await subtle.importKey(
95      'raw',
96      keyBuffer,
97      { name, hash: otherhash },
98      false,
99      ['verify']);
100    assert(!(await subtle.verify({ name }, keyWithOtherHash, signature, plaintext)));
101  }
102}
103
104async function testSign({ hash,
105                          keyBuffer,
106                          signature,
107                          plaintext }) {
108  const name = 'HMAC';
109  const [
110    key,
111    noSignKey,
112    rsaKeys,
113  ] = await Promise.all([
114    subtle.importKey(
115      'raw',
116      keyBuffer,
117      { name, hash },
118      false,
119      ['verify', 'sign']),
120    subtle.importKey(
121      'raw',
122      keyBuffer,
123      { name, hash },
124      false,
125      [ 'verify' ]),
126    subtle.generateKey(
127      {
128        name: 'RSA-PSS',
129        modulusLength: 1024,
130        publicExponent: new Uint8Array([1, 0, 1]),
131        hash: 'SHA-256',
132      },
133      false,
134      ['sign']),
135  ]);
136
137  {
138    const sig = await subtle.sign({ name, hash }, key, plaintext);
139    assert.strictEqual(
140      Buffer.from(sig).toString('hex'),
141      signature.toString('hex'));
142    assert(await subtle.verify({ name, hash }, key, sig, plaintext));
143  }
144
145  {
146    const copy = Buffer.from(plaintext);
147    const p = subtle.sign({ name, hash }, key, copy);
148    copy[0] = 255 - copy[0];
149    const sig = await p;
150    assert(await subtle.verify({ name, hash }, key, sig, plaintext));
151  }
152
153  await assert.rejects(
154    subtle.generateKey({ name }, false, ['sign', 'verify']), {
155      name: 'TypeError',
156      code: 'ERR_MISSING_OPTION',
157    });
158
159  // Test failure when no sign usage
160  await assert.rejects(
161    subtle.sign({ name, hash }, noSignKey, plaintext), {
162      message: /Unable to use this key to sign/
163    });
164
165  // Test failure when using the wrong algorithms
166  await assert.rejects(
167    subtle.sign({ name, hash }, rsaKeys.privateKey, plaintext), {
168      message: /Unable to use this key to sign/
169    });
170}
171
172(async function() {
173  const variations = [];
174
175  vectors.forEach((vector) => {
176    variations.push(testVerify(vector));
177    variations.push(testSign(vector));
178  });
179
180  await Promise.all(variations);
181})().then(common.mustCall());
182