I2CP, NetDB, Console: Encrypted LS2 handling fixes (WIP)

log tweaks
This commit is contained in:
zzz
2019-03-02 21:52:12 +00:00
parent 7cbb43ab75
commit 54d9a29855
6 changed files with 78 additions and 18 deletions

View File

@ -448,11 +448,12 @@ class NetDbRenderer {
buf.append("<div class=\"leasesets_container\">");
for (LeaseSet ls : leases) {
Destination dest = ls.getDestination();
Hash key = dest.calculateHash();
Hash key = ls.getHash();
buf.append("<table class=\"leaseset\">\n")
.append("<tr><th><b>").append(_t("LeaseSet")).append(":</b>&nbsp;<code>").append(key.toBase64()).append("</code>");
if (_context.keyRing().get(key) != null)
buf.append(" (").append(_t("Encrypted")).append(')');
int type = ls.getType();
if (type == DatabaseEntry.KEY_TYPE_ENCRYPTED_LS2 || _context.keyRing().get(key) != null)
buf.append(" <b>(").append(_t("Encrypted")).append(")</b>");
buf.append("</th>");
if (_context.clientManager().isLocal(dest)) {
buf.append("<th><a href=\"tunnels#" + key.toBase64().substring(0,4) + "\">" + _t("Local") + "</a> ");
@ -477,7 +478,7 @@ class NetDbRenderer {
buf.append(" colspan=\"2\"");
}
buf.append(">");
String b32 = dest.toBase32();
String b32 = key.toBase32();
buf.append("<a href=\"http://").append(b32).append("\">").append(b32).append("</a></td>");
if (linkSusi && !unpublished) {
if (host == null) {
@ -505,13 +506,23 @@ class NetDbRenderer {
}
}
}
buf.append("</tr>\n<tr><td colspan=\"2\">\n");
long exp = ls.getLatestLeaseDate()-now;
long exp;
if (type == DatabaseEntry.KEY_TYPE_LEASESET) {
exp = ls.getLatestLeaseDate() - now;
} else {
LeaseSet2 ls2 = (LeaseSet2) ls;
long pub = now - ls2.getPublished();
buf.append("</tr>\n<tr><td colspan=\"2\">\n<b>")
.append(_t("Published {0} ago", DataHelper.formatDuration2(pub)))
.append("</b>");
exp = ((LeaseSet2)ls).getExpires()-now;
}
buf.append("</tr>\n<tr><td colspan=\"2\">\n<b>");
if (exp > 0)
buf.append("<b>").append(_t("Expires in {0}", DataHelper.formatDuration2(exp))).append("</b>");
buf.append(_t("Expires in {0}", DataHelper.formatDuration2(exp)));
else
buf.append("<b>").append(_t("Expired {0} ago", DataHelper.formatDuration2(0-exp))).append("</b>");
buf.append("</td></tr>\n");
buf.append(_t("Expired {0} ago", DataHelper.formatDuration2(0-exp)));
buf.append("</b></td></tr>\n");
if (debug) {
buf.append("<tr><td colspan=\"2\">");
buf.append("<b>RAP?</b> ").append(ls.getReceivedAsPublished());
@ -522,7 +533,6 @@ class NetDbRenderer {
median = dist;
}
buf.append("&nbsp;&nbsp;<b>Distance: </b>").append(fmt.format(biLog2(dist)));
int type = ls.getType();
buf.append("&nbsp;&nbsp;<b>Type: </b>").append(type);
if (type != DatabaseEntry.KEY_TYPE_LEASESET) {
LeaseSet2 ls2 = (LeaseSet2) ls;

View File

@ -286,6 +286,8 @@ public class EncryptedLeaseSet extends LeaseSet2 {
}
/**
* This must be used instead of getDestination().getHash().
*
* Overridden because we have a blinded key, not a dest.
* This is the hash of the signing public key type and the signing public key.
* Throws IllegalStateException if not initialized.
@ -537,6 +539,9 @@ public class EncryptedLeaseSet extends LeaseSet2 {
*/
@Override
public boolean verifySignature() {
// TODO use fields in super
if (_decryptedLS2 != null)
return _decryptedLS2.verifySignature();
if (_log.shouldDebug()) {
_log.debug("Sig verify outer with key: " + _signingKey.getType() + ' ' + _signingKey.toBase64());
_log.debug("Outer sig: " + _signature.getType() + ' ' + _signature.toBase64());
@ -596,6 +601,8 @@ public class EncryptedLeaseSet extends LeaseSet2 {
StringBuilder buf = new StringBuilder(128);
buf.append("[EncryptedLeaseSet: ");
buf.append("\n\tBlinded Key: ").append(_signingKey);
buf.append("\n\tHash: ").append(getHash());
buf.append("\n\tB32: ").append(getHash().toBase32());
if (isOffline()) {
buf.append("\n\tTransient Key: ").append(_transientSigningPublicKey);
buf.append("\n\tTransient Expires: ").append(new java.util.Date(_transientExpires));

View File

@ -402,9 +402,9 @@ public class LeaseSet extends DatabaseEntry {
StringBuilder buf = new StringBuilder(128);
buf.append("[LeaseSet: ");
buf.append("\n\tDestination: ").append(_destination);
buf.append("\n\tB32: ").append(_destination.toBase32());
buf.append("\n\tEncryptionKey: ").append(_encryptionKey);
buf.append("\n\tSigningKey: ").append(_signingKey);
//buf.append("\n\tVersion: ").append(getVersion());
buf.append("\n\tSignature: ").append(_signature);
buf.append("\n\tLeases: #").append(getLeaseCount());
for (int i = 0; i < getLeaseCount(); i++)

View File

@ -55,7 +55,7 @@ public class LeaseSet2 extends LeaseSet {
/**
* Published timestamp, as received.
* Different than getDate(), which is the earliest lease expiration.
* Different than getDate() or getEarliestLeaseDate(), which are the earliest lease expiration.
*
* @return in ms, with 1 second resolution
* @since 0.9.39
@ -64,6 +64,17 @@ public class LeaseSet2 extends LeaseSet {
return _published;
}
/**
* Published expiration, as received.
* May be different than getLatestLeaseDate(), which is the latest lease expiration.
*
* @return in ms, with 1 second resolution
* @since 0.9.39
*/
public long getExpires() {
return _expires;
}
public boolean isUnpublished() {
return (_flags & FLAG_UNPUBLISHED) != 0;
}
@ -578,6 +589,7 @@ public class LeaseSet2 extends LeaseSet {
StringBuilder buf = new StringBuilder(128);
buf.append("[LeaseSet2: ");
buf.append("\n\tDestination: ").append(_destination);
buf.append("\n\tB32: ").append(_destination.toBase32());
List<PublicKey> keys = getEncryptionKeys();
int sz = keys.size();
buf.append("\n\tEncryption Keys: ").append(sz);

View File

@ -17,6 +17,7 @@ import net.i2p.crypto.SigType;
import net.i2p.data.DatabaseEntry;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.data.EncryptedLeaseSet;
import net.i2p.data.Hash;
import net.i2p.data.LeaseSet;
import net.i2p.data.LeaseSet2;
@ -631,7 +632,16 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
}
}
try {
if (_log.shouldDebug())
_log.debug("Publishing: " + ls);
_context.netDb().publish(ls);
if (type == DatabaseEntry.KEY_TYPE_ENCRYPTED_LS2) {
// store the decrypted ls also
EncryptedLeaseSet encls = (EncryptedLeaseSet) ls;
if (_log.shouldDebug())
_log.debug("Storing decrypted: " + encls.getDecryptedLeaseSet());
_context.netDb().store(dest.getHash(), encls.getDecryptedLeaseSet());
}
} catch (IllegalArgumentException iae) {
if (_log.shouldLog(Log.ERROR))
_log.error("Invalid leaseset from client", iae);
@ -642,7 +652,12 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
_log.info("New lease set granted for destination " + dest);
// leaseSetCreated takes care of all the LeaseRequestState stuff (including firing any jobs)
_runner.leaseSetCreated(ls);
if (type == DatabaseEntry.KEY_TYPE_ENCRYPTED_LS2) {
EncryptedLeaseSet encls = (EncryptedLeaseSet) ls;
_runner.leaseSetCreated(encls.getDecryptedLeaseSet());
} else {
_runner.leaseSetCreated(ls);
}
}
/** override for testing */

View File

@ -29,6 +29,7 @@ import net.i2p.data.Destination;
import net.i2p.data.Hash;
import net.i2p.data.KeyCertificate;
import net.i2p.data.LeaseSet;
import net.i2p.data.LeaseSet2;
import net.i2p.data.i2np.DatabaseLookupMessage;
import net.i2p.data.i2np.DatabaseStoreMessage;
import net.i2p.data.router.RouterAddress;
@ -683,7 +684,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
_log.warn("publish() before initialized: " + localLeaseSet, new Exception("I did it"));
return;
}
Hash h = localLeaseSet.getDestination().calculateHash();
Hash h = localLeaseSet.getHash();
try {
store(h, localLeaseSet);
} catch (IllegalArgumentException iae) {
@ -798,10 +799,10 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
* @return reason why the entry is not valid, or null if it is valid
*/
private String validate(Hash key, LeaseSet leaseSet) throws UnsupportedCryptoException {
if (!key.equals(leaseSet.getDestination().calculateHash())) {
if (!key.equals(leaseSet.getHash())) {
if (_log.shouldLog(Log.WARN))
_log.warn("Invalid store attempt! key does not match leaseSet.destination! key = "
+ key + ", leaseSet = " + leaseSet);
+ key.toBase32() + ", leaseSet = " + leaseSet);
return "Key does not match leaseSet.destination - " + key.toBase64();
}
// todo experimental sig types
@ -812,8 +813,23 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
_log.warn("Invalid leaseSet signature! " + leaseSet);
return "Invalid leaseSet signature on " + key;
}
long earliest = leaseSet.getEarliestLeaseDate();
long latest = leaseSet.getLatestLeaseDate();
long earliest;
long latest;
int type = leaseSet.getType();
if (type == DatabaseEntry.KEY_TYPE_ENCRYPTED_LS2) {
LeaseSet2 ls2 = (LeaseSet2) leaseSet;
// we'll assume it's not an encrypted meta, for now
earliest = ls2.getPublished();
latest = ls2.getExpires();
} else if (type == DatabaseEntry.KEY_TYPE_META_LS2) {
LeaseSet2 ls2 = (LeaseSet2) leaseSet;
// TODO this isn't right, and must adjust limits below also
earliest = Math.min(ls2.getEarliestLeaseDate(), ls2.getPublished());
latest = Math.min(ls2.getLatestLeaseDate(), ls2.getExpires());
} else {
earliest = leaseSet.getEarliestLeaseDate();
latest = leaseSet.getLatestLeaseDate();
}
long now = _context.clock().now();
if (earliest <= now - 10*60*1000L ||
// same as the isCurrent(Router.CLOCK_FUDGE_FACTOR) test in