forked from I2P_Developers/i2p.i2p
i2ptunnel: Display encrypted b32
Blinding: Allow secret flag without attached secret
This commit is contained in:
@ -19,6 +19,7 @@ import net.i2p.I2PAppContext;
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.app.ClientAppManager;
|
||||
import net.i2p.app.Outproxy;
|
||||
import net.i2p.crypto.Blinding;
|
||||
import net.i2p.data.Certificate;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Destination;
|
||||
@ -552,6 +553,26 @@ public class IndexBean {
|
||||
return d.toBase32();
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Works even if tunnel is not running.
|
||||
* @return "{56 chars}.b32.i2p" or "" if not blinded
|
||||
* @since 0.9.40
|
||||
*/
|
||||
public String getEncryptedBase32(int tunnel) {
|
||||
Destination d = getDestination(tunnel);
|
||||
if (d != null) {
|
||||
int mode = _helper.getEncryptMode(tunnel);
|
||||
if (mode > 1) {
|
||||
try {
|
||||
String secret = _helper.getBlindedPassword(tunnel);
|
||||
boolean requireSecret = secret != null && secret.length() > 0;
|
||||
return Blinding.encode(_context, d.getSigningPublicKey(), requireSecret, false);
|
||||
} catch (RuntimeException re) {}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Works even if tunnel is not running.
|
||||
|
@ -505,10 +505,10 @@
|
||||
int curSigType = editBean.getSigType(curTunnel, tunnelType);
|
||||
if (curSigType == 7 || curSigType == 11) {
|
||||
%>
|
||||
<span class="multiOption"><label title="<%=intl._t("Prevents snooping by floodfills")%>"><input value="2" type="radio" name="encryptMode"<%=(curEncryptMode.equals("2") ? " checked=\"checked\"" : "")%> class="tickbox" />
|
||||
<span class="multiOption"><label title="<%=intl._t("Prevents server discovery by floodfills")%>"><input value="2" type="radio" name="encryptMode"<%=(curEncryptMode.equals("2") ? " checked=\"checked\"" : "")%> class="tickbox" />
|
||||
<%=intl._t("Blinded")%></label></span>
|
||||
<span class="multiOption"><label title="<%=intl._t("Only clients with the password will be able to connect")%>"><input value="3" type="radio" name="encryptMode"<%=(curEncryptMode.equals("3") ? " checked=\"checked\"" : "")%> class="tickbox" />
|
||||
<%=intl._t("Blinded with password")%></label></span>
|
||||
<%=intl._t("Blinded with lookup password")%></label></span>
|
||||
<%
|
||||
if (editBean.isAdvanced()) {
|
||||
// TODO, unimplemented
|
||||
@ -516,11 +516,11 @@
|
||||
<span class="multiOption"><label title="<%=intl._t("Only clients with the encryption key will be able to connect")%>"><input value="4" type="radio" name="encryptMode"<%=(curEncryptMode.equals("4") ? " checked=\"checked\"" : "")%> class="tickbox" />
|
||||
<%=intl._t("Blinded with shared key")%></label></span>
|
||||
<span class="multiOption"><label title="<%=intl._t("Only clients with the password and key will be able to connect")%>"><input value="5" type="radio" name="encryptMode"<%=(curEncryptMode.equals("5") ? " checked=\"checked\"" : "")%> class="tickbox" />
|
||||
<%=intl._t("Blinded with shared key and password")%></label></span>
|
||||
<%=intl._t("Blinded with lookup password and shared key")%></label></span>
|
||||
<span class="multiOption"><label title="<%=intl._t("Only clients with the encryption key will be able to connect")%>"><input value="6" type="radio" name="encryptMode"<%=(curEncryptMode.equals("6") ? " checked=\"checked\"" : "")%> class="tickbox" />
|
||||
<%=intl._t("Blinded with per-user key")%></label></span>
|
||||
<span class="multiOption"><label title="<%=intl._t("Only clients with the password and key will be able to connect")%>"><input value="7" type="radio" name="encryptMode"<%=(curEncryptMode.equals("7") ? " checked=\"checked\"" : "")%> class="tickbox" />
|
||||
<%=intl._t("Blinded with shared password and per-user key")%></label></span>
|
||||
<%=intl._t("Blinded with lookup password and per-user key")%></label></span>
|
||||
<%
|
||||
} // isAdvanced()
|
||||
} // curSigType
|
||||
@ -553,7 +553,7 @@
|
||||
%>
|
||||
<tr>
|
||||
<td>
|
||||
<b><%=intl._t("Blinded Password")%>:</b>
|
||||
<b><%=intl._t("Optional lookup password")%>:</b>
|
||||
<input type="password" name="nofilter_blindedPassword" title="<%=intl._t("Set password required to access this service")%>" value="<%=editBean.getBlindedPassword(curTunnel)%>" class="freetext password" />
|
||||
</td><td> </td>
|
||||
</tr>
|
||||
|
@ -197,15 +197,29 @@
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<%
|
||||
String encName = indexBean.getEncryptedBase32(curServer);
|
||||
if (encName != null && encName.length() > 0) {
|
||||
%>
|
||||
<tr>
|
||||
<td class="tunnelDestination" colspan="6">
|
||||
<span class="tunnelDestinationLabel"><b><%=intl._t("Encrypted")%>:</b></span>
|
||||
<%=encName%>
|
||||
</td>
|
||||
</tr>
|
||||
<%
|
||||
} // encName
|
||||
%>
|
||||
|
||||
<tr>
|
||||
<td class="tunnelDescription" colspan="6">
|
||||
<span class="tunnelDescriptionLabel"><b>Description:</b></span>
|
||||
<span class="tunnelDestinationLabel"><b><%=intl._t("Description")%>:</b></span>
|
||||
<%=indexBean.getTunnelDescription(curServer)%>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<%
|
||||
}
|
||||
} // for loop
|
||||
%>
|
||||
|
||||
<tr>
|
||||
|
@ -33,6 +33,10 @@ public final class Blinding {
|
||||
private static final String INFO = "i2pblinding1";
|
||||
private static final byte[] INFO_ALPHA = DataHelper.getASCII("I2PGenerateAlpha");
|
||||
|
||||
private static final byte FLAG_TWOBYTE = 0x01;
|
||||
private static final byte FLAG_SECRET = 0x02;
|
||||
private static final byte FLAG_AUTH = 0x04;
|
||||
|
||||
// following copied from RouterKeyGenerator
|
||||
private static final String FORMAT = "yyyyMMdd";
|
||||
private static final int LENGTH = FORMAT.length();
|
||||
@ -233,9 +237,9 @@ public final class Blinding {
|
||||
int flag = b[0] & 0xff;
|
||||
if ((flag & 0xf8) != 0)
|
||||
throw new IllegalArgumentException("Corrupt b32 or unsupported options");
|
||||
if ((flag & 0x01) != 0)
|
||||
if ((flag & FLAG_TWOBYTE) != 0)
|
||||
throw new IllegalArgumentException("Two byte sig types unsupported");
|
||||
if ((flag & 0x04) != 0)
|
||||
if ((flag & FLAG_AUTH) != 0)
|
||||
throw new IllegalArgumentException("Per-client auth unsupported");
|
||||
// TODO two-byte sigtypes
|
||||
int st1 = b[1] & 0xff;
|
||||
@ -258,13 +262,16 @@ public final class Blinding {
|
||||
System.arraycopy(b, 3, spkData, 0, spkLen);
|
||||
SigningPublicKey spk = new SigningPublicKey(sigt1, spkData);
|
||||
String secret;
|
||||
if ((flag & 0x02) != 0) {
|
||||
if (4 + spkLen > b.length)
|
||||
throw new IllegalArgumentException("No secret data");
|
||||
int secLen = b[3 + spkLen] & 0xff;
|
||||
if (4 + spkLen + secLen != b.length)
|
||||
throw new IllegalArgumentException("Bad b32 length");
|
||||
secret = DataHelper.getUTF8(b, 4 + spkLen, secLen);
|
||||
if ((flag & FLAG_SECRET) != 0) {
|
||||
if (4 + spkLen > b.length) {
|
||||
//throw new IllegalArgumentException("No secret data");
|
||||
secret = null;
|
||||
} else {
|
||||
int secLen = b[3 + spkLen] & 0xff;
|
||||
if (4 + spkLen + secLen != b.length)
|
||||
throw new IllegalArgumentException("Bad b32 length");
|
||||
secret = DataHelper.getUTF8(b, 4 + spkLen, secLen);
|
||||
}
|
||||
} else if (3 + spkLen != b.length) {
|
||||
throw new IllegalArgumentException("b32 too long");
|
||||
} else {
|
||||
@ -274,6 +281,33 @@ public final class Blinding {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a public key as a new-format b32 address.
|
||||
* PRELIMINARY - Subject to change - see proposal 149
|
||||
*
|
||||
* @return (56 chars).b32.i2p
|
||||
* @throws IllegalArgumentException on bad inputs
|
||||
* @throws UnsupportedOperationException unless supported SigTypes
|
||||
* @since 0.9.40
|
||||
*/
|
||||
public static String encode(I2PAppContext ctx, SigningPublicKey key) throws RuntimeException {
|
||||
return encode(ctx, key, false, false, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a public key as a new-format b32 address.
|
||||
* PRELIMINARY - Subject to change - see proposal 149
|
||||
*
|
||||
* @return (56 chars).b32.i2p
|
||||
* @throws IllegalArgumentException on bad inputs
|
||||
* @throws UnsupportedOperationException unless supported SigTypes
|
||||
* @since 0.9.40
|
||||
*/
|
||||
public static String encode(I2PAppContext ctx, SigningPublicKey key,
|
||||
boolean requireSecret, boolean requireAuth) throws RuntimeException {
|
||||
return encode(ctx, key, requireSecret, requireAuth, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a public key as a new-format b32 address.
|
||||
* PRELIMINARY - Subject to change - see proposal 149
|
||||
@ -284,7 +318,9 @@ public final class Blinding {
|
||||
* @throws UnsupportedOperationException unless supported SigTypes
|
||||
* @since 0.9.40
|
||||
*/
|
||||
public static String encode(I2PAppContext ctx, SigningPublicKey key, String secret) throws RuntimeException {
|
||||
public static String encode(I2PAppContext ctx, SigningPublicKey key,
|
||||
boolean requireSecret, boolean requireAuth,
|
||||
String secret) throws RuntimeException {
|
||||
SigType type = key.getType();
|
||||
if (type != TYPE && type != TYPER)
|
||||
throw new UnsupportedOperationException();
|
||||
@ -303,8 +339,10 @@ public final class Blinding {
|
||||
crc.update(b, 3, b.length - 3);
|
||||
long check = crc.getValue();
|
||||
// TODO two-byte sigtypes
|
||||
if (slen > 0)
|
||||
b[0] = 0x02;
|
||||
if (slen > 0 || requireSecret)
|
||||
b[0] = FLAG_SECRET;
|
||||
if (requireAuth)
|
||||
b[0] |= FLAG_AUTH;
|
||||
b[1] = (byte) (type.getCode() & 0xff);
|
||||
b[2] = (byte) (TYPER.getCode() & 0xff);
|
||||
b[0] ^= (byte) check;
|
||||
|
Reference in New Issue
Block a user