1 /*! asn1x509-1.0.7.js (c) 2013 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 Kenji Urushima (kenji.urushima@gmail.com)
  7  *
  8  * This software is licensed under the terms of the MIT License.
  9  * http://kjur.github.com/jsrsasign/license
 10  *
 11  * The above copyright and license notice shall be 
 12  * included in all copies or substantial portions of the Software.
 13  */
 14 
 15 /**
 16  * @fileOverview
 17  * @name asn1x509-1.0.js
 18  * @author Kenji Urushima kenji.urushima@gmail.com
 19  * @version 1.0.7 (2013-Oct-11)
 20  * @since jsrsasign 2.1
 21  * @license <a href="http://kjur.github.io/jsrsasign/license/">MIT License</a>
 22  */
 23 
 24 /** 
 25  * kjur's class library name space
 26  * // already documented in asn1-1.0.js
 27  * @name KJUR
 28  * @namespace kjur's class library name space
 29  */
 30 if (typeof KJUR == "undefined" || !KJUR) KJUR = {};
 31 
 32 /**
 33  * kjur's ASN.1 class library name space
 34  * // already documented in asn1-1.0.js
 35  * @name KJUR.asn1
 36  * @namespace
 37  */
 38 if (typeof KJUR.asn1 == "undefined" || !KJUR.asn1) KJUR.asn1 = {};
 39 
 40 /**
 41  * kjur's ASN.1 class for X.509 certificate library name space
 42  * <p>
 43  * <h4>FEATURES</h4>
 44  * <ul>
 45  * <li>easily issue any kind of certificate</li>
 46  * <li>APIs are very similar to BouncyCastle library ASN.1 classes. So easy to learn.</li>
 47  * </ul>
 48  * </p>
 49  * <h4>PROVIDED CLASSES</h4>
 50  * <ul>
 51  * <li>{@link KJUR.asn1.x509.Certificate}</li>
 52  * <li>{@link KJUR.asn1.x509.TBSCertificate}</li>
 53  * <li>{@link KJUR.asn1.x509.Extension}</li>
 54  * <li>{@link KJUR.asn1.x509.X500Name}</li>
 55  * <li>{@link KJUR.asn1.x509.RDN}</li>
 56  * <li>{@link KJUR.asn1.x509.AttributeTypeAndValue}</li>
 57  * <li>{@link KJUR.asn1.x509.SubjectPublicKeyInfo}</li>
 58  * <li>{@link KJUR.asn1.x509.AlgorithmIdentifier}</li>
 59  * <li>{@link KJUR.asn1.x509.GeneralName}</li>
 60  * <li>{@link KJUR.asn1.x509.GeneralNames}</li>
 61  * <li>{@link KJUR.asn1.x509.DistributionPointName}</li>
 62  * <li>{@link KJUR.asn1.x509.DistributionPoint}</li>
 63  * <li>{@link KJUR.asn1.x509.CRL}</li>
 64  * <li>{@link KJUR.asn1.x509.TBSCertList}</li>
 65  * <li>{@link KJUR.asn1.x509.CRLEntry}</li>
 66  * <li>{@link KJUR.asn1.x509.OID}</li>
 67  * </ul>
 68  * <h4>SUPPORTED EXTENSIONS</h4>
 69  * <ul>
 70  * <li>{@link KJUR.asn1.x509.BasicConstraints}</li>
 71  * <li>{@link KJUR.asn1.x509.KeyUsage}</li>
 72  * <li>{@link KJUR.asn1.x509.CRLDistributionPoints}</li>
 73  * <li>{@link KJUR.asn1.x509.ExtKeyUsage}</li>
 74  * </ul>
 75  * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.
 76  * @name KJUR.asn1.x509
 77  * @namespace
 78  */
 79 if (typeof KJUR.asn1.x509 == "undefined" || !KJUR.asn1.x509) KJUR.asn1.x509 = {};
 80 
 81 // === BEGIN Certificate ===================================================
 82 
 83 /**
 84  * X.509 Certificate class to sign and generate hex encoded certificate
 85  * @name KJUR.asn1.x509.Certificate
 86  * @class X.509 Certificate class to sign and generate hex encoded certificate
 87  * @param {Array} params associative array of parameters (ex. {'tbscertobj': obj, 'prvkeyobj': key})
 88  * @extends KJUR.asn1.ASN1Object
 89  * @description
 90  * <br/>
 91  * As for argument 'params' for constructor, you can specify one of
 92  * following properties:
 93  * <ul>
 94  * <li>tbscertobj - specify {@link KJUR.asn1.x509.TBSCertificate} object</li>
 95  * <li>prvkeyobj - specify {@link RSAKey}, {@link KJUR.crypto.ECDSA} or {@link KJUR.crypto.DSA} object for CA private key to sign the certificate</li>
 96  * <li>(DEPRECATED)rsaprvkey - specify {@link RSAKey} object CA private key</li>
 97  * <li>(DEPRECATED)rsaprvpem - specify PEM string of RSA CA private key</li>
 98  * </ul>
 99  * NOTE1: 'params' can be omitted.<br/>
100  * NOTE2: DSA/ECDSA is also supported for CA signging key from asn1x509 1.0.6.
101  * @example
102  * var caKey = KEYUTIL.getKey(caKeyPEM); // CA's private key
103  * var cert = new KJUR.asn1x509.Certificate({'tbscertobj': tbs, 'prvkeyobj': caKey});
104  * cert.sign(); // issue certificate by CA's private key
105  * var certPEM = cert.getPEMString();
106  *
107  * // Certificate  ::=  SEQUENCE  {
108  * //     tbsCertificate       TBSCertificate,
109  * //     signatureAlgorithm   AlgorithmIdentifier,
110  * //     signature            BIT STRING  }	    
111  */
112 KJUR.asn1.x509.Certificate = function(params) {
113     KJUR.asn1.x509.Certificate.superclass.constructor.call(this);
114     var asn1TBSCert = null;
115     var asn1SignatureAlg = null;
116     var asn1Sig = null;
117     var hexSig = null;
118     var prvKey = null;
119     var rsaPrvKey = null; // DEPRECATED
120 
121     
122     /**
123      * set PKCS#5 encrypted RSA PEM private key as CA key
124      * @name setRsaPrvKeyByPEMandPass
125      * @memberOf KJUR.asn1.x509.Certificate
126      * @function
127      * @param {String} rsaPEM string of PKCS#5 encrypted RSA PEM private key
128      * @param {String} passPEM passcode string to decrypt private key
129      * @since 1.0.1
130      * @description
131      * <br/>
132      * <h4>EXAMPLES</h4>
133      * @example
134      * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs});
135      * cert.setRsaPrvKeyByPEMandPass("-----BEGIN RSA PRIVATE..(snip)", "password");
136      */
137     this.setRsaPrvKeyByPEMandPass = function(rsaPEM, passPEM) {
138 	var caKeyHex = PKCS5PKEY.getDecryptedKeyHex(rsaPEM, passPEM);
139 	var caKey = new RSAKey();
140 	caKey.readPrivateKeyFromASN1HexString(caKeyHex);  
141 	this.prvKey = caKey;
142     };
143 
144     /**
145      * sign TBSCertificate and set signature value internally
146      * @name sign
147      * @memberOf KJUR.asn1.x509.Certificate
148      * @function
149      * @description
150      * @example
151      * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs, 'rsaprvkey': prvKey});
152      * cert.sign();
153      */
154     this.sign = function() {
155 	this.asn1SignatureAlg = this.asn1TBSCert.asn1SignatureAlg;
156 
157 	sig = new KJUR.crypto.Signature({'alg': 'SHA1withRSA'});
158 	sig.init(this.prvKey);
159 	sig.updateHex(this.asn1TBSCert.getEncodedHex());
160 	this.hexSig = sig.sign();
161 
162 	this.asn1Sig = new KJUR.asn1.DERBitString({'hex': '00' + this.hexSig});
163 	
164 	var seq = new KJUR.asn1.DERSequence({'array': [this.asn1TBSCert,
165 						       this.asn1SignatureAlg,
166 						       this.asn1Sig]});
167 	this.hTLV = seq.getEncodedHex();
168 	this.isModified = false;
169     };
170 
171     this.getEncodedHex = function() {
172 	if (this.isModified == false && this.hTLV != null) return this.hTLV;
173 	throw "not signed yet";
174     };
175 
176     /**
177      * get PEM formatted certificate string after signed
178      * @name getPEMString
179      * @memberOf KJUR.asn1.x509.Certificate
180      * @function
181      * @return PEM formatted string of certificate
182      * @description
183      * @example
184      * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs, 'rsaprvkey': prvKey});
185      * cert.sign();
186      * var sPEM =  cert.getPEMString();
187      */
188     this.getPEMString = function() {
189 	var hCert = this.getEncodedHex();
190 	var wCert = CryptoJS.enc.Hex.parse(hCert);
191 	var b64Cert = CryptoJS.enc.Base64.stringify(wCert);
192 	var pemBody = b64Cert.replace(/(.{64})/g, "$1\r\n");
193 	return "-----BEGIN CERTIFICATE-----\r\n" + pemBody + "\r\n-----END CERTIFICATE-----\r\n";
194     };
195 
196     if (typeof params != "undefined") {
197 	if (typeof params['tbscertobj'] != "undefined") {
198 	    this.asn1TBSCert = params['tbscertobj'];
199 	}
200 	if (typeof params['prvkeyobj'] != "undefined") {
201 	    this.prvKey = params['prvkeyobj'];
202 	} else if (typeof params['rsaprvkey'] != "undefined") {
203 	    this.prvKey = params['rsaprvkey'];
204         } else if ((typeof params['rsaprvpem'] != "undefined") &&
205 	    (typeof params['rsaprvpas'] != "undefined")) {
206 	    this.setRsaPrvKeyByPEMandPass(params['rsaprvpem'], params['rsaprvpas']);
207 	}
208     }
209 };
210 YAHOO.lang.extend(KJUR.asn1.x509.Certificate, KJUR.asn1.ASN1Object);
211 
212 /**
213  * ASN.1 TBSCertificate structure class
214  * @name KJUR.asn1.x509.TBSCertificate
215  * @class ASN.1 TBSCertificate structure class
216  * @param {Array} params associative array of parameters (ex. {})
217  * @extends KJUR.asn1.ASN1Object
218  * @description
219  * <br/>
220  * <h4>EXAMPLE</h4>
221  * @example
222  *  var o = new KJUR.asn1.x509.TBSCertificate();
223  *  o.setSerialNumberByParam({'int': 4});
224  *  o.setSignatureAlgByParam({'name': 'SHA1withRSA'});
225  *  o.setIssuerByParam({'str': '/C=US/O=a'});
226  *  o.setNotBeforeByParam({'str': '130504235959Z'});
227  *  o.setNotAfterByParam({'str': '140504235959Z'});
228  *  o.setSubjectByParam({'str': '/C=US/CN=b'});
229  *  o.setSubjectPublicKeyByParam({'rsakey': rsaKey});
230  *  o.appendExtension(new KJUR.asn1.x509.BasicConstraints({'cA':true}));
231  *  o.appendExtension(new KJUR.asn1.x509.KeyUsage({'bin':'11'}));
232  */
233 KJUR.asn1.x509.TBSCertificate = function(params) {
234     KJUR.asn1.x509.TBSCertificate.superclass.constructor.call(this);
235 
236     this._initialize = function() {
237 	this.asn1Array = new Array();
238 
239 	this.asn1Version = 
240 	    new KJUR.asn1.DERTaggedObject({'obj': new KJUR.asn1.DERInteger({'int': 2})});
241 	this.asn1SerialNumber = null;
242 	this.asn1SignatureAlg = null;
243 	this.asn1Issuer = null;
244 	this.asn1NotBefore = null;
245 	this.asn1NotAfter = null;
246 	this.asn1Subject = null;
247 	this.asn1SubjPKey = null;
248 	this.extensionsArray = new Array();
249     };
250 
251     /**
252      * set serial number field by parameter
253      * @name setSerialNumberByParam
254      * @memberOf KJUR.asn1.x509.TBSCertificate
255      * @function
256      * @param {Array} intParam DERInteger param
257      * @description
258      * @example
259      * tbsc.setSerialNumberByParam({'int': 3});
260      */
261     this.setSerialNumberByParam = function(intParam) {
262 	this.asn1SerialNumber = new KJUR.asn1.DERInteger(intParam);
263     };
264 
265     /**
266      * set signature algorithm field by parameter
267      * @name setSignatureAlgByParam
268      * @memberOf KJUR.asn1.x509.TBSCertificate
269      * @function
270      * @param {Array} algIdParam AlgorithmIdentifier parameter
271      * @description
272      * @example
273      * tbsc.setSignatureAlgByParam({'name': 'SHA1withRSA'});
274      */
275     this.setSignatureAlgByParam = function(algIdParam) {
276 	this.asn1SignatureAlg = new KJUR.asn1.x509.AlgorithmIdentifier(algIdParam);
277     };
278 
279     /**
280      * set issuer name field by parameter
281      * @name setIssuerByParam
282      * @memberOf KJUR.asn1.x509.TBSCertificate
283      * @function
284      * @param {Array} x500NameParam X500Name parameter
285      * @description
286      * @example
287      * tbsc.setIssuerParam({'str': '/C=US/CN=b'});
288      * @see KJUR.asn1.x509.X500Name
289      */
290     this.setIssuerByParam = function(x500NameParam) {
291 	this.asn1Issuer = new KJUR.asn1.x509.X500Name(x500NameParam);
292     };
293 
294     /**
295      * set notBefore field by parameter
296      * @name setNotBeforeByParam
297      * @memberOf KJUR.asn1.x509.TBSCertificate
298      * @function
299      * @param {Array} timeParam Time parameter
300      * @description
301      * @example
302      * tbsc.setNotBeforeByParam({'str': '130508235959Z'});
303      * @see KJUR.asn1.x509.Time
304      */
305     this.setNotBeforeByParam = function(timeParam) {
306 	this.asn1NotBefore = new KJUR.asn1.x509.Time(timeParam);
307     };
308     
309     /**
310      * set notAfter field by parameter
311      * @name setNotAfterByParam
312      * @memberOf KJUR.asn1.x509.TBSCertificate
313      * @function
314      * @param {Array} timeParam Time parameter
315      * @description
316      * @example
317      * tbsc.setNotAfterByParam({'str': '130508235959Z'});
318      * @see KJUR.asn1.x509.Time
319      */
320     this.setNotAfterByParam = function(timeParam) {
321 	this.asn1NotAfter = new KJUR.asn1.x509.Time(timeParam);
322     };
323 
324     /**
325      * set subject name field by parameter
326      * @name setSubjectByParam
327      * @memberOf KJUR.asn1.x509.TBSCertificate
328      * @function
329      * @param {Array} x500NameParam X500Name parameter
330      * @description
331      * @example
332      * tbsc.setSubjectParam({'str': '/C=US/CN=b'});
333      * @see KJUR.asn1.x509.X500Name
334      */
335     this.setSubjectByParam = function(x500NameParam) {
336 	this.asn1Subject = new KJUR.asn1.x509.X500Name(x500NameParam);
337     };
338 
339     /**
340      * (DEPRECATED) set subject public key info field by RSA key parameter
341      * @name setSubjectPublicKeyByParam
342      * @memberOf KJUR.asn1.x509.TBSCertificate
343      * @function
344      * @param {Array} subjPKeyParam SubjectPublicKeyInfo parameter of RSA
345      * @deprecated
346      * @description
347      * @example
348      * tbsc.setSubjectPublicKeyByParam({'rsakey': pubKey});
349      * @see KJUR.asn1.x509.SubjectPublicKeyInfo
350      */
351     this.setSubjectPublicKeyByParam = function(subjPKeyParam) {
352 	this.asn1SubjPKey = new KJUR.asn1.x509.SubjectPublicKeyInfo(subjPKeyParam);
353     };
354 
355     /**
356      * set subject public key info by RSA/ECDSA/DSA key parameter
357      * @name setSubjectPublicKeyByGetKey
358      * @memberOf KJUR.asn1.x509.TBSCertificate
359      * @function
360      * @param {Object} keyParam public key parameter which passed to {@link KEYUTIL.getKey} argument
361      * @description
362      * @example
363      * tbsc.setSubjectPublicKeyByGetKeyParam(certPEMString); // or 
364      * tbsc.setSubjectPublicKeyByGetKeyParam(pkcs8PublicKeyPEMString); // or 
365      * tbsc.setSubjectPublicKeyByGetKeyParam(kjurCryptoECDSAKeyObject); // et.al.
366      * @see KJUR.asn1.x509.SubjectPublicKeyInfo
367      * @see KEYUTIL.getKey
368      * @since asn1x509 1.0.6
369      */
370     this.setSubjectPublicKeyByGetKey = function(keyParam) {
371 	var keyObj = KEYUTIL.getKey(keyParam);
372 	this.asn1SubjPKey = new KJUR.asn1.x509.SubjectPublicKeyInfo(keyObj);
373     };
374 
375     /**
376      * append X.509v3 extension to this object
377      * @name appendExtension
378      * @memberOf KJUR.asn1.x509.TBSCertificate
379      * @function
380      * @param {Extension} extObj X.509v3 Extension object
381      * @description
382      * @example
383      * tbsc.appendExtension(new KJUR.asn1.x509.BasicConstraints({'cA':true, 'critical': true}));
384      * tbsc.appendExtension(new KJUR.asn1.x509.KeyUsage({'bin':'11'}));
385      * @see KJUR.asn1.x509.Extension
386      */
387     this.appendExtension = function(extObj) {
388 	this.extensionsArray.push(extObj);
389     };
390 
391     /**
392      * append X.509v3 extension to this object by name and parameters
393      * @name appendExtensionByName
394      * @memberOf KJUR.asn1.x509.TBSCertificate
395      * @function
396      * @param {name} name name of X.509v3 Extension object
397      * @param {Array} extParams parameters as argument of Extension constructor.
398      * @description
399      * @example
400      * tbsc.appendExtensionByName('BasicConstraints', {'cA':true, 'critical': true});
401      * tbsc.appendExtensionByName('KeyUsage', {'bin':'11'});
402      * tbsc.appendExtensionByName('CRLDistributionPoints', {uri: 'http://aaa.com/a.crl'});
403      * tbsc.appendExtensionByName('ExtKeyUsage', {array: [{name: 'clientAuth'}]});
404      * @see KJUR.asn1.x509.Extension
405      */
406     this.appendExtensionByName = function(name, extParams) {
407 	if (name.toLowerCase() == "basicconstraints") {
408 	    var extObj = new KJUR.asn1.x509.BasicConstraints(extParams);
409 	    this.appendExtension(extObj);
410 	} else if (name.toLowerCase() == "keyusage") {
411 	    var extObj = new KJUR.asn1.x509.KeyUsage(extParams);
412 	    this.appendExtension(extObj);
413 	} else if (name.toLowerCase() == "crldistributionpoints") {
414 	    var extObj = new KJUR.asn1.x509.CRLDistributionPoints(extParams);
415 	    this.appendExtension(extObj);
416 	} else if (name.toLowerCase() == "extkeyusage") {
417 	    var extObj = new KJUR.asn1.x509.ExtKeyUsage(extParams);
418 	    this.appendExtension(extObj);
419 	} else {
420 	    throw "unsupported extension name: " + name;
421 	}
422     };
423 
424     this.getEncodedHex = function() {
425 	if (this.asn1NotBefore == null || this.asn1NotAfter == null)
426 	    throw "notBefore and/or notAfter not set";
427 	var asn1Validity = 
428 	    new KJUR.asn1.DERSequence({'array':[this.asn1NotBefore, this.asn1NotAfter]});
429 
430 	this.asn1Array = new Array();
431 
432 	this.asn1Array.push(this.asn1Version);
433 	this.asn1Array.push(this.asn1SerialNumber);
434 	this.asn1Array.push(this.asn1SignatureAlg);
435 	this.asn1Array.push(this.asn1Issuer);
436 	this.asn1Array.push(asn1Validity);
437 	this.asn1Array.push(this.asn1Subject);
438 	this.asn1Array.push(this.asn1SubjPKey);
439 
440 	if (this.extensionsArray.length > 0) {
441 	    var extSeq = new KJUR.asn1.DERSequence({"array": this.extensionsArray});
442 	    var extTagObj = new KJUR.asn1.DERTaggedObject({'explicit': true,
443 							   'tag': 'a3',
444 							   'obj': extSeq});
445 	    this.asn1Array.push(extTagObj);
446 	}
447 
448 	var o = new KJUR.asn1.DERSequence({"array": this.asn1Array});
449 	this.hTLV = o.getEncodedHex();
450 	this.isModified = false;
451 	return this.hTLV;
452     };
453 
454     this._initialize();
455 };
456 YAHOO.lang.extend(KJUR.asn1.x509.TBSCertificate, KJUR.asn1.ASN1Object);
457 
458 // === END   TBSCertificate ===================================================
459 
460 // === BEGIN X.509v3 Extensions Related =======================================
461 
462 /**
463  * base Extension ASN.1 structure class
464  * @name KJUR.asn1.x509.Extension
465  * @class base Extension ASN.1 structure class
466  * @param {Array} params associative array of parameters (ex. {'critical': true})
467  * @extends KJUR.asn1.ASN1Object
468  * @description
469  * @example
470  * // Extension  ::=  SEQUENCE  {
471  * //     extnID      OBJECT IDENTIFIER,
472  * //     critical    BOOLEAN DEFAULT FALSE,
473  * //     extnValue   OCTET STRING  }
474  */
475 KJUR.asn1.x509.Extension = function(params) {
476     KJUR.asn1.x509.Extension.superclass.constructor.call(this);
477     var asn1ExtnValue = null;
478 
479     this.getEncodedHex = function() {
480 	var asn1Oid = new KJUR.asn1.DERObjectIdentifier({'oid': this.oid});
481 	var asn1EncapExtnValue = 
482 	    new KJUR.asn1.DEROctetString({'hex': this.getExtnValueHex()});
483 
484 	var asn1Array = new Array();
485 	asn1Array.push(asn1Oid);
486 	if (this.critical) asn1Array.push(new KJUR.asn1.DERBoolean());
487 	asn1Array.push(asn1EncapExtnValue);
488 
489 	var asn1Seq = new KJUR.asn1.DERSequence({'array': asn1Array});
490 	return asn1Seq.getEncodedHex();
491     };
492 
493     this.critical = false;
494     if (typeof params != "undefined") {
495 	if (typeof params['critical'] != "undefined") {
496 	    this.critical = params['critical'];
497 	}
498     }
499 };
500 YAHOO.lang.extend(KJUR.asn1.x509.Extension, KJUR.asn1.ASN1Object);
501 
502 /**
503  * KeyUsage ASN.1 structure class
504  * @name KJUR.asn1.x509.KeyUsage
505  * @class KeyUsage ASN.1 structure class
506  * @param {Array} params associative array of parameters (ex. {'bin': '11', 'critical': true})
507  * @extends KJUR.asn1.x509.Extension
508  * @description
509  * @example
510  */
511 KJUR.asn1.x509.KeyUsage = function(params) {
512     KJUR.asn1.x509.KeyUsage.superclass.constructor.call(this, params);
513 
514     this.getExtnValueHex = function() {
515 	return this.asn1ExtnValue.getEncodedHex();
516     };
517 
518     this.oid = "2.5.29.15";
519     if (typeof params != "undefined") {
520 	if (typeof params['bin'] != "undefined") {
521 	    this.asn1ExtnValue = new KJUR.asn1.DERBitString(params);
522 	}
523     }
524 };
525 YAHOO.lang.extend(KJUR.asn1.x509.KeyUsage, KJUR.asn1.x509.Extension);
526 
527 /**
528  * BasicConstraints ASN.1 structure class
529  * @name KJUR.asn1.x509.BasicConstraints
530  * @class BasicConstraints ASN.1 structure class
531  * @param {Array} params associative array of parameters (ex. {'cA': true, 'critical': true})
532  * @extends KJUR.asn1.x509.Extension
533  * @description
534  * @example
535  */
536 KJUR.asn1.x509.BasicConstraints = function(params) {
537     KJUR.asn1.x509.BasicConstraints.superclass.constructor.call(this, params);
538     var cA = false;
539     var pathLen = -1;
540 
541     this.getExtnValueHex = function() {
542 	var asn1Array = new Array();
543 	if (this.cA) asn1Array.push(new KJUR.asn1.DERBoolean());
544 	if (this.pathLen > -1) 
545 	    asn1Array.push(new KJUR.asn1.DERInteger({'int': this.pathLen}));
546 	var asn1Seq = new KJUR.asn1.DERSequence({'array': asn1Array});
547 	this.asn1ExtnValue = asn1Seq;
548 	return this.asn1ExtnValue.getEncodedHex();
549     };
550 
551     this.oid = "2.5.29.19";
552     this.cA = false;
553     this.pathLen = -1;
554     if (typeof params != "undefined") {
555 	if (typeof params['cA'] != "undefined") {
556 	    this.cA = params['cA'];
557 	}
558 	if (typeof params['pathLen'] != "undefined") {
559 	    this.pathLen = params['pathLen'];
560 	}
561     }
562 };
563 YAHOO.lang.extend(KJUR.asn1.x509.BasicConstraints, KJUR.asn1.x509.Extension);
564 
565 /**
566  * CRLDistributionPoints ASN.1 structure class
567  * @name KJUR.asn1.x509.CRLDistributionPoints
568  * @class CRLDistributionPoints ASN.1 structure class
569  * @param {Array} params associative array of parameters (ex. {'uri': 'http://a.com/', 'critical': true})
570  * @extends KJUR.asn1.x509.Extension
571  * @description
572  * @example
573  */
574 KJUR.asn1.x509.CRLDistributionPoints = function(params) {
575     KJUR.asn1.x509.CRLDistributionPoints.superclass.constructor.call(this, params);
576 
577     this.getExtnValueHex = function() {
578 	return this.asn1ExtnValue.getEncodedHex();
579     };
580 
581     this.setByDPArray = function(dpArray) {
582 	this.asn1ExtnValue = new KJUR.asn1.DERSequence({'array': dpArray});
583     };
584 
585     this.setByOneURI = function(uri) {
586 	var gn1 = new KJUR.asn1.x509.GeneralNames([{'uri': uri}]);
587 	var dpn1 = new KJUR.asn1.x509.DistributionPointName(gn1);
588 	var dp1 = new KJUR.asn1.x509.DistributionPoint({'dpobj': dpn1});
589 	this.setByDPArray([dp1]);
590     };
591 
592     this.oid = "2.5.29.31";
593     if (typeof params != "undefined") {
594 	if (typeof params['array'] != "undefined") {
595 	    this.setByDPArray(params['array']);
596 	} else if (typeof params['uri'] != "undefined") {
597 	    this.setByOneURI(params['uri']);
598 	}
599     }
600 };
601 YAHOO.lang.extend(KJUR.asn1.x509.CRLDistributionPoints, KJUR.asn1.x509.Extension);
602 
603 /**
604  * KeyUsage ASN.1 structure class
605  * @name KJUR.asn1.x509.ExtKeyUsage
606  * @class ExtKeyUsage ASN.1 structure class
607  * @param {Array} params associative array of parameters
608  * @extends KJUR.asn1.x509.Extension
609  * @description
610  * @example
611  * var e1 = 
612  *     new KJUR.asn1.x509.ExtKeyUsage({'critical': true,
613  *                                     'array':
614  *                                     [{'oid': '2.5.29.37.0',  // anyExtendedKeyUsage
615  *                                       'name': 'clientAuth'}]});
616  *
617  * // id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
618  * // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
619  * // KeyPurposeId ::= OBJECT IDENTIFIER
620  */
621 KJUR.asn1.x509.ExtKeyUsage = function(params) {
622     KJUR.asn1.x509.ExtKeyUsage.superclass.constructor.call(this, params);
623 
624     this.setPurposeArray = function(purposeArray) {
625 	this.asn1ExtnValue = new KJUR.asn1.DERSequence();
626 	for (var i = 0; i < purposeArray.length; i++) {
627 	    var o = new KJUR.asn1.DERObjectIdentifier(purposeArray[i]);
628 	    this.asn1ExtnValue.appendASN1Object(o);
629 	}
630     };
631 
632     this.getExtnValueHex = function() {
633 	return this.asn1ExtnValue.getEncodedHex();
634     };
635 
636     this.oid = "2.5.29.37";
637     if (typeof params != "undefined") {
638 	if (typeof params['array'] != "undefined") {
639             this.setPurposeArray(params['array']);
640 	}
641     }
642 };
643 YAHOO.lang.extend(KJUR.asn1.x509.ExtKeyUsage, KJUR.asn1.x509.Extension);
644 
645 
646 // === END   X.509v3 Extensions Related =======================================
647 
648 // === BEGIN CRL Related ===================================================
649 /**
650  * X.509 CRL class to sign and generate hex encoded CRL
651  * @name KJUR.asn1.x509.CRL
652  * @class X.509 CRL class to sign and generate hex encoded certificate
653  * @param {Array} params associative array of parameters (ex. {'tbsobj': obj, 'rsaprvkey': key})
654  * @extends KJUR.asn1.ASN1Object
655  * @since 1.0.3
656  * @description
657  * <br/>
658  * As for argument 'params' for constructor, you can specify one of
659  * following properties:
660  * <ul>
661  * <li>tbsobj - specify {@link KJUR.asn1.x509.TBSCertList} object to be signed</li>
662  * <li>rsaprvkey - specify {@link RSAKey} object CA private key</li>
663  * </ul>
664  * NOTE: 'params' can be omitted.
665  * <h4>EXAMPLE</h4>
666  * @example
667  * var prvKey = new RSAKey(); // CA's private key
668  * prvKey.readPrivateKeyFromASN1HexString("3080...");
669  * var crl = new KJUR.asn1x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey});
670  * crl.sign(); // issue CRL by CA's private key
671  * var hCRL = crl.getEncodedHex();
672  *
673  * // CertificateList  ::=  SEQUENCE  {
674  * //     tbsCertList          TBSCertList,
675  * //     signatureAlgorithm   AlgorithmIdentifier,
676  * //     signatureValue       BIT STRING  }
677  */
678 KJUR.asn1.x509.CRL = function(params) {
679     KJUR.asn1.x509.CRL.superclass.constructor.call(this);
680 
681     var asn1TBSCertList = null;
682     var asn1SignatureAlg = null;
683     var asn1Sig = null;
684     var hexSig = null;
685     var rsaPrvKey = null;
686     
687     /**
688      * set PKCS#5 encrypted RSA PEM private key as CA key
689      * @name setRsaPrvKeyByPEMandPass
690      * @memberOf KJUR.asn1.x509.CRL
691      * @function
692      * @param {String} rsaPEM string of PKCS#5 encrypted RSA PEM private key
693      * @param {String} passPEM passcode string to decrypt private key
694      * @description
695      * <br/>
696      * <h4>EXAMPLES</h4>
697      * @example
698      */
699     this.setRsaPrvKeyByPEMandPass = function(rsaPEM, passPEM) {
700 	var caKeyHex = PKCS5PKEY.getDecryptedKeyHex(rsaPEM, passPEM);
701 	var caKey = new RSAKey();
702 	caKey.readPrivateKeyFromASN1HexString(caKeyHex);  
703 	this.rsaPrvKey = caKey;
704     };
705 
706     /**
707      * sign TBSCertList and set signature value internally
708      * @name sign
709      * @memberOf KJUR.asn1.x509.CRL
710      * @function
711      * @description
712      * @example
713      * var cert = new KJUR.asn1.x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey});
714      * cert.sign();
715      */
716     this.sign = function() {
717 	this.asn1SignatureAlg = this.asn1TBSCertList.asn1SignatureAlg;
718 
719 	sig = new KJUR.crypto.Signature({'alg': 'SHA1withRSA', 'prov': 'cryptojs/jsrsa'});
720 	sig.initSign(this.rsaPrvKey);
721 	sig.updateHex(this.asn1TBSCertList.getEncodedHex());
722 	this.hexSig = sig.sign();
723 
724 	this.asn1Sig = new KJUR.asn1.DERBitString({'hex': '00' + this.hexSig});
725 	
726 	var seq = new KJUR.asn1.DERSequence({'array': [this.asn1TBSCertList,
727 						       this.asn1SignatureAlg,
728 						       this.asn1Sig]});
729 	this.hTLV = seq.getEncodedHex();
730 	this.isModified = false;
731     };
732 
733     this.getEncodedHex = function() {
734 	if (this.isModified == false && this.hTLV != null) return this.hTLV;
735 	throw "not signed yet";
736     };
737 
738     /**
739      * get PEM formatted CRL string after signed
740      * @name getPEMString
741      * @memberOf KJUR.asn1.x509.CRL
742      * @function
743      * @return PEM formatted string of certificate
744      * @description
745      * @example
746      * var cert = new KJUR.asn1.x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey});
747      * cert.sign();
748      * var sPEM =  cert.getPEMString();
749      */
750     this.getPEMString = function() {
751 	var hCert = this.getEncodedHex();
752 	var wCert = CryptoJS.enc.Hex.parse(hCert);
753 	var b64Cert = CryptoJS.enc.Base64.stringify(wCert);
754 	var pemBody = b64Cert.replace(/(.{64})/g, "$1\r\n");
755 	return "-----BEGIN X509 CRL-----\r\n" + pemBody + "\r\n-----END X509 CRL-----\r\n";
756     };
757 
758     if (typeof params != "undefined") {
759 	if (typeof params['tbsobj'] != "undefined") {
760 	    this.asn1TBSCertList = params['tbsobj'];
761 	}
762 	if (typeof params['rsaprvkey'] != "undefined") {
763 	    this.rsaPrvKey = params['rsaprvkey'];
764 	}
765 	if ((typeof params['rsaprvpem'] != "undefined") &&
766 	    (typeof params['rsaprvpas'] != "undefined")) {
767 	    this.setRsaPrvKeyByPEMandPass(params['rsaprvpem'], params['rsaprvpas']);
768 	}
769     }
770 };
771 YAHOO.lang.extend(KJUR.asn1.x509.CRL, KJUR.asn1.ASN1Object);
772 
773 /**
774  * ASN.1 TBSCertList structure class for CRL
775  * @name KJUR.asn1.x509.TBSCertList
776  * @class ASN.1 TBSCertList structure class for CRL
777  * @param {Array} params associative array of parameters (ex. {})
778  * @extends KJUR.asn1.ASN1Object
779  * @since 1.0.3
780  * @description
781  * <br/>
782  * <h4>EXAMPLE</h4>
783  * @example
784  *  var o = new KJUR.asn1.x509.TBSCertList();
785  *  o.setSignatureAlgByParam({'name': 'SHA1withRSA'});
786  *  o.setIssuerByParam({'str': '/C=US/O=a'});
787  *  o.setNotThisUpdateByParam({'str': '130504235959Z'});
788  *  o.setNotNextUpdateByParam({'str': '140504235959Z'});
789  *  o.addRevokedCert({'int': 4}, {'str':'130514235959Z'}));
790  *  o.addRevokedCert({'hex': '0f34dd'}, {'str':'130514235959Z'}));
791  * 
792  * // TBSCertList  ::=  SEQUENCE  {
793  * //        version                 Version OPTIONAL,
794  * //                                     -- if present, MUST be v2
795  * //        signature               AlgorithmIdentifier,
796  * //        issuer                  Name,
797  * //        thisUpdate              Time,
798  * //        nextUpdate              Time OPTIONAL,
799  * //        revokedCertificates     SEQUENCE OF SEQUENCE  {
800  * //             userCertificate         CertificateSerialNumber,
801  * //             revocationDate          Time,
802  * //             crlEntryExtensions      Extensions OPTIONAL
803  * //                                      -- if present, version MUST be v2
804  * //                                  }  OPTIONAL,
805  * //        crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
806  */
807 KJUR.asn1.x509.TBSCertList = function(params) {
808     KJUR.asn1.x509.TBSCertList.superclass.constructor.call(this);
809     var aRevokedCert = null;
810 
811     /**
812      * set signature algorithm field by parameter
813      * @name setSignatureAlgByParam
814      * @memberOf KJUR.asn1.x509.TBSCertList
815      * @function
816      * @param {Array} algIdParam AlgorithmIdentifier parameter
817      * @description
818      * @example
819      * tbsc.setSignatureAlgByParam({'name': 'SHA1withRSA'});
820      */
821     this.setSignatureAlgByParam = function(algIdParam) {
822 	this.asn1SignatureAlg = new KJUR.asn1.x509.AlgorithmIdentifier(algIdParam);
823     };
824 
825     /**
826      * set issuer name field by parameter
827      * @name setIssuerByParam
828      * @memberOf KJUR.asn1.x509.TBSCertList
829      * @function
830      * @param {Array} x500NameParam X500Name parameter
831      * @description
832      * @example
833      * tbsc.setIssuerParam({'str': '/C=US/CN=b'});
834      * @see KJUR.asn1.x509.X500Name
835      */
836     this.setIssuerByParam = function(x500NameParam) {
837 	this.asn1Issuer = new KJUR.asn1.x509.X500Name(x500NameParam);
838     };
839 
840     /**
841      * set thisUpdate field by parameter
842      * @name setThisUpdateByParam
843      * @memberOf KJUR.asn1.x509.TBSCertList
844      * @function
845      * @param {Array} timeParam Time parameter
846      * @description
847      * @example
848      * tbsc.setThisUpdateByParam({'str': '130508235959Z'});
849      * @see KJUR.asn1.x509.Time
850      */
851     this.setThisUpdateByParam = function(timeParam) {
852 	this.asn1ThisUpdate = new KJUR.asn1.x509.Time(timeParam);
853     };
854 
855     /**
856      * set nextUpdate field by parameter
857      * @name setNextUpdateByParam
858      * @memberOf KJUR.asn1.x509.TBSCertList
859      * @function
860      * @param {Array} timeParam Time parameter
861      * @description
862      * @example
863      * tbsc.setNextUpdateByParam({'str': '130508235959Z'});
864      * @see KJUR.asn1.x509.Time
865      */
866     this.setNextUpdateByParam = function(timeParam) {
867 	this.asn1NextUpdate = new KJUR.asn1.x509.Time(timeParam);
868     };
869 
870     /**
871      * add revoked certficate by parameter
872      * @name addRevokedCert
873      * @memberOf KJUR.asn1.x509.TBSCertList
874      * @function
875      * @param {Array} snParam DERInteger parameter for certificate serial number
876      * @param {Array} timeParam Time parameter for revocation date
877      * @description
878      * @example
879      * tbsc.addRevokedCert({'int': 3}, {'str': '130508235959Z'});
880      * @see KJUR.asn1.x509.Time
881      */
882     this.addRevokedCert = function(snParam, timeParam) {
883 	var param = {};
884 	if (snParam != undefined && snParam != null) param['sn'] = snParam;
885 	if (timeParam != undefined && timeParam != null) param['time'] = timeParam;
886 	var o = new KJUR.asn1.x509.CRLEntry(param);
887 	this.aRevokedCert.push(o);
888     };
889 
890     this.getEncodedHex = function() {
891 	this.asn1Array = new Array();
892 
893 	if (this.asn1Version != null) this.asn1Array.push(this.asn1Version);
894 	this.asn1Array.push(this.asn1SignatureAlg);
895 	this.asn1Array.push(this.asn1Issuer);
896 	this.asn1Array.push(this.asn1ThisUpdate);
897 	if (this.asn1NextUpdate != null) this.asn1Array.push(this.asn1NextUpdate);
898 
899 	if (this.aRevokedCert.length > 0) {
900 	    var seq = new KJUR.asn1.DERSequence({'array': this.aRevokedCert});
901 	    this.asn1Array.push(seq);
902 	}
903 
904 	var o = new KJUR.asn1.DERSequence({"array": this.asn1Array});
905 	this.hTLV = o.getEncodedHex();
906 	this.isModified = false;
907 	return this.hTLV;
908     };
909 
910     this._initialize = function() {
911 	this.asn1Version = null;
912 	this.asn1SignatureAlg = null;
913 	this.asn1Issuer = null;
914 	this.asn1ThisUpdate = null;
915 	this.asn1NextUpdate = null;
916 	this.aRevokedCert = new Array();
917     };
918 
919     this._initialize();
920 };
921 YAHOO.lang.extend(KJUR.asn1.x509.TBSCertList, KJUR.asn1.ASN1Object);
922 
923 /**
924  * ASN.1 CRLEntry structure class for CRL
925  * @name KJUR.asn1.x509.CRLEntry
926  * @class ASN.1 CRLEntry structure class for CRL
927  * @param {Array} params associative array of parameters (ex. {})
928  * @extends KJUR.asn1.ASN1Object
929  * @since 1.0.3
930  * @description
931  * @example
932  * var e = new KJUR.asn1.x509.CRLEntry({'time': {'str': '130514235959Z'}, 'sn': {'int': 234}});
933  * 
934  * // revokedCertificates     SEQUENCE OF SEQUENCE  {
935  * //     userCertificate         CertificateSerialNumber,
936  * //     revocationDate          Time,
937  * //     crlEntryExtensions      Extensions OPTIONAL
938  * //                             -- if present, version MUST be v2 }
939  */
940 KJUR.asn1.x509.CRLEntry = function(params) {
941     KJUR.asn1.x509.CRLEntry.superclass.constructor.call(this);
942     var sn = null;
943     var time = null;
944 
945     /**
946      * set DERInteger parameter for serial number of revoked certificate 
947      * @name setCertSerial
948      * @memberOf KJUR.asn1.x509.CRLEntry
949      * @function
950      * @param {Array} intParam DERInteger parameter for certificate serial number
951      * @description
952      * @example
953      * entry.setCertSerial({'int': 3});
954      */
955     this.setCertSerial = function(intParam) {
956 	this.sn = new KJUR.asn1.DERInteger(intParam);
957     };
958 
959     /**
960      * set Time parameter for revocation date
961      * @name setRevocationDate
962      * @memberOf KJUR.asn1.x509.CRLEntry
963      * @function
964      * @param {Array} timeParam Time parameter for revocation date
965      * @description
966      * @example
967      * entry.setRevocationDate({'str': '130508235959Z'});
968      */
969     this.setRevocationDate = function(timeParam) {
970 	this.time = new KJUR.asn1.x509.Time(timeParam);
971     };
972 
973     this.getEncodedHex = function() {
974 	var o = new KJUR.asn1.DERSequence({"array": [this.sn, this.time]});
975 	this.TLV = o.getEncodedHex();
976 	return this.TLV;
977     };
978     
979     if (typeof params != "undefined") {
980 	if (typeof params['time'] != "undefined") {
981 	    this.setRevocationDate(params['time']);
982 	}
983 	if (typeof params['sn'] != "undefined") {
984 	    this.setCertSerial(params['sn']);
985 	}
986     }
987 };
988 YAHOO.lang.extend(KJUR.asn1.x509.CRLEntry, KJUR.asn1.ASN1Object);
989 
990 // === END   CRL Related ===================================================
991 
992 // === BEGIN X500Name Related =================================================
993 /**
994  * X500Name ASN.1 structure class
995  * @name KJUR.asn1.x509.X500Name
996  * @class X500Name ASN.1 structure class
997  * @param {Array} params associative array of parameters (ex. {'str': '/C=US/O=a'})
998  * @extends KJUR.asn1.ASN1Object
999  * @description
1000  * @example
1001  */
1002 KJUR.asn1.x509.X500Name = function(params) {
1003     KJUR.asn1.x509.X500Name.superclass.constructor.call(this);
1004     this.asn1Array = new Array();
1005 
1006     this.setByString = function(dnStr) {
1007 	var a = dnStr.split('/');
1008 	a.shift();
1009 	for (var i = 0; i < a.length; i++) {
1010 	    this.asn1Array.push(new KJUR.asn1.x509.RDN({'str':a[i]}));
1011 	}
1012     };
1013 
1014     this.getEncodedHex = function() {
1015 	var o = new KJUR.asn1.DERSequence({"array": this.asn1Array});
1016 	this.TLV = o.getEncodedHex();
1017 	return this.TLV;
1018     };
1019 
1020     if (typeof params != "undefined") {
1021 	if (typeof params['str'] != "undefined") {
1022 	    this.setByString(params['str']);
1023 	}
1024     }
1025 
1026 };
1027 YAHOO.lang.extend(KJUR.asn1.x509.X500Name, KJUR.asn1.ASN1Object);
1028 
1029 /**
1030  * RDN (Relative Distinguish Name) ASN.1 structure class
1031  * @name KJUR.asn1.x509.RDN
1032  * @class RDN (Relative Distinguish Name) ASN.1 structure class
1033  * @param {Array} params associative array of parameters (ex. {'str': 'C=US'})
1034  * @extends KJUR.asn1.ASN1Object
1035  * @description
1036  * @example
1037  */
1038 KJUR.asn1.x509.RDN = function(params) {
1039     KJUR.asn1.x509.RDN.superclass.constructor.call(this);
1040     this.asn1Array = new Array();
1041 
1042     this.addByString = function(rdnStr) {
1043 	this.asn1Array.push(new KJUR.asn1.x509.AttributeTypeAndValue({'str':rdnStr}));
1044     };
1045 
1046     this.getEncodedHex = function() {
1047 	var o = new KJUR.asn1.DERSet({"array": this.asn1Array});
1048 	this.TLV = o.getEncodedHex();
1049 	return this.TLV;
1050     };
1051 
1052     if (typeof params != "undefined") {
1053 	if (typeof params['str'] != "undefined") {
1054 	    this.addByString(params['str']);
1055 	}
1056     }
1057 };
1058 YAHOO.lang.extend(KJUR.asn1.x509.RDN, KJUR.asn1.ASN1Object);
1059 
1060 /**
1061  * AttributeTypeAndValue ASN.1 structure class
1062  * @name KJUR.asn1.x509.AttributeTypeAndValue
1063  * @class AttributeTypeAndValue ASN.1 structure class
1064  * @param {Array} params associative array of parameters (ex. {'str': 'C=US'})
1065  * @extends KJUR.asn1.ASN1Object
1066  * @description
1067  * @example
1068  */
1069 KJUR.asn1.x509.AttributeTypeAndValue = function(params) {
1070     KJUR.asn1.x509.AttributeTypeAndValue.superclass.constructor.call(this);
1071     var typeObj = null;
1072     var valueObj = null;
1073     var defaultDSType = "utf8";
1074 
1075     this.setByString = function(attrTypeAndValueStr) {
1076 	if (attrTypeAndValueStr.match(/^([^=]+)=(.+)$/)) {
1077 	    this.setByAttrTypeAndValueStr(RegExp.$1, RegExp.$2);
1078 	} else {
1079 	    throw "malformed attrTypeAndValueStr: " + attrTypeAndValueStr;
1080 	}
1081     };
1082 
1083     this.setByAttrTypeAndValueStr = function(shortAttrType, valueStr) {
1084 	this.typeObj = KJUR.asn1.x509.OID.atype2obj(shortAttrType);
1085 	var dsType = defaultDSType;
1086 	if (shortAttrType == "C") dsType = "prn";
1087 	this.valueObj = this.getValueObj(dsType, valueStr);
1088     };
1089 
1090     this.getValueObj = function(dsType, valueStr) {
1091 	if (dsType == "utf8")	return new KJUR.asn1.DERUTF8String({"str": valueStr});
1092 	if (dsType == "prn")	return new KJUR.asn1.DERPrintableString({"str": valueStr});
1093 	if (dsType == "tel")	return new KJUR.asn1.DERTeletexString({"str": valueStr});
1094 	if (dsType == "ia5")	return new KJUR.asn1.DERIA5String({"str": valueStr});
1095 	throw "unsupported directory string type: type=" + dsType + " value=" + valueStr;
1096     };
1097 
1098     this.getEncodedHex = function() {
1099 	var o = new KJUR.asn1.DERSequence({"array": [this.typeObj, this.valueObj]});
1100 	this.TLV = o.getEncodedHex();
1101 	return this.TLV;
1102     };
1103 
1104     if (typeof params != "undefined") {
1105 	if (typeof params['str'] != "undefined") {
1106 	    this.setByString(params['str']);
1107 	}
1108     }
1109 };
1110 YAHOO.lang.extend(KJUR.asn1.x509.AttributeTypeAndValue, KJUR.asn1.ASN1Object);
1111 
1112 // === END   X500Name Related =================================================
1113 
1114 // === BEGIN Other ASN1 structure class  ======================================
1115 
1116 /**
1117  * SubjectPublicKeyInfo ASN.1 structure class
1118  * @name KJUR.asn1.x509.SubjectPublicKeyInfo
1119  * @class SubjectPublicKeyInfo ASN.1 structure class
1120  * @param {Object} params parameter for subject public key
1121  * @extends KJUR.asn1.ASN1Object
1122  * @description
1123  * <br/>
1124  * As for argument 'params' for constructor, you can specify one of
1125  * following properties:
1126  * <ul>
1127  * <li>{@link RSAKey} object</li>
1128  * <li>{@link KJUR.crypto.ECDSA} object</li>
1129  * <li>{@link KJUR.crypto.DSA} object</li>
1130  * <li>(DEPRECATED)rsakey - specify {@link RSAKey} object of subject public key</li>
1131  * <li>(DEPRECATED)rsapem - specify a string of PEM public key of RSA key</li>
1132  * </ul>
1133  * NOTE1: 'params' can be omitted.<br/>
1134  * NOTE2: DSA/ECDSA key object is also supported since asn1x509 1.0.6.<br/>
1135  * <h4>EXAMPLE</h4>
1136  * @example
1137  * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(RSAKey_object);
1138  * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoECDSA_object);
1139  * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoDSA_object);
1140  */
1141 KJUR.asn1.x509.SubjectPublicKeyInfo = function(params) {
1142     KJUR.asn1.x509.SubjectPublicKeyInfo.superclass.constructor.call(this);
1143     var asn1AlgId = null;
1144     var asn1SubjPKey = null;
1145     var rsaKey = null;
1146 
1147     /**
1148      * (DEPRECATED) set RSAKey object as subject public key
1149      * @name setRSAKey
1150      * @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo
1151      * @function
1152      * @param {RSAKey} rsaKey {@link RSAKey} object for RSA public key
1153      * @description
1154      * @deprecated
1155      * @example
1156      * spki.setRSAKey(rsaKey);
1157      */
1158     this.setRSAKey = function(rsaKey) {
1159 	if (! RSAKey.prototype.isPrototypeOf(rsaKey))
1160 	    throw "argument is not RSAKey instance";
1161         this.rsaKey = rsaKey;
1162 	var asn1RsaN = new KJUR.asn1.DERInteger({'bigint': rsaKey.n});
1163 	var asn1RsaE = new KJUR.asn1.DERInteger({'int': rsaKey.e});
1164 	var asn1RsaPub = new KJUR.asn1.DERSequence({'array': [asn1RsaN, asn1RsaE]});
1165 	var rsaKeyHex = asn1RsaPub.getEncodedHex();
1166 	this.asn1AlgId = new KJUR.asn1.x509.AlgorithmIdentifier({'name':'rsaEncryption'});
1167 	this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex':'00'+rsaKeyHex});
1168     };
1169 
1170     /**
1171      * (DEPRECATED) set a PEM formatted RSA public key string as RSA public key
1172      * @name setRSAPEM
1173      * @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo
1174      * @function
1175      * @param {String} rsaPubPEM PEM formatted RSA public key string
1176      * @deprecated
1177      * @description
1178      * @example
1179      * spki.setRSAPEM(rsaPubPEM);
1180      */
1181     this.setRSAPEM = function(rsaPubPEM) {
1182 	if (rsaPubPEM.match(/-----BEGIN PUBLIC KEY-----/)) {
1183 	    var s = rsaPubPEM;
1184 	    s = s.replace(/^-----[^-]+-----/, '');
1185 	    s = s.replace(/-----[^-]+-----\s*$/, '');
1186 	    var rsaB64 = s.replace(/\s+/g, '');
1187 	    var rsaWA = CryptoJS.enc.Base64.parse(rsaB64);
1188 	    var rsaP8Hex = CryptoJS.enc.Hex.stringify(rsaWA);
1189 	    var a = _rsapem_getHexValueArrayOfChildrenFromHex(rsaP8Hex);
1190 	    var hBitStrVal = a[1];
1191 	    var rsaHex = hBitStrVal.substr(2);
1192 	    var a3 = _rsapem_getHexValueArrayOfChildrenFromHex(rsaHex);
1193 	    var rsaKey = new RSAKey();
1194 	    rsaKey.setPublic(a3[0], a3[1]);
1195 	    this.setRSAKey(rsaKey);
1196 	} else {
1197 	    throw "key not supported";
1198 	}
1199     };
1200 
1201     /*
1202      * @since asn1x509 1.0.7
1203      */
1204     this.getASN1Object = function() {
1205 	if (this.asn1AlgId == null || this.asn1SubjPKey == null)
1206 	    throw "algId and/or subjPubKey not set";
1207 	var o = new KJUR.asn1.DERSequence({'array':
1208 					   [this.asn1AlgId, this.asn1SubjPKey]});
1209 	return o;
1210     };
1211 
1212     this.getEncodedHex = function() {
1213 	var o = this.getASN1Object();
1214 	this.hTLV = o.getEncodedHex();
1215 	return this.hTLV;
1216     };
1217 
1218     this._setRSAKey = function(key) {
1219 	var asn1RsaPub = KJUR.asn1.ASN1Util.newObject({
1220 		'seq': [{'int': {'bigint': key.n}}, {'int': {'int': key.e}}]
1221 	    });
1222 	var rsaKeyHex = asn1RsaPub.getEncodedHex();
1223 	this.asn1AlgId = new KJUR.asn1.x509.AlgorithmIdentifier({'name':'rsaEncryption'});
1224 	this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex':'00'+rsaKeyHex});
1225     };
1226 
1227     this._setEC = function(key) {
1228 	var asn1Params = new KJUR.asn1.DERObjectIdentifier({'name': key.curveName});
1229 	this.asn1AlgId = 
1230 	    new KJUR.asn1.x509.AlgorithmIdentifier({'name': 'ecPublicKey',
1231 						    'asn1params': asn1Params});
1232 	this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex': '00' + key.pubKeyHex});
1233     };
1234 
1235     this._setDSA = function(key) {
1236 	var asn1Params = new KJUR.asn1.ASN1Util.newObject({
1237 		'seq': [{'int': {'bigint': key.p}},
1238 	                {'int': {'bigint': key.q}},
1239 	                {'int': {'bigint': key.g}}]
1240 	    });
1241 	this.asn1AlgId = 
1242 	    new KJUR.asn1.x509.AlgorithmIdentifier({'name': 'dsa',
1243 						    'asn1params': asn1Params});
1244 	var pubInt = new KJUR.asn1.DERInteger({'bigint': key.y});
1245 	this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex': '00' + pubInt.getEncodedHex()});
1246     };
1247 
1248     if (typeof params != "undefined") {
1249 	if (typeof RSAKey != 'undefined' && params instanceof RSAKey) {
1250 	    this._setRSAKey(params);
1251 	} else if (typeof KJUR.crypto.ECDSA != 'undefined' &&
1252 		   params instanceof KJUR.crypto.ECDSA) {
1253 	    this._setEC(params);
1254 	} else if (typeof KJUR.crypto.DSA != 'undefined' &&
1255 		   params instanceof KJUR.crypto.DSA) {
1256 	    this._setDSA(params);
1257 	} else if (typeof params['rsakey'] != "undefined") {
1258 	    this.setRSAKey(params['rsakey']);
1259 	} else if (typeof params['rsapem'] != "undefined") {
1260 	    this.setRSAPEM(params['rsapem']);
1261 	}
1262     }
1263 };
1264 YAHOO.lang.extend(KJUR.asn1.x509.SubjectPublicKeyInfo, KJUR.asn1.ASN1Object);
1265 
1266 /**
1267  * Time ASN.1 structure class
1268  * @name KJUR.asn1.x509.Time
1269  * @class Time ASN.1 structure class
1270  * @param {Array} params associative array of parameters (ex. {'str': '130508235959Z'})
1271  * @extends KJUR.asn1.ASN1Object
1272  * @description
1273  * <br/>
1274  * <h4>EXAMPLES</h4>
1275  * @example
1276  * var t1 = new KJUR.asn1.x509.Time{'str': '130508235959Z'} // UTCTime by default
1277  * var t2 = new KJUR.asn1.x509.Time{'type': 'gen',  'str': '20130508235959Z'} // GeneralizedTime
1278  */
1279 KJUR.asn1.x509.Time = function(params) {
1280     KJUR.asn1.x509.Time.superclass.constructor.call(this);
1281     var type = null;
1282     var timeParams = null;
1283 
1284     this.setTimeParams = function(timeParams) {
1285 	this.timeParams = timeParams;
1286     }
1287 
1288     this.getEncodedHex = function() {
1289 	if (this.timeParams == null) {
1290 	    throw "timeParams shall be specified. ({'str':'130403235959Z'}}";
1291 	}
1292 	var o = null;
1293 	if (this.type == "utc") {
1294 	    o = new KJUR.asn1.DERUTCTime(this.timeParams);
1295 	} else {
1296 	    o = new KJUR.asn1.DERGeneralizedTime(this.timeParams);
1297 	}
1298 	this.TLV = o.getEncodedHex();
1299 	return this.TLV;
1300     };
1301  
1302     this.type = "utc";
1303     if (typeof params != "undefined") {
1304 	if (typeof params['type'] != "undefined") {
1305 	    this.type = params['type'];
1306 	}
1307 	this.timeParams = params;
1308     }
1309 };
1310 YAHOO.lang.extend(KJUR.asn1.x509.Time, KJUR.asn1.ASN1Object);
1311 
1312 /**
1313  * AlgorithmIdentifier ASN.1 structure class
1314  * @name KJUR.asn1.x509.AlgorithmIdentifier
1315  * @class AlgorithmIdentifier ASN.1 structure class
1316  * @param {Array} params associative array of parameters (ex. {'name': 'SHA1withRSA'})
1317  * @extends KJUR.asn1.ASN1Object
1318  * @description
1319  * @example
1320  */
1321 KJUR.asn1.x509.AlgorithmIdentifier = function(params) {
1322     KJUR.asn1.x509.AlgorithmIdentifier.superclass.constructor.call(this);
1323     var nameAlg = null;
1324     var asn1Alg = null;
1325     var asn1Params = null;
1326     var paramEmpty = false;
1327 
1328     this.getEncodedHex = function() {
1329 	if (this.nameAlg == null && this.asn1Alg == null) {
1330 	    throw "algorithm not specified";
1331 	}
1332 	if (this.nameAlg != null && this.asn1Alg == null) {
1333 	    this.asn1Alg = KJUR.asn1.x509.OID.name2obj(this.nameAlg);
1334 	}
1335 	var a = [this.asn1Alg];
1336 	if (! this.paramEmpty) a.push(this.asn1Params);
1337 	var o = new KJUR.asn1.DERSequence({'array': a});
1338 	this.hTLV = o.getEncodedHex();
1339 	return this.hTLV;
1340     };
1341 
1342     if (typeof params != "undefined") {
1343 	if (typeof params['name'] != "undefined") {
1344 	    this.nameAlg = params['name'];
1345 	}
1346 	if (typeof params['asn1params'] != "undefined") {
1347 	    this.asn1Params = params['asn1params'];
1348 	}
1349 	if (typeof params['paramempty'] != "undefined") {
1350 	    this.paramEmpty = params['paramempty'];
1351 	}
1352     }
1353     if (this.asn1Params == null) {
1354 	this.asn1Params = new KJUR.asn1.DERNull();
1355     }
1356 };
1357 YAHOO.lang.extend(KJUR.asn1.x509.AlgorithmIdentifier, KJUR.asn1.ASN1Object);
1358 
1359 /**
1360  * GeneralName ASN.1 structure class
1361  * @name KJUR.asn1.x509.GeneralName
1362  * @class GeneralName ASN.1 structure class
1363  * @description
1364  * <br/>
1365  * As for argument 'params' for constructor, you can specify one of
1366  * following properties:
1367  * <ul>
1368  * <li>rfc822 - rfc822Name[1] (ex. user1@foo.com)</li>
1369  * <li>dns - dNSName[2] (ex. foo.com)</li>
1370  * <li>uri - uniformResourceIdentifier[6] (ex. http://foo.com/)</li>
1371  * </ul>
1372  * NOTE: Currently this only supports 'uniformResourceIdentifier'.
1373  * <h4>EXAMPLE AND ASN.1 SYNTAX</h4>
1374  * @example
1375  * var gn = new KJUR.asn1.x509.GeneralName({'uri': 'http://aaa.com/'});
1376  *
1377  * GeneralName ::= CHOICE {
1378  *         otherName                       [0]     OtherName,
1379  *         rfc822Name                      [1]     IA5String,
1380  *         dNSName                         [2]     IA5String,
1381  *         x400Address                     [3]     ORAddress,
1382  *         directoryName                   [4]     Name,
1383  *         ediPartyName                    [5]     EDIPartyName,
1384  *         uniformResourceIdentifier       [6]     IA5String,
1385  *         iPAddress                       [7]     OCTET STRING,
1386  *         registeredID                    [8]     OBJECT IDENTIFIER } 
1387  */
1388 KJUR.asn1.x509.GeneralName = function(params) {
1389     KJUR.asn1.x509.GeneralName.superclass.constructor.call(this);
1390     var asn1Obj = null;
1391     var type = null;
1392     var pTag = {'rfc822': '81', 'dns': '82', 'uri': '86'};
1393 
1394     this.setByParam = function(params) {
1395 	var str = null;
1396 	var v = null;
1397 
1398 	if (typeof params['rfc822'] != "undefined") {
1399 	    this.type = 'rfc822';
1400 	    v = new KJUR.asn1.DERIA5String({'str': params[this.type]});
1401 	}
1402 	if (typeof params['dns'] != "undefined") {
1403 	    this.type = 'dns';
1404 	    v = new KJUR.asn1.DERIA5String({'str': params[this.type]});
1405 	}
1406 	if (typeof params['uri'] != "undefined") {
1407 	    this.type = 'uri';
1408 	    v = new KJUR.asn1.DERIA5String({'str': params[this.type]});
1409 	}
1410 
1411 	if (this.type == null)
1412 	    throw "unsupported type in params=" + params;
1413         this.asn1Obj = new KJUR.asn1.DERTaggedObject({'explicit': false,
1414 						      'tag': pTag[this.type],
1415 						      'obj': v});
1416     };
1417 
1418     this.getEncodedHex = function() {
1419 	return this.asn1Obj.getEncodedHex();
1420     }
1421 
1422     if (typeof params != "undefined") {
1423 	this.setByParam(params);
1424     }
1425 
1426 };
1427 YAHOO.lang.extend(KJUR.asn1.x509.GeneralName, KJUR.asn1.ASN1Object);
1428 
1429 /**
1430  * GeneralNames ASN.1 structure class
1431  * @name KJUR.asn1.x509.GeneralNames
1432  * @class GeneralNames ASN.1 structure class
1433  * @description
1434  * <br/>
1435  * <h4>EXAMPLE AND ASN.1 SYNTAX</h4>
1436  * @example
1437  * var gns = new KJUR.asn1.x509.GeneralNames([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]); 
1438  *
1439  * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
1440  */
1441 KJUR.asn1.x509.GeneralNames = function(paramsArray) {
1442     KJUR.asn1.x509.GeneralNames.superclass.constructor.call(this);
1443     var asn1Array = null;
1444 
1445     /**
1446      * set a array of {@link KJUR.asn1.x509.GeneralName} parameters
1447      * @name setByParamArray
1448      * @memberOf KJUR.asn1.x509.GeneralNames
1449      * @function
1450      * @param {Array} paramsArray Array of {@link KJUR.asn1.x509.GeneralNames}
1451      * @description
1452      * <br/>
1453      * <h4>EXAMPLES</h4>
1454      * @example
1455      * var gns = new KJUR.asn1.x509.GeneralNames();
1456      * gns.setByParamArray([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]);
1457      */
1458     this.setByParamArray = function(paramsArray) {
1459 	for (var i = 0; i < paramsArray.length; i++) {
1460 	    var o = new KJUR.asn1.x509.GeneralName(paramsArray[i]);
1461 	    this.asn1Array.push(o);
1462 	}
1463     };
1464 
1465     this.getEncodedHex = function() {
1466 	var o = new KJUR.asn1.DERSequence({'array': this.asn1Array});
1467 	return o.getEncodedHex();
1468     };
1469 
1470     this.asn1Array = new Array();
1471     if (typeof paramsArray != "undefined") {
1472 	this.setByParamArray(paramsArray);
1473     }
1474 };
1475 YAHOO.lang.extend(KJUR.asn1.x509.GeneralNames, KJUR.asn1.ASN1Object);
1476 
1477 /**
1478  * DistributionPointName ASN.1 structure class
1479  * @name KJUR.asn1.x509.DistributionPointName
1480  * @class DistributionPointName ASN.1 structure class
1481  * @description
1482  * @example
1483  */
1484 KJUR.asn1.x509.DistributionPointName = function(gnOrRdn) {
1485     KJUR.asn1.x509.DistributionPointName.superclass.constructor.call(this);
1486     var asn1Obj = null;
1487     var type = null;
1488     var tag = null;
1489     var asn1V = null;
1490 
1491     this.getEncodedHex = function() {
1492 	if (this.type != "full")
1493 	    throw "currently type shall be 'full': " + this.type;
1494 	this.asn1Obj = new KJUR.asn1.DERTaggedObject({'explicit': false,
1495 						      'tag': this.tag,
1496 						      'obj': this.asn1V});
1497 	this.hTLV = this.asn1Obj.getEncodedHex();
1498 	return this.hTLV;
1499     };
1500 
1501     if (typeof gnOrRdn != "undefined") {
1502 	if (KJUR.asn1.x509.GeneralNames.prototype.isPrototypeOf(gnOrRdn)) {
1503 	    this.type = "full";
1504 	    this.tag = "a0";
1505 	    this.asn1V = gnOrRdn;
1506 	} else {
1507 	    throw "This class supports GeneralNames only as argument";
1508 	}
1509     }
1510 };
1511 YAHOO.lang.extend(KJUR.asn1.x509.DistributionPointName, KJUR.asn1.ASN1Object);
1512 
1513 /**
1514  * DistributionPoint ASN.1 structure class
1515  * @name KJUR.asn1.x509.DistributionPoint
1516  * @class DistributionPoint ASN.1 structure class
1517  * @description
1518  * @example
1519  */
1520 KJUR.asn1.x509.DistributionPoint = function(params) {
1521     KJUR.asn1.x509.DistributionPoint.superclass.constructor.call(this);
1522     var asn1DP = null;
1523 
1524     this.getEncodedHex = function() {
1525 	var seq = new KJUR.asn1.DERSequence();
1526 	if (this.asn1DP != null) {
1527 	    var o1 = new KJUR.asn1.DERTaggedObject({'explicit': true,
1528 						    'tag': 'a0',
1529 						    'obj': this.asn1DP});
1530 	    seq.appendASN1Object(o1);
1531 	}
1532 	this.hTLV = seq.getEncodedHex();
1533 	return this.hTLV;
1534     };
1535 
1536     if (typeof params != "undefined") {
1537 	if (typeof params['dpobj'] != "undefined") {
1538 	    this.asn1DP = params['dpobj'];
1539 	}
1540     }
1541 };
1542 YAHOO.lang.extend(KJUR.asn1.x509.DistributionPoint, KJUR.asn1.ASN1Object);
1543 
1544 /**
1545  * static object for OID
1546  * @name KJUR.asn1.x509.OID
1547  * @class static object for OID
1548  * @property {Assoc Array} atype2oidList for short attribyte type name and oid (i.e. 'C' and '2.5.4.6')
1549  * @property {Assoc Array} name2oidList for oid name and oid (i.e. 'keyUsage' and '2.5.29.15')
1550  * @property {Assoc Array} objCache for caching name and DERObjectIdentifier object 
1551  * @description
1552  * <dl>
1553  * <dt><b>atype2oidList</b>
1554  * <dd>currently supports 'C', 'O', 'OU', 'ST', 'L' and 'CN' only.
1555  * <dt><b>name2oidList</b>
1556  * <dd>currently supports 'SHA1withRSA', 'rsaEncryption' and some extension OIDs
1557  * </dl>
1558  * @example
1559  */
1560 KJUR.asn1.x509.OID = new function(params) {
1561     this.atype2oidList = {
1562 	'C':	'2.5.4.6',
1563 	'O':	'2.5.4.10',
1564 	'OU':	'2.5.4.11',
1565 	'ST':	'2.5.4.8',
1566 	'L':	'2.5.4.7',
1567 	'CN':	'2.5.4.3',
1568     };
1569     this.name2oidList = {
1570 	'sha384':			'2.16.840.1.101.3.4.2.2',
1571 	'sha224':			'2.16.840.1.101.3.4.2.4',
1572 
1573 	'MD2withRSA':			'1.2.840.113549.1.1.2',
1574 	'MD4withRSA':			'1.2.840.113549.1.1.3',
1575 	'MD5withRSA':			'1.2.840.113549.1.1.4',
1576 	'SHA1withRSA':			'1.2.840.113549.1.1.5',
1577 	'SHA224withRSA':		'1.2.840.113549.1.1.14',
1578 	'SHA256withRSA':		'1.2.840.113549.1.1.11',
1579 	'SHA384withRSA':		'1.2.840.113549.1.1.12',
1580 	'SHA512withRSA':		'1.2.840.113549.1.1.13',
1581 
1582 	'SHA1withECDSA':		'1.2.840.10045.4.1',
1583 	'SHA224withECDSA':		'1.2.840.10045.4.3.1',
1584 	'SHA256withECDSA':		'1.2.840.10045.4.3.2',
1585 	'SHA384withECDSA':		'1.2.840.10045.4.3.3',
1586 	'SHA512withECDSA':		'1.2.840.10045.4.3.4',
1587 
1588 	'dsa':				'1.2.840.10040.4.1',
1589 	'SHA1withDSA':			'1.2.840.10040.4.3',
1590 	'SHA224withDSA':		'2.16.840.1.101.3.4.3.1',
1591 	'SHA256withDSA':		'2.16.840.1.101.3.4.3.2',
1592 
1593         'rsaEncryption':		'1.2.840.113549.1.1.1',
1594 	'subjectKeyIdentifier':		'2.5.29.14',
1595 
1596 	'countryName':			'2.5.4.6',
1597 	'organization':			'2.5.4.10',
1598 	'organizationalUnit':		'2.5.4.11',
1599 	'stateOrProvinceName':		'2.5.4.8',
1600 	'locality':			'2.5.4.7',
1601 	'commonName':			'2.5.4.3',
1602 
1603 	'keyUsage':			'2.5.29.15',
1604 	'basicConstraints':		'2.5.29.19',
1605 	'cRLDistributionPoints':	'2.5.29.31',
1606 	'certificatePolicies':		'2.5.29.32',
1607 	'authorityKeyIdentifier':	'2.5.29.35',
1608 	'extKeyUsage':			'2.5.29.37',
1609 
1610 	'anyExtendedKeyUsage':		'2.5.29.37.0',
1611 	'serverAuth':			'1.3.6.1.5.5.7.3.1',
1612 	'clientAuth':			'1.3.6.1.5.5.7.3.2',
1613 	'codeSigning':			'1.3.6.1.5.5.7.3.3',
1614 	'emailProtection':		'1.3.6.1.5.5.7.3.4',
1615 	'timeStamping':			'1.3.6.1.5.5.7.3.8',
1616 	'ocspSigning':			'1.3.6.1.5.5.7.3.9',
1617 
1618 	'ecPublicKey':			'1.2.840.10045.2.1',
1619 	'secp256r1':			'1.2.840.10045.3.1.7',
1620 	'secp256k1':			'1.3.132.0.10',
1621 	'secp384r1':			'1.3.132.0.34',
1622 
1623 	'pkcs5PBES2':			'1.2.840.113549.1.5.13',
1624 	'pkcs5PBKDF2':			'1.2.840.113549.1.5.12',
1625 
1626 	'des-EDE3-CBC':			'1.2.840.113549.3.7',
1627     };
1628 
1629     this.objCache = {};
1630 
1631     /**
1632      * get DERObjectIdentifier by registered OID name
1633      * @name name2obj
1634      * @memberOf KJUR.asn1.x509.OID
1635      * @function
1636      * @param {String} name OID
1637      * @description
1638      * @example
1639      * var asn1ObjOID = OID.name2obj('SHA1withRSA');
1640      */
1641     this.name2obj = function(name) {
1642 	if (typeof this.objCache[name] != "undefined")
1643 	    return this.objCache[name];
1644 	if (typeof this.name2oidList[name] == "undefined")
1645 	    throw "Name of ObjectIdentifier not defined: " + name;
1646 	var oid = this.name2oidList[name];
1647 	var obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid});
1648 	this.objCache[name] = obj;
1649 	return obj;
1650     };
1651 
1652     /**
1653      * get DERObjectIdentifier by registered attribyte type name such like 'C' or 'CN'
1654      * @name atype2obj
1655      * @memberOf KJUR.asn1.x509.OID
1656      * @function
1657      * @param {String} atype short attribute type name such like 'C' or 'CN'
1658      * @description
1659      * @example
1660      * var asn1ObjOID = OID.atype2obj('CN');
1661      */
1662     this.atype2obj = function(atype) {
1663 	if (typeof this.objCache[atype] != "undefined")
1664 	    return this.objCache[atype];
1665 	if (typeof this.atype2oidList[atype] == "undefined")
1666 	    throw "AttributeType name undefined: " + atype;
1667 	var oid = this.atype2oidList[atype];
1668 	var obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid});
1669 	this.objCache[atype] = obj;
1670 	return obj;
1671     };
1672 };
1673 
1674 /**
1675  * X.509 certificate and CRL utilities class
1676  * @name KJUR.asn1.x509.X509Util
1677  * @class X.509 certificate and CRL utilities class
1678  */
1679 KJUR.asn1.x509.X509Util = new function() {
1680     /**
1681      * get PKCS#8 PEM public key string from RSAKey object
1682      * @name getPKCS8PubKeyPEMfromRSAKey
1683      * @memberOf KJUR.asn1.x509.X509Util
1684      * @function
1685      * @param {RSAKey} rsaKey RSA public key of {@link RSAKey} object
1686      * @description
1687      * @example
1688      * var pem = KJUR.asn1.x509.X509Util.getPKCS8PubKeyPEMfromRSAKey(pubKey);
1689      */
1690    this.getPKCS8PubKeyPEMfromRSAKey = function(rsaKey) {
1691        var pem = null;
1692        var hN = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(rsaKey.n);
1693        var hE = KJUR.asn1.ASN1Util.integerToByteHex(rsaKey.e);
1694        var iN = new KJUR.asn1.DERInteger({hex: hN});
1695        var iE = new KJUR.asn1.DERInteger({hex: hE});
1696        var asn1PubKey = new KJUR.asn1.DERSequence({array: [iN, iE]});
1697        var hPubKey = asn1PubKey.getEncodedHex();
1698        var o1 = new KJUR.asn1.x509.AlgorithmIdentifier({name: 'rsaEncryption'});
1699        var o2 = new KJUR.asn1.DERBitString({hex: '00' + hPubKey});
1700        var seq = new KJUR.asn1.DERSequence({array: [o1, o2]});
1701        var hP8 = seq.getEncodedHex();
1702        var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(hP8, "PUBLIC KEY");
1703        return pem;
1704    };
1705 };
1706 /**
1707  * issue a certificate in PEM format
1708  * @name newCertPEM
1709  * @memberOf KJUR.asn1.x509.X509Util
1710  * @function
1711  * @param {Array} param parameter to issue a certificate
1712  * @since asn1x509 1.0.6
1713  * @description
1714  * This method can issue a certificate by a simple
1715  * JSON object.
1716  * NOTE: When using DSA or ECDSA CA signing key,
1717  * use 'paramempty' in 'sigalg' to ommit parameter field
1718  * of AlgorithmIdentifer. In case of RSA, parameter
1719  * NULL will be specified by default.
1720  * @example
1721  * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM(
1722  * { serial: {int: 4},
1723  *   sigalg: {name: 'SHA1withECDSA', paramempty: true},
1724  *   issuer: {str: '/C=US/O=a'},
1725  *   notbefore: {'str': '130504235959Z'},
1726  *   notafter: {'str': '140504235959Z'},
1727  *   subject: {str: '/C=US/O=b'},
1728  *   sbjpubkey: pubKeyPEM,
1729  *   ext: [
1730  *     {basicConstraints: {cA: true, critical: true}},
1731  *     {keyUsage: {bin: '11'}},
1732  *   ],
1733  *   cakey: [prvkey, pass]}
1734  * );
1735  */
1736 KJUR.asn1.x509.X509Util.newCertPEM = function(param) {
1737     var ns1 = KJUR.asn1.x509;
1738     var o = new ns1.TBSCertificate();
1739 
1740     if (param.serial !== undefined)
1741 	o.setSerialNumberByParam(param.serial);
1742     else
1743 	throw "serial number undefined.";
1744 
1745     if (typeof param.sigalg.name == 'string')
1746 	o.setSignatureAlgByParam(param.sigalg);
1747     else 
1748 	throw "unproper signature algorithm name";
1749 
1750     if (param.issuer !== undefined)
1751 	o.setIssuerByParam(param.issuer);
1752     else
1753 	throw "issuer name undefined.";
1754     
1755     if (param.notbefore !== undefined)
1756 	o.setNotBeforeByParam(param.notbefore);
1757     else
1758 	throw "notbefore undefined.";
1759 
1760     if (param.notafter !== undefined)
1761 	o.setNotAfterByParam(param.notafter);
1762     else
1763 	throw "notafter undefined.";
1764 
1765     if (param.subject !== undefined)
1766 	o.setSubjectByParam(param.subject);
1767     else
1768 	throw "subject name undefined.";
1769 
1770     if (param.sbjpubkey !== undefined)
1771 	o.setSubjectPublicKeyByGetKey(param.sbjpubkey);
1772     else
1773 	throw "subject public key undefined.";
1774 
1775     if (param.ext.length !== undefined) {
1776 	for (var i = 0; i < param.ext.length; i++) {
1777 	    for (key in param.ext[i]) {
1778 		o.appendExtensionByName(key, param.ext[i][key]);
1779 	    }
1780 	}
1781     }
1782 
1783     var caKey = null;
1784     if (param.cakey)
1785 	caKey = KEYUTIL.getKey.apply(null, param.cakey);
1786     else
1787 	throw "ca key undefined";
1788 
1789     var cert = new ns1.Certificate({'tbscertobj': o, 'prvkeyobj': caKey});
1790     cert.sign();
1791     return cert.getPEMString();
1792 };
1793 
1794 /*
1795 org.bouncycastle.asn1.x500
1796 AttributeTypeAndValue
1797 DirectoryString
1798 RDN
1799 X500Name
1800 X500NameBuilder
1801 
1802 org.bouncycastleasn1.x509
1803 TBSCertificate
1804  */
1805