diff --git a/src/ciphers/asymmetric/jsbn2.js b/src/ciphers/asymmetric/jsbn2.js deleted file mode 100644 index 4f60185c..00000000 --- a/src/ciphers/asymmetric/jsbn2.js +++ /dev/null @@ -1,720 +0,0 @@ -/* - * Copyright (c) 2003-2005 Tom Wu (tjw@cs.Stanford.EDU) - * All Rights Reserved. - * - * Modified by Recurity Labs GmbH - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, - * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF - * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * In addition, the following condition applies: - * - * All redistributions must retain an intact copy of this copyright notice - * and disclaimer. - */ -// Extended JavaScript BN functions, required for RSA private ops. - -// Version 1.1: new BigInteger("0", 10) returns "proper" zero -// Version 1.2: square() API, isProbablePrime fix - -// (public) -function bnClone() { var r = nbi(); this.copyTo(r); return r; } - -// (public) return value as integer -function bnIntValue() { - if(this.s < 0) { - if(this.t == 1) return this[0]-this.DV; - else if(this.t == 0) return -1; - } - else if(this.t == 1) return this[0]; - else if(this.t == 0) return 0; - // assumes 16 < DB < 32 - return ((this[1]&((1<<(32-this.DB))-1))<>24; } - -// (public) return value as short (assumes DB>=16) -function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } - -// (protected) return x s.t. r^x < DV -function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } - -// (public) 0 if this == 0, 1 if this > 0 -function bnSigNum() { - if(this.s < 0) return -1; - else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; - else return 1; -} - -// (protected) convert to radix string -function bnpToRadix(b) { - if(b == null) b = 10; - if(this.signum() == 0 || b < 2 || b > 36) return "0"; - var cs = this.chunkSize(b); - var a = Math.pow(b,cs); - var d = nbv(a), y = nbi(), z = nbi(), r = ""; - this.divRemTo(d,y,z); - while(y.signum() > 0) { - r = (a+z.intValue()).toString(b).substr(1) + r; - y.divRemTo(d,y,z); - } - return z.intValue().toString(b) + r; -} - -// (protected) convert from radix string -function bnpFromRadix(s,b) { - this.fromInt(0); - if(b == null) b = 10; - var cs = this.chunkSize(b); - var d = Math.pow(b,cs), mi = false, j = 0, w = 0; - for(var i = 0; i < s.length; ++i) { - var x = intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-" && this.signum() == 0) mi = true; - continue; - } - w = b*w+x; - if(++j >= cs) { - this.dMultiply(d); - this.dAddOffset(w,0); - j = 0; - w = 0; - } - } - if(j > 0) { - this.dMultiply(Math.pow(b,j)); - this.dAddOffset(w,0); - } - if(mi) BigInteger.ZERO.subTo(this,this); -} - -// (protected) alternate constructor -function bnpFromNumber(a,b,c) { - if("number" == typeof b) { - // new BigInteger(int,int,RNG) - if(a < 2) this.fromInt(1); - else { - this.fromNumber(a,c); - if(!this.testBit(a-1)) // force MSB set - this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); - if(this.isEven()) this.dAddOffset(1,0); // force odd - while(!this.isProbablePrime(b)) { - this.dAddOffset(2,0); - if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); - } - } - } - else { - // new BigInteger(int,RNG) - var x = new Array(), t = a&7; - x.length = (a>>3)+1; - b.nextBytes(x); - if(t > 0) x[0] &= ((1< 0) { - if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) - r[k++] = d|(this.s<<(this.DB-p)); - while(i >= 0) { - if(p < 8) { - d = (this[i]&((1<>(p+=this.DB-8); - } - else { - d = (this[i]>>(p-=8))&0xff; - if(p <= 0) { p += this.DB; --i; } - } - //if((d&0x80) != 0) d |= -256; - //if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; - if(k > 0 || d != this.s) r[k++] = d; - } - } - return r; -} - -function bnEquals(a) { return(this.compareTo(a)==0); } -function bnMin(a) { return(this.compareTo(a)<0)?this:a; } -function bnMax(a) { return(this.compareTo(a)>0)?this:a; } - -// (protected) r = this op a (bitwise) -function bnpBitwiseTo(a,op,r) { - var i, f, m = Math.min(a.t,this.t); - for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); - if(a.t < this.t) { - f = a.s&this.DM; - for(i = m; i < this.t; ++i) r[i] = op(this[i],f); - r.t = this.t; - } - else { - f = this.s&this.DM; - for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); - r.t = a.t; - } - r.s = op(this.s,a.s); - r.clamp(); -} - -// (public) this & a -function op_and(x,y) { return x&y; } -function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } - -// (public) this | a -function op_or(x,y) { return x|y; } -function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } - -// (public) this ^ a -function op_xor(x,y) { return x^y; } -function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } - -// (public) this & ~a -function op_andnot(x,y) { return x&~y; } -function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } - -// (public) ~this -function bnNot() { - var r = nbi(); - for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; - r.t = this.t; - r.s = ~this.s; - return r; -} - -// (public) this << n -function bnShiftLeft(n) { - var r = nbi(); - if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); - return r; -} - -// (public) this >> n -function bnShiftRight(n) { - var r = nbi(); - if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); - return r; -} - -// return index of lowest 1-bit in x, x < 2^31 -function lbit(x) { - if(x == 0) return -1; - var r = 0; - if((x&0xffff) == 0) { x >>= 16; r += 16; } - if((x&0xff) == 0) { x >>= 8; r += 8; } - if((x&0xf) == 0) { x >>= 4; r += 4; } - if((x&3) == 0) { x >>= 2; r += 2; } - if((x&1) == 0) ++r; - return r; -} - -// (public) returns index of lowest 1-bit (or -1 if none) -function bnGetLowestSetBit() { - for(var i = 0; i < this.t; ++i) - if(this[i] != 0) return i*this.DB+lbit(this[i]); - if(this.s < 0) return this.t*this.DB; - return -1; -} - -// return number of 1 bits in x -function cbit(x) { - var r = 0; - while(x != 0) { x &= x-1; ++r; } - return r; -} - -// (public) return number of set bits -function bnBitCount() { - var r = 0, x = this.s&this.DM; - for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); - return r; -} - -// (public) true iff nth bit is set -function bnTestBit(n) { - var j = Math.floor(n/this.DB); - if(j >= this.t) return(this.s!=0); - return((this[j]&(1<<(n%this.DB)))!=0); -} - -// (protected) this op (1<>= this.DB; - } - if(a.t < this.t) { - c += a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c += a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += a.s; - } - r.s = (c<0)?-1:0; - if(c > 0) r[i++] = c; - else if(c < -1) r[i++] = this.DV+c; - r.t = i; - r.clamp(); -} - -// (public) this + a -function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } - -// (public) this - a -function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } - -// (public) this * a -function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } - -// (public) this^2 -function bnSquare() { var r = nbi(); this.squareTo(r); return r; } - -// (public) this / a -function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } - -// (public) this % a -function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } - -// (public) [this/a,this%a] -function bnDivideAndRemainder(a) { - var q = nbi(), r = nbi(); - this.divRemTo(a,q,r); - return new Array(q,r); -} - -// (protected) this *= n, this >= 0, 1 < n < DV -function bnpDMultiply(n) { - this[this.t] = this.am(0,n-1,this,0,0,this.t); - ++this.t; - this.clamp(); -} - -// (protected) this += n << w words, this >= 0 -function bnpDAddOffset(n,w) { - if(n == 0) return; - while(this.t <= w) this[this.t++] = 0; - this[w] += n; - while(this[w] >= this.DV) { - this[w] -= this.DV; - if(++w >= this.t) this[this.t++] = 0; - ++this[w]; - } -} - -// A "null" reducer -function NullExp() {} -function nNop(x) { return x; } -function nMulTo(x,y,r) { x.multiplyTo(y,r); } -function nSqrTo(x,r) { x.squareTo(r); } - -NullExp.prototype.convert = nNop; -NullExp.prototype.revert = nNop; -NullExp.prototype.mulTo = nMulTo; -NullExp.prototype.sqrTo = nSqrTo; - -// (public) this^e -function bnPow(e) { return this.exp(e,new NullExp()); } - -// (protected) r = lower n words of "this * a", a.t <= n -// "this" should be the larger one if appropriate. -function bnpMultiplyLowerTo(a,n,r) { - var i = Math.min(this.t+a.t,n); - r.s = 0; // assumes a,this >= 0 - r.t = i; - while(i > 0) r[--i] = 0; - var j; - for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); - for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); - r.clamp(); -} - -// (protected) r = "this * a" without lower n words, n > 0 -// "this" should be the larger one if appropriate. -function bnpMultiplyUpperTo(a,n,r) { - --n; - var i = r.t = this.t+a.t-n; - r.s = 0; // assumes a,this >= 0 - while(--i >= 0) r[i] = 0; - for(i = Math.max(n-this.t,0); i < a.t; ++i) - r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); - r.clamp(); - r.drShiftTo(1,r); -} - -// Barrett modular reduction -function Barrett(m) { - // setup Barrett - this.r2 = nbi(); - this.q3 = nbi(); - BigInteger.ONE.dlShiftTo(2*m.t,this.r2); - this.mu = this.r2.divide(m); - this.m = m; -} - -function barrettConvert(x) { - if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); - else if(x.compareTo(this.m) < 0) return x; - else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } -} - -function barrettRevert(x) { return x; } - -// x = x mod m (HAC 14.42) -function barrettReduce(x) { - x.drShiftTo(this.m.t-1,this.r2); - if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } - this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); - this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); - while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); - x.subTo(this.r2,x); - while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); -} - -// r = x^2 mod m; x != r -function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -// r = x*y mod m; x,y != r -function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - -Barrett.prototype.convert = barrettConvert; -Barrett.prototype.revert = barrettRevert; -Barrett.prototype.reduce = barrettReduce; -Barrett.prototype.mulTo = barrettMulTo; -Barrett.prototype.sqrTo = barrettSqrTo; - -// (public) this^e % m (HAC 14.85) -function bnModPow(e,m) { - var i = e.bitLength(), k, r = nbv(1), z; - if(i <= 0) return r; - else if(i < 18) k = 1; - else if(i < 48) k = 3; - else if(i < 144) k = 4; - else if(i < 768) k = 5; - else k = 6; - if(i < 8) - z = new Classic(m); - else if(m.isEven()) - z = new Barrett(m); - else - z = new Montgomery(m); - - // precomputation - var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { - var g2 = nbi(); - z.sqrTo(g[1],g2); - while(n <= km) { - g[n] = nbi(); - z.mulTo(g2,g[n-2],g[n]); - n += 2; - } - } - - var j = e.t-1, w, is1 = true, r2 = nbi(), t; - i = nbits(e[j])-1; - while(j >= 0) { - if(i >= k1) w = (e[j]>>(i-k1))&km; - else { - w = (e[j]&((1<<(i+1))-1))<<(k1-i); - if(j > 0) w |= e[j-1]>>(this.DB+i-k1); - } - - n = k; - while((w&1) == 0) { w >>= 1; --n; } - if((i -= n) < 0) { i += this.DB; --j; } - if(is1) { // ret == 1, don't bother squaring or multiplying it - g[w].copyTo(r); - is1 = false; - } - else { - while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } - if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } - z.mulTo(r2,g[w],r); - } - - while(j >= 0 && (e[j]&(1< 0) { - x.rShiftTo(g,x); - y.rShiftTo(g,y); - } - while(x.signum() > 0) { - if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); - if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); - if(x.compareTo(y) >= 0) { - x.subTo(y,x); - x.rShiftTo(1,x); - } - else { - y.subTo(x,y); - y.rShiftTo(1,y); - } - } - if(g > 0) y.lShiftTo(g,y); - return y; -} - -// (protected) this % n, n < 2^26 -function bnpModInt(n) { - if(n <= 0) return 0; - var d = this.DV%n, r = (this.s<0)?n-1:0; - if(this.t > 0) - if(d == 0) r = this[0]%n; - else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; - return r; -} - -// (public) 1/this % m (HAC 14.61) -function bnModInverse(m) { - var ac = m.isEven(); - if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; - var u = m.clone(), v = this.clone(); - var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); - while(u.signum() != 0) { - while(u.isEven()) { - u.rShiftTo(1,u); - if(ac) { - if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } - a.rShiftTo(1,a); - } - else if(!b.isEven()) b.subTo(m,b); - b.rShiftTo(1,b); - } - while(v.isEven()) { - v.rShiftTo(1,v); - if(ac) { - if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } - c.rShiftTo(1,c); - } - else if(!d.isEven()) d.subTo(m,d); - d.rShiftTo(1,d); - } - if(u.compareTo(v) >= 0) { - u.subTo(v,u); - if(ac) a.subTo(c,a); - b.subTo(d,b); - } - else { - v.subTo(u,v); - if(ac) c.subTo(a,c); - d.subTo(b,d); - } - } - if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; - if(d.compareTo(m) >= 0) return d.subtract(m); - if(d.signum() < 0) d.addTo(m,d); else return d; - if(d.signum() < 0) return d.add(m); else return d; -} - -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]; -var lplim = (1<<26)/lowprimes[lowprimes.length-1]; - -// (public) test primality with certainty >= 1-.5^t -function bnIsProbablePrime(t) { - var i, x = this.abs(); - if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { - for(i = 0; i < lowprimes.length; ++i) - if(x[0] == lowprimes[i]) return true; - return false; - } - if(x.isEven()) return false; - i = 1; - while(i < lowprimes.length) { - var m = lowprimes[i], j = i+1; - while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; - m = x.modInt(m); - while(i < j) if(m%lowprimes[i++] == 0) return false; - } - return x.millerRabin(t); -} - -/* added by Recurity Labs */ - -function nbits(x) { - var n = 1, t; - if ((t = x >>> 16) != 0) { - x = t; - n += 16; - } - if ((t = x >> 8) != 0) { - x = t; - n += 8; - } - if ((t = x >> 4) != 0) { - x = t; - n += 4; - } - if ((t = x >> 2) != 0) { - x = t; - n += 2; - } - if ((t = x >> 1) != 0) { - x = t; - n += 1; - } - return n; -} - -function bnToMPI () { - var ba = this.toByteArray(); - var size = (ba.length-1)*8+nbits(ba[0]); - var result = ""; - result += String.fromCharCode((size & 0xFF00) >> 8); - result += String.fromCharCode(size & 0xFF); - result += util.bin2str(ba); - return result; -} -/* END of addition */ - -// (protected) true if probably prime (HAC 4.24, Miller-Rabin) -function bnpMillerRabin(t) { - var n1 = this.subtract(BigInteger.ONE); - var k = n1.getLowestSetBit(); - if(k <= 0) return false; - var r = n1.shiftRight(k); - t = (t+1)>>1; - if(t > lowprimes.length) t = lowprimes.length; - var a = nbi(); - var j, bases = []; - for(var i = 0; i < t; ++i) { - //Pick bases at random, instead of starting at 2 - for (;;) { - j = lowprimes[Math.floor(Math.random() * lowprimes.length)]; - if (bases.indexOf(j) == -1) break; - } - bases.push(j); - a.fromInt(j); - var y = a.modPow(r,this); - if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { - var j = 1; - while(j++ < k && y.compareTo(n1) != 0) { - y = y.modPowInt(2,this); - if(y.compareTo(BigInteger.ONE) == 0) return false; - } - if(y.compareTo(n1) != 0) return false; - } - } - return true; -} - -// protected -BigInteger.prototype.chunkSize = bnpChunkSize; -BigInteger.prototype.toRadix = bnpToRadix; -BigInteger.prototype.fromRadix = bnpFromRadix; -BigInteger.prototype.fromNumber = bnpFromNumber; -BigInteger.prototype.bitwiseTo = bnpBitwiseTo; -BigInteger.prototype.changeBit = bnpChangeBit; -BigInteger.prototype.addTo = bnpAddTo; -BigInteger.prototype.dMultiply = bnpDMultiply; -BigInteger.prototype.dAddOffset = bnpDAddOffset; -BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; -BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; -BigInteger.prototype.modInt = bnpModInt; -BigInteger.prototype.millerRabin = bnpMillerRabin; - -// public -BigInteger.prototype.clone = bnClone; -BigInteger.prototype.intValue = bnIntValue; -BigInteger.prototype.byteValue = bnByteValue; -BigInteger.prototype.shortValue = bnShortValue; -BigInteger.prototype.signum = bnSigNum; -BigInteger.prototype.toByteArray = bnToByteArray; -BigInteger.prototype.equals = bnEquals; -BigInteger.prototype.min = bnMin; -BigInteger.prototype.max = bnMax; -BigInteger.prototype.and = bnAnd; -BigInteger.prototype.or = bnOr; -BigInteger.prototype.xor = bnXor; -BigInteger.prototype.andNot = bnAndNot; -BigInteger.prototype.not = bnNot; -BigInteger.prototype.shiftLeft = bnShiftLeft; -BigInteger.prototype.shiftRight = bnShiftRight; -BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; -BigInteger.prototype.bitCount = bnBitCount; -BigInteger.prototype.testBit = bnTestBit; -BigInteger.prototype.setBit = bnSetBit; -BigInteger.prototype.clearBit = bnClearBit; -BigInteger.prototype.flipBit = bnFlipBit; -BigInteger.prototype.add = bnAdd; -BigInteger.prototype.subtract = bnSubtract; -BigInteger.prototype.multiply = bnMultiply; -BigInteger.prototype.divide = bnDivide; -BigInteger.prototype.remainder = bnRemainder; -BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; -BigInteger.prototype.modPow = bnModPow; -BigInteger.prototype.modInverse = bnModInverse; -BigInteger.prototype.pow = bnPow; -BigInteger.prototype.gcd = bnGCD; -BigInteger.prototype.isProbablePrime = bnIsProbablePrime; -BigInteger.prototype.toMPI = bnToMPI; - -// JSBN-specific extension -BigInteger.prototype.square = bnSquare; diff --git a/src/ciphers/openpgp.crypto.js b/src/ciphers/openpgp.crypto.js deleted file mode 100644 index b1ef62f4..00000000 --- a/src/ciphers/openpgp.crypto.js +++ /dev/null @@ -1,431 +0,0 @@ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -// The GPG4Browsers crypto interface - -/** - * Encrypts data using the specified public key multiprecision integers - * and the specified algorithm. - * @param {Integer} algo Algorithm to be used (See RFC4880 9.1) - * @param {openpgp_type_mpi[]} publicMPIs Algorithm dependent multiprecision integers - * @param {openpgp_type_mpi} data Data to be encrypted as MPI - * @return {(openpgp_type_mpi|openpgp_type_mpi[])} if RSA an openpgp_type_mpi; - * if elgamal encryption an array of two openpgp_type_mpi is returned; otherwise null - */ -function openpgp_crypto_asymetricEncrypt(algo, publicMPIs, data) { - switch(algo) { - case 1: // RSA (Encrypt or Sign) [HAC] - case 2: // RSA Encrypt-Only [HAC] - case 3: // RSA Sign-Only [HAC] - var rsa = new RSA(); - var n = publicMPIs[0].toBigInteger(); - var e = publicMPIs[1].toBigInteger(); - var m = data.toBigInteger(); - return rsa.encrypt(m,e,n).toMPI(); - case 16: // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] - var elgamal = new Elgamal(); - var p = publicMPIs[0].toBigInteger(); - var g = publicMPIs[1].toBigInteger(); - var y = publicMPIs[2].toBigInteger(); - var m = data.toBigInteger(); - return elgamal.encrypt(m,g,p,y); - default: - return null; - } -} - -/** - * Decrypts data using the specified public key multiprecision integers of the private key, - * the specified secretMPIs of the private key and the specified algorithm. - * @param {Integer} algo Algorithm to be used (See RFC4880 9.1) - * @param {openpgp_type_mpi[]} publicMPIs Algorithm dependent multiprecision integers - * of the public key part of the private key - * @param {openpgp_type_mpi[]} secretMPIs Algorithm dependent multiprecision integers - * of the private key used - * @param {openpgp_type_mpi} data Data to be encrypted as MPI - * @return {BigInteger} returns a big integer containing the decrypted data; otherwise null - */ - -function openpgp_crypto_asymetricDecrypt(algo, publicMPIs, secretMPIs, dataMPIs) { - switch(algo) { - case 1: // RSA (Encrypt or Sign) [HAC] - case 2: // RSA Encrypt-Only [HAC] - case 3: // RSA Sign-Only [HAC] - var rsa = new RSA(); - var d = secretMPIs[0].toBigInteger(); - var p = secretMPIs[1].toBigInteger(); - var q = secretMPIs[2].toBigInteger(); - var u = secretMPIs[3].toBigInteger(); - var m = dataMPIs[0].toBigInteger(); - return rsa.decrypt(m, d, p, q, u); - case 16: // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] - var elgamal = new Elgamal(); - var x = secretMPIs[0].toBigInteger(); - var c1 = dataMPIs[0].toBigInteger(); - var c2 = dataMPIs[1].toBigInteger(); - var p = publicMPIs[0].toBigInteger(); - return elgamal.decrypt(c1,c2,p,x); - default: - return null; - } - -} - -/** - * generate random byte prefix as string for the specified algorithm - * @param {Integer} algo Algorithm to use (see RFC4880 9.2) - * @return {String} Random bytes with length equal to the block - * size of the cipher - */ -function openpgp_crypto_getPrefixRandom(algo) { - switch(algo) { - case 2: - case 3: - case 4: - return openpgp_crypto_getRandomBytes(8); - case 7: - case 8: - case 9: - case 10: - return openpgp_crypto_getRandomBytes(16); - default: - return null; - } -} - -/** - * retrieve the MDC prefixed bytes by decrypting them - * @param {Integer} algo Algorithm to use (see RFC4880 9.2) - * @param {String} key Key as string. length is depending on the algorithm used - * @param {String} data Encrypted data where the prefix is decrypted from - * @return {String} Plain text data of the prefixed data - */ -function openpgp_crypto_MDCSystemBytes(algo, key, data) { - util.print_debug_hexstr_dump("openpgp_crypto_symmetricDecrypt:\nencrypteddata:",data); - switch(algo) { - case 0: // Plaintext or unencrypted data - return data; - case 2: // TripleDES (DES-EDE, [SCHNEIER] [HAC] - 168 bit key derived from 192) - return openpgp_cfb_mdc(desede, 8, key, data, openpgp_cfb); - case 3: // CAST5 (128 bit key, as per [RFC2144]) - return openpgp_cfb_mdc(cast5_encrypt, 8, key, data); - case 4: // Blowfish (128 bit key, 16 rounds) [BLOWFISH] - return openpgp_cfb_mdc(BFencrypt, 8, key, data); - case 7: // AES with 128-bit key [AES] - case 8: // AES with 192-bit key - case 9: // AES with 256-bit key - return openpgp_cfb_mdc(AESencrypt, 16, keyExpansion(key), data); - case 10: - return openpgp_cfb_mdc(TFencrypt, 16, key, data); - case 1: // IDEA [IDEA] - util.print_error(""+ (algo == 1 ? "IDEA Algorithm not implemented" : "Twofish Algorithm not implemented")); - return null; - default: - } - return null; -} -/** - * Generating a session key for the specified symmetric algorithm - * @param {Integer} algo Algorithm to use (see RFC4880 9.2) - * @return {String} Random bytes as a string to be used as a key - */ -function openpgp_crypto_generateSessionKey(algo) { - switch (algo) { - case 2: // TripleDES (DES-EDE, [SCHNEIER] [HAC] - 168 bit key derived from 192) - case 8: // AES with 192-bit key - return openpgp_crypto_getRandomBytes(24); - case 3: // CAST5 (128 bit key, as per [RFC2144]) - case 4: // Blowfish (128 bit key, 16 rounds) [BLOWFISH] - case 7: // AES with 128-bit key [AES] - util.print_debug("length = 16:\n"+util.hexstrdump(openpgp_crypto_getRandomBytes(16))); - return openpgp_crypto_getRandomBytes(16); - case 9: // AES with 256-bit key - case 10:// Twofish with 256-bit key [TWOFISH] - return openpgp_crypto_getRandomBytes(32); - } - return null; -} - -/** - * - * @param {Integer} algo public Key algorithm - * @param {Integer} hash_algo Hash algorithm - * @param {openpgp_type_mpi[]} msg_MPIs Signature multiprecision integers - * @param {openpgp_type_mpi[]} publickey_MPIs Public key multiprecision integers - * @param {String} data Data on where the signature was computed on. - * @return {Boolean} true if signature (sig_data was equal to data over hash) - */ -function openpgp_crypto_verifySignature(algo, hash_algo, msg_MPIs, publickey_MPIs, data) { - var calc_hash = openpgp_crypto_hashData(hash_algo, data); - switch(algo) { - case 1: // RSA (Encrypt or Sign) [HAC] - case 2: // RSA Encrypt-Only [HAC] - case 3: // RSA Sign-Only [HAC] - var rsa = new RSA(); - var n = publickey_MPIs[0].toBigInteger(); - var e = publickey_MPIs[1].toBigInteger(); - var x = msg_MPIs[0].toBigInteger(); - var dopublic = rsa.verify(x,e,n); - var hash = openpgp_encoding_emsa_pkcs1_decode(hash_algo,dopublic.toMPI().substring(2)); - if (hash == -1) { - util.print_error("PKCS1 padding in message or key incorrect. Aborting..."); - return false; - } - util.print_debug('hash: '+util.hexdump(hash)); - util.print_debug('calc_hash: '+util.hexdump(calc_hash)); - return hash == calc_hash; - - case 16: // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] - util.print_error("signing with Elgamal is not defined in the OpenPGP standard."); - return null; - case 17: // DSA (Digital Signature Algorithm) [FIPS186] [HAC] - var dsa = new DSA(); - var s1 = msg_MPIs[0].toBigInteger(); - var s2 = msg_MPIs[1].toBigInteger(); - var p = publickey_MPIs[0].toBigInteger(); - var q = publickey_MPIs[1].toBigInteger(); - var g = publickey_MPIs[2].toBigInteger(); - var y = publickey_MPIs[3].toBigInteger(); - var m = data; - var dopublic = dsa.verify(hash_algo,s1,s2,m,p,q,g,y); - return dopublic.compareTo(s1) == 0; - default: - return null; - } - -} - -/** - * Create a signature on data using the specified algorithm - * @param {Integer} hash_algo hash Algorithm to use (See RFC4880 9.4) - * @param {Integer} algo Asymmetric cipher algorithm to use (See RFC4880 9.1) - * @param {openpgp_type_mpi[]} publicMPIs Public key multiprecision integers - * of the private key - * @param {openpgp_type_mpi[]} secretMPIs Private key multiprecision - * integers which is used to sign the data - * @param {String} data Data to be signed - * @return {(String|openpgp_type_mpi)} - */ -function openpgp_crypto_signData(hash_algo, algo, publicMPIs, secretMPIs, data) { - - switch(algo) { - case 1: // RSA (Encrypt or Sign) [HAC] - case 2: // RSA Encrypt-Only [HAC] - case 3: // RSA Sign-Only [HAC] - var rsa = new RSA(); - var d = secretMPIs[0].toBigInteger(); - var n = publicMPIs[0].toBigInteger(); - var m = openpgp_encoding_emsa_pkcs1_encode(hash_algo, data,publicMPIs[0].mpiByteLength); - util.print_debug("signing using RSA"); - return rsa.sign(m, d, n).toMPI(); - case 17: // DSA (Digital Signature Algorithm) [FIPS186] [HAC] - var dsa = new DSA(); - util.print_debug("DSA Sign: q size in Bytes:"+publicMPIs[1].getByteLength()); - var p = publicMPIs[0].toBigInteger(); - var q = publicMPIs[1].toBigInteger(); - var g = publicMPIs[2].toBigInteger(); - var y = publicMPIs[3].toBigInteger(); - var x = secretMPIs[0].toBigInteger(); - var m = data; - var result = dsa.sign(hash_algo,m, g, p, q, x); - util.print_debug("signing using DSA\n result:"+util.hexstrdump(result[0])+"|"+util.hexstrdump(result[1])); - return result[0]+result[1]; - case 16: // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] - util.print_debug("signing with Elgamal is not defined in the OpenPGP standard."); - return null; - default: - return null; - } -} - -/** - * Create a hash on the specified data using the specified algorithm - * @param {Integer} algo Hash algorithm type (see RFC4880 9.4) - * @param {String} data Data to be hashed - * @return {String} hash value - */ -function openpgp_crypto_hashData(algo, data) { - var hash = null; - switch(algo) { - case 1: // - MD5 [HAC] - hash = MD5(data); - break; - case 2: // - SHA-1 [FIPS180] - hash = str_sha1(data); - break; - case 3: // - RIPE-MD/160 [HAC] - hash = RMDstring(data); - break; - case 8: // - SHA256 [FIPS180] - hash = str_sha256(data); - break; - case 9: // - SHA384 [FIPS180] - hash = str_sha384(data); - break; - case 10:// - SHA512 [FIPS180] - hash = str_sha512(data); - break; - case 11:// - SHA224 [FIPS180] - hash = str_sha224(data); - default: - break; - } - return hash; -} - -/** - * Returns the hash size in bytes of the specified hash algorithm type - * @param {Integer} algo Hash algorithm type (See RFC4880 9.4) - * @return {Integer} Size in bytes of the resulting hash - */ -function openpgp_crypto_getHashByteLength(algo) { - var hash = null; - switch(algo) { - case 1: // - MD5 [HAC] - return 16; - case 2: // - SHA-1 [FIPS180] - case 3: // - RIPE-MD/160 [HAC] - return 20; - case 8: // - SHA256 [FIPS180] - return 32; - case 9: // - SHA384 [FIPS180] - return 48 - case 10:// - SHA512 [FIPS180] - return 64; - case 11:// - SHA224 [FIPS180] - return 28; - } - return null; -} - -/** - * Retrieve secure random byte string of the specified length - * @param {Integer} length Length in bytes to generate - * @return {String} Random byte string - */ -function openpgp_crypto_getRandomBytes(length) { - var result = ''; - for (var i = 0; i < length; i++) { - result += String.fromCharCode(openpgp_crypto_getSecureRandomOctet()); - } - return result; -} - -/** - * Return a pseudo-random number in the specified range - * @param {Integer} from Min of the random number - * @param {Integer} to Max of the random number (max 32bit) - * @return {Integer} A pseudo random number - */ -function openpgp_crypto_getPseudoRandom(from, to) { - return Math.round(Math.random()*(to-from))+from; -} - -/** - * Return a secure random number in the specified range - * @param {Integer} from Min of the random number - * @param {Integer} to Max of the random number (max 32bit) - * @return {Integer} A secure random number - */ -function openpgp_crypto_getSecureRandom(from, to) { - var buf = new Uint32Array(1); - window.crypto.getRandomValues(buf); - var bits = ((to-from)).toString(2).length; - while ((buf[0] & (Math.pow(2, bits) -1)) > (to-from)) - window.crypto.getRandomValues(buf); - return from+(Math.abs(buf[0] & (Math.pow(2, bits) -1))); -} - -function openpgp_crypto_getSecureRandomOctet() { - var buf = new Uint32Array(1); - window.crypto.getRandomValues(buf); - return buf[0] & 0xFF; -} - -/** - * Create a secure random big integer of bits length - * @param {Integer} bits Bit length of the MPI to create - * @return {BigInteger} Resulting big integer - */ -function openpgp_crypto_getRandomBigInteger(bits) { - if (bits < 0) - return null; - var numBytes = Math.floor((bits+7)/8); - - var randomBits = openpgp_crypto_getRandomBytes(numBytes); - if (bits % 8 > 0) { - - randomBits = String.fromCharCode( - (Math.pow(2,bits % 8)-1) & - randomBits.charCodeAt(0)) + - randomBits.substring(1); - } - return new openpgp_type_mpi().create(randomBits).toBigInteger(); -} - -function openpgp_crypto_getRandomBigIntegerInRange(min, max) { - if (max.compareTo(min) <= 0) - return; - var range = max.subtract(min); - var r = openpgp_crypto_getRandomBigInteger(range.bitLength()); - while (r > range) { - r = openpgp_crypto_getRandomBigInteger(range.bitLength()); - } - return min.add(r); -} - - -//This is a test method to ensure that encryption/decryption with a given 1024bit RSAKey object functions as intended -function openpgp_crypto_testRSA(key){ - var rsa = new RSA(); - var mpi = new openpgp_type_mpi(); - mpi.create(openpgp_encoding_eme_pkcs1_encode('ABABABAB', 128)); - var msg = rsa.encrypt(mpi.toBigInteger(),key.ee,key.n); - var result = rsa.decrypt(msg, key.d, key.p, key.q, key.u); -} - -/** - * @typedef {Object} openpgp_keypair - * @property {openpgp_packet_keymaterial} privateKey - * @property {openpgp_packet_keymaterial} publicKey - */ - -/** - * Calls the necessary crypto functions to generate a keypair. - * Called directly by openpgp.js - * @param {Integer} keyType Follows OpenPGP algorithm convention. - * @param {Integer} numBits Number of bits to make the key to be generated - * @return {openpgp_keypair} - */ -function openpgp_crypto_generateKeyPair(keyType, numBits, passphrase, s2kHash, symmetricEncryptionAlgorithm){ - var privKeyPacket; - var publicKeyPacket; - var d = new Date(); - d = d.getTime()/1000; - var timePacket = String.fromCharCode(Math.floor(d/0x1000000%0x100)) + String.fromCharCode(Math.floor(d/0x10000%0x100)) + String.fromCharCode(Math.floor(d/0x100%0x100)) + String.fromCharCode(Math.floor(d%0x100)); - switch(keyType){ - case 1: - var rsa = new RSA(); - var key = rsa.generate(numBits,"10001"); - privKeyPacket = new openpgp_packet_keymaterial().write_private_key(keyType, key, passphrase, s2kHash, symmetricEncryptionAlgorithm, timePacket); - publicKeyPacket = new openpgp_packet_keymaterial().write_public_key(keyType, key, timePacket); - break; - default: - util.print_error("Unknown keytype "+keyType) - } - return {privateKey: privKeyPacket, publicKey: publicKeyPacket}; -} diff --git a/src/ciphers/symmetric/dessrc.js b/src/ciphers/symmetric/dessrc.js deleted file mode 100644 index 3666077a..00000000 --- a/src/ciphers/symmetric/dessrc.js +++ /dev/null @@ -1,243 +0,0 @@ -//Paul Tero, July 2001 -//http://www.tero.co.uk/des/ -// -//Optimised for performance with large blocks by Michael Hayworth, November 2001 -//http://www.netdealing.com -// -// Modified by Recurity Labs GmbH - -//THIS SOFTWARE IS PROVIDED "AS IS" AND -//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -//FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -//DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -//OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -//HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -//OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -//SUCH DAMAGE. - -//des -//this takes the key, the message, and whether to encrypt or decrypt - -// added by Recurity Labs -function desede(block,key) { - var key1 = key.substring(0,8); - var key2 = key.substring(8,16); - var key3 = key.substring(16,24); - return util.str2bin(des(des_createKeys(key3),des(des_createKeys(key2),des(des_createKeys(key1),util.bin2str(block), true, 0,null,null), false, 0,null,null), true, 0,null,null)); -} - - -function des (keys, message, encrypt, mode, iv, padding) { - //declaring this locally speeds things up a bit - var spfunction1 = new Array (0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x1010400,0x1010404,0x400,0x1000404,0x1010004,0x1000000,0x4,0x404,0x1000400,0x1000400,0x10400,0x10400,0x1010000,0x1010000,0x1000404,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000,0x10000,0x1010404,0x4,0x1010000,0x1010400,0x1000000,0x1000000,0x400,0x1010004,0x10000,0x10400,0x1000004,0x400,0x4,0x1000404,0x10404,0x1010404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10004,0x10400,0,0x1010004); - var spfunction2 = new Array (-0x7fef7fe0,-0x7fff8000,0x8000,0x108020,0x100000,0x20,-0x7fefffe0,-0x7fff7fe0,-0x7fffffe0,-0x7fef7fe0,-0x7fef8000,-0x80000000,-0x7fff8000,0x100000,0x20,-0x7fefffe0,0x108000,0x100020,-0x7fff7fe0,0,-0x80000000,0x8000,0x108020,-0x7ff00000,0x100020,-0x7fffffe0,0,0x108000,0x8020,-0x7fef8000,-0x7ff00000,0x8020,0,0x108020,-0x7fefffe0,0x100000,-0x7fff7fe0,-0x7ff00000,-0x7fef8000,0x8000,-0x7ff00000,-0x7fff8000,0x20,-0x7fef7fe0,0x108020,0x20,0x8000,-0x80000000,0x8020,-0x7fef8000,0x100000,-0x7fffffe0,0x100020,-0x7fff7fe0,-0x7fffffe0,0x100020,0x108000,0,-0x7fff8000,0x8020,-0x80000000,-0x7fefffe0,-0x7fef7fe0,0x108000); - var spfunction3 = new Array (0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000,0x8020208,0x20008,0x8020000,0x208,0x8000000,0x8,0x8020200,0x200,0x20200,0x8020000,0x8020008,0x20208,0x8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x8000000,0x8020200,0x8000000,0x20008,0x208,0x20000,0x8020200,0x8000200,0,0x200,0x20008,0x8020208,0x8000200,0x8000008,0x200,0,0x8020008,0x8000208,0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x8020000,0x8000208,0x208,0x8020000,0x20208,0x8,0x8020008,0x20200); - var spfunction4 = new Array (0x802001,0x2081,0x2081,0x80,0x802080,0x800081,0x800001,0x2001,0,0x802000,0x802000,0x802081,0x81,0,0x800080,0x800001,0x1,0x2000,0x800000,0x802001,0x80,0x800000,0x2001,0x2080,0x800081,0x1,0x2080,0x800080,0x2000,0x802080,0x802081,0x81,0x800080,0x800001,0x802000,0x802081,0x81,0,0,0x802000,0x2080,0x800080,0x800081,0x1,0x802001,0x2081,0x2081,0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x800081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080); - var spfunction5 = new Array (0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x40000000,0x2080000,0x40080100,0x80000,0x2000100,0x40080100,0x42000100,0x42080000,0x80100,0x40000000,0x2000000,0x40080000,0x40080000,0,0x40000100,0x42080100,0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x2000000,0x42000000,0x80100,0x80000,0x42000100,0x100,0x2000000,0x40000000,0x2080000,0x42000100,0x40080100,0x2000100,0x40000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000,0x42080000,0x42080100,0x80100,0x42000000,0x42080100,0x2080000,0,0x40080000,0x42000000,0x80100,0x2000100,0x40000100,0x80000,0,0x40080000,0x2080100,0x40000100); - var spfunction6 = new Array (0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x404010,0x400000,0x20000010,0x400010,0x20004000,0x20000000,0x4010,0,0x400010,0x20004010,0x4000,0x404000,0x20004010,0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x20000000,0x20004000,0x10,0x20400010,0x404000,0x20404010,0x400000,0x4010,0x20000010,0x400000,0x20004000,0x20000000,0x4010,0x20000010,0x20404010,0x404000,0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400000,0x404010,0x4000,0x400010,0x20004010,0,0x20404000,0x20000000,0x400010,0x20004010); - var spfunction7 = new Array (0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002,0x2,0x4000000,0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000,0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x4000000,0x200800,0x200000,0x4000802,0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x200802,0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800,0x200002); - var spfunction8 = new Array (0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0x41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000,0x40040,0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1000,0x40,0x10040040,0x1000,0x41040,0x10001000,0x40,0x10000040,0x10040000,0x10040040,0x10000000,0x40000,0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x10000000,0x10041000); - - //create the 16 or 48 subkeys we will need - var m=0, i, j, temp, temp2, right1, right2, left, right, looping; - var cbcleft, cbcleft2, cbcright, cbcright2 - var endloop, loopinc; - var len = message.length; - var chunk = 0; - //set up the loops for single and triple des - var iterations = keys.length == 32 ? 3 : 9; //single or triple des - if (iterations == 3) {looping = encrypt ? new Array (0, 32, 2) : new Array (30, -2, -2);} - else {looping = encrypt ? new Array (0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array (94, 62, -2, 32, 64, 2, 30, -2, -2);} - - //pad the message depending on the padding parameter - //only add padding if encrypting - note that you need to use the same padding option for both encrypt and decrypt - if (encrypt) { - message = des_addPadding(message, padding); - len = message.length; - } - - //store the result here - result = ""; - tempresult = ""; - - if (mode == 1) { //CBC mode - cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++); - cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++); - m=0; - } - - //loop through each 64 bit chunk of the message - while (m < len) { - left = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++); - right = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++); - - //for Cipher Block Chaining mode, xor the message with the previous result - if (mode == 1) {if (encrypt) {left ^= cbcleft; right ^= cbcright;} else {cbcleft2 = cbcleft; cbcright2 = cbcright; cbcleft = left; cbcright = right;}} - - //first each 64 but chunk of the message must be permuted according to IP - temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4); - temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16); - temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2); - temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8); - temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); - - left = ((left << 1) | (left >>> 31)); - right = ((right << 1) | (right >>> 31)); - - //do this either 1 or 3 times for each chunk of the message - for (j=0; j>> 4) | (right << 28)) ^ keys[i+1]; - //the result is attained by passing these bytes through the S selection functions - temp = left; - left = right; - right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f] - | spfunction6[(right1 >>> 8) & 0x3f] | spfunction8[right1 & 0x3f] - | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & 0x3f] - | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]); - } - temp = left; left = right; right = temp; //unreverse left and right - } //for either 1 or 3 iterations - - //move then each one bit to the right - left = ((left >>> 1) | (left << 31)); - right = ((right >>> 1) | (right << 31)); - - //now perform IP-1, which is IP in the opposite direction - temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); - temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8); - temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2); - temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16); - temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4); - - //for Cipher Block Chaining mode, xor the message with the previous result - if (mode == 1) {if (encrypt) {cbcleft = left; cbcright = right;} else {left ^= cbcleft2; right ^= cbcright2;}} - tempresult += String.fromCharCode ((left>>>24), ((left>>>16) & 0xff), ((left>>>8) & 0xff), (left & 0xff), (right>>>24), ((right>>>16) & 0xff), ((right>>>8) & 0xff), (right & 0xff)); - - chunk += 8; - if (chunk == 512) {result += tempresult; tempresult = ""; chunk = 0;} - } //for every 8 characters, or 64 bits in the message - - //return the result as an array - result += tempresult; - - //only remove padding if decrypting - note that you need to use the same padding option for both encrypt and decrypt - if (!encrypt) { - result = des_removePadding(result, padding); - } - - return result; -} //end of des - - - -//des_createKeys -//this takes as input a 64 bit key (even though only 56 bits are used) -//as an array of 2 integers, and returns 16 48 bit keys -function des_createKeys (key) { - //declaring this locally speeds things up a bit - pc2bytes0 = new Array (0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204); - pc2bytes1 = new Array (0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0x4000101,0x4100100,0x4100101); - pc2bytes2 = new Array (0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808,0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808); - pc2bytes3 = new Array (0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000); - pc2bytes4 = new Array (0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x1010,0x41010); - pc2bytes5 = new Array (0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420); - pc2bytes6 = new Array (0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002); - pc2bytes7 = new Array (0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x20020000,0x20030000,0x20020800,0x20030800); - pc2bytes8 = new Array (0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002); - pc2bytes9 = new Array (0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x10000400,0x408,0x10000408); - pc2bytes10 = new Array (0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0x102020); - pc2bytes11 = new Array (0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x5000200,0x4200000,0x5200000,0x4200200,0x5200200); - pc2bytes12 = new Array (0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010); - pc2bytes13 = new Array (0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105); - - //how many iterations (1 for des, 3 for triple des) - var iterations = key.length > 8 ? 3 : 1; //changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys - //stores the return keys - var keys = new Array (32 * iterations); - //now define the left shifts which need to be done - var shifts = new Array (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0); - //other variables - var lefttemp, righttemp, m=0, n=0, temp; - - for (var j=0; j>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4); - temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16); - temp = ((left >>> 2) ^ right) & 0x33333333; right ^= temp; left ^= (temp << 2); - temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16); - temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); - temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8); - temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); - - //the right side needs to be shifted and to get the last four bits of the left side - temp = (left << 8) | ((right >>> 20) & 0x000000f0); - //left needs to be put upside down - left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0); - right = temp; - - //now go through and perform these shifts on the left and right keys - for (i=0; i < shifts.length; i++) { - //shift the keys either one or two bits to the left - if (shifts[i]) {left = (left << 2) | (left >>> 26); right = (right << 2) | (right >>> 26);} - else {left = (left << 1) | (left >>> 27); right = (right << 1) | (right >>> 27);} - left &= -0xf; right &= -0xf; - - //now apply PC-2, in such a way that E is easier when encrypting or decrypting - //this conversion will look like PC-2 except only the last 6 bits of each byte are used - //rather than 48 consecutive bits and the order of lines will be according to - //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7 - lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf] - | pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(left >>> 16) & 0xf] - | pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf] - | pc2bytes6[(left >>> 4) & 0xf]; - righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf] - | pc2bytes9[(right >>> 20) & 0xf] | pc2bytes10[(right >>> 16) & 0xf] - | pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf] - | pc2bytes13[(right >>> 4) & 0xf]; - temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff; - keys[n++] = lefttemp ^ temp; keys[n++] = righttemp ^ (temp << 16); - } - } //for each iterations - //return the keys we've created - return keys; -} //end of des_createKeys - - -function des_addPadding(message, padding) { - var padLength = 8 - (message.length % 8); - if ((padding == 2) && (padLength < 8)) { //pad the message with spaces - message += " ".substr(0, padLength); - } - else if (padding == 1) { //PKCS7 padding - message += String.fromCharCode(padLength, padLength, padLength, padLength, padLength, padLength, padLength, padLength).substr(0, padLength); - } - else if (!padding && (padLength < 8)) { //pad the message out with null bytes - message += "\0\0\0\0\0\0\0\0".substr(0, padLength); - } - return message; -} - -function des_removePadding(message, padding) { - if (padding == 2) { // space padded - message = message.replace(/ *$/g, ""); - } - else if (padding == 1) { // PKCS7 - var padCount = message.charCodeAt(message.length - 1); - message = message.substr(0, message.length - padCount); - } - else if (!padding) { // null padding - message = message.replace(/\0*$/g, ""); - } - return message; -} - diff --git a/src/compression/zlib/jsxcompressor.js b/src/compression/zlib/jsxcompressor.js deleted file mode 100644 index 1fdee266..00000000 --- a/src/compression/zlib/jsxcompressor.js +++ /dev/null @@ -1,1223 +0,0 @@ -JXG = {exists: (function(undefined){return function(v){return !(v===undefined || v===null);}})()}; -JXG.decompress = function(str) {return unescape((new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(str))).unzip()[0][0]);}; -/* - Copyright 2008-2012 - Matthias Ehmann, - Michael Gerhaeuser, - Carsten Miller, - Bianca Valentin, - Alfred Wassermann, - Peter Wilfahrt - - This file is part of JSXGraph. - - Dual licensed under the Apache License Version 2.0, or LGPL Version 3 licenses. - - You should have received a copy of the GNU Lesser General Public License - along with JSXCompressor. If not, see . - - You should have received a copy of the Apache License along with JSXCompressor. - If not, see . - -*/ - -/** - * @class Util class - * @classdesc Utilities for uncompressing and base64 decoding - * Class for gunzipping, unzipping and base64 decoding of files. - * It is used for reading GEONExT, Geogebra and Intergeo files. - * - * Only Huffman codes are decoded in gunzip. - * The code is based on the source code for gunzip.c by Pasi Ojala - * {@link http://www.cs.tut.fi/~albert/Dev/gunzip/gunzip.c} - * {@link http://www.cs.tut.fi/~albert} - */ -JXG.Util = {}; - -/** - * Unzip zip files - */ -JXG.Util.Unzip = function (barray){ - var outputArr = [], - output = "", - debug = false, - gpflags, - files = 0, - unzipped = [], - crc, - buf32k = new Array(32768), - bIdx = 0, - modeZIP=false, - - CRC, SIZE, - - bitReverse = [ - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff - ], - - cplens = [ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 - ], - - cplext = [ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99 - ], /* 99==invalid */ - - cpdist = [ - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d, - 0x0011, 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1, - 0x0101, 0x0181, 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01, - 0x1001, 0x1801, 0x2001, 0x3001, 0x4001, 0x6001 - ], - - cpdext = [ - 0, 0, 0, 0, 1, 1, 2, 2, - 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, - 11, 11, 12, 12, 13, 13 - ], - - border = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15], - - bA = barray, - - bytepos=0, - bitpos=0, - bb = 1, - bits=0, - - NAMEMAX = 256, - - nameBuf = [], - - fileout; - - function readByte(){ - bits+=8; - if (bytepos"); - return bA[bytepos++]; - } else - return -1; - }; - - function byteAlign(){ - bb = 1; - }; - - function readBit(){ - var carry; - bits++; - carry = (bb & 1); - bb >>= 1; - if (bb==0){ - bb = readByte(); - carry = (bb & 1); - bb = (bb>>1) | 0x80; - } - return carry; - }; - - function readBits(a) { - var res = 0, - i = a; - - while(i--) { - res = (res<<1) | readBit(); - } - if(a) { - res = bitReverse[res]>>(8-a); - } - return res; - }; - - function flushBuffer(){ - //document.write('FLUSHBUFFER:'+buf32k); - bIdx = 0; - }; - function addBuffer(a){ - SIZE++; - //CRC=updcrc(a,crc); - buf32k[bIdx++] = a; - outputArr.push(String.fromCharCode(a)); - //output+=String.fromCharCode(a); - if(bIdx==0x8000){ - //document.write('ADDBUFFER:'+buf32k); - bIdx=0; - } - }; - - function HufNode() { - this.b0=0; - this.b1=0; - this.jump = null; - this.jumppos = -1; - }; - - var LITERALS = 288; - - var literalTree = new Array(LITERALS); - var distanceTree = new Array(32); - var treepos=0; - var Places = null; - var Places2 = null; - - var impDistanceTree = new Array(64); - var impLengthTree = new Array(64); - - var len = 0; - var fpos = new Array(17); - fpos[0]=0; - var flens; - var fmax; - - function IsPat() { - while (1) { - if (fpos[len] >= fmax) - return -1; - if (flens[fpos[len]] == len) - return fpos[len]++; - fpos[len]++; - } - }; - - function Rec() { - var curplace = Places[treepos]; - var tmp; - if (debug) - document.write("
len:"+len+" treepos:"+treepos); - if(len==17) { //war 17 - return -1; - } - treepos++; - len++; - - tmp = IsPat(); - if (debug) - document.write("
IsPat "+tmp); - if(tmp >= 0) { - curplace.b0 = tmp; /* leaf cell for 0-bit */ - if (debug) - document.write("
b0 "+curplace.b0); - } else { - /* Not a Leaf cell */ - curplace.b0 = 0x8000; - if (debug) - document.write("
b0 "+curplace.b0); - if(Rec()) - return -1; - } - tmp = IsPat(); - if(tmp >= 0) { - curplace.b1 = tmp; /* leaf cell for 1-bit */ - if (debug) - document.write("
b1 "+curplace.b1); - curplace.jump = null; /* Just for the display routine */ - } else { - /* Not a Leaf cell */ - curplace.b1 = 0x8000; - if (debug) - document.write("
b1 "+curplace.b1); - curplace.jump = Places[treepos]; - curplace.jumppos = treepos; - if(Rec()) - return -1; - } - len--; - return 0; - }; - - function CreateTree(currentTree, numval, lengths, show) { - var i; - /* Create the Huffman decode tree/table */ - //document.write("
createtree
"); - if (debug) - document.write("currentTree "+currentTree+" numval "+numval+" lengths "+lengths+" show "+show); - Places = currentTree; - treepos=0; - flens = lengths; - fmax = numval; - for (i=0;i<17;i++) - fpos[i] = 0; - len = 0; - if(Rec()) { - //fprintf(stderr, "invalid huffman tree\n"); - if (debug) - alert("invalid huffman tree\n"); - return -1; - } - if (debug){ - document.write('
Tree: '+Places.length); - for (var a=0;a<32;a++){ - document.write("Places["+a+"].b0="+Places[a].b0+"
"); - document.write("Places["+a+"].b1="+Places[a].b1+"
"); - } - } - - /*if(show) { - var tmp; - for(tmp=currentTree;tmpjump?tmp->jump-currentTree:0,(tmp->jump?tmp->jump-currentTree:0)*6+0xcf0); - if(!(tmp.b0 & 0x8000)) { - //fprintf(stdout, " 0x%03x (%c)", tmp->b0,(tmp->b0<256 && isprint(tmp->b0))?tmp->b0:'�'); - } - if(!(tmp.b1 & 0x8000)) { - if((tmp.b0 & 0x8000)) - fprintf(stdout, " "); - fprintf(stdout, " 0x%03x (%c)", tmp->b1,(tmp->b1<256 && isprint(tmp->b1))?tmp->b1:'�'); - } - fprintf(stdout, "\n"); - } - }*/ - return 0; - }; - - function DecodeValue(currentTree) { - var len, i, - xtreepos=0, - X = currentTree[xtreepos], - b; - - /* decode one symbol of the data */ - while(1) { - b=readBit(); - if (debug) - document.write("b="+b); - if(b) { - if(!(X.b1 & 0x8000)){ - if (debug) - document.write("ret1"); - return X.b1; /* If leaf node, return data */ - } - X = X.jump; - len = currentTree.length; - for (i=0;i>1); - if(j > 23) { - j = (j<<1) | readBit(); /* 48..255 */ - - if(j > 199) { /* 200..255 */ - j -= 128; /* 72..127 */ - j = (j<<1) | readBit(); /* 144..255 << */ - } else { /* 48..199 */ - j -= 48; /* 0..151 */ - if(j > 143) { - j = j+136; /* 280..287 << */ - /* 0..143 << */ - } - } - } else { /* 0..23 */ - j += 256; /* 256..279 << */ - } - if(j < 256) { - addBuffer(j); - //document.write("out:"+String.fromCharCode(j)); - /*fprintf(errfp, "@%d %02x\n", SIZE, j);*/ - } else if(j == 256) { - /* EOF */ - break; - } else { - var len, dist; - - j -= 256 + 1; /* bytes + EOF */ - len = readBits(cplext[j]) + cplens[j]; - - j = bitReverse[readBits(5)]>>3; - if(cpdext[j] > 8) { - dist = readBits(8); - dist |= (readBits(cpdext[j]-8)<<8); - } else { - dist = readBits(cpdext[j]); - } - dist += cpdist[j]; - - /*fprintf(errfp, "@%d (l%02x,d%04x)\n", SIZE, len, dist);*/ - for(j=0;jparam: "+literalCodes+" "+distCodes+" "+lenCodes+"
"); - for(j=0; j<19; j++) { - ll[j] = 0; - } - - // Get the decode tree code lengths - - //document.write("
"); - for(j=0; jll:'+ll); - len = distanceTree.length; - for (i=0; idistanceTree"); - for(var a=0;a"+distanceTree[a].b0+" "+distanceTree[a].b1+" "+distanceTree[a].jump+" "+distanceTree[a].jumppos); - /*if (distanceTree[a].jumppos!=-1) - document.write(" "+distanceTree[a].jump.b0+" "+distanceTree[a].jump.b1); - */ - } - } - //document.write('
tree created'); - - //read in literal and distance code lengths - n = literalCodes + distCodes; - i = 0; - var z=-1; - if (debug) - document.write("
n="+n+" bits: "+bits+"
"); - while(i < n) { - z++; - j = DecodeValue(distanceTree); - if (debug) - document.write("
"+z+" i:"+i+" decode: "+j+" bits "+bits+"
"); - if(j<16) { // length of code in bits (0..15) - ll[i++] = j; - } else if(j==16) { // repeat last length 3 to 6 times - var l; - j = 3 + readBits(2); - if(i+j > n) { - flushBuffer(); - return 1; - } - l = i ? ll[i-1] : 0; - while(j--) { - ll[i++] = l; - } - } else { - if(j==17) { // 3 to 10 zero length codes - j = 3 + readBits(3); - } else { // j == 18: 11 to 138 zero length codes - j = 11 + readBits(7); - } - if(i+j > n) { - flushBuffer(); - return 1; - } - while(j--) { - ll[i++] = 0; - } - } - } - /*for(j=0; jliteralTree"); - outer: - while(1) { - j = DecodeValue(literalTree); - if(j >= 256) { // In C64: if carry set - var len, dist; - j -= 256; - if(j == 0) { - // EOF - break; - } - j--; - len = readBits(cplext[j]) + cplens[j]; - - j = DecodeValue(distanceTree); - if(cpdext[j] > 8) { - dist = readBits(8); - dist |= (readBits(cpdext[j]-8)<<8); - } else { - dist = readBits(cpdext[j]); - } - dist += cpdist[j]; - while(len--) { - if(bIdx - dist < 0) { - break outer; - } - var c = buf32k[(bIdx - dist) & 0x7fff]; - addBuffer(c); - } - } else { - addBuffer(j); - } - } - } - } while(!last); - flushBuffer(); - - byteAlign(); - return 0; -}; - -JXG.Util.Unzip.prototype.unzipFile = function(name) { - var i; - this.unzip(); - //alert(unzipped[0][1]); - for (i=0;i"); - } - */ - //alert(bA); - nextFile(); - return unzipped; - }; - - function nextFile(){ - if (debug) - alert("NEXTFILE"); - outputArr = []; - var tmp = []; - modeZIP = false; - tmp[0] = readByte(); - tmp[1] = readByte(); - if (debug) - alert("type: "+tmp[0]+" "+tmp[1]); - if (tmp[0] == parseInt("78",16) && tmp[1] == parseInt("da",16)){ //GZIP - if (debug) - alert("GEONExT-GZIP"); - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "geonext.gxt"; - files++; - } - if (tmp[0] == parseInt("78",16) && tmp[1] == parseInt("9c",16)){ //ZLIB - if (debug) - alert("ZLIB"); - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "ZLIB"; - files++; - } - if (tmp[0] == parseInt("1f",16) && tmp[1] == parseInt("8b",16)){ //GZIP - if (debug) - alert("GZIP"); - //DeflateLoop(); - skipdir(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "file"; - files++; - } - if (tmp[0] == parseInt("50",16) && tmp[1] == parseInt("4b",16)){ //ZIP - modeZIP = true; - tmp[2] = readByte(); - tmp[3] = readByte(); - if (tmp[2] == parseInt("3",16) && tmp[3] == parseInt("4",16)){ - //MODE_ZIP - tmp[0] = readByte(); - tmp[1] = readByte(); - if (debug) - alert("ZIP-Version: "+tmp[1]+" "+tmp[0]/10+"."+tmp[0]%10); - - gpflags = readByte(); - gpflags |= (readByte()<<8); - if (debug) - alert("gpflags: "+gpflags); - - var method = readByte(); - method |= (readByte()<<8); - if (debug) - alert("method: "+method); - - readByte(); - readByte(); - readByte(); - readByte(); - - var crc = readByte(); - crc |= (readByte()<<8); - crc |= (readByte()<<16); - crc |= (readByte()<<24); - - var compSize = readByte(); - compSize |= (readByte()<<8); - compSize |= (readByte()<<16); - compSize |= (readByte()<<24); - - var size = readByte(); - size |= (readByte()<<8); - size |= (readByte()<<16); - size |= (readByte()<<24); - - if (debug) - alert("local CRC: "+crc+"\nlocal Size: "+size+"\nlocal CompSize: "+compSize); - - var filelen = readByte(); - filelen |= (readByte()<<8); - - var extralen = readByte(); - extralen |= (readByte()<<8); - - if (debug) - alert("filelen "+filelen); - i = 0; - nameBuf = []; - while (filelen--){ - var c = readByte(); - if (c == "/" | c ==":"){ - i = 0; - } else if (i < NAMEMAX-1) - nameBuf[i++] = String.fromCharCode(c); - } - if (debug) - alert("nameBuf: "+nameBuf); - - //nameBuf[i] = "\0"; - if (!fileout) - fileout = nameBuf; - - var i = 0; - while (i < extralen){ - c = readByte(); - i++; - } - - CRC = 0xffffffff; - SIZE = 0; - - if (size == 0 && fileOut.charAt(fileout.length-1)=="/"){ - //skipdir - if (debug) - alert("skipdir"); - } - if (method == 8){ - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = nameBuf.join(''); - files++; - //return outputArr.join(''); - } - skipdir(); - } - } - }; - -function skipdir(){ - var crc, - tmp = [], - compSize, size, os, i, c; - - if ((gpflags & 8)) { - tmp[0] = readByte(); - tmp[1] = readByte(); - tmp[2] = readByte(); - tmp[3] = readByte(); - - if (tmp[0] == parseInt("50",16) && - tmp[1] == parseInt("4b",16) && - tmp[2] == parseInt("07",16) && - tmp[3] == parseInt("08",16)) - { - crc = readByte(); - crc |= (readByte()<<8); - crc |= (readByte()<<16); - crc |= (readByte()<<24); - } else { - crc = tmp[0] | (tmp[1]<<8) | (tmp[2]<<16) | (tmp[3]<<24); - } - - compSize = readByte(); - compSize |= (readByte()<<8); - compSize |= (readByte()<<16); - compSize |= (readByte()<<24); - - size = readByte(); - size |= (readByte()<<8); - size |= (readByte()<<16); - size |= (readByte()<<24); - - if (debug) - alert("CRC:"); - } - - if (modeZIP) - nextFile(); - - tmp[0] = readByte(); - if (tmp[0] != 8) { - if (debug) - alert("Unknown compression method!"); - return 0; - } - - gpflags = readByte(); - if (debug){ - if ((gpflags & ~(parseInt("1f",16)))) - alert("Unknown flags set!"); - } - - readByte(); - readByte(); - readByte(); - readByte(); - - readByte(); - os = readByte(); - - if ((gpflags & 4)){ - tmp[0] = readByte(); - tmp[2] = readByte(); - len = tmp[0] + 256*tmp[1]; - if (debug) - alert("Extra field size: "+len); - for (i=0;i> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - - output.push([this._keyStr.charAt(enc1), - this._keyStr.charAt(enc2), - this._keyStr.charAt(enc3), - this._keyStr.charAt(enc4)].join('')); - } - - return output.join(''); - }, - - // public method for decoding - decode : function (input, utf8) { - var output = [], - chr1, chr2, chr3, - enc1, enc2, enc3, enc4, - i = 0; - - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - - while (i < input.length) { - - enc1 = this._keyStr.indexOf(input.charAt(i++)); - enc2 = this._keyStr.indexOf(input.charAt(i++)); - enc3 = this._keyStr.indexOf(input.charAt(i++)); - enc4 = this._keyStr.indexOf(input.charAt(i++)); - - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - - output.push(String.fromCharCode(chr1)); - - if (enc3 != 64) { - output.push(String.fromCharCode(chr2)); - } - if (enc4 != 64) { - output.push(String.fromCharCode(chr3)); - } - } - - output = output.join(''); - - if (utf8) { - output = JXG.Util.Base64._utf8_decode(output); - } - return output; - - }, - - // private method for UTF-8 encoding - _utf8_encode : function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - - var c = string.charCodeAt(n); - - if (c < 128) { - utftext += String.fromCharCode(c); - } - else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } - else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }, - - // private method for UTF-8 decoding - _utf8_decode : function (utftext) { - var string = [], - i = 0, - c = 0, c2 = 0, c3 = 0; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - if (c < 128) { - string.push(String.fromCharCode(c)); - i++; - } - else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); - i += 2; - } - else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); - i += 3; - } - } - return string.join(''); - }, - - _destrip: function (stripped, wrap){ - var lines = [], lineno, i, - destripped = []; - - if (wrap==null) - wrap = 76; - - stripped.replace(/ /g, ""); - lineno = stripped.length / wrap; - for (i = 0; i < lineno; i++) - lines[i]=stripped.substr(i * wrap, wrap); - if (lineno != stripped.length / wrap) - lines[lines.length]=stripped.substr(lineno * wrap, stripped.length-(lineno * wrap)); - - for (i = 0; i < lines.length; i++) - destripped.push(lines[i]); - return destripped.join('\n'); - }, - - decodeAsArray: function (input){ - var dec = this.decode(input), - ar = [], i; - for (i=0;i255){ - switch (c) { - case 8364: c=128; - break; - case 8218: c=130; - break; - case 402: c=131; - break; - case 8222: c=132; - break; - case 8230: c=133; - break; - case 8224: c=134; - break; - case 8225: c=135; - break; - case 710: c=136; - break; - case 8240: c=137; - break; - case 352: c=138; - break; - case 8249: c=139; - break; - case 338: c=140; - break; - case 381: c=142; - break; - case 8216: c=145; - break; - case 8217: c=146; - break; - case 8220: c=147; - break; - case 8221: c=148; - break; - case 8226: c=149; - break; - case 8211: c=150; - break; - case 8212: c=151; - break; - case 732: c=152; - break; - case 8482: c=153; - break; - case 353: c=154; - break; - case 8250: c=155; - break; - case 339: c=156; - break; - case 382: c=158; - break; - case 376: c=159; - break; - default: - break; - } - } - return c; -}; - -/** - * Decoding string into utf-8 - * @param {String} string to decode - * @return {String} utf8 decoded string - */ -JXG.Util.utf8Decode = function(utftext) { - var string = []; - var i = 0; - var c = 0, c1 = 0, c2 = 0, c3; - if (!JXG.exists(utftext)) return ''; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - - if (c < 128) { - string.push(String.fromCharCode(c)); - i++; - } else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); - i += 2; - } else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); - i += 3; - } - }; - return string.join(''); -}; - -/** - * Generate a random uuid. - * http://www.broofa.com - * mailto:robert@broofa.com - * - * Copyright (c) 2010 Robert Kieffer - * Dual licensed under the MIT and GPL licenses. - * - * EXAMPLES: - * >>> Math.uuid() - * "92329D39-6F5C-4520-ABFC-AAB64544E172" - */ -JXG.Util.genUUID = function() { - // Private array of chars to use - var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''), - uuid = new Array(36), rnd=0, r; - - for (var i = 0; i < 36; i++) { - if (i==8 || i==13 || i==18 || i==23) { - uuid[i] = '-'; - } else if (i==14) { - uuid[i] = '4'; - } else { - if (rnd <= 0x02) rnd = 0x2000000 + (Math.random()*0x1000000)|0; - r = rnd & 0xf; - rnd = rnd >> 4; - uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; - } - } - - return uuid.join(''); -}; - diff --git a/src/encoding/openpgp.encoding.asciiarmor.js b/src/encoding/openpgp.encoding.asciiarmor.js deleted file mode 100644 index a44d9c76..00000000 --- a/src/encoding/openpgp.encoding.asciiarmor.js +++ /dev/null @@ -1,330 +0,0 @@ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * DeArmor an OpenPGP armored message; verify the checksum and return - * the encoded bytes - * @param {String} text OpenPGP armored message - * @returns {(Boolean|Object)} Either false in case of an error - * or an object with attribute "text" containing the message text - * and an attribute "openpgp" containing the bytes. - */ -function openpgp_encoding_deArmor(text) { - var reSplit = /^-----[^-]+-----$\n/m; - - text = text.replace(/\r/g, ''); - - var type = openpgp_encoding_get_type(text); - - var splittedtext = text.split(reSplit); - - // IE has a bug in split with a re. If the pattern matches the beginning of the - // string it doesn't create an empty array element 0. So we need to detect this - // so we know the index of the data we are interested in. - var indexBase = 1; - - var result, checksum; - - if (text.search(reSplit) != splittedtext[0].length) { - indexBase = 0; - } - - if (type != 2) { - // splittedtext[indexBase] - the message and checksum - - // chunks separated by blank lines - var msg = openpgp_encoding_split_headers(splittedtext[indexBase].replace(/^- /mg, '')); - var msg_sum = openpgp_encoding_split_checksum(msg.body); - - result = { - openpgp: openpgp_encoding_base64_decode(msg_sum.body), - type: type - }; - checksum = msg_sum.checksum; - } else { - // splittedtext[indexBase] - the message - // splittedtext[indexBase + 1] - the signature and checksum - - var msg = openpgp_encoding_split_headers(splittedtext[indexBase].replace(/^- /mg, '').replace(/[\t ]+\n/g, "\n")); - var sig = openpgp_encoding_split_headers(splittedtext[indexBase + 1].replace(/^- /mg, '')); - var sig_sum = openpgp_encoding_split_checksum(sig.body); - - result = { - text: msg.body.replace(/\n$/, "").replace(/\n/g, "\r\n"), - openpgp: openpgp_encoding_base64_decode(sig_sum.body), - type: type - }; - - checksum = sig_sum.checksum; - } - - if (!verifyCheckSum(result.openpgp, checksum)) { - util.print_error("Ascii armor integrity check on message failed: '" - + checksum - + "' should be '" - + getCheckSum(result) + "'"); - return false; - } else { - return result; - } -} - -/** - * Splits a message into two parts, the headers and the body. This is an internal function - * @param {String} text OpenPGP armored message part - * @returns {(Boolean|Object)} Either false in case of an error - * or an object with attribute "headers" containing the headers and - * and an attribute "body" containing the body. - */ -function openpgp_encoding_split_headers(text) { - var reEmptyLine = /^[\t ]*\n/m; - var headers = ""; - var body = text; - - var matchResult = reEmptyLine.exec(text); - - if (matchResult != null) { - headers = text.slice(0, matchResult.index); - body = text.slice(matchResult.index + matchResult[0].length); - } - - return { headers: headers, body: body }; -} - -/** - * Splits a message into two parts, the body and the checksum. This is an internal function - * @param {String} text OpenPGP armored message part - * @returns {(Boolean|Object)} Either false in case of an error - * or an object with attribute "body" containing the body - * and an attribute "checksum" containing the checksum. - */ -function openpgp_encoding_split_checksum(text) { - var reChecksumStart = /^=/m; - var body = text; - var checksum = ""; - - var matchResult = reChecksumStart.exec(text); - - if (matchResult != null) { - body = text.slice(0, matchResult.index); - checksum = text.slice(matchResult.index + 1); - } - - return { body: body, checksum: checksum }; -} - -/** - * Finds out which Ascii Armoring type is used. This is an internal function - * @param {String} text [String] ascii armored text - * @returns {Integer} 0 = MESSAGE PART n of m - * 1 = MESSAGE PART n - * 2 = SIGNED MESSAGE - * 3 = PGP MESSAGE - * 4 = PUBLIC KEY BLOCK - * 5 = PRIVATE KEY BLOCK - * null = unknown - */ -function openpgp_encoding_get_type(text) { - var reHeader = /^-----([^-]+)-----$\n/m; - - var header = text.match(reHeader); - // BEGIN PGP MESSAGE, PART X/Y - // Used for multi-part messages, where the armor is split amongst Y - // parts, and this is the Xth part out of Y. - if (header[1].match(/BEGIN PGP MESSAGE, PART \d+\/\d+/)) { - return 0; - } else - // BEGIN PGP MESSAGE, PART X - // Used for multi-part messages, where this is the Xth part of an - // unspecified number of parts. Requires the MESSAGE-ID Armor - // Header to be used. - if (header[1].match(/BEGIN PGP MESSAGE, PART \d+/)) { - return 1; - - } else - // BEGIN PGP SIGNED MESSAGE - // Used for detached signatures, OpenPGP/MIME signatures, and - // cleartext signatures. Note that PGP 2.x uses BEGIN PGP MESSAGE - // for detached signatures. - if (header[1].match(/BEGIN PGP SIGNED MESSAGE/)) { - return 2; - - } else - // BEGIN PGP MESSAGE - // Used for signed, encrypted, or compressed files. - if (header[1].match(/BEGIN PGP MESSAGE/)) { - return 3; - - } else - // BEGIN PGP PUBLIC KEY BLOCK - // Used for armoring public keys. - if (header[1].match(/BEGIN PGP PUBLIC KEY BLOCK/)) { - return 4; - - } else - // BEGIN PGP PRIVATE KEY BLOCK - // Used for armoring private keys. - if (header[1].match(/BEGIN PGP PRIVATE KEY BLOCK/)) { - return 5; - } -} - -/** - * Add additional information to the armor version of an OpenPGP binary - * packet block. - * @author Alex - * @version 2011-12-16 - * @returns {String} The header information - */ -function openpgp_encoding_armor_addheader() { - var result = ""; - if (openpgp.config.config.show_version) { - result += "Version: "+openpgp.config.versionstring+'\r\n'; - } - if (openpgp.config.config.show_comment) { - result += "Comment: "+openpgp.config.commentstring+'\r\n'; - } - result += '\r\n'; - return result; -} - -/** - * Armor an OpenPGP binary packet block - * @param {Integer} messagetype type of the message - * @param data - * @param {Integer} partindex - * @param {Integer} parttotal - * @returns {String} Armored text - */ -function openpgp_encoding_armor(messagetype, data, partindex, parttotal) { - var result = ""; - switch(messagetype) { - case 0: - result += "-----BEGIN PGP MESSAGE, PART "+partindex+"/"+parttotal+"-----\r\n"; - result += openpgp_encoding_armor_addheader(); - result += openpgp_encoding_base64_encode(data); - result += "\r\n="+getCheckSum(data)+"\r\n"; - result += "-----END PGP MESSAGE, PART "+partindex+"/"+parttotal+"-----\r\n"; - break; - case 1: - result += "-----BEGIN PGP MESSAGE, PART "+partindex+"-----\r\n"; - result += openpgp_encoding_armor_addheader(); - result += openpgp_encoding_base64_encode(data); - result += "\r\n="+getCheckSum(data)+"\r\n"; - result += "-----END PGP MESSAGE, PART "+partindex+"-----\r\n"; - break; - case 2: - result += "\r\n-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: "+data.hash+"\r\n\r\n"; - result += data.text.replace(/\n-/g,"\n- -"); - result += "\r\n-----BEGIN PGP SIGNATURE-----\r\n"; - result += openpgp_encoding_armor_addheader(); - result += openpgp_encoding_base64_encode(data.openpgp); - result += "\r\n="+getCheckSum(data.openpgp)+"\r\n"; - result += "-----END PGP SIGNATURE-----\r\n"; - break; - case 3: - result += "-----BEGIN PGP MESSAGE-----\r\n"; - result += openpgp_encoding_armor_addheader(); - result += openpgp_encoding_base64_encode(data); - result += "\r\n="+getCheckSum(data)+"\r\n"; - result += "-----END PGP MESSAGE-----\r\n"; - break; - case 4: - result += "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n"; - result += openpgp_encoding_armor_addheader(); - result += openpgp_encoding_base64_encode(data); - result += "\r\n="+getCheckSum(data)+"\r\n"; - result += "-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n"; - break; - case 5: - result += "-----BEGIN PGP PRIVATE KEY BLOCK-----\r\n"; - result += openpgp_encoding_armor_addheader(); - result += openpgp_encoding_base64_encode(data); - result += "\r\n="+getCheckSum(data)+"\r\n"; - result += "-----END PGP PRIVATE KEY BLOCK-----\r\n"; - break; - } - - return result; -} - -/** - * Calculates a checksum over the given data and returns it base64 encoded - * @param {String} data Data to create a CRC-24 checksum for - * @return {String} Base64 encoded checksum - */ -function getCheckSum(data) { - var c = createcrc24(data); - var str = "" + String.fromCharCode(c >> 16)+ - String.fromCharCode((c >> 8) & 0xFF)+ - String.fromCharCode(c & 0xFF); - return openpgp_encoding_base64_encode(str); -} - -/** - * Calculates the checksum over the given data and compares it with the - * given base64 encoded checksum - * @param {String} data Data to create a CRC-24 checksum for - * @param {String} checksum Base64 encoded checksum - * @return {Boolean} True if the given checksum is correct; otherwise false - */ -function verifyCheckSum(data, checksum) { - var c = getCheckSum(data); - var d = checksum; - return c[0] == d[0] && c[1] == d[1] && c[2] == d[2]; -} -/** - * Internal function to calculate a CRC-24 checksum over a given string (data) - * @param {String} data Data to create a CRC-24 checksum for - * @return {Integer} The CRC-24 checksum as number - */ -var crc_table = [ -0x00000000, 0x00864cfb, 0x018ad50d, 0x010c99f6, 0x0393e6e1, 0x0315aa1a, 0x021933ec, 0x029f7f17, 0x07a18139, 0x0727cdc2, 0x062b5434, 0x06ad18cf, 0x043267d8, 0x04b42b23, 0x05b8b2d5, 0x053efe2e, 0x0fc54e89, 0x0f430272, 0x0e4f9b84, 0x0ec9d77f, 0x0c56a868, 0x0cd0e493, 0x0ddc7d65, 0x0d5a319e, 0x0864cfb0, 0x08e2834b, 0x09ee1abd, 0x09685646, 0x0bf72951, 0x0b7165aa, 0x0a7dfc5c, 0x0afbb0a7, 0x1f0cd1e9, 0x1f8a9d12, 0x1e8604e4, 0x1e00481f, 0x1c9f3708, 0x1c197bf3, 0x1d15e205, 0x1d93aefe, 0x18ad50d0, 0x182b1c2b, 0x192785dd, 0x19a1c926, 0x1b3eb631, 0x1bb8faca, 0x1ab4633c, 0x1a322fc7, 0x10c99f60, 0x104fd39b, 0x11434a6d, 0x11c50696, 0x135a7981, 0x13dc357a, 0x12d0ac8c, 0x1256e077, 0x17681e59, 0x17ee52a2, 0x16e2cb54, 0x166487af, 0x14fbf8b8, 0x147db443, 0x15712db5, 0x15f7614e, 0x3e19a3d2, 0x3e9fef29, 0x3f9376df, 0x3f153a24, 0x3d8a4533, 0x3d0c09c8, 0x3c00903e, 0x3c86dcc5, 0x39b822eb, 0x393e6e10, 0x3832f7e6, 0x38b4bb1d, 0x3a2bc40a, 0x3aad88f1, 0x3ba11107, 0x3b275dfc, 0x31dced5b, 0x315aa1a0, -0x30563856, 0x30d074ad, 0x324f0bba, 0x32c94741, 0x33c5deb7, 0x3343924c, 0x367d6c62, 0x36fb2099, 0x37f7b96f, 0x3771f594, 0x35ee8a83, 0x3568c678, 0x34645f8e, 0x34e21375, 0x2115723b, 0x21933ec0, 0x209fa736, 0x2019ebcd, 0x228694da, 0x2200d821, 0x230c41d7, 0x238a0d2c, 0x26b4f302, 0x2632bff9, 0x273e260f, 0x27b86af4, 0x252715e3, 0x25a15918, 0x24adc0ee, 0x242b8c15, 0x2ed03cb2, 0x2e567049, 0x2f5ae9bf, 0x2fdca544, 0x2d43da53, 0x2dc596a8, 0x2cc90f5e, 0x2c4f43a5, 0x2971bd8b, 0x29f7f170, 0x28fb6886, 0x287d247d, 0x2ae25b6a, 0x2a641791, 0x2b688e67, 0x2beec29c, 0x7c3347a4, 0x7cb50b5f, 0x7db992a9, 0x7d3fde52, 0x7fa0a145, 0x7f26edbe, 0x7e2a7448, 0x7eac38b3, 0x7b92c69d, 0x7b148a66, 0x7a181390, 0x7a9e5f6b, 0x7801207c, 0x78876c87, 0x798bf571, 0x790db98a, 0x73f6092d, 0x737045d6, 0x727cdc20, 0x72fa90db, 0x7065efcc, 0x70e3a337, 0x71ef3ac1, 0x7169763a, 0x74578814, 0x74d1c4ef, 0x75dd5d19, 0x755b11e2, 0x77c46ef5, 0x7742220e, 0x764ebbf8, 0x76c8f703, 0x633f964d, 0x63b9dab6, 0x62b54340, 0x62330fbb, -0x60ac70ac, 0x602a3c57, 0x6126a5a1, 0x61a0e95a, 0x649e1774, 0x64185b8f, 0x6514c279, 0x65928e82, 0x670df195, 0x678bbd6e, 0x66872498, 0x66016863, 0x6cfad8c4, 0x6c7c943f, 0x6d700dc9, 0x6df64132, 0x6f693e25, 0x6fef72de, 0x6ee3eb28, 0x6e65a7d3, 0x6b5b59fd, 0x6bdd1506, 0x6ad18cf0, 0x6a57c00b, 0x68c8bf1c, 0x684ef3e7, 0x69426a11, 0x69c426ea, 0x422ae476, 0x42aca88d, 0x43a0317b, 0x43267d80, 0x41b90297, 0x413f4e6c, 0x4033d79a, 0x40b59b61, 0x458b654f, 0x450d29b4, 0x4401b042, 0x4487fcb9, 0x461883ae, 0x469ecf55, 0x479256a3, 0x47141a58, 0x4defaaff, 0x4d69e604, 0x4c657ff2, 0x4ce33309, 0x4e7c4c1e, 0x4efa00e5, 0x4ff69913, 0x4f70d5e8, 0x4a4e2bc6, 0x4ac8673d, 0x4bc4fecb, 0x4b42b230, 0x49ddcd27, 0x495b81dc, 0x4857182a, 0x48d154d1, 0x5d26359f, 0x5da07964, 0x5cace092, 0x5c2aac69, 0x5eb5d37e, 0x5e339f85, 0x5f3f0673, 0x5fb94a88, 0x5a87b4a6, 0x5a01f85d, 0x5b0d61ab, 0x5b8b2d50, 0x59145247, 0x59921ebc, 0x589e874a, 0x5818cbb1, 0x52e37b16, 0x526537ed, 0x5369ae1b, 0x53efe2e0, 0x51709df7, 0x51f6d10c, -0x50fa48fa, 0x507c0401, 0x5542fa2f, 0x55c4b6d4, 0x54c82f22, 0x544e63d9, 0x56d11cce, 0x56575035, 0x575bc9c3, 0x57dd8538]; - -function createcrc24(input) { - var crc = 0xB704CE; - var index = 0; - - while((input.length - index) > 16) { - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+1)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+2)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+3)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+4)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+5)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+6)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+7)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+8)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+9)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+10)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+11)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+12)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+13)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+14)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+15)) & 0xff]; - index += 16; - } - - for(var j = index; j < input.length; j++) { - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index++)) & 0xff] - } - return crc & 0xffffff; -} - diff --git a/src/openpgp.msg.message.js b/src/openpgp.msg.message.js deleted file mode 100644 index 418a38de..00000000 --- a/src/openpgp.msg.message.js +++ /dev/null @@ -1,136 +0,0 @@ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @protected - * @class - * @classdesc Top-level message object. Contains information from one or more packets - */ - -function openpgp_msg_message() { - - // -1 = no valid passphrase submitted - // -2 = no private key found - // -3 = decryption error - // text = valid decryption - this.text = ""; - this.messagePacket = null; - this.type = null; - - /** - * Decrypts a message and generates user interface message out of the found. - * MDC will be verified as well as message signatures - * @param {openpgp_msg_privatekey} private_key the private the message is encrypted with (corresponding to the session key) - * @param {openpgp_packet_encryptedsessionkey} sessionkey the session key to be used to decrypt the message - * @return {String} plaintext of the message or null on error - */ - function decrypt(private_key, sessionkey) { - return this.decryptAndVerifySignature(private_key, sessionkey).text; - } - - /** - * Decrypts a message and generates user interface message out of the found. - * MDC will be verified as well as message signatures - * @param {openpgp_msg_privatekey} private_key the private the message is encrypted with (corresponding to the session key) - * @param {openpgp_packet_encryptedsessionkey} sessionkey the session key to be used to decrypt the message - * @param {openpgp_msg_publickey} pubkey Array of public keys to check signature against. If not provided, checks local keystore. - * @return {String} plaintext of the message or null on error - */ - function decryptAndVerifySignature(private_key, sessionkey, pubkey) { - if (private_key == null || sessionkey == null || sessionkey == "") - return null; - var decrypted = sessionkey.decrypt(this, private_key.keymaterial); - if (decrypted == null) - return null; - var packet; - var position = 0; - var len = decrypted.length; - var validSignatures = new Array(); - util.print_debug_hexstr_dump("openpgp.msg.messge decrypt:\n",decrypted); - - var messages = openpgp.read_messages_dearmored({text: decrypted, openpgp: decrypted}); - for(var m in messages){ - if(messages[m].data){ - this.text = messages[m].data; - } - if(messages[m].signature){ - validSignatures.push(messages[m].verifySignature(pubkey)); - } - } - return {text:this.text, validSignatures:validSignatures}; - } - - /** - * Verifies a message signature. This function can be called after read_message if the message was signed only. - * @param {openpgp_msg_publickey} pubkey Array of public keys to check signature against. If not provided, checks local keystore. - * @return {boolean} true if the signature was correct; otherwise false - */ - function verifySignature(pubkey) { - var result = false; - if (this.signature.tagType == 2) { - if (!pubkey || pubkey.length == 0) { - var pubkey; - if (this.signature.version == 4) { - pubkey = openpgp.keyring.getPublicKeysForKeyId(this.signature.issuerKeyId); - } else if (this.signature.version == 3) { - pubkey = openpgp.keyring.getPublicKeysForKeyId(this.signature.keyId); - } else { - util.print_error("unknown signature type on message!"); - return false; - } - } - if (pubkey.length == 0) { - util.print_warning("Unable to verify signature of issuer: "+util.hexstrdump(this.signature.issuerKeyId)+". Public key not found in keyring."); - } else { - for (var i = 0 ; i < pubkey.length; i++) { - if (this.signature.verify(this.text, pubkey[i])) { - util.print_info("Found Good Signature from "+pubkey[i].obj.userIds[0].text+" (0x"+util.hexstrdump(pubkey[i].obj.getKeyId()).substring(8)+")"); - result = true; - break; - } else { - util.print_error("Signature verification failed: Bad Signature from "+pubkey[i].obj.userIds[0].text+" (0x"+util.hexstrdump(pubkey[0].obj.getKeyId()).substring(8)+")"); - } - } - } - } - return result; - } - - function toString() { - var result = "Session Keys:\n"; - if (this.sessionKeys !=null) - for (var i = 0; i < this.sessionKeys.length; i++) { - result += this.sessionKeys[i].toString(); - } - result += "\n\n EncryptedData:\n"; - if(this.encryptedData != null) - result += this.encryptedData.toString(); - - result += "\n\n Signature:\n"; - if(this.signature != null) - result += this.signature.toString(); - - result += "\n\n Text:\n" - if(this.signature != null) - result += this.text; - return result; - } - this.decrypt = decrypt; - this.decryptAndVerifySignature = decryptAndVerifySignature; - this.verifySignature = verifySignature; - this.toString = toString; -} diff --git a/src/openpgp.msg.publickey.js b/src/openpgp.msg.publickey.js deleted file mode 100644 index 6a1506ed..00000000 --- a/src/openpgp.msg.publickey.js +++ /dev/null @@ -1,265 +0,0 @@ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @class - * @classdesc Decoded public key object for internal openpgp.js use - */ -function openpgp_msg_publickey() { - this.tostring = "OPENPGP PUBLIC KEY\n"; - this.bindingSignature = null; - this.publicKeyPacket = null; - this.userIds = new Array(); - this.userAttributes = new Array(); - this.revocationSignatures = new Array(); - this.subKeys = new Array(); - this.arbitraryPacket = new Array(); - this.directSignatures = new Array(); - /** - * - * @return last position - */ - function read_nodes(parent_node, input, position, len) { - this.publicKeyPacket = parent_node; - var exit = false; - var pos = position; - var l = len; - while (input.length != pos) { - var result = openpgp_packet.read_packet(input, pos, input.length - pos); - if (result == null) { - util.print_error("openpgp.msg.publickey read_nodes:\n"+'[pub_key]parsing ends here @:' + pos + " l:" + l); - break; - } else { - switch (result.tagType) { - case 2: // public key revocation signature - if (result.signatureType == 32) - this.revocationSignatures[this.revocationSignatures.length] = result; - else if (result.signatureType == 16 || result.signatureType == 17 || result.signatureType == 18 || result.signatureType == 19) - this.certificationSignature = result; - else if (result.signatureType == 25) { - this.bindingSignature = result; - } else if (result.signatureType == 31) { - this.directSignatures[this.directSignatures.length] = result; - } else - util.print_error("openpgp.msg.publickey read_nodes:\n"+"unknown signature type directly on key "+result.signatureType); - pos += result.packetLength + result.headerLength; - break; - case 14: // Public-Subkey Packet - this.subKeys[this.subKeys.length] = result; - pos += result.packetLength + result.headerLength; - pos += result.read_nodes(this.publicKeyPacket,input, pos, input.length - pos); - break; - case 17: // User Attribute Packet - this.userAttributes[this.userAttributes.length] = result; - pos += result.packetLength + result.headerLength; - pos += result.read_nodes(this.publicKeyPacket,input, pos, input.length - pos); - break; - case 13: // User ID Packet - this.userIds[this.userIds.length] = result; - pos += result.packetLength + result.headerLength; - pos += result.read_nodes(this.publicKeyPacket, input, pos, input.length - pos); - break; - default: - this.data = input; - this.position = position - this.publicKeyPacket.packetLength - this.publicKeyPacket.headerLength; - this.len = pos - position; - return this.len; - } - } - } - this.data = input; - this.position = position - (this.publicKeyPacket.packetLength - this.publicKeyPacket.headerLength); - this.len = pos - position; - return this.len; - } - - function write() { - - } - - function getKeyId() { - return this.publicKeyPacket.getKeyId(); - } - - function getFingerprint() { - return this.publicKeyPacket.getFingerprint(); - } - - - - function validate() { - // check revocation keys - for (var i = 0; i < this.revocationSignatures.length; i++) { - var tohash = this.publicKeyPacket.header+this.publicKeyPacket.data; - if (this.revocationSignatures[i].verify(tohash, this.publicKeyPacket)) - return false; - } - - if (this.subKeys.length != 0) { - // search for a valid subkey - var found = false; - for (var i = 0; i < this.subKeys.length; i++) - if (this.subKeys[i].verifyKey() == 3) { - found = true; - break; - } - if (!found) - return false; - } - // search for one valid userid - found = false; - for (var i = 0; i < this.userIds.length; i++) - if (this.userIds[i].verify(this.publicKeyPacket) == 0) { - found = true; - break; - } - if (!found) - return false; - return true; - } - - /** - * verifies all signatures - * @return a 2 dimensional array. the first dimension corresponds to the userids available - */ - function verifyCertificationSignatures() { - var result = new Array(); - for (var i = 0; i < this.userIds.length; i++) { - result[i] = this.userIds[i].verifyCertificationSignatures(this.publicKeyPacket); - } - return result; - } - this.verifyCertificationSignatures = verifyCertificationSignatures; - - /** - * verifies: - * - revocation certificates directly on key - * - self signatures - * - subkey binding and revocation certificates - * - * This is useful for validating the key - * @returns {Boolean} true if the basic signatures are all valid - */ - function verifyBasicSignatures() { - for (var i = 0; i < this.revocationSignatures.length; i++) { - var tohash = this.publicKeyPacket.header+this.publicKeyPacket.data; - if (this.revocationSignatures[i].verify(tohash, this.publicKeyPacket)) - return false; - } - - if (this.subKeys.length != 0) { - // search for a valid subkey - var found = false; - for (var i = 0; i < this.subKeys.length; i++) { - if (this.subKeys[i] == null) - continue; - var result = this.subKeys[i].verifyKey(); - if (result == 3) { - found = true; - break; - } - } - if (!found) - return false; - } - var keyId = this.getKeyId(); - for (var i = 0; i < this.userIds.length; i++) { - for (var j = 0; j < this.userIds[i].certificationRevocationSignatures.length; j++) { - if (this.userIds[i].certificationSignatures[j].getIssuer == keyId && - this.userIds[i].certificationSignatures[j].verifyBasic(this.publicKeyPacket) != 4) - return false; - } - } - return true; - } - - function toString() { - var result = " OPENPGP Public Key\n length: "+this.len+"\n"; - result += " Revocation Signatures:\n" - for (var i=0; i < this.revocationSignatures.length; i++) { - result += " "+this.revocationSignatures[i].toString(); - } - result += " User Ids:\n"; - for (var i=0; i < this.userIds.length; i++) { - result += " "+this.userIds[i].toString(); - } - result += " User Attributes:\n"; - for (var i=0; i < this.userAttributes.length; i++) { - result += " "+this.userAttributes[i].toString(); - } - result += " Public Key SubKeys:\n"; - for (var i=0; i < this.subKeys.length; i++) { - result += " "+this.subKeys[i].toString(); - } - return result; - } - - /** - * finds an encryption key for this public key - * @returns null if no encryption key has been found - */ - function getEncryptionKey() { - // V4: by convention subkeys are prefered for encryption service - // V3: keys MUST NOT have subkeys - for (var j = 0; j < this.subKeys.length; j++) - if (this.subKeys[j].publicKeyAlgorithm != 17 && - this.subKeys[j].publicKeyAlgorithm != 3 && - this.subKeys[j].verifyKey()) { - return this.subKeys[j]; - } - // if no valid subkey for encryption, use primary key - if (this.publicKeyPacket.publicKeyAlgorithm != 17 && this.publicKeyPacket.publicKeyAlgorithm != 3 - && this.publicKeyPacket.verifyKey()) { - return this.publicKeyPacket; - } - return null; - } - - function getSigningKey() { - if ((this.publicKeyPacket.publicKeyAlgorithm == 17 || - this.publicKeyPacket.publicKeyAlgorithm != 2)) - return this.publicKeyPacket; - else if (this.publicKeyPacket.version == 4) // V3 keys MUST NOT have subkeys. - for (var j = 0; j < this.subKeys.length; j++) { - if ((this.subKeys[j].publicKeyAlgorithm == 17 || - this.subKeys[j].publicKeyAlgorithm != 2) && - this.subKeys[j].verifyKey()) - return this.subKeys[j]; - } - return null; - } - - /* Returns the i-th subKey as a openpgp_msg_publickey object */ - function getSubKeyAsKey(i) { - var ret = new openpgp_msg_publickey(); - ret.userIds = this.userIds; - ret.userAttributes = this.userAttributes; - ret.publicKeyPacket = this.subKeys[i]; - return ret; - } - - this.getEncryptionKey = getEncryptionKey; - this.getSigningKey = getSigningKey; - this.read_nodes = read_nodes; - this.write = write; - this.toString = toString; - this.validate = validate; - this.getFingerprint = getFingerprint; - this.getKeyId = getKeyId; - this.verifyBasicSignatures = verifyBasicSignatures; - this.getSubKeyAsKey = getSubKeyAsKey; -} diff --git a/src/packet/openpgp.packet.encryptedintegrityprotecteddata.js b/src/packet/openpgp.packet.encryptedintegrityprotecteddata.js deleted file mode 100644 index f823f42c..00000000 --- a/src/packet/openpgp.packet.encryptedintegrityprotecteddata.js +++ /dev/null @@ -1,155 +0,0 @@ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @class - * @classdesc Implementation of the Sym. Encrypted Integrity Protected Data - * Packet (Tag 18) - * - * RFC4880 5.13: The Symmetrically Encrypted Integrity Protected Data packet is - * a variant of the Symmetrically Encrypted Data packet. It is a new feature - * created for OpenPGP that addresses the problem of detecting a modification to - * encrypted data. It is used in combination with a Modification Detection Code - * packet. - */ - -function openpgp_packet_encryptedintegrityprotecteddata() { - this.tagType = 18; - this.version = null; // integer == 1 - this.packetLength = null; // integer - this.encryptedData = null; // string - this.decrytpedData = null; // string - this.hash = null; // string - /** - * Parsing function for the packet. - * - * @param {String} input Payload of a tag 18 packet - * @param {Integer} position - * position to start reading from the input string - * @param {Integer} len Length of the packet or the remaining length of - * input at position - * @return {openpgp_packet_encryptedintegrityprotecteddata} object - * representation - */ - function read_packet(input, position, len) { - this.packetLength = len; - // - A one-octet version number. The only currently defined value is - // 1. - this.version = input.charCodeAt(position); - if (this.version != 1) { - util - .print_error('openpgp.packet.encryptedintegrityprotecteddata.js\nunknown encrypted integrity protected data packet version: ' - + this.version - + " , @ " - + position - + "hex:" - + util.hexstrdump(input)); - return null; - } - // - Encrypted data, the output of the selected symmetric-key cipher - // operating in Cipher Feedback mode with shift amount equal to the - // block size of the cipher (CFB-n where n is the block size). - this.encryptedData = input.substring(position + 1, position + 1 + len); - util.print_debug("openpgp.packet.encryptedintegrityprotecteddata.js\n" - + this.toString()); - return this; - } - - /** - * Creates a string representation of a Sym. Encrypted Integrity Protected - * Data Packet (tag 18) (see RFC4880 5.13) - * - * @param {Integer} symmetric_algorithm - * The selected symmetric encryption algorithm to be used - * @param {String} key The key of cipher blocksize length to be used - * @param {String} data - * Plaintext data to be encrypted within the packet - * @return {String} A string representation of the packet - */ - function write_packet(symmetric_algorithm, key, data) { - - var prefixrandom = openpgp_crypto_getPrefixRandom(symmetric_algorithm); - var prefix = prefixrandom - + prefixrandom.charAt(prefixrandom.length - 2) - + prefixrandom.charAt(prefixrandom.length - 1); - var tohash = data; - tohash += String.fromCharCode(0xD3); - tohash += String.fromCharCode(0x14); - util.print_debug_hexstr_dump("data to be hashed:" - , prefix + tohash); - tohash += str_sha1(prefix + tohash); - util.print_debug_hexstr_dump("hash:" - , tohash.substring(tohash.length - 20, - tohash.length)); - var result = openpgp_crypto_symmetricEncrypt(prefixrandom, - symmetric_algorithm, key, tohash, false).substring(0, - prefix.length + tohash.length); - var header = openpgp_packet.write_packet_header(18, result.length + 1) - + String.fromCharCode(1); - this.encryptedData = result; - return header + result; - } - - /** - * Decrypts the encrypted data contained in this object read_packet must - * have been called before - * - * @param {Integer} symmetric_algorithm_type - * The selected symmetric encryption algorithm to be used - * @param {String} key The key of cipher blocksize length to be used - * @return {String} The decrypted data of this packet - */ - function decrypt(symmetric_algorithm_type, key) { - this.decryptedData = openpgp_crypto_symmetricDecrypt( - symmetric_algorithm_type, key, this.encryptedData, false); - // there must be a modification detection code packet as the - // last packet and everything gets hashed except the hash itself - this.hash = str_sha1(openpgp_crypto_MDCSystemBytes( - symmetric_algorithm_type, key, this.encryptedData) - + this.decryptedData.substring(0, - this.decryptedData.length - 20)); - util.print_debug_hexstr_dump("calc hash = ", this.hash); - if (this.hash == this.decryptedData.substring( - this.decryptedData.length - 20, this.decryptedData.length)) - return this.decryptedData; - else - util - .print_error("Decryption stopped: discovered a modification of encrypted data."); - return null; - } - - function toString() { - var data = ''; - if(openpgp.config.debug) - data = ' data: Bytes [' - + util.hexstrdump(this.encryptedData) + ']'; - - return '5.13. Sym. Encrypted Integrity Protected Data Packet (Tag 18)\n' - + ' length: ' - + this.packetLength - + '\n' - + ' version: ' - + this.version - + '\n' - + data; - } - - this.write_packet = write_packet; - this.read_packet = read_packet; - this.toString = toString; - this.decrypt = decrypt; -}; diff --git a/src/packet/openpgp.packet.encryptedsessionkey.js b/src/packet/openpgp.packet.encryptedsessionkey.js deleted file mode 100644 index e8d3817a..00000000 --- a/src/packet/openpgp.packet.encryptedsessionkey.js +++ /dev/null @@ -1,226 +0,0 @@ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @class - * @classdesc Public-Key Encrypted Session Key Packets (Tag 1) - * - * RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key - * used to encrypt a message. Zero or more Public-Key Encrypted Session Key - * packets and/or Symmetric-Key Encrypted Session Key packets may precede a - * Symmetrically Encrypted Data Packet, which holds an encrypted message. The - * message is encrypted with the session key, and the session key is itself - * encrypted and stored in the Encrypted Session Key packet(s). The - * Symmetrically Encrypted Data Packet is preceded by one Public-Key Encrypted - * Session Key packet for each OpenPGP key to which the message is encrypted. - * The recipient of the message finds a session key that is encrypted to their - * public key, decrypts the session key, and then uses the session key to - * decrypt the message. - */ -function openpgp_packet_encryptedsessionkey() { - - /** - * Parsing function for a publickey encrypted session key packet (tag 1). - * - * @param {String} input Payload of a tag 1 packet - * @param {Integer} position Position to start reading from the input string - * @param {Integer} len Length of the packet or the remaining length of - * input at position - * @return {openpgp_packet_encrypteddata} Object representation - */ - function read_pub_key_packet(input, position, len) { - this.tagType = 1; - this.packetLength = len; - var mypos = position; - if (len < 10) { - util - .print_error("openpgp.packet.encryptedsessionkey.js\n" + 'invalid length'); - return null; - } - - this.version = input.charCodeAt(mypos++); - this.keyId = new openpgp_type_keyid(); - this.keyId.read_packet(input, mypos); - mypos += 8; - this.publicKeyAlgorithmUsed = input.charCodeAt(mypos++); - - switch (this.publicKeyAlgorithmUsed) { - case 1: - case 2: // RSA - this.MPIs = new Array(); - this.MPIs[0] = new openpgp_type_mpi(); - this.MPIs[0].read(input, mypos, mypos - position); - break; - case 16: // Elgamal - this.MPIs = new Array(); - this.MPIs[0] = new openpgp_type_mpi(); - this.MPIs[0].read(input, mypos, mypos - position); - mypos += this.MPIs[0].packetLength; - this.MPIs[1] = new openpgp_type_mpi(); - this.MPIs[1].read(input, mypos, mypos - position); - break; - default: - util.print_error("openpgp.packet.encryptedsessionkey.js\n" - + "unknown public key packet algorithm type " - + this.publicKeyAlgorithmType); - break; - } - return this; - } - - /** - * Create a string representation of a tag 1 packet - * - * @param {String} publicKeyId - * The public key id corresponding to publicMPIs key as string - * @param {openpgp_type_mpi[]} publicMPIs - * Multiprecision integer objects describing the public key - * @param {Integer} pubalgo - * The corresponding public key algorithm // See RFC4880 9.1 - * @param {Integer} symmalgo - * The symmetric cipher algorithm used to encrypt the data - * within an encrypteddatapacket or encryptedintegrity- - * protecteddatapacket - * following this packet //See RFC4880 9.2 - * @param {String} sessionkey - * A string of randombytes representing the session key - * @return {String} The string representation - */ - function write_pub_key_packet(publicKeyId, publicMPIs, pubalgo, symmalgo, - sessionkey) { - var result = String.fromCharCode(3); - var data = String.fromCharCode(symmalgo); - data += sessionkey; - var checksum = util.calc_checksum(sessionkey); - data += String.fromCharCode((checksum >> 8) & 0xFF); - data += String.fromCharCode((checksum) & 0xFF); - result += publicKeyId; - result += String.fromCharCode(pubalgo); - var mpi = new openpgp_type_mpi(); - var mpiresult = openpgp_crypto_asymetricEncrypt(pubalgo, publicMPIs, - mpi.create(openpgp_encoding_eme_pkcs1_encode(data, - publicMPIs[0].mpiByteLength))); - for ( var i = 0; i < mpiresult.length; i++) { - result += mpiresult[i]; - } - result = openpgp_packet.write_packet_header(1, result.length) + result; - return result; - } - - /** - * Parsing function for a symmetric encrypted session key packet (tag 3). - * - * @param {String} input Payload of a tag 1 packet - * @param {Integer} position Position to start reading from the input string - * @param {Integer} len - * Length of the packet or the remaining length of - * input at position - * @return {openpgp_packet_encrypteddata} Object representation - */ - function read_symmetric_key_packet(input, position, len) { - this.tagType = 3; - var mypos = position; - // A one-octet version number. The only currently defined version is 4. - this.version = input[mypos++]; - - // A one-octet number describing the symmetric algorithm used. - this.symmetricKeyAlgorithmUsed = input[mypos++]; - // A string-to-key (S2K) specifier, length as defined above. - this.s2k = new openpgp_type_s2k(); - this.s2k.read(input, mypos); - - // Optionally, the encrypted session key itself, which is decrypted - // with the string-to-key object. - if ((s2k.s2kLength + mypos) < len) { - this.encryptedSessionKey = new Array(); - for ( var i = (mypos - position); i < len; i++) { - this.encryptedSessionKey[i] = input[mypos++]; - } - } - return this; - } - /** - * Decrypts the session key (only for public key encrypted session key - * packets (tag 1) - * - * @param {openpgp_msg_message} msg - * The message object (with member encryptedData - * @param {openpgp_msg_privatekey} key - * Private key with secMPIs unlocked - * @return {String} The unencrypted session key - */ - function decrypt(msg, key) { - if (this.tagType == 1) { - var result = openpgp_crypto_asymetricDecrypt( - this.publicKeyAlgorithmUsed, key.publicKey.MPIs, - key.secMPIs, this.MPIs).toMPI(); - var checksum = ((result.charCodeAt(result.length - 2) << 8) + result - .charCodeAt(result.length - 1)); - var decoded = openpgp_encoding_eme_pkcs1_decode(result.substring(2, result.length - 2), key.publicKey.MPIs[0].getByteLength()); - var sesskey = decoded.substring(1); - var algo = decoded.charCodeAt(0); - if (msg.encryptedData.tagType == 18) - return msg.encryptedData.decrypt(algo, sesskey); - else - return msg.encryptedData.decrypt_sym(algo, sesskey); - } else if (this.tagType == 3) { - util - .print_error("Symmetric encrypted sessionkey is not supported!"); - return null; - } - } - - /** - * Creates a string representation of this object (useful for debug - * purposes) - * - * @return {String} The string containing a openpgp description - */ - function toString() { - if (this.tagType == 1) { - var result = '5.1. Public-Key Encrypted Session Key Packets (Tag 1)\n' - + ' KeyId: ' - + this.keyId.toString() - + '\n' - + ' length: ' - + this.packetLength - + '\n' - + ' version:' - + this.version - + '\n' - + ' pubAlgUs:' - + this.publicKeyAlgorithmUsed + '\n'; - for ( var i = 0; i < this.MPIs.length; i++) { - result += this.MPIs[i].toString(); - } - return result; - } else - return '5.3 Symmetric-Key Encrypted Session Key Packets (Tag 3)\n' - + ' KeyId: ' + this.keyId.toString() + '\n' - + ' length: ' + this.packetLength + '\n' - + ' version:' + this.version + '\n' + ' symKeyA:' - + this.symmetricKeyAlgorithmUsed + '\n' + ' s2k: ' - + this.s2k + '\n'; - } - - this.read_pub_key_packet = read_pub_key_packet; - this.read_symmetric_key_packet = read_symmetric_key_packet; - this.write_pub_key_packet = write_pub_key_packet; - this.toString = toString; - this.decrypt = decrypt; -}; - diff --git a/src/packet/openpgp.packet.js b/src/packet/openpgp.packet.js deleted file mode 100644 index 840e9ef2..00000000 --- a/src/packet/openpgp.packet.js +++ /dev/null @@ -1,407 +0,0 @@ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @class - * @classdesc Parent openpgp packet class. Operations focus on determining - * packet types and packet header. - */ -function _openpgp_packet() { - /** - * Encodes a given integer of length to the openpgp length specifier to a - * string - * - * @param {Integer} length The length to encode - * @return {String} String with openpgp length representation - */ - function encode_length(length) { - result = ""; - if (length < 192) { - result += String.fromCharCode(length); - } else if (length > 191 && length < 8384) { - /* - * let a = (total data packet length) - 192 let bc = two octet - * representation of a let d = b + 192 - */ - result += String.fromCharCode(((length - 192) >> 8) + 192); - result += String.fromCharCode((length - 192) & 0xFF); - } else { - result += String.fromCharCode(255); - result += String.fromCharCode((length >> 24) & 0xFF); - result += String.fromCharCode((length >> 16) & 0xFF); - result += String.fromCharCode((length >> 8) & 0xFF); - result += String.fromCharCode(length & 0xFF); - } - return result; - } - this.encode_length = encode_length; - - /** - * Writes a packet header version 4 with the given tag_type and length to a - * string - * - * @param {Integer} tag_type Tag type - * @param {Integer} length Length of the payload - * @return {String} String of the header - */ - function write_packet_header(tag_type, length) { - /* we're only generating v4 packet headers here */ - var result = ""; - result += String.fromCharCode(0xC0 | tag_type); - result += encode_length(length); - return result; - } - - /** - * Writes a packet header Version 3 with the given tag_type and length to a - * string - * - * @param {Integer} tag_type Tag type - * @param {Integer} length Length of the payload - * @return {String} String of the header - */ - function write_old_packet_header(tag_type, length) { - var result = ""; - if (length < 256) { - result += String.fromCharCode(0x80 | (tag_type << 2)); - result += String.fromCharCode(length); - } else if (length < 65536) { - result += String.fromCharCode(0x80 | (tag_type << 2) | 1); - result += String.fromCharCode(length >> 8); - result += String.fromCharCode(length & 0xFF); - } else { - result += String.fromCharCode(0x80 | (tag_type << 2) | 2); - result += String.fromCharCode((length >> 24) & 0xFF); - result += String.fromCharCode((length >> 16) & 0xFF); - result += String.fromCharCode((length >> 8) & 0xFF); - result += String.fromCharCode(length & 0xFF); - } - return result; - } - this.write_old_packet_header = write_old_packet_header; - this.write_packet_header = write_packet_header; - /** - * Generic static Packet Parser function - * - * @param {String} input Input stream as string - * @param {integer} position Position to start parsing - * @param {integer} len Length of the input from position on - * @return {Object} Returns a parsed openpgp_packet - */ - function read_packet(input, position, len) { - // some sanity checks - if (input == null || input.length <= position - || input.substring(position).length < 2 - || (input.charCodeAt(position) & 0x80) == 0) { - util - .print_error("Error during parsing. This message / key is probably not containing a valid OpenPGP format."); - return null; - } - var mypos = position; - var tag = -1; - var format = -1; - - format = 0; // 0 = old format; 1 = new format - if ((input.charCodeAt(mypos) & 0x40) != 0) { - format = 1; - } - - var packet_length_type; - if (format) { - // new format header - tag = input.charCodeAt(mypos) & 0x3F; // bit 5-0 - } else { - // old format header - tag = (input.charCodeAt(mypos) & 0x3F) >> 2; // bit 5-2 - packet_length_type = input.charCodeAt(mypos) & 0x03; // bit 1-0 - } - - // header octet parsing done - mypos++; - - // parsed length from length field - var bodydata = null; - - // used for partial body lengths - var real_packet_length = -1; - if (!format) { - // 4.2.1. Old Format Packet Lengths - switch (packet_length_type) { - case 0: // The packet has a one-octet length. The header is 2 octets - // long. - packet_length = input.charCodeAt(mypos++); - break; - case 1: // The packet has a two-octet length. The header is 3 octets - // long. - packet_length = (input.charCodeAt(mypos++) << 8) - | input.charCodeAt(mypos++); - break; - case 2: // The packet has a four-octet length. The header is 5 - // octets long. - packet_length = (input.charCodeAt(mypos++) << 24) - | (input.charCodeAt(mypos++) << 16) - | (input.charCodeAt(mypos++) << 8) - | input.charCodeAt(mypos++); - break; - default: - // 3 - The packet is of indeterminate length. The header is 1 - // octet long, and the implementation must determine how long - // the packet is. If the packet is in a file, this means that - // the packet extends until the end of the file. In general, - // an implementation SHOULD NOT use indeterminate-length - // packets except where the end of the data will be clear - // from the context, and even then it is better to use a - // definite length, or a new format header. The new format - // headers described below have a mechanism for precisely - // encoding data of indeterminate length. - packet_length = len; - break; - } - - } else // 4.2.2. New Format Packet Lengths - { - - // 4.2.2.1. One-Octet Lengths - if (input.charCodeAt(mypos) < 192) { - packet_length = input.charCodeAt(mypos++); - util.print_debug("1 byte length:" + packet_length); - // 4.2.2.2. Two-Octet Lengths - } else if (input.charCodeAt(mypos) >= 192 - && input.charCodeAt(mypos) < 224) { - packet_length = ((input.charCodeAt(mypos++) - 192) << 8) - + (input.charCodeAt(mypos++)) + 192; - util.print_debug("2 byte length:" + packet_length); - // 4.2.2.4. Partial Body Lengths - } else if (input.charCodeAt(mypos) > 223 - && input.charCodeAt(mypos) < 255) { - packet_length = 1 << (input.charCodeAt(mypos++) & 0x1F); - util.print_debug("4 byte length:" + packet_length); - // EEEK, we're reading the full data here... - var mypos2 = mypos + packet_length; - bodydata = input.substring(mypos, mypos + packet_length); - while (true) { - if (input.charCodeAt(mypos2) < 192) { - var tmplen = input.charCodeAt(mypos2++); - packet_length += tmplen; - bodydata += input.substring(mypos2, mypos2 + tmplen); - mypos2 += tmplen; - break; - } else if (input.charCodeAt(mypos2) >= 192 - && input.charCodeAt(mypos2) < 224) { - var tmplen = ((input.charCodeAt(mypos2++) - 192) << 8) - + (input.charCodeAt(mypos2++)) + 192; - packet_length += tmplen; - bodydata += input.substring(mypos2, mypos2 + tmplen); - mypos2 += tmplen; - break; - } else if (input.charCodeAt(mypos2) > 223 - && input.charCodeAt(mypos2) < 255) { - var tmplen = 1 << (input.charCodeAt(mypos2++) & 0x1F); - packet_length += tmplen; - bodydata += input.substring(mypos2, mypos2 + tmplen); - mypos2 += tmplen; - } else { - mypos2++; - var tmplen = (input.charCodeAt(mypos2++) << 24) - | (input.charCodeAt(mypos2++) << 16) - | (input.charCodeAt(mypos2++) << 8) - | input.charCodeAt(mypos2++); - bodydata += input.substring(mypos2, mypos2 + tmplen); - packet_length += tmplen; - mypos2 += tmplen; - break; - } - } - real_packet_length = mypos2; - // 4.2.2.3. Five-Octet Lengths - } else { - mypos++; - packet_length = (input.charCodeAt(mypos++) << 24) - | (input.charCodeAt(mypos++) << 16) - | (input.charCodeAt(mypos++) << 8) - | input.charCodeAt(mypos++); - } - } - - // if there was'nt a partial body length: use the specified - // packet_length - if (real_packet_length == -1) { - real_packet_length = packet_length; - } - - if (bodydata == null) { - bodydata = input.substring(mypos, mypos + real_packet_length); - } - - // alert('tag type: '+this.tag+' length: '+packet_length); - var version = 1; // (old format; 2= new format) - // if (input.charCodeAt(mypos++) > 15) - // version = 2; - - switch (tag) { - case 0: // Reserved - a packet tag MUST NOT have this value - break; - case 1: // Public-Key Encrypted Session Key Packet - var result = new openpgp_packet_encryptedsessionkey(); - if (result.read_pub_key_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 2: // Signature Packet - var result = new openpgp_packet_signature(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 3: // Symmetric-Key Encrypted Session Key Packet - var result = new openpgp_packet_encryptedsessionkey(); - if (result.read_symmetric_key_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 4: // One-Pass Signature Packet - var result = new openpgp_packet_onepasssignature(); - if (result.read_packet(bodydata, 0, packet_length)) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 5: // Secret-Key Packet - var result = new openpgp_packet_keymaterial(); - result.header = input.substring(position, mypos); - if (result.read_tag5(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 6: // Public-Key Packet - var result = new openpgp_packet_keymaterial(); - result.header = input.substring(position, mypos); - if (result.read_tag6(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 7: // Secret-Subkey Packet - var result = new openpgp_packet_keymaterial(); - if (result.read_tag7(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 8: // Compressed Data Packet - var result = new openpgp_packet_compressed(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 9: // Symmetrically Encrypted Data Packet - var result = new openpgp_packet_encrypteddata(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 10: // Marker Packet = PGP (0x50, 0x47, 0x50) - var result = new openpgp_packet_marker(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 11: // Literal Data Packet - var result = new openpgp_packet_literaldata(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.header = input.substring(position, mypos); - result.packetLength = real_packet_length; - return result; - } - break; - case 12: // Trust Packet - // TODO: to be implemented - break; - case 13: // User ID Packet - var result = new openpgp_packet_userid(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 14: // Public-Subkey Packet - var result = new openpgp_packet_keymaterial(); - result.header = input.substring(position, mypos); - if (result.read_tag14(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 17: // User Attribute Packet - var result = new openpgp_packet_userattribute(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 18: // Sym. Encrypted and Integrity Protected Data Packet - var result = new openpgp_packet_encryptedintegrityprotecteddata(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 19: // Modification Detection Code Packet - var result = new openpgp_packet_modificationdetectioncode(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - default: - util.print_error("openpgp.packet.js\n" - + "[ERROR] openpgp_packet: failed to parse packet @:" - + mypos + "\nchar:'" - + util.hexstrdump(input.substring(mypos)) + "'\ninput:" - + util.hexstrdump(input)); - return null; - break; - } - } - - this.read_packet = read_packet; -} - -var openpgp_packet = new _openpgp_packet(); diff --git a/src/packet/openpgp.packet.keymaterial.js b/src/packet/openpgp.packet.keymaterial.js deleted file mode 100644 index 6c50c6ee..00000000 --- a/src/packet/openpgp.packet.keymaterial.js +++ /dev/null @@ -1,819 +0,0 @@ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @class - * @classdesc Implementation of the Key Material Packet (Tag 5,6,7,14) - * - * RFC4480 5.5: - * A key material packet contains all the information about a public or - * private key. There are four variants of this packet type, and two - * major versions. Consequently, this section is complex. - */ -function openpgp_packet_keymaterial() { - // members: - this.publicKeyAlgorithm = null; - this.tagType = null; - this.creationTime = null; - this.version = null; - this.expiration = null;// V3 - this.MPIs = null; - this.secMPIs = null; - this.publicKey = null; - this.symmetricEncryptionAlgorithm = null; - this.s2kUsageConventions = null; - this.IVLength = null; - this.encryptedMPIData = null; - this.hasUnencryptedSecretKeyData = null; - this.checksum = null; - this.parentNode = null; - this.subKeySignature = null; - this.subKeyRevocationSignature = null; - - // 5.5.1. Key Packet Variants - - // 5.5.1.3. Secret-Key Packet (Tag 5) - /** - * This function reads the payload of a secret key packet (Tag 5) - * and initializes the openpgp_packet_keymaterial - * @param {String} input Input string to read the packet from - * @param {Integer} position Start position for the parser - * @param {Intefer} len Length of the packet or remaining length of input - * @return {openpgp_packet_keymaterial} - */ - function read_tag5(input, position, len) { - this.tagType = 5; - this.read_priv_key(input, position, len); - return this; - } - - // 5.5.1.1. Public-Key Packet (Tag 6) - /** - * This function reads the payload of a public key packet (Tag 6) - * and initializes the openpgp_packet_keymaterial - * @param {String} input Input string to read the packet from - * @param {Integer} position Start position for the parser - * @param {Integer} len Length of the packet or remaining length of input - * @return {openpgp_packet_keymaterial} - */ - function read_tag6(input, position, len) { - // A Public-Key packet starts a series of packets that forms an OpenPGP - // key (sometimes called an OpenPGP certificate). - this.tagType = 6; - this.packetLength = len; - this.read_pub_key(input, position,len); - - return this; - } - - // 5.5.1.4. Secret-Subkey Packet (Tag 7) - /** - * This function reads the payload of a secret key sub packet (Tag 7) - * and initializes the openpgp_packet_keymaterial - * @param {String} input Input string to read the packet from - * @param {Integer} position Start position for the parser - * @param {Integer} len Length of the packet or remaining length of input - * @return {openpgp_packet_keymaterial} - */ - function read_tag7(input, position, len) { - this.tagType = 7; - this.packetLength = len; - return this.read_priv_key(input, position, len); - } - - // 5.5.1.2. Public-Subkey Packet (Tag 14) - /** - * This function reads the payload of a public key sub packet (Tag 14) - * and initializes the openpgp_packet_keymaterial - * @param {String} input Input string to read the packet from - * @param {Integer} position Start position for the parser - * @param {Integer} len Length of the packet or remaining length of input - * @return {openpgp_packet_keymaterial} - */ - function read_tag14(input, position, len) { - this.subKeySignature = null; - this.subKeyRevocationSignature = new Array(); - this.tagType = 14; - this.packetLength = len; - this.read_pub_key(input, position,len); - return this; - } - - /** - * Internal Parser for public keys as specified in RFC 4880 section - * 5.5.2 Public-Key Packet Formats - * called by read_tag<num> - * @param {String} input Input string to read the packet from - * @param {Integer} position Start position for the parser - * @param {Integer} len Length of the packet or remaining length of input - * @return {Object} This object with attributes set by the parser - */ - function read_pub_key(input, position, len) { - var mypos = position; - // A one-octet version number (3 or 4). - this.version = input.charCodeAt(mypos++); - if (this.version == 3) { - // A four-octet number denoting the time that the key was created. - this.creationTime = new Date(((input.charCodeAt(mypos++) << 24) | - (input.charCodeAt(mypos++) << 16) | - (input.charCodeAt(mypos++) << 8) | - (input.charCodeAt(mypos++)))*1000); - - // - A two-octet number denoting the time in days that this key is - // valid. If this number is zero, then it does not expire. - this.expiration = (input.charCodeAt(mypos++) << 8) | input.charCodeAt(mypos++); - - // - A one-octet number denoting the public-key algorithm of this key. - this.publicKeyAlgorithm = input.charCodeAt(mypos++); - var mpicount = 0; - // - A series of multiprecision integers comprising the key material: - // Algorithm-Specific Fields for RSA public keys: - // - a multiprecision integer (MPI) of RSA public modulus n; - // - an MPI of RSA public encryption exponent e. - if (this.publicKeyAlgorithm > 0 && this.publicKeyAlgorithm < 4) - mpicount = 2; - // Algorithm-Specific Fields for Elgamal public keys: - // - MPI of Elgamal prime p; - // - MPI of Elgamal group generator g; - // - MPI of Elgamal public key value y (= g**x mod p where x is secret). - - else if (this.publicKeyAlgorithm == 16) - mpicount = 3; - // Algorithm-Specific Fields for DSA public keys: - // - MPI of DSA prime p; - // - MPI of DSA group order q (q is a prime divisor of p-1); - // - MPI of DSA group generator g; - // - MPI of DSA public-key value y (= g**x mod p where x is secret). - else if (this.publicKeyAlgorithm == 17) - mpicount = 4; - - this.MPIs = new Array(); - for (var i = 0; i < mpicount; i++) { - this.MPIs[i] = new openpgp_type_mpi(); - if (this.MPIs[i].read(input, mypos, (mypos-position)) != null && - !this.packetLength < (mypos-position)) { - mypos += this.MPIs[i].packetLength; - } else { - util.print_error("openpgp.packet.keymaterial.js\n"+'error reading MPI @:'+mypos); - } - } - this.packetLength = mypos-position; - } else if (this.version == 4) { - // - A four-octet number denoting the time that the key was created. - this.creationTime = new Date(((input.charCodeAt(mypos++) << 24) | - (input.charCodeAt(mypos++) << 16) | - (input.charCodeAt(mypos++) << 8) | - (input.charCodeAt(mypos++)))*1000); - - // - A one-octet number denoting the public-key algorithm of this key. - this.publicKeyAlgorithm = input.charCodeAt(mypos++); - var mpicount = 0; - // - A series of multiprecision integers comprising the key material: - // Algorithm-Specific Fields for RSA public keys: - // - a multiprecision integer (MPI) of RSA public modulus n; - // - an MPI of RSA public encryption exponent e. - if (this.publicKeyAlgorithm > 0 && this.publicKeyAlgorithm < 4) - mpicount = 2; - // Algorithm-Specific Fields for Elgamal public keys: - // - MPI of Elgamal prime p; - // - MPI of Elgamal group generator g; - // - MPI of Elgamal public key value y (= g**x mod p where x is secret). - else if (this.publicKeyAlgorithm == 16) - mpicount = 3; - - // Algorithm-Specific Fields for DSA public keys: - // - MPI of DSA prime p; - // - MPI of DSA group order q (q is a prime divisor of p-1); - // - MPI of DSA group generator g; - // - MPI of DSA public-key value y (= g**x mod p where x is secret). - else if (this.publicKeyAlgorithm == 17) - mpicount = 4; - - this.MPIs = new Array(); - var i = 0; - for (var i = 0; i < mpicount; i++) { - this.MPIs[i] = new openpgp_type_mpi(); - if (this.MPIs[i].read(input, mypos, (mypos-position)) != null && - !this.packetLength < (mypos-position)) { - mypos += this.MPIs[i].packetLength; - } else { - util.print_error("openpgp.packet.keymaterial.js\n"+'error reading MPI @:'+mypos); - } - } - this.packetLength = mypos-position; - } else { - return null; - } - this.data = input.substring(position, mypos); - this.packetdata = input.substring(position, mypos); - return this; - } - - // 5.5.3. Secret-Key Packet Formats - - /** - * Internal parser for private keys as specified in RFC 4880 section 5.5.3 - * @param {String} input Input string to read the packet from - * @param {Integer} position Start position for the parser - * @param {Integer} len Length of the packet or remaining length of input - * @return {Object} This object with attributes set by the parser - */ - function read_priv_key(input,position, len) { - // - A Public-Key or Public-Subkey packet, as described above. - this.publicKey = new openpgp_packet_keymaterial(); - if (this.publicKey.read_pub_key(input,position, len) == null) { - util.print_error("openpgp.packet.keymaterial.js\n"+"Failed reading public key portion of a private key: "+input.charCodeAt(position)+" "+position+" "+len+"\n Aborting here..."); - return null; - } - this.publicKey.header = openpgp_packet.write_old_packet_header(6,this.publicKey.packetLength); - // this.publicKey.header = String.fromCharCode(0x99) + String.fromCharCode(this.publicKey.packetLength >> 8 & 0xFF)+String.fromCharCode(this.publicKey.packetLength & 0xFF); - var mypos = position + this.publicKey.data.length; - this.packetLength = len; - - // - One octet indicating string-to-key usage conventions. Zero - // indicates that the secret-key data is not encrypted. 255 or 254 - // indicates that a string-to-key specifier is being given. Any - // other value is a symmetric-key encryption algorithm identifier. - this.s2kUsageConventions = input.charCodeAt(mypos++); - - if (this.s2kUsageConventions == 0) - this.hasUnencryptedSecretKeyData = true; - - // - [Optional] If string-to-key usage octet was 255 or 254, a one- - // octet symmetric encryption algorithm. - if (this.s2kUsageConventions == 255 || this.s2kUsageConventions == 254) { - this.symmetricEncryptionAlgorithm = input.charCodeAt(mypos++); - } - - // - [Optional] If string-to-key usage octet was 255 or 254, a - // string-to-key specifier. The length of the string-to-key - // specifier is implied by its type, as described above. - if (this.s2kUsageConventions == 255 || this.s2kUsageConventions == 254) { - this.s2k = new openpgp_type_s2k(); - this.s2k.read(input, mypos); - mypos +=this.s2k.s2kLength; - } - - // - [Optional] If secret data is encrypted (string-to-key usage octet - // not zero), an Initial Vector (IV) of the same length as the - // cipher's block size. - this.symkeylength = 0; - if (this.s2kUsageConventions != 0 && this.s2kUsageConventions != 255 && - this.s2kUsageConventions != 254) { - this.symmetricEncryptionAlgorithm = this.s2kUsageConventions; - } - if (this.s2kUsageConventions != 0 && this.s2k.type != 1001) { - this.hasIV = true; - switch (this.symmetricEncryptionAlgorithm) { - case 1: // - IDEA [IDEA] - util.print_error("openpgp.packet.keymaterial.js\n"+"symmetric encrytryption algorithim: IDEA is not implemented"); - return null; - case 2: // - TripleDES (DES-EDE, [SCHNEIER] [HAC] - 168 bit key derived from 192) - case 3: // - CAST5 (128 bit key, as per [RFC2144]) - this.IVLength = 8; - break; - case 4: // - Blowfish (128 bit key, 16 rounds) [BLOWFISH] - case 7: // - AES with 128-bit key [AES] - case 8: // - AES with 192-bit key - case 9: // - AES with 256-bit key - this.IVLength = 16; - break; - case 10: // - Twofish with 256-bit key [TWOFISH] - this.IVLength = 32; - break; - case 5: // - Reserved - case 6: // - Reserved - default: - util.print_error("openpgp.packet.keymaterial.js\n"+"unknown encryption algorithm for secret key :"+this.symmetricEncryptionAlgorithm); - return null; - } - mypos++; - this.IV = input.substring(mypos, mypos+this.IVLength); - mypos += this.IVLength; - } - // - Plain or encrypted multiprecision integers comprising the secret - // key data. These algorithm-specific fields are as described - // below. - - // s2k type 1001 corresponds to GPG specific extension without primary key secrets - // http://www.gnupg.org/faq/GnuPG-FAQ.html#how-can-i-use-gnupg-in-an-automated-environment - if (this.s2kUsageConventions != 0 && this.s2k.type == 1001) { - this.secMPIs = null; - this.encryptedMPIData = null; - } else if (!this.hasUnencryptedSecretKeyData) { - this.encryptedMPIData = input.substring(mypos, len); - mypos += this.encryptedMPIData.length; - } else { - if (this.publicKey.publicKeyAlgorithm > 0 && this.publicKey.publicKeyAlgorithm < 4) { - // Algorithm-Specific Fields for RSA secret keys: - // - multiprecision integer (MPI) of RSA secret exponent d. - // - MPI of RSA secret prime value p. - // - MPI of RSA secret prime value q (p < q). - // - MPI of u, the multiplicative inverse of p, mod q. - this.secMPIs = new Array(); - this.secMPIs[0] = new openpgp_type_mpi(); - this.secMPIs[0].read(input, mypos, len-2- (mypos - position)); - mypos += this.secMPIs[0].packetLength; - this.secMPIs[1] = new openpgp_type_mpi(); - this.secMPIs[1].read(input, mypos, len-2- (mypos - position)); - mypos += this.secMPIs[1].packetLength; - this.secMPIs[2] = new openpgp_type_mpi(); - this.secMPIs[2].read(input, mypos, len-2- (mypos - position)); - mypos += this.secMPIs[2].packetLength; - this.secMPIs[3] = new openpgp_type_mpi(); - this.secMPIs[3].read(input, mypos, len-2- (mypos - position)); - mypos += this.secMPIs[3].packetLength; - } else if (this.publicKey.publicKeyAlgorithm == 16) { - // Algorithm-Specific Fields for Elgamal secret keys: - // - MPI of Elgamal secret exponent x. - this.secMPIs = new Array(); - this.secMPIs[0] = new openpgp_type_mpi(); - this.secMPIs[0].read(input, mypos, len-2- (mypos - position)); - mypos += this.secMPIs[0].packetLength; - } else if (this.publicKey.publicKeyAlgorithm == 17) { - // Algorithm-Specific Fields for DSA secret keys: - // - MPI of DSA secret exponent x. - this.secMPIs = new Array(); - this.secMPIs[0] = new openpgp_type_mpi(); - this.secMPIs[0].read(input, mypos, len-2- (mypos - position)); - mypos += this.secMPIs[0].packetLength; - } - // checksum because s2k usage convention is 0 - this.checksum = new Array(); - this.checksum[0] = input.charCodeAt(mypos++); - this.checksum[1] = input.charCodeAt(mypos++); - } - return this; - } - - - /** - * Decrypts the private key MPIs which are needed to use the key. - * openpgp_packet_keymaterial.hasUnencryptedSecretKeyData should be - * false otherwise - * a call to this function is not needed - * - * @param {String} str_passphrase The passphrase for this private key - * as string - * @return {Boolean} True if the passphrase was correct; false if not - */ - function decryptSecretMPIs(str_passphrase) { - if (this.hasUnencryptedSecretKeyData) - return this.secMPIs; - // creating a key out of the passphrase - var key = this.s2k.produce_key(str_passphrase); - var cleartextMPIs = ""; - switch (this.symmetricEncryptionAlgorithm) { - case 1: // - IDEA [IDEA] - util.print_error("openpgp.packet.keymaterial.js\n"+"symmetric encryption algorithim: IDEA is not implemented"); - return false; - case 2: // - TripleDES (DES-EDE, [SCHNEIER] [HAC] - 168 bit key derived from 192) - cleartextMPIs = normal_cfb_decrypt(function(block, key) { - return des(key, block,1,null,0); - }, this.IVLength, key, this.encryptedMPIData, this.IV); - break; - case 3: // - CAST5 (128 bit key, as per [RFC2144]) - cleartextMPIs = normal_cfb_decrypt(function(block, key) { - var cast5 = new openpgp_symenc_cast5(); - cast5.setKey(key); - return cast5.encrypt(util.str2bin(block)); - }, this.IVLength, util.str2bin(key.substring(0,16)), this.encryptedMPIData, this.IV); - break; - case 4: // - Blowfish (128 bit key, 16 rounds) [BLOWFISH] - cleartextMPIs = normal_cfb_decrypt(function(block, key) { - var blowfish = new Blowfish(key); - return blowfish.encrypt(block); - }, this.IVLength, key, this.encryptedMPIData, this.IV); - break; - case 7: // - AES with 128-bit key [AES] - case 8: // - AES with 192-bit key - case 9: // - AES with 256-bit key - var numBytes = 16; - //This is a weird way to achieve this. If's within a switch is probably not ideal. - if(this.symmetricEncryptionAlgorithm == 8){ - numBytes = 24; - key = this.s2k.produce_key(str_passphrase,numBytes); - } - if(this.symmetricEncryptionAlgorithm == 9){ - numBytes = 32; - key = this.s2k.produce_key(str_passphrase,numBytes); - } - cleartextMPIs = normal_cfb_decrypt(function(block,key){ - return AESencrypt(util.str2bin(block),key); - }, - this.IVLength, keyExpansion(key.substring(0,numBytes)), this.encryptedMPIData, this.IV); - break; - case 10: // - Twofish with 256-bit key [TWOFISH] - util.print_error("openpgp.packet.keymaterial.js\n"+"Key material is encrypted with twofish: not implemented"); - return false; - case 5: // - Reserved - case 6: // - Reserved - default: - util.print_error("openpgp.packet.keymaterial.js\n"+"unknown encryption algorithm for secret key :"+this.symmetricEncryptionAlgorithm); - return false; - } - - if (cleartextMPIs == null) { - util.print_error("openpgp.packet.keymaterial.js\n"+"cleartextMPIs was null"); - return false; - } - - var cleartextMPIslength = cleartextMPIs.length; - - if (this.s2kUsageConventions == 254 && - str_sha1(cleartextMPIs.substring(0,cleartextMPIs.length - 20)) == - cleartextMPIs.substring(cleartextMPIs.length - 20)) { - cleartextMPIslength -= 20; - } else if (this.s2kUsageConventions != 254 && util.calc_checksum(cleartextMPIs.substring(0,cleartextMPIs.length - 2)) == - (cleartextMPIs.charCodeAt(cleartextMPIs.length -2) << 8 | cleartextMPIs.charCodeAt(cleartextMPIs.length -1))) { - cleartextMPIslength -= 2; - } else { - return false; - } - - if (this.publicKey.publicKeyAlgorithm > 0 && this.publicKey.publicKeyAlgorithm < 4) { - // Algorithm-Specific Fields for RSA secret keys: - // - multiprecision integer (MPI) of RSA secret exponent d. - // - MPI of RSA secret prime value p. - // - MPI of RSA secret prime value q (p < q). - // - MPI of u, the multiplicative inverse of p, mod q. - var mypos = 0; - this.secMPIs = new Array(); - this.secMPIs[0] = new openpgp_type_mpi(); - this.secMPIs[0].read(cleartextMPIs, 0, cleartextMPIslength); - mypos += this.secMPIs[0].packetLength; - this.secMPIs[1] = new openpgp_type_mpi(); - this.secMPIs[1].read(cleartextMPIs, mypos, cleartextMPIslength-mypos); - mypos += this.secMPIs[1].packetLength; - this.secMPIs[2] = new openpgp_type_mpi(); - this.secMPIs[2].read(cleartextMPIs, mypos, cleartextMPIslength-mypos); - mypos += this.secMPIs[2].packetLength; - this.secMPIs[3] = new openpgp_type_mpi(); - this.secMPIs[3].read(cleartextMPIs, mypos, cleartextMPIslength-mypos); - mypos += this.secMPIs[3].packetLength; - } else if (this.publicKey.publicKeyAlgorithm == 16) { - // Algorithm-Specific Fields for Elgamal secret keys: - // - MPI of Elgamal secret exponent x. - this.secMPIs = new Array(); - this.secMPIs[0] = new openpgp_type_mpi(); - this.secMPIs[0].read(cleartextMPIs, 0, cleartextMPIs); - } else if (this.publicKey.publicKeyAlgorithm == 17) { - // Algorithm-Specific Fields for DSA secret keys: - // - MPI of DSA secret exponent x. - this.secMPIs = new Array(); - this.secMPIs[0] = new openpgp_type_mpi(); - this.secMPIs[0].read(cleartextMPIs, 0, cleartextMPIslength); - } - return true; - } - - /** - * Generates Debug output - * @return String which gives some information about the keymaterial - */ - function toString() { - var result = ""; - switch (this.tagType) { - case 6: - result += '5.5.1.1. Public-Key Packet (Tag 6)\n'+ - ' length: '+this.packetLength+'\n'+ - ' version: '+this.version+'\n'+ - ' creation time: '+this.creationTime+'\n'+ - ' expiration time: '+this.expiration+'\n'+ - ' publicKeyAlgorithm: '+this.publicKeyAlgorithm+'\n'; - break; - case 14: - result += '5.5.1.2. Public-Subkey Packet (Tag 14)\n'+ - ' length: '+this.packetLength+'\n'+ - ' version: '+this.version+'\n'+ - ' creation time: '+this.creationTime+'\n'+ - ' expiration time: '+this.expiration+'\n'+ - ' publicKeyAlgorithm: '+this.publicKeyAlgorithm+'\n'; - break; - case 5: - result +='5.5.1.3. Secret-Key Packet (Tag 5)\n'+ - ' length: '+this.packetLength+'\n'+ - ' version: '+this.publicKey.version+'\n'+ - ' creation time: '+this.publicKey.creationTime+'\n'+ - ' expiration time: '+this.publicKey.expiration+'\n'+ - ' publicKeyAlgorithm: '+this.publicKey.publicKeyAlgorithm+'\n'; - break; - case 7: - result += '5.5.1.4. Secret-Subkey Packet (Tag 7)\n'+ - ' length: '+this.packetLength+'\n'+ - ' version[1]: '+(this.version == 4)+'\n'+ - ' creationtime[4]: '+this.creationTime+'\n'+ - ' expiration[2]: '+this.expiration+'\n'+ - ' publicKeyAlgorithm: '+this.publicKeyAlgorithm+'\n'; - break; - default: - result += 'unknown key material packet\n'; - } - if (this.MPIs != null) { - result += "Public Key MPIs:\n"; - for (var i = 0; i < this.MPIs.length; i++) { - result += this.MPIs[i].toString(); - } - } - if (this.publicKey != null && this.publicKey.MPIs != null) { - result += "Public Key MPIs:\n"; - for (var i = 0; i < this.publicKey.MPIs.length; i++) { - result += this.publicKey.MPIs[i].toString(); - } - } - if (this.secMPIs != null) { - result += "Secret Key MPIs:\n"; - for (var i = 0; i < this.secMPIs.length; i++) { - result += this.secMPIs[i].toString(); - } - } - - if (this.subKeySignature != null) - result += "subKey Signature:\n"+this.subKeySignature.toString(); - - if (this.subKeyRevocationSignature != null ) - result += "subKey Revocation Signature:\n"+this.subKeyRevocationSignature.toString(); - return result; - } - - /** - * Continue parsing packets belonging to the key material such as signatures - * @param {Object} parent_node The parent object - * @param {String} input Input string to read the packet(s) from - * @param {Integer} position Start position for the parser - * @param {Integer} len Length of the packet(s) or remaining length of input - * @return {Integer} Length of nodes read - */ - function read_nodes(parent_node, input, position, len) { - this.parentNode = parent_node; - if (this.tagType == 14) { // public sub-key packet - var pos = position; - var result = null; - while (input.length != pos) { - var l = input.length - pos; - result = openpgp_packet.read_packet(input, pos, l); - if (result == null) { - util.print_error("openpgp.packet.keymaterial.js\n"+'[user_keymat_pub]parsing ends here @:' + pos + " l:" + l); - break; - } else { - - switch (result.tagType) { - case 2: // Signature Packet certification signature - if (result.signatureType == 24) { // subkey binding signature - this.subKeySignature = result; - pos += result.packetLength + result.headerLength; - break; - } else if (result.signatureType == 40) { // subkey revocation signature - this.subKeyRevocationSignature[this.subKeyRevocationSignature.length] = result; - pos += result.packetLength + result.headerLength; - break; - } else { - util.print_error("openpgp.packet.keymaterial.js\nunknown signature:"+result.toString()); - } - - default: - this.data = input; - this.position = position - this.parentNode.packetLength; - this.len = pos - position; - return this.len; - break; - } - } - } - this.data = input; - this.position = position - this.parentNode.packetLength; - this.len = pos - position; - return this.len; - } else if (this.tagType == 7) { // private sub-key packet - var pos = position; - while (input.length != pos) { - var result = openpgp_packet.read_packet(input, pos, len - (pos - position)); - if (result == null) { - util.print_error("openpgp.packet.keymaterial.js\n"+'[user_keymat_priv] parsing ends here @:' + pos); - break; - } else { - switch (result.tagType) { - case 2: // Signature Packet certification signature - if (result.signatureType == 24) // subkey embedded signature - this.subKeySignature = result; - else if (result.signatureType == 40) // subkey revocation signature - this.subKeyRevocationSignature[this.subKeyRevocationSignature.length] = result; - pos += result.packetLength + result.headerLength; - break; - default: - this.data = input; - this.position = position - this.parentNode.packetLength; - this.len = pos - position; - return this.len; - } - } - } - this.data = input; - this.position = position - this.parentNode.packetLength; - this.len = pos - position; - return this.len; - } else { - util.print_error("openpgp.packet.keymaterial.js\n"+"unknown parent node for a key material packet "+parent_node.tagType); - } - } - - /** - * Checks the validity for usage of this (sub)key - * @return {Integer} 0 = bad key, 1 = expired, 2 = revoked, 3 = valid - */ - function verifyKey() { - if (this.tagType == 14) { - if (this.subKeySignature == null) { - return 0; - } - if (this.subKeySignature.version == 4 && - this.subKeySignature.keyNeverExpires != null && - !this.subKeySignature.keyNeverExpires && - new Date((this.subKeySignature.keyExpirationTime*1000)+ this.creationTime.getTime()) < new Date()) { - return 1; - } - var hashdata = String.fromCharCode(0x99)+this.parentNode.header.substring(1)+this.parentNode.data+ - String.fromCharCode(0x99)+this.header.substring(1)+this.packetdata; - if (!this.subKeySignature.verify(hashdata,this.parentNode)) { - return 0; - } - for (var i = 0; i < this.subKeyRevocationSignature.length; i++) { - if (this.getKeyId() == this.subKeyRevocationSignature[i].keyId){ - return 2; - } - } - } - return 3; - } - - /** - * Calculates the key id of they key - * @return {String} A 8 byte key id - */ - function getKeyId() { - if (this.version == 4) { - var f = this.getFingerprint(); - return f.substring(12,20); - } else if (this.version == 3 && this.publicKeyAlgorithm > 0 && this.publicKeyAlgorithm < 4) { - var key_id = this.MPIs[0].MPI.substring((this.MPIs[0].mpiByteLength-8)); - util.print_debug("openpgp.msg.publickey read_nodes:\n"+"V3 key ID: "+key_id); - return key_id; - } - } - - /** - * Calculates the fingerprint of the key - * @return {String} A string containing the fingerprint - */ - function getFingerprint() { - if (this.version == 4) { - tohash = String.fromCharCode(0x99)+ String.fromCharCode(((this.packetdata.length) >> 8) & 0xFF) - + String.fromCharCode((this.packetdata.length) & 0xFF)+this.packetdata; - util.print_debug("openpgp.msg.publickey creating subkey fingerprint by hashing:"+util.hexstrdump(tohash)+"\npublickeyalgorithm: "+this.publicKeyAlgorithm); - return str_sha1(tohash, tohash.length); - } else if (this.version == 3 && this.publicKeyAlgorithm > 0 && this.publicKeyAlgorithm < 4) { - return MD5(this.MPIs[0].MPI); - } - } - - /* - * Creates an OpenPGP key packet for the given key. much - * TODO in regards to s2k, subkeys. - * @param {Integer} keyType Follows the OpenPGP algorithm standard, - * IE 1 corresponds to RSA. - * @param {RSA.keyObject} key - * @param password - * @param s2kHash - * @param symmetricEncryptionAlgorithm - * @param timePacket - * @return {Object} {body: [string]OpenPGP packet body contents, - header: [string] OpenPGP packet header, string: [string] header+body} - */ - function write_private_key(keyType, key, password, s2kHash, symmetricEncryptionAlgorithm, timePacket){ - this.symmetricEncryptionAlgorithm = symmetricEncryptionAlgorithm; - var tag = 5; - var body = String.fromCharCode(4); - body += timePacket; - switch(keyType){ - case 1: - body += String.fromCharCode(keyType);//public key algo - body += key.n.toMPI(); - body += key.ee.toMPI(); - var algorithmStart = body.length; - //below shows ske/s2k - if(password){ - body += String.fromCharCode(254); //octet of 254 indicates s2k with SHA1 - //if s2k == 255,254 then 1 octet symmetric encryption algo - body += String.fromCharCode(this.symmetricEncryptionAlgorithm); - //if s2k == 255,254 then s2k specifier - body += String.fromCharCode(3); //s2k salt+iter - body += String.fromCharCode(s2kHash); - //8 octet salt value - //1 octet count - var cleartextMPIs = key.d.toMPI() + key.p.toMPI() + key.q.toMPI() + key.u.toMPI(); - var sha1Hash = str_sha1(cleartextMPIs); - util.print_debug_hexstr_dump('write_private_key sha1: ',sha1Hash); - var salt = openpgp_crypto_getRandomBytes(8); - util.print_debug_hexstr_dump('write_private_key Salt: ',salt); - body += salt; - var c = 96; //c of 96 translates to count of 65536 - body += String.fromCharCode(c); - util.print_debug('write_private_key c: '+ c); - var s2k = new openpgp_type_s2k(); - var hashKey = s2k.write(3, s2kHash, password, salt, c); - //if s2k, IV of same length as cipher's block - switch(this.symmetricEncryptionAlgorithm){ - case 3: - this.IVLength = 8; - this.IV = openpgp_crypto_getRandomBytes(this.IVLength); - ciphertextMPIs = normal_cfb_encrypt(function(block, key) { - var cast5 = new openpgp_symenc_cast5(); - cast5.setKey(key); - return cast5.encrypt(util.str2bin(block)); - }, this.IVLength, util.str2bin(hashKey.substring(0,16)), cleartextMPIs + sha1Hash, this.IV); - body += this.IV + ciphertextMPIs; - break; - case 7: - case 8: - case 9: - this.IVLength = 16; - this.IV = openpgp_crypto_getRandomBytes(this.IVLength); - ciphertextMPIs = normal_cfb_encrypt(AESencrypt, - this.IVLength, hashKey, cleartextMPIs + sha1Hash, this.IV); - body += this.IV + ciphertextMPIs; - break; - } - } - else{ - body += String.fromCharCode(0);//1 octet -- s2k, 0 for no s2k - body += key.d.toMPI() + key.p.toMPI() + key.q.toMPI() + key.u.toMPI(); - var checksum = util.calc_checksum(key.d.toMPI() + key.p.toMPI() + key.q.toMPI() + key.u.toMPI()); - body += String.fromCharCode(checksum/0x100) + String.fromCharCode(checksum%0x100);//DEPRECATED:s2k == 0, 255: 2 octet checksum, sum all octets%65536 - util.print_debug_hexstr_dump('write_private_key basic checksum: '+ checksum); - } - break; - default : - body = ""; - util.print_error("openpgp.packet.keymaterial.js\n"+'error writing private key, unknown type :'+keyType); - } - var header = openpgp_packet.write_packet_header(tag,body.length); - return {string: header+body , header: header, body: body}; - } - - /* - * Same as write_private_key, but has less information because of - * public key. - * @param {Integer} keyType Follows the OpenPGP algorithm standard, - * IE 1 corresponds to RSA. - * @param {RSA.keyObject} key - * @param timePacket - * @return {Object} {body: [string]OpenPGP packet body contents, - * header: [string] OpenPGP packet header, string: [string] header+body} - */ - function write_public_key(keyType, key, timePacket){ - var tag = 6; - var body = String.fromCharCode(4); - body += timePacket; - switch(keyType){ - case 1: - body += String.fromCharCode(1);//public key algo - body += key.n.toMPI(); - body += key.ee.toMPI(); - break; - default: - util.print_error("openpgp.packet.keymaterial.js\n"+'error writing private key, unknown type :'+keyType); - } - var header = openpgp_packet.write_packet_header(tag,body.length); - return {string: header+body , header: header, body: body}; - } - - - this.read_tag5 = read_tag5; - this.read_tag6 = read_tag6; - this.read_tag7 = read_tag7; - this.read_tag14 = read_tag14; - this.toString = toString; - this.read_pub_key = read_pub_key; - this.read_priv_key = read_priv_key; - this.decryptSecretMPIs = decryptSecretMPIs; - this.read_nodes = read_nodes; - this.verifyKey = verifyKey; - this.getKeyId = getKeyId; - this.getFingerprint = getFingerprint; - this.write_private_key = write_private_key; - this.write_public_key = write_public_key; -} diff --git a/src/packet/openpgp.packet.marker.js b/src/packet/openpgp.packet.marker.js deleted file mode 100644 index a9d6bf87..00000000 --- a/src/packet/openpgp.packet.marker.js +++ /dev/null @@ -1,65 +0,0 @@ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @class - * @classdesc Implementation of the strange "Marker packet" (Tag 10) - * - * RFC4880 5.8: An experimental version of PGP used this packet as the Literal - * packet, but no released version of PGP generated Literal packets with this - * tag. With PGP 5.x, this packet has been reassigned and is reserved for use as - * the Marker packet. - * - * Such a packet MUST be ignored when received. - */ -function openpgp_packet_marker() { - this.tagType = 10; - /** - * Parsing function for a literal data packet (tag 10). - * - * @param {String} input Payload of a tag 10 packet - * @param {Integer} position - * Position to start reading from the input string - * @param {Integer} len - * Length of the packet or the remaining length of - * input at position - * @return {openpgp_packet_encrypteddata} Object representation - */ - function read_packet(input, position, len) { - this.packetLength = 3; - if (input.charCodeAt(position) == 0x50 && // P - input.charCodeAt(position + 1) == 0x47 && // G - input.charCodeAt(position + 2) == 0x50) // P - return this; - // marker packet does not contain "PGP" - return null; - } - - /** - * Generates Debug output - * - * @return {String} String which gives some information about the - * keymaterial - */ - function toString() { - return "5.8. Marker Packet (Obsolete Literal Packet) (Tag 10)\n" - + " packet reads: \"PGP\"\n"; - } - - this.read_packet = read_packet; - this.toString = toString; -} diff --git a/src/packet/openpgp.packet.signature.js b/src/packet/openpgp.packet.signature.js deleted file mode 100644 index 8a43ae10..00000000 --- a/src/packet/openpgp.packet.signature.js +++ /dev/null @@ -1,744 +0,0 @@ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @class - * @classdesc Implementation of the Signature Packet (Tag 2) - * - * RFC4480 5.2: - * A Signature packet describes a binding between some public key and - * some data. The most common signatures are a signature of a file or a - * block of text, and a signature that is a certification of a User ID. - */ -function openpgp_packet_signature() { - this.tagType = 2; - this.signatureType = null; - this.creationTime = null; - this.keyId = null; - this.signatureData = null; - this.signatureExpirationTime = null; - this.signatureNeverExpires = null; - this.signedHashValue = null; - this.MPIs = null; - this.publicKeyAlgorithm = null; - this.hashAlgorithm = null; - this.exportable = null; - this.trustLevel = null; - this.trustAmount = null; - this.regular_expression = null; - this.revocable = null; - this.keyExpirationTime = null; - this.keyNeverExpires = null; - this.preferredSymmetricAlgorithms = null; - this.revocationKeyClass = null; - this.revocationKeyAlgorithm = null; - this.revocationKeyFingerprint = null; - this.issuerKeyId = null; - this.notationFlags = null; - this.notationName = null; - this.notationValue = null; - this.preferredHashAlgorithms = null; - this.preferredCompressionAlgorithms = null; - this.keyServerPreferences = null; - this.preferredKeyServer = null; - this.isPrimaryUserID = null; - this.policyURI = null; - this.keyFlags = null; - this.signersUserId = null; - this.reasonForRevocationFlag = null; - this.reasonForRevocationString = null; - this.signatureTargetPublicKeyAlgorithm = null; - this.signatureTargetHashAlgorithm = null; - this.signatureTargetHash = null; - this.embeddedSignature = null; - this.verified = false; - - - /** - * parsing function for a signature packet (tag 2). - * @param {String} input payload of a tag 2 packet - * @param {Integer} position position to start reading from the input string - * @param {Integer} len length of the packet or the remaining length of input at position - * @return {openpgp_packet_encrypteddata} object representation - */ - function read_packet(input, position, len) { - this.data = input.substring (position, position+len); - if (len < 0) { - util.print_debug("openpgp.packet.signature.js\n"+"openpgp_packet_signature read_packet length < 0 @:"+position); - return null; - } - var mypos = position; - this.packetLength = len; - // alert('starting parsing signature: '+position+' '+this.packetLength); - this.version = input.charCodeAt(mypos++); - // switch on version (3 and 4) - switch (this.version) { - case 3: - // One-octet length of following hashed material. MUST be 5. - if (input.charCodeAt(mypos++) != 5) - util.print_debug("openpgp.packet.signature.js\n"+'invalid One-octet length of following hashed material. MUST be 5. @:'+(mypos-1)); - var sigpos = mypos; - // One-octet signature type. - this.signatureType = input.charCodeAt(mypos++); - - // Four-octet creation time. - this.creationTime = new Date(((input.charCodeAt(mypos++)) << 24 | - (input.charCodeAt(mypos++) << 16) | (input.charCodeAt(mypos++) << 8) | - input.charCodeAt(mypos++))* 1000); - - // storing data appended to data which gets verified - this.signatureData = input.substring(sigpos, mypos); - - // Eight-octet Key ID of signer. - this.keyId = input.substring(mypos, mypos +8); - mypos += 8; - - // One-octet public-key algorithm. - this.publicKeyAlgorithm = input.charCodeAt(mypos++); - - // One-octet hash algorithm. - this.hashAlgorithm = input.charCodeAt(mypos++); - - // Two-octet field holding left 16 bits of signed hash value. - this.signedHashValue = (input.charCodeAt(mypos++) << 8) | input.charCodeAt(mypos++); - var mpicount = 0; - // Algorithm-Specific Fields for RSA signatures: - // - multiprecision integer (MPI) of RSA signature value m**d mod n. - if (this.publicKeyAlgorithm > 0 && this.publicKeyAlgorithm < 4) - mpicount = 1; - // Algorithm-Specific Fields for DSA signatures: - // - MPI of DSA value r. - // - MPI of DSA value s. - else if (this.publicKeyAlgorithm == 17) - mpicount = 2; - - this.MPIs = new Array(); - for (var i = 0; i < mpicount; i++) { - this.MPIs[i] = new openpgp_type_mpi(); - if (this.MPIs[i].read(input, mypos, (mypos-position)) != null && - !this.packetLength < (mypos-position)) { - mypos += this.MPIs[i].packetLength; - } else { - util.print_error('signature contains invalid MPI @:'+mypos); - } - } - break; - case 4: - this.signatureType = input.charCodeAt(mypos++); - this.publicKeyAlgorithm = input.charCodeAt(mypos++); - this.hashAlgorithm = input.charCodeAt(mypos++); - - // Two-octet scalar octet count for following hashed subpacket - // data. - var hashed_subpacket_count = (input.charCodeAt(mypos++) << 8) + input.charCodeAt(mypos++); - - // Hashed subpacket data set (zero or more subpackets) - var subpacket_length = 0; - while (hashed_subpacket_count != subpacket_length) { - if (hashed_subpacket_count < subpacket_length) { - util.print_debug("openpgp.packet.signature.js\n"+"hashed missed something: "+mypos+" c:"+hashed_subpacket_count+" l:"+subpacket_length); - } - - subpacket_length += this._raw_read_signature_sub_packet(input, - mypos + subpacket_length, hashed_subpacket_count - - subpacket_length); - } - - mypos += hashed_subpacket_count; - this.signatureData = input.substring(position, mypos); - - // alert("signatureData: "+util.hexstrdump(this.signatureData)); - - // Two-octet scalar octet count for the following unhashed subpacket - var subpacket_count = (input.charCodeAt(mypos++) << 8) + input.charCodeAt(mypos++); - - // Unhashed subpacket data set (zero or more subpackets). - subpacket_length = 0; - while (subpacket_count != subpacket_length) { - if (subpacket_count < subpacket_length) { - util.print_debug("openpgp.packet.signature.js\n"+"missed something: "+subpacket_length+" c:"+subpacket_count+" "+" l:"+subpacket_length); - } - subpacket_length += this._raw_read_signature_sub_packet(input, - mypos + subpacket_length, subpacket_count - - subpacket_length); - - } - mypos += subpacket_count; - // Two-octet field holding the left 16 bits of the signed hash - // value. - this.signedHashValue = (input.charCodeAt(mypos++) << 8) | input.charCodeAt(mypos++); - // One or more multiprecision integers comprising the signature. - // This portion is algorithm specific, as described above. - var mpicount = 0; - if (this.publicKeyAlgorithm > 0 && this.publicKeyAlgorithm < 4) - mpicount = 1; - else if (this.publicKeyAlgorithm == 17) - mpicount = 2; - - this.MPIs = new Array(); - for (var i = 0; i < mpicount; i++) { - this.MPIs[i] = new openpgp_type_mpi(); - if (this.MPIs[i].read(input, mypos, (mypos-position)) != null && - !this.packetLength < (mypos-position)) { - mypos += this.MPIs[i].packetLength; - } else { - util.print_error('signature contains invalid MPI @:'+mypos); - } - } - break; - default: - util.print_error("openpgp.packet.signature.js\n"+'unknown signature packet version'+this.version); - break; - } - // util.print_message("openpgp.packet.signature.js\n"+"end signature: l: "+this.packetLength+"m: "+mypos+" m-p: "+(mypos-position)); - return this; - } - /** - * creates a string representation of a message signature packet (tag 2). - * This can be only used on text data - * @param {Integer} signature_type should be 1 (one) - * @param {String} data data to be signed - * @param {openpgp_msg_privatekey} privatekey private key used to sign the message. (secMPIs MUST be unlocked) - * @return {String} string representation of a signature packet - */ - function write_message_signature(signature_type, data, privatekey) { - var publickey = privatekey.privateKeyPacket.publicKey; - var hash_algo = privatekey.getPreferredSignatureHashAlgorithm(); - var result = String.fromCharCode(4); - result += String.fromCharCode(signature_type); - result += String.fromCharCode(publickey.publicKeyAlgorithm); - result += String.fromCharCode(hash_algo); - var d = Math.round(new Date().getTime() / 1000); - var datesubpacket = write_sub_signature_packet(2,""+ - String.fromCharCode((d >> 24) & 0xFF) + - String.fromCharCode((d >> 16) & 0xFF) + - String.fromCharCode((d >> 8) & 0xFF) + - String.fromCharCode(d & 0xFF)); - var issuersubpacket = write_sub_signature_packet(16, privatekey.getKeyId()); - result += String.fromCharCode(((datesubpacket.length + issuersubpacket.length) >> 8) & 0xFF); - result += String.fromCharCode ((datesubpacket.length + issuersubpacket.length) & 0xFF); - result += datesubpacket; - result += issuersubpacket; - var trailer = ''; - - trailer += String.fromCharCode(4); - trailer += String.fromCharCode(0xFF); - trailer += String.fromCharCode((result.length) >> 24); - trailer += String.fromCharCode(((result.length) >> 16) & 0xFF); - trailer += String.fromCharCode(((result.length) >> 8) & 0xFF); - trailer += String.fromCharCode((result.length) & 0xFF); - var result2 = String.fromCharCode(0); - result2 += String.fromCharCode(0); - var hash = openpgp_crypto_hashData(hash_algo, data+result+trailer); - util.print_debug("DSA Signature is calculated with:|"+data+result+trailer+"|\n"+util.hexstrdump(data+result+trailer)+"\n hash:"+util.hexstrdump(hash)); - result2 += hash.charAt(0); - result2 += hash.charAt(1); - result2 += openpgp_crypto_signData(hash_algo,privatekey.privateKeyPacket.publicKey.publicKeyAlgorithm, - publickey.MPIs, - privatekey.privateKeyPacket.secMPIs, - data+result+trailer); - return {openpgp: (openpgp_packet.write_packet_header(2, (result+result2).length)+result + result2), - hash: util.get_hashAlgorithmString(hash_algo)}; - } - /** - * creates a string representation of a sub signature packet (See RFC 4880 5.2.3.1) - * @param {Integer} type subpacket signature type. Signature types as described in RFC4880 Section 5.2.3.2 - * @param {String} data data to be included - * @return {String} a string-representation of a sub signature packet (See RFC 4880 5.2.3.1) - */ - function write_sub_signature_packet(type, data) { - var result = ""; - result += openpgp_packet.encode_length(data.length+1); - result += String.fromCharCode(type); - result += data; - return result; - } - - // V4 signature sub packets - - this._raw_read_signature_sub_packet = function(input, position, len) { - if (len < 0) - util.print_debug("openpgp.packet.signature.js\n"+"_raw_read_signature_sub_packet length < 0 @:"+position); - var mypos = position; - var subplen = 0; - // alert('starting signature subpackage read at position:'+position+' length:'+len); - if (input.charCodeAt(mypos) < 192) { - subplen = input.charCodeAt(mypos++); - } else if (input.charCodeAt(mypos) >= 192 && input.charCodeAt(mypos) < 224) { - subplen = ((input.charCodeAt(mypos++) - 192) << 8) + (input.charCodeAt(mypos++)) + 192; - } else if (input.charCodeAt(mypos) > 223 && input.charCodeAt(mypos) < 255) { - subplen = 1 << (input.charCodeAt(mypos++) & 0x1F); - } else if (input.charCodeAt(mypos) < 255) { - mypos++; - subplen = (input.charCodeAt(mypos++) << 24) | (input.charCodeAt(mypos++) << 16) - | (input.charCodeAt(mypos++) << 8) | input.charCodeAt(mypos++); - } - - var type = input.charCodeAt(mypos++) & 0x7F; - // alert('signature subpacket type '+type+" with length: "+subplen); - // subpacket type - switch (type) { - case 2: // Signature Creation Time - this.creationTime = new Date(((input.charCodeAt(mypos++) << 24) | (input.charCodeAt(mypos++) << 16) - | (input.charCodeAt(mypos++) << 8) | input.charCodeAt(mypos++))*1000); - break; - case 3: // Signature Expiration Time - this.signatureExpirationTime = (input.charCodeAt(mypos++) << 24) - | (input.charCodeAt(mypos++) << 16) | (input.charCodeAt(mypos++) << 8) - | input.charCodeAt(mypos++); - this.signatureNeverExpires = (this.signature_expiration_time == 0); - - break; - case 4: // Exportable Certification - this.exportable = input.charCodeAt(mypos++) == 1; - break; - case 5: // Trust Signature - this.trustLevel = input.charCodeAt(mypos++); - this.trustAmount = input.charCodeAt(mypos++); - break; - case 6: // Regular Expression - this.regular_expression = new String(); - for (var i = 0; i < subplen - 1; i++) - this.regular_expression += (input[mypos++]); - break; - case 7: // Revocable - this.revocable = input.charCodeAt(mypos++) == 1; - break; - case 9: // Key Expiration Time - this.keyExpirationTime = (input.charCodeAt(mypos++) << 24) - | (input.charCodeAt(mypos++) << 16) | (input.charCodeAt(mypos++) << 8) - | input.charCodeAt(mypos++); - this.keyNeverExpires = (this.keyExpirationTime == 0); - break; - case 11: // Preferred Symmetric Algorithms - this.preferredSymmetricAlgorithms = new Array(); - for (var i = 0; i < subplen-1; i++) { - this.preferredSymmetricAlgorithms = input.charCodeAt(mypos++); - } - break; - case 12: // Revocation Key - // (1 octet of class, 1 octet of public-key algorithm ID, 20 - // octets of - // fingerprint) - this.revocationKeyClass = input.charCodeAt(mypos++); - this.revocationKeyAlgorithm = input.charCodeAt(mypos++); - this.revocationKeyFingerprint = new Array(); - for ( var i = 0; i < 20; i++) { - this.revocationKeyFingerprint = input.charCodeAt(mypos++); - } - break; - case 16: // Issuer - this.issuerKeyId = input.substring(mypos,mypos+8); - mypos += 8; - break; - case 20: // Notation Data - this.notationFlags = (input.charCodeAt(mypos++) << 24) | - (input.charCodeAt(mypos++) << 16) | - (input.charCodeAt(mypos++) << 8) | - (input.charCodeAt(mypos++)); - var nameLength = (input.charCodeAt(mypos++) << 8) | (input.charCodeAt(mypos++)); - var valueLength = (input.charCodeAt(mypos++) << 8) | (input.charCodeAt(mypos++)); - this.notationName = ""; - for (var i = 0; i < nameLength; i++) { - this.notationName += input[mypos++]; - } - this.notationValue = ""; - for (var i = 0; i < valueLength; i++) { - this.notationValue += input[mypos++]; - } - break; - case 21: // Preferred Hash Algorithms - this.preferredHashAlgorithms = new Array(); - for (var i = 0; i < subplen-1; i++) { - this.preferredHashAlgorithms = input.charCodeAt(mypos++); - } - break; - case 22: // Preferred Compression Algorithms - this.preferredCompressionAlgorithms = new Array(); - for ( var i = 0; i < subplen-1; i++) { - this.preferredCompressionAlgorithms = input.charCodeAt(mypos++); - } - break; - case 23: // Key Server Preferences - this.keyServerPreferences = new Array(); - for ( var i = 0; i < subplen-1; i++) { - this.keyServerPreferences = input.charCodeAt(mypos++); - } - break; - case 24: // Preferred Key Server - this.preferredKeyServer = new String(); - for ( var i = 0; i < subplen-1; i++) { - this.preferredKeyServer += input[mypos++]; - } - break; - case 25: // Primary User ID - this.isPrimaryUserID = input[mypos++] != 0; - break; - case 26: // Policy URI - this.policyURI = new String(); - for ( var i = 0; i < subplen-1; i++) { - this.policyURI += input[mypos++]; - } - break; - case 27: // Key Flags - this.keyFlags = new Array(); - for ( var i = 0; i < subplen-1; i++) { - this.keyFlags = input.charCodeAt(mypos++); - } - break; - case 28: // Signer's User ID - this.signersUserId = new String(); - for ( var i = 0; i < subplen-1; i++) { - this.signersUserId += input[mypos++]; - } - break; - case 29: // Reason for Revocation - this.reasonForRevocationFlag = input.charCodeAt(mypos++); - this.reasonForRevocationString = new String(); - for ( var i = 0; i < subplen -2; i++) { - this.reasonForRevocationString += input[mypos++]; - } - break; - case 30: // Features - // TODO: to be implemented - return subplen+1; - case 31: // Signature Target - // (1 octet public-key algorithm, 1 octet hash algorithm, N octets hash) - this.signatureTargetPublicKeyAlgorithm = input.charCodeAt(mypos++); - this.signatureTargetHashAlgorithm = input.charCodeAt(mypos++); - var signatureTargetHashAlgorithmLength = 0; - switch(this.signatureTargetHashAlgorithm) { - case 1: // - MD5 [HAC] "MD5" - case 2: // - SHA-1 [FIPS180] "SHA1" - signatureTargetHashAlgorithmLength = 20; - break; - case 3: // - RIPE-MD/160 [HAC] "RIPEMD160" - case 8: // - SHA256 [FIPS180] "SHA256" - case 9: // - SHA384 [FIPS180] "SHA384" - case 10: // - SHA512 [FIPS180] "SHA512" - case 11: // - SHA224 [FIPS180] "SHA224" - break; - // 100 to 110 - Private/Experimental algorithm - default: - util.print_error("openpgp.packet.signature.js\n"+"unknown signature target hash algorithm:"+this.signatureTargetHashAlgorithm); - return null; - } - this.signatureTargetHash = new Array(); - for (var i = 0; i < signatureTargetHashAlgorithmLength; i++) { - this.signatureTargetHash[i] = input[mypos++]; - } - case 32: // Embedded Signature - this.embeddedSignature = new openpgp_packet_signature(); - this.embeddedSignature.read_packet(input, mypos, len -(mypos-position)); - return ((mypos+ this.embeddedSignature.packetLength) - position); - break; - case 100: // Private or experimental - case 101: // Private or experimental - case 102: // Private or experimental - case 103: // Private or experimental - case 104: // Private or experimental - case 105: // Private or experimental - case 106: // Private or experimental - case 107: // Private or experimental - case 108: // Private or experimental - case 109: // Private or experimental - case 110: // Private or experimental - util.print_error("openpgp.packet.signature.js\n"+'private or experimental signature subpacket type '+type+" @:"+mypos+" subplen:"+subplen+" len:"+len); - return subplen+1; - break; - case 0: // Reserved - case 1: // Reserved - case 8: // Reserved - case 10: // Placeholder for backward compatibility - case 13: // Reserved - case 14: // Reserved - case 15: // Reserved - case 17: // Reserved - case 18: // Reserved - case 19: // Reserved - default: - util.print_error("openpgp.packet.signature.js\n"+'unknown signature subpacket type '+type+" @:"+mypos+" subplen:"+subplen+" len:"+len); - return subplen+1; - break; - } - return mypos -position; - }; - /** - * verifys the signature packet. Note: not signature types are implemented - * @param {String} data data which on the signature applies - * @param {openpgp_msg_privatekey} key the public key to verify the signature - * @return {boolean} True if message is verified, else false. - */ - function verify(data, key) { - // calculating the trailer - var trailer = ''; - trailer += String.fromCharCode(this.version); - trailer += String.fromCharCode(0xFF); - trailer += String.fromCharCode(this.signatureData.length >> 24); - trailer += String.fromCharCode((this.signatureData.length >> 16) &0xFF); - trailer += String.fromCharCode((this.signatureData.length >> 8) &0xFF); - trailer += String.fromCharCode(this.signatureData.length & 0xFF); - switch(this.signatureType) { - case 0: // 0x00: Signature of a binary document. - if (this.version == 4) { - this.verified = openpgp_crypto_verifySignature(this.publicKeyAlgorithm, this.hashAlgorithm, - this.MPIs, key.obj.publicKeyPacket.MPIs, data+this.signatureData+trailer); - } else if (this.version == 3) { - this.verified = openpgp_crypto_verifySignature(this.publicKeyAlgorithm, this.hashAlgorithm, - this.MPIs, key.obj.publicKeyPacket.MPIs, data+this.signatureData); - } else { - this.verified = false; - } - break; - - case 1: // 0x01: Signature of a canonical text document. - var canonicalMsgText = data.replace(/\r/g,'').replace(/\n/g,"\r\n"); - if (openpgp.config.debug) { - util.print_debug('canonicalMsgText: '+util.hexdump(canonicalMsgText)); - util.print_debug('signatureData: '+util.hexdump(this.signatureData)); - util.print_debug('trailer: '+util.hexdump(trailer)); - } - if (this.version == 4) { - this.verified = openpgp_crypto_verifySignature(this.publicKeyAlgorithm, this.hashAlgorithm, - this.MPIs, key.obj.publicKeyPacket.MPIs, canonicalMsgText+this.signatureData+trailer); - } else if (this.version == 3) { - this.verified = openpgp_crypto_verifySignature(this.publicKeyAlgorithm, this.hashAlgorithm, - this.MPIs, key.obj.publicKeyPacket.MPIs, canonicalMsgText+this.signatureData); - } else { - this.verified = false; - } - break; - - case 2: // 0x02: Standalone signature. - // This signature is a signature of only its own subpacket contents. - // It is calculated identically to a signature over a zero-length - // binary document. Note that it doesn't make sense to have a V3 - // standalone signature. - if (this.version == 4) { - this.verified = openpgp_crypto_verifySignature(this.publicKeyAlgorithm, this.hashAlgorithm, - this.MPIs, key.obj.publicKeyPacket.MPIs, this.signatureData+trailer); - } else { - this.verified = false; - } - break; - case 16: - // 0x10: Generic certification of a User ID and Public-Key packet. - // The issuer of this certification does not make any particular - // assertion as to how well the certifier has checked that the owner - // of the key is in fact the person described by the User ID. - case 17: - // 0x11: Persona certification of a User ID and Public-Key packet. - // The issuer of this certification has not done any verification of - // the claim that the owner of this key is the User ID specified. - case 18: - // 0x12: Casual certification of a User ID and Public-Key packet. - // The issuer of this certification has done some casual - // verification of the claim of identity. - case 19: - // 0x13: Positive certification of a User ID and Public-Key packet. - // The issuer of this certification has done substantial - // verification of the claim of identity. - // - // Most OpenPGP implementations make their "key signatures" as 0x10 - // certifications. Some implementations can issue 0x11-0x13 - // certifications, but few differentiate between the types. - case 48: - // 0x30: Certification revocation signature - // This signature revokes an earlier User ID certification signature - // (signature class 0x10 through 0x13) or direct-key signature - // (0x1F). It should be issued by the same key that issued the - // revoked signature or an authorized revocation key. The signature - // is computed over the same data as the certificate that it - // revokes, and should have a later creation date than that - // certificate. - - this.verified = openpgp_crypto_verifySignature(this.publicKeyAlgorithm, this.hashAlgorithm, - this.MPIs, key.MPIs, data+this.signatureData+trailer); - break; - - case 24: - // 0x18: Subkey Binding Signature - // This signature is a statement by the top-level signing key that - // indicates that it owns the subkey. This signature is calculated - // directly on the primary key and subkey, and not on any User ID or - // other packets. A signature that binds a signing subkey MUST have - // an Embedded Signature subpacket in this binding signature that - // contains a 0x19 signature made by the signing subkey on the - // primary key and subkey. - if (this.version == 3) { - this.verified = false; - break; - } - - this.verified = openpgp_crypto_verifySignature(this.publicKeyAlgorithm, this.hashAlgorithm, - this.MPIs, key.MPIs, data+this.signatureData+trailer); - break; - case 25: - // 0x19: Primary Key Binding Signature - // This signature is a statement by a signing subkey, indicating - // that it is owned by the primary key and subkey. This signature - // is calculated the same way as a 0x18 signature: directly on the - // primary key and subkey, and not on any User ID or other packets. - - // When a signature is made over a key, the hash data starts with the - // octet 0x99, followed by a two-octet length of the key, and then body - // of the key packet. (Note that this is an old-style packet header for - // a key packet with two-octet length.) A subkey binding signature - // (type 0x18) or primary key binding signature (type 0x19) then hashes - // the subkey using the same format as the main key (also using 0x99 as - // the first octet). - case 31: - // 0x1F: Signature directly on a key - // This signature is calculated directly on a key. It binds the - // information in the Signature subpackets to the key, and is - // appropriate to be used for subpackets that provide information - // about the key, such as the Revocation Key subpacket. It is also - // appropriate for statements that non-self certifiers want to make - // about the key itself, rather than the binding between a key and a - // name. - case 32: - // 0x20: Key revocation signature - // The signature is calculated directly on the key being revoked. A - // revoked key is not to be used. Only revocation signatures by the - // key being revoked, or by an authorized revocation key, should be - // considered valid revocation signatures. - case 40: - // 0x28: Subkey revocation signature - // The signature is calculated directly on the subkey being revoked. - // A revoked subkey is not to be used. Only revocation signatures - // by the top-level signature key that is bound to this subkey, or - // by an authorized revocation key, should be considered valid - // revocation signatures. - this.verified = openpgp_crypto_verifySignature(this.publicKeyAlgorithm, this.hashAlgorithm, - this.MPIs, key.MPIs, data+this.signatureData+trailer); - break; - - // Key revocation signatures (types 0x20 and 0x28) - // hash only the key being revoked. - case 64: - // 0x40: Timestamp signature. - // This signature is only meaningful for the timestamp contained in - // it. - case 80: - // 0x50: Third-Party Confirmation signature. - // This signature is a signature over some other OpenPGP Signature - // packet(s). It is analogous to a notary seal on the signed data. - // A third-party signature SHOULD include Signature Target - // subpacket(s) to give easy identification. Note that we really do - // mean SHOULD. There are plausible uses for this (such as a blind - // party that only sees the signature, not the key or source - // document) that cannot include a target subpacket. - default: - util.print_error("openpgp.packet.signature.js\n"+"signature verification for type"+ this.signatureType+" not implemented"); - this.verified = false; - break; - } - return this.verified; - } - /** - * generates debug output (pretty print) - * @return {String} String which gives some information about the signature packet - */ - - function toString () { - if (this.version == 3) { - var result = '5.2. Signature Packet (Tag 2)\n'+ - "Packet Length: :"+this.packetLength+'\n'+ - "Packet version: :"+this.version+'\n'+ - "One-octet signature type :"+this.signatureType+'\n'+ - "Four-octet creation time. :"+this.creationTime+'\n'+ - "Eight-octet Key ID of signer. :"+util.hexidump(this.keyId)+'\n'+ - "One-octet public-key algorithm. :"+this.publicKeyAlgorithm+'\n'+ - "One-octet hash algorithm. :"+this.hashAlgorithm+'\n'+ - "Two-octet field holding left\n" + - " 16 bits of signed hash value. :"+this.signedHashValue+'\n'; - } else { - var result = '5.2. Signature Packet (Tag 2)\n'+ - "Packet Length: :"+this.packetLength+'\n'+ - "Packet version: :"+this.version+'\n'+ - "One-octet signature type :"+this.signatureType+'\n'+ - "One-octet public-key algorithm. :"+this.publicKeyAlgorithm+'\n'+ - "One-octet hash algorithm. :"+this.hashAlgorithm+'\n'+ - "Two-octet field holding left\n" + - " 16 bits of signed hash value. :"+this.signedHashValue+'\n'+ - "Signature Creation Time :"+this.creationTime+'\n'+ - "Signature Expiration Time :"+this.signatureExpirationTime+'\n'+ - "Signature Never Expires :"+this.signatureNeverExpires+'\n'+ - "Exportable Certification :"+this.exportable+'\n'+ - "Trust Signature level: :"+this.trustLevel+' amount'+this.trustAmount+'\n'+ - "Regular Expression :"+this.regular_expression+'\n'+ - "Revocable :"+this.revocable+'\n'+ - "Key Expiration Time :"+this.keyExpirationTime+" "+this.keyNeverExpires+'\n'+ - "Preferred Symmetric Algorithms :"+this.preferredSymmetricAlgorithms+'\n'+ - "Revocation Key"+'\n'+ - " ( 1 octet of class, :"+this.revocationKeyClass +'\n'+ - " 1 octet of public-key ID, :" +this.revocationKeyAlgorithm+'\n'+ - " 20 octets of fingerprint) :"+this.revocationKeyFingerprint+'\n'+ - "Issuer :"+util.hexstrdump(this.issuerKeyId)+'\n'+ - "Preferred Hash Algorithms :"+this.preferredHashAlgorithms+'\n'+ - "Preferred Compression Alg. :"+this.preferredCompressionAlgorithms+'\n'+ - "Key Server Preferences :"+this.keyServerPreferences+'\n'+ - "Preferred Key Server :"+this.preferredKeyServer+'\n'+ - "Primary User ID :"+this.isPrimaryUserID+'\n'+ - "Policy URI :"+this.policyURI+'\n'+ - "Key Flags :"+this.keyFlags+'\n'+ - "Signer's User ID :"+this.signersUserId+'\n'+ - "Notation :"+this.notationName+" = "+this.notationValue+"\n"+ - "Reason for Revocation\n"+ - " Flag :"+this.reasonForRevocationFlag+'\n'+ - " Reason :"+this.reasonForRevocationString+'\nMPI:\n'; - } - for (var i = 0; i < this.MPIs.length; i++) { - result += this.MPIs[i].toString(); - } - return result; - } - - /** - * gets the issuer key id of this signature - * @return {String} issuer key id as string (8bytes) - */ - function getIssuer() { - if (this.version == 4) - return this.issuerKeyId; - if (this.version == 3) - return this.keyId; - return null; - } - - /** - * Tries to get the corresponding public key out of the public keyring for the issuer created this signature - * @return {Object} {obj: [openpgp_msg_publickey], text: [String]} if found the public key will be returned. null otherwise - */ - function getIssuerKey() { - var result = null; - if (this.version == 4) { - result = openpgp.keyring.getPublicKeysForKeyId(this.issuerKeyId); - } else if (this.version == 3) { - result = openpgp.keyring.getPublicKeysForKeyId(this.keyId); - } else return null; - if (result.length == 0) - return null; - return result[0]; - } - this.getIssuerKey = getIssuerKey; - this.getIssuer = getIssuer; - this.write_message_signature = write_message_signature; - this.verify = verify; - this.read_packet = read_packet; - this.toString = toString; -} diff --git a/src/packet/openpgp.packet.userattribute.js b/src/packet/openpgp.packet.userattribute.js deleted file mode 100644 index 26be64c8..00000000 --- a/src/packet/openpgp.packet.userattribute.js +++ /dev/null @@ -1,155 +0,0 @@ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @class - * @classdesc Implementation of the User Attribute Packet (Tag 17) - * The User Attribute packet is a variation of the User ID packet. It - * is capable of storing more types of data than the User ID packet, - * which is limited to text. Like the User ID packet, a User Attribute - * packet may be certified by the key owner ("self-signed") or any other - * key owner who cares to certify it. Except as noted, a User Attribute - * packet may be used anywhere that a User ID packet may be used. - * - * While User Attribute packets are not a required part of the OpenPGP - * standard, implementations SHOULD provide at least enough - * compatibility to properly handle a certification signature on the - * User Attribute packet. A simple way to do this is by treating the - * User Attribute packet as a User ID packet with opaque contents, but - * an implementation may use any method desired. - */ -function openpgp_packet_userattribute() { - this.tagType = 17; - this.certificationSignatures = new Array(); - this.certificationRevocationSignatures = new Array(); - this.revocationSignatures = new Array(); - this.parentNode = null; - - /** - * parsing function for a user attribute packet (tag 17). - * @param {String} input payload of a tag 17 packet - * @param {Integer} position position to start reading from the input string - * @param {Integer} len length of the packet or the remaining length of input at position - * @return {openpgp_packet_encrypteddata} object representation - */ - function read_packet (input, position, len) { - var total_len = 0; - this.packetLength = len; - this.userattributes = new Array(); - var count = 0; - var mypos = position; - while (len != total_len) { - var current_len = 0; - // 4.2.2.1. One-Octet Lengths - if (input.charCodeAt(mypos) < 192) { - packet_length = input.charCodeAt(mypos++); - current_len = 1; - // 4.2.2.2. Two-Octet Lengths - } else if (input.charCodeAt(mypos) >= 192 && input.charCodeAt(mypos) < 224) { - packet_length = ((input.charCodeAt(mypos++) - 192) << 8) - + (input.charCodeAt(mypos++)) + 192; - current_len = 2; - // 4.2.2.4. Partial Body Lengths - } else if (input.charCodeAt(mypos) > 223 && input.charCodeAt(mypos) < 255) { - packet_length = 1 << (input.charCodeAt(mypos++) & 0x1F); - current_len = 1; - // 4.2.2.3. Five-Octet Lengths - } else { - current_len = 5; - mypos++; - packet_length = (input.charCodeAt(mypos++) << 24) | (input.charCodeAt(mypos++) << 16) - | (input.charCodeAt(mypos++) << 8) | input.charCodeAt(mypos++); - } - - var subpackettype = input.charCodeAt(mypos++); - packet_length--; - current_len++; - this.userattributes[count] = new Array(); - this.userattributes[count] = input.substring(mypos, mypos + packet_length); - mypos += packet_length; - total_len += current_len+packet_length; - } - this.packetLength = mypos - position; - return this; - } - - /** - * generates debug output (pretty print) - * @return {String} String which gives some information about the user attribute packet - */ - function toString() { - var result = '5.12. User Attribute Packet (Tag 17)\n'+ - ' AttributePackets: (count = '+this.userattributes.length+')\n'; - for (var i = 0; i < this.userattributes.length; i++) { - result += ' ('+this.userattributes[i].length+') bytes: ['+util.hexidump(this.userattributes[i])+']\n'; - } - return result; - } - - /** - * Continue parsing packets belonging to the user attribute packet such as signatures - * @param {Object} parent_node the parent object - * @param {String} input input string to read the packet(s) from - * @param {Integer} position start position for the parser - * @param {Integer} len length of the packet(s) or remaining length of input - * @return {Integer} length of nodes read - */ - function read_nodes(parent_node, input, position, len) { - - this.parentNode = parent_node; - var exit = false; - var pos = position; - var l = len; - while (input.length != pos) { - var result = openpgp_packet.read_packet(input, pos, l); - if (result == null) { - util.print_error("openpgp.packet.userattribute.js\n"+'[user_attr] parsing ends here @:' + pos + " l:" + l); - break; - } else { - switch (result.tagType) { - case 2: // Signature Packet - if (result.signatureType > 15 - && result.signatureType < 20) // certification - // // - // signature - this.certificationSignatures[this.certificationSignatures.length] = result; - else if (result.signatureType == 32) // certification revocation signature - this.certificationRevocationSignatures[this.certificationRevocationSignatures.length] = result; - pos += result.packetLength + result.headerLength; - l = len - (pos - position); - break; - default: - this.data = input; - this.position = position - parent_node.packetLength; - this.len = pos - position; - return this.len; - break; - } - } - } - this.data = input; - this.position = position - parent_node.packetLength; - this.len = pos - position; - return this.len; - - } - - this.read_packet = read_packet; - this.read_nodes = read_nodes; - this.toString = toString; - -}; diff --git a/src/packet/openpgp.packet.userid.js b/src/packet/openpgp.packet.userid.js deleted file mode 100644 index 427a035f..00000000 --- a/src/packet/openpgp.packet.userid.js +++ /dev/null @@ -1,358 +0,0 @@ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @class - * @classdesc Implementation of the User ID Packet (Tag 13) - * A User ID packet consists of UTF-8 text that is intended to represent - * the name and email address of the key holder. By convention, it - * includes an RFC 2822 [RFC2822] mail name-addr, but there are no - * restrictions on its content. The packet length in the header - * specifies the length of the User ID. - */ - -function openpgp_packet_userid() { - this.text = '' - this.tagType = 13; - this.certificationSignatures = new Array(); - this.certificationRevocationSignatures = new Array(); - this.revocationSignatures = new Array(); - this.parentNode = null; - - /** - * Set the packet text field to a native javascript string - * Conversion to a proper utf8 encoding takes place when the - * packet is written. - * @param {String} str Any native javascript string - */ - this.set_text = function(str) { - this.text = str; - } - - /** - * Set the packet text to value represented by the provided string - * of bytes. - * @param {String} bytes A string of bytes - */ - this.set_text_bytes = function(bytes) { - this.text = util.decode_utf8(bytes); - } - - /** - * Get the byte sequence representing the text of this packet. - * @returns {String} A sequence of bytes - */ - this.get_text_bytes = function() { - return util.encode_utf8(this.text); - } - - - /** - * Parsing function for a user id packet (tag 13). - * @param {String} input payload of a tag 13 packet - * @param {Integer} position position to start reading from the input string - * @param {Integer} len length of the packet or the remaining length of input at position - * @return {openpgp_packet_encrypteddata} object representation - */ - this.read_packet = function(input, position, len) { - this.packetLength = len; - this.set_text_bytes(input.substr(position, len)); - return this; - } - - /** - * Creates a string representation of the user id packet - * @param {String} user_id the user id as string ("John Doe 15 - && result.signatureType < 20) { // certification - // // - // signature - this.certificationSignatures[this.certificationSignatures.length] = result; - break; - } else if (result.signatureType == 48) {// certification revocation signature - this.certificationRevocationSignatures[this.certificationRevocationSignatures.length] = result; - break; - } else if (result.signatureType == 24) { // omg. standalone signature - this.certificationSignatures[this.certificationSignatures.length] = result; - break; - } else { - util.print_debug("unknown sig t: "+result.signatureType+"@"+(pos - (result.packetLength + result.headerLength))); - } - default: - this.data = input; - this.position = position - parent_node.packetLength; - this.len = pos - position -(result.headerLength + result.packetLength); - return this.len; - } - } - } - this.data = input; - this.position = position - parent_node.packetLength; - this.len = pos - position -(result.headerLength + result.packetLength); - return this.len; - } else if (parent_node.tagType == 5) { // secret Key - this.parentNode = parent_node; - var exit = false; - var pos = position; - while (input.length != pos) { - var result = openpgp_packet.read_packet(input, pos, l - (pos - position)); - if (result == null) { - util.print_error('parsing ends here @:' + pos + " l:" + l); - break; - } else { - pos += result.packetLength + result.headerLength; - l = input.length - pos; - switch (result.tagType) { - case 2: // Signature Packet certification signature - if (result.signatureType > 15 - && result.signatureType < 20) - this.certificationSignatures[this.certificationSignatures.length] = result; - // certification revocation signature - else if (result.signatureType == 48) - this.certificationRevocationSignatures[this.certificationRevocationSignatures.length] = result; - default: - this.data = input; - this.position = position - parent_node.packetLength; - this.len = pos - position -(result.headerLength + result.packetLength); - return this.len; - } - } - } - } else { - util.print_error("unknown parent node for a userId packet "+parent_node.tagType); - } - } - - /** - * generates debug output (pretty print) - * @return {String} String which gives some information about the user id packet - */ - this.toString = function() { - var result = ' 5.11. User ID Packet (Tag 13)\n' + ' text (' - + this.text.length + '): "' + this.text.replace("<", "<") - + '"\n'; - result +="certification signatures:\n"; - for (var i = 0; i < this.certificationSignatures.length; i++) { - result += " "+this.certificationSignatures[i].toString(); - } - result +="certification revocation signatures:\n"; - for (var i = 0; i < this.certificationRevocationSignatures.length; i++) { - result += " "+this.certificationRevocationSignatures[i].toString(); - } - return result; - } - - /** - * lookup function to find certification revocation signatures - * @param {String} keyId string containing the key id of the issuer of this signature - * @return a CertificationRevocationSignature if found; otherwise null - */ - this.hasCertificationRevocationSignature = function(keyId) { - for (var i = 0; i < this.certificationRevocationSignatures.length; i++) { - if ((this.certificationRevocationSignatures[i].version == 3 && - this.certificationRevocationSignatures[i].keyId == keyId) || - (this.certificationRevocationSignatures[i].version == 4 && - this.certificationRevocationSignatures[i].issuerKeyId == keyId)) - return this.certificationRevocationSignatures[i]; - } - return null; - } - - /** - * Verifies all certification signatures. This method does not consider possible revocation signatures. - * @param {Object} publicKeyPacket the top level key material - * @return {Integer[]} An array of integers corresponding to the array of certification signatures. The meaning of each integer is the following: - * 0 = bad signature - * 1 = signature expired - * 2 = issuer key not available - * 3 = revoked - * 4 = signature valid - * 5 = signature by key owner expired - * 6 = signature by key owner revoked - */ - this.verifyCertificationSignatures = function(publicKeyPacket) { - var bytes = this.get_text_bytes(); - result = new Array(); - for (var i = 0 ; i < this.certificationSignatures.length; i++) { - // A certification signature (type 0x10 through 0x13) hashes the User - // ID being bound to the key into the hash context after the above - // data. A V3 certification hashes the contents of the User ID or - // attribute packet packet, without any header. A V4 certification - // hashes the constant 0xB4 for User ID certifications or the constant - // 0xD1 for User Attribute certifications, followed by a four-octet - // number giving the length of the User ID or User Attribute data, and - // then the User ID or User Attribute data. - - if (this.certificationSignatures[i].version == 4) { - if (this.certificationSignatures[i].signatureExpirationTime != null && - this.certificationSignatures[i].signatureExpirationTime != null && - this.certificationSignatures[i].signatureExpirationTime != 0 && - !this.certificationSignatures[i].signatureNeverExpires && - new Date(this.certificationSignatures[i].creationTime.getTime() +(this.certificationSignatures[i].signatureExpirationTime*1000)) < new Date()) { - if (this.certificationSignatures[i].issuerKeyId == publicKeyPacket.getKeyId()) - result[i] = 5; - else - result[i] = 1; - continue; - } - if (this.certificationSignatures[i].issuerKeyId == null) { - result[i] = 0; - continue; - } - var issuerPublicKey = openpgp.keyring.getPublicKeysForKeyId(this.certificationSignatures[i].issuerKeyId); - if (issuerPublicKey == null || issuerPublicKey.length == 0) { - result[i] = 2; - continue; - } - // TODO: try to verify all returned issuer public keys (key ids are not unique!) - var issuerPublicKey = issuerPublicKey[0]; - var signingKey = issuerPublicKey.obj.getSigningKey(); - if (signingKey == null) { - result[i] = 0; - continue; - } - var revocation = this.hasCertificationRevocationSignature(this.certificationSignatures[i].issuerKeyId); - if (revocation != null && revocation.creationTime > - this.certificationSignatures[i].creationTime) { - - var signaturedata = String.fromCharCode(0x99)+ publicKeyPacket.header.substring(1)+ - publicKeyPacket.data+String.fromCharCode(0xB4)+ - String.fromCharCode((bytes.length >> 24) & 0xFF)+ - String.fromCharCode((bytes.length >> 16) & 0xFF)+ - String.fromCharCode((bytes.length >> 8) & 0xFF)+ - String.fromCharCode((bytes.length) & 0xFF)+ - bytes; - if (revocation.verify(signaturedata, signingKey)) { - if (this.certificationSignatures[i].issuerKeyId == publicKeyPacket.getKeyId()) - result[i] = 6; - else - result[i] = 3; - continue; - } - } - - var signaturedata = String.fromCharCode(0x99)+ publicKeyPacket.header.substring(1)+ - publicKeyPacket.data+String.fromCharCode(0xB4)+ - String.fromCharCode((bytes.length >> 24) & 0xFF)+ - String.fromCharCode((bytes.length >> 16) & 0xFF)+ - String.fromCharCode((bytes.length >> 8) & 0xFF)+ - String.fromCharCode((bytes.length) & 0xFF)+ - bytes; - if (this.certificationSignatures[i].verify(signaturedata, signingKey)) { - result[i] = 4; - } else - result[i] = 0; - } else if (this.certificationSignatures[i].version == 3) { - if (this.certificationSignatures[i].keyId == null) { - result[i] = 0; - continue; - } - var issuerPublicKey = openpgp.keyring.getPublicKeysForKeyId(this.certificationSignatures[i].keyId); - if (issuerPublicKey == null || issuerPublicKey.length == 0) { - result[i] = 2; - continue; - } - issuerPublicKey = issuerPublicKey[0]; - var signingKey = publicKey.obj.getSigningKey(); - if (signingKey == null) { - result[i] = 0; - continue; - } - var revocation = this.hasCertificationRevocationSignature(this.certificationSignatures[i].keyId); - if (revocation != null && revocation.creationTime > - this.certificationSignatures[i].creationTime) { - var signaturedata = String.fromCharCode(0x99)+ this.publicKeyPacket.header.substring(1)+ - this.publicKeyPacket.data+bytes; - if (revocation.verify(signaturedata, signingKey)) { - if (revocation.keyId == publicKeyPacket.getKeyId()) - result[i] = 6; - else - result[i] = 3; - continue; - } - } - var signaturedata = String.fromCharCode(0x99)+ publicKeyPacket.header.substring(1)+ - publicKeyPacket.data + bytes; - if (this.certificationSignatures[i].verify(signaturedata, signingKey)) { - result[i] = 4; - } else - result[i] = 0; - } else { - result[i] = 0; - } - } - return result; - } - - /** - * verifies the signatures of the user id - * @return 0 if the userid is valid; 1 = userid expired; 2 = userid revoked - */ - this.verify = function(publicKeyPacket) { - var result = this.verifyCertificationSignatures(publicKeyPacket); - if (result.indexOf(6) != -1) - return 2; - if (result.indexOf(5) != -1) - return 1; - return 0; - } - - // TODO: implementation missing - this.addCertification = function(publicKeyPacket, privateKeyPacket) { - - } - - // TODO: implementation missing - this.revokeCertification = function(publicKeyPacket, privateKeyPacket) { - - } -} diff --git a/src/type/openpgp.type.mpi.js b/src/type/openpgp.type.mpi.js deleted file mode 100644 index c766fa4a..00000000 --- a/src/type/openpgp.type.mpi.js +++ /dev/null @@ -1,135 +0,0 @@ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -// Hint: We hold our MPIs as an array of octets in big endian format preceeding a two -// octet scalar: MPI: [a,b,c,d,e,f] -// - MPI size: (a << 8) | b -// - MPI = c | d << 8 | e << ((MPI.length -2)*8) | f ((MPI.length -2)*8) - -/** - * @class - * @classdescImplementation of type MPI (RFC4880 3.2) - * Multiprecision integers (also called MPIs) are unsigned integers used - * to hold large integers such as the ones used in cryptographic - * calculations. - * An MPI consists of two pieces: a two-octet scalar that is the length - * of the MPI in bits followed by a string of octets that contain the - * actual integer. - */ -function openpgp_type_mpi() { - this.MPI = null; - this.mpiBitLength = null; - this.mpiByteLength = null; - this.data = null; - /** - * Parsing function for a mpi (RFC 4880 3.2). - * @param {String} input Payload of mpi data - * @param {Integer} position Position to start reading from the input - * string - * @param {Integer} len Length of the packet or the remaining length of - * input at position - * @return {openpgp_type_mpi} Object representation - */ - function read(input, position, len) { - var mypos = position; - - this.mpiBitLength = (input.charCodeAt(mypos++) << 8) | input.charCodeAt(mypos++); - - // Additional rules: - // - // The size of an MPI is ((MPI.length + 7) / 8) + 2 octets. - // - // The length field of an MPI describes the length starting from its - // most significant non-zero bit. Thus, the MPI [00 02 01] is not - // formed correctly. It should be [00 01 01]. - - // TODO: Verification of this size method! This size calculation as - // specified above is not applicable in JavaScript - this.mpiByteLength = (this.mpiBitLength - (this.mpiBitLength % 8)) / 8; - if (this.mpiBitLength % 8 != 0) - this.mpiByteLength++; - - this.MPI = input.substring(mypos,mypos+this.mpiByteLength); - this.data = input.substring(position, position+2+this.mpiByteLength); - this.packetLength = this.mpiByteLength +2; - return this; - } - - /** - * Generates debug output (pretty print) - * @return {String} String which gives some information about the mpi - */ - function toString() { - var r = " MPI("+this.mpiBitLength+"b/"+this.mpiByteLength+"B) : 0x"; - r+=util.hexstrdump(this.MPI); - return r+'\n'; - } - - /** - * Converts the mpi to an BigInteger object - * @return {BigInteger} - */ - function getBigInteger() { - return new BigInteger(util.hexstrdump(this.MPI),16); - } - - - function getBits(num) { - for (var i = 0; i < 9; i++) - if (num >> i == 0) - return i; - } - - /** - * Gets the length of the mpi in bytes - * @return {Integer} Mpi byte length - */ - function getByteLength() { - return this.mpiByteLength; - } - - /** - * Creates an mpi from the specified string - * @param {String} data Data to read the mpi from - * @return {openpgp_type_mpi} - */ - function create(data) { - this.MPI = data; - this.mpiBitLength = (data.length -1) *8 + getBits(data.charCodeAt(0)); - this.mpiByteLength = data.length; - return this; - } - - /** - * Converts the mpi object to a string as specified in RFC4880 3.2 - * @return {String} mpi Byte representation - */ - function toBin() { - var result = String.fromCharCode((this.mpiBitLength >> 8) & 0xFF); - result += String.fromCharCode(this.mpiBitLength & 0xFF); - result += this.MPI; - return result; - } - - this.read = read; - this.toBigInteger = getBigInteger; - this.toString = toString; - this.create = create; - this.toBin = toBin; - this.getByteLength = getByteLength; -} - diff --git a/src/type/openpgp.type.s2k.js b/src/type/openpgp.type.s2k.js deleted file mode 100644 index 64360ee8..00000000 --- a/src/type/openpgp.type.s2k.js +++ /dev/null @@ -1,141 +0,0 @@ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @class - * @classdesc Implementation of the String-to-key specifier (RFC4880 3.7) - * String-to-key (S2K) specifiers are used to convert passphrase strings - into symmetric-key encryption/decryption keys. They are used in two - places, currently: to encrypt the secret part of private keys in the - private keyring, and to convert passphrases to encryption keys for - symmetrically encrypted messages. - */ -function openpgp_type_s2k() { - /** - * Parsing function for a string-to-key specifier (RFC 4880 3.7). - * @param {String} input Payload of string-to-key specifier - * @param {Integer} position Position to start reading from the input string - * @return {openpgp_type_s2k} Object representation - */ - function read(input, position) { - var mypos = position; - this.type = input.charCodeAt(mypos++); - switch (this.type) { - case 0: // Simple S2K - // Octet 1: hash algorithm - this.hashAlgorithm = input.charCodeAt(mypos++); - this.s2kLength = 1; - break; - - case 1: // Salted S2K - // Octet 1: hash algorithm - this.hashAlgorithm = input.charCodeAt(mypos++); - - // Octets 2-9: 8-octet salt value - this.saltValue = input.substring(mypos, mypos+8); - mypos += 8; - this.s2kLength = 9; - break; - - case 3: // Iterated and Salted S2K - // Octet 1: hash algorithm - this.hashAlgorithm = input.charCodeAt(mypos++); - - // Octets 2-9: 8-octet salt value - this.saltValue = input.substring(mypos, mypos+8); - mypos += 8; - - // Octet 10: count, a one-octet, coded value - this.EXPBIAS = 6; - var c = input.charCodeAt(mypos++); - this.count = (16 + (c & 15)) << ((c >> 4) + this.EXPBIAS); - this.s2kLength = 10; - break; - - case 101: - if(input.substring(mypos+1, mypos+4) == "GNU") { - this.hashAlgorithm = input.charCodeAt(mypos++); - mypos += 3; // GNU - var gnuExtType = 1000 + input.charCodeAt(mypos++); - if(gnuExtType == 1001) { - this.type = gnuExtType; - this.s2kLength = 5; - // GnuPG extension mode 1001 -- don't write secret key at all - } else { - util.print_error("unknown s2k gnu protection mode! "+this.type); - } - } else { - util.print_error("unknown s2k type! "+this.type); - } - break; - - case 2: // Reserved value - default: - util.print_error("unknown s2k type! "+this.type); - break; - } - return this; - } - - - /** - * writes an s2k hash based on the inputs. - * @return {String} Produced key of hashAlgorithm hash length - */ - function write(type, hash, passphrase, salt, c){ - this.type = type; - if(this.type == 3){this.saltValue = salt; - this.hashAlgorithm = hash; - this.count = (16 + (c & 15)) << ((c >> 4) + 6); - this.s2kLength = 10; - } - return this.produce_key(passphrase); - } - - /** - * Produces a key using the specified passphrase and the defined - * hashAlgorithm - * @param {String} passphrase Passphrase containing user input - * @return {String} Produced key with a length corresponding to - * hashAlgorithm hash length - */ - function produce_key(passphrase, numBytes) { - passphrase = util.encode_utf8(passphrase); - if (this.type == 0) { - return openpgp_crypto_hashData(this.hashAlgorithm,passphrase); - } else if (this.type == 1) { - return openpgp_crypto_hashData(this.hashAlgorithm,this.saltValue+passphrase); - } else if (this.type == 3) { - var isp = []; - isp[0] = this.saltValue+passphrase; - while (isp.length*(this.saltValue+passphrase).length < this.count) - isp.push(this.saltValue+passphrase); - isp = isp.join(''); - if (isp.length > this.count) - isp = isp.substr(0, this.count); - if(numBytes && (numBytes == 24 || numBytes == 32)){ //This if accounts for RFC 4880 3.7.1.1 -- If hash size is greater than block size, use leftmost bits. If blocksize larger than hash size, we need to rehash isp and prepend with 0. - var key = openpgp_crypto_hashData(this.hashAlgorithm,isp); - return key + openpgp_crypto_hashData(this.hashAlgorithm,String.fromCharCode(0)+isp); - } - return openpgp_crypto_hashData(this.hashAlgorithm,isp); - } else return null; - } - - this.read = read; - this.write = write; - this.produce_key = produce_key; -} diff --git a/test/ciphers/symmetric/des.js b/test/ciphers/symmetric/des.js deleted file mode 100644 index ee96b4f7..00000000 --- a/test/ciphers/symmetric/des.js +++ /dev/null @@ -1,155 +0,0 @@ - -unittests.register("TripleDES (EDE) cipher test with test vectors from http://csrc.nist.gov/publications/nistpubs/800-20/800-20.pdf", function() { - var result = new Array(); - var key = util.bin2str([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]); - var testvectors = [[[0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x95,0xF8,0xA5,0xE5,0xDD,0x31,0xD9,0x00]], - [[0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0xDD,0x7F,0x12,0x1C,0xA5,0x01,0x56,0x19]], - [[0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x2E,0x86,0x53,0x10,0x4F,0x38,0x34,0xEA]], - [[0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x4B,0xD3,0x88,0xFF,0x6C,0xD8,0x1D,0x4F]], - [[0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x20,0xB9,0xE7,0x67,0xB2,0xFB,0x14,0x56]], - [[0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x55,0x57,0x93,0x80,0xD7,0x71,0x38,0xEF]], - [[0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x6C,0xC5,0xDE,0xFA,0xAF,0x04,0x51,0x2F]], - [[0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x0D,0x9F,0x27,0x9B,0xA5,0xD8,0x72,0x60]], - [[0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00],[0xD9,0x03,0x1B,0x02,0x71,0xBD,0x5A,0x0A]], - [[0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00],[0x42,0x42,0x50,0xB3,0x7C,0x3D,0xD9,0x51]], - [[0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00],[0xB8,0x06,0x1B,0x7E,0xCD,0x9A,0x21,0xE5]], - [[0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00],[0xF1,0x5D,0x0F,0x28,0x6B,0x65,0xBD,0x28]], - [[0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00],[0xAD,0xD0,0xCC,0x8D,0x6E,0x5D,0xEB,0xA1]], - [[0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00],[0xE6,0xD5,0xF8,0x27,0x52,0xAD,0x63,0xD1]], - [[0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00],[0xEC,0xBF,0xE3,0xBD,0x3F,0x59,0x1A,0x5E]], - [[0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00],[0xF3,0x56,0x83,0x43,0x79,0xD1,0x65,0xCD]], - [[0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00],[0x2B,0x9F,0x98,0x2F,0x20,0x03,0x7F,0xA9]], - [[0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00],[0x88,0x9D,0xE0,0x68,0xA1,0x6F,0x0B,0xE6]], - [[0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00],[0xE1,0x9E,0x27,0x5D,0x84,0x6A,0x12,0x98]], - [[0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00],[0x32,0x9A,0x8E,0xD5,0x23,0xD7,0x1A,0xEC]], - [[0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00],[0xE7,0xFC,0xE2,0x25,0x57,0xD2,0x3C,0x97]], - [[0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00],[0x12,0xA9,0xF5,0x81,0x7F,0xF2,0xD6,0x5D]], - [[0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00],[0xA4,0x84,0xC3,0xAD,0x38,0xDC,0x9C,0x19]], - [[0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00],[0xFB,0xE0,0x0A,0x8A,0x1E,0xF8,0xAD,0x72]], - [[0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00],[0x75,0x0D,0x07,0x94,0x07,0x52,0x13,0x63]], - [[0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00],[0x64,0xFE,0xED,0x9C,0x72,0x4C,0x2F,0xAF]], - [[0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00],[0xF0,0x2B,0x26,0x3B,0x32,0x8E,0x2B,0x60]], - [[0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00],[0x9D,0x64,0x55,0x5A,0x9A,0x10,0xB8,0x52]], - [[0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00],[0xD1,0x06,0xFF,0x0B,0xED,0x52,0x55,0xD7]], - [[0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00],[0xE1,0x65,0x2C,0x6B,0x13,0x8C,0x64,0xA5]], - [[0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00],[0xE4,0x28,0x58,0x11,0x86,0xEC,0x8F,0x46]], - [[0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00],[0xAE,0xB5,0xF5,0xED,0xE2,0x2D,0x1A,0x36]], - [[0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00],[0xE9,0x43,0xD7,0x56,0x8A,0xEC,0x0C,0x5C]], - [[0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00],[0xDF,0x98,0xC8,0x27,0x6F,0x54,0xB0,0x4B]], - [[0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00],[0xB1,0x60,0xE4,0x68,0x0F,0x6C,0x69,0x6F]], - [[0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00],[0xFA,0x07,0x52,0xB0,0x7D,0x9C,0x4A,0xB8]], - [[0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00],[0xCA,0x3A,0x2B,0x03,0x6D,0xBC,0x85,0x02]], - [[0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00],[0x5E,0x09,0x05,0x51,0x7B,0xB5,0x9B,0xCF]], - [[0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00],[0x81,0x4E,0xEB,0x3B,0x91,0xD9,0x07,0x26]], - [[0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00],[0x4D,0x49,0xDB,0x15,0x32,0x91,0x9C,0x9F]], - [[0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00],[0x25,0xEB,0x5F,0xC3,0xF8,0xCF,0x06,0x21]], - [[0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00],[0xAB,0x6A,0x20,0xC0,0x62,0x0D,0x1C,0x6F]], - [[0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00],[0x79,0xE9,0x0D,0xBC,0x98,0xF9,0x2C,0xCA]], - [[0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00],[0x86,0x6E,0xCE,0xDD,0x80,0x72,0xBB,0x0E]], - [[0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00],[0x8B,0x54,0x53,0x6F,0x2F,0x3E,0x64,0xA8]], - [[0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00],[0xEA,0x51,0xD3,0x97,0x55,0x95,0xB8,0x6B]], - [[0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00],[0xCA,0xFF,0xC6,0xAC,0x45,0x42,0xDE,0x31]], - [[0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00],[0x8D,0xD4,0x5A,0x2D,0xDF,0x90,0x79,0x6C]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00],[0x10,0x29,0xD5,0x5E,0x88,0x0E,0xC2,0xD0]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00],[0x5D,0x86,0xCB,0x23,0x63,0x9D,0xBE,0xA9]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00],[0x1D,0x1C,0xA8,0x53,0xAE,0x7C,0x0C,0x5F]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00],[0xCE,0x33,0x23,0x29,0x24,0x8F,0x32,0x28]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00],[0x84,0x05,0xD1,0xAB,0xE2,0x4F,0xB9,0x42]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00],[0xE6,0x43,0xD7,0x80,0x90,0xCA,0x42,0x07]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00],[0x48,0x22,0x1B,0x99,0x37,0x74,0x8A,0x23]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00],[0xDD,0x7C,0x0B,0xBD,0x61,0xFA,0xFD,0x54]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80],[0x2F,0xBC,0x29,0x1A,0x57,0x0D,0xB5,0xC4]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40],[0xE0,0x7C,0x30,0xD7,0xE4,0xE2,0x6E,0x12]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20],[0x09,0x53,0xE2,0x25,0x8E,0x8E,0x90,0xA1]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10],[0x5B,0x71,0x1B,0xC4,0xCE,0xEB,0xF2,0xEE]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08],[0xCC,0x08,0x3F,0x1E,0x6D,0x9E,0x85,0xF6]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04],[0xD2,0xFD,0x88,0x67,0xD5,0x0D,0x2D,0xFE]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02],[0x06,0xE7,0xEA,0x22,0xCE,0x92,0x70,0x8F]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01],[0x16,0x6B,0x40,0xB4,0x4A,0xBA,0x4B,0xD6]]]; - - var res = true; - var j = 0; - for (var i = 0; i < testvectors.length; i++) { - var deseded = desede(testvectors[i][0], key); - var res2 = (util.bin2str(deseded) == util.bin2str(testvectors[i][1])); - res &= res2; - if (!res2) { - result[j] = new test_result("Testing vector with block "+ - util.hexidump(testvectors[i][0])+ - " and key "+util.hexstrdump(key)+ - " should be "+util.hexidump(testvectors[i][1])+" != "+util.hexidump(deseded), - false); - j++; - } - } - if (res) { - result[j] = new test_result("All " + testvectors.length + " 3DES EDE test vectors completed", true); - } - return result; -}); - - -unittests.register("DES encrypt/decrypt padding tests", function() { - var result = new Array(); - var key = util.bin2str([0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF]); - var testvectors = new Array(); - testvectors[0] = [[[0x01],[0x24,0xC7,0x4A,0x9A,0x79,0x75,0x4B,0xC7]], - [[0x02,0x03],[0xA7,0x7A,0x9A,0x59,0x8A,0x86,0x85,0xC5]], - [[0x03,0x04,0x05],[0x01,0xCF,0xEB,0x6A,0x74,0x60,0xF5,0x02]], - [[0x04,0x05,0x06,0x07],[0xA8,0xF0,0x3D,0x59,0xBA,0x6B,0x0E,0x76]], - [[0x05,0x06,0x07,0x08,0x09],[0x86,0x40,0x33,0x61,0x3F,0x55,0x73,0x49]], - [[0x06,0x07,0x08,0x09,0x0A,0x0B],[0x13,0x21,0x3E,0x0E,0xCE,0x2C,0x94,0x01]], - [[0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D],[0x30,0x49,0x97,0xC1,0xDA,0xD5,0x59,0xA5]], - [[0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F],[0x83,0x25,0x79,0x06,0x54,0xA4,0x44,0xD9]]]; - testvectors[1] = [[[0x01],[0xF2,0xAB,0x1C,0x9E,0x70,0x7D,0xCC,0x92]], - [[0x02,0x03],[0x6B,0x4C,0x67,0x24,0x9F,0xB7,0x4D,0xAC]], - [[0x03,0x04,0x05],[0x68,0x95,0xAB,0xA8,0xEA,0x53,0x13,0x23]], - [[0x04,0x05,0x06,0x07],[0xC8,0xDE,0x60,0x8F,0xF6,0x09,0x90,0xB5]], - [[0x05,0x06,0x07,0x08,0x09],[0x19,0x13,0x50,0x20,0x70,0x40,0x2E,0x09]], - [[0x06,0x07,0x08,0x09,0x0A,0x0B],[0xA8,0x23,0x40,0xC6,0x17,0xA6,0x31,0x4A]], - [[0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D],[0x36,0x62,0xF2,0x99,0x68,0xD4,0xBF,0x7C]], - [[0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F],[0x83,0x25,0x79,0x06,0x54,0xA4,0x44,0xD9,0x08,0x6F,0x9A,0x1D,0x74,0xC9,0x4D,0x4E]]]; - testvectors[2] = [[[0x01],[0x83,0x68,0xE4,0x9C,0x84,0xCC,0xCB,0xF0]], - [[0x02,0x03],[0xBB,0xA8,0x0B,0x66,0x1B,0x62,0xC4,0xC8]], - [[0x03,0x04,0x05],[0x9A,0xD7,0x5A,0x24,0xFD,0x3F,0xBF,0x22]], - [[0x04,0x05,0x06,0x07],[0x14,0x4E,0x68,0x6D,0x2E,0xC1,0xB7,0x52]], - [[0x05,0x06,0x07,0x08,0x09],[0x12,0x0A,0x51,0x08,0xF9,0xA3,0x03,0x74]], - [[0x06,0x07,0x08,0x09,0x0A,0x0B],[0xB2,0x07,0xD1,0x05,0xF6,0x67,0xAF,0xBA]], - [[0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D],[0xCA,0x59,0x61,0x3A,0x83,0x23,0x26,0xDD]], - [[0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F],[0x83,0x25,0x79,0x06,0x54,0xA4,0x44,0xD9]]]; - - var keys = des_createKeys(key); - - var res = true; - var j = 0; - - for (var padding = 0; padding < 3; padding++) { - var thisVectorSet = testvectors[padding]; - - for (var i = 0; i < thisVectorSet.length; i++) { - var encrypted = des(keys, util.bin2str(thisVectorSet[i][0]), true, 0, null, padding); - var decrypted = des(keys, encrypted, false, 0, null, padding); - - var res2 = (encrypted == util.bin2str(thisVectorSet[i][1])); - var res3 = (decrypted == util.bin2str(thisVectorSet[i][0])); - res &= res2; - res &= res3; - if (!res2 || !res3) { - result[j] = new test_result( - "Testing vector with block [" + - util.hexidump(thisVectorSet[i][0]) + - "] and key [" + util.hexstrdump(key) + - "] and padding [" + padding + - "] should be " + util.hexidump(thisVectorSet[i][1]) + " - Actually [ENC:" + util.hexdump(encrypted) + ", DEC:" + util.hexdump(decrypted) + "]", - false); - j++; - } - } - } - if (res) { - result[j] = new test_result("All DES test vectors completed", true); - } - return result; -}); - - diff --git a/test/integration/index.html b/test/integration/index.html deleted file mode 100644 index ca87d20d..00000000 --- a/test/integration/index.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - JavaScript Unit Tests - - - - -
- - - - - - - - - diff --git a/test/integration/main.js b/test/integration/main.js deleted file mode 100644 index 4f26593f..00000000 --- a/test/integration/main.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict'; - -// config require.js -require.config({ - baseUrl: './', - paths: { - openpgp: '../../resources/openpgp', - jquery: '../../resources/jquery.min' - }, - shim: { - openpgp: { - exports: 'window' - }, - jquery: { - exports: 'window' - } - } -}); - -// start mocha tests -mocha.setup('bdd'); -require( - [ - 'pgp-test' - ], function() { - // require modules loaded -> run tests - mocha.run(); - } -); diff --git a/test/integration/pgp-test.js b/test/integration/pgp-test.js deleted file mode 100644 index 7d1082f6..00000000 --- a/test/integration/pgp-test.js +++ /dev/null @@ -1,253 +0,0 @@ -define(function(require) { - 'use strict'; - - var PGP = require('pgp'), - expect = chai.expect; - - describe('PGP Crypto Api unit tests', function() { - var pgp, - user = 'test@t-online.de', - passphrase = 'asdf', - keySize = 512, - keyId = 'F6F60E9B42CDFF4C', - pubkey = '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' + - 'Version: OpenPGP.js v.1.20131011\n' + - 'Comment: http://openpgpjs.org\n' + - '\n' + - 'xk0EUlhMvAEB/2MZtCUOAYvyLFjDp3OBMGn3Ev8FwjzyPbIF0JUw+L7y2XR5\n' + - 'RVGvbK88unV3cU/1tOYdNsXI6pSp/Ztjyv7vbBUAEQEAAc0pV2hpdGVvdXQg\n' + - 'VXNlciA8d2hpdGVvdXQudGVzdEB0LW9ubGluZS5kZT7CXAQQAQgAEAUCUlhM\n' + - 'vQkQ9vYOm0LN/0wAAAW4Af9C+kYW1AvNWmivdtr0M0iYCUjM9DNOQH1fcvXq\n' + - 'IiN602mWrkd8jcEzLsW5IUNzVPLhrFIuKyBDTpLnC07Loce1\n' + - '=6XMW\n' + - '-----END PGP PUBLIC KEY BLOCK-----', - privkey = '-----BEGIN PGP PRIVATE KEY BLOCK-----\n' + - 'Version: OpenPGP.js v.1.20131011\n' + - 'Comment: http://openpgpjs.org\n' + - '\n' + - 'xcBeBFJYTLwBAf9jGbQlDgGL8ixYw6dzgTBp9xL/BcI88j2yBdCVMPi+8tl0\n' + - 'eUVRr2yvPLp1d3FP9bTmHTbFyOqUqf2bY8r+72wVABEBAAH+AwMIhNB4ivtv\n' + - 'Y2xg6VeMcjjHxZayESHACV+nQx5Tx6ev6xzIF1Qh72fNPDppLhFSFOuTTMsU\n' + - 'kTN4c+BVYt29spH+cA1jcDAxQ2ULrNAXo+hheOqhpedTs8aCbcLFkJAS16hk\n' + - 'YSk4OnJgp/z24rVju1SHRSFbgundPzmNgXeX9e8IkviGhhQ11Wc5YwVkx03t\n' + - 'Z3MdDMF0jyhopbPIoBdyJB0dhvBh98w3JmwpYh9wjUA9MBHD1tvHpRmSZ3BM\n' + - 'UCmATn2ZLWBRWiYqFbgDnL1GM80pV2hpdGVvdXQgVXNlciA8d2hpdGVvdXQu\n' + - 'dGVzdEB0LW9ubGluZS5kZT7CXAQQAQgAEAUCUlhMvQkQ9vYOm0LN/0wAAAW4\n' + - 'Af9C+kYW1AvNWmivdtr0M0iYCUjM9DNOQH1fcvXqIiN602mWrkd8jcEzLsW5\n' + - 'IUNzVPLhrFIuKyBDTpLnC07Loce1\n' + - '=ULta\n' + - '-----END PGP PRIVATE KEY BLOCK-----'; - - beforeEach(function() { - pgp = new PGP(); - }); - - afterEach(function() {}); - - describe('Generate key pair', function() { - it('should fail', function(done) { - pgp.generateKeys({ - emailAddress: 'test@t-onlinede', - keySize: keySize, - passphrase: passphrase - }, function(err, keys) { - expect(err).to.exist; - expect(keys).to.not.exist; - done(); - }); - }); - it('should fail', function(done) { - pgp.generateKeys({ - emailAddress: 'testt-online.de', - keySize: keySize, - passphrase: passphrase - }, function(err, keys) { - expect(err).to.exist; - expect(keys).to.not.exist; - done(); - }); - }); - it('should work', function(done) { - pgp.generateKeys({ - emailAddress: user, - keySize: keySize, - passphrase: passphrase - }, function(err, keys) { - expect(err).to.not.exist; - expect(keys.keyId).to.exist; - expect(keys.privateKeyArmored).to.exist; - expect(keys.publicKeyArmored).to.exist; - done(); - }); - }); - }); - - describe('Import/Export key pair', function() { - it('should fail', function(done) { - pgp.importKeys({ - passphrase: 'asd', - privateKeyArmored: privkey, - publicKeyArmored: pubkey - }, function(err) { - expect(err).to.exist; - - pgp.exportKeys(function(err, keys) { - expect(err).to.exist; - expect(keys).to.not.exist; - done(); - }); - }); - }); - it('should work', function(done) { - pgp.importKeys({ - passphrase: passphrase, - privateKeyArmored: privkey, - publicKeyArmored: pubkey - }, function(err) { - expect(err).to.not.exist; - - pgp.exportKeys(function(err, keys) { - expect(err).to.not.exist; - expect(keys.keyId).to.equal(keyId); - expect(keys.privateKeyArmored).to.equal(privkey); - expect(keys.publicKeyArmored).to.equal(pubkey); - done(); - }); - }); - }); - }); - - describe('Encryption', function() { - var message = 'asdfs\n\nThursday, Nov 21, 2013 7:38 PM asdf@example.com wrote:\n' + - '> asdf\n' + - '> \n' + - '> Thursday, Nov 21, 2013 7:32 PM asdf@example.com wrote:\n' + - '> > secret 3', - ciphertext; - - beforeEach(function(done) { - pgp.importKeys({ - passphrase: passphrase, - privateKeyArmored: privkey, - publicKeyArmored: pubkey - }, function(err) { - expect(err).to.not.exist; - done(); - }); - }); - - describe('Encrypt and Sign', function() { - it('should work', function(done) { - pgp.encrypt(message, [pubkey], function(err, ct) { - expect(err).to.not.exist; - expect(ct).to.exist; - ciphertext = ct; - done(); - }); - }); - }); - - describe('Decrypt and Verify', function() { - it('should work', function(done) { - pgp.decrypt(ciphertext, pubkey, function(err, pt) { - expect(err).to.not.exist; - expect(pt.text).to.equal(message.replace(/\r/g,'').replace(/\n/g,"\r\n")); - expect(pt.validSignatures[0]).to.be.true; - done(); - }); - }); - }); - - }); - - describe('Verify clearsign from gpg', function() { - var v3_clearsign_msg = '-----BEGIN PGP SIGNED MESSAGE-----\r\n' + - 'Hash: SHA1\r\n' + - '\r\n' + - 'This is a test message.\r\n' + - '\r\n' + - 'This paragraph is separated form the next by a line of dashes.\r\n' + - '\r\n' + - '- --------------------------------------------------------------------------\r\n' + - '\r\n' + - 'The next paragraph has a number of blank lines between this one and it.\r\n' + - '\r\n' + - '\r\n' + - '\r\n' + - '\r\n' + - '\r\n' + - '\r\n' + - 'This is the last paragraph.\r\n' + - '\r\n' + - '- --\r\n' + - '\r\n' + - 'Joe Test\r\n' + - '-----BEGIN PGP SIGNATURE-----\r\n' + - 'Version: GnuPG v1.4.15 (GNU/Linux)\r\n' + - '\r\n' + - 'iQBVAwUBUp/7GPb2DptCzf9MAQKviQH6A6Pqa63kxWI+atMiaSXz5uifgsBoiOof\r\n' + - 'E3/oVTIGyGTgB7KnwZiFkDMFrUNREJVSQGt6+4nxje8gARcuYpMnWw==\r\n' + - '=lOCC\r\n' + - '-----END PGP SIGNATURE-----\r\n'; - var v4_clearsign_msg = '-----BEGIN PGP SIGNED MESSAGE-----\r\n' + - 'Hash: SHA1\r\n' + - '\r\n' + - 'This is a test message.\r\n' + - '\r\n' + - 'This paragraph is separated form the next by a line of dashes.\r\n' + - '\r\n' + - '- --------------------------------------------------------------------------\r\n' + - '\r\n' + - 'The next paragraph has a number of blank lines between this one and it.\r\n' + - '\r\n' + - '\r\n' + - '\r\n' + - '\r\n' + - '\r\n' + - '\r\n' + - 'This is the last paragraph.\r\n' + - '\r\n' + - '- --\r\n' + - '\r\n' + - 'Joe Test\r\n' + - '-----BEGIN PGP SIGNATURE-----\r\n' + - 'Version: GnuPG v1.4.15 (GNU/Linux)\r\n' + - '\r\n' + - 'iFwEAQECAAYFAlKf5LcACgkQ9vYOm0LN/0ybVwH8CItdDh4kWKVcyUx3Q3hWZnWd\r\n' + - 'zP9CUbIa9uToIPABjV3GOTDM3ZgiP0/SE6Al5vG8hlx+/u2piVojoLovk/4LnA==\r\n' + - '=i6ew\r\n' + - '-----END PGP SIGNATURE-----\r\n'; - - beforeEach(function(done) { - pgp.importKeys({ - passphrase: passphrase, - privateKeyArmored: privkey, - publicKeyArmored: pubkey - }, function(err) { - expect(err).to.not.exist; - done(); - }); - }); - - describe('Verify V3 signature', function() { - it('should work', function(done) { - pgp.verify(v3_clearsign_msg, pubkey, function(err, pt) { - expect(err).to.not.exist; - expect(pt).to.be.true; - done(); - }); - }); - }); - - describe('Verify V4 signature', function() { - it('should work', function(done) { - pgp.verify(v4_clearsign_msg, pubkey, function(err, pt) { - expect(err).to.not.exist; - expect(pt).to.be.true; - done(); - }); - }); - }); - }); - }); - }); diff --git a/test/integration/pgp.js b/test/integration/pgp.js deleted file mode 100644 index 65479279..00000000 --- a/test/integration/pgp.js +++ /dev/null @@ -1,191 +0,0 @@ -/** - * High level crypto api that handles all calls to OpenPGP.js - */ -function showMessages(str) { -} - -define(function(require) { - 'use strict'; - - var openpgp = require('openpgp').openpgp, - util = require('openpgp').util, - jquery = require('jquery').jquery; - - var PGP = function() { - openpgp.init(); - }; - - /** - * Generate a key pair for the user - */ - PGP.prototype.generateKeys = function(options, callback) { - var keys, userId; - - if (!util.emailRegEx.test(options.emailAddress) || !options.keySize || typeof options.passphrase !== 'string') { - callback({ - errMsg: 'Crypto init failed. Not all options set!' - }); - return; - } - - // generate keypair (keytype 1=RSA) - try { - userId = 'Whiteout User <' + options.emailAddress + '>'; - keys = openpgp.generate_key_pair(1, options.keySize, userId, options.passphrase); - } catch (e) { - callback({ - errMsg: 'Keygeneration failed!', - err: e - }); - return; - } - - callback(null, { - keyId: util.hexstrdump(keys.privateKey.getKeyId()).toUpperCase(), - privateKeyArmored: keys.privateKeyArmored, - publicKeyArmored: keys.publicKeyArmored - }); - }; - - /** - * Import the user's key pair - */ - PGP.prototype.importKeys = function(options, callback) { - var publicKey, privateKey; - - // check passphrase - if (typeof options.passphrase !== 'string' || !options.privateKeyArmored || !options.publicKeyArmored) { - callback({ - errMsg: 'Importing keys failed. Not all options set!' - }); - return; - } - - // clear any keypair already in the keychain - openpgp.keyring.init(); - // unlock and import private key - if (!openpgp.keyring.importPrivateKey(options.privateKeyArmored, options.passphrase)) { - openpgp.keyring.init(); - callback({ - errMsg: 'Incorrect passphrase!' - }); - return; - } - // import public key - openpgp.keyring.importPublicKey(options.publicKeyArmored); - - // check if keys have the same id - privateKey = openpgp.keyring.exportPrivateKey(0); - publicKey = openpgp.keyring.getPublicKeysForKeyId(privateKey.keyId)[0]; - if (!privateKey || !privateKey.armored || !publicKey || !publicKey.armored || privateKey.keyId !== publicKey.keyId) { - // reset keyring - openpgp.keyring.init(); - callback({ - errMsg: 'Key IDs dont match!' - }); - return; - } - - callback(); - }; - - /** - * Export the user's key pair - */ - PGP.prototype.exportKeys = function(callback) { - var publicKey, privateKey; - - privateKey = openpgp.keyring.exportPrivateKey(0); - if (privateKey && privateKey.keyId) { - publicKey = openpgp.keyring.getPublicKeysForKeyId(privateKey.keyId)[0]; - } - - if (!privateKey || !privateKey.keyId || !privateKey.armored || !publicKey || !publicKey.armored) { - callback({ - errMsg: 'Could not export keys!' - }); - return; - } - - callback(null, { - keyId: util.hexstrdump(privateKey.keyId).toUpperCase(), - privateKeyArmored: privateKey.armored, - publicKeyArmored: publicKey.armored - }); - }; - - /** - * Encrypt and sign a pgp message for a list of receivers - */ - PGP.prototype.encrypt = function(plaintext, receiverKeys, callback) { - var ct, i, - privateKey = openpgp.keyring.exportPrivateKey(0).obj; - - for (i = 0; i < receiverKeys.length; i++) { - receiverKeys[i] = openpgp.read_publicKey(receiverKeys[i])[0]; - } - - ct = openpgp.write_signed_and_encrypted_message(privateKey, receiverKeys, plaintext); - - callback(null, ct); - }; - - /** - * Decrypt and verify a pgp message for a single sender - */ - PGP.prototype.decrypt = function(ciphertext, senderKey, callback) { - var privateKey = openpgp.keyring.exportPrivateKey(0).obj; - var publicKey = openpgp.read_publicKey(senderKey)[0]; - var pubKeys = [ { armored: senderKey, obj: publicKey, keyId: publicKey.getKeyId() } ]; - - var msg = openpgp.read_message(ciphertext)[0]; - var keymat = null; - var sesskey = null; - - // Find the private (sub)key for the session key of the message - for (var i = 0; i < msg.sessionKeys.length; i++) { - if (privateKey.privateKeyPacket.publicKey.getKeyId() === msg.sessionKeys[i].keyId.bytes) { - keymat = { - key: privateKey, - keymaterial: privateKey.privateKeyPacket - }; - sesskey = msg.sessionKeys[i]; - break; - } - for (var j = 0; j < privateKey.subKeys.length; j++) { - if (privateKey.subKeys[j].publicKey.getKeyId() === msg.sessionKeys[i].keyId.bytes) { - keymat = { - key: privateKey, - keymaterial: privateKey.subKeys[j] - }; - sesskey = msg.sessionKeys[i]; - break; - } - } - } - if (keymat !== null) { - var decrypted = msg.decryptAndVerifySignature(keymat, sesskey, pubKeys); - callback(null, decrypted); - - } else { - callback({ - errMsg: 'No private key found!' - }); - } - }; - - /** - * Verify a clearsign message for a single sender - */ - PGP.prototype.verify = function(message, senderKey, callback) { - var publicKey = openpgp.read_publicKey(senderKey)[0]; - var pubKeys = [ { armored: senderKey, obj: publicKey, keyId: publicKey.getKeyId() } ]; - - var msg = openpgp.read_message(message)[0]; - - var verified = msg.verifySignature(pubKeys); - callback(null, verified); - }; - - return PGP; -});