1 /* asn1x509-1.1.7.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.14 asn1x509 1.1.7 (2020-Apr-11)
 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.ExtKeyUsage}</li>
 74  * <li>{@link KJUR.asn1.x509.AuthorityKeyIdentifier}</li>
 75  * <li>{@link KJUR.asn1.x509.SubjectKeyIdentifier}</li>
 76  * <li>{@link KJUR.asn1.x509.AuthorityInfoAccess}</li>
 77  * <li>{@link KJUR.asn1.x509.SubjectAltName}</li>
 78  * <li>{@link KJUR.asn1.x509.IssuerAltName}</li>
 79  * </ul>
 80  * NOTE1: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.<br/>
 81  * NOTE2: SubjectAltName and IssuerAltName extension were supported since 
 82  * jsrsasign 6.2.3 asn1x509 1.0.19.<br/>
 83  * @name KJUR.asn1.x509
 84  * @namespace
 85  */
 86 if (typeof KJUR.asn1.x509 == "undefined" || !KJUR.asn1.x509) KJUR.asn1.x509 = {};
 87 
 88 // === BEGIN Certificate ===================================================
 89 
 90 /**
 91  * X.509 Certificate class to sign and generate hex encoded certificate
 92  * @name KJUR.asn1.x509.Certificate
 93  * @class X.509 Certificate class to sign and generate hex encoded certificate
 94  * @param {Array} params associative array of parameters (ex. {'tbscertobj': obj, 'prvkeyobj': key})
 95  * @extends KJUR.asn1.ASN1Object
 96  * @description
 97  * <br/>
 98  * As for argument 'params' for constructor, you can specify one of
 99  * following properties:
100  * <ul>
101  * <li>tbscertobj - specify {@link KJUR.asn1.x509.TBSCertificate} object</li>
102  * <li>prvkeyobj - specify {@link RSAKey}, {@link KJUR.crypto.ECDSA} or {@link KJUR.crypto.DSA} object for CA private key to sign the certificate</li>
103  * </ul>
104  * NOTE1: 'params' can be omitted.<br/>
105  * NOTE2: DSA/ECDSA is also supported for CA signging key from asn1x509 1.0.6.
106  * @example
107  * var caKey = KEYUTIL.getKey(caKeyPEM); // CA's private key
108  * var cert = new KJUR.asn1x509.Certificate({'tbscertobj': tbs, 'prvkeyobj': caKey});
109  * cert.sign(); // issue certificate by CA's private key
110  * var certPEM = cert.getPEMString();
111  *
112  * // Certificate  ::=  SEQUENCE  {
113  * //     tbsCertificate       TBSCertificate,
114  * //     signatureAlgorithm   AlgorithmIdentifier,
115  * //     signature            BIT STRING  }
116  */
117 KJUR.asn1.x509.Certificate = function(params) {
118     KJUR.asn1.x509.Certificate.superclass.constructor.call(this);
119     var asn1TBSCert = null,
120 	asn1SignatureAlg = null,
121 	asn1Sig = null,
122 	hexSig = null,
123         prvKey = null,
124 	_KJUR = KJUR,
125 	_KJUR_crypto = _KJUR.crypto,
126 	_KJUR_asn1 = _KJUR.asn1,
127 	_DERSequence = _KJUR_asn1.DERSequence,
128 	_DERBitString = _KJUR_asn1.DERBitString;
129 
130     /**
131      * sign TBSCertificate and set signature value internally
132      * @name sign
133      * @memberOf KJUR.asn1.x509.Certificate#
134      * @function
135      * @description
136      * @example
137      * var cert = new KJUR.asn1.x509.Certificate({tbscertobj: tbs, prvkeyobj: prvKey});
138      * cert.sign();
139      */
140     this.sign = function() {
141         this.asn1SignatureAlg = this.asn1TBSCert.asn1SignatureAlg;
142 	
143         var sig = new KJUR.crypto.Signature({alg: this.asn1SignatureAlg.nameAlg});
144         sig.init(this.prvKey);
145         sig.updateHex(this.asn1TBSCert.getEncodedHex());
146         this.hexSig = sig.sign();
147 
148         this.asn1Sig = new _DERBitString({'hex': '00' + this.hexSig});
149 
150         var seq = new _DERSequence({'array': [this.asn1TBSCert,
151                                               this.asn1SignatureAlg,
152                                               this.asn1Sig]});
153         this.hTLV = seq.getEncodedHex();
154         this.isModified = false;
155     };
156 
157     /**
158      * set signature value internally by hex string
159      * @name setSignatureHex
160      * @memberOf KJUR.asn1.x509.Certificate#
161      * @function
162      * @since asn1x509 1.0.8
163      * @description
164      * @example
165      * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs});
166      * cert.setSignatureHex('01020304');
167      */
168     this.setSignatureHex = function(sigHex) {
169         this.asn1SignatureAlg = this.asn1TBSCert.asn1SignatureAlg;
170         this.hexSig = sigHex;
171         this.asn1Sig = new _DERBitString({'hex': '00' + this.hexSig});
172 
173         var seq = new _DERSequence({'array': [this.asn1TBSCert,
174                                               this.asn1SignatureAlg,
175                                               this.asn1Sig]});
176         this.hTLV = seq.getEncodedHex();
177         this.isModified = false;
178     };
179 
180     this.getEncodedHex = function() {
181         if (this.isModified == false && this.hTLV != null) return this.hTLV;
182         throw "not signed yet";
183     };
184 
185     /**
186      * get PEM formatted certificate string after signed
187      * @name getPEMString
188      * @memberOf KJUR.asn1.x509.Certificate#
189      * @function
190      * @return PEM formatted string of certificate
191      * @description
192      * @example
193      * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs, 'prvkeyobj': prvKey});
194      * cert.sign();
195      * var sPEM = cert.getPEMString();
196      */
197     this.getPEMString = function() {
198 	var pemBody = hextob64nl(this.getEncodedHex());
199         return "-----BEGIN CERTIFICATE-----\r\n" + 
200 	    pemBody + 
201 	    "\r\n-----END CERTIFICATE-----\r\n";
202     };
203 
204     if (params !== undefined) {
205         if (params.tbscertobj !== undefined) {
206             this.asn1TBSCert = params.tbscertobj;
207         }
208         if (params.prvkeyobj !== undefined) {
209             this.prvKey = params.prvkeyobj;
210         }
211     }
212 };
213 YAHOO.lang.extend(KJUR.asn1.x509.Certificate, KJUR.asn1.ASN1Object);
214 
215 /**
216  * ASN.1 TBSCertificate structure class
217  * @name KJUR.asn1.x509.TBSCertificate
218  * @class ASN.1 TBSCertificate structure class
219  * @param {Array} params associative array of parameters (ex. {})
220  * @extends KJUR.asn1.ASN1Object
221  * @description
222  * <br/>
223  * <h4>EXAMPLE</h4>
224  * @example
225  *  var o = new KJUR.asn1.x509.TBSCertificate();
226  *  o.setSerialNumberByParam({'int': 4});
227  *  o.setSignatureAlgByParam({'name': 'SHA1withRSA'});
228  *  o.setIssuerByParam({'str': '/C=US/O=a'});
229  *  o.setNotBeforeByParam({'str': '130504235959Z'});
230  *  o.setNotAfterByParam({'str': '140504235959Z'});
231  *  o.setSubjectByParam({'str': '/C=US/CN=b'});
232  *  o.setSubjectPublicKey(rsaPubKey);
233  *  o.appendExtension(new KJUR.asn1.x509.BasicConstraints({'cA':true}));
234  *  o.appendExtension(new KJUR.asn1.x509.KeyUsage({'bin':'11'}));
235  */
236 KJUR.asn1.x509.TBSCertificate = function(params) {
237     KJUR.asn1.x509.TBSCertificate.superclass.constructor.call(this);
238 
239     var _KJUR = KJUR,
240 	_KJUR_asn1 = _KJUR.asn1,
241 	_DERSequence = _KJUR_asn1.DERSequence,
242 	_DERInteger = _KJUR_asn1.DERInteger,
243 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
244 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
245 	_Time = _KJUR_asn1_x509.Time,
246 	_X500Name = _KJUR_asn1_x509.X500Name,
247 	_SubjectPublicKeyInfo = _KJUR_asn1_x509.SubjectPublicKeyInfo;
248 
249     this._initialize = function() {
250         this.asn1Array = new Array();
251 
252         this.asn1Version =
253             new _DERTaggedObject({'obj': new _DERInteger({'int': 2})});
254         this.asn1SerialNumber = null;
255         this.asn1SignatureAlg = null;
256         this.asn1Issuer = null;
257         this.asn1NotBefore = null;
258         this.asn1NotAfter = null;
259         this.asn1Subject = null;
260         this.asn1SubjPKey = null;
261         this.extensionsArray = new Array();
262     };
263 
264     /**
265      * set serial number field by parameter
266      * @name setSerialNumberByParam
267      * @memberOf KJUR.asn1.x509.TBSCertificate#
268      * @function
269      * @param {Array} intParam DERInteger param
270      * @description
271      * @example
272      * tbsc.setSerialNumberByParam({'int': 3});
273      */
274     this.setSerialNumberByParam = function(intParam) {
275         this.asn1SerialNumber = new _DERInteger(intParam);
276     };
277 
278     /**
279      * set signature algorithm field by parameter
280      * @name setSignatureAlgByParam
281      * @memberOf KJUR.asn1.x509.TBSCertificate#
282      * @function
283      * @param {Array} algIdParam AlgorithmIdentifier parameter
284      * @description
285      * @example
286      * tbsc.setSignatureAlgByParam({'name': 'SHA1withRSA'});
287      */
288     this.setSignatureAlgByParam = function(algIdParam) {
289         this.asn1SignatureAlg = new _KJUR_asn1_x509.AlgorithmIdentifier(algIdParam);
290     };
291 
292     /**
293      * set issuer name field by parameter
294      * @name setIssuerByParam
295      * @memberOf KJUR.asn1.x509.TBSCertificate#
296      * @function
297      * @param {Array} x500NameParam X500Name parameter
298      * @description
299      * @example
300      * tbsc.setIssuerParam({'str': '/C=US/CN=b'});
301      * @see KJUR.asn1.x509.X500Name
302      */
303     this.setIssuerByParam = function(x500NameParam) {
304         this.asn1Issuer = new _X500Name(x500NameParam);
305     };
306 
307     /**
308      * set notBefore field by parameter
309      * @name setNotBeforeByParam
310      * @memberOf KJUR.asn1.x509.TBSCertificate#
311      * @function
312      * @param {Array} timeParam Time parameter
313      * @description
314      * @example
315      * tbsc.setNotBeforeByParam({'str': '130508235959Z'});
316      * @see KJUR.asn1.x509.Time
317      */
318     this.setNotBeforeByParam = function(timeParam) {
319         this.asn1NotBefore = new _Time(timeParam);
320     };
321 
322     /**
323      * set notAfter field by parameter
324      * @name setNotAfterByParam
325      * @memberOf KJUR.asn1.x509.TBSCertificate#
326      * @function
327      * @param {Array} timeParam Time parameter
328      * @description
329      * @example
330      * tbsc.setNotAfterByParam({'str': '130508235959Z'});
331      * @see KJUR.asn1.x509.Time
332      */
333     this.setNotAfterByParam = function(timeParam) {
334         this.asn1NotAfter = new _Time(timeParam);
335     };
336 
337     /**
338      * set subject name field by parameter
339      * @name setSubjectByParam
340      * @memberOf KJUR.asn1.x509.TBSCertificate#
341      * @function
342      * @param {Array} x500NameParam X500Name parameter
343      * @description
344      * @example
345      * tbsc.setSubjectParam({'str': '/C=US/CN=b'});
346      * @see KJUR.asn1.x509.X500Name
347      */
348     this.setSubjectByParam = function(x500NameParam) {
349         this.asn1Subject = new _X500Name(x500NameParam);
350     };
351 
352     /**
353      * set subject public key info field by key object
354      * @name setSubjectPublicKey
355      * @memberOf KJUR.asn1.x509.TBSCertificate#
356      * @function
357      * @param {Array} param {@link KJUR.asn1.x509.SubjectPublicKeyInfo} class constructor parameter
358      * @description
359      * @example
360      * tbsc.setSubjectPublicKey(keyobj);
361      * @see KJUR.asn1.x509.SubjectPublicKeyInfo
362      */
363     this.setSubjectPublicKey = function(param) {
364         this.asn1SubjPKey = new _SubjectPublicKeyInfo(param);
365     };
366 
367     /**
368      * set subject public key info by RSA/ECDSA/DSA key parameter
369      * @name setSubjectPublicKeyByGetKey
370      * @memberOf KJUR.asn1.x509.TBSCertificate
371      * @function
372      * @param {Object} keyParam public key parameter which passed to {@link KEYUTIL.getKey} argument
373      * @description
374      * @example
375      * tbsc.setSubjectPublicKeyByGetKeyParam(certPEMString); // or
376      * tbsc.setSubjectPublicKeyByGetKeyParam(pkcs8PublicKeyPEMString); // or
377      * tbsc.setSubjectPublicKeyByGetKeyParam(kjurCryptoECDSAKeyObject); // et.al.
378      * @see KJUR.asn1.x509.SubjectPublicKeyInfo
379      * @see KEYUTIL.getKey
380      * @since asn1x509 1.0.6
381      */
382     this.setSubjectPublicKeyByGetKey = function(keyParam) {
383         var keyObj = KEYUTIL.getKey(keyParam);
384         this.asn1SubjPKey = new _SubjectPublicKeyInfo(keyObj);
385     };
386 
387     /**
388      * append X.509v3 extension to this object
389      * @name appendExtension
390      * @memberOf KJUR.asn1.x509.TBSCertificate#
391      * @function
392      * @param {Extension} extObj X.509v3 Extension object
393      * @description
394      * @example
395      * tbsc.appendExtension(new KJUR.asn1.x509.BasicConstraints({'cA':true, 'critical': true}));
396      * tbsc.appendExtension(new KJUR.asn1.x509.KeyUsage({'bin':'11'}));
397      * @see KJUR.asn1.x509.Extension
398      */
399     this.appendExtension = function(extObj) {
400         this.extensionsArray.push(extObj);
401     };
402 
403     /**
404      * append X.509v3 extension to this object by name and parameters
405      * @name appendExtensionByName
406      * @memberOf KJUR.asn1.x509.TBSCertificate#
407      * @function
408      * @param {name} name name of X.509v3 Extension object
409      * @param {Array} extParams parameters as argument of Extension constructor.
410      * @description
411      * This method adds a X.509v3 extension specified by name 
412      * and extParams to internal extension array of X.509v3 extension objects.
413      * Here is supported names of extension:
414      * <ul>
415      * <li>BasicConstraints - {@link KJUR.asn1.x509.BasicConstraints}</li>
416      * <li>KeyUsage - {@link KJUR.asn1.x509.KeyUsage}</li>
417      * <li>CRLDistributionPoints - {@link KJUR.asn1.x509.CRLDistributionPoints}</li>
418      * <li>ExtKeyUsage - {@link KJUR.asn1.x509.ExtKeyUsage}</li>
419      * <li>AuthorityKeyIdentifier - {@link KJUR.asn1.x509.AuthorityKeyIdentifier}</li>
420      * <li>SubjectKeyIdentifier - {@link KJUR.asn1.x509.SubjectKeyIdentifier}</li>
421      * <li>AuthorityInfoAccess - {@link KJUR.asn1.x509.AuthorityInfoAccess}</li>
422      * <li>SubjectAltName - {@link KJUR.asn1.x509.SubjectAltName}</li>
423      * <li>IssuerAltName - {@link KJUR.asn1.x509.IssuerAltName}</li>
424      * </ul>
425      * @example
426      * var o = new KJUR.asn1.x509.TBSCertificate();
427      * o.appendExtensionByName('BasicConstraints', {'cA':true, 'critical': true});
428      * o.appendExtensionByName('KeyUsage', {'bin':'11'});
429      * o.appendExtensionByName('CRLDistributionPoints', {uri: 'http://aaa.com/a.crl'});
430      * o.appendExtensionByName('ExtKeyUsage', {array: [{name: 'clientAuth'}]});
431      * o.appendExtensionByName('AuthorityKeyIdentifier', {kid: '1234ab..'});
432      * o.appendExtensionByName('SubjectKeyIdentifier', {kid: '1234ab..'});
433      * o.appendExtensionByName('AuthorityInfoAccess', {array: [{accessMethod:{oid:...},accessLocation:{uri:...}}]});
434      * @see KJUR.asn1.x509.Extension
435      */
436     this.appendExtensionByName = function(name, extParams) {
437 	KJUR.asn1.x509.Extension.appendByNameToArray(name,
438 						     extParams,
439 						     this.extensionsArray);
440     };
441 
442     this.getEncodedHex = function() {
443         if (this.asn1NotBefore == null || this.asn1NotAfter == null)
444             throw "notBefore and/or notAfter not set";
445         var asn1Validity =
446             new _DERSequence({'array':[this.asn1NotBefore, this.asn1NotAfter]});
447 
448         this.asn1Array = new Array();
449 
450         this.asn1Array.push(this.asn1Version);
451         this.asn1Array.push(this.asn1SerialNumber);
452         this.asn1Array.push(this.asn1SignatureAlg);
453         this.asn1Array.push(this.asn1Issuer);
454         this.asn1Array.push(asn1Validity);
455         this.asn1Array.push(this.asn1Subject);
456         this.asn1Array.push(this.asn1SubjPKey);
457 
458         if (this.extensionsArray.length > 0) {
459             var extSeq = new _DERSequence({"array": this.extensionsArray});
460             var extTagObj = new _DERTaggedObject({'explicit': true,
461                                                   'tag': 'a3',
462                                                   'obj': extSeq});
463             this.asn1Array.push(extTagObj);
464         }
465 
466         var o = new _DERSequence({"array": this.asn1Array});
467         this.hTLV = o.getEncodedHex();
468         this.isModified = false;
469         return this.hTLV;
470     };
471 
472     this._initialize();
473 };
474 YAHOO.lang.extend(KJUR.asn1.x509.TBSCertificate, KJUR.asn1.ASN1Object);
475 
476 // === END   TBSCertificate ===================================================
477 
478 // === BEGIN X.509v3 Extensions Related =======================================
479 
480 /**
481  * base Extension ASN.1 structure class
482  * @name KJUR.asn1.x509.Extension
483  * @class base Extension ASN.1 structure class
484  * @param {Array} params associative array of parameters (ex. {'critical': true})
485  * @extends KJUR.asn1.ASN1Object
486  * @description
487  * @example
488  * // Extension  ::=  SEQUENCE  {
489  * //     extnID      OBJECT IDENTIFIER,
490  * //     critical    BOOLEAN DEFAULT FALSE,
491  * //     extnValue   OCTET STRING  }
492  */
493 KJUR.asn1.x509.Extension = function(params) {
494     KJUR.asn1.x509.Extension.superclass.constructor.call(this);
495     var asn1ExtnValue = null,
496 	_KJUR = KJUR,
497 	_KJUR_asn1 = _KJUR.asn1,
498 	_DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
499 	_DEROctetString = _KJUR_asn1.DEROctetString,
500 	_DERBitString = _KJUR_asn1.DERBitString,
501 	_DERBoolean = _KJUR_asn1.DERBoolean,
502 	_DERSequence = _KJUR_asn1.DERSequence;
503 
504     this.getEncodedHex = function() {
505         var asn1Oid = new _DERObjectIdentifier({'oid': this.oid});
506         var asn1EncapExtnValue =
507             new _DEROctetString({'hex': this.getExtnValueHex()});
508 
509         var asn1Array = new Array();
510         asn1Array.push(asn1Oid);
511         if (this.critical) asn1Array.push(new _DERBoolean());
512         asn1Array.push(asn1EncapExtnValue);
513 
514         var asn1Seq = new _DERSequence({'array': asn1Array});
515         return asn1Seq.getEncodedHex();
516     };
517 
518     this.critical = false;
519     if (params !== undefined) {
520         if (params.critical !== undefined) {
521             this.critical = params.critical;
522         }
523     }
524 };
525 YAHOO.lang.extend(KJUR.asn1.x509.Extension, KJUR.asn1.ASN1Object);
526 
527 /**
528  * append X.509v3 extension to any specified array<br/>
529  * @name appendByNameToArray
530  * @memberOf KJUR.asn1.x509.Extension
531  * @function
532  * @param {String} name X.509v3 extension name
533  * @param {Object} extParams associative array of extension parameters
534  * @param {Array} a array to add specified extension
535  * @see KJUR.asn1.x509.Extension
536  * @since jsrsasign 6.2.3 asn1x509 1.0.19
537  * @description
538  * This static function add a X.509v3 extension specified by name and extParams to
539  * array 'a' so that 'a' will be an array of X.509v3 extension objects.
540  * See {@link KJUR.asn1.x509.TBSCertificate#appendExtensionByName}
541  * for supported names of extensions.
542  * @example
543  * var a = new Array();
544  * KJUR.asn1.x509.Extension.appendByNameToArray("BasicConstraints", {'cA':true, 'critical': true}, a);
545  * KJUR.asn1.x509.Extension.appendByNameToArray("KeyUsage", {'bin':'11'}, a);
546  */
547 KJUR.asn1.x509.Extension.appendByNameToArray = function(name, extParams, a) {
548     var _lowname = name.toLowerCase(),
549 	_KJUR_asn1_x509 = KJUR.asn1.x509;
550     
551     if (_lowname == "basicconstraints") {
552         var extObj = new _KJUR_asn1_x509.BasicConstraints(extParams);
553         a.push(extObj);
554     } else if (_lowname == "keyusage") {
555         var extObj = new _KJUR_asn1_x509.KeyUsage(extParams);
556         a.push(extObj);
557     } else if (_lowname == "crldistributionpoints") {
558         var extObj = new _KJUR_asn1_x509.CRLDistributionPoints(extParams);
559         a.push(extObj);
560     } else if (_lowname == "extkeyusage") {
561         var extObj = new _KJUR_asn1_x509.ExtKeyUsage(extParams);
562         a.push(extObj);
563     } else if (_lowname == "authoritykeyidentifier") {
564         var extObj = new _KJUR_asn1_x509.AuthorityKeyIdentifier(extParams);
565         a.push(extObj);
566     } else if (_lowname == "subjectkeyidentifier") {
567         var extObj = new _KJUR_asn1_x509.SubjectKeyIdentifier(extParams);
568         a.push(extObj);
569     } else if (_lowname == "authorityinfoaccess") {
570         var extObj = new _KJUR_asn1_x509.AuthorityInfoAccess(extParams);
571         a.push(extObj);
572     } else if (_lowname == "subjectaltname") {
573         var extObj = new _KJUR_asn1_x509.SubjectAltName(extParams);
574         a.push(extObj);
575     } else if (_lowname == "issueraltname") {
576         var extObj = new _KJUR_asn1_x509.IssuerAltName(extParams);
577         a.push(extObj);
578     } else {
579         throw "unsupported extension name: " + name;
580     }
581 };
582 
583 /**
584  * KeyUsage ASN.1 structure class
585  * @name KJUR.asn1.x509.KeyUsage
586  * @class KeyUsage ASN.1 structure class
587  * @param {Array} params associative array of parameters (ex. {'bin': '11', 'critical': true})
588  * @extends KJUR.asn1.x509.Extension
589  * @description
590  * This class is for <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.3" target="_blank">KeyUsage</a> X.509v3 extension.
591  * <pre>
592  * id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }
593  * KeyUsage ::= BIT STRING {
594  *   digitalSignature   (0),
595  *   nonRepudiation     (1),
596  *   keyEncipherment    (2),
597  *   dataEncipherment   (3),
598  *   keyAgreement       (4),
599  *   keyCertSign        (5),
600  *   cRLSign            (6),
601  *   encipherOnly       (7),
602  *   decipherOnly       (8) }
603  * </pre><br/>
604  * NOTE: 'names' parameter is supprted since jsrsasign 8.0.14.
605  * @example
606  * o = new KJUR.asn1.x509.KeyUsage({bin: "11"});
607  * o = new KJUR.asn1.x509.KeyUsage({critical: true, bin: "11"});
608  * o = new KJUR.asn1.x509.KeyUsage({names: ['digitalSignature', 'keyAgreement']});
609  */
610 KJUR.asn1.x509.KeyUsage = function(params) {
611     KJUR.asn1.x509.KeyUsage.superclass.constructor.call(this, params);
612     var _KEYUSAGE_NAME = X509.KEYUSAGE_NAME;
613 
614     this.getExtnValueHex = function() {
615         return this.asn1ExtnValue.getEncodedHex();
616     };
617 
618     this.oid = "2.5.29.15";
619     if (params !== undefined) {
620         if (params.bin !== undefined) {
621             this.asn1ExtnValue = new KJUR.asn1.DERBitString(params);
622         }
623 	if (params.names !== undefined &&
624 	    params.names.length !== undefined) {
625 	    var names = params.names;
626 	    var s = "000000000";
627 	    for (var i = 0; i < names.length; i++) {
628 		for (var j = 0; j < _KEYUSAGE_NAME.length; j++) {
629 		    if (names[i] === _KEYUSAGE_NAME[j]) {
630 			s = s.substring(0, j) + '1' + 
631 			    s.substring(j + 1, s.length);
632 		    }
633 		}
634 	    }
635             this.asn1ExtnValue = new KJUR.asn1.DERBitString({bin: s});
636 	}
637     }
638 };
639 YAHOO.lang.extend(KJUR.asn1.x509.KeyUsage, KJUR.asn1.x509.Extension);
640 
641 /**
642  * BasicConstraints ASN.1 structure class
643  * @name KJUR.asn1.x509.BasicConstraints
644  * @class BasicConstraints ASN.1 structure class
645  * @param {Array} params associative array of parameters (ex. {'cA': true, 'critical': true})
646  * @extends KJUR.asn1.x509.Extension
647  * @description
648  * @example
649  */
650 KJUR.asn1.x509.BasicConstraints = function(params) {
651     KJUR.asn1.x509.BasicConstraints.superclass.constructor.call(this, params);
652     var cA = false;
653     var pathLen = -1;
654 
655     this.getExtnValueHex = function() {
656         var asn1Array = new Array();
657         if (this.cA) asn1Array.push(new KJUR.asn1.DERBoolean());
658         if (this.pathLen > -1)
659             asn1Array.push(new KJUR.asn1.DERInteger({'int': this.pathLen}));
660         var asn1Seq = new KJUR.asn1.DERSequence({'array': asn1Array});
661         this.asn1ExtnValue = asn1Seq;
662         return this.asn1ExtnValue.getEncodedHex();
663     };
664 
665     this.oid = "2.5.29.19";
666     this.cA = false;
667     this.pathLen = -1;
668     if (params !== undefined) {
669         if (params.cA !== undefined) {
670             this.cA = params.cA;
671         }
672         if (params.pathLen !== undefined) {
673             this.pathLen = params.pathLen;
674         }
675     }
676 };
677 YAHOO.lang.extend(KJUR.asn1.x509.BasicConstraints, KJUR.asn1.x509.Extension);
678 
679 /**
680  * CRLDistributionPoints ASN.1 structure class
681  * @name KJUR.asn1.x509.CRLDistributionPoints
682  * @class CRLDistributionPoints ASN.1 structure class
683  * @param {Array} params associative array of parameters (ex. {'uri': 'http://a.com/', 'critical': true})
684  * @extends KJUR.asn1.x509.Extension
685  * @description
686  * <pre>
687  * id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::=  { id-ce 31 }
688  *
689  * CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
690  *
691  * DistributionPoint ::= SEQUENCE {
692  *      distributionPoint       [0]     DistributionPointName OPTIONAL,
693  *      reasons                 [1]     ReasonFlags OPTIONAL,
694  *      cRLIssuer               [2]     GeneralNames OPTIONAL }
695  *
696  * DistributionPointName ::= CHOICE {
697  *      fullName                [0]     GeneralNames,
698  *      nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
699  * 
700  * ReasonFlags ::= BIT STRING {
701  *      unused                  (0),
702  *      keyCompromise           (1),
703  *      cACompromise            (2),
704  *      affiliationChanged      (3),
705  *      superseded              (4),
706  *      cessationOfOperation    (5),
707  *      certificateHold         (6),
708  *      privilegeWithdrawn      (7),
709  *      aACompromise            (8) }
710  * </pre>
711  * @example
712  */
713 KJUR.asn1.x509.CRLDistributionPoints = function(params) {
714     KJUR.asn1.x509.CRLDistributionPoints.superclass.constructor.call(this, params);
715     var _KJUR = KJUR,
716 	_KJUR_asn1 = _KJUR.asn1,
717 	_KJUR_asn1_x509 = _KJUR_asn1.x509;
718 
719     this.getExtnValueHex = function() {
720         return this.asn1ExtnValue.getEncodedHex();
721     };
722 
723     this.setByDPArray = function(dpArray) {
724         this.asn1ExtnValue = new _KJUR_asn1.DERSequence({'array': dpArray});
725     };
726 
727     this.setByOneURI = function(uri) {
728         var gn1 = new _KJUR_asn1_x509.GeneralNames([{'uri': uri}]);
729         var dpn1 = new _KJUR_asn1_x509.DistributionPointName(gn1);
730         var dp1 = new _KJUR_asn1_x509.DistributionPoint({'dpobj': dpn1});
731         this.setByDPArray([dp1]);
732     };
733 
734     this.oid = "2.5.29.31";
735     if (params !== undefined) {
736         if (params.array !== undefined) {
737             this.setByDPArray(params.array);
738         } else if (params.uri !== undefined) {
739             this.setByOneURI(params.uri);
740         }
741     }
742 };
743 YAHOO.lang.extend(KJUR.asn1.x509.CRLDistributionPoints, KJUR.asn1.x509.Extension);
744 
745 /**
746  * KeyUsage ASN.1 structure class
747  * @name KJUR.asn1.x509.ExtKeyUsage
748  * @class ExtKeyUsage ASN.1 structure class
749  * @param {Array} params associative array of parameters
750  * @extends KJUR.asn1.x509.Extension
751  * @description
752  * @example
753  * e1 = new KJUR.asn1.x509.ExtKeyUsage({
754  *   critical: true,
755  *   array: [
756  *     {oid: '2.5.29.37.0'},  // anyExtendedKeyUsage
757  *     {name: 'clientAuth'}
758  *   ]
759  * });
760  * // id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
761  * // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
762  * // KeyPurposeId ::= OBJECT IDENTIFIER
763  */
764 KJUR.asn1.x509.ExtKeyUsage = function(params) {
765     KJUR.asn1.x509.ExtKeyUsage.superclass.constructor.call(this, params);
766     var _KJUR = KJUR,
767 	_KJUR_asn1 = _KJUR.asn1;
768 
769     this.setPurposeArray = function(purposeArray) {
770         this.asn1ExtnValue = new _KJUR_asn1.DERSequence();
771         for (var i = 0; i < purposeArray.length; i++) {
772             var o = new _KJUR_asn1.DERObjectIdentifier(purposeArray[i]);
773             this.asn1ExtnValue.appendASN1Object(o);
774         }
775     };
776 
777     this.getExtnValueHex = function() {
778         return this.asn1ExtnValue.getEncodedHex();
779     };
780 
781     this.oid = "2.5.29.37";
782     if (params !== undefined) {
783         if (params.array !== undefined) {
784             this.setPurposeArray(params.array);
785         }
786     }
787 };
788 YAHOO.lang.extend(KJUR.asn1.x509.ExtKeyUsage, KJUR.asn1.x509.Extension);
789 
790 /**
791  * AuthorityKeyIdentifier ASN.1 structure class
792  * @name KJUR.asn1.x509.AuthorityKeyIdentifier
793  * @class AuthorityKeyIdentifier ASN.1 structure class
794  * @param {Array} params associative array of parameters (ex. {kid: {hex: '89ab...'}, critical: true})
795  * @extends KJUR.asn1.x509.Extension
796  * @since asn1x509 1.0.8
797  * @description
798  * <pre>
799  * d-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 }
800  * AuthorityKeyIdentifier ::= SEQUENCE {
801  *    keyIdentifier             [0] KeyIdentifier           OPTIONAL,
802  *    authorityCertIssuer       [1] GeneralNames            OPTIONAL,
803  *    authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
804  * KeyIdentifier ::= OCTET STRING
805  * </pre>
806  * @example
807  * e1 = new KJUR.asn1.x509.AuthorityKeyIdentifier({
808  *   critical: true,
809  *   kid:    {hex: '89ab'},
810  *   issuer: {str: '/C=US/CN=a'},
811  *   sn:     {hex: '1234'}
812  * });
813  */
814 KJUR.asn1.x509.AuthorityKeyIdentifier = function(params) {
815     KJUR.asn1.x509.AuthorityKeyIdentifier.superclass.constructor.call(this, params);
816     var _KJUR = KJUR,
817 	_KJUR_asn1 = _KJUR.asn1,
818 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject;
819 
820     this.asn1KID = null;
821     this.asn1CertIssuer = null;
822     this.asn1CertSN = null;
823 
824     this.getExtnValueHex = function() {
825         var a = new Array();
826         if (this.asn1KID)
827             a.push(new _DERTaggedObject({'explicit': false,
828                                          'tag': '80',
829                                          'obj': this.asn1KID}));
830         if (this.asn1CertIssuer)
831             a.push(new _DERTaggedObject({'explicit': false,
832                                          'tag': 'a1',
833                                          'obj': this.asn1CertIssuer}));
834         if (this.asn1CertSN)
835             a.push(new _DERTaggedObject({'explicit': false,
836                                          'tag': '82',
837                                          'obj': this.asn1CertSN}));
838 
839         var asn1Seq = new _KJUR_asn1.DERSequence({'array': a});
840         this.asn1ExtnValue = asn1Seq;
841         return this.asn1ExtnValue.getEncodedHex();
842     };
843 
844     /**
845      * set keyIdentifier value by DERInteger parameter
846      * @name setKIDByParam
847      * @memberOf KJUR.asn1.x509.AuthorityKeyIdentifier#
848      * @function
849      * @param {Array} param array of {@link KJUR.asn1.DERInteger} parameter
850      * @since asn1x509 1.0.8
851      * @description
852      * NOTE: Automatic keyIdentifier value calculation by an issuer
853      * public key will be supported in future version.
854      */
855     this.setKIDByParam = function(param) {
856         this.asn1KID = new KJUR.asn1.DEROctetString(param);
857     };
858 
859     /**
860      * set authorityCertIssuer value by X500Name parameter
861      * @name setCertIssuerByParam
862      * @memberOf KJUR.asn1.x509.AuthorityKeyIdentifier#
863      * @function
864      * @param {Array} param array of {@link KJUR.asn1.x509.X500Name} parameter
865      * @since asn1x509 1.0.8
866      * @description
867      * NOTE: Automatic authorityCertIssuer name setting by an issuer
868      * certificate will be supported in future version.
869      */
870     this.setCertIssuerByParam = function(param) {
871         this.asn1CertIssuer = new KJUR.asn1.x509.X500Name(param);
872     };
873 
874     /**
875      * set authorityCertSerialNumber value by DERInteger parameter
876      * @name setCertSerialNumberByParam
877      * @memberOf KJUR.asn1.x509.AuthorityKeyIdentifier#
878      * @function
879      * @param {Array} param array of {@link KJUR.asn1.DERInteger} parameter
880      * @since asn1x509 1.0.8
881      * @description
882      * NOTE: Automatic authorityCertSerialNumber setting by an issuer
883      * certificate will be supported in future version.
884      */
885     this.setCertSNByParam = function(param) {
886         this.asn1CertSN = new KJUR.asn1.DERInteger(param);
887     };
888 
889     this.oid = "2.5.29.35";
890     if (params !== undefined) {
891         if (params.kid !== undefined) {
892             this.setKIDByParam(params.kid);
893         }
894         if (params.issuer !== undefined) {
895             this.setCertIssuerByParam(params.issuer);
896         }
897         if (params.sn !== undefined) {
898             this.setCertSNByParam(params.sn);
899         }
900     }
901 };
902 YAHOO.lang.extend(KJUR.asn1.x509.AuthorityKeyIdentifier, KJUR.asn1.x509.Extension);
903 
904 /**
905  * SubjectKeyIdentifier ASN.1 structure class
906  * @name KJUR.asn1.x509.SubjectKeyIdentifier
907  * @class SubjectKeyIdentifier ASN.1 structure class
908  * @param {Array} params associative array of parameters (ex. {kid: {hex: '89ab...'}, critical: true})
909  * @extends KJUR.asn1.x509.Extension
910  * @since asn1x509 1.1.7 jsrsasign 8.0.14
911  * @description
912  * <pre>
913  * d-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 14 }
914  * SubjectKeyIdentifier ::= KeyIdentifier
915  * KeyIdentifier ::= OCTET STRING
916  * </pre>
917  * @example
918  * e1 = new KJUR.asn1.x509.SubjectKeyIdentifier({
919  *   critical: true,
920  *   kid:    {hex: '89ab'},
921  * });
922  */
923 KJUR.asn1.x509.SubjectKeyIdentifier = function(params) {
924     KJUR.asn1.x509.SubjectKeyIdentifier.superclass.constructor.call(this, params);
925     var _KJUR = KJUR,
926 	_KJUR_asn1 = _KJUR.asn1,
927 	_DEROctetString = _KJUR_asn1.DEROctetString;
928 
929     this.asn1KID = null;
930 
931     this.getExtnValueHex = function() {
932         this.asn1ExtnValue = this.asn1KID;
933         return this.asn1ExtnValue.getEncodedHex();
934     };
935 
936     /**
937      * set keyIdentifier value by DERInteger parameter
938      * @name setKIDByParam
939      * @memberOf KJUR.asn1.x509.SubjectKeyIdentifier#
940      * @function
941      * @param {Array} param array of {@link KJUR.asn1.DERInteger} parameter
942      * @since asn1x509 1.1.7 jsrsasign 8.0.14
943      * @description
944      * NOTE: Automatic keyIdentifier value calculation by an issuer
945      * public key will be supported in future version.
946      */
947     this.setKIDByParam = function(param) {
948         this.asn1KID = new _DEROctetString(param);
949     };
950 
951     this.oid = "2.5.29.14";
952     if (params !== undefined) {
953         if (params.kid !== undefined) {
954             this.setKIDByParam(params.kid);
955         }
956     }
957 };
958 YAHOO.lang.extend(KJUR.asn1.x509.SubjectKeyIdentifier, KJUR.asn1.x509.Extension);
959 
960 /**
961  * AuthorityInfoAccess ASN.1 structure class
962  * @name KJUR.asn1.x509.AuthorityInfoAccess
963  * @class AuthorityInfoAccess ASN.1 structure class
964  * @param {Array} params associative array of parameters
965  * @extends KJUR.asn1.x509.Extension
966  * @since asn1x509 1.0.8
967  * @description
968  * <pre>
969  * id-pe OBJECT IDENTIFIER  ::=  { id-pkix 1 }
970  * id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
971  * AuthorityInfoAccessSyntax  ::=
972  *         SEQUENCE SIZE (1..MAX) OF AccessDescription
973  * AccessDescription  ::=  SEQUENCE {
974  *         accessMethod          OBJECT IDENTIFIER,
975  *         accessLocation        GeneralName  }
976  * id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
977  * id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
978  * id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
979  * </pre>
980  * @example
981  * e1 = new KJUR.asn1.x509.AuthorityInfoAccess({
982  *   array: [{
983  *     accessMethod:{'oid': '1.3.6.1.5.5.7.48.1'},
984  *     accessLocation:{'uri': 'http://ocsp.cacert.org'}
985  *   }]
986  * });
987  */
988 KJUR.asn1.x509.AuthorityInfoAccess = function(params) {
989     KJUR.asn1.x509.AuthorityInfoAccess.superclass.constructor.call(this, params);
990 
991     this.setAccessDescriptionArray = function(accessDescriptionArray) {
992         var array = new Array(),
993 	    _KJUR = KJUR,
994 	    _KJUR_asn1 = _KJUR.asn1,
995 	    _DERSequence = _KJUR_asn1.DERSequence;
996 
997         for (var i = 0; i < accessDescriptionArray.length; i++) {
998             var o = new _KJUR_asn1.DERObjectIdentifier(accessDescriptionArray[i].accessMethod);
999             var gn = new _KJUR_asn1.x509.GeneralName(accessDescriptionArray[i].accessLocation);
1000             var accessDescription = new _DERSequence({'array':[o, gn]});
1001             array.push(accessDescription);
1002         }
1003         this.asn1ExtnValue = new _DERSequence({'array':array});
1004     };
1005 
1006     this.getExtnValueHex = function() {
1007         return this.asn1ExtnValue.getEncodedHex();
1008     };
1009 
1010     this.oid = "1.3.6.1.5.5.7.1.1";
1011     if (params !== undefined) {
1012         if (params.array !== undefined) {
1013             this.setAccessDescriptionArray(params.array);
1014         }
1015     }
1016 };
1017 YAHOO.lang.extend(KJUR.asn1.x509.AuthorityInfoAccess, KJUR.asn1.x509.Extension);
1018 
1019 /**
1020  * SubjectAltName ASN.1 structure class<br/>
1021  * @name KJUR.asn1.x509.SubjectAltName
1022  * @class SubjectAltName ASN.1 structure class
1023  * @param {Array} params associative array of parameters
1024  * @extends KJUR.asn1.x509.Extension
1025  * @since jsrsasign 6.2.3 asn1x509 1.0.19
1026  * @see KJUR.asn1.x509.GeneralNames
1027  * @see KJUR.asn1.x509.GeneralName
1028  * @description
1029  * This class provides X.509v3 SubjectAltName extension.
1030  * <pre>
1031  * id-ce-subjectAltName OBJECT IDENTIFIER ::=  { id-ce 17 }
1032  * SubjectAltName ::= GeneralNames
1033  * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
1034  * GeneralName ::= CHOICE {
1035  *   otherName                  [0] OtherName,
1036  *   rfc822Name                 [1] IA5String,
1037  *   dNSName                    [2] IA5String,
1038  *   x400Address                [3] ORAddress,
1039  *   directoryName              [4] Name,
1040  *   ediPartyName               [5] EDIPartyName,
1041  *   uniformResourceIdentifier  [6] IA5String,
1042  *   iPAddress                  [7] OCTET STRING,
1043  *   registeredID               [8] OBJECT IDENTIFIER }
1044  * </pre>
1045  * @example
1046  * e1 = new KJUR.asn1.x509.SubjectAltName({
1047  *   critical: true,
1048  *   array: [{uri: 'http://aaa.com/'}, {uri: 'http://bbb.com/'}]
1049  * });
1050  */
1051 KJUR.asn1.x509.SubjectAltName = function(params) {
1052     KJUR.asn1.x509.SubjectAltName.superclass.constructor.call(this, params)
1053 
1054     this.setNameArray = function(paramsArray) {
1055 	this.asn1ExtnValue = new KJUR.asn1.x509.GeneralNames(paramsArray);
1056     };
1057 
1058     this.getExtnValueHex = function() {
1059         return this.asn1ExtnValue.getEncodedHex();
1060     };
1061 
1062     this.oid = "2.5.29.17";
1063     if (params !== undefined) {
1064         if (params.array !== undefined) {
1065             this.setNameArray(params.array);
1066         }
1067     }
1068 };
1069 YAHOO.lang.extend(KJUR.asn1.x509.SubjectAltName, KJUR.asn1.x509.Extension);
1070 
1071 /**
1072  * IssuerAltName ASN.1 structure class<br/>
1073  * @name KJUR.asn1.x509.IssuerAltName
1074  * @class IssuerAltName ASN.1 structure class
1075  * @param {Array} params associative array of parameters
1076  * @extends KJUR.asn1.x509.Extension
1077  * @since jsrsasign 6.2.3 asn1x509 1.0.19
1078  * @see KJUR.asn1.x509.GeneralNames
1079  * @see KJUR.asn1.x509.GeneralName
1080  * @description
1081  * This class provides X.509v3 IssuerAltName extension.
1082  * <pre>
1083  * id-ce-subjectAltName OBJECT IDENTIFIER ::=  { id-ce 18 }
1084  * IssuerAltName ::= GeneralNames
1085  * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
1086  * GeneralName ::= CHOICE {
1087  *   otherName                  [0] OtherName,
1088  *   rfc822Name                 [1] IA5String,
1089  *   dNSName                    [2] IA5String,
1090  *   x400Address                [3] ORAddress,
1091  *   directoryName              [4] Name,
1092  *   ediPartyName               [5] EDIPartyName,
1093  *   uniformResourceIdentifier  [6] IA5String,
1094  *   iPAddress                  [7] OCTET STRING,
1095  *   registeredID               [8] OBJECT IDENTIFIER }
1096  * </pre>
1097  * @example
1098  * e1 = new KJUR.asn1.x509.IssuerAltName({
1099  *   critical: true,
1100  *   array: [{uri: 'http://aaa.com/'}, {uri: 'http://bbb.com/'}]
1101  * });
1102  */
1103 KJUR.asn1.x509.IssuerAltName = function(params) {
1104     KJUR.asn1.x509.IssuerAltName.superclass.constructor.call(this, params)
1105 
1106     this.setNameArray = function(paramsArray) {
1107 	this.asn1ExtnValue = new KJUR.asn1.x509.GeneralNames(paramsArray);
1108     };
1109 
1110     this.getExtnValueHex = function() {
1111         return this.asn1ExtnValue.getEncodedHex();
1112     };
1113 
1114     this.oid = "2.5.29.18";
1115     if (params !== undefined) {
1116         if (params.array !== undefined) {
1117             this.setNameArray(params.array);
1118         }
1119     }
1120 };
1121 YAHOO.lang.extend(KJUR.asn1.x509.IssuerAltName, KJUR.asn1.x509.Extension);
1122 
1123 // === END   X.509v3 Extensions Related =======================================
1124 
1125 // === BEGIN CRL Related ===================================================
1126 /**
1127  * X.509 CRL class to sign and generate hex encoded CRL
1128  * @name KJUR.asn1.x509.CRL
1129  * @class X.509 CRL class to sign and generate hex encoded certificate
1130  * @param {Array} params associative array of parameters (ex. {'tbsobj': obj, 'rsaprvkey': key})
1131  * @extends KJUR.asn1.ASN1Object
1132  * @since 1.0.3
1133  * @description
1134  * <br/>
1135  * As for argument 'params' for constructor, you can specify one of
1136  * following properties:
1137  * <ul>
1138  * <li>tbsobj - specify {@link KJUR.asn1.x509.TBSCertList} object to be signed</li>
1139  * <li>rsaprvkey - specify {@link RSAKey} object CA private key</li>
1140  * </ul>
1141  * NOTE: 'params' can be omitted.
1142  * <h4>EXAMPLE</h4>
1143  * @example
1144  * var prvKey = new RSAKey(); // CA's private key
1145  * prvKey.readPrivateKeyFromASN1HexString("3080...");
1146  * var crl = new KJUR.asn1x509.CRL({'tbsobj': tbs, 'prvkeyobj': prvKey});
1147  * crl.sign(); // issue CRL by CA's private key
1148  * var hCRL = crl.getEncodedHex();
1149  *
1150  * // CertificateList  ::=  SEQUENCE  {
1151  * //     tbsCertList          TBSCertList,
1152  * //     signatureAlgorithm   AlgorithmIdentifier,
1153  * //     signatureValue       BIT STRING  }
1154  */
1155 KJUR.asn1.x509.CRL = function(params) {
1156     KJUR.asn1.x509.CRL.superclass.constructor.call(this);
1157 
1158     var asn1TBSCertList = null,
1159 	asn1SignatureAlg = null,
1160 	asn1Sig = null,
1161 	hexSig = null,
1162 	prvKey = null;
1163 
1164     /**
1165      * sign TBSCertList and set signature value internally
1166      * @name sign
1167      * @memberOf KJUR.asn1.x509.CRL#
1168      * @function
1169      * @description
1170      * @example
1171      * var cert = new KJUR.asn1.x509.CRL({'tbsobj': tbs, 'prvkeyobj': prvKey});
1172      * cert.sign();
1173      */
1174     this.sign = function() {
1175         this.asn1SignatureAlg = this.asn1TBSCertList.asn1SignatureAlg;
1176 
1177         sig = new KJUR.crypto.Signature({'alg': 'SHA1withRSA', 'prov': 'cryptojs/jsrsa'});
1178         sig.init(this.prvKey);
1179         sig.updateHex(this.asn1TBSCertList.getEncodedHex());
1180         this.hexSig = sig.sign();
1181 
1182         this.asn1Sig = new KJUR.asn1.DERBitString({'hex': '00' + this.hexSig});
1183 
1184         var seq = new KJUR.asn1.DERSequence({'array': [this.asn1TBSCertList,
1185                                                        this.asn1SignatureAlg,
1186                                                        this.asn1Sig]});
1187         this.hTLV = seq.getEncodedHex();
1188         this.isModified = false;
1189     };
1190 
1191     this.getEncodedHex = function() {
1192         if (this.isModified == false && this.hTLV != null) return this.hTLV;
1193         throw "not signed yet";
1194     };
1195 
1196     /**
1197      * get PEM formatted CRL string after signed
1198      * @name getPEMString
1199      * @memberOf KJUR.asn1.x509.CRL#
1200      * @function
1201      * @return PEM formatted string of certificate
1202      * @description
1203      * @example
1204      * var cert = new KJUR.asn1.x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey});
1205      * cert.sign();
1206      * var sPEM =  cert.getPEMString();
1207      */
1208     this.getPEMString = function() {
1209         var pemBody = hextob64nl(this.getEncodedHex());
1210         return "-----BEGIN X509 CRL-----\r\n" + 
1211 	    pemBody + 
1212 	    "\r\n-----END X509 CRL-----\r\n";
1213     };
1214 
1215     if (params !== undefined) {
1216         if (params.tbsobj !== undefined) {
1217             this.asn1TBSCertList = params.tbsobj;
1218         }
1219         if (params.prvkeyobj !== undefined) {
1220             this.prvKey = params.prvkeyobj;
1221         }
1222     }
1223 };
1224 YAHOO.lang.extend(KJUR.asn1.x509.CRL, KJUR.asn1.ASN1Object);
1225 
1226 /**
1227  * ASN.1 TBSCertList structure class for CRL
1228  * @name KJUR.asn1.x509.TBSCertList
1229  * @class ASN.1 TBSCertList structure class for CRL
1230  * @param {Array} params associative array of parameters (ex. {})
1231  * @extends KJUR.asn1.ASN1Object
1232  * @since 1.0.3
1233  * @description
1234  * <br/>
1235  * <h4>EXAMPLE</h4>
1236  * @example
1237  *  var o = new KJUR.asn1.x509.TBSCertList();
1238  *  o.setSignatureAlgByParam({'name': 'SHA1withRSA'});
1239  *  o.setIssuerByParam({'str': '/C=US/O=a'});
1240  *  o.setNotThisUpdateByParam({'str': '130504235959Z'});
1241  *  o.setNotNextUpdateByParam({'str': '140504235959Z'});
1242  *  o.addRevokedCert({'int': 4}, {'str':'130514235959Z'}));
1243  *  o.addRevokedCert({'hex': '0f34dd'}, {'str':'130514235959Z'}));
1244  *
1245  * // TBSCertList  ::=  SEQUENCE  {
1246  * //        version                 Version OPTIONAL,
1247  * //                                     -- if present, MUST be v2
1248  * //        signature               AlgorithmIdentifier,
1249  * //        issuer                  Name,
1250  * //        thisUpdate              Time,
1251  * //        nextUpdate              Time OPTIONAL,
1252  * //        revokedCertificates     SEQUENCE OF SEQUENCE  {
1253  * //             userCertificate         CertificateSerialNumber,
1254  * //             revocationDate          Time,
1255  * //             crlEntryExtensions      Extensions OPTIONAL
1256  * //                                      -- if present, version MUST be v2
1257  * //                                  }  OPTIONAL,
1258  * //        crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
1259  */
1260 KJUR.asn1.x509.TBSCertList = function(params) {
1261     KJUR.asn1.x509.TBSCertList.superclass.constructor.call(this);
1262     var aRevokedCert = null,
1263 	_KJUR = KJUR,
1264 	_KJUR_asn1 = _KJUR.asn1,
1265 	_DERSequence = _KJUR_asn1.DERSequence,
1266 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
1267 	_Time = _KJUR_asn1_x509.Time;
1268 
1269     /**
1270      * set signature algorithm field by parameter
1271      * @name setSignatureAlgByParam
1272      * @memberOf KJUR.asn1.x509.TBSCertList#
1273      * @function
1274      * @param {Array} algIdParam AlgorithmIdentifier parameter
1275      * @description
1276      * @example
1277      * tbsc.setSignatureAlgByParam({'name': 'SHA1withRSA'});
1278      */
1279     this.setSignatureAlgByParam = function(algIdParam) {
1280         this.asn1SignatureAlg = 
1281 	    new _KJUR_asn1_x509.AlgorithmIdentifier(algIdParam);
1282     };
1283 
1284     /**
1285      * set issuer name field by parameter
1286      * @name setIssuerByParam
1287      * @memberOf KJUR.asn1.x509.TBSCertList#
1288      * @function
1289      * @param {Array} x500NameParam X500Name parameter
1290      * @description
1291      * @example
1292      * tbsc.setIssuerParam({'str': '/C=US/CN=b'});
1293      * @see KJUR.asn1.x509.X500Name
1294      */
1295     this.setIssuerByParam = function(x500NameParam) {
1296         this.asn1Issuer = new _KJUR_asn1_x509.X500Name(x500NameParam);
1297     };
1298 
1299     /**
1300      * set thisUpdate field by parameter
1301      * @name setThisUpdateByParam
1302      * @memberOf KJUR.asn1.x509.TBSCertList#
1303      * @function
1304      * @param {Array} timeParam Time parameter
1305      * @description
1306      * @example
1307      * tbsc.setThisUpdateByParam({'str': '130508235959Z'});
1308      * @see KJUR.asn1.x509.Time
1309      */
1310     this.setThisUpdateByParam = function(timeParam) {
1311         this.asn1ThisUpdate = new _Time(timeParam);
1312     };
1313 
1314     /**
1315      * set nextUpdate field by parameter
1316      * @name setNextUpdateByParam
1317      * @memberOf KJUR.asn1.x509.TBSCertList#
1318      * @function
1319      * @param {Array} timeParam Time parameter
1320      * @description
1321      * @example
1322      * tbsc.setNextUpdateByParam({'str': '130508235959Z'});
1323      * @see KJUR.asn1.x509.Time
1324      */
1325     this.setNextUpdateByParam = function(timeParam) {
1326         this.asn1NextUpdate = new _Time(timeParam);
1327     };
1328 
1329     /**
1330      * add revoked certificate by parameter
1331      * @name addRevokedCert
1332      * @memberOf KJUR.asn1.x509.TBSCertList#
1333      * @function
1334      * @param {Array} snParam DERInteger parameter for certificate serial number
1335      * @param {Array} timeParam Time parameter for revocation date
1336      * @description
1337      * @example
1338      * tbsc.addRevokedCert({'int': 3}, {'str': '130508235959Z'});
1339      * @see KJUR.asn1.x509.Time
1340      */
1341     this.addRevokedCert = function(snParam, timeParam) {
1342         var param = {};
1343         if (snParam != undefined && snParam != null)
1344 	    param['sn'] = snParam;
1345         if (timeParam != undefined && timeParam != null)
1346 	    param['time'] = timeParam;
1347         var o = new _KJUR_asn1_x509.CRLEntry(param);
1348         this.aRevokedCert.push(o);
1349     };
1350 
1351     this.getEncodedHex = function() {
1352         this.asn1Array = new Array();
1353 
1354         if (this.asn1Version != null) this.asn1Array.push(this.asn1Version);
1355         this.asn1Array.push(this.asn1SignatureAlg);
1356         this.asn1Array.push(this.asn1Issuer);
1357         this.asn1Array.push(this.asn1ThisUpdate);
1358         if (this.asn1NextUpdate != null) this.asn1Array.push(this.asn1NextUpdate);
1359 
1360         if (this.aRevokedCert.length > 0) {
1361             var seq = new _DERSequence({'array': this.aRevokedCert});
1362             this.asn1Array.push(seq);
1363         }
1364 
1365         var o = new _DERSequence({"array": this.asn1Array});
1366         this.hTLV = o.getEncodedHex();
1367         this.isModified = false;
1368         return this.hTLV;
1369     };
1370 
1371     this._initialize = function() {
1372         this.asn1Version = null;
1373         this.asn1SignatureAlg = null;
1374         this.asn1Issuer = null;
1375         this.asn1ThisUpdate = null;
1376         this.asn1NextUpdate = null;
1377         this.aRevokedCert = new Array();
1378     };
1379 
1380     this._initialize();
1381 };
1382 YAHOO.lang.extend(KJUR.asn1.x509.TBSCertList, KJUR.asn1.ASN1Object);
1383 
1384 /**
1385  * ASN.1 CRLEntry structure class for CRL
1386  * @name KJUR.asn1.x509.CRLEntry
1387  * @class ASN.1 CRLEntry structure class for CRL
1388  * @param {Array} params associative array of parameters (ex. {})
1389  * @extends KJUR.asn1.ASN1Object
1390  * @since 1.0.3
1391  * @description
1392  * @example
1393  * var e = new KJUR.asn1.x509.CRLEntry({'time': {'str': '130514235959Z'}, 'sn': {'int': 234}});
1394  *
1395  * // revokedCertificates     SEQUENCE OF SEQUENCE  {
1396  * //     userCertificate         CertificateSerialNumber,
1397  * //     revocationDate          Time,
1398  * //     crlEntryExtensions      Extensions OPTIONAL
1399  * //                             -- if present, version MUST be v2 }
1400  */
1401 KJUR.asn1.x509.CRLEntry = function(params) {
1402     KJUR.asn1.x509.CRLEntry.superclass.constructor.call(this);
1403     var sn = null,
1404 	time = null,
1405 	_KJUR = KJUR,
1406 	_KJUR_asn1 = _KJUR.asn1;
1407 
1408     /**
1409      * set DERInteger parameter for serial number of revoked certificate
1410      * @name setCertSerial
1411      * @memberOf KJUR.asn1.x509.CRLEntry
1412      * @function
1413      * @param {Array} intParam DERInteger parameter for certificate serial number
1414      * @description
1415      * @example
1416      * entry.setCertSerial({'int': 3});
1417      */
1418     this.setCertSerial = function(intParam) {
1419         this.sn = new _KJUR_asn1.DERInteger(intParam);
1420     };
1421 
1422     /**
1423      * set Time parameter for revocation date
1424      * @name setRevocationDate
1425      * @memberOf KJUR.asn1.x509.CRLEntry
1426      * @function
1427      * @param {Array} timeParam Time parameter for revocation date
1428      * @description
1429      * @example
1430      * entry.setRevocationDate({'str': '130508235959Z'});
1431      */
1432     this.setRevocationDate = function(timeParam) {
1433         this.time = new _KJUR_asn1.x509.Time(timeParam);
1434     };
1435 
1436     this.getEncodedHex = function() {
1437         var o = new _KJUR_asn1.DERSequence({"array": [this.sn, this.time]});
1438         this.TLV = o.getEncodedHex();
1439         return this.TLV;
1440     };
1441 
1442     if (params !== undefined) {
1443         if (params.time !== undefined) {
1444             this.setRevocationDate(params.time);
1445         }
1446         if (params.sn !== undefined) {
1447             this.setCertSerial(params.sn);
1448         }
1449     }
1450 };
1451 YAHOO.lang.extend(KJUR.asn1.x509.CRLEntry, KJUR.asn1.ASN1Object);
1452 
1453 // === END   CRL Related ===================================================
1454 
1455 // === BEGIN X500Name Related =================================================
1456 /**
1457  * X500Name ASN.1 structure class
1458  * @name KJUR.asn1.x509.X500Name
1459  * @class X500Name ASN.1 structure class
1460  * @param {Array} params associative array of parameters (ex. {'str': '/C=US/O=a'})
1461  * @extends KJUR.asn1.ASN1Object
1462  * @see KJUR.asn1.x509.X500Name
1463  * @see KJUR.asn1.x509.RDN
1464  * @see KJUR.asn1.x509.AttributeTypeAndValue
1465  * @description
1466  * This class provides DistinguishedName ASN.1 class structure
1467  * defined in <a href="https://tools.ietf.org/html/rfc2253#section-2">RFC 2253 section 2</a>.
1468  * <blockquote><pre>
1469  * DistinguishedName ::= RDNSequence
1470  *
1471  * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
1472  *
1473  * RelativeDistinguishedName ::= SET SIZE (1..MAX) OF
1474  *   AttributeTypeAndValue
1475  *
1476  * AttributeTypeAndValue ::= SEQUENCE {
1477  *   type  AttributeType,
1478  *   value AttributeValue }
1479  * </pre></blockquote>
1480  * <br/>
1481  * For string representation of distinguished name in jsrsasign,
1482  * OpenSSL oneline format is used. Please see <a href="https://github.com/kjur/jsrsasign/wiki/NOTE-distinguished-name-representation-in-jsrsasign">wiki article</a> for it.
1483  * <br/>
1484  * NOTE: Multi-valued RDN is supported since jsrsasign 6.2.1 asn1x509 1.0.17.
1485  * @example
1486  * // 1. construct with string
1487  * o = new KJUR.asn1.x509.X500Name({str: "/C=US/O=aaa/OU=bbb/CN=foo@example.com"});
1488  * o = new KJUR.asn1.x509.X500Name({str: "/C=US/O=aaa+CN=contact@example.com"}); // multi valued
1489  * // 2. construct by object
1490  * o = new KJUR.asn1.x509.X500Name({C: "US", O: "aaa", CN: "http://example.com/"});
1491  */
1492 KJUR.asn1.x509.X500Name = function(params) {
1493     KJUR.asn1.x509.X500Name.superclass.constructor.call(this);
1494     this.asn1Array = new Array();
1495     var _KJUR = KJUR,
1496 	_KJUR_asn1 = _KJUR.asn1,
1497 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
1498 	_pemtohex = pemtohex;
1499 
1500     /**
1501      * set DN by OpenSSL oneline distinguished name string<br/>
1502      * @name setByString
1503      * @memberOf KJUR.asn1.x509.X500Name#
1504      * @function
1505      * @param {String} dnStr distinguished name by string (ex. /C=US/O=aaa)
1506      * @description
1507      * Sets distinguished name by string. 
1508      * dnStr must be formatted as 
1509      * "/type0=value0/type1=value1/type2=value2...".
1510      * No need to escape a slash in an attribute value.
1511      * @example
1512      * name = new KJUR.asn1.x509.X500Name();
1513      * name.setByString("/C=US/O=aaa/OU=bbb/CN=foo@example.com");
1514      * // no need to escape slash in an attribute value
1515      * name.setByString("/C=US/O=aaa/CN=1980/12/31");
1516      */
1517     this.setByString = function(dnStr) {
1518         var a = dnStr.split('/');
1519         a.shift();
1520 
1521 	var a1 = [];
1522 	for (var i = 0; i < a.length; i++) {
1523 	  if (a[i].match(/^[^=]+=.+$/)) {
1524 	    a1.push(a[i]);
1525 	  } else {
1526 	    var lastidx = a1.length - 1;
1527 	    a1[lastidx] = a1[lastidx] + "/" + a[i];
1528 	  }
1529 	}
1530 
1531         for (var i = 0; i < a1.length; i++) {
1532             this.asn1Array.push(new _KJUR_asn1_x509.RDN({'str':a1[i]}));
1533         }
1534     };
1535 
1536     /**
1537      * set DN by LDAP(RFC 2253) distinguished name string<br/>
1538      * @name setByLdapString
1539      * @memberOf KJUR.asn1.x509.X500Name#
1540      * @function
1541      * @param {String} dnStr distinguished name by LDAP string (ex. O=aaa,C=US)
1542      * @since jsrsasign 6.2.2 asn1x509 1.0.18
1543      * @description
1544      * @example
1545      * name = new KJUR.asn1.x509.X500Name();
1546      * name.setByLdapString("CN=foo@example.com,OU=bbb,O=aaa,C=US");
1547      */
1548     this.setByLdapString = function(dnStr) {
1549 	var oneline = _KJUR_asn1_x509.X500Name.ldapToOneline(dnStr);
1550 	this.setByString(oneline);
1551     };
1552 
1553     /**
1554      * set DN by associative array<br/>
1555      * @name setByObject
1556      * @memberOf KJUR.asn1.x509.X500Name#
1557      * @function
1558      * @param {Array} dnObj associative array of DN (ex. {C: "US", O: "aaa"})
1559      * @since jsrsasign 4.9. asn1x509 1.0.13
1560      * @description
1561      * @example
1562      * name = new KJUR.asn1.x509.X500Name();
1563      * name.setByObject({C: "US", O: "aaa", CN="http://example.com/"1});
1564      */
1565     this.setByObject = function(dnObj) {
1566         // Get all the dnObject attributes and stuff them in the ASN.1 array.
1567         for (var x in dnObj) {
1568             if (dnObj.hasOwnProperty(x)) {
1569                 var newRDN = new KJUR.asn1.x509.RDN(
1570                     {'str': x + '=' + dnObj[x]});
1571                 // Initialize or push into the ANS1 array.
1572                 this.asn1Array ? this.asn1Array.push(newRDN)
1573                     : this.asn1Array = [newRDN];
1574             }
1575         }
1576     };
1577 
1578     this.getEncodedHex = function() {
1579         if (typeof this.hTLV == "string") return this.hTLV;
1580         var o = new _KJUR_asn1.DERSequence({"array": this.asn1Array});
1581         this.hTLV = o.getEncodedHex();
1582         return this.hTLV;
1583     };
1584 
1585     if (params !== undefined) {
1586         if (params.str !== undefined) {
1587             this.setByString(params.str);
1588         } else if (params.ldapstr !== undefined) {
1589 	    this.setByLdapString(params.ldapstr);
1590         // If params is an object, then set the ASN1 array just using the object
1591         // attributes. This is nice for fields that have lots of special
1592         // characters (i.e. CN: 'https://www.github.com/kjur//').
1593         } else if (typeof params === "object") {
1594             this.setByObject(params);
1595         }
1596 
1597         if (params.certissuer !== undefined) {
1598             var x = new X509();
1599             x.hex = _pemtohex(params.certissuer);
1600             this.hTLV = x.getIssuerHex();
1601         }
1602         if (params.certsubject !== undefined) {
1603             var x = new X509();
1604             x.hex = _pemtohex(params.certsubject);
1605             this.hTLV = x.getSubjectHex();
1606         }
1607     }
1608 };
1609 YAHOO.lang.extend(KJUR.asn1.x509.X500Name, KJUR.asn1.ASN1Object);
1610 
1611 /**
1612  * convert OpenSSL oneline distinguished name format string to LDAP(RFC 2253) format<br/>
1613  * @name onelineToLDAP
1614  * @memberOf KJUR.asn1.x509.X500Name
1615  * @function
1616  * @param {String} s distinguished name string in OpenSSL oneline format (ex. /C=US/O=test)
1617  * @return {String} distinguished name string in LDAP(RFC 2253) format (ex. O=test,C=US)
1618  * @since jsrsasign 6.2.2 asn1x509 1.0.18
1619  * @description
1620  * This static method converts a distinguished name string in OpenSSL oneline 
1621  * format to LDAP(RFC 2253) format.
1622  * @see <a href="https://github.com/kjur/jsrsasign/wiki/NOTE-distinguished-name-representation-in-jsrsasign">jsrsasign wiki: distinguished name string difference between OpenSSL oneline and LDAP(RFC 2253)</a>
1623  * @example
1624  * KJUR.asn1.x509.X500Name.onelineToLDAP("/C=US/O=test") → 'O=test,C=US'
1625  * KJUR.asn1.x509.X500Name.onelineToLDAP("/C=US/O=a,a") → 'O=a\,a,C=US'
1626  */
1627 KJUR.asn1.x509.X500Name.onelineToLDAP = function(s) {
1628     if (s.substr(0, 1) !== "/") throw "malformed input";
1629 
1630     var result = "";
1631     s = s.substr(1);
1632 
1633     var a = s.split("/");
1634     a.reverse();
1635     a = a.map(function(s) {return s.replace(/,/, "\\,")});
1636 
1637     return a.join(",");
1638 };
1639 
1640 /**
1641  * convert LDAP(RFC 2253) distinguished name format string to OpenSSL oneline format<br/>
1642  * @name ldapToOneline
1643  * @memberOf KJUR.asn1.x509.X500Name
1644  * @function
1645  * @param {String} s distinguished name string in LDAP(RFC 2253) format (ex. O=test,C=US)
1646  * @return {String} distinguished name string in OpenSSL oneline format (ex. /C=US/O=test)
1647  * @since jsrsasign 6.2.2 asn1x509 1.0.18
1648  * @description
1649  * This static method converts a distinguished name string in 
1650  * LDAP(RFC 2253) format to OpenSSL oneline format.
1651  * @see <a href="https://github.com/kjur/jsrsasign/wiki/NOTE-distinguished-name-representation-in-jsrsasign">jsrsasign wiki: distinguished name string difference between OpenSSL oneline and LDAP(RFC 2253)</a>
1652  * @example
1653  * KJUR.asn1.x509.X500Name.ldapToOneline('O=test,C=US') → '/C=US/O=test'
1654  * KJUR.asn1.x509.X500Name.ldapToOneline('O=a\,a,C=US') → '/C=US/O=a,a'
1655  * KJUR.asn1.x509.X500Name.ldapToOneline('O=a/a,C=US')  → '/C=US/O=a\/a'
1656  */
1657 KJUR.asn1.x509.X500Name.ldapToOneline = function(s) {
1658     var a = s.split(",");
1659 
1660     // join \,
1661     var isBSbefore = false;
1662     var a2 = [];
1663     for (var i = 0; a.length > 0; i++) {
1664 	var item = a.shift();
1665 	//console.log("item=" + item);
1666 
1667 	if (isBSbefore === true) {
1668 	    var a2last = a2.pop();
1669 	    var newitem = (a2last + "," + item).replace(/\\,/g, ",");
1670 	    a2.push(newitem);
1671 	    isBSbefore = false;
1672 	} else {
1673 	    a2.push(item);
1674 	}
1675 
1676 	if (item.substr(-1, 1) === "\\") isBSbefore = true;
1677     }
1678 
1679     a2 = a2.map(function(s) {return s.replace("/", "\\/")});
1680     a2.reverse();
1681     return "/" + a2.join("/");
1682 };
1683 
1684 /**
1685  * RDN (Relative Distinguished Name) ASN.1 structure class
1686  * @name KJUR.asn1.x509.RDN
1687  * @class RDN (Relative Distinguished Name) ASN.1 structure class
1688  * @param {Array} params associative array of parameters (ex. {'str': 'C=US'})
1689  * @extends KJUR.asn1.ASN1Object
1690  * @see KJUR.asn1.x509.X500Name
1691  * @see KJUR.asn1.x509.RDN
1692  * @see KJUR.asn1.x509.AttributeTypeAndValue
1693  * @description
1694  * This class provides RelativeDistinguishedName ASN.1 class structure
1695  * defined in <a href="https://tools.ietf.org/html/rfc2253#section-2">RFC 2253 section 2</a>.
1696  * <blockquote><pre>
1697  * RelativeDistinguishedName ::= SET SIZE (1..MAX) OF
1698  *   AttributeTypeAndValue
1699  *
1700  * AttributeTypeAndValue ::= SEQUENCE {
1701  *   type  AttributeType,
1702  *   value AttributeValue }
1703  * </pre></blockquote>
1704  * <br/>
1705  * NOTE: Multi-valued RDN is supported since jsrsasign 6.2.1 asn1x509 1.0.17.
1706  * @example
1707  * rdn = new KJUR.asn1.x509.RDN({str: "CN=test"});
1708  * rdn = new KJUR.asn1.x509.RDN({str: "O=a+O=bb+O=c"}); // multi-valued
1709  * rdn = new KJUR.asn1.x509.RDN({str: "O=a+O=b\\+b+O=c"}); // plus escaped
1710  * rdn = new KJUR.asn1.x509.RDN({str: "O=a+O=\"b+b\"+O=c"}); // double quoted
1711  */
1712 KJUR.asn1.x509.RDN = function(params) {
1713     KJUR.asn1.x509.RDN.superclass.constructor.call(this);
1714     this.asn1Array = new Array();
1715 
1716     /**
1717      * add one AttributeTypeAndValue by string<br/>
1718      * @name addByString
1719      * @memberOf KJUR.asn1.x509.RDN#
1720      * @function
1721      * @param {String} s string of AttributeTypeAndValue
1722      * @return {Object} unspecified
1723      * @description
1724      * This method add one AttributeTypeAndValue to RDN object.
1725      * @example
1726      * rdn = new KJUR.asn1.x509.RDN();
1727      * rdn.addByString("CN=john");
1728      * rdn.addByString("serialNumber=1234"); // for multi-valued RDN
1729      */
1730     this.addByString = function(s) {
1731         this.asn1Array.push(new KJUR.asn1.x509.AttributeTypeAndValue({'str': s}));
1732     };
1733 
1734     /**
1735      * add one AttributeTypeAndValue by multi-valued string<br/>
1736      * @name addByMultiValuedString
1737      * @memberOf KJUR.asn1.x509.RDN#
1738      * @function
1739      * @param {String} s string of multi-valued RDN
1740      * @return {Object} unspecified
1741      * @since jsrsasign 6.2.1 asn1x509 1.0.17
1742      * @description
1743      * This method add multi-valued RDN to RDN object.
1744      * @example
1745      * rdn = new KJUR.asn1.x509.RDN();
1746      * rdn.addByMultiValuedString("CN=john+O=test");
1747      * rdn.addByMultiValuedString("O=a+O=b\+b\+b+O=c"); // multi-valued RDN with quoted plus
1748      * rdn.addByMultiValuedString("O=a+O=\"b+b+b\"+O=c"); // multi-valued RDN with quoted quotation
1749      */
1750     this.addByMultiValuedString = function(s) {
1751 	var a = KJUR.asn1.x509.RDN.parseString(s);
1752 	for (var i = 0; i < a.length; i++) {
1753 	    this.addByString(a[i]);
1754 	}
1755     };
1756 
1757     this.getEncodedHex = function() {
1758         var o = new KJUR.asn1.DERSet({"array": this.asn1Array});
1759         this.TLV = o.getEncodedHex();
1760         return this.TLV;
1761     };
1762 
1763     if (params !== undefined) {
1764         if (params.str !== undefined) {
1765             this.addByMultiValuedString(params.str);
1766         }
1767     }
1768 };
1769 YAHOO.lang.extend(KJUR.asn1.x509.RDN, KJUR.asn1.ASN1Object);
1770 
1771 /**
1772  * parse multi-valued RDN string and split into array of 'AttributeTypeAndValue'<br/>
1773  * @name parseString
1774  * @memberOf KJUR.asn1.x509.RDN
1775  * @function
1776  * @param {String} s multi-valued string of RDN
1777  * @return {Array} array of string of AttributeTypeAndValue
1778  * @since jsrsasign 6.2.1 asn1x509 1.0.17
1779  * @description
1780  * This static method parses multi-valued RDN string and split into
1781  * array of AttributeTypeAndValue.
1782  * @example
1783  * KJUR.asn1.x509.RDN.parseString("CN=john") → ["CN=john"]
1784  * KJUR.asn1.x509.RDN.parseString("CN=john+OU=test") → ["CN=john", "OU=test"]
1785  * KJUR.asn1.x509.RDN.parseString('CN="jo+hn"+OU=test') → ["CN=jo+hn", "OU=test"]
1786  * KJUR.asn1.x509.RDN.parseString('CN=jo\+hn+OU=test') → ["CN=jo+hn", "OU=test"]
1787  * KJUR.asn1.x509.RDN.parseString("CN=john+OU=test+OU=t1") → ["CN=john", "OU=test", "OU=t1"]
1788  */
1789 KJUR.asn1.x509.RDN.parseString = function(s) {
1790     var a = s.split(/\+/);
1791 
1792     // join \+
1793     var isBSbefore = false;
1794     var a2 = [];
1795     for (var i = 0; a.length > 0; i++) {
1796 	var item = a.shift();
1797 	//console.log("item=" + item);
1798 
1799 	if (isBSbefore === true) {
1800 	    var a2last = a2.pop();
1801 	    var newitem = (a2last + "+" + item).replace(/\\\+/g, "+");
1802 	    a2.push(newitem);
1803 	    isBSbefore = false;
1804 	} else {
1805 	    a2.push(item);
1806 	}
1807 
1808 	if (item.substr(-1, 1) === "\\") isBSbefore = true;
1809     }
1810 
1811     // join quote
1812     var beginQuote = false;
1813     var a3 = [];
1814     for (var i = 0; a2.length > 0; i++) {
1815 	var item = a2.shift();
1816 
1817 	if (beginQuote === true) {
1818 	    var a3last = a3.pop();
1819 	    if (item.match(/"$/)) {
1820 		var newitem = (a3last + "+" + item).replace(/^([^=]+)="(.*)"$/, "$1=$2");
1821 		a3.push(newitem);
1822 		beginQuote = false;
1823 	    } else {
1824 		a3.push(a3last + "+" + item);
1825 	    }
1826 	} else {
1827 	    a3.push(item);
1828 	}
1829 
1830 	if (item.match(/^[^=]+="/)) {
1831 	    //console.log(i + "=" + item);
1832 	    beginQuote = true;
1833 	}
1834     }
1835 
1836     return a3;
1837 };
1838 
1839 /**
1840  * AttributeTypeAndValue ASN.1 structure class
1841  * @name KJUR.asn1.x509.AttributeTypeAndValue
1842  * @class AttributeTypeAndValue ASN.1 structure class
1843  * @param {Array} params associative array of parameters (ex. {'str': 'C=US'})
1844  * @extends KJUR.asn1.ASN1Object
1845  * @description
1846  * @see KJUR.asn1.x509.X500Name
1847  * @see KJUR.asn1.x509.RDN
1848  * @see KJUR.asn1.x509.AttributeTypeAndValue
1849  * @example
1850  */
1851 KJUR.asn1.x509.AttributeTypeAndValue = function(params) {
1852     KJUR.asn1.x509.AttributeTypeAndValue.superclass.constructor.call(this);
1853     var typeObj = null,
1854 	valueObj = null,
1855 	defaultDSType = "utf8",
1856 	_KJUR = KJUR,
1857 	_KJUR_asn1 = _KJUR.asn1;
1858 
1859     this.setByString = function(attrTypeAndValueStr) {
1860         var matchResult = attrTypeAndValueStr.match(/^([^=]+)=(.+)$/);
1861         if (matchResult) {
1862             this.setByAttrTypeAndValueStr(matchResult[1], matchResult[2]);
1863         } else {
1864             throw "malformed attrTypeAndValueStr: " + attrTypeAndValueStr;
1865         }
1866     };
1867 
1868     this.setByAttrTypeAndValueStr = function(shortAttrType, valueStr) {
1869         this.typeObj = KJUR.asn1.x509.OID.atype2obj(shortAttrType);
1870         var dsType = defaultDSType;
1871         if (shortAttrType == "C") dsType = "prn";
1872         this.valueObj = this.getValueObj(dsType, valueStr);
1873     };
1874 
1875     this.getValueObj = function(dsType, valueStr) {
1876         if (dsType == "utf8")   return new _KJUR_asn1.DERUTF8String({"str": valueStr});
1877         if (dsType == "prn")    return new _KJUR_asn1.DERPrintableString({"str": valueStr});
1878         if (dsType == "tel")    return new _KJUR_asn1.DERTeletexString({"str": valueStr});
1879         if (dsType == "ia5")    return new _KJUR_asn1.DERIA5String({"str": valueStr});
1880         throw "unsupported directory string type: type=" + dsType + " value=" + valueStr;
1881     };
1882 
1883     this.getEncodedHex = function() {
1884         var o = new _KJUR_asn1.DERSequence({"array": [this.typeObj, this.valueObj]});
1885         this.TLV = o.getEncodedHex();
1886         return this.TLV;
1887     };
1888 
1889     if (params !== undefined) {
1890         if (params.str !== undefined) {
1891             this.setByString(params.str);
1892         }
1893     }
1894 };
1895 YAHOO.lang.extend(KJUR.asn1.x509.AttributeTypeAndValue, KJUR.asn1.ASN1Object);
1896 
1897 // === END   X500Name Related =================================================
1898 
1899 // === BEGIN Other ASN1 structure class  ======================================
1900 
1901 /**
1902  * SubjectPublicKeyInfo ASN.1 structure class
1903  * @name KJUR.asn1.x509.SubjectPublicKeyInfo
1904  * @class SubjectPublicKeyInfo ASN.1 structure class
1905  * @param {Object} params parameter for subject public key
1906  * @extends KJUR.asn1.ASN1Object
1907  * @description
1908  * <br/>
1909  * As for argument 'params' for constructor, you can specify one of
1910  * following properties:
1911  * <ul>
1912  * <li>{@link RSAKey} object</li>
1913  * <li>{@link KJUR.crypto.ECDSA} object</li>
1914  * <li>{@link KJUR.crypto.DSA} object</li>
1915  * </ul>
1916  * NOTE1: 'params' can be omitted.<br/>
1917  * NOTE2: DSA/ECDSA key object is also supported since asn1x509 1.0.6.<br/>
1918  * <h4>EXAMPLE</h4>
1919  * @example
1920  * spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(RSAKey_object);
1921  * spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoECDSA_object);
1922  * spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoDSA_object);
1923  */
1924 KJUR.asn1.x509.SubjectPublicKeyInfo = function(params) {
1925     KJUR.asn1.x509.SubjectPublicKeyInfo.superclass.constructor.call(this);
1926     var asn1AlgId = null,
1927 	asn1SubjPKey = null,
1928 	_KJUR = KJUR,
1929 	_KJUR_asn1 = _KJUR.asn1,
1930 	_DERInteger = _KJUR_asn1.DERInteger,
1931 	_DERBitString = _KJUR_asn1.DERBitString,
1932 	_DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
1933 	_DERSequence = _KJUR_asn1.DERSequence,
1934 	_newObject = _KJUR_asn1.ASN1Util.newObject,
1935 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
1936 	_AlgorithmIdentifier = _KJUR_asn1_x509.AlgorithmIdentifier,
1937 	_KJUR_crypto = _KJUR.crypto,
1938 	_KJUR_crypto_ECDSA = _KJUR_crypto.ECDSA,
1939 	_KJUR_crypto_DSA = _KJUR_crypto.DSA;
1940 
1941     /*
1942      * @since asn1x509 1.0.7
1943      */
1944     this.getASN1Object = function() {
1945         if (this.asn1AlgId == null || this.asn1SubjPKey == null)
1946             throw "algId and/or subjPubKey not set";
1947         var o = new _DERSequence({'array':
1948                                   [this.asn1AlgId, this.asn1SubjPKey]});
1949         return o;
1950     };
1951 
1952     this.getEncodedHex = function() {
1953         var o = this.getASN1Object();
1954         this.hTLV = o.getEncodedHex();
1955         return this.hTLV;
1956     };
1957 
1958     /**
1959      * @name setPubKey
1960      * @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo#
1961      * @function
1962      * @param {Object} {@link RSAKey}, {@link KJUR.crypto.ECDSA} or {@link KJUR.crypto.DSA} object
1963      * @since jsrsasign 8.0.0 asn1x509 1.1.0
1964      * @description
1965      * @example
1966      * spki = new KJUR.asn1.x509.SubjectPublicKeyInfo();
1967      * pubKey = KEYUTIL.getKey(PKCS8PUBKEYPEM);
1968      * spki.setPubKey(pubKey);
1969      */
1970     this.setPubKey = function(key) {
1971 	try {
1972 	    if (key instanceof RSAKey) {
1973 		var asn1RsaPub = _newObject({
1974 		    'seq': [{'int': {'bigint': key.n}}, {'int': {'int': key.e}}]
1975 		});
1976 		var rsaKeyHex = asn1RsaPub.getEncodedHex();
1977 		this.asn1AlgId = new _AlgorithmIdentifier({'name':'rsaEncryption'});
1978 		this.asn1SubjPKey = new _DERBitString({'hex':'00'+rsaKeyHex});
1979 	    }
1980 	} catch(ex) {};
1981 
1982 	try {
1983 	    if (key instanceof KJUR.crypto.ECDSA) {
1984 		var asn1Params = new _DERObjectIdentifier({'name': key.curveName});
1985 		this.asn1AlgId =
1986 		    new _AlgorithmIdentifier({'name': 'ecPublicKey',
1987 					      'asn1params': asn1Params});
1988 		this.asn1SubjPKey = new _DERBitString({'hex': '00' + key.pubKeyHex});
1989 	    }
1990 	} catch(ex) {};
1991 
1992 	try {
1993 	    if (key instanceof KJUR.crypto.DSA) {
1994 		var asn1Params = new _newObject({
1995 		    'seq': [{'int': {'bigint': key.p}},
1996 			    {'int': {'bigint': key.q}},
1997 			    {'int': {'bigint': key.g}}]
1998 		});
1999 		this.asn1AlgId =
2000 		    new _AlgorithmIdentifier({'name': 'dsa',
2001 					      'asn1params': asn1Params});
2002 		var pubInt = new _DERInteger({'bigint': key.y});
2003 		this.asn1SubjPKey = 
2004 		    new _DERBitString({'hex': '00' + pubInt.getEncodedHex()});
2005 	    }
2006 	} catch(ex) {};
2007     };
2008 
2009     if (params !== undefined) {
2010 	this.setPubKey(params);
2011     }
2012 };
2013 YAHOO.lang.extend(KJUR.asn1.x509.SubjectPublicKeyInfo, KJUR.asn1.ASN1Object);
2014 
2015 /**
2016  * Time ASN.1 structure class
2017  * @name KJUR.asn1.x509.Time
2018  * @class Time ASN.1 structure class
2019  * @param {Array} params associative array of parameters (ex. {'str': '130508235959Z'})
2020  * @extends KJUR.asn1.ASN1Object
2021  * @description
2022  * <br/>
2023  * <h4>EXAMPLES</h4>
2024  * @example
2025  * var t1 = new KJUR.asn1.x509.Time{'str': '130508235959Z'} // UTCTime by default
2026  * var t2 = new KJUR.asn1.x509.Time{'type': 'gen',  'str': '20130508235959Z'} // GeneralizedTime
2027  */
2028 KJUR.asn1.x509.Time = function(params) {
2029     KJUR.asn1.x509.Time.superclass.constructor.call(this);
2030     var type = null,
2031 	timeParams = null,
2032 	_KJUR = KJUR,
2033 	_KJUR_asn1 = _KJUR.asn1,
2034 	_DERUTCTime = _KJUR_asn1.DERUTCTime,
2035 	_DERGeneralizedTime = _KJUR_asn1.DERGeneralizedTime;
2036 
2037     this.setTimeParams = function(timeParams) {
2038         this.timeParams = timeParams;
2039     }
2040 
2041     this.getEncodedHex = function() {
2042         var o = null;
2043 
2044         if (this.timeParams != null) {
2045             if (this.type == "utc") {
2046                 o = new _DERUTCTime(this.timeParams);
2047             } else {
2048                 o = new _DERGeneralizedTime(this.timeParams);
2049             }
2050         } else {
2051             if (this.type == "utc") {
2052                 o = new _DERUTCTime();
2053             } else {
2054                 o = new _DERGeneralizedTime();
2055             }
2056         }
2057         this.TLV = o.getEncodedHex();
2058         return this.TLV;
2059     };
2060 
2061     this.type = "utc";
2062     if (params !== undefined) {
2063         if (params.type !== undefined) {
2064             this.type = params.type;
2065         } else {
2066             if (params.str !== undefined) {
2067                 if (params.str.match(/^[0-9]{12}Z$/)) this.type = "utc";
2068                 if (params.str.match(/^[0-9]{14}Z$/)) this.type = "gen";
2069             }
2070         }
2071         this.timeParams = params;
2072     }
2073 };
2074 YAHOO.lang.extend(KJUR.asn1.x509.Time, KJUR.asn1.ASN1Object);
2075 
2076 /**
2077  * AlgorithmIdentifier ASN.1 structure class
2078  * @name KJUR.asn1.x509.AlgorithmIdentifier
2079  * @class AlgorithmIdentifier ASN.1 structure class
2080  * @param {Array} params associative array of parameters (ex. {'name': 'SHA1withRSA'})
2081  * @extends KJUR.asn1.ASN1Object
2082  * @description
2083  * The 'params' argument is an associative array and has following parameters:
2084  * <ul>
2085  * <li>name: algorithm name (MANDATORY, ex. sha1, SHA256withRSA)</li>
2086  * <li>asn1params: explicitly specify ASN.1 object for algorithm.
2087  * (OPTION)</li>
2088  * <li>paramempty: set algorithm parameter to NULL by force.
2089  * If paramempty is false, algorithm parameter will be set automatically.
2090  * If paramempty is false and algorithm name is "*withDSA" or "withECDSA" parameter field of
2091  * AlgorithmIdentifier will be ommitted otherwise
2092  * it will be NULL by default.
2093  * (OPTION, DEFAULT = false)</li>
2094  * </ul>
2095  * @example
2096  * algId = new KJUR.asn1.x509.AlgorithmIdentifier({name: "sha1"});
2097  * // set parameter to NULL authomatically if algorithm name is "*withRSA".
2098  * algId = new KJUR.asn1.x509.AlgorithmIdentifier({name: "SHA256withRSA"});
2099  * // set parameter to NULL authomatically if algorithm name is "rsaEncryption".
2100  * algId = new KJUR.asn1.x509.AlgorithmIdentifier({name: "rsaEncryption"});
2101  * // SHA256withRSA and set parameter empty by force
2102  * algId = new KJUR.asn1.x509.AlgorithmIdentifier({name: "SHA256withRSA", paramempty: true});
2103  */
2104 KJUR.asn1.x509.AlgorithmIdentifier = function(params) {
2105     KJUR.asn1.x509.AlgorithmIdentifier.superclass.constructor.call(this);
2106     this.nameAlg = null;
2107     this.asn1Alg = null;
2108     this.asn1Params = null;
2109     this.paramEmpty = false;
2110     var _KJUR = KJUR,
2111 	_KJUR_asn1 = _KJUR.asn1;
2112 
2113     this.getEncodedHex = function() {
2114         if (this.nameAlg === null && this.asn1Alg === null) {
2115             throw "algorithm not specified";
2116         }
2117         if (this.nameAlg !== null && this.asn1Alg === null) {
2118             this.asn1Alg = _KJUR_asn1.x509.OID.name2obj(this.nameAlg);
2119         }
2120         var a = [this.asn1Alg];
2121         if (this.asn1Params !== null) a.push(this.asn1Params);
2122 
2123         var o = new _KJUR_asn1.DERSequence({'array': a});
2124         this.hTLV = o.getEncodedHex();
2125         return this.hTLV;
2126     };
2127 
2128     if (params !== undefined) {
2129         if (params.name !== undefined) {
2130             this.nameAlg = params.name;
2131         }
2132         if (params.asn1params !== undefined) {
2133             this.asn1Params = params.asn1params;
2134         }
2135         if (params.paramempty !== undefined) {
2136             this.paramEmpty = params.paramempty;
2137         }
2138     }
2139 
2140     // set algorithm parameters will be ommitted for
2141     // "*withDSA" or "*withECDSA" otherwise will be NULL.
2142     if (this.asn1Params === null &&
2143 	this.paramEmpty === false &&
2144 	this.nameAlg !== null) {
2145 	var lcNameAlg = this.nameAlg.toLowerCase();
2146 	if (lcNameAlg.substr(-7, 7) !== "withdsa" &&
2147 	    lcNameAlg.substr(-9, 9) !== "withecdsa") {
2148             this.asn1Params = new _KJUR_asn1.DERNull();
2149 	}
2150     }
2151 };
2152 YAHOO.lang.extend(KJUR.asn1.x509.AlgorithmIdentifier, KJUR.asn1.ASN1Object);
2153 
2154 /**
2155  * GeneralName ASN.1 structure class<br/>
2156  * @name KJUR.asn1.x509.GeneralName
2157  * @class GeneralName ASN.1 structure class
2158  * @description
2159  * <br/>
2160  * As for argument 'params' for constructor, you can specify one of
2161  * following properties:
2162  * <ul>
2163  * <li>rfc822 - rfc822Name[1] (ex. user1@foo.com)</li>
2164  * <li>dns - dNSName[2] (ex. foo.com)</li>
2165  * <li>uri - uniformResourceIdentifier[6] (ex. http://foo.com/)</li>
2166  * <li>dn - directoryName[4] (ex. /C=US/O=Test)</li>
2167  * <li>ldapdn - directoryName[4] (ex. O=Test,C=US)</li>
2168  * <li>certissuer - directoryName[4] (PEM or hex string of cert)</li>
2169  * <li>certsubj - directoryName[4] (PEM or hex string of cert)</li>
2170  * <li>ip - iPAddress[7] (ex. 192.168.1.1, 2001:db3::43, 3faa0101...)</li>
2171  * </ul>
2172  * NOTE1: certissuer and certsubj were supported since asn1x509 1.0.10.<br/>
2173  * NOTE2: dn and ldapdn were supported since jsrsasign 6.2.3 asn1x509 1.0.19.<br/>
2174  * NOTE3: ip were supported since jsrsasign 8.0.10 asn1x509 1.1.4.<br/>
2175  *
2176  * Here is definition of the ASN.1 syntax:
2177  * <pre>
2178  * -- NOTE: under the CHOICE, it will always be explicit.
2179  * GeneralName ::= CHOICE {
2180  *   otherName                  [0] OtherName,
2181  *   rfc822Name                 [1] IA5String,
2182  *   dNSName                    [2] IA5String,
2183  *   x400Address                [3] ORAddress,
2184  *   directoryName              [4] Name,
2185  *   ediPartyName               [5] EDIPartyName,
2186  *   uniformResourceIdentifier  [6] IA5String,
2187  *   iPAddress                  [7] OCTET STRING,
2188  *   registeredID               [8] OBJECT IDENTIFIER }
2189  * </pre>
2190  *
2191  * @example
2192  * gn = new KJUR.asn1.x509.GeneralName({rfc822:     'test@aaa.com'});
2193  * gn = new KJUR.asn1.x509.GeneralName({dns:        'aaa.com'});
2194  * gn = new KJUR.asn1.x509.GeneralName({uri:        'http://aaa.com/'});
2195  * gn = new KJUR.asn1.x509.GeneralName({dn:         '/C=US/O=Test'});
2196  * gn = new KJUR.asn1.x509.GeneralName({ldapdn:     'O=Test,C=US'});
2197  * gn = new KJUR.asn1.x509.GeneralName({certissuer: certPEM});
2198  * gn = new KJUR.asn1.x509.GeneralName({certsubj:   certPEM});
2199  * gn = new KJUR.asn1.x509.GeneralName({ip:         '192.168.1.1'});
2200  * gn = new KJUR.asn1.x509.GeneralName({ip:         '2001:db4::4:1'});
2201  * gn = new KJUR.asn1.x509.GeneralName({ip:         'c0a80101'});
2202  */
2203 KJUR.asn1.x509.GeneralName = function(params) {
2204     KJUR.asn1.x509.GeneralName.superclass.constructor.call(this);
2205     var asn1Obj = null,
2206 	type = null,
2207 	pTag = {rfc822: '81', dns: '82', dn: 'a4',  uri: '86', ip: '87'},
2208 	_KJUR = KJUR,
2209 	_KJUR_asn1 = _KJUR.asn1,
2210 	_DERSequence = _KJUR_asn1.DERSequence,
2211 	_DEROctetString = _KJUR_asn1.DEROctetString,
2212 	_DERIA5String = _KJUR_asn1.DERIA5String,
2213 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
2214 	_ASN1Object = _KJUR_asn1.ASN1Object,
2215 	_X500Name = _KJUR_asn1.x509.X500Name,
2216 	_pemtohex = pemtohex;
2217 	
2218     this.explicit = false;
2219 
2220     this.setByParam = function(params) {
2221         var str = null;
2222         var v = null;
2223 
2224 	if (params === undefined) return;
2225 
2226         if (params.rfc822 !== undefined) {
2227             this.type = 'rfc822';
2228             v = new _DERIA5String({str: params[this.type]});
2229         }
2230 
2231         if (params.dns !== undefined) {
2232             this.type = 'dns';
2233             v = new _DERIA5String({str: params[this.type]});
2234         }
2235 
2236         if (params.uri !== undefined) {
2237             this.type = 'uri';
2238             v = new _DERIA5String({str: params[this.type]});
2239         }
2240 
2241         if (params.dn !== undefined) {
2242 	    this.type = 'dn';
2243 	    this.explicit = true;
2244 	    v = new _X500Name({str: params.dn});
2245 	}
2246 
2247         if (params.ldapdn !== undefined) {
2248 	    this.type = 'dn';
2249 	    this.explicit = true;
2250 	    v = new _X500Name({ldapstr: params.ldapdn});
2251 	}
2252 
2253 	if (params.certissuer !== undefined) {
2254 	    this.type = 'dn';
2255 	    this.explicit = true;
2256 	    var certStr = params.certissuer;
2257 	    var certHex = null;
2258 
2259 	    if (certStr.match(/^[0-9A-Fa-f]+$/)) {
2260 		certHex == certStr;
2261             }
2262 
2263 	    if (certStr.indexOf("-----BEGIN ") != -1) {
2264 		certHex = _pemtohex(certStr);
2265 	    }
2266 
2267 	    if (certHex == null) throw "certissuer param not cert";
2268 	    var x = new X509();
2269 	    x.hex = certHex;
2270 	    var dnHex = x.getIssuerHex();
2271 	    v = new _ASN1Object();
2272 	    v.hTLV = dnHex;
2273 	}
2274 
2275 	if (params.certsubj !== undefined) {
2276 	    this.type = 'dn';
2277 	    this.explicit = true;
2278 	    var certStr = params.certsubj;
2279 	    var certHex = null;
2280 	    if (certStr.match(/^[0-9A-Fa-f]+$/)) {
2281 		certHex == certStr;
2282             }
2283 	    if (certStr.indexOf("-----BEGIN ") != -1) {
2284 		certHex = _pemtohex(certStr);
2285 	    }
2286 	    if (certHex == null) throw "certsubj param not cert";
2287 	    var x = new X509();
2288 	    x.hex = certHex;
2289 	    var dnHex = x.getSubjectHex();
2290 	    v = new _ASN1Object();
2291 	    v.hTLV = dnHex;
2292 	}
2293 
2294 	if (params.ip !== undefined) {
2295 	    this.type = 'ip';
2296 	    this.explicit = false;
2297 	    var ip = params.ip;
2298 	    var hIP;
2299 	    var malformedIPMsg = "malformed IP address";
2300 	    if (ip.match(/^[0-9.]+[.][0-9.]+$/)) { // ipv4
2301 		hIP = intarystrtohex("[" + ip.split(".").join(",") + "]");
2302 		if (hIP.length !== 8) throw malformedIPMsg;
2303 	    } else if (ip.match(/^[0-9A-Fa-f:]+:[0-9A-Fa-f:]+$/)) { // ipv6
2304 		hIP = ipv6tohex(ip);
2305 	    } else if (ip.match(/^([0-9A-Fa-f][0-9A-Fa-f]){1,}$/)) { // hex
2306 		hIP = ip;
2307 	    } else {
2308 		throw malformedIPMsg;
2309 	    }
2310 	    v = new _DEROctetString({hex: hIP});
2311 	}
2312 
2313         if (this.type == null)
2314             throw "unsupported type in params=" + params;
2315         this.asn1Obj = new _DERTaggedObject({'explicit': this.explicit,
2316                                              'tag': pTag[this.type],
2317                                              'obj': v});
2318     };
2319 
2320     this.getEncodedHex = function() {
2321         return this.asn1Obj.getEncodedHex();
2322     }
2323 
2324     if (params !== undefined) {
2325         this.setByParam(params);
2326     }
2327 
2328 };
2329 YAHOO.lang.extend(KJUR.asn1.x509.GeneralName, KJUR.asn1.ASN1Object);
2330 
2331 /**
2332  * GeneralNames ASN.1 structure class<br/>
2333  * @name KJUR.asn1.x509.GeneralNames
2334  * @class GeneralNames ASN.1 structure class
2335  * @description
2336  * <br/>
2337  * <h4>EXAMPLE AND ASN.1 SYNTAX</h4>
2338  * @example
2339  * gns = new KJUR.asn1.x509.GeneralNames([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]);
2340  *
2341  * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
2342  */
2343 KJUR.asn1.x509.GeneralNames = function(paramsArray) {
2344     KJUR.asn1.x509.GeneralNames.superclass.constructor.call(this);
2345     var asn1Array = null,
2346 	_KJUR = KJUR,
2347 	_KJUR_asn1 = _KJUR.asn1;
2348 
2349     /**
2350      * set a array of {@link KJUR.asn1.x509.GeneralName} parameters<br/>
2351      * @name setByParamArray
2352      * @memberOf KJUR.asn1.x509.GeneralNames#
2353      * @function
2354      * @param {Array} paramsArray Array of {@link KJUR.asn1.x509.GeneralNames}
2355      * @description
2356      * <br/>
2357      * <h4>EXAMPLES</h4>
2358      * @example
2359      * gns = new KJUR.asn1.x509.GeneralNames();
2360      * gns.setByParamArray([{uri: 'http://aaa.com/'}, {uri: 'http://bbb.com/'}]);
2361      */
2362     this.setByParamArray = function(paramsArray) {
2363         for (var i = 0; i < paramsArray.length; i++) {
2364             var o = new _KJUR_asn1.x509.GeneralName(paramsArray[i]);
2365             this.asn1Array.push(o);
2366         }
2367     };
2368 
2369     this.getEncodedHex = function() {
2370         var o = new _KJUR_asn1.DERSequence({'array': this.asn1Array});
2371         return o.getEncodedHex();
2372     };
2373 
2374     this.asn1Array = new Array();
2375     if (typeof paramsArray != "undefined") {
2376         this.setByParamArray(paramsArray);
2377     }
2378 };
2379 YAHOO.lang.extend(KJUR.asn1.x509.GeneralNames, KJUR.asn1.ASN1Object);
2380 
2381 /**
2382  * DistributionPointName ASN.1 structure class<br/>
2383  * @name KJUR.asn1.x509.DistributionPointName
2384  * @class DistributionPointName ASN.1 structure class
2385  * @description
2386  * <pre>
2387  * DistributionPoint ::= SEQUENCE {
2388  *      distributionPoint       [0]     DistributionPointName OPTIONAL,
2389  *      reasons                 [1]     ReasonFlags OPTIONAL,
2390  *      cRLIssuer               [2]     GeneralNames OPTIONAL }
2391  *
2392  * DistributionPointName ::= CHOICE {
2393  *      fullName                [0]     GeneralNames,
2394  *      nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
2395  * 
2396  * ReasonFlags ::= BIT STRING {
2397  *      unused                  (0),
2398  *      keyCompromise           (1),
2399  *      cACompromise            (2),
2400  *      affiliationChanged      (3),
2401  *      superseded              (4),
2402  *      cessationOfOperation    (5),
2403  *      certificateHold         (6),
2404  *      privilegeWithdrawn      (7),
2405  *      aACompromise            (8) }
2406  * </pre>
2407  * @example
2408  */
2409 KJUR.asn1.x509.DistributionPointName = function(gnOrRdn) {
2410     KJUR.asn1.x509.DistributionPointName.superclass.constructor.call(this);
2411     var asn1Obj = null,
2412 	type = null,
2413 	tag = null,
2414 	asn1V = null,
2415 	_KJUR = KJUR,
2416 	_KJUR_asn1 = _KJUR.asn1,
2417 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject;
2418 
2419     this.getEncodedHex = function() {
2420         if (this.type != "full")
2421             throw "currently type shall be 'full': " + this.type;
2422         this.asn1Obj = new _DERTaggedObject({'explicit': false,
2423                                              'tag': this.tag,
2424                                              'obj': this.asn1V});
2425         this.hTLV = this.asn1Obj.getEncodedHex();
2426         return this.hTLV;
2427     };
2428 
2429     if (gnOrRdn !== undefined) {
2430         if (_KJUR_asn1.x509.GeneralNames.prototype.isPrototypeOf(gnOrRdn)) {
2431             this.type = "full";
2432             this.tag = "a0";
2433             this.asn1V = gnOrRdn;
2434         } else {
2435             throw "This class supports GeneralNames only as argument";
2436         }
2437     }
2438 };
2439 YAHOO.lang.extend(KJUR.asn1.x509.DistributionPointName, KJUR.asn1.ASN1Object);
2440 
2441 /**
2442  * DistributionPoint ASN.1 structure class<br/>
2443  * @name KJUR.asn1.x509.DistributionPoint
2444  * @class DistributionPoint ASN.1 structure class
2445  * @description
2446  * <pre>
2447  * DistributionPoint ::= SEQUENCE {
2448  *      distributionPoint       [0]     DistributionPointName OPTIONAL,
2449  *      reasons                 [1]     ReasonFlags OPTIONAL,
2450  *      cRLIssuer               [2]     GeneralNames OPTIONAL }
2451  *
2452  * DistributionPointName ::= CHOICE {
2453  *      fullName                [0]     GeneralNames,
2454  *      nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
2455  * 
2456  * ReasonFlags ::= BIT STRING {
2457  *      unused                  (0),
2458  *      keyCompromise           (1),
2459  *      cACompromise            (2),
2460  *      affiliationChanged      (3),
2461  *      superseded              (4),
2462  *      cessationOfOperation    (5),
2463  *      certificateHold         (6),
2464  *      privilegeWithdrawn      (7),
2465  *      aACompromise            (8) }
2466  * </pre>
2467  * @example
2468  */
2469 KJUR.asn1.x509.DistributionPoint = function(params) {
2470     KJUR.asn1.x509.DistributionPoint.superclass.constructor.call(this);
2471     var asn1DP = null,
2472 	_KJUR = KJUR,
2473 	_KJUR_asn1 = _KJUR.asn1;
2474 
2475     this.getEncodedHex = function() {
2476         var seq = new _KJUR_asn1.DERSequence();
2477         if (this.asn1DP != null) {
2478             var o1 = new _KJUR_asn1.DERTaggedObject({'explicit': true,
2479                                                      'tag': 'a0',
2480                                                      'obj': this.asn1DP});
2481             seq.appendASN1Object(o1);
2482         }
2483         this.hTLV = seq.getEncodedHex();
2484         return this.hTLV;
2485     };
2486 
2487     if (params !== undefined) {
2488         if (params.dpobj !== undefined) {
2489             this.asn1DP = params.dpobj;
2490         }
2491     }
2492 };
2493 YAHOO.lang.extend(KJUR.asn1.x509.DistributionPoint, KJUR.asn1.ASN1Object);
2494 
2495 /**
2496  * static object for OID
2497  * @name KJUR.asn1.x509.OID
2498  * @class static object for OID
2499  * @property {Assoc Array} atype2oidList for short attribute type name and oid (ex. 'C' and '2.5.4.6')
2500  * @property {Assoc Array} name2oidList for oid name and oid (ex. 'keyUsage' and '2.5.29.15')
2501  * @property {Assoc Array} objCache for caching name and DERObjectIdentifier object
2502  * @description
2503  * This class defines OID name and values.
2504  * AttributeType names registered in OID.atype2oidList are following:
2505  * <table style="border-width: thin; border-style: solid; witdh: 100%">
2506  * <tr><th>short</th><th>long</th><th>OID</th></tr>
2507  * <tr><td>CN</td>commonName<td></td><td>2.5.4.3</td></tr>
2508  * <tr><td>L</td><td>localityName</td><td>2.5.4.7</td></tr>
2509  * <tr><td>ST</td><td>stateOrProvinceName</td><td>2.5.4.8</td></tr>
2510  * <tr><td>O</td><td>organizationName</td><td>2.5.4.10</td></tr>
2511  * <tr><td>OU</td><td>organizationalUnitName</td><td>2.5.4.11</td></tr>
2512  * <tr><td>C</td><td></td>countryName<td>2.5.4.6</td></tr>
2513  * <tr><td>STREET</td>streetAddress<td></td><td>2.5.4.6</td></tr>
2514  * <tr><td>DC</td><td>domainComponent</td><td>0.9.2342.19200300.100.1.25</td></tr>
2515  * <tr><td>UID</td><td>userId</td><td>0.9.2342.19200300.100.1.1</td></tr>
2516  * <tr><td>SN</td><td>surname</td><td>2.5.4.4</td></tr>
2517  * <tr><td>DN</td><td>distinguishedName</td><td>2.5.4.49</td></tr>
2518  * <tr><td>E</td><td>emailAddress</td><td>1.2.840.113549.1.9.1</td></tr>
2519  * <tr><td></td><td>businessCategory</td><td>2.5.4.15</td></tr>
2520  * <tr><td></td><td>postalCode</td><td>2.5.4.17</td></tr>
2521  * <tr><td></td><td>jurisdictionOfIncorporationL</td><td>1.3.6.1.4.1.311.60.2.1.1</td></tr>
2522  * <tr><td></td><td>jurisdictionOfIncorporationSP</td><td>1.3.6.1.4.1.311.60.2.1.2</td></tr>
2523  * <tr><td></td><td>jurisdictionOfIncorporationC</td><td>1.3.6.1.4.1.311.60.2.1.3</td></tr>
2524  * </table>
2525  *
2526  * @example
2527  */
2528 KJUR.asn1.x509.OID = new function(params) {
2529     this.atype2oidList = {
2530 	// RFC 4514 AttributeType name string (MUST recognized)
2531         'CN':		'2.5.4.3',
2532         'L':		'2.5.4.7',
2533         'ST':		'2.5.4.8',
2534         'O':		'2.5.4.10',
2535         'OU':		'2.5.4.11',
2536         'C':		'2.5.4.6',
2537         'STREET':	'2.5.4.9',
2538         'DC':		'0.9.2342.19200300.100.1.25',
2539         'UID':		'0.9.2342.19200300.100.1.1',
2540 	// other AttributeType name string
2541 	// http://blog.livedoor.jp/k_urushima/archives/656114.html
2542         'SN':		'2.5.4.4', // surname
2543         'T':		'2.5.4.12', // title
2544         'DN':		'2.5.4.49', // distinguishedName
2545         'E':		'1.2.840.113549.1.9.1', // emailAddress in MS.NET or Bouncy
2546 	// other AttributeType name string (no short name)
2547 	'description':			'2.5.4.13',
2548 	'businessCategory':		'2.5.4.15',
2549 	'postalCode':			'2.5.4.17',
2550 	'serialNumber':			'2.5.4.5',
2551 	'uniqueIdentifier':		'2.5.4.45',
2552 	'organizationIdentifier':	'2.5.4.97',
2553 	'jurisdictionOfIncorporationL':	'1.3.6.1.4.1.311.60.2.1.1',
2554 	'jurisdictionOfIncorporationSP':'1.3.6.1.4.1.311.60.2.1.2',
2555 	'jurisdictionOfIncorporationC':	'1.3.6.1.4.1.311.60.2.1.3'
2556     };
2557     this.name2oidList = {
2558         'sha1':                 '1.3.14.3.2.26',
2559         'sha256':               '2.16.840.1.101.3.4.2.1',
2560         'sha384':               '2.16.840.1.101.3.4.2.2',
2561         'sha512':               '2.16.840.1.101.3.4.2.3',
2562         'sha224':               '2.16.840.1.101.3.4.2.4',
2563         'md5':                  '1.2.840.113549.2.5',
2564         'md2':                  '1.3.14.7.2.2.1',
2565         'ripemd160':            '1.3.36.3.2.1',
2566 
2567         'MD2withRSA':           '1.2.840.113549.1.1.2',
2568         'MD4withRSA':           '1.2.840.113549.1.1.3',
2569         'MD5withRSA':           '1.2.840.113549.1.1.4',
2570         'SHA1withRSA':          '1.2.840.113549.1.1.5',
2571         'SHA224withRSA':        '1.2.840.113549.1.1.14',
2572         'SHA256withRSA':        '1.2.840.113549.1.1.11',
2573         'SHA384withRSA':        '1.2.840.113549.1.1.12',
2574         'SHA512withRSA':        '1.2.840.113549.1.1.13',
2575 
2576         'SHA1withECDSA':        '1.2.840.10045.4.1',
2577         'SHA224withECDSA':      '1.2.840.10045.4.3.1',
2578         'SHA256withECDSA':      '1.2.840.10045.4.3.2',
2579         'SHA384withECDSA':      '1.2.840.10045.4.3.3',
2580         'SHA512withECDSA':      '1.2.840.10045.4.3.4',
2581 
2582         'dsa':                  '1.2.840.10040.4.1',
2583         'SHA1withDSA':          '1.2.840.10040.4.3',
2584         'SHA224withDSA':        '2.16.840.1.101.3.4.3.1',
2585         'SHA256withDSA':        '2.16.840.1.101.3.4.3.2',
2586 
2587         'rsaEncryption':        '1.2.840.113549.1.1.1',
2588 
2589 	// X.500 AttributeType defined in RFC 4514
2590         'commonName':			'2.5.4.3',
2591         'countryName':			'2.5.4.6',
2592         'localityName':			'2.5.4.7',
2593         'stateOrProvinceName':		'2.5.4.8',
2594         'streetAddress':		'2.5.4.9',
2595         'organizationName':		'2.5.4.10',
2596         'organizationalUnitName':	'2.5.4.11',
2597         'domainComponent':		'0.9.2342.19200300.100.1.25',
2598         'userId':			'0.9.2342.19200300.100.1.1',
2599 	// other AttributeType name string
2600 	'surname':			'2.5.4.4',
2601         'title':			'2.5.4.12',
2602 	'distinguishedName':		'2.5.4.49',
2603 	'emailAddress':			'1.2.840.113549.1.9.1',
2604 	// other AttributeType name string (no short name)
2605 	'description':			'2.5.4.13',
2606 	'businessCategory':		'2.5.4.15',
2607 	'postalCode':			'2.5.4.17',
2608 	'uniqueIdentifier':		'2.5.4.45',
2609 	'organizationIdentifier':	'2.5.4.97',
2610 	'jurisdictionOfIncorporationL':	'1.3.6.1.4.1.311.60.2.1.1',
2611 	'jurisdictionOfIncorporationSP':'1.3.6.1.4.1.311.60.2.1.2',
2612 	'jurisdictionOfIncorporationC':	'1.3.6.1.4.1.311.60.2.1.3',
2613 
2614         'subjectKeyIdentifier': '2.5.29.14',
2615         'keyUsage':             '2.5.29.15',
2616         'subjectAltName':       '2.5.29.17',
2617         'issuerAltName':        '2.5.29.18',
2618         'basicConstraints':     '2.5.29.19',
2619         'nameConstraints':      '2.5.29.30',
2620         'cRLDistributionPoints':'2.5.29.31',
2621         'certificatePolicies':  '2.5.29.32',
2622         'authorityKeyIdentifier':'2.5.29.35',
2623         'policyConstraints':    '2.5.29.36',
2624         'extKeyUsage':          '2.5.29.37',
2625         'authorityInfoAccess':  '1.3.6.1.5.5.7.1.1',
2626         'ocsp':                 '1.3.6.1.5.5.7.48.1',
2627         'caIssuers':            '1.3.6.1.5.5.7.48.2',
2628 
2629         'anyExtendedKeyUsage':  '2.5.29.37.0',
2630         'serverAuth':           '1.3.6.1.5.5.7.3.1',
2631         'clientAuth':           '1.3.6.1.5.5.7.3.2',
2632         'codeSigning':          '1.3.6.1.5.5.7.3.3',
2633         'emailProtection':      '1.3.6.1.5.5.7.3.4',
2634         'timeStamping':         '1.3.6.1.5.5.7.3.8',
2635         'ocspSigning':          '1.3.6.1.5.5.7.3.9',
2636 
2637         'ecPublicKey':          '1.2.840.10045.2.1',
2638         'secp256r1':            '1.2.840.10045.3.1.7',
2639         'secp256k1':            '1.3.132.0.10',
2640         'secp384r1':            '1.3.132.0.34',
2641 
2642         'pkcs5PBES2':           '1.2.840.113549.1.5.13',
2643         'pkcs5PBKDF2':          '1.2.840.113549.1.5.12',
2644 
2645         'des-EDE3-CBC':         '1.2.840.113549.3.7',
2646 
2647         'data':                 '1.2.840.113549.1.7.1', // CMS data
2648         'signed-data':          '1.2.840.113549.1.7.2', // CMS signed-data
2649         'enveloped-data':       '1.2.840.113549.1.7.3', // CMS enveloped-data
2650         'digested-data':        '1.2.840.113549.1.7.5', // CMS digested-data
2651         'encrypted-data':       '1.2.840.113549.1.7.6', // CMS encrypted-data
2652         'authenticated-data':   '1.2.840.113549.1.9.16.1.2', // CMS authenticated-data
2653         'tstinfo':              '1.2.840.113549.1.9.16.1.4', // RFC3161 TSTInfo
2654         'extensionRequest':     '1.2.840.113549.1.9.14',// CSR extensionRequest
2655     };
2656 
2657     this.objCache = {};
2658 
2659     /**
2660      * get DERObjectIdentifier by registered OID name
2661      * @name name2obj
2662      * @memberOf KJUR.asn1.x509.OID
2663      * @function
2664      * @param {String} name OID
2665      * @description
2666      * @example
2667      * var asn1ObjOID = OID.name2obj('SHA1withRSA');
2668      */
2669     this.name2obj = function(name) {
2670         if (typeof this.objCache[name] != "undefined")
2671             return this.objCache[name];
2672         if (typeof this.name2oidList[name] == "undefined")
2673             throw "Name of ObjectIdentifier not defined: " + name;
2674         var oid = this.name2oidList[name];
2675         var obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid});
2676         this.objCache[name] = obj;
2677         return obj;
2678     };
2679 
2680     /**
2681      * get DERObjectIdentifier by registered attribute type name such like 'C' or 'CN'<br/>
2682      * @name atype2obj
2683      * @memberOf KJUR.asn1.x509.OID
2684      * @function
2685      * @param {String} atype short attribute type name such like 'C' or 'CN'
2686      * @description
2687      * @example
2688      * KJUR.asn1.x509.OID.atype2obj('CN') → 2.5.4.3
2689      * KJUR.asn1.x509.OID.atype2obj('OU') → 2.5.4.11
2690      */
2691     this.atype2obj = function(atype) {
2692         if (typeof this.objCache[atype] != "undefined")
2693             return this.objCache[atype];
2694         if (typeof this.atype2oidList[atype] == "undefined")
2695             throw "AttributeType name undefined: " + atype;
2696         var oid = this.atype2oidList[atype];
2697         var obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid});
2698         this.objCache[atype] = obj;
2699         return obj;
2700     };
2701 };
2702 
2703 /**
2704  * convert OID to name<br/>
2705  * @name oid2name
2706  * @memberOf KJUR.asn1.x509.OID
2707  * @function
2708  * @param {String} oid dot noted Object Identifer string (ex. 1.2.3.4)
2709  * @return {String} OID name if registered otherwise empty string
2710  * @since asn1x509 1.0.9
2711  * @description
2712  * This static method converts OID string to its name.
2713  * If OID is undefined then it returns empty string (i.e. '').
2714  * @example
2715  * KJUR.asn1.x509.OID.oid2name("1.3.6.1.5.5.7.1.1") → 'authorityInfoAccess'
2716  */
2717 KJUR.asn1.x509.OID.oid2name = function(oid) {
2718     var list = KJUR.asn1.x509.OID.name2oidList;
2719     for (var name in list) {
2720         if (list[name] == oid) return name;
2721     }
2722     return '';
2723 };
2724 
2725 /**
2726  * convert OID to AttributeType name<br/>
2727  * @name oid2atype
2728  * @memberOf KJUR.asn1.x509.OID
2729  * @function
2730  * @param {String} oid dot noted Object Identifer string (ex. 1.2.3.4)
2731  * @return {String} OID AttributeType name if registered otherwise oid
2732  * @since jsrsasign 6.2.2 asn1x509 1.0.18
2733  * @description
2734  * This static method converts OID string to its AttributeType name.
2735  * If OID is not defined in OID.atype2oidList associative array then it returns OID
2736  * specified as argument.
2737  * @example
2738  * KJUR.asn1.x509.OID.oid2atype("2.5.4.3") → CN
2739  * KJUR.asn1.x509.OID.oid2atype("1.3.6.1.4.1.311.60.2.1.3") → jurisdictionOfIncorporationC
2740  * KJUR.asn1.x509.OID.oid2atype("0.1.2.3.4") → 0.1.2.3.4 // unregistered OID
2741  */
2742 KJUR.asn1.x509.OID.oid2atype = function(oid) {
2743     var list = KJUR.asn1.x509.OID.atype2oidList;
2744     for (var atype in list) {
2745         if (list[atype] == oid) return atype;
2746     }
2747     return oid;
2748 };
2749 
2750 /**
2751  * convert OID name to OID value<br/>
2752  * @name name2oid
2753  * @memberOf KJUR.asn1.x509.OID
2754  * @function
2755  * @param {String} OID name
2756  * @return {String} dot noted Object Identifer string (ex. 1.2.3.4)
2757  * @since asn1x509 1.0.11
2758  * @description
2759  * This static method converts from OID name to OID string.
2760  * If OID is undefined then it returns empty string (i.e. '').
2761  * @example
2762  * KJUR.asn1.x509.OID.name2oid("authorityInfoAccess") → 1.3.6.1.5.5.7.1.1
2763  */
2764 KJUR.asn1.x509.OID.name2oid = function(name) {
2765     var list = KJUR.asn1.x509.OID.name2oidList;
2766     if (list[name] === undefined) return '';
2767     return list[name];
2768 };
2769 
2770 /**
2771  * X.509 certificate and CRL utilities class<br/>
2772  * @name KJUR.asn1.x509.X509Util
2773  * @class X.509 certificate and CRL utilities class
2774  */
2775 KJUR.asn1.x509.X509Util = {};
2776 
2777 /**
2778  * issue a certificate in PEM format
2779  * @name newCertPEM
2780  * @memberOf KJUR.asn1.x509.X509Util
2781  * @function
2782  * @param {Array} param parameter to issue a certificate
2783  * @since asn1x509 1.0.6
2784  * @description
2785  * This method can issue a certificate by a simple
2786  * JSON object.
2787  * Signature value will be provided by signing with
2788  * private key using 'cakey' parameter or
2789  * hexa decimal signature value by 'sighex' parameter.
2790  * <br/>
2791  * NOTE: Algorithm parameter of AlgorithmIdentifier will
2792  * be set automatically by default. (see {@link KJUR.asn1.x509.AlgorithmIdentifier})
2793  * from jsrsasign 7.1.1 asn1x509 1.0.20.
2794  *
2795  * @example
2796  * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM({
2797  *   serial: {int: 4},
2798  *   sigalg: {name: 'SHA1withECDSA'},
2799  *   issuer: {str: '/C=US/O=a'},
2800  *   notbefore: {'str': '130504235959Z'},
2801  *   notafter: {'str': '140504235959Z'},
2802  *   subject: {str: '/C=US/O=b'},
2803  *   sbjpubkey: pubKeyObj,
2804  *   ext: [
2805  *     {basicConstraints: {cA: true, critical: true}},
2806  *     {keyUsage: {bin: '11'}},
2807  *   ],
2808  *   cakey: prvKeyObj
2809  * });
2810  * // -- or --
2811  * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM({
2812  *   serial: {int: 4},
2813  *   sigalg: {name: 'SHA1withECDSA'},
2814  *   issuer: {str: '/C=US/O=a'},
2815  *   notbefore: {'str': '130504235959Z'},
2816  *   notafter: {'str': '140504235959Z'},
2817  *   subject: {str: '/C=US/O=b'},
2818  *   sbjpubkey: pubKeyPEM,
2819  *   ext: [
2820  *     {basicConstraints: {cA: true, critical: true}},
2821  *     {keyUsage: {bin: '11'}},
2822  *   ],
2823  *   cakey: [prvkey, pass]}
2824  * );
2825  * // -- or --
2826  * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM({
2827  *   serial: {int: 1},
2828  *   sigalg: {name: 'SHA1withRSA'},
2829  *   issuer: {str: '/C=US/O=T1'},
2830  *   notbefore: {'str': '130504235959Z'},
2831  *   notafter: {'str': '140504235959Z'},
2832  *   subject: {str: '/C=US/O=T1'},
2833  *   sbjpubkey: pubKeyObj,
2834  *   sighex: '0102030405..'
2835  * });
2836  * // for the issuer and subject field, another
2837  * // representation is also available
2838  * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM({
2839  *   serial: {int: 1},
2840  *   sigalg: {name: 'SHA256withRSA'},
2841  *   issuer: {C: "US", O: "T1"},
2842  *   notbefore: {'str': '130504235959Z'},
2843  *   notafter: {'str': '140504235959Z'},
2844  *   subject: {C: "US", O: "T1", CN: "http://example.com/"},
2845  *   sbjpubkey: pubKeyObj,
2846  *   sighex: '0102030405..'
2847  * });
2848  */
2849 KJUR.asn1.x509.X509Util.newCertPEM = function(param) {
2850     var _KJUR_asn1_x509 = KJUR.asn1.x509,
2851 	_TBSCertificate = _KJUR_asn1_x509.TBSCertificate,
2852 	_Certificate = _KJUR_asn1_x509.Certificate;
2853     var o = new _TBSCertificate();
2854 
2855     if (param.serial !== undefined)
2856         o.setSerialNumberByParam(param.serial);
2857     else
2858         throw "serial number undefined.";
2859 
2860     if (typeof param.sigalg.name === 'string')
2861         o.setSignatureAlgByParam(param.sigalg);
2862     else
2863         throw "unproper signature algorithm name";
2864 
2865     if (param.issuer !== undefined)
2866         o.setIssuerByParam(param.issuer);
2867     else
2868         throw "issuer name undefined.";
2869 
2870     if (param.notbefore !== undefined)
2871         o.setNotBeforeByParam(param.notbefore);
2872     else
2873         throw "notbefore undefined.";
2874 
2875     if (param.notafter !== undefined)
2876         o.setNotAfterByParam(param.notafter);
2877     else
2878         throw "notafter undefined.";
2879 
2880     if (param.subject !== undefined)
2881         o.setSubjectByParam(param.subject);
2882     else
2883         throw "subject name undefined.";
2884 
2885     if (param.sbjpubkey !== undefined)
2886         o.setSubjectPublicKeyByGetKey(param.sbjpubkey);
2887     else
2888         throw "subject public key undefined.";
2889 
2890     if (param.ext !== undefined && param.ext.length !== undefined) {
2891         for (var i = 0; i < param.ext.length; i++) {
2892             for (key in param.ext[i]) {
2893                 o.appendExtensionByName(key, param.ext[i][key]);
2894             }
2895         }
2896     }
2897 
2898     // set signature
2899     if (param.cakey === undefined && param.sighex === undefined)
2900         throw "param cakey and sighex undefined.";
2901 
2902     var caKey = null;
2903     var cert = null;
2904 
2905     if (param.cakey) {
2906 	if (param.cakey.isPrivate === true) {
2907 	    caKey = param.cakey;
2908 	} else {
2909             caKey = KEYUTIL.getKey.apply(null, param.cakey);
2910 	}
2911         cert = new _Certificate({'tbscertobj': o, 'prvkeyobj': caKey});
2912         cert.sign();
2913     }
2914 
2915     if (param.sighex) {
2916         cert = new _Certificate({'tbscertobj': o});
2917         cert.setSignatureHex(param.sighex);
2918     }
2919 
2920     return cert.getPEMString();
2921 };
2922 
2923