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,143 lines (1,034 loc) • 99.1 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.ocsp" namespace
if(typeof in_window.org.pkijs.simpl.ocsp === "undefined")
in_window.org.pkijs.simpl.ocsp = {};
else
{
if(typeof in_window.org.pkijs.simpl.ocsp !== "object")
throw new Error("Name org.pkijs.simpl.ocsp already exists and it's not an object" + " but " + (typeof in_window.org.pkijs.simpl.ocsp));
}
// #endregion
// #region "org.pkijs.simpl.tsp" namespace
if(typeof in_window.org.pkijs.simpl.tsp === "undefined")
in_window.org.pkijs.simpl.tsp = {};
else
{
if(typeof in_window.org.pkijs.simpl.tsp !== "object")
throw new Error("Name org.pkijs.simpl.tsp already exists and it's not an object" + " but " + (typeof in_window.org.pkijs.simpl.tsp));
}
// #endregion
// #region "local" namespace
var local = {};
// #endregion
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "CertID" type
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.CertID =
function()
{
// #region Internal properties of the object
this.hashAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER();
this.issuerNameHash = new in_window.org.pkijs.asn1.OCTETSTRING();
this.issuerKeyHash = new in_window.org.pkijs.asn1.OCTETSTRING();
this.serialNumber = 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.ocsp.CertID.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.hashAlgorithm = arguments[0].hashAlgorithm || new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER();
this.issuerNameHash = arguments[0].issuerNameHash || new in_window.org.pkijs.asn1.OCTETSTRING();
this.issuerKeyHash = arguments[0].issuerKeyHash || new in_window.org.pkijs.asn1.OCTETSTRING();
this.serialNumber = arguments[0].serialNumber || new in_window.org.pkijs.asn1.INTEGER();
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.CertID.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.ocsp.CertID({
names: {
hashAlgorithm: "hashAlgorithm",
issuerNameHash: "issuerNameHash",
issuerKeyHash: "issuerKeyHash",
serialNumber: "serialNumber"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for CertID");
// #endregion
// #region Get internal properties from parsed schema
this.hashAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({ schema: asn1.result["hashAlgorithm"] });
this.issuerNameHash = asn1.result["issuerNameHash"];
this.issuerKeyHash = asn1.result["issuerKeyHash"];
this.serialNumber = asn1.result["serialNumber"];;
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.CertID.prototype.toSchema =
function()
{
// #region Construct and return new ASN.1 schema for this object
return (new in_window.org.pkijs.asn1.SEQUENCE({
value: [
this.hashAlgorithm.toSchema(),
this.issuerNameHash,
this.issuerKeyHash,
this.serialNumber
]
}));
// #endregion
}
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "Request" type
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.Request =
function()
{
// #region Internal properties of the object
this.reqCert = new in_window.org.pkijs.simpl.ocsp.CertID();
// OPTIONAL this.singleRequestExtensions = new Array(); // Array of in_window.org.pkijs.simpl.EXTENSION();
// #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.ocsp.Request.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.reqCert = arguments[0].reqCert || new in_window.org.pkijs.simpl.ocsp.CertID();
if("singleRequestExtensions" in arguments[0])
this.singleRequestExtensions = arguments[0].singleRequestExtensions;
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.Request.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.ocsp.Request({
names: {
reqCert: {
names: {
block_name: "reqCert"
}
},
singleRequestExtensions: {
names: {
block_name: "singleRequestExtensions"
}
}
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for Request");
// #endregion
// #region Get internal properties from parsed schema
this.reqCert = new in_window.org.pkijs.simpl.ocsp.CertID({ schema: asn1.result["reqCert"] });
if("singleRequestExtensions" in asn1.result)
{
this.singleRequestExtensions = new Array();
var exts = asn1.result["singleRequestExtensions"].value_block.value;
for(var i = 0; i < exts.length; i++)
this.singleRequestExtensions.push(new in_window.org.pkijs.simpl.EXTENSION({ schema: exts[i] }));
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.Request.prototype.toSchema =
function()
{
// #region Create array for output sequence
var output_array = new Array();
output_array.push(this.reqCert.toSchema());
if("singleRequestExtensions" in this)
{
var extensions = new Array();
for(var j = 0; j < this.singleRequestExtensions.length; j++)
extensions.push(this.singleRequestExtensions[j].toSchema());
output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
optional: true,
id_block: {
tag_class: 3, // CONTEXT-SPECIFIC
tag_number: 0 // [0]
},
value: [
new in_window.org.pkijs.asn1.SEQUENCE({
value: extensions
})
]
}));
}
// #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 "TBSRequest" type
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.TBSRequest =
function()
{
// #region Internal properties of the object
this.tbs = new ArrayBuffer(0); // Value of TBS part before decode
// OPTIONAL this.version = 0;
// OPTIONAL this.requestorName = new in_window.org.pkijs.simpl.GENERAL_NAME();
this.requestList = new Array(); // Array of "Request" objects
// OPTIONAL this.requestExtensions = new Array(); // Array of in_window.org.pkijs.simpl.EXTENSION();
// #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.ocsp.TBSRequest.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.tbs = arguments[0].tbs || new ArrayBuffer(0); // Value of TBS part before decode
if("version" in arguments[0])
this.version = arguments[0].version;
if("requestorName" in arguments[0])
this.requestorName = arguments[0].requestorName;
this.requestList = arguments[0].requestList || new Array(); // Array of "Request" objects
if("requestExtensions" in arguments[0])
this.requestExtensions = arguments[0].requestExtensions;
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.TBSRequest.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.ocsp.TBSRequest()
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for TBSRequest");
// #endregion
// #region Get internal properties from parsed schema
this.tbs = asn1.result["TBSRequest"].value_before_decode;
if("TBSRequest.version" in asn1.result)
this.version = asn1.result["TBSRequest.version"].value_block.value_dec;
if("TBSRequest.requestorName" in asn1.result)
this.requestorName = new in_window.org.pkijs.simpl.GENERAL_NAME({ schema: asn1.result["TBSRequest.requestorName"] });
var requests = asn1.result["TBSRequest.requests"];
for(var i = 0; i < requests.length; i++)
this.requestList.push(new in_window.org.pkijs.simpl.ocsp.Request({ schema: requests[i] }));
if("TBSRequest.requestExtensions" in asn1.result)
{
this.requestExtensions = new Array();
var exts = asn1.result["TBSRequest.requestExtensions"].value_block.value;
for(var i = 0; i < exts.length; i++)
this.requestExtensions.push(new in_window.org.pkijs.simpl.EXTENSION({ schema: exts[i] }));
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.TBSRequest.prototype.toSchema =
function(encodeFlag)
{
/// <param name="encodeFlag" type="Boolean">If param equal to false then create TBS schema via decoding stored value. In othe case create TBS schema via assembling from TBS parts.</param>
// #region Check "encodeFlag"
if(typeof encodeFlag === "undefined")
encodeFlag = false;
// #endregion
// #region Decode stored TBS value
var tbs_schema;
if(encodeFlag === false)
{
if(this.tbs.byteLength === 0) // No stored TBS part
return in_window.org.pkijs.schema.ocsp.TBSRequest();
tbs_schema = in_window.org.pkijs.fromBER(this.tbs).result;
}
// #endregion
// #region Create TBS schema via assembling from TBS parts
else
{
var output_array = new Array();
if("version" in this)
output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
optional: true,
id_block: {
tag_class: 3, // CONTEXT-SPECIFIC
tag_number: 0 // [0]
},
value: [new in_window.org.pkijs.asn1.INTEGER({ value: this.version })]
}));
if("requestorName" in this)
output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
optional: true,
id_block: {
tag_class: 3, // CONTEXT-SPECIFIC
tag_number: 1 // [1]
},
value: [this.requestorName.toSchema()]
}));
var requests = new Array();
for(var i = 0; i < this.requestList.length; i++)
requests.push(this.requestList[i].toSchema());
output_array.push(new in_window.org.pkijs.asn1.SEQUENCE({
value: requests
}));
if("requestExtensions" in this)
{
var extensions = new Array();
for(var j = 0; j < this.requestExtensions.length; j++)
extensions.push(this.requestExtensions[j].toSchema());
output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
optional: true,
id_block: {
tag_class: 3, // CONTEXT-SPECIFIC
tag_number: 2 // [2]
},
value: [
new in_window.org.pkijs.asn1.SEQUENCE({
value: extensions
})
]
}));
}
tbs_schema = new in_window.org.pkijs.asn1.SEQUENCE({
value: output_array
});
}
// #endregion
// #region Construct and return new ASN.1 schema for this object
return tbs_schema;
// #endregion
}
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "Signature" type
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.Signature =
function()
{
// #region Internal properties of the object
this.signatureAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER();
this.signature = new in_window.org.pkijs.asn1.BITSTRING();
// OPTIONAL this.certs = new Array(); // Array of X.509 certificates
// #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.ocsp.Signature.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.signatureAlgorithm = arguments[0].signatureAlgorithm || new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER();
this.signature = arguments[0].signature || new in_window.org.pkijs.asn1.BITSTRING();
if("certs" in arguments[0])
this.certs = arguments[0].certs; // Array of X.509 certificates
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.Signature.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.ocsp.Signature({
names: {
signatureAlgorithm: {
names: {
block_name: "signatureAlgorithm"
}
},
signature: "signature",
certs: "certs"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for ocsp.Signature");
// #endregion
// #region Get internal properties from parsed schema
this.signatureAlgorithm = new in_window.org.pkijs.simpl.ALGORITHM_IDENTIFIER({ schema: asn1.result["signatureAlgorithm"] });
this.signature = asn1.result["signature"];
if("certs" in asn1.result)
{
this.certs = new Array();
var certs_array = asn1.result["certs"];
for(var i = 0; i < certs_array; i++)
this.certs.push(new in_window.org.pkijs.simpl.CERT({ schema: certs_array[i] }));
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.Signature.prototype.toSchema =
function()
{
// #region Create array of output sequence
var output_array = new Array();
output_array.push(this.signatureAlgorithm.toSchema());
output_array.push(this.signature);
if("certs" in this)
{
// #region Create certificate array
var cert_array = new Array();
for(var i = 0; i < this.certs; i++)
cert_array.push(this.certs[i].toSchema());
// #endregion
output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
optional: true,
id_block: {
tag_class: 3, // CONTEXT-SPECIFIC
tag_number: 0 // [0]
},
value: [
new in_window.org.pkijs.asn1.SEQUENCE({
value: cert_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 "OCSP_REQUEST" type
//**************************************************************************************
in_window.org.pkijs.simpl.OCSP_REQUEST =
function()
{
// #region Internal properties of the object
// OPTIONAL this.version = 0;
// OPTIONAL this.requestorName = new in_window.org.pkijs.simpl.GENERAL_NAME();
this.requestList = new Array(); // Array of "Request" objects
// OPTIONAL this.requestExtensions = new Array(); // Array of in_window.org.pkijs.simpl.EXTENSION();
// OPTIONAL this.optionalSignature = new in_window.org.pkijs.simpl.ocsp.Signature();
// #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.OCSP_REQUEST.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.tbsRequest = arguments[0].tbsRequest || new in_window.org.pkijs.simpl.ocsp.TBSRequest();
if("optionalSignature" in arguments[0])
this.optionalSignature = arguments[0].optionalSignature;
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.OCSP_REQUEST.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.OCSP_REQUEST()
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for OCSP_REQUEST");
// #endregion
// #region Get internal properties from parsed schema
if("TBSRequest.version" in asn1.result)
this.version = asn1.result["TBSRequest.version"].value_block.value_dec;
if("TBSRequest.requestorName" in asn1.result)
this.requestorName = new in_window.org.pkijs.simpl.GENERAL_NAME({ schema: asn1.result["TBSRequest.requestorName"] });
var requests = asn1.result["TBSRequest.requests"];
for(var i = 0; i < requests.length; i++)
this.requestList.push(new in_window.org.pkijs.simpl.ocsp.Request({ schema: requests[i] }));
if("TBSRequest.requestExtensions" in asn1.result)
{
this.requestExtensions = new Array();
var exts = asn1.result["TBSRequest.requestExtensions"].value_block.value;
for(var i = 0; i < exts.length; i++)
this.requestExtensions.push(new in_window.org.pkijs.simpl.EXTENSION({ schema: exts[i] }));
}
if("optionalSignature" in asn1.result)
this.optionalSignature = new in_window.org.pkijs.simpl.ocsp.Signature({ schema: asn1.result["optionalSignature"] });
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.OCSP_REQUEST.prototype.toSchema =
function()
{
// #region Create array for output sequence
var output_array = new Array();
// #region Create TBSRequest
var tbs_array = new Array();
if("version" in this)
tbs_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
optional: true,
id_block: {
tag_class: 3, // CONTEXT-SPECIFIC
tag_number: 0 // [0]
},
value: [new in_window.org.pkijs.asn1.INTEGER({ value: this.version })]
}));
if("requestorName" in this)
tbs_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
optional: true,
id_block: {
tag_class: 3, // CONTEXT-SPECIFIC
tag_number: 1 // [1]
},
value: [this.requestorName.toSchema()]
}));
var requests = new Array();
for(var i = 0; i < this.requestList.length; i++)
requests.push(this.requestList[i].toSchema());
tbs_array.push(new in_window.org.pkijs.asn1.SEQUENCE({
value: requests
}));
if("requestExtensions" in this)
{
var extensions = new Array();
for(var j = 0; j < this.requestExtensions.length; j++)
extensions.push(this.requestExtensions[j].toSchema());
tbs_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
optional: true,
id_block: {
tag_class: 3, // CONTEXT-SPECIFIC
tag_number: 2 // [2]
},
value: [
new in_window.org.pkijs.asn1.SEQUENCE({
value: extensions
})
]
}));
}
output_array.push(new in_window.org.pkijs.asn1.SEQUENCE({ value: tbs_array }));
// #endregion
if("optionalSignature" in this)
output_array.push(this.optionalSignature.toSchema());
// #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.OCSP_REQUEST.prototype.sign =
function(privateKey)
{
/// <param name="privateKey" type="Key">Private key for "subjectPublicKeyInfo" structure</param>
// #region Initial variables
var _this = this;
// #endregion
// #region Get a private key from function parameter
if(typeof privateKey === "undefined")
return new Promise(function(resolve, reject) { reject("Need to provide a private key for signing"); });
// #endregion
// #region Check that "optionalSignature" exists in the current request
if(("optionalSignature" in this) === false)
return new Promise(function(resolve, reject) { reject("Need to create \"optionalSignature\" field before signing"); });
// #endregion
// #region Find a correct hashing algorithm
var sha_algorithm = "";
switch(this.optionalSignature.signatureAlgorithm.algorithm_id)
{
case "1.2.840.113549.1.1.5":
sha_algorithm = "sha-1";
break;
case "1.2.840.113549.1.1.11":
sha_algorithm = "sha-256";
break;
case "1.2.840.113549.1.1.12":
sha_algorithm = "sha-384";
break;
case "1.2.840.113549.1.1.13":
sha_algorithm = "sha-512";
break;
default:
return new Promise(function(resolve, reject) { reject("Unsupported signature algorithm: " + this.signature.signatureAlgorithm.algorithm_id); });
};
// #endregion
// #region Create TBS data for signing
var tbs = this.tbsRequest.toSchema(true).toBER(false);
// #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 Signing TBS data on provided private key
return crypto.sign({ name: privateKey.algorithm.name, hash: { name: sha_algorithm } },
privateKey,
new Uint8Array(tbs)).then(
function(result)
{
_this.optionalSignature.signature = new in_window.org.pkijs.asn1.BITSTRING({ value_hex: result });
},
function(error)
{
return new Promise(function(resolve, reject) { reject("Signing error: " + error); });
}
);
// #endregion
}
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "ResponseBytes" type
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.ResponseBytes =
function()
{
// #region Internal properties of the object
this.responseType = "";
this.response = new in_window.org.pkijs.asn1.OCTETSTRING();
// #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.ocsp.ResponseBytes.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.responseType = arguments[0].responseType || "";
this.response = arguments[0].response || new in_window.org.pkijs.asn1.OCTETSTRING();
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.ResponseBytes.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.ocsp.ResponseBytes({
names: {
responseType: "responseType",
response: "response"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for ResponseBytes");
// #endregion
// #region Get internal properties from parsed schema
this.responseType = asn1.result["responseType"].value_block.toString();
this.response = asn1.result["response"];
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.ResponseBytes.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.responseType }),
this.response
]
}));
// #endregion
}
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "OCSP_RESPONSE" type
//**************************************************************************************
in_window.org.pkijs.simpl.OCSP_RESPONSE =
function()
{
// #region Internal properties of the object
this.responseStatus = new in_window.org.pkijs.asn1.ENUMERATED();
// OPTIONAL this.responseBytes = new in_window.org.pkijs.simpl.ocsp.ResponseBytes();
// #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.OCSP_RESPONSE.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.responseStatus = arguments[0].responseStatus || new in_window.org.pkijs.asn1.ENUMERATED();
if("responseBytes" in arguments[0])
this.responseBytes = arguments[0].responseBytes;
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.OCSP_RESPONSE.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.OCSP_RESPONSE()
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for OCSP_RESPONSE");
// #endregion
// #region Get internal properties from parsed schema
this.responseStatus = asn1.result["responseStatus"];
if("responseBytes" in asn1.result)
this.responseBytes = new in_window.org.pkijs.simpl.ocsp.ResponseBytes({ schema: asn1.result["responseBytes"] });
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.OCSP_RESPONSE.prototype.toSchema =
function()
{
// #region Create array for output sequence
var output_array = new Array();
output_array.push(this.responseStatus);
if("responseBytes" in this)
output_array.push(new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
id_block: {
tag_class: 3, // CONTEXT-SPECIFIC
tag_number: 0 // [0]
},
value: [this.responseBytes.toSchema()]
}));
// #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.OCSP_RESPONSE.prototype.verify =
function()
{
/// <summary>!!! Works well in Chrome dev versions only (April 2014th) !!!</summary>
/// <returns type="Promise">Returns a new Promise object (in case of error), or a result of "crypto.subtle.veryfy" function</returns>
// #region Check that ResponseBytes exists in the object
if(("responseBytes" in this) === false)
return new Promise(function(resolve, reject) { reject("Empty ResponseBytes field"); });
// #endregion
// #region Check that ResponceData has type BasicOCSPResponse and verify it
if(this.responseBytes.responseType === "1.3.6.1.5.5.7.48.1.1")
{
var asn1 = in_window.org.pkijs.fromBER(this.responseBytes.response.value_block.value_hex);
var basic_resp_simpl = new in_window.org.pkijs.simpl.OCSP_BASIC_RESPONSE({ schema: asn1.result });
return basic_resp_simpl.verify();
}
else
return new Promise(function(resolve, reject) { reject("Unknown ResponseBytes type: " + this.responseBytes.responseType); });
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.OCSP_RESPONSE.prototype.sign =
function(privateKey)
{
/// <param name="privateKey" type="Key">Private key for "subjectPublicKeyInfo" structure</param>
// #region Check that ResponceData has type BasicOCSPResponse and verify it
if(this.responseBytes.responseType === "1.3.6.1.5.5.7.48.1.1")
{
var asn1 = in_window.org.pkijs.fromBER(this.responseBytes.response.value_block.value_hex);
var basic_resp_simpl = new in_window.org.pkijs.simpl.OCSP_BASIC_RESPONSE({ schema: asn1.result });
return basic_resp_simpl.sign(privateKey);
}
else
return new Promise(function(resolve, reject) { reject("Unknown ResponseBytes type: " + this.responseBytes.responseType); });
// #endregion
}
//**************************************************************************************
// #endregion
//**************************************************************************************
// #region Simplified structure for "SingleResponse" type
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.SingleResponse =
function()
{
// #region Internal properties of the object
this.certID = new in_window.org.pkijs.simpl.ocsp.CertID();
this.certStatus = new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
id_block: {
tag_class: 3, // CONTEXT-SPECIFIC
tag_number: 3 // [3]
},
value: []
}); // Fiction value
this.thisUpdate = new Date(0, 0, 0);
// OPTIONAL this.nextUpdate = new Date(0, 0, 0);
// OPTIONAL this.singleExtensions = new Array(); // Array of in_window.org.pkijs.simpl.EXTENSION();
// #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.ocsp.SingleResponse.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.certID = arguments[0].certID || new in_window.org.pkijs.simpl.ocsp.CertID();
this.certStatus = arguments[0].certStatus || new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
id_block: {
tag_class: 3, // CONTEXT-SPECIFIC
tag_number: 3 // [3]
},
value: []
}); // Fiction value
this.thisUpdate = arguments[0].thisUpdate || new Date(0, 0, 0);
if("nextUpdate" in arguments[0])
this.nextUpdate = arguments[0].nextUpdate;
if("singleExtensions" in arguments[0])
this.singleExtensions = arguments[0].singleExtensions;
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.SingleResponse.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.ocsp.SingleResponse({
names: {
certID: {
names: {
block_name: "certID"
}
},
certStatus: "certStatus",
thisUpdate: "thisUpdate",
nextUpdate: "nextUpdate",
singleExtensions: "singleExtensions"
}
})
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for SingleResponse");
// #endregion
// #region Get internal properties from parsed schema
this.certID = new in_window.org.pkijs.simpl.ocsp.CertID({ schema: asn1.result["certID"] });
this.certStatus = asn1.result["certStatus"];
this.thisUpdate = asn1.result["thisUpdate"].toDate();
if("nextUpdate" in asn1.result)
this.nextUpdate = asn1.result["nextUpdate"].toDate();
if("singleExtensions" in asn1.result)
{
this.singleExtensions = new Array();
var exts = asn1.result["singleExtensions"].value_block.value;
for(var i = 0; i < exts.length; i++)
this.singleExtensions.push(new in_window.org.pkijs.simpl.EXTENSION({ schema: exts[i] }));
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.SingleResponse.prototype.toSchema =
function()
{
// #region Create value array for output sequence
var output_array = new Array();
output_array.push(this.certID.toSchema());
output_array.push(this.certStatus);
output_array.push(new in_window.org.pkijs.asn1.GENERALIZEDTIME({ value_date: this.thisUpdate }));
if("nextUpdate" in this)
output_array.push(new in_window.org.pkijs.asn1.GENERALIZEDTIME({ value_date: this.nextUpdate }));
if("singleExtensions" in this)
{
var extensions = new Array();
for(var j = 0; j < this.singleExtensions.length; j++)
extensions.push(this.singleExtensions[j].toSchema());
output_array.push(new in_window.org.pkijs.asn1.SEQUENCE({
value: extensions
}));
}
// #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 "ResponseData" type
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.ResponseData =
function()
{
// #region Internal properties of the object
this.tbs = new ArrayBuffer(0);
// OPTIONAL this.version = 0;
this.responderID = new in_window.org.pkijs.simpl.RDN(); // Fake value
this.producedAt = new Date(0, 0, 0);
this.responses = new Array(); // Array of "SingleResponse" objects
// OPTIONAL this.responseExtensions = new Array(); // Array of in_window.org.pkijs.simpl.EXTENSION();
// #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.ocsp.ResponseData.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("version" in arguments[0])
this.version = arguments[0].version;
this.responderID = arguments[0].responderID || new in_window.org.pkijs.asn1.ASN1_CONSTRUCTED({
id_block: {
tag_class: 3, // CONTEXT-SPECIFIC
tag_number: 10 // [10]
},
value: []
}); // Fake value
this.producedAt = arguments[0].producedAt || new Date(0, 0, 0);
this.responses = arguments[0].responses || new Array(); // Array of "SingleResponse" objects
if("responseExtensions" in arguments[0])
this.responseExtensions = arguments[0].responseExtensions;
}
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.ResponseData.prototype.fromSchema =
function(schema)
{
// #region Check the schema is valid
var asn1 = in_window.org.pkijs.compareSchema(schema,
schema,
in_window.org.pkijs.schema.ocsp.ResponseData()
);
if(asn1.verified === false)
throw new Error("Object's schema was not verified against input data for ocsp.ResponseData");
// #endregion
// #region Get internal properties from parsed schema
this.tbs = asn1.result["ResponseData"].value_before_decode;
if("ResponseData.version" in asn1.result)
this.version = asn1.result["ResponseData.version"].value_block.value_dec;
if(asn1.result["ResponseData.responderID"].id_block.tag_number === 1)
this.responderID = new in_window.org.pkijs.simpl.RDN({ schema: asn1.result["ResponseData.responderID"].value_block.value[0] });
else
this.responderID = asn1.result["ResponseData.responderID"].value_block.value[0]; // OCTETSTRING
this.producedAt = asn1.result["ResponseData.producedAt"].toDate();
var responses_array = asn1.result["ResponseData.responses"];
for(var i = 0; i < responses_array.length; i++)
this.responses.push(new in_window.org.pkijs.simpl.ocsp.SingleResponse({ schema: responses_array[i] }));
if("ResponseData.responseExtensions" in asn1.result)
{
this.responseExtensions = new Array();
var exts = asn1.result["ResponseData.responseExtensions"].value_block.value;
for(var i = 0; i < exts.length; i++)
this.responseExtensions.push(new in_window.org.pkijs.simpl.EXTENSION({ schema: exts[i] }));
}
// #endregion
}
//**************************************************************************************
in_window.org.pkijs.simpl.ocsp.ResponseData.prototype.toSchema =
function(encodeFlag)
{
/// <param name="encodeFlag" type="Boolean">If param equal to false then create TBS schema via decoding sto