* I2CP Client: Generate revocation key of same type as signing key

* i2ptunnel: Only offer Sig options that are available in the JVM
 * LeaseSet: Add check for SigTYpe mismatch
 * SigType: Add isAvailable()
This commit is contained in:
zzz
2014-02-21 17:47:30 +00:00
parent 3102970540
commit 18b4a2427b
8 changed files with 70 additions and 3 deletions

View File

@ -15,6 +15,7 @@ import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import net.i2p.client.I2PClient; import net.i2p.client.I2PClient;
import net.i2p.crypto.SigType;
import net.i2p.data.Base64; import net.i2p.data.Base64;
import net.i2p.data.Destination; import net.i2p.data.Destination;
import net.i2p.data.PrivateKeyFile; import net.i2p.data.PrivateKeyFile;
@ -183,6 +184,12 @@ public class EditBean extends IndexBean {
return getProperty(tunnel, I2PClient.PROP_SIGTYPE, 0); 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 */ /** @since 0.8.9 */
public boolean getDCC(int tunnel) { public boolean getDCC(int tunnel) {
return getBooleanProperty(tunnel, I2PTunnelIRCClient.PROP_DCC); return getBooleanProperty(tunnel, I2PTunnelIRCClient.PROP_DCC);

View File

@ -461,18 +461,24 @@ input.default { width: 1px; height: 1px; visibility: hidden; }
<label>DSA-SHA1</label> <label>DSA-SHA1</label>
<input value="0" type="radio" id="startOnLoad" name="sigType" title="Default"<%=(editBean.getSigType(curTunnel)==0 ? " checked=\"checked\"" : "")%> class="tickbox" /> <input value="0" type="radio" id="startOnLoad" name="sigType" title="Default"<%=(editBean.getSigType(curTunnel)==0 ? " checked=\"checked\"" : "")%> class="tickbox" />
</div> </div>
<% if (editBean.isSigTypeAvailable(1)) { %>
<div id="portField" class="rowItem"> <div id="portField" class="rowItem">
<label>ECDSA-P256</label> <label>ECDSA-P256</label>
<input value="1" type="radio" id="startOnLoad" name="sigType" title="Advanced users only"<%=(editBean.getSigType(curTunnel)==1 ? " checked=\"checked\"" : "")%> class="tickbox" /> <input value="1" type="radio" id="startOnLoad" name="sigType" title="Advanced users only"<%=(editBean.getSigType(curTunnel)==1 ? " checked=\"checked\"" : "")%> class="tickbox" />
</div> </div>
<% }
if (editBean.isSigTypeAvailable(2)) { %>
<div id="portField" class="rowItem"> <div id="portField" class="rowItem">
<label>ECDSA-P384</label> <label>ECDSA-P384</label>
<input value="2" type="radio" id="startOnLoad" name="sigType" title="Advanced users only"<%=(editBean.getSigType(curTunnel)==2 ? " checked=\"checked\"" : "")%> class="tickbox" /> <input value="2" type="radio" id="startOnLoad" name="sigType" title="Advanced users only"<%=(editBean.getSigType(curTunnel)==2 ? " checked=\"checked\"" : "")%> class="tickbox" />
</div> </div>
<% }
if (editBean.isSigTypeAvailable(3)) { %>
<div id="portField" class="rowItem"> <div id="portField" class="rowItem">
<label>ECDSA-P521</label> <label>ECDSA-P521</label>
<input value="3" type="radio" id="startOnLoad" name="sigType" title="Advanced users only"<%=(editBean.getSigType(curTunnel)==3 ? " checked=\"checked\"" : "")%> class="tickbox" /> <input value="3" type="radio" id="startOnLoad" name="sigType" title="Advanced users only"<%=(editBean.getSigType(curTunnel)==3 ? " checked=\"checked\"" : "")%> class="tickbox" />
</div> </div>
<% } // isAvailable %>
</div> </div>
<div class="subdivider"> <div class="subdivider">

View File

@ -563,18 +563,24 @@ input.default { width: 1px; height: 1px; visibility: hidden; }
<label>DSA-SHA1</label> <label>DSA-SHA1</label>
<input value="0" type="radio" id="startOnLoad" name="sigType" title="Default"<%=(editBean.getSigType(curTunnel)==0 ? " checked=\"checked\"" : "")%> class="tickbox" /> <input value="0" type="radio" id="startOnLoad" name="sigType" title="Default"<%=(editBean.getSigType(curTunnel)==0 ? " checked=\"checked\"" : "")%> class="tickbox" />
</div> </div>
<% if (editBean.isSigTypeAvailable(1)) { %>
<div id="portField" class="rowItem"> <div id="portField" class="rowItem">
<label>ECDSA-P256</label> <label>ECDSA-P256</label>
<input value="1" type="radio" id="startOnLoad" name="sigType" title="Advanced users only"<%=(editBean.getSigType(curTunnel)==1 ? " checked=\"checked\"" : "")%> class="tickbox" /> <input value="1" type="radio" id="startOnLoad" name="sigType" title="Advanced users only"<%=(editBean.getSigType(curTunnel)==1 ? " checked=\"checked\"" : "")%> class="tickbox" />
</div> </div>
<% }
if (editBean.isSigTypeAvailable(2)) { %>
<div id="portField" class="rowItem"> <div id="portField" class="rowItem">
<label>ECDSA-P384</label> <label>ECDSA-P384</label>
<input value="2" type="radio" id="startOnLoad" name="sigType" title="Advanced users only"<%=(editBean.getSigType(curTunnel)==2 ? " checked=\"checked\"" : "")%> class="tickbox" /> <input value="2" type="radio" id="startOnLoad" name="sigType" title="Advanced users only"<%=(editBean.getSigType(curTunnel)==2 ? " checked=\"checked\"" : "")%> class="tickbox" />
</div> </div>
<% }
if (editBean.isSigTypeAvailable(3)) { %>
<div id="portField" class="rowItem"> <div id="portField" class="rowItem">
<label>ECDSA-P521</label> <label>ECDSA-P521</label>
<input value="3" type="radio" id="startOnLoad" name="sigType" title="Advanced users only"<%=(editBean.getSigType(curTunnel)==3 ? " checked=\"checked\"" : "")%> class="tickbox" /> <input value="3" type="radio" id="startOnLoad" name="sigType" title="Advanced users only"<%=(editBean.getSigType(curTunnel)==3 ? " checked=\"checked\"" : "")%> class="tickbox" />
</div> </div>
<% } // isAvailable %>
</div> </div>
<div class="subdivider"> <div class="subdivider">

View File

@ -9,6 +9,7 @@ package net.i2p.client;
* *
*/ */
import java.security.GeneralSecurityException;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -25,6 +26,7 @@ import net.i2p.data.PublicKey;
import net.i2p.data.SessionKey; import net.i2p.data.SessionKey;
import net.i2p.data.SigningPrivateKey; import net.i2p.data.SigningPrivateKey;
import net.i2p.data.SigningPublicKey; import net.i2p.data.SigningPublicKey;
import net.i2p.data.SimpleDataStructure;
import net.i2p.data.i2cp.I2CPMessage; import net.i2p.data.i2cp.I2CPMessage;
import net.i2p.data.i2cp.RequestLeaseSetMessage; import net.i2p.data.i2cp.RequestLeaseSetMessage;
import net.i2p.util.Log; import net.i2p.util.Log;
@ -129,9 +131,16 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
private final PrivateKey _privKey; private final PrivateKey _privKey;
private final SigningPublicKey _signingPubKey; private final SigningPublicKey _signingPubKey;
private final SigningPrivateKey _signingPrivKey; private final SigningPrivateKey _signingPrivKey;
public LeaseInfo(Destination dest) { public LeaseInfo(Destination dest) {
Object encKeys[] = KeyGenerator.getInstance().generatePKIKeypair(); 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]; _pubKey = (PublicKey) encKeys[0];
_privKey = (PrivateKey) encKeys[1]; _privKey = (PrivateKey) encKeys[1];
_signingPubKey = (SigningPublicKey) signKeys[0]; _signingPubKey = (SigningPublicKey) signKeys[0];

View File

@ -2,6 +2,7 @@ package net.i2p.crypto;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.Signature;
import java.security.spec.AlgorithmParameterSpec; import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException; import java.security.spec.InvalidParameterSpecException;
import java.util.HashMap; 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<Integer, SigType> BY_CODE = new HashMap<Integer, SigType>(); private static final Map<Integer, SigType> BY_CODE = new HashMap<Integer, SigType>();
static { static {

View File

@ -137,12 +137,23 @@ public class LeaseSet extends DatabaseEntry {
_encryptionKey = encryptionKey; _encryptionKey = encryptionKey;
} }
/** @deprecated unused */ /**
* The revocation key.
* @deprecated unused
*/
public SigningPublicKey getSigningKey() { public SigningPublicKey getSigningKey() {
return _signingKey; 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) { public void setSigningKey(SigningPublicKey key) {
if (key != null && _destination != null &&
key.getType() != _destination.getSigningPublicKey().getType())
throw new IllegalArgumentException("Signing key type mismatch");
_signingKey = key; _signingKey = key;
} }

View File

@ -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 2014-02-20 zzz
* i2ptunnel: Add inproxy block option to HTTP server * i2ptunnel: Add inproxy block option to HTTP server
* Router: Allow null args to main() (broke Android) * Router: Allow null args to main() (broke Android)

View File

@ -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 = 10; public final static long BUILD = 11;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = ""; public final static String EXTRA = "";