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