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