APIs

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