| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 | /* * Copyright 2018 Scytl Secure Electronic Voting SA * * All rights reserved * * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package *//* jshint node:true */'use strict';var RsaPublicKey = require('./rsa-public-key');var RsaPrivateKey = require('./rsa-private-key');var KeyPair = require('./keypair');var KeyPairGenerator = require('./keypair-generator');var Signer = require('./signer');var SignatureVerifier = require('./signature-verifier');var AsymmetricEncrypter = require('./encrypter');var AsymmetricDecrypter = require('./decrypter');var validator = require('./input-validator');var cryptoPolicy = require('scytl-cryptopolicy');var secureRandom = require('scytl-securerandom');var forge = require('node-forge');module.exports = AsymmetricCryptographyService;/** * @class AsymmetricCryptographyService * @classdesc The asymmetric cryptography service API. To instantiate this *            object, use the method {@link newService}. * @hideconstructor * @param {Object} *            [options] An object containing optional arguments. * @param {Policy} *            [options.policy=Default policy] The cryptographic policy to use. * @param {SecureRandomService} *            [options.secureRandomService=Created internally] The secure random *            service to use. */function AsymmetricCryptographyService(options) {  options = options || {};  var policy_;  if (options.policy) {    policy_ = options.policy;  } else {    policy_ = cryptoPolicy.newInstance();  }  var secureRandomService_;  if (options.secureRandomService) {    secureRandomService_ = options.secureRandomService;  } else {    secureRandomService_ = secureRandom.newService();  }  /**   * Creates a new RsaPublicKey object from a provided RSA public key or its   * components.   *   * @function newRsaPublicKey   * @memberof AsymmetricCryptographyService   * @param {Object}   *            params An object containing the input parameters for the   *            RsaPublicKey object creation.   * @param {string}   *            params.pem a PEM string representation of the key. Any   *            additional parameters will be ignored.   * @param {number}   *            params.n The modulus of the key. Required if   *            <code>params.pem</code> is undefined.   * @param {number}   *            params.e The public exponent of the key. Required if   *            <code>params.pem</code> is undefined.   * @returns {RsaPublicKey} The new RsaPublicKey object.   */  this.newRsaPublicKey = function(params) {    validator.checkIsObjectWithProperties(        params, 'Parameters object for creation of RsaPublicKey object');    if (!params.pem) {      checkPublicKeyData(params);      return new RsaPublicKey(params);    } else {      validator.checkIsNonEmptyString(          params.pem, 'RSA public key, PEM encoded');      var forgePublicKey = forge.pki.publicKeyFromPem(params.pem);      if (typeof forgePublicKey.encrypt === 'undefined') {        throw new Error(            'PEM encoding of public key for creation of RsaPublicKey object is corrupt');      }      return new RsaPublicKey({n: forgePublicKey.n, e: forgePublicKey.e});    }  };  /**   * Creates a new RsaPrivateKey object from a provided RSA private key or its   * components.   *   * @function newRsaPrivateKey   * @memberof AsymmetricCryptographyService   * @param {Object}   *            params An object containing the input parameters for the   *            RsaPrivateKey object creation.   * @param {Object}   *            params An object containing the required input parameters.   * @param {string}   *            params.pem a PEM string representation of the key. Any   *            additional parameters will be ignored.   * @param {number}   *            params.n The modulus of the key. Required if   *            <code>params.pem</code> is undefined.   * @param {number}   *            params.e The public exponent of the key. Required if   *            <code>params.pem</code> is undefined.   * @param {number}   *            params.d The private exponent of the key. Required if   *            <code>params.pem</code> is undefined.   * @param {number}   *            params.p The first prime of the key. Required if   *            <code>params.pem</code> is undefined.   * @param {number}   *            params.q The second prime of the key Required if   *            <code>params.pem</code> is undefined.   * @param {number}   *            params.dP The first exponent of the key. Required if   *            <code>params.pem</code> is undefined.   * @param {number}   *            params.dQ The second exponent of the key. Required if   *            <code>params.pem</code> is undefined.   * @param {number}   *            params.qInv The coefficient of the key. Required if   *            <code>params.pem</code> is undefined.   * @returns {RsaPrivateKey} The new RsaPrivateKey object.   */  this.newRsaPrivateKey = function(params) {    validator.checkIsObjectWithProperties(        params, 'Parameters object for creation of RsaPrivateKey object');    if (!params.pem) {      checkPrivateKeyData(params);      return new RsaPrivateKey(params);    } else {      validator.checkIsNonEmptyString(          params.pem, 'RSA public key, PEM encoded');      var forgePrivateKey = forge.pki.privateKeyFromPem(params.pem);      if (typeof forgePrivateKey.decrypt === 'undefined') {        throw new Error(            'PEM encoding of private key for creation of RsaPrivateKey object is corrupt');      }      return new RsaPrivateKey({        n: forgePrivateKey.n,        e: forgePrivateKey.e,        d: forgePrivateKey.d,        p: forgePrivateKey.p,        q: forgePrivateKey.q,        dP: forgePrivateKey.dP,        dQ: forgePrivateKey.dQ,        qInv: forgePrivateKey.qInv      });    }  };  /**   * Creates a new KeyPair object from a provided key pair.   *   * @function newKeyPair   * @memberof AsymmetricCryptographyService   * @param {string}   *            publicKey The public key comprising the key pair, in PEM   *            format.   * @param {string}   *            privateKey The private key comprising the key pair, in PEM   *            format.   * @returns {KeyPair} The new KeyPair object.   */  this.newKeyPair = function(publicKey, privateKey) {    validator.checkIsNonEmptyString(publicKey, 'Public key, PEM encoded');    validator.checkIsNonEmptyString(privateKey, 'Private key, PEM encoded');    return new KeyPair(publicKey, privateKey);  };  /**   * Creates a new KeyPairGenerator object for generating key pairs.   *   * @function newKeyPairGenerator   * @memberof AsymmetricCryptographyService   * @returns {RsaKeyPairGenerator} The new RsaKeyPairGenerator object.   */  this.newKeyPairGenerator = function() {    return new KeyPairGenerator(policy_, secureRandomService_);  };  /**   * Creates a new Signer object for digitally signing data. It must be   * initialized with a private key.   *   * @function newSigner   * @memberof AsymmetricCryptographyService   * @returns {Signer} The new Signer object.   */  this.newSigner = function() {    return new Signer(policy_, secureRandomService_);  };  /**   * Creates a new SignatureVerifier object for verifying a digital   * signatures. It must be initialized with a public key.   *   * @function newSignatureVerifier   * @memberof AsymmetricCryptographyService   * @returns {SignatureVerifier} The new SignatureVerifier object.   */  this.newSignatureVerifier = function() {    return new SignatureVerifier(policy_, secureRandomService_);  };  /**   * Creates a new AsymmetricEncrypter object for encrypting data. It must be   * initialized with a public key.   *   * @function newEncrypter   * @memberof AsymmetricCryptographyService   * @returns {AsymmetricEncrypter} The new AsymmetricEncrypter object.   */  this.newEncrypter = function() {    return new AsymmetricEncrypter(policy_, secureRandomService_);  };  /**   * Creates a new AsymmetricDecrypter object for decrypting data. It must be   * initialized with a private key.   *   * @function newDecrypter   * @memberof AsymmetricCryptographyService   * @returns {AsymmetricDecrypter} The new AsymmetricDecrypter object.   */  this.newDecrypter = function() {    return new AsymmetricDecrypter(policy_);  };  function checkPublicKeyData(params) {    validator.checkIsPositiveBigInteger(params.n, 'RSA public key modulus');    validator.checkIsPositiveBigInteger(        params.e, 'RSA public key public exponent');  }  function checkPrivateKeyData(params) {    validator.checkIsPositiveBigInteger(params.n, 'RSA private key modulus');    validator.checkIsPositiveBigInteger(        params.e, 'RSA private key public exponent');    validator.checkIsPositiveBigInteger(        params.d, 'RSA private key private exponent');    validator.checkIsPositiveBigInteger(        params.p, 'RSA private key first prime');    validator.checkIsPositiveBigInteger(        params.q, 'RSA private key second prime');    validator.checkIsPositiveBigInteger(        params.dP, 'RSA private key first exponent');    validator.checkIsPositiveBigInteger(        params.dQ, 'RSA private key second exponent');    validator.checkIsPositiveBigInteger(        params.qInv, 'RSA private key coefficient');  }}
 |