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