1 /*! asn1-1.0.6.js (c) 2013 Kenji Urushima | kjur.github.com/jsrsasign/license
  2  */
  3 /*
  4  * asn1.js - ASN.1 DER encoder classes
  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 asn1-1.0.js
 18  * @author Kenji Urushima kenji.urushima@gmail.com
 19  * @version asn1 1.0.6 (2014-May-21)
 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  * <p>
 27  * This name space provides following name spaces:
 28  * <ul>
 29  * <li>{@link KJUR.asn1} - ASN.1 primitive hexadecimal encoder</li>
 30  * <li>{@link KJUR.asn1.x509} - ASN.1 structure for X.509 certificate and CRL</li>
 31  * <li>{@link KJUR.crypto} - Java Cryptographic Extension(JCE) style MessageDigest/Signature 
 32  * class and utilities</li>
 33  * </ul>
 34  * </p> 
 35  * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.
 36  * @name KJUR
 37  * @namespace kjur's class library name space
 38  */
 39 if (typeof KJUR == "undefined" || !KJUR) KJUR = {};
 40 
 41 /**
 42  * kjur's ASN.1 class library name space
 43  * <p>
 44  * This is ITU-T X.690 ASN.1 DER encoder class library and
 45  * class structure and methods is very similar to 
 46  * org.bouncycastle.asn1 package of 
 47  * well known BouncyCaslte Cryptography Library.
 48  *
 49  * <h4>PROVIDING ASN.1 PRIMITIVES</h4>
 50  * Here are ASN.1 DER primitive classes.
 51  * <ul>
 52  * <li>0x01 {@link KJUR.asn1.DERBoolean}</li>
 53  * <li>0x02 {@link KJUR.asn1.DERInteger}</li>
 54  * <li>0x03 {@link KJUR.asn1.DERBitString}</li>
 55  * <li>0x04 {@link KJUR.asn1.DEROctetString}</li>
 56  * <li>0x05 {@link KJUR.asn1.DERNull}</li>
 57  * <li>0x06 {@link KJUR.asn1.DERObjectIdentifier}</li>
 58  * <li>0x0a {@link KJUR.asn1.DEREnumerated}</li>
 59  * <li>0x0c {@link KJUR.asn1.DERUTF8String}</li>
 60  * <li>0x12 {@link KJUR.asn1.DERNumericString}</li>
 61  * <li>0x13 {@link KJUR.asn1.DERPrintableString}</li>
 62  * <li>0x14 {@link KJUR.asn1.DERTeletexString}</li>
 63  * <li>0x16 {@link KJUR.asn1.DERIA5String}</li>
 64  * <li>0x17 {@link KJUR.asn1.DERUTCTime}</li>
 65  * <li>0x18 {@link KJUR.asn1.DERGeneralizedTime}</li>
 66  * <li>0x30 {@link KJUR.asn1.DERSequence}</li>
 67  * <li>0x31 {@link KJUR.asn1.DERSet}</li>
 68  * </ul>
 69  *
 70  * <h4>OTHER ASN.1 CLASSES</h4>
 71  * <ul>
 72  * <li>{@link KJUR.asn1.ASN1Object}</li>
 73  * <li>{@link KJUR.asn1.DERAbstractString}</li>
 74  * <li>{@link KJUR.asn1.DERAbstractTime}</li>
 75  * <li>{@link KJUR.asn1.DERAbstractStructured}</li>
 76  * <li>{@link KJUR.asn1.DERTaggedObject}</li>
 77  * </ul>
 78  * </p>
 79  * NOTE: Please ignore method summary and document of this namespace. 
 80  * This caused by a bug of jsdoc2.
 81  * @name KJUR.asn1
 82  * @namespace
 83  */
 84 if (typeof KJUR.asn1 == "undefined" || !KJUR.asn1) KJUR.asn1 = {};
 85 
 86 /**
 87  * ASN1 utilities class
 88  * @name KJUR.asn1.ASN1Util
 89  * @class ASN1 utilities class
 90  * @since asn1 1.0.2
 91  */
 92 KJUR.asn1.ASN1Util = new function() {
 93     this.integerToByteHex = function(i) {
 94         var h = i.toString(16);
 95         if ((h.length % 2) == 1) h = '0' + h;
 96         return h;
 97     };
 98     this.bigIntToMinTwosComplementsHex = function(bigIntegerValue) {
 99         var h = bigIntegerValue.toString(16);
100         if (h.substr(0, 1) != '-') {
101             if (h.length % 2 == 1) {
102                 h = '0' + h;
103             } else {
104                 if (! h.match(/^[0-7]/)) {
105                     h = '00' + h;
106                 }
107             }
108         } else {
109             var hPos = h.substr(1);
110             var xorLen = hPos.length;
111             if (xorLen % 2 == 1) {
112                 xorLen += 1;
113             } else {
114                 if (! h.match(/^[0-7]/)) {
115                     xorLen += 2;
116                 }
117             }
118             var hMask = '';
119             for (var i = 0; i < xorLen; i++) {
120                 hMask += 'f';
121             }
122             var biMask = new BigInteger(hMask, 16);
123             var biNeg = biMask.xor(bigIntegerValue).add(BigInteger.ONE);
124             h = biNeg.toString(16).replace(/^-/, '');
125         }
126         return h;
127     };
128     /**
129      * get PEM string from hexadecimal data and header string
130      * @name getPEMStringFromHex
131      * @memberOf KJUR.asn1.ASN1Util
132      * @function
133      * @param {String} dataHex hexadecimal string of PEM body
134      * @param {String} pemHeader PEM header string (ex. 'RSA PRIVATE KEY')
135      * @return {String} PEM formatted string of input data
136      * @description
137      * @example
138      * var pem  = KJUR.asn1.ASN1Util.getPEMStringFromHex('616161', 'RSA PRIVATE KEY');
139      * // value of pem will be:
140      * -----BEGIN PRIVATE KEY-----
141      * YWFh
142      * -----END PRIVATE KEY-----
143      */
144     this.getPEMStringFromHex = function(dataHex, pemHeader) {
145         var ns1 = KJUR.asn1;
146         var dataWA = CryptoJS.enc.Hex.parse(dataHex);
147         var dataB64 = CryptoJS.enc.Base64.stringify(dataWA);
148         var pemBody = dataB64.replace(/(.{64})/g, "$1\r\n");
149         pemBody = pemBody.replace(/\r\n$/, '');
150         return "-----BEGIN " + pemHeader + "-----\r\n" + 
151             pemBody + 
152             "\r\n-----END " + pemHeader + "-----\r\n";
153     };
154 
155     /**
156      * generate ASN1Object specifed by JSON parameters
157      * @name newObject
158      * @memberOf KJUR.asn1.ASN1Util
159      * @function
160      * @param {Array} param JSON parameter to generate ASN1Object
161      * @return {KJUR.asn1.ASN1Object} generated object
162      * @since asn1 1.0.3
163      * @description
164      * generate any ASN1Object specified by JSON param
165      * including ASN.1 primitive or structured.
166      * Generally 'param' can be described as follows:
167      * <blockquote>
168      * {TYPE-OF-ASNOBJ: ASN1OBJ-PARAMETER}
169      * </blockquote>
170      * 'TYPE-OF-ASN1OBJ' can be one of following symbols:
171      * <ul>
172      * <li>'bool' - DERBoolean</li>
173      * <li>'int' - DERInteger</li>
174      * <li>'bitstr' - DERBitString</li>
175      * <li>'octstr' - DEROctetString</li>
176      * <li>'null' - DERNull</li>
177      * <li>'oid' - DERObjectIdentifier</li>
178      * <li>'enum' - DEREnumerated</li>
179      * <li>'utf8str' - DERUTF8String</li>
180      * <li>'numstr' - DERNumericString</li>
181      * <li>'prnstr' - DERPrintableString</li>
182      * <li>'telstr' - DERTeletexString</li>
183      * <li>'ia5str' - DERIA5String</li>
184      * <li>'utctime' - DERUTCTime</li>
185      * <li>'gentime' - DERGeneralizedTime</li>
186      * <li>'seq' - DERSequence</li>
187      * <li>'set' - DERSet</li>
188      * <li>'tag' - DERTaggedObject</li>
189      * </ul>
190      * @example
191      * newObject({'prnstr': 'aaa'});
192      * newObject({'seq': [{'int': 3}, {'prnstr': 'aaa'}]})
193      * // ASN.1 Tagged Object
194      * newObject({'tag': {'tag': 'a1', 
195      *                    'explicit': true,
196      *                    'obj': {'seq': [{'int': 3}, {'prnstr': 'aaa'}]}}});
197      * // more simple representation of ASN.1 Tagged Object
198      * newObject({'tag': ['a1',
199      *                    true,
200      *                    {'seq': [
201      *                      {'int': 3}, 
202      *                      {'prnstr': 'aaa'}]}
203      *                   ]});
204      */
205     this.newObject = function(param) {
206         var ns1 = KJUR.asn1;
207         var keys = Object.keys(param);
208         if (keys.length != 1)
209             throw "key of param shall be only one.";
210         var key = keys[0];
211 
212         if (":bool:int:bitstr:octstr:null:oid:enum:utf8str:numstr:prnstr:telstr:ia5str:utctime:gentime:seq:set:tag:".indexOf(":" + key + ":") == -1)
213             throw "undefined key: " + key;
214 
215         if (key == "bool")    return new ns1.DERBoolean(param[key]);
216         if (key == "int")     return new ns1.DERInteger(param[key]);
217         if (key == "bitstr")  return new ns1.DERBitString(param[key]);
218         if (key == "octstr")  return new ns1.DEROctetString(param[key]);
219         if (key == "null")    return new ns1.DERNull(param[key]);
220         if (key == "oid")     return new ns1.DERObjectIdentifier(param[key]);
221         if (key == "enum")    return new ns1.DEREnumerated(param[key]);
222         if (key == "utf8str") return new ns1.DERUTF8String(param[key]);
223         if (key == "numstr")  return new ns1.DERNumericString(param[key]);
224         if (key == "prnstr")  return new ns1.DERPrintableString(param[key]);
225         if (key == "telstr")  return new ns1.DERTeletexString(param[key]);
226         if (key == "ia5str")  return new ns1.DERIA5String(param[key]);
227         if (key == "utctime") return new ns1.DERUTCTime(param[key]);
228         if (key == "gentime") return new ns1.DERGeneralizedTime(param[key]);
229 
230         if (key == "seq") {
231             var paramList = param[key];
232             var a = [];
233             for (var i = 0; i < paramList.length; i++) {
234                 var asn1Obj = ns1.ASN1Util.newObject(paramList[i]);
235                 a.push(asn1Obj);
236             }
237             return new ns1.DERSequence({'array': a});
238         }
239 
240         if (key == "set") {
241             var paramList = param[key];
242             var a = [];
243             for (var i = 0; i < paramList.length; i++) {
244                 var asn1Obj = ns1.ASN1Util.newObject(paramList[i]);
245                 a.push(asn1Obj);
246             }
247             return new ns1.DERSet({'array': a});
248         }
249 
250         if (key == "tag") {
251             var tagParam = param[key];
252             if (Object.prototype.toString.call(tagParam) === '[object Array]' &&
253                 tagParam.length == 3) {
254                 var obj = ns1.ASN1Util.newObject(tagParam[2]);
255                 return new ns1.DERTaggedObject({tag: tagParam[0], explicit: tagParam[1], obj: obj});
256             } else {
257                 var newParam = {};
258                 if (tagParam.explicit !== undefined)
259                     newParam.explicit = tagParam.explicit;
260                 if (tagParam.tag !== undefined)
261                     newParam.tag = tagParam.tag;
262                 if (tagParam.obj === undefined)
263                     throw "obj shall be specified for 'tag'.";
264                 newParam.obj = ns1.ASN1Util.newObject(tagParam.obj);
265                 return new ns1.DERTaggedObject(newParam);
266             }
267         }
268     };
269 
270     /**
271      * get encoded hexadecimal string of ASN1Object specifed by JSON parameters
272      * @name jsonToASN1HEX
273      * @memberOf KJUR.asn1.ASN1Util
274      * @function
275      * @param {Array} param JSON parameter to generate ASN1Object
276      * @return hexadecimal string of ASN1Object
277      * @since asn1 1.0.4
278      * @description
279      * As for ASN.1 object representation of JSON object,
280      * please see {@link newObject}.
281      * @example
282      * jsonToASN1HEX({'prnstr': 'aaa'}); 
283      */
284     this.jsonToASN1HEX = function(param) {
285         var asn1Obj = this.newObject(param);
286         return asn1Obj.getEncodedHex();
287     };
288 };
289 
290 // ********************************************************************
291 //  Abstract ASN.1 Classes
292 // ********************************************************************
293 
294 // ********************************************************************
295 
296 /**
297  * base class for ASN.1 DER encoder object
298  * @name KJUR.asn1.ASN1Object
299  * @class base class for ASN.1 DER encoder object
300  * @property {Boolean} isModified flag whether internal data was changed
301  * @property {String} hTLV hexadecimal string of ASN.1 TLV
302  * @property {String} hT hexadecimal string of ASN.1 TLV tag(T)
303  * @property {String} hL hexadecimal string of ASN.1 TLV length(L)
304  * @property {String} hV hexadecimal string of ASN.1 TLV value(V)
305  * @description
306  */
307 KJUR.asn1.ASN1Object = function() {
308     var isModified = true;
309     var hTLV = null;
310     var hT = '00';
311     var hL = '00';
312     var hV = '';
313 
314     /**
315      * get hexadecimal ASN.1 TLV length(L) bytes from TLV value(V)
316      * @name getLengthHexFromValue
317      * @memberOf KJUR.asn1.ASN1Object
318      * @function
319      * @return {String} hexadecimal string of ASN.1 TLV length(L)
320      */
321     this.getLengthHexFromValue = function() {
322         if (typeof this.hV == "undefined" || this.hV == null) {
323             throw "this.hV is null or undefined.";
324         }
325         if (this.hV.length % 2 == 1) {
326             throw "value hex must be even length: n=" + hV.length + ",v=" + this.hV;
327         }
328         var n = this.hV.length / 2;
329         var hN = n.toString(16);
330         if (hN.length % 2 == 1) {
331             hN = "0" + hN;
332         }
333         if (n < 128) {
334             return hN;
335         } else {
336             var hNlen = hN.length / 2;
337             if (hNlen > 15) {
338                 throw "ASN.1 length too long to represent by 8x: n = " + n.toString(16);
339             }
340             var head = 128 + hNlen;
341             return head.toString(16) + hN;
342         }
343     };
344 
345     /**
346      * get hexadecimal string of ASN.1 TLV bytes
347      * @name getEncodedHex
348      * @memberOf KJUR.asn1.ASN1Object
349      * @function
350      * @return {String} hexadecimal string of ASN.1 TLV
351      */
352     this.getEncodedHex = function() {
353         if (this.hTLV == null || this.isModified) {
354             this.hV = this.getFreshValueHex();
355             this.hL = this.getLengthHexFromValue();
356             this.hTLV = this.hT + this.hL + this.hV;
357             this.isModified = false;
358             //alert("first time: " + this.hTLV);
359         }
360         return this.hTLV;
361     };
362 
363     /**
364      * get hexadecimal string of ASN.1 TLV value(V) bytes
365      * @name getValueHex
366      * @memberOf KJUR.asn1.ASN1Object
367      * @function
368      * @return {String} hexadecimal string of ASN.1 TLV value(V) bytes
369      */
370     this.getValueHex = function() {
371         this.getEncodedHex();
372         return this.hV;
373     }
374 
375     this.getFreshValueHex = function() {
376         return '';
377     };
378 };
379 
380 // == BEGIN DERAbstractString ================================================
381 /**
382  * base class for ASN.1 DER string classes
383  * @name KJUR.asn1.DERAbstractString
384  * @class base class for ASN.1 DER string classes
385  * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
386  * @property {String} s internal string of value
387  * @extends KJUR.asn1.ASN1Object
388  * @description
389  * <br/>
390  * As for argument 'params' for constructor, you can specify one of
391  * following properties:
392  * <ul>
393  * <li>str - specify initial ASN.1 value(V) by a string</li>
394  * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
395  * </ul>
396  * NOTE: 'params' can be omitted.
397  */
398 KJUR.asn1.DERAbstractString = function(params) {
399     KJUR.asn1.DERAbstractString.superclass.constructor.call(this);
400     var s = null;
401     var hV = null;
402 
403     /**
404      * get string value of this string object
405      * @name getString
406      * @memberOf KJUR.asn1.DERAbstractString
407      * @function
408      * @return {String} string value of this string object
409      */
410     this.getString = function() {
411         return this.s;
412     };
413 
414     /**
415      * set value by a string
416      * @name setString
417      * @memberOf KJUR.asn1.DERAbstractString
418      * @function
419      * @param {String} newS value by a string to set
420      */
421     this.setString = function(newS) {
422         this.hTLV = null;
423         this.isModified = true;
424         this.s = newS;
425         this.hV = stohex(this.s);
426     };
427 
428     /**
429      * set value by a hexadecimal string
430      * @name setStringHex
431      * @memberOf KJUR.asn1.DERAbstractString
432      * @function
433      * @param {String} newHexString value by a hexadecimal string to set
434      */
435     this.setStringHex = function(newHexString) {
436         this.hTLV = null;
437         this.isModified = true;
438         this.s = null;
439         this.hV = newHexString;
440     };
441 
442     this.getFreshValueHex = function() {
443         return this.hV;
444     };
445 
446     if (typeof params != "undefined") {
447         if (typeof params == "string") {
448             this.setString(params);
449         } else if (typeof params['str'] != "undefined") {
450             this.setString(params['str']);
451         } else if (typeof params['hex'] != "undefined") {
452             this.setStringHex(params['hex']);
453         }
454     }
455 };
456 YAHOO.lang.extend(KJUR.asn1.DERAbstractString, KJUR.asn1.ASN1Object);
457 // == END   DERAbstractString ================================================
458 
459 // == BEGIN DERAbstractTime ==================================================
460 /**
461  * base class for ASN.1 DER Generalized/UTCTime class
462  * @name KJUR.asn1.DERAbstractTime
463  * @class base class for ASN.1 DER Generalized/UTCTime class
464  * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'})
465  * @extends KJUR.asn1.ASN1Object
466  * @description
467  * @see KJUR.asn1.ASN1Object - superclass
468  */
469 KJUR.asn1.DERAbstractTime = function(params) {
470     KJUR.asn1.DERAbstractTime.superclass.constructor.call(this);
471     var s = null;
472     var date = null;
473 
474     // --- PRIVATE METHODS --------------------
475     this.localDateToUTC = function(d) {
476         utc = d.getTime() + (d.getTimezoneOffset() * 60000);
477         var utcDate = new Date(utc);
478         return utcDate;
479     };
480 
481     /*
482      * format date string by Data object
483      * @name formatDate
484      * @memberOf KJUR.asn1.AbstractTime;
485      * @param {Date} dateObject 
486      * @param {string} type 'utc' or 'gen'
487      * @param {boolean} withMillis flag for with millisections or not
488      * @description
489      * 'withMillis' flag is supported from asn1 1.0.6.
490      */
491     this.formatDate = function(dateObject, type, withMillis) {
492         var pad = this.zeroPadding;
493         var d = this.localDateToUTC(dateObject);
494         var year = String(d.getFullYear());
495         if (type == 'utc') year = year.substr(2, 2);
496         var month = pad(String(d.getMonth() + 1), 2);
497         var day = pad(String(d.getDate()), 2);
498         var hour = pad(String(d.getHours()), 2);
499         var min = pad(String(d.getMinutes()), 2);
500         var sec = pad(String(d.getSeconds()), 2);
501         var s = year + month + day + hour + min + sec;
502         if (withMillis === true) {
503             var millis = d.getMilliseconds();
504             if (millis != 0) {
505                 var sMillis = pad(String(millis), 3);
506                 sMillis = sMillis.replace(/[0]+$/, "");
507                 s = s + "." + sMillis;
508             }
509         }
510         return s + "Z";
511     };
512 
513     this.zeroPadding = function(s, len) {
514         if (s.length >= len) return s;
515         return new Array(len - s.length + 1).join('0') + s;
516     };
517 
518     // --- PUBLIC METHODS --------------------
519     /**
520      * get string value of this string object
521      * @name getString
522      * @memberOf KJUR.asn1.DERAbstractTime
523      * @function
524      * @return {String} string value of this time object
525      */
526     this.getString = function() {
527         return this.s;
528     };
529 
530     /**
531      * set value by a string
532      * @name setString
533      * @memberOf KJUR.asn1.DERAbstractTime
534      * @function
535      * @param {String} newS value by a string to set such like "130430235959Z"
536      */
537     this.setString = function(newS) {
538         this.hTLV = null;
539         this.isModified = true;
540         this.s = newS;
541         this.hV = stohex(newS);
542     };
543 
544     /**
545      * set value by a Date object
546      * @name setByDateValue
547      * @memberOf KJUR.asn1.DERAbstractTime
548      * @function
549      * @param {Integer} year year of date (ex. 2013)
550      * @param {Integer} month month of date between 1 and 12 (ex. 12)
551      * @param {Integer} day day of month
552      * @param {Integer} hour hours of date
553      * @param {Integer} min minutes of date
554      * @param {Integer} sec seconds of date
555      */
556     this.setByDateValue = function(year, month, day, hour, min, sec) {
557         var dateObject = new Date(Date.UTC(year, month - 1, day, hour, min, sec, 0));
558         this.setByDate(dateObject);
559     };
560 
561     this.getFreshValueHex = function() {
562         return this.hV;
563     };
564 };
565 YAHOO.lang.extend(KJUR.asn1.DERAbstractTime, KJUR.asn1.ASN1Object);
566 // == END   DERAbstractTime ==================================================
567 
568 // == BEGIN DERAbstractStructured ============================================
569 /**
570  * base class for ASN.1 DER structured class
571  * @name KJUR.asn1.DERAbstractStructured
572  * @class base class for ASN.1 DER structured class
573  * @property {Array} asn1Array internal array of ASN1Object
574  * @extends KJUR.asn1.ASN1Object
575  * @description
576  * @see KJUR.asn1.ASN1Object - superclass
577  */
578 KJUR.asn1.DERAbstractStructured = function(params) {
579     KJUR.asn1.DERAbstractString.superclass.constructor.call(this);
580     var asn1Array = null;
581 
582     /**
583      * set value by array of ASN1Object
584      * @name setByASN1ObjectArray
585      * @memberOf KJUR.asn1.DERAbstractStructured
586      * @function
587      * @param {array} asn1ObjectArray array of ASN1Object to set
588      */
589     this.setByASN1ObjectArray = function(asn1ObjectArray) {
590         this.hTLV = null;
591         this.isModified = true;
592         this.asn1Array = asn1ObjectArray;
593     };
594 
595     /**
596      * append an ASN1Object to internal array
597      * @name appendASN1Object
598      * @memberOf KJUR.asn1.DERAbstractStructured
599      * @function
600      * @param {ASN1Object} asn1Object to add
601      */
602     this.appendASN1Object = function(asn1Object) {
603         this.hTLV = null;
604         this.isModified = true;
605         this.asn1Array.push(asn1Object);
606     };
607 
608     this.asn1Array = new Array();
609     if (typeof params != "undefined") {
610         if (typeof params['array'] != "undefined") {
611             this.asn1Array = params['array'];
612         }
613     }
614 };
615 YAHOO.lang.extend(KJUR.asn1.DERAbstractStructured, KJUR.asn1.ASN1Object);
616 
617 
618 // ********************************************************************
619 //  ASN.1 Object Classes
620 // ********************************************************************
621 
622 // ********************************************************************
623 /**
624  * class for ASN.1 DER Boolean
625  * @name KJUR.asn1.DERBoolean
626  * @class class for ASN.1 DER Boolean
627  * @extends KJUR.asn1.ASN1Object
628  * @description
629  * @see KJUR.asn1.ASN1Object - superclass
630  */
631 KJUR.asn1.DERBoolean = function() {
632     KJUR.asn1.DERBoolean.superclass.constructor.call(this);
633     this.hT = "01";
634     this.hTLV = "0101ff";
635 };
636 YAHOO.lang.extend(KJUR.asn1.DERBoolean, KJUR.asn1.ASN1Object);
637 
638 // ********************************************************************
639 /**
640  * class for ASN.1 DER Integer
641  * @name KJUR.asn1.DERInteger
642  * @class class for ASN.1 DER Integer
643  * @extends KJUR.asn1.ASN1Object
644  * @description
645  * <br/>
646  * As for argument 'params' for constructor, you can specify one of
647  * following properties:
648  * <ul>
649  * <li>int - specify initial ASN.1 value(V) by integer value</li>
650  * <li>bigint - specify initial ASN.1 value(V) by BigInteger object</li>
651  * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
652  * </ul>
653  * NOTE: 'params' can be omitted.
654  */
655 KJUR.asn1.DERInteger = function(params) {
656     KJUR.asn1.DERInteger.superclass.constructor.call(this);
657     this.hT = "02";
658 
659     /**
660      * set value by Tom Wu's BigInteger object
661      * @name setByBigInteger
662      * @memberOf KJUR.asn1.DERInteger
663      * @function
664      * @param {BigInteger} bigIntegerValue to set
665      */
666     this.setByBigInteger = function(bigIntegerValue) {
667         this.hTLV = null;
668         this.isModified = true;
669         this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue);
670     };
671 
672     /**
673      * set value by integer value
674      * @name setByInteger
675      * @memberOf KJUR.asn1.DERInteger
676      * @function
677      * @param {Integer} integer value to set
678      */
679     this.setByInteger = function(intValue) {
680         var bi = new BigInteger(String(intValue), 10);
681         this.setByBigInteger(bi);
682     };
683 
684     /**
685      * set value by integer value
686      * @name setValueHex
687      * @memberOf KJUR.asn1.DERInteger
688      * @function
689      * @param {String} hexadecimal string of integer value
690      * @description
691      * <br/>
692      * NOTE: Value shall be represented by minimum octet length of
693      * two's complement representation.
694      * @example
695      * new KJUR.asn1.DERInteger(123);
696      * new KJUR.asn1.DERInteger({'int': 123});
697      * new KJUR.asn1.DERInteger({'hex': '1fad'});
698      */
699     this.setValueHex = function(newHexString) {
700         this.hV = newHexString;
701     };
702 
703     this.getFreshValueHex = function() {
704         return this.hV;
705     };
706 
707     if (typeof params != "undefined") {
708         if (typeof params['bigint'] != "undefined") {
709             this.setByBigInteger(params['bigint']);
710         } else if (typeof params['int'] != "undefined") {
711             this.setByInteger(params['int']);
712         } else if (typeof params == "number") {
713             this.setByInteger(params);
714         } else if (typeof params['hex'] != "undefined") {
715             this.setValueHex(params['hex']);
716         }
717     }
718 };
719 YAHOO.lang.extend(KJUR.asn1.DERInteger, KJUR.asn1.ASN1Object);
720 
721 // ********************************************************************
722 /**
723  * class for ASN.1 DER encoded BitString primitive
724  * @name KJUR.asn1.DERBitString
725  * @class class for ASN.1 DER encoded BitString primitive
726  * @extends KJUR.asn1.ASN1Object
727  * @description 
728  * <br/>
729  * As for argument 'params' for constructor, you can specify one of
730  * following properties:
731  * <ul>
732  * <li>bin - specify binary string (ex. '10111')</li>
733  * <li>array - specify array of boolean (ex. [true,false,true,true])</li>
734  * <li>hex - specify hexadecimal string of ASN.1 value(V) including unused bits</li>
735  * </ul>
736  * NOTE: 'params' can be omitted.
737  */
738 KJUR.asn1.DERBitString = function(params) {
739     KJUR.asn1.DERBitString.superclass.constructor.call(this);
740     this.hT = "03";
741 
742     /**
743      * set ASN.1 value(V) by a hexadecimal string including unused bits
744      * @name setHexValueIncludingUnusedBits
745      * @memberOf KJUR.asn1.DERBitString
746      * @function
747      * @param {String} newHexStringIncludingUnusedBits
748      */
749     this.setHexValueIncludingUnusedBits = function(newHexStringIncludingUnusedBits) {
750         this.hTLV = null;
751         this.isModified = true;
752         this.hV = newHexStringIncludingUnusedBits;
753     };
754 
755     /**
756      * set ASN.1 value(V) by unused bit and hexadecimal string of value
757      * @name setUnusedBitsAndHexValue
758      * @memberOf KJUR.asn1.DERBitString
759      * @function
760      * @param {Integer} unusedBits
761      * @param {String} hValue
762      */
763     this.setUnusedBitsAndHexValue = function(unusedBits, hValue) {
764         if (unusedBits < 0 || 7 < unusedBits) {
765             throw "unused bits shall be from 0 to 7: u = " + unusedBits;
766         }
767         var hUnusedBits = "0" + unusedBits;
768         this.hTLV = null;
769         this.isModified = true;
770         this.hV = hUnusedBits + hValue;
771     };
772 
773     /**
774      * set ASN.1 DER BitString by binary string
775      * @name setByBinaryString
776      * @memberOf KJUR.asn1.DERBitString
777      * @function
778      * @param {String} binaryString binary value string (i.e. '10111')
779      * @description
780      * Its unused bits will be calculated automatically by length of 
781      * 'binaryValue'. <br/>
782      * NOTE: Trailing zeros '0' will be ignored.
783      */
784     this.setByBinaryString = function(binaryString) {
785         binaryString = binaryString.replace(/0+$/, '');
786         var unusedBits = 8 - binaryString.length % 8;
787         if (unusedBits == 8) unusedBits = 0;
788         for (var i = 0; i <= unusedBits; i++) {
789             binaryString += '0';
790         }
791         var h = '';
792         for (var i = 0; i < binaryString.length - 1; i += 8) {
793             var b = binaryString.substr(i, 8);
794             var x = parseInt(b, 2).toString(16);
795             if (x.length == 1) x = '0' + x;
796             h += x;  
797         }
798         this.hTLV = null;
799         this.isModified = true;
800         this.hV = '0' + unusedBits + h;
801     };
802 
803     /**
804      * set ASN.1 TLV value(V) by an array of boolean
805      * @name setByBooleanArray
806      * @memberOf KJUR.asn1.DERBitString
807      * @function
808      * @param {array} booleanArray array of boolean (ex. [true, false, true])
809      * @description
810      * NOTE: Trailing falses will be ignored.
811      */
812     this.setByBooleanArray = function(booleanArray) {
813         var s = '';
814         for (var i = 0; i < booleanArray.length; i++) {
815             if (booleanArray[i] == true) {
816                 s += '1';
817             } else {
818                 s += '0';
819             }
820         }
821         this.setByBinaryString(s);
822     };
823 
824     /**
825      * generate an array of false with specified length
826      * @name newFalseArray
827      * @memberOf KJUR.asn1.DERBitString
828      * @function
829      * @param {Integer} nLength length of array to generate
830      * @return {array} array of boolean faluse
831      * @description
832      * This static method may be useful to initialize boolean array.
833      */
834     this.newFalseArray = function(nLength) {
835         var a = new Array(nLength);
836         for (var i = 0; i < nLength; i++) {
837             a[i] = false;
838         }
839         return a;
840     };
841 
842     this.getFreshValueHex = function() {
843         return this.hV;
844     };
845 
846     if (typeof params != "undefined") {
847         if (typeof params == "string" && params.toLowerCase().match(/^[0-9a-f]+$/)) {
848             this.setHexValueIncludingUnusedBits(params);
849         } else if (typeof params['hex'] != "undefined") {
850             this.setHexValueIncludingUnusedBits(params['hex']);
851         } else if (typeof params['bin'] != "undefined") {
852             this.setByBinaryString(params['bin']);
853         } else if (typeof params['array'] != "undefined") {
854             this.setByBooleanArray(params['array']);
855         }
856     }
857 };
858 YAHOO.lang.extend(KJUR.asn1.DERBitString, KJUR.asn1.ASN1Object);
859 
860 // ********************************************************************
861 /**
862  * class for ASN.1 DER OctetString
863  * @name KJUR.asn1.DEROctetString
864  * @class class for ASN.1 DER OctetString
865  * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
866  * @extends KJUR.asn1.DERAbstractString
867  * @description
868  * @see KJUR.asn1.DERAbstractString - superclass
869  */
870 KJUR.asn1.DEROctetString = function(params) {
871     KJUR.asn1.DEROctetString.superclass.constructor.call(this, params);
872     this.hT = "04";
873 };
874 YAHOO.lang.extend(KJUR.asn1.DEROctetString, KJUR.asn1.DERAbstractString);
875 
876 // ********************************************************************
877 /**
878  * class for ASN.1 DER Null
879  * @name KJUR.asn1.DERNull
880  * @class class for ASN.1 DER Null
881  * @extends KJUR.asn1.ASN1Object
882  * @description
883  * @see KJUR.asn1.ASN1Object - superclass
884  */
885 KJUR.asn1.DERNull = function() {
886     KJUR.asn1.DERNull.superclass.constructor.call(this);
887     this.hT = "05";
888     this.hTLV = "0500";
889 };
890 YAHOO.lang.extend(KJUR.asn1.DERNull, KJUR.asn1.ASN1Object);
891 
892 // ********************************************************************
893 /**
894  * class for ASN.1 DER ObjectIdentifier
895  * @name KJUR.asn1.DERObjectIdentifier
896  * @class class for ASN.1 DER ObjectIdentifier
897  * @param {Array} params associative array of parameters (ex. {'oid': '2.5.4.5'})
898  * @extends KJUR.asn1.ASN1Object
899  * @description
900  * <br/>
901  * As for argument 'params' for constructor, you can specify one of
902  * following properties:
903  * <ul>
904  * <li>oid - specify initial ASN.1 value(V) by a oid string (ex. 2.5.4.13)</li>
905  * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
906  * </ul>
907  * NOTE: 'params' can be omitted.
908  */
909 KJUR.asn1.DERObjectIdentifier = function(params) {
910     var itox = function(i) {
911         var h = i.toString(16);
912         if (h.length == 1) h = '0' + h;
913         return h;
914     };
915     var roidtox = function(roid) {
916         var h = '';
917         var bi = new BigInteger(roid, 10);
918         var b = bi.toString(2);
919         var padLen = 7 - b.length % 7;
920         if (padLen == 7) padLen = 0;
921         var bPad = '';
922         for (var i = 0; i < padLen; i++) bPad += '0';
923         b = bPad + b;
924         for (var i = 0; i < b.length - 1; i += 7) {
925             var b8 = b.substr(i, 7);
926             if (i != b.length - 7) b8 = '1' + b8;
927             h += itox(parseInt(b8, 2));
928         }
929         return h;
930     }
931 
932     KJUR.asn1.DERObjectIdentifier.superclass.constructor.call(this);
933     this.hT = "06";
934 
935     /**
936      * set value by a hexadecimal string
937      * @name setValueHex
938      * @memberOf KJUR.asn1.DERObjectIdentifier
939      * @function
940      * @param {String} newHexString hexadecimal value of OID bytes
941      */
942     this.setValueHex = function(newHexString) {
943         this.hTLV = null;
944         this.isModified = true;
945         this.s = null;
946         this.hV = newHexString;
947     };
948 
949     /**
950      * set value by a OID string
951      * @name setValueOidString
952      * @memberOf KJUR.asn1.DERObjectIdentifier
953      * @function
954      * @param {String} oidString OID string (ex. 2.5.4.13)
955      */
956     this.setValueOidString = function(oidString) {
957         if (! oidString.match(/^[0-9.]+$/)) {
958             throw "malformed oid string: " + oidString;
959         }
960         var h = '';
961         var a = oidString.split('.');
962         var i0 = parseInt(a[0]) * 40 + parseInt(a[1]);
963         h += itox(i0);
964         a.splice(0, 2);
965         for (var i = 0; i < a.length; i++) {
966             h += roidtox(a[i]);
967         }
968         this.hTLV = null;
969         this.isModified = true;
970         this.s = null;
971         this.hV = h;
972     };
973 
974     /**
975      * set value by a OID name
976      * @name setValueName
977      * @memberOf KJUR.asn1.DERObjectIdentifier
978      * @function
979      * @param {String} oidName OID name (ex. 'serverAuth')
980      * @since 1.0.1
981      * @description
982      * OID name shall be defined in 'KJUR.asn1.x509.OID.name2oidList'.
983      * Otherwise raise error.
984      */
985     this.setValueName = function(oidName) {
986         if (typeof KJUR.asn1.x509.OID.name2oidList[oidName] != "undefined") {
987             var oid = KJUR.asn1.x509.OID.name2oidList[oidName];
988             this.setValueOidString(oid);
989         } else {
990             throw "DERObjectIdentifier oidName undefined: " + oidName;
991         }
992     };
993 
994     this.getFreshValueHex = function() {
995         return this.hV;
996     };
997 
998     if (typeof params != "undefined") {
999         if (typeof params == "string" && params.match(/^[0-2].[0-9.]+$/)) {
1000             this.setValueOidString(params);
1001         } else if (KJUR.asn1.x509.OID.name2oidList[params] !== undefined) {
1002             this.setValueOidString(KJUR.asn1.x509.OID.name2oidList[params]);
1003         } else if (typeof params['oid'] != "undefined") {
1004             this.setValueOidString(params['oid']);
1005         } else if (typeof params['hex'] != "undefined") {
1006             this.setValueHex(params['hex']);
1007         } else if (typeof params['name'] != "undefined") {
1008             this.setValueName(params['name']);
1009         }
1010     }
1011 };
1012 YAHOO.lang.extend(KJUR.asn1.DERObjectIdentifier, KJUR.asn1.ASN1Object);
1013 
1014 // ********************************************************************
1015 /**
1016  * class for ASN.1 DER Enumerated
1017  * @name KJUR.asn1.DEREnumerated
1018  * @class class for ASN.1 DER Enumerated
1019  * @extends KJUR.asn1.ASN1Object
1020  * @description
1021  * <br/>
1022  * As for argument 'params' for constructor, you can specify one of
1023  * following properties:
1024  * <ul>
1025  * <li>int - specify initial ASN.1 value(V) by integer value</li>
1026  * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
1027  * </ul>
1028  * NOTE: 'params' can be omitted.
1029  */
1030 KJUR.asn1.DEREnumerated = function(params) {
1031     KJUR.asn1.DEREnumerated.superclass.constructor.call(this);
1032     this.hT = "0a";
1033 
1034     /**
1035      * set value by Tom Wu's BigInteger object
1036      * @name setByBigInteger
1037      * @memberOf KJUR.asn1.DEREnumerated
1038      * @function
1039      * @param {BigInteger} bigIntegerValue to set
1040      */
1041     this.setByBigInteger = function(bigIntegerValue) {
1042         this.hTLV = null;
1043         this.isModified = true;
1044         this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue);
1045     };
1046 
1047     /**
1048      * set value by integer value
1049      * @name setByInteger
1050      * @memberOf KJUR.asn1.DEREnumerated
1051      * @function
1052      * @param {Integer} integer value to set
1053      */
1054     this.setByInteger = function(intValue) {
1055         var bi = new BigInteger(String(intValue), 10);
1056         this.setByBigInteger(bi);
1057     };
1058 
1059     /**
1060      * set value by integer value
1061      * @name setValueHex
1062      * @memberOf KJUR.asn1.DEREnumerated
1063      * @function
1064      * @param {String} hexadecimal string of integer value
1065      * @description
1066      * <br/>
1067      * NOTE: Value shall be represented by minimum octet length of
1068      * two's complement representation.
1069      * @example
1070      * new KJUR.asn1.DEREnumerated(123);
1071      * new KJUR.asn1.DEREnumerated({'int': 123});
1072      * new KJUR.asn1.DEREnumerated({'hex': '1fad'});
1073      */
1074     this.setValueHex = function(newHexString) {
1075         this.hV = newHexString;
1076     };
1077 
1078     this.getFreshValueHex = function() {
1079         return this.hV;
1080     };
1081 
1082     if (typeof params != "undefined") {
1083         if (typeof params['int'] != "undefined") {
1084             this.setByInteger(params['int']);
1085         } else if (typeof params == "number") {
1086             this.setByInteger(params);
1087         } else if (typeof params['hex'] != "undefined") {
1088             this.setValueHex(params['hex']);
1089         }
1090     }
1091 };
1092 YAHOO.lang.extend(KJUR.asn1.DEREnumerated, KJUR.asn1.ASN1Object);
1093 
1094 // ********************************************************************
1095 /**
1096  * class for ASN.1 DER UTF8String
1097  * @name KJUR.asn1.DERUTF8String
1098  * @class class for ASN.1 DER UTF8String
1099  * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
1100  * @extends KJUR.asn1.DERAbstractString
1101  * @description
1102  * @see KJUR.asn1.DERAbstractString - superclass
1103  */
1104 KJUR.asn1.DERUTF8String = function(params) {
1105     KJUR.asn1.DERUTF8String.superclass.constructor.call(this, params);
1106     this.hT = "0c";
1107 };
1108 YAHOO.lang.extend(KJUR.asn1.DERUTF8String, KJUR.asn1.DERAbstractString);
1109 
1110 // ********************************************************************
1111 /**
1112  * class for ASN.1 DER NumericString
1113  * @name KJUR.asn1.DERNumericString
1114  * @class class for ASN.1 DER NumericString
1115  * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
1116  * @extends KJUR.asn1.DERAbstractString
1117  * @description
1118  * @see KJUR.asn1.DERAbstractString - superclass
1119  */
1120 KJUR.asn1.DERNumericString = function(params) {
1121     KJUR.asn1.DERNumericString.superclass.constructor.call(this, params);
1122     this.hT = "12";
1123 };
1124 YAHOO.lang.extend(KJUR.asn1.DERNumericString, KJUR.asn1.DERAbstractString);
1125 
1126 // ********************************************************************
1127 /**
1128  * class for ASN.1 DER PrintableString
1129  * @name KJUR.asn1.DERPrintableString
1130  * @class class for ASN.1 DER PrintableString
1131  * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
1132  * @extends KJUR.asn1.DERAbstractString
1133  * @description
1134  * @see KJUR.asn1.DERAbstractString - superclass
1135  */
1136 KJUR.asn1.DERPrintableString = function(params) {
1137     KJUR.asn1.DERPrintableString.superclass.constructor.call(this, params);
1138     this.hT = "13";
1139 };
1140 YAHOO.lang.extend(KJUR.asn1.DERPrintableString, KJUR.asn1.DERAbstractString);
1141 
1142 // ********************************************************************
1143 /**
1144  * class for ASN.1 DER TeletexString
1145  * @name KJUR.asn1.DERTeletexString
1146  * @class class for ASN.1 DER TeletexString
1147  * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
1148  * @extends KJUR.asn1.DERAbstractString
1149  * @description
1150  * @see KJUR.asn1.DERAbstractString - superclass
1151  */
1152 KJUR.asn1.DERTeletexString = function(params) {
1153     KJUR.asn1.DERTeletexString.superclass.constructor.call(this, params);
1154     this.hT = "14";
1155 };
1156 YAHOO.lang.extend(KJUR.asn1.DERTeletexString, KJUR.asn1.DERAbstractString);
1157 
1158 // ********************************************************************
1159 /**
1160  * class for ASN.1 DER IA5String
1161  * @name KJUR.asn1.DERIA5String
1162  * @class class for ASN.1 DER IA5String
1163  * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
1164  * @extends KJUR.asn1.DERAbstractString
1165  * @description
1166  * @see KJUR.asn1.DERAbstractString - superclass
1167  */
1168 KJUR.asn1.DERIA5String = function(params) {
1169     KJUR.asn1.DERIA5String.superclass.constructor.call(this, params);
1170     this.hT = "16";
1171 };
1172 YAHOO.lang.extend(KJUR.asn1.DERIA5String, KJUR.asn1.DERAbstractString);
1173 
1174 // ********************************************************************
1175 /**
1176  * class for ASN.1 DER UTCTime
1177  * @name KJUR.asn1.DERUTCTime
1178  * @class class for ASN.1 DER UTCTime
1179  * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'})
1180  * @extends KJUR.asn1.DERAbstractTime
1181  * @description
1182  * <br/>
1183  * As for argument 'params' for constructor, you can specify one of
1184  * following properties:
1185  * <ul>
1186  * <li>str - specify initial ASN.1 value(V) by a string (ex.'130430235959Z')</li>
1187  * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
1188  * <li>date - specify Date object.</li>
1189  * </ul>
1190  * NOTE: 'params' can be omitted.
1191  * <h4>EXAMPLES</h4>
1192  * @example
1193  * var d1 = new KJUR.asn1.DERUTCTime();
1194  * d1.setString('130430125959Z');
1195  *
1196  * var d2 = new KJUR.asn1.DERUTCTime({'str': '130430125959Z'});
1197  * var d3 = new KJUR.asn1.DERUTCTime({'date': new Date(Date.UTC(2015, 0, 31, 0, 0, 0, 0))});
1198  * var d4 = new KJUR.asn1.DERUTCTime('130430125959Z');
1199  */
1200 KJUR.asn1.DERUTCTime = function(params) {
1201     KJUR.asn1.DERUTCTime.superclass.constructor.call(this, params);
1202     this.hT = "17";
1203 
1204     /**
1205      * set value by a Date object
1206      * @name setByDate
1207      * @memberOf KJUR.asn1.DERUTCTime
1208      * @function
1209      * @param {Date} dateObject Date object to set ASN.1 value(V)
1210      */
1211     this.setByDate = function(dateObject) {
1212         this.hTLV = null;
1213         this.isModified = true;
1214         this.date = dateObject;
1215         this.s = this.formatDate(this.date, 'utc');
1216         this.hV = stohex(this.s);
1217     };
1218 
1219     this.getFreshValueHex = function() {
1220         if (typeof this.date == "undefined" && typeof this.s == "undefined") {
1221             this.date = new Date();
1222             this.s = this.formatDate(this.date, 'utc');
1223             this.hV = stohex(this.s);
1224         }
1225         return this.hV;
1226     };
1227 
1228     if (typeof params != "undefined") {
1229         if (typeof params['str'] != "undefined") {
1230             this.setString(params['str']);
1231         } else if (typeof params == "string" && params.match(/^[0-9]{12}Z$/)) {
1232             this.setString(params);
1233         } else if (typeof params['hex'] != "undefined") {
1234             this.setStringHex(params['hex']);
1235         } else if (typeof params['date'] != "undefined") {
1236             this.setByDate(params['date']);
1237         }
1238     }
1239 };
1240 YAHOO.lang.extend(KJUR.asn1.DERUTCTime, KJUR.asn1.DERAbstractTime);
1241 
1242 // ********************************************************************
1243 /**
1244  * class for ASN.1 DER GeneralizedTime
1245  * @name KJUR.asn1.DERGeneralizedTime
1246  * @class class for ASN.1 DER GeneralizedTime
1247  * @param {Array} params associative array of parameters (ex. {'str': '20130430235959Z'})
1248  * @property {Boolean} withMillis flag to show milliseconds or not
1249  * @extends KJUR.asn1.DERAbstractTime
1250  * @description
1251  * <br/>
1252  * As for argument 'params' for constructor, you can specify one of
1253  * following properties:
1254  * <ul>
1255  * <li>str - specify initial ASN.1 value(V) by a string (ex.'20130430235959Z')</li>
1256  * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
1257  * <li>date - specify Date object.</li>
1258  * <li>millis - specify flag to show milliseconds (from 1.0.6)</li>
1259  * </ul>
1260  * NOTE1: 'params' can be omitted.
1261  * NOTE2: 'withMillis' property is supported from asn1 1.0.6.
1262  */
1263 KJUR.asn1.DERGeneralizedTime = function(params) {
1264     KJUR.asn1.DERGeneralizedTime.superclass.constructor.call(this, params);
1265     this.hT = "18";
1266     this.withMillis = false;
1267 
1268     /**
1269      * set value by a Date object
1270      * @name setByDate
1271      * @memberOf KJUR.asn1.DERGeneralizedTime
1272      * @function
1273      * @param {Date} dateObject Date object to set ASN.1 value(V)
1274      * @example
1275      * When you specify UTC time, use 'Date.UTC' method like this:<br/>
1276      * var o = new DERUTCTime();
1277      * var date = new Date(Date.UTC(2015, 0, 31, 23, 59, 59, 0)); #2015JAN31 23:59:59
1278      * o.setByDate(date);
1279      */
1280     this.setByDate = function(dateObject) {
1281         this.hTLV = null;
1282         this.isModified = true;
1283         this.date = dateObject;
1284         this.s = this.formatDate(this.date, 'gen', this.withMillis);
1285         this.hV = stohex(this.s);
1286     };
1287 
1288     this.getFreshValueHex = function() {
1289         if (typeof this.date == "undefined" && typeof this.s == "undefined") {
1290             this.date = new Date();
1291             this.s = this.formatDate(this.date, 'gen', this.withMillis);
1292             this.hV = stohex(this.s);
1293         }
1294         return this.hV;
1295     };
1296 
1297     if (typeof params != "undefined") {
1298         if (typeof params['str'] != "undefined") {
1299             this.setString(params['str']);
1300         } else if (typeof params == "string" && params.match(/^[0-9]{14}Z$/)) {
1301             this.setString(params);
1302         } else if (typeof params['hex'] != "undefined") {
1303             this.setStringHex(params['hex']);
1304         } else if (typeof params['date'] != "undefined") {
1305             this.setByDate(params['date']);
1306         } else if (params.millis === true) {
1307             this.withMillis = true;
1308         }
1309     }
1310 };
1311 YAHOO.lang.extend(KJUR.asn1.DERGeneralizedTime, KJUR.asn1.DERAbstractTime);
1312 
1313 // ********************************************************************
1314 /**
1315  * class for ASN.1 DER Sequence
1316  * @name KJUR.asn1.DERSequence
1317  * @class class for ASN.1 DER Sequence
1318  * @extends KJUR.asn1.DERAbstractStructured
1319  * @description
1320  * <br/>
1321  * As for argument 'params' for constructor, you can specify one of
1322  * following properties:
1323  * <ul>
1324  * <li>array - specify array of ASN1Object to set elements of content</li>
1325  * </ul>
1326  * NOTE: 'params' can be omitted.
1327  */
1328 KJUR.asn1.DERSequence = function(params) {
1329     KJUR.asn1.DERSequence.superclass.constructor.call(this, params);
1330     this.hT = "30";
1331     this.getFreshValueHex = function() {
1332         var h = '';
1333         for (var i = 0; i < this.asn1Array.length; i++) {
1334             var asn1Obj = this.asn1Array[i];
1335             h += asn1Obj.getEncodedHex();
1336         }
1337         this.hV = h;
1338         return this.hV;
1339     };
1340 };
1341 YAHOO.lang.extend(KJUR.asn1.DERSequence, KJUR.asn1.DERAbstractStructured);
1342 
1343 // ********************************************************************
1344 /**
1345  * class for ASN.1 DER Set
1346  * @name KJUR.asn1.DERSet
1347  * @class class for ASN.1 DER Set
1348  * @extends KJUR.asn1.DERAbstractStructured
1349  * @description
1350  * <br/>
1351  * As for argument 'params' for constructor, you can specify one of
1352  * following properties:
1353  * <ul>
1354  * <li>array - specify array of ASN1Object to set elements of content</li>
1355  * <li>sortflag - flag for sort (default: true). ASN.1 BER is not sorted in 'SET OF'.</li>
1356  * </ul>
1357  * NOTE1: 'params' can be omitted.<br/>
1358  * NOTE2: sortflag is supported since 1.0.5.
1359  */
1360 KJUR.asn1.DERSet = function(params) {
1361     KJUR.asn1.DERSet.superclass.constructor.call(this, params);
1362     this.hT = "31";
1363     this.sortFlag = true; // item shall be sorted only in ASN.1 DER
1364     this.getFreshValueHex = function() {
1365         var a = new Array();
1366         for (var i = 0; i < this.asn1Array.length; i++) {
1367             var asn1Obj = this.asn1Array[i];
1368             a.push(asn1Obj.getEncodedHex());
1369         }
1370         if (this.sortFlag == true) a.sort();
1371         this.hV = a.join('');
1372         return this.hV;
1373     };
1374 
1375     if (typeof params != "undefined") {
1376         if (typeof params.sortflag != "undefined" &&
1377             params.sortflag == false)
1378             this.sortFlag = false;
1379     }
1380 };
1381 YAHOO.lang.extend(KJUR.asn1.DERSet, KJUR.asn1.DERAbstractStructured);
1382 
1383 // ********************************************************************
1384 /**
1385  * class for ASN.1 DER TaggedObject
1386  * @name KJUR.asn1.DERTaggedObject
1387  * @class class for ASN.1 DER TaggedObject
1388  * @extends KJUR.asn1.ASN1Object
1389  * @description
1390  * <br/>
1391  * Parameter 'tagNoNex' is ASN.1 tag(T) value for this object.
1392  * For example, if you find '[1]' tag in a ASN.1 dump, 
1393  * 'tagNoHex' will be 'a1'.
1394  * <br/>
1395  * As for optional argument 'params' for constructor, you can specify *ANY* of
1396  * following properties:
1397  * <ul>
1398  * <li>explicit - specify true if this is explicit tag otherwise false 
1399  *     (default is 'true').</li>
1400  * <li>tag - specify tag (default is 'a0' which means [0])</li>
1401  * <li>obj - specify ASN1Object which is tagged</li>
1402  * </ul>
1403  * @example
1404  * d1 = new KJUR.asn1.DERUTF8String({'str':'a'});
1405  * d2 = new KJUR.asn1.DERTaggedObject({'obj': d1});
1406  * hex = d2.getEncodedHex();
1407  */
1408 KJUR.asn1.DERTaggedObject = function(params) {
1409     KJUR.asn1.DERTaggedObject.superclass.constructor.call(this);
1410     this.hT = "a0";
1411     this.hV = '';
1412     this.isExplicit = true;
1413     this.asn1Object = null;
1414 
1415     /**
1416      * set value by an ASN1Object
1417      * @name setString
1418      * @memberOf KJUR.asn1.DERTaggedObject
1419      * @function
1420      * @param {Boolean} isExplicitFlag flag for explicit/implicit tag
1421      * @param {Integer} tagNoHex hexadecimal string of ASN.1 tag
1422      * @param {ASN1Object} asn1Object ASN.1 to encapsulate
1423      */
1424     this.setASN1Object = function(isExplicitFlag, tagNoHex, asn1Object) {
1425         this.hT = tagNoHex;
1426         this.isExplicit = isExplicitFlag;
1427         this.asn1Object = asn1Object;
1428         if (this.isExplicit) {
1429             this.hV = this.asn1Object.getEncodedHex();
1430             this.hTLV = null;
1431             this.isModified = true;
1432         } else {
1433             this.hV = null;
1434             this.hTLV = asn1Object.getEncodedHex();
1435             this.hTLV = this.hTLV.replace(/^../, tagNoHex);
1436             this.isModified = false;
1437         }
1438     };
1439 
1440     this.getFreshValueHex = function() {
1441         return this.hV;
1442     };
1443 
1444     if (typeof params != "undefined") {
1445         if (typeof params['tag'] != "undefined") {
1446             this.hT = params['tag'];
1447         }
1448         if (typeof params['explicit'] != "undefined") {
1449             this.isExplicit = params['explicit'];
1450         }
1451         if (typeof params['obj'] != "undefined") {
1452             this.asn1Object = params['obj'];
1453             this.setASN1Object(this.isExplicit, this.hT, this.asn1Object);
1454         }
1455     }
1456 };
1457 YAHOO.lang.extend(KJUR.asn1.DERTaggedObject, KJUR.asn1.ASN1Object);
1458