1542 lines
53 KiB
JavaScript
1542 lines
53 KiB
JavaScript
/*
|
|
* Copyright (c) 2014, GMO GlobalSign
|
|
* Copyright (c) 2015, Peculiar Ventures
|
|
* All rights reserved.
|
|
*
|
|
* Author 2014-2015, Yury Strozhevsky <www.strozhevsky.com>.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software without
|
|
* specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
|
* OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
(
|
|
function(in_window)
|
|
{
|
|
//**************************************************************************************
|
|
// #region Declaration of global variables
|
|
//**************************************************************************************
|
|
// #region "org" namespace
|
|
if(typeof in_window.org === "undefined")
|
|
in_window.org = {};
|
|
else
|
|
{
|
|
if(typeof in_window.org !== "object")
|
|
throw new Error("Name org already exists and it's not an object");
|
|
}
|
|
// #endregion
|
|
|
|
// #region "org.pkijs" namespace
|
|
if(typeof in_window.org.pkijs === "undefined")
|
|
in_window.org.pkijs = {};
|
|
else
|
|
{
|
|
if(typeof in_window.org.pkijs !== "object")
|
|
throw new Error("Name org.pkijs already exists and it's not an object" + " but " + (typeof in_window.org.pkijs));
|
|
}
|
|
// #endregion
|
|
|
|
// #region "local" namespace
|
|
var local = {};
|
|
// #endregion
|
|
//**************************************************************************************
|
|
// #endregion
|
|
//**************************************************************************************
|
|
// #region Settings for "crypto engine"
|
|
//**************************************************************************************
|
|
local.engine = {
|
|
name: "none",
|
|
crypto: null,
|
|
subtle: null
|
|
};
|
|
|
|
if(typeof window != "undefined")
|
|
{
|
|
if("crypto" in window)
|
|
{
|
|
var engineName = "webcrypto";
|
|
var cryptoObject = window.crypto;
|
|
var subtleObject = null;
|
|
|
|
// Apple Safari support
|
|
if("webkitSubtle" in window.crypto)
|
|
subtleObject = window.crypto.webkitSubtle;
|
|
|
|
if("subtle" in window.crypto)
|
|
subtleObject = window.crypto.subtle;
|
|
|
|
local.engine = {
|
|
name: engineName,
|
|
crypto: cryptoObject,
|
|
subtle: subtleObject
|
|
};
|
|
}
|
|
}
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.setEngine =
|
|
function(name, crypto, subtle)
|
|
{
|
|
/// <summary>Setting the global "crypto engine" parameters</summary>
|
|
/// <param name="name" type="String">Auxiliary name for "crypto engine"</param>
|
|
/// <param name="crypto" type="Object">Object handling all root cryptographic requests (in fact currently it must handle only "getRandomValues")</param>
|
|
/// <param name="subtle" type="Object">Object handling all main cryptographic requests</param>
|
|
|
|
local.engine = {
|
|
name: name,
|
|
crypto: crypto,
|
|
subtle: subtle
|
|
};
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.getEngine =
|
|
function()
|
|
{
|
|
return local.engine;
|
|
};
|
|
//**************************************************************************************
|
|
// #endregion
|
|
//**************************************************************************************
|
|
// #region Declaration of common functions
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.emptyObject =
|
|
function()
|
|
{
|
|
this.toJSON = function()
|
|
{
|
|
return {};
|
|
};
|
|
this.toSchema = function()
|
|
{
|
|
return {};
|
|
};
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.getNames =
|
|
function(arg)
|
|
{
|
|
/// <summary>Get correct "names" array for all "schema" objects</summary>
|
|
|
|
var names = {};
|
|
|
|
if(arg instanceof Object)
|
|
names = (arg.names || {});
|
|
|
|
return names;
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.inheriteObjectFields =
|
|
function(from)
|
|
{
|
|
for(var i in from.prototype)
|
|
{
|
|
if(typeof from.prototype[i] === "function")
|
|
continue;
|
|
|
|
this[i] = from.prototype[i];
|
|
}
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.getUTCDate =
|
|
function(date)
|
|
{
|
|
/// <summary>Making UTC date from local date</summary>
|
|
/// <param name="date" type="Date">Date to convert from</param>
|
|
|
|
var current_date = date;
|
|
return new Date(current_date.getTime() + (current_date.getTimezoneOffset() * 60000));
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.padNumber =
|
|
function(input_number, full_length)
|
|
{
|
|
var str = input_number.toString(10);
|
|
var dif = full_length - str.length;
|
|
|
|
var padding = new Array(dif);
|
|
for(var i = 0; i < dif; i++)
|
|
padding[i] = '0';
|
|
|
|
var padding_string = padding.join('');
|
|
|
|
return padding_string.concat(str);
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.getValue =
|
|
function(args, item, default_value)
|
|
{
|
|
if(item in args)
|
|
return args[item];
|
|
else
|
|
return default_value;
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.isEqual_view =
|
|
function(input_view1, input_view2)
|
|
{
|
|
/// <summary>Compare two Uint8Arrays</summary>
|
|
/// <param name="input_view1" type="Uint8Array">First Uint8Array for comparision</param>
|
|
/// <param name="input_view2" type="Uint8Array">Second Uint8Array for comparision</param>
|
|
|
|
if(input_view1.length !== input_view2.length)
|
|
return false;
|
|
|
|
for(var i = 0; i < input_view1.length; i++)
|
|
{
|
|
if(input_view1[i] != input_view2[i])
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.isEqual_buffer =
|
|
function(input_buffer1, input_buffer2)
|
|
{
|
|
/// <summary>Compare two array buffers</summary>
|
|
/// <param name="input_buffer1" type="ArrayBuffer">First ArrayBuffer for comparision</param>
|
|
/// <param name="input_buffer2" type="ArrayBuffer">Second ArrayBuffer for comparision</param>
|
|
|
|
if(input_buffer1.byteLength != input_buffer2.byteLength)
|
|
return false;
|
|
|
|
var view1 = new Uint8Array(input_buffer1);
|
|
var view2 = new Uint8Array(input_buffer2);
|
|
|
|
return in_window.org.pkijs.isEqual_view(view1, view2);
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.concat_buffers =
|
|
function(input_buf1, input_buf2)
|
|
{
|
|
/// <summary>Concatenate two ArrayBuffers</summary>
|
|
/// <param name="input_buf1" type="ArrayBuffer">First ArrayBuffer (first part of concatenated array)</param>
|
|
/// <param name="input_buf2" type="ArrayBuffer">Second ArrayBuffer (second part of concatenated array)</param>
|
|
|
|
var input_view1 = new Uint8Array(input_buf1);
|
|
var input_view2 = new Uint8Array(input_buf2);
|
|
|
|
var ret_buf = new ArrayBuffer(input_buf1.byteLength + input_buf2.byteLength);
|
|
var ret_view = new Uint8Array(ret_buf);
|
|
|
|
for(var i = 0; i < input_buf1.byteLength; i++)
|
|
ret_view[i] = input_view1[i];
|
|
|
|
for(var j = 0; j < input_buf2.byteLength; j++)
|
|
ret_view[input_buf1.byteLength + j] = input_view2[j];
|
|
|
|
return ret_buf;
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.copyBuffer =
|
|
function(input_buffer)
|
|
{
|
|
var result = new ArrayBuffer(input_buffer.byteLength);
|
|
|
|
var resultView = new Uint8Array(result);
|
|
var inputView = new Uint8Array(input_buffer);
|
|
|
|
for(var i = 0; i < inputView.length; i++)
|
|
resultView[i] = inputView[i];
|
|
|
|
return result;
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.getCrypto =
|
|
function()
|
|
{
|
|
var crypto_temp;
|
|
|
|
if(local.engine.subtle !== null)
|
|
crypto_temp = local.engine.subtle;
|
|
|
|
return crypto_temp;
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.stringPrep =
|
|
function(input_string)
|
|
{
|
|
/// <summary>String preparation function. In a future here will be realization of algorithm from RFC4518.</summary>
|
|
/// <param name="input_string" type="String">JavaScript string. As soon as for each ASN.1 string type we have a specific transformation function here we will work with pure JavaScript string</param>
|
|
/// <returns type="String">Formated string</returns>
|
|
|
|
var result = input_string.replace(/^\s+|\s+$/g, ""); // Trim input string
|
|
result = result.replace(/\s+/g, " "); // Change all sequence of SPACE down to SPACE char
|
|
result = result.toLowerCase();
|
|
|
|
return result;
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.bufferToHexCodes =
|
|
function(input_buffer, input_offset, input_lenght)
|
|
{
|
|
var result = "";
|
|
|
|
var int_buffer = new Uint8Array(input_buffer, input_offset, input_lenght);
|
|
|
|
for(var i = 0; i < int_buffer.length; i++)
|
|
{
|
|
var str = int_buffer[i].toString(16).toUpperCase();
|
|
result = result + ((str.length === 1) ? "0" : "") + str;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.bufferFromHexCodes =
|
|
function(hexString)
|
|
{
|
|
/// <summary>Create an ArrayBuffer from string having hexdecimal codes</summary>
|
|
/// <param name="hexString" type="String">String to create ArrayBuffer from</param>
|
|
|
|
// #region Initial variables
|
|
var stringLength = hexString.length;
|
|
|
|
var resultBuffer = new ArrayBuffer(stringLength >> 1);
|
|
var resultView = new Uint8Array(resultBuffer);
|
|
|
|
var hex_map = {};
|
|
|
|
hex_map['0'] = 0x00;
|
|
hex_map['1'] = 0x01;
|
|
hex_map['2'] = 0x02;
|
|
hex_map['3'] = 0x03;
|
|
hex_map['4'] = 0x04;
|
|
hex_map['5'] = 0x05;
|
|
hex_map['6'] = 0x06;
|
|
hex_map['7'] = 0x07;
|
|
hex_map['8'] = 0x08;
|
|
hex_map['9'] = 0x09;
|
|
hex_map['A'] = 0x0A;
|
|
hex_map['a'] = 0x0A;
|
|
hex_map['B'] = 0x0B;
|
|
hex_map['b'] = 0x0B;
|
|
hex_map['C'] = 0x0C;
|
|
hex_map['c'] = 0x0C;
|
|
hex_map['D'] = 0x0D;
|
|
hex_map['d'] = 0x0D;
|
|
hex_map['E'] = 0x0E;
|
|
hex_map['e'] = 0x0E;
|
|
hex_map['F'] = 0x0F;
|
|
hex_map['f'] = 0x0F;
|
|
|
|
var j = 0;
|
|
var temp = 0x00;
|
|
// #endregion
|
|
|
|
// #region Convert char-by-char
|
|
for(var i = 0; i < stringLength; i++)
|
|
{
|
|
if(!(i % 2))
|
|
temp = hex_map[hexString.charAt(i)] << 4;
|
|
else
|
|
{
|
|
temp |= hex_map[hexString.charAt(i)];
|
|
|
|
resultView[j] = temp;
|
|
j++;
|
|
}
|
|
}
|
|
// #endregion
|
|
|
|
return resultBuffer;
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.getRandomValues =
|
|
function(view)
|
|
{
|
|
/// <param name="view" type="Uint8Array">New array which gives a length for random value</param>
|
|
|
|
if(local.engine.crypto !== null)
|
|
return local.engine.crypto.getRandomValues(view);
|
|
else
|
|
throw new Error("No support for Web Cryptography API");
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.getAlgorithmParameters =
|
|
function(algorithmName, operation)
|
|
{
|
|
/// <param name="algorithmName" type="String">Algorithm name to get common parameters for</param>
|
|
/// <param name="operation" type="String">Kind of operation: "sign", "encrypt", "generatekey", "importkey", "exportkey", "verify"</param>
|
|
|
|
var result = {
|
|
algorithm: {},
|
|
usages: []
|
|
};
|
|
|
|
switch(algorithmName.toUpperCase())
|
|
{
|
|
case "RSASSA-PKCS1-V1_5":
|
|
switch(operation.toLowerCase())
|
|
{
|
|
case "generatekey":
|
|
result = {
|
|
algorithm: {
|
|
name: "RSASSA-PKCS1-v1_5",
|
|
modulusLength: 2048,
|
|
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
|
|
hash: {
|
|
name: "SHA-256"
|
|
}
|
|
},
|
|
usages: ["sign", "verify"]
|
|
};
|
|
break;
|
|
case "verify":
|
|
case "sign":
|
|
case "importkey":
|
|
result = {
|
|
algorithm: {
|
|
name: "RSASSA-PKCS1-v1_5",
|
|
hash: {
|
|
name: "SHA-256"
|
|
}
|
|
},
|
|
usages: ["verify"] // For importKey("pkcs8") usage must be "sign" only
|
|
};
|
|
break;
|
|
case "exportkey":
|
|
default:
|
|
return {
|
|
algorithm: {
|
|
name: "RSASSA-PKCS1-v1_5"
|
|
},
|
|
usages: []
|
|
};
|
|
}
|
|
break;
|
|
case "RSA-PSS":
|
|
switch(operation.toLowerCase())
|
|
{
|
|
case "sign":
|
|
case "verify":
|
|
result = {
|
|
algorithm: {
|
|
name: "RSA-PSS",
|
|
hash: {
|
|
name: "SHA-1"
|
|
},
|
|
saltLength: 20
|
|
},
|
|
usages: ["sign", "verify"]
|
|
};
|
|
break;
|
|
case "generatekey":
|
|
result = {
|
|
algorithm: {
|
|
name: "RSA-PSS",
|
|
modulusLength: 2048,
|
|
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
|
|
hash: {
|
|
name: "SHA-1"
|
|
}
|
|
},
|
|
usages: ["sign", "verify"]
|
|
};
|
|
break;
|
|
case "importkey":
|
|
result = {
|
|
algorithm: {
|
|
name: "RSA-PSS",
|
|
hash: {
|
|
name: "SHA-1"
|
|
}
|
|
},
|
|
usages: ["verify"] // For importKey("pkcs8") usage must be "sign" only
|
|
};
|
|
break;
|
|
case "exportkey":
|
|
default:
|
|
return {
|
|
algorithm: {
|
|
name: "RSA-PSS"
|
|
},
|
|
usages: []
|
|
};
|
|
}
|
|
break;
|
|
case "RSA-OAEP":
|
|
switch(operation.toLowerCase())
|
|
{
|
|
case "encrypt":
|
|
case "decrypt":
|
|
result = {
|
|
algorithm: {
|
|
name: "RSA-OAEP"
|
|
},
|
|
usages: ["encrypt", "decrypt"]
|
|
};
|
|
break;
|
|
break;
|
|
case "generatekey":
|
|
result = {
|
|
algorithm: {
|
|
name: "RSA-OAEP",
|
|
modulusLength: 2048,
|
|
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
|
|
hash: {
|
|
name: "SHA-256"
|
|
}
|
|
},
|
|
usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
|
|
};
|
|
break;
|
|
case "importkey":
|
|
result = {
|
|
algorithm: {
|
|
name: "RSA-OAEP",
|
|
hash: {
|
|
name: "SHA-256"
|
|
}
|
|
},
|
|
usages: ["encrypt"] // encrypt for "spki" and decrypt for "pkcs8"
|
|
};
|
|
break;
|
|
case "exportkey":
|
|
default:
|
|
return {
|
|
algorithm: {
|
|
name: "RSA-OAEP"
|
|
},
|
|
usages: []
|
|
};
|
|
}
|
|
break;
|
|
case "ECDSA":
|
|
switch(operation.toLowerCase())
|
|
{
|
|
case "generatekey":
|
|
result = {
|
|
algorithm: {
|
|
name: "ECDSA",
|
|
namedCurve: "P-256"
|
|
},
|
|
usages: ["sign", "verify"]
|
|
};
|
|
break;
|
|
case "importkey":
|
|
result = {
|
|
algorithm: {
|
|
name: "ECDSA",
|
|
namedCurve: "P-256"
|
|
},
|
|
usages: ["verify"] // "sign" for "pkcs8"
|
|
};
|
|
break;
|
|
case "verify":
|
|
case "sign":
|
|
result = {
|
|
algorithm: {
|
|
name: "ECDSA",
|
|
hash: {
|
|
name: "SHA-256"
|
|
}
|
|
},
|
|
usages: ["sign"]
|
|
};
|
|
break;
|
|
default:
|
|
return {
|
|
algorithm: {
|
|
name: "ECDSA"
|
|
},
|
|
usages: []
|
|
};
|
|
}
|
|
break;
|
|
case "ECDH":
|
|
switch(operation.toLowerCase())
|
|
{
|
|
case "exportkey":
|
|
case "importkey":
|
|
case "generatekey":
|
|
result = {
|
|
algorithm: {
|
|
name: "ECDH",
|
|
namedCurve: "P-256"
|
|
},
|
|
usages: ["deriveKey", "deriveBits"]
|
|
};
|
|
break;
|
|
case "derivekey":
|
|
case "derivebits":
|
|
result = {
|
|
algorithm: {
|
|
name: "ECDH",
|
|
namedCurve: "P-256",
|
|
public: [] // Must be a "publicKey"
|
|
},
|
|
usages: ["encrypt", "decrypt"]
|
|
};
|
|
break;
|
|
default:
|
|
return {
|
|
algorithm: {
|
|
name: "ECDH"
|
|
},
|
|
usages: []
|
|
};
|
|
}
|
|
break;
|
|
case "AES-CTR":
|
|
switch(operation.toLowerCase())
|
|
{
|
|
case "importkey":
|
|
case "exportkey":
|
|
case "generatekey":
|
|
result = {
|
|
algorithm: {
|
|
name: "AES-CTR",
|
|
length: 256
|
|
},
|
|
usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
|
|
};
|
|
break;
|
|
case "decrypt":
|
|
case "encrypt":
|
|
result = {
|
|
algorithm: {
|
|
name: "AES-CTR",
|
|
counter: new Uint8Array(16),
|
|
length: 10
|
|
},
|
|
usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
|
|
};
|
|
break;
|
|
default:
|
|
return {
|
|
algorithm: {
|
|
name: "AES-CTR"
|
|
},
|
|
usages: []
|
|
};
|
|
}
|
|
break;
|
|
case "AES-CBC":
|
|
switch(operation.toLowerCase())
|
|
{
|
|
case "importkey":
|
|
case "exportkey":
|
|
case "generatekey":
|
|
result = {
|
|
algorithm: {
|
|
name: "AES-CBC",
|
|
length: 256
|
|
},
|
|
usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
|
|
};
|
|
break;
|
|
case "decrypt":
|
|
case "encrypt":
|
|
result = {
|
|
algorithm: {
|
|
name: "AES-CBC",
|
|
iv: in_window.org.pkijs.getRandomValues(new Uint8Array(16)) // For "decrypt" the value should be replaced with value got on "encrypt" step
|
|
},
|
|
usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
|
|
};
|
|
break;
|
|
default:
|
|
return {
|
|
algorithm: {
|
|
name: "AES-CBC"
|
|
},
|
|
usages: []
|
|
};
|
|
}
|
|
break;
|
|
case "AES-GCM":
|
|
switch(operation.toLowerCase())
|
|
{
|
|
case "importkey":
|
|
case "exportkey":
|
|
case "generatekey":
|
|
result = {
|
|
algorithm: {
|
|
name: "AES-GCM",
|
|
length: 256
|
|
},
|
|
usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
|
|
};
|
|
break;
|
|
case "decrypt":
|
|
case "encrypt":
|
|
result = {
|
|
algorithm: {
|
|
name: "AES-GCM",
|
|
iv: in_window.org.pkijs.getRandomValues(new Uint8Array(16)) // For "decrypt" the value should be replaced with value got on "encrypt" step
|
|
},
|
|
usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
|
|
};
|
|
break;
|
|
default:
|
|
return {
|
|
algorithm: {
|
|
name: "AES-GCM"
|
|
},
|
|
usages: []
|
|
};
|
|
}
|
|
break;
|
|
case "AES-KW":
|
|
switch(operation.toLowerCase())
|
|
{
|
|
case "importkey":
|
|
case "exportkey":
|
|
case "generatekey":
|
|
case "wrapkey":
|
|
case "unwrapkey":
|
|
result = {
|
|
algorithm: {
|
|
name: "AES-KW",
|
|
length: 256
|
|
},
|
|
usages: ["wrapKey", "unwrapKey"]
|
|
};
|
|
break;
|
|
default:
|
|
return {
|
|
algorithm: {
|
|
name: "AES-KW"
|
|
},
|
|
usages: []
|
|
};
|
|
}
|
|
break;
|
|
case "HMAC":
|
|
switch(operation.toLowerCase())
|
|
{
|
|
case "sign":
|
|
case "verify":
|
|
result = {
|
|
algorithm: {
|
|
name: "HMAC"
|
|
},
|
|
usages: ["sign", "verify"]
|
|
};
|
|
break;
|
|
case "importkey":
|
|
case "exportkey":
|
|
case "generatekey":
|
|
result = {
|
|
algorithm: {
|
|
name: "HMAC",
|
|
length: 32,
|
|
hash: {
|
|
name: "SHA-256"
|
|
}
|
|
},
|
|
usages: ["sign", "verify"]
|
|
};
|
|
break;
|
|
default:
|
|
return {
|
|
algorithm: {
|
|
name: "HMAC"
|
|
},
|
|
usages: []
|
|
};
|
|
}
|
|
break;
|
|
case "HKDF":
|
|
switch(operation.toLowerCase())
|
|
{
|
|
case "derivekey":
|
|
result = {
|
|
algorithm: {
|
|
name: "HKDF",
|
|
hash: "SHA-256",
|
|
salt: new Uint8Array(),
|
|
info: new Uint8Array()
|
|
},
|
|
usages: ["encrypt", "decrypt"]
|
|
};
|
|
break;
|
|
default:
|
|
return {
|
|
algorithm: {
|
|
name: "HKDF"
|
|
},
|
|
usages: []
|
|
};
|
|
}
|
|
break;
|
|
case "PBKDF2":
|
|
switch(operation.toLowerCase())
|
|
{
|
|
case "derivekey":
|
|
result = {
|
|
algorithm: {
|
|
name: "PBKDF2",
|
|
hash: { name: "SHA-256" },
|
|
salt: new Uint8Array(),
|
|
iterations: 1000
|
|
},
|
|
usages: ["encrypt", "decrypt"]
|
|
};
|
|
break;
|
|
default:
|
|
return {
|
|
algorithm: {
|
|
name: "PBKDF2"
|
|
},
|
|
usages: []
|
|
};
|
|
}
|
|
break;
|
|
default:
|
|
}
|
|
|
|
return result;
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.getOIDByAlgorithm =
|
|
function(algorithm)
|
|
{
|
|
/// <summary>Get OID for each specific WebCrypto algorithm</summary>
|
|
/// <param name="algorithm" type="Object">WebCrypto algorithm</param>
|
|
|
|
var result = "";
|
|
|
|
switch(algorithm.name.toUpperCase())
|
|
{
|
|
case "RSASSA-PKCS1-V1_5":
|
|
switch(algorithm.hash.name.toUpperCase())
|
|
{
|
|
case "SHA-1":
|
|
result = "1.2.840.113549.1.1.5";
|
|
break;
|
|
case "SHA-256":
|
|
result = "1.2.840.113549.1.1.11";
|
|
break;
|
|
case "SHA-384":
|
|
result = "1.2.840.113549.1.1.12";
|
|
break;
|
|
case "SHA-512":
|
|
result = "1.2.840.113549.1.1.13";
|
|
break;
|
|
default:
|
|
}
|
|
break;
|
|
case "RSA-PSS":
|
|
result = "1.2.840.113549.1.1.10";
|
|
break;
|
|
case "RSA-OAEP":
|
|
result = "1.2.840.113549.1.1.7";
|
|
break;
|
|
case "ECDSA":
|
|
switch(algorithm.hash.name.toUpperCase())
|
|
{
|
|
case "SHA-1":
|
|
result = "1.2.840.10045.4.1";
|
|
break;
|
|
case "SHA-256":
|
|
result = "1.2.840.10045.4.3.2";
|
|
break;
|
|
case "SHA-384":
|
|
result = "1.2.840.10045.4.3.3";
|
|
break;
|
|
case "SHA-512":
|
|
result = "1.2.840.10045.4.3.4";
|
|
break;
|
|
default:
|
|
}
|
|
break;
|
|
case "ECDH":
|
|
switch(algorithm.kdf.toUpperCase()) // Non-standard addition - hash algorithm of KDF function
|
|
{
|
|
case "SHA-1":
|
|
result = "1.3.133.16.840.63.0.2"; // dhSinglePass-stdDH-sha1kdf-scheme
|
|
break;
|
|
case "SHA-256":
|
|
result = "1.3.132.1.11.1"; // dhSinglePass-stdDH-sha256kdf-scheme
|
|
break;
|
|
case "SHA-384":
|
|
result = "1.3.132.1.11.2"; // dhSinglePass-stdDH-sha384kdf-scheme
|
|
break;
|
|
case "SHA-512":
|
|
result = "1.3.132.1.11.3"; // dhSinglePass-stdDH-sha512kdf-scheme
|
|
break;
|
|
default:
|
|
}
|
|
break;
|
|
case "AES-CTR":
|
|
break;
|
|
case "AES-CBC":
|
|
switch(algorithm.length)
|
|
{
|
|
case 128:
|
|
result = "2.16.840.1.101.3.4.1.2";
|
|
break;
|
|
case 192:
|
|
result = "2.16.840.1.101.3.4.1.22";
|
|
break;
|
|
case 256:
|
|
result = "2.16.840.1.101.3.4.1.42";
|
|
break;
|
|
default:
|
|
}
|
|
break;
|
|
case "AES-CMAC":
|
|
break;
|
|
case "AES-GCM":
|
|
switch(algorithm.length)
|
|
{
|
|
case 128:
|
|
result = "2.16.840.1.101.3.4.1.6";
|
|
break;
|
|
case 192:
|
|
result = "2.16.840.1.101.3.4.1.26";
|
|
break;
|
|
case 256:
|
|
result = "2.16.840.1.101.3.4.1.46";
|
|
break;
|
|
default:
|
|
}
|
|
break;
|
|
case "AES-CFB":
|
|
switch(algorithm.length)
|
|
{
|
|
case 128:
|
|
result = "2.16.840.1.101.3.4.1.4";
|
|
break;
|
|
case 192:
|
|
result = "2.16.840.1.101.3.4.1.24";
|
|
break;
|
|
case 256:
|
|
result = "2.16.840.1.101.3.4.1.44";
|
|
break;
|
|
default:
|
|
}
|
|
break;
|
|
case "AES-KW":
|
|
switch(algorithm.length)
|
|
{
|
|
case 128:
|
|
result = "2.16.840.1.101.3.4.1.5";
|
|
break;
|
|
case 192:
|
|
result = "2.16.840.1.101.3.4.1.25";
|
|
break;
|
|
case 256:
|
|
result = "2.16.840.1.101.3.4.1.45";
|
|
break;
|
|
default:
|
|
}
|
|
break;
|
|
case "HMAC":
|
|
switch(algorithm.hash.name.toUpperCase())
|
|
{
|
|
case "SHA-1":
|
|
result = "1.2.840.113549.2.7";
|
|
break;
|
|
case "SHA-256":
|
|
result = "1.2.840.113549.2.9";
|
|
break;
|
|
case "SHA-384":
|
|
result = "1.2.840.113549.2.10";
|
|
break;
|
|
case "SHA-512":
|
|
result = "1.2.840.113549.2.11";
|
|
break;
|
|
default:
|
|
}
|
|
break;
|
|
case "DH":
|
|
result = "1.2.840.113549.1.9.16.3.5";
|
|
break;
|
|
case "SHA-1":
|
|
result = "1.3.14.3.2.26";
|
|
break;
|
|
case "SHA-256":
|
|
result = "2.16.840.1.101.3.4.2.1";
|
|
break;
|
|
case "SHA-384":
|
|
result = "2.16.840.1.101.3.4.2.2";
|
|
break;
|
|
case "SHA-512":
|
|
result = "2.16.840.1.101.3.4.2.3";
|
|
break;
|
|
case "CONCAT":
|
|
break;
|
|
case "HKDF":
|
|
break;
|
|
case "PBKDF2":
|
|
result = "1.2.840.113549.1.5.12";
|
|
break;
|
|
// #region Special case - OIDs for ECC curves
|
|
case "P-256":
|
|
result = "1.2.840.10045.3.1.7";
|
|
break;
|
|
case "P-384":
|
|
result = "1.3.132.0.34";
|
|
break;
|
|
case "P-521":
|
|
result = "1.3.132.0.35";
|
|
break;
|
|
// #endregion
|
|
|
|
default:
|
|
}
|
|
|
|
return result;
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.getAlgorithmByOID =
|
|
function(oid)
|
|
{
|
|
/// <summary>Get WebCrypto algorithm by wel-known OID</summary>
|
|
/// <param name="oid" type="String">Wel-known OID to search for</param>
|
|
|
|
var result = {};
|
|
|
|
switch(oid)
|
|
{
|
|
case "1.2.840.113549.1.1.5":
|
|
result = {
|
|
name: "RSASSA-PKCS1-v1_5",
|
|
hash: {
|
|
name: "SHA-1"
|
|
}
|
|
};
|
|
break;
|
|
case "1.2.840.113549.1.1.11":
|
|
result = {
|
|
name: "RSASSA-PKCS1-v1_5",
|
|
hash: {
|
|
name: "SHA-256"
|
|
}
|
|
};
|
|
break;
|
|
case "1.2.840.113549.1.1.12":
|
|
result = {
|
|
name: "RSASSA-PKCS1-v1_5",
|
|
hash: {
|
|
name: "SHA-384"
|
|
}
|
|
};
|
|
break;
|
|
case "1.2.840.113549.1.1.13":
|
|
result = {
|
|
name: "RSASSA-PKCS1-v1_5",
|
|
hash: {
|
|
name: "SHA-512"
|
|
}
|
|
};
|
|
break;
|
|
case "1.2.840.113549.1.1.10":
|
|
result = {
|
|
name: "RSA-PSS"
|
|
};
|
|
break;
|
|
case "1.2.840.113549.1.1.7":
|
|
result = {
|
|
name: "RSA-OAEP"
|
|
};
|
|
break;
|
|
case "1.2.840.10045.4.1":
|
|
result = {
|
|
name: "ECDSA",
|
|
hash: {
|
|
name: "SHA-1"
|
|
}
|
|
};
|
|
break;
|
|
case "1.2.840.10045.4.3.2":
|
|
result = {
|
|
name: "ECDSA",
|
|
hash: {
|
|
name: "SHA-256"
|
|
}
|
|
};
|
|
break;
|
|
case "1.2.840.10045.4.3.3":
|
|
result = {
|
|
name: "ECDSA",
|
|
hash: {
|
|
name: "SHA-384"
|
|
}
|
|
};
|
|
break;
|
|
case "1.2.840.10045.4.3.4":
|
|
result = {
|
|
name: "ECDSA",
|
|
hash: {
|
|
name: "SHA-512"
|
|
}
|
|
};
|
|
break;
|
|
case "1.3.133.16.840.63.0.2":
|
|
result = {
|
|
name: "ECDH",
|
|
kdf: "SHA-1"
|
|
};
|
|
break;
|
|
case "1.3.132.1.11.1":
|
|
result = {
|
|
name: "ECDH",
|
|
kdf: "SHA-256"
|
|
};
|
|
break;
|
|
case "1.3.132.1.11.2":
|
|
result = {
|
|
name: "ECDH",
|
|
kdf: "SHA-384"
|
|
};
|
|
break;
|
|
case "1.3.132.1.11.3":
|
|
result = {
|
|
name: "ECDH",
|
|
kdf: "SHA-512"
|
|
};
|
|
break;
|
|
case "2.16.840.1.101.3.4.1.2":
|
|
result = {
|
|
name: "AES-CBC",
|
|
length: 128
|
|
};
|
|
break;
|
|
case "2.16.840.1.101.3.4.1.22":
|
|
result = {
|
|
name: "AES-CBC",
|
|
length: 192
|
|
};
|
|
break;
|
|
case "2.16.840.1.101.3.4.1.42":
|
|
result = {
|
|
name: "AES-CBC",
|
|
length: 256
|
|
};
|
|
break;
|
|
case "2.16.840.1.101.3.4.1.6":
|
|
result = {
|
|
name: "AES-GCM",
|
|
length: 128
|
|
};
|
|
break;
|
|
case "2.16.840.1.101.3.4.1.26":
|
|
result = {
|
|
name: "AES-GCM",
|
|
length: 192
|
|
};
|
|
break;
|
|
case "2.16.840.1.101.3.4.1.46":
|
|
result = {
|
|
name: "AES-GCM",
|
|
length: 256
|
|
};
|
|
break;
|
|
case "2.16.840.1.101.3.4.1.4":
|
|
result = {
|
|
name: "AES-CFB",
|
|
length: 128
|
|
};
|
|
break;
|
|
case "2.16.840.1.101.3.4.1.24":
|
|
result = {
|
|
name: "AES-CFB",
|
|
length: 192
|
|
};
|
|
break;
|
|
case "2.16.840.1.101.3.4.1.44":
|
|
result = {
|
|
name: "AES-CFB",
|
|
length: 256
|
|
};
|
|
break;
|
|
case "2.16.840.1.101.3.4.1.5":
|
|
result = {
|
|
name: "AES-KW",
|
|
length: 128
|
|
};
|
|
break;
|
|
case "2.16.840.1.101.3.4.1.25":
|
|
result = {
|
|
name: "AES-KW",
|
|
length: 192
|
|
};
|
|
break;
|
|
case "2.16.840.1.101.3.4.1.45":
|
|
result = {
|
|
name: "AES-KW",
|
|
length: 256
|
|
};
|
|
break;
|
|
case "1.2.840.113549.2.7":
|
|
result = {
|
|
name: "HMAC",
|
|
hash: {
|
|
name: "SHA-1"
|
|
}
|
|
};
|
|
break;
|
|
case "1.2.840.113549.2.9":
|
|
result = {
|
|
name: "HMAC",
|
|
hash: {
|
|
name: "SHA-256"
|
|
}
|
|
};
|
|
break;
|
|
case "1.2.840.113549.2.10":
|
|
result = {
|
|
name: "HMAC",
|
|
hash: {
|
|
name: "SHA-384"
|
|
}
|
|
};
|
|
break;
|
|
case "1.2.840.113549.2.11":
|
|
result = {
|
|
name: "HMAC",
|
|
hash: {
|
|
name: "SHA-512"
|
|
}
|
|
};
|
|
break;
|
|
case "1.2.840.113549.1.9.16.3.5":
|
|
result = {
|
|
name: "DH"
|
|
};
|
|
break;
|
|
case "1.3.14.3.2.26":
|
|
result = {
|
|
name: "SHA-1"
|
|
};
|
|
break;
|
|
case "2.16.840.1.101.3.4.2.1":
|
|
result = {
|
|
name: "SHA-256"
|
|
};
|
|
break;
|
|
case "2.16.840.1.101.3.4.2.2":
|
|
result = {
|
|
name: "SHA-384"
|
|
};
|
|
break;
|
|
case "2.16.840.1.101.3.4.2.3":
|
|
result = {
|
|
name: "SHA-512"
|
|
};
|
|
break;
|
|
case "1.2.840.113549.1.5.12":
|
|
result = {
|
|
name: "PBKDF2"
|
|
};
|
|
break;
|
|
// #region Special case - OIDs for ECC curves
|
|
case "1.2.840.10045.3.1.7":
|
|
result = {
|
|
name: "P-256"
|
|
};
|
|
break;
|
|
case "1.3.132.0.34":
|
|
result = {
|
|
name: "P-384"
|
|
};
|
|
break;
|
|
case "1.3.132.0.35":
|
|
result = {
|
|
name: "P-521"
|
|
};
|
|
break;
|
|
// #endregion
|
|
|
|
default:
|
|
}
|
|
|
|
return result;
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.getHashAlgorithm =
|
|
function(signatureAlgorithm)
|
|
{
|
|
/// <summary>Getting hash algorithm by signature algorithm</summary>
|
|
/// <param name="signatureAlgorithm" type="in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER">Signature algorithm</param>
|
|
|
|
var result = "";
|
|
|
|
switch(signatureAlgorithm.algorithm_id)
|
|
{
|
|
case "1.2.840.10045.4.1": // ecdsa-with-SHA1
|
|
case "1.2.840.113549.1.1.5":
|
|
result = "SHA-1";
|
|
break;
|
|
case "1.2.840.10045.4.3.2": // ecdsa-with-SHA256
|
|
case "1.2.840.113549.1.1.11":
|
|
result = "SHA-256";
|
|
break;
|
|
case "1.2.840.10045.4.3.3": // ecdsa-with-SHA384
|
|
case "1.2.840.113549.1.1.12":
|
|
result = "SHA-384";
|
|
break;
|
|
case "1.2.840.10045.4.3.4": // ecdsa-with-SHA512
|
|
case "1.2.840.113549.1.1.13":
|
|
result = "SHA-512";
|
|
break;
|
|
case "1.2.840.113549.1.1.10": // RSA-PSS
|
|
{
|
|
var params;
|
|
|
|
try
|
|
{
|
|
params = new in_window.org.pkijs.simpl.x509.RSASSA_PSS_params({ schema: signatureAlgorithm.algorithm_params });
|
|
if("hashAlgorithm" in params)
|
|
{
|
|
var algorithm = in_window.org.pkijs.getAlgorithmByOID(params.hashAlgorithm.algorithm_id);
|
|
if(("name" in algorithm) === false)
|
|
return "";
|
|
|
|
result = algorithm.name;
|
|
}
|
|
else
|
|
result = "SHA-1";
|
|
}
|
|
catch(ex)
|
|
{
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
}
|
|
|
|
return result;
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.createCMSECDSASignature =
|
|
function(signatureBuffer)
|
|
{
|
|
/// <summary>Create CMS ECDSA signature from WebCrypto ECDSA signature</summary>
|
|
/// <param name="signatureBuffer" type="ArrayBuffer">WebCrypto result of "sign" function</param>
|
|
|
|
// #region Initial check for correct length
|
|
if((signatureBuffer.byteLength % 2) != 0)
|
|
return new ArrayBuffer(0);
|
|
// #endregion
|
|
|
|
// #region Initial variables
|
|
var i = 0;
|
|
var length = signatureBuffer.byteLength / 2; // There are two equal parts inside incoming ArrayBuffer
|
|
|
|
var signatureView = new Uint8Array(signatureBuffer);
|
|
|
|
var r_buffer = new ArrayBuffer(length);
|
|
var r_view = new Uint8Array(r_buffer);
|
|
var r_corrected_buffer;
|
|
var r_corrected_view;
|
|
|
|
var s_buffer = new ArrayBuffer(length);
|
|
var s_view = new Uint8Array(s_buffer);
|
|
var s_corrected_buffer;
|
|
var s_corrected_view;
|
|
// #endregion
|
|
|
|
// #region Get "r" part of ECDSA signature
|
|
for(; i < length; i++)
|
|
r_view[i] = signatureView[i];
|
|
|
|
if(r_view[0] & 0x80)
|
|
{
|
|
r_corrected_buffer = new ArrayBuffer(length + 1);
|
|
r_corrected_view = new Uint8Array(r_corrected_buffer);
|
|
|
|
r_corrected_view[0] = 0x00;
|
|
|
|
for(var j = 0; j < length; j++)
|
|
r_corrected_view[j + 1] = r_view[j];
|
|
}
|
|
else
|
|
{
|
|
r_corrected_buffer = r_buffer;
|
|
r_corrected_view = r_view;
|
|
}
|
|
// #endregion
|
|
|
|
// #region Get "s" part of ECDSA signature
|
|
for(; i < signatureBuffer.byteLength; i++)
|
|
s_view[i - length] = signatureView[i];
|
|
|
|
|
|
if(s_view[0] & 0x80)
|
|
{
|
|
s_corrected_buffer = new ArrayBuffer(length + 1);
|
|
s_corrected_view = new Uint8Array(s_corrected_buffer);
|
|
|
|
s_corrected_view[0] = 0x00;
|
|
|
|
for(var j = 0; j < length; j++)
|
|
s_corrected_view[j + 1] = s_view[j];
|
|
}
|
|
else
|
|
{
|
|
s_corrected_buffer = s_buffer;
|
|
s_corrected_view = s_view;
|
|
}
|
|
// #endregion
|
|
|
|
// #region Create ASN.1 structure of CMS ECDSA signature
|
|
var r_integer = new in_window.org.pkijs.asn1.INTEGER();
|
|
r_integer.value_block.is_hex_only = true;
|
|
r_integer.value_block.value_hex = in_window.org.pkijs.copyBuffer(r_corrected_buffer);
|
|
|
|
var s_integer = new in_window.org.pkijs.asn1.INTEGER();
|
|
s_integer.value_block.is_hex_only = true;
|
|
s_integer.value_block.value_hex = in_window.org.pkijs.copyBuffer(s_corrected_buffer);
|
|
|
|
var asn1 = new in_window.org.pkijs.asn1.SEQUENCE({
|
|
value: [
|
|
r_integer,
|
|
s_integer
|
|
]
|
|
});
|
|
// #endregion
|
|
|
|
return asn1.toBER(false);
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.createECDSASignatureFromCMS =
|
|
function(cmsSignature)
|
|
{
|
|
/// <summary>Create a single ArrayBuffer from CMS ECDSA signature</summary>
|
|
/// <param name="cmsSignature" type="in_window.org.pkijs.asn1.SEQUENCE">ASN.1 SEQUENCE contains CMS ECDSA signature</param>
|
|
|
|
// #region Initial variables
|
|
var length = 0;
|
|
|
|
var r_start = 0;
|
|
var s_start = 0;
|
|
|
|
var r_length = cmsSignature.value_block.value[0].value_block.value_hex.byteLength;
|
|
var s_length = cmsSignature.value_block.value[1].value_block.value_hex.byteLength;
|
|
// #endregion
|
|
|
|
// #region Get length of final "ArrayBuffer"
|
|
var r_view = new Uint8Array(cmsSignature.value_block.value[0].value_block.value_hex);
|
|
if((r_view[0] === 0x00) && (r_view[1] & 0x80))
|
|
{
|
|
length = r_length - 1;
|
|
r_start = 1;
|
|
}
|
|
else
|
|
length = r_length;
|
|
|
|
var s_view = new Uint8Array(cmsSignature.value_block.value[1].value_block.value_hex);
|
|
if((s_view[0] === 0x00) && (s_view[1] & 0x80))
|
|
{
|
|
length += s_length - 1;
|
|
s_start = 1;
|
|
}
|
|
else
|
|
length += s_length;
|
|
// #endregion
|
|
|
|
// #region Copy values from CMS ECDSA signature
|
|
var result = new ArrayBuffer(length);
|
|
var result_view = new Uint8Array(result);
|
|
|
|
for(var i = r_start; i < r_length; i++)
|
|
result_view[i - r_start] = r_view[i];
|
|
|
|
for(var i = s_start; i < s_length; i++)
|
|
result_view[i - s_start + r_length - r_start] = s_view[i];
|
|
// #endregion
|
|
|
|
return result;
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.getEncryptionAlgorithm =
|
|
function(algorithm)
|
|
{
|
|
/// <summary>Get encryption algorithm OID by WebCrypto algorithm's object</summary>
|
|
/// <param name="algorithm" type="WebCryptoAlgorithm">WebCrypto algorithm object</param>
|
|
|
|
var result = "";
|
|
|
|
switch(algorithm.name.toUpperCase())
|
|
{
|
|
case "AES-CBC":
|
|
switch(algorithm.length)
|
|
{
|
|
case 128:
|
|
result = "2.16.840.1.101.3.4.1.2";
|
|
break;
|
|
case 192:
|
|
result = "2.16.840.1.101.3.4.1.22";
|
|
break;
|
|
case 256:
|
|
result = "2.16.840.1.101.3.4.1.42";
|
|
break;
|
|
default:
|
|
}
|
|
break;
|
|
case "AES-GCM":
|
|
switch(algorithm.length)
|
|
{
|
|
case 128:
|
|
result = "2.16.840.1.101.3.4.1.6";
|
|
break;
|
|
case 192:
|
|
result = "2.16.840.1.101.3.4.1.26";
|
|
break;
|
|
case 256:
|
|
result = "2.16.840.1.101.3.4.1.46";
|
|
break;
|
|
default:
|
|
}
|
|
break;
|
|
default:
|
|
}
|
|
|
|
return result;
|
|
};
|
|
//**************************************************************************************
|
|
in_window.org.pkijs.getAlgorithmByEncryptionOID =
|
|
function(oid)
|
|
{
|
|
/// <summary>Get encryption algorithm name by OID</summary>
|
|
/// <param name="oid" type="String">OID of encryption algorithm</param>
|
|
|
|
var result = "";
|
|
|
|
switch(oid)
|
|
{
|
|
case "2.16.840.1.101.3.4.1.2":
|
|
case "2.16.840.1.101.3.4.1.22":
|
|
case "2.16.840.1.101.3.4.1.42":
|
|
result = "AES-CBC";
|
|
break;
|
|
case "2.16.840.1.101.3.4.1.6":
|
|
case "2.16.840.1.101.3.4.1.26":
|
|
case "2.16.840.1.101.3.4.1.46":
|
|
result = "AES-GCM";
|
|
break;
|
|
default:
|
|
}
|
|
|
|
return result;
|
|
};
|
|
//**************************************************************************************
|
|
// #endregion
|
|
//**************************************************************************************
|
|
}
|
|
)(typeof exports !== "undefined" ? exports : window); |