/*! asn1x509-1.0.9.js (c) 2013-2014 Kenji Urushima | kjur.github.com/jsrsasign/license
*/
/*
* asn1x509.js - ASN.1 DER encoder classes for X.509 certificate
*
* Copyright (c) 2013-2014 Kenji Urushima (kenji.urushima@gmail.com)
*
* This software is licensed under the terms of the MIT License.
* http://kjur.github.com/jsrsasign/license
*
* The above copyright and license notice shall be
* included in all copies or substantial portions of the Software.
*/
/**
* @fileOverview
* @name asn1x509-1.0.js
* @author Kenji Urushima kenji.urushima@gmail.com
* @version 1.0.9 (2014-May-17)
* @since jsrsasign 2.1
* @license MIT License
*/
/**
* kjur's class library name space
* // already documented in asn1-1.0.js
* @name KJUR
* @namespace kjur's class library name space
*/
if (typeof KJUR == "undefined" || !KJUR) KJUR = {};
/**
* kjur's ASN.1 class library name space
* // already documented in asn1-1.0.js
* @name KJUR.asn1
* @namespace
*/
if (typeof KJUR.asn1 == "undefined" || !KJUR.asn1) KJUR.asn1 = {};
/**
* kjur's ASN.1 class for X.509 certificate library name space
*
*
FEATURES
*
* - easily issue any kind of certificate
* - APIs are very similar to BouncyCastle library ASN.1 classes. So easy to learn.
*
*
* PROVIDED CLASSES
*
* - {@link KJUR.asn1.x509.Certificate}
* - {@link KJUR.asn1.x509.TBSCertificate}
* - {@link KJUR.asn1.x509.Extension}
* - {@link KJUR.asn1.x509.X500Name}
* - {@link KJUR.asn1.x509.RDN}
* - {@link KJUR.asn1.x509.AttributeTypeAndValue}
* - {@link KJUR.asn1.x509.SubjectPublicKeyInfo}
* - {@link KJUR.asn1.x509.AlgorithmIdentifier}
* - {@link KJUR.asn1.x509.GeneralName}
* - {@link KJUR.asn1.x509.GeneralNames}
* - {@link KJUR.asn1.x509.DistributionPointName}
* - {@link KJUR.asn1.x509.DistributionPoint}
* - {@link KJUR.asn1.x509.CRL}
* - {@link KJUR.asn1.x509.TBSCertList}
* - {@link KJUR.asn1.x509.CRLEntry}
* - {@link KJUR.asn1.x509.OID}
*
* SUPPORTED EXTENSIONS
*
* - {@link KJUR.asn1.x509.BasicConstraints}
* - {@link KJUR.asn1.x509.KeyUsage}
* - {@link KJUR.asn1.x509.CRLDistributionPoints}
* - {@link KJUR.asn1.x509.ExtKeyUsage}
* - {@link KJUR.asn1.x509.AuthorityKeyIdentifier}
*
* NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.
* @name KJUR.asn1.x509
* @namespace
*/
if (typeof KJUR.asn1.x509 == "undefined" || !KJUR.asn1.x509) KJUR.asn1.x509 = {};
// === BEGIN Certificate ===================================================
/**
* X.509 Certificate class to sign and generate hex encoded certificate
* @name KJUR.asn1.x509.Certificate
* @class X.509 Certificate class to sign and generate hex encoded certificate
* @param {Array} params associative array of parameters (ex. {'tbscertobj': obj, 'prvkeyobj': key})
* @extends KJUR.asn1.ASN1Object
* @description
*
* As for argument 'params' for constructor, you can specify one of
* following properties:
*
* - tbscertobj - specify {@link KJUR.asn1.x509.TBSCertificate} object
* - prvkeyobj - specify {@link RSAKey}, {@link KJUR.crypto.ECDSA} or {@link KJUR.crypto.DSA} object for CA private key to sign the certificate
* - (DEPRECATED)rsaprvkey - specify {@link RSAKey} object CA private key
* - (DEPRECATED)rsaprvpem - specify PEM string of RSA CA private key
*
* NOTE1: 'params' can be omitted.
* NOTE2: DSA/ECDSA is also supported for CA signging key from asn1x509 1.0.6.
* @example
* var caKey = KEYUTIL.getKey(caKeyPEM); // CA's private key
* var cert = new KJUR.asn1x509.Certificate({'tbscertobj': tbs, 'prvkeyobj': caKey});
* cert.sign(); // issue certificate by CA's private key
* var certPEM = cert.getPEMString();
*
* // Certificate ::= SEQUENCE {
* // tbsCertificate TBSCertificate,
* // signatureAlgorithm AlgorithmIdentifier,
* // signature BIT STRING }
*/
KJUR.asn1.x509.Certificate = function(params) {
KJUR.asn1.x509.Certificate.superclass.constructor.call(this);
var asn1TBSCert = null;
var asn1SignatureAlg = null;
var asn1Sig = null;
var hexSig = null;
var prvKey = null;
var rsaPrvKey = null; // DEPRECATED
/**
* set PKCS#5 encrypted RSA PEM private key as CA key
* @name setRsaPrvKeyByPEMandPass
* @memberOf KJUR.asn1.x509.Certificate
* @function
* @param {String} rsaPEM string of PKCS#5 encrypted RSA PEM private key
* @param {String} passPEM passcode string to decrypt private key
* @since 1.0.1
* @description
*
* EXAMPLES
* @example
* var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs});
* cert.setRsaPrvKeyByPEMandPass("-----BEGIN RSA PRIVATE..(snip)", "password");
*/
this.setRsaPrvKeyByPEMandPass = function(rsaPEM, passPEM) {
var caKeyHex = PKCS5PKEY.getDecryptedKeyHex(rsaPEM, passPEM);
var caKey = new RSAKey();
caKey.readPrivateKeyFromASN1HexString(caKeyHex);
this.prvKey = caKey;
};
/**
* sign TBSCertificate and set signature value internally
* @name sign
* @memberOf KJUR.asn1.x509.Certificate
* @function
* @description
* @example
* var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs, 'rsaprvkey': prvKey});
* cert.sign();
*/
this.sign = function() {
this.asn1SignatureAlg = this.asn1TBSCert.asn1SignatureAlg;
sig = new KJUR.crypto.Signature({'alg': 'SHA1withRSA'});
sig.init(this.prvKey);
sig.updateHex(this.asn1TBSCert.getEncodedHex());
this.hexSig = sig.sign();
this.asn1Sig = new KJUR.asn1.DERBitString({'hex': '00' + this.hexSig});
var seq = new KJUR.asn1.DERSequence({'array': [this.asn1TBSCert,
this.asn1SignatureAlg,
this.asn1Sig]});
this.hTLV = seq.getEncodedHex();
this.isModified = false;
};
/**
* set signature value internally by hex string
* @name setSignatureHex
* @memberOf KJUR.asn1.x509.Certificate
* @function
* @since asn1x509 1.0.8
* @description
* @example
* var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs});
* cert.setSignatureHex('01020304');
*/
this.setSignatureHex = function(sigHex) {
this.asn1SignatureAlg = this.asn1TBSCert.asn1SignatureAlg;
this.hexSig = sigHex;
this.asn1Sig = new KJUR.asn1.DERBitString({'hex': '00' + this.hexSig});
var seq = new KJUR.asn1.DERSequence({'array': [this.asn1TBSCert,
this.asn1SignatureAlg,
this.asn1Sig]});
this.hTLV = seq.getEncodedHex();
this.isModified = false;
};
this.getEncodedHex = function() {
if (this.isModified == false && this.hTLV != null) return this.hTLV;
throw "not signed yet";
};
/**
* get PEM formatted certificate string after signed
* @name getPEMString
* @memberOf KJUR.asn1.x509.Certificate
* @function
* @return PEM formatted string of certificate
* @description
* @example
* var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs, 'rsaprvkey': prvKey});
* cert.sign();
* var sPEM = cert.getPEMString();
*/
this.getPEMString = function() {
var hCert = this.getEncodedHex();
var wCert = CryptoJS.enc.Hex.parse(hCert);
var b64Cert = CryptoJS.enc.Base64.stringify(wCert);
var pemBody = b64Cert.replace(/(.{64})/g, "$1\r\n");
return "-----BEGIN CERTIFICATE-----\r\n" + pemBody + "\r\n-----END CERTIFICATE-----\r\n";
};
if (typeof params != "undefined") {
if (typeof params['tbscertobj'] != "undefined") {
this.asn1TBSCert = params['tbscertobj'];
}
if (typeof params['prvkeyobj'] != "undefined") {
this.prvKey = params['prvkeyobj'];
} else if (typeof params['rsaprvkey'] != "undefined") {
this.prvKey = params['rsaprvkey'];
} else if ((typeof params['rsaprvpem'] != "undefined") &&
(typeof params['rsaprvpas'] != "undefined")) {
this.setRsaPrvKeyByPEMandPass(params['rsaprvpem'], params['rsaprvpas']);
}
}
};
YAHOO.lang.extend(KJUR.asn1.x509.Certificate, KJUR.asn1.ASN1Object);
/**
* ASN.1 TBSCertificate structure class
* @name KJUR.asn1.x509.TBSCertificate
* @class ASN.1 TBSCertificate structure class
* @param {Array} params associative array of parameters (ex. {})
* @extends KJUR.asn1.ASN1Object
* @description
*
* EXAMPLE
* @example
* var o = new KJUR.asn1.x509.TBSCertificate();
* o.setSerialNumberByParam({'int': 4});
* o.setSignatureAlgByParam({'name': 'SHA1withRSA'});
* o.setIssuerByParam({'str': '/C=US/O=a'});
* o.setNotBeforeByParam({'str': '130504235959Z'});
* o.setNotAfterByParam({'str': '140504235959Z'});
* o.setSubjectByParam({'str': '/C=US/CN=b'});
* o.setSubjectPublicKeyByParam({'rsakey': rsaKey});
* o.appendExtension(new KJUR.asn1.x509.BasicConstraints({'cA':true}));
* o.appendExtension(new KJUR.asn1.x509.KeyUsage({'bin':'11'}));
*/
KJUR.asn1.x509.TBSCertificate = function(params) {
KJUR.asn1.x509.TBSCertificate.superclass.constructor.call(this);
this._initialize = function() {
this.asn1Array = new Array();
this.asn1Version =
new KJUR.asn1.DERTaggedObject({'obj': new KJUR.asn1.DERInteger({'int': 2})});
this.asn1SerialNumber = null;
this.asn1SignatureAlg = null;
this.asn1Issuer = null;
this.asn1NotBefore = null;
this.asn1NotAfter = null;
this.asn1Subject = null;
this.asn1SubjPKey = null;
this.extensionsArray = new Array();
};
/**
* set serial number field by parameter
* @name setSerialNumberByParam
* @memberOf KJUR.asn1.x509.TBSCertificate
* @function
* @param {Array} intParam DERInteger param
* @description
* @example
* tbsc.setSerialNumberByParam({'int': 3});
*/
this.setSerialNumberByParam = function(intParam) {
this.asn1SerialNumber = new KJUR.asn1.DERInteger(intParam);
};
/**
* set signature algorithm field by parameter
* @name setSignatureAlgByParam
* @memberOf KJUR.asn1.x509.TBSCertificate
* @function
* @param {Array} algIdParam AlgorithmIdentifier parameter
* @description
* @example
* tbsc.setSignatureAlgByParam({'name': 'SHA1withRSA'});
*/
this.setSignatureAlgByParam = function(algIdParam) {
this.asn1SignatureAlg = new KJUR.asn1.x509.AlgorithmIdentifier(algIdParam);
};
/**
* set issuer name field by parameter
* @name setIssuerByParam
* @memberOf KJUR.asn1.x509.TBSCertificate
* @function
* @param {Array} x500NameParam X500Name parameter
* @description
* @example
* tbsc.setIssuerParam({'str': '/C=US/CN=b'});
* @see KJUR.asn1.x509.X500Name
*/
this.setIssuerByParam = function(x500NameParam) {
this.asn1Issuer = new KJUR.asn1.x509.X500Name(x500NameParam);
};
/**
* set notBefore field by parameter
* @name setNotBeforeByParam
* @memberOf KJUR.asn1.x509.TBSCertificate
* @function
* @param {Array} timeParam Time parameter
* @description
* @example
* tbsc.setNotBeforeByParam({'str': '130508235959Z'});
* @see KJUR.asn1.x509.Time
*/
this.setNotBeforeByParam = function(timeParam) {
this.asn1NotBefore = new KJUR.asn1.x509.Time(timeParam);
};
/**
* set notAfter field by parameter
* @name setNotAfterByParam
* @memberOf KJUR.asn1.x509.TBSCertificate
* @function
* @param {Array} timeParam Time parameter
* @description
* @example
* tbsc.setNotAfterByParam({'str': '130508235959Z'});
* @see KJUR.asn1.x509.Time
*/
this.setNotAfterByParam = function(timeParam) {
this.asn1NotAfter = new KJUR.asn1.x509.Time(timeParam);
};
/**
* set subject name field by parameter
* @name setSubjectByParam
* @memberOf KJUR.asn1.x509.TBSCertificate
* @function
* @param {Array} x500NameParam X500Name parameter
* @description
* @example
* tbsc.setSubjectParam({'str': '/C=US/CN=b'});
* @see KJUR.asn1.x509.X500Name
*/
this.setSubjectByParam = function(x500NameParam) {
this.asn1Subject = new KJUR.asn1.x509.X500Name(x500NameParam);
};
/**
* (DEPRECATED) set subject public key info field by RSA key parameter
* @name setSubjectPublicKeyByParam
* @memberOf KJUR.asn1.x509.TBSCertificate
* @function
* @param {Array} subjPKeyParam SubjectPublicKeyInfo parameter of RSA
* @deprecated
* @description
* @example
* tbsc.setSubjectPublicKeyByParam({'rsakey': pubKey});
* @see KJUR.asn1.x509.SubjectPublicKeyInfo
*/
this.setSubjectPublicKeyByParam = function(subjPKeyParam) {
this.asn1SubjPKey = new KJUR.asn1.x509.SubjectPublicKeyInfo(subjPKeyParam);
};
/**
* set subject public key info by RSA/ECDSA/DSA key parameter
* @name setSubjectPublicKeyByGetKey
* @memberOf KJUR.asn1.x509.TBSCertificate
* @function
* @param {Object} keyParam public key parameter which passed to {@link KEYUTIL.getKey} argument
* @description
* @example
* tbsc.setSubjectPublicKeyByGetKeyParam(certPEMString); // or
* tbsc.setSubjectPublicKeyByGetKeyParam(pkcs8PublicKeyPEMString); // or
* tbsc.setSubjectPublicKeyByGetKeyParam(kjurCryptoECDSAKeyObject); // et.al.
* @see KJUR.asn1.x509.SubjectPublicKeyInfo
* @see KEYUTIL.getKey
* @since asn1x509 1.0.6
*/
this.setSubjectPublicKeyByGetKey = function(keyParam) {
var keyObj = KEYUTIL.getKey(keyParam);
this.asn1SubjPKey = new KJUR.asn1.x509.SubjectPublicKeyInfo(keyObj);
};
/**
* append X.509v3 extension to this object
* @name appendExtension
* @memberOf KJUR.asn1.x509.TBSCertificate
* @function
* @param {Extension} extObj X.509v3 Extension object
* @description
* @example
* tbsc.appendExtension(new KJUR.asn1.x509.BasicConstraints({'cA':true, 'critical': true}));
* tbsc.appendExtension(new KJUR.asn1.x509.KeyUsage({'bin':'11'}));
* @see KJUR.asn1.x509.Extension
*/
this.appendExtension = function(extObj) {
this.extensionsArray.push(extObj);
};
/**
* append X.509v3 extension to this object by name and parameters
* @name appendExtensionByName
* @memberOf KJUR.asn1.x509.TBSCertificate
* @function
* @param {name} name name of X.509v3 Extension object
* @param {Array} extParams parameters as argument of Extension constructor.
* @description
* @example
* tbsc.appendExtensionByName('BasicConstraints', {'cA':true, 'critical': true});
* tbsc.appendExtensionByName('KeyUsage', {'bin':'11'});
* tbsc.appendExtensionByName('CRLDistributionPoints', {uri: 'http://aaa.com/a.crl'});
* tbsc.appendExtensionByName('ExtKeyUsage', {array: [{name: 'clientAuth'}]});
* tbsc.appendExtensionByName('AuthorityKeyIdentifier', {kid: '1234ab..'});
* @see KJUR.asn1.x509.Extension
*/
this.appendExtensionByName = function(name, extParams) {
if (name.toLowerCase() == "basicconstraints") {
var extObj = new KJUR.asn1.x509.BasicConstraints(extParams);
this.appendExtension(extObj);
} else if (name.toLowerCase() == "keyusage") {
var extObj = new KJUR.asn1.x509.KeyUsage(extParams);
this.appendExtension(extObj);
} else if (name.toLowerCase() == "crldistributionpoints") {
var extObj = new KJUR.asn1.x509.CRLDistributionPoints(extParams);
this.appendExtension(extObj);
} else if (name.toLowerCase() == "extkeyusage") {
var extObj = new KJUR.asn1.x509.ExtKeyUsage(extParams);
this.appendExtension(extObj);
} else if (name.toLowerCase() == "authoritykeyidentifier") {
var extObj = new KJUR.asn1.x509.AuthorityKeyIdentifier(extParams);
this.appendExtension(extObj);
} else {
throw "unsupported extension name: " + name;
}
};
this.getEncodedHex = function() {
if (this.asn1NotBefore == null || this.asn1NotAfter == null)
throw "notBefore and/or notAfter not set";
var asn1Validity =
new KJUR.asn1.DERSequence({'array':[this.asn1NotBefore, this.asn1NotAfter]});
this.asn1Array = new Array();
this.asn1Array.push(this.asn1Version);
this.asn1Array.push(this.asn1SerialNumber);
this.asn1Array.push(this.asn1SignatureAlg);
this.asn1Array.push(this.asn1Issuer);
this.asn1Array.push(asn1Validity);
this.asn1Array.push(this.asn1Subject);
this.asn1Array.push(this.asn1SubjPKey);
if (this.extensionsArray.length > 0) {
var extSeq = new KJUR.asn1.DERSequence({"array": this.extensionsArray});
var extTagObj = new KJUR.asn1.DERTaggedObject({'explicit': true,
'tag': 'a3',
'obj': extSeq});
this.asn1Array.push(extTagObj);
}
var o = new KJUR.asn1.DERSequence({"array": this.asn1Array});
this.hTLV = o.getEncodedHex();
this.isModified = false;
return this.hTLV;
};
this._initialize();
};
YAHOO.lang.extend(KJUR.asn1.x509.TBSCertificate, KJUR.asn1.ASN1Object);
// === END TBSCertificate ===================================================
// === BEGIN X.509v3 Extensions Related =======================================
/**
* base Extension ASN.1 structure class
* @name KJUR.asn1.x509.Extension
* @class base Extension ASN.1 structure class
* @param {Array} params associative array of parameters (ex. {'critical': true})
* @extends KJUR.asn1.ASN1Object
* @description
* @example
* // Extension ::= SEQUENCE {
* // extnID OBJECT IDENTIFIER,
* // critical BOOLEAN DEFAULT FALSE,
* // extnValue OCTET STRING }
*/
KJUR.asn1.x509.Extension = function(params) {
KJUR.asn1.x509.Extension.superclass.constructor.call(this);
var asn1ExtnValue = null;
this.getEncodedHex = function() {
var asn1Oid = new KJUR.asn1.DERObjectIdentifier({'oid': this.oid});
var asn1EncapExtnValue =
new KJUR.asn1.DEROctetString({'hex': this.getExtnValueHex()});
var asn1Array = new Array();
asn1Array.push(asn1Oid);
if (this.critical) asn1Array.push(new KJUR.asn1.DERBoolean());
asn1Array.push(asn1EncapExtnValue);
var asn1Seq = new KJUR.asn1.DERSequence({'array': asn1Array});
return asn1Seq.getEncodedHex();
};
this.critical = false;
if (typeof params != "undefined") {
if (typeof params['critical'] != "undefined") {
this.critical = params['critical'];
}
}
};
YAHOO.lang.extend(KJUR.asn1.x509.Extension, KJUR.asn1.ASN1Object);
/**
* KeyUsage ASN.1 structure class
* @name KJUR.asn1.x509.KeyUsage
* @class KeyUsage ASN.1 structure class
* @param {Array} params associative array of parameters (ex. {'bin': '11', 'critical': true})
* @extends KJUR.asn1.x509.Extension
* @description
* @example
*/
KJUR.asn1.x509.KeyUsage = function(params) {
KJUR.asn1.x509.KeyUsage.superclass.constructor.call(this, params);
this.getExtnValueHex = function() {
return this.asn1ExtnValue.getEncodedHex();
};
this.oid = "2.5.29.15";
if (typeof params != "undefined") {
if (typeof params['bin'] != "undefined") {
this.asn1ExtnValue = new KJUR.asn1.DERBitString(params);
}
}
};
YAHOO.lang.extend(KJUR.asn1.x509.KeyUsage, KJUR.asn1.x509.Extension);
/**
* BasicConstraints ASN.1 structure class
* @name KJUR.asn1.x509.BasicConstraints
* @class BasicConstraints ASN.1 structure class
* @param {Array} params associative array of parameters (ex. {'cA': true, 'critical': true})
* @extends KJUR.asn1.x509.Extension
* @description
* @example
*/
KJUR.asn1.x509.BasicConstraints = function(params) {
KJUR.asn1.x509.BasicConstraints.superclass.constructor.call(this, params);
var cA = false;
var pathLen = -1;
this.getExtnValueHex = function() {
var asn1Array = new Array();
if (this.cA) asn1Array.push(new KJUR.asn1.DERBoolean());
if (this.pathLen > -1)
asn1Array.push(new KJUR.asn1.DERInteger({'int': this.pathLen}));
var asn1Seq = new KJUR.asn1.DERSequence({'array': asn1Array});
this.asn1ExtnValue = asn1Seq;
return this.asn1ExtnValue.getEncodedHex();
};
this.oid = "2.5.29.19";
this.cA = false;
this.pathLen = -1;
if (typeof params != "undefined") {
if (typeof params['cA'] != "undefined") {
this.cA = params['cA'];
}
if (typeof params['pathLen'] != "undefined") {
this.pathLen = params['pathLen'];
}
}
};
YAHOO.lang.extend(KJUR.asn1.x509.BasicConstraints, KJUR.asn1.x509.Extension);
/**
* CRLDistributionPoints ASN.1 structure class
* @name KJUR.asn1.x509.CRLDistributionPoints
* @class CRLDistributionPoints ASN.1 structure class
* @param {Array} params associative array of parameters (ex. {'uri': 'http://a.com/', 'critical': true})
* @extends KJUR.asn1.x509.Extension
* @description
* @example
*/
KJUR.asn1.x509.CRLDistributionPoints = function(params) {
KJUR.asn1.x509.CRLDistributionPoints.superclass.constructor.call(this, params);
this.getExtnValueHex = function() {
return this.asn1ExtnValue.getEncodedHex();
};
this.setByDPArray = function(dpArray) {
this.asn1ExtnValue = new KJUR.asn1.DERSequence({'array': dpArray});
};
this.setByOneURI = function(uri) {
var gn1 = new KJUR.asn1.x509.GeneralNames([{'uri': uri}]);
var dpn1 = new KJUR.asn1.x509.DistributionPointName(gn1);
var dp1 = new KJUR.asn1.x509.DistributionPoint({'dpobj': dpn1});
this.setByDPArray([dp1]);
};
this.oid = "2.5.29.31";
if (typeof params != "undefined") {
if (typeof params['array'] != "undefined") {
this.setByDPArray(params['array']);
} else if (typeof params['uri'] != "undefined") {
this.setByOneURI(params['uri']);
}
}
};
YAHOO.lang.extend(KJUR.asn1.x509.CRLDistributionPoints, KJUR.asn1.x509.Extension);
/**
* KeyUsage ASN.1 structure class
* @name KJUR.asn1.x509.ExtKeyUsage
* @class ExtKeyUsage ASN.1 structure class
* @param {Array} params associative array of parameters
* @extends KJUR.asn1.x509.Extension
* @description
* @example
* var e1 =
* new KJUR.asn1.x509.ExtKeyUsage({'critical': true,
* 'array':
* [{'oid': '2.5.29.37.0', // anyExtendedKeyUsage
* 'name': 'clientAuth'}]});
*
* // id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
* // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
* // KeyPurposeId ::= OBJECT IDENTIFIER
*/
KJUR.asn1.x509.ExtKeyUsage = function(params) {
KJUR.asn1.x509.ExtKeyUsage.superclass.constructor.call(this, params);
this.setPurposeArray = function(purposeArray) {
this.asn1ExtnValue = new KJUR.asn1.DERSequence();
for (var i = 0; i < purposeArray.length; i++) {
var o = new KJUR.asn1.DERObjectIdentifier(purposeArray[i]);
this.asn1ExtnValue.appendASN1Object(o);
}
};
this.getExtnValueHex = function() {
return this.asn1ExtnValue.getEncodedHex();
};
this.oid = "2.5.29.37";
if (typeof params != "undefined") {
if (typeof params['array'] != "undefined") {
this.setPurposeArray(params['array']);
}
}
};
YAHOO.lang.extend(KJUR.asn1.x509.ExtKeyUsage, KJUR.asn1.x509.Extension);
/**
* AuthorityKeyIdentifier ASN.1 structure class
* @name KJUR.asn1.x509.AuthorityKeyIdentifier
* @class AuthorityKeyIdentifier ASN.1 structure class
* @param {Array} params associative array of parameters (ex. {'uri': 'http://a.com/', 'critical': true})
* @extends KJUR.asn1.x509.Extension
* @since asn1x509 1.0.8
* @description
*
* d-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 }
* AuthorityKeyIdentifier ::= SEQUENCE {
* keyIdentifier [0] KeyIdentifier OPTIONAL,
* authorityCertIssuer [1] GeneralNames OPTIONAL,
* authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
* KeyIdentifier ::= OCTET STRING
*
* @example
* var param = {'kid': {'hex': '89ab'},
* 'issuer': {'str': '/C=US/CN=a'},
* 'sn': {'hex': '1234'},
* 'critical': true});
* var e1 = new KJUR.asn1.x509.AuthorityKeyIdentifier(param);
*/
KJUR.asn1.x509.AuthorityKeyIdentifier = function(params) {
KJUR.asn1.x509.AuthorityKeyIdentifier.superclass.constructor.call(this, params);
this.asn1KID = null;
this.asn1CertIssuer = null;
this.asn1CertSN = null;
this.getExtnValueHex = function() {
var a = new Array();
if (this.asn1KID)
a.push(new KJUR.asn1.DERTaggedObject({'explicit': false,
'tag': '80',
'obj': this.asn1KID}));
if (this.asn1CertIssuer)
a.push(new KJUR.asn1.DERTaggedObject({'explicit': false,
'tag': 'a1',
'obj': this.asn1CertIssuer}));
if (this.asn1CertSN)
a.push(new KJUR.asn1.DERTaggedObject({'explicit': false,
'tag': '82',
'obj': this.asn1CertSN}));
var asn1Seq = new KJUR.asn1.DERSequence({'array': a});
this.asn1ExtnValue = asn1Seq;
return this.asn1ExtnValue.getEncodedHex();
};
/**
* set keyIdentifier value by DERInteger parameter
* @name setKIDByParam
* @memberOf KJUR.asn1.x509.AuthorityKeyIdentifier
* @function
* @param {Array} param array of {@link KJUR.asn1.DERInteger} parameter
* @since asn1x509 1.0.8
* @description
* NOTE: Automatic keyIdentifier value calculation by an issuer
* public key will be supported in future version.
*/
this.setKIDByParam = function(param) {
this.asn1KID = new KJUR.asn1.DEROctetString(param);
};
/**
* set authorityCertIssuer value by X500Name parameter
* @name setCertIssuerByParam
* @memberOf KJUR.asn1.x509.AuthorityKeyIdentifier
* @function
* @param {Array} param array of {@link KJUR.asn1.x509.X500Name} parameter
* @since asn1x509 1.0.8
* @description
* NOTE: Automatic authorityCertIssuer name setting by an issuer
* certificate will be supported in future version.
*/
this.setCertIssuerByParam = function(param) {
this.asn1CertIssuer = new KJUR.asn1.x509.X500Name(param);
};
/**
* set authorityCertSerialNumber value by DERInteger parameter
* @name setCertSerialNumberByParam
* @memberOf KJUR.asn1.x509.AuthorityKeyIdentifier
* @function
* @param {Array} param array of {@link KJUR.asn1.DERInteger} parameter
* @since asn1x509 1.0.8
* @description
* NOTE: Automatic authorityCertSerialNumber setting by an issuer
* certificate will be supported in future version.
*/
this.setCertSNByParam = function(param) {
this.asn1CertSN = new KJUR.asn1.DERInteger(param);
};
this.oid = "2.5.29.35";
if (typeof params != "undefined") {
if (typeof params['kid'] != "undefined") {
this.setKIDByParam(params['kid']);
}
if (typeof params['issuer'] != "undefined") {
this.setCertIssuerByParam(params['issuer']);
}
if (typeof params['sn'] != "undefined") {
this.setCertSNByParam(params['sn']);
}
}
};
YAHOO.lang.extend(KJUR.asn1.x509.AuthorityKeyIdentifier, KJUR.asn1.x509.Extension);
// === END X.509v3 Extensions Related =======================================
// === BEGIN CRL Related ===================================================
/**
* X.509 CRL class to sign and generate hex encoded CRL
* @name KJUR.asn1.x509.CRL
* @class X.509 CRL class to sign and generate hex encoded certificate
* @param {Array} params associative array of parameters (ex. {'tbsobj': obj, 'rsaprvkey': key})
* @extends KJUR.asn1.ASN1Object
* @since 1.0.3
* @description
*
* As for argument 'params' for constructor, you can specify one of
* following properties:
*
* - tbsobj - specify {@link KJUR.asn1.x509.TBSCertList} object to be signed
* - rsaprvkey - specify {@link RSAKey} object CA private key
*
* NOTE: 'params' can be omitted.
* EXAMPLE
* @example
* var prvKey = new RSAKey(); // CA's private key
* prvKey.readPrivateKeyFromASN1HexString("3080...");
* var crl = new KJUR.asn1x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey});
* crl.sign(); // issue CRL by CA's private key
* var hCRL = crl.getEncodedHex();
*
* // CertificateList ::= SEQUENCE {
* // tbsCertList TBSCertList,
* // signatureAlgorithm AlgorithmIdentifier,
* // signatureValue BIT STRING }
*/
KJUR.asn1.x509.CRL = function(params) {
KJUR.asn1.x509.CRL.superclass.constructor.call(this);
var asn1TBSCertList = null;
var asn1SignatureAlg = null;
var asn1Sig = null;
var hexSig = null;
var rsaPrvKey = null;
/**
* set PKCS#5 encrypted RSA PEM private key as CA key
* @name setRsaPrvKeyByPEMandPass
* @memberOf KJUR.asn1.x509.CRL
* @function
* @param {String} rsaPEM string of PKCS#5 encrypted RSA PEM private key
* @param {String} passPEM passcode string to decrypt private key
* @description
*
* EXAMPLES
* @example
*/
this.setRsaPrvKeyByPEMandPass = function(rsaPEM, passPEM) {
var caKeyHex = PKCS5PKEY.getDecryptedKeyHex(rsaPEM, passPEM);
var caKey = new RSAKey();
caKey.readPrivateKeyFromASN1HexString(caKeyHex);
this.rsaPrvKey = caKey;
};
/**
* sign TBSCertList and set signature value internally
* @name sign
* @memberOf KJUR.asn1.x509.CRL
* @function
* @description
* @example
* var cert = new KJUR.asn1.x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey});
* cert.sign();
*/
this.sign = function() {
this.asn1SignatureAlg = this.asn1TBSCertList.asn1SignatureAlg;
sig = new KJUR.crypto.Signature({'alg': 'SHA1withRSA', 'prov': 'cryptojs/jsrsa'});
sig.initSign(this.rsaPrvKey);
sig.updateHex(this.asn1TBSCertList.getEncodedHex());
this.hexSig = sig.sign();
this.asn1Sig = new KJUR.asn1.DERBitString({'hex': '00' + this.hexSig});
var seq = new KJUR.asn1.DERSequence({'array': [this.asn1TBSCertList,
this.asn1SignatureAlg,
this.asn1Sig]});
this.hTLV = seq.getEncodedHex();
this.isModified = false;
};
this.getEncodedHex = function() {
if (this.isModified == false && this.hTLV != null) return this.hTLV;
throw "not signed yet";
};
/**
* get PEM formatted CRL string after signed
* @name getPEMString
* @memberOf KJUR.asn1.x509.CRL
* @function
* @return PEM formatted string of certificate
* @description
* @example
* var cert = new KJUR.asn1.x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey});
* cert.sign();
* var sPEM = cert.getPEMString();
*/
this.getPEMString = function() {
var hCert = this.getEncodedHex();
var wCert = CryptoJS.enc.Hex.parse(hCert);
var b64Cert = CryptoJS.enc.Base64.stringify(wCert);
var pemBody = b64Cert.replace(/(.{64})/g, "$1\r\n");
return "-----BEGIN X509 CRL-----\r\n" + pemBody + "\r\n-----END X509 CRL-----\r\n";
};
if (typeof params != "undefined") {
if (typeof params['tbsobj'] != "undefined") {
this.asn1TBSCertList = params['tbsobj'];
}
if (typeof params['rsaprvkey'] != "undefined") {
this.rsaPrvKey = params['rsaprvkey'];
}
if ((typeof params['rsaprvpem'] != "undefined") &&
(typeof params['rsaprvpas'] != "undefined")) {
this.setRsaPrvKeyByPEMandPass(params['rsaprvpem'], params['rsaprvpas']);
}
}
};
YAHOO.lang.extend(KJUR.asn1.x509.CRL, KJUR.asn1.ASN1Object);
/**
* ASN.1 TBSCertList structure class for CRL
* @name KJUR.asn1.x509.TBSCertList
* @class ASN.1 TBSCertList structure class for CRL
* @param {Array} params associative array of parameters (ex. {})
* @extends KJUR.asn1.ASN1Object
* @since 1.0.3
* @description
*
* EXAMPLE
* @example
* var o = new KJUR.asn1.x509.TBSCertList();
* o.setSignatureAlgByParam({'name': 'SHA1withRSA'});
* o.setIssuerByParam({'str': '/C=US/O=a'});
* o.setNotThisUpdateByParam({'str': '130504235959Z'});
* o.setNotNextUpdateByParam({'str': '140504235959Z'});
* o.addRevokedCert({'int': 4}, {'str':'130514235959Z'}));
* o.addRevokedCert({'hex': '0f34dd'}, {'str':'130514235959Z'}));
*
* // TBSCertList ::= SEQUENCE {
* // version Version OPTIONAL,
* // -- if present, MUST be v2
* // signature AlgorithmIdentifier,
* // issuer Name,
* // thisUpdate Time,
* // nextUpdate Time OPTIONAL,
* // revokedCertificates SEQUENCE OF SEQUENCE {
* // userCertificate CertificateSerialNumber,
* // revocationDate Time,
* // crlEntryExtensions Extensions OPTIONAL
* // -- if present, version MUST be v2
* // } OPTIONAL,
* // crlExtensions [0] EXPLICIT Extensions OPTIONAL
*/
KJUR.asn1.x509.TBSCertList = function(params) {
KJUR.asn1.x509.TBSCertList.superclass.constructor.call(this);
var aRevokedCert = null;
/**
* set signature algorithm field by parameter
* @name setSignatureAlgByParam
* @memberOf KJUR.asn1.x509.TBSCertList
* @function
* @param {Array} algIdParam AlgorithmIdentifier parameter
* @description
* @example
* tbsc.setSignatureAlgByParam({'name': 'SHA1withRSA'});
*/
this.setSignatureAlgByParam = function(algIdParam) {
this.asn1SignatureAlg = new KJUR.asn1.x509.AlgorithmIdentifier(algIdParam);
};
/**
* set issuer name field by parameter
* @name setIssuerByParam
* @memberOf KJUR.asn1.x509.TBSCertList
* @function
* @param {Array} x500NameParam X500Name parameter
* @description
* @example
* tbsc.setIssuerParam({'str': '/C=US/CN=b'});
* @see KJUR.asn1.x509.X500Name
*/
this.setIssuerByParam = function(x500NameParam) {
this.asn1Issuer = new KJUR.asn1.x509.X500Name(x500NameParam);
};
/**
* set thisUpdate field by parameter
* @name setThisUpdateByParam
* @memberOf KJUR.asn1.x509.TBSCertList
* @function
* @param {Array} timeParam Time parameter
* @description
* @example
* tbsc.setThisUpdateByParam({'str': '130508235959Z'});
* @see KJUR.asn1.x509.Time
*/
this.setThisUpdateByParam = function(timeParam) {
this.asn1ThisUpdate = new KJUR.asn1.x509.Time(timeParam);
};
/**
* set nextUpdate field by parameter
* @name setNextUpdateByParam
* @memberOf KJUR.asn1.x509.TBSCertList
* @function
* @param {Array} timeParam Time parameter
* @description
* @example
* tbsc.setNextUpdateByParam({'str': '130508235959Z'});
* @see KJUR.asn1.x509.Time
*/
this.setNextUpdateByParam = function(timeParam) {
this.asn1NextUpdate = new KJUR.asn1.x509.Time(timeParam);
};
/**
* add revoked certficate by parameter
* @name addRevokedCert
* @memberOf KJUR.asn1.x509.TBSCertList
* @function
* @param {Array} snParam DERInteger parameter for certificate serial number
* @param {Array} timeParam Time parameter for revocation date
* @description
* @example
* tbsc.addRevokedCert({'int': 3}, {'str': '130508235959Z'});
* @see KJUR.asn1.x509.Time
*/
this.addRevokedCert = function(snParam, timeParam) {
var param = {};
if (snParam != undefined && snParam != null) param['sn'] = snParam;
if (timeParam != undefined && timeParam != null) param['time'] = timeParam;
var o = new KJUR.asn1.x509.CRLEntry(param);
this.aRevokedCert.push(o);
};
this.getEncodedHex = function() {
this.asn1Array = new Array();
if (this.asn1Version != null) this.asn1Array.push(this.asn1Version);
this.asn1Array.push(this.asn1SignatureAlg);
this.asn1Array.push(this.asn1Issuer);
this.asn1Array.push(this.asn1ThisUpdate);
if (this.asn1NextUpdate != null) this.asn1Array.push(this.asn1NextUpdate);
if (this.aRevokedCert.length > 0) {
var seq = new KJUR.asn1.DERSequence({'array': this.aRevokedCert});
this.asn1Array.push(seq);
}
var o = new KJUR.asn1.DERSequence({"array": this.asn1Array});
this.hTLV = o.getEncodedHex();
this.isModified = false;
return this.hTLV;
};
this._initialize = function() {
this.asn1Version = null;
this.asn1SignatureAlg = null;
this.asn1Issuer = null;
this.asn1ThisUpdate = null;
this.asn1NextUpdate = null;
this.aRevokedCert = new Array();
};
this._initialize();
};
YAHOO.lang.extend(KJUR.asn1.x509.TBSCertList, KJUR.asn1.ASN1Object);
/**
* ASN.1 CRLEntry structure class for CRL
* @name KJUR.asn1.x509.CRLEntry
* @class ASN.1 CRLEntry structure class for CRL
* @param {Array} params associative array of parameters (ex. {})
* @extends KJUR.asn1.ASN1Object
* @since 1.0.3
* @description
* @example
* var e = new KJUR.asn1.x509.CRLEntry({'time': {'str': '130514235959Z'}, 'sn': {'int': 234}});
*
* // revokedCertificates SEQUENCE OF SEQUENCE {
* // userCertificate CertificateSerialNumber,
* // revocationDate Time,
* // crlEntryExtensions Extensions OPTIONAL
* // -- if present, version MUST be v2 }
*/
KJUR.asn1.x509.CRLEntry = function(params) {
KJUR.asn1.x509.CRLEntry.superclass.constructor.call(this);
var sn = null;
var time = null;
/**
* set DERInteger parameter for serial number of revoked certificate
* @name setCertSerial
* @memberOf KJUR.asn1.x509.CRLEntry
* @function
* @param {Array} intParam DERInteger parameter for certificate serial number
* @description
* @example
* entry.setCertSerial({'int': 3});
*/
this.setCertSerial = function(intParam) {
this.sn = new KJUR.asn1.DERInteger(intParam);
};
/**
* set Time parameter for revocation date
* @name setRevocationDate
* @memberOf KJUR.asn1.x509.CRLEntry
* @function
* @param {Array} timeParam Time parameter for revocation date
* @description
* @example
* entry.setRevocationDate({'str': '130508235959Z'});
*/
this.setRevocationDate = function(timeParam) {
this.time = new KJUR.asn1.x509.Time(timeParam);
};
this.getEncodedHex = function() {
var o = new KJUR.asn1.DERSequence({"array": [this.sn, this.time]});
this.TLV = o.getEncodedHex();
return this.TLV;
};
if (typeof params != "undefined") {
if (typeof params['time'] != "undefined") {
this.setRevocationDate(params['time']);
}
if (typeof params['sn'] != "undefined") {
this.setCertSerial(params['sn']);
}
}
};
YAHOO.lang.extend(KJUR.asn1.x509.CRLEntry, KJUR.asn1.ASN1Object);
// === END CRL Related ===================================================
// === BEGIN X500Name Related =================================================
/**
* X500Name ASN.1 structure class
* @name KJUR.asn1.x509.X500Name
* @class X500Name ASN.1 structure class
* @param {Array} params associative array of parameters (ex. {'str': '/C=US/O=a'})
* @extends KJUR.asn1.ASN1Object
* @description
* @example
*/
KJUR.asn1.x509.X500Name = function(params) {
KJUR.asn1.x509.X500Name.superclass.constructor.call(this);
this.asn1Array = new Array();
this.setByString = function(dnStr) {
var a = dnStr.split('/');
a.shift();
for (var i = 0; i < a.length; i++) {
this.asn1Array.push(new KJUR.asn1.x509.RDN({'str':a[i]}));
}
};
this.getEncodedHex = function() {
if (typeof this.hTLV == "string") return this.hTLV;
var o = new KJUR.asn1.DERSequence({"array": this.asn1Array});
this.hTLV = o.getEncodedHex();
return this.hTLV;
};
if (typeof params != "undefined") {
if (typeof params['str'] != "undefined") {
this.setByString(params['str']);
}
if (typeof params.certissuer != "undefined") {
var x = new X509();
x.hex = X509.pemToHex(params.certissuer);
this.hTLV = x.getIssuerHex();
}
if (typeof params.certsubject != "undefined") {
var x = new X509();
x.hex = X509.pemToHex(params.certsubject);
this.hTLV = x.getSubjectHex();
}
}
};
YAHOO.lang.extend(KJUR.asn1.x509.X500Name, KJUR.asn1.ASN1Object);
/**
* RDN (Relative Distinguish Name) ASN.1 structure class
* @name KJUR.asn1.x509.RDN
* @class RDN (Relative Distinguish Name) ASN.1 structure class
* @param {Array} params associative array of parameters (ex. {'str': 'C=US'})
* @extends KJUR.asn1.ASN1Object
* @description
* @example
*/
KJUR.asn1.x509.RDN = function(params) {
KJUR.asn1.x509.RDN.superclass.constructor.call(this);
this.asn1Array = new Array();
this.addByString = function(rdnStr) {
this.asn1Array.push(new KJUR.asn1.x509.AttributeTypeAndValue({'str':rdnStr}));
};
this.getEncodedHex = function() {
var o = new KJUR.asn1.DERSet({"array": this.asn1Array});
this.TLV = o.getEncodedHex();
return this.TLV;
};
if (typeof params != "undefined") {
if (typeof params['str'] != "undefined") {
this.addByString(params['str']);
}
}
};
YAHOO.lang.extend(KJUR.asn1.x509.RDN, KJUR.asn1.ASN1Object);
/**
* AttributeTypeAndValue ASN.1 structure class
* @name KJUR.asn1.x509.AttributeTypeAndValue
* @class AttributeTypeAndValue ASN.1 structure class
* @param {Array} params associative array of parameters (ex. {'str': 'C=US'})
* @extends KJUR.asn1.ASN1Object
* @description
* @example
*/
KJUR.asn1.x509.AttributeTypeAndValue = function(params) {
KJUR.asn1.x509.AttributeTypeAndValue.superclass.constructor.call(this);
var typeObj = null;
var valueObj = null;
var defaultDSType = "utf8";
this.setByString = function(attrTypeAndValueStr) {
if (attrTypeAndValueStr.match(/^([^=]+)=(.+)$/)) {
this.setByAttrTypeAndValueStr(RegExp.$1, RegExp.$2);
} else {
throw "malformed attrTypeAndValueStr: " + attrTypeAndValueStr;
}
};
this.setByAttrTypeAndValueStr = function(shortAttrType, valueStr) {
this.typeObj = KJUR.asn1.x509.OID.atype2obj(shortAttrType);
var dsType = defaultDSType;
if (shortAttrType == "C") dsType = "prn";
this.valueObj = this.getValueObj(dsType, valueStr);
};
this.getValueObj = function(dsType, valueStr) {
if (dsType == "utf8") return new KJUR.asn1.DERUTF8String({"str": valueStr});
if (dsType == "prn") return new KJUR.asn1.DERPrintableString({"str": valueStr});
if (dsType == "tel") return new KJUR.asn1.DERTeletexString({"str": valueStr});
if (dsType == "ia5") return new KJUR.asn1.DERIA5String({"str": valueStr});
throw "unsupported directory string type: type=" + dsType + " value=" + valueStr;
};
this.getEncodedHex = function() {
var o = new KJUR.asn1.DERSequence({"array": [this.typeObj, this.valueObj]});
this.TLV = o.getEncodedHex();
return this.TLV;
};
if (typeof params != "undefined") {
if (typeof params['str'] != "undefined") {
this.setByString(params['str']);
}
}
};
YAHOO.lang.extend(KJUR.asn1.x509.AttributeTypeAndValue, KJUR.asn1.ASN1Object);
// === END X500Name Related =================================================
// === BEGIN Other ASN1 structure class ======================================
/**
* SubjectPublicKeyInfo ASN.1 structure class
* @name KJUR.asn1.x509.SubjectPublicKeyInfo
* @class SubjectPublicKeyInfo ASN.1 structure class
* @param {Object} params parameter for subject public key
* @extends KJUR.asn1.ASN1Object
* @description
*
* As for argument 'params' for constructor, you can specify one of
* following properties:
*
* - {@link RSAKey} object
* - {@link KJUR.crypto.ECDSA} object
* - {@link KJUR.crypto.DSA} object
* - (DEPRECATED)rsakey - specify {@link RSAKey} object of subject public key
* - (DEPRECATED)rsapem - specify a string of PEM public key of RSA key
*
* NOTE1: 'params' can be omitted.
* NOTE2: DSA/ECDSA key object is also supported since asn1x509 1.0.6.
* EXAMPLE
* @example
* var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(RSAKey_object);
* var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoECDSA_object);
* var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoDSA_object);
*/
KJUR.asn1.x509.SubjectPublicKeyInfo = function(params) {
KJUR.asn1.x509.SubjectPublicKeyInfo.superclass.constructor.call(this);
var asn1AlgId = null;
var asn1SubjPKey = null;
var rsaKey = null;
/**
* (DEPRECATED) set RSAKey object as subject public key
* @name setRSAKey
* @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo
* @function
* @param {RSAKey} rsaKey {@link RSAKey} object for RSA public key
* @description
* @deprecated
* @example
* spki.setRSAKey(rsaKey);
*/
this.setRSAKey = function(rsaKey) {
if (! RSAKey.prototype.isPrototypeOf(rsaKey))
throw "argument is not RSAKey instance";
this.rsaKey = rsaKey;
var asn1RsaN = new KJUR.asn1.DERInteger({'bigint': rsaKey.n});
var asn1RsaE = new KJUR.asn1.DERInteger({'int': rsaKey.e});
var asn1RsaPub = new KJUR.asn1.DERSequence({'array': [asn1RsaN, asn1RsaE]});
var rsaKeyHex = asn1RsaPub.getEncodedHex();
this.asn1AlgId = new KJUR.asn1.x509.AlgorithmIdentifier({'name':'rsaEncryption'});
this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex':'00'+rsaKeyHex});
};
/**
* (DEPRECATED) set a PEM formatted RSA public key string as RSA public key
* @name setRSAPEM
* @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo
* @function
* @param {String} rsaPubPEM PEM formatted RSA public key string
* @deprecated
* @description
* @example
* spki.setRSAPEM(rsaPubPEM);
*/
this.setRSAPEM = function(rsaPubPEM) {
if (rsaPubPEM.match(/-----BEGIN PUBLIC KEY-----/)) {
var s = rsaPubPEM;
s = s.replace(/^-----[^-]+-----/, '');
s = s.replace(/-----[^-]+-----\s*$/, '');
var rsaB64 = s.replace(/\s+/g, '');
var rsaWA = CryptoJS.enc.Base64.parse(rsaB64);
var rsaP8Hex = CryptoJS.enc.Hex.stringify(rsaWA);
var a = _rsapem_getHexValueArrayOfChildrenFromHex(rsaP8Hex);
var hBitStrVal = a[1];
var rsaHex = hBitStrVal.substr(2);
var a3 = _rsapem_getHexValueArrayOfChildrenFromHex(rsaHex);
var rsaKey = new RSAKey();
rsaKey.setPublic(a3[0], a3[1]);
this.setRSAKey(rsaKey);
} else {
throw "key not supported";
}
};
/*
* @since asn1x509 1.0.7
*/
this.getASN1Object = function() {
if (this.asn1AlgId == null || this.asn1SubjPKey == null)
throw "algId and/or subjPubKey not set";
var o = new KJUR.asn1.DERSequence({'array':
[this.asn1AlgId, this.asn1SubjPKey]});
return o;
};
this.getEncodedHex = function() {
var o = this.getASN1Object();
this.hTLV = o.getEncodedHex();
return this.hTLV;
};
this._setRSAKey = function(key) {
var asn1RsaPub = KJUR.asn1.ASN1Util.newObject({
'seq': [{'int': {'bigint': key.n}}, {'int': {'int': key.e}}]
});
var rsaKeyHex = asn1RsaPub.getEncodedHex();
this.asn1AlgId = new KJUR.asn1.x509.AlgorithmIdentifier({'name':'rsaEncryption'});
this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex':'00'+rsaKeyHex});
};
this._setEC = function(key) {
var asn1Params = new KJUR.asn1.DERObjectIdentifier({'name': key.curveName});
this.asn1AlgId =
new KJUR.asn1.x509.AlgorithmIdentifier({'name': 'ecPublicKey',
'asn1params': asn1Params});
this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex': '00' + key.pubKeyHex});
};
this._setDSA = function(key) {
var asn1Params = new KJUR.asn1.ASN1Util.newObject({
'seq': [{'int': {'bigint': key.p}},
{'int': {'bigint': key.q}},
{'int': {'bigint': key.g}}]
});
this.asn1AlgId =
new KJUR.asn1.x509.AlgorithmIdentifier({'name': 'dsa',
'asn1params': asn1Params});
var pubInt = new KJUR.asn1.DERInteger({'bigint': key.y});
this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex': '00' + pubInt.getEncodedHex()});
};
if (typeof params != "undefined") {
if (typeof RSAKey != 'undefined' && params instanceof RSAKey) {
this._setRSAKey(params);
} else if (typeof KJUR.crypto.ECDSA != 'undefined' &&
params instanceof KJUR.crypto.ECDSA) {
this._setEC(params);
} else if (typeof KJUR.crypto.DSA != 'undefined' &&
params instanceof KJUR.crypto.DSA) {
this._setDSA(params);
} else if (typeof params['rsakey'] != "undefined") {
this.setRSAKey(params['rsakey']);
} else if (typeof params['rsapem'] != "undefined") {
this.setRSAPEM(params['rsapem']);
}
}
};
YAHOO.lang.extend(KJUR.asn1.x509.SubjectPublicKeyInfo, KJUR.asn1.ASN1Object);
/**
* Time ASN.1 structure class
* @name KJUR.asn1.x509.Time
* @class Time ASN.1 structure class
* @param {Array} params associative array of parameters (ex. {'str': '130508235959Z'})
* @extends KJUR.asn1.ASN1Object
* @description
*
* EXAMPLES
* @example
* var t1 = new KJUR.asn1.x509.Time{'str': '130508235959Z'} // UTCTime by default
* var t2 = new KJUR.asn1.x509.Time{'type': 'gen', 'str': '20130508235959Z'} // GeneralizedTime
*/
KJUR.asn1.x509.Time = function(params) {
KJUR.asn1.x509.Time.superclass.constructor.call(this);
var type = null;
var timeParams = null;
this.setTimeParams = function(timeParams) {
this.timeParams = timeParams;
}
this.getEncodedHex = function() {
var o = null;
if (this.timeParams != null) {
if (this.type == "utc") {
o = new KJUR.asn1.DERUTCTime(this.timeParams);
} else {
o = new KJUR.asn1.DERGeneralizedTime(this.timeParams);
}
} else {
if (this.type == "utc") {
o = new KJUR.asn1.DERUTCTime();
} else {
o = new KJUR.asn1.DERGeneralizedTime();
}
}
this.TLV = o.getEncodedHex();
return this.TLV;
};
this.type = "utc";
if (typeof params != "undefined") {
if (typeof params.type != "undefined") {
this.type = params.type;
} else {
if (typeof params.str != "undefined") {
if (params.str.match(/^[0-9]{12}Z$/)) this.type = "utc";
if (params.str.match(/^[0-9]{14}Z$/)) this.type = "gen";
}
}
this.timeParams = params;
}
};
YAHOO.lang.extend(KJUR.asn1.x509.Time, KJUR.asn1.ASN1Object);
/**
* AlgorithmIdentifier ASN.1 structure class
* @name KJUR.asn1.x509.AlgorithmIdentifier
* @class AlgorithmIdentifier ASN.1 structure class
* @param {Array} params associative array of parameters (ex. {'name': 'SHA1withRSA'})
* @extends KJUR.asn1.ASN1Object
* @description
* @example
*/
KJUR.asn1.x509.AlgorithmIdentifier = function(params) {
KJUR.asn1.x509.AlgorithmIdentifier.superclass.constructor.call(this);
var nameAlg = null;
var asn1Alg = null;
var asn1Params = null;
var paramEmpty = false;
this.getEncodedHex = function() {
if (this.nameAlg == null && this.asn1Alg == null) {
throw "algorithm not specified";
}
if (this.nameAlg != null && this.asn1Alg == null) {
this.asn1Alg = KJUR.asn1.x509.OID.name2obj(this.nameAlg);
}
var a = [this.asn1Alg];
if (! this.paramEmpty) a.push(this.asn1Params);
var o = new KJUR.asn1.DERSequence({'array': a});
this.hTLV = o.getEncodedHex();
return this.hTLV;
};
if (typeof params != "undefined") {
if (typeof params['name'] != "undefined") {
this.nameAlg = params['name'];
}
if (typeof params['asn1params'] != "undefined") {
this.asn1Params = params['asn1params'];
}
if (typeof params['paramempty'] != "undefined") {
this.paramEmpty = params['paramempty'];
}
}
if (this.asn1Params == null) {
this.asn1Params = new KJUR.asn1.DERNull();
}
};
YAHOO.lang.extend(KJUR.asn1.x509.AlgorithmIdentifier, KJUR.asn1.ASN1Object);
/**
* GeneralName ASN.1 structure class
* @name KJUR.asn1.x509.GeneralName
* @class GeneralName ASN.1 structure class
* @description
*
* As for argument 'params' for constructor, you can specify one of
* following properties:
*
* - rfc822 - rfc822Name[1] (ex. user1@foo.com)
* - dns - dNSName[2] (ex. foo.com)
* - uri - uniformResourceIdentifier[6] (ex. http://foo.com/)
*
* NOTE: Currently this only supports 'uniformResourceIdentifier'.
* EXAMPLE AND ASN.1 SYNTAX
* @example
* var gn = new KJUR.asn1.x509.GeneralName({'uri': 'http://aaa.com/'});
*
* GeneralName ::= CHOICE {
* otherName [0] OtherName,
* rfc822Name [1] IA5String,
* dNSName [2] IA5String,
* x400Address [3] ORAddress,
* directoryName [4] Name,
* ediPartyName [5] EDIPartyName,
* uniformResourceIdentifier [6] IA5String,
* iPAddress [7] OCTET STRING,
* registeredID [8] OBJECT IDENTIFIER }
*/
KJUR.asn1.x509.GeneralName = function(params) {
KJUR.asn1.x509.GeneralName.superclass.constructor.call(this);
var asn1Obj = null;
var type = null;
var pTag = {'rfc822': '81', 'dns': '82', 'uri': '86'};
this.setByParam = function(params) {
var str = null;
var v = null;
if (typeof params['rfc822'] != "undefined") {
this.type = 'rfc822';
v = new KJUR.asn1.DERIA5String({'str': params[this.type]});
}
if (typeof params['dns'] != "undefined") {
this.type = 'dns';
v = new KJUR.asn1.DERIA5String({'str': params[this.type]});
}
if (typeof params['uri'] != "undefined") {
this.type = 'uri';
v = new KJUR.asn1.DERIA5String({'str': params[this.type]});
}
if (this.type == null)
throw "unsupported type in params=" + params;
this.asn1Obj = new KJUR.asn1.DERTaggedObject({'explicit': false,
'tag': pTag[this.type],
'obj': v});
};
this.getEncodedHex = function() {
return this.asn1Obj.getEncodedHex();
}
if (typeof params != "undefined") {
this.setByParam(params);
}
};
YAHOO.lang.extend(KJUR.asn1.x509.GeneralName, KJUR.asn1.ASN1Object);
/**
* GeneralNames ASN.1 structure class
* @name KJUR.asn1.x509.GeneralNames
* @class GeneralNames ASN.1 structure class
* @description
*
* EXAMPLE AND ASN.1 SYNTAX
* @example
* var gns = new KJUR.asn1.x509.GeneralNames([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]);
*
* GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
*/
KJUR.asn1.x509.GeneralNames = function(paramsArray) {
KJUR.asn1.x509.GeneralNames.superclass.constructor.call(this);
var asn1Array = null;
/**
* set a array of {@link KJUR.asn1.x509.GeneralName} parameters
* @name setByParamArray
* @memberOf KJUR.asn1.x509.GeneralNames
* @function
* @param {Array} paramsArray Array of {@link KJUR.asn1.x509.GeneralNames}
* @description
*
* EXAMPLES
* @example
* var gns = new KJUR.asn1.x509.GeneralNames();
* gns.setByParamArray([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]);
*/
this.setByParamArray = function(paramsArray) {
for (var i = 0; i < paramsArray.length; i++) {
var o = new KJUR.asn1.x509.GeneralName(paramsArray[i]);
this.asn1Array.push(o);
}
};
this.getEncodedHex = function() {
var o = new KJUR.asn1.DERSequence({'array': this.asn1Array});
return o.getEncodedHex();
};
this.asn1Array = new Array();
if (typeof paramsArray != "undefined") {
this.setByParamArray(paramsArray);
}
};
YAHOO.lang.extend(KJUR.asn1.x509.GeneralNames, KJUR.asn1.ASN1Object);
/**
* DistributionPointName ASN.1 structure class
* @name KJUR.asn1.x509.DistributionPointName
* @class DistributionPointName ASN.1 structure class
* @description
* @example
*/
KJUR.asn1.x509.DistributionPointName = function(gnOrRdn) {
KJUR.asn1.x509.DistributionPointName.superclass.constructor.call(this);
var asn1Obj = null;
var type = null;
var tag = null;
var asn1V = null;
this.getEncodedHex = function() {
if (this.type != "full")
throw "currently type shall be 'full': " + this.type;
this.asn1Obj = new KJUR.asn1.DERTaggedObject({'explicit': false,
'tag': this.tag,
'obj': this.asn1V});
this.hTLV = this.asn1Obj.getEncodedHex();
return this.hTLV;
};
if (typeof gnOrRdn != "undefined") {
if (KJUR.asn1.x509.GeneralNames.prototype.isPrototypeOf(gnOrRdn)) {
this.type = "full";
this.tag = "a0";
this.asn1V = gnOrRdn;
} else {
throw "This class supports GeneralNames only as argument";
}
}
};
YAHOO.lang.extend(KJUR.asn1.x509.DistributionPointName, KJUR.asn1.ASN1Object);
/**
* DistributionPoint ASN.1 structure class
* @name KJUR.asn1.x509.DistributionPoint
* @class DistributionPoint ASN.1 structure class
* @description
* @example
*/
KJUR.asn1.x509.DistributionPoint = function(params) {
KJUR.asn1.x509.DistributionPoint.superclass.constructor.call(this);
var asn1DP = null;
this.getEncodedHex = function() {
var seq = new KJUR.asn1.DERSequence();
if (this.asn1DP != null) {
var o1 = new KJUR.asn1.DERTaggedObject({'explicit': true,
'tag': 'a0',
'obj': this.asn1DP});
seq.appendASN1Object(o1);
}
this.hTLV = seq.getEncodedHex();
return this.hTLV;
};
if (typeof params != "undefined") {
if (typeof params['dpobj'] != "undefined") {
this.asn1DP = params['dpobj'];
}
}
};
YAHOO.lang.extend(KJUR.asn1.x509.DistributionPoint, KJUR.asn1.ASN1Object);
/**
* static object for OID
* @name KJUR.asn1.x509.OID
* @class static object for OID
* @property {Assoc Array} atype2oidList for short attribyte type name and oid (i.e. 'C' and '2.5.4.6')
* @property {Assoc Array} name2oidList for oid name and oid (i.e. 'keyUsage' and '2.5.29.15')
* @property {Assoc Array} objCache for caching name and DERObjectIdentifier object
* @description
*
* - atype2oidList
*
- currently supports 'C', 'O', 'OU', 'ST', 'L' and 'CN' only.
*
- name2oidList
*
- currently supports 'SHA1withRSA', 'rsaEncryption' and some extension OIDs
*
* @example
*/
KJUR.asn1.x509.OID = new function(params) {
this.atype2oidList = {
'C': '2.5.4.6',
'O': '2.5.4.10',
'OU': '2.5.4.11',
'ST': '2.5.4.8',
'L': '2.5.4.7',
'CN': '2.5.4.3',
'DN': '2.5.4.49',
'DC': '0.9.2342.19200300.100.1.25',
};
this.name2oidList = {
'sha1': '1.3.14.3.2.26',
'sha256': '2.16.840.1.101.3.4.2.1',
'sha384': '2.16.840.1.101.3.4.2.2',
'sha512': '2.16.840.1.101.3.4.2.3',
'sha224': '2.16.840.1.101.3.4.2.4',
'md5': '1.2.840.113549.2.5',
'md2': '1.3.14.7.2.2.1',
'ripemd160': '1.3.36.3.2.1',
'MD2withRSA': '1.2.840.113549.1.1.2',
'MD4withRSA': '1.2.840.113549.1.1.3',
'MD5withRSA': '1.2.840.113549.1.1.4',
'SHA1withRSA': '1.2.840.113549.1.1.5',
'SHA224withRSA': '1.2.840.113549.1.1.14',
'SHA256withRSA': '1.2.840.113549.1.1.11',
'SHA384withRSA': '1.2.840.113549.1.1.12',
'SHA512withRSA': '1.2.840.113549.1.1.13',
'SHA1withECDSA': '1.2.840.10045.4.1',
'SHA224withECDSA': '1.2.840.10045.4.3.1',
'SHA256withECDSA': '1.2.840.10045.4.3.2',
'SHA384withECDSA': '1.2.840.10045.4.3.3',
'SHA512withECDSA': '1.2.840.10045.4.3.4',
'dsa': '1.2.840.10040.4.1',
'SHA1withDSA': '1.2.840.10040.4.3',
'SHA224withDSA': '2.16.840.1.101.3.4.3.1',
'SHA256withDSA': '2.16.840.1.101.3.4.3.2',
'rsaEncryption': '1.2.840.113549.1.1.1',
'subjectKeyIdentifier': '2.5.29.14',
'countryName': '2.5.4.6',
'organization': '2.5.4.10',
'organizationalUnit': '2.5.4.11',
'stateOrProvinceName': '2.5.4.8',
'locality': '2.5.4.7',
'commonName': '2.5.4.3',
'keyUsage': '2.5.29.15',
'basicConstraints': '2.5.29.19',
'cRLDistributionPoints':'2.5.29.31',
'certificatePolicies': '2.5.29.32',
'authorityKeyIdentifier':'2.5.29.35',
'extKeyUsage': '2.5.29.37',
'anyExtendedKeyUsage': '2.5.29.37.0',
'serverAuth': '1.3.6.1.5.5.7.3.1',
'clientAuth': '1.3.6.1.5.5.7.3.2',
'codeSigning': '1.3.6.1.5.5.7.3.3',
'emailProtection': '1.3.6.1.5.5.7.3.4',
'timeStamping': '1.3.6.1.5.5.7.3.8',
'ocspSigning': '1.3.6.1.5.5.7.3.9',
'ecPublicKey': '1.2.840.10045.2.1',
'secp256r1': '1.2.840.10045.3.1.7',
'secp256k1': '1.3.132.0.10',
'secp384r1': '1.3.132.0.34',
'pkcs5PBES2': '1.2.840.113549.1.5.13',
'pkcs5PBKDF2': '1.2.840.113549.1.5.12',
'des-EDE3-CBC': '1.2.840.113549.3.7',
'data': '1.2.840.113549.1.7.1', // CMS data
'signed-data': '1.2.840.113549.1.7.2', // CMS signed-data
'enveloped-data': '1.2.840.113549.1.7.3', // CMS enveloped-data
'digested-data': '1.2.840.113549.1.7.5', // CMS digested-data
'encrypted-data': '1.2.840.113549.1.7.6', // CMS encrypted-data
'authenticated-data': '1.2.840.113549.1.9.16.1.2', // CMS authenticated-data
'tstinfo': '1.2.840.113549.1.9.16.1.4', // RFC3161 TSTInfo
};
this.objCache = {};
/**
* get DERObjectIdentifier by registered OID name
* @name name2obj
* @memberOf KJUR.asn1.x509.OID
* @function
* @param {String} name OID
* @description
* @example
* var asn1ObjOID = OID.name2obj('SHA1withRSA');
*/
this.name2obj = function(name) {
if (typeof this.objCache[name] != "undefined")
return this.objCache[name];
if (typeof this.name2oidList[name] == "undefined")
throw "Name of ObjectIdentifier not defined: " + name;
var oid = this.name2oidList[name];
var obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid});
this.objCache[name] = obj;
return obj;
};
/**
* get DERObjectIdentifier by registered attribyte type name such like 'C' or 'CN'
* @name atype2obj
* @memberOf KJUR.asn1.x509.OID
* @function
* @param {String} atype short attribute type name such like 'C' or 'CN'
* @description
* @example
* var asn1ObjOID = OID.atype2obj('CN');
*/
this.atype2obj = function(atype) {
if (typeof this.objCache[atype] != "undefined")
return this.objCache[atype];
if (typeof this.atype2oidList[atype] == "undefined")
throw "AttributeType name undefined: " + atype;
var oid = this.atype2oidList[atype];
var obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid});
this.objCache[atype] = obj;
return obj;
};
};
/*
* @since asn1x509 1.0.9
*/
KJUR.asn1.x509.OID.oid2name = function(oid) {
var list = KJUR.asn1.x509.OID.name2oidList;
for (var name in list) {
if (list[name] == oid) return name;
}
return '';
};
/**
* X.509 certificate and CRL utilities class
* @name KJUR.asn1.x509.X509Util
* @class X.509 certificate and CRL utilities class
*/
KJUR.asn1.x509.X509Util = new function() {
/**
* get PKCS#8 PEM public key string from RSAKey object
* @name getPKCS8PubKeyPEMfromRSAKey
* @memberOf KJUR.asn1.x509.X509Util
* @function
* @param {RSAKey} rsaKey RSA public key of {@link RSAKey} object
* @description
* @example
* var pem = KJUR.asn1.x509.X509Util.getPKCS8PubKeyPEMfromRSAKey(pubKey);
*/
this.getPKCS8PubKeyPEMfromRSAKey = function(rsaKey) {
var pem = null;
var hN = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(rsaKey.n);
var hE = KJUR.asn1.ASN1Util.integerToByteHex(rsaKey.e);
var iN = new KJUR.asn1.DERInteger({hex: hN});
var iE = new KJUR.asn1.DERInteger({hex: hE});
var asn1PubKey = new KJUR.asn1.DERSequence({array: [iN, iE]});
var hPubKey = asn1PubKey.getEncodedHex();
var o1 = new KJUR.asn1.x509.AlgorithmIdentifier({name: 'rsaEncryption'});
var o2 = new KJUR.asn1.DERBitString({hex: '00' + hPubKey});
var seq = new KJUR.asn1.DERSequence({array: [o1, o2]});
var hP8 = seq.getEncodedHex();
var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(hP8, "PUBLIC KEY");
return pem;
};
};
/**
* issue a certificate in PEM format
* @name newCertPEM
* @memberOf KJUR.asn1.x509.X509Util
* @function
* @param {Array} param parameter to issue a certificate
* @since asn1x509 1.0.6
* @description
* This method can issue a certificate by a simple
* JSON object.
* Signature value will be provided by signing with
* private key using 'cakey' parameter or
* hexa decimal signature value by 'sighex' parameter.
*
* NOTE: When using DSA or ECDSA CA signing key,
* use 'paramempty' in 'sigalg' to ommit parameter field
* of AlgorithmIdentifer. In case of RSA, parameter
* NULL will be specified by default.
*
* @example
* var certPEM = KJUR.asn1.x509.X509Util.newCertPEM(
* { serial: {int: 4},
* sigalg: {name: 'SHA1withECDSA', paramempty: true},
* issuer: {str: '/C=US/O=a'},
* notbefore: {'str': '130504235959Z'},
* notafter: {'str': '140504235959Z'},
* subject: {str: '/C=US/O=b'},
* sbjpubkey: pubKeyPEM,
* ext: [
* {basicConstraints: {cA: true, critical: true}},
* {keyUsage: {bin: '11'}},
* ],
* cakey: [prvkey, pass]}
* );
* // -- or --
* var certPEM = KJUR.asn1.x509.X509Util.newCertPEM(
* { serial: {int: 1},
* sigalg: {name: 'SHA1withRSA', paramempty: true},
* issuer: {str: '/C=US/O=T1'},
* notbefore: {'str': '130504235959Z'},
* notafter: {'str': '140504235959Z'},
* subject: {str: '/C=US/O=T1'},
* sbjpubkey: pubKeyObj,
* sighex: '0102030405..'}
* );
*/
KJUR.asn1.x509.X509Util.newCertPEM = function(param) {
var ns1 = KJUR.asn1.x509;
var o = new ns1.TBSCertificate();
if (param.serial !== undefined)
o.setSerialNumberByParam(param.serial);
else
throw "serial number undefined.";
if (typeof param.sigalg.name == 'string')
o.setSignatureAlgByParam(param.sigalg);
else
throw "unproper signature algorithm name";
if (param.issuer !== undefined)
o.setIssuerByParam(param.issuer);
else
throw "issuer name undefined.";
if (param.notbefore !== undefined)
o.setNotBeforeByParam(param.notbefore);
else
throw "notbefore undefined.";
if (param.notafter !== undefined)
o.setNotAfterByParam(param.notafter);
else
throw "notafter undefined.";
if (param.subject !== undefined)
o.setSubjectByParam(param.subject);
else
throw "subject name undefined.";
if (param.sbjpubkey !== undefined)
o.setSubjectPublicKeyByGetKey(param.sbjpubkey);
else
throw "subject public key undefined.";
if (param.ext !== undefined && param.ext.length !== undefined) {
for (var i = 0; i < param.ext.length; i++) {
for (key in param.ext[i]) {
o.appendExtensionByName(key, param.ext[i][key]);
}
}
}
// set signature
if (param.cakey === undefined && param.sighex === undefined)
throw "param cakey and sighex undefined.";
var caKey = null;
var cert = null;
if (param.cakey) {
caKey = KEYUTIL.getKey.apply(null, param.cakey);
cert = new ns1.Certificate({'tbscertobj': o, 'prvkeyobj': caKey});
cert.sign();
}
if (param.sighex) {
cert = new ns1.Certificate({'tbscertobj': o});
cert.setSignatureHex(param.sighex);
}
return cert.getPEMString();
};
/*
org.bouncycastle.asn1.x500
AttributeTypeAndValue
DirectoryString
RDN
X500Name
X500NameBuilder
org.bouncycastleasn1.x509
TBSCertificate
*/