123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- /*
- * 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.symmetric = cryptolib.modules.symmetric || {};
- /**
- * Defines the MACs of the module.
- *
- * @namespace symmetric/mac
- */
- cryptolib.modules.symmetric.mac = function(box) {
- 'use strict';
- box.symmetric = box.symmetric || {};
- box.symmetric.mac = {};
- /**
- * Allows a symmetric MAC factory to be obtained.
- *
- * @exports symmetric/mac/factory
- */
- box.symmetric.mac.factory = {};
- var policies = {
- mac: {
- hash: box.policies.symmetric.mac.hash,
- provider: box.policies.symmetric.mac.provider
- }
- };
- var converters;
- var exceptions;
- cryptolib('commons', function(box) {
- converters = new box.commons.utils.Converters();
- exceptions = box.commons.exceptions;
- });
- /**
- * Factory class that allows a MAC to be obtained.
- *
- * @class
- */
- box.symmetric.mac.factory.MacFactory = function() {};
- box.symmetric.mac.factory.MacFactory.prototype = {
- /**
- * Create a new MAC.
- * <p>
- * The particular MAC that is returned depends on the policies.
- *
- * @function
- * @returns a new MAC.
- */
- create: function() {
- try {
- if (policies.mac.provider === Config.symmetric.mac.provider.FORGE) {
- return this.createCryptoForgeMac();
- } else {
- throw new exceptions.CryptoLibException(
- 'No suitable provider was provided.');
- }
- } catch (error) {
- throw new exceptions.CryptoLibException(
- 'A CryptoMac could not be obtained.', error);
- }
- },
- /**
- * Create a new CryptoForgeMac.
- *
- * @function
- * @returns {symmetric/mac.CryptoForgeMac} a new CryptoForgeMac.
- */
- createCryptoForgeMac: function() {
- return new CryptoForgeMac();
- }
- };
- /**
- * Represents a MAC.
- *
- * @class
- * @memberof symmetric/mac
- */
- function CryptoForgeMac() {
- this.hmacDigester = forge.hmac.create();
- }
- CryptoForgeMac.prototype = {
- /**
- * Generates MAC for some data.
- *
- * @function
- * @param secretKeyBase64
- * {String} Secret key, as string in Base64 encoded format
- * @param arrayDataBase64
- * {String} The input data for the MAC, as an array of string
- * in Base64 encoded format. It is assumed that the array is
- * not empty.
- * @returns The generated MAC, in Base64 encoded format.
- */
- generate: function(secretKeyBase64, arrayDataBase64) {
- var secretKey = converters.base64Decode(secretKeyBase64);
- var secretKeyBuffer = new forge.util.ByteBuffer(secretKey);
- try {
- this.hmacDigester.start(policies.mac.hash, secretKeyBuffer);
- } catch (error) {
- throw new exceptions.CryptoLibException(
- 'MAC message digester could not be initialized.', error);
- }
- try {
- if (arrayDataBase64.length < 1) {
- throw new exceptions.CryptoLibException(
- 'The array of data should have at least one element');
- }
- var dataB64;
- for (var i = 0; i < arrayDataBase64.length; i++) {
- dataB64 = arrayDataBase64[i];
- var data = converters.base64Decode(dataB64);
- this.hmacDigester.update(data);
- }
- } catch (error) {
- throw new exceptions.CryptoLibException(
- 'MAC message digester could not be updated.', error);
- }
- try {
- var hmacMessageDigest = this.hmacDigester.digest();
- return converters.base64Encode(hmacMessageDigest.getBytes());
- } catch (error) {
- throw new exceptions.CryptoLibException(
- 'MAC message digest could not be generated.', error);
- }
- },
- /**
- * Verify that a given MAC is indeed the MAC for the given data, using
- * the given secret key.
- *
- * @function
- * @param macBase64
- * {String} The MAC to be verified, as string in Base64
- * encoded format.
- * @param secretKeyBase64
- * {String} Secret key, as string in Base64 encoded format
- * @param arrayDataBase64
- * {String} The input data for the MAC, as an array of string
- * in Base64 encoded format. It is assumed that the array is
- * not empty.
- *
- * @returns True if the MAC is the MAC of the given data and SecretKey,
- * false otherwise.
- */
- verify: function(macBase64, secretKeyBase64, arrayDataBase64) {
- if (typeof macBase64 === 'undefined' || macBase64 === null) {
- return false;
- }
- var macBase64ToVerify = this.generate(secretKeyBase64, arrayDataBase64);
- if (macBase64.length !== macBase64ToVerify.length) {
- return false;
- }
- var equals = true;
- for (var i = 0; i < macBase64ToVerify.length; i++) {
- if (macBase64ToVerify.charCodeAt(i) !== macBase64.charCodeAt(i)) {
- equals = false;
- }
- }
- return equals;
- }
- };
- };
|