Data: Check sooner for unknown sig type;

minor efficiency improvements in parsing
This commit is contained in:
zzz
2018-08-04 13:41:01 +00:00
parent c0be83fe08
commit f1df49606d
4 changed files with 29 additions and 14 deletions

View File

@ -89,7 +89,8 @@ public class Certificate extends DataStructureImpl {
* @since 0.8.3 * @since 0.8.3
*/ */
public static Certificate create(InputStream in) throws DataFormatException, IOException { public static Certificate create(InputStream in) throws DataFormatException, IOException {
int type = (int) DataHelper.readLong(in, 1); // EOF will be thrown in next read
int type = in.read();
int length = (int) DataHelper.readLong(in, 2); int length = (int) DataHelper.readLong(in, 2);
if (type == 0 && length == 0) if (type == 0 && length == 0)
return NULL_CERT; return NULL_CERT;
@ -161,7 +162,8 @@ public class Certificate extends DataStructureImpl {
public void readBytes(InputStream in) throws DataFormatException, IOException { public void readBytes(InputStream in) throws DataFormatException, IOException {
if (_type != 0 || _payload != null) if (_type != 0 || _payload != null)
throw new IllegalStateException("already set"); throw new IllegalStateException("already set");
_type = (int) DataHelper.readLong(in, 1); // EOF will be thrown in next read
_type = in.read();
int length = (int) DataHelper.readLong(in, 2); int length = (int) DataHelper.readLong(in, 2);
if (length > 0) { if (length > 0) {
_payload = new byte[length]; _payload = new byte[length];

View File

@ -19,6 +19,7 @@ import java.util.List;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.crypto.DSAEngine; import net.i2p.crypto.DSAEngine;
import net.i2p.crypto.SigType;
import net.i2p.util.Clock; import net.i2p.util.Clock;
import net.i2p.util.Log; import net.i2p.util.Log;
import net.i2p.util.RandomSource; import net.i2p.util.RandomSource;
@ -327,9 +328,15 @@ public class LeaseSet extends DatabaseEntry {
_destination = Destination.create(in); _destination = Destination.create(in);
_encryptionKey = PublicKey.create(in); _encryptionKey = PublicKey.create(in);
// revocation signing key must be same type as the destination signing key // revocation signing key must be same type as the destination signing key
_signingKey = new SigningPublicKey(_destination.getSigningPublicKey().getType()); SigType type = _destination.getSigningPublicKey().getType();
// Even if not verifying, we have to construct a Signature object
// below, which will fail for null type.
if (type == null)
throw new DataFormatException("unknown sig type");
_signingKey = new SigningPublicKey(type);
// EOF will be thrown in signature read below
_signingKey.readBytes(in); _signingKey.readBytes(in);
int numLeases = (int) DataHelper.readLong(in, 1); int numLeases = in.read();
if (numLeases > MAX_LEASES) if (numLeases > MAX_LEASES)
throw new DataFormatException("Too many leases - max is " + MAX_LEASES); throw new DataFormatException("Too many leases - max is " + MAX_LEASES);
//_version = DataHelper.readLong(in, 4); //_version = DataHelper.readLong(in, 4);
@ -339,7 +346,7 @@ public class LeaseSet extends DatabaseEntry {
addLease(lease); addLease(lease);
} }
// signature must be same type as the destination signing key // signature must be same type as the destination signing key
_signature = new Signature(_destination.getSigningPublicKey().getType()); _signature = new Signature(type);
_signature.readBytes(in); _signature.readBytes(in);
} }

View File

@ -279,7 +279,8 @@ public class RouterAddress extends DataStructureImpl {
public void readBytes(InputStream in) throws DataFormatException, IOException { public void readBytes(InputStream in) throws DataFormatException, IOException {
if (_transportStyle != null) if (_transportStyle != null)
throw new IllegalStateException(); throw new IllegalStateException();
_cost = (short) DataHelper.readLong(in, 1); // EOF will be thrown in next read
_cost = (short) in.read();
_expiration = DataHelper.readLong(in, 8); _expiration = DataHelper.readLong(in, 8);
_transportStyle = DataHelper.readString(in); _transportStyle = DataHelper.readString(in);
// reduce Object proliferation // reduce Object proliferation

View File

@ -549,11 +549,15 @@ public class RouterInfo extends DatabaseEntry {
// can't set the digest until we know the sig type // can't set the digest until we know the sig type
InputStream din; InputStream din;
MessageDigest digest; MessageDigest digest;
SigType type = _identity.getSigningPublicKey().getType();
// Even if not verifying, we have to construct a Signature object
// below, which will fail for null type.
if (type == null)
throw new DataFormatException("unknown sig type");
if (verifySig) { if (verifySig) {
SigType type = _identity.getSigningPublicKey().getType();
if (type != SigType.EdDSA_SHA512_Ed25519) { if (type != SigType.EdDSA_SHA512_Ed25519) {
// This won't work for EdDSA // This won't work for EdDSA
digest = _identity.getSigningPublicKey().getType().getDigestInstance(); digest = type.getDigestInstance();
// TODO any better way? // TODO any better way?
digest.update(_identity.toByteArray()); digest.update(_identity.toByteArray());
din = new DigestInputStream(in, digest); din = new DigestInputStream(in, digest);
@ -572,14 +576,16 @@ public class RouterInfo extends DatabaseEntry {
//else //else
// _published = when.getTime(); // _published = when.getTime();
_published = DataHelper.readLong(din, 8); _published = DataHelper.readLong(din, 8);
int numAddresses = (int) DataHelper.readLong(din, 1); // EOF will be thrown in properties read below
int numAddresses = din.read();
for (int i = 0; i < numAddresses; i++) { for (int i = 0; i < numAddresses; i++) {
RouterAddress address = new RouterAddress(); RouterAddress address = new RouterAddress();
address.readBytes(din); address.readBytes(din);
_addresses.add(address); _addresses.add(address);
} }
int numPeers = (int) DataHelper.readLong(din, 1); // EOF will be thrown in properties read below
if (numPeers == 0) { int numPeers = din.read();
if (numPeers <= 0) {
_peers = null; _peers = null;
} else { } else {
_peers = new HashSet<Hash>(numPeers); _peers = new HashSet<Hash>(numPeers);
@ -590,14 +596,13 @@ public class RouterInfo extends DatabaseEntry {
} }
} }
DataHelper.readProperties(din, _options); DataHelper.readProperties(din, _options);
_signature = new Signature(_identity.getSigningPublicKey().getType()); _signature = new Signature(type);
_signature.readBytes(in); _signature.readBytes(in);
if (verifySig) { if (verifySig) {
SigType type = _identity.getSigningPublicKey().getType();
if (type != SigType.EdDSA_SHA512_Ed25519) { if (type != SigType.EdDSA_SHA512_Ed25519) {
// This won't work for EdDSA // This won't work for EdDSA
SimpleDataStructure hash = _identity.getSigningPublicKey().getType().getHashInstance(); SimpleDataStructure hash = type.getHashInstance();
hash.setData(digest.digest()); hash.setData(digest.digest());
_isValid = DSAEngine.getInstance().verifySignature(_signature, hash, _identity.getSigningPublicKey()); _isValid = DSAEngine.getInstance().verifySignature(_signature, hash, _identity.getSigningPublicKey());
_validated = true; _validated = true;