i2ptunnel: Encrypt keys in forms

This commit is contained in:
zzz
2020-05-12 12:50:35 +00:00
parent e77c3f23d3
commit 13cfdf0d5a
3 changed files with 84 additions and 4 deletions

View File

@@ -294,19 +294,23 @@ public class EditBean extends IndexBean {
* @since 0.9.18
*/
public String getKey1(int tunnel) {
return _helper.getInboundRandomKey(tunnel);
String v = _helper.getInboundRandomKey(tunnel);
return encrypt(tunnel, "inbound.randomKey", v);
}
public String getKey2(int tunnel) {
return _helper.getOutboundRandomKey(tunnel);
String v = _helper.getOutboundRandomKey(tunnel);
return encrypt(tunnel, "outbound.randomKey", v);
}
public String getKey3(int tunnel) {
return _helper.getLeaseSetSigningPrivateKey(tunnel);
String v = _helper.getLeaseSetSigningPrivateKey(tunnel);
return encrypt(tunnel, "i2cp.leaseSetSigningPrivateKey", v);
}
public String getKey4(int tunnel) {
return _helper.getLeaseSetPrivateKey(tunnel);
String v = _helper.getLeaseSetPrivateKey(tunnel);
return encrypt(tunnel, "i2cp.leaseSetPrivateKey", v);
}
/** @since 0.8.9 */

View File

@@ -11,14 +11,17 @@ package net.i2p.i2ptunnel.web;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.app.ClientAppManager;
import net.i2p.app.Outproxy;
import net.i2p.crypto.ChaCha20;
import net.i2p.crypto.Blinding;
import net.i2p.data.Base64;
import net.i2p.data.Certificate;
@@ -78,6 +81,7 @@ public class IndexBean {
/** store nonces in a static FIFO instead of in System Properties @since 0.8.1 */
private static final List<String> _nonces = new ArrayList<String>(MAX_NONCES + 1);
private static final UIMessages _messages = new UIMessages(100);
private static final Map<Integer, SessionKey> _formKeys = new HashMap<Integer, SessionKey>();
private static final String PROP_THEME_NAME = "routerconsole.theme";
private static final String DEFAULT_THEME = "light";
@@ -1252,21 +1256,92 @@ public class IndexBean {
* @since 0.9.18
*/
public void setKey1(String s) {
s = decrypt("inbound.randomKey", s);
_config.setInboundRandomKey(s);
}
public void setKey2(String s) {
s = decrypt("outbound.randomKey", s);
_config.setOutboundRandomKey(s);
}
public void setKey3(String s) {
s = decrypt("i2cp.leaseSetSigningPrivateKey", s);
_config.setLeaseSetSigningPrivateKey(s);
}
public void setKey4(String s) {
s = decrypt("i2cp.leaseSetPrivateKey", s);
_config.setLeaseSetPrivateKey(s);
}
/**
* Decrypt a property using an in-memory key, for
* interaction with the UI only, using ChaCha20.
* IV is SHA256(k).
*
* These are transient keys by design, but are persisted
* to hide restarts. They are hidden inputs in the edit form.
* Storage in config files is not encrypted.
*
* @param k non-null
* @param v Base64, or empty, or null
* @since 0.9.46
*/
private String decrypt(String k, String v) {
if (v == null || v.length() <= 0)
return v;
byte[] enc = Base64.decode(v);
if (enc == null)
return null;
SessionKey key;
synchronized(_formKeys) {
key = _formKeys.get(Integer.valueOf(_tunnel));
}
if (key == null)
return null;
byte[] kb = DataHelper.getUTF8(k);
byte[] iv = new byte[32];
_context.sha().calculateHash(kb, 0, kb.length, iv, 0);
ChaCha20.decrypt(key.getData(), iv, enc, 0, enc, 0, enc.length);
return DataHelper.getUTF8(enc);
}
/**
* Encrypt a property using an in-memory key, for
* interaction with the UI only, using ChaCha20.
* IV is SHA256(k).
*
* These are transient keys by design, but are persisted
* to hide restarts. They are hidden inputs in the edit form.
* Storage in config files is not encrypted.
*
* @param k non-null
* @param v may be empty or null
* @return Base64, or empty, or null
* @since 0.9.46
*/
protected String encrypt(int tunnel, String k, String v) {
if (v == null || v.length() <= 0)
return v;
byte[] dec = DataHelper.getUTF8(v);
SessionKey key;
synchronized(_formKeys) {
key = _formKeys.get(Integer.valueOf(tunnel));
if (key == null) {
byte[] keyb = new byte[32];
_context.random().nextBytes(keyb);
key = new SessionKey(keyb);
_formKeys.put(Integer.valueOf(tunnel), key);
}
}
byte[] kb = DataHelper.getUTF8(k);
byte[] iv = new byte[32];
_context.sha().calculateHash(kb, 0, kb.length, iv, 0);
ChaCha20.encrypt(key.getData(), iv, dec, 0, dec, 0, dec.length);
return Base64.encode(dec);
}
/** Modify or create a destination */
private String modifyDestination() {
String privKeyFile = _config.getPrivKeyFile();

View File

@@ -5,6 +5,7 @@
%><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<jsp:useBean class="net.i2p.i2ptunnel.web.IndexBean" id="indexBean" scope="request" />
<jsp:setProperty name="indexBean" property="tunnel" /><%-- must be set before key1-4 --%>
<jsp:setProperty name="indexBean" property="*" />
<jsp:useBean class="net.i2p.i2ptunnel.ui.Messages" id="intl" scope="request" />
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">