/* * 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 */ cryptolib.modules.asymmetric = cryptolib.modules.asymmetric || {}; /** @namespace asymmetric/keypair */ cryptolib.modules.asymmetric.keypair = function(box) { 'use strict'; box.asymmetric = box.asymmetric || {}; box.asymmetric.keypair = {}; /** * A module that holds certificates functionalities. * * @exports asymmetric/keypair/factory */ box.asymmetric.keypair.factory = {}; var policies = { encryption: { algorithm: box.policies.asymmetric.keypair.encryption.algorithm, provider: box.policies.asymmetric.keypair.encryption.provider, keyLength: box.policies.asymmetric.keypair.encryption.keyLength, publicExponent: box.policies.asymmetric.keypair.encryption.publicExponent } }; var exceptions, randomFactory; var f = function(box) { exceptions = box.commons.exceptions; randomFactory = new box.primitives.securerandom.factory.SecureRandomFactory(); }; f.policies = { primitives: { secureRandom: {provider: box.policies.asymmetric.keypair.secureRandom.provider} } }; cryptolib('commons.exceptions', 'primitives.securerandom', f); /** * A factory class for generating * {@link asymmetric.keypair.CryptoForgeKeyPairGenerator} objects. * * @class */ box.asymmetric.keypair.factory.KeyPairGeneratorFactory = function() {}; box.asymmetric.keypair.factory.KeyPairGeneratorFactory.prototype = { /** * @function * @returns CryptoForgeKeyPairGenerator */ getEncryptionCryptoKeyPairGenerator: function() { var secureRandom; try { if (policies.encryption.provider === Config.asymmetric.keypair.encryption.provider.FORGE) { secureRandom = randomFactory.getCryptoRandomBytes(); return this.getCryptoForgeKeyPairGenerator(secureRandom); } else { throw new exceptions.CryptoLibException( 'No suitable provider was provided.'); } } catch (error) { throw new exceptions.CryptoLibException( 'An encryption CryptoKeyPairGenerator could not be obtained.', error); } }, getCryptoForgeKeyPairGenerator: function(secureRandom) { return new CryptoForgeKeyPairGenerator(secureRandom); } }; /** * Defines an encryption key pair generator for the FORGE provider. * * @class * @memberof asymmetric/keypair */ function CryptoForgeKeyPairGenerator(secureRandom) { this.secureRandom = secureRandom; } CryptoForgeKeyPairGenerator.prototype = { /** * Generates an encryption key pair. * * @returns {asymmetric/keypair.KeyPair} an encryption key pair. */ generate: function() { try { if (policies.encryption.algorithm === Config.asymmetric.keypair.encryption.algorithm.RSA) { var options = {prng: this.secureRandom}; var keys = forge.pki.rsa.generateKeyPair( policies.encryption.keyLength, policies.encryption.publicExponent, options); var forgePublicKey = keys.publicKey; var forgePrivateKey = keys.privateKey; var publicKeyPem = forge.pki.publicKeyToPem(forgePublicKey); var privateKeyPem = forge.pki.privateKeyToPem(forgePrivateKey); var publicKey = new PublicKey( policies.encryption.algorithm, forgePublicKey.n, forgePublicKey.e, publicKeyPem); var privateKey = new PrivateKey( policies.encryption.algorithm, forgePrivateKey.n, forgePrivateKey.e, forgePrivateKey.d, forgePrivateKey.p, forgePrivateKey.q, forgePrivateKey.dP, forgePrivateKey.dQ, forgePrivateKey.qInv, privateKeyPem); return new KeyPair(publicKey, privateKey); } else { throw new exceptions.CryptoLibException( 'The given algorithm is not supported.'); } } catch (error) { throw new exceptions.CryptoLibException( 'Encryption key pair could not be generated.', error); } } }; /** * Container class for an encryption key pair. * * @class * @param publicKey * public key of the encryption key pair. * @param privateKey * private key of the encryption key pair. * @memberof asymmetric/keypair */ function KeyPair(publicKey, privateKey) { /** * Retrieves the public key of the encryption key pair. * * @function * @returns PrivateKey Public key of encryption key pair. */ var getPublicKey = function() { return publicKey; }; /** * Retrieves the private key of the encryption key pair. * * @function * @returns PrivateKey Private key of encryption key pair. */ var getPrivateKey = function() { return privateKey; }; return {getPublicKey: getPublicKey, getPrivateKey: getPrivateKey}; } /** * @class PrivateKey * @memberof asymmetric/keypair */ function PrivateKey(algorithm, n, e, d, p, q, dP, dQ, qInv, pem) { /** * @function * @returns {string} * @memberof asymmetric/keypair.PrivateKey */ var getAlgorithm = function() { return algorithm; }; /** * @function * @memberof asymmetric/keypair.PrivateKey */ var getModulus = function() { return n; }; /** * @function * @memberof asymmetric/keypair.PrivateKey */ var getPublicExponent = function() { return e; }; /** * @function * @memberof asymmetric/keypair.PrivateKey */ var getPrivateExponent = function() { return d; }; /** * @function * @memberof asymmetric/keypair.PrivateKey */ var getPrime1 = function() { return p; }; /** * @function * @memberof asymmetric/keypair.PrivateKey */ var getPrime2 = function() { return q; }; /** * @function * @memberof asymmetric/keypair.PrivateKey */ var getExponent1 = function() { return dP; }; /** * @function * @memberof asymmetric/keypair.PrivateKey */ var getExponent2 = function() { return dQ; }; /** * @function * @memberof asymmetric/keypair.PrivateKey */ var getCoefficient = function() { return qInv; }; /** * @function * @memberof asymmetric/keypair.PrivateKey */ var getPem = function() { return pem; }; return { getAlgorithm: getAlgorithm, getModulus: getModulus, getPublicExponent: getPublicExponent, getPrivateExponent: getPrivateExponent, getPrime1: getPrime1, getPrime2: getPrime2, getExponent1: getExponent1, getExponent2: getExponent2, getCoefficient: getCoefficient, getPem: getPem }; } /** @class PublicKey */ function PublicKey(algorithm, n, e, pem) { /** * @function * @memberof asymmetric/keypair.PublicKey */ var getAlgorithm = function() { return algorithm; }; /** * @function * @memberof asymmetric/keypair.PublicKey */ var getModulus = function() { return n; }; /** * @function * @memberof asymmetric/keypair.PublicKey */ var getPublicExponent = function() { return e; }; /** * @function * @memberof asymmetric/keypair.PublicKey */ var getPem = function() { return pem; }; return { getAlgorithm: getAlgorithm, getModulus: getModulus, getPublicExponent: getPublicExponent, getPem: getPem }; } };