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