1 /*! asn1-1.0.9.js (c) 2013-2015 Kenji Urushima | kjur.github.com/jsrsasign/license 2 */ 3 /* 4 * asn1.js - ASN.1 DER encoder classes 5 * 6 * Copyright (c) 2013-2015 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.9 (2015-Nov-26) 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 * @example 144 * var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex('616161', 'RSA PRIVATE KEY'); 145 * // value of pem will be: 146 * -----BEGIN PRIVATE KEY----- 147 * YWFh 148 * -----END PRIVATE KEY----- 149 */ 150 this.getPEMStringFromHex = function(dataHex, pemHeader) { 151 var ns1 = KJUR.asn1; 152 var dataWA = CryptoJS.enc.Hex.parse(dataHex); 153 var dataB64 = CryptoJS.enc.Base64.stringify(dataWA); 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 * </ul> 831 * NOTE: 'params' can be omitted. 832 */ 833 KJUR.asn1.DERBitString = function(params) { 834 KJUR.asn1.DERBitString.superclass.constructor.call(this); 835 this.hT = "03"; 836 837 /** 838 * set ASN.1 value(V) by a hexadecimal string including unused bits 839 * @name setHexValueIncludingUnusedBits 840 * @memberOf KJUR.asn1.DERBitString 841 * @function 842 * @param {String} newHexStringIncludingUnusedBits 843 */ 844 this.setHexValueIncludingUnusedBits = function(newHexStringIncludingUnusedBits) { 845 this.hTLV = null; 846 this.isModified = true; 847 this.hV = newHexStringIncludingUnusedBits; 848 }; 849 850 /** 851 * set ASN.1 value(V) by unused bit and hexadecimal string of value 852 * @name setUnusedBitsAndHexValue 853 * @memberOf KJUR.asn1.DERBitString 854 * @function 855 * @param {Integer} unusedBits 856 * @param {String} hValue 857 */ 858 this.setUnusedBitsAndHexValue = function(unusedBits, hValue) { 859 if (unusedBits < 0 || 7 < unusedBits) { 860 throw "unused bits shall be from 0 to 7: u = " + unusedBits; 861 } 862 var hUnusedBits = "0" + unusedBits; 863 this.hTLV = null; 864 this.isModified = true; 865 this.hV = hUnusedBits + hValue; 866 }; 867 868 /** 869 * set ASN.1 DER BitString by binary string 870 * @name setByBinaryString 871 * @memberOf KJUR.asn1.DERBitString 872 * @function 873 * @param {String} binaryString binary value string (i.e. '10111') 874 * @description 875 * Its unused bits will be calculated automatically by length of 876 * 'binaryValue'. <br/> 877 * NOTE: Trailing zeros '0' will be ignored. 878 */ 879 this.setByBinaryString = function(binaryString) { 880 binaryString = binaryString.replace(/0+$/, ''); 881 var unusedBits = 8 - binaryString.length % 8; 882 if (unusedBits == 8) unusedBits = 0; 883 for (var i = 0; i <= unusedBits; i++) { 884 binaryString += '0'; 885 } 886 var h = ''; 887 for (var i = 0; i < binaryString.length - 1; i += 8) { 888 var b = binaryString.substr(i, 8); 889 var x = parseInt(b, 2).toString(16); 890 if (x.length == 1) x = '0' + x; 891 h += x; 892 } 893 this.hTLV = null; 894 this.isModified = true; 895 this.hV = '0' + unusedBits + h; 896 }; 897 898 /** 899 * set ASN.1 TLV value(V) by an array of boolean 900 * @name setByBooleanArray 901 * @memberOf KJUR.asn1.DERBitString 902 * @function 903 * @param {array} booleanArray array of boolean (ex. [true, false, true]) 904 * @description 905 * NOTE: Trailing falses will be ignored. 906 */ 907 this.setByBooleanArray = function(booleanArray) { 908 var s = ''; 909 for (var i = 0; i < booleanArray.length; i++) { 910 if (booleanArray[i] == true) { 911 s += '1'; 912 } else { 913 s += '0'; 914 } 915 } 916 this.setByBinaryString(s); 917 }; 918 919 /** 920 * generate an array of false with specified length 921 * @name newFalseArray 922 * @memberOf KJUR.asn1.DERBitString 923 * @function 924 * @param {Integer} nLength length of array to generate 925 * @return {array} array of boolean faluse 926 * @description 927 * This static method may be useful to initialize boolean array. 928 */ 929 this.newFalseArray = function(nLength) { 930 var a = new Array(nLength); 931 for (var i = 0; i < nLength; i++) { 932 a[i] = false; 933 } 934 return a; 935 }; 936 937 this.getFreshValueHex = function() { 938 return this.hV; 939 }; 940 941 if (typeof params != "undefined") { 942 if (typeof params == "string" && params.toLowerCase().match(/^[0-9a-f]+$/)) { 943 this.setHexValueIncludingUnusedBits(params); 944 } else if (typeof params['hex'] != "undefined") { 945 this.setHexValueIncludingUnusedBits(params['hex']); 946 } else if (typeof params['bin'] != "undefined") { 947 this.setByBinaryString(params['bin']); 948 } else if (typeof params['array'] != "undefined") { 949 this.setByBooleanArray(params['array']); 950 } 951 } 952 }; 953 YAHOO.lang.extend(KJUR.asn1.DERBitString, KJUR.asn1.ASN1Object); 954 955 // ******************************************************************** 956 /** 957 * class for ASN.1 DER OctetString 958 * @name KJUR.asn1.DEROctetString 959 * @class class for ASN.1 DER OctetString 960 * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) 961 * @extends KJUR.asn1.DERAbstractString 962 * @description 963 * @see KJUR.asn1.DERAbstractString - superclass 964 */ 965 KJUR.asn1.DEROctetString = function(params) { 966 KJUR.asn1.DEROctetString.superclass.constructor.call(this, params); 967 this.hT = "04"; 968 }; 969 YAHOO.lang.extend(KJUR.asn1.DEROctetString, KJUR.asn1.DERAbstractString); 970 971 // ******************************************************************** 972 /** 973 * class for ASN.1 DER Null 974 * @name KJUR.asn1.DERNull 975 * @class class for ASN.1 DER Null 976 * @extends KJUR.asn1.ASN1Object 977 * @description 978 * @see KJUR.asn1.ASN1Object - superclass 979 */ 980 KJUR.asn1.DERNull = function() { 981 KJUR.asn1.DERNull.superclass.constructor.call(this); 982 this.hT = "05"; 983 this.hTLV = "0500"; 984 }; 985 YAHOO.lang.extend(KJUR.asn1.DERNull, KJUR.asn1.ASN1Object); 986 987 // ******************************************************************** 988 /** 989 * class for ASN.1 DER ObjectIdentifier 990 * @name KJUR.asn1.DERObjectIdentifier 991 * @class class for ASN.1 DER ObjectIdentifier 992 * @param {Array} params associative array of parameters (ex. {'oid': '2.5.4.5'}) 993 * @extends KJUR.asn1.ASN1Object 994 * @description 995 * <br/> 996 * As for argument 'params' for constructor, you can specify one of 997 * following properties: 998 * <ul> 999 * <li>oid - specify initial ASN.1 value(V) by a oid string (ex. 2.5.4.13)</li> 1000 * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li> 1001 * </ul> 1002 * NOTE: 'params' can be omitted. 1003 */ 1004 KJUR.asn1.DERObjectIdentifier = function(params) { 1005 var itox = function(i) { 1006 var h = i.toString(16); 1007 if (h.length == 1) h = '0' + h; 1008 return h; 1009 }; 1010 var roidtox = function(roid) { 1011 var h = ''; 1012 var bi = new BigInteger(roid, 10); 1013 var b = bi.toString(2); 1014 var padLen = 7 - b.length % 7; 1015 if (padLen == 7) padLen = 0; 1016 var bPad = ''; 1017 for (var i = 0; i < padLen; i++) bPad += '0'; 1018 b = bPad + b; 1019 for (var i = 0; i < b.length - 1; i += 7) { 1020 var b8 = b.substr(i, 7); 1021 if (i != b.length - 7) b8 = '1' + b8; 1022 h += itox(parseInt(b8, 2)); 1023 } 1024 return h; 1025 } 1026 1027 KJUR.asn1.DERObjectIdentifier.superclass.constructor.call(this); 1028 this.hT = "06"; 1029 1030 /** 1031 * set value by a hexadecimal string 1032 * @name setValueHex 1033 * @memberOf KJUR.asn1.DERObjectIdentifier 1034 * @function 1035 * @param {String} newHexString hexadecimal value of OID bytes 1036 */ 1037 this.setValueHex = function(newHexString) { 1038 this.hTLV = null; 1039 this.isModified = true; 1040 this.s = null; 1041 this.hV = newHexString; 1042 }; 1043 1044 /** 1045 * set value by a OID string 1046 * @name setValueOidString 1047 * @memberOf KJUR.asn1.DERObjectIdentifier 1048 * @function 1049 * @param {String} oidString OID string (ex. 2.5.4.13) 1050 */ 1051 this.setValueOidString = function(oidString) { 1052 if (! oidString.match(/^[0-9.]+$/)) { 1053 throw "malformed oid string: " + oidString; 1054 } 1055 var h = ''; 1056 var a = oidString.split('.'); 1057 var i0 = parseInt(a[0]) * 40 + parseInt(a[1]); 1058 h += itox(i0); 1059 a.splice(0, 2); 1060 for (var i = 0; i < a.length; i++) { 1061 h += roidtox(a[i]); 1062 } 1063 this.hTLV = null; 1064 this.isModified = true; 1065 this.s = null; 1066 this.hV = h; 1067 }; 1068 1069 /** 1070 * set value by a OID name 1071 * @name setValueName 1072 * @memberOf KJUR.asn1.DERObjectIdentifier 1073 * @function 1074 * @param {String} oidName OID name (ex. 'serverAuth') 1075 * @since 1.0.1 1076 * @description 1077 * OID name shall be defined in 'KJUR.asn1.x509.OID.name2oidList'. 1078 * Otherwise raise error. 1079 */ 1080 this.setValueName = function(oidName) { 1081 if (typeof KJUR.asn1.x509.OID.name2oidList[oidName] != "undefined") { 1082 var oid = KJUR.asn1.x509.OID.name2oidList[oidName]; 1083 this.setValueOidString(oid); 1084 } else { 1085 throw "DERObjectIdentifier oidName undefined: " + oidName; 1086 } 1087 }; 1088 1089 this.getFreshValueHex = function() { 1090 return this.hV; 1091 }; 1092 1093 if (typeof params != "undefined") { 1094 if (typeof params == "string" && params.match(/^[0-2].[0-9.]+$/)) { 1095 this.setValueOidString(params); 1096 } else if (KJUR.asn1.x509.OID.name2oidList[params] !== undefined) { 1097 this.setValueOidString(KJUR.asn1.x509.OID.name2oidList[params]); 1098 } else if (typeof params['oid'] != "undefined") { 1099 this.setValueOidString(params['oid']); 1100 } else if (typeof params['hex'] != "undefined") { 1101 this.setValueHex(params['hex']); 1102 } else if (typeof params['name'] != "undefined") { 1103 this.setValueName(params['name']); 1104 } 1105 } 1106 }; 1107 YAHOO.lang.extend(KJUR.asn1.DERObjectIdentifier, KJUR.asn1.ASN1Object); 1108 1109 // ******************************************************************** 1110 /** 1111 * class for ASN.1 DER Enumerated 1112 * @name KJUR.asn1.DEREnumerated 1113 * @class class for ASN.1 DER Enumerated 1114 * @extends KJUR.asn1.ASN1Object 1115 * @description 1116 * <br/> 1117 * As for argument 'params' for constructor, you can specify one of 1118 * following properties: 1119 * <ul> 1120 * <li>int - specify initial ASN.1 value(V) by integer value</li> 1121 * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li> 1122 * </ul> 1123 * NOTE: 'params' can be omitted. 1124 */ 1125 KJUR.asn1.DEREnumerated = function(params) { 1126 KJUR.asn1.DEREnumerated.superclass.constructor.call(this); 1127 this.hT = "0a"; 1128 1129 /** 1130 * set value by Tom Wu's BigInteger object 1131 * @name setByBigInteger 1132 * @memberOf KJUR.asn1.DEREnumerated 1133 * @function 1134 * @param {BigInteger} bigIntegerValue to set 1135 */ 1136 this.setByBigInteger = function(bigIntegerValue) { 1137 this.hTLV = null; 1138 this.isModified = true; 1139 this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue); 1140 }; 1141 1142 /** 1143 * set value by integer value 1144 * @name setByInteger 1145 * @memberOf KJUR.asn1.DEREnumerated 1146 * @function 1147 * @param {Integer} integer value to set 1148 */ 1149 this.setByInteger = function(intValue) { 1150 var bi = new BigInteger(String(intValue), 10); 1151 this.setByBigInteger(bi); 1152 }; 1153 1154 /** 1155 * set value by integer value 1156 * @name setValueHex 1157 * @memberOf KJUR.asn1.DEREnumerated 1158 * @function 1159 * @param {String} hexadecimal string of integer value 1160 * @description 1161 * <br/> 1162 * NOTE: Value shall be represented by minimum octet length of 1163 * two's complement representation. 1164 * @example 1165 * new KJUR.asn1.DEREnumerated(123); 1166 * new KJUR.asn1.DEREnumerated({'int': 123}); 1167 * new KJUR.asn1.DEREnumerated({'hex': '1fad'}); 1168 */ 1169 this.setValueHex = function(newHexString) { 1170 this.hV = newHexString; 1171 }; 1172 1173 this.getFreshValueHex = function() { 1174 return this.hV; 1175 }; 1176 1177 if (typeof params != "undefined") { 1178 if (typeof params['int'] != "undefined") { 1179 this.setByInteger(params['int']); 1180 } else if (typeof params == "number") { 1181 this.setByInteger(params); 1182 } else if (typeof params['hex'] != "undefined") { 1183 this.setValueHex(params['hex']); 1184 } 1185 } 1186 }; 1187 YAHOO.lang.extend(KJUR.asn1.DEREnumerated, KJUR.asn1.ASN1Object); 1188 1189 // ******************************************************************** 1190 /** 1191 * class for ASN.1 DER UTF8String 1192 * @name KJUR.asn1.DERUTF8String 1193 * @class class for ASN.1 DER UTF8String 1194 * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) 1195 * @extends KJUR.asn1.DERAbstractString 1196 * @description 1197 * @see KJUR.asn1.DERAbstractString - superclass 1198 */ 1199 KJUR.asn1.DERUTF8String = function(params) { 1200 KJUR.asn1.DERUTF8String.superclass.constructor.call(this, params); 1201 this.hT = "0c"; 1202 }; 1203 YAHOO.lang.extend(KJUR.asn1.DERUTF8String, KJUR.asn1.DERAbstractString); 1204 1205 // ******************************************************************** 1206 /** 1207 * class for ASN.1 DER NumericString 1208 * @name KJUR.asn1.DERNumericString 1209 * @class class for ASN.1 DER NumericString 1210 * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) 1211 * @extends KJUR.asn1.DERAbstractString 1212 * @description 1213 * @see KJUR.asn1.DERAbstractString - superclass 1214 */ 1215 KJUR.asn1.DERNumericString = function(params) { 1216 KJUR.asn1.DERNumericString.superclass.constructor.call(this, params); 1217 this.hT = "12"; 1218 }; 1219 YAHOO.lang.extend(KJUR.asn1.DERNumericString, KJUR.asn1.DERAbstractString); 1220 1221 // ******************************************************************** 1222 /** 1223 * class for ASN.1 DER PrintableString 1224 * @name KJUR.asn1.DERPrintableString 1225 * @class class for ASN.1 DER PrintableString 1226 * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) 1227 * @extends KJUR.asn1.DERAbstractString 1228 * @description 1229 * @see KJUR.asn1.DERAbstractString - superclass 1230 */ 1231 KJUR.asn1.DERPrintableString = function(params) { 1232 KJUR.asn1.DERPrintableString.superclass.constructor.call(this, params); 1233 this.hT = "13"; 1234 }; 1235 YAHOO.lang.extend(KJUR.asn1.DERPrintableString, KJUR.asn1.DERAbstractString); 1236 1237 // ******************************************************************** 1238 /** 1239 * class for ASN.1 DER TeletexString 1240 * @name KJUR.asn1.DERTeletexString 1241 * @class class for ASN.1 DER TeletexString 1242 * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) 1243 * @extends KJUR.asn1.DERAbstractString 1244 * @description 1245 * @see KJUR.asn1.DERAbstractString - superclass 1246 */ 1247 KJUR.asn1.DERTeletexString = function(params) { 1248 KJUR.asn1.DERTeletexString.superclass.constructor.call(this, params); 1249 this.hT = "14"; 1250 }; 1251 YAHOO.lang.extend(KJUR.asn1.DERTeletexString, KJUR.asn1.DERAbstractString); 1252 1253 // ******************************************************************** 1254 /** 1255 * class for ASN.1 DER IA5String 1256 * @name KJUR.asn1.DERIA5String 1257 * @class class for ASN.1 DER IA5String 1258 * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) 1259 * @extends KJUR.asn1.DERAbstractString 1260 * @description 1261 * @see KJUR.asn1.DERAbstractString - superclass 1262 */ 1263 KJUR.asn1.DERIA5String = function(params) { 1264 KJUR.asn1.DERIA5String.superclass.constructor.call(this, params); 1265 this.hT = "16"; 1266 }; 1267 YAHOO.lang.extend(KJUR.asn1.DERIA5String, KJUR.asn1.DERAbstractString); 1268 1269 // ******************************************************************** 1270 /** 1271 * class for ASN.1 DER UTCTime 1272 * @name KJUR.asn1.DERUTCTime 1273 * @class class for ASN.1 DER UTCTime 1274 * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'}) 1275 * @extends KJUR.asn1.DERAbstractTime 1276 * @description 1277 * <br/> 1278 * As for argument 'params' for constructor, you can specify one of 1279 * following properties: 1280 * <ul> 1281 * <li>str - specify initial ASN.1 value(V) by a string (ex.'130430235959Z')</li> 1282 * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li> 1283 * <li>date - specify Date object.</li> 1284 * </ul> 1285 * NOTE: 'params' can be omitted. 1286 * <h4>EXAMPLES</h4> 1287 * @example 1288 * var d1 = new KJUR.asn1.DERUTCTime(); 1289 * d1.setString('130430125959Z'); 1290 * 1291 * var d2 = new KJUR.asn1.DERUTCTime({'str': '130430125959Z'}); 1292 * var d3 = new KJUR.asn1.DERUTCTime({'date': new Date(Date.UTC(2015, 0, 31, 0, 0, 0, 0))}); 1293 * var d4 = new KJUR.asn1.DERUTCTime('130430125959Z'); 1294 */ 1295 KJUR.asn1.DERUTCTime = function(params) { 1296 KJUR.asn1.DERUTCTime.superclass.constructor.call(this, params); 1297 this.hT = "17"; 1298 1299 /** 1300 * set value by a Date object 1301 * @name setByDate 1302 * @memberOf KJUR.asn1.DERUTCTime 1303 * @function 1304 * @param {Date} dateObject Date object to set ASN.1 value(V) 1305 */ 1306 this.setByDate = function(dateObject) { 1307 this.hTLV = null; 1308 this.isModified = true; 1309 this.date = dateObject; 1310 this.s = this.formatDate(this.date, 'utc'); 1311 this.hV = stohex(this.s); 1312 }; 1313 1314 this.getFreshValueHex = function() { 1315 if (typeof this.date == "undefined" && typeof this.s == "undefined") { 1316 this.date = new Date(); 1317 this.s = this.formatDate(this.date, 'utc'); 1318 this.hV = stohex(this.s); 1319 } 1320 return this.hV; 1321 }; 1322 1323 if (params !== undefined) { 1324 if (params.str !== undefined) { 1325 this.setString(params.str); 1326 } else if (typeof params == "string" && params.match(/^[0-9]{12}Z$/)) { 1327 this.setString(params); 1328 } else if (params.hex !== undefined) { 1329 this.setStringHex(params.hex); 1330 } else if (params.date !== undefined) { 1331 this.setByDate(params.date); 1332 } 1333 } 1334 }; 1335 YAHOO.lang.extend(KJUR.asn1.DERUTCTime, KJUR.asn1.DERAbstractTime); 1336 1337 // ******************************************************************** 1338 /** 1339 * class for ASN.1 DER GeneralizedTime 1340 * @name KJUR.asn1.DERGeneralizedTime 1341 * @class class for ASN.1 DER GeneralizedTime 1342 * @param {Array} params associative array of parameters (ex. {'str': '20130430235959Z'}) 1343 * @property {Boolean} withMillis flag to show milliseconds or not 1344 * @extends KJUR.asn1.DERAbstractTime 1345 * @description 1346 * <br/> 1347 * As for argument 'params' for constructor, you can specify one of 1348 * following properties: 1349 * <ul> 1350 * <li>str - specify initial ASN.1 value(V) by a string (ex.'20130430235959Z')</li> 1351 * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li> 1352 * <li>date - specify Date object.</li> 1353 * <li>millis - specify flag to show milliseconds (from 1.0.6)</li> 1354 * </ul> 1355 * NOTE1: 'params' can be omitted. 1356 * NOTE2: 'withMillis' property is supported from asn1 1.0.6. 1357 */ 1358 KJUR.asn1.DERGeneralizedTime = function(params) { 1359 KJUR.asn1.DERGeneralizedTime.superclass.constructor.call(this, params); 1360 this.hT = "18"; 1361 this.withMillis = false; 1362 1363 /** 1364 * set value by a Date object 1365 * @name setByDate 1366 * @memberOf KJUR.asn1.DERGeneralizedTime 1367 * @function 1368 * @param {Date} dateObject Date object to set ASN.1 value(V) 1369 * @example 1370 * When you specify UTC time, use 'Date.UTC' method like this:<br/> 1371 * var o = new DERUTCTime(); 1372 * var date = new Date(Date.UTC(2015, 0, 31, 23, 59, 59, 0)); #2015JAN31 23:59:59 1373 * o.setByDate(date); 1374 */ 1375 this.setByDate = function(dateObject) { 1376 this.hTLV = null; 1377 this.isModified = true; 1378 this.date = dateObject; 1379 this.s = this.formatDate(this.date, 'gen', this.withMillis); 1380 this.hV = stohex(this.s); 1381 }; 1382 1383 this.getFreshValueHex = function() { 1384 if (this.date === undefined && this.s === undefined) { 1385 this.date = new Date(); 1386 this.s = this.formatDate(this.date, 'gen', this.withMillis); 1387 this.hV = stohex(this.s); 1388 } 1389 return this.hV; 1390 }; 1391 1392 if (params !== undefined) { 1393 if (params.str !== undefined) { 1394 this.setString(params.str); 1395 } else if (typeof params == "string" && params.match(/^[0-9]{14}Z$/)) { 1396 this.setString(params); 1397 } else if (params.hex !== undefined) { 1398 this.setStringHex(params.hex); 1399 } else if (params.date !== undefined) { 1400 this.setByDate(params.date); 1401 } 1402 if (params.millis === true) { 1403 this.withMillis = true; 1404 } 1405 } 1406 }; 1407 YAHOO.lang.extend(KJUR.asn1.DERGeneralizedTime, KJUR.asn1.DERAbstractTime); 1408 1409 // ******************************************************************** 1410 /** 1411 * class for ASN.1 DER Sequence 1412 * @name KJUR.asn1.DERSequence 1413 * @class class for ASN.1 DER Sequence 1414 * @extends KJUR.asn1.DERAbstractStructured 1415 * @description 1416 * <br/> 1417 * As for argument 'params' for constructor, you can specify one of 1418 * following properties: 1419 * <ul> 1420 * <li>array - specify array of ASN1Object to set elements of content</li> 1421 * </ul> 1422 * NOTE: 'params' can be omitted. 1423 */ 1424 KJUR.asn1.DERSequence = function(params) { 1425 KJUR.asn1.DERSequence.superclass.constructor.call(this, params); 1426 this.hT = "30"; 1427 this.getFreshValueHex = function() { 1428 var h = ''; 1429 for (var i = 0; i < this.asn1Array.length; i++) { 1430 var asn1Obj = this.asn1Array[i]; 1431 h += asn1Obj.getEncodedHex(); 1432 } 1433 this.hV = h; 1434 return this.hV; 1435 }; 1436 }; 1437 YAHOO.lang.extend(KJUR.asn1.DERSequence, KJUR.asn1.DERAbstractStructured); 1438 1439 // ******************************************************************** 1440 /** 1441 * class for ASN.1 DER Set 1442 * @name KJUR.asn1.DERSet 1443 * @class class for ASN.1 DER Set 1444 * @extends KJUR.asn1.DERAbstractStructured 1445 * @description 1446 * <br/> 1447 * As for argument 'params' for constructor, you can specify one of 1448 * following properties: 1449 * <ul> 1450 * <li>array - specify array of ASN1Object to set elements of content</li> 1451 * <li>sortflag - flag for sort (default: true). ASN.1 BER is not sorted in 'SET OF'.</li> 1452 * </ul> 1453 * NOTE1: 'params' can be omitted.<br/> 1454 * NOTE2: sortflag is supported since 1.0.5. 1455 */ 1456 KJUR.asn1.DERSet = function(params) { 1457 KJUR.asn1.DERSet.superclass.constructor.call(this, params); 1458 this.hT = "31"; 1459 this.sortFlag = true; // item shall be sorted only in ASN.1 DER 1460 this.getFreshValueHex = function() { 1461 var a = new Array(); 1462 for (var i = 0; i < this.asn1Array.length; i++) { 1463 var asn1Obj = this.asn1Array[i]; 1464 a.push(asn1Obj.getEncodedHex()); 1465 } 1466 if (this.sortFlag == true) a.sort(); 1467 this.hV = a.join(''); 1468 return this.hV; 1469 }; 1470 1471 if (typeof params != "undefined") { 1472 if (typeof params.sortflag != "undefined" && 1473 params.sortflag == false) 1474 this.sortFlag = false; 1475 } 1476 }; 1477 YAHOO.lang.extend(KJUR.asn1.DERSet, KJUR.asn1.DERAbstractStructured); 1478 1479 // ******************************************************************** 1480 /** 1481 * class for ASN.1 DER TaggedObject 1482 * @name KJUR.asn1.DERTaggedObject 1483 * @class class for ASN.1 DER TaggedObject 1484 * @extends KJUR.asn1.ASN1Object 1485 * @description 1486 * <br/> 1487 * Parameter 'tagNoNex' is ASN.1 tag(T) value for this object. 1488 * For example, if you find '[1]' tag in a ASN.1 dump, 1489 * 'tagNoHex' will be 'a1'. 1490 * <br/> 1491 * As for optional argument 'params' for constructor, you can specify *ANY* of 1492 * following properties: 1493 * <ul> 1494 * <li>explicit - specify true if this is explicit tag otherwise false 1495 * (default is 'true').</li> 1496 * <li>tag - specify tag (default is 'a0' which means [0])</li> 1497 * <li>obj - specify ASN1Object which is tagged</li> 1498 * </ul> 1499 * @example 1500 * d1 = new KJUR.asn1.DERUTF8String({'str':'a'}); 1501 * d2 = new KJUR.asn1.DERTaggedObject({'obj': d1}); 1502 * hex = d2.getEncodedHex(); 1503 */ 1504 KJUR.asn1.DERTaggedObject = function(params) { 1505 KJUR.asn1.DERTaggedObject.superclass.constructor.call(this); 1506 this.hT = "a0"; 1507 this.hV = ''; 1508 this.isExplicit = true; 1509 this.asn1Object = null; 1510 1511 /** 1512 * set value by an ASN1Object 1513 * @name setString 1514 * @memberOf KJUR.asn1.DERTaggedObject 1515 * @function 1516 * @param {Boolean} isExplicitFlag flag for explicit/implicit tag 1517 * @param {Integer} tagNoHex hexadecimal string of ASN.1 tag 1518 * @param {ASN1Object} asn1Object ASN.1 to encapsulate 1519 */ 1520 this.setASN1Object = function(isExplicitFlag, tagNoHex, asn1Object) { 1521 this.hT = tagNoHex; 1522 this.isExplicit = isExplicitFlag; 1523 this.asn1Object = asn1Object; 1524 if (this.isExplicit) { 1525 this.hV = this.asn1Object.getEncodedHex(); 1526 this.hTLV = null; 1527 this.isModified = true; 1528 } else { 1529 this.hV = null; 1530 this.hTLV = asn1Object.getEncodedHex(); 1531 this.hTLV = this.hTLV.replace(/^../, tagNoHex); 1532 this.isModified = false; 1533 } 1534 }; 1535 1536 this.getFreshValueHex = function() { 1537 return this.hV; 1538 }; 1539 1540 if (typeof params != "undefined") { 1541 if (typeof params['tag'] != "undefined") { 1542 this.hT = params['tag']; 1543 } 1544 if (typeof params['explicit'] != "undefined") { 1545 this.isExplicit = params['explicit']; 1546 } 1547 if (typeof params['obj'] != "undefined") { 1548 this.asn1Object = params['obj']; 1549 this.setASN1Object(this.isExplicit, this.hT, this.asn1Object); 1550 } 1551 } 1552 }; 1553 YAHOO.lang.extend(KJUR.asn1.DERTaggedObject, KJUR.asn1.ASN1Object); 1554