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