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