1/* 2* jCryption JavaScript data encryption v3.1.0 3* http://www.jcryption.org/ 4* 5* Copyright (c) 2013 Daniel Griesser 6* MIT license. 7* http://www.opensource.org/licenses/mit-license.php 8* 9* If you need any further information about this plugin please 10* visit my homepage or contact me under [email protected] 11*/ 12(function($) { 13 $.jCryption = function(el, options) { 14 var base = this; 15 16 base.$el = $(el); 17 base.el = el; 18 19 base.$el.data("jCryption", base); 20 base.$el.data("key", null); 21 22 base.init = function() { 23 base.options = $.extend({}, $.jCryption.defaultOptions, options); 24 25 $encryptedElement = $("<input />",{ 26 type:'hidden', 27 name:base.options.postVariable 28 }); 29 30 if (base.options.submitElement !== false) { 31 var $submitElement = base.options.submitElement; 32 } else { 33 var $submitElement = base.$el.find(":input:submit"); 34 } 35 36 $submitElement.bind(base.options.submitEvent, function() { 37 $(this).attr("disabled", true); 38 if (base.options.beforeEncryption()) { 39 base.authenticate( 40 function(AESEncryptionKey) { 41 var toEncrypt = base.$el.serialize(); 42 if ($submitElement.is(":submit")) { 43 toEncrypt = toEncrypt + "&" + $submitElement.attr("name") + "=" + $submitElement.val(); 44 } 45 $encryptedElement.val($.jCryption.encrypt(toEncrypt, AESEncryptionKey)); 46 $(base.$el).find(base.options.formFieldSelector) 47 .attr("disabled", true).end() 48 .append($encryptedElement).submit(); 49 }, 50 function() { 51 // Authentication with AES Failed ... sending form without protection 52 confirm("Authentication with Server failed, are you sure you want to submit this form unencrypted?", function() { 53 $(base.$el).submit(); 54 }); 55 } 56 ); 57 } 58 return false; 59 }); 60 }; 61 62 base.init(); 63 64 /** 65 * Creates a random string(key) for use in the AES algorithm 66 */ 67 base.getKey = function() { 68 if (base.$el.data("key") !== null) { 69 return base.$el.data("key"); 70 } 71 72 var key; 73 74 if (window.crypto && window.crypto.getRandomValues) { 75 var ckey = new Uint32Array(8); 76 window.crypto.getRandomValues(ckey); 77 key = CryptoJS.lib.WordArray.create(ckey); 78 } else { 79 key = CryptoJS.lib.WordArray.random(128/4); 80 } 81 82 var salt = CryptoJS.lib.WordArray.random(128/8); 83 base.$el.data("key", key.toString()); 84 return base.getKey(); 85 }; 86 87 /** 88 * Authenticate with the server (One way) 89 * @param {function} success The function to call if the operation was successfull 90 * @param {function} failure The function to call if an error has occurred 91 */ 92 base.authenticate = function(success, failure) { 93 var key = base.getKey(); 94 $.jCryption.authenticate(key, base.options.getKeysURL, base.options.handshakeURL, success, failure); 95 }; 96 }; 97 98 /** 99 * Authenticates with the server 100 * @param {string} AESEncryptionKey The AES key 101 * @param {string} publicKeyURL The public key URL 102 * @param {string} handshakeURL The handshake URL 103 * @param {function} success The function to call if the operation was successfull 104 * @param {function} failure The function to call if an error has occurred 105 */ 106 $.jCryption.authenticate = function(AESEncryptionKey, publicKeyURL, handshakeURL, success, failure) { 107 $.jCryption.getPublicKey(publicKeyURL, function() { 108 $.jCryption.encryptKey(AESEncryptionKey, function(encryptedKey) { 109 $.jCryption.handshake(handshakeURL, encryptedKey, function(response) { 110 if ($.jCryption.challenge(response.challenge, AESEncryptionKey)) { 111 success.call(this, AESEncryptionKey); 112 } else { 113 failure.call(this); 114 } 115 }); 116 }); 117 }); 118 }; 119 120 /** 121 * Gets the RSA keys from the specified url, and saves it into a RSA keypair 122 * @param {string} url The url to contact 123 * @param {function} callback The function to call when the operation has finshed 124 */ 125 $.jCryption.getPublicKey = function(url, callback) { 126 $.getJSON(url, function(data) { 127 $.jCryption.crypt.setKey(data.publickey); 128 if($.isFunction(callback)) { 129 callback.call(this); 130 } 131 }); 132 }; 133 134 /** 135 * Decrypts data using AES 256 136 * @param {string} data The data to decrypt(Ciphertext) 137 * @param {string} secret The AES secret 138 * @returns {string} The result of the decryption(Plaintext) 139 */ 140 $.jCryption.decrypt = function(data, secret) { 141 return $.jCryption.hex2string(CryptoJS.AES.decrypt(data, secret) + ""); 142 }; 143 144 /** 145 * Encrypts data using AES 256 146 * @param {string} data The data to encrypt(Plaintext) 147 * @param {string} secret The AES secret 148 * @returns {string} The result of the encryption(Ciphertext) 149 */ 150 $.jCryption.encrypt = function(data, secret) {
151 return CryptoJS.AES.encrypt(data, secret) + ""; 152 }; 153 154 /** 155 * Makes sure that the challenge the client sent, is correct 156 * @param {string} challenge The challenge string 157 * @param {string} secret The AES secret 158 */ 159 $.jCryption.challenge = function(challenge, secret) { 160 var decrypt = $.jCryption.decrypt(challenge, secret); 161 if (decrypt == secret) { 162 return true; 163 } 164 return false; 165 }; 166 167 168 /** 169 * Converts a hex into a string 170 * @param {hex} string representing a hex number 171 * @returns {string} ASCII sting of input hex 172 */ 173 $.jCryption.hex2string = function(hex) { 174 var str = ''; 175 for (var i = 0; i < hex.length; i += 2) { 176 str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); 177 } 178 return str; 179 }; 180 181 /** 182 * Executes a handshake with the server 183 * @param {string} url The url to connect to 184 * @param {string} ecrypted The encrypted AES secret 185 * @param {function} callback The function to call when the handshaking has finished 186 */ 187 $.jCryption.handshake = function(url, ecrypted, callback) { 188 $.ajax({ 189 url: url, 190 dataType: "json", 191 type: "POST", 192 data: { 193 key: ecrypted 194 }, 195 success: function(response) { 196 callback.call(this, response); 197 } 198 }); 199 }; 200 201 /** 202 * Encrypts the AES secret using RSA 203 * @param {string} secret The AES secret 204 * @param {function} callback The function to call when the encryption has finished 205 */ 206 $.jCryption.encryptKey = function(secret, callback) { 207 var encryptedString = $.jCryption.crypt.encrypt(secret); 208 if($.isFunction(callback)) { 209 callback(encryptedString); 210 } else { 211 return encryptedString; 212 } 213 }; 214 215 $.jCryption.defaultOptions = { 216 submitElement: false, 217 submitEvent: "click", 218 getKeysURL: "jcryption.php?getPublicKey=true", 219 handshakeURL: "jcryption.php?handshake=true", 220 beforeEncryption: function() { return true }, 221 postVariable: "jCryption", 222 formFieldSelector: ":input" 223 }; 224 225 $.fn.jCryption = function(options) { 226 return this.each(function(){ 227 (new $.jCryption(this, options)); 228 }); 229 }; 230 231})(jQuery); 232 233 234var JSEncryptExports = {}; 235(function(exports) { 236// Copyright (c) 2005 Tom Wu 237// All Rights Reserved. 238// See "LICENSE" for details. 239 240// Basic JavaScript BN library - subset useful for RSA encryption. 241 242// Bits per digit 243var dbits; 244 245// JavaScript engine analysis 246var canary = 0xdeadbeefcafe; 247var j_lm = ((canary&0xffffff)==0xefcafe); 248 249// (public) Constructor 250function BigInteger(a,b,c) { 251 if(a != null) 252 if("number" == typeof a) this.fromNumber(a,b,c); 253 else if(b == null && "string" != typeof a) this.fromString(a,256); 254 else this.fromString(a,b); 255} 256 257// return new, unset BigInteger 258function nbi() { return new BigInteger(null); } 259 260// am: Compute w_j += (x*this_i), propagate carries, 261// c is initial carry, returns final carry. 262// c < 3*dvalue, x < 2*dvalue, this_i < dvalue 263// We need to select the fastest one that works in this environment. 264 265// am1: use a single mult and divide to get the high bits, 266// max digit bits should be 26 because 267// max internal value = 2*dvalue^2-2*dvalue (< 2^53) 268function am1(i,x,w,j,c,n) { 269 while(--n >= 0) { 270 var v = x*this[i++]+w[j]+c; 271 c = Math.floor(v/0x4000000); 272 w[j++] = v&0x3ffffff; 273 } 274 return c; 275} 276// am2 avoids a big mult-and-extract completely. 277// Max digit bits should be <= 30 because we do bitwise ops 278// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) 279function am2(i,x,w,j,c,n) { 280 var xl = x&0x7fff, xh = x>>15; 281 while(--n >= 0) { 282 var l = this[i]&0x7fff; 283 var h = this[i++]>>15; 284 var m = xh*l+h*xl; 285 l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); 286 c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); 287 w[j++] = l&0x3fffffff; 288 } 289 return c; 290} 291// Alternately, set max digit bits to 28 since some 292// browsers slow down when dealing with 32-bit numbers. 293function am3(i,x,w,j,c,n) { 294 var xl = x&0x3fff, xh = x>>14; 295 while(--n >= 0) { 296 var l = this[i]&0x3fff; 297 var h = this[i++]>>14; 298 var m = xh*l+h*xl; 299 l = xl*l+((m&0x3fff)<<14)+w[j]+c; 300 c = (l>>28)+(m>>14)+xh*h; 301 w[j++] = l&0xfffffff; 302 } 303 return c; 304} 305if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { 306 BigInteger.prototype.am = am2; 307 dbits = 30; 308} 309else if(j_lm && (navigator.appName != "Netscape")) { 310 BigInteger.prototype.am = am1; 311 dbits = 26; 312} 313else { // Mozilla/Netscape seems to prefer am3 314 BigInteger.prototype.am = am3; 315 dbits = 28; 316} 317 318BigInteger.prototype.DB = dbits; 319BigInteger.prototype.DM = ((1<<dbits)-1); 320BigInteger.prototype.DV = (1<<dbits); 321 322var BI_FP = 52; 323BigInteger.prototype.FV = Math.pow(2,BI_FP); 324BigInteger.prototype.F1 = BI_FP-dbits; 325BigInteger.prototype.F2 = 2*dbits-BI_FP; 326 327// Digit conversions 328var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; 329var BI_RC = new Array(); 330var rr,vv; 331rr = "0".charCodeAt(0); 332for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; 333rr = "a".charCodeAt(0); 334for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; 335rr = "A".charCodeAt(0); 336for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; 337 338function int2char(n) { return BI_RM.charAt(n); } 339function intAt(s,i) {
vendor: 28,444 bytes, lines 340-1382
340 var c = BI_RC[s.charCodeAt(i)]; 341 return (c==null)?-1:c; 342} 343 344// (protected) copy this to r 345function bnpCopyTo(r) { 346 for(var i = this.t-1; i >= 0; --i) r[i] = this[i]; 347 r.t = this.t; 348 r.s = this.s; 349} 350 351// (protected) set from integer value x, -DV <= x < DV 352function bnpFromInt(x) { 353 this.t = 1; 354 this.s = (x<0)?-1:0; 355 if(x > 0) this[0] = x; 356 else if(x < -1) this[0] = x+DV; 357 else this.t = 0; 358} 359 360// return bigint initialized to value 361function nbv(i) { var r = nbi(); r.fromInt(i); return r; } 362 363// (protected) set from string and radix 364function bnpFromString(s,b) { 365 var k; 366 if(b == 16) k = 4; 367 else if(b == 8) k = 3; 368 else if(b == 256) k = 8; // byte array 369 else if(b == 2) k = 1; 370 else if(b == 32) k = 5; 371 else if(b == 4) k = 2; 372 else { this.fromRadix(s,b); return; } 373 this.t = 0; 374 this.s = 0; 375 var i = s.length, mi = false, sh = 0; 376 while(--i >= 0) { 377 var x = (k==8)?s[i]&0xff:intAt(s,i); 378 if(x < 0) { 379 if(s.charAt(i) == "-") mi = true; 380 continue; 381 } 382 mi = false; 383 if(sh == 0) 384 this[this.t++] = x; 385 else if(sh+k > this.DB) { 386 this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh; 387 this[this.t++] = (x>>(this.DB-sh)); 388 } 389 else 390 this[this.t-1] |= x<<sh; 391 sh += k; 392 if(sh >= this.DB) sh -= this.DB; 393 } 394 if(k == 8 && (s[0]&0x80) != 0) { 395 this.s = -1; 396 if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh; 397 } 398 this.clamp(); 399 if(mi) BigInteger.ZERO.subTo(this,this); 400} 401 402// (protected) clamp off excess high words 403function bnpClamp() { 404 var c = this.s&this.DM; 405 while(this.t > 0 && this[this.t-1] == c) --this.t; 406} 407 408// (public) return string representation in given radix 409function bnToString(b) { 410 if(this.s < 0) return "-"+this.negate().toString(b); 411 var k; 412 if(b == 16) k = 4; 413 else if(b == 8) k = 3; 414 else if(b == 2) k = 1; 415 else if(b == 32) k = 5; 416 else if(b == 4) k = 2; 417 else return this.toRadix(b); 418 var km = (1<<k)-1, d, m = false, r = "", i = this.t; 419 var p = this.DB-(i*this.DB)%k; 420 if(i-- > 0) { 421 if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } 422 while(i >= 0) { 423 if(p < k) { 424 d = (this[i]&((1<<p)-1))<<(k-p); 425 d |= this[--i]>>(p+=this.DB-k); 426 } 427 else { 428 d = (this[i]>>(p-=k))&km; 429 if(p <= 0) { p += this.DB; --i; } 430 } 431 if(d > 0) m = true; 432 if(m) r += int2char(d); 433 } 434 } 435 return m?r:"0"; 436} 437 438// (public) -this 439function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } 440 441// (public) |this| 442function bnAbs() { return (this.s<0)?this.negate():this; } 443 444// (public) return + if this > a, - if this < a, 0 if equal 445function bnCompareTo(a) { 446 var r = this.s-a.s; 447 if(r != 0) return r; 448 var i = this.t; 449 r = i-a.t; 450 if(r != 0) return (this.s<0)?-r:r; 451 while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; 452 return 0; 453} 454 455// returns bit length of the integer x 456function nbits(x) { 457 var r = 1, t; 458 if((t=x>>>16) != 0) { x = t; r += 16; } 459 if((t=x>>8) != 0) { x = t; r += 8; } 460 if((t=x>>4) != 0) { x = t; r += 4; } 461 if((t=x>>2) != 0) { x = t; r += 2; } 462 if((t=x>>1) != 0) { x = t; r += 1; } 463 return r; 464} 465 466// (public) return the number of bits in "this" 467function bnBitLength() { 468 if(this.t <= 0) return 0; 469 return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); 470} 471 472// (protected) r = this << n*DB 473function bnpDLShiftTo(n,r) { 474 var i; 475 for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; 476 for(i = n-1; i >= 0; --i) r[i] = 0; 477 r.t = this.t+n; 478 r.s = this.s; 479} 480 481// (protected) r = this >> n*DB 482function bnpDRShiftTo(n,r) { 483 for(var i = n; i < this.t; ++i) r[i-n] = this[i]; 484 r.t = Math.max(this.t-n,0); 485 r.s = this.s; 486} 487 488// (protected) r = this << n 489function bnpLShiftTo(n,r) { 490 var bs = n%this.DB; 491 var cbs = this.DB-bs; 492 var bm = (1<<cbs)-1; 493 var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i; 494 for(i = this.t-1; i >= 0; --i) { 495 r[i+ds+1] = (this[i]>>cbs)|c; 496 c = (this[i]&bm)<<bs; 497 } 498 for(i = ds-1; i >= 0; --i) r[i] = 0; 499 r[ds] = c; 500 r.t = this.t+ds+1; 501 r.s = this.s; 502 r.clamp(); 503} 504 505// (protected) r = this >> n 506function bnpRShiftTo(n,r) { 507 r.s = this.s; 508 var ds = Math.floor(n/this.DB); 509 if(ds >= this.t) { r.t = 0; return; } 510 var bs = n%this.DB; 511 var cbs = this.DB-bs; 512 var bm = (1<<bs)-1; 513 r[0] = this[ds]>>bs; 514 for(var i = ds+1; i < this.t; ++i) { 515 r[i-ds-1] |= (this[i]&bm)<<cbs; 516 r[i-ds] = this[i]>>bs; 517 } 518 if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs; 519 r.t = this.t-ds; 520 r.clamp(); 521} 522 523// (protected) r = this - a 524function bnpSubTo(a,r) { 525 var i = 0, c = 0, m = Math.min(a.t,this.t); 526 while(i < m) { 527 c += this[i]-a[i]; 528 r[i++] = c&this.DM; 529 c >>= this.DB; 530 } 531 if(a.t < this.t) { 532 c -= a.s; 533 while(i < this.t) { 534 c += this[i]; 535 r[i++] = c&this.DM; 536 c >>= this.DB; 537 } 538 c += this.s; 539 } 540 else { 541 c += this.s; 542 while(i < a.t) { 543 c -= a[i]; 544 r[i++] = c&this.DM; 545 c >>= this.DB; 546 } 547 c -= a.s; 548 } 549 r.s = (c<0)?-1:0; 550 if(c < -1) r[i++] = this.DV+c; 551 else if(c > 0) r[i++] = c; 552 r.t = i; 553 r.clamp(); 554} 555 556// (protected) r = this * a, r != this,a (HAC 14.12) 557// "this" should be the larger one if appropriate. 558function bnpMultiplyTo(a,r) { 559 var x = this.abs(), y = a.abs(); 560 var i = x.t; 561 r.t = i+y.t; 562 while(--i >= 0) r[i] = 0; 563 for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); 564 r.s = 0; 565 r.clamp(); 566 if(this.s != a.s) BigInteger.ZERO.subTo(r,r); 567} 568 569// (protected) r = this^2, r != this (HAC 14.16) 570function bnpSquareTo(r) { 571 var x = this.abs(); 572 var i = r.t = 2*x.t; 573 while(--i >= 0) r[i] = 0; 574 for(i = 0; i < x.t-1; ++i) { 575 var c = x.am(i,x[i],r,2*i,0,1); 576 if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { 577 r[i+x.t] -= x.DV; 578 r[i+x.t+1] = 1; 579 } 580 } 581 if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); 582 r.s = 0; 583 r.clamp(); 584} 585 586// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) 587// r != q, this != m. q or r may be null. 588function bnpDivRemTo(m,q,r) { 589 var pm = m.abs(); 590 if(pm.t <= 0) return; 591 var pt = this.abs(); 592 if(pt.t < pm.t) { 593 if(q != null) q.fromInt(0); 594 if(r != null) this.copyTo(r); 595 return; 596 } 597 if(r == null) r = nbi(); 598 var y = nbi(), ts = this.s, ms = m.s; 599 var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus 600 if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } 601 else { pm.copyTo(y); pt.copyTo(r); } 602 var ys = y.t; 603 var y0 = y[ys-1]; 604 if(y0 == 0) return; 605 var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0); 606 var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2; 607 var i = r.t, j = i-ys, t = (q==null)?nbi():q; 608 y.dlShiftTo(j,t); 609 if(r.compareTo(t) >= 0) { 610 r[r.t++] = 1; 611 r.subTo(t,r); 612 } 613 BigInteger.ONE.dlShiftTo(ys,t); 614 t.subTo(y,y); // "negative" y so we can replace sub with am later 615 while(y.t < ys) y[y.t++] = 0; 616 while(--j >= 0) { 617 // Estimate quotient digit 618 var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); 619 if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out 620 y.dlShiftTo(j,t); 621 r.subTo(t,r); 622 while(r[i] < --qd) r.subTo(t,r); 623 } 624 } 625 if(q != null) { 626 r.drShiftTo(ys,q); 627 if(ts != ms) BigInteger.ZERO.subTo(q,q); 628 } 629 r.t = ys; 630 r.clamp(); 631 if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder 632 if(ts < 0) BigInteger.ZERO.subTo(r,r); 633} 634 635// (public) this mod a 636function bnMod(a) { 637 var r = nbi(); 638 this.abs().divRemTo(a,null,r); 639 if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); 640 return r; 641} 642 643// Modular reduction using "classic" algorithm 644function Classic(m) { this.m = m; } 645function cConvert(x) { 646 if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); 647 else return x; 648} 649function cRevert(x) { return x; } 650function cReduce(x) { x.divRemTo(this.m,null,x); } 651function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } 652function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } 653 654Classic.prototype.convert = cConvert; 655Classic.prototype.revert = cRevert; 656Classic.prototype.reduce = cReduce; 657Classic.prototype.mulTo = cMulTo; 658Classic.prototype.sqrTo = cSqrTo; 659 660// (protected) return "-1/this % 2^DB"; useful for Mont. reduction 661// justification: 662// xy == 1 (mod m) 663// xy = 1+km 664// xy(2-xy) = (1+km)(1-km) 665// x[y(2-xy)] = 1-k^2m^2 666// x[y(2-xy)] == 1 (mod m^2) 667// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 668// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. 669// JS multiply "overflows" differently from C/C++, so care is needed here. 670function bnpInvDigit() { 671 if(this.t < 1) return 0; 672 var x = this[0]; 673 if((x&1) == 0) return 0; 674 var y = x&3; // y == 1/x mod 2^2 675 y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 676 y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 677 y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 678 // last step - calculate inverse mod DV directly; 679 // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints 680 y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits 681 // we really want the negative inverse, and -DV < y < DV 682 return (y>0)?this.DV-y:-y; 683} 684 685// Montgomery reduction 686function Montgomery(m) { 687 this.m = m; 688 this.mp = m.invDigit(); 689 this.mpl = this.mp&0x7fff; 690 this.mph = this.mp>>15; 691 this.um = (1<<(m.DB-15))-1; 692 this.mt2 = 2*m.t; 693} 694 695// xR mod m 696function montConvert(x) { 697 var r = nbi(); 698 x.abs().dlShiftTo(this.m.t,r); 699 r.divRemTo(this.m,null,r); 700 if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); 701 return r; 702} 703 704// x/R mod m 705function montRevert(x) { 706 var r = nbi(); 707 x.copyTo(r); 708 this.reduce(r); 709 return r; 710} 711 712// x = x/R mod m (HAC 14.32) 713function montReduce(x) { 714 while(x.t <= this.mt2) // pad x so am has enough room later 715 x[x.t++] = 0; 716 for(var i = 0; i < this.m.t; ++i) { 717 // faster way of calculating u0 = x[i]*mp mod DV 718 var j = x[i]&0x7fff; 719 var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; 720 // use am to combine the multiply-shift-add into one call 721 j = i+this.m.t; 722 x[j] += this.m.am(0,u0,x,i,0,this.m.t); 723 // propagate carry 724 while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } 725 } 726 x.clamp(); 727 x.drShiftTo(this.m.t,x); 728 if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); 729} 730 731// r = "x^2/R mod m"; x != r 732function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } 733 734// r = "xy/R mod m"; x,y != r 735function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } 736 737Montgomery.prototype.convert = montConvert; 738Montgomery.prototype.revert = montRevert; 739Montgomery.prototype.reduce = montReduce; 740Montgomery.prototype.mulTo = montMulTo; 741Montgomery.prototype.sqrTo = montSqrTo; 742 743// (protected) true iff this is even 744function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } 745 746// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) 747function bnpExp(e,z) { 748 if(e > 0xffffffff || e < 1) return BigInteger.ONE; 749 var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; 750 g.copyTo(r); 751 while(--i >= 0) { 752 z.sqrTo(r,r2); 753 if((e&(1<<i)) > 0) z.mulTo(r2,g,r); 754 else { var t = r; r = r2; r2 = t; } 755 } 756 return z.revert(r); 757} 758 759// (public) this^e % m, 0 <= e < 2^32 760function bnModPowInt(e,m) { 761 var z; 762 if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); 763 return this.exp(e,z); 764} 765 766// protected 767BigInteger.prototype.copyTo = bnpCopyTo; 768BigInteger.prototype.fromInt = bnpFromInt; 769BigInteger.prototype.fromString = bnpFromString; 770BigInteger.prototype.clamp = bnpClamp; 771BigInteger.prototype.dlShiftTo = bnpDLShiftTo; 772BigInteger.prototype.drShiftTo = bnpDRShiftTo; 773BigInteger.prototype.lShiftTo = bnpLShiftTo; 774BigInteger.prototype.rShiftTo = bnpRShiftTo; 775BigInteger.prototype.subTo = bnpSubTo; 776BigInteger.prototype.multiplyTo = bnpMultiplyTo; 777BigInteger.prototype.squareTo = bnpSquareTo; 778BigInteger.prototype.divRemTo = bnpDivRemTo; 779BigInteger.prototype.invDigit = bnpInvDigit; 780BigInteger.prototype.isEven = bnpIsEven; 781BigInteger.prototype.exp = bnpExp; 782 783// public 784BigInteger.prototype.toString = bnToString; 785BigInteger.prototype.negate = bnNegate; 786BigInteger.prototype.abs = bnAbs; 787BigInteger.prototype.compareTo = bnCompareTo; 788BigInteger.prototype.bitLength = bnBitLength; 789BigInteger.prototype.mod = bnMod; 790BigInteger.prototype.modPowInt = bnModPowInt; 791 792// "constants" 793BigInteger.ZERO = nbv(0); 794BigInteger.ONE = nbv(1); 795// Copyright (c) 2005-2009 Tom Wu 796// All Rights Reserved. 797// See "LICENSE" for details. 798 799// Extended JavaScript BN functions, required for RSA private ops. 800 801// Version 1.1: new BigInteger("0", 10) returns "proper" zero 802// Version 1.2: square() API, isProbablePrime fix 803 804// (public) 805function bnClone() { var r = nbi(); this.copyTo(r); return r; } 806 807// (public) return value as integer 808function bnIntValue() { 809 if(this.s < 0) { 810 if(this.t == 1) return this[0]-this.DV; 811 else if(this.t == 0) return -1; 812 } 813 else if(this.t == 1) return this[0]; 814 else if(this.t == 0) return 0; 815 // assumes 16 < DB < 32 816 return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0]; 817} 818 819// (public) return value as byte 820function bnByteValue() { return (this.t==0)?this.s:(this[0]<<24)>>24; } 821 822// (public) return value as short (assumes DB>=16) 823function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } 824 825// (protected) return x s.t. r^x < DV 826function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } 827 828// (public) 0 if this == 0, 1 if this > 0 829function bnSigNum() { 830 if(this.s < 0) return -1; 831 else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; 832 else return 1; 833} 834 835// (protected) convert to radix string 836function bnpToRadix(b) { 837 if(b == null) b = 10; 838 if(this.signum() == 0 || b < 2 || b > 36) return "0"; 839 var cs = this.chunkSize(b); 840 var a = Math.pow(b,cs); 841 var d = nbv(a), y = nbi(), z = nbi(), r = ""; 842 this.divRemTo(d,y,z); 843 while(y.signum() > 0) { 844 r = (a+z.intValue()).toString(b).substr(1) + r; 845 y.divRemTo(d,y,z); 846 } 847 return z.intValue().toString(b) + r; 848} 849 850// (protected) convert from radix string 851function bnpFromRadix(s,b) { 852 this.fromInt(0); 853 if(b == null) b = 10; 854 var cs = this.chunkSize(b); 855 var d = Math.pow(b,cs), mi = false, j = 0, w = 0; 856 for(var i = 0; i < s.length; ++i) { 857 var x = intAt(s,i); 858 if(x < 0) { 859 if(s.charAt(i) == "-" && this.signum() == 0) mi = true; 860 continue; 861 } 862 w = b*w+x; 863 if(++j >= cs) { 864 this.dMultiply(d); 865 this.dAddOffset(w,0); 866 j = 0; 867 w = 0; 868 } 869 } 870 if(j > 0) { 871 this.dMultiply(Math.pow(b,j)); 872 this.dAddOffset(w,0); 873 } 874 if(mi) BigInteger.ZERO.subTo(this,this); 875} 876 877// (protected) alternate constructor 878function bnpFromNumber(a,b,c) { 879 if("number" == typeof b) { 880 // new BigInteger(int,int,RNG) 881 if(a < 2) this.fromInt(1); 882 else { 883 this.fromNumber(a,c); 884 if(!this.testBit(a-1)) // force MSB set 885 this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); 886 if(this.isEven()) this.dAddOffset(1,0); // force odd 887 while(!this.isProbablePrime(b)) { 888 this.dAddOffset(2,0); 889 if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); 890 } 891 } 892 } 893 else { 894 // new BigInteger(int,RNG) 895 var x = new Array(), t = a&7; 896 x.length = (a>>3)+1; 897 b.nextBytes(x); 898 if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0; 899 this.fromString(x,256); 900 } 901} 902 903// (public) convert to bigendian byte array 904function bnToByteArray() { 905 var i = this.t, r = new Array(); 906 r[0] = this.s; 907 var p = this.DB-(i*this.DB)%8, d, k = 0; 908 if(i-- > 0) { 909 if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) 910 r[k++] = d|(this.s<<(this.DB-p)); 911 while(i >= 0) { 912 if(p < 8) { 913 d = (this[i]&((1<<p)-1))<<(8-p); 914 d |= this[--i]>>(p+=this.DB-8); 915 } 916 else { 917 d = (this[i]>>(p-=8))&0xff; 918 if(p <= 0) { p += this.DB; --i; } 919 } 920 if((d&0x80) != 0) d |= -256; 921 if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; 922 if(k > 0 || d != this.s) r[k++] = d; 923 } 924 } 925 return r; 926} 927 928function bnEquals(a) { return(this.compareTo(a)==0); } 929function bnMin(a) { return(this.compareTo(a)<0)?this:a; } 930function bnMax(a) { return(this.compareTo(a)>0)?this:a; } 931 932// (protected) r = this op a (bitwise) 933function bnpBitwiseTo(a,op,r) { 934 var i, f, m = Math.min(a.t,this.t); 935 for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); 936 if(a.t < this.t) { 937 f = a.s&this.DM; 938 for(i = m; i < this.t; ++i) r[i] = op(this[i],f); 939 r.t = this.t; 940 } 941 else { 942 f = this.s&this.DM; 943 for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); 944 r.t = a.t; 945 } 946 r.s = op(this.s,a.s); 947 r.clamp(); 948} 949 950// (public) this & a 951function op_and(x,y) { return x&y; } 952function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } 953 954// (public) this | a 955function op_or(x,y) { return x|y; } 956function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } 957 958// (public) this ^ a 959function op_xor(x,y) { return x^y; } 960function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } 961 962// (public) this & ~a 963function op_andnot(x,y) { return x&~y; } 964function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } 965 966// (public) ~this 967function bnNot() { 968 var r = nbi(); 969 for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; 970 r.t = this.t; 971 r.s = ~this.s; 972 return r; 973} 974 975// (public) this << n 976function bnShiftLeft(n) { 977 var r = nbi(); 978 if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); 979 return r; 980} 981 982// (public) this >> n 983function bnShiftRight(n) { 984 var r = nbi(); 985 if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); 986 return r; 987} 988 989// return index of lowest 1-bit in x, x < 2^31 990function lbit(x) { 991 if(x == 0) return -1; 992 var r = 0; 993 if((x&0xffff) == 0) { x >>= 16; r += 16; } 994 if((x&0xff) == 0) { x >>= 8; r += 8; } 995 if((x&0xf) == 0) { x >>= 4; r += 4; } 996 if((x&3) == 0) { x >>= 2; r += 2; } 997 if((x&1) == 0) ++r; 998 return r; 999} 1000 1001// (public) returns index of lowest 1-bit (or -1 if none) 1002function bnGetLowestSetBit() { 1003 for(var i = 0; i < this.t; ++i) 1004 if(this[i] != 0) return i*this.DB+lbit(this[i]); 1005 if(this.s < 0) return this.t*this.DB; 1006 return -1; 1007} 1008 1009// return number of 1 bits in x 1010function cbit(x) { 1011 var r = 0; 1012 while(x != 0) { x &= x-1; ++r; } 1013 return r; 1014} 1015 1016// (public) return number of set bits 1017function bnBitCount() { 1018 var r = 0, x = this.s&this.DM; 1019 for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); 1020 return r; 1021} 1022 1023// (public) true iff nth bit is set 1024function bnTestBit(n) { 1025 var j = Math.floor(n/this.DB); 1026 if(j >= this.t) return(this.s!=0); 1027 return((this[j]&(1<<(n%this.DB)))!=0); 1028} 1029 1030// (protected) this op (1<<n) 1031function bnpChangeBit(n,op) { 1032 var r = BigInteger.ONE.shiftLeft(n); 1033 this.bitwiseTo(r,op,r); 1034 return r; 1035} 1036 1037// (public) this | (1<<n) 1038function bnSetBit(n) { return this.changeBit(n,op_or); } 1039 1040// (public) this & ~(1<<n) 1041function bnClearBit(n) { return this.changeBit(n,op_andnot); } 1042 1043// (public) this ^ (1<<n) 1044function bnFlipBit(n) { return this.changeBit(n,op_xor); } 1045 1046// (protected) r = this + a 1047function bnpAddTo(a,r) { 1048 var i = 0, c = 0, m = Math.min(a.t,this.t); 1049 while(i < m) { 1050 c += this[i]+a[i]; 1051 r[i++] = c&this.DM; 1052 c >>= this.DB; 1053 } 1054 if(a.t < this.t) { 1055 c += a.s; 1056 while(i < this.t) { 1057 c += this[i]; 1058 r[i++] = c&this.DM; 1059 c >>= this.DB; 1060 } 1061 c += this.s; 1062 } 1063 else { 1064 c += this.s; 1065 while(i < a.t) { 1066 c += a[i]; 1067 r[i++] = c&this.DM; 1068 c >>= this.DB; 1069 } 1070 c += a.s; 1071 } 1072 r.s = (c<0)?-1:0; 1073 if(c > 0) r[i++] = c; 1074 else if(c < -1) r[i++] = this.DV+c; 1075 r.t = i; 1076 r.clamp(); 1077} 1078 1079// (public) this + a 1080function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } 1081 1082// (public) this - a 1083function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } 1084 1085// (public) this * a 1086function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } 1087 1088// (public) this^2 1089function bnSquare() { var r = nbi(); this.squareTo(r); return r; } 1090 1091// (public) this / a 1092function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } 1093 1094// (public) this % a 1095function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } 1096 1097// (public) [this/a,this%a] 1098function bnDivideAndRemainder(a) { 1099 var q = nbi(), r = nbi(); 1100 this.divRemTo(a,q,r); 1101 return new Array(q,r); 1102} 1103 1104// (protected) this *= n, this >= 0, 1 < n < DV 1105function bnpDMultiply(n) { 1106 this[this.t] = this.am(0,n-1,this,0,0,this.t); 1107 ++this.t; 1108 this.clamp(); 1109} 1110 1111// (protected) this += n << w words, this >= 0 1112function bnpDAddOffset(n,w) { 1113 if(n == 0) return; 1114 while(this.t <= w) this[this.t++] = 0; 1115 this[w] += n; 1116 while(this[w] >= this.DV) { 1117 this[w] -= this.DV; 1118 if(++w >= this.t) this[this.t++] = 0; 1119 ++this[w]; 1120 } 1121} 1122 1123// A "null" reducer 1124function NullExp() {} 1125function nNop(x) { return x; } 1126function nMulTo(x,y,r) { x.multiplyTo(y,r); } 1127function nSqrTo(x,r) { x.squareTo(r); } 1128 1129NullExp.prototype.convert = nNop; 1130NullExp.prototype.revert = nNop; 1131NullExp.prototype.mulTo = nMulTo; 1132NullExp.prototype.sqrTo = nSqrTo; 1133 1134// (public) this^e 1135function bnPow(e) { return this.exp(e,new NullExp()); } 1136 1137// (protected) r = lower n words of "this * a", a.t <= n 1138// "this" should be the larger one if appropriate. 1139function bnpMultiplyLowerTo(a,n,r) { 1140 var i = Math.min(this.t+a.t,n); 1141 r.s = 0; // assumes a,this >= 0 1142 r.t = i; 1143 while(i > 0) r[--i] = 0; 1144 var j; 1145 for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); 1146 for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); 1147 r.clamp(); 1148} 1149 1150// (protected) r = "this * a" without lower n words, n > 0 1151// "this" should be the larger one if appropriate. 1152function bnpMultiplyUpperTo(a,n,r) { 1153 --n; 1154 var i = r.t = this.t+a.t-n; 1155 r.s = 0; // assumes a,this >= 0 1156 while(--i >= 0) r[i] = 0; 1157 for(i = Math.max(n-this.t,0); i < a.t; ++i) 1158 r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); 1159 r.clamp(); 1160 r.drShiftTo(1,r); 1161} 1162 1163// Barrett modular reduction 1164function Barrett(m) { 1165 // setup Barrett 1166 this.r2 = nbi(); 1167 this.q3 = nbi(); 1168 BigInteger.ONE.dlShiftTo(2*m.t,this.r2); 1169 this.mu = this.r2.divide(m); 1170 this.m = m; 1171} 1172 1173function barrettConvert(x) { 1174 if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); 1175 else if(x.compareTo(this.m) < 0) return x; 1176 else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } 1177} 1178 1179function barrettRevert(x) { return x; } 1180 1181// x = x mod m (HAC 14.42) 1182function barrettReduce(x) { 1183 x.drShiftTo(this.m.t-1,this.r2); 1184 if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } 1185 this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); 1186 this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); 1187 while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); 1188 x.subTo(this.r2,x); 1189 while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); 1190} 1191 1192// r = x^2 mod m; x != r 1193function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } 1194 1195// r = x*y mod m; x,y != r 1196function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } 1197 1198Barrett.prototype.convert = barrettConvert; 1199Barrett.prototype.revert = barrettRevert; 1200Barrett.prototype.reduce = barrettReduce; 1201Barrett.prototype.mulTo = barrettMulTo; 1202Barrett.prototype.sqrTo = barrettSqrTo; 1203 1204// (public) this^e % m (HAC 14.85) 1205function bnModPow(e,m) { 1206 var i = e.bitLength(), k, r = nbv(1), z; 1207 if(i <= 0) return r; 1208 else if(i < 18) k = 1; 1209 else if(i < 48) k = 3; 1210 else if(i < 144) k = 4; 1211 else if(i < 768) k = 5; 1212 else k = 6; 1213 if(i < 8) 1214 z = new Classic(m); 1215 else if(m.isEven()) 1216 z = new Barrett(m); 1217 else 1218 z = new Montgomery(m); 1219 1220 // precomputation 1221 var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1; 1222 g[1] = z.convert(this); 1223 if(k > 1) { 1224 var g2 = nbi(); 1225 z.sqrTo(g[1],g2); 1226 while(n <= km) { 1227 g[n] = nbi(); 1228 z.mulTo(g2,g[n-2],g[n]); 1229 n += 2; 1230 } 1231 } 1232 1233 var j = e.t-1, w, is1 = true, r2 = nbi(), t; 1234 i = nbits(e[j])-1; 1235 while(j >= 0) { 1236 if(i >= k1) w = (e[j]>>(i-k1))&km; 1237 else { 1238 w = (e[j]&((1<<(i+1))-1))<<(k1-i); 1239 if(j > 0) w |= e[j-1]>>(this.DB+i-k1); 1240 } 1241 1242 n = k; 1243 while((w&1) == 0) { w >>= 1; --n; } 1244 if((i -= n) < 0) { i += this.DB; --j; } 1245 if(is1) { // ret == 1, don't bother squaring or multiplying it 1246 g[w].copyTo(r); 1247 is1 = false; 1248 } 1249 else { 1250 while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } 1251 if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } 1252 z.mulTo(r2,g[w],r); 1253 } 1254 1255 while(j >= 0 && (e[j]&(1<<i)) == 0) { 1256 z.sqrTo(r,r2); t = r; r = r2; r2 = t; 1257 if(--i < 0) { i = this.DB-1; --j; } 1258 } 1259 } 1260 return z.revert(r); 1261} 1262 1263// (public) gcd(this,a) (HAC 14.54) 1264function bnGCD(a) { 1265 var x = (this.s<0)?this.negate():this.clone(); 1266 var y = (a.s<0)?a.negate():a.clone(); 1267 if(x.compareTo(y) < 0) { var t = x; x = y; y = t; } 1268 var i = x.getLowestSetBit(), g = y.getLowestSetBit(); 1269 if(g < 0) return x; 1270 if(i < g) g = i; 1271 if(g > 0) { 1272 x.rShiftTo(g,x); 1273 y.rShiftTo(g,y); 1274 } 1275 while(x.signum() > 0) { 1276 if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); 1277 if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); 1278 if(x.compareTo(y) >= 0) { 1279 x.subTo(y,x); 1280 x.rShiftTo(1,x); 1281 } 1282 else { 1283 y.subTo(x,y); 1284 y.rShiftTo(1,y); 1285 } 1286 } 1287 if(g > 0) y.lShiftTo(g,y); 1288 return y; 1289} 1290 1291// (protected) this % n, n < 2^26 1292function bnpModInt(n) { 1293 if(n <= 0) return 0; 1294 var d = this.DV%n, r = (this.s<0)?n-1:0; 1295 if(this.t > 0) 1296 if(d == 0) r = this[0]%n; 1297 else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; 1298 return r; 1299} 1300 1301// (public) 1/this % m (HAC 14.61) 1302function bnModInverse(m) { 1303 var ac = m.isEven(); 1304 if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; 1305 var u = m.clone(), v = this.clone(); 1306 var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); 1307 while(u.signum() != 0) { 1308 while(u.isEven()) { 1309 u.rShiftTo(1,u); 1310 if(ac) { 1311 if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } 1312 a.rShiftTo(1,a); 1313 } 1314 else if(!b.isEven()) b.subTo(m,b); 1315 b.rShiftTo(1,b); 1316 } 1317 while(v.isEven()) { 1318 v.rShiftTo(1,v); 1319 if(ac) { 1320 if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } 1321 c.rShiftTo(1,c); 1322 } 1323 else if(!d.isEven()) d.subTo(m,d); 1324 d.rShiftTo(1,d); 1325 } 1326 if(u.compareTo(v) >= 0) { 1327 u.subTo(v,u); 1328 if(ac) a.subTo(c,a); 1329 b.subTo(d,b); 1330 } 1331 else { 1332 v.subTo(u,v); 1333 if(ac) c.subTo(a,c); 1334 d.subTo(b,d); 1335 } 1336 } 1337 if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; 1338 if(d.compareTo(m) >= 0) return d.subtract(m); 1339 if(d.signum() < 0) d.addTo(m,d); else return d; 1340 if(d.signum() < 0) return d.add(m); else return d; 1341} 1342 1343var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; 1344var lplim = (1<<26)/lowprimes[lowprimes.length-1]; 1345 1346// (public) test primality with certainty >= 1-.5^t 1347function bnIsProbablePrime(t) { 1348 var i, x = this.abs(); 1349 if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { 1350 for(i = 0; i < lowprimes.length; ++i) 1351 if(x[0] == lowprimes[i]) return true; 1352 return false; 1353 } 1354 if(x.isEven()) return false; 1355 i = 1; 1356 while(i < lowprimes.length) { 1357 var m = lowprimes[i], j = i+1; 1358 while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; 1359 m = x.modInt(m); 1360 while(i < j) if(m%lowprimes[i++] == 0) return false; 1361 } 1362 return x.millerRabin(t); 1363} 1364 1365// (protected) true if probably prime (HAC 4.24, Miller-Rabin) 1366function bnpMillerRabin(t) { 1367 var n1 = this.subtract(BigInteger.ONE); 1368 var k = n1.getLowestSetBit(); 1369 if(k <= 0) return false; 1370 var r = n1.shiftRight(k); 1371 t = (t+1)>>1; 1372 if(t > lowprimes.length) t = lowprimes.length; 1373 var a = nbi(); 1374 for(var i = 0; i < t; ++i) { 1375 //Pick bases at random, instead of starting at 2 1376 a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); 1377 var y = a.modPow(r,this); 1378 if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { 1379 var j = 1; 1380 while(j++ < k && y.compareTo(n1) != 0) { 1381 y = y.modPowInt(2,this); 1382 if(y.compareTo(BigInteger.ONE) == 0) return false;
1383 } 1384 if(y.compareTo(n1) != 0) return false; 1385 } 1386 } 1387 return true; 1388} 1389 1390// protected 1391BigInteger.prototype.chunkSize = bnpChunkSize; 1392BigInteger.prototype.toRadix = bnpToRadix; 1393BigInteger.prototype.fromRadix = bnpFromRadix; 1394BigInteger.prototype.fromNumber = bnpFromNumber; 1395BigInteger.prototype.bitwiseTo = bnpBitwiseTo; 1396BigInteger.prototype.changeBit = bnpChangeBit; 1397BigInteger.prototype.addTo = bnpAddTo; 1398BigInteger.prototype.dMultiply = bnpDMultiply; 1399BigInteger.prototype.dAddOffset = bnpDAddOffset; 1400BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; 1401BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; 1402BigInteger.prototype.modInt = bnpModInt; 1403BigInteger.prototype.millerRabin = bnpMillerRabin; 1404 1405// public 1406BigInteger.prototype.clone = bnClone; 1407BigInteger.prototype.intValue = bnIntValue; 1408BigInteger.prototype.byteValue = bnByteValue; 1409BigInteger.prototype.shortValue = bnShortValue; 1410BigInteger.prototype.signum = bnSigNum; 1411BigInteger.prototype.toByteArray = bnToByteArray; 1412BigInteger.prototype.equals = bnEquals; 1413BigInteger.prototype.min = bnMin; 1414BigInteger.prototype.max = bnMax; 1415BigInteger.prototype.and = bnAnd; 1416BigInteger.prototype.or = bnOr; 1417BigInteger.prototype.xor = bnXor; 1418BigInteger.prototype.andNot = bnAndNot; 1419BigInteger.prototype.not = bnNot; 1420BigInteger.prototype.shiftLeft = bnShiftLeft; 1421BigInteger.prototype.shiftRight = bnShiftRight; 1422BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; 1423BigInteger.prototype.bitCount = bnBitCount; 1424BigInteger.prototype.testBit = bnTestBit; 1425BigInteger.prototype.setBit = bnSetBit; 1426BigInteger.prototype.clearBit = bnClearBit; 1427BigInteger.prototype.flipBit = bnFlipBit; 1428BigInteger.prototype.add = bnAdd; 1429BigInteger.prototype.subtract = bnSubtract; 1430BigInteger.prototype.multiply = bnMultiply; 1431BigInteger.prototype.divide = bnDivide; 1432BigInteger.prototype.remainder = bnRemainder; 1433BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; 1434BigInteger.prototype.modPow = bnModPow; 1435BigInteger.prototype.modInverse = bnModInverse; 1436BigInteger.prototype.pow = bnPow; 1437BigInteger.prototype.gcd = bnGCD; 1438BigInteger.prototype.isProbablePrime = bnIsProbablePrime; 1439 1440// JSBN-specific extension 1441BigInteger.prototype.square = bnSquare; 1442 1443// BigInteger interfaces not implemented in jsbn: 1444 1445// BigInteger(int signum, byte[] magnitude) 1446// double doubleValue() 1447// float floatValue() 1448// int hashCode() 1449// long longValue() 1450// static BigInteger valueOf(long val) 1451// prng4.js - uses Arcfour as a PRNG 1452 1453function Arcfour() { 1454 this.i = 0; 1455 this.j = 0; 1456 this.S = new Array(); 1457} 1458 1459// Initialize arcfour context from key, an array of ints, each from [0..255] 1460function ARC4init(key) { 1461 var i, j, t; 1462 for(i = 0; i < 256; ++i) 1463 this.S[i] = i; 1464 j = 0; 1465 for(i = 0; i < 256; ++i) { 1466 j = (j + this.S[i] + key[i % key.length]) & 255; 1467 t = this.S[i]; 1468 this.S[i] = this.S[j]; 1469 this.S[j] = t; 1470 } 1471 this.i = 0; 1472 this.j = 0; 1473} 1474 1475function ARC4next() { 1476 var t; 1477 this.i = (this.i + 1) & 255; 1478 this.j = (this.j + this.S[this.i]) & 255; 1479 t = this.S[this.i]; 1480 this.S[this.i] = this.S[this.j]; 1481 this.S[this.j] = t; 1482 return this.S[(t + this.S[this.i]) & 255]; 1483} 1484 1485Arcfour.prototype.init = ARC4init; 1486Arcfour.prototype.next = ARC4next; 1487 1488// Plug in your RNG constructor here 1489function prng_newstate() { 1490 return new Arcfour(); 1491} 1492 1493// Pool size must be a multiple of 4 and greater than 32. 1494// An array of bytes the size of the pool will be passed to init() 1495var rng_psize = 256; 1496// Random number generator - requires a PRNG backend, e.g. prng4.js 1497 1498// For best results, put code like 1499// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'> 1500// in your main HTML document. 1501 1502var rng_state; 1503var rng_pool; 1504var rng_pptr; 1505 1506// Mix in a 32-bit integer into the pool 1507function rng_seed_int(x) { 1508 rng_pool[rng_pptr++] ^= x & 255; 1509 rng_pool[rng_pptr++] ^= (x >> 8) & 255; 1510 rng_pool[rng_pptr++] ^= (x >> 16) & 255; 1511 rng_pool[rng_pptr++] ^= (x >> 24) & 255; 1512 if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; 1513} 1514 1515// Mix in the current time (w/milliseconds) into the pool 1516function rng_seed_time() { 1517 rng_seed_int(new Date().getTime()); 1518} 1519 1520// Initialize the pool with junk if needed. 1521if(rng_pool == null) { 1522 rng_pool = new Array(); 1523 rng_pptr = 0; 1524 var t; 1525 if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { 1526 // Extract entropy (256 bits) from NS4 RNG if available 1527 var z = window.crypto.random(32); 1528 for(t = 0; t < z.length; ++t) 1529 rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; 1530 } 1531 while(rng_pptr < rng_psize) { // extract some randomness from Math.random() 1532 t = Math.floor(65536 * Math.random()); 1533 rng_pool[rng_pptr++] = t >>> 8; 1534 rng_pool[rng_pptr++] = t & 255; 1535 } 1536 rng_pptr = 0; 1537 rng_seed_time(); 1538 //rng_seed_int(window.screenX); 1539 //rng_seed_int(window.screenY); 1540} 1541 1542function rng_get_byte() { 1543 if(rng_state == null) { 1544 rng_seed_time(); 1545 rng_state = prng_newstate(); 1546 rng_state.init(rng_pool); 1547 for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) 1548 rng_pool[rng_pptr] = 0; 1549 rng_pptr = 0; 1550 //rng_pool = null; 1551 } 1552 // TODO: allow reseeding after first request 1553 return rng_state.next(); 1554} 1555 1556function rng_get_bytes(ba) { 1557 var i; 1558 for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); 1559} 1560 1561function SecureRandom() {} 1562 1563SecureRandom.prototype.nextBytes = rng_get_bytes; 1564// Depends on jsbn.js and rng.js 1565 1566// Version 1.1: support utf-8 encoding in pkcs1pad2 1567 1568// convert a (hex) string to a bignum object 1569function parseBigInt(str,r) { 1570 return new BigInteger(str,r); 1571} 1572 1573function linebrk(s,n) { 1574 var ret = ""; 1575 var i = 0; 1576 while(i + n < s.length) { 1577 ret += s.substring(i,i+n) + "\n"; 1578 i += n; 1579 } 1580 return ret + s.substring(i,s.length); 1581} 1582 1583function byte2Hex(b) { 1584 if(b < 0x10) 1585 return "0" + b.toString(16); 1586 else 1587 return b.toString(16); 1588} 1589 1590// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint 1591function pkcs1pad2(s,n) {
1592 if(n < s.length + 11) { // TODO: fix for utf-8 1593 console.error("Message too long for RSA"); 1594 return null; 1595 } 1596 var ba = new Array(); 1597 var i = s.length - 1; 1598 while(i >= 0 && n > 0) { 1599 var c = s.charCodeAt(i--); 1600 if(c < 128) { // encode using utf-8 1601 ba[--n] = c; 1602 } 1603 else if((c > 127) && (c < 2048)) { 1604 ba[--n] = (c & 63) | 128; 1605 ba[--n] = (c >> 6) | 192; 1606 } 1607 else { 1608 ba[--n] = (c & 63) | 128; 1609 ba[--n] = ((c >> 6) & 63) | 128; 1610 ba[--n] = (c >> 12) | 224; 1611 } 1612 } 1613 ba[--n] = 0; 1614 var rng = new SecureRandom(); 1615 var x = new Array(); 1616 while(n > 2) { // random non-zero pad 1617 x[0] = 0; 1618 while(x[0] == 0) rng.nextBytes(x); 1619 ba[--n] = x[0]; 1620 } 1621 ba[--n] = 2; 1622 ba[--n] = 0; 1623 return new BigInteger(ba); 1624} 1625 1626// "empty" RSA key constructor 1627function RSAKey() { 1628 this.n = null; 1629 this.e = 0; 1630 this.d = null; 1631 this.p = null; 1632 this.q = null; 1633 this.dmp1 = null; 1634 this.dmq1 = null; 1635 this.coeff = null; 1636} 1637 1638// Set the public key fields N and e from hex strings 1639function RSASetPublic(N,E) { 1640 if(N != null && E != null && N.length > 0 && E.length > 0) { 1641 this.n = parseBigInt(N,16); 1642 this.e = parseInt(E,16); 1643 } 1644 else 1645 console.error("Invalid RSA public key"); 1646} 1647 1648// Perform raw public operation on "x": return x^e (mod n) 1649function RSADoPublic(x) { 1650 return x.modPowInt(this.e, this.n); 1651} 1652 1653// Return the PKCS#1 RSA encryption of "text" as an even-length hex string 1654function RSAEncrypt(text) { 1655 var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3); 1656 if(m == null) return null; 1657 var c = this.doPublic(m); 1658 if(c == null) return null; 1659 var h = c.toString(16); 1660 if((h.length & 1) == 0) return h; else return "0" + h; 1661} 1662 1663// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string 1664//function RSAEncryptB64(text) { 1665// var h = this.encrypt(text); 1666// if(h) return hex2b64(h); else return null; 1667//} 1668 1669// protected 1670RSAKey.prototype.doPublic = RSADoPublic; 1671 1672// public 1673RSAKey.prototype.setPublic = RSASetPublic; 1674RSAKey.prototype.encrypt = RSAEncrypt; 1675//RSAKey.prototype.encrypt_b64 = RSAEncryptB64; 1676// Depends on rsa.js and jsbn2.js 1677 1678// Version 1.1: support utf-8 decoding in pkcs1unpad2 1679 1680// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext 1681function pkcs1unpad2(d,n) { 1682 var b = d.toByteArray(); 1683 var i = 0; 1684 while(i < b.length && b[i] == 0) ++i; 1685 if(b.length-i != n-1 || b[i] != 2) 1686 return null; 1687 ++i; 1688 while(b[i] != 0) 1689 if(++i >= b.length) return null; 1690 var ret = ""; 1691 while(++i < b.length) { 1692 var c = b[i] & 255; 1693 if(c < 128) { // utf-8 decode 1694 ret += String.fromCharCode(c); 1695 } 1696 else if((c > 191) && (c < 224)) { 1697 ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63)); 1698 ++i; 1699 } 1700 else { 1701 ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63)); 1702 i += 2; 1703 } 1704 } 1705 return ret; 1706} 1707 1708// Set the private key fields N, e, and d from hex strings 1709function RSASetPrivate(N,E,D) { 1710 if(N != null && E != null && N.length > 0 && E.length > 0) { 1711 this.n = parseBigInt(N,16); 1712 this.e = parseInt(E,16); 1713 this.d = parseBigInt(D,16); 1714 } 1715 else 1716 console.error("Invalid RSA private key"); 1717} 1718 1719// Set the private key fields N, e, d and CRT params from hex strings 1720function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) { 1721 if(N != null && E != null && N.length > 0 && E.length > 0) { 1722 this.n = parseBigInt(N,16); 1723 this.e = parseInt(E,16); 1724 this.d = parseBigInt(D,16); 1725 this.p = parseBigInt(P,16); 1726 this.q = parseBigInt(Q,16); 1727 this.dmp1 = parseBigInt(DP,16); 1728 this.dmq1 = parseBigInt(DQ,16); 1729 this.coeff = parseBigInt(C,16); 1730 } 1731 else 1732 console.error("Invalid RSA private key"); 1733} 1734 1735// Generate a new random private key B bits long, using public expt E 1736function RSAGenerate(B,E) { 1737 var rng = new SecureRandom(); 1738 var qs = B>>1; 1739 this.e = parseInt(E,16); 1740 var ee = new BigInteger(E,16); 1741 for(;;) { 1742 for(;;) { 1743 this.p = new BigInteger(B-qs,1,rng); 1744 if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break; 1745 } 1746 for(;;) { 1747 this.q = new BigInteger(qs,1,rng); 1748 if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break; 1749 } 1750 if(this.p.compareTo(this.q) <= 0) { 1751 var t = this.p; 1752 this.p = this.q; 1753 this.q = t; 1754 } 1755 var p1 = this.p.subtract(BigInteger.ONE); 1756 var q1 = this.q.subtract(BigInteger.ONE); 1757 var phi = p1.multiply(q1); 1758 if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) { 1759 this.n = this.p.multiply(this.q); 1760 this.d = ee.modInverse(phi); 1761 this.dmp1 = this.d.mod(p1); 1762 this.dmq1 = this.d.mod(q1); 1763 this.coeff = this.q.modInverse(this.p); 1764 break; 1765 } 1766 } 1767} 1768 1769// Perform raw private operation on "x": return x^d (mod n) 1770function RSADoPrivate(x) { 1771 if(this.p == null || this.q == null) 1772 return x.modPow(this.d, this.n); 1773
1774 // TODO: re-calculate any missing CRT params 1775 var xp = x.mod(this.p).modPow(this.dmp1, this.p); 1776 var xq = x.mod(this.q).modPow(this.dmq1, this.q); 1777 1778 while(xp.compareTo(xq) < 0) 1779 xp = xp.add(this.p); 1780 return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq); 1781} 1782 1783// Return the PKCS#1 RSA decryption of "ctext". 1784// "ctext" is an even-length hex string and the output is a plain string. 1785function RSADecrypt(ctext) { 1786 var c = parseBigInt(ctext, 16); 1787 var m = this.doPrivate(c); 1788 if(m == null) return null; 1789 return pkcs1unpad2(m, (this.n.bitLength()+7)>>3); 1790} 1791 1792// Return the PKCS#1 RSA decryption of "ctext". 1793// "ctext" is a Base64-encoded string and the output is a plain string. 1794//function RSAB64Decrypt(ctext) { 1795// var h = b64tohex(ctext); 1796// if(h) return this.decrypt(h); else return null; 1797//} 1798 1799// protected 1800RSAKey.prototype.doPrivate = RSADoPrivate; 1801 1802// public 1803RSAKey.prototype.setPrivate = RSASetPrivate; 1804RSAKey.prototype.setPrivateEx = RSASetPrivateEx; 1805RSAKey.prototype.generate = RSAGenerate; 1806RSAKey.prototype.decrypt = RSADecrypt; 1807//RSAKey.prototype.b64_decrypt = RSAB64Decrypt; 1808// Copyright (c) 2011 Kevin M Burns Jr. 1809// All Rights Reserved. 1810// See "LICENSE" for details. 1811// 1812// Extension to jsbn which adds facilities for asynchronous RSA key generation 1813// Primarily created to avoid execution timeout on mobile devices 1814// 1815// http://www-cs-students.stanford.edu/~tjw/jsbn/ 1816// 1817// --- 1818 1819(function(){ 1820 1821// Generate a new random private key B bits long, using public expt E 1822var RSAGenerateAsync = function (B, E, callback) { 1823 //var rng = new SeededRandom(); 1824 var rng = new SecureRandom(); 1825 var qs = B >> 1; 1826 this.e = parseInt(E, 16); 1827 var ee = new BigInteger(E, 16); 1828 var rsa = this; 1829 // These functions have non-descript names because they were originally for(;;) loops. 1830 // I don't know about cryptography to give them better names than loop1-4. 1831 var loop1 = function() { 1832 var loop4 = function() { 1833 if (rsa.p.compareTo(rsa.q) <= 0) { 1834 var t = rsa.p; 1835 rsa.p = rsa.q; 1836 rsa.q = t; 1837 } 1838 var p1 = rsa.p.subtract(BigInteger.ONE); 1839 var q1 = rsa.q.subtract(BigInteger.ONE); 1840 var phi = p1.multiply(q1); 1841 if (phi.gcd(ee).compareTo(BigInteger.ONE) == 0) { 1842 rsa.n = rsa.p.multiply(rsa.q); 1843 rsa.d = ee.modInverse(phi); 1844 rsa.dmp1 = rsa.d.mod(p1); 1845 rsa.dmq1 = rsa.d.mod(q1); 1846 rsa.coeff = rsa.q.modInverse(rsa.p); 1847 setTimeout(function(){callback()},0); // escape 1848 } else { 1849 setTimeout(loop1,0); 1850 } 1851 }; 1852 var loop3 = function() { 1853 rsa.q = nbi(); 1854 rsa.q.fromNumberAsync(qs, 1, rng, function(){ 1855 rsa.q.subtract(BigInteger.ONE).gcda(ee, function(r){ 1856 if (r.compareTo(BigInteger.ONE) == 0 && rsa.q.isProbablePrime(10)) { 1857 setTimeout(loop4,0); 1858 } else { 1859 setTimeout(loop3,0); 1860 } 1861 }); 1862 }); 1863 }; 1864 var loop2 = function() { 1865 rsa.p = nbi(); 1866 rsa.p.fromNumberAsync(B - qs, 1, rng, function(){ 1867 rsa.p.subtract(BigInteger.ONE).gcda(ee, function(r){ 1868 if (r.compareTo(BigInteger.ONE) == 0 && rsa.p.isProbablePrime(10)) { 1869 setTimeout(loop3,0); 1870 } else { 1871 setTimeout(loop2,0); 1872 } 1873 }); 1874 }); 1875 }; 1876 setTimeout(loop2,0); 1877 }; 1878 setTimeout(loop1,0); 1879}; 1880RSAKey.prototype.generateAsync = RSAGenerateAsync; 1881 1882// Public API method 1883var bnGCDAsync = function (a, callback) { 1884 var x = (this.s < 0) ? this.negate() : this.clone(); 1885 var y = (a.s < 0) ? a.negate() : a.clone(); 1886 if (x.compareTo(y) < 0) { 1887 var t = x; 1888 x = y; 1889 y = t; 1890 } 1891 var i = x.getLowestSetBit(), 1892 g = y.getLowestSetBit(); 1893 if (g < 0) { 1894 callback(x); 1895 return; 1896 } 1897 if (i < g) g = i; 1898 if (g > 0) { 1899 x.rShiftTo(g, x); 1900 y.rShiftTo(g, y); 1901 } 1902 // Workhorse of the algorithm, gets called 200 - 800 times per 512 bit keygen. 1903 var gcda1 = function() {
1904 if ((i = x.getLowestSetBit()) > 0){ x.rShiftTo(i, x); } 1905 if ((i = y.getLowestSetBit()) > 0){ y.rShiftTo(i, y); } 1906 if (x.compareTo(y) >= 0) { 1907 x.subTo(y, x); 1908 x.rShiftTo(1, x); 1909 } else { 1910 y.subTo(x, y); 1911 y.rShiftTo(1, y); 1912 } 1913 if(!(x.signum() > 0)) { 1914 if (g > 0) y.lShiftTo(g, y); 1915 setTimeout(function(){callback(y)},0); // escape 1916 } else { 1917 setTimeout(gcda1,0); 1918 } 1919 }; 1920 setTimeout(gcda1,10); 1921}; 1922BigInteger.prototype.gcda = bnGCDAsync; 1923 1924// (protected) alternate constructor 1925var bnpFromNumberAsync = function (a,b,c,callback) { 1926 if("number" == typeof b) { 1927 if(a < 2) { 1928 this.fromInt(1); 1929 } else { 1930 this.fromNumber(a,c); 1931 if(!this.testBit(a-1)){ 1932 this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); 1933 } 1934 if(this.isEven()) { 1935 this.dAddOffset(1,0); 1936 } 1937 var bnp = this; 1938 var bnpfn1 = function(){ 1939 bnp.dAddOffset(2,0); 1940 if(bnp.bitLength() > a) bnp.subTo(BigInteger.ONE.shiftLeft(a-1),bnp); 1941 if(bnp.isProbablePrime(b)) { 1942 setTimeout(function(){callback()},0); // escape 1943 } else { 1944 setTimeout(bnpfn1,0); 1945 } 1946 }; 1947 setTimeout(bnpfn1,0); 1948 } 1949 } else { 1950 var x = new Array(), t = a&7; 1951 x.length = (a>>3)+1; 1952 b.nextBytes(x); 1953 if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0; 1954 this.fromString(x,256); 1955 } 1956}; 1957BigInteger.prototype.fromNumberAsync = bnpFromNumberAsync; 1958 1959})();var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 1960var b64pad="="; 1961 1962function hex2b64(h) { 1963 var i; 1964 var c; 1965 var ret = ""; 1966 for(i = 0; i+3 <= h.length; i+=3) { 1967 c = parseInt(h.substring(i,i+3),16); 1968 ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); 1969 } 1970 if(i+1 == h.length) { 1971 c = parseInt(h.substring(i,i+1),16); 1972 ret += b64map.charAt(c << 2); 1973 } 1974 else if(i+2 == h.length) { 1975 c = parseInt(h.substring(i,i+2),16); 1976 ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); 1977 } 1978 while((ret.length & 3) > 0) ret += b64pad; 1979 return ret; 1980} 1981 1982// convert a base64 string to hex 1983function b64tohex(s) { 1984 var ret = "" 1985 var i; 1986 var k = 0; // b64 state, 0-3 1987 var slop; 1988 for(i = 0; i < s.length; ++i) { 1989 if(s.charAt(i) == b64pad) break; 1990 v = b64map.indexOf(s.charAt(i)); 1991 if(v < 0) continue; 1992 if(k == 0) { 1993 ret += int2char(v >> 2); 1994 slop = v & 3; 1995 k = 1; 1996 } 1997 else if(k == 1) { 1998 ret += int2char((slop << 2) | (v >> 4)); 1999 slop = v & 0xf; 2000 k = 2; 2001 } 2002 else if(k == 2) { 2003 ret += int2char(slop); 2004 ret += int2char(v >> 2); 2005 slop = v & 3; 2006 k = 3; 2007 } 2008 else { 2009 ret += int2char((slop << 2) | (v >> 4)); 2010 ret += int2char(v & 0xf); 2011 k = 0; 2012 } 2013 } 2014 if(k == 1) 2015 ret += int2char(slop << 2); 2016 return ret; 2017} 2018 2019// convert a base64 string to a byte/number array 2020function b64toBA(s) { 2021 //piggyback on b64tohex for now, optimize later 2022 var h = b64tohex(s); 2023 var i; 2024 var a = new Array(); 2025 for(i = 0; 2*i < h.length; ++i) { 2026 a[i] = parseInt(h.substring(2*i,2*i+2),16); 2027 } 2028 return a; 2029} 2030/*! asn1-1.0.2.js (c) 2013 Kenji Urushima | kjur.github.com/jsrsasign/license 2031 */ 2032 2033var JSX = JSX || {}; 2034JSX.env = JSX.env || {}; 2035 2036var L = JSX, OP = Object.prototype, FUNCTION_TOSTRING = '[object Function]',ADD = ["toString", "valueOf"]; 2037 2038JSX.env.parseUA = function(agent) { 2039 2040 var numberify = function(s) { 2041 var c = 0; 2042 return parseFloat(s.replace(/\./g, function() { 2043 return (c++ == 1) ? '' : '.'; 2044 })); 2045 }, 2046 2047 nav = navigator, 2048 o = { 2049 ie: 0, 2050 opera: 0, 2051 gecko: 0, 2052 webkit: 0, 2053 chrome: 0, 2054 mobile: null, 2055 air: 0, 2056 ipad: 0, 2057 iphone: 0, 2058 ipod: 0, 2059 ios: null, 2060 android: 0, 2061 webos: 0, 2062 caja: nav && nav.cajaVersion, 2063 secure: false, 2064 os: null 2065 2066 }, 2067 2068 ua = agent || (navigator && navigator.userAgent), 2069 loc = window && window.location, 2070 href = loc && loc.href, 2071 m; 2072 2073 o.secure = href && (href.toLowerCase().indexOf("https") === 0); 2074 2075 if (ua) { 2076 2077 if ((/windows|win32/i).test(ua)) { 2078 o.os = 'windows'; 2079 } else if ((/macintosh/i).test(ua)) { 2080 o.os = 'macintosh'; 2081 } else if ((/rhino/i).test(ua)) { 2082 o.os = 'rhino'; 2083 } 2084 if ((/KHTML/).test(ua)) { 2085 o.webkit = 1; 2086 }
2087 m = ua.match(/AppleWebKit\/([^\s]*)/); 2088 if (m && m[1]) { 2089 o.webkit = numberify(m[1]); 2090 if (/ Mobile\//.test(ua)) { 2091 o.mobile = 'Apple'; // iPhone or iPod Touch 2092 m = ua.match(/OS ([^\s]*)/); 2093 if (m && m[1]) { 2094 m = numberify(m[1].replace('_', '.')); 2095 } 2096 o.ios = m; 2097 o.ipad = o.ipod = o.iphone = 0; 2098 m = ua.match(/iPad|iPod|iPhone/); 2099 if (m && m[0]) { 2100 o[m[0].toLowerCase()] = o.ios; 2101 } 2102 } else { 2103 m = ua.match(/NokiaN[^\/]*|Android \d\.\d|webOS\/\d\.\d/); 2104 if (m) { 2105 o.mobile = m[0]; 2106 } 2107 if (/webOS/.test(ua)) { 2108 o.mobile = 'WebOS'; 2109 m = ua.match(/webOS\/([^\s]*);/); 2110 if (m && m[1]) { 2111 o.webos = numberify(m[1]); 2112 } 2113 } 2114 if (/ Android/.test(ua)) { 2115 o.mobile = 'Android'; 2116 m = ua.match(/Android ([^\s]*);/); 2117 if (m && m[1]) { 2118 o.android = numberify(m[1]); 2119 } 2120 } 2121 } 2122 m = ua.match(/Chrome\/([^\s]*)/); 2123 if (m && m[1]) { 2124 o.chrome = numberify(m[1]); // Chrome 2125 } else { 2126 m = ua.match(/AdobeAIR\/([^\s]*)/); 2127 if (m) { 2128 o.air = m[0]; // Adobe AIR 1.0 or better 2129 } 2130 } 2131 } 2132 if (!o.webkit) { 2133 m = ua.match(/Opera[\s\/]([^\s]*)/); 2134 if (m && m[1]) { 2135 o.opera = numberify(m[1]); 2136 m = ua.match(/Version\/([^\s]*)/); 2137 if (m && m[1]) { 2138 o.opera = numberify(m[1]); // opera 10+ 2139 } 2140 m = ua.match(/Opera Mini[^;]*/); 2141 if (m) { 2142 o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316 2143 } 2144 } else { // not opera or webkit 2145 m = ua.match(/MSIE\s([^;]*)/); 2146 if (m && m[1]) { 2147 o.ie = numberify(m[1]); 2148 } else { // not opera, webkit, or ie 2149 m = ua.match(/Gecko\/([^\s]*)/); 2150 if (m) { 2151 o.gecko = 1; // Gecko detected, look for revision 2152 m = ua.match(/rv:([^\s\)]*)/); 2153 if (m && m[1]) { 2154 o.gecko = numberify(m[1]); 2155 } 2156 } 2157 } 2158 } 2159 } 2160 } 2161 return o; 2162}; 2163 2164JSX.env.ua = JSX.env.parseUA(); 2165 2166JSX.isFunction = function(o) { 2167 return (typeof o === 'function') || OP.toString.apply(o) === FUNCTION_TOSTRING; 2168}; 2169 2170JSX._IEEnumFix = (JSX.env.ua.ie) ? function(r, s) { 2171 var i, fname, f; 2172 for (i=0;i<ADD.length;i=i+1) { 2173 2174 fname = ADD[i]; 2175 f = s[fname]; 2176 2177 if (L.isFunction(f) && f!=OP[fname]) { 2178 r[fname]=f; 2179 } 2180 } 2181} : function(){}; 2182 2183JSX.extend = function(subc, superc, overrides) { 2184 if (!superc||!subc) { 2185 throw new Error("extend failed, please check that " + 2186 "all dependencies are included."); 2187 } 2188 var F = function() {}, i; 2189 F.prototype=superc.prototype; 2190 subc.prototype=new F(); 2191 subc.prototype.constructor=subc; 2192 subc.superclass=superc.prototype; 2193 if (superc.prototype.constructor == OP.constructor) { 2194 superc.prototype.constructor=superc; 2195 } 2196 2197 if (overrides) { 2198 for (i in overrides) { 2199 if (L.hasOwnProperty(overrides, i)) { 2200 subc.prototype[i]=overrides[i]; 2201 } 2202 } 2203 2204 L._IEEnumFix(subc.prototype, overrides); 2205 } 2206}; 2207 2208/* 2209 * asn1.js - ASN.1 DER encoder classes 2210 * 2211 * Copyright (c) 2013 Kenji Urushima ([email protected]) 2212 * 2213 * This software is licensed under the terms of the MIT License. 2214 * http://kjur.github.com/jsrsasign/license 2215 * 2216 * The above copyright and license notice shall be 2217 * included in all copies or substantial portions of the Software. 2218 */ 2219 2220/** 2221 * @fileOverview 2222 * @name asn1-1.0.js 2223 * @author Kenji Urushima [email protected] 2224 * @version 1.0.2 (2013-May-30) 2225 * @since 2.1 2226 * @license <a href="http://kjur.github.io/jsrsasign/license/">MIT License</a> 2227 */ 2228
2229/** 2230 * kjur's class library name space 2231 * <p> 2232 * This name space provides following name spaces: 2233 * <ul> 2234 * <li>{@link KJUR.asn1} - ASN.1 primitive hexadecimal encoder</li> 2235 * <li>{@link KJUR.asn1.x509} - ASN.1 structure for X.509 certificate and CRL</li> 2236 * <li>{@link KJUR.crypto} - Java Cryptographic Extension(JCE) style MessageDigest/Signature 2237 * class and utilities</li> 2238 * </ul> 2239 * </p> 2240 * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2. 2241 * @name KJUR 2242 * @namespace kjur's class library name space 2243 */ 2244if (typeof KJUR == "undefined" || !KJUR) KJUR = {}; 2245 2246/** 2247 * kjur's ASN.1 class library name space 2248 * <p> 2249 * This is ITU-T X.690 ASN.1 DER encoder class library and 2250 * class structure and methods is very similar to 2251 * org.bouncycastle.asn1 package of 2252 * well known BouncyCaslte Cryptography Library. 2253 * 2254 * <h4>PROVIDING ASN.1 PRIMITIVES</h4> 2255 * Here are ASN.1 DER primitive classes. 2256 * <ul> 2257 * <li>{@link KJUR.asn1.DERBoolean}</li> 2258 * <li>{@link KJUR.asn1.DERInteger}</li> 2259 * <li>{@link KJUR.asn1.DERBitString}</li> 2260 * <li>{@link KJUR.asn1.DEROctetString}</li> 2261 * <li>{@link KJUR.asn1.DERNull}</li> 2262 * <li>{@link KJUR.asn1.DERObjectIdentifier}</li> 2263 * <li>{@link KJUR.asn1.DERUTF8String}</li> 2264 * <li>{@link KJUR.asn1.DERNumericString}</li> 2265 * <li>{@link KJUR.asn1.DERPrintableString}</li> 2266 * <li>{@link KJUR.asn1.DERTeletexString}</li> 2267 * <li>{@link KJUR.asn1.DERIA5String}</li> 2268 * <li>{@link KJUR.asn1.DERUTCTime}</li> 2269 * <li>{@link KJUR.asn1.DERGeneralizedTime}</li> 2270 * <li>{@link KJUR.asn1.DERSequence}</li> 2271 * <li>{@link KJUR.asn1.DERSet}</li> 2272 * </ul> 2273 * 2274 * <h4>OTHER ASN.1 CLASSES</h4> 2275 * <ul> 2276 * <li>{@link KJUR.asn1.ASN1Object}</li> 2277 * <li>{@link KJUR.asn1.DERAbstractString}</li> 2278 * <li>{@link KJUR.asn1.DERAbstractTime}</li> 2279 * <li>{@link KJUR.asn1.DERAbstractStructured}</li> 2280 * <li>{@link KJUR.asn1.DERTaggedObject}</li> 2281 * </ul> 2282 * </p> 2283 * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2. 2284 * @name KJUR.asn1 2285 * @namespace 2286 */ 2287if (typeof KJUR.asn1 == "undefined" || !KJUR.asn1) KJUR.asn1 = {}; 2288 2289/** 2290 * ASN1 utilities class 2291 * @name KJUR.asn1.ASN1Util 2292 * @classs ASN1 utilities class 2293 * @since asn1 1.0.2 2294 */ 2295KJUR.asn1.ASN1Util = new function() { 2296 this.integerToByteHex = function(i) {
vendor: 17,485 bytes, lines 2297-2871
2297 var h = i.toString(16); 2298 if ((h.length % 2) == 1) h = '0' + h; 2299 return h; 2300 }; 2301 this.bigIntToMinTwosComplementsHex = function(bigIntegerValue) { 2302 var h = bigIntegerValue.toString(16); 2303 if (h.substr(0, 1) != '-') { 2304 if (h.length % 2 == 1) { 2305 h = '0' + h; 2306 } else { 2307 if (! h.match(/^[0-7]/)) { 2308 h = '00' + h; 2309 } 2310 } 2311 } else { 2312 var hPos = h.substr(1); 2313 var xorLen = hPos.length; 2314 if (xorLen % 2 == 1) { 2315 xorLen += 1; 2316 } else { 2317 if (! h.match(/^[0-7]/)) { 2318 xorLen += 2; 2319 } 2320 } 2321 var hMask = ''; 2322 for (var i = 0; i < xorLen; i++) { 2323 hMask += 'f'; 2324 } 2325 var biMask = new BigInteger(hMask, 16); 2326 var biNeg = biMask.xor(bigIntegerValue).add(BigInteger.ONE); 2327 h = biNeg.toString(16).replace(/^-/, ''); 2328 } 2329 return h; 2330 }; 2331 /** 2332 * get PEM string from hexadecimal data and header string 2333 * @name getPEMStringFromHex 2334 * @memberOf KJUR.asn1.ASN1Util 2335 * @function 2336 * @param {String} dataHex hexadecimal string of PEM body 2337 * @param {String} pemHeader PEM header string (ex. 'RSA PRIVATE KEY') 2338 * @return {String} PEM formatted string of input data 2339 * @description 2340 * @example 2341 * var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex('616161', 'RSA PRIVATE KEY'); 2342 * // value of pem will be: 2343 * -----BEGIN PRIVATE KEY----- 2344 * YWFh 2345 * -----END PRIVATE KEY----- 2346 */ 2347 this.getPEMStringFromHex = function(dataHex, pemHeader) { 2348 var dataWA = CryptoJS.enc.Hex.parse(dataHex); 2349 var dataB64 = CryptoJS.enc.Base64.stringify(dataWA); 2350 var pemBody = dataB64.replace(/(.{64})/g, "$1\r\n"); 2351 pemBody = pemBody.replace(/\r\n$/, ''); 2352 return "-----BEGIN " + pemHeader + "-----\r\n" + 2353 pemBody + 2354 "\r\n-----END " + pemHeader + "-----\r\n"; 2355 }; 2356}; 2357 2358// ******************************************************************** 2359// Abstract ASN.1 Classes 2360// ******************************************************************** 2361 2362// ******************************************************************** 2363 2364/** 2365 * base class for ASN.1 DER encoder object 2366 * @name KJUR.asn1.ASN1Object 2367 * @class base class for ASN.1 DER encoder object 2368 * @property {Boolean} isModified flag whether internal data was changed 2369 * @property {String} hTLV hexadecimal string of ASN.1 TLV 2370 * @property {String} hT hexadecimal string of ASN.1 TLV tag(T) 2371 * @property {String} hL hexadecimal string of ASN.1 TLV length(L) 2372 * @property {String} hV hexadecimal string of ASN.1 TLV value(V) 2373 * @description 2374 */ 2375KJUR.asn1.ASN1Object = function() { 2376 var isModified = true; 2377 var hTLV = null; 2378 var hT = '00' 2379 var hL = '00'; 2380 var hV = ''; 2381 2382 /** 2383 * get hexadecimal ASN.1 TLV length(L) bytes from TLV value(V) 2384 * @name getLengthHexFromValue 2385 * @memberOf KJUR.asn1.ASN1Object 2386 * @function 2387 * @return {String} hexadecimal string of ASN.1 TLV length(L) 2388 */ 2389 this.getLengthHexFromValue = function() { 2390 if (typeof this.hV == "undefined" || this.hV == null) { 2391 throw "this.hV is null or undefined."; 2392 } 2393 if (this.hV.length % 2 == 1) { 2394 throw "value hex must be even length: n=" + hV.length + ",v=" + this.hV; 2395 } 2396 var n = this.hV.length / 2; 2397 var hN = n.toString(16); 2398 if (hN.length % 2 == 1) { 2399 hN = "0" + hN; 2400 } 2401 if (n < 128) { 2402 return hN; 2403 } else { 2404 var hNlen = hN.length / 2; 2405 if (hNlen > 15) { 2406 throw "ASN.1 length too long to represent by 8x: n = " + n.toString(16); 2407 } 2408 var head = 128 + hNlen; 2409 return head.toString(16) + hN; 2410 } 2411 }; 2412 2413 /** 2414 * get hexadecimal string of ASN.1 TLV bytes 2415 * @name getEncodedHex 2416 * @memberOf KJUR.asn1.ASN1Object 2417 * @function 2418 * @return {String} hexadecimal string of ASN.1 TLV 2419 */ 2420 this.getEncodedHex = function() { 2421 if (this.hTLV == null || this.isModified) { 2422 this.hV = this.getFreshValueHex(); 2423 this.hL = this.getLengthHexFromValue(); 2424 this.hTLV = this.hT + this.hL + this.hV; 2425 this.isModified = false; 2426 //console.error("first time: " + this.hTLV); 2427 } 2428 return this.hTLV; 2429 }; 2430 2431 /** 2432 * get hexadecimal string of ASN.1 TLV value(V) bytes 2433 * @name getValueHex 2434 * @memberOf KJUR.asn1.ASN1Object 2435 * @function 2436 * @return {String} hexadecimal string of ASN.1 TLV value(V) bytes 2437 */ 2438 this.getValueHex = function() { 2439 this.getEncodedHex(); 2440 return this.hV; 2441 } 2442 2443 this.getFreshValueHex = function() { 2444 return ''; 2445 }; 2446}; 2447 2448// == BEGIN DERAbstractString ================================================ 2449/** 2450 * base class for ASN.1 DER string classes 2451 * @name KJUR.asn1.DERAbstractString 2452 * @class base class for ASN.1 DER string classes 2453 * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) 2454 * @property {String} s internal string of value 2455 * @extends KJUR.asn1.ASN1Object 2456 * @description 2457 * <br/> 2458 * As for argument 'params' for constructor, you can specify one of 2459 * following properties: 2460 * <ul> 2461 * <li>str - specify initial ASN.1 value(V) by a string</li> 2462 * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li> 2463 * </ul> 2464 * NOTE: 'params' can be omitted. 2465 */ 2466KJUR.asn1.DERAbstractString = function(params) { 2467 KJUR.asn1.DERAbstractString.superclass.constructor.call(this); 2468 var s = null; 2469 var hV = null; 2470 2471 /** 2472 * get string value of this string object 2473 * @name getString 2474 * @memberOf KJUR.asn1.DERAbstractString 2475 * @function 2476 * @return {String} string value of this string object 2477 */ 2478 this.getString = function() { 2479 return this.s; 2480 }; 2481 2482 /** 2483 * set value by a string 2484 * @name setString 2485 * @memberOf KJUR.asn1.DERAbstractString 2486 * @function 2487 * @param {String} newS value by a string to set 2488 */ 2489 this.setString = function(newS) { 2490 this.hTLV = null; 2491 this.isModified = true; 2492 this.s = newS; 2493 this.hV = stohex(this.s); 2494 }; 2495 2496 /** 2497 * set value by a hexadecimal string 2498 * @name setStringHex 2499 * @memberOf KJUR.asn1.DERAbstractString 2500 * @function 2501 * @param {String} newHexString value by a hexadecimal string to set 2502 */ 2503 this.setStringHex = function(newHexString) { 2504 this.hTLV = null; 2505 this.isModified = true; 2506 this.s = null; 2507 this.hV = newHexString; 2508 }; 2509 2510 this.getFreshValueHex = function() { 2511 return this.hV; 2512 }; 2513 2514 if (typeof params != "undefined") { 2515 if (typeof params['str'] != "undefined") { 2516 this.setString(params['str']); 2517 } else if (typeof params['hex'] != "undefined") { 2518 this.setStringHex(params['hex']); 2519 } 2520 } 2521}; 2522JSX.extend(KJUR.asn1.DERAbstractString, KJUR.asn1.ASN1Object); 2523// == END DERAbstractString ================================================ 2524 2525// == BEGIN DERAbstractTime ================================================== 2526/** 2527 * base class for ASN.1 DER Generalized/UTCTime class 2528 * @name KJUR.asn1.DERAbstractTime 2529 * @class base class for ASN.1 DER Generalized/UTCTime class 2530 * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'}) 2531 * @extends KJUR.asn1.ASN1Object 2532 * @description 2533 * @see KJUR.asn1.ASN1Object - superclass 2534 */ 2535KJUR.asn1.DERAbstractTime = function(params) { 2536 KJUR.asn1.DERAbstractTime.superclass.constructor.call(this); 2537 var s = null; 2538 var date = null; 2539 2540 // --- PRIVATE METHODS -------------------- 2541 this.localDateToUTC = function(d) { 2542 utc = d.getTime() + (d.getTimezoneOffset() * 60000); 2543 var utcDate = new Date(utc); 2544 return utcDate; 2545 }; 2546 2547 this.formatDate = function(dateObject, type) { 2548 var pad = this.zeroPadding; 2549 var d = this.localDateToUTC(dateObject); 2550 var year = String(d.getFullYear()); 2551 if (type == 'utc') year = year.substr(2, 2); 2552 var month = pad(String(d.getMonth() + 1), 2); 2553 var day = pad(String(d.getDate()), 2); 2554 var hour = pad(String(d.getHours()), 2); 2555 var min = pad(String(d.getMinutes()), 2); 2556 var sec = pad(String(d.getSeconds()), 2); 2557 return year + month + day + hour + min + sec + 'Z'; 2558 }; 2559 2560 this.zeroPadding = function(s, len) { 2561 if (s.length >= len) return s; 2562 return new Array(len - s.length + 1).join('0') + s; 2563 }; 2564 2565 // --- PUBLIC METHODS -------------------- 2566 /** 2567 * get string value of this string object 2568 * @name getString 2569 * @memberOf KJUR.asn1.DERAbstractTime 2570 * @function 2571 * @return {String} string value of this time object 2572 */ 2573 this.getString = function() { 2574 return this.s; 2575 }; 2576 2577 /** 2578 * set value by a string 2579 * @name setString 2580 * @memberOf KJUR.asn1.DERAbstractTime 2581 * @function 2582 * @param {String} newS value by a string to set such like "130430235959Z" 2583 */ 2584 this.setString = function(newS) { 2585 this.hTLV = null; 2586 this.isModified = true; 2587 this.s = newS; 2588 this.hV = stohex(this.s); 2589 }; 2590 2591 /** 2592 * set value by a Date object 2593 * @name setByDateValue 2594 * @memberOf KJUR.asn1.DERAbstractTime 2595 * @function 2596 * @param {Integer} year year of date (ex. 2013) 2597 * @param {Integer} month month of date between 1 and 12 (ex. 12) 2598 * @param {Integer} day day of month 2599 * @param {Integer} hour hours of date 2600 * @param {Integer} min minutes of date 2601 * @param {Integer} sec seconds of date 2602 */ 2603 this.setByDateValue = function(year, month, day, hour, min, sec) { 2604 var dateObject = new Date(Date.UTC(year, month - 1, day, hour, min, sec, 0)); 2605 this.setByDate(dateObject); 2606 }; 2607 2608 this.getFreshValueHex = function() { 2609 return this.hV; 2610 }; 2611}; 2612JSX.extend(KJUR.asn1.DERAbstractTime, KJUR.asn1.ASN1Object); 2613// == END DERAbstractTime ================================================== 2614 2615// == BEGIN DERAbstractStructured ============================================ 2616/** 2617 * base class for ASN.1 DER structured class 2618 * @name KJUR.asn1.DERAbstractStructured 2619 * @class base class for ASN.1 DER structured class 2620 * @property {Array} asn1Array internal array of ASN1Object 2621 * @extends KJUR.asn1.ASN1Object 2622 * @description 2623 * @see KJUR.asn1.ASN1Object - superclass 2624 */ 2625KJUR.asn1.DERAbstractStructured = function(params) { 2626 KJUR.asn1.DERAbstractString.superclass.constructor.call(this); 2627 var asn1Array = null; 2628 2629 /** 2630 * set value by array of ASN1Object 2631 * @name setByASN1ObjectArray 2632 * @memberOf KJUR.asn1.DERAbstractStructured 2633 * @function 2634 * @param {array} asn1ObjectArray array of ASN1Object to set 2635 */ 2636 this.setByASN1ObjectArray = function(asn1ObjectArray) { 2637 this.hTLV = null; 2638 this.isModified = true; 2639 this.asn1Array = asn1ObjectArray; 2640 }; 2641 2642 /** 2643 * append an ASN1Object to internal array 2644 * @name appendASN1Object 2645 * @memberOf KJUR.asn1.DERAbstractStructured 2646 * @function 2647 * @param {ASN1Object} asn1Object to add 2648 */ 2649 this.appendASN1Object = function(asn1Object) { 2650 this.hTLV = null; 2651 this.isModified = true; 2652 this.asn1Array.push(asn1Object); 2653 }; 2654 2655 this.asn1Array = new Array(); 2656 if (typeof params != "undefined") { 2657 if (typeof params['array'] != "undefined") { 2658 this.asn1Array = params['array']; 2659 } 2660 } 2661}; 2662JSX.extend(KJUR.asn1.DERAbstractStructured, KJUR.asn1.ASN1Object); 2663 2664 2665// ******************************************************************** 2666// ASN.1 Object Classes 2667// ******************************************************************** 2668 2669// ******************************************************************** 2670/** 2671 * class for ASN.1 DER Boolean 2672 * @name KJUR.asn1.DERBoolean 2673 * @class class for ASN.1 DER Boolean 2674 * @extends KJUR.asn1.ASN1Object 2675 * @description 2676 * @see KJUR.asn1.ASN1Object - superclass 2677 */ 2678KJUR.asn1.DERBoolean = function() { 2679 KJUR.asn1.DERBoolean.superclass.constructor.call(this); 2680 this.hT = "01"; 2681 this.hTLV = "0101ff"; 2682}; 2683JSX.extend(KJUR.asn1.DERBoolean, KJUR.asn1.ASN1Object); 2684 2685// ******************************************************************** 2686/** 2687 * class for ASN.1 DER Integer 2688 * @name KJUR.asn1.DERInteger 2689 * @class class for ASN.1 DER Integer 2690 * @extends KJUR.asn1.ASN1Object 2691 * @description 2692 * <br/> 2693 * As for argument 'params' for constructor, you can specify one of 2694 * following properties: 2695 * <ul> 2696 * <li>int - specify initial ASN.1 value(V) by integer value</li> 2697 * <li>bigint - specify initial ASN.1 value(V) by BigInteger object</li> 2698 * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li> 2699 * </ul> 2700 * NOTE: 'params' can be omitted. 2701 */ 2702KJUR.asn1.DERInteger = function(params) { 2703 KJUR.asn1.DERInteger.superclass.constructor.call(this); 2704 this.hT = "02"; 2705 2706 /** 2707 * set value by Tom Wu's BigInteger object 2708 * @name setByBigInteger 2709 * @memberOf KJUR.asn1.DERInteger 2710 * @function 2711 * @param {BigInteger} bigIntegerValue to set 2712 */ 2713 this.setByBigInteger = function(bigIntegerValue) { 2714 this.hTLV = null; 2715 this.isModified = true; 2716 this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue); 2717 }; 2718 2719 /** 2720 * set value by integer value 2721 * @name setByInteger 2722 * @memberOf KJUR.asn1.DERInteger 2723 * @function 2724 * @param {Integer} integer value to set 2725 */ 2726 this.setByInteger = function(intValue) { 2727 var bi = new BigInteger(String(intValue), 10); 2728 this.setByBigInteger(bi); 2729 }; 2730 2731 /** 2732 * set value by integer value 2733 * @name setValueHex 2734 * @memberOf KJUR.asn1.DERInteger 2735 * @function 2736 * @param {String} hexadecimal string of integer value 2737 * @description 2738 * <br/> 2739 * NOTE: Value shall be represented by minimum octet length of 2740 * two's complement representation. 2741 */ 2742 this.setValueHex = function(newHexString) { 2743 this.hV = newHexString; 2744 }; 2745 2746 this.getFreshValueHex = function() { 2747 return this.hV; 2748 }; 2749 2750 if (typeof params != "undefined") { 2751 if (typeof params['bigint'] != "undefined") { 2752 this.setByBigInteger(params['bigint']); 2753 } else if (typeof params['int'] != "undefined") { 2754 this.setByInteger(params['int']); 2755 } else if (typeof params['hex'] != "undefined") { 2756 this.setValueHex(params['hex']); 2757 } 2758 } 2759}; 2760JSX.extend(KJUR.asn1.DERInteger, KJUR.asn1.ASN1Object); 2761 2762// ******************************************************************** 2763/** 2764 * class for ASN.1 DER encoded BitString primitive 2765 * @name KJUR.asn1.DERBitString 2766 * @class class for ASN.1 DER encoded BitString primitive 2767 * @extends KJUR.asn1.ASN1Object 2768 * @description 2769 * <br/> 2770 * As for argument 'params' for constructor, you can specify one of 2771 * following properties: 2772 * <ul> 2773 * <li>bin - specify binary string (ex. '10111')</li> 2774 * <li>array - specify array of boolean (ex. [true,false,true,true])</li> 2775 * <li>hex - specify hexadecimal string of ASN.1 value(V) including unused bits</li> 2776 * </ul> 2777 * NOTE: 'params' can be omitted. 2778 */ 2779KJUR.asn1.DERBitString = function(params) { 2780 KJUR.asn1.DERBitString.superclass.constructor.call(this); 2781 this.hT = "03"; 2782 2783 /** 2784 * set ASN.1 value(V) by a hexadecimal string including unused bits 2785 * @name setHexValueIncludingUnusedBits 2786 * @memberOf KJUR.asn1.DERBitString 2787 * @function 2788 * @param {String} newHexStringIncludingUnusedBits 2789 */ 2790 this.setHexValueIncludingUnusedBits = function(newHexStringIncludingUnusedBits) { 2791 this.hTLV = null; 2792 this.isModified = true; 2793 this.hV = newHexStringIncludingUnusedBits; 2794 }; 2795 2796 /** 2797 * set ASN.1 value(V) by unused bit and hexadecimal string of value 2798 * @name setUnusedBitsAndHexValue 2799 * @memberOf KJUR.asn1.DERBitString 2800 * @function 2801 * @param {Integer} unusedBits 2802 * @param {String} hValue 2803 */ 2804 this.setUnusedBitsAndHexValue = function(unusedBits, hValue) { 2805 if (unusedBits < 0 || 7 < unusedBits) { 2806 throw "unused bits shall be from 0 to 7: u = " + unusedBits; 2807 } 2808 var hUnusedBits = "0" + unusedBits; 2809 this.hTLV = null; 2810 this.isModified = true; 2811 this.hV = hUnusedBits + hValue; 2812 }; 2813 2814 /** 2815 * set ASN.1 DER BitString by binary string 2816 * @name setByBinaryString 2817 * @memberOf KJUR.asn1.DERBitString 2818 * @function 2819 * @param {String} binaryString binary value string (i.e. '10111') 2820 * @description 2821 * Its unused bits will be calculated automatically by length of 2822 * 'binaryValue'. <br/> 2823 * NOTE: Trailing zeros '0' will be ignored. 2824 */ 2825 this.setByBinaryString = function(binaryString) { 2826 binaryString = binaryString.replace(/0+$/, ''); 2827 var unusedBits = 8 - binaryString.length % 8; 2828 if (unusedBits == 8) unusedBits = 0; 2829 for (var i = 0; i <= unusedBits; i++) { 2830 binaryString += '0'; 2831 } 2832 var h = ''; 2833 for (var i = 0; i < binaryString.length - 1; i += 8) { 2834 var b = binaryString.substr(i, 8); 2835 var x = parseInt(b, 2).toString(16); 2836 if (x.length == 1) x = '0' + x; 2837 h += x; 2838 } 2839 this.hTLV = null; 2840 this.isModified = true; 2841 this.hV = '0' + unusedBits + h; 2842 }; 2843 2844 /** 2845 * set ASN.1 TLV value(V) by an array of boolean 2846 * @name setByBooleanArray 2847 * @memberOf KJUR.asn1.DERBitString 2848 * @function 2849 * @param {array} booleanArray array of boolean (ex. [true, false, true]) 2850 * @description 2851 * NOTE: Trailing falses will be ignored. 2852 */ 2853 this.setByBooleanArray = function(booleanArray) { 2854 var s = ''; 2855 for (var i = 0; i < booleanArray.length; i++) { 2856 if (booleanArray[i] == true) { 2857 s += '1'; 2858 } else { 2859 s += '0'; 2860 } 2861 } 2862 this.setByBinaryString(s); 2863 }; 2864 2865 /** 2866 * generate an array of false with specified length 2867 * @name newFalseArray 2868 * @memberOf KJUR.asn1.DERBitString 2869 * @function 2870 * @param {Integer} nLength length of array to generate 2871 * @return {array} array of boolean faluse
2872 * @description 2873 * This static method may be useful to initialize boolean array. 2874 */ 2875 this.newFalseArray = function(nLength) { 2876 var a = new Array(nLength); 2877 for (var i = 0; i < nLength; i++) { 2878 a[i] = false; 2879 } 2880 return a; 2881 }; 2882 2883 this.getFreshValueHex = function() { 2884 return this.hV; 2885 }; 2886 2887 if (typeof params != "undefined") { 2888 if (typeof params['hex'] != "undefined") { 2889 this.setHexValueIncludingUnusedBits(params['hex']); 2890 } else if (typeof params['bin'] != "undefined") { 2891 this.setByBinaryString(params['bin']); 2892 } else if (typeof params['array'] != "undefined") { 2893 this.setByBooleanArray(params['array']); 2894 } 2895 } 2896}; 2897JSX.extend(KJUR.asn1.DERBitString, KJUR.asn1.ASN1Object); 2898 2899// ******************************************************************** 2900/** 2901 * class for ASN.1 DER OctetString 2902 * @name KJUR.asn1.DEROctetString 2903 * @class class for ASN.1 DER OctetString 2904 * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) 2905 * @extends KJUR.asn1.DERAbstractString 2906 * @description 2907 * @see KJUR.asn1.DERAbstractString - superclass 2908 */ 2909KJUR.asn1.DEROctetString = function(params) { 2910 KJUR.asn1.DEROctetString.superclass.constructor.call(this, params); 2911 this.hT = "04"; 2912}; 2913JSX.extend(KJUR.asn1.DEROctetString, KJUR.asn1.DERAbstractString); 2914 2915// ******************************************************************** 2916/** 2917 * class for ASN.1 DER Null 2918 * @name KJUR.asn1.DERNull 2919 * @class class for ASN.1 DER Null 2920 * @extends KJUR.asn1.ASN1Object 2921 * @description 2922 * @see KJUR.asn1.ASN1Object - superclass 2923 */ 2924KJUR.asn1.DERNull = function() { 2925 KJUR.asn1.DERNull.superclass.constructor.call(this); 2926 this.hT = "05"; 2927 this.hTLV = "0500"; 2928}; 2929JSX.extend(KJUR.asn1.DERNull, KJUR.asn1.ASN1Object); 2930 2931// ******************************************************************** 2932/** 2933 * class for ASN.1 DER ObjectIdentifier 2934 * @name KJUR.asn1.DERObjectIdentifier 2935 * @class class for ASN.1 DER ObjectIdentifier 2936 * @param {Array} params associative array of parameters (ex. {'oid': '2.5.4.5'}) 2937 * @extends KJUR.asn1.ASN1Object 2938 * @description 2939 * <br/> 2940 * As for argument 'params' for constructor, you can specify one of 2941 * following properties: 2942 * <ul> 2943 * <li>oid - specify initial ASN.1 value(V) by a oid string (ex. 2.5.4.13)</li> 2944 * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li> 2945 * </ul> 2946 * NOTE: 'params' can be omitted. 2947 */ 2948KJUR.asn1.DERObjectIdentifier = function(params) { 2949 var itox = function(i) {
vendor: 9,985 bytes, lines 2950-3258
2950 var h = i.toString(16); 2951 if (h.length == 1) h = '0' + h; 2952 return h; 2953 }; 2954 var roidtox = function(roid) { 2955 var h = ''; 2956 var bi = new BigInteger(roid, 10); 2957 var b = bi.toString(2); 2958 var padLen = 7 - b.length % 7; 2959 if (padLen == 7) padLen = 0; 2960 var bPad = ''; 2961 for (var i = 0; i < padLen; i++) bPad += '0'; 2962 b = bPad + b; 2963 for (var i = 0; i < b.length - 1; i += 7) { 2964 var b8 = b.substr(i, 7); 2965 if (i != b.length - 7) b8 = '1' + b8; 2966 h += itox(parseInt(b8, 2)); 2967 } 2968 return h; 2969 } 2970 2971 KJUR.asn1.DERObjectIdentifier.superclass.constructor.call(this); 2972 this.hT = "06"; 2973 2974 /** 2975 * set value by a hexadecimal string 2976 * @name setValueHex 2977 * @memberOf KJUR.asn1.DERObjectIdentifier 2978 * @function 2979 * @param {String} newHexString hexadecimal value of OID bytes 2980 */ 2981 this.setValueHex = function(newHexString) { 2982 this.hTLV = null; 2983 this.isModified = true; 2984 this.s = null; 2985 this.hV = newHexString; 2986 }; 2987 2988 /** 2989 * set value by a OID string 2990 * @name setValueOidString 2991 * @memberOf KJUR.asn1.DERObjectIdentifier 2992 * @function 2993 * @param {String} oidString OID string (ex. 2.5.4.13) 2994 */ 2995 this.setValueOidString = function(oidString) { 2996 if (! oidString.match(/^[0-9.]+$/)) { 2997 throw "malformed oid string: " + oidString; 2998 } 2999 var h = ''; 3000 var a = oidString.split('.'); 3001 var i0 = parseInt(a[0]) * 40 + parseInt(a[1]); 3002 h += itox(i0); 3003 a.splice(0, 2); 3004 for (var i = 0; i < a.length; i++) { 3005 h += roidtox(a[i]); 3006 } 3007 this.hTLV = null; 3008 this.isModified = true; 3009 this.s = null; 3010 this.hV = h; 3011 }; 3012 3013 /** 3014 * set value by a OID name 3015 * @name setValueName 3016 * @memberOf KJUR.asn1.DERObjectIdentifier 3017 * @function 3018 * @param {String} oidName OID name (ex. 'serverAuth') 3019 * @since 1.0.1 3020 * @description 3021 * OID name shall be defined in 'KJUR.asn1.x509.OID.name2oidList'. 3022 * Otherwise raise error. 3023 */ 3024 this.setValueName = function(oidName) { 3025 if (typeof KJUR.asn1.x509.OID.name2oidList[oidName] != "undefined") { 3026 var oid = KJUR.asn1.x509.OID.name2oidList[oidName]; 3027 this.setValueOidString(oid); 3028 } else { 3029 throw "DERObjectIdentifier oidName undefined: " + oidName; 3030 } 3031 }; 3032 3033 this.getFreshValueHex = function() { 3034 return this.hV; 3035 }; 3036 3037 if (typeof params != "undefined") { 3038 if (typeof params['oid'] != "undefined") { 3039 this.setValueOidString(params['oid']); 3040 } else if (typeof params['hex'] != "undefined") { 3041 this.setValueHex(params['hex']); 3042 } else if (typeof params['name'] != "undefined") { 3043 this.setValueName(params['name']); 3044 } 3045 } 3046}; 3047JSX.extend(KJUR.asn1.DERObjectIdentifier, KJUR.asn1.ASN1Object); 3048 3049// ******************************************************************** 3050/** 3051 * class for ASN.1 DER UTF8String 3052 * @name KJUR.asn1.DERUTF8String 3053 * @class class for ASN.1 DER UTF8String 3054 * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) 3055 * @extends KJUR.asn1.DERAbstractString 3056 * @description 3057 * @see KJUR.asn1.DERAbstractString - superclass 3058 */ 3059KJUR.asn1.DERUTF8String = function(params) { 3060 KJUR.asn1.DERUTF8String.superclass.constructor.call(this, params); 3061 this.hT = "0c"; 3062}; 3063JSX.extend(KJUR.asn1.DERUTF8String, KJUR.asn1.DERAbstractString); 3064 3065// ******************************************************************** 3066/** 3067 * class for ASN.1 DER NumericString 3068 * @name KJUR.asn1.DERNumericString 3069 * @class class for ASN.1 DER NumericString 3070 * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) 3071 * @extends KJUR.asn1.DERAbstractString 3072 * @description 3073 * @see KJUR.asn1.DERAbstractString - superclass 3074 */ 3075KJUR.asn1.DERNumericString = function(params) { 3076 KJUR.asn1.DERNumericString.superclass.constructor.call(this, params); 3077 this.hT = "12"; 3078}; 3079JSX.extend(KJUR.asn1.DERNumericString, KJUR.asn1.DERAbstractString); 3080 3081// ******************************************************************** 3082/** 3083 * class for ASN.1 DER PrintableString 3084 * @name KJUR.asn1.DERPrintableString 3085 * @class class for ASN.1 DER PrintableString 3086 * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) 3087 * @extends KJUR.asn1.DERAbstractString 3088 * @description 3089 * @see KJUR.asn1.DERAbstractString - superclass 3090 */ 3091KJUR.asn1.DERPrintableString = function(params) { 3092 KJUR.asn1.DERPrintableString.superclass.constructor.call(this, params); 3093 this.hT = "13"; 3094}; 3095JSX.extend(KJUR.asn1.DERPrintableString, KJUR.asn1.DERAbstractString); 3096 3097// ******************************************************************** 3098/** 3099 * class for ASN.1 DER TeletexString 3100 * @name KJUR.asn1.DERTeletexString 3101 * @class class for ASN.1 DER TeletexString 3102 * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) 3103 * @extends KJUR.asn1.DERAbstractString 3104 * @description 3105 * @see KJUR.asn1.DERAbstractString - superclass 3106 */ 3107KJUR.asn1.DERTeletexString = function(params) { 3108 KJUR.asn1.DERTeletexString.superclass.constructor.call(this, params); 3109 this.hT = "14"; 3110}; 3111JSX.extend(KJUR.asn1.DERTeletexString, KJUR.asn1.DERAbstractString); 3112 3113// ******************************************************************** 3114/** 3115 * class for ASN.1 DER IA5String 3116 * @name KJUR.asn1.DERIA5String 3117 * @class class for ASN.1 DER IA5String 3118 * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) 3119 * @extends KJUR.asn1.DERAbstractString 3120 * @description 3121 * @see KJUR.asn1.DERAbstractString - superclass 3122 */ 3123KJUR.asn1.DERIA5String = function(params) { 3124 KJUR.asn1.DERIA5String.superclass.constructor.call(this, params); 3125 this.hT = "16"; 3126}; 3127JSX.extend(KJUR.asn1.DERIA5String, KJUR.asn1.DERAbstractString); 3128 3129// ******************************************************************** 3130/** 3131 * class for ASN.1 DER UTCTime 3132 * @name KJUR.asn1.DERUTCTime 3133 * @class class for ASN.1 DER UTCTime 3134 * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'}) 3135 * @extends KJUR.asn1.DERAbstractTime 3136 * @description 3137 * <br/> 3138 * As for argument 'params' for constructor, you can specify one of 3139 * following properties: 3140 * <ul> 3141 * <li>str - specify initial ASN.1 value(V) by a string (ex.'130430235959Z')</li> 3142 * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li> 3143 * <li>date - specify Date object.</li> 3144 * </ul> 3145 * NOTE: 'params' can be omitted. 3146 * <h4>EXAMPLES</h4> 3147 * @example 3148 * var d1 = new KJUR.asn1.DERUTCTime(); 3149 * d1.setString('130430125959Z'); 3150 * 3151 * var d2 = new KJUR.asn1.DERUTCTime({'str': '130430125959Z'}); 3152 * 3153 * var d3 = new KJUR.asn1.DERUTCTime({'date': new Date(Date.UTC(2015, 0, 31, 0, 0, 0, 0))}); 3154 */ 3155KJUR.asn1.DERUTCTime = function(params) { 3156 KJUR.asn1.DERUTCTime.superclass.constructor.call(this, params); 3157 this.hT = "17"; 3158 3159 /** 3160 * set value by a Date object 3161 * @name setByDate 3162 * @memberOf KJUR.asn1.DERUTCTime 3163 * @function 3164 * @param {Date} dateObject Date object to set ASN.1 value(V) 3165 */ 3166 this.setByDate = function(dateObject) { 3167 this.hTLV = null; 3168 this.isModified = true; 3169 this.date = dateObject; 3170 this.s = this.formatDate(this.date, 'utc'); 3171 this.hV = stohex(this.s); 3172 }; 3173 3174 if (typeof params != "undefined") { 3175 if (typeof params['str'] != "undefined") { 3176 this.setString(params['str']); 3177 } else if (typeof params['hex'] != "undefined") { 3178 this.setStringHex(params['hex']); 3179 } else if (typeof params['date'] != "undefined") { 3180 this.setByDate(params['date']); 3181 } 3182 } 3183}; 3184JSX.extend(KJUR.asn1.DERUTCTime, KJUR.asn1.DERAbstractTime); 3185 3186// ******************************************************************** 3187/** 3188 * class for ASN.1 DER GeneralizedTime 3189 * @name KJUR.asn1.DERGeneralizedTime 3190 * @class class for ASN.1 DER GeneralizedTime 3191 * @param {Array} params associative array of parameters (ex. {'str': '20130430235959Z'}) 3192 * @extends KJUR.asn1.DERAbstractTime 3193 * @description 3194 * <br/> 3195 * As for argument 'params' for constructor, you can specify one of 3196 * following properties: 3197 * <ul> 3198 * <li>str - specify initial ASN.1 value(V) by a string (ex.'20130430235959Z')</li> 3199 * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li> 3200 * <li>date - specify Date object.</li> 3201 * </ul> 3202 * NOTE: 'params' can be omitted. 3203 */ 3204KJUR.asn1.DERGeneralizedTime = function(params) { 3205 KJUR.asn1.DERGeneralizedTime.superclass.constructor.call(this, params); 3206 this.hT = "18"; 3207 3208 /** 3209 * set value by a Date object 3210 * @name setByDate 3211 * @memberOf KJUR.asn1.DERGeneralizedTime 3212 * @function 3213 * @param {Date} dateObject Date object to set ASN.1 value(V) 3214 * @example 3215 * When you specify UTC time, use 'Date.UTC' method like this:<br/> 3216 * var o = new DERUTCTime(); 3217 * var date = new Date(Date.UTC(2015, 0, 31, 23, 59, 59, 0)); #2015JAN31 23:59:59 3218 * o.setByDate(date); 3219 */ 3220 this.setByDate = function(dateObject) { 3221 this.hTLV = null; 3222 this.isModified = true; 3223 this.date = dateObject; 3224 this.s = this.formatDate(this.date, 'gen'); 3225 this.hV = stohex(this.s); 3226 }; 3227 3228 if (typeof params != "undefined") { 3229 if (typeof params['str'] != "undefined") { 3230 this.setString(params['str']); 3231 } else if (typeof params['hex'] != "undefined") { 3232 this.setStringHex(params['hex']); 3233 } else if (typeof params['date'] != "undefined") { 3234 this.setByDate(params['date']); 3235 } 3236 } 3237}; 3238JSX.extend(KJUR.asn1.DERGeneralizedTime, KJUR.asn1.DERAbstractTime); 3239 3240// ******************************************************************** 3241/** 3242 * class for ASN.1 DER Sequence 3243 * @name KJUR.asn1.DERSequence 3244 * @class class for ASN.1 DER Sequence 3245 * @extends KJUR.asn1.DERAbstractStructured 3246 * @description 3247 * <br/> 3248 * As for argument 'params' for constructor, you can specify one of 3249 * following properties: 3250 * <ul> 3251 * <li>array - specify array of ASN1Object to set elements of content</li> 3252 * </ul> 3253 * NOTE: 'params' can be omitted. 3254 */ 3255KJUR.asn1.DERSequence = function(params) { 3256 KJUR.asn1.DERSequence.superclass.constructor.call(this, params); 3257 this.hT = "30"; 3258 this.getFreshValueHex = function() {
3259 var h = ''; 3260 for (var i = 0; i < this.asn1Array.length; i++) { 3261 var asn1Obj = this.asn1Array[i]; 3262 h += asn1Obj.getEncodedHex(); 3263 } 3264 this.hV = h; 3265 return this.hV; 3266 }; 3267}; 3268JSX.extend(KJUR.asn1.DERSequence, KJUR.asn1.DERAbstractStructured); 3269 3270// ******************************************************************** 3271/** 3272 * class for ASN.1 DER Set 3273 * @name KJUR.asn1.DERSet 3274 * @class class for ASN.1 DER Set 3275 * @extends KJUR.asn1.DERAbstractStructured 3276 * @description 3277 * <br/> 3278 * As for argument 'params' for constructor, you can specify one of 3279 * following properties: 3280 * <ul> 3281 * <li>array - specify array of ASN1Object to set elements of content</li> 3282 * </ul> 3283 * NOTE: 'params' can be omitted. 3284 */ 3285KJUR.asn1.DERSet = function(params) { 3286 KJUR.asn1.DERSet.superclass.constructor.call(this, params); 3287 this.hT = "31"; 3288 this.getFreshValueHex = function() { 3289 var a = new Array(); 3290 for (var i = 0; i < this.asn1Array.length; i++) { 3291 var asn1Obj = this.asn1Array[i]; 3292 a.push(asn1Obj.getEncodedHex()); 3293 } 3294 a.sort(); 3295 this.hV = a.join(''); 3296 return this.hV; 3297 }; 3298}; 3299JSX.extend(KJUR.asn1.DERSet, KJUR.asn1.DERAbstractStructured); 3300 3301// ******************************************************************** 3302/** 3303 * class for ASN.1 DER TaggedObject 3304 * @name KJUR.asn1.DERTaggedObject 3305 * @class class for ASN.1 DER TaggedObject 3306 * @extends KJUR.asn1.ASN1Object 3307 * @description 3308 * <br/> 3309 * Parameter 'tagNoNex' is ASN.1 tag(T) value for this object. 3310 * For example, if you find '[1]' tag in a ASN.1 dump, 3311 * 'tagNoHex' will be 'a1'. 3312 * <br/> 3313 * As for optional argument 'params' for constructor, you can specify *ANY* of 3314 * following properties: 3315 * <ul> 3316 * <li>explicit - specify true if this is explicit tag otherwise false 3317 * (default is 'true').</li> 3318 * <li>tag - specify tag (default is 'a0' which means [0])</li> 3319 * <li>obj - specify ASN1Object which is tagged</li> 3320 * </ul> 3321 * @example 3322 * d1 = new KJUR.asn1.DERUTF8String({'str':'a'}); 3323 * d2 = new KJUR.asn1.DERTaggedObject({'obj': d1}); 3324 * hex = d2.getEncodedHex(); 3325 */ 3326KJUR.asn1.DERTaggedObject = function(params) {
3327 KJUR.asn1.DERTaggedObject.superclass.constructor.call(this); 3328 this.hT = "a0"; 3329 this.hV = ''; 3330 this.isExplicit = true; 3331 this.asn1Object = null; 3332 3333 /** 3334 * set value by an ASN1Object 3335 * @name setString 3336 * @memberOf KJUR.asn1.DERTaggedObject 3337 * @function 3338 * @param {Boolean} isExplicitFlag flag for explicit/implicit tag 3339 * @param {Integer} tagNoHex hexadecimal string of ASN.1 tag 3340 * @param {ASN1Object} asn1Object ASN.1 to encapsulate 3341 */ 3342 this.setASN1Object = function(isExplicitFlag, tagNoHex, asn1Object) { 3343 this.hT = tagNoHex; 3344 this.isExplicit = isExplicitFlag; 3345 this.asn1Object = asn1Object; 3346 if (this.isExplicit) { 3347 this.hV = this.asn1Object.getEncodedHex(); 3348 this.hTLV = null; 3349 this.isModified = true; 3350 } else { 3351 this.hV = null; 3352 this.hTLV = asn1Object.getEncodedHex(); 3353 this.hTLV = this.hTLV.replace(/^../, tagNoHex); 3354 this.isModified = false; 3355 } 3356 }; 3357 3358 this.getFreshValueHex = function() { 3359 return this.hV; 3360 }; 3361 3362 if (typeof params != "undefined") { 3363 if (typeof params['tag'] != "undefined") { 3364 this.hT = params['tag']; 3365 } 3366 if (typeof params['explicit'] != "undefined") { 3367 this.isExplicit = params['explicit']; 3368 } 3369 if (typeof params['obj'] != "undefined") { 3370 this.asn1Object = params['obj']; 3371 this.setASN1Object(this.isExplicit, this.hT, this.asn1Object); 3372 } 3373 } 3374}; 3375JSX.extend(KJUR.asn1.DERTaggedObject, KJUR.asn1.ASN1Object);// Hex JavaScript decoder 3376// Copyright (c) 2008-2013 Lapo Luchini <[email protected]> 3377 3378// Permission to use, copy, modify, and/or distribute this software for any 3379// purpose with or without fee is hereby granted, provided that the above 3380// copyright notice and this permission notice appear in all copies. 3381// 3382// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 3383// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 3384// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 3385// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 3386// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 3387// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 3388// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 3389 3390/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */ 3391(function (undefined) { 3392"use strict"; 3393 3394var Hex = {}, 3395 decoder; 3396 3397Hex.decode = function(a) { 3398 var i; 3399 if (decoder === undefined) { 3400 var hex = "0123456789ABCDEF", 3401 ignore = " \f\n\r\t\u00A0\u2028\u2029"; 3402 decoder = []; 3403 for (i = 0; i < 16; ++i) 3404 decoder[hex.charAt(i)] = i; 3405 hex = hex.toLowerCase(); 3406 for (i = 10; i < 16; ++i) 3407 decoder[hex.charAt(i)] = i; 3408 for (i = 0; i < ignore.length; ++i) 3409 decoder[ignore.charAt(i)] = -1; 3410 } 3411 var out = [], 3412 bits = 0, 3413 char_count = 0; 3414 for (i = 0; i < a.length; ++i) { 3415 var c = a.charAt(i); 3416 if (c == '=') 3417 break; 3418 c = decoder[c]; 3419 if (c == -1) 3420 continue; 3421 if (c === undefined) 3422 throw 'Illegal character at offset ' + i; 3423 bits |= c; 3424 if (++char_count >= 2) { 3425 out[out.length] = bits; 3426 bits = 0; 3427 char_count = 0; 3428 } else { 3429 bits <<= 4; 3430 } 3431 } 3432 if (char_count) 3433 throw "Hex encoding incomplete: 4 bits missing"; 3434 return out; 3435}; 3436 3437// export globals 3438window.Hex = Hex; 3439})();// Base64 JavaScript decoder 3440// Copyright (c) 2008-2013 Lapo Luchini <[email protected]> 3441 3442// Permission to use, copy, modify, and/or distribute this software for any 3443// purpose with or without fee is hereby granted, provided that the above 3444// copyright notice and this permission notice appear in all copies. 3445// 3446// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 3447// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 3448// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 3449// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 3450// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 3451// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 3452// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 3453 3454/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */ 3455(function (undefined) { 3456"use strict"; 3457 3458var Base64 = {}, 3459 decoder; 3460 3461Base64.decode = function (a) { 3462 var i; 3463 if (decoder === undefined) { 3464 var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
3464+/", 3465 ignore = "= \f\n\r\t\u00A0\u2028\u2029"; 3466 decoder = []; 3467 for (i = 0; i < 64; ++i) 3468 decoder[b64.charAt(i)] = i; 3469 for (i = 0; i < ignore.length; ++i) 3470 decoder[ignore.charAt(i)] = -1; 3471 } 3472 var out = []; 3473 var bits = 0, char_count = 0; 3474 for (i = 0; i < a.length; ++i) { 3475 var c = a.charAt(i); 3476 if (c == '=') 3477 break; 3478 c = decoder[c]; 3479 if (c == -1) 3480 continue; 3481 if (c === undefined) 3482 throw 'Illegal character at offset ' + i; 3483 bits |= c; 3484 if (++char_count >= 4) { 3485 out[out.length] = (bits >> 16); 3486 out[out.length] = (bits >> 8) & 0xFF; 3487 out[out.length] = bits & 0xFF; 3488 bits = 0; 3489 char_count = 0; 3490 } else { 3491 bits <<= 6; 3492 } 3493 } 3494 switch (char_count) { 3495 case 1: 3496 throw "Base64 encoding incomplete: at least 2 bits missing"; 3497 case 2: 3498 out[out.length] = (bits >> 10); 3499 break; 3500 case 3: 3501 out[out.length] = (bits >> 16); 3502 out[out.length] = (bits >> 8) & 0xFF; 3503 break; 3504 } 3505 return out; 3506}; 3507 3508Base64.re = /-----BEGIN [^-]+-----([A-Za-z0-9+\/=\s]+)-----END [^-]+-----|begin-base64[^\n]+\n([A-Za-z0-9+\/=\s]+)====/; 3509Base64.unarmor = function (a) { 3510 var m = Base64.re.exec(a); 3511 if (m) { 3512 if (m[1]) 3513 a = m[1]; 3514 else if (m[2]) 3515 a = m[2]; 3516 else 3517 throw "RegExp out of sync"; 3518 } 3519 return Base64.decode(a); 3520}; 3521 3522// export globals 3523window.Base64 = Base64; 3524})();// ASN.1 JavaScript decoder 3525// Copyright (c) 2008-2013 Lapo Luchini <[email protected]> 3526 3527// Permission to use, copy, modify, and/or distribute this software for any 3528// purpose with or without fee is hereby granted, provided that the above 3529// copyright notice and this permission notice appear in all copies. 3530// 3531// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 3532// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 3533// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 3534// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 3535// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 3536// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 3537// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 3538 3539/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */ 3540/*global oids */ 3541(function (undefined) { 3542"use strict"; 3543 3544var hardLimit = 100, 3545 ellipsis = "\u2026", 3546 DOM = { 3547 tag: function (tagName, className) { 3548 var t = document.createElement(tagName); 3549 t.className = className; 3550 return t; 3551 }, 3552 text: function (str) { 3553 return document.createTextNode(str); 3554 } 3555 }; 3556 3557function Stream(enc, pos) { 3558 if (enc instanceof Stream) { 3559 this.enc = enc.enc; 3560 this.pos = enc.pos; 3561 } else { 3562 this.enc = enc; 3563 this.pos = pos; 3564 } 3565} 3566Stream.prototype.get = function (pos) { 3567 if (pos === undefined) 3568 pos = this.pos++; 3569 if (pos >= this.enc.length) 3570 throw 'Requesting byte offset ' + pos + ' on a stream of length ' + this.enc.length; 3571 return this.enc[pos]; 3572}; 3573Stream.prototype.hexDigits = "0123456789ABCDEF"; 3574Stream.prototype.hexByte = function (b) { 3575 return this.hexDigits.charAt((b >> 4) & 0xF) + this.hexDigits.charAt(b & 0xF); 3576}; 3577Stream.prototype.hexDump = function (start, end, raw) { 3578 var s = ""; 3579 for (var i = start; i < end; ++i) { 3580 s += this.hexByte(this.get(i)); 3581 if (raw !== true) 3582 switch (i & 0xF) { 3583 case 0x7: s += " "; break; 3584 case 0xF: s += "\n"; break; 3585 default: s += " "; 3586 } 3587 } 3588 return s; 3589}; 3590Stream.prototype.parseStringISO = function (start, end) { 3591 var s = ""; 3592 for (var i = start; i < end; ++i) 3593 s += String.fromCharCode(this.get(i)); 3594 return s; 3595}; 3596Stream.prototype.parseStringUTF = function (start, end) { 3597 var s = ""; 3598 for (var i = start; i < end; ) { 3599 var c = this.get(i++); 3600 if (c < 128) 3601 s += String.fromCharCode(c); 3602 else if ((c > 191) && (c < 224)) 3603 s += String.fromCharCode(((c & 0x1F) << 6) | (this.get(i++) & 0x3F)); 3604 else 3605 s += String.fromCharCode(((c & 0x0F) << 12) | ((this.get(i++) & 0x3F) << 6) | (this.get(i++) & 0x3F)); 3606 } 3607 return s; 3608}; 3609Stream.prototype.parseStringBMP = function (start, end) { 3610 var str = "" 3611 for (var i = start; i < end; i += 2) { 3612 var high_byte = this.get(i); 3613 var low_byte = this.get(i + 1); 3614 str += String.fromCharCode( (high_byte << 8) + low_byte ); 3615 } 3616 3617 return str; 3618}; 3619Stream.prototype.reTime = /^((?:1[89]|2\d)?\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/; 3620Stream.prototype.parseTime = function (start, end) { 3621 var s = this.parseStringISO(start, end), 3622 m = this.reTime.exec(s); 3623 if (!m) 3624 return "Unrecognized time: " + s; 3625 s = m[1] + "-" + m[2] + "-" + m[3] + " " + m[4]; 3626 if (m[5]) { 3627 s += ":" + m[5]; 3628 if (m[6]) { 3629 s += ":" + m[6]; 3630 if (m[7]) 3631 s += "." + m[7]; 3632 } 3633 } 3634 if (m[8]) { 3635 s += " UTC"; 3636 if (m[8] != 'Z') { 3637 s += m[8]; 3638 if (m[9]) 3639 s += ":" + m[9]; 3640 } 3641 } 3642 return s; 3643}; 3644Stream.prototype.parseInteger = function (start, end) { 3645 //TODO support negative numbers 3646 var len = end - start; 3647 if (len > 4) { 3648 len <<= 3; 3649 var s = this.get(start); 3650 if (s === 0) 3651 len -= 8; 3652 else 3653 while (s < 128) { 3654 s <<= 1; 3655 --len; 3656 } 3657 return "(" + len + " bit)"; 3658 } 3659 var n = 0; 3660 for (var i = start; i < end; ++i) 3661 n = (n << 8) | this.get(i); 3662 return n; 3663}; 3664Stream.prototype.parseBitString = function (start, end) { 3665 var unusedBit = this.get(start), 3666 lenBit = ((end - start - 1) << 3) - unusedBit, 3667 s = "(" + lenBit + " bit)"; 3668 if (lenBit <= 20) { 3669 var skip = unusedBit; 3670 s += " "; 3671 for (var i = end - 1; i > start; --i) { 3672 var b = this.get(i); 3673 for (var j = skip; j < 8; ++j) 3674 s += (b >> j) & 1 ? "1" : "0"; 3675 skip = 0; 3676 } 3677 } 3678 return s; 3679}; 3680Stream.prototype.parseOctetString = function (start, end) { 3681 var len = end - start, 3682 s = "(" + len + " byte) "; 3683 if (len > hardLimit) 3684 end = start + hardLimit; 3685 for (var i = start; i < end; ++i) 3686 s += this.hexByte(this.get(i)); //TODO: also try Latin1? 3687 if (len > hardLimit) 3688 s += ellipsis; 3689 return s; 3690}; 3691Stream.prototype.parseOID = function (start, end) { 3692 var s = '', 3693 n = 0, 3694 bits = 0; 3695 for (var i = start; i < end; ++i) { 3696 var v = this.get(i); 3697 n = (n << 7) | (v & 0x7F); 3698 bits += 7; 3699 if (!(v & 0x80)) { // finished 3700 if (s === '') { 3701 var m = n < 80 ? n < 40 ? 0 : 1 : 2; 3702 s = m + "." + (n - m * 40); 3703 } else 3704 s += "." + ((bits >= 31) ? "bigint" : n); 3705 n = bits = 0; 3706 } 3707 } 3708 return s; 3709}; 3710 3711function ASN1(stream, header, length, tag, sub) { 3712 this.stream = stream; 3713 this.header = header; 3714 this.length = length; 3715 this.tag = tag; 3716 this.sub = sub; 3717} 3718ASN1.prototype.typeName = function () { 3719 if (this.tag === undefined) 3720 return "unknown"; 3721 var tagClass = this.tag >> 6, 3722 tagConstructed = (this.tag >> 5) & 1, 3723 tagNumber = this.tag & 0x1F; 3724 switch (tagClass) { 3725 case 0: // universal 3726 switch (tagNumber) {
3727 case 0x00: return "EOC"; 3728 case 0x01: return "BOOLEAN"; 3729 case 0x02: return "INTEGER"; 3730 case 0x03: return "BIT_STRING"; 3731 case 0x04: return "OCTET_STRING"; 3732 case 0x05: return "NULL"; 3733 case 0x06: return "OBJECT_IDENTIFIER"; 3734 case 0x07: return "ObjectDescriptor"; 3735 case 0x08: return "EXTERNAL"; 3736 case 0x09: return "REAL"; 3737 case 0x0A: return "ENUMERATED"; 3738 case 0x0B: return "EMBEDDED_PDV"; 3739 case 0x0C: return "UTF8String"; 3740 case 0x10: return "SEQUENCE"; 3741 case 0x11: return "SET"; 3742 case 0x12: return "NumericString"; 3743 case 0x13: return "PrintableString"; // ASCII subset 3744 case 0x14: return "TeletexString"; // aka T61String 3745 case 0x15: return "VideotexString"; 3746 case 0x16: return "IA5String"; // ASCII 3747 case 0x17: return "UTCTime"; 3748 case 0x18: return "GeneralizedTime"; 3749 case 0x19: return "GraphicString"; 3750 case 0x1A: return "VisibleString"; // ASCII subset 3751 case 0x1B: return "GeneralString"; 3752 case 0x1C: return "UniversalString"; 3753 case 0x1E: return "BMPString"; 3754 default: return "Universal_" + tagNumber.toString(16); 3755 } 3756 case 1: return "Application_" + tagNumber.toString(16); 3757 case 2: return "[" + tagNumber + "]"; // Context 3758 case 3: return "Private_" + tagNumber.toString(16); 3759 } 3760}; 3761ASN1.prototype.reSeemsASCII = /^[ -~]+$/; 3762ASN1.prototype.content = function () { 3763 if (this.tag === undefined) 3764 return null; 3765 var tagClass = this.tag >> 6, 3766 tagNumber = this.tag & 0x1F, 3767 content = this.posContent(), 3768 len = Math.abs(this.length); 3769 if (tagClass !== 0) { // universal 3770 if (this.sub !== null) 3771 return "(" + this.sub.length + " elem)"; 3772 //TODO: TRY TO PARSE ASCII STRING 3773 var s = this.stream.parseStringISO(content, content + Math.min(len, hardLimit)); 3774 if (this.reSeemsASCII.test(s)) 3775 return s.substring(0, 2 * hardLimit) + ((s.length > 2 * hardLimit) ? ellipsis : ""); 3776 else 3777 return this.stream.parseOctetString(content, content + len); 3778 } 3779 switch (tagNumber) { 3780 case 0x01: // BOOLEAN 3781 return (this.stream.get(content) === 0) ? "false" : "true"; 3782 case 0x02: // INTEGER 3783 return this.stream.parseInteger(content, content + len); 3784 case 0x03: // BIT_STRING 3785 return this.sub ? "(" + this.sub.length + " elem)" : 3786 this.stream.parseBitString(content, content + len); 3787 case 0x04: // OCTET_STRING 3788 return this.sub ? "(" + this.sub.length + " elem)" : 3789 this.stream.parseOctetString(content, content + len); 3790 //case 0x05: // NULL 3791 case 0x06: // OBJECT_IDENTIFIER 3792 return this.stream.parseOID(content, content + len); 3793 //case 0x07: // ObjectDescriptor 3794 //case 0x08: // EXTERNAL 3795 //case 0x09: // REAL 3796 //case 0x0A: // ENUMERATED 3797 //case 0x0B: // EMBEDDED_PDV 3798 case 0x10: // SEQUENCE 3799 case 0x11: // SET 3800 return "(" + this.sub.length + " elem)"; 3801 case 0x0C: // UTF8String 3802 return this.stream.parseStringUTF(content, content + len); 3803 case 0x12: // NumericString 3804 case 0x13: // PrintableString 3805 case 0x14: // TeletexString 3806 case 0x15: // VideotexString 3807 case 0x16: // IA5String 3808 //case 0x19: // GraphicString 3809 case 0x1A: // VisibleString 3810 //case 0x1B: // GeneralString 3811 //case 0x1C: // UniversalString 3812 return this.stream.parseStringISO(content, content + len); 3813 case 0x1E: // BMPString 3814 return this.stream.parseStringBMP(content, content + len); 3815 case 0x17: // UTCTime 3816 case 0x18: // GeneralizedTime 3817 return this.stream.parseTime(content, content + len); 3818 } 3819 return null; 3820}; 3821ASN1.prototype.toString = function () { 3822 return this.typeName() + "@" + this.stream.pos + "[header:" + this.header + ",length:" + this.length + ",sub:" + ((this.sub === null) ? 'null' : this.sub.length) + "]"; 3823}; 3824ASN1.prototype.print = function (indent) { 3825 if (indent === undefined) indent = ''; 3826 document.writeln(indent + this); 3827 if (this.sub !== null) { 3828 indent += ' '; 3829 for (var i = 0, max = this.sub.length; i < max; ++i) 3830 this.sub[i].print(indent); 3831 } 3832}; 3833ASN1.prototype.toPrettyString = function (indent) { 3834 if (indent === undefined) indent = ''; 3835 var s = indent + this.typeName() + " @" + this.stream.pos; 3836 if (this.length >= 0) 3837 s += "+"; 3838 s += this.length; 3839 if (this.tag & 0x20) 3840 s += " (constructed)"; 3841 else if (((this.tag == 0x03) || (this.tag == 0x04)) && (this.sub !== null)) 3842 s += " (encapsulates)"; 3843 s += "\n"; 3844 if (this.sub !== null) { 3845 indent += ' '; 3846 for (var i = 0, max = this.sub.length; i < max; ++i) 3847 s += this.sub[i].toPrettyString(indent); 3848 } 3849 return s; 3850}; 3851ASN1.prototype.toDOM = function () { 3852 var node = DOM.tag("div", "node"); 3853 node.asn1 = this; 3854 var head = DOM.tag("div", "head"); 3855 var s = this.typeName().replace(/_/g, " "); 3856 head.innerHTML = s; 3857 var content = this.content(); 3858 if (content !== null) { 3859 content = String(content).replace(/</g, "<"); 3860 var preview = DOM.tag("span", "preview"); 3861 preview.appendChild(DOM.text(content)); 3862 head.appendChild(preview); 3863 } 3864 node.appendChild(head); 3865 this.node = node; 3866 this.head = head; 3867 var value = DOM.tag("div", "value"); 3868 s = "Offset: " + this.stream.pos + "<br/>"; 3869 s += "Length: " + this.header + "+"; 3870 if (this.length >= 0) 3871 s += this.length; 3872 else 3873 s += (-this.length) + " (undefined)"; 3874 if (this.tag & 0x20) 3875 s += "<br/>(constructed)"; 3876 else if (((this.tag == 0x03) || (this.tag == 0x04)) && (this.sub !== null)) 3877 s += "<br/>(encapsulates)"; 3878 //TODO if (this.tag == 0x03) s += "Unused bits: " 3879 if (content !== null) { 3880 s += "<br/>Value:<br/><b>" + content + "</b>"; 3881 if ((typeof oids === 'object') && (this.tag == 0x06)) { 3882 var oid = oids[content]; 3883 if (oid) { 3884 if (oid.d) s += "<br/>" + oid.d; 3885 if (oid.c) s += "<br/>" + oid.c; 3886 if (oid.w) s += "<br/>(warning!)"; 3887 } 3888 } 3889 } 3890 value.innerHTML = s; 3891 node.appendChild(value); 3892 var sub = DOM.tag("div", "sub"); 3893 if (this.sub !== null) { 3894 for (var i = 0, max = this.sub.length; i < max; ++i) 3895 sub.appendChild(this.sub[i].toDOM()); 3896 } 3897 node.appendChild(sub); 3898 head.onclick = function () {
3899 node.className = (node.className == "node collapsed") ? "node" : "node collapsed"; 3900 }; 3901 return node; 3902}; 3903ASN1.prototype.posStart = function () { 3904 return this.stream.pos; 3905}; 3906ASN1.prototype.posContent = function () { 3907 return this.stream.pos + this.header; 3908}; 3909ASN1.prototype.posEnd = function () { 3910 return this.stream.pos + this.header + Math.abs(this.length); 3911}; 3912ASN1.prototype.fakeHover = function (current) { 3913 this.node.className += " hover"; 3914 if (current) 3915 this.head.className += " hover"; 3916}; 3917ASN1.prototype.fakeOut = function (current) { 3918 var re = / ?hover/; 3919 this.node.className = this.node.className.replace(re, ""); 3920 if (current) 3921 this.head.className = this.head.className.replace(re, ""); 3922}; 3923ASN1.prototype.toHexDOM_sub = function (node, className, stream, start, end) { 3924 if (start >= end) 3925 return; 3926 var sub = DOM.tag("span", className); 3927 sub.appendChild(DOM.text( 3928 stream.hexDump(start, end))); 3929 node.appendChild(sub); 3930}; 3931ASN1.prototype.toHexDOM = function (root) { 3932 var node = DOM.tag("span", "hex"); 3933 if (root === undefined) root = node; 3934 this.head.hexNode = node; 3935 this.head.onmouseover = function () { this.hexNode.className = "hexCurrent"; }; 3936 this.head.onmouseout = function () { this.hexNode.className = "hex"; }; 3937 node.asn1 = this; 3938 node.onmouseover = function () { 3939 var current = !root.selected; 3940 if (current) { 3941 root.selected = this.asn1; 3942 this.className = "hexCurrent"; 3943 } 3944 this.asn1.fakeHover(current); 3945 }; 3946 node.onmouseout = function () { 3947 var current = (root.selected == this.asn1); 3948 this.asn1.fakeOut(current); 3949 if (current) { 3950 root.selected = null; 3951 this.className = "hex"; 3952 } 3953 }; 3954 this.toHexDOM_sub(node, "tag", this.stream, this.posStart(), this.posStart() + 1); 3955 this.toHexDOM_sub(node, (this.length >= 0) ? "dlen" : "ulen", this.stream, this.posStart() + 1, this.posContent()); 3956 if (this.sub === null) 3957 node.appendChild(DOM.text( 3958 this.stream.hexDump(this.posContent(), this.posEnd()))); 3959 else if (this.sub.length > 0) { 3960 var first = this.sub[0]; 3961 var last = this.sub[this.sub.length - 1]; 3962 this.toHexDOM_sub(node, "intro", this.stream, this.posContent(), first.posStart()); 3963 for (var i = 0, max = this.sub.length; i < max; ++i) 3964 node.appendChild(this.sub[i].toHexDOM(root)); 3965 this.toHexDOM_sub(node, "outro", this.stream, last.posEnd(), this.posEnd()); 3966 } 3967 return node; 3968}; 3969ASN1.prototype.toHexString = function (root) { 3970 return this.stream.hexDump(this.posStart(), this.posEnd(), true); 3971}; 3972ASN1.decodeLength = function (stream) { 3973 var buf = stream.get(), 3974 len = buf & 0x7F; 3975 if (len == buf) 3976 return len; 3977 if (len > 3) 3978 throw "Length over 24 bits not supported at position " + (stream.pos - 1); 3979 if (len === 0) 3980 return -1; // undefined 3981 buf = 0; 3982 for (var i = 0; i < len; ++i) 3983 buf = (buf << 8) | stream.get(); 3984 return buf; 3985}; 3986ASN1.hasContent = function (tag, len, stream) { 3987 if (tag & 0x20) // constructed 3988 return true; 3989 if ((tag < 0x03) || (tag > 0x04)) 3990 return false; 3991 var p = new Stream(stream); 3992 if (tag == 0x03) p.get(); // BitString unused bits, must be in [0, 7] 3993 var subTag = p.get(); 3994 if ((subTag >> 6) & 0x01) // not (universal or context) 3995 return false; 3996 try { 3997 var subLength = ASN1.decodeLength(p); 3998 return ((p.pos - stream.pos) + subLength == len); 3999 } catch (exception) { 4000 return false; 4001 } 4002}; 4003ASN1.decode = function (stream) { 4004 if (!(stream instanceof Stream)) 4005 stream = new Stream(stream, 0); 4006 var streamStart = new Stream(stream), 4007 tag = stream.get(), 4008 len = ASN1.decodeLength(stream), 4009 header = stream.pos - streamStart.pos, 4010 sub = null; 4011 if (ASN1.hasContent(tag, len, stream)) { 4012 // it has content, so we decode it 4013 var start = stream.pos; 4014 if (tag == 0x03) stream.get();
4014 // skip BitString unused bits, must be in [0, 7] 4015 sub = []; 4016 if (len >= 0) { 4017 // definite length 4018 var end = start + len; 4019 while (stream.pos < end) 4020 sub[sub.length] = ASN1.decode(stream); 4021 if (stream.pos != end) 4022 throw "Content size is not correct for container starting at offset " + start; 4023 } else { 4024 // undefined length 4025 try { 4026 for (;;) { 4027 var s = ASN1.decode(stream); 4028 if (s.tag === 0) 4029 break; 4030 sub[sub.length] = s; 4031 } 4032 len = start - stream.pos; 4033 } catch (e) { 4034 throw "Exception while decoding undefined length content: " + e; 4035 } 4036 } 4037 } else 4038 stream.pos += len; // skip content 4039 return new ASN1(streamStart, header, len, tag, sub); 4040}; 4041ASN1.test = function () { 4042 var test = [ 4043 { value: [0x27], expected: 0x27 }, 4044 { value: [0x81, 0xC9], expected: 0xC9 }, 4045 { value: [0x83, 0xFE, 0xDC, 0xBA], expected: 0xFEDCBA } 4046 ]; 4047 for (var i = 0, max = test.length; i < max; ++i) { 4048 var pos = 0, 4049 stream = new Stream(test[i].value, 0), 4050 res = ASN1.decodeLength(stream); 4051 if (res != test[i].expected) 4052 document.write("In test[" + i + "] expected " + test[i].expected + " got " + res + "\n"); 4053 } 4054}; 4055 4056// export globals 4057window.ASN1 = ASN1; 4058})();/** 4059 * Retrieve the hexadecimal value (as a string) of the current ASN.1 element 4060 * @returns {string} 4061 * @public 4062 */ 4063ASN1.prototype.getHexStringValue = function(){ 4064 var hexString = this.toHexString(); 4065 var offset = this.header * 2; 4066 var length = this.length * 2; 4067 return hexString.substr(offset,length); 4068}; 4069 4070/** 4071 * Method to parse a pem encoded string containing both a public or private key. 4072 * The method will translate the pem encoded string in a der encoded string and 4073 * will parse private key and public key parameters. This method accepts public key 4074 * in the rsaencryption pkcs #1 format (oid: 1.2.840.113549.1.1.1). 4075 * @todo Check how many rsa formats use the same format of pkcs #1. The format is defined as: 4076 * PublicKeyInfo ::= SEQUENCE { 4077 * algorithm AlgorithmIdentifier, 4078 * PublicKey BIT STRING 4079 * } 4080 * Where AlgorithmIdentifier is: 4081 * AlgorithmIdentifier ::= SEQUENCE { 4082 * algorithm OBJECT IDENTIFIER, the OID of the enc algorithm 4083 * parameters ANY DEFINED BY algorithm OPTIONAL (NULL for PKCS #1) 4084 * } 4085 * and PublicKey is a SEQUENCE encapsulated in a BIT STRING 4086 * RSAPublicKey ::= SEQUENCE { 4087 * modulus INTEGER, -- n 4088 * publicExponent INTEGER -- e 4089 * } 4090 * it's possible to examine the structure of the keys obtained from openssl using 4091 * an asn.1 dumper as the one used here to parse the components: http://lapo.it/asn1js/ 4092 * @argument {string} pem the pem encoded string, can include the BEGIN/END header/footer 4093 * @private 4094 */ 4095RSAKey.prototype.parseKey = function(pem) { 4096 try{ 4097 var reHex = /^\s*(?:[0-9A-Fa-f][0-9A-Fa-f]\s*)+$/; 4098 var der = reHex.test(pem) ? Hex.decode(pem) : Base64.unarmor(pem); 4099 var asn1 = ASN1.decode(der); 4100 if (asn1.sub.length === 9){ 4101 // the data is a Private key 4102 //in order 4103 //Algorithm version, n, e, d, p, q, dmp1, dmq1, coeff 4104 //Alg version, modulus, public exponent, private exponent, prime 1, prime 2, exponent 1, exponent 2, coefficient 4105 var modulus = asn1.sub[1].getHexStringValue(); //bigint 4106 this.n = parseBigInt(modulus, 16); 4107 4108 var public_exponent = asn1.sub[2].getHexStringValue(); //int 4109 this.e = parseInt(public_exponent, 16); 4110 4111 var private_exponent = asn1.sub[3].getHexStringValue(); //bigint 4112 this.d = parseBigInt(private_exponent, 16); 4113 4114 var prime1 = asn1.sub[4].getHexStringValue(); //bigint 4115 this.p = parseBigInt(prime1, 16); 4116 4117 var prime2 = asn1.sub[5].getHexStringValue(); //bigint 4118 this.q = parseBigInt(prime2, 16); 4119 4120 var exponent1 = asn1.sub[6].getHexStringValue(); //bigint 4121 this.dmp1 = parseBigInt(exponent1, 16); 4122 4123 var exponent2 = asn1.sub[7].getHexStringValue(); //bigint 4124 this.dmq1 = parseBigInt(exponent2, 16); 4125 4126 var coefficient = asn1.sub[8].getHexStringValue(); //bigint 4127 this.coeff = parseBigInt(coefficient, 16); 4128 4129 }else if (asn1.sub.length === 2){ 4130 //Public key 4131 //The data PROBABLY is a public key 4132 var bit_string = asn1.sub[1]; 4133 var sequence = bit_string.sub[0]; 4134 4135 var modulus = sequence.sub[0].getHexStringValue(); 4136 this.n = parseBigInt(modulus, 16); 4137 var public_exponent = sequence.sub[1].getHexStringValue(); 4138 this.e = parseInt(public_exponent, 16); 4139 4140 }else{ 4141 return false;
4142 } 4143 return true; 4144 }catch(ex){ 4145 return false; 4146 } 4147}; 4148 4149/** 4150 * Translate rsa parameters in a hex encoded string representing the rsa key. 4151 * The translation follow the ASN.1 notation : 4152 * RSAPrivateKey ::= SEQUENCE { 4153 * version Version, 4154 * modulus INTEGER, -- n 4155 * publicExponent INTEGER, -- e 4156 * privateExponent INTEGER, -- d 4157 * prime1 INTEGER, -- p 4158 * prime2 INTEGER, -- q 4159 * exponent1 INTEGER, -- d mod (p1) 4160 * exponent2 INTEGER, -- d mod (q-1) 4161 * coefficient INTEGER, -- (inverse of q) mod p 4162 * } 4163 * @returns {string} DER Encoded String representing the rsa private key 4164 * @private 4165 */ 4166RSAKey.prototype.getPrivateBaseKey = function() { 4167 //Algorithm version, n, e, d, p, q, dmp1, dmq1, coeff 4168 //Alg version, modulus, public exponent, private exponent, prime 1, prime 2, exponent 1, exponent 2, coefficient 4169 var options = { 4170 'array' : [ 4171 new KJUR.asn1.DERInteger({'int' : 0}), 4172 new KJUR.asn1.DERInteger({'bigint' : this.n}), 4173 new KJUR.asn1.DERInteger({'int' : this.e}), 4174 new KJUR.asn1.DERInteger({'bigint' : this.d}), 4175 new KJUR.asn1.DERInteger({'bigint' : this.p}), 4176 new KJUR.asn1.DERInteger({'bigint' : this.q}), 4177 new KJUR.asn1.DERInteger({'bigint' : this.dmp1}), 4178 new KJUR.asn1.DERInteger({'bigint' : this.dmq1}), 4179 new KJUR.asn1.DERInteger({'bigint' : this.coeff}) 4180 ] 4181 }; 4182 var seq = new KJUR.asn1.DERSequence(options); 4183 return seq.getEncodedHex(); 4184}; 4185 4186/** 4187 * base64 (pem) encoded version of the DER encoded representation 4188 * @returns {string} pem encoded representation without header and footer 4189 * @public 4190 */ 4191RSAKey.prototype.getPrivateBaseKeyB64 = function (){ 4192 return hex2b64(this.getPrivateBaseKey()); 4193}; 4194 4195/** 4196 * Translate rsa parameters in a hex encoded string representing the rsa public key. 4197 * The representation follow the ASN.1 notation : 4198 * PublicKeyInfo ::= SEQUENCE { 4199 * algorithm AlgorithmIdentifier, 4200 * PublicKey BIT STRING 4201 * } 4202 * Where AlgorithmIdentifier is: 4203 * AlgorithmIdentifier ::= SEQUENCE { 4204 * algorithm OBJECT IDENTIFIER, the OID of the enc algorithm 4205 * parameters ANY DEFINED BY algorithm OPTIONAL (NULL for PKCS #1) 4206 * } 4207 * and PublicKey is a SEQUENCE encapsulated in a BIT STRING 4208 * RSAPublicKey ::= SEQUENCE { 4209 * modulus INTEGER, -- n 4210 * publicExponent INTEGER -- e 4211 * } 4212 * @returns {string} DER Encoded String representing the rsa public key 4213 * @private 4214 */ 4215RSAKey.prototype.getPublicBaseKey = function() { 4216 var options = { 4217 'array' : [ 4218 new KJUR.asn1.DERObjectIdentifier({'oid':'1.2.840.113549.1.1.1'}), //RSA Encryption pkcs #1 oid 4219 new KJUR.asn1.DERNull() 4220 ] 4221 }; 4222 var first_sequence = new KJUR.asn1.DERSequence(options); 4223 4224 options = { 4225 'array' : [ 4226 new KJUR.asn1.DERInteger({'bigint' : this.n}), 4227 new KJUR.asn1.DERInteger({'int' : this.e}) 4228 ] 4229 }; 4230 var second_sequence = new KJUR.asn1.DERSequence(options); 4231 4232 options = { 4233 'hex' : '00'+second_sequence.getEncodedHex() 4234 }; 4235 var bit_string = new KJUR.asn1.DERBitString(options); 4236 4237 options = { 4238 'array' : [ 4239 first_sequence, 4240 bit_string 4241 ] 4242 }; 4243 var seq = new KJUR.asn1.DERSequence(options); 4244 return seq.getEncodedHex(); 4245}; 4246 4247/** 4248 * base64 (pem) encoded version of the DER encoded representation 4249 * @returns {string} pem encoded representation without header and footer 4250 * @public 4251 */ 4252RSAKey.prototype.getPublicBaseKeyB64 = function (){ 4253 return hex2b64(this.getPublicBaseKey()); 4254}; 4255 4256/** 4257 * wrap the string in block of width chars. The default value for rsa keys is 64 4258 * characters. 4259 * @param {string} str the pem encoded string without header and footer 4260 * @param {Number} [width=64] - the length the string has to be wrapped at 4261 * @returns {string} 4262 * @private 4263 */ 4264RSAKey.prototype.wordwrap = function(str, width) { 4265 width = width || 64; 4266 if (!str) 4267 return str;
4268 var regex = '(.{1,' + width + '})( +|$\n?)|(.{1,' + width + '})'; 4269 return str.match(RegExp(regex, 'g')).join('\n'); 4270}; 4271 4272/** 4273 * Retrieve the pem encoded private key 4274 * @returns {string} the pem encoded private key with header/footer 4275 * @public 4276 */ 4277RSAKey.prototype.getPrivateKey = function() { 4278 var key = "-----BEGIN RSA PRIVATE KEY-----\n"; 4279 key += this.wordwrap(this.getPrivateBaseKeyB64()) + "\n"; 4280 key += "-----END RSA PRIVATE KEY-----"; 4281 return key; 4282}; 4283 4284/** 4285 * Retrieve the pem encoded public key 4286 * @returns {string} the pem encoded public key with header/footer 4287 * @public 4288 */ 4289RSAKey.prototype.getPublicKey = function() { 4290 var key = "-----BEGIN PUBLIC KEY-----\n"; 4291 key += this.wordwrap(this.getPublicBaseKeyB64()) + "\n"; 4292 key += "-----END PUBLIC KEY-----"; 4293 return key; 4294}; 4295 4296/** 4297 * Check if the object contains the necessary parameters to populate the rsa modulus 4298 * and public exponent parameters. 4299 * @param {Object} [obj={}] - An object that may contain the two public key 4300 * parameters 4301 * @returns {boolean} true if the object contains both the modulus and the public exponent 4302 * properties (n and e) 4303 * @todo check for types of n and e. N should be a parseable bigInt object, E should 4304 * be a parseable integer number 4305 * @private 4306 */ 4307RSAKey.prototype.hasPublicKeyProperty = function(obj){ 4308 obj = obj || {}; 4309 return obj.hasOwnProperty('n') && 4310 obj.hasOwnProperty('e'); 4311}; 4312 4313/** 4314 * Check if the object contains ALL the parameters of an RSA key. 4315 * @param {Object} [obj={}] - An object that may contain nine rsa key 4316 * parameters 4317 * @returns {boolean} true if the object contains all the parameters needed 4318 * @todo check for types of the parameters all the parameters but the public exponent 4319 * should be parseable bigint objects, the public exponent should be a parseable integer number 4320 * @private 4321 */ 4322RSAKey.prototype.hasPrivateKeyProperty = function(obj){ 4323 obj = obj || {}; 4324 return obj.hasOwnProperty('n') && 4325 obj.hasOwnProperty('e') && 4326 obj.hasOwnProperty('d') && 4327 obj.hasOwnProperty('p') && 4328 obj.hasOwnProperty('q') && 4329 obj.hasOwnProperty('dmp1') && 4330 obj.hasOwnProperty('dmq1') && 4331 obj.hasOwnProperty('coeff'); 4332}; 4333 4334/** 4335 * Parse the properties of obj in the current rsa object. Obj should AT LEAST 4336 * include the modulus and public exponent (n, e) parameters. 4337 * @param {Object} obj - the object containing rsa parameters 4338 * @private 4339 */ 4340RSAKey.prototype.parsePropertiesFrom = function(obj){ 4341 this.n = obj.n; 4342 this.e = obj.e; 4343 4344 if (obj.hasOwnProperty('d')){ 4345 this.d = obj.d; 4346 this.p = obj.p; 4347 this.q = obj.q; 4348 this.dmp1 = obj.dmp1; 4349 this.dmq1 = obj.dmq1; 4350 this.coeff = obj.coeff; 4351 } 4352}; 4353 4354/** 4355 * Create a new JSEncryptRSAKey that extends Tom Wu's RSA key object. 4356 * This object is just a decorator for parsing the key parameter 4357 * @param {string|Object} key - The key in string format, or an object containing 4358 * the parameters needed to build a RSAKey object. 4359 * @constructor 4360 */ 4361var JSEncryptRSAKey = function(key) { 4362 // Call the super constructor. 4363 RSAKey.call(this); 4364 // If a key key was provided. 4365 if (key) { 4366 // If this is a string... 4367 if (typeof key === 'string') { 4368 this.parseKey(key); 4369 }else if (this.hasPrivateKeyProperty(key)||this.hasPublicKeyProperty(key)) { 4370 // Set the values for the key. 4371 this.parsePropertiesFrom(key); 4372 } 4373 } 4374}; 4375 4376// Derive from RSAKey. 4377JSEncryptRSAKey.prototype = new RSAKey(); 4378 4379// Reset the contructor. 4380JSEncryptRSAKey.prototype.constructor = JSEncryptRSAKey; 4381 4382 4383/** 4384 * 4385 * @param {Object} [options = {}] - An object to customize JSEncrypt behaviour 4386 * possible parameters are: 4387 * - default_key_size {number} default: 1024 the key size in bit 4388 * - default_public_exponent {string} default: '010001' the hexadecimal representation of the public exponent 4389 * - log {boolean} default: false whether log warn/error or not 4390 * @constructor 4391 */ 4392var JSEncrypt = function(options) { 4393 options = options || {}; 4394 this.default_key_size = parseInt(options.default_key_size) || 1024; 4395 this.default_public_exponent = options.default_public_exponent || '010001';
4395 //65537 default openssl public exponent for rsa key type 4396 this.log = options.log || false; 4397 // The private and public key. 4398 this.key = null; 4399}; 4400 4401/** 4402 * Method to set the rsa key parameter (one method is enough to set both the public 4403 * and the private key, since the private key contains the public key paramenters) 4404 * Log a warning if logs are enabled 4405 * @param {Object|string} key the pem encoded string or an object (with or without header/footer) 4406 * @public 4407 */ 4408JSEncrypt.prototype.setKey = function(key){ 4409 if (this.log && this.key) 4410 console.warn('A key was already set, overriding existing.'); 4411 this.key = new JSEncryptRSAKey(key); 4412}; 4413 4414/** 4415 * Proxy method for setKey, for api compatibility 4416 * @see setKey 4417 * @public 4418 */ 4419JSEncrypt.prototype.setPrivateKey = function(privkey) { 4420 // Create the key. 4421 this.setKey(privkey); 4422}; 4423 4424/** 4425 * Proxy method for setKey, for api compatibility 4426 * @see setKey 4427 * @public 4428 */ 4429JSEncrypt.prototype.setPublicKey = function(pubkey) { 4430 // Sets the public key. 4431 this.setKey(pubkey); 4432}; 4433 4434/** 4435 * Proxy method for RSAKey object's decrypt, decrypt the string using the private 4436 * components of the rsa key object. Note that if the object was not set will be created 4437 * on the fly (by the getKey method) using the parameters passed in the JSEncrypt constructor 4438 * @param {string} string base64 encoded crypted string to decrypt 4439 * @return {string} the decrypted string 4440 * @public 4441 */ 4442JSEncrypt.prototype.decrypt = function(string) { 4443 // Return the decrypted string. 4444 try{ 4445 return this.getKey().decrypt(b64tohex(string)); 4446 }catch(ex){ 4447 return false; 4448 } 4449}; 4450 4451/** 4452 * Proxy method for RSAKey object's encrypt, encrypt the string using the public 4453 * components of the rsa key object. Note that if the object was not set will be created 4454 * on the fly (by the getKey method) using the parameters passed in the JSEncrypt constructor 4455 * @param {string} string the string to encrypt 4456 * @return {string} the encrypted string encoded in base64 4457 * @public 4458 */ 4459JSEncrypt.prototype.encrypt = function(string) { 4460 // Return the encrypted string. 4461 try{ 4462 return hex2b64(this.getKey().encrypt(string)); 4463 }catch(ex){ 4464 return false; 4465 } 4466}; 4467 4468/** 4469 * Getter for the current JSEncryptRSAKey object. If it doesn't exists a new object 4470 * will be created and returned 4471 * @param {callback} [cb] the callback to be called if we want the key to be generated 4472 * in an async fashion 4473 * @returns {JSEncryptRSAKey} the JSEncryptRSAKey object 4474 * @public 4475 */ 4476JSEncrypt.prototype.getKey = function(cb){ 4477 // Only create new if it does not exist. 4478 if (!this.key) { 4479 // Get a new private key. 4480 this.key = new JSEncryptRSAKey(); 4481 if (cb && {}.toString.call(cb) === '[object Function]'){ 4482 this.key.generateAsync(this.default_key_size, this.default_public_exponent,cb); 4483 return; 4484 } 4485 // Generate the key. 4486 this.key.generate(this.default_key_size, this.default_public_exponent); 4487 } 4488 return this.key; 4489}; 4490 4491/** 4492 * Returns the pem encoded representation of the private key 4493 * If the key doesn't exists a new key will be created 4494 * @returns {string} pem encoded representation of the private key WITH header and footer 4495 * @public 4496 */ 4497JSEncrypt.prototype.getPrivateKey = function() { 4498 // Return the private representation of this key. 4499 return this.getKey().getPrivateKey(); 4500}; 4501 4502/** 4503 * Returns the pem encoded representation of the private key 4504 * If the key doesn't exists a new key will be created 4505 * @returns {string} pem encoded representation of the private key WITHOUT header and footer 4506 * @public 4507 */ 4508JSEncrypt.prototype.getPrivateKeyB64 = function() { 4509 // Return the private representation of this key. 4510 return this.getKey().getPrivateBaseKeyB64(); 4511}; 4512 4513 4514/** 4515 * Returns the pem encoded representation of the public key 4516 * If the key doesn't exists a new key will be created 4517 * @returns {string} pem encoded representation of the public key WITH header and footer 4518 * @public 4519 */ 4520JSEncrypt.prototype.getPublicKey = function() { 4521 // Return the private representation of this key. 4522 return this.getKey().getPublicKey(); 4523}; 4524 4525/** 4526 * Returns the pem encoded representation of the public key 4527 * If the key doesn't exists a new key will be created 4528 * @returns {string} pem encoded representation of the public key WITHOUT header and footer 4529 * @public 4530 */ 4531JSEncrypt.prototype.getPublicKeyB64 = function() { 4532 // Return the private representation of this key. 4533 return this.getKey().getPublicBaseKeyB64(); 4534}; 4535exports.JSEncrypt = JSEncrypt; 4536})(JSEncryptExports); 4537var JSEncrypt = JSEncryptExports.JSEncrypt; 4538 4539// Important call 4540$.jCryption.crypt = new JSEncrypt(); 4541 4542/* http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js */ 4543/* 4544CryptoJS v3.1.2 4545code.google.com/p/crypto-js
vendor: 4,768 bytes, lines 4546-4559
4546(c) 2009-2013 by Jeff Mott. All rights reserved. 4547code.google.com/p/crypto-js/wiki/License 4548*/ 4549var CryptoJS=CryptoJS||function(u,p){var d={},l=d.lib={},s=function(){},t=l.Base={extend:function(a){s.prototype=this;var c=new s;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}}, 4550r=l.WordArray=t.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=p?c:4*a.length},toString:function(a){return(a||v).stringify(this)},concat:function(a){var c=this.words,e=a.words,j=this.sigBytes;a=a.sigBytes;this.clamp();if(j%4)for(var k=0;k<a;k++)c[j+k>>>2]|=(e[k>>>2]>>>24-8*(k%4)&255)<<24-8*((j+k)%4);else if(65535<e.length)for(k=0;k<a;k+=4)c[j+k>>>2]=e[k>>>2];else c.push.apply(c,e);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< 455132-8*(c%4);a.length=u.ceil(c/4)},clone:function(){var a=t.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],e=0;e<a;e+=4)c.push(4294967296*u.random()|0);return new r.init(c,a)}}),w=d.enc={},v=w.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j<a;j++){var k=c[j>>>2]>>>24-8*(j%4)&255;e.push((k>>>4).toString(16));e.push((k&15).toString(16))}return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j<c;j+=2)e[j>>>3]|=parseInt(a.substr(j, 45522),16)<<24-4*(j%8);return new r.init(e,c/2)}},b=w.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j<a;j++)e.push(String.fromCharCode(c[j>>>2]>>>24-8*(j%4)&255));return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j<c;j++)e[j>>>2]|=(a.charCodeAt(j)&255)<<24-8*(j%4);return new r.init(e,c)}},x=w.Utf8={stringify:function(a){try{return decodeURIComponent(escape(b.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return b.parse(unescape(encodeURIComponent(a)))}}, 4553q=l.BufferedBlockAlgorithm=t.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=x.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,e=c.words,j=c.sigBytes,k=this.blockSize,b=j/(4*k),b=a?u.ceil(b):u.max((b|0)-this._minBufferSize,0);a=b*k;j=u.min(4*a,j);if(a){for(var q=0;q<a;q+=k)this._doProcessBlock(e,q);q=e.splice(0,a);c.sigBytes-=j}return new r.init(q,j)},clone:function(){var a=t.clone.call(this); 4554a._data=this._data.clone();return a},_minBufferSize:0});l.Hasher=q.extend({cfg:t.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){q.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(b,e){return(new a.init(e)).finalize(b)}},_createHmacHelper:function(a){return function(b,e){return(new n.HMAC.init(a, 4555e)).finalize(b)}}});var n=d.algo={};return d}(Math); 4556(function(){var u=CryptoJS,p=u.lib.WordArray;u.enc.Base64={stringify:function(d){var l=d.words,p=d.sigBytes,t=this._map;d.clamp();d=[];for(var r=0;r<p;r+=3)for(var w=(l[r>>>2]>>>24-8*(r%4)&255)<<16|(l[r+1>>>2]>>>24-8*((r+1)%4)&255)<<8|l[r+2>>>2]>>>24-8*((r+2)%4)&255,v=0;4>v&&r+0.75*v<p;v++)d.push(t.charAt(w>>>6*(3-v)&63));if(l=t.charAt(64))for(;d.length%4;)d.push(l);return d.join("")},parse:function(d){var l=d.length,s=this._map,t=s.charAt(64);t&&(t=d.indexOf(t),-1!=t&&(l=t));for(var t=[],r=0,w=0;w< 4557l;w++)if(w%4){var v=s.indexOf(d.charAt(w-1))<<2*(w%4),b=s.indexOf(d.charAt(w))>>>6-2*(w%4);t[r>>>2]|=(v|b)<<24-8*(r%4);r++}return p.create(t,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}})(); 4558(function(u){function p(b,n,a,c,e,j,k){b=b+(n&a|~n&c)+e+k;return(b<<j|b>>>32-j)+n}function d(b,n,a,c,e,j,k){b=b+(n&c|a&~c)+e+k;return(b<<j|b>>>32-j)+n}function l(b,n,a,c,e,j,k){b=b+(n^a^c)+e+k;return(b<<j|b>>>32-j)+n}function s(b,n,a,c,e,j,k){b=b+(a^(n|~c))+e+k;return(b<<j|b>>>32-j)+n}for(var t=CryptoJS,r=t.lib,w=r.WordArray,v=r.Hasher,r=t.algo,b=[],x=0;64>x;x++)b[x]=4294967296*u.abs(u.sin(x+1))|0;r=r.MD5=v.extend({_doReset:function(){this._hash=new w.init([1732584193,4023233417,2562383102,271733878])}, 4559_doProcessBlock:function(q,n){for(var a=0;16>a;a++){var c=n+a,e=q[c];q[c]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360}var a=this._hash.words,c=q[n+0],e=q[n+1],j=q[n+2],k=q[n+3],z=q[n+4],r=q[n+5],t=q[n+6],w=q[n+7],v=q[n+8],A=q[n+9],B=q[n+10],C=q[n+11],u=q[n+12],D=q[n+13],E=q[
vendor: 8,545 bytes, lines 4559-4577
4559n+14],x=q[n+15],f=a[0],m=a[1],g=a[2],h=a[3],f=p(f,m,g,h,c,7,b[0]),h=p(h,f,m,g,e,12,b[1]),g=p(g,h,f,m,j,17,b[2]),m=p(m,g,h,f,k,22,b[3]),f=p(f,m,g,h,z,7,b[4]),h=p(h,f,m,g,r,12,b[5]),g=p(g,h,f,m,t,17,b[6]),m=p(m,g,h,f,w,22,b[7]), 4560f=p(f,m,g,h,v,7,b[8]),h=p(h,f,m,g,A,12,b[9]),g=p(g,h,f,m,B,17,b[10]),m=p(m,g,h,f,C,22,b[11]),f=p(f,m,g,h,u,7,b[12]),h=p(h,f,m,g,D,12,b[13]),g=p(g,h,f,m,E,17,b[14]),m=p(m,g,h,f,x,22,b[15]),f=d(f,m,g,h,e,5,b[16]),h=d(h,f,m,g,t,9,b[17]),g=d(g,h,f,m,C,14,b[18]),m=d(m,g,h,f,c,20,b[19]),f=d(f,m,g,h,r,5,b[20]),h=d(h,f,m,g,B,9,b[21]),g=d(g,h,f,m,x,14,b[22]),m=d(m,g,h,f,z,20,b[23]),f=d(f,m,g,h,A,5,b[24]),h=d(h,f,m,g,E,9,b[25]),g=d(g,h,f,m,k,14,b[26]),m=d(m,g,h,f,v,20,b[27]),f=d(f,m,g,h,D,5,b[28]),h=d(h,f, 4561m,g,j,9,b[29]),g=d(g,h,f,m,w,14,b[30]),m=d(m,g,h,f,u,20,b[31]),f=l(f,m,g,h,r,4,b[32]),h=l(h,f,m,g,v,11,b[33]),g=l(g,h,f,m,C,16,b[34]),m=l(m,g,h,f,E,23,b[35]),f=l(f,m,g,h,e,4,b[36]),h=l(h,f,m,g,z,11,b[37]),g=l(g,h,f,m,w,16,b[38]),m=l(m,g,h,f,B,23,b[39]),f=l(f,m,g,h,D,4,b[40]),h=l(h,f,m,g,c,11,b[41]),g=l(g,h,f,m,k,16,b[42]),m=l(m,g,h,f,t,23,b[43]),f=l(f,m,g,h,A,4,b[44]),h=l(h,f,m,g,u,11,b[45]),g=l(g,h,f,m,x,16,b[46]),m=l(m,g,h,f,j,23,b[47]),f=s(f,m,g,h,c,6,b[48]),h=s(h,f,m,g,w,10,b[49]),g=s(g,h,f,m, 4562E,15,b[50]),m=s(m,g,h,f,r,21,b[51]),f=s(f,m,g,h,u,6,b[52]),h=s(h,f,m,g,k,10,b[53]),g=s(g,h,f,m,B,15,b[54]),m=s(m,g,h,f,e,21,b[55]),f=s(f,m,g,h,v,6,b[56]),h=s(h,f,m,g,x,10,b[57]),g=s(g,h,f,m,t,15,b[58]),m=s(m,g,h,f,D,21,b[59]),f=s(f,m,g,h,z,6,b[60]),h=s(h,f,m,g,C,10,b[61]),g=s(g,h,f,m,j,15,b[62]),m=s(m,g,h,f,A,21,b[63]);a[0]=a[0]+f|0;a[1]=a[1]+m|0;a[2]=a[2]+g|0;a[3]=a[3]+h|0},_doFinalize:function(){var b=this._data,n=b.words,a=8*this._nDataBytes,c=8*b.sigBytes;n[c>>>5]|=128<<24-c%32;var e=u.floor(a/ 45634294967296);n[(c+64>>>9<<4)+15]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360;n[(c+64>>>9<<4)+14]=(a<<8|a>>>24)&16711935|(a<<24|a>>>8)&4278255360;b.sigBytes=4*(n.length+1);this._process();b=this._hash;n=b.words;for(a=0;4>a;a++)c=n[a],n[a]=(c<<8|c>>>24)&16711935|(c<<24|c>>>8)&4278255360;return b},clone:function(){var b=v.clone.call(this);b._hash=this._hash.clone();return b}});t.MD5=v._createHelper(r);t.HmacMD5=v._createHmacHelper(r)})(Math); 4564(function(){var u=CryptoJS,p=u.lib,d=p.Base,l=p.WordArray,p=u.algo,s=p.EvpKDF=d.extend({cfg:d.extend({keySize:4,hasher:p.MD5,iterations:1}),init:function(d){this.cfg=this.cfg.extend(d)},compute:function(d,r){for(var p=this.cfg,s=p.hasher.create(),b=l.create(),u=b.words,q=p.keySize,p=p.iterations;u.length<q;){n&&s.update(n);var n=s.update(d).finalize(r);s.reset();for(var a=1;a<p;a++)n=s.finalize(n),s.reset();b.concat(n)}b.sigBytes=4*q;return b}});u.EvpKDF=function(d,l,p){return s.create(p).compute(d, 4565l)}})(); 4566CryptoJS.lib.Cipher||function(u){var p=CryptoJS,d=p.lib,l=d.Base,s=d.WordArray,t=d.BufferedBlockAlgorithm,r=p.enc.Base64,w=p.algo.EvpKDF,v=d.Cipher=t.extend({cfg:l.extend(),createEncryptor:function(e,a){return this.create(this._ENC_XFORM_MODE,e,a)},createDecryptor:function(e,a){return this.create(this._DEC_XFORM_MODE,e,a)},init:function(e,a,b){this.cfg=this.cfg.extend(b);this._xformMode=e;this._key=a;this.reset()},reset:function(){t.reset.call(this);this._doReset()},process:function(e){this._append(e);return this._process()}, 4567finalize:function(e){e&&this._append(e);return this._doFinalize()},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(e){return{encrypt:function(b,k,d){return("string"==typeof k?c:a).encrypt(e,b,k,d)},decrypt:function(b,k,d){return("string"==typeof k?c:a).decrypt(e,b,k,d)}}}});d.StreamCipher=v.extend({_doFinalize:function(){return this._process(!0)},blockSize:1});var b=p.mode={},x=function(e,a,b){var c=this._iv;c?this._iv=u:c=this._prevBlock;for(var d=0;d<b;d++)e[a+d]^= 4568c[d]},q=(d.BlockCipherMode=l.extend({createEncryptor:function(e,a){return this.Encryptor.create(e,a)},createDecryptor:function(e,a){return this.Decryptor.create(e,a)},init:function(e,a){this._cipher=e;this._iv=a}})).extend();q.Encryptor=q.extend({processBlock:function(e,a){var b=this._cipher,c=b.blockSize;x.call(this,e,a,c);b.encryptBlock(e,a);this._prevBlock=e.slice(a,a+c)}});q.Decryptor=q.extend({processBlock:function(e,a){var b=this._cipher,c=b.blockSize,d=e.slice(a,a+c);b.decryptBlock(e,a);x.call(this, 4569e,a,c);this._prevBlock=d}});b=b.CBC=q;q=(p.pad={}).Pkcs7={pad:function(a,b){for(var c=4*b,c=c-a.sigBytes%c,d=c<<24|c<<16|c<<8|c,l=[],n=0;n<c;n+=4)l.push(d);c=s.create(l,c);a.concat(c)},unpad:function(a){a.sigBytes-=a.words[a.sigBytes-1>>>2]&255}};d.BlockCipher=v.extend({cfg:v.cfg.extend({mode:b,padding:q}),reset:function(){v.reset.call(this);var a=this.cfg,b=a.iv,a=a.mode;if(this._xformMode==this._ENC_XFORM_MODE)var c=a.createEncryptor;else c=a.createDecryptor,this._minBufferSize=1;this._mode=c.call(a, 4570this,b&&b.words)},_doProcessBlock:function(a,b){this._mode.processBlock(a,b)},_doFinalize:function(){var a=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){a.pad(this._data,this.blockSize);var b=this._process(!0)}else b=this._process(!0),a.unpad(b);return b},blockSize:4});var n=d.CipherParams=l.extend({init:function(a){this.mixIn(a)},toString:function(a){return(a||this.formatter).stringify(this)}}),b=(p.format={}).OpenSSL={stringify:function(a){var b=a.ciphertext;a=a.salt;return(a?s.create([1398893684, 45711701076831]).concat(a).concat(b):b).toString(r)},parse:function(a){a=r.parse(a);var b=a.words;if(1398893684==b[0]&&1701076831==b[1]){var c=s.create(b.slice(2,4));b.splice(0,4);a.sigBytes-=16}return n.create({ciphertext:a,salt:c})}},a=d.SerializableCipher=l.extend({cfg:l.extend({format:b}),encrypt:function(a,b,c,d){d=this.cfg.extend(d);var l=a.createEncryptor(c,d);b=l.finalize(b);l=l.cfg;return n.create({ciphertext:b,key:c,iv:l.iv,algorithm:a,mode:l.mode,padding:l.padding,blockSize:a.blockSize,formatter:d.format})}, 4572decrypt:function(a,b,c,d){d=this.cfg.extend(d);b=this._parse(b,d.format);return a.createDecryptor(c,d).finalize(b.ciphertext)},_parse:function(a,b){return"string"==typeof a?b.parse(a,this):a}}),p=(p.kdf={}).OpenSSL={execute:function(a,b,c,d){d||(d=s.random(8));a=w.create({keySize:b+c}).compute(a,d);c=s.create(a.words.slice(b),4*c);a.sigBytes=4*b;return n.create({key:a,iv:c,salt:d})}},c=d.PasswordBasedCipher=a.extend({cfg:a.cfg.extend({kdf:p}),encrypt:function(b,c,d,l){l=this.cfg.extend(l);d=l.kdf.execute(d, 4573b.keySize,b.ivSize);l.iv=d.iv;b=a.encrypt.call(this,b,c,d.key,l);b.mixIn(d);return b},decrypt:function(b,c,d,l){l=this.cfg.extend(l);c=this._parse(c,l.format);d=l.kdf.execute(d,b.keySize,b.ivSize,c.salt);l.iv=d.iv;return a.decrypt.call(this,b,c,d.key,l)}})}(); 4574(function(){for(var u=CryptoJS,p=u.lib.BlockCipher,d=u.algo,l=[],s=[],t=[],r=[],w=[],v=[],b=[],x=[],q=[],n=[],a=[],c=0;256>c;c++)a[c]=128>c?c<<1:c<<1^283;for(var e=0,j=0,c=0;256>c;c++){var k=j^j<<1^j<<2^j<<3^j<<4,k=k>>>8^k&255^99;l[e]=k;s[k]=e;var z=a[e],F=a[z],G=a[F],y=257*a[k]^16843008*k;t[e]=y<<24|y>>>8;r[e]=y<<16|y>>>16;w[e]=y<<8|y>>>24;v[e]=y;y=16843009*G^65537*F^257*z^16843008*e;b[k]=y<<24|y>>>8;x[k]=y<<16|y>>>16;q[k]=y<<8|y>>>24;n[k]=y;e?(e=z^a[a[a[G^z]]],j^=a[a[j]]):e=j=1}var H=[0,1,2,4,8, 457516,32,64,128,27,54],d=d.AES=p.extend({_doReset:function(){for(var a=this._key,c=a.words,d=a.sigBytes/4,a=4*((this._nRounds=d+6)+1),e=this._keySchedule=[],j=0;j<a;j++)if(j<d)e[j]=c[j];else{var k=e[j-1];j%d?6<d&&4==j%d&&(k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255]):(k=k<<8|k>>>24,k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255],k^=H[j/d|0]<<24);e[j]=e[j-d]^k}c=this._invKeySchedule=[];for(d=0;d<a;d++)j=a-d,k=d%4?e[j]:e[j-4],c[d]=4>d||4>=j?k:b[l[k>>>24]]^x[l[k>>>16&255]]^q[l[k>>> 45768&255]]^n[l[k&255]]},encryptBlock:function(a,b){this._doCryptBlock(a,b,this._keySchedule,t,r,w,v,l)},decryptBlock:function(a,c){var d=a[c+1];a[c+1]=a[c+3];a[c+3]=d;this._doCryptBlock(a,c,this._invKeySchedule,b,x,q,n,s);d=a[c+1];a[c+1]=a[c+3];a[c+3]=d},_doCryptBlock:function(a,b,c,d,e,j,l,f){for(var m=this._nRounds,g=a[b]^c[0],h=a[b+1]^c[1],k=a[b+2]^c[2],n=a[b+3]^c[3],p=4,r=1;r<m;r++)var q=d[g>>>24]^e[h>>>16&255]^j[k>>>8&255]^l[n&255]^c[p++],s=d[h>>>24]^e[k>>>16&255]^j[n>>>8&255]^l[g&255]^c[p++],t= 4577d[k>>>24]^e[n>>>16&255]^j[g>>>8&255]^l[h&255]^c[p++],n=d[n>>>24]^e[g>>>16&255]^j[h>>>8&255]^l[k&255]^c[p++],g=q,h=s,k=t;q=(f[g>>>24]<<24|f[h>>>16&255]<<16|f[k>>>8&255]<<8|f[n&255])^c[p++];s=(f[h>>>24]<<24|f[k>>>16&255]<<16|f[n>>>8&255]<<8|f[g&255])^c[p++];t=(f[k>>>24]<<24|f[n>>>16&255]<<16|f[g>>>8&255]<<8|f[h&255])^c[p++];n=(f[n>>>24]<<24|f[g>>>16&255]<<16|f[h>>>8&255]<<8|f[k&255])^c[p++];a[b]=q;a[b+1]=s;a[b+2]=t;a[b+3]=n},keySize:8});u.AES=p._createHelper(d)})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.