diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java index 77c89319b0..2f5152ad1f 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java @@ -15,6 +15,7 @@ import java.util.Set; import java.util.TreeMap; import net.i2p.client.I2PClient; +import net.i2p.crypto.SigType; import net.i2p.data.Base64; import net.i2p.data.Destination; import net.i2p.data.PrivateKeyFile; @@ -183,6 +184,12 @@ public class EditBean extends IndexBean { return getProperty(tunnel, I2PClient.PROP_SIGTYPE, 0); } + /** @since 0.9.12 */ + public boolean isSigTypeAvailable(int code) { + SigType type = SigType.getByCode(code); + return type != null && type.isAvailable(); + } + /** @since 0.8.9 */ public boolean getDCC(int tunnel) { return getBooleanProperty(tunnel, I2PTunnelIRCClient.PROP_DCC); diff --git a/apps/i2ptunnel/jsp/editClient.jsp b/apps/i2ptunnel/jsp/editClient.jsp index 2b560173c8..b07c964acb 100644 --- a/apps/i2ptunnel/jsp/editClient.jsp +++ b/apps/i2ptunnel/jsp/editClient.jsp @@ -461,18 +461,24 @@ input.default { width: 1px; height: 1px; visibility: hidden; } class="tickbox" /> + <% if (editBean.isSigTypeAvailable(1)) { %>
class="tickbox" />
+ <% } + if (editBean.isSigTypeAvailable(2)) { %>
class="tickbox" />
+ <% } + if (editBean.isSigTypeAvailable(3)) { %>
class="tickbox" />
+ <% } // isAvailable %>
diff --git a/apps/i2ptunnel/jsp/editServer.jsp b/apps/i2ptunnel/jsp/editServer.jsp index 1a109b22d9..e0e8023884 100644 --- a/apps/i2ptunnel/jsp/editServer.jsp +++ b/apps/i2ptunnel/jsp/editServer.jsp @@ -563,18 +563,24 @@ input.default { width: 1px; height: 1px; visibility: hidden; } class="tickbox" />
+ <% if (editBean.isSigTypeAvailable(1)) { %>
class="tickbox" />
+ <% } + if (editBean.isSigTypeAvailable(2)) { %>
class="tickbox" />
+ <% } + if (editBean.isSigTypeAvailable(3)) { %>
class="tickbox" />
+ <% } // isAvailable %>
diff --git a/core/java/src/net/i2p/client/RequestLeaseSetMessageHandler.java b/core/java/src/net/i2p/client/RequestLeaseSetMessageHandler.java index 09f224efc0..662d50969d 100644 --- a/core/java/src/net/i2p/client/RequestLeaseSetMessageHandler.java +++ b/core/java/src/net/i2p/client/RequestLeaseSetMessageHandler.java @@ -9,6 +9,7 @@ package net.i2p.client; * */ +import java.security.GeneralSecurityException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -25,6 +26,7 @@ import net.i2p.data.PublicKey; import net.i2p.data.SessionKey; import net.i2p.data.SigningPrivateKey; import net.i2p.data.SigningPublicKey; +import net.i2p.data.SimpleDataStructure; import net.i2p.data.i2cp.I2CPMessage; import net.i2p.data.i2cp.RequestLeaseSetMessage; import net.i2p.util.Log; @@ -129,9 +131,16 @@ class RequestLeaseSetMessageHandler extends HandlerImpl { private final PrivateKey _privKey; private final SigningPublicKey _signingPubKey; private final SigningPrivateKey _signingPrivKey; + public LeaseInfo(Destination dest) { Object encKeys[] = KeyGenerator.getInstance().generatePKIKeypair(); - Object signKeys[] = KeyGenerator.getInstance().generateSigningKeypair(); + // must be same type as the Destination's signing key + SimpleDataStructure signKeys[]; + try { + signKeys = KeyGenerator.getInstance().generateSigningKeys(dest.getSigningPublicKey().getType()); + } catch (GeneralSecurityException gse) { + throw new IllegalStateException(gse); + } _pubKey = (PublicKey) encKeys[0]; _privKey = (PrivateKey) encKeys[1]; _signingPubKey = (SigningPublicKey) signKeys[0]; diff --git a/core/java/src/net/i2p/crypto/SigType.java b/core/java/src/net/i2p/crypto/SigType.java index c5e32f048d..2ce774c841 100644 --- a/core/java/src/net/i2p/crypto/SigType.java +++ b/core/java/src/net/i2p/crypto/SigType.java @@ -2,6 +2,7 @@ package net.i2p.crypto; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.security.Signature; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import java.util.HashMap; @@ -159,6 +160,24 @@ public enum SigType { } } + /** + * @since 0.9.12 + * @return true if supported in this JVM + */ + public boolean isAvailable() { + if (DSA_SHA1 == this) + return true; + try { + getParams(); + Signature.getInstance(getAlgorithmName()); + getDigestInstance(); + getHashInstance(); + } catch (Exception e) { + return false; + } + return true; + } + private static final Map BY_CODE = new HashMap(); static { diff --git a/core/java/src/net/i2p/data/LeaseSet.java b/core/java/src/net/i2p/data/LeaseSet.java index cf9b39deb2..6ea3051af8 100644 --- a/core/java/src/net/i2p/data/LeaseSet.java +++ b/core/java/src/net/i2p/data/LeaseSet.java @@ -137,12 +137,23 @@ public class LeaseSet extends DatabaseEntry { _encryptionKey = encryptionKey; } - /** @deprecated unused */ + /** + * The revocation key. + * @deprecated unused + */ public SigningPublicKey getSigningKey() { return _signingKey; } + /** + * The revocation key. Unused. + * Must be the same type as the Destination's SigningPublicKey. + * @throws IllegalArgumentException if different type + */ public void setSigningKey(SigningPublicKey key) { + if (key != null && _destination != null && + key.getType() != _destination.getSigningPublicKey().getType()) + throw new IllegalArgumentException("Signing key type mismatch"); _signingKey = key; } diff --git a/history.txt b/history.txt index 2b77c35371..c36f910836 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,12 @@ +2014-02-21 zzz + * Build: Add property for target version + * I2CP Client: Generate revocation key of same type as signing key + * i2ptunnel: Only offer SigType options that are available in the JVM + * LeaseSet: Add check for SigType mismatch + * RouterAddress: Restore storage of expiration and use in signature + calculation, broken in 0.9.3, in anticipation of using it someday + * SigType: Add isAvailable() + 2014-02-20 zzz * i2ptunnel: Add inproxy block option to HTTP server * Router: Allow null args to main() (broke Android) diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 7ca1a3ec2c..5a58b19bc2 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 10; + public final static long BUILD = 11; /** for example "-test" */ public final static String EXTRA = "";