forked from I2P_Developers/i2p.i2p
2004-10-16 jrandom
* More aggressively fail peers if their tunnels are failing so that we move off them quicker. * Simplify some data structure serialization for reuse in the streaming lib, as well as add support for signing and verifying partial byte arrays. * Logging updates
This commit is contained in:
@ -50,8 +50,10 @@ public class DSAEngine {
|
||||
public static DSAEngine getInstance() {
|
||||
return I2PAppContext.getGlobalContext().dsa();
|
||||
}
|
||||
|
||||
public boolean verifySignature(Signature signature, byte signedData[], SigningPublicKey verifyingKey) {
|
||||
return verifySignature(signature, signedData, 0, signedData.length, verifyingKey);
|
||||
}
|
||||
public boolean verifySignature(Signature signature, byte signedData[], int offset, int size, SigningPublicKey verifyingKey) {
|
||||
long start = _context.clock().now();
|
||||
|
||||
byte[] sigbytes = signature.getData();
|
||||
@ -68,7 +70,7 @@ public class DSAEngine {
|
||||
BigInteger r = new NativeBigInteger(1, rbytes);
|
||||
BigInteger y = new NativeBigInteger(1, verifyingKey.getData());
|
||||
BigInteger w = s.modInverse(CryptoConstants.dsaq);
|
||||
byte data[] = calculateHash(signedData).getData();
|
||||
byte data[] = calculateHash(signedData, offset, size).getData();
|
||||
NativeBigInteger bi = new NativeBigInteger(1, data);
|
||||
BigInteger u1 = bi.multiply(w).mod(CryptoConstants.dsaq);
|
||||
BigInteger u2 = r.multiply(w).mod(CryptoConstants.dsaq);
|
||||
@ -88,6 +90,9 @@ public class DSAEngine {
|
||||
}
|
||||
|
||||
public Signature sign(byte data[], SigningPrivateKey signingKey) {
|
||||
return sign(data, 0, data.length, signingKey);
|
||||
}
|
||||
public Signature sign(byte data[], int offset, int length, SigningPrivateKey signingKey) {
|
||||
if ((signingKey == null) || (data == null) || (data.length <= 0)) return null;
|
||||
long start = _context.clock().now();
|
||||
|
||||
@ -100,7 +105,7 @@ public class DSAEngine {
|
||||
|
||||
BigInteger r = CryptoConstants.dsag.modPow(k, CryptoConstants.dsap).mod(CryptoConstants.dsaq);
|
||||
BigInteger kinv = k.modInverse(CryptoConstants.dsaq);
|
||||
Hash h = calculateHash(data);
|
||||
Hash h = calculateHash(data, offset, length);
|
||||
|
||||
if (h == null) return null;
|
||||
|
||||
@ -150,42 +155,42 @@ public class DSAEngine {
|
||||
|
||||
private int[] H0 = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0};
|
||||
|
||||
private Hash calculateHash(byte[] source) {
|
||||
long length = source.length * 8;
|
||||
private Hash calculateHash(byte[] source, int offset, int len) {
|
||||
long length = len * 8;
|
||||
int k = 448 - (int) ((length + 1) % 512);
|
||||
if (k < 0) {
|
||||
k += 512;
|
||||
}
|
||||
int padbytes = k / 8;
|
||||
int wordlength = source.length / 4 + padbytes / 4 + 3;
|
||||
int wordlength = len / 4 + padbytes / 4 + 3;
|
||||
int[] M0 = new int[wordlength];
|
||||
int wordcount = 0;
|
||||
int x = 0;
|
||||
for (x = 0; x < (source.length / 4) * 4; x += 4) {
|
||||
M0[wordcount] = source[x] << 24 >>> 24 << 24;
|
||||
M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16;
|
||||
M0[wordcount] |= source[x + 2] << 24 >>> 24 << 8;
|
||||
M0[wordcount] |= source[x + 3] << 24 >>> 24 << 0;
|
||||
for (x = 0; x < (len / 4) * 4; x += 4) {
|
||||
M0[wordcount] = source[offset + x] << 24 >>> 24 << 24;
|
||||
M0[wordcount] |= source[offset + x + 1] << 24 >>> 24 << 16;
|
||||
M0[wordcount] |= source[offset + x + 2] << 24 >>> 24 << 8;
|
||||
M0[wordcount] |= source[offset + x + 3] << 24 >>> 24 << 0;
|
||||
wordcount++;
|
||||
}
|
||||
|
||||
switch (source.length - (wordcount + 1) * 4 + 4) {
|
||||
switch (len - (wordcount + 1) * 4 + 4) {
|
||||
case 0:
|
||||
M0[wordcount] |= 0x80000000;
|
||||
break;
|
||||
case 1:
|
||||
M0[wordcount] = source[x] << 24 >>> 24 << 24;
|
||||
M0[wordcount] = source[offset + x] << 24 >>> 24 << 24;
|
||||
M0[wordcount] |= 0x00800000;
|
||||
break;
|
||||
case 2:
|
||||
M0[wordcount] = source[x] << 24 >>> 24 << 24;
|
||||
M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16;
|
||||
M0[wordcount] = source[offset + x] << 24 >>> 24 << 24;
|
||||
M0[wordcount] |= source[offset + x + 1] << 24 >>> 24 << 16;
|
||||
M0[wordcount] |= 0x00008000;
|
||||
break;
|
||||
case 3:
|
||||
M0[wordcount] = source[x] << 24 >>> 24 << 24;
|
||||
M0[wordcount] |= source[x + 1] << 24 >>> 24 << 16;
|
||||
M0[wordcount] |= source[x + 2] << 24 >>> 24 << 8;
|
||||
M0[wordcount] = source[offset + x] << 24 >>> 24 << 24;
|
||||
M0[wordcount] |= source[offset + x + 1] << 24 >>> 24 << 16;
|
||||
M0[wordcount] |= source[offset + x + 2] << 24 >>> 24 << 8;
|
||||
M0[wordcount] |= 0x00000080;
|
||||
break;
|
||||
}
|
||||
|
@ -86,6 +86,41 @@ public class Certificate extends DataStructureImpl {
|
||||
DataHelper.writeLong(out, 2, 0L);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int writeBytes(byte target[], int offset) {
|
||||
int cur = offset;
|
||||
DataHelper.toLong(target, cur, 1, _type);
|
||||
cur++;
|
||||
if (_payload != null) {
|
||||
DataHelper.toLong(target, cur, 2, _payload.length);
|
||||
cur += 2;
|
||||
System.arraycopy(_payload, 0, target, cur, _payload.length);
|
||||
cur += _payload.length;
|
||||
} else {
|
||||
DataHelper.toLong(target, cur, 2, 0);
|
||||
cur += 2;
|
||||
}
|
||||
return cur - offset;
|
||||
}
|
||||
|
||||
public int readBytes(byte source[], int offset) {
|
||||
int cur = offset;
|
||||
_type = (int)DataHelper.fromLong(source, cur, 1);
|
||||
cur++;
|
||||
int length = (int)DataHelper.fromLong(source, cur, 2);
|
||||
cur += 2;
|
||||
if (length > 0) {
|
||||
_payload = new byte[length];
|
||||
System.arraycopy(source, cur, _payload, 0, length);
|
||||
cur += length;
|
||||
}
|
||||
return cur - offset;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return 1 + 2 + (_payload != null ? _payload.length : 0);
|
||||
}
|
||||
|
||||
public boolean equals(Object object) {
|
||||
if ((object == null) || !(object instanceof Certificate)) return false;
|
||||
|
@ -263,12 +263,16 @@ public class DataHelper {
|
||||
}
|
||||
|
||||
public static byte[] toLong(int numBytes, long value) throws IllegalArgumentException {
|
||||
byte val[] = new byte[numBytes];
|
||||
toLong(val, 0, numBytes, value);
|
||||
return val;
|
||||
}
|
||||
|
||||
public static void toLong(byte target[], int offset, int numBytes, long value) throws IllegalArgumentException {
|
||||
if (numBytes <= 0) throw new IllegalArgumentException("Invalid number of bytes");
|
||||
if (value < 0) throw new IllegalArgumentException("Negative value not allowed");
|
||||
byte val[] = new byte[numBytes];
|
||||
for (int i = 0; i < numBytes; i++)
|
||||
val[numBytes-i-1] = (byte)(value >>> (i*8));
|
||||
return val;
|
||||
target[offset+numBytes-i-1] = (byte)(value >>> (i*8));
|
||||
}
|
||||
|
||||
public static long fromLong(byte src[], int offset, int numBytes) {
|
||||
|
@ -79,7 +79,41 @@ public class Destination extends DataStructureImpl {
|
||||
_signingKey.writeBytes(out);
|
||||
_certificate.writeBytes(out);
|
||||
}
|
||||
|
||||
public int writeBytes(byte target[], int offset) {
|
||||
int cur = offset;
|
||||
System.arraycopy(_publicKey.getData(), 0, target, cur, PublicKey.KEYSIZE_BYTES);
|
||||
cur += PublicKey.KEYSIZE_BYTES;
|
||||
System.arraycopy(_signingKey.getData(), 0, target, cur, SigningPublicKey.KEYSIZE_BYTES);
|
||||
cur += SigningPublicKey.KEYSIZE_BYTES;
|
||||
cur += _certificate.writeBytes(target, cur);
|
||||
return cur - offset;
|
||||
}
|
||||
|
||||
public int readBytes(byte source[], int offset) {
|
||||
int cur = offset;
|
||||
|
||||
_publicKey = new PublicKey();
|
||||
byte buf[] = new byte[PublicKey.KEYSIZE_BYTES];
|
||||
System.arraycopy(source, cur, buf, 0, PublicKey.KEYSIZE_BYTES);
|
||||
_publicKey.setData(buf);
|
||||
cur += PublicKey.KEYSIZE_BYTES;
|
||||
|
||||
_signingKey = new SigningPublicKey();
|
||||
buf = new byte[SigningPublicKey.KEYSIZE_BYTES];
|
||||
System.arraycopy(source, cur, buf, 0, SigningPublicKey.KEYSIZE_BYTES);
|
||||
cur += SigningPublicKey.KEYSIZE_BYTES;
|
||||
|
||||
_certificate = new Certificate();
|
||||
cur += _certificate.readBytes(buf, cur);
|
||||
|
||||
return cur - offset;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return PublicKey.KEYSIZE_BYTES + SigningPublicKey.KEYSIZE_BYTES + _certificate.size();
|
||||
}
|
||||
|
||||
public boolean equals(Object object) {
|
||||
if ((object == null) || !(object instanceof Destination)) return false;
|
||||
Destination dst = (Destination) object;
|
||||
|
Reference in New Issue
Block a user