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