1 /*! asn1x509-1.0.9.js (c) 2013-2014 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-2014 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.9 (2014-May-17)
 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  */
1138 KJUR.asn1.x509.X500Name = function(params) {
1139     KJUR.asn1.x509.X500Name.superclass.constructor.call(this);
1140     this.asn1Array = new Array();
1141 
1142     this.setByString = function(dnStr) {
1143         var a = dnStr.split('/');
1144         a.shift();
1145         for (var i = 0; i < a.length; i++) {
1146             this.asn1Array.push(new KJUR.asn1.x509.RDN({'str':a[i]}));
1147         }
1148     };
1149 
1150     this.getEncodedHex = function() {
1151         if (typeof this.hTLV == "string") return this.hTLV;
1152         var o = new KJUR.asn1.DERSequence({"array": this.asn1Array});
1153         this.hTLV = o.getEncodedHex();
1154         return this.hTLV;
1155     };
1156 
1157     if (typeof params != "undefined") {
1158         if (typeof params['str'] != "undefined") {
1159             this.setByString(params['str']);
1160         }
1161         if (typeof params.certissuer != "undefined") {
1162             var x = new X509();
1163             x.hex = X509.pemToHex(params.certissuer);
1164             this.hTLV = x.getIssuerHex();
1165         }
1166         if (typeof params.certsubject != "undefined") {
1167             var x = new X509();
1168             x.hex = X509.pemToHex(params.certsubject);
1169             this.hTLV = x.getSubjectHex();
1170         }
1171     }
1172 };
1173 YAHOO.lang.extend(KJUR.asn1.x509.X500Name, KJUR.asn1.ASN1Object);
1174 
1175 /**
1176  * RDN (Relative Distinguish Name) ASN.1 structure class
1177  * @name KJUR.asn1.x509.RDN
1178  * @class RDN (Relative Distinguish Name) ASN.1 structure class
1179  * @param {Array} params associative array of parameters (ex. {'str': 'C=US'})
1180  * @extends KJUR.asn1.ASN1Object
1181  * @description
1182  * @example
1183  */
1184 KJUR.asn1.x509.RDN = function(params) {
1185     KJUR.asn1.x509.RDN.superclass.constructor.call(this);
1186     this.asn1Array = new Array();
1187 
1188     this.addByString = function(rdnStr) {
1189         this.asn1Array.push(new KJUR.asn1.x509.AttributeTypeAndValue({'str':rdnStr}));
1190     };
1191 
1192     this.getEncodedHex = function() {
1193         var o = new KJUR.asn1.DERSet({"array": this.asn1Array});
1194         this.TLV = o.getEncodedHex();
1195         return this.TLV;
1196     };
1197 
1198     if (typeof params != "undefined") {
1199         if (typeof params['str'] != "undefined") {
1200             this.addByString(params['str']);
1201         }
1202     }
1203 };
1204 YAHOO.lang.extend(KJUR.asn1.x509.RDN, KJUR.asn1.ASN1Object);
1205 
1206 /**
1207  * AttributeTypeAndValue ASN.1 structure class
1208  * @name KJUR.asn1.x509.AttributeTypeAndValue
1209  * @class AttributeTypeAndValue ASN.1 structure class
1210  * @param {Array} params associative array of parameters (ex. {'str': 'C=US'})
1211  * @extends KJUR.asn1.ASN1Object
1212  * @description
1213  * @example
1214  */
1215 KJUR.asn1.x509.AttributeTypeAndValue = function(params) {
1216     KJUR.asn1.x509.AttributeTypeAndValue.superclass.constructor.call(this);
1217     var typeObj = null;
1218     var valueObj = null;
1219     var defaultDSType = "utf8";
1220 
1221     this.setByString = function(attrTypeAndValueStr) {
1222         if (attrTypeAndValueStr.match(/^([^=]+)=(.+)$/)) {
1223             this.setByAttrTypeAndValueStr(RegExp.$1, RegExp.$2);
1224         } else {
1225             throw "malformed attrTypeAndValueStr: " + attrTypeAndValueStr;
1226         }
1227     };
1228 
1229     this.setByAttrTypeAndValueStr = function(shortAttrType, valueStr) {
1230         this.typeObj = KJUR.asn1.x509.OID.atype2obj(shortAttrType);
1231         var dsType = defaultDSType;
1232         if (shortAttrType == "C") dsType = "prn";
1233         this.valueObj = this.getValueObj(dsType, valueStr);
1234     };
1235 
1236     this.getValueObj = function(dsType, valueStr) {
1237         if (dsType == "utf8")   return new KJUR.asn1.DERUTF8String({"str": valueStr});
1238         if (dsType == "prn")    return new KJUR.asn1.DERPrintableString({"str": valueStr});
1239         if (dsType == "tel")    return new KJUR.asn1.DERTeletexString({"str": valueStr});
1240         if (dsType == "ia5")    return new KJUR.asn1.DERIA5String({"str": valueStr});
1241         throw "unsupported directory string type: type=" + dsType + " value=" + valueStr;
1242     };
1243 
1244     this.getEncodedHex = function() {
1245         var o = new KJUR.asn1.DERSequence({"array": [this.typeObj, this.valueObj]});
1246         this.TLV = o.getEncodedHex();
1247         return this.TLV;
1248     };
1249 
1250     if (typeof params != "undefined") {
1251         if (typeof params['str'] != "undefined") {
1252             this.setByString(params['str']);
1253         }
1254     }
1255 };
1256 YAHOO.lang.extend(KJUR.asn1.x509.AttributeTypeAndValue, KJUR.asn1.ASN1Object);
1257 
1258 // === END   X500Name Related =================================================
1259 
1260 // === BEGIN Other ASN1 structure class  ======================================
1261 
1262 /**
1263  * SubjectPublicKeyInfo ASN.1 structure class
1264  * @name KJUR.asn1.x509.SubjectPublicKeyInfo
1265  * @class SubjectPublicKeyInfo ASN.1 structure class
1266  * @param {Object} params parameter for subject public key
1267  * @extends KJUR.asn1.ASN1Object
1268  * @description
1269  * <br/>
1270  * As for argument 'params' for constructor, you can specify one of
1271  * following properties:
1272  * <ul>
1273  * <li>{@link RSAKey} object</li>
1274  * <li>{@link KJUR.crypto.ECDSA} object</li>
1275  * <li>{@link KJUR.crypto.DSA} object</li>
1276  * <li>(DEPRECATED)rsakey - specify {@link RSAKey} object of subject public key</li>
1277  * <li>(DEPRECATED)rsapem - specify a string of PEM public key of RSA key</li>
1278  * </ul>
1279  * NOTE1: 'params' can be omitted.<br/>
1280  * NOTE2: DSA/ECDSA key object is also supported since asn1x509 1.0.6.<br/>
1281  * <h4>EXAMPLE</h4>
1282  * @example
1283  * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(RSAKey_object);
1284  * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoECDSA_object);
1285  * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoDSA_object);
1286  */
1287 KJUR.asn1.x509.SubjectPublicKeyInfo = function(params) {
1288     KJUR.asn1.x509.SubjectPublicKeyInfo.superclass.constructor.call(this);
1289     var asn1AlgId = null;
1290     var asn1SubjPKey = null;
1291     var rsaKey = null;
1292 
1293     /**
1294      * (DEPRECATED) set RSAKey object as subject public key
1295      * @name setRSAKey
1296      * @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo
1297      * @function
1298      * @param {RSAKey} rsaKey {@link RSAKey} object for RSA public key
1299      * @description
1300      * @deprecated
1301      * @example
1302      * spki.setRSAKey(rsaKey);
1303      */
1304     this.setRSAKey = function(rsaKey) {
1305         if (! RSAKey.prototype.isPrototypeOf(rsaKey))
1306             throw "argument is not RSAKey instance";
1307         this.rsaKey = rsaKey;
1308         var asn1RsaN = new KJUR.asn1.DERInteger({'bigint': rsaKey.n});
1309         var asn1RsaE = new KJUR.asn1.DERInteger({'int': rsaKey.e});
1310         var asn1RsaPub = new KJUR.asn1.DERSequence({'array': [asn1RsaN, asn1RsaE]});
1311         var rsaKeyHex = asn1RsaPub.getEncodedHex();
1312         this.asn1AlgId = new KJUR.asn1.x509.AlgorithmIdentifier({'name':'rsaEncryption'});
1313         this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex':'00'+rsaKeyHex});
1314     };
1315 
1316     /**
1317      * (DEPRECATED) set a PEM formatted RSA public key string as RSA public key
1318      * @name setRSAPEM
1319      * @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo
1320      * @function
1321      * @param {String} rsaPubPEM PEM formatted RSA public key string
1322      * @deprecated
1323      * @description
1324      * @example
1325      * spki.setRSAPEM(rsaPubPEM);
1326      */
1327     this.setRSAPEM = function(rsaPubPEM) {
1328         if (rsaPubPEM.match(/-----BEGIN PUBLIC KEY-----/)) {
1329             var s = rsaPubPEM;
1330             s = s.replace(/^-----[^-]+-----/, '');
1331             s = s.replace(/-----[^-]+-----\s*$/, '');
1332             var rsaB64 = s.replace(/\s+/g, '');
1333             var rsaWA = CryptoJS.enc.Base64.parse(rsaB64);
1334             var rsaP8Hex = CryptoJS.enc.Hex.stringify(rsaWA);
1335             var a = _rsapem_getHexValueArrayOfChildrenFromHex(rsaP8Hex);
1336             var hBitStrVal = a[1];
1337             var rsaHex = hBitStrVal.substr(2);
1338             var a3 = _rsapem_getHexValueArrayOfChildrenFromHex(rsaHex);
1339             var rsaKey = new RSAKey();
1340             rsaKey.setPublic(a3[0], a3[1]);
1341             this.setRSAKey(rsaKey);
1342         } else {
1343             throw "key not supported";
1344         }
1345     };
1346 
1347     /*
1348      * @since asn1x509 1.0.7
1349      */
1350     this.getASN1Object = function() {
1351         if (this.asn1AlgId == null || this.asn1SubjPKey == null)
1352             throw "algId and/or subjPubKey not set";
1353         var o = new KJUR.asn1.DERSequence({'array':
1354                                            [this.asn1AlgId, this.asn1SubjPKey]});
1355         return o;
1356     };
1357 
1358     this.getEncodedHex = function() {
1359         var o = this.getASN1Object();
1360         this.hTLV = o.getEncodedHex();
1361         return this.hTLV;
1362     };
1363 
1364     this._setRSAKey = function(key) {
1365         var asn1RsaPub = KJUR.asn1.ASN1Util.newObject({
1366             'seq': [{'int': {'bigint': key.n}}, {'int': {'int': key.e}}]
1367         });
1368         var rsaKeyHex = asn1RsaPub.getEncodedHex();
1369         this.asn1AlgId = new KJUR.asn1.x509.AlgorithmIdentifier({'name':'rsaEncryption'});
1370         this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex':'00'+rsaKeyHex});
1371     };
1372 
1373     this._setEC = function(key) {
1374         var asn1Params = new KJUR.asn1.DERObjectIdentifier({'name': key.curveName});
1375         this.asn1AlgId = 
1376             new KJUR.asn1.x509.AlgorithmIdentifier({'name': 'ecPublicKey',
1377                                                     'asn1params': asn1Params});
1378         this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex': '00' + key.pubKeyHex});
1379     };
1380 
1381     this._setDSA = function(key) {
1382         var asn1Params = new KJUR.asn1.ASN1Util.newObject({
1383             'seq': [{'int': {'bigint': key.p}},
1384                     {'int': {'bigint': key.q}},
1385                     {'int': {'bigint': key.g}}]
1386         });
1387         this.asn1AlgId = 
1388             new KJUR.asn1.x509.AlgorithmIdentifier({'name': 'dsa',
1389                                                     'asn1params': asn1Params});
1390         var pubInt = new KJUR.asn1.DERInteger({'bigint': key.y});
1391         this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex': '00' + pubInt.getEncodedHex()});
1392     };
1393 
1394     if (typeof params != "undefined") {
1395         if (typeof RSAKey != 'undefined' && params instanceof RSAKey) {
1396             this._setRSAKey(params);
1397         } else if (typeof KJUR.crypto.ECDSA != 'undefined' &&
1398                    params instanceof KJUR.crypto.ECDSA) {
1399             this._setEC(params);
1400         } else if (typeof KJUR.crypto.DSA != 'undefined' &&
1401                    params instanceof KJUR.crypto.DSA) {
1402             this._setDSA(params);
1403         } else if (typeof params['rsakey'] != "undefined") {
1404             this.setRSAKey(params['rsakey']);
1405         } else if (typeof params['rsapem'] != "undefined") {
1406             this.setRSAPEM(params['rsapem']);
1407         }
1408     }
1409 };
1410 YAHOO.lang.extend(KJUR.asn1.x509.SubjectPublicKeyInfo, KJUR.asn1.ASN1Object);
1411 
1412 /**
1413  * Time ASN.1 structure class
1414  * @name KJUR.asn1.x509.Time
1415  * @class Time ASN.1 structure class
1416  * @param {Array} params associative array of parameters (ex. {'str': '130508235959Z'})
1417  * @extends KJUR.asn1.ASN1Object
1418  * @description
1419  * <br/>
1420  * <h4>EXAMPLES</h4>
1421  * @example
1422  * var t1 = new KJUR.asn1.x509.Time{'str': '130508235959Z'} // UTCTime by default
1423  * var t2 = new KJUR.asn1.x509.Time{'type': 'gen',  'str': '20130508235959Z'} // GeneralizedTime
1424  */
1425 KJUR.asn1.x509.Time = function(params) {
1426     KJUR.asn1.x509.Time.superclass.constructor.call(this);
1427     var type = null;
1428     var timeParams = null;
1429 
1430     this.setTimeParams = function(timeParams) {
1431         this.timeParams = timeParams;
1432     }
1433 
1434     this.getEncodedHex = function() {
1435         var o = null;
1436 
1437         if (this.timeParams != null) {
1438             if (this.type == "utc") {
1439                 o = new KJUR.asn1.DERUTCTime(this.timeParams);
1440             } else {
1441                 o = new KJUR.asn1.DERGeneralizedTime(this.timeParams);
1442             }
1443         } else {
1444             if (this.type == "utc") {
1445                 o = new KJUR.asn1.DERUTCTime();
1446             } else {
1447                 o = new KJUR.asn1.DERGeneralizedTime();
1448             }
1449         }
1450         this.TLV = o.getEncodedHex();
1451         return this.TLV;
1452     };
1453     
1454     this.type = "utc";
1455     if (typeof params != "undefined") {
1456         if (typeof params.type != "undefined") {
1457             this.type = params.type;
1458         } else {
1459             if (typeof params.str != "undefined") {
1460                 if (params.str.match(/^[0-9]{12}Z$/)) this.type = "utc";
1461                 if (params.str.match(/^[0-9]{14}Z$/)) this.type = "gen";
1462             }
1463         }
1464         this.timeParams = params;
1465     }
1466 };
1467 YAHOO.lang.extend(KJUR.asn1.x509.Time, KJUR.asn1.ASN1Object);
1468 
1469 /**
1470  * AlgorithmIdentifier ASN.1 structure class
1471  * @name KJUR.asn1.x509.AlgorithmIdentifier
1472  * @class AlgorithmIdentifier ASN.1 structure class
1473  * @param {Array} params associative array of parameters (ex. {'name': 'SHA1withRSA'})
1474  * @extends KJUR.asn1.ASN1Object
1475  * @description
1476  * @example
1477  */
1478 KJUR.asn1.x509.AlgorithmIdentifier = function(params) {
1479     KJUR.asn1.x509.AlgorithmIdentifier.superclass.constructor.call(this);
1480     var nameAlg = null;
1481     var asn1Alg = null;
1482     var asn1Params = null;
1483     var paramEmpty = false;
1484 
1485     this.getEncodedHex = function() {
1486         if (this.nameAlg == null && this.asn1Alg == null) {
1487             throw "algorithm not specified";
1488         }
1489         if (this.nameAlg != null && this.asn1Alg == null) {
1490             this.asn1Alg = KJUR.asn1.x509.OID.name2obj(this.nameAlg);
1491         }
1492         var a = [this.asn1Alg];
1493         if (! this.paramEmpty) a.push(this.asn1Params);
1494         var o = new KJUR.asn1.DERSequence({'array': a});
1495         this.hTLV = o.getEncodedHex();
1496         return this.hTLV;
1497     };
1498 
1499     if (typeof params != "undefined") {
1500         if (typeof params['name'] != "undefined") {
1501             this.nameAlg = params['name'];
1502         }
1503         if (typeof params['asn1params'] != "undefined") {
1504             this.asn1Params = params['asn1params'];
1505         }
1506         if (typeof params['paramempty'] != "undefined") {
1507             this.paramEmpty = params['paramempty'];
1508         }
1509     }
1510     if (this.asn1Params == null) {
1511         this.asn1Params = new KJUR.asn1.DERNull();
1512     }
1513 };
1514 YAHOO.lang.extend(KJUR.asn1.x509.AlgorithmIdentifier, KJUR.asn1.ASN1Object);
1515 
1516 /**
1517  * GeneralName ASN.1 structure class
1518  * @name KJUR.asn1.x509.GeneralName
1519  * @class GeneralName ASN.1 structure class
1520  * @description
1521  * <br/>
1522  * As for argument 'params' for constructor, you can specify one of
1523  * following properties:
1524  * <ul>
1525  * <li>rfc822 - rfc822Name[1] (ex. user1@foo.com)</li>
1526  * <li>dns - dNSName[2] (ex. foo.com)</li>
1527  * <li>uri - uniformResourceIdentifier[6] (ex. http://foo.com/)</li>
1528  * </ul>
1529  * NOTE: Currently this only supports 'uniformResourceIdentifier'.
1530  * <h4>EXAMPLE AND ASN.1 SYNTAX</h4>
1531  * @example
1532  * var gn = new KJUR.asn1.x509.GeneralName({'uri': 'http://aaa.com/'});
1533  *
1534  * GeneralName ::= CHOICE {
1535  *         otherName                       [0]     OtherName,
1536  *         rfc822Name                      [1]     IA5String,
1537  *         dNSName                         [2]     IA5String,
1538  *         x400Address                     [3]     ORAddress,
1539  *         directoryName                   [4]     Name,
1540  *         ediPartyName                    [5]     EDIPartyName,
1541  *         uniformResourceIdentifier       [6]     IA5String,
1542  *         iPAddress                       [7]     OCTET STRING,
1543  *         registeredID                    [8]     OBJECT IDENTIFIER } 
1544  */
1545 KJUR.asn1.x509.GeneralName = function(params) {
1546     KJUR.asn1.x509.GeneralName.superclass.constructor.call(this);
1547     var asn1Obj = null;
1548     var type = null;
1549     var pTag = {'rfc822': '81', 'dns': '82', 'uri': '86'};
1550 
1551     this.setByParam = function(params) {
1552         var str = null;
1553         var v = null;
1554 
1555         if (typeof params['rfc822'] != "undefined") {
1556             this.type = 'rfc822';
1557             v = new KJUR.asn1.DERIA5String({'str': params[this.type]});
1558         }
1559         if (typeof params['dns'] != "undefined") {
1560             this.type = 'dns';
1561             v = new KJUR.asn1.DERIA5String({'str': params[this.type]});
1562         }
1563         if (typeof params['uri'] != "undefined") {
1564             this.type = 'uri';
1565             v = new KJUR.asn1.DERIA5String({'str': params[this.type]});
1566         }
1567 
1568         if (this.type == null)
1569             throw "unsupported type in params=" + params;
1570         this.asn1Obj = new KJUR.asn1.DERTaggedObject({'explicit': false,
1571                                                       'tag': pTag[this.type],
1572                                                       'obj': v});
1573     };
1574 
1575     this.getEncodedHex = function() {
1576         return this.asn1Obj.getEncodedHex();
1577     }
1578 
1579     if (typeof params != "undefined") {
1580         this.setByParam(params);
1581     }
1582 
1583 };
1584 YAHOO.lang.extend(KJUR.asn1.x509.GeneralName, KJUR.asn1.ASN1Object);
1585 
1586 /**
1587  * GeneralNames ASN.1 structure class
1588  * @name KJUR.asn1.x509.GeneralNames
1589  * @class GeneralNames ASN.1 structure class
1590  * @description
1591  * <br/>
1592  * <h4>EXAMPLE AND ASN.1 SYNTAX</h4>
1593  * @example
1594  * var gns = new KJUR.asn1.x509.GeneralNames([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]); 
1595  *
1596  * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
1597  */
1598 KJUR.asn1.x509.GeneralNames = function(paramsArray) {
1599     KJUR.asn1.x509.GeneralNames.superclass.constructor.call(this);
1600     var asn1Array = null;
1601 
1602     /**
1603      * set a array of {@link KJUR.asn1.x509.GeneralName} parameters
1604      * @name setByParamArray
1605      * @memberOf KJUR.asn1.x509.GeneralNames
1606      * @function
1607      * @param {Array} paramsArray Array of {@link KJUR.asn1.x509.GeneralNames}
1608      * @description
1609      * <br/>
1610      * <h4>EXAMPLES</h4>
1611      * @example
1612      * var gns = new KJUR.asn1.x509.GeneralNames();
1613      * gns.setByParamArray([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]);
1614      */
1615     this.setByParamArray = function(paramsArray) {
1616         for (var i = 0; i < paramsArray.length; i++) {
1617             var o = new KJUR.asn1.x509.GeneralName(paramsArray[i]);
1618             this.asn1Array.push(o);
1619         }
1620     };
1621 
1622     this.getEncodedHex = function() {
1623         var o = new KJUR.asn1.DERSequence({'array': this.asn1Array});
1624         return o.getEncodedHex();
1625     };
1626 
1627     this.asn1Array = new Array();
1628     if (typeof paramsArray != "undefined") {
1629         this.setByParamArray(paramsArray);
1630     }
1631 };
1632 YAHOO.lang.extend(KJUR.asn1.x509.GeneralNames, KJUR.asn1.ASN1Object);
1633 
1634 /**
1635  * DistributionPointName ASN.1 structure class
1636  * @name KJUR.asn1.x509.DistributionPointName
1637  * @class DistributionPointName ASN.1 structure class
1638  * @description
1639  * @example
1640  */
1641 KJUR.asn1.x509.DistributionPointName = function(gnOrRdn) {
1642     KJUR.asn1.x509.DistributionPointName.superclass.constructor.call(this);
1643     var asn1Obj = null;
1644     var type = null;
1645     var tag = null;
1646     var asn1V = null;
1647 
1648     this.getEncodedHex = function() {
1649         if (this.type != "full")
1650             throw "currently type shall be 'full': " + this.type;
1651         this.asn1Obj = new KJUR.asn1.DERTaggedObject({'explicit': false,
1652                                                       'tag': this.tag,
1653                                                       'obj': this.asn1V});
1654         this.hTLV = this.asn1Obj.getEncodedHex();
1655         return this.hTLV;
1656     };
1657 
1658     if (typeof gnOrRdn != "undefined") {
1659         if (KJUR.asn1.x509.GeneralNames.prototype.isPrototypeOf(gnOrRdn)) {
1660             this.type = "full";
1661             this.tag = "a0";
1662             this.asn1V = gnOrRdn;
1663         } else {
1664             throw "This class supports GeneralNames only as argument";
1665         }
1666     }
1667 };
1668 YAHOO.lang.extend(KJUR.asn1.x509.DistributionPointName, KJUR.asn1.ASN1Object);
1669 
1670 /**
1671  * DistributionPoint ASN.1 structure class
1672  * @name KJUR.asn1.x509.DistributionPoint
1673  * @class DistributionPoint ASN.1 structure class
1674  * @description
1675  * @example
1676  */
1677 KJUR.asn1.x509.DistributionPoint = function(params) {
1678     KJUR.asn1.x509.DistributionPoint.superclass.constructor.call(this);
1679     var asn1DP = null;
1680 
1681     this.getEncodedHex = function() {
1682         var seq = new KJUR.asn1.DERSequence();
1683         if (this.asn1DP != null) {
1684             var o1 = new KJUR.asn1.DERTaggedObject({'explicit': true,
1685                                                     'tag': 'a0',
1686                                                     'obj': this.asn1DP});
1687             seq.appendASN1Object(o1);
1688         }
1689         this.hTLV = seq.getEncodedHex();
1690         return this.hTLV;
1691     };
1692 
1693     if (typeof params != "undefined") {
1694         if (typeof params['dpobj'] != "undefined") {
1695             this.asn1DP = params['dpobj'];
1696         }
1697     }
1698 };
1699 YAHOO.lang.extend(KJUR.asn1.x509.DistributionPoint, KJUR.asn1.ASN1Object);
1700 
1701 /**
1702  * static object for OID
1703  * @name KJUR.asn1.x509.OID
1704  * @class static object for OID
1705  * @property {Assoc Array} atype2oidList for short attribyte type name and oid (i.e. 'C' and '2.5.4.6')
1706  * @property {Assoc Array} name2oidList for oid name and oid (i.e. 'keyUsage' and '2.5.29.15')
1707  * @property {Assoc Array} objCache for caching name and DERObjectIdentifier object 
1708  * @description
1709  * <dl>
1710  * <dt><b>atype2oidList</b>
1711  * <dd>currently supports 'C', 'O', 'OU', 'ST', 'L' and 'CN' only.
1712  * <dt><b>name2oidList</b>
1713  * <dd>currently supports 'SHA1withRSA', 'rsaEncryption' and some extension OIDs
1714  * </dl>
1715  * @example
1716  */
1717 KJUR.asn1.x509.OID = new function(params) {
1718     this.atype2oidList = {
1719         'C':    '2.5.4.6',
1720         'O':    '2.5.4.10',
1721         'OU':   '2.5.4.11',
1722         'ST':   '2.5.4.8',
1723         'L':    '2.5.4.7',
1724         'CN':   '2.5.4.3',
1725         'DN':   '2.5.4.49',
1726         'DC':   '0.9.2342.19200300.100.1.25',
1727     };
1728     this.name2oidList = {
1729         'sha1':                 '1.3.14.3.2.26',
1730         'sha256':               '2.16.840.1.101.3.4.2.1',
1731         'sha384':               '2.16.840.1.101.3.4.2.2',
1732         'sha512':               '2.16.840.1.101.3.4.2.3',
1733         'sha224':               '2.16.840.1.101.3.4.2.4',
1734         'md5':                  '1.2.840.113549.2.5',
1735         'md2':                  '1.3.14.7.2.2.1',
1736         'ripemd160':            '1.3.36.3.2.1',
1737 
1738         'MD2withRSA':           '1.2.840.113549.1.1.2',
1739         'MD4withRSA':           '1.2.840.113549.1.1.3',
1740         'MD5withRSA':           '1.2.840.113549.1.1.4',
1741         'SHA1withRSA':          '1.2.840.113549.1.1.5',
1742         'SHA224withRSA':        '1.2.840.113549.1.1.14',
1743         'SHA256withRSA':        '1.2.840.113549.1.1.11',
1744         'SHA384withRSA':        '1.2.840.113549.1.1.12',
1745         'SHA512withRSA':        '1.2.840.113549.1.1.13',
1746 
1747         'SHA1withECDSA':        '1.2.840.10045.4.1',
1748         'SHA224withECDSA':      '1.2.840.10045.4.3.1',
1749         'SHA256withECDSA':      '1.2.840.10045.4.3.2',
1750         'SHA384withECDSA':      '1.2.840.10045.4.3.3',
1751         'SHA512withECDSA':      '1.2.840.10045.4.3.4',
1752 
1753         'dsa':                  '1.2.840.10040.4.1',
1754         'SHA1withDSA':          '1.2.840.10040.4.3',
1755         'SHA224withDSA':        '2.16.840.1.101.3.4.3.1',
1756         'SHA256withDSA':        '2.16.840.1.101.3.4.3.2',
1757 
1758         'rsaEncryption':        '1.2.840.113549.1.1.1',
1759         'subjectKeyIdentifier': '2.5.29.14',
1760 
1761         'countryName':          '2.5.4.6',
1762         'organization':         '2.5.4.10',
1763         'organizationalUnit':   '2.5.4.11',
1764         'stateOrProvinceName':  '2.5.4.8',
1765         'locality':             '2.5.4.7',
1766         'commonName':           '2.5.4.3',
1767 
1768         'keyUsage':             '2.5.29.15',
1769         'basicConstraints':     '2.5.29.19',
1770         'cRLDistributionPoints':'2.5.29.31',
1771         'certificatePolicies':  '2.5.29.32',
1772         'authorityKeyIdentifier':'2.5.29.35',
1773         'extKeyUsage':          '2.5.29.37',
1774 
1775         'anyExtendedKeyUsage':  '2.5.29.37.0',
1776         'serverAuth':           '1.3.6.1.5.5.7.3.1',
1777         'clientAuth':           '1.3.6.1.5.5.7.3.2',
1778         'codeSigning':          '1.3.6.1.5.5.7.3.3',
1779         'emailProtection':      '1.3.6.1.5.5.7.3.4',
1780         'timeStamping':         '1.3.6.1.5.5.7.3.8',
1781         'ocspSigning':          '1.3.6.1.5.5.7.3.9',
1782 
1783         'ecPublicKey':          '1.2.840.10045.2.1',
1784         'secp256r1':            '1.2.840.10045.3.1.7',
1785         'secp256k1':            '1.3.132.0.10',
1786         'secp384r1':            '1.3.132.0.34',
1787 
1788         'pkcs5PBES2':           '1.2.840.113549.1.5.13',
1789         'pkcs5PBKDF2':          '1.2.840.113549.1.5.12',
1790 
1791         'des-EDE3-CBC':         '1.2.840.113549.3.7',
1792 
1793         'data':                 '1.2.840.113549.1.7.1', // CMS data
1794         'signed-data':          '1.2.840.113549.1.7.2', // CMS signed-data
1795         'enveloped-data':       '1.2.840.113549.1.7.3', // CMS enveloped-data
1796         'digested-data':        '1.2.840.113549.1.7.5', // CMS digested-data
1797         'encrypted-data':       '1.2.840.113549.1.7.6', // CMS encrypted-data
1798         'authenticated-data':   '1.2.840.113549.1.9.16.1.2', // CMS authenticated-data
1799         'tstinfo':              '1.2.840.113549.1.9.16.1.4', // RFC3161 TSTInfo
1800     };
1801 
1802     this.objCache = {};
1803 
1804     /**
1805      * get DERObjectIdentifier by registered OID name
1806      * @name name2obj
1807      * @memberOf KJUR.asn1.x509.OID
1808      * @function
1809      * @param {String} name OID
1810      * @description
1811      * @example
1812      * var asn1ObjOID = OID.name2obj('SHA1withRSA');
1813      */
1814     this.name2obj = function(name) {
1815         if (typeof this.objCache[name] != "undefined")
1816             return this.objCache[name];
1817         if (typeof this.name2oidList[name] == "undefined")
1818             throw "Name of ObjectIdentifier not defined: " + name;
1819         var oid = this.name2oidList[name];
1820         var obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid});
1821         this.objCache[name] = obj;
1822         return obj;
1823     };
1824 
1825     /**
1826      * get DERObjectIdentifier by registered attribyte type name such like 'C' or 'CN'
1827      * @name atype2obj
1828      * @memberOf KJUR.asn1.x509.OID
1829      * @function
1830      * @param {String} atype short attribute type name such like 'C' or 'CN'
1831      * @description
1832      * @example
1833      * var asn1ObjOID = OID.atype2obj('CN');
1834      */
1835     this.atype2obj = function(atype) {
1836         if (typeof this.objCache[atype] != "undefined")
1837             return this.objCache[atype];
1838         if (typeof this.atype2oidList[atype] == "undefined")
1839             throw "AttributeType name undefined: " + atype;
1840         var oid = this.atype2oidList[atype];
1841         var obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid});
1842         this.objCache[atype] = obj;
1843         return obj;
1844     };
1845 };
1846 
1847 /*
1848  * @since asn1x509 1.0.9
1849  */
1850 KJUR.asn1.x509.OID.oid2name = function(oid) {
1851     var list = KJUR.asn1.x509.OID.name2oidList;
1852     for (var name in list) {
1853         if (list[name] == oid) return name;
1854     }
1855     return '';
1856 };
1857 
1858 /**
1859  * X.509 certificate and CRL utilities class
1860  * @name KJUR.asn1.x509.X509Util
1861  * @class X.509 certificate and CRL utilities class
1862  */
1863 KJUR.asn1.x509.X509Util = new function() {
1864     /**
1865      * get PKCS#8 PEM public key string from RSAKey object
1866      * @name getPKCS8PubKeyPEMfromRSAKey
1867      * @memberOf KJUR.asn1.x509.X509Util
1868      * @function
1869      * @param {RSAKey} rsaKey RSA public key of {@link RSAKey} object
1870      * @description
1871      * @example
1872      * var pem = KJUR.asn1.x509.X509Util.getPKCS8PubKeyPEMfromRSAKey(pubKey);
1873      */
1874     this.getPKCS8PubKeyPEMfromRSAKey = function(rsaKey) {
1875         var pem = null;
1876         var hN = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(rsaKey.n);
1877         var hE = KJUR.asn1.ASN1Util.integerToByteHex(rsaKey.e);
1878         var iN = new KJUR.asn1.DERInteger({hex: hN});
1879         var iE = new KJUR.asn1.DERInteger({hex: hE});
1880         var asn1PubKey = new KJUR.asn1.DERSequence({array: [iN, iE]});
1881         var hPubKey = asn1PubKey.getEncodedHex();
1882         var o1 = new KJUR.asn1.x509.AlgorithmIdentifier({name: 'rsaEncryption'});
1883         var o2 = new KJUR.asn1.DERBitString({hex: '00' + hPubKey});
1884         var seq = new KJUR.asn1.DERSequence({array: [o1, o2]});
1885         var hP8 = seq.getEncodedHex();
1886         var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(hP8, "PUBLIC KEY");
1887         return pem;
1888     };
1889 };
1890 /**
1891  * issue a certificate in PEM format
1892  * @name newCertPEM
1893  * @memberOf KJUR.asn1.x509.X509Util
1894  * @function
1895  * @param {Array} param parameter to issue a certificate
1896  * @since asn1x509 1.0.6
1897  * @description
1898  * This method can issue a certificate by a simple
1899  * JSON object.
1900  * Signature value will be provided by signing with 
1901  * private key using 'cakey' parameter or 
1902  * hexa decimal signature value by 'sighex' parameter.
1903  *
1904  * NOTE: When using DSA or ECDSA CA signing key,
1905  * use 'paramempty' in 'sigalg' to ommit parameter field
1906  * of AlgorithmIdentifer. In case of RSA, parameter
1907  * NULL will be specified by default.
1908  *
1909  * @example
1910  * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM(
1911  * { serial: {int: 4},
1912  *   sigalg: {name: 'SHA1withECDSA', paramempty: true},
1913  *   issuer: {str: '/C=US/O=a'},
1914  *   notbefore: {'str': '130504235959Z'},
1915  *   notafter: {'str': '140504235959Z'},
1916  *   subject: {str: '/C=US/O=b'},
1917  *   sbjpubkey: pubKeyPEM,
1918  *   ext: [
1919  *     {basicConstraints: {cA: true, critical: true}},
1920  *     {keyUsage: {bin: '11'}},
1921  *   ],
1922  *   cakey: [prvkey, pass]}
1923  * );
1924  * // -- or --
1925  * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM(
1926  * { serial: {int: 1},
1927  *   sigalg: {name: 'SHA1withRSA', paramempty: true},
1928  *   issuer: {str: '/C=US/O=T1'},
1929  *   notbefore: {'str': '130504235959Z'},
1930  *   notafter: {'str': '140504235959Z'},
1931  *   subject: {str: '/C=US/O=T1'},
1932  *   sbjpubkey: pubKeyObj,
1933  *   sighex: '0102030405..'}
1934  * );
1935  */
1936 KJUR.asn1.x509.X509Util.newCertPEM = function(param) {
1937     var ns1 = KJUR.asn1.x509;
1938     var o = new ns1.TBSCertificate();
1939 
1940     if (param.serial !== undefined)
1941         o.setSerialNumberByParam(param.serial);
1942     else
1943         throw "serial number undefined.";
1944 
1945     if (typeof param.sigalg.name == 'string')
1946         o.setSignatureAlgByParam(param.sigalg);
1947     else 
1948         throw "unproper signature algorithm name";
1949 
1950     if (param.issuer !== undefined)
1951         o.setIssuerByParam(param.issuer);
1952     else
1953         throw "issuer name undefined.";
1954     
1955     if (param.notbefore !== undefined)
1956         o.setNotBeforeByParam(param.notbefore);
1957     else
1958         throw "notbefore undefined.";
1959 
1960     if (param.notafter !== undefined)
1961         o.setNotAfterByParam(param.notafter);
1962     else
1963         throw "notafter undefined.";
1964 
1965     if (param.subject !== undefined)
1966         o.setSubjectByParam(param.subject);
1967     else
1968         throw "subject name undefined.";
1969 
1970     if (param.sbjpubkey !== undefined)
1971         o.setSubjectPublicKeyByGetKey(param.sbjpubkey);
1972     else
1973         throw "subject public key undefined.";
1974 
1975     if (param.ext !== undefined && param.ext.length !== undefined) {
1976         for (var i = 0; i < param.ext.length; i++) {
1977             for (key in param.ext[i]) {
1978                 o.appendExtensionByName(key, param.ext[i][key]);
1979             }
1980         }
1981     }
1982 
1983     // set signature
1984     if (param.cakey === undefined && param.sighex === undefined)
1985         throw "param cakey and sighex undefined.";
1986 
1987     var caKey = null;
1988     var cert = null;
1989 
1990     if (param.cakey) {
1991         caKey = KEYUTIL.getKey.apply(null, param.cakey);
1992         cert = new ns1.Certificate({'tbscertobj': o, 'prvkeyobj': caKey});
1993         cert.sign();
1994     }
1995 
1996     if (param.sighex) {
1997         cert = new ns1.Certificate({'tbscertobj': o});
1998         cert.setSignatureHex(param.sighex);
1999     }
2000 
2001     return cert.getPEMString();
2002 };
2003 
2004 /*
2005   org.bouncycastle.asn1.x500
2006   AttributeTypeAndValue
2007   DirectoryString
2008   RDN
2009   X500Name
2010   X500NameBuilder
2011 
2012   org.bouncycastleasn1.x509
2013   TBSCertificate
2014 */
2015