| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 | /* * 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.primitives = cryptolib.modules.primitives || {};/** * @namespace primitives/messagedigest */cryptolib.modules.primitives.messagedigest = function(box) {  'use strict';  box.primitives = box.primitives || {};  box.primitives.messagedigest = box.primitives.messagedigest || {};  /**   * A module that holds message digest functionalities.   * @exports primitives/messagedigest   */  box.primitives.messagedigest.factory =      box.primitives.messagedigest.factory || {};  var policies = {    messagedigest: {      algorithm: box.policies.primitives.messagedigest.algorithm,      provider: box.policies.primitives.messagedigest.provider    }  };  var converters, exceptions;  cryptolib('commons', function(box) {    converters = new box.commons.utils.Converters();    exceptions = box.commons.exceptions;  });  /**   * A factory class for creating a message digest generator and verifier.   * @class   */  box.primitives.messagedigest.factory.MessageDigestFactory = function() {};  box.primitives.messagedigest.factory.MessageDigestFactory.prototype = {    /**     * Gets a message dister object.     * @function     * @returns {primitives/messagedigest.CryptoForgeMessageDigest}     */    getCryptoMessageDigest: function() {      try {        if (policies.messagedigest.provider ===            Config.primitives.messagedigest.provider.FORGE) {          return this.getCryptoForgeMessageDigest();        } else {          throw new exceptions.CryptoLibException(              'No suitable provider was provided.');        }      } catch (error) {        throw new exceptions.CryptoLibException(            'A CryptoSymmetricCipher could not be obtained.', error);      }    },    getCryptoForgeMessageDigest: function() {      return new CryptoForgeMessageDigest();    }  };  /**   * Defines a message digest hash function.   * @class   * @memberof primitives/messagedigest   */  function CryptoForgeMessageDigest() {    this.digester = null;    try {      if (policies.messagedigest.algorithm ===          Config.primitives.messagedigest.algorithm.SHA256) {        this.digester = forge.md.sha256.create();      } else if (          policies.messagedigest.algorithm ===          Config.primitives.messagedigest.algorithm.SHA512_224) {        this.digester = forge.md.sha512.sha224.create();      } else {        var errorMessage = 'Message digester type \'' +            policies.messagedigest.algorithm +            '\' not recognized by CryptoForgeMessageDigest.';        throw new exceptions.CryptoLibException(errorMessage);      }    } catch (error) {      throw new exceptions.CryptoLibException(          'CryptoForgeMessageDigest could not be created.', error);    }  }  CryptoForgeMessageDigest.prototype = {    /**     * Initializes the message digest generator.     * @function     */    start: function() {      try {        this.digester.start();      } catch (error) {        throw new exceptions.CryptoLibException(            'Message digest could not be initialized.', error);      }    },    /**     * Updates the message digest generator.     * @function     * @param {Array} arrayDataBase64     *            data to compute the hash, as an array of string in Base64     *            encoded format.     */    update: function(arrayDataBase64) {      try {        if (!arrayDataBase64 || arrayDataBase64.length < 1) {          throw new exceptions.CryptoLibException(              'The array of data in Base64 should contain at least one element.');        }        for (var i = 0; i < arrayDataBase64.length; i++) {          this.digester.update(converters.base64Decode(arrayDataBase64[i]));        }      } catch (error) {        throw new exceptions.CryptoLibException(            'Message digest could not be updated.', error);      }    },    /**     * Generates the message digest for the updated data.     * @function     * @returns {string} Message digest, as string in Base64 encoded format.     */    digest: function() {      try {        var messageDigest = this.digester.digest();        var rawOutput = messageDigest.getBytes();        var encodedOutput = converters.base64Encode(rawOutput);        return encodedOutput;      } catch (error) {        throw new exceptions.CryptoLibException(            'Message digest could not be generated.', error);      }    }  };};
 |