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