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/ecdsa')();
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ciasync function testVerify({ name,
141cb0ef41Sopenharmony_ci                            hash,
151cb0ef41Sopenharmony_ci                            namedCurve,
161cb0ef41Sopenharmony_ci                            publicKeyBuffer,
171cb0ef41Sopenharmony_ci                            privateKeyBuffer,
181cb0ef41Sopenharmony_ci                            signature,
191cb0ef41Sopenharmony_ci                            plaintext }) {
201cb0ef41Sopenharmony_ci  const [
211cb0ef41Sopenharmony_ci    publicKey,
221cb0ef41Sopenharmony_ci    noVerifyPublicKey,
231cb0ef41Sopenharmony_ci    privateKey,
241cb0ef41Sopenharmony_ci    hmacKey,
251cb0ef41Sopenharmony_ci    rsaKeys,
261cb0ef41Sopenharmony_ci    okpKeys,
271cb0ef41Sopenharmony_ci  ] = await Promise.all([
281cb0ef41Sopenharmony_ci    subtle.importKey(
291cb0ef41Sopenharmony_ci      'spki',
301cb0ef41Sopenharmony_ci      publicKeyBuffer,
311cb0ef41Sopenharmony_ci      { name, namedCurve },
321cb0ef41Sopenharmony_ci      false,
331cb0ef41Sopenharmony_ci      ['verify']),
341cb0ef41Sopenharmony_ci    subtle.importKey(
351cb0ef41Sopenharmony_ci      'spki',
361cb0ef41Sopenharmony_ci      publicKeyBuffer,
371cb0ef41Sopenharmony_ci      { name, namedCurve },
381cb0ef41Sopenharmony_ci      false,
391cb0ef41Sopenharmony_ci      [ /* No usages */ ]),
401cb0ef41Sopenharmony_ci    subtle.importKey(
411cb0ef41Sopenharmony_ci      'pkcs8',
421cb0ef41Sopenharmony_ci      privateKeyBuffer,
431cb0ef41Sopenharmony_ci      { name, namedCurve },
441cb0ef41Sopenharmony_ci      false,
451cb0ef41Sopenharmony_ci      ['sign']),
461cb0ef41Sopenharmony_ci    subtle.generateKey(
471cb0ef41Sopenharmony_ci      { name: 'HMAC', hash: 'SHA-256' },
481cb0ef41Sopenharmony_ci      false,
491cb0ef41Sopenharmony_ci      ['sign']),
501cb0ef41Sopenharmony_ci    subtle.generateKey(
511cb0ef41Sopenharmony_ci      {
521cb0ef41Sopenharmony_ci        name: 'RSA-PSS',
531cb0ef41Sopenharmony_ci        modulusLength: 1024,
541cb0ef41Sopenharmony_ci        publicExponent: new Uint8Array([1, 0, 1]),
551cb0ef41Sopenharmony_ci        hash: 'SHA-256',
561cb0ef41Sopenharmony_ci      },
571cb0ef41Sopenharmony_ci      false,
581cb0ef41Sopenharmony_ci      ['sign']),
591cb0ef41Sopenharmony_ci    subtle.generateKey(
601cb0ef41Sopenharmony_ci      {
611cb0ef41Sopenharmony_ci        name: 'Ed25519',
621cb0ef41Sopenharmony_ci      },
631cb0ef41Sopenharmony_ci      false,
641cb0ef41Sopenharmony_ci      ['sign']),
651cb0ef41Sopenharmony_ci  ]);
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  assert(await subtle.verify({ name, hash }, publicKey, signature, plaintext));
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  // Test verification with altered buffers
701cb0ef41Sopenharmony_ci  const copy = Buffer.from(plaintext);
711cb0ef41Sopenharmony_ci  const sigcopy = Buffer.from(signature);
721cb0ef41Sopenharmony_ci  const p = subtle.verify({ name, hash }, publicKey, sigcopy, copy);
731cb0ef41Sopenharmony_ci  copy[0] = 255 - copy[0];
741cb0ef41Sopenharmony_ci  sigcopy[0] = 255 - sigcopy[0];
751cb0ef41Sopenharmony_ci  assert(await p);
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci  // Test failure when using wrong key
781cb0ef41Sopenharmony_ci  await assert.rejects(
791cb0ef41Sopenharmony_ci    subtle.verify({ name, hash }, privateKey, signature, plaintext), {
801cb0ef41Sopenharmony_ci      message: /Unable to use this key to verify/
811cb0ef41Sopenharmony_ci    });
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci  await assert.rejects(
841cb0ef41Sopenharmony_ci    subtle.verify({ name, hash }, noVerifyPublicKey, signature, plaintext), {
851cb0ef41Sopenharmony_ci      message: /Unable to use this key to verify/
861cb0ef41Sopenharmony_ci    });
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci  // Test failure when using the wrong algorithms
891cb0ef41Sopenharmony_ci  await assert.rejects(
901cb0ef41Sopenharmony_ci    subtle.verify({ name, hash }, hmacKey, signature, plaintext), {
911cb0ef41Sopenharmony_ci      message: /Unable to use this key to verify/
921cb0ef41Sopenharmony_ci    });
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ci  await assert.rejects(
951cb0ef41Sopenharmony_ci    subtle.verify({ name, hash }, rsaKeys.publicKey, signature, plaintext), {
961cb0ef41Sopenharmony_ci      message: /Unable to use this key to verify/
971cb0ef41Sopenharmony_ci    });
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci  await assert.rejects(
1001cb0ef41Sopenharmony_ci    subtle.verify({ name, hash }, okpKeys.publicKey, signature, plaintext), {
1011cb0ef41Sopenharmony_ci      message: /Unable to use this key to verify/
1021cb0ef41Sopenharmony_ci    });
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  // Test failure when signature is altered
1051cb0ef41Sopenharmony_ci  {
1061cb0ef41Sopenharmony_ci    const copy = Buffer.from(signature);
1071cb0ef41Sopenharmony_ci    copy[0] = 255 - copy[0];
1081cb0ef41Sopenharmony_ci    assert(!(await subtle.verify(
1091cb0ef41Sopenharmony_ci      { name, hash },
1101cb0ef41Sopenharmony_ci      publicKey,
1111cb0ef41Sopenharmony_ci      copy,
1121cb0ef41Sopenharmony_ci      plaintext)));
1131cb0ef41Sopenharmony_ci    assert(!(await subtle.verify(
1141cb0ef41Sopenharmony_ci      { name, hash },
1151cb0ef41Sopenharmony_ci      publicKey,
1161cb0ef41Sopenharmony_ci      copy.slice(1),
1171cb0ef41Sopenharmony_ci      plaintext)));
1181cb0ef41Sopenharmony_ci  }
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci  // Test failure when data is altered
1211cb0ef41Sopenharmony_ci  {
1221cb0ef41Sopenharmony_ci    const copy = Buffer.from(plaintext);
1231cb0ef41Sopenharmony_ci    copy[0] = 255 - copy[0];
1241cb0ef41Sopenharmony_ci    assert(!(await subtle.verify({ name, hash }, publicKey, signature, copy)));
1251cb0ef41Sopenharmony_ci  }
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci  // Test failure when wrong hash is used
1281cb0ef41Sopenharmony_ci  {
1291cb0ef41Sopenharmony_ci    const otherhash = hash === 'SHA-1' ? 'SHA-256' : 'SHA-1';
1301cb0ef41Sopenharmony_ci    assert(!(await subtle.verify({
1311cb0ef41Sopenharmony_ci      name,
1321cb0ef41Sopenharmony_ci      hash: otherhash
1331cb0ef41Sopenharmony_ci    }, publicKey, signature, copy)));
1341cb0ef41Sopenharmony_ci  }
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci  await assert.rejects(
1371cb0ef41Sopenharmony_ci    subtle.verify({ name, hash: 'sha256' }, publicKey, signature, copy), {
1381cb0ef41Sopenharmony_ci      message: /Unrecognized algorithm name/,
1391cb0ef41Sopenharmony_ci      name: 'NotSupportedError',
1401cb0ef41Sopenharmony_ci    });
1411cb0ef41Sopenharmony_ci}
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ciasync function testSign({ name,
1441cb0ef41Sopenharmony_ci                          hash,
1451cb0ef41Sopenharmony_ci                          namedCurve,
1461cb0ef41Sopenharmony_ci                          publicKeyBuffer,
1471cb0ef41Sopenharmony_ci                          privateKeyBuffer,
1481cb0ef41Sopenharmony_ci                          signature,
1491cb0ef41Sopenharmony_ci                          plaintext }) {
1501cb0ef41Sopenharmony_ci  const [
1511cb0ef41Sopenharmony_ci    publicKey,
1521cb0ef41Sopenharmony_ci    privateKey,
1531cb0ef41Sopenharmony_ci    hmacKey,
1541cb0ef41Sopenharmony_ci    rsaKeys,
1551cb0ef41Sopenharmony_ci    okpKeys,
1561cb0ef41Sopenharmony_ci  ] = await Promise.all([
1571cb0ef41Sopenharmony_ci    subtle.importKey(
1581cb0ef41Sopenharmony_ci      'spki',
1591cb0ef41Sopenharmony_ci      publicKeyBuffer,
1601cb0ef41Sopenharmony_ci      { name, namedCurve },
1611cb0ef41Sopenharmony_ci      false,
1621cb0ef41Sopenharmony_ci      ['verify']),
1631cb0ef41Sopenharmony_ci    subtle.importKey(
1641cb0ef41Sopenharmony_ci      'pkcs8',
1651cb0ef41Sopenharmony_ci      privateKeyBuffer,
1661cb0ef41Sopenharmony_ci      { name, namedCurve },
1671cb0ef41Sopenharmony_ci      false,
1681cb0ef41Sopenharmony_ci      ['sign']),
1691cb0ef41Sopenharmony_ci    subtle.generateKey(
1701cb0ef41Sopenharmony_ci      { name: 'HMAC', hash: 'SHA-256' },
1711cb0ef41Sopenharmony_ci      false,
1721cb0ef41Sopenharmony_ci      ['sign']),
1731cb0ef41Sopenharmony_ci    subtle.generateKey(
1741cb0ef41Sopenharmony_ci      {
1751cb0ef41Sopenharmony_ci        name: 'RSA-PSS',
1761cb0ef41Sopenharmony_ci        modulusLength: 1024,
1771cb0ef41Sopenharmony_ci        publicExponent: new Uint8Array([1, 0, 1]),
1781cb0ef41Sopenharmony_ci        hash: 'SHA-256',
1791cb0ef41Sopenharmony_ci      },
1801cb0ef41Sopenharmony_ci      false,
1811cb0ef41Sopenharmony_ci      ['sign']),
1821cb0ef41Sopenharmony_ci    subtle.generateKey(
1831cb0ef41Sopenharmony_ci      {
1841cb0ef41Sopenharmony_ci        name: 'Ed25519',
1851cb0ef41Sopenharmony_ci      },
1861cb0ef41Sopenharmony_ci      false,
1871cb0ef41Sopenharmony_ci      ['sign']),
1881cb0ef41Sopenharmony_ci  ]);
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_ci  {
1911cb0ef41Sopenharmony_ci    const sig = await subtle.sign({ name, hash }, privateKey, plaintext);
1921cb0ef41Sopenharmony_ci    assert.strictEqual(sig.byteLength, signature.byteLength);
1931cb0ef41Sopenharmony_ci    assert(await subtle.verify({ name, hash }, publicKey, sig, plaintext));
1941cb0ef41Sopenharmony_ci  }
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci  {
1971cb0ef41Sopenharmony_ci    const copy = Buffer.from(plaintext);
1981cb0ef41Sopenharmony_ci    const p = subtle.sign({ name, hash }, privateKey, copy);
1991cb0ef41Sopenharmony_ci    copy[0] = 255 - copy[0];
2001cb0ef41Sopenharmony_ci    const sig = await p;
2011cb0ef41Sopenharmony_ci    assert(await subtle.verify({ name, hash }, publicKey, sig, plaintext));
2021cb0ef41Sopenharmony_ci  }
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_ci  // Test failure when using wrong key
2051cb0ef41Sopenharmony_ci  await assert.rejects(
2061cb0ef41Sopenharmony_ci    subtle.sign({ name, hash }, publicKey, plaintext), {
2071cb0ef41Sopenharmony_ci      message: /Unable to use this key to sign/
2081cb0ef41Sopenharmony_ci    });
2091cb0ef41Sopenharmony_ci
2101cb0ef41Sopenharmony_ci  // Test failure when using the wrong algorithms
2111cb0ef41Sopenharmony_ci  await assert.rejects(
2121cb0ef41Sopenharmony_ci    subtle.sign({ name, hash }, hmacKey, plaintext), {
2131cb0ef41Sopenharmony_ci      message: /Unable to use this key to sign/
2141cb0ef41Sopenharmony_ci    });
2151cb0ef41Sopenharmony_ci
2161cb0ef41Sopenharmony_ci  await assert.rejects(
2171cb0ef41Sopenharmony_ci    subtle.sign({ name, hash }, rsaKeys.privateKey, plaintext), {
2181cb0ef41Sopenharmony_ci      message: /Unable to use this key to sign/
2191cb0ef41Sopenharmony_ci    });
2201cb0ef41Sopenharmony_ci
2211cb0ef41Sopenharmony_ci  await assert.rejects(
2221cb0ef41Sopenharmony_ci    subtle.sign({ name, hash }, okpKeys.privateKey, plaintext), {
2231cb0ef41Sopenharmony_ci      message: /Unable to use this key to sign/
2241cb0ef41Sopenharmony_ci    });
2251cb0ef41Sopenharmony_ci}
2261cb0ef41Sopenharmony_ci
2271cb0ef41Sopenharmony_ci(async function() {
2281cb0ef41Sopenharmony_ci  const variations = [];
2291cb0ef41Sopenharmony_ci
2301cb0ef41Sopenharmony_ci  vectors.forEach((vector) => {
2311cb0ef41Sopenharmony_ci    variations.push(testVerify(vector));
2321cb0ef41Sopenharmony_ci    variations.push(testSign(vector));
2331cb0ef41Sopenharmony_ci  });
2341cb0ef41Sopenharmony_ci
2351cb0ef41Sopenharmony_ci  await Promise.all(variations);
2361cb0ef41Sopenharmony_ci})().then(common.mustCall());
237