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