11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciif (!common.hasCrypto)
61cb0ef41Sopenharmony_ci  common.skip('missing crypto');
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ciconst assert = require('assert');
91cb0ef41Sopenharmony_ciconst { subtle } = require('crypto').webcrypto;
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ciconst vectors = require('../fixtures/crypto/hmac')();
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ciasync function testVerify({ hash,
141cb0ef41Sopenharmony_ci                            keyBuffer,
151cb0ef41Sopenharmony_ci                            signature,
161cb0ef41Sopenharmony_ci                            plaintext }) {
171cb0ef41Sopenharmony_ci  const name = 'HMAC';
181cb0ef41Sopenharmony_ci  const [
191cb0ef41Sopenharmony_ci    key,
201cb0ef41Sopenharmony_ci    noVerifyKey,
211cb0ef41Sopenharmony_ci    rsaKeys,
221cb0ef41Sopenharmony_ci  ] = await Promise.all([
231cb0ef41Sopenharmony_ci    subtle.importKey(
241cb0ef41Sopenharmony_ci      'raw',
251cb0ef41Sopenharmony_ci      keyBuffer,
261cb0ef41Sopenharmony_ci      { name, hash },
271cb0ef41Sopenharmony_ci      false,
281cb0ef41Sopenharmony_ci      ['verify']),
291cb0ef41Sopenharmony_ci    subtle.importKey(
301cb0ef41Sopenharmony_ci      'raw',
311cb0ef41Sopenharmony_ci      keyBuffer,
321cb0ef41Sopenharmony_ci      { name, hash },
331cb0ef41Sopenharmony_ci      false,
341cb0ef41Sopenharmony_ci      ['sign']),
351cb0ef41Sopenharmony_ci    subtle.generateKey(
361cb0ef41Sopenharmony_ci      {
371cb0ef41Sopenharmony_ci        name: 'RSA-PSS',
381cb0ef41Sopenharmony_ci        modulusLength: 1024,
391cb0ef41Sopenharmony_ci        publicExponent: new Uint8Array([1, 0, 1]),
401cb0ef41Sopenharmony_ci        hash: 'SHA-256',
411cb0ef41Sopenharmony_ci      },
421cb0ef41Sopenharmony_ci      false,
431cb0ef41Sopenharmony_ci      ['sign']),
441cb0ef41Sopenharmony_ci  ]);
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci  assert(await subtle.verify({ name, hash }, key, signature, plaintext));
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  // Test verification with altered buffers
491cb0ef41Sopenharmony_ci  const copy = Buffer.from(plaintext);
501cb0ef41Sopenharmony_ci  const sigcopy = Buffer.from(signature);
511cb0ef41Sopenharmony_ci  const p = subtle.verify({ name, hash }, key, sigcopy, copy);
521cb0ef41Sopenharmony_ci  copy[0] = 255 - copy[0];
531cb0ef41Sopenharmony_ci  sigcopy[0] = 255 - sigcopy[0];
541cb0ef41Sopenharmony_ci  assert(await p);
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci  // Test failure when using wrong key
571cb0ef41Sopenharmony_ci  await assert.rejects(
581cb0ef41Sopenharmony_ci    subtle.verify({ name, hash }, noVerifyKey, signature, plaintext), {
591cb0ef41Sopenharmony_ci      message: /Unable to use this key to verify/
601cb0ef41Sopenharmony_ci    });
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci  // Test failure when using the wrong algorithms
631cb0ef41Sopenharmony_ci  await assert.rejects(
641cb0ef41Sopenharmony_ci    subtle.verify({ name, hash }, rsaKeys.publicKey, signature, plaintext), {
651cb0ef41Sopenharmony_ci      message: /Unable to use this key to verify/
661cb0ef41Sopenharmony_ci    });
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci  // Test failure when signature is altered
691cb0ef41Sopenharmony_ci  {
701cb0ef41Sopenharmony_ci    const copy = Buffer.from(signature);
711cb0ef41Sopenharmony_ci    copy[0] = 255 - copy[0];
721cb0ef41Sopenharmony_ci    assert(!(await subtle.verify(
731cb0ef41Sopenharmony_ci      { name, hash },
741cb0ef41Sopenharmony_ci      key,
751cb0ef41Sopenharmony_ci      copy,
761cb0ef41Sopenharmony_ci      plaintext)));
771cb0ef41Sopenharmony_ci    assert(!(await subtle.verify(
781cb0ef41Sopenharmony_ci      { name, hash },
791cb0ef41Sopenharmony_ci      key,
801cb0ef41Sopenharmony_ci      copy.slice(1),
811cb0ef41Sopenharmony_ci      plaintext)));
821cb0ef41Sopenharmony_ci  }
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci  // Test failure when data is altered
851cb0ef41Sopenharmony_ci  {
861cb0ef41Sopenharmony_ci    const copy = Buffer.from(plaintext);
871cb0ef41Sopenharmony_ci    copy[0] = 255 - copy[0];
881cb0ef41Sopenharmony_ci    assert(!(await subtle.verify({ name, hash }, key, signature, copy)));
891cb0ef41Sopenharmony_ci  }
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  // Test failure when wrong hash is used
921cb0ef41Sopenharmony_ci  {
931cb0ef41Sopenharmony_ci    const otherhash = hash === 'SHA-1' ? 'SHA-256' : 'SHA-1';
941cb0ef41Sopenharmony_ci    const keyWithOtherHash = await subtle.importKey(
951cb0ef41Sopenharmony_ci      'raw',
961cb0ef41Sopenharmony_ci      keyBuffer,
971cb0ef41Sopenharmony_ci      { name, hash: otherhash },
981cb0ef41Sopenharmony_ci      false,
991cb0ef41Sopenharmony_ci      ['verify']);
1001cb0ef41Sopenharmony_ci    assert(!(await subtle.verify({ name }, keyWithOtherHash, signature, plaintext)));
1011cb0ef41Sopenharmony_ci  }
1021cb0ef41Sopenharmony_ci}
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ciasync function testSign({ hash,
1051cb0ef41Sopenharmony_ci                          keyBuffer,
1061cb0ef41Sopenharmony_ci                          signature,
1071cb0ef41Sopenharmony_ci                          plaintext }) {
1081cb0ef41Sopenharmony_ci  const name = 'HMAC';
1091cb0ef41Sopenharmony_ci  const [
1101cb0ef41Sopenharmony_ci    key,
1111cb0ef41Sopenharmony_ci    noSignKey,
1121cb0ef41Sopenharmony_ci    rsaKeys,
1131cb0ef41Sopenharmony_ci  ] = await Promise.all([
1141cb0ef41Sopenharmony_ci    subtle.importKey(
1151cb0ef41Sopenharmony_ci      'raw',
1161cb0ef41Sopenharmony_ci      keyBuffer,
1171cb0ef41Sopenharmony_ci      { name, hash },
1181cb0ef41Sopenharmony_ci      false,
1191cb0ef41Sopenharmony_ci      ['verify', 'sign']),
1201cb0ef41Sopenharmony_ci    subtle.importKey(
1211cb0ef41Sopenharmony_ci      'raw',
1221cb0ef41Sopenharmony_ci      keyBuffer,
1231cb0ef41Sopenharmony_ci      { name, hash },
1241cb0ef41Sopenharmony_ci      false,
1251cb0ef41Sopenharmony_ci      [ 'verify' ]),
1261cb0ef41Sopenharmony_ci    subtle.generateKey(
1271cb0ef41Sopenharmony_ci      {
1281cb0ef41Sopenharmony_ci        name: 'RSA-PSS',
1291cb0ef41Sopenharmony_ci        modulusLength: 1024,
1301cb0ef41Sopenharmony_ci        publicExponent: new Uint8Array([1, 0, 1]),
1311cb0ef41Sopenharmony_ci        hash: 'SHA-256',
1321cb0ef41Sopenharmony_ci      },
1331cb0ef41Sopenharmony_ci      false,
1341cb0ef41Sopenharmony_ci      ['sign']),
1351cb0ef41Sopenharmony_ci  ]);
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci  {
1381cb0ef41Sopenharmony_ci    const sig = await subtle.sign({ name, hash }, key, plaintext);
1391cb0ef41Sopenharmony_ci    assert.strictEqual(
1401cb0ef41Sopenharmony_ci      Buffer.from(sig).toString('hex'),
1411cb0ef41Sopenharmony_ci      signature.toString('hex'));
1421cb0ef41Sopenharmony_ci    assert(await subtle.verify({ name, hash }, key, sig, plaintext));
1431cb0ef41Sopenharmony_ci  }
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci  {
1461cb0ef41Sopenharmony_ci    const copy = Buffer.from(plaintext);
1471cb0ef41Sopenharmony_ci    const p = subtle.sign({ name, hash }, key, copy);
1481cb0ef41Sopenharmony_ci    copy[0] = 255 - copy[0];
1491cb0ef41Sopenharmony_ci    const sig = await p;
1501cb0ef41Sopenharmony_ci    assert(await subtle.verify({ name, hash }, key, sig, plaintext));
1511cb0ef41Sopenharmony_ci  }
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci  await assert.rejects(
1541cb0ef41Sopenharmony_ci    subtle.generateKey({ name }, false, ['sign', 'verify']), {
1551cb0ef41Sopenharmony_ci      name: 'TypeError',
1561cb0ef41Sopenharmony_ci      code: 'ERR_MISSING_OPTION',
1571cb0ef41Sopenharmony_ci    });
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_ci  // Test failure when no sign usage
1601cb0ef41Sopenharmony_ci  await assert.rejects(
1611cb0ef41Sopenharmony_ci    subtle.sign({ name, hash }, noSignKey, plaintext), {
1621cb0ef41Sopenharmony_ci      message: /Unable to use this key to sign/
1631cb0ef41Sopenharmony_ci    });
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci  // Test failure when using the wrong algorithms
1661cb0ef41Sopenharmony_ci  await assert.rejects(
1671cb0ef41Sopenharmony_ci    subtle.sign({ name, hash }, rsaKeys.privateKey, plaintext), {
1681cb0ef41Sopenharmony_ci      message: /Unable to use this key to sign/
1691cb0ef41Sopenharmony_ci    });
1701cb0ef41Sopenharmony_ci}
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ci(async function() {
1731cb0ef41Sopenharmony_ci  const variations = [];
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci  vectors.forEach((vector) => {
1761cb0ef41Sopenharmony_ci    variations.push(testVerify(vector));
1771cb0ef41Sopenharmony_ci    variations.push(testSign(vector));
1781cb0ef41Sopenharmony_ci  });
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_ci  await Promise.all(variations);
1811cb0ef41Sopenharmony_ci})().then(common.mustCall());
182