pkijs
Version:
Public Key Infrastructure (PKI) is the basis of how identity and key management is performed on the web today. PKIjs is a pure JavaScript library implementing the formats that are used in PKI applications. It is built on WebCrypto and aspires to make it p
1,153 lines (1,064 loc) • 265 kB
JavaScript
/*
* Copyright (c) 2014, GMO GlobalSign
* All rights reserved.
*
* Author 2014, 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 "org.pkijs.simpl" namespace
if(typeof in_window.org.pkijs.simpl === "undefined")
in_window.org.pkijs.simpl = {};
else
{
if(typeof in_window.org.pkijs.simpl !== "object")
throw new Error("Name org.pkijs.simpl already exists and it's not an object" + " but " + (typeof in_window.org.pkijs.simpl));
}
// #endregion
// #region "org.pkijs.simpl.x509" namespace
if(typeof in_window.org.pkijs.simpl.x509 === "undefined")
in_window.org.pkijs.simpl.x509 = {};
else
{
if(typeof in_window.org.pkijs.simpl.x509 !== "object")
throw new Error("Name org.pkijs.simpl.x509 already exists and it's not an object" + " but " + (typeof in_window.org.pkijs.simpl.x509));
}
// #endregion
// #region "local" namespace
var local = {};
// #endregion
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "Time" type
//**************************************************************************************
in_window.org.pkijs.simpl.TIME =
function()
{
// #region Internal properties of the object
this.type = 0; // 0 - UTCTime; 1 - GeneralizedTime; 2 - empty value
this.value = new Date(0, 0, 0);
// #endregion
// #region If input argument array contains "schema" for this object
if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
in_window.org.pkijs.simpl.TIME.prototype.fromSchema.call(this, arguments[0].schema);
// #endregion
// #region If input argument array contains "native" values for internal properties
else
{
if(arguments[0] instanceof Object)
{
this.type = (arguments[0].type || 0);
this.value = (arguments[0].value || (new Date(0, 0, 0)));
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.TIME.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.TIME({
names: {
utcTimeName: "utcTimeName",
generalTimeName: "generalTimeName"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for TIME");
// #endregion
// #region Get internal properties from parsed schema
if("utcTimeName" in asn1.result)
{
this.type = 0;
this.value = asn1.result.utcTimeName.toDate();
}
if("generalTimeName" in asn1.result)
{
this.type = 1;
this.value = asn1.result.generalTimeName.toDate();
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.TIME.prototype.toSchema =
function()
{
// #region Construct and return new ASN.1 schema for this object
var result = {};
if(this.type === 0)
result = new in_window.org.pkijs.asn1.UTCTIME({ value_date: this.value });
if(this.type === 1)
result = new in_window.org.pkijs.asn1.GENERALIZEDTIME({ value_date: this.value });
return result;
// #endregion
}
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "GeneralName" type
//**************************************************************************************
in_window.org.pkijs.simpl.GENERAL_NAME =
function()
{
// #region Internal properties of the object
this.NameType = 9; // Name type - from a tagged value (0 for "otherName", 1 for "rfc822Name" etc.)
this.Name = {};
// #endregion
// #region If input argument array contains "schema" for this object
if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
in_window.org.pkijs.simpl.GENERAL_NAME.prototype.fromSchema.call(this, arguments[0].schema);
// #endregion
// #region If input argument array contains "native" values for internal properties
else
{
if(arguments[0] instanceof Object)
{
this.NameType = arguments[0].NameType || 9;
this.Name = arguments[0].Name || {};
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.GENERAL_NAME.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.GENERAL_NAME({
names: {
block_name: "block_name",
otherName: "otherName",
rfc822Name: "rfc822Name",
dNSName: "dNSName",
x400Address: "x400Address",
directoryName: {
names: {
block_name: "directoryName"
}
},
ediPartyName: "ediPartyName",
uniformResourceIdentifier: "uniformResourceIdentifier",
iPAddress: "iPAddress",
registeredID: "registeredID"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for GENERAL_NAME");
// #endregion
// #region Get internal properties from parsed schema
this.NameType = asn1.result["block_name"].id_block.tag_number;
switch(this.NameType)
{
case 0: // otherName
this.Name = asn1.result["block_name"];
break;
case 1: // rfc822Name + dNSName + uniformResourceIdentifier
case 2:
case 6:
{
var value = asn1.result["block_name"];
value.id_block.tag_class = 1; // UNIVERSAL
value.id_block.tag_number = 22; // IA5STRING
var value_ber = value.toBER(false);
this.Name = in_window.org.pkijs.fromBER(value_ber).result.value_block.value;
}
break;
case 3: // x400Address
this.Name = asn1.result["block_name"];
break;
case 4: // directoryName
this.Name = new in_window.org.pkijs.simpl.RDN({ schema: asn1.result["directoryName"] });
break;
case 5: // ediPartyName
this.Name = asn1.result["ediPartyName"];
break;
case 7: // iPAddress
this.Name = in_window.org.pkijs.asn1.OCTETSTRING({ value_hex: asn1.result["block_name"].value_block.value_hex });
break;
case 8: // registeredID
{
var value = asn1.result["block_name"];
value.id_block.tag_class = 1; // UNIVERSAL
value.id_block.tag_number = 6; // OID
var value_ber = value.toBER(false);
this.Name = in_window.org.pkijs.fromBER(value_ber).result.value_block.toString(); // Getting a string representation of the OID
}
break;
default:;
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.GENERAL_NAME.prototype.toSchema =
function(schema)
{
// #region Construct and return new ASN.1 schema for this object
switch(this.NameType)
{
case 0:
case 3:
case 5:
return new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
id_block: {
tag_class: 3, // CONTEXT-SPECIFIC
tag_number: this.NameType
},
value: [
this.Name
]
});
break;
case 1:
case 2:
case 6:
{
var value = new in_window.org.pkijs.asn1.IA5STRING({ value: this.Name });
value.id_block.tag_class = 3;
value.id_block.tag_number = this.NameType;
return value;
}
break;
case 4:
return new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
id_block: {
tag_class: 3, // CONTEXT-SPECIFIC
tag_number: 4
},
value: [this.Name.toSchema()]
});
break;
case 7:
{
var value = this.Name;
value.id_block.tag_class = 3;
value.id_block.tag_number = this.NameType;
return value;
}
break;
case 8:
{
var value = new in_window.org.pkijs.asn1.OID({ value: this.Name });
value.id_block.tag_class = 3;
value.id_block.tag_number = this.NameType;
return value;
}
break;
default:
return in_window.org.pkijs.schema.GENERAL_NAME();
}
// #endregion
}
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "GeneralNames" type
//**************************************************************************************
in_window.org.pkijs.simpl.GENERAL_NAMES =
function()
{
// #region Internal properties of the object
this.names = new Array(); // Array of "org.pkijs.simpl.GENERAL_NAME"
// #endregion
// #region If input argument array contains "schema" for this object
if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
in_window.org.pkijs.simpl.GENERAL_NAMES.prototype.fromSchema.call(this, arguments[0].schema);
// #endregion
// #region If input argument array contains "native" values for internal properties
else
{
if(arguments[0] instanceof Object)
{
this.names = arguments[0].names || new Array(); // Array of "org.pkijs.simpl.GENERAL_NAME"
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.GENERAL_NAMES.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
new in_window.org.pkijs.asn1.SEQUENCE({
value: [
in_window.org.pkijs.asn1.REPEATED({
name: "names",
value: n_window.org.pkijs.schema.GENERAL_NAME()
})
]
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for GENERAL_NAMES");
// #endregion
// #region Get internal properties from parsed schema
var n = asn1.result["names"];
for(var i = 0; i < n.length; i++)
this.names.push(new in_window.org.pkijs.simpl.GENERAL_NAME({ schema: n[i] }));
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.GENERAL_NAMES.prototype.toSchema =
function(schema)
{
// #region Construct and return new ASN.1 schema for this object
var output_array = new Array();
for(var i = 0; i < this.names.length; i++)
output_array.push(this.names[i].toSchema());
return (new in_window.org.pkijs.asn1.SEQUENCE({
value: output_array
}));
// #endregion
}
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "AlgorithmIdentifier" type
//**************************************************************************************
in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER =
function()
{
// #region Internal properties of the object
this.algorithm_id = "";
// OPTIONAL this.algorithm_params = new in_window.org.pkijs.asn1.NULL();
// #endregion
// #region If input argument array contains "schema" for this object
if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER.prototype.fromSchema.call(this, arguments[0].schema);
// #endregion
// #region If input argument array contains "native" values for internal properties
else
{
if(arguments[0] instanceof Object)
{
this.algorithm_id = arguments[0].algorithm_id || "";
if("algorithm_params" in arguments[0])
this.algorithm_params = arguments[0].algorithm_params;
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.ALGORITHM_IDENTIFIER({
names: {
algorithmIdentifier: "algorithm",
algorithmParams: "params"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for ALGORITHM_IDENTIFIER");
// #endregion
// #region Get internal properties from parsed schema
this.algorithm_id = asn1.result.algorithm.value_block.toString();
if("params" in asn1.result)
this.algorithm_params = asn1.result.params;
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER.prototype.toSchema =
function()
{
// #region Create array for output sequence
var output_array = new Array();
output_array.push(new in_window.org.pkijs.asn1.OID({ value: this.algorithm_id }));
if("algorithm_params" in this)
output_array.push(this.algorithm_params);
// #endregion
// #region Construct and return new ASN.1 schema for this object
return (new in_window.org.pkijs.asn1.SEQUENCE({
value: output_array
}));
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER.prototype.getCommonName =
function()
{
}
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "RSAPublicKey" type (RFC3447)
//**************************************************************************************
in_window.org.pkijs.simpl.x509.RSAPublicKey =
function()
{
// #region Internal properties of the object
this.modulus = new in_window.org.pkijs.asn1.INTEGER();
this.publicExponent = new in_window.org.pkijs.asn1.INTEGER();
// #endregion
// #region If input argument array contains "schema" for this object
if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
in_window.org.pkijs.simpl.x509.RSAPublicKey.prototype.fromSchema.call(this, arguments[0].schema);
// #endregion
// #region If input argument array contains "native" values for internal properties
else
{
if(arguments[0] instanceof Object)
{
this.modulus = arguments[0].modulus || new in_window.org.pkijs.asn1.INTEGER();
this.publicExponent = arguments[0].publicExponent || new in_window.org.pkijs.asn1.INTEGER();
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.x509.RSAPublicKey.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.x509.RSAPublicKey({
names: {
modulus: "modulus",
publicExponent: "publicExponent"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for RSAPublicKey");
// #endregion
// #region Get internal properties from parsed schema
this.modulus = asn1.result["modulus"];
this.publicExponent = asn1.result["publicExponent"];
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.x509.RSAPublicKey.prototype.toSchema =
function()
{
// #region Construct and return new ASN.1 schema for this object
return (new in_window.org.pkijs.asn1.SEQUENCE({
value: [
this.modulus,
this.publicExponent
]
}));
// #endregion
}
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "OtherPrimeInfo" type (RFC3447)
//**************************************************************************************
in_window.org.pkijs.simpl.x509.OtherPrimeInfo =
function()
{
// #region Internal properties of the object
this.prime = new in_window.org.pkijs.asn1.INTEGER();
this.exponent = new in_window.org.pkijs.asn1.INTEGER();
this.coefficient = new in_window.org.pkijs.asn1.INTEGER();
// #endregion
// #region If input argument array contains "schema" for this object
if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
in_window.org.pkijs.simpl.x509.OtherPrimeInfo.prototype.fromSchema.call(this, arguments[0].schema);
// #endregion
// #region If input argument array contains "native" values for internal properties
else
{
if(arguments[0] instanceof Object)
{
this.prime = arguments[0].prime || new in_window.org.pkijs.asn1.INTEGER();
this.exponent = arguments[0].exponent || new in_window.org.pkijs.asn1.INTEGER();
this.coefficient = arguments[0].coefficient || new in_window.org.pkijs.asn1.INTEGER();
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.x509.OtherPrimeInfo.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.x509.OtherPrimeInfo({
names: {
prime: "prime",
exponent: "exponent",
coefficient: "coefficient"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for OtherPrimeInfo");
// #endregion
// #region Get internal properties from parsed schema
this.prime = asn1.result["prime"];
this.exponent = asn1.result["exponent"];
this.coefficient = asn1.result["coefficient"];
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.x509.OtherPrimeInfo.prototype.toSchema =
function()
{
// #region Construct and return new ASN.1 schema for this object
return (new in_window.org.pkijs.asn1.SEQUENCE({
value: [
this.prime,
this.exponent,
this.coefficient
]
}));
// #endregion
}
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "RSAPrivateKey" type (RFC3447)
//**************************************************************************************
in_window.org.pkijs.simpl.x509.RSAPrivateKey =
function()
{
// #region Internal properties of the object
this.version = 0;
this.modulus = new in_window.org.pkijs.asn1.INTEGER();
this.publicExponent = new in_window.org.pkijs.asn1.INTEGER();
this.privateExponent = new in_window.org.pkijs.asn1.INTEGER();
this.prime1 = new in_window.org.pkijs.asn1.INTEGER();
this.prime2 = new in_window.org.pkijs.asn1.INTEGER();
this.exponent1 = new in_window.org.pkijs.asn1.INTEGER();
this.exponent2 = new in_window.org.pkijs.asn1.INTEGER();
this.coefficient = new in_window.org.pkijs.asn1.INTEGER();
// OPTIONAL this.otherPrimeInfos = new Array(); // Array of "OtherPrimeInfo"
// #endregion
// #region If input argument array contains "schema" for this object
if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
in_window.org.pkijs.simpl.x509.RSAPrivateKey.prototype.fromSchema.call(this, arguments[0].schema);
// #endregion
// #region If input argument array contains "native" values for internal properties
else
{
if(arguments[0] instanceof Object)
{
this.version = arguments[0].version || 0;
this.modulus = arguments[0].modulus || new in_window.org.pkijs.asn1.INTEGER();
this.publicExponent = arguments[0].publicExponent || new in_window.org.pkijs.asn1.INTEGER();
this.privateExponent = arguments[0].privateExponent || new in_window.org.pkijs.asn1.INTEGER();
this.prime1 = arguments[0].prime1 || new in_window.org.pkijs.asn1.INTEGER();
this.prime2 = arguments[0].prime2 || new in_window.org.pkijs.asn1.INTEGER();
this.exponent1 = arguments[0].exponent1 || new in_window.org.pkijs.asn1.INTEGER();
this.exponent2 = arguments[0].exponent2 || new in_window.org.pkijs.asn1.INTEGER();
this.coefficient = arguments[0].coefficient || new in_window.org.pkijs.asn1.INTEGER();
if("otherPrimeInfos" in arguments[0])
this.otherPrimeInfos = arguments[0].otherPrimeInfos || new Array();
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.x509.RSAPrivateKey.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.x509.RSAPrivateKey({
names: {
version: "version",
modulus: "modulus",
publicExponent: "publicExponent",
privateExponent: "privateExponent",
prime1: "prime1",
prime2: "prime2",
exponent1: "exponent1",
exponent2: "exponent2",
coefficient: "coefficient",
otherPrimeInfos: "otherPrimeInfos"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for RSAPrivateKey");
// #endregion
// #region Get internal properties from parsed schema
this.version = asn1.result["version"].value_block.value_dec;
this.modulus = asn1.result["modulus"];
this.publicExponent = asn1.result["publicExponent"];
this.privateExponent = asn1.result["privateExponent"];
this.prime1 = asn1.result["prime1"];
this.prime2 = asn1.result["prime2"];
this.exponent1 = asn1.result["exponent1"];
this.exponent2 = asn1.result["exponent2"];
this.coefficient = asn1.result["coefficient"];
if("otherPrimeInfos" in asn1.result)
{
var otherPrimeInfos_array = asn1.result["otherPrimeInfos"];
for(var i = 0; i < otherPrimeInfos_array.length; i++)
this.otherPrimeInfos.push(new in_window.org.pkijs.simpl.x509.OtherPrimeInfo({ schema: otherPrimeInfos_array[i] }));
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.x509.RSAPrivateKey.prototype.toSchema =
function()
{
// #region Create array for output sequence
var output_array = new Array();
output_array.push(new in_window.org.pkijs.asn1.INTEGER({ value: this.version }));
output_array.push(this.modulus);
output_array.push(this.publicExponent);
output_array.push(this.privateExponent);
output_array.push(this.prime1);
output_array.push(this.prime2);
output_array.push(this.exponent1);
output_array.push(this.exponent2);
output_array.push(this.coefficient);
if("otherPrimeInfos" in this)
{
var otherPrimeInfos_array = new Array();
for(var i = 0; i < this.otherPrimeInfos.length; i++)
otherPrimeInfos_array.push(this.otherPrimeInfos[i].toSchema());
output_array.push(new in_window.org.pkijs.asn1.SEQUENCE({ value: otherPrimeInfos_array }));
}
// #endregion
// #region Construct and return new ASN.1 schema for this object
return (new in_window.org.pkijs.asn1.SEQUENCE({
value: output_array
}));
// #endregion
}
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "SubjectPublicKeyInfo" type
//**************************************************************************************
in_window.org.pkijs.simpl.PUBLIC_KEY_INFO =
function()
{
// #region Internal properties of the object
this.algorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER();
this.subjectPublicKey = new in_window.org.pkijs.asn1.BITSTRING();
// #endregion
// #region If input argument array contains "schema" for this object
if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
in_window.org.pkijs.simpl.PUBLIC_KEY_INFO.prototype.fromSchema.call(this, arguments[0].schema);
// #endregion
// #region If input argument array contains "native" values for internal properties
else
{
if(arguments[0] instanceof Object)
{
this.algorithm = (arguments[0].algorithm || (new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER()));
this.subjectPublicKey = (arguments[0].subjectPublicKey || (new in_window.org.pkijs.asn1.BITSTRING()));
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.PUBLIC_KEY_INFO.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.PUBLIC_KEY_INFO({
names: {
algorithm: {
names: {
block_name: "algorithm"
}
},
subjectPublicKey: "subjectPublicKey"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for PUBLIC_KEY_INFO");
// #endregion
// #region Get internal properties from parsed schema
this.algorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({ schema: asn1.result.algorithm });
this.subjectPublicKey = asn1.result.subjectPublicKey;
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.PUBLIC_KEY_INFO.prototype.toSchema =
function()
{
// #region Construct and return new ASN.1 schema for this object
return (new in_window.org.pkijs.asn1.SEQUENCE({
value: [
this.algorithm.toSchema(),
this.subjectPublicKey
]
}));
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.PUBLIC_KEY_INFO.prototype.importKey =
function(publicKey)
{
/// <param name="publicKey" type="Key">Public key to work with</param>
// #region Initial variables
var sequence = Promise.resolve();
var _this = this;
// #endregion
// #region Initial check
if(typeof publicKey === "undefined")
return new Promise(function(resolve, reject) { reject("Need to provide publicKey input parameter"); });
// #endregion
// #region Get a "crypto" extension
var crypto = in_window.org.pkijs.getCrypto();
if(typeof crypto == "undefined")
return new Promise(function(resolve, reject) { reject("Unable to create WebCrypto object"); });
// #endregion
// #region Export public key
sequence = sequence.then(
function()
{
return crypto.exportKey("spki", publicKey);
}
);
// #endregion
// #region Initialize internal variables by parsing exported value
sequence = sequence.then(
function(exportedKey)
{
var asn1 = in_window.org.pkijs.fromBER(exportedKey);
try
{
in_window.org.pkijs.simpl.PUBLIC_KEY_INFO.prototype.fromSchema.call(_this, asn1.result);
}
catch(exception)
{
return new Promise(function(resolve, reject) { reject("Error during initializing object from schema"); });
}
},
function(error)
{
return new Promise(function(resolve, reject) { reject("Error during exporting public key: " + error); });
}
);
// #endregion
return sequence;
}
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "AttributeTypeAndValue" type (part of RelativeDistinguishedName)
//**************************************************************************************
in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE =
function()
{
// #region Internal properties of the object
this.type = "";
this.value = {};
// #endregion
// #region If input argument array contains "schema" for this object
if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE.prototype.fromSchema.call(this, arguments[0].schema);
// #endregion
// #region If input argument array contains "native" values for internal properties
else
{
if(arguments[0] instanceof Object)
{
this.type = (arguments[0].type || "");
this.value = (arguments[0].value || {});
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.ATTR_TYPE_AND_VALUE({
names: {
type: "type",
value: "typeValue"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for ATTR_TYPE_AND_VALUE");
// #endregion
// #region Get internal properties from parsed schema
this.type = asn1.result.type.value_block.toString();
this.value = asn1.result.typeValue;
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE.prototype.toSchema =
function()
{
// #region Construct and return new ASN.1 schema for this object
return (new in_window.org.pkijs.asn1.SEQUENCE({
value: [
new in_window.org.pkijs.asn1.OID({ value: this.type }),
this.value
]
}));
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE.prototype.isEqual =
function()
{
if(arguments[0] instanceof in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE)
{
if(this.type !== arguments[0].type)
return false;
if(((this.value instanceof in_window.org.pkijs.asn1.UTF8STRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.UTF8STRING)) ||
((this.value instanceof in_window.org.pkijs.asn1.BMPSTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.BMPSTRING)) ||
((this.value instanceof in_window.org.pkijs.asn1.UNIVERSALSTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.UNIVERSALSTRING)) ||
((this.value instanceof in_window.org.pkijs.asn1.NUMERICSTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.NUMERICSTRING)) ||
((this.value instanceof in_window.org.pkijs.asn1.PRINTABLESTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.PRINTABLESTRING)) ||
((this.value instanceof in_window.org.pkijs.asn1.TELETEXSTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.TELETEXSTRING)) ||
((this.value instanceof in_window.org.pkijs.asn1.VIDEOTEXSTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.VIDEOTEXSTRING)) ||
((this.value instanceof in_window.org.pkijs.asn1.IA5STRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.IA5STRING)) ||
((this.value instanceof in_window.org.pkijs.asn1.GRAPHICSTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.GRAPHICSTRING)) ||
((this.value instanceof in_window.org.pkijs.asn1.VISIBLESTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.VISIBLESTRING)) ||
((this.value instanceof in_window.org.pkijs.asn1.GENERALSTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.GENERALSTRING)) ||
((this.value instanceof in_window.org.pkijs.asn1.CHARACTERSTRING) && (arguments[0].value instanceof in_window.org.pkijs.asn1.CHARACTERSTRING)))
{
var value1 = in_window.org.pkijs.stringPrep(this.value.value_block.value);
var value2 = in_window.org.pkijs.stringPrep(arguments[0].value.value_block.value);
if(value1.localeCompare(value2) !== 0)
return false;
}
else // Comparing as two ArrayBuffers
{
if(in_window.org.pkijs.isEqual_buffer(this.value.value_before_decode, arguments[0].value.value_before_decode) === false)
return false;
}
return true;
}
else
return false;
}
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "RelativeDistinguishedName" type
//**************************************************************************************
in_window.org.pkijs.simpl.RDN =
function()
{
// #region Internal properties of the object
/// <field name="types_and_values" type="Array" elementType="in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE">Array of "type and value" objects</field>
this.types_and_values = new Array();
/// <field name="value_before_decode" type="ArrayBuffer">Value of the RDN before decoding from schema</field>
this.value_before_decode = new ArrayBuffer(0);
// #endregion
// #region If input argument array contains "schema" for this object
if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
in_window.org.pkijs.simpl.RDN.prototype.fromSchema.call(this, arguments[0].schema);
// #endregion
// #region If input argument array contains "native" values for internal properties
else
{
if(arguments[0] instanceof Object)
{
this.types_and_values = (arguments[0].types_and_values || (new Array()));
this.value_before_decode = arguments[0].value_before_decode || new ArrayBuffer(0);
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.RDN.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.RDN({
names: {
block_name: "RDN",
repeated_set: "types_and_values"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for RDN");
// #endregion
// #region Get internal properties from parsed schema
if("types_and_values" in asn1.result) // Could be a case when there is no "types and values"
{
var types_and_values_array = asn1.result.types_and_values;
for(var i = 0; i < types_and_values_array.length; i++)
this.types_and_values.push(new in_window.org.pkijs.simpl.ATTR_TYPE_AND_VALUE({ schema: types_and_values_array[i] }));
}
this.value_before_decode = asn1.result.RDN.value_before_decode;
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.RDN.prototype.toSchema =
function()
{
// #region Decode stored TBS value
if(this.value_before_decode.byteLength === 0) // No stored encoded array, create "from scratch"
{
// #region Create array for output set
var output_array = new Array();
for(var i = 0; i < this.types_and_values.length; i++)
output_array.push(this.types_and_values[i].toSchema());
// #endregion
return (new in_window.org.pkijs.asn1.SEQUENCE({
value: [new in_window.org.pkijs.asn1.SET({ value: output_array })]
}));
}
var asn1 = in_window.org.pkijs.fromBER(this.value_before_decode);
// #endregion
// #region Construct and return new ASN.1 schema for this object
return asn1.result;
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.RDN.prototype.isEqual =
function()
{
if(arguments[0] instanceof in_window.org.pkijs.simpl.RDN)
{
if(this.types_and_values.length != arguments[0].types_and_values.length)
return false;
for(var i = 0; i < this.types_and_values.length; i++)
{
if(this.types_and_values[i].isEqual(arguments[0].types_and_values[i]) === false)
return false;
}
return true;
}
else
{
if(arguments[0] instanceof ArrayBuffer)
return in_window.org.pkijs.isEqual_buffer(this.value_before_decode, arguments[0]);
else
return false;
}
return false;
}
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "AuthorityKeyIdentifier" type of extension
//**************************************************************************************
in_window.org.pkijs.simpl.x509.AuthorityKeyIdentifier =
function()
{
// #region Internal properties of the object
// OPTIONAL this.keyIdentifier - OCTETSTRING
// OPTIONAL this.authorityCertIssuer - Array of GeneralName
// OPTIONAL this.authorityCertSerialNumber - INTEGER
// #endregion
// #region If input argument array contains "schema" for this object
if((arguments[0] instanceof Object) && ("schema" in arguments[0]))
in_window.org.pkijs.simpl.x509.AuthorityKeyIdentifier.prototype.fromSchema.call(this, arguments[0].schema);
// #endregion
// #region If input argument array contains "native" values for internal properties
else
{
if(arguments[0] instanceof Object)
{
if("keyIdentifier" in arguments[0])
this.keyIdentifier = arguments[0].keyIdentifier;
if("authorityCertIssuer" in arguments[0])
this.authorityCertIssuer = arguments[0].authorityCertIssuer;
if("authorityCertSerialNumber" in arguments[0])
this.authorityCertSerialNumber = arguments[0].authorityCertSerialNumber;
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.x509.AuthorityKeyIdentifier.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.x509.AuthorityKeyIdentifier({
names: {
keyIdentifier: "keyIdentifier",
authorityCertIssuer: "authorityCertIssuer",
authorityCertSerialNumber: "authorityCertSerialNumber"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for AuthorityKeyIdentifier");
// #endregion
// #region Get internal properties from parsed schema
if("keyIdentifier" in asn1.result)
{
asn1.result["keyIdentifier"].id_block.tag_class = 1; // UNIVERSAL
asn1.result["keyIdentifier"].id_block.tag_number = 4; // OCTETSTRING
this.keyIdentifier = asn1.result["keyIdentifier"];
}
if("authorityCertIssuer" in asn1.result)
{
this.authorityCertIssuer = new Array();
var issuer_array = asn1.result["authorityCertIssuer"];
for(var i = 0; i < issuer_array.length; i++)
this.authorityCertIssuer.push(new in_window.org.pkijs.simpl.GENERAL_NAME({ schema: issuer_array[i] }));
}