forked from I2P_Developers/i2p.i2p
Router: MessageWrapper.wrap() and GMB support for ECIES (prop. #156 WIP)
NetDB parts still TODO Remove PK param from GMB.buildECIESMessage(), already in config
This commit is contained in:
28
history.txt
28
history.txt
@ -1,3 +1,30 @@
|
|||||||
|
2020-10-15 zzz
|
||||||
|
* Router:
|
||||||
|
- More efficient initialization of Noise state
|
||||||
|
- Destroy ratchet HandshakeState after NS failure
|
||||||
|
- Add support for ratchet zero key (proposals #144, #156)
|
||||||
|
|
||||||
|
2020-10-12 zzz
|
||||||
|
* DTG: Enable by default for Linux KDE and LXDE;
|
||||||
|
Hide option on /configservice if not supported
|
||||||
|
* New translations for Kurdish, Turkmen, Argentinian Spanish
|
||||||
|
* NTCP:
|
||||||
|
- Fix sending termination on idle timeout (ticket #2777)
|
||||||
|
- Catch possible race IAE in Reader
|
||||||
|
|
||||||
|
2020-10-11 zzz
|
||||||
|
* Installer: Disable pack200 (ticket #2778)
|
||||||
|
|
||||||
|
2020-10-10 zzz
|
||||||
|
* i2psnark: Cache length of metainfo
|
||||||
|
* Transport: Improved IPv6 address validation
|
||||||
|
|
||||||
|
2020-10-09 zzz
|
||||||
|
* NetDB:
|
||||||
|
- Don't use DSA-SHA1 routers for lookups, stores, or tunnel peers
|
||||||
|
- Don't use non-ElGamal routers for lookups or stores
|
||||||
|
- Prevent DSA-SHA1 routers from auto-floodfill
|
||||||
|
|
||||||
2020-10-07 zzz
|
2020-10-07 zzz
|
||||||
* Build:
|
* Build:
|
||||||
- Set javac release property (ticket #2775)
|
- Set javac release property (ticket #2775)
|
||||||
@ -5,6 +32,7 @@
|
|||||||
- Drop support for Xenial package build
|
- Drop support for Xenial package build
|
||||||
- Fix up BOB build configuration
|
- Fix up BOB build configuration
|
||||||
- Fix i2psnark standalone build
|
- Fix i2psnark standalone build
|
||||||
|
* i2ptunnel: Filter server response headers even if not compressing
|
||||||
|
|
||||||
2020-10-03 zzz
|
2020-10-03 zzz
|
||||||
* Router: Support building tunnels through ECIES routers (proposal 152)
|
* Router: Support building tunnels through ECIES routers (proposal 152)
|
||||||
|
@ -18,7 +18,7 @@ public class RouterVersion {
|
|||||||
/** deprecated */
|
/** deprecated */
|
||||||
public final static String ID = "Monotone";
|
public final static String ID = "Monotone";
|
||||||
public final static String VERSION = CoreVersion.VERSION;
|
public final static String VERSION = CoreVersion.VERSION;
|
||||||
public final static long BUILD = 6;
|
public final static long BUILD = 7;
|
||||||
|
|
||||||
/** for example "-test" */
|
/** for example "-test" */
|
||||||
public final static String EXTRA = "";
|
public final static String EXTRA = "";
|
||||||
|
@ -275,16 +275,14 @@ public class GarlicMessageBuilder {
|
|||||||
* Called by OCMJH only.
|
* Called by OCMJH only.
|
||||||
*
|
*
|
||||||
* @param ctx scope
|
* @param ctx scope
|
||||||
* @param config how/what to wrap
|
* @param config how/what to wrap, must have key set with setRecipientPublicKey()
|
||||||
* @param target public key of the location being garlic routed to (may be null if we
|
|
||||||
* know the encryptKey and encryptTag)
|
|
||||||
* @param callback may be null
|
* @param callback may be null
|
||||||
* @return null if expired or on other errors
|
* @return null if expired or on other errors
|
||||||
* @throws IllegalArgumentException on error
|
* @throws IllegalArgumentException on error
|
||||||
* @since 0.9.44
|
* @since 0.9.44
|
||||||
*/
|
*/
|
||||||
static GarlicMessage buildECIESMessage(RouterContext ctx, GarlicConfig config,
|
static GarlicMessage buildECIESMessage(RouterContext ctx, GarlicConfig config,
|
||||||
PublicKey target, Hash from, Destination to, SessionKeyManager skm,
|
Hash from, Destination to, SessionKeyManager skm,
|
||||||
ReplyCallback callback) {
|
ReplyCallback callback) {
|
||||||
PublicKey key = config.getRecipientPublicKey();
|
PublicKey key = config.getRecipientPublicKey();
|
||||||
if (key.getType() != EncType.ECIES_X25519)
|
if (key.getType() != EncType.ECIES_X25519)
|
||||||
@ -315,7 +313,7 @@ public class GarlicMessageBuilder {
|
|||||||
log.warn("No SKM for " + from.toBase32());
|
log.warn("No SKM for " + from.toBase32());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
byte encData[] = ctx.eciesEngine().encrypt(cloveSet, target, to, priv, rskm, callback);
|
byte encData[] = ctx.eciesEngine().encrypt(cloveSet, key, to, priv, rskm, callback);
|
||||||
if (encData == null) {
|
if (encData == null) {
|
||||||
if (log.shouldWarn())
|
if (log.shouldWarn())
|
||||||
log.warn("Encrypt fail for " + from.toBase32());
|
log.warn("Encrypt fail for " + from.toBase32());
|
||||||
@ -334,6 +332,42 @@ public class GarlicMessageBuilder {
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt from an anonymous source.
|
||||||
|
* ECIES_X25519 only.
|
||||||
|
* Called by MessageWrapper only.
|
||||||
|
*
|
||||||
|
* @param ctx scope
|
||||||
|
* @param config how/what to wrap, must have key set with setRecipientPublicKey()
|
||||||
|
* @throws IllegalArgumentException on error
|
||||||
|
* @since 0.9.48
|
||||||
|
*/
|
||||||
|
public static GarlicMessage buildECIESMessage(RouterContext ctx, GarlicConfig config) {
|
||||||
|
PublicKey key = config.getRecipientPublicKey();
|
||||||
|
if (key.getType() != EncType.ECIES_X25519)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
Log log = ctx.logManager().getLog(GarlicMessageBuilder.class);
|
||||||
|
GarlicMessage msg = new GarlicMessage(ctx);
|
||||||
|
CloveSet cloveSet = buildECIESCloveSet(ctx, config);
|
||||||
|
byte encData[] = ctx.eciesEngine().encrypt(cloveSet, key);
|
||||||
|
if (encData == null) {
|
||||||
|
if (log.shouldWarn())
|
||||||
|
log.warn("Encrypt fail for " + config);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
msg.setData(encData);
|
||||||
|
msg.setMessageExpiration(config.getExpiration());
|
||||||
|
long timeFromNow = config.getExpiration() - ctx.clock().now();
|
||||||
|
if (timeFromNow < 1*1000) {
|
||||||
|
if (log.shouldDebug())
|
||||||
|
log.debug("Building a message expiring in " + timeFromNow + "ms: " + config, new Exception("created by"));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (log.shouldDebug())
|
||||||
|
log.debug("Built ECIES CloveSet (" + config.getCloveCount() + " cloves) in " + msg);
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
/****
|
/****
|
||||||
private static void noteWrap(RouterContext ctx, GarlicMessage wrapper, GarlicConfig contained) {
|
private static void noteWrap(RouterContext ctx, GarlicMessage wrapper, GarlicConfig contained) {
|
||||||
for (int i = 0; i < contained.getCloveCount(); i++) {
|
for (int i = 0; i < contained.getCloveCount(); i++) {
|
||||||
|
@ -131,7 +131,7 @@ class OutboundClientMessageJobHelper {
|
|||||||
return null;
|
return null;
|
||||||
GarlicMessage msg;
|
GarlicMessage msg;
|
||||||
if (isECIES) {
|
if (isECIES) {
|
||||||
msg = GarlicMessageBuilder.buildECIESMessage(ctx, config, recipientPK, from, dest, skm, callback);
|
msg = GarlicMessageBuilder.buildECIESMessage(ctx, config, from, dest, skm, callback);
|
||||||
} else {
|
} else {
|
||||||
// no use sending tags unless we have a reply token set up already
|
// no use sending tags unless we have a reply token set up already
|
||||||
int tagsToSend = replyToken >= 0 ? (tagsToSendOverride > 0 ? tagsToSendOverride : skm.getTagsToSend()) : 0;
|
int tagsToSend = replyToken >= 0 ? (tagsToSendOverride > 0 ? tagsToSendOverride : skm.getTagsToSend()) : 0;
|
||||||
@ -146,6 +146,8 @@ class OutboundClientMessageJobHelper {
|
|||||||
* Make the top-level config, with a data clove, an optional ack clove, and
|
* Make the top-level config, with a data clove, an optional ack clove, and
|
||||||
* an optional leaseset clove.
|
* an optional leaseset clove.
|
||||||
*
|
*
|
||||||
|
* The returned GarlicConfig will have the recipientPublicKey set.
|
||||||
|
*
|
||||||
* @param dataClove may be null for ECIES-layer ack
|
* @param dataClove may be null for ECIES-layer ack
|
||||||
* @param replyTunnel non-null if requireAck is true or bundledReplyLeaseSet is non-null
|
* @param replyTunnel non-null if requireAck is true or bundledReplyLeaseSet is non-null
|
||||||
* @param requireAck if true, bundle replyToken in an ack clove
|
* @param requireAck if true, bundle replyToken in an ack clove
|
||||||
|
@ -125,16 +125,13 @@ public class MessageWrapper {
|
|||||||
/**
|
/**
|
||||||
* Garlic wrap a message from nobody, destined for a router,
|
* Garlic wrap a message from nobody, destined for a router,
|
||||||
* to hide the contents from the OBEP.
|
* to hide the contents from the OBEP.
|
||||||
* Forces ElGamal.
|
* Forces full asymmetric encryption.
|
||||||
*
|
*
|
||||||
* @param to must be ELGAMAL_2048 EncType
|
* @param to must be ELGAMAL_2048 or ECIES_X25519 EncType
|
||||||
* @return null on encrypt failure
|
* @return null on encrypt failure
|
||||||
* @since 0.9.5
|
* @since 0.9.5
|
||||||
*/
|
*/
|
||||||
static GarlicMessage wrap(RouterContext ctx, I2NPMessage m, RouterInfo to) {
|
static GarlicMessage wrap(RouterContext ctx, I2NPMessage m, RouterInfo to) {
|
||||||
PublicKey key = to.getIdentity().getPublicKey();
|
|
||||||
if (key.getType() != EncType.ELGAMAL_2048)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
PayloadGarlicConfig payload = new PayloadGarlicConfig(Certificate.NULL_CERT,
|
PayloadGarlicConfig payload = new PayloadGarlicConfig(Certificate.NULL_CERT,
|
||||||
ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE),
|
ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE),
|
||||||
@ -142,9 +139,19 @@ public class MessageWrapper {
|
|||||||
DeliveryInstructions.LOCAL, m);
|
DeliveryInstructions.LOCAL, m);
|
||||||
payload.setRecipient(to);
|
payload.setRecipient(to);
|
||||||
|
|
||||||
SessionKey sentKey = ctx.keyGenerator().generateSessionKey();
|
PublicKey key = to.getIdentity().getPublicKey();
|
||||||
GarlicMessage msg = GarlicMessageBuilder.buildMessage(ctx, payload, null,
|
EncType type = key.getType();
|
||||||
key, sentKey, null);
|
GarlicMessage msg;
|
||||||
|
if (type == EncType.ELGAMAL_2048) {
|
||||||
|
SessionKey sentKey = ctx.keyGenerator().generateSessionKey();
|
||||||
|
msg = GarlicMessageBuilder.buildMessage(ctx, payload, null, key, sentKey, null);
|
||||||
|
} else if (type == EncType.ECIES_X25519) {
|
||||||
|
payload.setRecipientPublicKey(key);
|
||||||
|
msg = GarlicMessageBuilder.buildECIESMessage(ctx, payload);
|
||||||
|
} else {
|
||||||
|
// unsupported
|
||||||
|
msg = null;
|
||||||
|
}
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user