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