1 /* asn1-1.0.13.js (c) 2013-2017 Kenji Urushima | kjur.github.com/jsrsasign/license
  2  */
  3 /*
  4  * asn1.js - ASN.1 DER encoder classes
  5  *
  6  * Copyright (c) 2013-2017 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.13 (2017-Jun-02)
 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      */
533     this.setString = function(newS) {
534         this.hTLV = null;
535         this.isModified = true;
536         this.s = newS;
537         this.hV = stohex(this.s);
538     };
539 
540     /**
541      * set value by a hexadecimal string
542      * @name setStringHex
543      * @memberOf KJUR.asn1.DERAbstractString#
544      * @function
545      * @param {String} newHexString value by a hexadecimal string to set
546      */
547     this.setStringHex = function(newHexString) {
548         this.hTLV = null;
549         this.isModified = true;
550         this.s = null;
551         this.hV = newHexString;
552     };
553 
554     this.getFreshValueHex = function() {
555         return this.hV;
556     };
557 
558     if (typeof params != "undefined") {
559         if (typeof params == "string") {
560             this.setString(params);
561         } else if (typeof params['str'] != "undefined") {
562             this.setString(params['str']);
563         } else if (typeof params['hex'] != "undefined") {
564             this.setStringHex(params['hex']);
565         }
566     }
567 };
568 YAHOO.lang.extend(KJUR.asn1.DERAbstractString, KJUR.asn1.ASN1Object);
569 // == END   DERAbstractString ================================================
570 
571 // == BEGIN DERAbstractTime ==================================================
572 /**
573  * base class for ASN.1 DER Generalized/UTCTime class
574  * @name KJUR.asn1.DERAbstractTime
575  * @class base class for ASN.1 DER Generalized/UTCTime class
576  * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'})
577  * @extends KJUR.asn1.ASN1Object
578  * @description
579  * @see KJUR.asn1.ASN1Object - superclass
580  */
581 KJUR.asn1.DERAbstractTime = function(params) {
582     KJUR.asn1.DERAbstractTime.superclass.constructor.call(this);
583     var s = null;
584     var date = null;
585 
586     // --- PRIVATE METHODS --------------------
587     this.localDateToUTC = function(d) {
588         utc = d.getTime() + (d.getTimezoneOffset() * 60000);
589         var utcDate = new Date(utc);
590         return utcDate;
591     };
592 
593     /*
594      * format date string by Data object
595      * @name formatDate
596      * @memberOf KJUR.asn1.AbstractTime;
597      * @param {Date} dateObject 
598      * @param {string} type 'utc' or 'gen'
599      * @param {boolean} withMillis flag for with millisections or not
600      * @description
601      * 'withMillis' flag is supported from asn1 1.0.6.
602      */
603     this.formatDate = function(dateObject, type, withMillis) {
604         var pad = this.zeroPadding;
605         var d = this.localDateToUTC(dateObject);
606         var year = String(d.getFullYear());
607         if (type == 'utc') year = year.substr(2, 2);
608         var month = pad(String(d.getMonth() + 1), 2);
609         var day = pad(String(d.getDate()), 2);
610         var hour = pad(String(d.getHours()), 2);
611         var min = pad(String(d.getMinutes()), 2);
612         var sec = pad(String(d.getSeconds()), 2);
613         var s = year + month + day + hour + min + sec;
614         if (withMillis === true) {
615             var millis = d.getMilliseconds();
616             if (millis != 0) {
617                 var sMillis = pad(String(millis), 3);
618                 sMillis = sMillis.replace(/[0]+$/, "");
619                 s = s + "." + sMillis;
620             }
621         }
622         return s + "Z";
623     };
624 
625     this.zeroPadding = function(s, len) {
626         if (s.length >= len) return s;
627         return new Array(len - s.length + 1).join('0') + s;
628     };
629 
630     // --- PUBLIC METHODS --------------------
631     /**
632      * get string value of this string object
633      * @name getString
634      * @memberOf KJUR.asn1.DERAbstractTime#
635      * @function
636      * @return {String} string value of this time object
637      */
638     this.getString = function() {
639         return this.s;
640     };
641 
642     /**
643      * set value by a string
644      * @name setString
645      * @memberOf KJUR.asn1.DERAbstractTime#
646      * @function
647      * @param {String} newS value by a string to set such like "130430235959Z"
648      */
649     this.setString = function(newS) {
650         this.hTLV = null;
651         this.isModified = true;
652         this.s = newS;
653         this.hV = stohex(newS);
654     };
655 
656     /**
657      * set value by a Date object
658      * @name setByDateValue
659      * @memberOf KJUR.asn1.DERAbstractTime#
660      * @function
661      * @param {Integer} year year of date (ex. 2013)
662      * @param {Integer} month month of date between 1 and 12 (ex. 12)
663      * @param {Integer} day day of month
664      * @param {Integer} hour hours of date
665      * @param {Integer} min minutes of date
666      * @param {Integer} sec seconds of date
667      */
668     this.setByDateValue = function(year, month, day, hour, min, sec) {
669         var dateObject = new Date(Date.UTC(year, month - 1, day, hour, min, sec, 0));
670         this.setByDate(dateObject);
671     };
672 
673     this.getFreshValueHex = function() {
674         return this.hV;
675     };
676 };
677 YAHOO.lang.extend(KJUR.asn1.DERAbstractTime, KJUR.asn1.ASN1Object);
678 // == END   DERAbstractTime ==================================================
679 
680 // == BEGIN DERAbstractStructured ============================================
681 /**
682  * base class for ASN.1 DER structured class
683  * @name KJUR.asn1.DERAbstractStructured
684  * @class base class for ASN.1 DER structured class
685  * @property {Array} asn1Array internal array of ASN1Object
686  * @extends KJUR.asn1.ASN1Object
687  * @description
688  * @see KJUR.asn1.ASN1Object - superclass
689  */
690 KJUR.asn1.DERAbstractStructured = function(params) {
691     KJUR.asn1.DERAbstractString.superclass.constructor.call(this);
692     var asn1Array = null;
693 
694     /**
695      * set value by array of ASN1Object
696      * @name setByASN1ObjectArray
697      * @memberOf KJUR.asn1.DERAbstractStructured#
698      * @function
699      * @param {array} asn1ObjectArray array of ASN1Object to set
700      */
701     this.setByASN1ObjectArray = function(asn1ObjectArray) {
702         this.hTLV = null;
703         this.isModified = true;
704         this.asn1Array = asn1ObjectArray;
705     };
706 
707     /**
708      * append an ASN1Object to internal array
709      * @name appendASN1Object
710      * @memberOf KJUR.asn1.DERAbstractStructured#
711      * @function
712      * @param {ASN1Object} asn1Object to add
713      */
714     this.appendASN1Object = function(asn1Object) {
715         this.hTLV = null;
716         this.isModified = true;
717         this.asn1Array.push(asn1Object);
718     };
719 
720     this.asn1Array = new Array();
721     if (typeof params != "undefined") {
722         if (typeof params['array'] != "undefined") {
723             this.asn1Array = params['array'];
724         }
725     }
726 };
727 YAHOO.lang.extend(KJUR.asn1.DERAbstractStructured, KJUR.asn1.ASN1Object);
728 
729 
730 // ********************************************************************
731 //  ASN.1 Object Classes
732 // ********************************************************************
733 
734 // ********************************************************************
735 /**
736  * class for ASN.1 DER Boolean
737  * @name KJUR.asn1.DERBoolean
738  * @class class for ASN.1 DER Boolean
739  * @extends KJUR.asn1.ASN1Object
740  * @description
741  * @see KJUR.asn1.ASN1Object - superclass
742  */
743 KJUR.asn1.DERBoolean = function() {
744     KJUR.asn1.DERBoolean.superclass.constructor.call(this);
745     this.hT = "01";
746     this.hTLV = "0101ff";
747 };
748 YAHOO.lang.extend(KJUR.asn1.DERBoolean, KJUR.asn1.ASN1Object);
749 
750 // ********************************************************************
751 /**
752  * class for ASN.1 DER Integer
753  * @name KJUR.asn1.DERInteger
754  * @class class for ASN.1 DER Integer
755  * @extends KJUR.asn1.ASN1Object
756  * @description
757  * <br/>
758  * As for argument 'params' for constructor, you can specify one of
759  * following properties:
760  * <ul>
761  * <li>int - specify initial ASN.1 value(V) by integer value</li>
762  * <li>bigint - specify initial ASN.1 value(V) by BigInteger object</li>
763  * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
764  * </ul>
765  * NOTE: 'params' can be omitted.
766  */
767 KJUR.asn1.DERInteger = function(params) {
768     KJUR.asn1.DERInteger.superclass.constructor.call(this);
769     this.hT = "02";
770 
771     /**
772      * set value by Tom Wu's BigInteger object
773      * @name setByBigInteger
774      * @memberOf KJUR.asn1.DERInteger#
775      * @function
776      * @param {BigInteger} bigIntegerValue to set
777      */
778     this.setByBigInteger = function(bigIntegerValue) {
779         this.hTLV = null;
780         this.isModified = true;
781         this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue);
782     };
783 
784     /**
785      * set value by integer value
786      * @name setByInteger
787      * @memberOf KJUR.asn1.DERInteger
788      * @function
789      * @param {Integer} integer value to set
790      */
791     this.setByInteger = function(intValue) {
792         var bi = new BigInteger(String(intValue), 10);
793         this.setByBigInteger(bi);
794     };
795 
796     /**
797      * set value by integer value
798      * @name setValueHex
799      * @memberOf KJUR.asn1.DERInteger#
800      * @function
801      * @param {String} hexadecimal string of integer value
802      * @description
803      * <br/>
804      * NOTE: Value shall be represented by minimum octet length of
805      * two's complement representation.
806      * @example
807      * new KJUR.asn1.DERInteger(123);
808      * new KJUR.asn1.DERInteger({'int': 123});
809      * new KJUR.asn1.DERInteger({'hex': '1fad'});
810      */
811     this.setValueHex = function(newHexString) {
812         this.hV = newHexString;
813     };
814 
815     this.getFreshValueHex = function() {
816         return this.hV;
817     };
818 
819     if (typeof params != "undefined") {
820         if (typeof params['bigint'] != "undefined") {
821             this.setByBigInteger(params['bigint']);
822         } else if (typeof params['int'] != "undefined") {
823             this.setByInteger(params['int']);
824         } else if (typeof params == "number") {
825             this.setByInteger(params);
826         } else if (typeof params['hex'] != "undefined") {
827             this.setValueHex(params['hex']);
828         }
829     }
830 };
831 YAHOO.lang.extend(KJUR.asn1.DERInteger, KJUR.asn1.ASN1Object);
832 
833 // ********************************************************************
834 /**
835  * class for ASN.1 DER encoded BitString primitive
836  * @name KJUR.asn1.DERBitString
837  * @class class for ASN.1 DER encoded BitString primitive
838  * @extends KJUR.asn1.ASN1Object
839  * @description 
840  * <br/>
841  * As for argument 'params' for constructor, you can specify one of
842  * following properties:
843  * <ul>
844  * <li>bin - specify binary string (ex. '10111')</li>
845  * <li>array - specify array of boolean (ex. [true,false,true,true])</li>
846  * <li>hex - specify hexadecimal string of ASN.1 value(V) including unused bits</li>
847  * <li>obj - specify {@link KJUR.asn1.ASN1Util.newObject} 
848  * argument for "BitString encapsulates" structure.</li>
849  * </ul>
850  * NOTE1: 'params' can be omitted.<br/>
851  * NOTE2: 'obj' parameter have been supported since
852  * asn1 1.0.11, jsrsasign 6.1.1 (2016-Sep-25).<br/>
853  * @example
854  * // default constructor
855  * o = new KJUR.asn1.DERBitString();
856  * // initialize with binary string
857  * o = new KJUR.asn1.DERBitString({bin: "1011"});
858  * // initialize with boolean array
859  * o = new KJUR.asn1.DERBitString({array: [true,false,true,true]});
860  * // initialize with hexadecimal string (04 is unused bits)
861  * o = new KJUR.asn1.DEROctetString({hex: "04bac0"});
862  * // initialize with ASN1Util.newObject argument for encapsulated
863  * o = new KJUR.asn1.DERBitString({obj: {seq: [{int: 3}, {prnstr: 'aaa'}]}});
864  * // above generates a ASN.1 data like this:
865  * // BIT STRING, encapsulates {
866  * //   SEQUENCE {
867  * //     INTEGER 3
868  * //     PrintableString 'aaa'
869  * //     }
870  * //   } 
871  */
872 KJUR.asn1.DERBitString = function(params) {
873     if (params !== undefined && typeof params.obj !== "undefined") {
874 	var o = KJUR.asn1.ASN1Util.newObject(params.obj);
875 	params.hex = "00" + o.getEncodedHex();
876     }
877     KJUR.asn1.DERBitString.superclass.constructor.call(this);
878     this.hT = "03";
879 
880     /**
881      * set ASN.1 value(V) by a hexadecimal string including unused bits
882      * @name setHexValueIncludingUnusedBits
883      * @memberOf KJUR.asn1.DERBitString#
884      * @function
885      * @param {String} newHexStringIncludingUnusedBits
886      */
887     this.setHexValueIncludingUnusedBits = function(newHexStringIncludingUnusedBits) {
888         this.hTLV = null;
889         this.isModified = true;
890         this.hV = newHexStringIncludingUnusedBits;
891     };
892 
893     /**
894      * set ASN.1 value(V) by unused bit and hexadecimal string of value
895      * @name setUnusedBitsAndHexValue
896      * @memberOf KJUR.asn1.DERBitString#
897      * @function
898      * @param {Integer} unusedBits
899      * @param {String} hValue
900      */
901     this.setUnusedBitsAndHexValue = function(unusedBits, hValue) {
902         if (unusedBits < 0 || 7 < unusedBits) {
903             throw "unused bits shall be from 0 to 7: u = " + unusedBits;
904         }
905         var hUnusedBits = "0" + unusedBits;
906         this.hTLV = null;
907         this.isModified = true;
908         this.hV = hUnusedBits + hValue;
909     };
910 
911     /**
912      * set ASN.1 DER BitString by binary string<br/>
913      * @name setByBinaryString
914      * @memberOf KJUR.asn1.DERBitString#
915      * @function
916      * @param {String} binaryString binary value string (i.e. '10111')
917      * @description
918      * Its unused bits will be calculated automatically by length of 
919      * 'binaryValue'. <br/>
920      * NOTE: Trailing zeros '0' will be ignored.
921      * @example
922      * o = new KJUR.asn1.DERBitString();
923      * o.setByBooleanArray("01011");
924      */
925     this.setByBinaryString = function(binaryString) {
926         binaryString = binaryString.replace(/0+$/, '');
927         var unusedBits = 8 - binaryString.length % 8;
928         if (unusedBits == 8) unusedBits = 0;
929         for (var i = 0; i <= unusedBits; i++) {
930             binaryString += '0';
931         }
932         var h = '';
933         for (var i = 0; i < binaryString.length - 1; i += 8) {
934             var b = binaryString.substr(i, 8);
935             var x = parseInt(b, 2).toString(16);
936             if (x.length == 1) x = '0' + x;
937             h += x;  
938         }
939         this.hTLV = null;
940         this.isModified = true;
941         this.hV = '0' + unusedBits + h;
942     };
943 
944     /**
945      * set ASN.1 TLV value(V) by an array of boolean<br/>
946      * @name setByBooleanArray
947      * @memberOf KJUR.asn1.DERBitString#
948      * @function
949      * @param {array} booleanArray array of boolean (ex. [true, false, true])
950      * @description
951      * NOTE: Trailing falses will be ignored in the ASN.1 DER Object.
952      * @example
953      * o = new KJUR.asn1.DERBitString();
954      * o.setByBooleanArray([false, true, false, true, true]);
955      */
956     this.setByBooleanArray = function(booleanArray) {
957         var s = '';
958         for (var i = 0; i < booleanArray.length; i++) {
959             if (booleanArray[i] == true) {
960                 s += '1';
961             } else {
962                 s += '0';
963             }
964         }
965         this.setByBinaryString(s);
966     };
967 
968     /**
969      * generate an array of falses with specified length<br/>
970      * @name newFalseArray
971      * @memberOf KJUR.asn1.DERBitString
972      * @function
973      * @param {Integer} nLength length of array to generate
974      * @return {array} array of boolean falses
975      * @description
976      * This static method may be useful to initialize boolean array.
977      * @example
978      * o = new KJUR.asn1.DERBitString();
979      * o.newFalseArray(3) → [false, false, false]
980      */
981     this.newFalseArray = function(nLength) {
982         var a = new Array(nLength);
983         for (var i = 0; i < nLength; i++) {
984             a[i] = false;
985         }
986         return a;
987     };
988 
989     this.getFreshValueHex = function() {
990         return this.hV;
991     };
992 
993     if (typeof params != "undefined") {
994         if (typeof params == "string" && params.toLowerCase().match(/^[0-9a-f]+$/)) {
995             this.setHexValueIncludingUnusedBits(params);
996         } else if (typeof params['hex'] != "undefined") {
997             this.setHexValueIncludingUnusedBits(params['hex']);
998         } else if (typeof params['bin'] != "undefined") {
999             this.setByBinaryString(params['bin']);
1000         } else if (typeof params['array'] != "undefined") {
1001             this.setByBooleanArray(params['array']);
1002         }
1003     }
1004 };
1005 YAHOO.lang.extend(KJUR.asn1.DERBitString, KJUR.asn1.ASN1Object);
1006 
1007 // ********************************************************************
1008 /**
1009  * class for ASN.1 DER OctetString<br/>
1010  * @name KJUR.asn1.DEROctetString
1011  * @class class for ASN.1 DER OctetString
1012  * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
1013  * @extends KJUR.asn1.DERAbstractString
1014  * @description
1015  * This class provides ASN.1 OctetString simple type.<br/>
1016  * Supported "params" attributes are:
1017  * <ul>
1018  * <li>str - to set a string as a value</li>
1019  * <li>hex - to set a hexadecimal string as a value</li>
1020  * <li>obj - to set a encapsulated ASN.1 value by JSON object 
1021  * which is defined in {@link KJUR.asn1.ASN1Util.newObject}</li>
1022  * </ul>
1023  * NOTE: A parameter 'obj' have been supported 
1024  * for "OCTET STRING, encapsulates" structure.
1025  * since asn1 1.0.11, jsrsasign 6.1.1 (2016-Sep-25).
1026  * @see KJUR.asn1.DERAbstractString - superclass
1027  * @example
1028  * // default constructor
1029  * o = new KJUR.asn1.DEROctetString();
1030  * // initialize with string
1031  * o = new KJUR.asn1.DEROctetString({str: "aaa"});
1032  * // initialize with hexadecimal string
1033  * o = new KJUR.asn1.DEROctetString({hex: "616161"});
1034  * // initialize with ASN1Util.newObject argument 
1035  * o = new KJUR.asn1.DEROctetString({obj: {seq: [{int: 3}, {prnstr: 'aaa'}]}});
1036  * // above generates a ASN.1 data like this:
1037  * // OCTET STRING, encapsulates {
1038  * //   SEQUENCE {
1039  * //     INTEGER 3
1040  * //     PrintableString 'aaa'
1041  * //     }
1042  * //   } 
1043  */
1044 KJUR.asn1.DEROctetString = function(params) {
1045     if (params !== undefined && typeof params.obj !== "undefined") {
1046 	var o = KJUR.asn1.ASN1Util.newObject(params.obj);
1047 	params.hex = o.getEncodedHex();
1048     }
1049     KJUR.asn1.DEROctetString.superclass.constructor.call(this, params);
1050     this.hT = "04";
1051 };
1052 YAHOO.lang.extend(KJUR.asn1.DEROctetString, KJUR.asn1.DERAbstractString);
1053 
1054 // ********************************************************************
1055 /**
1056  * class for ASN.1 DER Null
1057  * @name KJUR.asn1.DERNull
1058  * @class class for ASN.1 DER Null
1059  * @extends KJUR.asn1.ASN1Object
1060  * @description
1061  * @see KJUR.asn1.ASN1Object - superclass
1062  */
1063 KJUR.asn1.DERNull = function() {
1064     KJUR.asn1.DERNull.superclass.constructor.call(this);
1065     this.hT = "05";
1066     this.hTLV = "0500";
1067 };
1068 YAHOO.lang.extend(KJUR.asn1.DERNull, KJUR.asn1.ASN1Object);
1069 
1070 // ********************************************************************
1071 /**
1072  * class for ASN.1 DER ObjectIdentifier
1073  * @name KJUR.asn1.DERObjectIdentifier
1074  * @class class for ASN.1 DER ObjectIdentifier
1075  * @param {Array} params associative array of parameters (ex. {'oid': '2.5.4.5'})
1076  * @extends KJUR.asn1.ASN1Object
1077  * @description
1078  * <br/>
1079  * As for argument 'params' for constructor, you can specify one of
1080  * following properties:
1081  * <ul>
1082  * <li>oid - specify initial ASN.1 value(V) by a oid string (ex. 2.5.4.13)</li>
1083  * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
1084  * </ul>
1085  * NOTE: 'params' can be omitted.
1086  */
1087 KJUR.asn1.DERObjectIdentifier = function(params) {
1088     var itox = function(i) {
1089         var h = i.toString(16);
1090         if (h.length == 1) h = '0' + h;
1091         return h;
1092     };
1093     var roidtox = function(roid) {
1094         var h = '';
1095         var bi = new BigInteger(roid, 10);
1096         var b = bi.toString(2);
1097         var padLen = 7 - b.length % 7;
1098         if (padLen == 7) padLen = 0;
1099         var bPad = '';
1100         for (var i = 0; i < padLen; i++) bPad += '0';
1101         b = bPad + b;
1102         for (var i = 0; i < b.length - 1; i += 7) {
1103             var b8 = b.substr(i, 7);
1104             if (i != b.length - 7) b8 = '1' + b8;
1105             h += itox(parseInt(b8, 2));
1106         }
1107         return h;
1108     }
1109 
1110     KJUR.asn1.DERObjectIdentifier.superclass.constructor.call(this);
1111     this.hT = "06";
1112 
1113     /**
1114      * set value by a hexadecimal string
1115      * @name setValueHex
1116      * @memberOf KJUR.asn1.DERObjectIdentifier#
1117      * @function
1118      * @param {String} newHexString hexadecimal value of OID bytes
1119      */
1120     this.setValueHex = function(newHexString) {
1121         this.hTLV = null;
1122         this.isModified = true;
1123         this.s = null;
1124         this.hV = newHexString;
1125     };
1126 
1127     /**
1128      * set value by a OID string<br/>
1129      * @name setValueOidString
1130      * @memberOf KJUR.asn1.DERObjectIdentifier#
1131      * @function
1132      * @param {String} oidString OID string (ex. 2.5.4.13)
1133      * @example
1134      * o = new KJUR.asn1.DERObjectIdentifier();
1135      * o.setValueOidString("2.5.4.13");
1136      */
1137     this.setValueOidString = function(oidString) {
1138         if (! oidString.match(/^[0-9.]+$/)) {
1139             throw "malformed oid string: " + oidString;
1140         }
1141         var h = '';
1142         var a = oidString.split('.');
1143         var i0 = parseInt(a[0]) * 40 + parseInt(a[1]);
1144         h += itox(i0);
1145         a.splice(0, 2);
1146         for (var i = 0; i < a.length; i++) {
1147             h += roidtox(a[i]);
1148         }
1149         this.hTLV = null;
1150         this.isModified = true;
1151         this.s = null;
1152         this.hV = h;
1153     };
1154 
1155     /**
1156      * set value by a OID name
1157      * @name setValueName
1158      * @memberOf KJUR.asn1.DERObjectIdentifier#
1159      * @function
1160      * @param {String} oidName OID name (ex. 'serverAuth')
1161      * @since 1.0.1
1162      * @description
1163      * OID name shall be defined in 'KJUR.asn1.x509.OID.name2oidList'.
1164      * Otherwise raise error.
1165      * @example
1166      * o = new KJUR.asn1.DERObjectIdentifier();
1167      * o.setValueName("serverAuth");
1168      */
1169     this.setValueName = function(oidName) {
1170 	var oid = KJUR.asn1.x509.OID.name2oid(oidName);
1171 	if (oid !== '') {
1172             this.setValueOidString(oid);
1173         } else {
1174             throw "DERObjectIdentifier oidName undefined: " + oidName;
1175         }
1176     };
1177 
1178     this.getFreshValueHex = function() {
1179         return this.hV;
1180     };
1181 
1182     if (params !== undefined) {
1183         if (typeof params === "string") {
1184 	    if (params.match(/^[0-2].[0-9.]+$/)) {
1185 		this.setValueOidString(params);
1186 	    } else {
1187 		this.setValueName(params);
1188 	    }
1189         } else if (params.oid !== undefined) {
1190             this.setValueOidString(params.oid);
1191         } else if (params.hex !== undefined) {
1192             this.setValueHex(params.hex);
1193         } else if (params.name !== undefined) {
1194             this.setValueName(params.name);
1195         }
1196     }
1197 };
1198 YAHOO.lang.extend(KJUR.asn1.DERObjectIdentifier, KJUR.asn1.ASN1Object);
1199 
1200 // ********************************************************************
1201 /**
1202  * class for ASN.1 DER Enumerated
1203  * @name KJUR.asn1.DEREnumerated
1204  * @class class for ASN.1 DER Enumerated
1205  * @extends KJUR.asn1.ASN1Object
1206  * @description
1207  * <br/>
1208  * As for argument 'params' for constructor, you can specify one of
1209  * following properties:
1210  * <ul>
1211  * <li>int - specify initial ASN.1 value(V) by integer value</li>
1212  * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
1213  * </ul>
1214  * NOTE: 'params' can be omitted.
1215  * @example
1216  * new KJUR.asn1.DEREnumerated(123);
1217  * new KJUR.asn1.DEREnumerated({int: 123});
1218  * new KJUR.asn1.DEREnumerated({hex: '1fad'});
1219  */
1220 KJUR.asn1.DEREnumerated = function(params) {
1221     KJUR.asn1.DEREnumerated.superclass.constructor.call(this);
1222     this.hT = "0a";
1223 
1224     /**
1225      * set value by Tom Wu's BigInteger object
1226      * @name setByBigInteger
1227      * @memberOf KJUR.asn1.DEREnumerated#
1228      * @function
1229      * @param {BigInteger} bigIntegerValue to set
1230      */
1231     this.setByBigInteger = function(bigIntegerValue) {
1232         this.hTLV = null;
1233         this.isModified = true;
1234         this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue);
1235     };
1236 
1237     /**
1238      * set value by integer value
1239      * @name setByInteger
1240      * @memberOf KJUR.asn1.DEREnumerated#
1241      * @function
1242      * @param {Integer} integer value to set
1243      */
1244     this.setByInteger = function(intValue) {
1245         var bi = new BigInteger(String(intValue), 10);
1246         this.setByBigInteger(bi);
1247     };
1248 
1249     /**
1250      * set value by integer value
1251      * @name setValueHex
1252      * @memberOf KJUR.asn1.DEREnumerated#
1253      * @function
1254      * @param {String} hexadecimal string of integer value
1255      * @description
1256      * <br/>
1257      * NOTE: Value shall be represented by minimum octet length of
1258      * two's complement representation.
1259      */
1260     this.setValueHex = function(newHexString) {
1261         this.hV = newHexString;
1262     };
1263 
1264     this.getFreshValueHex = function() {
1265         return this.hV;
1266     };
1267 
1268     if (typeof params != "undefined") {
1269         if (typeof params['int'] != "undefined") {
1270             this.setByInteger(params['int']);
1271         } else if (typeof params == "number") {
1272             this.setByInteger(params);
1273         } else if (typeof params['hex'] != "undefined") {
1274             this.setValueHex(params['hex']);
1275         }
1276     }
1277 };
1278 YAHOO.lang.extend(KJUR.asn1.DEREnumerated, KJUR.asn1.ASN1Object);
1279 
1280 // ********************************************************************
1281 /**
1282  * class for ASN.1 DER UTF8String
1283  * @name KJUR.asn1.DERUTF8String
1284  * @class class for ASN.1 DER UTF8String
1285  * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
1286  * @extends KJUR.asn1.DERAbstractString
1287  * @description
1288  * @see KJUR.asn1.DERAbstractString - superclass
1289  */
1290 KJUR.asn1.DERUTF8String = function(params) {
1291     KJUR.asn1.DERUTF8String.superclass.constructor.call(this, params);
1292     this.hT = "0c";
1293 };
1294 YAHOO.lang.extend(KJUR.asn1.DERUTF8String, KJUR.asn1.DERAbstractString);
1295 
1296 // ********************************************************************
1297 /**
1298  * class for ASN.1 DER NumericString
1299  * @name KJUR.asn1.DERNumericString
1300  * @class class for ASN.1 DER NumericString
1301  * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
1302  * @extends KJUR.asn1.DERAbstractString
1303  * @description
1304  * @see KJUR.asn1.DERAbstractString - superclass
1305  */
1306 KJUR.asn1.DERNumericString = function(params) {
1307     KJUR.asn1.DERNumericString.superclass.constructor.call(this, params);
1308     this.hT = "12";
1309 };
1310 YAHOO.lang.extend(KJUR.asn1.DERNumericString, KJUR.asn1.DERAbstractString);
1311 
1312 // ********************************************************************
1313 /**
1314  * class for ASN.1 DER PrintableString
1315  * @name KJUR.asn1.DERPrintableString
1316  * @class class for ASN.1 DER PrintableString
1317  * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
1318  * @extends KJUR.asn1.DERAbstractString
1319  * @description
1320  * @see KJUR.asn1.DERAbstractString - superclass
1321  */
1322 KJUR.asn1.DERPrintableString = function(params) {
1323     KJUR.asn1.DERPrintableString.superclass.constructor.call(this, params);
1324     this.hT = "13";
1325 };
1326 YAHOO.lang.extend(KJUR.asn1.DERPrintableString, KJUR.asn1.DERAbstractString);
1327 
1328 // ********************************************************************
1329 /**
1330  * class for ASN.1 DER TeletexString
1331  * @name KJUR.asn1.DERTeletexString
1332  * @class class for ASN.1 DER TeletexString
1333  * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
1334  * @extends KJUR.asn1.DERAbstractString
1335  * @description
1336  * @see KJUR.asn1.DERAbstractString - superclass
1337  */
1338 KJUR.asn1.DERTeletexString = function(params) {
1339     KJUR.asn1.DERTeletexString.superclass.constructor.call(this, params);
1340     this.hT = "14";
1341 };
1342 YAHOO.lang.extend(KJUR.asn1.DERTeletexString, KJUR.asn1.DERAbstractString);
1343 
1344 // ********************************************************************
1345 /**
1346  * class for ASN.1 DER IA5String
1347  * @name KJUR.asn1.DERIA5String
1348  * @class class for ASN.1 DER IA5String
1349  * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
1350  * @extends KJUR.asn1.DERAbstractString
1351  * @description
1352  * @see KJUR.asn1.DERAbstractString - superclass
1353  */
1354 KJUR.asn1.DERIA5String = function(params) {
1355     KJUR.asn1.DERIA5String.superclass.constructor.call(this, params);
1356     this.hT = "16";
1357 };
1358 YAHOO.lang.extend(KJUR.asn1.DERIA5String, KJUR.asn1.DERAbstractString);
1359 
1360 // ********************************************************************
1361 /**
1362  * class for ASN.1 DER UTCTime
1363  * @name KJUR.asn1.DERUTCTime
1364  * @class class for ASN.1 DER UTCTime
1365  * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'})
1366  * @extends KJUR.asn1.DERAbstractTime
1367  * @description
1368  * <br/>
1369  * As for argument 'params' for constructor, you can specify one of
1370  * following properties:
1371  * <ul>
1372  * <li>str - specify initial ASN.1 value(V) by a string (ex.'130430235959Z')</li>
1373  * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
1374  * <li>date - specify Date object.</li>
1375  * </ul>
1376  * NOTE: 'params' can be omitted.
1377  * <h4>EXAMPLES</h4>
1378  * @example
1379  * d1 = new KJUR.asn1.DERUTCTime();
1380  * d1.setString('130430125959Z');
1381  *
1382  * d2 = new KJUR.asn1.DERUTCTime({'str': '130430125959Z'});
1383  * d3 = new KJUR.asn1.DERUTCTime({'date': new Date(Date.UTC(2015, 0, 31, 0, 0, 0, 0))});
1384  * d4 = new KJUR.asn1.DERUTCTime('130430125959Z');
1385  */
1386 KJUR.asn1.DERUTCTime = function(params) {
1387     KJUR.asn1.DERUTCTime.superclass.constructor.call(this, params);
1388     this.hT = "17";
1389 
1390     /**
1391      * set value by a Date object<br/>
1392      * @name setByDate
1393      * @memberOf KJUR.asn1.DERUTCTime#
1394      * @function
1395      * @param {Date} dateObject Date object to set ASN.1 value(V)
1396      * @example
1397      * o = new KJUR.asn1.DERUTCTime();
1398      * o.setByDate(new Date("2016/12/31"));
1399      */
1400     this.setByDate = function(dateObject) {
1401         this.hTLV = null;
1402         this.isModified = true;
1403         this.date = dateObject;
1404         this.s = this.formatDate(this.date, 'utc');
1405         this.hV = stohex(this.s);
1406     };
1407 
1408     this.getFreshValueHex = function() {
1409         if (typeof this.date == "undefined" && typeof this.s == "undefined") {
1410             this.date = new Date();
1411             this.s = this.formatDate(this.date, 'utc');
1412             this.hV = stohex(this.s);
1413         }
1414         return this.hV;
1415     };
1416 
1417     if (params !== undefined) {
1418         if (params.str !== undefined) {
1419             this.setString(params.str);
1420         } else if (typeof params == "string" && params.match(/^[0-9]{12}Z$/)) {
1421             this.setString(params);
1422         } else if (params.hex !== undefined) {
1423             this.setStringHex(params.hex);
1424         } else if (params.date !== undefined) {
1425             this.setByDate(params.date);
1426         }
1427     }
1428 };
1429 YAHOO.lang.extend(KJUR.asn1.DERUTCTime, KJUR.asn1.DERAbstractTime);
1430 
1431 // ********************************************************************
1432 /**
1433  * class for ASN.1 DER GeneralizedTime
1434  * @name KJUR.asn1.DERGeneralizedTime
1435  * @class class for ASN.1 DER GeneralizedTime
1436  * @param {Array} params associative array of parameters (ex. {'str': '20130430235959Z'})
1437  * @property {Boolean} withMillis flag to show milliseconds or not
1438  * @extends KJUR.asn1.DERAbstractTime
1439  * @description
1440  * <br/>
1441  * As for argument 'params' for constructor, you can specify one of
1442  * following properties:
1443  * <ul>
1444  * <li>str - specify initial ASN.1 value(V) by a string (ex.'20130430235959Z')</li>
1445  * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
1446  * <li>date - specify Date object.</li>
1447  * <li>millis - specify flag to show milliseconds (from 1.0.6)</li>
1448  * </ul>
1449  * NOTE1: 'params' can be omitted.
1450  * NOTE2: 'withMillis' property is supported from asn1 1.0.6.
1451  */
1452 KJUR.asn1.DERGeneralizedTime = function(params) {
1453     KJUR.asn1.DERGeneralizedTime.superclass.constructor.call(this, params);
1454     this.hT = "18";
1455     this.withMillis = false;
1456 
1457     /**
1458      * set value by a Date object
1459      * @name setByDate
1460      * @memberOf KJUR.asn1.DERGeneralizedTime#
1461      * @function
1462      * @param {Date} dateObject Date object to set ASN.1 value(V)
1463      * @example
1464      * When you specify UTC time, use 'Date.UTC' method like this:<br/>
1465      * o1 = new DERUTCTime();
1466      * o1.setByDate(date);
1467      *
1468      * date = new Date(Date.UTC(2015, 0, 31, 23, 59, 59, 0)); #2015JAN31 23:59:59
1469      */
1470     this.setByDate = function(dateObject) {
1471         this.hTLV = null;
1472         this.isModified = true;
1473         this.date = dateObject;
1474         this.s = this.formatDate(this.date, 'gen', this.withMillis);
1475         this.hV = stohex(this.s);
1476     };
1477 
1478     this.getFreshValueHex = function() {
1479         if (this.date === undefined && this.s === undefined) {
1480             this.date = new Date();
1481             this.s = this.formatDate(this.date, 'gen', this.withMillis);
1482             this.hV = stohex(this.s);
1483         }
1484         return this.hV;
1485     };
1486 
1487     if (params !== undefined) {
1488         if (params.str !== undefined) {
1489             this.setString(params.str);
1490         } else if (typeof params == "string" && params.match(/^[0-9]{14}Z$/)) {
1491             this.setString(params);
1492         } else if (params.hex !== undefined) {
1493             this.setStringHex(params.hex);
1494         } else if (params.date !== undefined) {
1495             this.setByDate(params.date);
1496         }
1497         if (params.millis === true) {
1498             this.withMillis = true;
1499         }
1500     }
1501 };
1502 YAHOO.lang.extend(KJUR.asn1.DERGeneralizedTime, KJUR.asn1.DERAbstractTime);
1503 
1504 // ********************************************************************
1505 /**
1506  * class for ASN.1 DER Sequence
1507  * @name KJUR.asn1.DERSequence
1508  * @class class for ASN.1 DER Sequence
1509  * @extends KJUR.asn1.DERAbstractStructured
1510  * @description
1511  * <br/>
1512  * As for argument 'params' for constructor, you can specify one of
1513  * following properties:
1514  * <ul>
1515  * <li>array - specify array of ASN1Object to set elements of content</li>
1516  * </ul>
1517  * NOTE: 'params' can be omitted.
1518  */
1519 KJUR.asn1.DERSequence = function(params) {
1520     KJUR.asn1.DERSequence.superclass.constructor.call(this, params);
1521     this.hT = "30";
1522     this.getFreshValueHex = function() {
1523         var h = '';
1524         for (var i = 0; i < this.asn1Array.length; i++) {
1525             var asn1Obj = this.asn1Array[i];
1526             h += asn1Obj.getEncodedHex();
1527         }
1528         this.hV = h;
1529         return this.hV;
1530     };
1531 };
1532 YAHOO.lang.extend(KJUR.asn1.DERSequence, KJUR.asn1.DERAbstractStructured);
1533 
1534 // ********************************************************************
1535 /**
1536  * class for ASN.1 DER Set
1537  * @name KJUR.asn1.DERSet
1538  * @class class for ASN.1 DER Set
1539  * @extends KJUR.asn1.DERAbstractStructured
1540  * @description
1541  * <br/>
1542  * As for argument 'params' for constructor, you can specify one of
1543  * following properties:
1544  * <ul>
1545  * <li>array - specify array of ASN1Object to set elements of content</li>
1546  * <li>sortflag - flag for sort (default: true). ASN.1 BER is not sorted in 'SET OF'.</li>
1547  * </ul>
1548  * NOTE1: 'params' can be omitted.<br/>
1549  * NOTE2: sortflag is supported since 1.0.5.
1550  */
1551 KJUR.asn1.DERSet = function(params) {
1552     KJUR.asn1.DERSet.superclass.constructor.call(this, params);
1553     this.hT = "31";
1554     this.sortFlag = true; // item shall be sorted only in ASN.1 DER
1555     this.getFreshValueHex = function() {
1556         var a = new Array();
1557         for (var i = 0; i < this.asn1Array.length; i++) {
1558             var asn1Obj = this.asn1Array[i];
1559             a.push(asn1Obj.getEncodedHex());
1560         }
1561         if (this.sortFlag == true) a.sort();
1562         this.hV = a.join('');
1563         return this.hV;
1564     };
1565 
1566     if (typeof params != "undefined") {
1567         if (typeof params.sortflag != "undefined" &&
1568             params.sortflag == false)
1569             this.sortFlag = false;
1570     }
1571 };
1572 YAHOO.lang.extend(KJUR.asn1.DERSet, KJUR.asn1.DERAbstractStructured);
1573 
1574 // ********************************************************************
1575 /**
1576  * class for ASN.1 DER TaggedObject
1577  * @name KJUR.asn1.DERTaggedObject
1578  * @class class for ASN.1 DER TaggedObject
1579  * @extends KJUR.asn1.ASN1Object
1580  * @description
1581  * <br/>
1582  * Parameter 'tagNoNex' is ASN.1 tag(T) value for this object.
1583  * For example, if you find '[1]' tag in a ASN.1 dump, 
1584  * 'tagNoHex' will be 'a1'.
1585  * <br/>
1586  * As for optional argument 'params' for constructor, you can specify *ANY* of
1587  * following properties:
1588  * <ul>
1589  * <li>explicit - specify true if this is explicit tag otherwise false 
1590  *     (default is 'true').</li>
1591  * <li>tag - specify tag (default is 'a0' which means [0])</li>
1592  * <li>obj - specify ASN1Object which is tagged</li>
1593  * </ul>
1594  * @example
1595  * d1 = new KJUR.asn1.DERUTF8String({'str':'a'});
1596  * d2 = new KJUR.asn1.DERTaggedObject({'obj': d1});
1597  * hex = d2.getEncodedHex();
1598  */
1599 KJUR.asn1.DERTaggedObject = function(params) {
1600     KJUR.asn1.DERTaggedObject.superclass.constructor.call(this);
1601     this.hT = "a0";
1602     this.hV = '';
1603     this.isExplicit = true;
1604     this.asn1Object = null;
1605 
1606     /**
1607      * set value by an ASN1Object
1608      * @name setString
1609      * @memberOf KJUR.asn1.DERTaggedObject#
1610      * @function
1611      * @param {Boolean} isExplicitFlag flag for explicit/implicit tag
1612      * @param {Integer} tagNoHex hexadecimal string of ASN.1 tag
1613      * @param {ASN1Object} asn1Object ASN.1 to encapsulate
1614      */
1615     this.setASN1Object = function(isExplicitFlag, tagNoHex, asn1Object) {
1616         this.hT = tagNoHex;
1617         this.isExplicit = isExplicitFlag;
1618         this.asn1Object = asn1Object;
1619         if (this.isExplicit) {
1620             this.hV = this.asn1Object.getEncodedHex();
1621             this.hTLV = null;
1622             this.isModified = true;
1623         } else {
1624             this.hV = null;
1625             this.hTLV = asn1Object.getEncodedHex();
1626             this.hTLV = this.hTLV.replace(/^../, tagNoHex);
1627             this.isModified = false;
1628         }
1629     };
1630 
1631     this.getFreshValueHex = function() {
1632         return this.hV;
1633     };
1634 
1635     if (typeof params != "undefined") {
1636         if (typeof params['tag'] != "undefined") {
1637             this.hT = params['tag'];
1638         }
1639         if (typeof params['explicit'] != "undefined") {
1640             this.isExplicit = params['explicit'];
1641         }
1642         if (typeof params['obj'] != "undefined") {
1643             this.asn1Object = params['obj'];
1644             this.setASN1Object(this.isExplicit, this.hT, this.asn1Object);
1645         }
1646     }
1647 };
1648 YAHOO.lang.extend(KJUR.asn1.DERTaggedObject, KJUR.asn1.ASN1Object);
1649