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