/* * 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 DigitalEnvelope = require('./envelope'); var DigitalEnvelopeGenerator = require('./generator'); var DigitalEnvelopeOpener = require('./opener'); var EncryptedSecretKeyPair = require('./encrypted-secret-keypair'); var validator = require('./input-validator'); var codec = require('scytl-codec'); module.exports = DigitalEnvelopeService; /** * @class DigitalEnvelopeService * @classdesc The digital envelope 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 {SymmetricCryptographyService} * [options.symmetricCryptographyService=Created internally] The * symmetric cryptography service to use. * @param {AsymmetricCryptographyService} * [options.asymmetricCryptographyService=Created internally] The * asymmetric cryptography service to use. */ function DigitalEnvelopeService(options) { /** * Creates a new DigitalEnvelopeGenerator object for generating digital * envelopes. It must be initialized with one or more public keys. * * @function newGenerator * @memberof DigitalEnvelopeService * @returns {DigitalEnvelopeGenerator} The new DigitalEnvelopeGenerator * object. */ this.newGenerator = function() { return new DigitalEnvelopeGenerator(options); }; /** * Creates a new DigitalEnvelopeOpener object for opening digital envelopes. * It must be initialized with a private key. * * @function newOpener * @memberof DigitalEnvelopeService * @returns {DigitalEnvelopeOpener} The new DigitalEnvelopeOpener object. */ this.newOpener = function() { return new DigitalEnvelopeOpener(options); }; } DigitalEnvelopeService.prototype = { /** * Creates a new DigitalEnvelope object from a provided digital envelope or * its components. * * @function newEnvelope * @memberof DigitalEnvelopeService * @param {Uint8Array} * encryptedDataOrJson The symmetrically encrypted data OR * a JSON string representation of a DigitalEnvelope object, * compatible with its toJson method. For the * latter case, any additional input arguments will be ignored. * @param {Uint8Array} * mac The MAC of the symmetrically encrypted data. * @param {EncryptedSecretKeyPair[]} * encryptedSecretKeyPairs The array of asymmetric encryptions of * the concatenation of the encryption secret key and MAC secret * key used to generate and open the digital envelope, each * asymmetric encryption having been generated using a different * one of the public keys used to initialize digital envelope * generator. * @returns {DigitalEnvelope} The new DigitalEnvelope object. * @throws {Error} * If the input data validation fails. */ newEnvelope: function(encryptedDataOrJson, mac, encryptedSecretKeyPairs) { if (typeof encryptedDataOrJson !== 'string') { validator.checkIsInstanceOf( encryptedDataOrJson, Uint8Array, 'Uint8Array', 'Symmetrically encrypted data for new DigitalEnvelope object'); validator.checkIsInstanceOf( mac, Uint8Array, 'Uint8Array', 'MAC for new DigitalEnvelope object'); checkEncryptedSecretKeyPairs( encryptedSecretKeyPairs, 'Encrypted secret key pairs for new DigitalEnvelope object'); return new DigitalEnvelope( encryptedDataOrJson, mac, encryptedSecretKeyPairs); } else { return jsonToEnvelope(encryptedDataOrJson); } } }; function checkEncryptedSecretKeyPairs(keyPairs, label) { validator.checkIsNonEmptyArray(keyPairs, label); for (var i = 0; i < keyPairs.length; i++) { validator.checkIsObjectWithProperties( keyPairs[i], 'element ' + i + ' of ' + label); } } function jsonToEnvelope(json) { validator.checkIsJsonString( json, 'JSON string to deserialize to DigitalEnvelope object'); var parsed = JSON.parse(json).digitalEnvelope; var encryptedData = codec.base64Decode(parsed.encryptedDataBase64); var mac = codec.base64Decode(parsed.macBase64); var encryptedSecretKeyPairsB64 = parsed.encryptedSecretKeyConcatsBase64; var publicKeysPem = parsed.publicKeysPem; var encryptedSecretKeyPairs = []; for (var i = 0; i < encryptedSecretKeyPairsB64.length; i++) { encryptedSecretKeyPairs.push(new EncryptedSecretKeyPair( codec.base64Decode(encryptedSecretKeyPairsB64[i]), publicKeysPem[i])); } return new DigitalEnvelope(encryptedData, mac, encryptedSecretKeyPairs); }