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