forked from I2P_Developers/i2p.i2p
Initial support for key certificates and arbitrary types and lengths
of signing keys and signatures in RouterIdentities and Destinations. Untested, not even for regressions, except with command line using PrivateKeyFile. Based on preliminary spec at http://zzz.i2p/topics/1442?page=1#p7524 Not done: - Transport handshake signing - Configuration of default type - Specification of type in options to I2PSocketManagerFactory - Specification of type in i2ptunnel - Fix up caching of SigningPublicKey and P256 key cert - Any non-default crypto type in the key cert - Documentation
This commit is contained in:
@ -5,6 +5,7 @@ import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.crypto.SigType;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.ByteArray;
|
||||
import net.i2p.data.DataFormatException;
|
||||
@ -436,8 +437,9 @@ class Packet {
|
||||
optionSize += _optionFrom.size();
|
||||
if (isFlagSet(FLAG_MAX_PACKET_SIZE_INCLUDED))
|
||||
optionSize += 2;
|
||||
if (isFlagSet(FLAG_SIGNATURE_INCLUDED))
|
||||
optionSize += Signature.SIGNATURE_BYTES;
|
||||
if (isFlagSet(FLAG_SIGNATURE_INCLUDED)) {
|
||||
optionSize += _optionSignature.length();
|
||||
}
|
||||
|
||||
DataHelper.toLong(buffer, cur, 2, optionSize);
|
||||
cur += 2;
|
||||
@ -455,10 +457,10 @@ class Packet {
|
||||
}
|
||||
if (isFlagSet(FLAG_SIGNATURE_INCLUDED)) {
|
||||
if (includeSig)
|
||||
System.arraycopy(_optionSignature.getData(), 0, buffer, cur, Signature.SIGNATURE_BYTES);
|
||||
System.arraycopy(_optionSignature.getData(), 0, buffer, cur, _optionSignature.length());
|
||||
else // we're signing (or validating)
|
||||
Arrays.fill(buffer, cur, cur+Signature.SIGNATURE_BYTES, (byte)0x0);
|
||||
cur += Signature.SIGNATURE_BYTES;
|
||||
Arrays.fill(buffer, cur, cur + _optionSignature.length(), (byte)0x0);
|
||||
cur += _optionSignature.length();
|
||||
}
|
||||
|
||||
if (_payload != null) {
|
||||
@ -511,7 +513,7 @@ class Packet {
|
||||
if (isFlagSet(FLAG_MAX_PACKET_SIZE_INCLUDED))
|
||||
size += 2;
|
||||
if (isFlagSet(FLAG_SIGNATURE_INCLUDED))
|
||||
size += Signature.SIGNATURE_BYTES;
|
||||
size += _optionSignature.length();
|
||||
|
||||
size += 2; // option size
|
||||
|
||||
@ -606,12 +608,37 @@ class Packet {
|
||||
cur += 2;
|
||||
}
|
||||
if (isFlagSet(FLAG_SIGNATURE_INCLUDED)) {
|
||||
Signature optionSignature = new Signature();
|
||||
byte buf[] = new byte[Signature.SIGNATURE_BYTES];
|
||||
System.arraycopy(buffer, cur, buf, 0, Signature.SIGNATURE_BYTES);
|
||||
Signature optionSignature;
|
||||
Destination from = getOptionalFrom();
|
||||
if (from != null) {
|
||||
optionSignature = new Signature(from.getSigningPublicKey().getType());
|
||||
} else {
|
||||
// super cheat for now, look for correct type,
|
||||
// assume no more options. If we add to the options
|
||||
// we will have to ask the manager.
|
||||
int siglen = payloadBegin - cur;
|
||||
SigType type = null;
|
||||
for (SigType t : SigType.values()) {
|
||||
if (t.getSigLen() == siglen) {
|
||||
type = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (type == null) {
|
||||
if (siglen < Signature.SIGNATURE_BYTES)
|
||||
throw new IllegalArgumentException("unknown sig type len=" + siglen);
|
||||
// Hope it's the default type with some unknown options following;
|
||||
// if not the sig will fail later
|
||||
type = SigType.DSA_SHA1;
|
||||
siglen = Signature.SIGNATURE_BYTES;
|
||||
}
|
||||
optionSignature = new Signature(type);
|
||||
}
|
||||
byte buf[] = new byte[optionSignature.length()];
|
||||
System.arraycopy(buffer, cur, buf, 0, buf.length);
|
||||
optionSignature.setData(buf);
|
||||
setOptionalSignature(optionSignature);
|
||||
cur += Signature.SIGNATURE_BYTES;
|
||||
cur += buf.length;
|
||||
}
|
||||
}
|
||||
|
||||
@ -667,12 +694,12 @@ class Packet {
|
||||
setFlag(FLAG_SIGNATURE_INCLUDED);
|
||||
int size = writePacket(buffer, offset, false);
|
||||
_optionSignature = ctx.dsa().sign(buffer, offset, size, key);
|
||||
if (false) {
|
||||
Log l = ctx.logManager().getLog(Packet.class);
|
||||
l.error("Signing: " + toString());
|
||||
l.error(Base64.encode(buffer, 0, size));
|
||||
l.error("Signature: " + Base64.encode(_optionSignature.getData()));
|
||||
}
|
||||
//if (false) {
|
||||
// Log l = ctx.logManager().getLog(Packet.class);
|
||||
// l.error("Signing: " + toString());
|
||||
// l.error(Base64.encode(buffer, 0, size));
|
||||
// l.error("Signature: " + Base64.encode(_optionSignature.getData()));
|
||||
//}
|
||||
// jump into the signed data and inject the signature where we
|
||||
// previously placed a bunch of zeroes
|
||||
int signatureOffset = offset
|
||||
@ -687,7 +714,7 @@ class Packet {
|
||||
+ (isFlagSet(FLAG_DELAY_REQUESTED) ? 2 : 0)
|
||||
+ (isFlagSet(FLAG_FROM_INCLUDED) ? _optionFrom.size() : 0)
|
||||
+ (isFlagSet(FLAG_MAX_PACKET_SIZE_INCLUDED) ? 2 : 0);
|
||||
System.arraycopy(_optionSignature.getData(), 0, buffer, signatureOffset, Signature.SIGNATURE_BYTES);
|
||||
System.arraycopy(_optionSignature.getData(), 0, buffer, signatureOffset, _optionSignature.length());
|
||||
return size;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user