%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/test/parallel/
Upload File :
Create Path :
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/test/parallel/test-webcrypto-keygen.js

// Flags: --expose-internals
'use strict';

const common = require('../common');

if (!common.hasCrypto)
  common.skip('missing crypto');

const assert = require('assert');
const { types: { isCryptoKey } } = require('util');
const {
  createSecretKey,
  KeyObject,
} = require('crypto');
const { subtle } = globalThis.crypto;

const { bigIntArrayToUnsignedBigInt } = require('internal/crypto/util');

const allUsages = [
  'encrypt',
  'decrypt',
  'sign',
  'verify',
  'deriveBits',
  'deriveKey',
  'wrapKey',
  'unwrapKey',
];
const vectors = {
  'AES-CTR': {
    algorithm: { length: 256 },
    result: 'CryptoKey',
    usages: [
      'encrypt',
      'decrypt',
      'wrapKey',
      'unwrapKey',
    ],
  },
  'AES-CBC': {
    algorithm: { length: 256 },
    result: 'CryptoKey',
    usages: [
      'encrypt',
      'decrypt',
      'wrapKey',
      'unwrapKey',
    ],
  },
  'AES-GCM': {
    algorithm: { length: 256 },
    result: 'CryptoKey',
    usages: [
      'encrypt',
      'decrypt',
      'wrapKey',
      'unwrapKey',
    ],
  },
  'AES-KW': {
    algorithm: { length: 256 },
    result: 'CryptoKey',
    usages: [
      'wrapKey',
      'unwrapKey',
    ],
  },
  'HMAC': {
    algorithm: { length: 256, hash: 'SHA-256' },
    result: 'CryptoKey',
    usages: [
      'sign',
      'verify',
    ],
  },
  'RSASSA-PKCS1-v1_5': {
    algorithm: {
      modulusLength: 1024,
      publicExponent: new Uint8Array([1, 0, 1]),
      hash: 'SHA-256'
    },
    result: 'CryptoKeyPair',
    usages: [
      'sign',
      'verify',
    ],
  },
  'RSA-PSS': {
    algorithm: {
      modulusLength: 1024,
      publicExponent: new Uint8Array([1, 0, 1]),
      hash: 'SHA-256'
    },
    result: 'CryptoKeyPair',
    usages: [
      'sign',
      'verify',
    ],
  },
  'RSA-OAEP': {
    algorithm: {
      modulusLength: 1024,
      publicExponent: new Uint8Array([1, 0, 1]),
      hash: 'SHA-256'
    },
    result: 'CryptoKeyPair',
    usages: [
      'encrypt',
      'decrypt',
      'wrapKey',
      'unwrapKey',
    ],
  },
  'ECDSA': {
    algorithm: { namedCurve: 'P-521' },
    result: 'CryptoKeyPair',
    usages: [
      'sign',
      'verify',
    ],
  },
  'ECDH': {
    algorithm: { namedCurve: 'P-521' },
    result: 'CryptoKeyPair',
    usages: [
      'deriveKey',
      'deriveBits',
    ],
  },
  'Ed25519': {
    result: 'CryptoKeyPair',
    usages: [
      'sign',
      'verify',
    ],
  },
  'Ed448': {
    result: 'CryptoKeyPair',
    usages: [
      'sign',
      'verify',
    ],
  },
  'X25519': {
    result: 'CryptoKeyPair',
    usages: [
      'deriveKey',
      'deriveBits',
    ],
  },
  'X448': {
    result: 'CryptoKeyPair',
    usages: [
      'deriveKey',
      'deriveBits',
    ],
  },
};

// Test invalid algorithms
{
  async function test(algorithm) {
    return assert.rejects(
      // The extractable and usages values are invalid here also,
      // but the unrecognized algorithm name should be caught first.
      subtle.generateKey(algorithm, 7, []), {
        message: /Unrecognized algorithm name/,
        name: 'NotSupportedError',
      });
  }

  const tests = [
    'AES',
    { name: 'AES' },
    { name: 'AES-CMAC' },
    { name: 'AES-CFB' },
    { name: 'HMAC', hash: 'MD5' },
    {
      name: 'RSA',
      hash: 'SHA-256',
      modulusLength: 2048,
      publicExponent: new Uint8Array([1, 0, 1])
    },
    {
      name: 'RSA-PSS',
      hash: 'SHA',
      modulusLength: 2048,
      publicExponent: new Uint8Array([1, 0, 1])
    },
    {
      name: 'EC',
      namedCurve: 'P521'
    },
  ].map(async (algorithm) => test(algorithm));

  Promise.all(tests).then(common.mustCall());
}

// Test bad usages
{
  async function test(name) {
    await assert.rejects(
      subtle.generateKey(
        {
          name, ...vectors[name].algorithm
        },
        true,
        []),
      { message: /Usages cannot be empty/ });

    // For CryptoKeyPair results the private key
    // usages must not be empty.
    // - ECDH(-like) algorithm key pairs only have private key usages
    // - Signing algorithm key pairs may pass a non-empty array but
    //   with only a public key usage
    if (
      vectors[name].result === 'CryptoKeyPair' &&
      vectors[name].usages.includes('verify')
    ) {
      await assert.rejects(
        subtle.generateKey(
          {
            name, ...vectors[name].algorithm
          },
          true,
          ['verify']),
        { message: /Usages cannot be empty/ });
    }

    const invalidUsages = [];
    allUsages.forEach((usage) => {
      if (!vectors[name].usages.includes(usage))
        invalidUsages.push(usage);
    });
    for (const invalidUsage of invalidUsages) {
      await assert.rejects(
        subtle.generateKey(
          {
            name, ...vectors[name].algorithm
          },
          true,
          [...vectors[name].usages, invalidUsage]),
        { message: /Unsupported key usage/ });
    }
  }

  const tests = Object.keys(vectors).map(test);

  Promise.all(tests).then(common.mustCall());
}

// Test RSA key generation
{
  async function test(
    name,
    modulusLength,
    publicExponent,
    hash,
    privateUsages,
    publicUsages = privateUsages) {
    let usages = privateUsages;
    if (publicUsages !== privateUsages)
      usages = usages.concat(publicUsages);
    const { publicKey, privateKey } = await subtle.generateKey({
      name,
      modulusLength,
      publicExponent,
      hash
    }, true, usages);

    assert(publicKey);
    assert(privateKey);
    assert(isCryptoKey(publicKey));
    assert(isCryptoKey(privateKey));

    assert(publicKey instanceof CryptoKey);
    assert(privateKey instanceof CryptoKey);

    assert.strictEqual(publicKey.type, 'public');
    assert.strictEqual(privateKey.type, 'private');
    assert.strictEqual(publicKey.toString(), '[object CryptoKey]');
    assert.strictEqual(privateKey.toString(), '[object CryptoKey]');
    assert.strictEqual(publicKey.extractable, true);
    assert.strictEqual(privateKey.extractable, true);
    assert.deepStrictEqual(publicKey.usages, publicUsages);
    assert.deepStrictEqual(privateKey.usages, privateUsages);
    assert.strictEqual(publicKey.algorithm.name, name);
    assert.strictEqual(publicKey.algorithm.modulusLength, modulusLength);
    assert.deepStrictEqual(publicKey.algorithm.publicExponent, publicExponent);
    assert.strictEqual(
      KeyObject.from(publicKey).asymmetricKeyDetails.publicExponent,
      bigIntArrayToUnsignedBigInt(publicExponent));
    assert.strictEqual(publicKey.algorithm.hash.name, hash);
    assert.strictEqual(privateKey.algorithm.name, name);
    assert.strictEqual(privateKey.algorithm.modulusLength, modulusLength);
    assert.deepStrictEqual(privateKey.algorithm.publicExponent, publicExponent);
    assert.strictEqual(
      KeyObject.from(privateKey).asymmetricKeyDetails.publicExponent,
      bigIntArrayToUnsignedBigInt(publicExponent));
    assert.strictEqual(privateKey.algorithm.hash.name, hash);

    // Missing parameters
    await assert.rejects(
      subtle.generateKey({ name, publicExponent, hash }, true, usages), {
        code: 'ERR_MISSING_OPTION'
      });

    await assert.rejects(
      subtle.generateKey({ name, modulusLength, hash }, true, usages), {
        code: 'ERR_MISSING_OPTION'
      });

    await assert.rejects(
      subtle.generateKey({ name, modulusLength }, true, usages), {
        code: 'ERR_MISSING_OPTION'
      });

    await Promise.all([{}].map((modulusLength) => {
      return assert.rejects(subtle.generateKey({
        name,
        modulusLength,
        publicExponent,
        hash
      }, true, usages), {
        code: 'ERR_INVALID_ARG_TYPE'
      });
    }));

    await Promise.all(
      [
        '',
        true,
        {},
        1,
        [],
        new Uint32Array(2),
      ].map((publicExponent) => {
        return assert.rejects(
          subtle.generateKey(
            { name, modulusLength, publicExponent, hash }, true, usages),
          { code: 'ERR_INVALID_ARG_TYPE' });
      }));

    await Promise.all([true, 1].map((hash) => {
      return assert.rejects(subtle.generateKey({
        name,
        modulusLength,
        publicExponent,
        hash
      }, true, usages), {
        message: /Unrecognized algorithm name/,
        name: 'NotSupportedError',
      });
    }));

    await Promise.all(['', {}, 1, false].map((usages) => {
      return assert.rejects(subtle.generateKey({
        name,
        modulusLength,
        publicExponent,
        hash
      }, true, usages), {
        code: 'ERR_INVALID_ARG_TYPE'
      });
    }));

    await Promise.all([[1], [1, 0, 0]].map((publicExponent) => {
      return assert.rejects(subtle.generateKey({
        name,
        modulusLength,
        publicExponent: new Uint8Array(publicExponent),
        hash
      }, true, usages), {
        name: 'OperationError',
      });
    }));
  }

  const kTests = [
    [
      'RSASSA-PKCS1-v1_5',
      1024,
      Buffer.from([1, 0, 1]),
      'SHA-256',
      ['sign'],
      ['verify'],
    ],
    [
      'RSA-PSS',
      2048,
      Buffer.from([1, 0, 1]),
      'SHA-512',
      ['sign'],
      ['verify'],
    ],
    [
      'RSA-OAEP',
      1024,
      Buffer.from([3]),
      'SHA-384',
      ['decrypt', 'unwrapKey'],
      ['encrypt', 'wrapKey'],
    ],
  ];

  const tests = kTests.map((args) => test(...args));

  Promise.all(tests).then(common.mustCall());
}

// Test EC Key Generation
{
  async function test(
    name,
    namedCurve,
    privateUsages,
    publicUsages = privateUsages) {

    let usages = privateUsages;
    if (publicUsages !== privateUsages)
      usages = usages.concat(publicUsages);

    const { publicKey, privateKey } = await subtle.generateKey({
      name,
      namedCurve
    }, true, usages);

    assert(publicKey);
    assert(privateKey);
    assert(isCryptoKey(publicKey));
    assert(isCryptoKey(privateKey));

    assert.strictEqual(publicKey.type, 'public');
    assert.strictEqual(privateKey.type, 'private');
    assert.strictEqual(publicKey.toString(), '[object CryptoKey]');
    assert.strictEqual(privateKey.toString(), '[object CryptoKey]');
    assert.strictEqual(publicKey.extractable, true);
    assert.strictEqual(privateKey.extractable, true);
    assert.deepStrictEqual(publicKey.usages, publicUsages);
    assert.deepStrictEqual(privateKey.usages, privateUsages);
    assert.strictEqual(publicKey.algorithm.name, name);
    assert.strictEqual(privateKey.algorithm.name, name);
    assert.strictEqual(publicKey.algorithm.namedCurve, namedCurve);
    assert.strictEqual(privateKey.algorithm.namedCurve, namedCurve);

    // Invalid parameters
    [1, true, {}, [], null].forEach(async (namedCurve) => {
      await assert.rejects(
        subtle.generateKey({ name, namedCurve }, true, privateUsages), {
          name: 'NotSupportedError'
        });
    });
    await assert.rejects(
      subtle.generateKey({ name, namedCurve: undefined }, true, privateUsages), {
        name: 'TypeError',
        code: 'ERR_MISSING_OPTION'
      });
  }

  const kTests = [
    [
      'ECDSA',
      'P-384',
      ['sign'],
      ['verify'],
    ],
    [
      'ECDSA',
      'P-521',
      ['sign'],
      ['verify'],
    ],
    [
      'ECDH',
      'P-384',
      ['deriveKey', 'deriveBits'],
      [],
    ],
    [
      'ECDH',
      'P-521',
      ['deriveKey', 'deriveBits'],
      [],
    ],
  ];

  const tests = kTests.map((args) => test(...args));

  // Test bad parameters

  Promise.all(tests).then(common.mustCall());
}

// Test AES Key Generation
{
  async function test(name, length, usages) {
    const key = await subtle.generateKey({
      name,
      length
    }, true, usages);

    assert(key);
    assert(isCryptoKey(key));

    assert.strictEqual(key.type, 'secret');
    assert.strictEqual(key.toString(), '[object CryptoKey]');
    assert.strictEqual(key.extractable, true);
    assert.deepStrictEqual(key.usages, usages);
    assert.strictEqual(key.algorithm.name, name);
    assert.strictEqual(key.algorithm.length, length);

    // Invalid parameters
    [1, 100, 257, '', false, null].forEach(async (length) => {
      await assert.rejects(
        subtle.generateKey({ name, length }, true, usages), {
          name: 'OperationError'
        });
    });

    await assert.rejects(
      subtle.generateKey({ name, length: undefined }, true, usages), {
        name: 'TypeError',
        code: 'ERR_MISSING_OPTION'
      });
  }

  const kTests = [
    [ 'AES-CTR', 128, ['encrypt', 'decrypt', 'wrapKey']],
    [ 'AES-CTR', 256, ['encrypt', 'decrypt', 'unwrapKey']],
    [ 'AES-CBC', 128, ['encrypt', 'decrypt']],
    [ 'AES-CBC', 256, ['encrypt', 'decrypt']],
    [ 'AES-GCM', 128, ['encrypt', 'decrypt']],
    [ 'AES-GCM', 256, ['encrypt', 'decrypt']],
    [ 'AES-KW', 128, ['wrapKey', 'unwrapKey']],
    [ 'AES-KW', 256, ['wrapKey', 'unwrapKey']],
  ];

  const tests = Promise.all(kTests.map((args) => test(...args)));

  tests.then(common.mustCall());
}

// Test HMAC Key Generation
{
  async function test(length, hash, usages) {
    const key = await subtle.generateKey({
      name: 'HMAC',
      length,
      hash
    }, true, usages);

    if (length === undefined) {
      switch (hash) {
        case 'SHA-1': length = 512; break;
        case 'SHA-256': length = 512; break;
        case 'SHA-384': length = 1024; break;
        case 'SHA-512': length = 1024; break;
      }
    }

    assert(key);
    assert(isCryptoKey(key));

    assert.strictEqual(key.type, 'secret');
    assert.strictEqual(key.toString(), '[object CryptoKey]');
    assert.strictEqual(key.extractable, true);
    assert.deepStrictEqual(key.usages, usages);
    assert.strictEqual(key.algorithm.name, 'HMAC');
    assert.strictEqual(key.algorithm.length, length);
    assert.strictEqual(key.algorithm.hash.name, hash);

    [1, false, null].forEach(async (hash) => {
      await assert.rejects(
        subtle.generateKey({ name: 'HMAC', length, hash }, true, usages), {
          message: /Unrecognized algorithm name/,
          name: 'NotSupportedError',
        });
    });
  }

  const kTests = [
    [ undefined, 'SHA-1', ['sign', 'verify']],
    [ undefined, 'SHA-256', ['sign', 'verify']],
    [ undefined, 'SHA-384', ['sign', 'verify']],
    [ undefined, 'SHA-512', ['sign', 'verify']],
    [ 128, 'SHA-256', ['sign', 'verify']],
    [ 1024, 'SHA-512', ['sign', 'verify']],
  ];

  const tests = Promise.all(kTests.map((args) => test(...args)));

  tests.then(common.mustCall());
}

// End user code cannot create CryptoKey directly
assert.throws(() => new CryptoKey(), { code: 'ERR_ILLEGAL_CONSTRUCTOR' });

{
  const buffer = Buffer.from('Hello World');
  const keyObject = createSecretKey(buffer);
  assert(!isCryptoKey(buffer));
  assert(!isCryptoKey(keyObject));
}

// Test OKP Key Generation
{
  async function test(
    name,
    privateUsages,
    publicUsages = privateUsages) {

    let usages = privateUsages;
    if (publicUsages !== privateUsages)
      usages = usages.concat(publicUsages);

    const { publicKey, privateKey } = await subtle.generateKey({
      name,
    }, true, usages);

    assert(publicKey);
    assert(privateKey);
    assert(isCryptoKey(publicKey));
    assert(isCryptoKey(privateKey));

    assert.strictEqual(publicKey.type, 'public');
    assert.strictEqual(privateKey.type, 'private');
    assert.strictEqual(publicKey.toString(), '[object CryptoKey]');
    assert.strictEqual(privateKey.toString(), '[object CryptoKey]');
    assert.strictEqual(publicKey.extractable, true);
    assert.strictEqual(privateKey.extractable, true);
    assert.deepStrictEqual(publicKey.usages, publicUsages);
    assert.deepStrictEqual(privateKey.usages, privateUsages);
    assert.strictEqual(publicKey.algorithm.name, name);
    assert.strictEqual(privateKey.algorithm.name, name);
  }

  const kTests = [
    [
      'Ed25519',
      ['sign'],
      ['verify'],
    ],
    [
      'Ed448',
      ['sign'],
      ['verify'],
    ],
    [
      'X25519',
      ['deriveKey', 'deriveBits'],
      [],
    ],
    [
      'X448',
      ['deriveKey', 'deriveBits'],
      [],
    ],
  ];

  const tests = kTests.map((args) => test(...args));

  // Test bad parameters

  Promise.all(tests).then(common.mustCall());
}

Zerion Mini Shell 1.0