0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel/**
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel *
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * Copyright (c) 2014 ForgeRock AS. All Rights Reserved
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel *
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * The contents of this file are subject to the terms
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * of the Common Development and Distribution License
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * (the License). You may not use this file except in
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * compliance with the License.
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel *
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * You can obtain a copy of the License at
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * http://forgerock.org/license/CDDLv1.0.html
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * See the License for the specific language governing
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * permission and limitations under the License.
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel *
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * When distributing Covered Code, include this CDDL
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * Header Notice in each file and include the License file
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * at http://forgerock.org/license/CDDLv1.0.html
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * If applicable, add the following below the CDDL Header,
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * with the fields enclosed by brackets [] replaced by
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * your own identifying information:
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel * "Portions Copyrighted [year] [name of copyright owner]"
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel */
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel/*global exports, openidm */
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel(function () {
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel var canBeEncrypted= function (value) {
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel // we are not going to do anything if the value is undefined/null/already encrypted
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel return typeof value !== 'undefined' && value !== null && !openidm.isEncrypted(value);
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel };
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel exports.encrypt = function (value, cipher, alias) {
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel cipher = cipher || 'AES/CBC/PKCS5Padding';
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel alias = alias || identityServer.getProperty('openidm.config.crypto.alias', 'true', true);
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel if (!canBeEncrypted(value)) {
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel return value;
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel }
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel return openidm.encrypt(value, cipher, alias);
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel };
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel exports.hash = function (value, algorithm) {
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel algorithm = algorithm || "SHA-256";
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel if (!canBeEncrypted(value) || typeof value !== "string") {
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel return value;
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel }
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel return openidm.hash(value, algorithm);
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel };
d05649bdb35c6814b435972c4bf5159913bf03baJake Feasel
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel /**
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel * Produces a random string conforming to a set of minimum complexity requirements and length.
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel * Useful for setting random passwords.
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel * @param {Object[]} minimum_requirements - a list of requirements for the random password
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel * @param {string} minimum_requirements[].rule - the one of UPPERCASE,LOWERCASE,INTEGERS,SPECIAL
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel * @param {number} minimum_requirements[].minimum - the number of characters required for this rule
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel * @param {number} total_length - the size of the final random string
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel * @example
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel require('crypto').generateRandomString([
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel { "rule": "UPPERCASE", "minimum": 1 },
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel { "rule": "LOWERCASE", "minimum": 1 },
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel { "rule": "INTEGERS", "minimum": 1 },
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel { "rule": "SPECIAL", "minimum": 1 }
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel ], 8) // returns a value like "R92kHZ;1"
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel */
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel exports.generateRandomString = function (minimum_requirements, total_length) {
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel // returns a random int between the minimum (inclusive) and maximum (exclusive)
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel function getRandomInt(minimum,maximum) {
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel return Math.floor(Math.random()*(maximum-minimum))+minimum;
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel }
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel // returns an index chosen at random from the set of found undefined
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel // value indexes in the provided array
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel function getRandomUndefinedPosition(array,max) {
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel var i = 0,foundUndefined = [];
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel for (i=0;i<max;i++) {
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel if (array[i] === undefined) {
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel foundUndefined.push(i);
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel }
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel }
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel return foundUndefined[getRandomInt(0,foundUndefined.length)];
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel }
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel var character_buffer = [],
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel i,j,
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel character_generators = {
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel UPPERCASE: function (buffer,max) {
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel // ASCII codes for A-Z: 65-90
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel buffer[getRandomUndefinedPosition(buffer,max)] = String.fromCharCode(getRandomInt(65,91));
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel },
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel LOWERCASE: function (buffer,max) {
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel // ASCII codes for a-z: 97-122
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel buffer[getRandomUndefinedPosition(buffer,max)] = String.fromCharCode(getRandomInt(97,123));
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel },
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel INTEGERS: function (buffer,max) {
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel buffer[getRandomUndefinedPosition(buffer,max)] = (getRandomInt(0,10) + "");
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel },
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel SPECIAL: function (buffer,max) {
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel // ASCII codes for 'special' characters: 58-64
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel buffer[getRandomUndefinedPosition(buffer,max)] = String.fromCharCode(getRandomInt(58,65));
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel }
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel }
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel for (i=0;i<minimum_requirements.length;i++) {
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel for (j=0;j<minimum_requirements[i].minimum;j++) {
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel character_generators[minimum_requirements[i].rule](character_buffer, total_length);
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel }
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel }
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel // while there aren't any remaining undefined positions, keep filling them in
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel while (getRandomUndefinedPosition(character_buffer, total_length) !== undefined) {
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel var generator_names = Object.keys(character_generators),
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel random_generator = character_generators[generator_names[getRandomInt(0,generator_names.length)]];
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel random_generator(character_buffer, total_length);
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel }
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel return character_buffer.join("");
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel };
d60e7ec0b9ab39495b9b2f1ab77d69ce731b57b3Jake Feasel
0415e6c7bc1be0990b4a52a14fd51bb810b3ad0dJake Feasel}());