1 /* asn1x509-1.1.12.js (c) 2013-2020 Kenji Urushima | kjur.github.com/jsrsasign/license
  2  */
  3 /*
  4  * asn1x509.js - ASN.1 DER encoder classes for X.509 certificate
  5  *
  6  * Copyright (c) 2013-2020 Kenji Urushima (kenji.urushima@gmail.com)
  7  *
  8  * This software is licensed under the terms of the MIT License.
  9  * https://kjur.github.io/jsrsasign/license
 10  *
 11  * The above copyright and license notice shall be
 12  * included in all copies or substantial portions of the Software.
 13  */
 14 
 15 /**
 16  * @fileOverview
 17  * @name asn1x509-1.0.js
 18  * @author Kenji Urushima kenji.urushima@gmail.com
 19  * @version jsrsasign 8.0.23 asn1x509 1.1.12 (2020-Apr-06)
 20  * @since jsrsasign 2.1
 21  * @license <a href="https://kjur.github.io/jsrsasign/license/">MIT License</a>
 22  */
 23 
 24 /**
 25  * kjur's class library name space
 26  * // already documented in asn1-1.0.js
 27  * @name KJUR
 28  * @namespace kjur's class library name space
 29  */
 30 if (typeof KJUR == "undefined" || !KJUR) KJUR = {};
 31 
 32 /**
 33  * kjur's ASN.1 class library name space
 34  * // already documented in asn1-1.0.js
 35  * @name KJUR.asn1
 36  * @namespace
 37  */
 38 if (typeof KJUR.asn1 == "undefined" || !KJUR.asn1) KJUR.asn1 = {};
 39 
 40 /**
 41  * kjur's ASN.1 class for X.509 certificate library name space
 42  * <p>
 43  * <h4>FEATURES</h4>
 44  * <ul>
 45  * <li>easily issue any kind of certificate</li>
 46  * <li>APIs are very similar to BouncyCastle library ASN.1 classes. So easy to learn.</li>
 47  * </ul>
 48  * </p>
 49  * <h4>PROVIDED CLASSES</h4>
 50  * <ul>
 51  * <li>{@link KJUR.asn1.x509.Certificate}</li>
 52  * <li>{@link KJUR.asn1.x509.TBSCertificate}</li>
 53  * <li>{@link KJUR.asn1.x509.Extension}</li>
 54  * <li>{@link KJUR.asn1.x509.X500Name}</li>
 55  * <li>{@link KJUR.asn1.x509.RDN}</li>
 56  * <li>{@link KJUR.asn1.x509.AttributeTypeAndValue}</li>
 57  * <li>{@link KJUR.asn1.x509.SubjectPublicKeyInfo}</li>
 58  * <li>{@link KJUR.asn1.x509.AlgorithmIdentifier}</li>
 59  * <li>{@link KJUR.asn1.x509.GeneralName}</li>
 60  * <li>{@link KJUR.asn1.x509.GeneralNames}</li>
 61  * <li>{@link KJUR.asn1.x509.DistributionPointName}</li>
 62  * <li>{@link KJUR.asn1.x509.DistributionPoint}</li>
 63  * <li>{@link KJUR.asn1.x509.CRL}</li>
 64  * <li>{@link KJUR.asn1.x509.TBSCertList}</li>
 65  * <li>{@link KJUR.asn1.x509.CRLEntry}</li>
 66  * <li>{@link KJUR.asn1.x509.OID}</li>
 67  * </ul>
 68  * <h4>SUPPORTED EXTENSIONS</h4>
 69  * <ul>
 70  * <li>{@link KJUR.asn1.x509.BasicConstraints}</li>
 71  * <li>{@link KJUR.asn1.x509.KeyUsage}</li>
 72  * <li>{@link KJUR.asn1.x509.CRLDistributionPoints}</li>
 73  * <li>{@link KJUR.asn1.x509.CertificatePolicies}</li>
 74  * <li>{@link KJUR.asn1.x509.ExtKeyUsage}</li>
 75  * <li>{@link KJUR.asn1.x509.AuthorityKeyIdentifier}</li>
 76  * <li>{@link KJUR.asn1.x509.SubjectKeyIdentifier}</li>
 77  * <li>{@link KJUR.asn1.x509.AuthorityInfoAccess}</li>
 78  * <li>{@link KJUR.asn1.x509.SubjectAltName}</li>
 79  * <li>{@link KJUR.asn1.x509.IssuerAltName}</li>
 80  * <li>{@link KJUR.asn1.x509.CertificatePolicies}</li>
 81  * </ul>
 82  * NOTE1: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.<br/>
 83  * NOTE2: SubjectAltName and IssuerAltName supported since 
 84  * jsrsasign 6.2.3 asn1x509 1.0.19.<br/>
 85  * NOTE3: CeritifcatePolicies supported supported since
 86  * jsrsasign 8.0.23 asn1x509 1.1.12<br/>
 87  * @name KJUR.asn1.x509
 88  * @namespace
 89  */
 90 if (typeof KJUR.asn1.x509 == "undefined" || !KJUR.asn1.x509) KJUR.asn1.x509 = {};
 91 
 92 // === BEGIN Certificate ===================================================
 93 
 94 /**
 95  * X.509 Certificate class to sign and generate hex encoded certificate
 96  * @name KJUR.asn1.x509.Certificate
 97  * @class X.509 Certificate class to sign and generate hex encoded certificate
 98  * @param {Array} params associative array of parameters (ex. {'tbscertobj': obj, 'prvkeyobj': key})
 99  * @extends KJUR.asn1.ASN1Object
100  * @description
101  * <br/>
102  * As for argument 'params' for constructor, you can specify one of
103  * following properties:
104  * <ul>
105  * <li>tbscertobj - specify {@link KJUR.asn1.x509.TBSCertificate} object</li>
106  * <li>prvkeyobj - specify {@link RSAKey}, {@link KJUR.crypto.ECDSA} or {@link KJUR.crypto.DSA} object for CA private key to sign the certificate</li>
107  * </ul>
108  * NOTE1: 'params' can be omitted.<br/>
109  * NOTE2: DSA/ECDSA is also supported for CA signging key from asn1x509 1.0.6.
110  * @example
111  * var caKey = KEYUTIL.getKey(caKeyPEM); // CA's private key
112  * var cert = new KJUR.asn1x509.Certificate({'tbscertobj': tbs, 'prvkeyobj': caKey});
113  * cert.sign(); // issue certificate by CA's private key
114  * var certPEM = cert.getPEMString();
115  *
116  * // Certificate  ::=  SEQUENCE  {
117  * //     tbsCertificate       TBSCertificate,
118  * //     signatureAlgorithm   AlgorithmIdentifier,
119  * //     signature            BIT STRING  }
120  */
121 KJUR.asn1.x509.Certificate = function(params) {
122     KJUR.asn1.x509.Certificate.superclass.constructor.call(this);
123     var asn1TBSCert = null,
124 	asn1SignatureAlg = null,
125 	asn1Sig = null,
126 	hexSig = null,
127         prvKey = null,
128 	_KJUR = KJUR,
129 	_KJUR_crypto = _KJUR.crypto,
130 	_KJUR_asn1 = _KJUR.asn1,
131 	_DERSequence = _KJUR_asn1.DERSequence,
132 	_DERBitString = _KJUR_asn1.DERBitString;
133 
134     /**
135      * sign TBSCertificate and set signature value internally
136      * @name sign
137      * @memberOf KJUR.asn1.x509.Certificate#
138      * @function
139      * @description
140      * @example
141      * var cert = new KJUR.asn1.x509.Certificate({tbscertobj: tbs, prvkeyobj: prvKey});
142      * cert.sign();
143      */
144     this.sign = function() {
145         this.asn1SignatureAlg = this.asn1TBSCert.asn1SignatureAlg;
146 	
147         var sig = new KJUR.crypto.Signature({alg: this.asn1SignatureAlg.nameAlg});
148         sig.init(this.prvKey);
149         sig.updateHex(this.asn1TBSCert.getEncodedHex());
150         this.hexSig = sig.sign();
151 
152         this.asn1Sig = new _DERBitString({'hex': '00' + this.hexSig});
153 
154         var seq = new _DERSequence({'array': [this.asn1TBSCert,
155                                               this.asn1SignatureAlg,
156                                               this.asn1Sig]});
157         this.hTLV = seq.getEncodedHex();
158         this.isModified = false;
159     };
160 
161     /**
162      * set signature value internally by hex string
163      * @name setSignatureHex
164      * @memberOf KJUR.asn1.x509.Certificate#
165      * @function
166      * @since asn1x509 1.0.8
167      * @description
168      * @example
169      * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs});
170      * cert.setSignatureHex('01020304');
171      */
172     this.setSignatureHex = function(sigHex) {
173         this.asn1SignatureAlg = this.asn1TBSCert.asn1SignatureAlg;
174         this.hexSig = sigHex;
175         this.asn1Sig = new _DERBitString({'hex': '00' + this.hexSig});
176 
177         var seq = new _DERSequence({'array': [this.asn1TBSCert,
178                                               this.asn1SignatureAlg,
179                                               this.asn1Sig]});
180         this.hTLV = seq.getEncodedHex();
181         this.isModified = false;
182     };
183 
184     this.getEncodedHex = function() {
185         if (this.isModified == false && this.hTLV != null) return this.hTLV;
186         throw "not signed yet";
187     };
188 
189     /**
190      * get PEM formatted certificate string after signed
191      * @name getPEMString
192      * @memberOf KJUR.asn1.x509.Certificate#
193      * @function
194      * @return PEM formatted string of certificate
195      * @description
196      * @example
197      * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs, 'prvkeyobj': prvKey});
198      * cert.sign();
199      * var sPEM = cert.getPEMString();
200      */
201     this.getPEMString = function() {
202 	var pemBody = hextob64nl(this.getEncodedHex());
203         return "-----BEGIN CERTIFICATE-----\r\n" + 
204 	    pemBody + 
205 	    "\r\n-----END CERTIFICATE-----\r\n";
206     };
207 
208     if (params !== undefined) {
209         if (params.tbscertobj !== undefined) {
210             this.asn1TBSCert = params.tbscertobj;
211         }
212         if (params.prvkeyobj !== undefined) {
213             this.prvKey = params.prvkeyobj;
214         }
215     }
216 };
217 YAHOO.lang.extend(KJUR.asn1.x509.Certificate, KJUR.asn1.ASN1Object);
218 
219 /**
220  * ASN.1 TBSCertificate structure class
221  * @name KJUR.asn1.x509.TBSCertificate
222  * @class ASN.1 TBSCertificate structure class
223  * @param {Array} params associative array of parameters (ex. {})
224  * @extends KJUR.asn1.ASN1Object
225  * @description
226  * <br/>
227  * <h4>EXAMPLE</h4>
228  * @example
229  *  var o = new KJUR.asn1.x509.TBSCertificate();
230  *  o.setSerialNumberByParam({'int': 4});
231  *  o.setSignatureAlgByParam({'name': 'SHA1withRSA'});
232  *  o.setIssuerByParam({'str': '/C=US/O=a'});
233  *  o.setNotBeforeByParam({'str': '130504235959Z'});
234  *  o.setNotAfterByParam({'str': '140504235959Z'});
235  *  o.setSubjectByParam({'str': '/C=US/CN=b'});
236  *  o.setSubjectPublicKey(rsaPubKey);
237  *  o.appendExtension(new KJUR.asn1.x509.BasicConstraints({'cA':true}));
238  *  o.appendExtension(new KJUR.asn1.x509.KeyUsage({'bin':'11'}));
239  */
240 KJUR.asn1.x509.TBSCertificate = function(params) {
241     KJUR.asn1.x509.TBSCertificate.superclass.constructor.call(this);
242 
243     var _KJUR = KJUR,
244 	_KJUR_asn1 = _KJUR.asn1,
245 	_DERSequence = _KJUR_asn1.DERSequence,
246 	_DERInteger = _KJUR_asn1.DERInteger,
247 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
248 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
249 	_Time = _KJUR_asn1_x509.Time,
250 	_X500Name = _KJUR_asn1_x509.X500Name,
251 	_SubjectPublicKeyInfo = _KJUR_asn1_x509.SubjectPublicKeyInfo;
252 
253     this._initialize = function() {
254         this.asn1Array = new Array();
255 
256         this.asn1Version =
257             new _DERTaggedObject({'obj': new _DERInteger({'int': 2})});
258         this.asn1SerialNumber = null;
259         this.asn1SignatureAlg = null;
260         this.asn1Issuer = null;
261         this.asn1NotBefore = null;
262         this.asn1NotAfter = null;
263         this.asn1Subject = null;
264         this.asn1SubjPKey = null;
265         this.extensionsArray = new Array();
266     };
267 
268     /**
269      * set serial number field by parameter
270      * @name setSerialNumberByParam
271      * @memberOf KJUR.asn1.x509.TBSCertificate#
272      * @function
273      * @param {Array} intParam DERInteger param
274      * @description
275      * @example
276      * tbsc.setSerialNumberByParam({'int': 3});
277      */
278     this.setSerialNumberByParam = function(intParam) {
279         this.asn1SerialNumber = new _DERInteger(intParam);
280     };
281 
282     /**
283      * set signature algorithm field by parameter
284      * @name setSignatureAlgByParam
285      * @memberOf KJUR.asn1.x509.TBSCertificate#
286      * @function
287      * @param {Array} algIdParam AlgorithmIdentifier parameter
288      * @see {@link KJUR.asn1.x509.AlgorithmIdentifier}
289      * @description
290      * @example
291      * tbsc.setSignatureAlgByParam({'name': 'SHA1withRSA'});
292      */
293     this.setSignatureAlgByParam = function(algIdParam) {
294         this.asn1SignatureAlg = new _KJUR_asn1_x509.AlgorithmIdentifier(algIdParam);
295     };
296 
297     /**
298      * set issuer name field by parameter
299      * @name setIssuerByParam
300      * @memberOf KJUR.asn1.x509.TBSCertificate#
301      * @function
302      * @param {Array} x500NameParam X500Name parameter
303      * @description
304      * @example
305      * tbsc.setIssuerParam({'str': '/C=US/CN=b'});
306      * @see KJUR.asn1.x509.X500Name
307      */
308     this.setIssuerByParam = function(x500NameParam) {
309         this.asn1Issuer = new _X500Name(x500NameParam);
310     };
311 
312     /**
313      * set notBefore field by parameter
314      * @name setNotBeforeByParam
315      * @memberOf KJUR.asn1.x509.TBSCertificate#
316      * @function
317      * @param {Array} timeParam Time parameter
318      * @description
319      * @example
320      * tbsc.setNotBeforeByParam({'str': '130508235959Z'});
321      * @see KJUR.asn1.x509.Time
322      */
323     this.setNotBeforeByParam = function(timeParam) {
324         this.asn1NotBefore = new _Time(timeParam);
325     };
326 
327     /**
328      * set notAfter field by parameter
329      * @name setNotAfterByParam
330      * @memberOf KJUR.asn1.x509.TBSCertificate#
331      * @function
332      * @param {Array} timeParam Time parameter
333      * @description
334      * @example
335      * tbsc.setNotAfterByParam({'str': '130508235959Z'});
336      * @see KJUR.asn1.x509.Time
337      */
338     this.setNotAfterByParam = function(timeParam) {
339         this.asn1NotAfter = new _Time(timeParam);
340     };
341 
342     /**
343      * set subject name field by parameter
344      * @name setSubjectByParam
345      * @memberOf KJUR.asn1.x509.TBSCertificate#
346      * @function
347      * @param {Array} x500NameParam X500Name parameter
348      * @description
349      * @example
350      * tbsc.setSubjectParam({'str': '/C=US/CN=b'});
351      * @see KJUR.asn1.x509.X500Name
352      */
353     this.setSubjectByParam = function(x500NameParam) {
354         this.asn1Subject = new _X500Name(x500NameParam);
355     };
356 
357     /**
358      * set subject public key info field by key object
359      * @name setSubjectPublicKey
360      * @memberOf KJUR.asn1.x509.TBSCertificate#
361      * @function
362      * @param {Array} param {@link KJUR.asn1.x509.SubjectPublicKeyInfo} class constructor parameter
363      * @description
364      * @example
365      * tbsc.setSubjectPublicKey(keyobj);
366      * @see KJUR.asn1.x509.SubjectPublicKeyInfo
367      */
368     this.setSubjectPublicKey = function(param) {
369         this.asn1SubjPKey = new _SubjectPublicKeyInfo(param);
370     };
371 
372     /**
373      * set subject public key info by RSA/ECDSA/DSA key parameter
374      * @name setSubjectPublicKeyByGetKey
375      * @memberOf KJUR.asn1.x509.TBSCertificate
376      * @function
377      * @param {Object} keyParam public key parameter which passed to {@link KEYUTIL.getKey} argument
378      * @description
379      * @example
380      * tbsc.setSubjectPublicKeyByGetKeyParam(certPEMString); // or
381      * tbsc.setSubjectPublicKeyByGetKeyParam(pkcs8PublicKeyPEMString); // or
382      * tbsc.setSubjectPublicKeyByGetKeyParam(kjurCryptoECDSAKeyObject); // et.al.
383      * @see KJUR.asn1.x509.SubjectPublicKeyInfo
384      * @see KEYUTIL.getKey
385      * @since asn1x509 1.0.6
386      */
387     this.setSubjectPublicKeyByGetKey = function(keyParam) {
388         var keyObj = KEYUTIL.getKey(keyParam);
389         this.asn1SubjPKey = new _SubjectPublicKeyInfo(keyObj);
390     };
391 
392     /**
393      * append X.509v3 extension to this object
394      * @name appendExtension
395      * @memberOf KJUR.asn1.x509.TBSCertificate#
396      * @function
397      * @param {Extension} extObj X.509v3 Extension object
398      * @description
399      * @example
400      * tbsc.appendExtension(new KJUR.asn1.x509.BasicConstraints({'cA':true, 'critical': true}));
401      * tbsc.appendExtension(new KJUR.asn1.x509.KeyUsage({'bin':'11'}));
402      * @see KJUR.asn1.x509.Extension
403      */
404     this.appendExtension = function(extObj) {
405         this.extensionsArray.push(extObj);
406     };
407 
408     /**
409      * append X.509v3 extension to this object by name and parameters
410      * @name appendExtensionByName
411      * @memberOf KJUR.asn1.x509.TBSCertificate#
412      * @function
413      * @param {name} name name of X.509v3 Extension object
414      * @param {Array} extParams parameters as argument of Extension constructor.
415      * @description
416      * This method adds a X.509v3 extension specified by name 
417      * and extParams to internal extension array of X.509v3 extension objects.
418      * Here is supported names of extension:
419      * <ul>
420      * <li>BasicConstraints - {@link KJUR.asn1.x509.BasicConstraints}</li>
421      * <li>KeyUsage - {@link KJUR.asn1.x509.KeyUsage}</li>
422      * <li>CRLDistributionPoints - {@link KJUR.asn1.x509.CRLDistributionPoints}</li>
423      * <li>CertificatePolicies - {@link KJUR.asn1.x509.CertificatePolicies}</li>
424      * <li>ExtKeyUsage - {@link KJUR.asn1.x509.ExtKeyUsage}</li>
425      * <li>AuthorityKeyIdentifier - {@link KJUR.asn1.x509.AuthorityKeyIdentifier}</li>
426      * <li>SubjectKeyIdentifier - {@link KJUR.asn1.x509.SubjectKeyIdentifier}</li>
427      * <li>AuthorityInfoAccess - {@link KJUR.asn1.x509.AuthorityInfoAccess}</li>
428      * <li>SubjectAltName - {@link KJUR.asn1.x509.SubjectAltName}</li>
429      * <li>IssuerAltName - {@link KJUR.asn1.x509.IssuerAltName}</li>
430      * <li>CertificatePolicies - {@link KJUR.asn1.x509.CertificatePolicies}</li>
431      * </ul>
432      * @example
433      * var o = new KJUR.asn1.x509.TBSCertificate();
434      * o.appendExtensionByName('BasicConstraints', {'cA':true, 'critical': true});
435      * o.appendExtensionByName('KeyUsage', {'bin':'11'});
436      * o.appendExtensionByName('CRLDistributionPoints', {uri: 'http://aaa.com/a.crl'});
437      * o.appendExtensionByName('ExtKeyUsage', {array: [{name: 'clientAuth'}]});
438      * o.appendExtensionByName('AuthorityKeyIdentifier', {kid: '1234ab..'});
439      * o.appendExtensionByName('SubjectKeyIdentifier', {kid: '1234ab..'});
440      * o.appendExtensionByName('AuthorityInfoAccess', {array: [{accessMethod:{oid:...},accessLocation:{uri:...}}]});
441      * @see KJUR.asn1.x509.Extension
442      */
443     this.appendExtensionByName = function(name, extParams) {
444 	KJUR.asn1.x509.Extension.appendByNameToArray(name,
445 						     extParams,
446 						     this.extensionsArray);
447     };
448 
449     this.getEncodedHex = function() {
450         if (this.asn1NotBefore == null || this.asn1NotAfter == null)
451             throw "notBefore and/or notAfter not set";
452         var asn1Validity =
453             new _DERSequence({'array':[this.asn1NotBefore, this.asn1NotAfter]});
454 
455         this.asn1Array = new Array();
456 
457         this.asn1Array.push(this.asn1Version);
458         this.asn1Array.push(this.asn1SerialNumber);
459         this.asn1Array.push(this.asn1SignatureAlg);
460         this.asn1Array.push(this.asn1Issuer);
461         this.asn1Array.push(asn1Validity);
462         this.asn1Array.push(this.asn1Subject);
463         this.asn1Array.push(this.asn1SubjPKey);
464 
465         if (this.extensionsArray.length > 0) {
466             var extSeq = new _DERSequence({"array": this.extensionsArray});
467             var extTagObj = new _DERTaggedObject({'explicit': true,
468                                                   'tag': 'a3',
469                                                   'obj': extSeq});
470             this.asn1Array.push(extTagObj);
471         }
472 
473         var o = new _DERSequence({"array": this.asn1Array});
474         this.hTLV = o.getEncodedHex();
475         this.isModified = false;
476         return this.hTLV;
477     };
478 
479     this._initialize();
480 };
481 YAHOO.lang.extend(KJUR.asn1.x509.TBSCertificate, KJUR.asn1.ASN1Object);
482 
483 // === END   TBSCertificate ===================================================
484 
485 // === BEGIN X.509v3 Extensions Related =======================================
486 
487 /**
488  * base Extension ASN.1 structure class
489  * @name KJUR.asn1.x509.Extension
490  * @class base Extension ASN.1 structure class
491  * @param {Array} params associative array of parameters (ex. {'critical': true})
492  * @extends KJUR.asn1.ASN1Object
493  * @description
494  * @example
495  * // Extension  ::=  SEQUENCE  {
496  * //     extnID      OBJECT IDENTIFIER,
497  * //     critical    BOOLEAN DEFAULT FALSE,
498  * //     extnValue   OCTET STRING  }
499  */
500 KJUR.asn1.x509.Extension = function(params) {
501     KJUR.asn1.x509.Extension.superclass.constructor.call(this);
502     var asn1ExtnValue = null,
503 	_KJUR = KJUR,
504 	_KJUR_asn1 = _KJUR.asn1,
505 	_DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
506 	_DEROctetString = _KJUR_asn1.DEROctetString,
507 	_DERBitString = _KJUR_asn1.DERBitString,
508 	_DERBoolean = _KJUR_asn1.DERBoolean,
509 	_DERSequence = _KJUR_asn1.DERSequence;
510 
511     this.getEncodedHex = function() {
512         var asn1Oid = new _DERObjectIdentifier({'oid': this.oid});
513         var asn1EncapExtnValue =
514             new _DEROctetString({'hex': this.getExtnValueHex()});
515 
516         var asn1Array = new Array();
517         asn1Array.push(asn1Oid);
518         if (this.critical) asn1Array.push(new _DERBoolean());
519         asn1Array.push(asn1EncapExtnValue);
520 
521         var asn1Seq = new _DERSequence({'array': asn1Array});
522         return asn1Seq.getEncodedHex();
523     };
524 
525     this.critical = false;
526     if (params !== undefined) {
527         if (params.critical !== undefined) {
528             this.critical = params.critical;
529         }
530     }
531 };
532 YAHOO.lang.extend(KJUR.asn1.x509.Extension, KJUR.asn1.ASN1Object);
533 
534 /**
535  * append X.509v3 extension to any specified array<br/>
536  * @name appendByNameToArray
537  * @memberOf KJUR.asn1.x509.Extension
538  * @function
539  * @param {String} name X.509v3 extension name
540  * @param {Object} extParams associative array of extension parameters
541  * @param {Array} a array to add specified extension
542  * @see KJUR.asn1.x509.Extension
543  * @since jsrsasign 6.2.3 asn1x509 1.0.19
544  * @description
545  * This static function add a X.509v3 extension specified by name and extParams to
546  * array 'a' so that 'a' will be an array of X.509v3 extension objects.
547  * See {@link KJUR.asn1.x509.TBSCertificate#appendExtensionByName}
548  * for supported names of extensions.
549  * @example
550  * var a = new Array();
551  * KJUR.asn1.x509.Extension.appendByNameToArray("BasicConstraints", {'cA':true, 'critical': true}, a);
552  * KJUR.asn1.x509.Extension.appendByNameToArray("KeyUsage", {'bin':'11'}, a);
553  */
554 KJUR.asn1.x509.Extension.appendByNameToArray = function(name, extParams, a) {
555     var _lowname = name.toLowerCase(),
556 	_KJUR_asn1_x509 = KJUR.asn1.x509;
557     
558     if (_lowname == "basicconstraints") {
559         var extObj = new _KJUR_asn1_x509.BasicConstraints(extParams);
560         a.push(extObj);
561     } else if (_lowname == "keyusage") {
562         var extObj = new _KJUR_asn1_x509.KeyUsage(extParams);
563         a.push(extObj);
564     } else if (_lowname == "crldistributionpoints") {
565         var extObj = new _KJUR_asn1_x509.CRLDistributionPoints(extParams);
566         a.push(extObj);
567     } else if (_lowname == "extkeyusage") {
568         var extObj = new _KJUR_asn1_x509.ExtKeyUsage(extParams);
569         a.push(extObj);
570     } else if (_lowname == "authoritykeyidentifier") {
571         var extObj = new _KJUR_asn1_x509.AuthorityKeyIdentifier(extParams);
572         a.push(extObj);
573     } else if (_lowname == "subjectkeyidentifier") {
574         var extObj = new _KJUR_asn1_x509.SubjectKeyIdentifier(extParams);
575         a.push(extObj);
576     } else if (_lowname == "authorityinfoaccess") {
577         var extObj = new _KJUR_asn1_x509.AuthorityInfoAccess(extParams);
578         a.push(extObj);
579     } else if (_lowname == "subjectaltname") {
580         var extObj = new _KJUR_asn1_x509.SubjectAltName(extParams);
581         a.push(extObj);
582     } else if (_lowname == "issueraltname") {
583         var extObj = new _KJUR_asn1_x509.IssuerAltName(extParams);
584         a.push(extObj);
585     } else if (_lowname == "certificatepolicies") {
586         var extObj = new _KJUR_asn1_x509.CertificatePolicies(extParams);
587         a.push(extObj);
588     } else {
589         throw new Error("unsupported extension name: " + name);
590     }
591 };
592 
593 /**
594  * KeyUsage ASN.1 structure class
595  * @name KJUR.asn1.x509.KeyUsage
596  * @class KeyUsage ASN.1 structure class
597  * @param {Array} params associative array of parameters (ex. {'bin': '11', 'critical': true})
598  * @extends KJUR.asn1.x509.Extension
599  * @description
600  * This class is for <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.3" target="_blank">KeyUsage</a> X.509v3 extension.
601  * <pre>
602  * id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }
603  * KeyUsage ::= BIT STRING {
604  *   digitalSignature   (0),
605  *   nonRepudiation     (1),
606  *   keyEncipherment    (2),
607  *   dataEncipherment   (3),
608  *   keyAgreement       (4),
609  *   keyCertSign        (5),
610  *   cRLSign            (6),
611  *   encipherOnly       (7),
612  *   decipherOnly       (8) }
613  * </pre><br/>
614  * NOTE: 'names' parameter is supprted since jsrsasign 8.0.14.
615  * @example
616  * o = new KJUR.asn1.x509.KeyUsage({bin: "11"});
617  * o = new KJUR.asn1.x509.KeyUsage({critical: true, bin: "11"});
618  * o = new KJUR.asn1.x509.KeyUsage({names: ['digitalSignature', 'keyAgreement']});
619  */
620 KJUR.asn1.x509.KeyUsage = function(params) {
621     KJUR.asn1.x509.KeyUsage.superclass.constructor.call(this, params);
622     var _KEYUSAGE_NAME = X509.KEYUSAGE_NAME;
623 
624     this.getExtnValueHex = function() {
625         return this.asn1ExtnValue.getEncodedHex();
626     };
627 
628     this.oid = "2.5.29.15";
629     if (params !== undefined) {
630         if (params.bin !== undefined) {
631             this.asn1ExtnValue = new KJUR.asn1.DERBitString(params);
632         }
633 	if (params.names !== undefined &&
634 	    params.names.length !== undefined) {
635 	    var names = params.names;
636 	    var s = "000000000";
637 	    for (var i = 0; i < names.length; i++) {
638 		for (var j = 0; j < _KEYUSAGE_NAME.length; j++) {
639 		    if (names[i] === _KEYUSAGE_NAME[j]) {
640 			s = s.substring(0, j) + '1' + 
641 			    s.substring(j + 1, s.length);
642 		    }
643 		}
644 	    }
645             this.asn1ExtnValue = new KJUR.asn1.DERBitString({bin: s});
646 	}
647     }
648 };
649 YAHOO.lang.extend(KJUR.asn1.x509.KeyUsage, KJUR.asn1.x509.Extension);
650 
651 /**
652  * BasicConstraints ASN.1 structure class
653  * @name KJUR.asn1.x509.BasicConstraints
654  * @class BasicConstraints ASN.1 structure class
655  * @param {Array} params associative array of parameters (ex. {'cA': true, 'critical': true})
656  * @extends KJUR.asn1.x509.Extension
657  * @description
658  * @example
659  */
660 KJUR.asn1.x509.BasicConstraints = function(params) {
661     KJUR.asn1.x509.BasicConstraints.superclass.constructor.call(this, params);
662     var cA = false;
663     var pathLen = -1;
664 
665     this.getExtnValueHex = function() {
666         var asn1Array = new Array();
667         if (this.cA) asn1Array.push(new KJUR.asn1.DERBoolean());
668         if (this.pathLen > -1)
669             asn1Array.push(new KJUR.asn1.DERInteger({'int': this.pathLen}));
670         var asn1Seq = new KJUR.asn1.DERSequence({'array': asn1Array});
671         this.asn1ExtnValue = asn1Seq;
672         return this.asn1ExtnValue.getEncodedHex();
673     };
674 
675     this.oid = "2.5.29.19";
676     this.cA = false;
677     this.pathLen = -1;
678     if (params !== undefined) {
679         if (params.cA !== undefined) {
680             this.cA = params.cA;
681         }
682         if (params.pathLen !== undefined) {
683             this.pathLen = params.pathLen;
684         }
685     }
686 };
687 YAHOO.lang.extend(KJUR.asn1.x509.BasicConstraints, KJUR.asn1.x509.Extension);
688 
689 /**
690  * CRLDistributionPoints ASN.1 structure class
691  * @name KJUR.asn1.x509.CRLDistributionPoints
692  * @class CRLDistributionPoints ASN.1 structure class
693  * @param {Array} params associative array of parameters (ex. {'uri': 'http://a.com/', 'critical': true})
694  * @extends KJUR.asn1.x509.Extension
695  * @description
696  * <pre>
697  * id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::=  { id-ce 31 }
698  *
699  * CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
700  *
701  * DistributionPoint ::= SEQUENCE {
702  *      distributionPoint       [0]     DistributionPointName OPTIONAL,
703  *      reasons                 [1]     ReasonFlags OPTIONAL,
704  *      cRLIssuer               [2]     GeneralNames OPTIONAL }
705  *
706  * DistributionPointName ::= CHOICE {
707  *      fullName                [0]     GeneralNames,
708  *      nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
709  * 
710  * ReasonFlags ::= BIT STRING {
711  *      unused                  (0),
712  *      keyCompromise           (1),
713  *      cACompromise            (2),
714  *      affiliationChanged      (3),
715  *      superseded              (4),
716  *      cessationOfOperation    (5),
717  *      certificateHold         (6),
718  *      privilegeWithdrawn      (7),
719  *      aACompromise            (8) }
720  * </pre>
721  * @example
722  */
723 KJUR.asn1.x509.CRLDistributionPoints = function(params) {
724     KJUR.asn1.x509.CRLDistributionPoints.superclass.constructor.call(this, params);
725     var _KJUR = KJUR,
726 	_KJUR_asn1 = _KJUR.asn1,
727 	_KJUR_asn1_x509 = _KJUR_asn1.x509;
728 
729     this.getExtnValueHex = function() {
730         return this.asn1ExtnValue.getEncodedHex();
731     };
732 
733     this.setByDPArray = function(dpArray) {
734         this.asn1ExtnValue = new _KJUR_asn1.DERSequence({'array': dpArray});
735     };
736 
737     this.setByOneURI = function(uri) {
738         var gn1 = new _KJUR_asn1_x509.GeneralNames([{'uri': uri}]);
739         var dpn1 = new _KJUR_asn1_x509.DistributionPointName(gn1);
740         var dp1 = new _KJUR_asn1_x509.DistributionPoint({'dpobj': dpn1});
741         this.setByDPArray([dp1]);
742     };
743 
744     this.oid = "2.5.29.31";
745     if (params !== undefined) {
746         if (params.array !== undefined) {
747             this.setByDPArray(params.array);
748         } else if (params.uri !== undefined) {
749             this.setByOneURI(params.uri);
750         }
751     }
752 };
753 YAHOO.lang.extend(KJUR.asn1.x509.CRLDistributionPoints, KJUR.asn1.x509.Extension);
754 
755 /**
756  * CertificatePolicies ASN.1 structure class
757  * @name KJUR.asn1.x509.CertificatePolicies
758  * @class CertificatePolicies ASN.1 structure class
759  * @param {Array} params associative array of parameters
760  * @extends KJUR.asn1.x509.Extension
761  * @since jsrsasign 8.0.23 asn1x509 1.1.12
762  * @description
763  * This class represents 
764  * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.4">
765  * CertificatePolicies extension defined in RFC 5280 4.2.1.4</a>.
766  * <pre>
767  * id-ce-certificatePolicies OBJECT IDENTIFIER ::=  { id-ce 32 }
768  * CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
769  * </pre>
770  * Its constructor can have following parameters:
771  * <ul>
772  * <li>array - array of {@link KJUR.asn1.x509.PolicyInformation} parameter</li>
773  * <li>critical - boolean: critical flag
774  * </ul>
775  * @example
776  * e1 = new KJUR.asn1.x509.CertificatePolicies({
777  *   array: [
778  *     { policyoid: "1.2.3.4.5",
779  *       array: [
780  *         { cps: "https://example.com/repository" },
781  *         { unotice: {
782  *           noticeref: { // CA SHOULD NOT use this by RFC
783  *             org: {type: "ia5", str: "Sample Org"},
784  *             noticenum: [{int: 5}, {hex: "01af"}]
785  *           },
786  *           exptext: {type: "ia5", str: "Sample Policy"}
787  *         }}
788  *       ]
789  *     }
790  *   ],
791  *   critical: true
792  * });
793  */
794 KJUR.asn1.x509.CertificatePolicies = function(params) {
795     KJUR.asn1.x509.CertificatePolicies.superclass.constructor.call(this, params);
796     var _KJUR = KJUR,
797 	_KJUR_asn1 = _KJUR.asn1,
798 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
799 	_DERSequence = _KJUR_asn1.DERSequence,
800 	_PolicyInformation = _KJUR_asn1_x509.PolicyInformation;
801 
802     this.params = null;
803 
804     this.getExtnValueHex = function() {
805 	var aPI = [];
806 	for (var i = 0; i < this.params.array.length; i++) {
807 	    aPI.push(new _PolicyInformation(this.params.array[i]));
808 	}
809 	var seq = new _DERSequence({array: aPI});
810 	this.asn1ExtnValue = seq;
811         return this.asn1ExtnValue.getEncodedHex();
812     };
813 
814     this.oid = "2.5.29.32";
815     if (params !== undefined) {
816 	this.params = params;
817     }
818 };
819 YAHOO.lang.extend(KJUR.asn1.x509.CertificatePolicies, KJUR.asn1.x509.Extension);
820 
821 /**
822  * PolicyInformation ASN.1 structure class
823  * @name KJUR.asn1.x509.PolicyInformation
824  * @class PolicyInformation ASN.1 structure class
825  * @param {Array} params associative array of parameters
826  * @extends KJUR.asn1.ASN1Object
827  * @since jsrsasign 8.0.23 asn1x509 1.1.12
828  * @description
829  * This class represents 
830  * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.4">
831  * PolicyInformation defined in RFC 5280 4.2.1.4</a>.
832  * <pre>
833  * PolicyInformation ::= SEQUENCE {
834  *      policyIdentifier   CertPolicyId,
835  *      policyQualifiers   SEQUENCE SIZE (1..MAX) OF
836  *                         PolicyQualifierInfo OPTIONAL }
837  * CertPolicyId ::= OBJECT IDENTIFIER
838  * Its constructor can have following parameters:
839  * <ul>
840  * <li>{String}policyoid - policy OID (ex. "1.2.3.4.5")</li>
841  * <li>{Object}array - array of {@link KJUR.asn1.x509.PolicyQualifierInfo}
842  * parameters (OPTIONAL)</li>
843  * </ul>
844  * @example
845  * new KJUR.asn1.x509.PolicyInformation({
846  *   policyoid: "1.2.3.4.5",
847  *   array: [
848  *     { cps: "https://example.com/repository" },
849  *     { unotice: {
850  *       noticeref: { // CA SHOULD NOT use this by RFC
851  *         org: {type: "ia5", str: "Sample Org"},
852  *         noticenum: [{int: 5}, {hex: "01af"}]
853  *       },
854  *       exptext: {type: "ia5", str: "Sample Policy"}
855  *     }}
856  *   ]
857  * })
858  */
859 KJUR.asn1.x509.PolicyInformation = function(params) {
860     KJUR.asn1.x509.PolicyInformation.superclass.constructor.call(this,
861 								 params);
862     var _KJUR_asn1 = KJUR.asn1,
863 	_DERSequence = _KJUR_asn1.DERSequence,
864 	_DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
865 	_PolicyQualifierInfo = _KJUR_asn1.x509.PolicyQualifierInfo;
866 
867     this.params = null;
868 
869     this.getEncodedHex = function() {
870 	if (this.params.policyoid === undefined &&
871 	    this.params.array === undefined)
872 	    throw new Error("parameter oid and array missing");
873 
874 	// policy oid
875 	var a = [new _DERObjectIdentifier({oid: this.params.policyoid})];
876 
877 	// array of ASN1Object of PolicyQualifierInfo
878 	if (this.params.array !== undefined) {
879 	    var aPQI = [];
880 	    for (var i = 0; i < this.params.array.length; i++) {
881 		aPQI.push(new _PolicyQualifierInfo(this.params.array[i]));
882 	    }
883 	    if (aPQI.length > 0) {
884 		a.push(new _DERSequence({array: aPQI}));
885 	    }
886 	}
887 
888 	var seq = new _DERSequence({array: a});
889 	return seq.getEncodedHex();
890     };
891 
892     if (params !== undefined) {
893 	this.params = params;
894     }
895 };
896 YAHOO.lang.extend(KJUR.asn1.x509.PolicyInformation, KJUR.asn1.ASN1Object);
897 
898 /**
899  * PolicyQualifierInfo ASN.1 structure class
900  * @name KJUR.asn1.x509.PolicyQualifierInfo
901  * @class PolicyQualifierInfo ASN.1 structure class
902  * @param {Array} params associative array of parameters
903  * @extends KJUR.asn1.ASN1Object
904  * @since jsrsasign 8.0.23 asn1x509 1.1.12
905  * @description
906  * This class represents 
907  * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.4">
908  * PolicyQualifierInfo defined in RFC 5280 4.2.1.4</a>.
909  * <pre>
910  * PolicyQualifierInfo ::= SEQUENCE {
911  *      policyQualifierId  PolicyQualifierId,
912  *      qualifier          ANY DEFINED BY policyQualifierId }
913  * PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
914  * CPSuri ::= IA5String
915  * </pre>
916  * Its constructor can have one of following two parameters:
917  * <ul>
918  * <li>{String}cps - URI string for CPS</li>
919  * <li>{Object}unotice - {@link KJUR.asn1.x509.UserNotice} parameter</li>
920  * </ul>
921  * @example
922  * new PolicyQualifierInfo({
923  *   cps: "https://example.com/repository/cps"
924  * })
925  *
926  * new PolicyQualifierInfo({
927  *   unotice: {
928  *     noticeref: { // CA SHOULD NOT use this by RFC
929  *       org: {type: "bmp", str: "Sample Org"},
930  *       noticenum: [{int: 3}, {hex: "01af"}]
931  *     },
932  *     exptext: {type: "ia5", str: "Sample Policy"}
933  *   }
934  * })
935  */
936 KJUR.asn1.x509.PolicyQualifierInfo = function(params) {
937     KJUR.asn1.x509.PolicyQualifierInfo.superclass.constructor.call(this,
938 								   params);
939     var _KJUR_asn1 = KJUR.asn1,
940 	_DERSequence = _KJUR_asn1.DERSequence,
941 	_DERIA5String = _KJUR_asn1.DERIA5String,
942 	_DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
943 	_UserNotice = _KJUR_asn1.x509.UserNotice;
944 
945     this.params = null;
946 
947     this.getEncodedHex = function() {
948 	if (this.params.cps !== undefined) {
949 	    var seq = new _DERSequence({array: [
950 		new _DERObjectIdentifier({oid: '1.3.6.1.5.5.7.2.1'}),
951 		new _DERIA5String({str: this.params.cps})
952 	    ]});
953 	    return seq.getEncodedHex();
954 	}
955 	if (this.params.unotice != undefined) {
956 	    var seq = new _DERSequence({array: [
957 		new _DERObjectIdentifier({oid: '1.3.6.1.5.5.7.2.2'}),
958 		new _UserNotice(this.params.unotice)
959 	    ]});
960 	    return seq.getEncodedHex();
961 	}
962     };
963 
964     if (params !== undefined) {
965 	this.params = params;
966     }
967 };
968 YAHOO.lang.extend(KJUR.asn1.x509.PolicyQualifierInfo, KJUR.asn1.ASN1Object);
969 
970 
971 /**
972  * UserNotice ASN.1 structure class
973  * @name KJUR.asn1.x509.UserNotice
974  * @class UserNotice ASN.1 structure class
975  * @param {Array} params associative array of parameters
976  * @extends KJUR.asn1.ASN1Object
977  * @since jsrsasign 8.0.23 asn1x509 1.1.12
978  * @description
979  * This class represents 
980  * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.4">
981  * UserNotice defined in RFC 5280 4.2.1.4</a>.
982  * <pre>
983  * UserNotice ::= SEQUENCE {
984  *      noticeRef        NoticeReference OPTIONAL,
985  *      explicitText     DisplayText OPTIONAL }
986  * </pre>
987  * Its constructor can have following two parameters:
988  * <ul>
989  * <li>{Object}noticeref - {@link KJUR.asn1.x509.NoticeReference} parameter.
990  * This SHALL NOT be set for conforming CA by RFC 5280. (OPTIONAL)</li>
991  * <li>{Object}exptext - explicitText value
992  * by {@link KJUR.asn1.x509.DisplayText} parameter (OPTIONAL)</li>
993  * </ul>
994  * @example
995  * new UserNotice({
996  *   noticeref: {
997  *     org: {type: "bmp", str: "Sample Org"},
998  *     noticenum: [{int: 3}, {hex: "01af"}]
999  *   },
1000  *   exptext: {type: "ia5", str: "Sample Policy"}
1001  * })
1002  */
1003 KJUR.asn1.x509.UserNotice = function(params) {
1004     KJUR.asn1.x509.UserNotice.superclass.constructor.call(this, params);
1005     var _DERSequence = KJUR.asn1.DERSequence,
1006 	_DERInteger = KJUR.asn1.DERInteger,
1007 	_DisplayText = KJUR.asn1.x509.DisplayText,
1008 	_NoticeReference = KJUR.asn1.x509.NoticeReference;
1009 
1010     this.params = null;
1011 
1012     this.getEncodedHex = function() {
1013 	var a = [];
1014 	if (this.params.noticeref !== undefined) {
1015 	    a.push(new _NoticeReference(this.params.noticeref));
1016 	}
1017 	if (this.params.exptext !== undefined) {
1018 	    a.push(new _DisplayText(this.params.exptext));
1019 	}
1020 	var seq = new _DERSequence({array: a});
1021 	return seq.getEncodedHex();
1022     };
1023 
1024     if (params !== undefined) {
1025 	this.params = params;
1026     }
1027 };
1028 YAHOO.lang.extend(KJUR.asn1.x509.UserNotice, KJUR.asn1.ASN1Object);
1029 
1030 /**
1031  * NoticeReference ASN.1 structure class
1032  * @name KJUR.asn1.x509.NoticeReference
1033  * @class NoticeReference ASN.1 structure class
1034  * @param {Array} params associative array of parameters
1035  * @extends KJUR.asn1.ASN1Object
1036  * @since jsrsasign 8.0.23 asn1x509 1.1.12
1037  * @description
1038  * This class represents 
1039  * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.4">
1040  * NoticeReference defined in RFC 5280 4.2.1.4</a>.
1041  * <pre>
1042  * NoticeReference ::= SEQUENCE {
1043  *      organization     DisplayText,
1044  *      noticeNumbers    SEQUENCE OF INTEGER }
1045  * </pre>
1046  * Its constructor can have following two parameters:
1047  * <ul>
1048  * <li>{Object}org - organization by {@link KJUR.asn1.x509.DisplayText}
1049  * parameter.</li>
1050  * <li>{Object}noticenum - noticeNumbers value by an array of
1051  * {@link KJUR.asn1.DERInteger} parameter</li>
1052  * </ul>
1053  * @example
1054  * new NoticeReference({
1055  *   org: {type: "bmp", str: "Sample Org"},
1056  *   noticenum: [{int: 3}, {hex: "01af"}]
1057  * })
1058  */
1059 KJUR.asn1.x509.NoticeReference = function(params) {
1060     KJUR.asn1.x509.NoticeReference.superclass.constructor.call(this, params);
1061     var _DERSequence = KJUR.asn1.DERSequence,
1062 	_DERInteger = KJUR.asn1.DERInteger,
1063 	_DisplayText = KJUR.asn1.x509.DisplayText;
1064 
1065     this.params = null;
1066 
1067     this.getEncodedHex = function() {
1068 	var a = [];
1069 	if (this.params.org !== undefined) {
1070 	    a.push(new _DisplayText(this.params.org));
1071 	}
1072 	if (this.params.noticenum !== undefined) {
1073 	    var aNoticeNum = [];
1074 	    var aNumParam = this.params.noticenum;
1075 	    for (var i = 0; i < aNumParam.length; i++) {
1076 		aNoticeNum.push(new _DERInteger(aNumParam[i]));
1077 	    }
1078 	    a.push(new _DERSequence({array: aNoticeNum}));
1079 	}
1080 	if (a.length == 0) throw new Error("parameter is empty");
1081 	var seq = new _DERSequence({array: a});
1082 	return seq.getEncodedHex();
1083     }
1084 
1085     if (params !== undefined) {
1086 	this.params = params;
1087     }
1088 };
1089 YAHOO.lang.extend(KJUR.asn1.x509.NoticeReference, KJUR.asn1.ASN1Object);
1090 
1091 /**
1092  * DisplayText ASN.1 structure class
1093  * @name KJUR.asn1.x509.DisplayText
1094  * @class DisplayText ASN.1 structure class
1095  * @param {Array} params associative array of parameters
1096  * @extends KJUR.asn1.DERAbstractString
1097  * @since jsrsasign 8.0.23 asn1x509 1.1.12
1098  * @description
1099  * This class represents 
1100  * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.4">
1101  * DisplayText defined in RFC 5280 4.2.1.4</a>.
1102  * <pre>
1103  * -- from RFC 5280 Appendix A
1104  * DisplayText ::= CHOICE {
1105  *      ia5String        IA5String      (SIZE (1..200)),
1106  *      visibleString    VisibleString  (SIZE (1..200)),
1107  *      bmpString        BMPString      (SIZE (1..200)),
1108  *      utf8String       UTF8String     (SIZE (1..200)) }
1109  * </pre>
1110  * {@link KJUR.asn1.DERAbstractString} parameters and methods
1111  * can be used.
1112  * Its constructor can also have following parameter:
1113  * <ul>
1114  * <li>{String} type - DirectoryString type of DisplayText.
1115  * "ia5" for IA5String, "vis" for VisibleString,
1116  * "bmp" for BMPString and "utf8" for UTF8String.
1117  * Default is "utf8". (OPTIONAL)</li>
1118  * </ul>
1119  * @example
1120  * new DisplayText({type: "bmp", str: "Sample Org"})
1121  * new DisplayText({type: "ia5", str: "Sample Org"})
1122  * new DisplayText({str: "Sample Org"})
1123  */
1124 KJUR.asn1.x509.DisplayText = function(params) {
1125     KJUR.asn1.x509.DisplayText.superclass.constructor.call(this, params);
1126 
1127     this.hT = "0c"; // DEFAULT "utf8"
1128 
1129     if (params !== undefined) {
1130 	if (params.type === "ia5") {
1131 	    this.hT = "16";
1132 	} else if (params.type === "vis") {
1133 	    this.hT = "1a";
1134 	} else if (params.type === "bmp") {
1135 	    this.hT = "1e";
1136 	}
1137     }
1138 };
1139 YAHOO.lang.extend(KJUR.asn1.x509.DisplayText, KJUR.asn1.DERAbstractString);
1140 
1141 // =====================================================================
1142 /**
1143  * KeyUsage ASN.1 structure class
1144  * @name KJUR.asn1.x509.ExtKeyUsage
1145  * @class ExtKeyUsage ASN.1 structure class
1146  * @param {Array} params associative array of parameters
1147  * @extends KJUR.asn1.x509.Extension
1148  * @description
1149  * @example
1150  * e1 = new KJUR.asn1.x509.ExtKeyUsage({
1151  *   critical: true,
1152  *   array: [
1153  *     {oid: '2.5.29.37.0'},  // anyExtendedKeyUsage
1154  *     {name: 'clientAuth'}
1155  *   ]
1156  * });
1157  * // id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
1158  * // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
1159  * // KeyPurposeId ::= OBJECT IDENTIFIER
1160  */
1161 KJUR.asn1.x509.ExtKeyUsage = function(params) {
1162     KJUR.asn1.x509.ExtKeyUsage.superclass.constructor.call(this, params);
1163     var _KJUR = KJUR,
1164 	_KJUR_asn1 = _KJUR.asn1;
1165 
1166     this.setPurposeArray = function(purposeArray) {
1167         this.asn1ExtnValue = new _KJUR_asn1.DERSequence();
1168         for (var i = 0; i < purposeArray.length; i++) {
1169             var o = new _KJUR_asn1.DERObjectIdentifier(purposeArray[i]);
1170             this.asn1ExtnValue.appendASN1Object(o);
1171         }
1172     };
1173 
1174     this.getExtnValueHex = function() {
1175         return this.asn1ExtnValue.getEncodedHex();
1176     };
1177 
1178     this.oid = "2.5.29.37";
1179     if (params !== undefined) {
1180         if (params.array !== undefined) {
1181             this.setPurposeArray(params.array);
1182         }
1183     }
1184 };
1185 YAHOO.lang.extend(KJUR.asn1.x509.ExtKeyUsage, KJUR.asn1.x509.Extension);
1186 
1187 /**
1188  * AuthorityKeyIdentifier ASN.1 structure class
1189  * @name KJUR.asn1.x509.AuthorityKeyIdentifier
1190  * @class AuthorityKeyIdentifier ASN.1 structure class
1191  * @param {Array} params associative array of parameters (ex. {kid: {hex: '89ab...'}, critical: true})
1192  * @extends KJUR.asn1.x509.Extension
1193  * @since asn1x509 1.0.8
1194  * @description
1195  * This class represents ASN.1 structure for <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.1">AuthorityKeyIdentifier in RFC 5280</a>.
1196  * Constructor of this class may have following parameters.: 
1197  * <ul>
1198  * <li>kid - When key object (RSA, KJUR.crypto.ECDSA/DSA) or PEM string of authority public key or authcertificate is specified, key identifier will be automatically calculated by the method specified in RFC 5280. When a hexadecimal string is specifed, kid will be set explicitly by it.</li>
1199  * <li>isscert - When PEM string of authority certificate is specified, both authorityCertIssuer and authorityCertSerialNumber will be set by the certificate.</li>
1200  * <li>issuer - {@link KJUR.asn1.x509.X500Name} parameter to specify issuer name explicitly.</li>
1201  * <li>sn - hexadecimal string to specify serial number explicitly.</li>
1202  * <li>critical - boolean to specify criticality of this extension
1203  * however conforming CA must mark this extension as non-critical in RFC 5280.</li>
1204  * </ul>
1205  * 
1206  * <pre>
1207  * d-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 }
1208  * AuthorityKeyIdentifier ::= SEQUENCE {
1209  *    keyIdentifier             [0] KeyIdentifier           OPTIONAL,
1210  *    authorityCertIssuer       [1] GeneralNames            OPTIONAL,
1211  *    authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
1212  * KeyIdentifier ::= OCTET STRING
1213  * </pre>
1214  *
1215  * @example
1216  * // 1. kid by key object
1217  * keyobj = KEYUTIL.getKey("-----BEGIN PUBLIC KEY...");
1218  * e1 = new KJUR.asn1.x509.AuthorityKeyIdentifier({kid: keyobj});
1219  * // 2. kid by PEM string of authority certificate or public key
1220  * e1 = new KJUR.asn1.x509.AuthorityKeyIdentifier({kid: "-----BEGIN..."});
1221  * // 3. specify kid explicitly
1222  * e1 = new KJUR.asn1.x509.AuthorityKeyIdentifier({kid: "8ab1d3..."});
1223  * });
1224  * // 4. issuer and serial number by auhtority PEM certificate
1225  * e1 = new KJUR.asn1.x509.AuthorityKeyIdentifier({isscert: "-----BEGIN..."});
1226  * // 5. issuer and serial number explicitly
1227  * e1 = new KJUR.asn1.x509.AuthorityKeyIdentifier({
1228  *   issuer: {ldapstr: "O=test,C=US"},
1229  *   sn: {hex: "1ac7..."}});
1230  * // 6. combination
1231  * e1 = new KJUR.asn1.x509.AuthorityKeyIdentifier({
1232  *   kid: "-----BEGIN CERTIFICATE...",
1233  *   isscert: "-----BEGIN CERTIFICATE..."});
1234  */
1235 KJUR.asn1.x509.AuthorityKeyIdentifier = function(params) {
1236     KJUR.asn1.x509.AuthorityKeyIdentifier.superclass.constructor.call(this, params);
1237     var _KJUR = KJUR,
1238 	_KJUR_asn1 = _KJUR.asn1,
1239 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
1240 	_GeneralNames = _KJUR_asn1.x509.GeneralNames,
1241 	_isKey = _KJUR.crypto.Util.isKey;
1242 
1243     this.asn1KID = null;
1244     this.asn1CertIssuer = null; // X500Name hTLV
1245     this.asn1CertSN = null;
1246 
1247     this.getExtnValueHex = function() {
1248         var a = new Array();
1249         if (this.asn1KID)
1250             a.push(new _DERTaggedObject({'explicit': false,
1251                                          'tag': '80',
1252                                          'obj': this.asn1KID}));
1253 
1254         if (this.asn1CertIssuer)
1255             a.push(new _DERTaggedObject({'explicit': false,
1256                                          'tag': 'a1',
1257                                          'obj': new _GeneralNames([{dn: this.asn1CertIssuer}])}));
1258 
1259         if (this.asn1CertSN)
1260             a.push(new _DERTaggedObject({'explicit': false,
1261                                          'tag': '82',
1262                                          'obj': this.asn1CertSN}));
1263 
1264         var asn1Seq = new _KJUR_asn1.DERSequence({'array': a});
1265         this.asn1ExtnValue = asn1Seq;
1266         return this.asn1ExtnValue.getEncodedHex();
1267     };
1268 
1269     /**
1270      * set keyIdentifier value by DEROctetString parameter, key object or PEM file
1271      * @name setKIDByParam
1272      * @memberOf KJUR.asn1.x509.AuthorityKeyIdentifier#
1273      * @function
1274      * @param {Array} param parameter to set key identifier
1275      * @since asn1x509 1.0.8
1276      * @description
1277      * This method will set keyIdentifier by param.
1278      * Its key identifier value can be set by following type of param argument:
1279      * <ul>
1280      * <li>{str: "123"} - by raw string</li>
1281      * <li>{hex: "01af..."} - by hexadecimal value</li>
1282      * <li>RSAKey/DSA/ECDSA - by RSAKey, KJUR.crypto.{DSA/ECDSA} public key object.
1283      * key identifier value will be calculated by the method described in
1284      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.2">RFC 5280 4.2.1.2 (1)</a>.
1285      * </li>
1286      * <li>certificate PEM string - extract subjectPublicKeyInfo from specified PEM
1287      * certificate and
1288      * key identifier value will be calculated by the method described in
1289      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.2">RFC 5280 4.2.1.2 (1)</a>.
1290      * <li>PKCS#1/#8 public key PEM string - pem will be converted to a key object and
1291      * to PKCS#8 ASN.1 structure then calculate 
1292      * a key identifier value will be calculated by the method described in
1293      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.2">RFC 5280 4.2.1.2 (1)</a>.
1294      * </ul>
1295      *
1296      * NOTE1: Automatic key identifier calculation is supported
1297      * since jsrsasign 8.0.16.
1298      *
1299      * @see KEYUTIL.getKeyID
1300      * 
1301      * @example
1302      * o = new KJUR.asn1.x509.AuthorityKeyIdentifier();
1303      * // set by hexadecimal string
1304      * o.setKIDByParam({hex: '1ad9...'});
1305      * // set by SubjectPublicKeyInfo of PEM certificate string
1306      * o.setKIDByParam("-----BEGIN CERTIFICATE...");
1307      * // set by PKCS#8 PEM public key string
1308      * o.setKIDByParam("-----BEGIN PUBLIC KEY...");
1309      * // set by public key object
1310      * pubkey = KEYUTIL.getKey("-----BEGIN CERTIFICATE...");
1311      * o.setKIDByParam(pubkey);
1312      */
1313     this.setKIDByParam = function(param) {
1314 	if (param.str !== undefined ||
1315 	    param.hex !== undefined) {
1316 	    this.asn1KID = new KJUR.asn1.DEROctetString(param);
1317 	} else if ((typeof param === "object" &&
1318 		    KJUR.crypto.Util.isKey(param)) ||
1319 		   (typeof param === "string" &&
1320 		    param.indexOf("BEGIN ") != -1)) {
1321 
1322 	    var keyobj = param;
1323 	    if (typeof param === "string") {
1324 		keyobj = KEYUTIL.getKey(param);
1325 	    }
1326 
1327 	    var kid = KEYUTIL.getKeyID(keyobj);
1328 	    this.asn1KID = new KJUR.asn1.DEROctetString({hex: kid});
1329 	}
1330     };
1331 
1332     /**
1333      * set authorityCertIssuer value by X500Name parameter
1334      * @name setCertIssuerByParam
1335      * @memberOf KJUR.asn1.x509.AuthorityKeyIdentifier#
1336      * @function
1337      * @param {Array} param parameter to set issuer name
1338      * @since asn1x509 1.0.8
1339      * @description
1340      * This method will set authorityCertIssuer name by param.
1341      * Issuer name can be set by following type of param argument:
1342      * <ul>
1343      * <li>str/ldapstr/hex/certsubject/certissuer - 
1344      * set issuer by {@link KJUR.asn1.x509.X500Name}
1345      * object with specified parameters.</li>
1346      * <li>PEM CERTIFICATE STRING - extract its subject name from 
1347      * specified issuer PEM certificate and set.
1348      * </ul>
1349      * NOTE1: Automatic authorityCertIssuer setting by certificate
1350      * is supported since jsrsasign 8.0.16.
1351      *
1352      * @see KJUR.asn1.x509.X500Name
1353      * @see KJUR.asn1.x509.GeneralNames
1354      * @see X509.getSubjectHex
1355      *
1356      * @example
1357      * var o = new KJUR.asn1.x509.AuthorityKeyIdentifier();
1358      * // 1. set it by string
1359      * o.setCertIssuerByParam({str: '/C=US/O=Test'});
1360      * // 2. set it by issuer PEM certificate
1361      * o.setCertIssuerByParam("-----BEGIN CERTIFICATE...");
1362      *
1363      */
1364     this.setCertIssuerByParam = function(param) {
1365 	if (param.str !== undefined ||
1366 	    param.ldapstr !== undefined ||
1367 	    param.hex !== undefined ||
1368 	    param.certsubject !== undefined ||
1369 	    param.certissuer !== undefined) {
1370             this.asn1CertIssuer = new KJUR.asn1.x509.X500Name(param);
1371 	} else if (typeof param === "string" &&
1372 		   param.indexOf("BEGIN ") != -1 &&
1373 		   param.indexOf("CERTIFICATE") != -1) {
1374             this.asn1CertIssuer = new KJUR.asn1.x509.X500Name({certissuer: param});
1375 	}
1376     };
1377 
1378     /**
1379      * set authorityCertSerialNumber value
1380      * @name setCertSerialNumberByParam
1381      * @memberOf KJUR.asn1.x509.AuthorityKeyIdentifier#
1382      * @function
1383      * @param {Object} param parameter to set serial number
1384      * @since asn1x509 1.0.8
1385      * @description
1386      * This method will set authorityCertSerialNumber by param.
1387      * Serial number can be set by following type of param argument:
1388      *
1389      * <ul>
1390      * <li>{int: 123} - by integer value</li>
1391      * <li>{hex: "01af"} - by hexadecimal integer value</li>
1392      * <li>{bigint: new BigInteger(...)} - by hexadecimal integer value</li>
1393      * <li>PEM CERTIFICATE STRING - extract serial number from issuer certificate and
1394      * set serial number.
1395      * 
1396      * NOTE1: Automatic authorityCertSerialNumber setting by certificate
1397      * is supported since jsrsasign 8.0.16.
1398      *
1399      * @see X509.getSerialNumberHex
1400      */
1401     this.setCertSNByParam = function(param) {
1402 	if (param.str !== undefined ||
1403 	    param.bigint !== undefined ||
1404 	    param.hex !== undefined) {
1405             this.asn1CertSN = new KJUR.asn1.DERInteger(param);
1406 	} else if (typeof param === "string" &&
1407 		   param.indexOf("BEGIN ") != -1 &&
1408 		   param.indexOf("CERTIFICATE")) {
1409 
1410             var x = new X509();
1411             x.readCertPEM(param);
1412 	    var sn = x.getSerialNumberHex();
1413 	    this.asn1CertSN = new KJUR.asn1.DERInteger({hex: sn});
1414 	}
1415     };
1416 
1417     this.oid = "2.5.29.35";
1418     if (params !== undefined) {
1419         if (params.kid !== undefined) {
1420             this.setKIDByParam(params.kid);
1421         }
1422         if (params.issuer !== undefined) {
1423             this.setCertIssuerByParam(params.issuer);
1424         }
1425         if (params.sn !== undefined) {
1426             this.setCertSNByParam(params.sn);
1427         }
1428 
1429 	if (params.issuersn !== undefined &&
1430 	    typeof params.issuersn === "string" &&
1431 	    params.issuersn.indexOf("BEGIN ") != -1 &&
1432 	    params.issuersn.indexOf("CERTIFICATE")) {
1433 	    this.setCertSNByParam(params.issuersn);
1434 	    this.setCertIssuerByParam(params.issuersn);
1435 	}
1436     }
1437 };
1438 YAHOO.lang.extend(KJUR.asn1.x509.AuthorityKeyIdentifier, KJUR.asn1.x509.Extension);
1439 
1440 /**
1441  * SubjectKeyIdentifier ASN.1 structure class
1442  * @name KJUR.asn1.x509.SubjectKeyIdentifier
1443  * @class SubjectKeyIdentifier ASN.1 structure class
1444  * @param {Array} params associative array of parameters (ex. {kid: {hex: '89ab...'}, critical: true})
1445  * @extends KJUR.asn1.x509.Extension
1446  * @since asn1x509 1.1.7 jsrsasign 8.0.14
1447  * @description
1448  * This class represents ASN.1 structure for <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.2">SubjectKeyIdentifier in RFC 5280</a>.
1449  * Constructor of this class may have following parameters:
1450  * <ul>
1451  * <li>kid - When key object (RSA, KJUR.crypto.ECDSA/DSA) or PEM string of authority public key or authcertificate is specified, key identifier will be automatically calculated by the method specified in RFC 5280. When a hexadecimal string is specifed, kid will be set explicitly by it.</li>
1452  * <li>critical - boolean to specify criticality of this extension
1453  * however conforming CA must mark this extension as non-critical in RFC 5280.</li>
1454  * </ul>
1455  * <pre>
1456  * d-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 14 }
1457  * SubjectKeyIdentifier ::= KeyIdentifier
1458  * KeyIdentifier ::= OCTET STRING
1459  * </pre>
1460  *
1461  * @example
1462  * // set by hexadecimal string
1463  * e = new KJUR.asn1.x509.SubjectKeyIdentifier({kid: {hex: '89ab'}});
1464  * // set by PEM public key or certificate string
1465  * e = new KJUR.asn1.x509.SubjectKeyIdentifier({kid: "-----BEGIN CERTIFICATE..."});
1466  * // set by public key object
1467  * pubkey = KEYUTIL.getKey("-----BEGIN CERTIFICATE...");
1468  * e = new KJUR.asn1.x509.SubjectKeyIdentifier({kid: pubkey});
1469  */
1470 KJUR.asn1.x509.SubjectKeyIdentifier = function(params) {
1471     KJUR.asn1.x509.SubjectKeyIdentifier.superclass.constructor.call(this, params);
1472     var _KJUR = KJUR,
1473 	_KJUR_asn1 = _KJUR.asn1,
1474 	_DEROctetString = _KJUR_asn1.DEROctetString;
1475 
1476     this.asn1KID = null;
1477 
1478     this.getExtnValueHex = function() {
1479         this.asn1ExtnValue = this.asn1KID;
1480         return this.asn1ExtnValue.getEncodedHex();
1481     };
1482 
1483     /**
1484      * set keyIdentifier value by DEROctetString parameter, key object or PEM file
1485      * @name setKIDByParam
1486      * @memberOf KJUR.asn1.x509.SubjectKeyIdentifier#
1487      * @function
1488      * @param {Array} param array of {@link KJUR.asn1.DERInteger} parameter
1489      * @since asn1x509 1.1.7 jsrsasign 8.0.14
1490      * @description
1491      * <ul>
1492      * <li>{str: "123"} - by raw string</li>
1493      * <li>{hex: "01af..."} - by hexadecimal value</li>
1494      * <li>RSAKey/DSA/ECDSA - by RSAKey, KJUR.crypto.{DSA/ECDSA} public key object.
1495      * key identifier value will be calculated by the method described in
1496      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.2">RFC 5280 4.2.1.2 (1)</a>.
1497      * </li>
1498      * <li>certificate PEM string - extract subjectPublicKeyInfo from specified PEM
1499      * certificate and
1500      * key identifier value will be calculated by the method described in
1501      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.2">RFC 5280 4.2.1.2 (1)</a>.
1502      * <li>PKCS#1/#8 public key PEM string - pem will be converted to a key object and
1503      * to PKCS#8 ASN.1 structure then calculate 
1504      * a key identifier value will be calculated by the method described in
1505      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.2">RFC 5280 4.2.1.2 (1)</a>.
1506      * </ul>
1507      *
1508      * NOTE1: Automatic key identifier calculation is supported
1509      * since jsrsasign 8.0.16.
1510      *
1511      * @see KEYUTIL.getKeyID
1512      *
1513      * @example
1514      * o = new KJUR.asn1.x509.SubjectKeyIdentifier();
1515      * // set by hexadecimal string
1516      * o.setKIDByParam({hex: '1ad9...'});
1517      * // set by SubjectPublicKeyInfo of PEM certificate string
1518      * o.setKIDByParam("-----BEGIN CERTIFICATE...");
1519      * // set by PKCS#8 PEM public key string
1520      * o.setKIDByParam("-----BEGIN PUBLIC KEY...");
1521      * // set by public key object
1522      * pubkey = KEYUTIL.getKey("-----BEGIN CERTIFICATE...");
1523      * o.setKIDByParam(pubkey);
1524      */
1525     this.setKIDByParam = function(param) {
1526 	if (param.str !== undefined ||
1527 	    param.hex !== undefined) {
1528 	    this.asn1KID = new _DEROctetString(param);
1529 	} else if ((typeof param === "object" &&
1530 		    KJUR.crypto.Util.isKey(param)) ||
1531 		   (typeof param === "string" &&
1532 		    param.indexOf("BEGIN") != -1)) {
1533 
1534 	    var keyobj = param;
1535 	    if (typeof param === "string") {
1536 		keyobj = KEYUTIL.getKey(param);
1537 	    }
1538 
1539 	    var kid = KEYUTIL.getKeyID(keyobj);
1540 	    this.asn1KID = new KJUR.asn1.DEROctetString({hex: kid});
1541 	}
1542     };
1543 
1544     this.oid = "2.5.29.14";
1545     if (params !== undefined) {
1546 	if (params.kid !== undefined) {
1547 	    this.setKIDByParam(params.kid);
1548 	}
1549     }
1550 };
1551 YAHOO.lang.extend(KJUR.asn1.x509.SubjectKeyIdentifier, KJUR.asn1.x509.Extension);
1552 
1553 /**
1554  * AuthorityInfoAccess ASN.1 structure class
1555  * @name KJUR.asn1.x509.AuthorityInfoAccess
1556  * @class AuthorityInfoAccess ASN.1 structure class
1557  * @param {Array} params associative array of parameters
1558  * @extends KJUR.asn1.x509.Extension
1559  * @since asn1x509 1.0.8
1560  * @description
1561  * <pre>
1562  * id-pe OBJECT IDENTIFIER  ::=  { id-pkix 1 }
1563  * id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
1564  * AuthorityInfoAccessSyntax  ::=
1565  *         SEQUENCE SIZE (1..MAX) OF AccessDescription
1566  * AccessDescription  ::=  SEQUENCE {
1567  *         accessMethod          OBJECT IDENTIFIER,
1568  *         accessLocation        GeneralName  }
1569  * id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
1570  * id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
1571  * id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
1572  * </pre>
1573  * @example
1574  * e1 = new KJUR.asn1.x509.AuthorityInfoAccess({
1575  *   array: [{
1576  *     accessMethod:{'oid': '1.3.6.1.5.5.7.48.1'},
1577  *     accessLocation:{'uri': 'http://ocsp.cacert.org'}
1578  *   }]
1579  * });
1580  */
1581 KJUR.asn1.x509.AuthorityInfoAccess = function(params) {
1582     KJUR.asn1.x509.AuthorityInfoAccess.superclass.constructor.call(this, params);
1583 
1584     this.setAccessDescriptionArray = function(accessDescriptionArray) {
1585         var array = new Array(),
1586 	    _KJUR = KJUR,
1587 	    _KJUR_asn1 = _KJUR.asn1,
1588 	    _DERSequence = _KJUR_asn1.DERSequence;
1589 
1590         for (var i = 0; i < accessDescriptionArray.length; i++) {
1591             var o = new _KJUR_asn1.DERObjectIdentifier(accessDescriptionArray[i].accessMethod);
1592             var gn = new _KJUR_asn1.x509.GeneralName(accessDescriptionArray[i].accessLocation);
1593             var accessDescription = new _DERSequence({'array':[o, gn]});
1594             array.push(accessDescription);
1595         }
1596         this.asn1ExtnValue = new _DERSequence({'array':array});
1597     };
1598 
1599     this.getExtnValueHex = function() {
1600         return this.asn1ExtnValue.getEncodedHex();
1601     };
1602 
1603     this.oid = "1.3.6.1.5.5.7.1.1";
1604     if (params !== undefined) {
1605         if (params.array !== undefined) {
1606             this.setAccessDescriptionArray(params.array);
1607         }
1608     }
1609 };
1610 YAHOO.lang.extend(KJUR.asn1.x509.AuthorityInfoAccess, KJUR.asn1.x509.Extension);
1611 
1612 /**
1613  * SubjectAltName ASN.1 structure class<br/>
1614  * @name KJUR.asn1.x509.SubjectAltName
1615  * @class SubjectAltName ASN.1 structure class
1616  * @param {Array} params associative array of parameters
1617  * @extends KJUR.asn1.x509.Extension
1618  * @since jsrsasign 6.2.3 asn1x509 1.0.19
1619  * @see KJUR.asn1.x509.GeneralNames
1620  * @see KJUR.asn1.x509.GeneralName
1621  * @description
1622  * This class provides X.509v3 SubjectAltName extension.
1623  * <pre>
1624  * id-ce-subjectAltName OBJECT IDENTIFIER ::=  { id-ce 17 }
1625  * SubjectAltName ::= GeneralNames
1626  * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
1627  * GeneralName ::= CHOICE {
1628  *   otherName                  [0] OtherName,
1629  *   rfc822Name                 [1] IA5String,
1630  *   dNSName                    [2] IA5String,
1631  *   x400Address                [3] ORAddress,
1632  *   directoryName              [4] Name,
1633  *   ediPartyName               [5] EDIPartyName,
1634  *   uniformResourceIdentifier  [6] IA5String,
1635  *   iPAddress                  [7] OCTET STRING,
1636  *   registeredID               [8] OBJECT IDENTIFIER }
1637  * </pre>
1638  * @example
1639  * e1 = new KJUR.asn1.x509.SubjectAltName({
1640  *   critical: true,
1641  *   array: [{uri: 'http://aaa.com/'}, {uri: 'http://bbb.com/'}]
1642  * });
1643  */
1644 KJUR.asn1.x509.SubjectAltName = function(params) {
1645     KJUR.asn1.x509.SubjectAltName.superclass.constructor.call(this, params)
1646 
1647     this.setNameArray = function(paramsArray) {
1648 	this.asn1ExtnValue = new KJUR.asn1.x509.GeneralNames(paramsArray);
1649     };
1650 
1651     this.getExtnValueHex = function() {
1652         return this.asn1ExtnValue.getEncodedHex();
1653     };
1654 
1655     this.oid = "2.5.29.17";
1656     if (params !== undefined) {
1657         if (params.array !== undefined) {
1658             this.setNameArray(params.array);
1659         }
1660     }
1661 };
1662 YAHOO.lang.extend(KJUR.asn1.x509.SubjectAltName, KJUR.asn1.x509.Extension);
1663 
1664 /**
1665  * IssuerAltName ASN.1 structure class<br/>
1666  * @name KJUR.asn1.x509.IssuerAltName
1667  * @class IssuerAltName ASN.1 structure class
1668  * @param {Array} params associative array of parameters
1669  * @extends KJUR.asn1.x509.Extension
1670  * @since jsrsasign 6.2.3 asn1x509 1.0.19
1671  * @see KJUR.asn1.x509.GeneralNames
1672  * @see KJUR.asn1.x509.GeneralName
1673  * @description
1674  * This class provides X.509v3 IssuerAltName extension.
1675  * <pre>
1676  * id-ce-subjectAltName OBJECT IDENTIFIER ::=  { id-ce 18 }
1677  * IssuerAltName ::= GeneralNames
1678  * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
1679  * GeneralName ::= CHOICE {
1680  *   otherName                  [0] OtherName,
1681  *   rfc822Name                 [1] IA5String,
1682  *   dNSName                    [2] IA5String,
1683  *   x400Address                [3] ORAddress,
1684  *   directoryName              [4] Name,
1685  *   ediPartyName               [5] EDIPartyName,
1686  *   uniformResourceIdentifier  [6] IA5String,
1687  *   iPAddress                  [7] OCTET STRING,
1688  *   registeredID               [8] OBJECT IDENTIFIER }
1689  * </pre>
1690  * @example
1691  * e1 = new KJUR.asn1.x509.IssuerAltName({
1692  *   critical: true,
1693  *   array: [{uri: 'http://aaa.com/'}, {uri: 'http://bbb.com/'}]
1694  * });
1695  */
1696 KJUR.asn1.x509.IssuerAltName = function(params) {
1697     KJUR.asn1.x509.IssuerAltName.superclass.constructor.call(this, params)
1698 
1699     this.setNameArray = function(paramsArray) {
1700 	this.asn1ExtnValue = new KJUR.asn1.x509.GeneralNames(paramsArray);
1701     };
1702 
1703     this.getExtnValueHex = function() {
1704         return this.asn1ExtnValue.getEncodedHex();
1705     };
1706 
1707     this.oid = "2.5.29.18";
1708     if (params !== undefined) {
1709         if (params.array !== undefined) {
1710             this.setNameArray(params.array);
1711         }
1712     }
1713 };
1714 YAHOO.lang.extend(KJUR.asn1.x509.IssuerAltName, KJUR.asn1.x509.Extension);
1715 
1716 // === END   X.509v3 Extensions Related =======================================
1717 
1718 // === BEGIN CRL Related ===================================================
1719 /**
1720  * X.509 CRL class to sign and generate hex encoded CRL
1721  * @name KJUR.asn1.x509.CRL
1722  * @class X.509 CRL class to sign and generate hex encoded certificate
1723  * @param {Array} params associative array of parameters (ex. {'tbsobj': obj, 'rsaprvkey': key})
1724  * @extends KJUR.asn1.ASN1Object
1725  * @since 1.0.3
1726  * @description
1727  * <br/>
1728  * As for argument 'params' for constructor, you can specify one of
1729  * following properties:
1730  * <ul>
1731  * <li>tbsobj - specify {@link KJUR.asn1.x509.TBSCertList} object to be signed</li>
1732  * <li>rsaprvkey - specify {@link RSAKey} object CA private key</li>
1733  * </ul>
1734  * NOTE: 'params' can be omitted.
1735  * <h4>EXAMPLE</h4>
1736  * @example
1737  * var prvKey = KEYUTIL.getKEY("-----BEGIN PRIVATE..."); // CA's private key
1738  * var crl = new KJUR.asn1x509.CRL({'tbsobj': tbs, 'prvkeyobj': prvKey});
1739  * crl.sign(); // issue CRL by CA's private key
1740  * var hCRL = crl.getEncodedHex();
1741  *
1742  * // CertificateList  ::=  SEQUENCE  {
1743  * //     tbsCertList          TBSCertList,
1744  * //     signatureAlgorithm   AlgorithmIdentifier,
1745  * //     signatureValue       BIT STRING  }
1746  */
1747 KJUR.asn1.x509.CRL = function(params) {
1748     KJUR.asn1.x509.CRL.superclass.constructor.call(this);
1749 
1750     var asn1TBSCertList = null,
1751 	asn1SignatureAlg = null,
1752 	asn1Sig = null,
1753 	hexSig = null,
1754 	prvKey = null;
1755 
1756     /**
1757      * sign TBSCertList and set signature value internally
1758      * @name sign
1759      * @memberOf KJUR.asn1.x509.CRL#
1760      * @function
1761      * @description
1762      * @example
1763      * var cert = new KJUR.asn1.x509.CRL({'tbsobj': tbs, 'prvkeyobj': prvKey});
1764      * cert.sign();
1765      */
1766     this.sign = function() {
1767         this.asn1SignatureAlg = this.asn1TBSCertList.asn1SignatureAlg;
1768 
1769         sig = new KJUR.crypto.Signature({'alg': this.asn1SignatureAlg.nameAlg, 'prov': 'cryptojs/jsrsa'});
1770         sig.init(this.prvKey);
1771         sig.updateHex(this.asn1TBSCertList.getEncodedHex());
1772         this.hexSig = sig.sign();
1773 
1774         this.asn1Sig = new KJUR.asn1.DERBitString({'hex': '00' + this.hexSig});
1775 
1776         var seq = new KJUR.asn1.DERSequence({'array': [this.asn1TBSCertList,
1777                                                        this.asn1SignatureAlg,
1778                                                        this.asn1Sig]});
1779         this.hTLV = seq.getEncodedHex();
1780         this.isModified = false;
1781     };
1782 
1783     this.getEncodedHex = function() {
1784         if (this.isModified == false && this.hTLV != null) return this.hTLV;
1785         throw "not signed yet";
1786     };
1787 
1788     /**
1789      * get PEM formatted CRL string after signed
1790      * @name getPEMString
1791      * @memberOf KJUR.asn1.x509.CRL#
1792      * @function
1793      * @return PEM formatted string of certificate
1794      * @description
1795      * @example
1796      * var cert = new KJUR.asn1.x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey});
1797      * cert.sign();
1798      * var sPEM =  cert.getPEMString();
1799      */
1800     this.getPEMString = function() {
1801         var pemBody = hextob64nl(this.getEncodedHex());
1802         return "-----BEGIN X509 CRL-----\r\n" + 
1803 	    pemBody + 
1804 	    "\r\n-----END X509 CRL-----\r\n";
1805     };
1806 
1807     if (params !== undefined) {
1808         if (params.tbsobj !== undefined) {
1809             this.asn1TBSCertList = params.tbsobj;
1810         }
1811         if (params.prvkeyobj !== undefined) {
1812             this.prvKey = params.prvkeyobj;
1813         }
1814     }
1815 };
1816 YAHOO.lang.extend(KJUR.asn1.x509.CRL, KJUR.asn1.ASN1Object);
1817 
1818 /**
1819  * ASN.1 TBSCertList structure class for CRL
1820  * @name KJUR.asn1.x509.TBSCertList
1821  * @class ASN.1 TBSCertList structure class for CRL
1822  * @param {Array} params associative array of parameters (ex. {})
1823  * @extends KJUR.asn1.ASN1Object
1824  * @since 1.0.3
1825  * @description
1826  * <br/>
1827  * <h4>EXAMPLE</h4>
1828  * @example
1829  *  var o = new KJUR.asn1.x509.TBSCertList();
1830  *  o.setSignatureAlgByParam({'name': 'SHA1withRSA'});
1831  *  o.setIssuerByParam({'str': '/C=US/O=a'});
1832  *  o.setNotThisUpdateByParam({'str': '130504235959Z'});
1833  *  o.setNotNextUpdateByParam({'str': '140504235959Z'});
1834  *  o.addRevokedCert({'int': 4}, {'str':'130514235959Z'}));
1835  *  o.addRevokedCert({'hex': '0f34dd'}, {'str':'130514235959Z'}));
1836  *
1837  * // TBSCertList  ::=  SEQUENCE  {
1838  * //        version                 Version OPTIONAL,
1839  * //                                     -- if present, MUST be v2
1840  * //        signature               AlgorithmIdentifier,
1841  * //        issuer                  Name,
1842  * //        thisUpdate              Time,
1843  * //        nextUpdate              Time OPTIONAL,
1844  * //        revokedCertificates     SEQUENCE OF SEQUENCE  {
1845  * //             userCertificate         CertificateSerialNumber,
1846  * //             revocationDate          Time,
1847  * //             crlEntryExtensions      Extensions OPTIONAL
1848  * //                                      -- if present, version MUST be v2
1849  * //                                  }  OPTIONAL,
1850  * //        crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
1851  */
1852 KJUR.asn1.x509.TBSCertList = function(params) {
1853     KJUR.asn1.x509.TBSCertList.superclass.constructor.call(this);
1854     var aRevokedCert = null,
1855 	_KJUR = KJUR,
1856 	_KJUR_asn1 = _KJUR.asn1,
1857 	_DERSequence = _KJUR_asn1.DERSequence,
1858 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
1859 	_Time = _KJUR_asn1_x509.Time;
1860 
1861     /**
1862      * set signature algorithm field by parameter
1863      * @name setSignatureAlgByParam
1864      * @memberOf KJUR.asn1.x509.TBSCertList#
1865      * @function
1866      * @param {Array} algIdParam AlgorithmIdentifier parameter
1867      * @description
1868      * @example
1869      * tbsc.setSignatureAlgByParam({'name': 'SHA1withRSA'});
1870      */
1871     this.setSignatureAlgByParam = function(algIdParam) {
1872         this.asn1SignatureAlg = 
1873 	    new _KJUR_asn1_x509.AlgorithmIdentifier(algIdParam);
1874     };
1875 
1876     /**
1877      * set issuer name field by parameter
1878      * @name setIssuerByParam
1879      * @memberOf KJUR.asn1.x509.TBSCertList#
1880      * @function
1881      * @param {Array} x500NameParam X500Name parameter
1882      * @description
1883      * @example
1884      * tbsc.setIssuerParam({'str': '/C=US/CN=b'});
1885      * @see KJUR.asn1.x509.X500Name
1886      */
1887     this.setIssuerByParam = function(x500NameParam) {
1888         this.asn1Issuer = new _KJUR_asn1_x509.X500Name(x500NameParam);
1889     };
1890 
1891     /**
1892      * set thisUpdate field by parameter
1893      * @name setThisUpdateByParam
1894      * @memberOf KJUR.asn1.x509.TBSCertList#
1895      * @function
1896      * @param {Array} timeParam Time parameter
1897      * @description
1898      * @example
1899      * tbsc.setThisUpdateByParam({'str': '130508235959Z'});
1900      * @see KJUR.asn1.x509.Time
1901      */
1902     this.setThisUpdateByParam = function(timeParam) {
1903         this.asn1ThisUpdate = new _Time(timeParam);
1904     };
1905 
1906     /**
1907      * set nextUpdate field by parameter
1908      * @name setNextUpdateByParam
1909      * @memberOf KJUR.asn1.x509.TBSCertList#
1910      * @function
1911      * @param {Array} timeParam Time parameter
1912      * @description
1913      * @example
1914      * tbsc.setNextUpdateByParam({'str': '130508235959Z'});
1915      * @see KJUR.asn1.x509.Time
1916      */
1917     this.setNextUpdateByParam = function(timeParam) {
1918         this.asn1NextUpdate = new _Time(timeParam);
1919     };
1920 
1921     /**
1922      * add revoked certificate by parameter
1923      * @name addRevokedCert
1924      * @memberOf KJUR.asn1.x509.TBSCertList#
1925      * @function
1926      * @param {Array} snParam DERInteger parameter for certificate serial number
1927      * @param {Array} timeParam Time parameter for revocation date
1928      * @description
1929      * @example
1930      * tbsc.addRevokedCert({'int': 3}, {'str': '130508235959Z'});
1931      * @see KJUR.asn1.x509.Time
1932      */
1933     this.addRevokedCert = function(snParam, timeParam) {
1934         var param = {};
1935         if (snParam != undefined && snParam != null)
1936 	    param['sn'] = snParam;
1937         if (timeParam != undefined && timeParam != null)
1938 	    param['time'] = timeParam;
1939         var o = new _KJUR_asn1_x509.CRLEntry(param);
1940         this.aRevokedCert.push(o);
1941     };
1942 
1943     this.getEncodedHex = function() {
1944         this.asn1Array = new Array();
1945 
1946         if (this.asn1Version != null) this.asn1Array.push(this.asn1Version);
1947         this.asn1Array.push(this.asn1SignatureAlg);
1948         this.asn1Array.push(this.asn1Issuer);
1949         this.asn1Array.push(this.asn1ThisUpdate);
1950         if (this.asn1NextUpdate != null) this.asn1Array.push(this.asn1NextUpdate);
1951 
1952         if (this.aRevokedCert.length > 0) {
1953             var seq = new _DERSequence({'array': this.aRevokedCert});
1954             this.asn1Array.push(seq);
1955         }
1956 
1957         var o = new _DERSequence({"array": this.asn1Array});
1958         this.hTLV = o.getEncodedHex();
1959         this.isModified = false;
1960         return this.hTLV;
1961     };
1962 
1963     this._initialize = function() {
1964         this.asn1Version = null;
1965         this.asn1SignatureAlg = null;
1966         this.asn1Issuer = null;
1967         this.asn1ThisUpdate = null;
1968         this.asn1NextUpdate = null;
1969         this.aRevokedCert = new Array();
1970     };
1971 
1972     this._initialize();
1973 };
1974 YAHOO.lang.extend(KJUR.asn1.x509.TBSCertList, KJUR.asn1.ASN1Object);
1975 
1976 /**
1977  * ASN.1 CRLEntry structure class for CRL
1978  * @name KJUR.asn1.x509.CRLEntry
1979  * @class ASN.1 CRLEntry structure class for CRL
1980  * @param {Array} params associative array of parameters (ex. {})
1981  * @extends KJUR.asn1.ASN1Object
1982  * @since 1.0.3
1983  * @description
1984  * @example
1985  * var e = new KJUR.asn1.x509.CRLEntry({'time': {'str': '130514235959Z'}, 'sn': {'int': 234}});
1986  *
1987  * // revokedCertificates     SEQUENCE OF SEQUENCE  {
1988  * //     userCertificate         CertificateSerialNumber,
1989  * //     revocationDate          Time,
1990  * //     crlEntryExtensions      Extensions OPTIONAL
1991  * //                             -- if present, version MUST be v2 }
1992  */
1993 KJUR.asn1.x509.CRLEntry = function(params) {
1994     KJUR.asn1.x509.CRLEntry.superclass.constructor.call(this);
1995     var sn = null,
1996 	time = null,
1997 	_KJUR = KJUR,
1998 	_KJUR_asn1 = _KJUR.asn1;
1999 
2000     /**
2001      * set DERInteger parameter for serial number of revoked certificate
2002      * @name setCertSerial
2003      * @memberOf KJUR.asn1.x509.CRLEntry
2004      * @function
2005      * @param {Array} intParam DERInteger parameter for certificate serial number
2006      * @description
2007      * @example
2008      * entry.setCertSerial({'int': 3});
2009      */
2010     this.setCertSerial = function(intParam) {
2011         this.sn = new _KJUR_asn1.DERInteger(intParam);
2012     };
2013 
2014     /**
2015      * set Time parameter for revocation date
2016      * @name setRevocationDate
2017      * @memberOf KJUR.asn1.x509.CRLEntry
2018      * @function
2019      * @param {Array} timeParam Time parameter for revocation date
2020      * @description
2021      * @example
2022      * entry.setRevocationDate({'str': '130508235959Z'});
2023      */
2024     this.setRevocationDate = function(timeParam) {
2025         this.time = new _KJUR_asn1.x509.Time(timeParam);
2026     };
2027 
2028     this.getEncodedHex = function() {
2029         var o = new _KJUR_asn1.DERSequence({"array": [this.sn, this.time]});
2030         this.TLV = o.getEncodedHex();
2031         return this.TLV;
2032     };
2033 
2034     if (params !== undefined) {
2035         if (params.time !== undefined) {
2036             this.setRevocationDate(params.time);
2037         }
2038         if (params.sn !== undefined) {
2039             this.setCertSerial(params.sn);
2040         }
2041     }
2042 };
2043 YAHOO.lang.extend(KJUR.asn1.x509.CRLEntry, KJUR.asn1.ASN1Object);
2044 
2045 // === END   CRL Related ===================================================
2046 
2047 // === BEGIN X500Name Related =================================================
2048 /**
2049  * X500Name ASN.1 structure class
2050  * @name KJUR.asn1.x509.X500Name
2051  * @class X500Name ASN.1 structure class
2052  * @param {Array} params associative array of parameters (ex. {'str': '/C=US/O=a'})
2053  * @extends KJUR.asn1.ASN1Object
2054  * @see KJUR.asn1.x509.X500Name
2055  * @see KJUR.asn1.x509.RDN
2056  * @see KJUR.asn1.x509.AttributeTypeAndValue
2057  * @description
2058  * This class provides DistinguishedName ASN.1 class structure
2059  * defined in <a href="https://tools.ietf.org/html/rfc2253#section-2">RFC 2253 section 2</a>.
2060  * <blockquote><pre>
2061  * DistinguishedName ::= RDNSequence
2062  *
2063  * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
2064  *
2065  * RelativeDistinguishedName ::= SET SIZE (1..MAX) OF
2066  *   AttributeTypeAndValue
2067  *
2068  * AttributeTypeAndValue ::= SEQUENCE {
2069  *   type  AttributeType,
2070  *   value AttributeValue }
2071  * </pre></blockquote>
2072  * <br/>
2073  * Argument for the constructor can be one of following parameters:
2074  * <ul>
2075  * <li>str - string for distingish name in OpenSSL One line foramt (ex: /C=US/O=test/CN=test) See <a href="https://github.com/kjur/jsrsasign/wiki/NOTE-distinguished-name-representation-in-jsrsasign">this</a> in detail.</li>
2076  * <li>ldapstr - string for distinguish name in LDAP format (ex: CN=test,O=test,C=US)</li>
2077  * <li>hex - hexadecimal string for ASN.1 distinguish name structure</li>
2078  * <li>certissuer - issuer name in the specified PEM certificate</li>
2079  * <li>certsubject - subject name in the specified PEM certificate</li>
2080  * </ul>
2081  * <br/>
2082  * NOTE: Multi-valued RDN is supported since jsrsasign 6.2.1 asn1x509 1.0.17.
2083  * @example
2084  * // 1. construct with string
2085  * o = new KJUR.asn1.x509.X500Name({str: "/C=US/O=aaa/OU=bbb/CN=foo@example.com"});
2086  * o = new KJUR.asn1.x509.X500Name({str: "/C=US/O=aaa+CN=contact@example.com"}); // multi valued
2087  * // 2. construct by LDAP string
2088  * o = new KJUR.asn1.x509.X500Name({ldapstr: "CN=foo@example.com,OU=bbb,C=US"});
2089  * // 3. construct by ASN.1 hex string
2090  * o = new KJUR.asn1.x509.X500Name({hex: "304c3120..."});
2091  * // 4. construct by issuer of PEM certificate
2092  * o = new KJUR.asn1.x509.X500Name({certsubject: "-----BEGIN CERT..."});
2093  * // 5. construct by subject of PEM certificate
2094  * o = new KJUR.asn1.x509.X500Name({certissuer: "-----BEGIN CERT..."});
2095  * // 6. construct by object
2096  * o = new KJUR.asn1.x509.X500Name({C: "US", O: "aaa", CN: "http://example.com/"});
2097  */
2098 KJUR.asn1.x509.X500Name = function(params) {
2099     KJUR.asn1.x509.X500Name.superclass.constructor.call(this);
2100     this.asn1Array = new Array();
2101     var _KJUR = KJUR,
2102 	_KJUR_asn1 = _KJUR.asn1,
2103 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
2104 	_pemtohex = pemtohex;
2105 
2106     /**
2107      * set DN by OpenSSL oneline distinguished name string<br/>
2108      * @name setByString
2109      * @memberOf KJUR.asn1.x509.X500Name#
2110      * @function
2111      * @param {String} dnStr distinguished name by string (ex. /C=US/O=aaa)
2112      * @description
2113      * Sets distinguished name by string. 
2114      * dnStr must be formatted as 
2115      * "/type0=value0/type1=value1/type2=value2...".
2116      * No need to escape a slash in an attribute value.
2117      * @example
2118      * name = new KJUR.asn1.x509.X500Name();
2119      * name.setByString("/C=US/O=aaa/OU=bbb/CN=foo@example.com");
2120      * // no need to escape slash in an attribute value
2121      * name.setByString("/C=US/O=aaa/CN=1980/12/31");
2122      */
2123     this.setByString = function(dnStr) {
2124         var a = dnStr.split('/');
2125         a.shift();
2126 
2127 	var a1 = [];
2128 	for (var i = 0; i < a.length; i++) {
2129 	  if (a[i].match(/^[^=]+=.+$/)) {
2130 	    a1.push(a[i]);
2131 	  } else {
2132 	    var lastidx = a1.length - 1;
2133 	    a1[lastidx] = a1[lastidx] + "/" + a[i];
2134 	  }
2135 	}
2136 
2137         for (var i = 0; i < a1.length; i++) {
2138             this.asn1Array.push(new _KJUR_asn1_x509.RDN({'str':a1[i]}));
2139         }
2140     };
2141 
2142     /**
2143      * set DN by LDAP(RFC 2253) distinguished name string<br/>
2144      * @name setByLdapString
2145      * @memberOf KJUR.asn1.x509.X500Name#
2146      * @function
2147      * @param {String} dnStr distinguished name by LDAP string (ex. O=aaa,C=US)
2148      * @since jsrsasign 6.2.2 asn1x509 1.0.18
2149      * @see {@link KJUR.asn1.x509.X500Name.ldapToCompat}
2150      * @description
2151      * @example
2152      * name = new KJUR.asn1.x509.X500Name();
2153      * name.setByLdapString("CN=foo@example.com,OU=bbb,O=aaa,C=US");
2154      */
2155     this.setByLdapString = function(dnStr) {
2156 	var compat = _KJUR_asn1_x509.X500Name.ldapToCompat(dnStr);
2157 	this.setByString(compat);
2158     };
2159 
2160     /**
2161      * set DN by associative array<br/>
2162      * @name setByObject
2163      * @memberOf KJUR.asn1.x509.X500Name#
2164      * @function
2165      * @param {Array} dnObj associative array of DN (ex. {C: "US", O: "aaa"})
2166      * @since jsrsasign 4.9. asn1x509 1.0.13
2167      * @description
2168      * @example
2169      * name = new KJUR.asn1.x509.X500Name();
2170      * name.setByObject({C: "US", O: "aaa", CN="http://example.com/"1});
2171      */
2172     this.setByObject = function(dnObj) {
2173         // Get all the dnObject attributes and stuff them in the ASN.1 array.
2174         for (var x in dnObj) {
2175             if (dnObj.hasOwnProperty(x)) {
2176                 var newRDN = new KJUR.asn1.x509.RDN(
2177                     {'str': x + '=' + dnObj[x]});
2178                 // Initialize or push into the ANS1 array.
2179                 this.asn1Array ? this.asn1Array.push(newRDN)
2180                     : this.asn1Array = [newRDN];
2181             }
2182         }
2183     };
2184 
2185     this.getEncodedHex = function() {
2186         if (typeof this.hTLV == "string") return this.hTLV;
2187         var o = new _KJUR_asn1.DERSequence({"array": this.asn1Array});
2188         this.hTLV = o.getEncodedHex();
2189         return this.hTLV;
2190     };
2191 
2192     if (params !== undefined) {
2193         if (params.str !== undefined) {
2194             this.setByString(params.str);
2195         } else if (params.ldapstr !== undefined) {
2196 	    this.setByLdapString(params.ldapstr);
2197 	} else if (params.hex !== undefined) {
2198 	    this.hTLV = params.hex;
2199         } else if (params.certissuer !== undefined) {
2200             var x = new X509();
2201             x.readCertPEM(params.certissuer);
2202             this.hTLV = x.getIssuerHex();
2203         } else if (params.certsubject !== undefined) {
2204             var x = new X509();
2205             x.readCertPEM(params.certsubject);
2206             this.hTLV = x.getSubjectHex();
2207         // If params is an object, then set the ASN1 array just using the object
2208         // attributes. This is nice for fields that have lots of special
2209         // characters (i.e. CN: 'https://www.github.com/kjur//').
2210         } else if (typeof params === "object" &&
2211 		   params.certsubject === undefined &&
2212 		   params.certissuer === undefined) {
2213             this.setByObject(params);
2214         }
2215     }
2216 };
2217 YAHOO.lang.extend(KJUR.asn1.x509.X500Name, KJUR.asn1.ASN1Object);
2218 
2219 /**
2220  * convert OpenSSL compat distinguished name format string to LDAP(RFC 2253) format<br/>
2221  * @name compatToLDAP
2222  * @memberOf KJUR.asn1.x509.X500Name
2223  * @function
2224  * @param {String} s distinguished name string in OpenSSL oneline compat (ex. /C=US/O=test)
2225  * @return {String} distinguished name string in LDAP(RFC 2253) format (ex. O=test,C=US)
2226  * @since jsrsasign 8.0.19 asn1x509 1.1.20
2227  * @description
2228  * This static method converts a distinguished name string in OpenSSL compat
2229  * format to LDAP(RFC 2253) format.
2230  * @see <a href="https://github.com/kjur/jsrsasign/wiki/NOTE-distinguished-name-representation-in-jsrsasign">jsrsasign wiki: distinguished name string difference between OpenSSL compat and LDAP(RFC 2253)</a>
2231  * @see <a href="https://www.openssl.org/docs/man1.0.2/man1/openssl-x509.html#NAME-OPTIONS">OpenSSL x509 command manual - NAME OPTIONS</a>
2232  * @example
2233  * KJUR.asn1.x509.X500Name.compatToLDAP("/C=US/O=test") → 'O=test,C=US'
2234  * KJUR.asn1.x509.X500Name.compatToLDAP("/C=US/O=a,a") → 'O=a\,a,C=US'
2235  */
2236 KJUR.asn1.x509.X500Name.compatToLDAP = function(s) {
2237     if (s.substr(0, 1) !== "/") throw "malformed input";
2238 
2239     var result = "";
2240     s = s.substr(1);
2241 
2242     var a = s.split("/");
2243     a.reverse();
2244     a = a.map(function(s) {return s.replace(/,/, "\\,")});
2245 
2246     return a.join(",");
2247 };
2248 
2249 /**
2250  * convert OpenSSL compat distinguished name format string to LDAP(RFC 2253) format (DEPRECATED)<br/>
2251  * @name onelineToLDAP
2252  * @memberOf KJUR.asn1.x509.X500Name
2253  * @function
2254  * @param {String} s distinguished name string in OpenSSL compat format (ex. /C=US/O=test)
2255  * @return {String} distinguished name string in LDAP(RFC 2253) format (ex. O=test,C=US)
2256  * @since jsrsasign 6.2.2 asn1x509 1.0.18
2257  * @see KJUR.asn1.x509.X500Name.compatToLDAP
2258  * @description
2259  * This method is deprecated. Please use 
2260  * {@link KJUR.asn1.x509.X500Name.compatToLDAP} instead.
2261  */
2262 KJUR.asn1.x509.X500Name.onelineToLDAP = function(s) {
2263     return KJUR.asn1.x509.X500Name.compatToLDAP(s);
2264 }
2265 
2266 /**
2267  * convert LDAP(RFC 2253) distinguished name format string to OpenSSL compat format<br/>
2268  * @name ldapToCompat
2269  * @memberOf KJUR.asn1.x509.X500Name
2270  * @function
2271  * @param {String} s distinguished name string in LDAP(RFC 2253) format (ex. O=test,C=US)
2272  * @return {String} distinguished name string in OpenSSL compat format (ex. /C=US/O=test)
2273  * @since jsrsasign 8.0.19 asn1x509 1.1.10
2274  * @description
2275  * This static method converts a distinguished name string in 
2276  * LDAP(RFC 2253) format to OpenSSL compat format.
2277  * @see <a href="https://github.com/kjur/jsrsasign/wiki/NOTE-distinguished-name-representation-in-jsrsasign">jsrsasign wiki: distinguished name string difference between OpenSSL compat and LDAP(RFC 2253)</a>
2278  * @example
2279  * KJUR.asn1.x509.X500Name.ldapToCompat('O=test,C=US') → '/C=US/O=test'
2280  * KJUR.asn1.x509.X500Name.ldapToCompat('O=a\,a,C=US') → '/C=US/O=a,a'
2281  * KJUR.asn1.x509.X500Name.ldapToCompat('O=a/a,C=US')  → '/C=US/O=a\/a'
2282  */
2283 KJUR.asn1.x509.X500Name.ldapToCompat = function(s) {
2284     var a = s.split(",");
2285 
2286     // join \,
2287     var isBSbefore = false;
2288     var a2 = [];
2289     for (var i = 0; a.length > 0; i++) {
2290 	var item = a.shift();
2291 	//console.log("item=" + item);
2292 
2293 	if (isBSbefore === true) {
2294 	    var a2last = a2.pop();
2295 	    var newitem = (a2last + "," + item).replace(/\\,/g, ",");
2296 	    a2.push(newitem);
2297 	    isBSbefore = false;
2298 	} else {
2299 	    a2.push(item);
2300 	}
2301 
2302 	if (item.substr(-1, 1) === "\\") isBSbefore = true;
2303     }
2304 
2305     a2 = a2.map(function(s) {return s.replace("/", "\\/")});
2306     a2.reverse();
2307     return "/" + a2.join("/");
2308 };
2309 
2310 /**
2311  * convert LDAP(RFC 2253) distinguished name format string to OpenSSL compat format (DEPRECATED)<br/>
2312  * @name ldapToOneline
2313  * @memberOf KJUR.asn1.x509.X500Name
2314  * @function
2315  * @param {String} s distinguished name string in LDAP(RFC 2253) format (ex. O=test,C=US)
2316  * @return {String} distinguished name string in OpenSSL compat format (ex. /C=US/O=test)
2317  * @since jsrsasign 6.2.2 asn1x509 1.0.18
2318  * @description
2319  * This method is deprecated. Please use 
2320  * {@link KJUR.asn1.x509.X500Name.ldapToCompat} instead.
2321  */
2322 KJUR.asn1.x509.X500Name.ldapToOneline = function(s) {
2323     return KJUR.asn1.x509.X500Name.ldapToCompat(s);
2324 };
2325 
2326 /**
2327  * RDN (Relative Distinguished Name) ASN.1 structure class
2328  * @name KJUR.asn1.x509.RDN
2329  * @class RDN (Relative Distinguished Name) ASN.1 structure class
2330  * @param {Array} params associative array of parameters (ex. {'str': 'C=US'})
2331  * @extends KJUR.asn1.ASN1Object
2332  * @see KJUR.asn1.x509.X500Name
2333  * @see KJUR.asn1.x509.RDN
2334  * @see KJUR.asn1.x509.AttributeTypeAndValue
2335  * @description
2336  * This class provides RelativeDistinguishedName ASN.1 class structure
2337  * defined in <a href="https://tools.ietf.org/html/rfc2253#section-2">RFC 2253 section 2</a>.
2338  * <blockquote><pre>
2339  * RelativeDistinguishedName ::= SET SIZE (1..MAX) OF
2340  *   AttributeTypeAndValue
2341  *
2342  * AttributeTypeAndValue ::= SEQUENCE {
2343  *   type  AttributeType,
2344  *   value AttributeValue }
2345  * </pre></blockquote>
2346  * <br/>
2347  * NOTE: Multi-valued RDN is supported since jsrsasign 6.2.1 asn1x509 1.0.17.
2348  * @example
2349  * rdn = new KJUR.asn1.x509.RDN({str: "CN=test"});
2350  * rdn = new KJUR.asn1.x509.RDN({str: "O=a+O=bb+O=c"}); // multi-valued
2351  * rdn = new KJUR.asn1.x509.RDN({str: "O=a+O=b\\+b+O=c"}); // plus escaped
2352  * rdn = new KJUR.asn1.x509.RDN({str: "O=a+O=\"b+b\"+O=c"}); // double quoted
2353  */
2354 KJUR.asn1.x509.RDN = function(params) {
2355     KJUR.asn1.x509.RDN.superclass.constructor.call(this);
2356     this.asn1Array = new Array();
2357 
2358     /**
2359      * add one AttributeTypeAndValue by string<br/>
2360      * @name addByString
2361      * @memberOf KJUR.asn1.x509.RDN#
2362      * @function
2363      * @param {String} s string of AttributeTypeAndValue
2364      * @return {Object} unspecified
2365      * @description
2366      * This method add one AttributeTypeAndValue to RDN object.
2367      * @example
2368      * rdn = new KJUR.asn1.x509.RDN();
2369      * rdn.addByString("CN=john");
2370      * rdn.addByString("serialNumber=1234"); // for multi-valued RDN
2371      */
2372     this.addByString = function(s) {
2373         this.asn1Array.push(new KJUR.asn1.x509.AttributeTypeAndValue({'str': s}));
2374     };
2375 
2376     /**
2377      * add one AttributeTypeAndValue by multi-valued string<br/>
2378      * @name addByMultiValuedString
2379      * @memberOf KJUR.asn1.x509.RDN#
2380      * @function
2381      * @param {String} s string of multi-valued RDN
2382      * @return {Object} unspecified
2383      * @since jsrsasign 6.2.1 asn1x509 1.0.17
2384      * @description
2385      * This method add multi-valued RDN to RDN object.
2386      * @example
2387      * rdn = new KJUR.asn1.x509.RDN();
2388      * rdn.addByMultiValuedString("CN=john+O=test");
2389      * rdn.addByMultiValuedString("O=a+O=b\+b\+b+O=c"); // multi-valued RDN with quoted plus
2390      * rdn.addByMultiValuedString("O=a+O=\"b+b+b\"+O=c"); // multi-valued RDN with quoted quotation
2391      */
2392     this.addByMultiValuedString = function(s) {
2393 	var a = KJUR.asn1.x509.RDN.parseString(s);
2394 	for (var i = 0; i < a.length; i++) {
2395 	    this.addByString(a[i]);
2396 	}
2397     };
2398 
2399     this.getEncodedHex = function() {
2400         var o = new KJUR.asn1.DERSet({"array": this.asn1Array});
2401         this.TLV = o.getEncodedHex();
2402         return this.TLV;
2403     };
2404 
2405     if (params !== undefined) {
2406         if (params.str !== undefined) {
2407             this.addByMultiValuedString(params.str);
2408         }
2409     }
2410 };
2411 YAHOO.lang.extend(KJUR.asn1.x509.RDN, KJUR.asn1.ASN1Object);
2412 
2413 /**
2414  * parse multi-valued RDN string and split into array of 'AttributeTypeAndValue'<br/>
2415  * @name parseString
2416  * @memberOf KJUR.asn1.x509.RDN
2417  * @function
2418  * @param {String} s multi-valued string of RDN
2419  * @return {Array} array of string of AttributeTypeAndValue
2420  * @since jsrsasign 6.2.1 asn1x509 1.0.17
2421  * @description
2422  * This static method parses multi-valued RDN string and split into
2423  * array of AttributeTypeAndValue.
2424  * @example
2425  * KJUR.asn1.x509.RDN.parseString("CN=john") → ["CN=john"]
2426  * KJUR.asn1.x509.RDN.parseString("CN=john+OU=test") → ["CN=john", "OU=test"]
2427  * KJUR.asn1.x509.RDN.parseString('CN="jo+hn"+OU=test') → ["CN=jo+hn", "OU=test"]
2428  * KJUR.asn1.x509.RDN.parseString('CN=jo\+hn+OU=test') → ["CN=jo+hn", "OU=test"]
2429  * KJUR.asn1.x509.RDN.parseString("CN=john+OU=test+OU=t1") → ["CN=john", "OU=test", "OU=t1"]
2430  */
2431 KJUR.asn1.x509.RDN.parseString = function(s) {
2432     var a = s.split(/\+/);
2433 
2434     // join \+
2435     var isBSbefore = false;
2436     var a2 = [];
2437     for (var i = 0; a.length > 0; i++) {
2438 	var item = a.shift();
2439 	//console.log("item=" + item);
2440 
2441 	if (isBSbefore === true) {
2442 	    var a2last = a2.pop();
2443 	    var newitem = (a2last + "+" + item).replace(/\\\+/g, "+");
2444 	    a2.push(newitem);
2445 	    isBSbefore = false;
2446 	} else {
2447 	    a2.push(item);
2448 	}
2449 
2450 	if (item.substr(-1, 1) === "\\") isBSbefore = true;
2451     }
2452 
2453     // join quote
2454     var beginQuote = false;
2455     var a3 = [];
2456     for (var i = 0; a2.length > 0; i++) {
2457 	var item = a2.shift();
2458 
2459 	if (beginQuote === true) {
2460 	    var a3last = a3.pop();
2461 	    if (item.match(/"$/)) {
2462 		var newitem = (a3last + "+" + item).replace(/^([^=]+)="(.*)"$/, "$1=$2");
2463 		a3.push(newitem);
2464 		beginQuote = false;
2465 	    } else {
2466 		a3.push(a3last + "+" + item);
2467 	    }
2468 	} else {
2469 	    a3.push(item);
2470 	}
2471 
2472 	if (item.match(/^[^=]+="/)) {
2473 	    //console.log(i + "=" + item);
2474 	    beginQuote = true;
2475 	}
2476     }
2477 
2478     return a3;
2479 };
2480 
2481 /**
2482  * AttributeTypeAndValue ASN.1 structure class
2483  * @name KJUR.asn1.x509.AttributeTypeAndValue
2484  * @class AttributeTypeAndValue ASN.1 structure class
2485  * @param {Array} params associative array of parameters (ex. {'str': 'C=US'})
2486  * @extends KJUR.asn1.ASN1Object
2487  * @description
2488  * @see KJUR.asn1.x509.X500Name
2489  * @see KJUR.asn1.x509.RDN
2490  * @see KJUR.asn1.x509.AttributeTypeAndValue
2491  * @example
2492  */
2493 KJUR.asn1.x509.AttributeTypeAndValue = function(params) {
2494     KJUR.asn1.x509.AttributeTypeAndValue.superclass.constructor.call(this);
2495     var typeObj = null,
2496 	valueObj = null,
2497 	defaultDSType = "utf8",
2498 	_KJUR = KJUR,
2499 	_KJUR_asn1 = _KJUR.asn1;
2500 
2501     this.setByString = function(attrTypeAndValueStr) {
2502         var matchResult = attrTypeAndValueStr.match(/^([^=]+)=(.+)$/);
2503         if (matchResult) {
2504             this.setByAttrTypeAndValueStr(matchResult[1], matchResult[2]);
2505         } else {
2506             throw "malformed attrTypeAndValueStr: " + attrTypeAndValueStr;
2507         }
2508     };
2509 
2510     this.setByAttrTypeAndValueStr = function(shortAttrType, valueStr) {
2511         this.typeObj = KJUR.asn1.x509.OID.atype2obj(shortAttrType);
2512         var dsType = defaultDSType;
2513         if (shortAttrType == "C") dsType = "prn";
2514         this.valueObj = this.getValueObj(dsType, valueStr);
2515     };
2516 
2517     this.getValueObj = function(dsType, valueStr) {
2518         if (dsType == "utf8")   return new _KJUR_asn1.DERUTF8String({"str": valueStr});
2519         if (dsType == "prn")    return new _KJUR_asn1.DERPrintableString({"str": valueStr});
2520         if (dsType == "tel")    return new _KJUR_asn1.DERTeletexString({"str": valueStr});
2521         if (dsType == "ia5")    return new _KJUR_asn1.DERIA5String({"str": valueStr});
2522         throw "unsupported directory string type: type=" + dsType + " value=" + valueStr;
2523     };
2524 
2525     this.getEncodedHex = function() {
2526         var o = new _KJUR_asn1.DERSequence({"array": [this.typeObj, this.valueObj]});
2527         this.TLV = o.getEncodedHex();
2528         return this.TLV;
2529     };
2530 
2531     if (params !== undefined) {
2532         if (params.str !== undefined) {
2533             this.setByString(params.str);
2534         }
2535     }
2536 };
2537 YAHOO.lang.extend(KJUR.asn1.x509.AttributeTypeAndValue, KJUR.asn1.ASN1Object);
2538 
2539 // === END   X500Name Related =================================================
2540 
2541 // === BEGIN Other ASN1 structure class  ======================================
2542 
2543 /**
2544  * SubjectPublicKeyInfo ASN.1 structure class
2545  * @name KJUR.asn1.x509.SubjectPublicKeyInfo
2546  * @class SubjectPublicKeyInfo ASN.1 structure class
2547  * @param {Object} params parameter for subject public key
2548  * @extends KJUR.asn1.ASN1Object
2549  * @description
2550  * <br/>
2551  * As for argument 'params' for constructor, you can specify one of
2552  * following properties:
2553  * <ul>
2554  * <li>{@link RSAKey} object</li>
2555  * <li>{@link KJUR.crypto.ECDSA} object</li>
2556  * <li>{@link KJUR.crypto.DSA} object</li>
2557  * </ul>
2558  * NOTE1: 'params' can be omitted.<br/>
2559  * NOTE2: DSA/ECDSA key object is also supported since asn1x509 1.0.6.<br/>
2560  * <h4>EXAMPLE</h4>
2561  * @example
2562  * spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(RSAKey_object);
2563  * spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoECDSA_object);
2564  * spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoDSA_object);
2565  */
2566 KJUR.asn1.x509.SubjectPublicKeyInfo = function(params) {
2567     KJUR.asn1.x509.SubjectPublicKeyInfo.superclass.constructor.call(this);
2568     var asn1AlgId = null,
2569 	asn1SubjPKey = null,
2570 	_KJUR = KJUR,
2571 	_KJUR_asn1 = _KJUR.asn1,
2572 	_DERInteger = _KJUR_asn1.DERInteger,
2573 	_DERBitString = _KJUR_asn1.DERBitString,
2574 	_DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
2575 	_DERSequence = _KJUR_asn1.DERSequence,
2576 	_newObject = _KJUR_asn1.ASN1Util.newObject,
2577 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
2578 	_AlgorithmIdentifier = _KJUR_asn1_x509.AlgorithmIdentifier,
2579 	_KJUR_crypto = _KJUR.crypto,
2580 	_KJUR_crypto_ECDSA = _KJUR_crypto.ECDSA,
2581 	_KJUR_crypto_DSA = _KJUR_crypto.DSA;
2582 
2583     /*
2584      * @since asn1x509 1.0.7
2585      */
2586     this.getASN1Object = function() {
2587         if (this.asn1AlgId == null || this.asn1SubjPKey == null)
2588             throw "algId and/or subjPubKey not set";
2589         var o = new _DERSequence({'array':
2590                                   [this.asn1AlgId, this.asn1SubjPKey]});
2591         return o;
2592     };
2593 
2594     this.getEncodedHex = function() {
2595         var o = this.getASN1Object();
2596         this.hTLV = o.getEncodedHex();
2597         return this.hTLV;
2598     };
2599 
2600     /**
2601      * @name setPubKey
2602      * @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo#
2603      * @function
2604      * @param {Object} {@link RSAKey}, {@link KJUR.crypto.ECDSA} or {@link KJUR.crypto.DSA} object
2605      * @since jsrsasign 8.0.0 asn1x509 1.1.0
2606      * @description
2607      * @example
2608      * spki = new KJUR.asn1.x509.SubjectPublicKeyInfo();
2609      * pubKey = KEYUTIL.getKey(PKCS8PUBKEYPEM);
2610      * spki.setPubKey(pubKey);
2611      */
2612     this.setPubKey = function(key) {
2613 	try {
2614 	    if (key instanceof RSAKey) {
2615 		var asn1RsaPub = _newObject({
2616 		    'seq': [{'int': {'bigint': key.n}}, {'int': {'int': key.e}}]
2617 		});
2618 		var rsaKeyHex = asn1RsaPub.getEncodedHex();
2619 		this.asn1AlgId = new _AlgorithmIdentifier({'name':'rsaEncryption'});
2620 		this.asn1SubjPKey = new _DERBitString({'hex':'00'+rsaKeyHex});
2621 	    }
2622 	} catch(ex) {};
2623 
2624 	try {
2625 	    if (key instanceof KJUR.crypto.ECDSA) {
2626 		var asn1Params = new _DERObjectIdentifier({'name': key.curveName});
2627 		this.asn1AlgId =
2628 		    new _AlgorithmIdentifier({'name': 'ecPublicKey',
2629 					      'asn1params': asn1Params});
2630 		this.asn1SubjPKey = new _DERBitString({'hex': '00' + key.pubKeyHex});
2631 	    }
2632 	} catch(ex) {};
2633 
2634 	try {
2635 	    if (key instanceof KJUR.crypto.DSA) {
2636 		var asn1Params = new _newObject({
2637 		    'seq': [{'int': {'bigint': key.p}},
2638 			    {'int': {'bigint': key.q}},
2639 			    {'int': {'bigint': key.g}}]
2640 		});
2641 		this.asn1AlgId =
2642 		    new _AlgorithmIdentifier({'name': 'dsa',
2643 					      'asn1params': asn1Params});
2644 		var pubInt = new _DERInteger({'bigint': key.y});
2645 		this.asn1SubjPKey = 
2646 		    new _DERBitString({'hex': '00' + pubInt.getEncodedHex()});
2647 	    }
2648 	} catch(ex) {};
2649     };
2650 
2651     if (params !== undefined) {
2652 	this.setPubKey(params);
2653     }
2654 };
2655 YAHOO.lang.extend(KJUR.asn1.x509.SubjectPublicKeyInfo, KJUR.asn1.ASN1Object);
2656 
2657 /**
2658  * Time ASN.1 structure class
2659  * @name KJUR.asn1.x509.Time
2660  * @class Time ASN.1 structure class
2661  * @param {Array} params associative array of parameters (ex. {'str': '130508235959Z'})
2662  * @extends KJUR.asn1.ASN1Object
2663  * @description
2664  * <br/>
2665  * <h4>EXAMPLES</h4>
2666  * @example
2667  * var t1 = new KJUR.asn1.x509.Time{'str': '130508235959Z'} // UTCTime by default
2668  * var t2 = new KJUR.asn1.x509.Time{'type': 'gen',  'str': '20130508235959Z'} // GeneralizedTime
2669  */
2670 KJUR.asn1.x509.Time = function(params) {
2671     KJUR.asn1.x509.Time.superclass.constructor.call(this);
2672     var type = null,
2673 	timeParams = null,
2674 	_KJUR = KJUR,
2675 	_KJUR_asn1 = _KJUR.asn1,
2676 	_DERUTCTime = _KJUR_asn1.DERUTCTime,
2677 	_DERGeneralizedTime = _KJUR_asn1.DERGeneralizedTime;
2678 
2679     this.setTimeParams = function(timeParams) {
2680         this.timeParams = timeParams;
2681     }
2682 
2683     this.getEncodedHex = function() {
2684         var o = null;
2685 
2686         if (this.timeParams != null) {
2687             if (this.type == "utc") {
2688                 o = new _DERUTCTime(this.timeParams);
2689             } else {
2690                 o = new _DERGeneralizedTime(this.timeParams);
2691             }
2692         } else {
2693             if (this.type == "utc") {
2694                 o = new _DERUTCTime();
2695             } else {
2696                 o = new _DERGeneralizedTime();
2697             }
2698         }
2699         this.TLV = o.getEncodedHex();
2700         return this.TLV;
2701     };
2702 
2703     this.type = "utc";
2704     if (params !== undefined) {
2705         if (params.type !== undefined) {
2706             this.type = params.type;
2707         } else {
2708             if (params.str !== undefined) {
2709                 if (params.str.match(/^[0-9]{12}Z$/)) this.type = "utc";
2710                 if (params.str.match(/^[0-9]{14}Z$/)) this.type = "gen";
2711             }
2712         }
2713         this.timeParams = params;
2714     }
2715 };
2716 YAHOO.lang.extend(KJUR.asn1.x509.Time, KJUR.asn1.ASN1Object);
2717 
2718 /**
2719  * AlgorithmIdentifier ASN.1 structure class
2720  * @name KJUR.asn1.x509.AlgorithmIdentifier
2721  * @class AlgorithmIdentifier ASN.1 structure class
2722  * @param {Array} params associative array of parameters (ex. {'name': 'SHA1withRSA'})
2723  * @extends KJUR.asn1.ASN1Object
2724  * @description
2725  * The 'params' argument is an associative array and has following parameters:
2726  * <ul>
2727  * <li>name: algorithm name (MANDATORY, ex. sha1, SHA256withRSA)</li>
2728  * <li>asn1params: explicitly specify ASN.1 object for algorithm.
2729  * (OPTION)</li>
2730  * <li>paramempty: set algorithm parameter to NULL by force.
2731  * If paramempty is false, algorithm parameter will be set automatically.
2732  * If paramempty is false and algorithm name is "*withDSA" or "withECDSA" parameter field of
2733  * AlgorithmIdentifier will be ommitted otherwise
2734  * it will be NULL by default.
2735  * (OPTION, DEFAULT = false)</li>
2736  * </ul>
2737  * RSA-PSS algorithm names such as SHA{,256,384,512}withRSAandMGF1 are
2738  * special names. They will set a suite of algorithm OID and multiple algorithm
2739  * parameters. Its ASN.1 schema is defined in 
2740  * <a href="https://tools.ietf.org/html/rfc3447#appendix-A.2.3">RFC 3447 PKCS#1 2.1
2741  * section A.2.3</a>.
2742  * <blockquote><pre>
2743  * id-RSASSA-PSS  OBJECT IDENTIFIER ::= { pkcs-1 10 }
2744  * RSASSA-PSS-params ::= SEQUENCE {
2745  *   hashAlgorithm      [0] HashAlgorithm    DEFAULT sha1,
2746  *   maskGenAlgorithm   [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
2747  *   saltLength         [2] INTEGER          DEFAULT 20,
2748  *   trailerField       [3] TrailerField     DEFAULT trailerFieldBC }
2749  * mgf1SHA1    MaskGenAlgorithm ::= {
2750  *   algorithm   id-mgf1,
2751  *   parameters  HashAlgorithm : sha1 }
2752  * id-mgf1     OBJECT IDENTIFIER ::= { pkcs-1 8 }
2753  * TrailerField ::= INTEGER { trailerFieldBC(1) }
2754  * </pre></blockquote>
2755  * Here is a table for PSS parameters:
2756  * <table>
2757  * <tr><th>Name</th><th>alg oid</th><th>pss hash</th><th>maskgen</th></th><th>pss saltlen</th><th>trailer</th></tr>
2758  * <tr><td>SHAwithRSAandMGF1</td><td>1.2.840.113549.1.1.10(rsapss)</td><td>default(sha1)</td><td>default(mgf1sha1)</td><td>default(20)</td><td>default(1)</td></tr>
2759  * <tr><td>SHA256withRSAandMGF1</td><td>1.2.840.113549.1.1.10(rsapss)</td><td>sha256</td><td>mgf1sha256</td><td>32</td><td>default(1)</td></tr>
2760  * <tr><td>SHA384withRSAandMGF1</td><td>1.2.840.113549.1.1.10(rsapss)</td><td>sha384</td><td>mgf1sha384</td><td>48</td><td>default(1)</td></tr>
2761  * <tr><td>SHA512withRSAandMGF1</td><td>1.2.840.113549.1.1.10(rsapss)</td><td>sha512</td><td>mgf1sha512</td><td>64</td><td>default(1)</td></tr>
2762  * </table>
2763  * Default value is omitted as defined in ASN.1 schema.
2764  * These parameters are interoperable to OpenSSL or IAIK toolkit.
2765  * <br/>
2766  * NOTE: RSA-PSS algorihtm names are supported since jsrsasign 8.0.21. 
2767  * @example
2768  * new KJUR.asn1.x509.AlgorithmIdentifier({name: "sha1"})
2769  * new KJUR.asn1.x509.AlgorithmIdentifier({name: "SHA256withRSA"})
2770  * new KJUR.asn1.x509.AlgorithmIdentifier({name: "SHA512withRSAandMGF1"}) // set parameters automatically
2771  * new KJUR.asn1.x509.AlgorithmIdentifier({name: "SHA256withRSA", paramempty: true})
2772  * new KJUR.asn1.x509.AlgorithmIdentifier({name: "rsaEncryption"})
2773  */
2774 KJUR.asn1.x509.AlgorithmIdentifier = function(params) {
2775     KJUR.asn1.x509.AlgorithmIdentifier.superclass.constructor.call(this);
2776     this.nameAlg = null;
2777     this.asn1Alg = null;
2778     this.asn1Params = null;
2779     this.paramEmpty = false;
2780 
2781     var _KJUR = KJUR,
2782 	_KJUR_asn1 = _KJUR.asn1,
2783 	_PSSNAME2ASN1TLV = _KJUR_asn1.x509.AlgorithmIdentifier.PSSNAME2ASN1TLV;
2784 
2785     this.getEncodedHex = function() {
2786         if (this.nameAlg === null && this.asn1Alg === null) {
2787             throw new Error("algorithm not specified");
2788         }
2789 
2790 	// for RSAPSS algorithm name
2791 	//  && this.hTLV === null
2792 	if (this.nameAlg !== null) {
2793 	    var hTLV = null;
2794 	    for (var key in _PSSNAME2ASN1TLV) {
2795 		if (key === this.nameAlg) {
2796 		    hTLV = _PSSNAME2ASN1TLV[key];
2797 		}
2798 	    }
2799 	    if (hTLV !== null) {
2800 		this.hTLV = hTLV;
2801 		return this.hTLV;
2802 	    }
2803 	}
2804 
2805         if (this.nameAlg !== null && this.asn1Alg === null) {
2806             this.asn1Alg = _KJUR_asn1.x509.OID.name2obj(this.nameAlg);
2807         }
2808         var a = [this.asn1Alg];
2809         if (this.asn1Params !== null) a.push(this.asn1Params);
2810 
2811         var o = new _KJUR_asn1.DERSequence({'array': a});
2812         this.hTLV = o.getEncodedHex();
2813         return this.hTLV;
2814     };
2815 
2816     if (params !== undefined) {
2817         if (params.name !== undefined) {
2818             this.nameAlg = params.name;
2819         }
2820         if (params.asn1params !== undefined) {
2821             this.asn1Params = params.asn1params;
2822         }
2823         if (params.paramempty !== undefined) {
2824             this.paramEmpty = params.paramempty;
2825         }
2826     }
2827 
2828     // set algorithm parameters will be ommitted for
2829     // "*withDSA" or "*withECDSA" otherwise will be NULL.
2830     if (this.asn1Params === null &&
2831 	this.paramEmpty === false &&
2832 	this.nameAlg !== null) {
2833 	var lcNameAlg = this.nameAlg.toLowerCase();
2834 	if (lcNameAlg.substr(-7, 7) !== "withdsa" &&
2835 	    lcNameAlg.substr(-9, 9) !== "withecdsa") {
2836             this.asn1Params = new _KJUR_asn1.DERNull();
2837 	}
2838     }
2839 };
2840 YAHOO.lang.extend(KJUR.asn1.x509.AlgorithmIdentifier, KJUR.asn1.ASN1Object);
2841 
2842 /**
2843  * AlgorithmIdentifier ASN.1 TLV string associative array for RSA-PSS algorithm names
2844  * @const
2845  */
2846 KJUR.asn1.x509.AlgorithmIdentifier.PSSNAME2ASN1TLV = {
2847     "SHAwithRSAandMGF1":
2848     "300d06092a864886f70d01010a3000",
2849     "SHA256withRSAandMGF1":
2850     "303d06092a864886f70d01010a3030a00d300b0609608648016503040201a11a301806092a864886f70d010108300b0609608648016503040201a203020120",
2851     "SHA384withRSAandMGF1":
2852     "303d06092a864886f70d01010a3030a00d300b0609608648016503040202a11a301806092a864886f70d010108300b0609608648016503040202a203020130",
2853     "SHA512withRSAandMGF1":
2854     "303d06092a864886f70d01010a3030a00d300b0609608648016503040203a11a301806092a864886f70d010108300b0609608648016503040203a203020140"
2855 };
2856 
2857 /**
2858  * GeneralName ASN.1 structure class<br/>
2859  * @name KJUR.asn1.x509.GeneralName
2860  * @class GeneralName ASN.1 structure class
2861  * @description
2862  * <br/>
2863  * As for argument 'params' for constructor, you can specify one of
2864  * following properties:
2865  * <ul>
2866  * <li>rfc822 - rfc822Name[1] (ex. user1@foo.com)</li>
2867  * <li>dns - dNSName[2] (ex. foo.com)</li>
2868  * <li>uri - uniformResourceIdentifier[6] (ex. http://foo.com/)</li>
2869  * <li>dn - directoryName[4] 
2870  * distinguished name string or X500Name class parameters can be
2871  * specified (ex. "/C=US/O=Test", {hex: '301c...')</li>
2872  * <li>ldapdn - directoryName[4] (ex. O=Test,C=US)</li>
2873  * <li>certissuer - directoryName[4] (PEM or hex string of cert)</li>
2874  * <li>certsubj - directoryName[4] (PEM or hex string of cert)</li>
2875  * <li>ip - iPAddress[7] (ex. 192.168.1.1, 2001:db3::43, 3faa0101...)</li>
2876  * </ul>
2877  * NOTE1: certissuer and certsubj were supported since asn1x509 1.0.10.<br/>
2878  * NOTE2: dn and ldapdn were supported since jsrsasign 6.2.3 asn1x509 1.0.19.<br/>
2879  * NOTE3: ip were supported since jsrsasign 8.0.10 asn1x509 1.1.4.<br/>
2880  * NOTE4: X500Name parameters in dn were supported since jsrsasign 8.0.16.<br/>
2881  *
2882  * Here is definition of the ASN.1 syntax:
2883  * <pre>
2884  * -- NOTE: under the CHOICE, it will always be explicit.
2885  * GeneralName ::= CHOICE {
2886  *   otherName                  [0] OtherName,
2887  *   rfc822Name                 [1] IA5String,
2888  *   dNSName                    [2] IA5String,
2889  *   x400Address                [3] ORAddress,
2890  *   directoryName              [4] Name,
2891  *   ediPartyName               [5] EDIPartyName,
2892  *   uniformResourceIdentifier  [6] IA5String,
2893  *   iPAddress                  [7] OCTET STRING,
2894  *   registeredID               [8] OBJECT IDENTIFIER }
2895  * </pre>
2896  *
2897  * @example
2898  * gn = new KJUR.asn1.x509.GeneralName({dn:     '/C=US/O=Test'});
2899  * gn = new KJUR.asn1.x509.GeneralName({dn:     X500NameObject);
2900  * gn = new KJUR.asn1.x509.GeneralName({dn:     {str: /C=US/O=Test'});
2901  * gn = new KJUR.asn1.x509.GeneralName({dn:     {ldapstr: 'O=Test,C=US'});
2902  * gn = new KJUR.asn1.x509.GeneralName({dn:     {hex: '301c...'});
2903  * gn = new KJUR.asn1.x509.GeneralName({dn:     {certissuer: PEMCERTSTRING});
2904  * gn = new KJUR.asn1.x509.GeneralName({dn:     {certsubject: PEMCERTSTRING});
2905  * gn = new KJUR.asn1.x509.GeneralName({ip:     '192.168.1.1'});
2906  * gn = new KJUR.asn1.x509.GeneralName({ip:     '2001:db4::4:1'});
2907  * gn = new KJUR.asn1.x509.GeneralName({ip:     'c0a80101'});
2908  * gn = new KJUR.asn1.x509.GeneralName({rfc822: 'test@aaa.com'});
2909  * gn = new KJUR.asn1.x509.GeneralName({dns:    'aaa.com'});
2910  * gn = new KJUR.asn1.x509.GeneralName({uri:    'http://aaa.com/'});
2911  *
2912  * gn = new KJUR.asn1.x509.GeneralName({ldapdn:     'O=Test,C=US'}); // DEPRECATED
2913  * gn = new KJUR.asn1.x509.GeneralName({certissuer: certPEM});       // DEPRECATED
2914  * gn = new KJUR.asn1.x509.GeneralName({certsubj:   certPEM});       // DEPRECATED
2915  */
2916 KJUR.asn1.x509.GeneralName = function(params) {
2917     KJUR.asn1.x509.GeneralName.superclass.constructor.call(this);
2918     var asn1Obj = null,
2919 	type = null,
2920 	pTag = {rfc822: '81', dns: '82', dn: 'a4',  uri: '86', ip: '87'},
2921 	_KJUR = KJUR,
2922 	_KJUR_asn1 = _KJUR.asn1,
2923 	_DERSequence = _KJUR_asn1.DERSequence,
2924 	_DEROctetString = _KJUR_asn1.DEROctetString,
2925 	_DERIA5String = _KJUR_asn1.DERIA5String,
2926 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
2927 	_ASN1Object = _KJUR_asn1.ASN1Object,
2928 	_X500Name = _KJUR_asn1.x509.X500Name,
2929 	_pemtohex = pemtohex;
2930 	
2931     this.explicit = false;
2932 
2933     this.setByParam = function(params) {
2934         var str = null;
2935         var v = null;
2936 
2937 	if (params === undefined) return;
2938 
2939         if (params.rfc822 !== undefined) {
2940             this.type = 'rfc822';
2941             v = new _DERIA5String({str: params[this.type]});
2942         }
2943 
2944         if (params.dns !== undefined) {
2945             this.type = 'dns';
2946             v = new _DERIA5String({str: params[this.type]});
2947         }
2948 
2949         if (params.uri !== undefined) {
2950             this.type = 'uri';
2951             v = new _DERIA5String({str: params[this.type]});
2952         }
2953 
2954         if (params.dn !== undefined) {
2955 	    this.type = 'dn';
2956 	    this.explicit = true;
2957 	    if (typeof params.dn === "string") {
2958 		v = new _X500Name({str: params.dn});
2959 	    } else if (params.dn instanceof KJUR.asn1.x509.X500Name) {
2960 		v = params.dn;
2961 	    } else {
2962 		v = new _X500Name(params.dn);
2963 	    }
2964 	}
2965 
2966         if (params.ldapdn !== undefined) {
2967 	    this.type = 'dn';
2968 	    this.explicit = true;
2969 	    v = new _X500Name({ldapstr: params.ldapdn});
2970 	}
2971 
2972 	if (params.certissuer !== undefined) {
2973 	    this.type = 'dn';
2974 	    this.explicit = true;
2975 	    var certStr = params.certissuer;
2976 	    var certHex = null;
2977 
2978 	    if (certStr.match(/^[0-9A-Fa-f]+$/)) {
2979 		certHex == certStr;
2980             }
2981 
2982 	    if (certStr.indexOf("-----BEGIN ") != -1) {
2983 		certHex = _pemtohex(certStr);
2984 	    }
2985 
2986 	    if (certHex == null) throw "certissuer param not cert";
2987 	    var x = new X509();
2988 	    x.hex = certHex;
2989 	    var dnHex = x.getIssuerHex();
2990 	    v = new _ASN1Object();
2991 	    v.hTLV = dnHex;
2992 	}
2993 
2994 	if (params.certsubj !== undefined) {
2995 	    this.type = 'dn';
2996 	    this.explicit = true;
2997 	    var certStr = params.certsubj;
2998 	    var certHex = null;
2999 	    if (certStr.match(/^[0-9A-Fa-f]+$/)) {
3000 		certHex == certStr;
3001             }
3002 	    if (certStr.indexOf("-----BEGIN ") != -1) {
3003 		certHex = _pemtohex(certStr);
3004 	    }
3005 	    if (certHex == null) throw "certsubj param not cert";
3006 	    var x = new X509();
3007 	    x.hex = certHex;
3008 	    var dnHex = x.getSubjectHex();
3009 	    v = new _ASN1Object();
3010 	    v.hTLV = dnHex;
3011 	}
3012 
3013 	if (params.ip !== undefined) {
3014 	    this.type = 'ip';
3015 	    this.explicit = false;
3016 	    var ip = params.ip;
3017 	    var hIP;
3018 	    var malformedIPMsg = "malformed IP address";
3019 	    if (ip.match(/^[0-9.]+[.][0-9.]+$/)) { // ipv4
3020 		hIP = intarystrtohex("[" + ip.split(".").join(",") + "]");
3021 		if (hIP.length !== 8) throw malformedIPMsg;
3022 	    } else if (ip.match(/^[0-9A-Fa-f:]+:[0-9A-Fa-f:]+$/)) { // ipv6
3023 		hIP = ipv6tohex(ip);
3024 	    } else if (ip.match(/^([0-9A-Fa-f][0-9A-Fa-f]){1,}$/)) { // hex
3025 		hIP = ip;
3026 	    } else {
3027 		throw malformedIPMsg;
3028 	    }
3029 	    v = new _DEROctetString({hex: hIP});
3030 	}
3031 
3032         if (this.type == null)
3033             throw "unsupported type in params=" + params;
3034         this.asn1Obj = new _DERTaggedObject({'explicit': this.explicit,
3035                                              'tag': pTag[this.type],
3036                                              'obj': v});
3037     };
3038 
3039     this.getEncodedHex = function() {
3040         return this.asn1Obj.getEncodedHex();
3041     }
3042 
3043     if (params !== undefined) {
3044         this.setByParam(params);
3045     }
3046 
3047 };
3048 YAHOO.lang.extend(KJUR.asn1.x509.GeneralName, KJUR.asn1.ASN1Object);
3049 
3050 /**
3051  * GeneralNames ASN.1 structure class<br/>
3052  * @name KJUR.asn1.x509.GeneralNames
3053  * @class GeneralNames ASN.1 structure class
3054  * @description
3055  * <br/>
3056  * <h4>EXAMPLE AND ASN.1 SYNTAX</h4>
3057  * @example
3058  * gns = new KJUR.asn1.x509.GeneralNames([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]);
3059  *
3060  * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
3061  */
3062 KJUR.asn1.x509.GeneralNames = function(paramsArray) {
3063     KJUR.asn1.x509.GeneralNames.superclass.constructor.call(this);
3064     var asn1Array = null,
3065 	_KJUR = KJUR,
3066 	_KJUR_asn1 = _KJUR.asn1;
3067 
3068     /**
3069      * set a array of {@link KJUR.asn1.x509.GeneralName} parameters<br/>
3070      * @name setByParamArray
3071      * @memberOf KJUR.asn1.x509.GeneralNames#
3072      * @function
3073      * @param {Array} paramsArray Array of {@link KJUR.asn1.x509.GeneralNames}
3074      * @description
3075      * <br/>
3076      * <h4>EXAMPLES</h4>
3077      * @example
3078      * gns = new KJUR.asn1.x509.GeneralNames();
3079      * gns.setByParamArray([{uri: 'http://aaa.com/'}, {uri: 'http://bbb.com/'}]);
3080      */
3081     this.setByParamArray = function(paramsArray) {
3082         for (var i = 0; i < paramsArray.length; i++) {
3083             var o = new _KJUR_asn1.x509.GeneralName(paramsArray[i]);
3084             this.asn1Array.push(o);
3085         }
3086     };
3087 
3088     this.getEncodedHex = function() {
3089         var o = new _KJUR_asn1.DERSequence({'array': this.asn1Array});
3090         return o.getEncodedHex();
3091     };
3092 
3093     this.asn1Array = new Array();
3094     if (typeof paramsArray != "undefined") {
3095         this.setByParamArray(paramsArray);
3096     }
3097 };
3098 YAHOO.lang.extend(KJUR.asn1.x509.GeneralNames, KJUR.asn1.ASN1Object);
3099 
3100 /**
3101  * DistributionPointName ASN.1 structure class<br/>
3102  * @name KJUR.asn1.x509.DistributionPointName
3103  * @class DistributionPointName ASN.1 structure class
3104  * @description
3105  * <pre>
3106  * DistributionPoint ::= SEQUENCE {
3107  *      distributionPoint       [0]     DistributionPointName OPTIONAL,
3108  *      reasons                 [1]     ReasonFlags OPTIONAL,
3109  *      cRLIssuer               [2]     GeneralNames OPTIONAL }
3110  *
3111  * DistributionPointName ::= CHOICE {
3112  *      fullName                [0]     GeneralNames,
3113  *      nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
3114  * 
3115  * ReasonFlags ::= BIT STRING {
3116  *      unused                  (0),
3117  *      keyCompromise           (1),
3118  *      cACompromise            (2),
3119  *      affiliationChanged      (3),
3120  *      superseded              (4),
3121  *      cessationOfOperation    (5),
3122  *      certificateHold         (6),
3123  *      privilegeWithdrawn      (7),
3124  *      aACompromise            (8) }
3125  * </pre>
3126  * @example
3127  */
3128 KJUR.asn1.x509.DistributionPointName = function(gnOrRdn) {
3129     KJUR.asn1.x509.DistributionPointName.superclass.constructor.call(this);
3130     var asn1Obj = null,
3131 	type = null,
3132 	tag = null,
3133 	asn1V = null,
3134 	_KJUR = KJUR,
3135 	_KJUR_asn1 = _KJUR.asn1,
3136 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject;
3137 
3138     this.getEncodedHex = function() {
3139         if (this.type != "full")
3140             throw "currently type shall be 'full': " + this.type;
3141         this.asn1Obj = new _DERTaggedObject({'explicit': false,
3142                                              'tag': this.tag,
3143                                              'obj': this.asn1V});
3144         this.hTLV = this.asn1Obj.getEncodedHex();
3145         return this.hTLV;
3146     };
3147 
3148     if (gnOrRdn !== undefined) {
3149         if (_KJUR_asn1.x509.GeneralNames.prototype.isPrototypeOf(gnOrRdn)) {
3150             this.type = "full";
3151             this.tag = "a0";
3152             this.asn1V = gnOrRdn;
3153         } else {
3154             throw "This class supports GeneralNames only as argument";
3155         }
3156     }
3157 };
3158 YAHOO.lang.extend(KJUR.asn1.x509.DistributionPointName, KJUR.asn1.ASN1Object);
3159 
3160 /**
3161  * DistributionPoint ASN.1 structure class<br/>
3162  * @name KJUR.asn1.x509.DistributionPoint
3163  * @class DistributionPoint ASN.1 structure class
3164  * @description
3165  * <pre>
3166  * DistributionPoint ::= SEQUENCE {
3167  *      distributionPoint       [0]     DistributionPointName OPTIONAL,
3168  *      reasons                 [1]     ReasonFlags OPTIONAL,
3169  *      cRLIssuer               [2]     GeneralNames OPTIONAL }
3170  *
3171  * DistributionPointName ::= CHOICE {
3172  *      fullName                [0]     GeneralNames,
3173  *      nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
3174  * 
3175  * ReasonFlags ::= BIT STRING {
3176  *      unused                  (0),
3177  *      keyCompromise           (1),
3178  *      cACompromise            (2),
3179  *      affiliationChanged      (3),
3180  *      superseded              (4),
3181  *      cessationOfOperation    (5),
3182  *      certificateHold         (6),
3183  *      privilegeWithdrawn      (7),
3184  *      aACompromise            (8) }
3185  * </pre>
3186  * @example
3187  */
3188 KJUR.asn1.x509.DistributionPoint = function(params) {
3189     KJUR.asn1.x509.DistributionPoint.superclass.constructor.call(this);
3190     var asn1DP = null,
3191 	_KJUR = KJUR,
3192 	_KJUR_asn1 = _KJUR.asn1;
3193 
3194     this.getEncodedHex = function() {
3195         var seq = new _KJUR_asn1.DERSequence();
3196         if (this.asn1DP != null) {
3197             var o1 = new _KJUR_asn1.DERTaggedObject({'explicit': true,
3198                                                      'tag': 'a0',
3199                                                      'obj': this.asn1DP});
3200             seq.appendASN1Object(o1);
3201         }
3202         this.hTLV = seq.getEncodedHex();
3203         return this.hTLV;
3204     };
3205 
3206     if (params !== undefined) {
3207         if (params.dpobj !== undefined) {
3208             this.asn1DP = params.dpobj;
3209         }
3210     }
3211 };
3212 YAHOO.lang.extend(KJUR.asn1.x509.DistributionPoint, KJUR.asn1.ASN1Object);
3213 
3214 /**
3215  * static object for OID
3216  * @name KJUR.asn1.x509.OID
3217  * @class static object for OID
3218  * @property {Assoc Array} atype2oidList for short attribute type name and oid (ex. 'C' and '2.5.4.6')
3219  * @property {Assoc Array} name2oidList for oid name and oid (ex. 'keyUsage' and '2.5.29.15')
3220  * @property {Assoc Array} objCache for caching name and DERObjectIdentifier object
3221  * @description
3222  * This class defines OID name and values.
3223  * AttributeType names registered in OID.atype2oidList are following:
3224  * <table style="border-width: thin; border-style: solid; witdh: 100%">
3225  * <tr><th>short</th><th>long</th><th>OID</th></tr>
3226  * <tr><td>CN</td>commonName<td></td><td>2.5.4.3</td></tr>
3227  * <tr><td>L</td><td>localityName</td><td>2.5.4.7</td></tr>
3228  * <tr><td>ST</td><td>stateOrProvinceName</td><td>2.5.4.8</td></tr>
3229  * <tr><td>O</td><td>organizationName</td><td>2.5.4.10</td></tr>
3230  * <tr><td>OU</td><td>organizationalUnitName</td><td>2.5.4.11</td></tr>
3231  * <tr><td>C</td><td></td>countryName<td>2.5.4.6</td></tr>
3232  * <tr><td>STREET</td>streetAddress<td></td><td>2.5.4.6</td></tr>
3233  * <tr><td>DC</td><td>domainComponent</td><td>0.9.2342.19200300.100.1.25</td></tr>
3234  * <tr><td>UID</td><td>userId</td><td>0.9.2342.19200300.100.1.1</td></tr>
3235  * <tr><td>SN</td><td>surname</td><td>2.5.4.4</td></tr>
3236  * <tr><td>DN</td><td>distinguishedName</td><td>2.5.4.49</td></tr>
3237  * <tr><td>E</td><td>emailAddress</td><td>1.2.840.113549.1.9.1</td></tr>
3238  * <tr><td></td><td>businessCategory</td><td>2.5.4.15</td></tr>
3239  * <tr><td></td><td>postalCode</td><td>2.5.4.17</td></tr>
3240  * <tr><td></td><td>jurisdictionOfIncorporationL</td><td>1.3.6.1.4.1.311.60.2.1.1</td></tr>
3241  * <tr><td></td><td>jurisdictionOfIncorporationSP</td><td>1.3.6.1.4.1.311.60.2.1.2</td></tr>
3242  * <tr><td></td><td>jurisdictionOfIncorporationC</td><td>1.3.6.1.4.1.311.60.2.1.3</td></tr>
3243  * </table>
3244  *
3245  * @example
3246  */
3247 KJUR.asn1.x509.OID = new function(params) {
3248     this.atype2oidList = {
3249 	// RFC 4514 AttributeType name string (MUST recognized)
3250         'CN':		'2.5.4.3',
3251         'L':		'2.5.4.7',
3252         'ST':		'2.5.4.8',
3253         'O':		'2.5.4.10',
3254         'OU':		'2.5.4.11',
3255         'C':		'2.5.4.6',
3256         'STREET':	'2.5.4.9',
3257         'DC':		'0.9.2342.19200300.100.1.25',
3258         'UID':		'0.9.2342.19200300.100.1.1',
3259 	// other AttributeType name string
3260 	// http://blog.livedoor.jp/k_urushima/archives/656114.html
3261         'SN':		'2.5.4.4', // surname
3262         'T':		'2.5.4.12', // title
3263         'DN':		'2.5.4.49', // distinguishedName
3264         'E':		'1.2.840.113549.1.9.1', // emailAddress in MS.NET or Bouncy
3265 	// other AttributeType name string (no short name)
3266 	'description':			'2.5.4.13',
3267 	'businessCategory':		'2.5.4.15',
3268 	'postalCode':			'2.5.4.17',
3269 	'serialNumber':			'2.5.4.5',
3270 	'uniqueIdentifier':		'2.5.4.45',
3271 	'organizationIdentifier':	'2.5.4.97',
3272 	'jurisdictionOfIncorporationL':	'1.3.6.1.4.1.311.60.2.1.1',
3273 	'jurisdictionOfIncorporationSP':'1.3.6.1.4.1.311.60.2.1.2',
3274 	'jurisdictionOfIncorporationC':	'1.3.6.1.4.1.311.60.2.1.3'
3275     };
3276     this.name2oidList = {
3277         'sha1':                 '1.3.14.3.2.26',
3278         'sha256':               '2.16.840.1.101.3.4.2.1',
3279         'sha384':               '2.16.840.1.101.3.4.2.2',
3280         'sha512':               '2.16.840.1.101.3.4.2.3',
3281         'sha224':               '2.16.840.1.101.3.4.2.4',
3282         'md5':                  '1.2.840.113549.2.5',
3283         'md2':                  '1.3.14.7.2.2.1',
3284         'ripemd160':            '1.3.36.3.2.1',
3285 
3286         'MD2withRSA':           '1.2.840.113549.1.1.2',
3287         'MD4withRSA':           '1.2.840.113549.1.1.3',
3288         'MD5withRSA':           '1.2.840.113549.1.1.4',
3289         'SHA1withRSA':          '1.2.840.113549.1.1.5',
3290         'SHA224withRSA':        '1.2.840.113549.1.1.14',
3291         'SHA256withRSA':        '1.2.840.113549.1.1.11',
3292         'SHA384withRSA':        '1.2.840.113549.1.1.12',
3293         'SHA512withRSA':        '1.2.840.113549.1.1.13',
3294 
3295         'SHA1withECDSA':        '1.2.840.10045.4.1',
3296         'SHA224withECDSA':      '1.2.840.10045.4.3.1',
3297         'SHA256withECDSA':      '1.2.840.10045.4.3.2',
3298         'SHA384withECDSA':      '1.2.840.10045.4.3.3',
3299         'SHA512withECDSA':      '1.2.840.10045.4.3.4',
3300 
3301         'dsa':                  '1.2.840.10040.4.1',
3302         'SHA1withDSA':          '1.2.840.10040.4.3',
3303         'SHA224withDSA':        '2.16.840.1.101.3.4.3.1',
3304         'SHA256withDSA':        '2.16.840.1.101.3.4.3.2',
3305 
3306         'rsaEncryption':        '1.2.840.113549.1.1.1',
3307 
3308 	// X.500 AttributeType defined in RFC 4514
3309         'commonName':			'2.5.4.3',
3310         'countryName':			'2.5.4.6',
3311         'localityName':			'2.5.4.7',
3312         'stateOrProvinceName':		'2.5.4.8',
3313         'streetAddress':		'2.5.4.9',
3314         'organizationName':		'2.5.4.10',
3315         'organizationalUnitName':	'2.5.4.11',
3316         'domainComponent':		'0.9.2342.19200300.100.1.25',
3317         'userId':			'0.9.2342.19200300.100.1.1',
3318 	// other AttributeType name string
3319 	'surname':			'2.5.4.4',
3320         'title':			'2.5.4.12',
3321 	'distinguishedName':		'2.5.4.49',
3322 	'emailAddress':			'1.2.840.113549.1.9.1',
3323 	// other AttributeType name string (no short name)
3324 	'description':			'2.5.4.13',
3325 	'businessCategory':		'2.5.4.15',
3326 	'postalCode':			'2.5.4.17',
3327 	'uniqueIdentifier':		'2.5.4.45',
3328 	'organizationIdentifier':	'2.5.4.97',
3329 	'jurisdictionOfIncorporationL':	'1.3.6.1.4.1.311.60.2.1.1',
3330 	'jurisdictionOfIncorporationSP':'1.3.6.1.4.1.311.60.2.1.2',
3331 	'jurisdictionOfIncorporationC':	'1.3.6.1.4.1.311.60.2.1.3',
3332 
3333         'subjectKeyIdentifier': '2.5.29.14',
3334         'keyUsage':             '2.5.29.15',
3335         'subjectAltName':       '2.5.29.17',
3336         'issuerAltName':        '2.5.29.18',
3337         'basicConstraints':     '2.5.29.19',
3338         'nameConstraints':      '2.5.29.30',
3339         'cRLDistributionPoints':'2.5.29.31',
3340         'certificatePolicies':  '2.5.29.32',
3341         'authorityKeyIdentifier':'2.5.29.35',
3342         'policyConstraints':    '2.5.29.36',
3343         'extKeyUsage':          '2.5.29.37',
3344         'authorityInfoAccess':  '1.3.6.1.5.5.7.1.1',
3345         'ocsp':                 '1.3.6.1.5.5.7.48.1',
3346         'caIssuers':            '1.3.6.1.5.5.7.48.2',
3347 
3348         'anyExtendedKeyUsage':  '2.5.29.37.0',
3349         'serverAuth':           '1.3.6.1.5.5.7.3.1',
3350         'clientAuth':           '1.3.6.1.5.5.7.3.2',
3351         'codeSigning':          '1.3.6.1.5.5.7.3.3',
3352         'emailProtection':      '1.3.6.1.5.5.7.3.4',
3353         'timeStamping':         '1.3.6.1.5.5.7.3.8',
3354         'ocspSigning':          '1.3.6.1.5.5.7.3.9',
3355 
3356         'ecPublicKey':          '1.2.840.10045.2.1',
3357         'secp256r1':            '1.2.840.10045.3.1.7',
3358         'secp256k1':            '1.3.132.0.10',
3359         'secp384r1':            '1.3.132.0.34',
3360 
3361         'pkcs5PBES2':           '1.2.840.113549.1.5.13',
3362         'pkcs5PBKDF2':          '1.2.840.113549.1.5.12',
3363 
3364         'des-EDE3-CBC':         '1.2.840.113549.3.7',
3365 
3366         'data':                 '1.2.840.113549.1.7.1', // CMS data
3367         'signed-data':          '1.2.840.113549.1.7.2', // CMS signed-data
3368         'enveloped-data':       '1.2.840.113549.1.7.3', // CMS enveloped-data
3369         'digested-data':        '1.2.840.113549.1.7.5', // CMS digested-data
3370         'encrypted-data':       '1.2.840.113549.1.7.6', // CMS encrypted-data
3371         'authenticated-data':   '1.2.840.113549.1.9.16.1.2', // CMS authenticated-data
3372         'tstinfo':              '1.2.840.113549.1.9.16.1.4', // RFC3161 TSTInfo
3373         'extensionRequest':     '1.2.840.113549.1.9.14',// CSR extensionRequest
3374     };
3375 
3376     this.objCache = {};
3377 
3378     /**
3379      * get DERObjectIdentifier by registered OID name
3380      * @name name2obj
3381      * @memberOf KJUR.asn1.x509.OID
3382      * @function
3383      * @param {String} name OID
3384      * @description
3385      * @example
3386      * var asn1ObjOID = OID.name2obj('SHA1withRSA');
3387      */
3388     this.name2obj = function(name) {
3389         if (typeof this.objCache[name] != "undefined")
3390             return this.objCache[name];
3391         if (typeof this.name2oidList[name] == "undefined")
3392             throw "Name of ObjectIdentifier not defined: " + name;
3393         var oid = this.name2oidList[name];
3394         var obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid});
3395         this.objCache[name] = obj;
3396         return obj;
3397     };
3398 
3399     /**
3400      * get DERObjectIdentifier by registered attribute type name such like 'C' or 'CN'<br/>
3401      * @name atype2obj
3402      * @memberOf KJUR.asn1.x509.OID
3403      * @function
3404      * @param {String} atype short attribute type name such like 'C' or 'CN'
3405      * @description
3406      * @example
3407      * KJUR.asn1.x509.OID.atype2obj('CN') → 2.5.4.3
3408      * KJUR.asn1.x509.OID.atype2obj('OU') → 2.5.4.11
3409      */
3410     this.atype2obj = function(atype) {
3411         if (typeof this.objCache[atype] != "undefined")
3412             return this.objCache[atype];
3413         if (typeof this.atype2oidList[atype] == "undefined")
3414             throw "AttributeType name undefined: " + atype;
3415         var oid = this.atype2oidList[atype];
3416         var obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid});
3417         this.objCache[atype] = obj;
3418         return obj;
3419     };
3420 };
3421 
3422 /**
3423  * convert OID to name<br/>
3424  * @name oid2name
3425  * @memberOf KJUR.asn1.x509.OID
3426  * @function
3427  * @param {String} oid dot noted Object Identifer string (ex. 1.2.3.4)
3428  * @return {String} OID name if registered otherwise empty string
3429  * @since asn1x509 1.0.9
3430  * @description
3431  * This static method converts OID string to its name.
3432  * If OID is undefined then it returns empty string (i.e. '').
3433  * @example
3434  * KJUR.asn1.x509.OID.oid2name("1.3.6.1.5.5.7.1.1") → 'authorityInfoAccess'
3435  */
3436 KJUR.asn1.x509.OID.oid2name = function(oid) {
3437     var list = KJUR.asn1.x509.OID.name2oidList;
3438     for (var name in list) {
3439         if (list[name] == oid) return name;
3440     }
3441     return '';
3442 };
3443 
3444 /**
3445  * convert OID to AttributeType name<br/>
3446  * @name oid2atype
3447  * @memberOf KJUR.asn1.x509.OID
3448  * @function
3449  * @param {String} oid dot noted Object Identifer string (ex. 1.2.3.4)
3450  * @return {String} OID AttributeType name if registered otherwise oid
3451  * @since jsrsasign 6.2.2 asn1x509 1.0.18
3452  * @description
3453  * This static method converts OID string to its AttributeType name.
3454  * If OID is not defined in OID.atype2oidList associative array then it returns OID
3455  * specified as argument.
3456  * @example
3457  * KJUR.asn1.x509.OID.oid2atype("2.5.4.3") → CN
3458  * KJUR.asn1.x509.OID.oid2atype("1.3.6.1.4.1.311.60.2.1.3") → jurisdictionOfIncorporationC
3459  * KJUR.asn1.x509.OID.oid2atype("0.1.2.3.4") → 0.1.2.3.4 // unregistered OID
3460  */
3461 KJUR.asn1.x509.OID.oid2atype = function(oid) {
3462     var list = KJUR.asn1.x509.OID.atype2oidList;
3463     for (var atype in list) {
3464         if (list[atype] == oid) return atype;
3465     }
3466     return oid;
3467 };
3468 
3469 /**
3470  * convert OID name to OID value<br/>
3471  * @name name2oid
3472  * @memberOf KJUR.asn1.x509.OID
3473  * @function
3474  * @param {String} OID name
3475  * @return {String} dot noted Object Identifer string (ex. 1.2.3.4)
3476  * @since asn1x509 1.0.11
3477  * @description
3478  * This static method converts from OID name to OID string.
3479  * If OID is undefined then it returns empty string (i.e. '').
3480  * @example
3481  * KJUR.asn1.x509.OID.name2oid("authorityInfoAccess") → 1.3.6.1.5.5.7.1.1
3482  */
3483 KJUR.asn1.x509.OID.name2oid = function(name) {
3484     var list = KJUR.asn1.x509.OID.name2oidList;
3485     if (list[name] === undefined) return '';
3486     return list[name];
3487 };
3488 
3489 /**
3490  * X.509 certificate and CRL utilities class<br/>
3491  * @name KJUR.asn1.x509.X509Util
3492  * @class X.509 certificate and CRL utilities class
3493  */
3494 KJUR.asn1.x509.X509Util = {};
3495 
3496 /**
3497  * issue a certificate in PEM format
3498  * @name newCertPEM
3499  * @memberOf KJUR.asn1.x509.X509Util
3500  * @function
3501  * @param {Array} param parameter to issue a certificate
3502  * @since asn1x509 1.0.6
3503  * @description
3504  * This method can issue a certificate by a simple
3505  * JSON object.
3506  * Signature value will be provided by signing with
3507  * private key using 'cakey' parameter or
3508  * hexa decimal signature value by 'sighex' parameter.
3509  * <br/>
3510  * NOTE: Algorithm parameter of AlgorithmIdentifier will
3511  * be set automatically by default. 
3512  * (see {@link KJUR.asn1.x509.AlgorithmIdentifier})
3513  * from jsrsasign 7.1.1 asn1x509 1.0.20.
3514  * <br/>
3515  * NOTE2: 
3516  * RSA-PSS algorithm has been supported from jsrsasign 8.0.21.
3517  * As for RSA-PSS signature algorithm names and signing parameters 
3518  * such as MGF function and salt length, please see
3519  * {@link KJUR.asn1.x509.AlgorithmIdentifier} class.
3520  *
3521  * @example
3522  * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM({
3523  *   serial: {int: 4},
3524  *   sigalg: {name: 'SHA1withECDSA'},
3525  *   issuer: {str: '/C=US/O=a'},
3526  *   notbefore: {'str': '130504235959Z'},
3527  *   notafter: {'str': '140504235959Z'},
3528  *   subject: {str: '/C=US/O=b'},
3529  *   sbjpubkey: pubKeyObj,
3530  *   ext: [
3531  *     {basicConstraints: {cA: true, critical: true}},
3532  *     {keyUsage: {bin: '11'}},
3533  *   ],
3534  *   cakey: prvKeyObj
3535  * });
3536  * // -- or --
3537  * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM({
3538  *   serial: {int: 4},
3539  *   sigalg: {name: 'SHA1withECDSA'},
3540  *   issuer: {str: '/C=US/O=a'},
3541  *   notbefore: {'str': '130504235959Z'},
3542  *   notafter: {'str': '140504235959Z'},
3543  *   subject: {str: '/C=US/O=b'},
3544  *   sbjpubkey: pubKeyPEM,
3545  *   ext: [
3546  *     {basicConstraints: {cA: true, critical: true}},
3547  *     {keyUsage: {bin: '11'}},
3548  *   ],
3549  *   cakey: [prvkey, pass]}
3550  * );
3551  * // -- or --
3552  * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM({
3553  *   serial: {int: 1},
3554  *   sigalg: {name: 'SHA1withRSA'},
3555  *   issuer: {str: '/C=US/O=T1'},
3556  *   notbefore: {'str': '130504235959Z'},
3557  *   notafter: {'str': '140504235959Z'},
3558  *   subject: {str: '/C=US/O=T1'},
3559  *   sbjpubkey: pubKeyObj,
3560  *   sighex: '0102030405..'
3561  * });
3562  * // for the issuer and subject field, another
3563  * // representation is also available
3564  * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM({
3565  *   serial: {int: 1},
3566  *   sigalg: {name: 'SHA256withRSA'},
3567  *   issuer: {C: "US", O: "T1"},
3568  *   notbefore: {'str': '130504235959Z'},
3569  *   notafter: {'str': '140504235959Z'},
3570  *   subject: {C: "US", O: "T1", CN: "http://example.com/"},
3571  *   sbjpubkey: pubKeyObj,
3572  *   sighex: '0102030405..'
3573  * });
3574  */
3575 KJUR.asn1.x509.X509Util.newCertPEM = function(param) {
3576     var _KJUR_asn1_x509 = KJUR.asn1.x509,
3577 	_TBSCertificate = _KJUR_asn1_x509.TBSCertificate,
3578 	_Certificate = _KJUR_asn1_x509.Certificate;
3579     var o = new _TBSCertificate();
3580 
3581     if (param.serial !== undefined)
3582         o.setSerialNumberByParam(param.serial);
3583     else
3584         throw "serial number undefined.";
3585 
3586     if (typeof param.sigalg.name === 'string')
3587         o.setSignatureAlgByParam(param.sigalg);
3588     else
3589         throw "unproper signature algorithm name";
3590 
3591     if (param.issuer !== undefined)
3592         o.setIssuerByParam(param.issuer);
3593     else
3594         throw "issuer name undefined.";
3595 
3596     if (param.notbefore !== undefined)
3597         o.setNotBeforeByParam(param.notbefore);
3598     else
3599         throw "notbefore undefined.";
3600 
3601     if (param.notafter !== undefined)
3602         o.setNotAfterByParam(param.notafter);
3603     else
3604         throw "notafter undefined.";
3605 
3606     if (param.subject !== undefined)
3607         o.setSubjectByParam(param.subject);
3608     else
3609         throw "subject name undefined.";
3610 
3611     if (param.sbjpubkey !== undefined)
3612         o.setSubjectPublicKeyByGetKey(param.sbjpubkey);
3613     else
3614         throw "subject public key undefined.";
3615 
3616     if (param.ext !== undefined && param.ext.length !== undefined) {
3617         for (var i = 0; i < param.ext.length; i++) {
3618             for (key in param.ext[i]) {
3619                 o.appendExtensionByName(key, param.ext[i][key]);
3620             }
3621         }
3622     }
3623 
3624     // set signature
3625     if (param.cakey === undefined && param.sighex === undefined)
3626         throw "param cakey and sighex undefined.";
3627 
3628     var caKey = null;
3629     var cert = null;
3630 
3631     if (param.cakey) {
3632 	if (param.cakey.isPrivate === true) {
3633 	    caKey = param.cakey;
3634 	} else {
3635             caKey = KEYUTIL.getKey.apply(null, param.cakey);
3636 	}
3637         cert = new _Certificate({'tbscertobj': o, 'prvkeyobj': caKey});
3638         cert.sign();
3639     }
3640 
3641     if (param.sighex) {
3642         cert = new _Certificate({'tbscertobj': o});
3643         cert.setSignatureHex(param.sighex);
3644     }
3645 
3646     return cert.getPEMString();
3647 };
3648 
3649