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