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