WTF WORKS IF U TRY A TON???????????

This commit is contained in:
ayunami2000 2022-01-23 19:55:36 -05:00
parent fbe96f6469
commit 3099109d0d
83 changed files with 25898 additions and 18866 deletions

161
javascript/asn1-parser.js Normal file
View File

@ -0,0 +1,161 @@
// Copyright 2018 AJ ONeal. All rights reserved
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
;(function (exports) {
'use strict';
if (!exports.ASN1) { exports.ASN1 = {}; }
if (!exports.Enc) { exports.Enc = {}; }
if (!exports.PEM) { exports.PEM = {}; }
var ASN1 = exports.ASN1;
var Enc = exports.Enc;
var PEM = exports.PEM;
//
// Parser
//
// Although I've only seen 9 max in https certificates themselves,
// but each domain list could have up to 100
ASN1.ELOOPN = 102;
ASN1.ELOOP = "uASN1.js Error: iterated over " + ASN1.ELOOPN + "+ elements (probably a malformed file)";
// I've seen https certificates go 29 deep
ASN1.EDEEPN = 60;
ASN1.EDEEP = "uASN1.js Error: element nested " + ASN1.EDEEPN + "+ layers deep (probably a malformed file)";
// Container Types are Sequence 0x30, Container Array? (0xA0, 0xA1)
// Value Types are Boolean 0x01, Integer 0x02, Null 0x05, Object ID 0x06, String 0x0C, 0x16, 0x13, 0x1e Value Array? (0x82)
// Bit String (0x03) and Octet String (0x04) may be values or containers
// Sometimes Bit String is used as a container (RSA Pub Spki)
ASN1.CTYPES = [ 0x30, 0x31, 0xa0, 0xa1 ];
ASN1.VTYPES = [ 0x01, 0x02, 0x05, 0x06, 0x0c, 0x82 ];
ASN1.parse = function parseAsn1Helper(buf) {
//var ws = ' ';
function parseAsn1(buf, depth, eager) {
if (depth.length >= ASN1.EDEEPN) { throw new Error(ASN1.EDEEP); }
var index = 2; // we know, at minimum, data starts after type (0) and lengthSize (1)
var asn1 = { type: buf[0], lengthSize: 0, length: buf[1] };
var child;
var iters = 0;
var adjust = 0;
var adjustedLen;
// Determine how many bytes the length uses, and what it is
if (0x80 & asn1.length) {
asn1.lengthSize = 0x7f & asn1.length;
// I think that buf->hex->int solves the problem of Endianness... not sure
asn1.length = parseInt(Enc.bufToHex(buf.slice(index, index + asn1.lengthSize)), 16);
index += asn1.lengthSize;
}
// High-order bit Integers have a leading 0x00 to signify that they are positive.
// Bit Streams use the first byte to signify padding, which x.509 doesn't use.
if (0x00 === buf[index] && (0x02 === asn1.type || 0x03 === asn1.type)) {
// However, 0x00 on its own is a valid number
if (asn1.length > 1) {
index += 1;
adjust = -1;
}
}
adjustedLen = asn1.length + adjust;
//console.warn(depth.join(ws) + '0x' + Enc.numToHex(asn1.type), index, 'len:', asn1.length, asn1);
function parseChildren(eager) {
asn1.children = [];
//console.warn('1 len:', (2 + asn1.lengthSize + asn1.length), 'idx:', index, 'clen:', 0);
while (iters < ASN1.ELOOPN && index < (2 + asn1.length + asn1.lengthSize)) {
iters += 1;
depth.length += 1;
child = parseAsn1(buf.slice(index, index + adjustedLen), depth, eager);
depth.length -= 1;
// The numbers don't match up exactly and I don't remember why...
// probably something with adjustedLen or some such, but the tests pass
index += (2 + child.lengthSize + child.length);
//console.warn('2 len:', (2 + asn1.lengthSize + asn1.length), 'idx:', index, 'clen:', (2 + child.lengthSize + child.length));
if (index > (2 + asn1.lengthSize + asn1.length)) {
if (!eager) { console.error(JSON.stringify(asn1, ASN1._replacer, 2)); }
throw new Error("Parse error: child value length (" + child.length
+ ") is greater than remaining parent length (" + (asn1.length - index)
+ " = " + asn1.length + " - " + index + ")");
}
asn1.children.push(child);
//console.warn(depth.join(ws) + '0x' + Enc.numToHex(asn1.type), index, 'len:', asn1.length, asn1);
}
if (index !== (2 + asn1.lengthSize + asn1.length)) {
//console.warn('index:', index, 'length:', (2 + asn1.lengthSize + asn1.length));
throw new Error("premature end-of-file");
}
if (iters >= ASN1.ELOOPN) { throw new Error(ASN1.ELOOP); }
delete asn1.value;
return asn1;
}
// Recurse into types that are _always_ containers
if (-1 !== ASN1.CTYPES.indexOf(asn1.type)) { return parseChildren(eager); }
// Return types that are _always_ values
asn1.value = buf.slice(index, index + adjustedLen);
if (-1 !== ASN1.VTYPES.indexOf(asn1.type)) { return asn1; }
// For ambigious / unknown types, recurse and return on failure
// (and return child array size to zero)
try { return parseChildren(true); }
catch(e) { asn1.children.length = 0; return asn1; }
}
var asn1 = parseAsn1(buf, []);
var len = buf.byteLength || buf.length;
if (len !== 2 + asn1.lengthSize + asn1.length) {
throw new Error("Length of buffer does not match length of ASN.1 sequence.");
}
return asn1;
};
ASN1._replacer = function (k, v) {
if ('type' === k) { return '0x' + Enc.numToHex(v); }
if (v && 'value' === k) { return '0x' + Enc.bufToHex(v.data || v); }
return v;
};
// don't replace the full parseBlock, if it exists
PEM.parseBlock = PEM.parseBlock || function (str) {
var der = str.split(/\n/).filter(function (line) {
return !/-----/.test(line);
}).join('');
return { der: Enc.base64ToBuf(der) };
};
Enc.base64ToBuf = function (b64) {
return Enc.binToBuf(atob(b64));
};
Enc.binToBuf = function (bin) {
var arr = bin.split('').map(function (ch) {
return ch.charCodeAt(0);
});
return 'undefined' !== typeof Uint8Array ? new Uint8Array(arr) : arr;
};
Enc.bufToHex = function (u8) {
var hex = [];
var i, h;
var len = (u8.byteLength || u8.length);
for (i = 0; i < len; i += 1) {
h = u8[i].toString(16);
if (h.length % 2) { h = '0' + h; }
hex.push(h);
}
return hex.join('').toLowerCase();
};
Enc.numToHex = function (d) {
d = d.toString(16);
if (d.length % 2) {
return '0' + d;
}
return d;
};
}('undefined' !== typeof window ? window : module.exports));

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,17 @@
<html> <html>
<head> <head>
<title>eagler</title> <title>eagler</title>
<script type="text/javascript" src="jsencrypt.min.js"></script>
<script type="text/javascript" src="jsbn/jsbn.js"></script>
<script type="text/javascript" src="jsbn/jsbn2.js"></script>
<script type="text/javascript" src="jsbn/prng4.js"></script>
<script type="text/javascript" src="jsbn/rng.js"></script>
<script type="text/javascript" src="jsbn/rsa.js"></script>
<script type="text/javascript" src="jsbn/rsa2.js"></script>
<script type="text/javascript" src="jsbn/base64.js"></script>
<script type="text/javascript" src="asn1-parser.js"></script>
<script type="text/javascript" src="classes.js"></script> <script type="text/javascript" src="classes.js"></script>
<!--script src="https://unpkg.com/@peculiar/x509"></script--> <!--script src="https://unpkg.com/@peculiar/x509"></script-->
<script type="text/javascript"> <script type="text/javascript">

71
javascript/jsbn/base64.js Normal file
View File

@ -0,0 +1,71 @@
var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var b64padchar="=";
function hex2b64(h) {
var i;
var c;
var ret = "";
for(i = 0; i+3 <= h.length; i+=3) {
c = parseInt(h.substring(i,i+3),16);
ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
}
if(i+1 == h.length) {
c = parseInt(h.substring(i,i+1),16);
ret += b64map.charAt(c << 2);
}
else if(i+2 == h.length) {
c = parseInt(h.substring(i,i+2),16);
ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
}
while((ret.length & 3) > 0) ret += b64padchar;
return ret;
}
// convert a base64 string to hex
function b64tohex(s) {
var ret = ""
var i;
var k = 0; // b64 state, 0-3
var slop;
for(i = 0; i < s.length; ++i) {
if(s.charAt(i) == b64padchar) break;
v = b64map.indexOf(s.charAt(i));
if(v < 0) continue;
if(k == 0) {
ret += int2char(v >> 2);
slop = v & 3;
k = 1;
}
else if(k == 1) {
ret += int2char((slop << 2) | (v >> 4));
slop = v & 0xf;
k = 2;
}
else if(k == 2) {
ret += int2char(slop);
ret += int2char(v >> 2);
slop = v & 3;
k = 3;
}
else {
ret += int2char((slop << 2) | (v >> 4));
ret += int2char(v & 0xf);
k = 0;
}
}
if(k == 1)
ret += int2char(slop << 2);
return ret;
}
// convert a base64 string to a byte/number array
function b64toBA(s) {
//piggyback on b64tohex for now, optimize later
var h = b64tohex(s);
var i;
var a = new Array();
for(i = 0; 2*i < h.length; ++i) {
a[i] = parseInt(h.substring(2*i,2*i+2),16);
}
return a;
}

559
javascript/jsbn/jsbn.js Normal file
View File

@ -0,0 +1,559 @@
// Copyright (c) 2005 Tom Wu
// All Rights Reserved.
// See "LICENSE" for details.
// Basic JavaScript BN library - subset useful for RSA encryption.
// Bits per digit
var dbits;
// JavaScript engine analysis
var canary = 0xdeadbeefcafe;
var j_lm = ((canary&0xffffff)==0xefcafe);
// (public) Constructor
function BigInteger(a,b,c) {
if(a != null)
if("number" == typeof a) this.fromNumber(a,b,c);
else if(b == null && "string" != typeof a) this.fromString(a,256);
else this.fromString(a,b);
}
// return new, unset BigInteger
function nbi() { return new BigInteger(null); }
// am: Compute w_j += (x*this_i), propagate carries,
// c is initial carry, returns final carry.
// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
// We need to select the fastest one that works in this environment.
// am1: use a single mult and divide to get the high bits,
// max digit bits should be 26 because
// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
function am1(i,x,w,j,c,n) {
while(--n >= 0) {
var v = x*this[i++]+w[j]+c;
c = Math.floor(v/0x4000000);
w[j++] = v&0x3ffffff;
}
return c;
}
// am2 avoids a big mult-and-extract completely.
// Max digit bits should be <= 30 because we do bitwise ops
// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
function am2(i,x,w,j,c,n) {
var xl = x&0x7fff, xh = x>>15;
while(--n >= 0) {
var l = this[i]&0x7fff;
var h = this[i++]>>15;
var m = xh*l+h*xl;
l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);
c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
w[j++] = l&0x3fffffff;
}
return c;
}
// Alternately, set max digit bits to 28 since some
// browsers slow down when dealing with 32-bit numbers.
function am3(i,x,w,j,c,n) {
var xl = x&0x3fff, xh = x>>14;
while(--n >= 0) {
var l = this[i]&0x3fff;
var h = this[i++]>>14;
var m = xh*l+h*xl;
l = xl*l+((m&0x3fff)<<14)+w[j]+c;
c = (l>>28)+(m>>14)+xh*h;
w[j++] = l&0xfffffff;
}
return c;
}
if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
BigInteger.prototype.am = am2;
dbits = 30;
}
else if(j_lm && (navigator.appName != "Netscape")) {
BigInteger.prototype.am = am1;
dbits = 26;
}
else { // Mozilla/Netscape seems to prefer am3
BigInteger.prototype.am = am3;
dbits = 28;
}
BigInteger.prototype.DB = dbits;
BigInteger.prototype.DM = ((1<<dbits)-1);
BigInteger.prototype.DV = (1<<dbits);
var BI_FP = 52;
BigInteger.prototype.FV = Math.pow(2,BI_FP);
BigInteger.prototype.F1 = BI_FP-dbits;
BigInteger.prototype.F2 = 2*dbits-BI_FP;
// Digit conversions
var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
var BI_RC = new Array();
var rr,vv;
rr = "0".charCodeAt(0);
for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
rr = "a".charCodeAt(0);
for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
rr = "A".charCodeAt(0);
for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
function int2char(n) { return BI_RM.charAt(n); }
function intAt(s,i) {
var c = BI_RC[s.charCodeAt(i)];
return (c==null)?-1:c;
}
// (protected) copy this to r
function bnpCopyTo(r) {
for(var i = this.t-1; i >= 0; --i) r[i] = this[i];
r.t = this.t;
r.s = this.s;
}
// (protected) set from integer value x, -DV <= x < DV
function bnpFromInt(x) {
this.t = 1;
this.s = (x<0)?-1:0;
if(x > 0) this[0] = x;
else if(x < -1) this[0] = x+this.DV;
else this.t = 0;
}
// return bigint initialized to value
function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
// (protected) set from string and radix
function bnpFromString(s,b) {
var k;
if(b == 16) k = 4;
else if(b == 8) k = 3;
else if(b == 256) k = 8; // byte array
else if(b == 2) k = 1;
else if(b == 32) k = 5;
else if(b == 4) k = 2;
else { this.fromRadix(s,b); return; }
this.t = 0;
this.s = 0;
var i = s.length, mi = false, sh = 0;
while(--i >= 0) {
var x = (k==8)?s[i]&0xff:intAt(s,i);
if(x < 0) {
if(s.charAt(i) == "-") mi = true;
continue;
}
mi = false;
if(sh == 0)
this[this.t++] = x;
else if(sh+k > this.DB) {
this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
this[this.t++] = (x>>(this.DB-sh));
}
else
this[this.t-1] |= x<<sh;
sh += k;
if(sh >= this.DB) sh -= this.DB;
}
if(k == 8 && (s[0]&0x80) != 0) {
this.s = -1;
if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
}
this.clamp();
if(mi) BigInteger.ZERO.subTo(this,this);
}
// (protected) clamp off excess high words
function bnpClamp() {
var c = this.s&this.DM;
while(this.t > 0 && this[this.t-1] == c) --this.t;
}
// (public) return string representation in given radix
function bnToString(b) {
if(this.s < 0) return "-"+this.negate().toString(b);
var k;
if(b == 16) k = 4;
else if(b == 8) k = 3;
else if(b == 2) k = 1;
else if(b == 32) k = 5;
else if(b == 4) k = 2;
else return this.toRadix(b);
var km = (1<<k)-1, d, m = false, r = "", i = this.t;
var p = this.DB-(i*this.DB)%k;
if(i-- > 0) {
if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }
while(i >= 0) {
if(p < k) {
d = (this[i]&((1<<p)-1))<<(k-p);
d |= this[--i]>>(p+=this.DB-k);
}
else {
d = (this[i]>>(p-=k))&km;
if(p <= 0) { p += this.DB; --i; }
}
if(d > 0) m = true;
if(m) r += int2char(d);
}
}
return m?r:"0";
}
// (public) -this
function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
// (public) |this|
function bnAbs() { return (this.s<0)?this.negate():this; }
// (public) return + if this > a, - if this < a, 0 if equal
function bnCompareTo(a) {
var r = this.s-a.s;
if(r != 0) return r;
var i = this.t;
r = i-a.t;
if(r != 0) return (this.s<0)?-r:r;
while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
return 0;
}
// returns bit length of the integer x
function nbits(x) {
var r = 1, t;
if((t=x>>>16) != 0) { x = t; r += 16; }
if((t=x>>8) != 0) { x = t; r += 8; }
if((t=x>>4) != 0) { x = t; r += 4; }
if((t=x>>2) != 0) { x = t; r += 2; }
if((t=x>>1) != 0) { x = t; r += 1; }
return r;
}
// (public) return the number of bits in "this"
function bnBitLength() {
if(this.t <= 0) return 0;
return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
}
// (protected) r = this << n*DB
function bnpDLShiftTo(n,r) {
var i;
for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
for(i = n-1; i >= 0; --i) r[i] = 0;
r.t = this.t+n;
r.s = this.s;
}
// (protected) r = this >> n*DB
function bnpDRShiftTo(n,r) {
for(var i = n; i < this.t; ++i) r[i-n] = this[i];
r.t = Math.max(this.t-n,0);
r.s = this.s;
}
// (protected) r = this << n
function bnpLShiftTo(n,r) {
var bs = n%this.DB;
var cbs = this.DB-bs;
var bm = (1<<cbs)-1;
var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
for(i = this.t-1; i >= 0; --i) {
r[i+ds+1] = (this[i]>>cbs)|c;
c = (this[i]&bm)<<bs;
}
for(i = ds-1; i >= 0; --i) r[i] = 0;
r[ds] = c;
r.t = this.t+ds+1;
r.s = this.s;
r.clamp();
}
// (protected) r = this >> n
function bnpRShiftTo(n,r) {
r.s = this.s;
var ds = Math.floor(n/this.DB);
if(ds >= this.t) { r.t = 0; return; }
var bs = n%this.DB;
var cbs = this.DB-bs;
var bm = (1<<bs)-1;
r[0] = this[ds]>>bs;
for(var i = ds+1; i < this.t; ++i) {
r[i-ds-1] |= (this[i]&bm)<<cbs;
r[i-ds] = this[i]>>bs;
}
if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;
r.t = this.t-ds;
r.clamp();
}
// (protected) r = this - a
function bnpSubTo(a,r) {
var i = 0, c = 0, m = Math.min(a.t,this.t);
while(i < m) {
c += this[i]-a[i];
r[i++] = c&this.DM;
c >>= 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 < -1) r[i++] = this.DV+c;
else if(c > 0) r[i++] = c;
r.t = i;
r.clamp();
}
// (protected) r = this * a, r != this,a (HAC 14.12)
// "this" should be the larger one if appropriate.
function bnpMultiplyTo(a,r) {
var x = this.abs(), y = a.abs();
var i = x.t;
r.t = i+y.t;
while(--i >= 0) r[i] = 0;
for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
r.s = 0;
r.clamp();
if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
}
// (protected) r = this^2, r != this (HAC 14.16)
function bnpSquareTo(r) {
var x = this.abs();
var i = r.t = 2*x.t;
while(--i >= 0) r[i] = 0;
for(i = 0; i < x.t-1; ++i) {
var c = x.am(i,x[i],r,2*i,0,1);
if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
r[i+x.t] -= x.DV;
r[i+x.t+1] = 1;
}
}
if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
r.s = 0;
r.clamp();
}
// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
// r != q, this != m. q or r may be null.
function bnpDivRemTo(m,q,r) {
var pm = m.abs();
if(pm.t <= 0) return;
var pt = this.abs();
if(pt.t < pm.t) {
if(q != null) q.fromInt(0);
if(r != null) this.copyTo(r);
return;
}
if(r == null) r = nbi();
var y = nbi(), ts = this.s, ms = m.s;
var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus
if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
else { pm.copyTo(y); pt.copyTo(r); }
var ys = y.t;
var y0 = y[ys-1];
if(y0 == 0) return;
var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);
var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
var i = r.t, j = i-ys, t = (q==null)?nbi():q;
y.dlShiftTo(j,t);
if(r.compareTo(t) >= 0) {
r[r.t++] = 1;
r.subTo(t,r);
}
BigInteger.ONE.dlShiftTo(ys,t);
t.subTo(y,y); // "negative" y so we can replace sub with am later
while(y.t < ys) y[y.t++] = 0;
while(--j >= 0) {
// Estimate quotient digit
var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out
y.dlShiftTo(j,t);
r.subTo(t,r);
while(r[i] < --qd) r.subTo(t,r);
}
}
if(q != null) {
r.drShiftTo(ys,q);
if(ts != ms) BigInteger.ZERO.subTo(q,q);
}
r.t = ys;
r.clamp();
if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder
if(ts < 0) BigInteger.ZERO.subTo(r,r);
}
// (public) this mod a
function bnMod(a) {
var r = nbi();
this.abs().divRemTo(a,null,r);
if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
return r;
}
// Modular reduction using "classic" algorithm
function Classic(m) { this.m = m; }
function cConvert(x) {
if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
else return x;
}
function cRevert(x) { return x; }
function cReduce(x) { x.divRemTo(this.m,null,x); }
function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
Classic.prototype.convert = cConvert;
Classic.prototype.revert = cRevert;
Classic.prototype.reduce = cReduce;
Classic.prototype.mulTo = cMulTo;
Classic.prototype.sqrTo = cSqrTo;
// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
// justification:
// xy == 1 (mod m)
// xy = 1+km
// xy(2-xy) = (1+km)(1-km)
// x[y(2-xy)] = 1-k^2m^2
// x[y(2-xy)] == 1 (mod m^2)
// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
// JS multiply "overflows" differently from C/C++, so care is needed here.
function bnpInvDigit() {
if(this.t < 1) return 0;
var x = this[0];
if((x&1) == 0) return 0;
var y = x&3; // y == 1/x mod 2^2
y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4
y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8
y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16
// last step - calculate inverse mod DV directly;
// assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits
// we really want the negative inverse, and -DV < y < DV
return (y>0)?this.DV-y:-y;
}
// Montgomery reduction
function Montgomery(m) {
this.m = m;
this.mp = m.invDigit();
this.mpl = this.mp&0x7fff;
this.mph = this.mp>>15;
this.um = (1<<(m.DB-15))-1;
this.mt2 = 2*m.t;
}
// xR mod m
function montConvert(x) {
var r = nbi();
x.abs().dlShiftTo(this.m.t,r);
r.divRemTo(this.m,null,r);
if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
return r;
}
// x/R mod m
function montRevert(x) {
var r = nbi();
x.copyTo(r);
this.reduce(r);
return r;
}
// x = x/R mod m (HAC 14.32)
function montReduce(x) {
while(x.t <= this.mt2) // pad x so am has enough room later
x[x.t++] = 0;
for(var i = 0; i < this.m.t; ++i) {
// faster way of calculating u0 = x[i]*mp mod DV
var j = x[i]&0x7fff;
var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
// use am to combine the multiply-shift-add into one call
j = i+this.m.t;
x[j] += this.m.am(0,u0,x,i,0,this.m.t);
// propagate carry
while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
}
x.clamp();
x.drShiftTo(this.m.t,x);
if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
}
// r = "x^2/R mod m"; x != r
function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
// r = "xy/R mod m"; x,y != r
function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
Montgomery.prototype.convert = montConvert;
Montgomery.prototype.revert = montRevert;
Montgomery.prototype.reduce = montReduce;
Montgomery.prototype.mulTo = montMulTo;
Montgomery.prototype.sqrTo = montSqrTo;
// (protected) true iff this is even
function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
function bnpExp(e,z) {
if(e > 0xffffffff || e < 1) return BigInteger.ONE;
var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
g.copyTo(r);
while(--i >= 0) {
z.sqrTo(r,r2);
if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
else { var t = r; r = r2; r2 = t; }
}
return z.revert(r);
}
// (public) this^e % m, 0 <= e < 2^32
function bnModPowInt(e,m) {
var z;
if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
return this.exp(e,z);
}
// protected
BigInteger.prototype.copyTo = bnpCopyTo;
BigInteger.prototype.fromInt = bnpFromInt;
BigInteger.prototype.fromString = bnpFromString;
BigInteger.prototype.clamp = bnpClamp;
BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
BigInteger.prototype.drShiftTo = bnpDRShiftTo;
BigInteger.prototype.lShiftTo = bnpLShiftTo;
BigInteger.prototype.rShiftTo = bnpRShiftTo;
BigInteger.prototype.subTo = bnpSubTo;
BigInteger.prototype.multiplyTo = bnpMultiplyTo;
BigInteger.prototype.squareTo = bnpSquareTo;
BigInteger.prototype.divRemTo = bnpDivRemTo;
BigInteger.prototype.invDigit = bnpInvDigit;
BigInteger.prototype.isEven = bnpIsEven;
BigInteger.prototype.exp = bnpExp;
// public
BigInteger.prototype.toString = bnToString;
BigInteger.prototype.negate = bnNegate;
BigInteger.prototype.abs = bnAbs;
BigInteger.prototype.compareTo = bnCompareTo;
BigInteger.prototype.bitLength = bnBitLength;
BigInteger.prototype.mod = bnMod;
BigInteger.prototype.modPowInt = bnModPowInt;
// "constants"
BigInteger.ZERO = nbv(0);
BigInteger.ONE = nbv(1);

656
javascript/jsbn/jsbn2.js Normal file
View File

@ -0,0 +1,656 @@
// Copyright (c) 2005-2009 Tom Wu
// All Rights Reserved.
// See "LICENSE" for details.
// 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))<<this.DB)|this[0];
}
// (public) return value as byte
function bnByteValue() { return (this.t==0)?this.s:(this[0]<<24)>>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<<t)-1); else x[0] = 0;
this.fromString(x,256);
}
}
// (public) convert to bigendian byte array
function bnToByteArray() {
var i = this.t, r = new Array();
r[0] = this.s;
var p = this.DB-(i*this.DB)%8, d, k = 0;
if(i-- > 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)-1))<<(8-p);
d |= this[--i]>>(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<<n)
function bnpChangeBit(n,op) {
var r = BigInteger.ONE.shiftLeft(n);
this.bitwiseTo(r,op,r);
return r;
}
// (public) this | (1<<n)
function bnSetBit(n) { return this.changeBit(n,op_or); }
// (public) this & ~(1<<n)
function bnClearBit(n) { return this.changeBit(n,op_andnot); }
// (public) this ^ (1<<n)
function bnFlipBit(n) { return this.changeBit(n,op_xor); }
// (protected) r = this + a
function bnpAddTo(a,r) {
var i = 0, c = 0, m = Math.min(a.t,this.t);
while(i < m) {
c += this[i]+a[i];
r[i++] = c&this.DM;
c >>= 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<<k)-1;
g[1] = z.convert(this);
if(k > 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<<i)) == 0) {
z.sqrTo(r,r2); t = r; r = r2; r2 = t;
if(--i < 0) { i = this.DB-1; --j; }
}
}
return z.revert(r);
}
// (public) gcd(this,a) (HAC 14.54)
function bnGCD(a) {
var x = (this.s<0)?this.negate():this.clone();
var y = (a.s<0)?a.negate():a.clone();
if(x.compareTo(y) < 0) { var t = x; x = y; y = t; }
var i = x.getLowestSetBit(), g = y.getLowestSetBit();
if(g < 0) return x;
if(i < g) g = i;
if(g > 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);
}
// (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();
for(var i = 0; i < t; ++i) {
//Pick bases at random, instead of starting at 2
a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]);
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;
// JSBN-specific extension
BigInteger.prototype.square = bnSquare;
// BigInteger interfaces not implemented in jsbn:
// BigInteger(int signum, byte[] magnitude)
// double doubleValue()
// float floatValue()
// int hashCode()
// long longValue()
// static BigInteger valueOf(long val)

45
javascript/jsbn/prng4.js Normal file
View File

@ -0,0 +1,45 @@
// prng4.js - uses Arcfour as a PRNG
function Arcfour() {
this.i = 0;
this.j = 0;
this.S = new Array();
}
// Initialize arcfour context from key, an array of ints, each from [0..255]
function ARC4init(key) {
var i, j, t;
for(i = 0; i < 256; ++i)
this.S[i] = i;
j = 0;
for(i = 0; i < 256; ++i) {
j = (j + this.S[i] + key[i % key.length]) & 255;
t = this.S[i];
this.S[i] = this.S[j];
this.S[j] = t;
}
this.i = 0;
this.j = 0;
}
function ARC4next() {
var t;
this.i = (this.i + 1) & 255;
this.j = (this.j + this.S[this.i]) & 255;
t = this.S[this.i];
this.S[this.i] = this.S[this.j];
this.S[this.j] = t;
return this.S[(t + this.S[this.i]) & 255];
}
Arcfour.prototype.init = ARC4init;
Arcfour.prototype.next = ARC4next;
// Plug in your RNG constructor here
function prng_newstate() {
return new Arcfour();
}
// Pool size must be a multiple of 4 and greater than 32.
// An array of bytes the size of the pool will be passed to init()
var rng_psize = 256;

75
javascript/jsbn/rng.js Normal file
View File

@ -0,0 +1,75 @@
// Random number generator - requires a PRNG backend, e.g. prng4.js
// For best results, put code like
// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
// in your main HTML document.
var rng_state;
var rng_pool;
var rng_pptr;
// Mix in a 32-bit integer into the pool
function rng_seed_int(x) {
rng_pool[rng_pptr++] ^= x & 255;
rng_pool[rng_pptr++] ^= (x >> 8) & 255;
rng_pool[rng_pptr++] ^= (x >> 16) & 255;
rng_pool[rng_pptr++] ^= (x >> 24) & 255;
if(rng_pptr >= rng_psize) rng_pptr -= rng_psize;
}
// Mix in the current time (w/milliseconds) into the pool
function rng_seed_time() {
rng_seed_int(new Date().getTime());
}
// Initialize the pool with junk if needed.
if(rng_pool == null) {
rng_pool = new Array();
rng_pptr = 0;
var t;
if(window.crypto && window.crypto.getRandomValues) {
// Use webcrypto if available
var ua = new Uint8Array(32);
window.crypto.getRandomValues(ua);
for(t = 0; t < 32; ++t)
rng_pool[rng_pptr++] = ua[t];
}
if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) {
// Extract entropy (256 bits) from NS4 RNG if available
var z = window.crypto.random(32);
for(t = 0; t < z.length; ++t)
rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;
}
while(rng_pptr < rng_psize) { // extract some randomness from Math.random()
t = Math.floor(65536 * Math.random());
rng_pool[rng_pptr++] = t >>> 8;
rng_pool[rng_pptr++] = t & 255;
}
rng_pptr = 0;
rng_seed_time();
//rng_seed_int(window.screenX);
//rng_seed_int(window.screenY);
}
function rng_get_byte() {
if(rng_state == null) {
rng_seed_time();
rng_state = prng_newstate();
rng_state.init(rng_pool);
for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)
rng_pool[rng_pptr] = 0;
rng_pptr = 0;
//rng_pool = null;
}
// TODO: allow reseeding after first request
return rng_state.next();
}
function rng_get_bytes(ba) {
var i;
for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();
}
function SecureRandom() {}
SecureRandom.prototype.nextBytes = rng_get_bytes;

112
javascript/jsbn/rsa.js Normal file
View File

@ -0,0 +1,112 @@
// Depends on jsbn.js and rng.js
// Version 1.1: support utf-8 encoding in pkcs1pad2
// convert a (hex) string to a bignum object
function parseBigInt(str,r) {
return new BigInteger(str,r);
}
function linebrk(s,n) {
var ret = "";
var i = 0;
while(i + n < s.length) {
ret += s.substring(i,i+n) + "\n";
i += n;
}
return ret + s.substring(i,s.length);
}
function byte2Hex(b) {
if(b < 0x10)
return "0" + b.toString(16);
else
return b.toString(16);
}
// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
function pkcs1pad2(s,n) {
if(n < s.length + 11) { // TODO: fix for utf-8
alert("Message too long for RSA");
return null;
}
var ba = new Array();
var i = s.length - 1;
while(i >= 0 && n > 0) {
var c = s.charCodeAt(i--);
if(c < 128) { // encode using utf-8
ba[--n] = c;
}
else if((c > 127) && (c < 2048)) {
ba[--n] = (c & 63) | 128;
ba[--n] = (c >> 6) | 192;
}
else {
ba[--n] = (c & 63) | 128;
ba[--n] = ((c >> 6) & 63) | 128;
ba[--n] = (c >> 12) | 224;
}
}
ba[--n] = 0;
var rng = new SecureRandom();
var x = new Array();
while(n > 2) { // random non-zero pad
x[0] = 0;
while(x[0] == 0) rng.nextBytes(x);
ba[--n] = x[0];
}
ba[--n] = 2;
ba[--n] = 0;
return new BigInteger(ba);
}
// "empty" RSA key constructor
function RSAKey() {
this.n = null;
this.e = 0;
this.d = null;
this.p = null;
this.q = null;
this.dmp1 = null;
this.dmq1 = null;
this.coeff = null;
}
// Set the public key fields N and e from hex strings
function RSASetPublic(N,E) {
if(N != null && E != null && N.length > 0 && E.length > 0) {
this.n = parseBigInt(N,16);
this.e = parseInt(E,16);
}
else
alert("Invalid RSA public key");
}
// Perform raw public operation on "x": return x^e (mod n)
function RSADoPublic(x) {
return x.modPowInt(this.e, this.n);
}
// Return the PKCS#1 RSA encryption of "text" as an even-length hex string
function RSAEncrypt(text) {
var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
if(m == null) return null;
var c = this.doPublic(m);
if(c == null) return null;
var h = c.toString(16);
if((h.length & 1) == 0) return h; else return "0" + h;
}
// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
//function RSAEncryptB64(text) {
// var h = this.encrypt(text);
// if(h) return hex2b64(h); else return null;
//}
// protected
RSAKey.prototype.doPublic = RSADoPublic;
// public
RSAKey.prototype.setPublic = RSASetPublic;
RSAKey.prototype.encrypt = RSAEncrypt;
//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;

132
javascript/jsbn/rsa2.js Normal file
View File

@ -0,0 +1,132 @@
// Depends on rsa.js and jsbn2.js
// Version 1.1: support utf-8 decoding in pkcs1unpad2
// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
function pkcs1unpad2(d,n) {
var b = d.toByteArray();
var i = 0;
while(i < b.length && b[i] == 0) ++i;
if(b.length-i != n-1 || b[i] != 2)
return null;
++i;
while(b[i] != 0)
if(++i >= b.length) return null;
var ret = "";
while(++i < b.length) {
var c = b[i] & 255;
if(c < 128) { // utf-8 decode
ret += String.fromCharCode(c);
}
else if((c > 191) && (c < 224)) {
ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63));
++i;
}
else {
ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63));
i += 2;
}
}
return ret;
}
// Set the private key fields N, e, and d from hex strings
function RSASetPrivate(N,E,D) {
if(N != null && E != null && N.length > 0 && E.length > 0) {
this.n = parseBigInt(N,16);
this.e = parseInt(E,16);
this.d = parseBigInt(D,16);
}
else
alert("Invalid RSA private key");
}
// Set the private key fields N, e, d and CRT params from hex strings
function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) {
if(N != null && E != null && N.length > 0 && E.length > 0) {
this.n = parseBigInt(N,16);
this.e = parseInt(E,16);
this.d = parseBigInt(D,16);
this.p = parseBigInt(P,16);
this.q = parseBigInt(Q,16);
this.dmp1 = parseBigInt(DP,16);
this.dmq1 = parseBigInt(DQ,16);
this.coeff = parseBigInt(C,16);
}
else
alert("Invalid RSA private key");
}
// Generate a new random private key B bits long, using public expt E
function RSAGenerate(B,E) {
var rng = new SecureRandom();
var qs = B>>1;
this.e = parseInt(E,16);
var ee = new BigInteger(E,16);
for(;;) {
for(;;) {
this.p = new BigInteger(B-qs,1,rng);
if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break;
}
for(;;) {
this.q = new BigInteger(qs,1,rng);
if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break;
}
if(this.p.compareTo(this.q) <= 0) {
var t = this.p;
this.p = this.q;
this.q = t;
}
var p1 = this.p.subtract(BigInteger.ONE);
var q1 = this.q.subtract(BigInteger.ONE);
var phi = p1.multiply(q1);
if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
this.n = this.p.multiply(this.q);
this.d = ee.modInverse(phi);
this.dmp1 = this.d.mod(p1);
this.dmq1 = this.d.mod(q1);
this.coeff = this.q.modInverse(this.p);
break;
}
}
}
// Perform raw private operation on "x": return x^d (mod n)
function RSADoPrivate(x) {
if(this.p == null || this.q == null)
return x.modPow(this.d, this.n);
// TODO: re-calculate any missing CRT params
var xp = x.mod(this.p).modPow(this.dmp1, this.p);
var xq = x.mod(this.q).modPow(this.dmq1, this.q);
while(xp.compareTo(xq) < 0)
xp = xp.add(this.p);
return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);
}
// Return the PKCS#1 RSA decryption of "ctext".
// "ctext" is an even-length hex string and the output is a plain string.
function RSADecrypt(ctext) {
var c = parseBigInt(ctext, 16);
var m = this.doPrivate(c);
if(m == null) return null;
return pkcs1unpad2(m, (this.n.bitLength()+7)>>3);
}
// Return the PKCS#1 RSA decryption of "ctext".
// "ctext" is a Base64-encoded string and the output is a plain string.
//function RSAB64Decrypt(ctext) {
// var h = b64tohex(ctext);
// if(h) return this.decrypt(h); else return null;
//}
// protected
RSAKey.prototype.doPrivate = RSADoPrivate;
// public
RSAKey.prototype.setPrivate = RSASetPrivate;
RSAKey.prototype.setPrivateEx = RSASetPrivateEx;
RSAKey.prototype.generate = RSAGenerate;
RSAKey.prototype.decrypt = RSADecrypt;
//RSAKey.prototype.b64_decrypt = RSAB64Decrypt;

File diff suppressed because one or more lines are too long

View File

@ -87,11 +87,8 @@ public class NetClientHandler extends NetHandler {
} }
public void handleServerAuthData(Packet253ServerAuthData par1Packet253ServerAuthData) { public void handleServerAuthData(Packet253ServerAuthData par1Packet253ServerAuthData) {
String var2 = par1Packet253ServerAuthData.getServerId().trim(); //String var2 = par1Packet253ServerAuthData.getServerId().trim();
PublicKey var3 = par1Packet253ServerAuthData.getPublicKey(); this.addToSendQueue(new Packet252SharedKey(CryptManager.createNewSharedKey(), par1Packet253ServerAuthData.getPublicKey(), par1Packet253ServerAuthData.getVerifyToken()));
SecretKey var4 = CryptManager.createNewSharedKey();
this.addToSendQueue(new Packet252SharedKey(var4, var3, par1Packet253ServerAuthData.getVerifyToken()));
} }
public void handleSharedKey(Packet252SharedKey par1Packet252SharedKey) { public void handleSharedKey(Packet252SharedKey par1Packet252SharedKey) {

View File

@ -6,6 +6,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import me.ayunami2000.ayuncraft.PubKey;
import me.ayunami2000.ayuncraft.java.security.Key; import me.ayunami2000.ayuncraft.java.security.Key;
import me.ayunami2000.ayuncraft.java.security.PrivateKey; import me.ayunami2000.ayuncraft.java.security.PrivateKey;
import me.ayunami2000.ayuncraft.java.security.PublicKey; import me.ayunami2000.ayuncraft.java.security.PublicKey;
@ -23,11 +24,11 @@ public class Packet252SharedKey extends Packet
public Packet252SharedKey() {} public Packet252SharedKey() {}
public Packet252SharedKey(SecretKey par1SecretKey, PublicKey par2PublicKey, byte[] par3ArrayOfByte) public Packet252SharedKey(SecretKey par1SecretKey, PubKey par2PublicKey, byte[] par3ArrayOfByte)
{ {
this.sharedKey = par1SecretKey; this.sharedKey = par1SecretKey;
this.sharedSecret = CryptManager.encryptData((Key) par2PublicKey, par1SecretKey.getEncoded()); this.sharedSecret = CryptManager.encryptData(par2PublicKey, par1SecretKey.getEncoded());
this.verifyToken = CryptManager.encryptData((Key) par2PublicKey, par3ArrayOfByte); this.verifyToken = CryptManager.encryptData(par2PublicKey, par3ArrayOfByte);
} }
/** /**
@ -67,7 +68,7 @@ public class Packet252SharedKey extends Packet
/** /**
* Return secretKey, decrypting it from the sharedSecret byte array if needed * Return secretKey, decrypting it from the sharedSecret byte array if needed
*/ */
public SecretKey getSharedKey(PrivateKey par1PrivateKey) public SecretKey getSharedKey(PubKey par1PrivateKey)
{ {
return par1PrivateKey == null ? this.sharedKey : (this.sharedKey = CryptManager.decryptSharedKey(par1PrivateKey, this.sharedSecret)); return par1PrivateKey == null ? this.sharedKey : (this.sharedKey = CryptManager.decryptSharedKey(par1PrivateKey, this.sharedSecret));
} }
@ -83,8 +84,8 @@ public class Packet252SharedKey extends Packet
/** /**
* Return verifyToken * Return verifyToken
*/ */
public byte[] getVerifyToken(PrivateKey par1PrivateKey) public byte[] getVerifyToken(PubKey par1PrivateKey)
{ {
return par1PrivateKey == null ? this.verifyToken : CryptManager.decryptData((Key) par1PrivateKey, this.verifyToken); return par1PrivateKey == null ? this.verifyToken : CryptManager.decryptData(par1PrivateKey, this.verifyToken);
} }
} }

View File

@ -5,17 +5,20 @@ import me.ayunami2000.ayuncraft.CryptManager;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.math.BigInteger;
import me.ayunami2000.ayuncraft.PubKey;
import me.ayunami2000.ayuncraft.java.security.PublicKey; import me.ayunami2000.ayuncraft.java.security.PublicKey;
public class Packet253ServerAuthData extends Packet public class Packet253ServerAuthData extends Packet
{ {
private String serverId; private String serverId;
private PublicKey publicKey; private PubKey publicKey;
private byte[] verifyToken = new byte[0]; private byte[] verifyToken = new byte[0];
public Packet253ServerAuthData() {} public Packet253ServerAuthData() {}
public Packet253ServerAuthData(String par1Str, PublicKey par2PublicKey, byte[] par3ArrayOfByte) public Packet253ServerAuthData(String par1Str, PubKey par2PublicKey, byte[] par3ArrayOfByte)
{ {
this.serverId = par1Str; this.serverId = par1Str;
this.publicKey = par2PublicKey; this.publicKey = par2PublicKey;
@ -63,7 +66,7 @@ public class Packet253ServerAuthData extends Packet
return this.serverId; return this.serverId;
} }
public PublicKey getPublicKey() public PubKey getPublicKey()
{ {
return this.publicKey; return this.publicKey;
} }

View File

@ -0,0 +1,186 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber;
import com.beanit.asn1bean.util.HexString;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
public class BerLength implements Serializable {
private static final long serialVersionUID = 1L;
public int val;
public BerLength() {}
public static int encodeLength(OutputStream reverseOS, int length) throws IOException {
if (length <= 127) {
// this is the short form
reverseOS.write(length);
return 1;
}
if (length <= 255) {
reverseOS.write(length);
reverseOS.write(0x81);
return 2;
}
if (length <= 65535) {
reverseOS.write(length);
reverseOS.write(length >> 8);
reverseOS.write(0x82);
return 3;
}
if (length <= 16777215) {
reverseOS.write(length);
reverseOS.write(length >> 8);
reverseOS.write(length >> 16);
reverseOS.write(0x83);
return 4;
}
int numLengthBytes = 1;
while (((int) (Math.pow(2, 8 * numLengthBytes) - 1)) < length) {
numLengthBytes++;
}
for (int i = 0; i < numLengthBytes; i++) {
reverseOS.write(length >> (8 * i));
}
reverseOS.write(0x80 | numLengthBytes);
return 1 + numLengthBytes;
}
public static int readEocByte(InputStream is) throws IOException {
int b = is.read();
if (b != 0) {
if (b == -1) {
throw new EOFException("Unexpected end of input stream.");
}
throw new IOException(
"Byte " + HexString.fromByte(b) + " does not match end of contents octet of zero.");
}
return 1;
}
public static int readEocByte(InputStream is, OutputStream os) throws IOException {
int b = is.read();
if (b != 0) {
if (b == -1) {
throw new EOFException("Unexpected end of input stream.");
}
os.write(b);
throw new IOException(
"Byte " + HexString.fromByte(b) + " does not match end of contents octet of zero.");
}
os.write(b);
return 1;
}
public int decode(InputStream is) throws IOException {
val = is.read();
// check for short form
if (val < 128) {
if (val == -1) {
throw new EOFException("Unexpected end of input stream.");
}
return 1;
}
int lengthLength = val & 0x7f;
// check for indefinite length
if (lengthLength == 0) {
val = -1;
return 1;
}
if (lengthLength > 4) {
throw new IOException("Length is out of bounds: " + lengthLength);
}
val = 0;
for (int i = 0; i < lengthLength; i++) {
int nextByte = is.read();
if (nextByte == -1) {
throw new EOFException("Unexpected end of input stream.");
}
val |= nextByte << (8 * (lengthLength - i - 1));
}
return lengthLength + 1;
}
public int decode(InputStream is, OutputStream os) throws IOException {
val = is.read();
if (val == -1) {
throw new EOFException("Unexpected end of input stream.");
}
os.write(val);
// check for short form
if (val < 128) {
return 1;
}
int lengthLength = val & 0x7f;
// check for indefinite length
if (lengthLength == 0) {
val = -1;
return 1;
}
if (lengthLength > 4) {
throw new IOException("Length is out of bounds: " + lengthLength);
}
val = 0;
for (int i = 0; i < lengthLength; i++) {
int nextByte = is.read();
if (nextByte == -1) {
throw new EOFException("Unexpected end of input stream.");
}
os.write(nextByte);
val |= nextByte << (8 * (lengthLength - i - 1));
}
return lengthLength + 1;
}
/**
* Reads the end of contents octets from the given input stream if this length object has the
* indefinite form.
*
* @param is the input stream
* @return the number of bytes read from the input stream
* @throws IOException if an error occurs while reading from the input stream
*/
public int readEocIfIndefinite(InputStream is) throws IOException {
if (val >= 0) {
return 0;
}
readEocByte(is);
readEocByte(is);
return 2;
}
}

View File

@ -0,0 +1,259 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber;
import com.beanit.asn1bean.util.HexString;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
public class BerTag implements Serializable {
public static final int UNIVERSAL_CLASS = 0x00;
public static final int APPLICATION_CLASS = 0x40;
public static final int CONTEXT_CLASS = 0x80;
public static final int PRIVATE_CLASS = 0xc0;
public static final int PRIMITIVE = 0x00;
public static final int CONSTRUCTED = 0x20;
public static final int BOOLEAN_TAG = 1;
public static final int INTEGER_TAG = 2;
public static final int BIT_STRING_TAG = 3;
public static final int OCTET_STRING_TAG = 4;
public static final int NULL_TAG = 5;
public static final int OBJECT_IDENTIFIER_TAG = 6;
public static final int OBJECT_DESCRIPTOR_TAG = 7;
public static final int REAL_TAG = 9;
public static final int ENUMERATED_TAG = 10;
public static final int UTF8_STRING_TAG = 12;
public static final int TIME_TAG = 14;
public static final int SEQUENCE_TAG = 16;
public static final int SET_TAG = 17;
public static final int NUMERIC_STRING_TAG = 18;
public static final int PRINTABLE_STRING_TAG = 19;
public static final int TELETEX_STRING_TAG = 20;
public static final int VIDEOTEX_STRING_TAG = 21;
public static final int IA5_STRING_TAG = 22;
public static final int UTC_TIME_TAG = 23;
public static final int GENERALIZED_TIME_TAG = 24;
public static final int GRAPHIC_STRING_TAG = 25;
public static final int VISIBLE_STRING_TAG = 26;
public static final int GENERAL_STRING_TAG = 27;
public static final int UNIVERSAL_STRING_TAG = 28;
public static final int BMP_STRING_TAG = 30;
public static final int DATE_TAG = 31;
public static final int TIME_OF_DAY_TAG = 32;
public static final int DATE_TIME_TAG = 33;
public static final int DURATION_TAG = 34;
public static final BerTag SEQUENCE = new BerTag(UNIVERSAL_CLASS, CONSTRUCTED, SEQUENCE_TAG);
public static final BerTag SET = new BerTag(UNIVERSAL_CLASS, CONSTRUCTED, SET_TAG);
private static final long serialVersionUID = 1L;
public byte[] tagBytes = null;
public int tagClass;
public int primitive;
public int tagNumber;
public BerTag(int identifierClass, int primitive, int tagNumber) {
this.tagClass = identifierClass;
this.primitive = primitive;
this.tagNumber = tagNumber;
code();
}
public BerTag() {}
private void code() {
if (tagNumber < 31) {
tagBytes = new byte[1];
tagBytes[0] = (byte) (tagClass | primitive | tagNumber);
} else {
int tagLength = 1;
while (tagNumber > (Math.pow(2, (7 * tagLength)) - 1)) {
tagLength++;
}
tagBytes = new byte[1 + tagLength];
tagBytes[0] = (byte) (tagClass | primitive | 31);
for (int j = 1; j <= (tagLength - 1); j++) {
tagBytes[j] = (byte) (((tagNumber >> (7 * (tagLength - j))) & 0xff) | 0x80);
}
tagBytes[tagLength] = (byte) (tagNumber & 0x7f);
}
}
public int encode(OutputStream reverseOS) throws IOException {
if (tagBytes == null) {
code();
}
for (int i = (tagBytes.length - 1); i >= 0; i--) {
reverseOS.write(tagBytes[i]);
}
return tagBytes.length;
}
public int encodeForwards(OutputStream os) throws IOException {
if (tagBytes == null) {
code();
}
for (int i = 0; i < tagBytes.length; i++) {
os.write(tagBytes[i]);
}
return tagBytes.length;
}
public int decode(InputStream is) throws IOException {
int nextByte = is.read();
if (nextByte == -1) {
throw new EOFException("Unexpected end of input stream.");
}
tagClass = nextByte & 0xC0;
primitive = nextByte & 0x20;
tagNumber = nextByte & 0x1f;
int codeLength = 1;
if (tagNumber == 0x1f) {
tagNumber = 0;
int numTagBytes = 0;
do {
nextByte = is.read();
if (nextByte == -1) {
throw new EOFException("Unexpected end of input stream.");
}
codeLength++;
if (numTagBytes >= 6) {
throw new IOException("Tag is too large.");
}
tagNumber = tagNumber << 7;
tagNumber |= (nextByte & 0x7f);
numTagBytes++;
} while ((nextByte & 0x80) != 0);
}
tagBytes = null;
return codeLength;
}
public int decode(InputStream is, OutputStream os) throws IOException {
int nextByte = is.read();
if (nextByte == -1) {
throw new EOFException("Unexpected end of input stream.");
}
os.write(nextByte);
tagClass = nextByte & 0xC0;
primitive = nextByte & 0x20;
tagNumber = nextByte & 0x1f;
int codeLength = 1;
if (tagNumber == 0x1f) {
tagNumber = 0;
int numTagBytes = 0;
do {
nextByte = is.read();
if (nextByte == -1) {
throw new EOFException("Unexpected end of input stream.");
}
os.write(nextByte);
codeLength++;
if (numTagBytes >= 6) {
throw new IOException("Tag is too large.");
}
tagNumber = tagNumber << 7;
tagNumber |= (nextByte & 0x7f);
numTagBytes++;
} while ((nextByte & 0x80) != 0);
}
tagBytes = null;
return codeLength;
}
/**
* Decodes the Identifier from the ByteArrayInputStream and throws an Exception if it is not equal
* to itself. Returns the number of bytes read from the InputStream.
*
* @param is the input stream to read the identifier from.
* @return the length of the identifier read.
* @throws IOException if an exception occurs reading the identifier from the stream.
*/
public int decodeAndCheck(InputStream is) throws IOException {
if (tagBytes == null) {
code();
}
for (byte identifierByte : tagBytes) {
int nextByte = is.read();
if (nextByte == -1) {
throw new EOFException("Unexpected end of input stream.");
}
if (nextByte != (identifierByte & 0xff)) {
throw new IOException(
"Identifier does not match, expected: 0x"
+ HexString.fromByte(identifierByte)
+ ", received: 0x"
+ HexString.fromByte((byte) nextByte));
}
}
return tagBytes.length;
}
public boolean equals(int identifierClass, int primitive, int tagNumber) {
return (this.tagNumber == tagNumber
&& this.tagClass == identifierClass
&& this.primitive == primitive);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof BerTag)) {
return false;
}
if (obj == this) {
return true;
}
BerTag berIdentifier = (BerTag) obj;
return (tagNumber == berIdentifier.tagNumber
&& tagClass == berIdentifier.tagClass
&& primitive == berIdentifier.primitive);
}
@Override
public int hashCode() {
int hash = 17;
hash = hash * 31 + tagNumber;
hash = hash * 31 + tagClass;
hash = hash * 31 + primitive;
return hash;
}
@Override
public String toString() {
return "identifier class: "
+ tagClass
+ ", primitive: "
+ primitive
+ ", tag number: "
+ tagNumber;
}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright 2021 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber;
import com.beanit.asn1bean.ber.internal.Util;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class DecodeUtil {
private DecodeUtil() {
throw new AssertionError();
}
public static int decodeUnknownComponent(InputStream is) throws IOException {
int byteCount = 0;
BerLength length = new BerLength();
byteCount += length.decode(is);
int lengthVal = length.val;
BerTag berTag = new BerTag();
if (lengthVal < 0) {
byteCount += berTag.decode(is);
while (!berTag.equals(0, 0, 0)) {
byteCount += decodeUnknownComponent(is);
byteCount += berTag.decode(is);
}
byteCount += BerLength.readEocByte(is);
return byteCount;
} else {
Util.readFullyAndDiscard(is, lengthVal);
return byteCount + lengthVal;
}
}
public static int decodeUnknownComponent(InputStream is, OutputStream os) throws IOException {
int byteCount = 0;
BerLength length = new BerLength();
byteCount += length.decode(is, os);
int lengthVal = length.val;
BerTag berTag = new BerTag();
if (lengthVal < 0) {
byteCount += berTag.decode(is, os);
while (!berTag.equals(0, 0, 0)) {
byteCount += decodeUnknownComponent(is, os);
byteCount += berTag.decode(is, os);
}
byteCount += BerLength.readEocByte(is, os);
return byteCount;
} else {
byte[] contentBytes = new byte[lengthVal];
Util.readFully(is, contentBytes);
os.write(contentBytes);
return byteCount + lengthVal;
}
}
}

View File

@ -0,0 +1,123 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber;
import java.io.OutputStream;
import java.nio.ByteBuffer;
public class ReverseByteArrayOutputStream extends OutputStream {
private final boolean automaticResize;
public byte[] buffer;
public int index;
/**
* Creates a <code>ReverseByteArrayOutputStream</code> with a byte array of size <code>bufferSize
* </code>. The buffer will not be resized automatically. Use {@link
* #ReverseByteArrayOutputStream(int, boolean)} instead if you want the buffer to be dynamically
* resized.
*
* @param bufferSize the size of the underlying buffer
*/
public ReverseByteArrayOutputStream(int bufferSize) {
this(new byte[bufferSize], bufferSize - 1, false);
}
public ReverseByteArrayOutputStream(int bufferSize, boolean automaticResize) {
this(new byte[bufferSize], bufferSize - 1, automaticResize);
}
public ReverseByteArrayOutputStream(byte[] buffer) {
this(buffer, buffer.length - 1, false);
}
public ReverseByteArrayOutputStream(byte[] buffer, int startingIndex) {
this(buffer, startingIndex, false);
}
public ReverseByteArrayOutputStream(byte[] buffer, int startingIndex, boolean automaticResize) {
if (buffer.length <= 0) {
throw new IllegalArgumentException("buffer size may not be <= 0");
}
this.buffer = buffer;
index = startingIndex;
this.automaticResize = automaticResize;
}
@Override
public void write(int arg0) {
write((byte) arg0);
}
public void write(byte arg0) {
try {
buffer[index] = arg0;
} catch (ArrayIndexOutOfBoundsException e) {
if (automaticResize) {
resize();
buffer[index] = arg0;
} else {
throw new ArrayIndexOutOfBoundsException("buffer.length = " + buffer.length);
}
}
index--;
}
private void resize() {
byte[] newBuffer = new byte[buffer.length * 2];
System.arraycopy(
buffer, index + 1, newBuffer, buffer.length + index + 1, buffer.length - index - 1);
index += buffer.length;
buffer = newBuffer;
}
@Override
public void write(byte[] byteArray) {
// check if there is enough space - resize otherwise
while (index + 1 - byteArray.length < 0) {
if (automaticResize) {
resize();
} else {
throw new ArrayIndexOutOfBoundsException("buffer.length = " + buffer.length);
}
}
System.arraycopy(byteArray, 0, buffer, index - byteArray.length + 1, byteArray.length);
index -= byteArray.length;
}
/**
* Returns a new array containing the subarray of the stream array that contains the coded
* content.
*
* @return a new array containing the subarray of the stream array
*/
public byte[] getArray() {
if (index == -1) {
return buffer;
}
int subBufferLength = buffer.length - index - 1;
byte[] subBuffer = new byte[subBufferLength];
System.arraycopy(buffer, index + 1, subBuffer, 0, subBufferLength);
return subBuffer;
}
public ByteBuffer getByteBuffer() {
return ByteBuffer.wrap(buffer, index + 1, buffer.length - (index + 1));
}
public void reset() {
index = buffer.length - 1;
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.internal;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
public class Util {
public static void readFully(InputStream is, byte[] buffer) throws IOException {
readFully(is, buffer, 0, buffer.length);
}
public static void readFully(InputStream is, byte[] buffer, int off, int len) throws IOException {
while (len > 0) {
int bytesRead = is.read(buffer, off, len);
if (bytesRead == -1) {
throw new EOFException("End of input stream reached.");
}
len -= bytesRead;
off += bytesRead;
}
}
public static void readFullyAndDiscard(InputStream is, int lengthVal) throws IOException {
readFully(is, new byte[lengthVal]);
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.DecodeUtil;
import com.beanit.asn1bean.util.HexString;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
public class BerAny implements Serializable, BerType {
private static final long serialVersionUID = 1L;
public byte[] value;
public BerAny() {}
public BerAny(byte[] value) {
this.value = value;
}
@Override
public int encode(OutputStream reverseOS) throws IOException {
reverseOS.write(value);
return value.length;
}
@Override
public int decode(InputStream is) throws IOException {
return decode(is, null);
}
public int decode(InputStream is, BerTag tag) throws IOException {
int byteCount = 0;
ByteArrayOutputStream os = new ByteArrayOutputStream();
if (tag == null) {
tag = new BerTag();
byteCount = tag.decode(is, os);
} else {
tag.encode(os);
}
byteCount += DecodeUtil.decodeUnknownComponent(is, os);
value = os.toByteArray();
return byteCount;
}
@Override
public String toString() {
return HexString.fromBytes(value);
}
}

View File

@ -0,0 +1,166 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerLength;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.internal.Util;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
public class BerBitString implements Serializable, BerType {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.BIT_STRING_TAG);
private static final long serialVersionUID = 1L;
public byte[] value = null;
public int numBits;
private byte[] code = null;
public BerBitString() {}
public BerBitString(byte[] value, int numBits) {
if (value == null) {
throw new NullPointerException("value cannot be null");
}
if (numBits < 0) {
throw new IllegalArgumentException("numBits cannot be negative.");
}
if (numBits > (value.length * 8)) {
throw new IllegalArgumentException("'value' is too short to hold all bits.");
}
this.value = value;
this.numBits = numBits;
}
public BerBitString(boolean[] value) {
if (value == null) {
throw new NullPointerException("value cannot be null");
}
numBits = value.length;
this.value = new byte[(numBits + 7) / 8];
for (int i = 0; i < numBits; i++) {
if (value[i]) {
this.value[i / 8] = (byte) (this.value[i / 8] | (1 << (7 - (i % 8))));
}
}
}
public BerBitString(byte[] code) {
this.code = code;
}
public boolean[] getValueAsBooleans() {
if (value == null) {
return null;
}
boolean[] booleans = new boolean[numBits];
for (int i = 0; i < numBits; i++) {
booleans[i] = ((value[i / 8] & (1 << (7 - (i % 8)))) > 0);
}
return booleans;
}
@Override
public int encode(OutputStream reverseOS) throws IOException {
return encode(reverseOS, true);
}
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
if (code != null) {
reverseOS.write(code);
if (withTag) {
return tag.encode(reverseOS) + code.length;
}
return code.length;
}
for (int i = (value.length - 1); i >= 0; i--) {
reverseOS.write(value[i]);
}
reverseOS.write(value.length * 8 - numBits);
int codeLength = value.length + 1;
codeLength += BerLength.encodeLength(reverseOS, codeLength);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is) throws IOException {
return decode(is, true);
}
public int decode(InputStream is, boolean withTag) throws IOException {
// could be encoded in primitiv and constructed mode
// only primitiv mode is implemented
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
BerLength length = new BerLength();
codeLength += length.decode(is);
value = new byte[length.val - 1];
int unusedBits = is.read();
if (unusedBits == -1) {
throw new EOFException("Unexpected end of input stream.");
}
if (unusedBits > 7) {
throw new IOException(
"Number of unused bits in bit string expected to be less than 8 but is: " + unusedBits);
}
numBits = (value.length * 8) - unusedBits;
if (value.length > 0) {
Util.readFully(is, value);
}
codeLength += value.length + 1;
return codeLength;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (boolean bit : getValueAsBooleans()) {
if (bit) {
sb.append('1');
} else {
sb.append('0');
}
}
return sb.toString();
}
}

View File

@ -0,0 +1,116 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerLength;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.ReverseByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
public class BerBoolean implements Serializable, BerType {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.BOOLEAN_TAG);
private static final long serialVersionUID = 1L;
public boolean value;
private byte[] code = null;
public BerBoolean() {}
public BerBoolean(byte[] code) {
this.code = code;
}
public BerBoolean(boolean value) {
this.value = value;
}
@Override
public int encode(OutputStream reverseOS) throws IOException {
return encode(reverseOS, true);
}
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
if (code != null) {
reverseOS.write(code);
if (withTag) {
return tag.encode(reverseOS) + code.length;
}
return code.length;
}
int codeLength = 1;
if (value) {
reverseOS.write(0xff);
} else {
reverseOS.write(0);
}
codeLength += BerLength.encodeLength(reverseOS, codeLength);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is) throws IOException {
return decode(is, true);
}
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
BerLength length = new BerLength();
codeLength += length.decode(is);
if (length.val != 1) {
throw new IOException("Decoded length of BerBoolean is not correct");
}
int nextByte = is.read();
if (nextByte == -1) {
throw new EOFException("Unexpected end of input stream.");
}
codeLength++;
value = nextByte != 0;
return codeLength;
}
public void encodeAndSave(int encodingSizeGuess) throws IOException {
ReverseByteArrayOutputStream os = new ReverseByteArrayOutputStream(encodingSizeGuess);
encode(os, false);
code = os.getArray();
}
@Override
public String toString() {
return "" + value;
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerTag;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class BerDate extends BerTime {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.DATE_TAG);
private static final long serialVersionUID = 1L;
public BerDate() {}
public BerDate(byte[] value) {
super(value);
}
public BerDate(String valueAsString) {
super(valueAsString);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerTag;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class BerDateTime extends BerTime {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.DATE_TIME_TAG);
private static final long serialVersionUID = 1L;
public BerDateTime() {}
public BerDateTime(byte[] value) {
super(value);
}
public BerDateTime(String valueAsString) {
super(valueAsString);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerTag;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class BerDuration extends BerTime {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.DURATION_TAG);
private static final long serialVersionUID = 1L;
public BerDuration() {}
public BerDuration(byte[] value) {
super(value);
}
public BerDuration(String valueAsString) {
super(valueAsString);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,780 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerLength;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.ReverseByteArrayOutputStream;
import com.beanit.asn1bean.ber.types.string.BerObjectDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
public class BerEmbeddedPdv implements BerType, Serializable {
public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 11);
private static final long serialVersionUID = 1L;
private byte[] code = null;
private Identification identification = null;
private BerObjectDescriptor dataValueDescriptor = null;
private BerOctetString dataValue = null;
public BerEmbeddedPdv() {}
public BerEmbeddedPdv(byte[] code) {
this.code = code;
}
public Identification getIdentification() {
return identification;
}
public void setIdentification(Identification identification) {
this.identification = identification;
}
public BerObjectDescriptor getDataValueDescriptor() {
return dataValueDescriptor;
}
public void setDataValueDescriptor(BerObjectDescriptor dataValueDescriptor) {
this.dataValueDescriptor = dataValueDescriptor;
}
public BerOctetString getDataValue() {
return dataValue;
}
public void setDataValue(BerOctetString dataValue) {
this.dataValue = dataValue;
}
@Override
public int encode(OutputStream reverseOS) throws IOException {
return encode(reverseOS, true);
}
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
if (code != null) {
reverseOS.write(code);
if (withTag) {
return tag.encode(reverseOS) + code.length;
}
return code.length;
}
int codeLength = 0;
int sublength;
codeLength += dataValue.encode(reverseOS, false);
// write tag: CONTEXT_CLASS, PRIMITIVE, 2
reverseOS.write(0x82);
codeLength += 1;
if (dataValueDescriptor != null) {
codeLength += dataValueDescriptor.encode(reverseOS, false);
// write tag: CONTEXT_CLASS, PRIMITIVE, 1
reverseOS.write(0x81);
codeLength += 1;
}
sublength = identification.encode(reverseOS);
codeLength += sublength;
codeLength += BerLength.encodeLength(reverseOS, sublength);
// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
reverseOS.write(0xA0);
codeLength += 1;
codeLength += BerLength.encodeLength(reverseOS, codeLength);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is) throws IOException {
return decode(is, true);
}
public int decode(InputStream is, boolean withTag) throws IOException {
int tlByteCount = 0;
int vByteCount = 0;
BerTag berTag = new BerTag();
if (withTag) {
tlByteCount += tag.decodeAndCheck(is);
}
BerLength length = new BerLength();
tlByteCount += length.decode(is);
int lengthVal = length.val;
vByteCount += berTag.decode(is);
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
vByteCount += length.decode(is);
identification = new Identification();
vByteCount += identification.decode(is, null);
vByteCount += length.readEocIfIndefinite(is);
vByteCount += berTag.decode(is);
} else {
throw new IOException("Tag does not match mandatory sequence component.");
}
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
dataValueDescriptor = new BerObjectDescriptor();
vByteCount += dataValueDescriptor.decode(is, false);
vByteCount += berTag.decode(is);
}
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
dataValue = new BerOctetString();
vByteCount += dataValue.decode(is, false);
if (lengthVal >= 0 && vByteCount == lengthVal) {
return tlByteCount + vByteCount;
}
vByteCount += berTag.decode(is);
} else {
throw new IOException("Tag does not match mandatory sequence component.");
}
if (lengthVal < 0) {
if (!berTag.equals(0, 0, 0)) {
throw new IOException("Decoded sequence has wrong end of contents octets");
}
vByteCount += BerLength.readEocByte(is);
return tlByteCount + vByteCount;
}
throw new IOException(
"Unexpected end of sequence, length tag: " + lengthVal + ", bytes decoded: " + vByteCount);
}
public void encodeAndSave(int encodingSizeGuess) throws IOException {
ReverseByteArrayOutputStream reverseOS = new ReverseByteArrayOutputStream(encodingSizeGuess);
encode(reverseOS, false);
code = reverseOS.getArray();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
appendAsString(sb, 0);
return sb.toString();
}
public void appendAsString(StringBuilder sb, int indentLevel) {
sb.append("{");
sb.append("\n");
for (int i = 0; i < indentLevel + 1; i++) {
sb.append("\t");
}
if (identification != null) {
sb.append("identification: ");
identification.appendAsString(sb, indentLevel + 1);
} else {
sb.append("identification: <empty-required-field>");
}
if (dataValueDescriptor != null) {
sb.append(",\n");
for (int i = 0; i < indentLevel + 1; i++) {
sb.append("\t");
}
sb.append("dataValueDescriptor: ").append(dataValueDescriptor);
}
sb.append(",\n");
for (int i = 0; i < indentLevel + 1; i++) {
sb.append("\t");
}
if (dataValue != null) {
sb.append("dataValue: ").append(dataValue);
} else {
sb.append("dataValue: <empty-required-field>");
}
sb.append("\n");
for (int i = 0; i < indentLevel; i++) {
sb.append("\t");
}
sb.append("}");
}
public static class Identification implements BerType, Serializable {
private static final long serialVersionUID = 1L;
private byte[] code = null;
private Syntaxes syntaxes = null;
private BerObjectIdentifier syntax = null;
private BerInteger presentationContextId = null;
private ContextNegotiation contextNegotiation = null;
private BerObjectIdentifier transferSyntax = null;
private BerNull fixed = null;
public Identification() {}
public Identification(byte[] code) {
this.code = code;
}
public Syntaxes getSyntaxes() {
return syntaxes;
}
public void setSyntaxes(Syntaxes syntaxes) {
this.syntaxes = syntaxes;
}
public BerObjectIdentifier getSyntax() {
return syntax;
}
public void setSyntax(BerObjectIdentifier syntax) {
this.syntax = syntax;
}
public BerInteger getPresentationContextId() {
return presentationContextId;
}
public void setPresentationContextId(BerInteger presentationContextId) {
this.presentationContextId = presentationContextId;
}
public ContextNegotiation getContextNegotiation() {
return contextNegotiation;
}
public void setContextNegotiation(ContextNegotiation contextNegotiation) {
this.contextNegotiation = contextNegotiation;
}
public BerObjectIdentifier getTransferSyntax() {
return transferSyntax;
}
public void setTransferSyntax(BerObjectIdentifier transferSyntax) {
this.transferSyntax = transferSyntax;
}
public BerNull getFixed() {
return fixed;
}
public void setFixed(BerNull fixed) {
this.fixed = fixed;
}
@Override
public int encode(OutputStream reverseOS) throws IOException {
if (code != null) {
reverseOS.write(code);
return code.length;
}
int codeLength = 0;
if (fixed != null) {
codeLength += fixed.encode(reverseOS, false);
// write tag: CONTEXT_CLASS, PRIMITIVE, 5
reverseOS.write(0x85);
codeLength += 1;
return codeLength;
}
if (transferSyntax != null) {
codeLength += transferSyntax.encode(reverseOS, false);
// write tag: CONTEXT_CLASS, PRIMITIVE, 4
reverseOS.write(0x84);
codeLength += 1;
return codeLength;
}
if (contextNegotiation != null) {
codeLength += contextNegotiation.encode(reverseOS, false);
// write tag: CONTEXT_CLASS, CONSTRUCTED, 3
reverseOS.write(0xA3);
codeLength += 1;
return codeLength;
}
if (presentationContextId != null) {
codeLength += presentationContextId.encode(reverseOS, false);
// write tag: CONTEXT_CLASS, PRIMITIVE, 2
reverseOS.write(0x82);
codeLength += 1;
return codeLength;
}
if (syntax != null) {
codeLength += syntax.encode(reverseOS, false);
// write tag: CONTEXT_CLASS, PRIMITIVE, 1
reverseOS.write(0x81);
codeLength += 1;
return codeLength;
}
if (syntaxes != null) {
codeLength += syntaxes.encode(reverseOS, false);
// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
reverseOS.write(0xA0);
codeLength += 1;
return codeLength;
}
throw new IOException("Error encoding CHOICE: No element of CHOICE was selected.");
}
@Override
public int decode(InputStream is) throws IOException {
return decode(is, null);
}
public int decode(InputStream is, BerTag berTag) throws IOException {
int tlvByteCount = 0;
boolean tagWasPassed = (berTag != null);
if (berTag == null) {
berTag = new BerTag();
tlvByteCount += berTag.decode(is);
}
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
syntaxes = new Syntaxes();
tlvByteCount += syntaxes.decode(is, false);
return tlvByteCount;
}
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
syntax = new BerObjectIdentifier();
tlvByteCount += syntax.decode(is, false);
return tlvByteCount;
}
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
presentationContextId = new BerInteger();
tlvByteCount += presentationContextId.decode(is, false);
return tlvByteCount;
}
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
contextNegotiation = new ContextNegotiation();
tlvByteCount += contextNegotiation.decode(is, false);
return tlvByteCount;
}
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 4)) {
transferSyntax = new BerObjectIdentifier();
tlvByteCount += transferSyntax.decode(is, false);
return tlvByteCount;
}
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 5)) {
fixed = new BerNull();
tlvByteCount += fixed.decode(is, false);
return tlvByteCount;
}
if (tagWasPassed) {
return 0;
}
throw new IOException("Error decoding CHOICE: Tag " + berTag + " matched to no item.");
}
public void encodeAndSave(int encodingSizeGuess) throws IOException {
ReverseByteArrayOutputStream reverseOS = new ReverseByteArrayOutputStream(encodingSizeGuess);
encode(reverseOS);
code = reverseOS.getArray();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
appendAsString(sb, 0);
return sb.toString();
}
public void appendAsString(StringBuilder sb, int indentLevel) {
if (syntaxes != null) {
sb.append("syntaxes: ");
syntaxes.appendAsString(sb, indentLevel + 1);
return;
}
if (syntax != null) {
sb.append("syntax: ").append(syntax);
return;
}
if (presentationContextId != null) {
sb.append("presentationContextId: ").append(presentationContextId);
return;
}
if (contextNegotiation != null) {
sb.append("contextNegotiation: ");
contextNegotiation.appendAsString(sb, indentLevel + 1);
return;
}
if (transferSyntax != null) {
sb.append("transferSyntax: ").append(transferSyntax);
return;
}
if (fixed != null) {
sb.append("fixed: ").append(fixed);
return;
}
sb.append("<none>");
}
public static class Syntaxes implements BerType, Serializable {
public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
private static final long serialVersionUID = 1L;
private byte[] code = null;
private BerObjectIdentifier abstract_ = null;
private BerObjectIdentifier transfer = null;
public Syntaxes() {}
public Syntaxes(byte[] code) {
this.code = code;
}
public BerObjectIdentifier getAbstract() {
return abstract_;
}
public void setAbstract(BerObjectIdentifier abstract_) {
this.abstract_ = abstract_;
}
public BerObjectIdentifier getTransfer() {
return transfer;
}
public void setTransfer(BerObjectIdentifier transfer) {
this.transfer = transfer;
}
@Override
public int encode(OutputStream reverseOS) throws IOException {
return encode(reverseOS, true);
}
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
if (code != null) {
reverseOS.write(code);
if (withTag) {
return tag.encode(reverseOS) + code.length;
}
return code.length;
}
int codeLength = 0;
codeLength += transfer.encode(reverseOS, false);
// write tag: CONTEXT_CLASS, PRIMITIVE, 1
reverseOS.write(0x81);
codeLength += 1;
codeLength += abstract_.encode(reverseOS, false);
// write tag: CONTEXT_CLASS, PRIMITIVE, 0
reverseOS.write(0x80);
codeLength += 1;
codeLength += BerLength.encodeLength(reverseOS, codeLength);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is) throws IOException {
return decode(is, true);
}
public int decode(InputStream is, boolean withTag) throws IOException {
int tlByteCount = 0;
int vByteCount = 0;
BerTag berTag = new BerTag();
if (withTag) {
tlByteCount += tag.decodeAndCheck(is);
}
BerLength length = new BerLength();
tlByteCount += length.decode(is);
int lengthVal = length.val;
vByteCount += berTag.decode(is);
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
abstract_ = new BerObjectIdentifier();
vByteCount += abstract_.decode(is, false);
vByteCount += berTag.decode(is);
} else {
throw new IOException("Tag does not match mandatory sequence component.");
}
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
transfer = new BerObjectIdentifier();
vByteCount += transfer.decode(is, false);
if (lengthVal >= 0 && vByteCount == lengthVal) {
return tlByteCount + vByteCount;
}
vByteCount += berTag.decode(is);
} else {
throw new IOException("Tag does not match mandatory sequence component.");
}
if (lengthVal < 0) {
if (!berTag.equals(0, 0, 0)) {
throw new IOException("Decoded sequence has wrong end of contents octets");
}
vByteCount += BerLength.readEocByte(is);
return tlByteCount + vByteCount;
}
throw new IOException(
"Unexpected end of sequence, length tag: "
+ lengthVal
+ ", bytes decoded: "
+ vByteCount);
}
public void encodeAndSave(int encodingSizeGuess) throws IOException {
ReverseByteArrayOutputStream reverseOS =
new ReverseByteArrayOutputStream(encodingSizeGuess);
encode(reverseOS, false);
code = reverseOS.getArray();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
appendAsString(sb, 0);
return sb.toString();
}
public void appendAsString(StringBuilder sb, int indentLevel) {
sb.append("{");
sb.append("\n");
for (int i = 0; i < indentLevel + 1; i++) {
sb.append("\t");
}
if (abstract_ != null) {
sb.append("abstract_: ").append(abstract_);
} else {
sb.append("abstract_: <empty-required-field>");
}
sb.append(",\n");
for (int i = 0; i < indentLevel + 1; i++) {
sb.append("\t");
}
if (transfer != null) {
sb.append("transfer: ").append(transfer);
} else {
sb.append("transfer: <empty-required-field>");
}
sb.append("\n");
for (int i = 0; i < indentLevel; i++) {
sb.append("\t");
}
sb.append("}");
}
}
public static class ContextNegotiation implements BerType, Serializable {
public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
private static final long serialVersionUID = 1L;
private byte[] code = null;
private BerInteger presentationContextId = null;
private BerObjectIdentifier transferSyntax = null;
public ContextNegotiation() {}
public ContextNegotiation(byte[] code) {
this.code = code;
}
public BerInteger getPresentationContextId() {
return presentationContextId;
}
public void setPresentationContextId(BerInteger presentationContextId) {
this.presentationContextId = presentationContextId;
}
public BerObjectIdentifier getTransferSyntax() {
return transferSyntax;
}
public void setTransferSyntax(BerObjectIdentifier transferSyntax) {
this.transferSyntax = transferSyntax;
}
@Override
public int encode(OutputStream reverseOS) throws IOException {
return encode(reverseOS, true);
}
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
if (code != null) {
reverseOS.write(code);
if (withTag) {
return tag.encode(reverseOS) + code.length;
}
return code.length;
}
int codeLength = 0;
codeLength += transferSyntax.encode(reverseOS, false);
// write tag: CONTEXT_CLASS, PRIMITIVE, 1
reverseOS.write(0x81);
codeLength += 1;
codeLength += presentationContextId.encode(reverseOS, false);
// write tag: CONTEXT_CLASS, PRIMITIVE, 0
reverseOS.write(0x80);
codeLength += 1;
codeLength += BerLength.encodeLength(reverseOS, codeLength);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is) throws IOException {
return decode(is, true);
}
public int decode(InputStream is, boolean withTag) throws IOException {
int tlByteCount = 0;
int vByteCount = 0;
BerTag berTag = new BerTag();
if (withTag) {
tlByteCount += tag.decodeAndCheck(is);
}
BerLength length = new BerLength();
tlByteCount += length.decode(is);
int lengthVal = length.val;
vByteCount += berTag.decode(is);
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
presentationContextId = new BerInteger();
vByteCount += presentationContextId.decode(is, false);
vByteCount += berTag.decode(is);
} else {
throw new IOException("Tag does not match mandatory sequence component.");
}
if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
transferSyntax = new BerObjectIdentifier();
vByteCount += transferSyntax.decode(is, false);
if (lengthVal >= 0 && vByteCount == lengthVal) {
return tlByteCount + vByteCount;
}
vByteCount += berTag.decode(is);
} else {
throw new IOException("Tag does not match mandatory sequence component.");
}
if (lengthVal < 0) {
if (!berTag.equals(0, 0, 0)) {
throw new IOException("Decoded sequence has wrong end of contents octets");
}
vByteCount += BerLength.readEocByte(is);
return tlByteCount + vByteCount;
}
throw new IOException(
"Unexpected end of sequence, length tag: "
+ lengthVal
+ ", bytes decoded: "
+ vByteCount);
}
public void encodeAndSave(int encodingSizeGuess) throws IOException {
ReverseByteArrayOutputStream reverseOS =
new ReverseByteArrayOutputStream(encodingSizeGuess);
encode(reverseOS, false);
code = reverseOS.getArray();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
appendAsString(sb, 0);
return sb.toString();
}
public void appendAsString(StringBuilder sb, int indentLevel) {
sb.append("{");
sb.append("\n");
for (int i = 0; i < indentLevel + 1; i++) {
sb.append("\t");
}
if (presentationContextId != null) {
sb.append("presentationContextId: ").append(presentationContextId);
} else {
sb.append("presentationContextId: <empty-required-field>");
}
sb.append(",\n");
for (int i = 0; i < indentLevel + 1; i++) {
sb.append("\t");
}
if (transferSyntax != null) {
sb.append("transferSyntax: ").append(transferSyntax);
} else {
sb.append("transferSyntax: <empty-required-field>");
}
sb.append("\n");
for (int i = 0; i < indentLevel; i++) {
sb.append("\t");
}
sb.append("}");
}
}
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerTag;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
public class BerEnum extends BerInteger {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.ENUMERATED_TAG);
private static final long serialVersionUID = 1L;
public BerEnum() {}
public BerEnum(byte[] code) {
super(code);
}
public BerEnum(BigInteger val) {
this.value = val;
}
public BerEnum(long val) {
this.value = BigInteger.valueOf(val);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,148 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.types.string.BerVisibleString;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class BerGeneralizedTime extends BerVisibleString {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.GENERALIZED_TIME_TAG);
private static final long serialVersionUID = 1L;
/**
* Generalized time is one of the following (ITU-T X.680 08/2015): YYYYMMDDHH[MM[SS]][.fff]
* LocalTime YYYYMMDDHH[MM[SS]][.fff]Z UTC YYYYMMDDHH[MM[SS]][.fff]+-HH[MM] local time with time
* zone
*
* <p>Regexp: ^ (?<year>\\d{4}) YYYY (?<month>\\d{2}) MM (?<day>\\d{2}) DD (?<hour>\\d{2}) HH (
* [MM[SS]] (?<minute>\\d{2}) MM (?<second>\\d{2})? [SS] )? ([.,](?<frac>\\d+))? [.fff] (or
* [,fff]) (?<timezone> "" or "Z" or "+-HH[MM]" Z | ( "+-HH[MM]" [+-] "+-" \\d{2}(?<tzmin>\\d{2})?
* HH[MM] ) )? $
*/
private static final String GENERALIZED_TIME_PATTERN =
"^(?<year>\\d{4})(?<month>\\d{2})(?<day>\\d{2})(?<hour>\\d{2})((?<minute>\\d{2})(?<second>\\d{2})?)?([.,](?<frac>\\d+))?(?<timezone>Z|([+-]\\d{2}(?<tzmin>\\d{2})?))?$";
private static final Pattern generalizedTimePattern = Pattern.compile(GENERALIZED_TIME_PATTERN);
public BerGeneralizedTime() {}
public BerGeneralizedTime(byte[] value) {
super(value);
}
public BerGeneralizedTime(String valueAsString) {
super(valueAsString);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
public Calendar asCalendar() throws ParseException {
Matcher matcher = generalizedTimePattern.matcher(toString());
if (!matcher.find()) {
throw new ParseException("", 0);
}
String mg, mgf;
int year = Integer.parseInt(matcher.group("year"));
int month = Integer.parseInt(matcher.group("month"));
month -= 1; // java.util.Calendar's month goes from 0 to 11
int day = Integer.parseInt(matcher.group("day"));
int hour = Integer.parseInt(matcher.group("hour"));
mg = matcher.group("minute");
mgf = matcher.group("frac");
int minute = 0, second = 0, millisec = 0;
double frac = mgf == null ? 0 : Double.parseDouble("0." + mgf);
if (mg == null) {
// Missing minutes and seconds
if (mgf != null) {
// frac is a fraction of a hour
millisec = (int) Math.round(1000 * 60 * 60 * frac);
}
} else {
minute = Integer.parseInt(mg);
mg = matcher.group("second");
if (mg == null) {
// Missing seconds
if (mgf != null) {
// frac is a fraction of a minute
millisec = (int) Math.round(1000 * 60 * frac);
}
} else {
second = Integer.parseInt(mg);
if (mgf != null) {
// frac is a fraction of a second
millisec = (int) Math.round(1000 * frac);
}
}
}
mg = matcher.group("timezone");
String mgt = matcher.group("tzmin");
String timeZoneStr =
mg == null
? TimeZone.getDefault().getID()
: (mg.equals("Z") ? "UTC" : (mgt == null ? "GMT" + mg + "00" : "GMT" + mg));
TimeZone timeZone = TimeZone.getTimeZone(timeZoneStr);
Calendar calendar = Calendar.getInstance();
calendar.setLenient(true); // accept millisec greater than 999
calendar.set(year, month, day, hour, minute, second);
calendar.set(Calendar.MILLISECOND, millisec);
calendar.setTimeZone(timeZone);
return calendar;
}
public Date asDate() throws ParseException {
return asCalendar().getTime();
}
}

View File

@ -0,0 +1,132 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerLength;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.ReverseByteArrayOutputStream;
import com.beanit.asn1bean.ber.internal.Util;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.math.BigInteger;
public class BerInteger implements Serializable, BerType {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.INTEGER_TAG);
private static final long serialVersionUID = 1L;
public BigInteger value;
private byte[] code = null;
public BerInteger() {}
public BerInteger(byte[] code) {
this.code = code;
}
public BerInteger(BigInteger val) {
this.value = val;
}
public BerInteger(long val) {
this.value = BigInteger.valueOf(val);
}
@Override
public int encode(OutputStream reverseOS) throws IOException {
return encode(reverseOS, true);
}
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
if (code != null) {
reverseOS.write(code);
if (withTag) {
return tag.encode(reverseOS) + code.length;
}
return code.length;
}
byte[] encoded = value.toByteArray();
int codeLength = encoded.length;
reverseOS.write(encoded);
codeLength += BerLength.encodeLength(reverseOS, codeLength);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is) throws IOException {
return decode(is, true);
}
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
BerLength length = new BerLength();
codeLength += length.decode(is);
if (length.val < 1) {
throw new IOException("Decoded length of BerInteger is not correct");
}
byte[] byteCode = new byte[length.val];
Util.readFully(is, byteCode);
codeLength += length.val;
value = new BigInteger(byteCode);
return codeLength;
}
public void encodeAndSave(int encodingSizeGuess) throws IOException {
ReverseByteArrayOutputStream os = new ReverseByteArrayOutputStream(encodingSizeGuess);
encode(os, false);
code = os.getArray();
}
@Override
public String toString() {
return "" + value;
}
public byte byteValue() {
return value.byteValue();
}
public short shortValue() {
return value.shortValue();
}
public int intValue() {
return value.intValue();
}
public long longValue() {
return value.longValue();
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerLength;
import com.beanit.asn1bean.ber.BerTag;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
public class BerNull implements Serializable, BerType {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.NULL_TAG);
private static final long serialVersionUID = 1L;
public BerNull() {}
public BerNull(byte[] code) {}
@Override
public int encode(OutputStream reverseOS) throws IOException {
return encode(reverseOS, true);
}
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = BerLength.encodeLength(reverseOS, 0);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is) throws IOException {
return decode(is, true);
}
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
BerLength length = new BerLength();
codeLength += length.decode(is);
if (length.val != 0) {
throw new IOException("Decoded length of BerNull is not correct");
}
return codeLength;
}
@Override
public String toString() {
return "ASN1_NULL";
}
}

View File

@ -0,0 +1,199 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerLength;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.internal.Util;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class BerObjectIdentifier implements Serializable, BerType {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.OBJECT_IDENTIFIER_TAG);
private static final long serialVersionUID = 1L;
public int[] value;
private byte[] code = null;
public BerObjectIdentifier() {}
public BerObjectIdentifier(byte[] code) {
this.code = code;
}
public BerObjectIdentifier(int[] value) {
if ((value.length < 2)
|| ((value[0] == 0 || value[0] == 1) && (value[1] > 39))
|| value[0] > 2) {
throw new IllegalArgumentException("invalid object identifier components");
}
for (int objectIdentifierComponent : value) {
if (objectIdentifierComponent < 0) {
throw new IllegalArgumentException("invalid object identifier components");
}
}
this.value = value;
}
@Override
public int encode(OutputStream reverseOS) throws IOException {
return encode(reverseOS, true);
}
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
if (code != null) {
reverseOS.write(code);
if (withTag) {
return tag.encode(reverseOS) + code.length;
}
return code.length;
}
int firstSubidentifier = 40 * value[0] + value[1];
int subidentifier;
int codeLength = 0;
for (int i = (value.length - 1); i > 0; i--) {
if (i == 1) {
subidentifier = firstSubidentifier;
} else {
subidentifier = value[i];
}
// get length of subidentifier
int subIDLength = 1;
while (subidentifier > (Math.pow(2, (7 * subIDLength)) - 1)) {
subIDLength++;
}
reverseOS.write(subidentifier & 0x7f);
for (int j = 1; j <= (subIDLength - 1); j++) {
reverseOS.write(((subidentifier >> (7 * j)) & 0xff) | 0x80);
}
codeLength += subIDLength;
}
codeLength += BerLength.encodeLength(reverseOS, codeLength);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is) throws IOException {
return decode(is, true);
}
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
BerLength length = new BerLength();
codeLength += length.decode(is);
if (length.val == 0) {
value = new int[0];
return codeLength;
}
byte[] byteCode = new byte[length.val];
Util.readFully(is, byteCode);
codeLength += length.val;
List<Integer> objectIdentifierComponentsList = new ArrayList<>();
int subIDEndIndex = 0;
while ((byteCode[subIDEndIndex] & 0x80) == 0x80) {
if (subIDEndIndex >= (length.val - 1)) {
throw new IOException("Invalid Object Identifier");
}
subIDEndIndex++;
}
int subidentifier = 0;
for (int i = 0; i <= subIDEndIndex; i++) {
subidentifier |= ((byteCode[i] & 0x7f) << ((subIDEndIndex - i) * 7));
}
if (subidentifier < 40) {
objectIdentifierComponentsList.add(0);
objectIdentifierComponentsList.add(subidentifier);
} else if (subidentifier < 80) {
objectIdentifierComponentsList.add(1);
objectIdentifierComponentsList.add(subidentifier - 40);
} else {
objectIdentifierComponentsList.add(2);
objectIdentifierComponentsList.add(subidentifier - 80);
}
subIDEndIndex++;
while (subIDEndIndex < length.val) {
int subIDStartIndex = subIDEndIndex;
while ((byteCode[subIDEndIndex] & 0x80) == 0x80) {
if (subIDEndIndex == (length.val - 1)) {
throw new IOException("Invalid Object Identifier");
}
subIDEndIndex++;
}
subidentifier = 0;
for (int j = subIDStartIndex; j <= subIDEndIndex; j++) {
subidentifier |= ((byteCode[j] & 0x7f) << ((subIDEndIndex - j) * 7));
}
objectIdentifierComponentsList.add(subidentifier);
subIDEndIndex++;
}
value = new int[objectIdentifierComponentsList.size()];
for (int i = 0; i < objectIdentifierComponentsList.size(); i++) {
value[i] = objectIdentifierComponentsList.get(i);
}
return codeLength;
}
@Override
public String toString() {
if (value == null || value.length == 0) {
return "";
}
StringBuilder sb = new StringBuilder(Integer.toString(value[0]));
for (int i = 1; i < value.length; i++) {
sb.append(".").append(value[i]);
}
return sb.toString();
}
}

View File

@ -0,0 +1,142 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerLength;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.internal.Util;
import com.beanit.asn1bean.util.HexString;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
public class BerOctetString implements Serializable, BerType {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.OCTET_STRING_TAG);
private static final long serialVersionUID = 1L;
public byte[] value;
public BerOctetString() {}
public BerOctetString(byte[] value) {
this.value = value;
}
@Override
public int encode(OutputStream reverseOS) throws IOException {
return encode(reverseOS, true);
}
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
reverseOS.write(value);
int codeLength = value.length;
codeLength += BerLength.encodeLength(reverseOS, codeLength);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is) throws IOException {
return decode(is, true);
}
public int decode(InputStream is, boolean withTag) throws IOException {
if (withTag) {
int nextByte = is.read();
switch (nextByte) {
case -1:
throw new EOFException("Unexpected end of input stream.");
case 0x04:
return 1 + decodePrimitiveOctetString(is);
case 0x24:
return 1 + decodeConstructedOctetString(is);
default:
throw new IOException(
"Octet String identifier does not match, expected: 0x04 or 0x24, received: 0x"
+ HexString.fromByte((byte) nextByte));
}
}
return decodePrimitiveOctetString(is);
}
private int decodeConstructedOctetString(InputStream is) throws IOException {
BerLength length = new BerLength();
int lengthLength = length.decode(is);
value = new byte[0];
int vLength = 0;
if (length.val < 0) {
BerTag berTag = new BerTag();
vLength += berTag.decode(is);
while (!berTag.equals(0, 0, 0)) {
BerOctetString subOctetString = new BerOctetString();
vLength += subOctetString.decode(is, false);
value = concatenate(value, subOctetString.value);
vLength += berTag.decode(is);
}
vLength += BerLength.readEocByte(is);
} else {
while (vLength < length.val) {
BerOctetString subOctetString = new BerOctetString();
vLength += subOctetString.decode(is);
value = concatenate(value, subOctetString.value);
}
}
return lengthLength + vLength;
}
private byte[] concatenate(byte[] a, byte[] b) {
int aLen = a.length;
int bLen = b.length;
byte[] c = new byte[aLen + bLen];
System.arraycopy(a, 0, c, 0, aLen);
System.arraycopy(b, 0, c, aLen, bLen);
return c;
}
private int decodePrimitiveOctetString(InputStream is) throws IOException {
int codeLength = 0;
BerLength length = new BerLength();
codeLength += length.decode(is);
value = new byte[length.val];
if (length.val != 0) {
Util.readFully(is, value);
codeLength += length.val;
}
return codeLength;
}
@Override
public String toString() {
return HexString.fromBytes(value);
}
}

View File

@ -0,0 +1,240 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerLength;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.ReverseByteArrayOutputStream;
import com.beanit.asn1bean.ber.internal.Util;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.math.BigInteger;
public class BerReal implements Serializable, BerType {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.REAL_TAG);
private static final long serialVersionUID = 1L;
public double value;
private byte[] code = null;
public BerReal() {}
public BerReal(byte[] code) {
this.code = code;
}
public BerReal(double value) {
this.value = value;
}
@Override
public int encode(OutputStream reverseOS) throws IOException {
return encode(reverseOS, true);
}
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
if (code != null) {
reverseOS.write(code);
if (withTag) {
return tag.encode(reverseOS) + code.length;
}
return code.length;
}
int codeLength = encodeValue(reverseOS);
codeLength += BerLength.encodeLength(reverseOS, codeLength);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
private int encodeValue(OutputStream reverseOS) throws IOException {
// explained in Annex C and Ch. 8.5 of X.690
// we use binary encoding, with base 2 and F==0
// F is only needed when encoding with base 8 or 16
long longBits = Double.doubleToLongBits(value);
boolean isNegative = (longBits & 0x8000000000000000L) == 0x8000000000000000L;
int exponent = ((int) (longBits >> 52)) & 0x7ff;
long mantissa = (longBits & 0x000fffffffffffffL) | 0x0010000000000000L;
if (exponent == 0x7ff) {
if (mantissa == 0x0010000000000000L) {
if (isNegative) {
// - infinity
reverseOS.write(0x41);
} else {
// + infinity
reverseOS.write(0x40);
}
return 1;
} else {
throw new IOException("NAN not supported");
}
}
if ((exponent == 0 && mantissa == 0x0010000000000000L)) {
// zero
return 0;
}
// because IEEE double-precision format is (-1)^sign * 1.b51b50..b0 * 2^(e-1023) we need to
// subtract 1023 and 52
// from the exponent to get an exponent corresponding to an integer matissa as need here.
exponent -= 1075; // 1023 + 52 = 1075
// trailing zeros of the mantissa should be removed. Therefor find out how much the mantissa can
// be shifted and
// the exponent can be increased
int exponentIncr = 0;
while (((mantissa >> exponentIncr) & 0xff) == 0x00) {
exponentIncr += 8;
}
while (((mantissa >> exponentIncr) & 0x01) == 0x00) {
exponentIncr++;
}
exponent += exponentIncr;
mantissa >>= exponentIncr;
int mantissaLength = (Long.SIZE - Long.numberOfLeadingZeros(mantissa) + 7) / 8;
for (int i = 0; i < mantissaLength; i++) {
reverseOS.write((int) (mantissa >> (8 * i)));
}
int codeLength = mantissaLength;
byte[] exponentBytes = BigInteger.valueOf(exponent).toByteArray();
reverseOS.write(exponentBytes);
codeLength += exponentBytes.length;
byte exponentFormat;
if (exponentBytes.length < 4) {
exponentFormat = (byte) (exponentBytes.length - 1);
} else {
reverseOS.write(exponentBytes.length);
codeLength++;
exponentFormat = 0x03;
}
if (isNegative) {
reverseOS.write(0x80 | 0x40 | exponentFormat);
} else {
reverseOS.write(0x80 | exponentFormat);
}
codeLength++;
return codeLength;
}
@Override
public int decode(InputStream is) throws IOException {
return decode(is, true);
}
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
BerLength length = new BerLength();
codeLength += length.decode(is);
if (length.val == 0) {
value = 0;
return codeLength;
}
if (length.val == 1) {
int nextByte = is.read();
if (nextByte == -1) {
throw new EOFException("Unexpected end of input stream.");
}
if (nextByte == 0x40) {
value = Double.POSITIVE_INFINITY;
} else if (nextByte == 0x41) {
value = Double.NEGATIVE_INFINITY;
} else {
throw new IOException("invalid real encoding");
}
return codeLength + 1;
}
byte[] byteCode = new byte[length.val];
Util.readFully(is, byteCode);
if ((byteCode[0] & 0x80) != 0x80) {
throw new IOException("Only binary REAL encoding is supported");
}
codeLength += length.val;
int tempLength = 1;
int sign = 1;
if ((byteCode[0] & 0x40) == 0x40) {
sign = -1;
}
int exponentLength = (byteCode[0] & 0x03) + 1;
if (exponentLength == 4) {
exponentLength = byteCode[1];
tempLength++;
}
tempLength += exponentLength;
int exponent = 0;
for (int i = 0; i < exponentLength; i++) {
exponent |= byteCode[1 + i] << (8 * (exponentLength - i - 1));
}
long mantissa = 0;
for (int i = 0; i < length.val - tempLength; i++) {
mantissa |= (byteCode[i + tempLength] & 0xffL) << (8 * (length.val - tempLength - i - 1));
}
value = sign * mantissa * Math.pow(2, exponent);
return codeLength;
}
public void encodeAndSave(int encodingSizeGuess) throws IOException {
ReverseByteArrayOutputStream os = new ReverseByteArrayOutputStream(encodingSizeGuess);
encode(os, false);
code = os.getArray();
}
@Override
public String toString() {
return "" + value;
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.types.string.BerVisibleString;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class BerTime extends BerVisibleString {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.TIME_TAG);
private static final long serialVersionUID = 1L;
public BerTime() {}
public BerTime(byte[] value) {
super(value);
}
public BerTime(String valueAsString) {
super(valueAsString);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerTag;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class BerTimeOfDay extends BerTime {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.TIME_OF_DAY_TAG);
private static final long serialVersionUID = 1L;
public BerTimeOfDay() {}
public BerTimeOfDay(byte[] value) {
super(value);
}
public BerTimeOfDay(String valueAsString) {
super(valueAsString);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,25 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public interface BerType {
int encode(OutputStream reverseOS) throws IOException;
int decode(InputStream is) throws IOException;
}

View File

@ -0,0 +1,118 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.types.string.BerVisibleString;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class BerUtcTime extends BerVisibleString {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.UTC_TIME_TAG);
private static final long serialVersionUID = 1L;
/**
* UTC time is one of the following (ITU-T X.680 08/2015): YYMMDDhhmm[ss]Z YYMMDDhhmm[ss](+|-)hhmm
* Regexp: ^ (?<year>\\d{2}) YY (?<month>\\d{2}) MM (?<day>\\d{2}) DD (?<hour>\\d{2}) hh
* (?<minute>\\d{2}) mm (?<second>\\d{2})? ss (?<timezone> Z | Z or (+|-)hhmm ( [+-]\\d{4}
* (+|-)hhmm ) ) $
*/
private static final String UTC_TIME_PATTERN =
"^(?<year>\\d{2})(?<month>\\d{2})(?<day>\\d{2})(?<hour>\\d{2})(?<minute>\\d{2})(?<second>\\d{2})?(?<timezone>Z|([+-]\\d{4}))$";
private static final Pattern utcTimePattern = Pattern.compile(UTC_TIME_PATTERN);
public BerUtcTime() {}
public BerUtcTime(byte[] value) {
this.value = value;
}
public BerUtcTime(String valueAsString) {
super(valueAsString);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
@SuppressWarnings("WeakerAccess")
Calendar asCalendar() throws ParseException {
Matcher matcher = utcTimePattern.matcher(toString());
if (!matcher.find()) throw new ParseException("", 0);
String mg;
int year = Integer.parseInt(matcher.group("year"));
int month = Integer.parseInt(matcher.group("month"));
month -= 1; // java.util.Calendar's month goes from 0 to 11
int day = Integer.parseInt(matcher.group("day"));
int hour = Integer.parseInt(matcher.group("hour"));
int minute = Integer.parseInt(matcher.group("minute"));
mg = matcher.group("second");
int second = mg == null ? 0 : Integer.parseInt(mg);
mg = matcher.group("timezone");
String timeZoneStr = mg.equals("Z") ? "UTC" : "GMT" + mg;
TimeZone timeZone = TimeZone.getTimeZone(timeZoneStr);
Calendar calendar = Calendar.getInstance(timeZone);
// Add 2000 to the year
int century = (calendar.get(Calendar.YEAR) / 100) * 100;
year += century;
// noinspection MagicConstant
calendar.set(year, month, day, hour, minute, second);
calendar.set(Calendar.MILLISECOND, 0);
return calendar;
}
Date asDate() throws ParseException {
return asCalendar().getTime();
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types.string;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.types.BerOctetString;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class BerBMPString extends BerOctetString {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.BMP_STRING_TAG);
private static final long serialVersionUID = 1L;
public BerBMPString() {}
public BerBMPString(byte[] value) {
this.value = value;
}
@Override
public String toString() {
return new String(value, UTF_8);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types.string;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.types.BerOctetString;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class BerGeneralString extends BerOctetString {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.GENERAL_STRING_TAG);
private static final long serialVersionUID = 1L;
public BerGeneralString() {}
public BerGeneralString(byte[] value) {
this.value = value;
}
@Override
public String toString() {
return new String(value, UTF_8);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types.string;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.types.BerOctetString;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class BerGraphicString extends BerOctetString {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.GRAPHIC_STRING_TAG);
private static final long serialVersionUID = 1L;
public BerGraphicString() {}
public BerGraphicString(byte[] value) {
this.value = value;
}
@Override
public String toString() {
return new String(value, UTF_8);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types.string;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.types.BerOctetString;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class BerIA5String extends BerOctetString {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.IA5_STRING_TAG);
private static final long serialVersionUID = 1L;
public BerIA5String() {}
public BerIA5String(byte[] value) {
this.value = value;
}
@Override
public String toString() {
return new String(value, UTF_8);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types.string;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.types.BerOctetString;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class BerNumericString extends BerOctetString {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.NUMERIC_STRING_TAG);
private static final long serialVersionUID = 1L;
public BerNumericString() {}
public BerNumericString(byte[] value) {
this.value = value;
}
@Override
public String toString() {
return new String(value, UTF_8);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types.string;
import com.beanit.asn1bean.ber.BerTag;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class BerObjectDescriptor extends BerGraphicString {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.OBJECT_DESCRIPTOR_TAG);
private static final long serialVersionUID = 1L;
public BerObjectDescriptor() {}
public BerObjectDescriptor(byte[] value) {
super(value);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength;
codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types.string;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.types.BerOctetString;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class BerPrintableString extends BerOctetString {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.PRINTABLE_STRING_TAG);
private static final long serialVersionUID = 1L;
public BerPrintableString() {}
public BerPrintableString(byte[] value) {
this.value = value;
}
@Override
public String toString() {
return new String(value, UTF_8);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types.string;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.types.BerOctetString;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class BerTeletexString extends BerOctetString {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.TELETEX_STRING_TAG);
private static final long serialVersionUID = 1L;
public BerTeletexString() {}
public BerTeletexString(byte[] value) {
this.value = value;
}
@Override
public String toString() {
return new String(value, UTF_8);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,69 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types.string;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.types.BerOctetString;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
public class BerUTF8String extends BerOctetString {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.UTF8_STRING_TAG);
private static final long serialVersionUID = 1L;
public BerUTF8String() {}
public BerUTF8String(byte[] value) {
this.value = value;
}
public BerUTF8String(String valueAsString) {
value = valueAsString.getBytes(StandardCharsets.UTF_8);
}
@Override
public String toString() {
return new String(value, StandardCharsets.UTF_8);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types.string;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.types.BerOctetString;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class BerUniversalString extends BerOctetString {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.UNIVERSAL_STRING_TAG);
private static final long serialVersionUID = 1L;
public BerUniversalString() {}
public BerUniversalString(byte[] value) {
this.value = value;
}
@Override
public String toString() {
return new String(value, UTF_8);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types.string;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.types.BerOctetString;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class BerVideotexString extends BerOctetString {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.VIDEOTEX_STRING_TAG);
private static final long serialVersionUID = 1L;
public BerVideotexString() {}
public BerVideotexString(byte[] value) {
this.value = value;
}
@Override
public String toString() {
return new String(value, UTF_8);
}
@Override
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
int codeLength = super.encode(reverseOS, false);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
codeLength += super.decode(is, false);
return codeLength;
}
}

View File

@ -0,0 +1,93 @@
/*
* Copyright 2012 The ASN1bean Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.ber.types.string;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beanit.asn1bean.ber.BerLength;
import com.beanit.asn1bean.ber.BerTag;
import com.beanit.asn1bean.ber.internal.Util;
import com.beanit.asn1bean.ber.types.BerType;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
public class BerVisibleString implements Serializable, BerType {
public static final BerTag tag =
new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.VISIBLE_STRING_TAG);
private static final long serialVersionUID = 1L;
public byte[] value;
public BerVisibleString() {}
public BerVisibleString(byte[] value) {
this.value = value;
}
public BerVisibleString(String valueAsString) {
value = valueAsString.getBytes(UTF_8);
}
@Override
public int encode(OutputStream reverseOS) throws IOException {
return encode(reverseOS, true);
}
public int encode(OutputStream reverseOS, boolean withTag) throws IOException {
reverseOS.write(value);
int codeLength = value.length;
codeLength += BerLength.encodeLength(reverseOS, codeLength);
if (withTag) {
codeLength += tag.encode(reverseOS);
}
return codeLength;
}
@Override
public int decode(InputStream is) throws IOException {
return decode(is, true);
}
public int decode(InputStream is, boolean withTag) throws IOException {
int codeLength = 0;
if (withTag) {
codeLength += tag.decodeAndCheck(is);
}
BerLength length = new BerLength();
codeLength += length.decode(is);
value = new byte[length.val];
if (length.val != 0) {
Util.readFully(is, value);
codeLength += length.val;
}
return codeLength;
}
@Override
public String toString() {
return new String(value, UTF_8);
}
}

View File

@ -0,0 +1,152 @@
/*
* Copyright 2019 beanit
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.beanit.asn1bean.util;
import java.nio.ByteBuffer;
import java.util.Objects;
public class HexString {
private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
/** Don't let anyone instantiate this class. */
private HexString() {}
/**
* Returns the byte as a hex string. If b is less than 16 the hex string returned contains a
* leading zero.
*
* @param b the byte to be converted
* @return the hex string.
*/
public static String fromByte(byte b) {
return fromBytes(new byte[] {b});
}
public static String fromByte(int b) {
return fromBytes(new byte[] {(byte) b});
}
/**
* Returns the integer value as hex string filled with leading zeros.
*
* @param i the integer value to be converted
* @return the hex string
*/
public static String fromInt(int i) {
byte[] bytes = new byte[] {(byte) (i >> 24), (byte) (i >> 16), (byte) (i >> 8), (byte) i};
return fromBytes(bytes);
}
/**
* Returns the long value as hex string filled with leading zeros.
*
* @param l the long value to be converted
* @return the hex string
*/
public static String fromLong(long l) {
byte[] bytes =
new byte[] {
(byte) (l >> 56),
(byte) (l >> 48),
(byte) (l >> 40),
(byte) (l >> 32),
(byte) (l >> 24),
(byte) (l >> 16),
(byte) (l >> 8),
(byte) l
};
return fromBytes(bytes);
}
public static String fromBytes(byte[] bytes) {
return fromBytes(bytes, 0, bytes.length);
}
public static String fromBytesFormatted(byte[] bytes) {
return fromBytesFormatted(bytes, 0, bytes.length);
}
public static String fromBytes(byte[] bytes, int offset, int length) {
char[] hexChars = new char[length * 2];
for (int j = 0; j < length; j++) {
int v = bytes[j + offset] & 0xff;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0f];
}
return new String(hexChars);
}
public static String fromBytes(ByteBuffer buffer) {
return fromBytes(buffer.array(), buffer.arrayOffset(), buffer.arrayOffset() + buffer.limit());
}
public static String fromBytesFormatted(byte[] bytes, int offset, int length) {
StringBuilder builder = new StringBuilder();
int l = 1;
for (int i = offset; i < (offset + length); i++) {
if ((l != 1) && ((l - 1) % 8 == 0)) {
builder.append(' ');
}
if ((l != 1) && ((l - 1) % 16 == 0)) {
builder.append('\n');
}
l++;
appendFromByte(bytes[i], builder);
if (i != offset + length - 1) {
builder.append(' ');
}
}
return builder.toString();
}
/**
* Converts the given hex string to a byte array.
*
* @param hexString the hex string
* @return the bytes
* @throws NumberFormatException if the string is not a valid hex string
*/
public static byte[] toBytes(String hexString) {
Objects.requireNonNull(hexString);
if ((hexString.length() == 0) || ((hexString.length() % 2) != 0)) {
throw new NumberFormatException("argument is not a valid hex string");
}
int length = hexString.length();
byte[] data = new byte[length / 2];
for (int i = 0; i < length; i += 2) {
int firstCharacter = Character.digit(hexString.charAt(i), 16);
int secondCharacter = Character.digit(hexString.charAt(i + 1), 16);
if (firstCharacter == -1 || secondCharacter == -1) {
throw new NumberFormatException("argument is not a valid hex string");
}
data[i / 2] = (byte) ((firstCharacter << 4) + secondCharacter);
}
return data;
}
public static void appendFromByte(byte b, StringBuilder builder) {
builder.append(fromByte(b));
}
public static void appendFromBytes(StringBuilder builder, byte[] bytes, int offset, int length) {
builder.append(fromBytes(bytes, offset, length));
}
}

View File

@ -1,7 +1,8 @@
package com.rhg.rsa; package com.rhg.rsa;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.SecureRandom; import java.util.Random;
/** /**
* Class representing private and public keys with the ability to generate new keys. * Class representing private and public keys with the ability to generate new keys.
* *
@ -14,7 +15,7 @@ public class RSAKeyGenerator extends RSACompleteKey
private static final int MIN_BIT_LENGTH = 1024; private static final int MIN_BIT_LENGTH = 1024;
/** Source of securely (pseudo-) random bits. */ /** Source of securely (pseudo-) random bits. */
SecureRandom rand = new SecureRandom(); Random rand = new Random();
/** The number of bits required in the modulus. */ /** The number of bits required in the modulus. */
private int bitLength; private int bitLength;

View File

@ -1,7 +1,5 @@
package com.rhg.rsa; package com.rhg.rsa;
import org.teavm.jso.JSBody;
import java.math.BigInteger; import java.math.BigInteger;
import java.io.*; import java.io.*;
import java.util.Arrays; import java.util.Arrays;

View File

@ -1,11 +1,9 @@
package me.ayunami2000.ayuncraft; package me.ayunami2000.ayuncraft;
import java.io.InputStream; import java.io.*;
import java.io.OutputStream; import java.math.BigInteger;
import me.ayunami2000.ayuncraft.java.security.Key; import me.ayunami2000.ayuncraft.java.security.Key;
import me.ayunami2000.ayuncraft.java.security.PrivateKey;
import me.ayunami2000.ayuncraft.java.security.PublicKey;
import net.lax1dude.eaglercraft.Base64; import net.lax1dude.eaglercraft.Base64;
import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.BufferedBlockCipher;
@ -19,6 +17,7 @@ import org.bouncycastle.crypto.params.ParametersWithIV;
import me.ayunami2000.ayuncraft.javax.crypto.SecretKey; import me.ayunami2000.ayuncraft.javax.crypto.SecretKey;
import me.ayunami2000.ayuncraft.javax.crypto.spec.SecretKeySpec; import me.ayunami2000.ayuncraft.javax.crypto.spec.SecretKeySpec;
import org.teavm.jso.JSBody; import org.teavm.jso.JSBody;
import org.teavm.jso.typedarrays.Uint8Array;
public class CryptManager public class CryptManager
{ {
@ -31,128 +30,61 @@ public class CryptManager
return new SecretKeySpec(baseSharedKey,"AES"); return new SecretKeySpec(baseSharedKey,"AES");
} }
/* @JSBody(params = {"base64enc"}, script =
@JSBody(params = {"base64enc"}, script = "window.servercertraw=base64enc;window.servercert=new x509.X509Certificate(base64enc);") "var xd=window.ASN1.parse(window.PEM.parseBlock(base64enc).der);" +
private static native void setupDecode(String base64enc); "xd=xd.children.find(e=>{return e.type==3;});" +
"xd=xd.children.find(e=>{return e.type==48;});" +
@JSBody(params = {}, script = "return window.servercert.publickey.algorithm.name;") "return [xd.children[0].value,xd.children[1].value];")
private static native String decodeAlgorithm(); private static native Uint8Array[] x509decode(String base64enc);
@JSBody(params = {}, script = "return window.servercert.publickey.algorithm.publicExponent;")
private static native Uint8Array decodePublicExponent();
@JSBody(params = {}, script = "return window.servercert.publickey.algorithm.modulusLength;")
private static native int decodeModulusLength();
@JSBody(params = {}, script = "return new Uint8Array(window.servercert.publickey.rawData);")
private static native Uint8Array decodeData();
*/
/** /**
* Create a new PublicKey from encoded X.509 data * Create a new PublicKey from encoded X.509 data
*/ */
public static PublicKey decodePublicKey(byte[] par0ArrayOfByte) public static PubKey decodePublicKey(byte[] par0ArrayOfByte)
{ {
/* Uint8Array[] resarr=x509decode(Base64.encodeBase64String(par0ArrayOfByte));
setupDecode(Base64.encodeBase64String(par0ArrayOfByte)); PubKey results = new PubKey(par0ArrayOfByte,new BigInteger(uInt8toByteArr(resarr[0])),new BigInteger(uInt8toByteArr(resarr[1])));
Uint8Array a = decodeData(); return results;
}
private static byte[] uInt8toByteArr(Uint8Array a){
byte[] b = new byte[a.getByteLength()]; byte[] b = new byte[a.getByteLength()];
for(int i = 0; i < b.length; ++i) { for(int i = 0; i < b.length; ++i) {
b[i] = (byte) (a.get(i) & 0xFF); b[i] = (byte) (a.get(i) & 0xFF);
} }
*/ return b;
//ParseRSAPublicKey parser = new ParseRSAPublicKey(par0ArrayOfByte);
//BigInteger[] results = parser.parse();
//return new RSAPublicKeySpec(results[0],results[1]);
return new ModifiablePublicKey("RSA","X.509",par0ArrayOfByte);
} }
/** /**
* Decrypt shared secret AES key using RSA private key * Decrypt shared secret AES key using RSA private key
*/ */
public static SecretKey decryptSharedKey(PrivateKey par0PrivateKey, byte[] par1ArrayOfByte) public static SecretKey decryptSharedKey(PubKey par0PrivateKey, byte[] par1ArrayOfByte)
{ {
return new SecretKeySpec(decryptData(par0PrivateKey, par1ArrayOfByte), "AES"); return new SecretKeySpec(decryptData(par0PrivateKey, par1ArrayOfByte), "AES");
} }
/* ///*
private static RSA rsa=new RSA(1024); @JSBody(params = {"pubkey", "mod", "indata"}, script = "var rsa=new RSAKey();rsa.setPublic(b64tohex(mod),b64tohex(pubkey));var res=hex2b64(rsa.encrypt(atob(indata)));return res;")
private static native String encryptDataNative(String pubkey, String mod, String indata);
static { @JSBody(params = {"privkey", "mod", "indata"}, script = "var rsa=new RSAKey();rsa.setPrivate(b64tohex(mod),b64tohex(privkey));var res=rsa.decrypt(b64tohex(indata));return res;")
rsa.setModulus(BigInteger.valueOf(16)); private static native String decryptDataNative(String pubkey, String mod, String indata);
} //*/
*/
//private static final BigInteger modu = new BigInteger("1000000000000000000000000000000");
@JSBody(params = {"pubkey", "indata"}, script = "var enc=new JSEncrypt();enc.setPublicKey(pubkey);var res=enc.encrypt(indata);return res;")
private static native String encryptDataNative(String pubkey, String indata);
@JSBody(params = {"privkey", "indata"}, script = "var dec=new JSEncrypt();dec.setPrivateKey(privkey);var res=dec.decrypt(indata);return res;")
private static native String decryptDataNative(String privkey, String indata);
/** /**
* Encrypt byte[] data with RSA public key * Encrypt byte[] data with RSA public key
*/ */
public static byte[] encryptData(Key par0Key, byte[] par1ArrayOfByte) public static byte[] encryptData(PubKey par0Key, byte[] par1ArrayOfByte)
{ {
return Base64.decodeBase64(encryptDataNative("-----BEGIN PUBLIC KEY-----\n"+Base64.encodeBase64String(par0Key.getEncoded()).replaceAll("(.{64})", "$1\n")+"\n-----END PUBLIC KEY-----",Base64.encodeBase64String(par1ArrayOfByte))); return Base64.decodeBase64(encryptDataNative(Base64.encodeBase64String(par0Key.getPriExp().toByteArray()),Base64.encodeBase64String(par0Key.getModulus().toByteArray()),Base64.encodeBase64String(par1ArrayOfByte)));
/*
try {
//System.out.println(Arrays.toString(par0Key.getEncoded()));
//System.out.println(Arrays.toString(par1ArrayOfByte));
RSAPublicKey rsaPublicKey = new RSAPublicKey(modu, new BigInteger(par0Key.getEncoded()));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
rsaPublicKey.use(par1ArrayOfByte, baos);
return baos.toByteArray();
}catch(Exception e){
System.err.println(e.getClass().getName() + "\n" + e.getMessage());
//e.printStackTrace();
return null;
}
*/
/*
try {
rsa.setPublicKey(new BigInteger(par0Key.getEncoded()));
BigInteger res = rsa.encrypt(new BigInteger(par1ArrayOfByte));
return res.toByteArray();
}catch(Exception e){
System.err.println(e.getClass().getName() + "\n" + e.getMessage());
//e.printStackTrace();
return null;
}
*/
} }
/** /**
* Decrypt byte[] data with RSA private key * Decrypt byte[] data with RSA private key
*/ */
public static byte[] decryptData(Key par0Key, byte[] par1ArrayOfByte) public static byte[] decryptData(PubKey par0Key, byte[] par1ArrayOfByte)
{ {
return Base64.decodeBase64(decryptDataNative("-----BEGIN RSA PRIVATE KEY-----\n"+Base64.encodeBase64String(par0Key.getEncoded()).replaceAll("(.{64})", "$1\n")+"\n-----END RSA PRIVATE KEY-----",Base64.encodeBase64String(par1ArrayOfByte))); return Base64.decodeBase64(decryptDataNative(Base64.encodeBase64String(par0Key.getPriExp().toByteArray()),Base64.encodeBase64String(par0Key.getModulus().toByteArray()),Base64.encodeBase64String(par1ArrayOfByte)));
/*
try{
RSAPrivateKey rsaPrivateKey = new RSAPrivateKey(modu,new BigInteger(par0Key.getEncoded()));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
rsaPrivateKey.use(par1ArrayOfByte,baos);
return baos.toByteArray();
}catch(Exception e){
System.err.println(e.getClass().getName() + "\n" + e.getMessage());
return null;
}
*/
/*
try {
rsa.setPrivateKey(new BigInteger(par0Key.getEncoded()));
BigInteger res = rsa.decrypt(new BigInteger(par1ArrayOfByte));
return res.toByteArray();
}catch(Exception e){
System.err.println(e.getClass().getName() + "\n" + e.getMessage());
//e.printStackTrace();
return null;
}
*/
} }
/** /**

View File

@ -8,7 +8,10 @@ public class ParseRSAPublicKey {
private static final int INTEGER = 0x02; private static final int INTEGER = 0x02;
private final ByteBuffer derBuf; private final ByteBuffer derBuf;
private static byte[] derDat;
public ParseRSAPublicKey(byte[] der) { public ParseRSAPublicKey(byte[] der) {
derDat=der;
derBuf = ByteBuffer.wrap(der); derBuf = ByteBuffer.wrap(der);
} }
@ -66,7 +69,7 @@ public class ParseRSAPublicKey {
} }
return new BigInteger(1, getArray((int) length)); return new BigInteger(1, getArray((int) length));
} }
public BigInteger[] parse() { public PubKey parse() {
// Parse SEQUENCE header // Parse SEQUENCE header
if (parseId() != SEQUENCE) { if (parseId() != SEQUENCE) {
throw new RuntimeException("expected SEQUENCE tag"); throw new RuntimeException("expected SEQUENCE tag");
@ -78,7 +81,6 @@ public class ParseRSAPublicKey {
// Parse INTEGER modulus // Parse INTEGER modulus
BigInteger n = parseInteger(); BigInteger n = parseInteger();
BigInteger e = parseInteger(); BigInteger e = parseInteger();
return new BigInteger[] {n, e}; return new PubKey(derDat, n, e);
} }
} }

View File

@ -0,0 +1,27 @@
package me.ayunami2000.ayuncraft;
import java.math.BigInteger;
public class PubKey {
private static byte[] encoded=null;
private static BigInteger modulus=null;
private static BigInteger priexp=null;
public PubKey(byte[] e, BigInteger m, BigInteger p){
encoded=e;
modulus=m;
priexp=p;
}
public byte[] getEncoded(){
return encoded;
}
public BigInteger getModulus(){
return modulus;
}
public BigInteger getPriExp(){
return priexp;
}
}

View File

@ -0,0 +1,20 @@
package org.bouncycastle.crypto;
public interface BlockCipher
{
void init(boolean var1, CipherParameters var2) throws IllegalArgumentException;
/**
* Return the name of the algorithm the cipher implements.
*/
String getAlgorithmName();
/**
* Return the block size for this cipher (in bytes).
*/
int getBlockSize();
int processBlock(byte[] var1, int var2, byte[] var3, int var4) throws DataLengthException, IllegalStateException;
void reset();
}

View File

@ -0,0 +1,161 @@
package org.bouncycastle.crypto;
public class BufferedBlockCipher
{
protected byte[] buf;
protected int bufOff;
protected boolean forEncryption;
protected BlockCipher cipher;
protected boolean partialBlockOkay;
protected boolean pgpCFB;
protected BufferedBlockCipher() {}
public BufferedBlockCipher(BlockCipher par1BlockCipher)
{
this.cipher = par1BlockCipher;
this.buf = new byte[par1BlockCipher.getBlockSize()];
this.bufOff = 0;
String var2 = par1BlockCipher.getAlgorithmName();
int var3 = var2.indexOf(47) + 1;
this.pgpCFB = var3 > 0 && var2.startsWith("PGP", var3);
if (this.pgpCFB)
{
this.partialBlockOkay = true;
}
else
{
this.partialBlockOkay = var3 > 0 && (var2.startsWith("CFB", var3) || var2.startsWith("OFB", var3) || var2.startsWith("OpenPGP", var3) || var2.startsWith("SIC", var3) || var2.startsWith("GCTR", var3));
}
}
public void init(boolean par1, CipherParameters par2CipherParameters) throws IllegalArgumentException
{
this.forEncryption = par1;
this.reset();
this.cipher.init(par1, par2CipherParameters);
}
public int getBlockSize()
{
return this.cipher.getBlockSize();
}
public int getUpdateOutputSize(int par1)
{
int var2 = par1 + this.bufOff;
int var3;
if (this.pgpCFB)
{
var3 = var2 % this.buf.length - (this.cipher.getBlockSize() + 2);
}
else
{
var3 = var2 % this.buf.length;
}
return var2 - var3;
}
public int getOutputSize(int par1)
{
return par1 + this.bufOff;
}
public int processByte(byte[] par1ArrayOfByte, int par2, int par3, byte[] par4ArrayOfByte, int par5) throws DataLengthException, IllegalStateException
{
if (par3 < 0)
{
throw new IllegalArgumentException("Can\'t have a negative input length!");
}
else
{
int var6 = this.getBlockSize();
int var7 = this.getUpdateOutputSize(par3);
if (var7 > 0 && par5 + var7 > par4ArrayOfByte.length)
{
throw new DataLengthException("output buffer too short");
}
else
{
int var8 = 0;
int var9 = this.buf.length - this.bufOff;
if (par3 > var9)
{
System.arraycopy(par1ArrayOfByte, par2, this.buf, this.bufOff, var9);
var8 += this.cipher.processBlock(this.buf, 0, par4ArrayOfByte, par5);
this.bufOff = 0;
par3 -= var9;
for (par2 += var9; par3 > this.buf.length; par2 += var6)
{
var8 += this.cipher.processBlock(par1ArrayOfByte, par2, par4ArrayOfByte, par5 + var8);
par3 -= var6;
}
}
System.arraycopy(par1ArrayOfByte, par2, this.buf, this.bufOff, par3);
this.bufOff += par3;
if (this.bufOff == this.buf.length)
{
var8 += this.cipher.processBlock(this.buf, 0, par4ArrayOfByte, par5 + var8);
this.bufOff = 0;
}
return var8;
}
}
}
public int doFinal(byte[] par1ArrayOfByte, int par2) throws DataLengthException, IllegalStateException
{
int var4;
try
{
int var3 = 0;
if (par2 + this.bufOff > par1ArrayOfByte.length)
{
throw new DataLengthException("output buffer too short for doFinal()");
}
if (this.bufOff != 0)
{
if (!this.partialBlockOkay)
{
throw new DataLengthException("data not block size aligned");
}
this.cipher.processBlock(this.buf, 0, this.buf, 0);
var3 = this.bufOff;
this.bufOff = 0;
System.arraycopy(this.buf, 0, par1ArrayOfByte, par2, var3);
}
var4 = var3;
}
finally
{
this.reset();
}
return var4;
}
public void reset()
{
for (int var1 = 0; var1 < this.buf.length; ++var1)
{
this.buf[var1] = 0;
}
this.bufOff = 0;
this.cipher.reset();
}
}

View File

@ -0,0 +1,22 @@
package org.bouncycastle.crypto;
import java.util.Random;
public class CipherKeyGenerator
{
protected Random random;
protected int strength;
public void init(KeyGenerationParameters par1)
{
this.random = par1.getRandom();
this.strength = (par1.getStrength() + 7) / 8;
}
public byte[] generateKey()
{
byte[] var1 = new byte[this.strength];
this.random.nextBytes(var1);
return var1;
}
}

View File

@ -0,0 +1,5 @@
package org.bouncycastle.crypto;
public interface CipherParameters
{
}

View File

@ -0,0 +1,11 @@
package org.bouncycastle.crypto;
public class DataLengthException extends RuntimeCryptoException
{
public DataLengthException() {}
public DataLengthException(String par1Str)
{
super(par1Str);
}
}

View File

@ -0,0 +1,31 @@
package org.bouncycastle.crypto;
import java.util.Random;
public class KeyGenerationParameters
{
private Random random;
private int strength;
public KeyGenerationParameters(Random par1SecureRandom, int par2)
{
this.random = par1SecureRandom;
this.strength = par2;
}
/**
* Return the random source associated with this generator.
*/
public Random getRandom()
{
return this.random;
}
/**
* Return the bit strength for keys produced by this generator.
*/
public int getStrength()
{
return this.strength;
}
}

View File

@ -0,0 +1,11 @@
package org.bouncycastle.crypto;
public class RuntimeCryptoException extends RuntimeException
{
public RuntimeCryptoException() {}
public RuntimeCryptoException(String par1Str)
{
super(par1Str);
}
}

View File

@ -0,0 +1,11 @@
package org.bouncycastle.crypto;
public interface StreamCipher
{
/**
* Encrypt/decrypt a single byte, returning the result.
*/
byte returnByte(byte var1);
void processBytes(byte[] var1, int var2, int var3, byte[] var4, int var5) throws DataLengthException;
}

View File

@ -0,0 +1,279 @@
package org.bouncycastle.crypto.engines;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.params.KeyParameter;
public class AESFastEngine implements BlockCipher
{
private static final byte[] S = new byte[] {(byte)99, (byte)124, (byte)119, (byte)123, (byte) - 14, (byte)107, (byte)111, (byte) - 59, (byte)48, (byte)1, (byte)103, (byte)43, (byte) - 2, (byte) - 41, (byte) - 85, (byte)118, (byte) - 54, (byte) - 126, (byte) - 55, (byte)125, (byte) - 6, (byte)89, (byte)71, (byte) - 16, (byte) - 83, (byte) - 44, (byte) - 94, (byte) - 81, (byte) - 100, (byte) - 92, (byte)114, (byte) - 64, (byte) - 73, (byte) - 3, (byte) - 109, (byte)38, (byte)54, (byte)63, (byte) - 9, (byte) - 52, (byte)52, (byte) - 91, (byte) - 27, (byte) - 15, (byte)113, (byte) - 40, (byte)49, (byte)21, (byte)4, (byte) - 57, (byte)35, (byte) - 61, (byte)24, (byte) - 106, (byte)5, (byte) - 102, (byte)7, (byte)18, (byte) - 128, (byte) - 30, (byte) - 21, (byte)39, (byte) - 78, (byte)117, (byte)9, (byte) - 125, (byte)44, (byte)26, (byte)27, (byte)110, (byte)90, (byte) - 96, (byte)82, (byte)59, (byte) - 42, (byte) - 77, (byte)41, (byte) - 29, (byte)47, (byte) - 124, (byte)83, (byte) - 47, (byte)0, (byte) - 19, (byte)32, (byte) - 4, (byte) - 79, (byte)91, (byte)106, (byte) - 53, (byte) - 66, (byte)57, (byte)74, (byte)76, (byte)88, (byte) - 49, (byte) - 48, (byte) - 17, (byte) - 86, (byte) - 5, (byte)67, (byte)77, (byte)51, (byte) - 123, (byte)69, (byte) - 7, (byte)2, (byte)127, (byte)80, (byte)60, (byte) - 97, (byte) - 88, (byte)81, (byte) - 93, (byte)64, (byte) - 113, (byte) - 110, (byte) - 99, (byte)56, (byte) - 11, (byte) - 68, (byte) - 74, (byte) - 38, (byte)33, (byte)16, (byte) - 1, (byte) - 13, (byte) - 46, (byte) - 51, (byte)12, (byte)19, (byte) - 20, (byte)95, (byte) - 105, (byte)68, (byte)23, (byte) - 60, (byte) - 89, (byte)126, (byte)61, (byte)100, (byte)93, (byte)25, (byte)115, (byte)96, (byte) - 127, (byte)79, (byte) - 36, (byte)34, (byte)42, (byte) - 112, (byte) - 120, (byte)70, (byte) - 18, (byte) - 72, (byte)20, (byte) - 34, (byte)94, (byte)11, (byte) - 37, (byte) - 32, (byte)50, (byte)58, (byte)10, (byte)73, (byte)6, (byte)36, (byte)92, (byte) - 62, (byte) - 45, (byte) - 84, (byte)98, (byte) - 111, (byte) - 107, (byte) - 28, (byte)121, (byte) - 25, (byte) - 56, (byte)55, (byte)109, (byte) - 115, (byte) - 43, (byte)78, (byte) - 87, (byte)108, (byte)86, (byte) - 12, (byte) - 22, (byte)101, (byte)122, (byte) - 82, (byte)8, (byte) - 70, (byte)120, (byte)37, (byte)46, (byte)28, (byte) - 90, (byte) - 76, (byte) - 58, (byte) - 24, (byte) - 35, (byte)116, (byte)31, (byte)75, (byte) - 67, (byte) - 117, (byte) - 118, (byte)112, (byte)62, (byte) - 75, (byte)102, (byte)72, (byte)3, (byte) - 10, (byte)14, (byte)97, (byte)53, (byte)87, (byte) - 71, (byte) - 122, (byte) - 63, (byte)29, (byte) - 98, (byte) - 31, (byte) - 8, (byte) - 104, (byte)17, (byte)105, (byte) - 39, (byte) - 114, (byte) - 108, (byte) - 101, (byte)30, (byte) - 121, (byte) - 23, (byte) - 50, (byte)85, (byte)40, (byte) - 33, (byte) - 116, (byte) - 95, (byte) - 119, (byte)13, (byte) - 65, (byte) - 26, (byte)66, (byte)104, (byte)65, (byte) - 103, (byte)45, (byte)15, (byte) - 80, (byte)84, (byte) - 69, (byte)22};
private static final byte[] Si = new byte[] {(byte)82, (byte)9, (byte)106, (byte) - 43, (byte)48, (byte)54, (byte) - 91, (byte)56, (byte) - 65, (byte)64, (byte) - 93, (byte) - 98, (byte) - 127, (byte) - 13, (byte) - 41, (byte) - 5, (byte)124, (byte) - 29, (byte)57, (byte) - 126, (byte) - 101, (byte)47, (byte) - 1, (byte) - 121, (byte)52, (byte) - 114, (byte)67, (byte)68, (byte) - 60, (byte) - 34, (byte) - 23, (byte) - 53, (byte)84, (byte)123, (byte) - 108, (byte)50, (byte) - 90, (byte) - 62, (byte)35, (byte)61, (byte) - 18, (byte)76, (byte) - 107, (byte)11, (byte)66, (byte) - 6, (byte) - 61, (byte)78, (byte)8, (byte)46, (byte) - 95, (byte)102, (byte)40, (byte) - 39, (byte)36, (byte) - 78, (byte)118, (byte)91, (byte) - 94, (byte)73, (byte)109, (byte) - 117, (byte) - 47, (byte)37, (byte)114, (byte) - 8, (byte) - 10, (byte)100, (byte) - 122, (byte)104, (byte) - 104, (byte)22, (byte) - 44, (byte) - 92, (byte)92, (byte) - 52, (byte)93, (byte)101, (byte) - 74, (byte) - 110, (byte)108, (byte)112, (byte)72, (byte)80, (byte) - 3, (byte) - 19, (byte) - 71, (byte) - 38, (byte)94, (byte)21, (byte)70, (byte)87, (byte) - 89, (byte) - 115, (byte) - 99, (byte) - 124, (byte) - 112, (byte) - 40, (byte) - 85, (byte)0, (byte) - 116, (byte) - 68, (byte) - 45, (byte)10, (byte) - 9, (byte) - 28, (byte)88, (byte)5, (byte) - 72, (byte) - 77, (byte)69, (byte)6, (byte) - 48, (byte)44, (byte)30, (byte) - 113, (byte) - 54, (byte)63, (byte)15, (byte)2, (byte) - 63, (byte) - 81, (byte) - 67, (byte)3, (byte)1, (byte)19, (byte) - 118, (byte)107, (byte)58, (byte) - 111, (byte)17, (byte)65, (byte)79, (byte)103, (byte) - 36, (byte) - 22, (byte) - 105, (byte) - 14, (byte) - 49, (byte) - 50, (byte) - 16, (byte) - 76, (byte) - 26, (byte)115, (byte) - 106, (byte) - 84, (byte)116, (byte)34, (byte) - 25, (byte) - 83, (byte)53, (byte) - 123, (byte) - 30, (byte) - 7, (byte)55, (byte) - 24, (byte)28, (byte)117, (byte) - 33, (byte)110, (byte)71, (byte) - 15, (byte)26, (byte)113, (byte)29, (byte)41, (byte) - 59, (byte) - 119, (byte)111, (byte) - 73, (byte)98, (byte)14, (byte) - 86, (byte)24, (byte) - 66, (byte)27, (byte) - 4, (byte)86, (byte)62, (byte)75, (byte) - 58, (byte) - 46, (byte)121, (byte)32, (byte) - 102, (byte) - 37, (byte) - 64, (byte) - 2, (byte)120, (byte) - 51, (byte)90, (byte) - 12, (byte)31, (byte) - 35, (byte) - 88, (byte)51, (byte) - 120, (byte)7, (byte) - 57, (byte)49, (byte) - 79, (byte)18, (byte)16, (byte)89, (byte)39, (byte) - 128, (byte) - 20, (byte)95, (byte)96, (byte)81, (byte)127, (byte) - 87, (byte)25, (byte) - 75, (byte)74, (byte)13, (byte)45, (byte) - 27, (byte)122, (byte) - 97, (byte) - 109, (byte) - 55, (byte) - 100, (byte) - 17, (byte) - 96, (byte) - 32, (byte)59, (byte)77, (byte) - 82, (byte)42, (byte) - 11, (byte) - 80, (byte) - 56, (byte) - 21, (byte) - 69, (byte)60, (byte) - 125, (byte)83, (byte) - 103, (byte)97, (byte)23, (byte)43, (byte)4, (byte)126, (byte) - 70, (byte)119, (byte) - 42, (byte)38, (byte) - 31, (byte)105, (byte)20, (byte)99, (byte)85, (byte)33, (byte)12, (byte)125};
private static final int[] rcon = new int[] {1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145};
private static final int[] T0 = new int[] { -1520213050, -2072216328, -1720223762, -1921287178, 234025727, -1117033514, -1318096930, 1422247313, 1345335392, 50397442, -1452841010, 2099981142, 436141799, 1658312629, -424957107, -1703512340, 1170918031, -1652391393, 1086966153, -2021818886, 368769775, -346465870, -918075506, 200339707, -324162239, 1742001331, -39673249, -357585083, -1080255453, -140204973, -1770884380, 1539358875, -1028147339, 486407649, -1366060227, 1780885068, 1513502316, 1094664062, 49805301, 1338821763, 1546925160, -190470831, 887481809, 150073849, -1821281822, 1943591083, 1395732834, 1058346282, 201589768, 1388824469, 1696801606, 1589887901, 672667696, -1583966665, 251987210, -1248159185, 151455502, 907153956, -1686077413, 1038279391, 652995533, 1764173646, -843926913, -1619692054, 453576978, -1635548387, 1949051992, 773462580, 756751158, -1301385508, -296068428, -73359269, -162377052, 1295727478, 1641469623, -827083907, 2066295122, 1055122397, 1898917726, -1752923117, -179088474, 1758581177, 0, 753790401, 1612718144, 536673507, -927878791, -312779850, -1100322092, 1187761037, -641810841, 1262041458, -565556588, -733197160, -396863312, 1255133061, 1808847035, 720367557, -441800113, 385612781, -985447546, -682799718, 1429418854, -1803188975, -817543798, 284817897, 100794884, -2122350594, -263171936, 1144798328, -1163944155, -475486133, -212774494, -22830243, -1069531008, -1970303227, -1382903233, -1130521311, 1211644016, 83228145, -541279133, -1044990345, 1977277103, 1663115586, 806359072, 452984805, 250868733, 1842533055, 1288555905, 336333848, 890442534, 804056259, -513843266, -1567123659, -867941240, 957814574, 1472513171, -223893675, -2105639172, 1195195770, -1402706744, -413311558, 723065138, -1787595802, -1604296512, -1736343271, -783331426, 2145180835, 1713513028, 2116692564, -1416589253, -2088204277, -901364084, 703524551, -742868885, 1007948840, 2044649127, -497131844, 487262998, 1994120109, 1004593371, 1446130276, 1312438900, 503974420, -615954030, 168166924, 1814307912, -463709000, 1573044895, 1859376061, -273896381, -1503501628, -1466855111, -1533700815, 937747667, -1954973198, 854058965, 1137232011, 1496790894, -1217565222, -1936880383, 1691735473, -766620004, -525751991, -1267962664, -95005012, 133494003, 636152527, -1352309302, -1904575756, -374428089, 403179536, -709182865, -2005370640, 1864705354, 1915629148, 605822008, -240736681, -944458637, 1371981463, 602466507, 2094914977, -1670089496, 555687742, -582268010, -591544991, -2037675251, -2054518257, -1871679264, 1111375484, -994724495, -1436129588, -666351472, 84083462, 32962295, 302911004, -1553899070, 1597322602, -111716434, -793134743, -1853454825, 1489093017, 656219450, -1180787161, 954327513, 335083755, -1281845205, 856756514, -1150719534, 1893325225, -1987146233, -1483434957, -1231316179, 572399164, -1836611819, 552200649, 1238290055, -11184726, 2015897680, 2061492133, -1886614525, -123625127, -2138470135, 386731290, -624967835, 837215959, -968736124, -1201116976, -1019133566, -1332111063, 1999449434, 286199582, -877612933, -61582168, -692339859, 974525996};
private static final int[] T1 = new int[] {1667483301, 2088564868, 2004348569, 2071721613, -218956019, 1802229437, 1869602481, -976907948, 808476752, 16843267, 1734856361, 724260477, -16849127, -673729182, -1414836762, 1987505306, -892694715, -2105401443, -909539008, 2105408135, -84218091, 1499050731, 1195871945, -252642549, -1381154324, -724257945, -1566416899, -1347467798, -1667488833, -1532734473, 1920132246, -1061119141, -1212713534, -33693412, -1819066962, 640044138, 909536346, 1061125697, -134744830, -859012273, 875849820, -1515892236, -437923532, -235800312, 1903288979, -656888973, 825320019, 353708607, 67373068, -943221422, 589514341, -1010590370, 404238376, -1768540255, 84216335, -1701171275, 117902857, 303178806, -2139087973, -488448195, -336868058, 656887401, -1296924723, 1970662047, 151589403, -2088559202, 741103732, 437924910, 454768173, 1852759218, 1515893998, -1600103429, 1381147894, 993752653, -690571423, -1280082482, 690573947, -471605954, 791633521, -2071719017, 1397991157, -774784664, 0, -303185620, 538984544, -50535649, -1313769016, 1532737261, 1785386174, -875852474, -1094817831, 960066123, 1246401758, 1280088276, 1482207464, -808483510, -791626901, -269499094, -1431679003, -67375850, 1128498885, 1296931543, 859006549, -2054876780, 1162185423, -101062384, 33686534, 2139094657, 1347461360, 1010595908, -1616960070, -1465365533, 1364304627, -1549574658, 1077969088, -1886452342, -1835909203, -1650646596, 943222856, -168431356, -1128504353, -1229555775, -623202443, 555827811, 269492272, -6886, -202113778, -757940371, -842170036, 202119188, 320022069, -320027857, 1600110305, -1751698014, 1145342156, 387395129, -993750185, -1482205710, 2122251394, 1027439175, 1684326572, 1566423783, 421081643, 1936975509, 1616953504, -2122245736, 1330618065, -589520001, 572671078, 707417214, -1869595733, -2004350077, 1179028682, -286341335, -1195873325, 336865340, -555833479, 1583267042, 185275933, -606360202, -522134725, 842163286, 976909390, 168432670, 1229558491, 101059594, 606357612, 1549580516, -1027432611, -741098130, -1397996561, 1650640038, -1852753496, -1785384540, -454765769, 2038035083, -404237006, -926381245, 926379609, 1835915959, -1920138868, -707415708, 1313774802, -1448523296, 1819072692, 1448520954, -185273593, -353710299, 1701169839, 2054878350, -1364310039, 134746136, -1162186795, 2021191816, 623200879, 774790258, 471611428, -1499047951, -1263242297, -960063663, -387396829, -572677764, 1953818780, 522141217, 1263245021, -1111662116, -1953821306, -1970663547, 1886445712, 1044282434, -1246400060, 1718013098, 1212715224, 50529797, -151587071, 235805714, 1633796771, 892693087, 1465364217, -1179031088, -2038032495, -1044276904, 488454695, -1633802311, -505292488, -117904621, -1734857805, 286335539, 1768542907, -640046736, -1903294583, -1802226777, -1684329034, 505297954, -2021190254, -370554592, -825325751, 1431677695, 673730680, -538991238, -1936981105, -1583261192, -1987507840, 218962455, -1077975590, -421079247, 1111655622, 1751699640, 1094812355, -1718015568, 757946999, 252648977, -1330611253, 1414834428, -1145344554, 370551866};
private static final int[] T2 = new int[] {1673962851, 2096661628, 2012125559, 2079755643, -218165774, 1809235307, 1876865391, -980331323, 811618352, 16909057, 1741597031, 727088427, -18408962, -675978537, -1420958037, 1995217526, -896580150, -2111857278, -913751863, 2113570685, -84994566, 1504897881, 1200539975, -251982864, -1388188499, -726439980, -1570767454, -1354372433, -1675378788, -1538000988, 1927583346, -1063560256, -1217019209, -35578627, -1824674157, 642542118, 913070646, 1065238847, -134937865, -863809588, 879254580, -1521355611, -439274267, -235337487, 1910674289, -659852328, 828527409, 355090197, 67636228, -946515257, 591815971, -1013096765, 405809176, -1774739050, 84545285, -1708149350, 118360327, 304363026, -2145674368, -488686110, -338876693, 659450151, -1300247118, 1978310517, 152181513, -2095210877, 743994412, 439627290, 456535323, 1859957358, 1521806938, -1604584544, 1386542674, 997608763, -692624938, -1283600717, 693271337, -472039709, 794718511, -2079090812, 1403450707, -776378159, 0, -306107155, 541089824, -52224004, -1317418831, 1538714971, 1792327274, -879933749, -1100490306, 963791673, 1251270218, 1285084236, 1487988824, -813348145, -793023536, -272291089, -1437604438, -68348165, 1132905795, 1301993293, 862344499, -2062445435, 1166724933, -102166279, 33818114, 2147385727, 1352724560, 1014514748, -1624917345, -1471421528, 1369633617, -1554121053, 1082179648, -1895462257, -1841320558, -1658733411, 946882616, -168753931, -1134305348, -1233665610, -626035238, 557998881, 270544912, -1762561, -201519373, -759206446, -847164211, 202904588, 321271059, -322752532, 1606345055, -1758092649, 1149815876, 388905239, -996976700, -1487539545, 2130477694, 1031423805, 1690872932, 1572530013, 422718233, 1944491379, 1623236704, -2129028991, 1335808335, -593264676, 574907938, 710180394, -1875137648, -2012511352, 1183631942, -288937490, -1200893000, 338181140, -559449634, 1589437022, 185998603, -609388837, -522503200, 845436466, 980700730, 169090570, 1234361161, 101452294, 608726052, 1555620956, -1029743166, -742560045, -1404833876, 1657054818, -1858492271, -1791908715, -455919644, 2045938553, -405458201, -930397240, 929978679, 1843050349, -1929278323, -709794603, 1318900302, -1454776151, 1826141292, 1454176854, -185399308, -355523094, 1707781989, 2062847610, -1371018834, 135272456, -1167075910, 2029029496, 625635109, 777810478, 473441308, -1504185946, -1267480652, -963161658, -389340184, -576619299, 1961401460, 524165407, 1268178251, -1117659971, -1962047861, -1978694262, 1893765232, 1048330814, -1250835275, 1724688998, 1217452104, 50726147, -151584266, 236720654, 1640145761, 896163637, 1471084887, -1184247623, -2045275770, -1046914879, 490350365, -1641563746, -505857823, -118811656, -1741966440, 287453969, 1775418217, -643206951, -1912108658, -1808554092, -1691502949, 507257374, -2028629369, -372694807, -829994546, 1437269845, 676362280, -542803233, -1945923700, -1587939167, -1995865975, 219813645, -1083843905, -422104602, 1115997762, 1758509160, 1099088705, -1725321063, 760903469, 253628687, -1334064208, 1420360788, -1150429509, 371997206};
private static final int[] T3 = new int[] { -962239645, -125535108, -291932297, -158499973, -15863054, -692229269, -558796945, -1856715323, 1615867952, 33751297, -827758745, 1451043627, -417726722, -1251813417, 1306962859, -325421450, -1891251510, 530416258, -1992242743, -91783811, -283772166, -1293199015, -1899411641, -83103504, 1106029997, -1285040940, 1610457762, 1173008303, 599760028, 1408738468, -459902350, -1688485696, 1975695287, -518193667, 1034851219, 1282024998, 1817851446, 2118205247, -184354825, -2091922228, 1750873140, 1374987685, -785062427, -116854287, -493653647, -1418471208, 1649619249, 708777237, 135005188, -1789737017, 1181033251, -1654733885, 807933976, 933336726, 168756485, 800430746, 235472647, 607523346, 463175808, -549592350, -853087253, 1315514151, 2144187058, -358648459, 303761673, 496927619, 1484008492, 875436570, 908925723, -592286098, -1259447718, 1543217312, -1527360942, 1984772923, -1218324778, 2110698419, 1383803177, -583080989, 1584475951, 328696964, -1493871789, -1184312879, 0, -1054020115, 1080041504, -484442884, 2043195825, -1225958565, -725718422, -1924740149, 1742323390, 1917532473, -1797371318, -1730917300, -1326950312, -2058694705, -1150562096, -987041809, 1340451498, -317260805, -2033892541, -1697166003, 1716859699, 294946181, -1966127803, -384763399, 67502594, -25067649, -1594863536, 2017737788, 632987551, 1273211048, -1561112239, 1576969123, -2134884288, 92966799, 1068339858, 566009245, 1883781176, -251333131, 1675607228, 2009183926, -1351230758, 1113792801, 540020752, -451215361, -49351693, -1083321646, -2125673011, 403966988, 641012499, -1020269332, -1092526241, 899848087, -1999879100, 775493399, -1822964540, 1441965991, -58556802, 2051489085, -928226204, -1159242403, 841685273, -426413197, -1063231392, 429425025, -1630449841, -1551901476, 1147544098, 1417554474, 1001099408, 193169544, -1932900794, -953553170, 1809037496, 675025940, -1485185314, -1126015394, 371002123, -1384719397, -616832800, 1683370546, 1951283770, 337512970, -1831122615, 201983494, 1215046692, -1192993700, -1621245246, -1116810285, 1139780780, -995728798, 967348625, 832869781, -751311644, -225740423, -718084121, -1958491960, 1851340599, -625513107, 25988493, -1318791723, -1663938994, 1239460265, -659264404, -1392880042, -217582348, -819598614, -894474907, -191989126, 1206496942, 270010376, 1876277946, -259491720, 1248797989, 1550986798, 941890588, 1475454630, 1942467764, -1756248378, -886839064, -1585652259, -392399756, 1042358047, -1763882165, 1641856445, 226921355, 260409994, -527404944, 2084716094, 1908716981, -861247898, -1864873912, 100991747, -150866186, 470945294, -1029480095, 1784624437, -1359390889, 1775286713, 395413126, -1722236479, 975641885, 666476190, -650583583, -351012616, 733190296, 573772049, -759469719, -1452221991, 126455438, 866620564, 766942107, 1008868894, 361924487, -920589847, -2025206066, -1426107051, 1350051880, -1518673953, 59739276, 1509466529, 159418761, 437718285, 1708834751, -684595482, -2067381694, -793221016, -2101132991, 699439513, 1517759789, 504434447, 2076946608, -1459858348, 1842789307, 742004246};
private static final int[] Tinv0 = new int[] {1353184337, 1399144830, -1012656358, -1772214470, -882136261, -247096033, -1420232020, -1828461749, 1442459680, -160598355, -1854485368, 625738485, -52959921, -674551099, -2143013594, -1885117771, 1230680542, 1729870373, -1743852987, -507445667, 41234371, 317738113, -1550367091, -956705941, -413167869, -1784901099, -344298049, -631680363, 763608788, -752782248, 694804553, 1154009486, 1787413109, 2021232372, 1799248025, -579749593, -1236278850, 397248752, 1722556617, -1271214467, 407560035, -2110711067, 1613975959, 1165972322, -529046351, -2068943941, 480281086, -1809118983, 1483229296, 436028815, -2022908268, -1208452270, 601060267, -503166094, 1468997603, 715871590, 120122290, 63092015, -1703164538, -1526188077, -226023376, -1297760477, -1167457534, 1552029421, 723308426, -1833666137, -252573709, -1578997426, -839591323, -708967162, 526529745, -1963022652, -1655493068, -1604979806, 853641733, 1978398372, 971801355, -1427152832, 111112542, 1360031421, -108388034, 1023860118, -1375387939, 1186850381, -1249028975, 90031217, 1876166148, -15380384, 620468249, -1746289194, -868007799, 2006899047, -1119688528, -2004121337, 945494503, -605108103, 1191869601, -384875908, -920746760, 0, -2088337399, 1223502642, -1401941730, 1316117100, -67170563, 1446544655, 517320253, 658058550, 1691946762, 564550760, -783000677, 976107044, -1318647284, 266819475, -761860428, -1634624741, 1338359936, -1574904735, 1766553434, 370807324, 179999714, -450191168, 1138762300, 488053522, 185403662, -1379431438, -1180125651, -928440812, -2061897385, 1275557295, -1143105042, -44007517, -1624899081, -1124765092, -985962940, 880737115, 1982415755, -590994485, 1761406390, 1676797112, -891538985, 277177154, 1076008723, 538035844, 2099530373, -130171950, 288553390, 1839278535, 1261411869, -214912292, -330136051, -790380169, 1813426987, -1715900247, -95906799, 577038663, -997393240, 440397984, -668172970, -275762398, -951170681, -1043253031, -22885748, 906744984, -813566554, 685669029, 646887386, -1530942145, -459458004, 227702864, -1681105046, 1648787028, -1038905866, -390539120, 1593260334, -173030526, -1098883681, 2090061929, -1456614033, -1290656305, 999926984, -1484974064, 1852021992, 2075868123, 158869197, -199730834, 28809964, -1466282109, 1701746150, 2129067946, 147831841, -420997649, -644094022, -835293366, -737566742, -696471511, -1347247055, 824393514, 815048134, -1067015627, 935087732, -1496677636, -1328508704, 366520115, 1251476721, -136647615, 240176511, 804688151, -1915335306, 1303441219, 1414376140, -553347356, -474623586, 461924940, -1205916479, 2136040774, 82468509, 1563790337, 1937016826, 776014843, 1511876531, 1389550482, 861278441, 323475053, -1939744870, 2047648055, -1911228327, -1992551445, -299390514, 902390199, -303751967, 1018251130, 1507840668, 1064563285, 2043548696, -1086863501, -355600557, 1537932639, 342834655, -2032450440, -2114736182, 1053059257, 741614648, 1598071746, 1925389590, 203809468, -1958134744, 1100287487, 1895934009, -558691320, -1662733096, -1866377628, 1636092795, 1890988757, 1952214088, 1113045200};
private static final int[] Tinv1 = new int[] { -1477160624, 1698790995, -1541989693, 1579629206, 1806384075, 1167925233, 1492823211, 65227667, -97509291, 1836494326, 1993115793, 1275262245, -672837636, -886389289, 1144333952, -1553812081, 1521606217, 465184103, 250234264, -1057071647, 1966064386, -263421678, -1756983901, -103584826, 1603208167, -1668147819, 2054012907, 1498584538, -2084645843, 561273043, 1776306473, -926314940, -1983744662, 2039411832, 1045993835, 1907959773, 1340194486, -1383534569, -1407137434, 986611124, 1256153880, 823846274, 860985184, 2136171077, 2003087840, -1368671356, -1602093540, 722008468, 1749577816, -45773031, 1826526343, -126135625, -747394269, 38499042, -1893735593, -1420466646, 686535175, -1028313341, 2076542618, 137876389, -2027409166, -1514200142, 1778582202, -2112426660, 483363371, -1267095662, -234359824, -496415071, -187013683, -1106966827, 1647628575, -22625142, 1395537053, 1442030240, -511048398, -336157579, -326956231, -278904662, -1619960314, 275692881, -1977532679, 115185213, 88006062, -1108980410, -1923837515, 1573155077, -737803153, 357589247, -73918172, -373434729, 1128303052, -1629919369, 1122545853, -1953953912, 1528424248, -288851493, 175939911, 256015593, 512030921, 0, -2038429309, -315936184, 1880170156, 1918528590, -15794693, 948244310, -710001378, 959264295, -653325724, -1503893471, 1415289809, 775300154, 1728711857, -413691121, -1762741038, -1852105826, -977239985, 551313826, 1266113129, 437394454, -1164713462, 715178213, -534627261, 387650077, 218697227, -947129683, -1464455751, -1457646392, 435246981, 125153100, -577114437, 1618977789, 637663135, -177054532, 996558021, 2130402100, 692292470, -970732580, -51530136, -236668829, -600713270, -2057092592, 580326208, 298222624, 608863613, 1035719416, 855223825, -1591097491, 798891339, 817028339, 1384517100, -473860144, 380840812, -1183798887, 1217663482, 1693009698, -1929598780, 1072734234, 746411736, -1875696913, 1313441735, -784803391, -1563783938, 198481974, -2114607409, -562387672, -1900553690, -1079165020, -1657131804, -1837608947, -866162021, 1182684258, 328070850, -1193766680, -147247522, -1346141451, -2141347906, -1815058052, 768962473, 304467891, -1716729797, 2098729127, 1671227502, -1153705093, 2015808777, 408514292, -1214583807, -1706064984, 1855317605, -419452290, -809754360, -401215514, -1679312167, 913263310, 161475284, 2091919830, -1297862225, 591342129, -1801075152, 1721906624, -1135709129, -897385306, -795811664, -660131051, -1744506550, -622050825, 1355644686, -158263505, -699566451, -1326496947, 1303039060, 76997855, -1244553501, -2006299621, 523026872, 1365591679, -362898172, 898367837, 1955068531, 1091304238, 493335386, -757362094, 1443948851, 1205234963, 1641519756, 211892090, 351820174, 1007938441, 665439982, -916342987, -451091987, -1320715716, -539845543, 1945261375, -837543815, 935818175, -839429142, -1426235557, 1866325780, -616269690, -206583167, -999769794, 874788908, 1084473951, -1021503886, 635616268, 1228679307, -1794244799, 27801969, -1291056930, -457910116, -1051302768, -2067039391, -1238182544, 1550600308, 1471729730};
private static final int[] Tinv2 = new int[] { -195997529, 1098797925, 387629988, 658151006, -1422144661, -1658851003, -89347240, -481586429, 807425530, 1991112301, -863465098, 49620300, -447742761, 717608907, 891715652, 1656065955, -1310832294, -1171953893, -364537842, -27401792, 801309301, 1283527408, 1183687575, -747911431, -1895569569, -1844079204, 1841294202, 1385552473, -1093390973, 1951978273, -532076183, -913423160, -1032492407, -1896580999, 1486449470, -1188569743, -507595185, -1997531219, 550069932, -830622662, -547153846, 451248689, 1368875059, 1398949247, 1689378935, 1807451310, -2114052960, 150574123, 1215322216, 1167006205, -560691348, 2069018616, 1940595667, 1265820162, 534992783, 1432758955, -340654296, -1255210046, -981034373, 936617224, 674296455, -1088179547, 50510442, 384654466, -813028580, 2041025204, 133427442, 1766760930, -630862348, 84334014, 886120290, -1497068802, 775200083, -207445931, -1979370783, -156994069, -2096416276, 1614850799, 1901987487, 1857900816, 557775242, -577356538, 1054715397, -431143235, 1418835341, -999226019, 100954068, 1348534037, -1743182597, -1110009879, 1082772547, -647530594, -391070398, -1995994997, 434583643, -931537938, 2090944266, 1115482383, -2064070370, 0, -2146860154, 724715757, 287222896, 1517047410, 251526143, -2062592456, -1371726123, 758523705, 252339417, 1550328230, 1536938324, 908343854, 168604007, 1469255655, -290139498, -1692688751, -1065332795, -597581280, 2002413899, 303830554, -1813902662, -1597971158, 574374880, 454171927, 151915277, -1947030073, -1238517336, 504678569, -245922535, 1974422535, -1712407587, 2141453664, 33005350, 1918680309, 1715782971, -77908866, 1133213225, 600562886, -306812676, -457677839, 836225756, 1665273989, -1760346078, -964419567, 1250262308, -1143801795, -106032846, 700935585, -1642247377, -1294142672, -2045907886, -1049112349, -1288999914, 1890163129, -1810761144, -381214108, -56048500, -257942977, 2102843436, 857927568, 1233635150, 953795025, -896729438, -728222197, -173617279, 2057644254, -1210440050, -1388337985, 976020637, 2018512274, 1600822220, 2119459398, -1913208301, -661591880, 959340279, -1014827601, 1570750080, -798393197, -714102483, 634368786, -1396163687, 403744637, -1662488989, 1004239803, 650971512, 1500443672, -1695809097, 1334028442, -1780062866, -5603610, -1138685745, 368043752, -407184997, 1867173430, -1612000247, -1339435396, -1540247630, 1059729699, -1513738092, -1573535642, 1316239292, -2097371446, -1864322864, -1489824296, 82922136, -331221030, -847311280, -1860751370, 1299615190, -280801872, -1429449651, -1763385596, -778116171, 1783372680, 750893087, 1699118929, 1587348714, -1946067659, -2013629580, 201010753, 1739807261, -611167534, 283718486, -697494713, -677737375, -1590199796, -128348652, 334203196, -1446056409, 1639396809, 484568549, 1199193265, -761505313, -229294221, 337148366, -948715721, -145495347, -44082262, 1038029935, 1148749531, -1345682957, 1756970692, 607661108, -1547542720, 488010435, -490992603, 1009290057, 234832277, -1472630527, 201907891, -1260872476, 1449431233, -881106556, 852848822, 1816687708, -1194311081};
private static final int[] Tinv3 = new int[] {1364240372, 2119394625, 449029143, 982933031, 1003187115, 535905693, -1398056710, 1267925987, 542505520, -1376359050, -2003732788, -182105086, 1341970405, -975713494, 645940277, -1248877726, -565617999, 627514298, 1167593194, 1575076094, -1023249105, -2129465268, -1918658746, 1808202195, 65494927, 362126482, -1075086739, -1780852398, -735214658, 1490231668, 1227450848, -1908094775, 1969916354, -193431154, -1721024936, 668823993, -1095348255, -266883704, -916018144, 2108963534, 1662536415, -444452582, -1755303087, 1648721747, -1310689436, -1148932501, -31678335, -107730168, 1884842056, -1894122171, -1803064098, 1387788411, -1423715469, 1927414347, -480800993, 1714072405, -1308153621, 788775605, -2036696123, -744159177, 821200680, 598910399, 45771267, -312704490, -1976886065, -1483557767, -202313209, 1319232105, 1707996378, 114671109, -786472396, -997523802, 882725678, -1566550541, 87220618, -1535775754, 188345475, 1084944224, 1577492337, -1118760850, 1056541217, -1774385443, -575797954, 1296481766, -1850372780, 1896177092, 74437638, 1627329872, 421854104, -694687299, -1983102144, 1735892697, -1329773848, 126389129, -415737063, 2044456648, -1589179780, 2095648578, -121037180, 0, 159614592, 843640107, 514617361, 1817080410, -33816818, 257308805, 1025430958, 908540205, 174381327, 1747035740, -1680780197, 607792694, 212952842, -1827674281, -1261267218, 463376795, -2142255680, 1638015196, 1516850039, 471210514, -502613357, -1058723168, 1011081250, 303896347, 235605257, -223492213, 767142070, 348694814, 1468340721, -1353971851, -289677927, -1543675777, -140564991, 1555887474, 1153776486, 1530167035, -1955190461, -874723805, -1234633491, -1201409564, -674571215, 1108378979, 322970263, -2078273082, -2055396278, -755483205, -1374604551, -949116631, 491466654, -588042062, 233591430, 2010178497, 728503987, -1449543312, 301615252, 1193436393, -1463513860, -1608892432, 1457007741, 586125363, -2016981431, -641609416, -1929469238, -1741288492, -1496350219, -1524048262, -635007305, 1067761581, 753179962, 1343066744, 1788595295, 1415726718, -155053171, -1863796520, 777975609, -2097827901, -1614905251, 1769771984, 1873358293, -810347995, -935618132, 279411992, -395418724, -612648133, -855017434, 1861490777, -335431782, -2086102449, -429560171, -1434523905, 554225596, -270079979, -1160143897, 1255028335, -355202657, 701922480, 833598116, 707863359, -969894747, 901801634, 1949809742, -56178046, -525283184, 857069735, -246769660, 1106762476, 2131644621, 389019281, 1989006925, 1129165039, -866890326, -455146346, -1629243951, 1276872810, -1044898004, 1182749029, -1660622242, 22885772, -93096825, -80854773, -1285939865, -1840065829, -382511600, 1829980118, -1702075945, 930745505, 1502483704, -343327725, -823253079, -1221211807, -504503012, 2050797895, -1671831598, 1430221810, 410635796, 1941911495, 1407897079, 1599843069, -552308931, 2022103876, -897453137, -1187068824, 942421028, -1033944925, 376619805, -1140054558, 680216892, -12479219, 963707304, 148812556, -660806476, 1687208278, 2069988555, -714033614, 1215585388, -800958536};
private int ROUNDS;
private int[][] WorkingKey = (int[][])null;
private int C0;
private int C1;
private int C2;
private int C3;
private boolean forEncryption;
private int shift(int par1, int par2)
{
return par1 >>> par2 | par1 << -par2;
}
private int FFmulX(int par1)
{
return (par1 & 2139062143) << 1 ^ ((par1 & -2139062144) >>> 7) * 27;
}
private int inv_mcol(int par1)
{
int var2 = this.FFmulX(par1);
int var3 = this.FFmulX(var2);
int var4 = this.FFmulX(var3);
int var5 = par1 ^ var4;
return var2 ^ var3 ^ var4 ^ this.shift(var2 ^ var5, 8) ^ this.shift(var3 ^ var5, 16) ^ this.shift(var5, 24);
}
private int subWord(int par1)
{
return S[par1 & 255] & 255 | (S[par1 >> 8 & 255] & 255) << 8 | (S[par1 >> 16 & 255] & 255) << 16 | S[par1 >> 24 & 255] << 24;
}
private int[][] generateWorkingKey(byte[] par1ArrayOfByte, boolean par2)
{
int var3 = par1ArrayOfByte.length / 4;
if ((var3 == 4 || var3 == 6 || var3 == 8) && var3 * 4 == par1ArrayOfByte.length)
{
this.ROUNDS = var3 + 6;
int[][] var5 = new int[this.ROUNDS + 1][4];
int var4 = 0;
int var6;
for (var6 = 0; var6 < par1ArrayOfByte.length; ++var4)
{
var5[var4 >> 2][var4 & 3] = par1ArrayOfByte[var6] & 255 | (par1ArrayOfByte[var6 + 1] & 255) << 8 | (par1ArrayOfByte[var6 + 2] & 255) << 16 | par1ArrayOfByte[var6 + 3] << 24;
var6 += 4;
}
int var7 = this.ROUNDS + 1 << 2;
int var8;
for (var6 = var3; var6 < var7; ++var6)
{
var8 = var5[var6 - 1 >> 2][var6 - 1 & 3];
if (var6 % var3 == 0)
{
var8 = this.subWord(this.shift(var8, 8)) ^ rcon[var6 / var3 - 1];
}
else if (var3 > 6 && var6 % var3 == 4)
{
var8 = this.subWord(var8);
}
var5[var6 >> 2][var6 & 3] = var5[var6 - var3 >> 2][var6 - var3 & 3] ^ var8;
}
if (!par2)
{
for (var8 = 1; var8 < this.ROUNDS; ++var8)
{
for (var6 = 0; var6 < 4; ++var6)
{
var5[var8][var6] = this.inv_mcol(var5[var8][var6]);
}
}
}
return var5;
}
else
{
throw new IllegalArgumentException("Key length not 128/192/256 bits.");
}
}
public void init(boolean par1, CipherParameters par2CipherParameters) throws IllegalArgumentException
{
if (par2CipherParameters instanceof KeyParameter)
{
this.WorkingKey = this.generateWorkingKey(((KeyParameter)par2CipherParameters).getKey(), par1);
this.forEncryption = par1;
}
else
{
throw new IllegalArgumentException("invalid parameter passed to AES init - " + par2CipherParameters.getClass().getName());
}
}
/**
* Return the name of the algorithm the cipher implements.
*/
public String getAlgorithmName()
{
return "AES";
}
/**
* Return the block size for this cipher (in bytes).
*/
public int getBlockSize()
{
return 16;
}
public int processBlock(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) throws DataLengthException, IllegalStateException
{
if (this.WorkingKey == null)
{
throw new IllegalStateException("AES engine not initialised");
}
else if (par2 + 16 > par1ArrayOfByte.length)
{
throw new DataLengthException("input buffer too short");
}
else if (par4 + 16 > par3ArrayOfByte.length)
{
throw new DataLengthException("output buffer too short");
}
else
{
if (this.forEncryption)
{
this.unpackBlock(par1ArrayOfByte, par2);
this.encryptBlock(this.WorkingKey);
this.packBlock(par3ArrayOfByte, par4);
}
else
{
this.unpackBlock(par1ArrayOfByte, par2);
this.decryptBlock(this.WorkingKey);
this.packBlock(par3ArrayOfByte, par4);
}
return 16;
}
}
public void reset() {}
private void unpackBlock(byte[] par1ArrayOfByte, int par2)
{
int var3 = par2 + 1;
this.C0 = par1ArrayOfByte[par2] & 255;
this.C0 |= (par1ArrayOfByte[var3++] & 255) << 8;
this.C0 |= (par1ArrayOfByte[var3++] & 255) << 16;
this.C0 |= par1ArrayOfByte[var3++] << 24;
this.C1 = par1ArrayOfByte[var3++] & 255;
this.C1 |= (par1ArrayOfByte[var3++] & 255) << 8;
this.C1 |= (par1ArrayOfByte[var3++] & 255) << 16;
this.C1 |= par1ArrayOfByte[var3++] << 24;
this.C2 = par1ArrayOfByte[var3++] & 255;
this.C2 |= (par1ArrayOfByte[var3++] & 255) << 8;
this.C2 |= (par1ArrayOfByte[var3++] & 255) << 16;
this.C2 |= par1ArrayOfByte[var3++] << 24;
this.C3 = par1ArrayOfByte[var3++] & 255;
this.C3 |= (par1ArrayOfByte[var3++] & 255) << 8;
this.C3 |= (par1ArrayOfByte[var3++] & 255) << 16;
this.C3 |= par1ArrayOfByte[var3++] << 24;
}
private void packBlock(byte[] par1ArrayOfByte, int par2)
{
int var3 = par2 + 1;
par1ArrayOfByte[par2] = (byte)this.C0;
par1ArrayOfByte[var3++] = (byte)(this.C0 >> 8);
par1ArrayOfByte[var3++] = (byte)(this.C0 >> 16);
par1ArrayOfByte[var3++] = (byte)(this.C0 >> 24);
par1ArrayOfByte[var3++] = (byte)this.C1;
par1ArrayOfByte[var3++] = (byte)(this.C1 >> 8);
par1ArrayOfByte[var3++] = (byte)(this.C1 >> 16);
par1ArrayOfByte[var3++] = (byte)(this.C1 >> 24);
par1ArrayOfByte[var3++] = (byte)this.C2;
par1ArrayOfByte[var3++] = (byte)(this.C2 >> 8);
par1ArrayOfByte[var3++] = (byte)(this.C2 >> 16);
par1ArrayOfByte[var3++] = (byte)(this.C2 >> 24);
par1ArrayOfByte[var3++] = (byte)this.C3;
par1ArrayOfByte[var3++] = (byte)(this.C3 >> 8);
par1ArrayOfByte[var3++] = (byte)(this.C3 >> 16);
par1ArrayOfByte[var3++] = (byte)(this.C3 >> 24);
}
private void encryptBlock(int[][] par1ArrayOfInteger)
{
this.C0 ^= par1ArrayOfInteger[0][0];
this.C1 ^= par1ArrayOfInteger[0][1];
this.C2 ^= par1ArrayOfInteger[0][2];
this.C3 ^= par1ArrayOfInteger[0][3];
int var2;
int var3;
int var4;
int var5;
int var6;
for (var2 = 1; var2 < this.ROUNDS - 1; this.C3 = T0[var6 & 255] ^ T1[var3 >> 8 & 255] ^ T2[var4 >> 16 & 255] ^ T3[var5 >> 24 & 255] ^ par1ArrayOfInteger[var2++][3])
{
var3 = T0[this.C0 & 255] ^ T1[this.C1 >> 8 & 255] ^ T2[this.C2 >> 16 & 255] ^ T3[this.C3 >> 24 & 255] ^ par1ArrayOfInteger[var2][0];
var4 = T0[this.C1 & 255] ^ T1[this.C2 >> 8 & 255] ^ T2[this.C3 >> 16 & 255] ^ T3[this.C0 >> 24 & 255] ^ par1ArrayOfInteger[var2][1];
var5 = T0[this.C2 & 255] ^ T1[this.C3 >> 8 & 255] ^ T2[this.C0 >> 16 & 255] ^ T3[this.C1 >> 24 & 255] ^ par1ArrayOfInteger[var2][2];
var6 = T0[this.C3 & 255] ^ T1[this.C0 >> 8 & 255] ^ T2[this.C1 >> 16 & 255] ^ T3[this.C2 >> 24 & 255] ^ par1ArrayOfInteger[var2++][3];
this.C0 = T0[var3 & 255] ^ T1[var4 >> 8 & 255] ^ T2[var5 >> 16 & 255] ^ T3[var6 >> 24 & 255] ^ par1ArrayOfInteger[var2][0];
this.C1 = T0[var4 & 255] ^ T1[var5 >> 8 & 255] ^ T2[var6 >> 16 & 255] ^ T3[var3 >> 24 & 255] ^ par1ArrayOfInteger[var2][1];
this.C2 = T0[var5 & 255] ^ T1[var6 >> 8 & 255] ^ T2[var3 >> 16 & 255] ^ T3[var4 >> 24 & 255] ^ par1ArrayOfInteger[var2][2];
}
var3 = T0[this.C0 & 255] ^ T1[this.C1 >> 8 & 255] ^ T2[this.C2 >> 16 & 255] ^ T3[this.C3 >> 24 & 255] ^ par1ArrayOfInteger[var2][0];
var4 = T0[this.C1 & 255] ^ T1[this.C2 >> 8 & 255] ^ T2[this.C3 >> 16 & 255] ^ T3[this.C0 >> 24 & 255] ^ par1ArrayOfInteger[var2][1];
var5 = T0[this.C2 & 255] ^ T1[this.C3 >> 8 & 255] ^ T2[this.C0 >> 16 & 255] ^ T3[this.C1 >> 24 & 255] ^ par1ArrayOfInteger[var2][2];
var6 = T0[this.C3 & 255] ^ T1[this.C0 >> 8 & 255] ^ T2[this.C1 >> 16 & 255] ^ T3[this.C2 >> 24 & 255] ^ par1ArrayOfInteger[var2++][3];
this.C0 = S[var3 & 255] & 255 ^ (S[var4 >> 8 & 255] & 255) << 8 ^ (S[var5 >> 16 & 255] & 255) << 16 ^ S[var6 >> 24 & 255] << 24 ^ par1ArrayOfInteger[var2][0];
this.C1 = S[var4 & 255] & 255 ^ (S[var5 >> 8 & 255] & 255) << 8 ^ (S[var6 >> 16 & 255] & 255) << 16 ^ S[var3 >> 24 & 255] << 24 ^ par1ArrayOfInteger[var2][1];
this.C2 = S[var5 & 255] & 255 ^ (S[var6 >> 8 & 255] & 255) << 8 ^ (S[var3 >> 16 & 255] & 255) << 16 ^ S[var4 >> 24 & 255] << 24 ^ par1ArrayOfInteger[var2][2];
this.C3 = S[var6 & 255] & 255 ^ (S[var3 >> 8 & 255] & 255) << 8 ^ (S[var4 >> 16 & 255] & 255) << 16 ^ S[var5 >> 24 & 255] << 24 ^ par1ArrayOfInteger[var2][3];
}
private void decryptBlock(int[][] par1ArrayOfInteger)
{
this.C0 ^= par1ArrayOfInteger[this.ROUNDS][0];
this.C1 ^= par1ArrayOfInteger[this.ROUNDS][1];
this.C2 ^= par1ArrayOfInteger[this.ROUNDS][2];
this.C3 ^= par1ArrayOfInteger[this.ROUNDS][3];
int var2;
int var3;
int var4;
int var5;
int var6;
for (var6 = this.ROUNDS - 1; var6 > 1; this.C3 = Tinv0[var5 & 255] ^ Tinv1[var4 >> 8 & 255] ^ Tinv2[var3 >> 16 & 255] ^ Tinv3[var2 >> 24 & 255] ^ par1ArrayOfInteger[var6--][3])
{
var2 = Tinv0[this.C0 & 255] ^ Tinv1[this.C3 >> 8 & 255] ^ Tinv2[this.C2 >> 16 & 255] ^ Tinv3[this.C1 >> 24 & 255] ^ par1ArrayOfInteger[var6][0];
var3 = Tinv0[this.C1 & 255] ^ Tinv1[this.C0 >> 8 & 255] ^ Tinv2[this.C3 >> 16 & 255] ^ Tinv3[this.C2 >> 24 & 255] ^ par1ArrayOfInteger[var6][1];
var4 = Tinv0[this.C2 & 255] ^ Tinv1[this.C1 >> 8 & 255] ^ Tinv2[this.C0 >> 16 & 255] ^ Tinv3[this.C3 >> 24 & 255] ^ par1ArrayOfInteger[var6][2];
var5 = Tinv0[this.C3 & 255] ^ Tinv1[this.C2 >> 8 & 255] ^ Tinv2[this.C1 >> 16 & 255] ^ Tinv3[this.C0 >> 24 & 255] ^ par1ArrayOfInteger[var6--][3];
this.C0 = Tinv0[var2 & 255] ^ Tinv1[var5 >> 8 & 255] ^ Tinv2[var4 >> 16 & 255] ^ Tinv3[var3 >> 24 & 255] ^ par1ArrayOfInteger[var6][0];
this.C1 = Tinv0[var3 & 255] ^ Tinv1[var2 >> 8 & 255] ^ Tinv2[var5 >> 16 & 255] ^ Tinv3[var4 >> 24 & 255] ^ par1ArrayOfInteger[var6][1];
this.C2 = Tinv0[var4 & 255] ^ Tinv1[var3 >> 8 & 255] ^ Tinv2[var2 >> 16 & 255] ^ Tinv3[var5 >> 24 & 255] ^ par1ArrayOfInteger[var6][2];
}
var2 = Tinv0[this.C0 & 255] ^ Tinv1[this.C3 >> 8 & 255] ^ Tinv2[this.C2 >> 16 & 255] ^ Tinv3[this.C1 >> 24 & 255] ^ par1ArrayOfInteger[var6][0];
var3 = Tinv0[this.C1 & 255] ^ Tinv1[this.C0 >> 8 & 255] ^ Tinv2[this.C3 >> 16 & 255] ^ Tinv3[this.C2 >> 24 & 255] ^ par1ArrayOfInteger[var6][1];
var4 = Tinv0[this.C2 & 255] ^ Tinv1[this.C1 >> 8 & 255] ^ Tinv2[this.C0 >> 16 & 255] ^ Tinv3[this.C3 >> 24 & 255] ^ par1ArrayOfInteger[var6][2];
var5 = Tinv0[this.C3 & 255] ^ Tinv1[this.C2 >> 8 & 255] ^ Tinv2[this.C1 >> 16 & 255] ^ Tinv3[this.C0 >> 24 & 255] ^ par1ArrayOfInteger[var6][3];
this.C0 = Si[var2 & 255] & 255 ^ (Si[var5 >> 8 & 255] & 255) << 8 ^ (Si[var4 >> 16 & 255] & 255) << 16 ^ Si[var3 >> 24 & 255] << 24 ^ par1ArrayOfInteger[0][0];
this.C1 = Si[var3 & 255] & 255 ^ (Si[var2 >> 8 & 255] & 255) << 8 ^ (Si[var5 >> 16 & 255] & 255) << 16 ^ Si[var4 >> 24 & 255] << 24 ^ par1ArrayOfInteger[0][1];
this.C2 = Si[var4 & 255] & 255 ^ (Si[var3 >> 8 & 255] & 255) << 8 ^ (Si[var2 >> 16 & 255] & 255) << 16 ^ Si[var5 >> 24 & 255] << 24 ^ par1ArrayOfInteger[0][2];
this.C3 = Si[var5 & 255] & 255 ^ (Si[var4 >> 8 & 255] & 255) << 8 ^ (Si[var3 >> 16 & 255] & 255) << 16 ^ Si[var2 >> 24 & 255] << 24 ^ par1ArrayOfInteger[0][3];
}
}

View File

@ -0,0 +1,178 @@
package org.bouncycastle.crypto.io;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.StreamCipher;
public class CipherInputStream extends FilterInputStream
{
private BufferedBlockCipher theBufferedBlockCipher;
private StreamCipher theStreamCipher;
private byte[] buf;
private byte[] inBuf;
private int bufOff;
private int maxBuf;
private boolean finalized;
public CipherInputStream(InputStream par1InputStream, BufferedBlockCipher par2BufferedBlockCipher)
{
super(par1InputStream);
this.theBufferedBlockCipher = par2BufferedBlockCipher;
this.buf = new byte[par2BufferedBlockCipher.getOutputSize(2048)];
this.inBuf = new byte[2048];
}
private int nextChunk() throws IOException
{
int var1 = super.available();
if (var1 <= 0)
{
var1 = 1;
}
if (var1 > this.inBuf.length)
{
var1 = super.read(this.inBuf, 0, this.inBuf.length);
}
else
{
var1 = super.read(this.inBuf, 0, var1);
}
if (var1 < 0)
{
if (this.finalized)
{
return -1;
}
try
{
if (this.theBufferedBlockCipher != null)
{
this.maxBuf = this.theBufferedBlockCipher.doFinal(this.buf, 0);
}
else
{
this.maxBuf = 0;
}
}
catch (Exception var4)
{
throw new IOException("error processing stream: " + var4.toString());
}
this.bufOff = 0;
this.finalized = true;
if (this.bufOff == this.maxBuf)
{
return -1;
}
}
else
{
this.bufOff = 0;
try
{
if (this.theBufferedBlockCipher != null)
{
this.maxBuf = this.theBufferedBlockCipher.processByte(this.inBuf, 0, var1, this.buf, 0);
}
else
{
this.theStreamCipher.processBytes(this.inBuf, 0, var1, this.buf, 0);
this.maxBuf = var1;
}
}
catch (Exception var3)
{
throw new IOException("error processing stream: " + var3.toString());
}
if (this.maxBuf == 0)
{
return this.nextChunk();
}
}
return this.maxBuf;
}
public int read() throws IOException
{
return this.bufOff == this.maxBuf && this.nextChunk() < 0 ? -1 : this.buf[this.bufOff++] & 255;
}
public int read(byte[] par1ArrayOfByte) throws IOException
{
return this.read(par1ArrayOfByte, 0, par1ArrayOfByte.length);
}
public int read(byte[] par1ArrayOfByte, int par2, int par3) throws IOException
{
if (this.bufOff == this.maxBuf && this.nextChunk() < 0)
{
return -1;
}
else
{
int var4 = this.maxBuf - this.bufOff;
if (par3 > var4)
{
System.arraycopy(this.buf, this.bufOff, par1ArrayOfByte, par2, var4);
this.bufOff = this.maxBuf;
return var4;
}
else
{
System.arraycopy(this.buf, this.bufOff, par1ArrayOfByte, par2, par3);
this.bufOff += par3;
return par3;
}
}
}
public long skip(long par1) throws IOException
{
if (par1 <= 0L)
{
return 0L;
}
else
{
int var3 = this.maxBuf - this.bufOff;
if (par1 > (long)var3)
{
this.bufOff = this.maxBuf;
return (long)var3;
}
else
{
this.bufOff += (int)par1;
return (long)((int)par1);
}
}
}
public int available() throws IOException
{
return this.maxBuf - this.bufOff;
}
public void close() throws IOException
{
super.close();
}
public boolean markSupported()
{
return false;
}
}

View File

@ -0,0 +1,97 @@
package org.bouncycastle.crypto.io;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.StreamCipher;
public class CipherOutputStream extends FilterOutputStream
{
private BufferedBlockCipher theBufferedBlockCipher;
private StreamCipher theStreamCipher;
private byte[] oneByte = new byte[1];
private byte[] buf;
public CipherOutputStream(OutputStream par1OutputStream, BufferedBlockCipher par2BufferedBlockCipher)
{
super(par1OutputStream);
this.theBufferedBlockCipher = par2BufferedBlockCipher;
this.buf = new byte[par2BufferedBlockCipher.getBlockSize()];
}
public void write(int par1) throws IOException
{
this.oneByte[0] = (byte)par1;
if (this.theBufferedBlockCipher != null)
{
int var2 = this.theBufferedBlockCipher.processByte(this.oneByte, 0, 1, this.buf, 0);
if (var2 != 0)
{
this.out.write(this.buf, 0, var2);
}
}
else
{
this.out.write(this.theStreamCipher.returnByte((byte)par1));
}
}
public void write(byte[] par1) throws IOException
{
this.write(par1, 0, par1.length);
}
public void write(byte[] par1, int par2, int par3) throws IOException
{
byte[] var4;
if (this.theBufferedBlockCipher != null)
{
var4 = new byte[this.theBufferedBlockCipher.getOutputSize(par3)];
int var5 = this.theBufferedBlockCipher.processByte(par1, par2, par3, var4, 0);
if (var5 != 0)
{
this.out.write(var4, 0, var5);
}
}
else
{
var4 = new byte[par3];
this.theStreamCipher.processBytes(par1, par2, par3, var4, 0);
this.out.write(var4, 0, par3);
}
}
public void flush() throws IOException
{
super.flush();
}
public void close() throws IOException
{
try
{
if (this.theBufferedBlockCipher != null)
{
byte[] var1 = new byte[this.theBufferedBlockCipher.getOutputSize(0)];
int var2 = this.theBufferedBlockCipher.doFinal(var1, 0);
if (var2 != 0)
{
this.out.write(var1, 0, var2);
}
}
}
catch (Exception var3)
{
throw new IOException("Error closing stream: " + var3.toString());
}
this.flush();
super.close();
}
}

View File

@ -0,0 +1,139 @@
package org.bouncycastle.crypto.modes;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.params.ParametersWithIV;
public class CFBBlockCipher implements BlockCipher
{
private byte[] IV;
private byte[] cfbV;
private byte[] cfbOutV;
private int blockSize;
private BlockCipher cipher = null;
private boolean encrypting;
public CFBBlockCipher(BlockCipher par1BlockCipher, int par2)
{
this.cipher = par1BlockCipher;
this.blockSize = par2 / 8;
this.IV = new byte[par1BlockCipher.getBlockSize()];
this.cfbV = new byte[par1BlockCipher.getBlockSize()];
this.cfbOutV = new byte[par1BlockCipher.getBlockSize()];
}
public void init(boolean par1, CipherParameters par2CipherParameters) throws IllegalArgumentException
{
this.encrypting = par1;
if (par2CipherParameters instanceof ParametersWithIV)
{
ParametersWithIV var3 = (ParametersWithIV)par2CipherParameters;
byte[] var4 = var3.getIV();
if (var4.length < this.IV.length)
{
System.arraycopy(var4, 0, this.IV, this.IV.length - var4.length, var4.length);
for (int var5 = 0; var5 < this.IV.length - var4.length; ++var5)
{
this.IV[var5] = 0;
}
}
else
{
System.arraycopy(var4, 0, this.IV, 0, this.IV.length);
}
this.reset();
if (var3.getParameters() != null)
{
this.cipher.init(true, var3.getParameters());
}
}
else
{
this.reset();
this.cipher.init(true, par2CipherParameters);
}
}
/**
* Return the name of the algorithm the cipher implements.
*/
public String getAlgorithmName()
{
return this.cipher.getAlgorithmName() + "/CFB" + this.blockSize * 8;
}
/**
* Return the block size for this cipher (in bytes).
*/
public int getBlockSize()
{
return this.blockSize;
}
public int processBlock(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) throws DataLengthException, IllegalStateException
{
return this.encrypting ? this.encryptBlock(par1ArrayOfByte, par2, par3ArrayOfByte, par4) : this.decryptBlock(par1ArrayOfByte, par2, par3ArrayOfByte, par4);
}
public int encryptBlock(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) throws DataLengthException, IllegalStateException
{
if (par2 + this.blockSize > par1ArrayOfByte.length)
{
throw new DataLengthException("input buffer too short");
}
else if (par4 + this.blockSize > par3ArrayOfByte.length)
{
throw new DataLengthException("output buffer too short");
}
else
{
this.cipher.processBlock(this.cfbV, 0, this.cfbOutV, 0);
for (int var5 = 0; var5 < this.blockSize; ++var5)
{
par3ArrayOfByte[par4 + var5] = (byte)(this.cfbOutV[var5] ^ par1ArrayOfByte[par2 + var5]);
}
System.arraycopy(this.cfbV, this.blockSize, this.cfbV, 0, this.cfbV.length - this.blockSize);
System.arraycopy(par3ArrayOfByte, par4, this.cfbV, this.cfbV.length - this.blockSize, this.blockSize);
return this.blockSize;
}
}
public int decryptBlock(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) throws DataLengthException, IllegalStateException
{
if (par2 + this.blockSize > par1ArrayOfByte.length)
{
throw new DataLengthException("input buffer too short");
}
else if (par4 + this.blockSize > par3ArrayOfByte.length)
{
throw new DataLengthException("output buffer too short");
}
else
{
this.cipher.processBlock(this.cfbV, 0, this.cfbOutV, 0);
System.arraycopy(this.cfbV, this.blockSize, this.cfbV, 0, this.cfbV.length - this.blockSize);
System.arraycopy(par1ArrayOfByte, par2, this.cfbV, this.cfbV.length - this.blockSize, this.blockSize);
for (int var5 = 0; var5 < this.blockSize; ++var5)
{
par3ArrayOfByte[par4 + var5] = (byte)(this.cfbOutV[var5] ^ par1ArrayOfByte[par2 + var5]);
}
return this.blockSize;
}
}
public void reset()
{
System.arraycopy(this.IV, 0, this.cfbV, 0, this.IV.length);
this.cipher.reset();
}
}

View File

@ -0,0 +1,24 @@
package org.bouncycastle.crypto.params;
import org.bouncycastle.crypto.CipherParameters;
public class KeyParameter implements CipherParameters
{
private byte[] key;
public KeyParameter(byte[] par1ArrayOfByte)
{
this(par1ArrayOfByte, 0, par1ArrayOfByte.length);
}
public KeyParameter(byte[] par1ArrayOfByte, int par2, int par3)
{
this.key = new byte[par3];
System.arraycopy(par1ArrayOfByte, par2, this.key, 0, par3);
}
public byte[] getKey()
{
return this.key;
}
}

View File

@ -0,0 +1,26 @@
package org.bouncycastle.crypto.params;
import org.bouncycastle.crypto.CipherParameters;
public class ParametersWithIV implements CipherParameters
{
private byte[] iv;
private CipherParameters parameters;
public ParametersWithIV(CipherParameters par1CipherParameters, byte[] par2ArrayOfByte, int par3, int par4)
{
this.iv = new byte[par4];
this.parameters = par1CipherParameters;
System.arraycopy(par2ArrayOfByte, par3, this.iv, 0, par4);
}
public byte[] getIV()
{
return this.iv;
}
public CipherParameters getParameters()
{
return this.parameters;
}
}