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:
zzz
2013-12-24 16:41:05 +00:00
parent bf485d8bce
commit 5842e25205
21 changed files with 698 additions and 78 deletions

View File

@ -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;
}