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