Compare commits

...

5 Commits

3 changed files with 112 additions and 101 deletions

View File

@ -89,89 +89,82 @@ public class ConfigKeyringHandler extends FormHandler {
addFormError(_t("Requires hostname, destination, or blinded Base32"));
return;
}
// from BlindCache
List<Hash> clientBase32s = _context.netDbSegmentor().lookupClientBySigningPublicKey(spk);
// TODO: This updates all of the blind data for all clients, turning the blind cache into a shared context for the owner of an encrypted leaseSet.
// This is probably not ideal, with some social-engineering a service operator who owns an encrypted destination could associate 2 tunnels.
// How realistic is it? Maybe not very, but I don't like it. Still, this is better than nothing.
for (Hash clientBase32 : clientBase32s) {
BlindData bdold = _context.clientNetDb(clientBase32).getBlindData(spk);
if (bdold != null && d == null)
d = bdold.getDestination();
if (d != null && _context.clientManager().isLocal(d)) {
// don't bother translating
addFormError("Cannot add key for local destination. Enable encryption in the Hidden Services Manager.");
BlindData bdold = _context.netDb().getBlindData(spk);
if (bdold != null && d == null)
d = bdold.getDestination();
if (d != null && _context.clientManager().isLocal(d)) {
// don't bother translating
addFormError("Cannot add key for local destination. Enable encryption in the Hidden Services Manager.");
return;
}
SigType blindType;
if (bdin != null) {
blindType = bdin.getBlindedSigType();
} else if (bdold != null) {
blindType = bdold.getBlindedSigType();
} else {
blindType = Blinding.getDefaultBlindedType(spk.getType());
}
int atype;
PrivateKey pk;
if (_mode == 4 || _mode == 5) {
atype = BlindData.AUTH_PSK;
// use supplied pk
pk = new PrivateKey(EncType.ECIES_X25519, b);
} else if (_mode == 6 || _mode == 7) {
atype = BlindData.AUTH_DH;
// create new pk
b = new byte[32];
_context.random().nextBytes(b);
pk = new PrivateKey(EncType.ECIES_X25519, b);
} else {
// modes 2 and 3
atype = BlindData.AUTH_NONE;
pk = null;
}
if (_mode == 2 || _mode == 4 || _mode == 6)
_secret = null;
if (bdin != null) {
// more checks based on supplied b33
if (bdin.getSecretRequired() && _secret == null) {
addFormError(_t("Destination requires lookup password"));
return;
}
if (!bdin.getSecretRequired() && _secret != null) {
addFormError(_t("Destination does not require lookup password"));
return;
}
if (bdin.getAuthRequired() && pk == null) {
addFormError(_t("Destination requires encryption key"));
return;
}
if (!bdin.getAuthRequired() && pk != null) {
addFormError(_t("Destination does not require encryption key"));
return;
}
}
SigType blindType;
if (bdin != null) {
blindType = bdin.getBlindedSigType();
} else if (bdold != null) {
blindType = bdold.getBlindedSigType();
} else {
blindType = Blinding.getDefaultBlindedType(spk.getType());
}
int atype;
PrivateKey pk;
if (_mode == 4 || _mode == 5) {
atype = BlindData.AUTH_PSK;
// use supplied pk
pk = new PrivateKey(EncType.ECIES_X25519, b);
} else if (_mode == 6 || _mode == 7) {
atype = BlindData.AUTH_DH;
// create new pk
b = new byte[32];
_context.random().nextBytes(b);
pk = new PrivateKey(EncType.ECIES_X25519, b);
} else {
// modes 2 and 3
atype = BlindData.AUTH_NONE;
pk = null;
}
if (_mode == 2 || _mode == 4 || _mode == 6)
_secret = null;
if (bdin != null) {
// more checks based on supplied b33
if (bdin.getSecretRequired() && _secret == null) {
addFormError(_t("Destination requires lookup password"));
return;
}
if (!bdin.getSecretRequired() && _secret != null) {
addFormError(_t("Destination does not require lookup password"));
return;
}
if (bdin.getAuthRequired() && pk == null) {
addFormError(_t("Destination requires encryption key"));
return;
}
if (!bdin.getAuthRequired() && pk != null) {
addFormError(_t("Destination does not require encryption key"));
return;
}
}
// to BlindCache
BlindData bdout;
if (d != null) {
bdout = new BlindData(_context, d, blindType, _secret, atype, pk);
} else {
bdout = new BlindData(_context, spk, blindType, _secret, atype, pk);
}
if (bdold != null) {
if (_log.shouldDebug())
_log.debug("already cached: " + bdold);
}
try {
_context.clientNetDb(clientBase32).setBlindData(bdout);
addFormNotice(_t("Key for {0} added to keyring", bdout.toBase32()));
if (_mode == 6 || _mode == 7) {
addFormNotice(_t("Send key to server operator.") + ' ' + pk.toPublic().toBase64());
}
} catch (IllegalArgumentException iae) {
addFormError(_t("Invalid destination") + ": " + iae.getLocalizedMessage());
// to BlindCache
BlindData bdout;
if (d != null) {
bdout = new BlindData(_context, d, blindType, _secret, atype, pk);
} else {
bdout = new BlindData(_context, spk, blindType, _secret, atype, pk);
}
if (bdold != null) {
if (_log.shouldDebug())
_log.debug("already cached: " + bdold);
}
try {
_context.netDb().setBlindData(bdout);
addFormNotice(_t("Key for {0} added to keyring", bdout.toBase32()));
if (_mode == 6 || _mode == 7) {
addFormNotice(_t("Send key to server operator.") + ' ' + pk.toPublic().toBase64());
}
} catch (IllegalArgumentException iae) {
addFormError(_t("Invalid destination") + ": " + iae.getLocalizedMessage());
}
}
} else if (_action.equals(_t("Delete key")) && _revokes != null) {

View File

@ -104,7 +104,7 @@ public class ConfigKeyringHelper extends HelperBase {
}
// LS2
if (!local) {
List<BlindData> bdata = _context.netDbSegmentor().getLocalClientsBlindData();
List<BlindData> bdata = _context.netDb().getBlindData();
if (bdata.size() > 1)
Collections.sort(bdata, new BDComparator());
for (BlindData bd : bdata) {

View File

@ -180,12 +180,13 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
_peerSelector = createPeerSelector();
_publishingLeaseSets = new HashMap<Hash, RepublishLeaseSetJob>(8);
_activeRequests = new HashMap<Hash, SearchJob>(8);
if (!isMainDb())
if (!isMainDb()) {
_reseedChecker = null;
else
_blindCache = null;
} else {
_reseedChecker = new ReseedChecker(context);
_blindCache = new BlindCache(context);
_blindCache = new BlindCache(context);
}
_localKey = null;
if (_log.shouldLog(Log.DEBUG))
_log.debug("Created KademliaNetworkDatabaseFacade for id: " + dbid);
@ -223,6 +224,20 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
return _reseedChecker;
}
/**
* We still always use a single blind cache in the main Db(for now),
* see issue #421 on i2pgit.org/i2p-hackers/i2p.i2p for details.
* This checks if we're the main DB already and returns our blind
* cache if we are. If not, it looks up the main Db and gets it.
*
* @return
*/
protected BlindCache blindCache() {
if (isMainDb())
return _blindCache;
return _context.netDb().blindCache();
}
KBucketSet<Hash> getKBuckets() { return _kb; }
DataStore getDataStore() { return _ds; }
@ -269,7 +284,8 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
_exploreKeys.clear();
if (_negativeCache != null)
_negativeCache.clear();
_blindCache.shutdown();
if (isMainDb())
blindCache().shutdown();
}
public synchronized void restart() {
@ -280,7 +296,8 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
}
_ds.restart();
_exploreKeys.clear();
_blindCache.startup();
if (isMainDb())
blindCache().startup();
_initialized = true;
@ -370,7 +387,8 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
throw new RuntimeException("Unable to initialize netdb storage", ioe);
}
_negativeCache = new NegativeLookupCache(_context);
_blindCache.startup();
if (isMainDb())
blindCache().startup();
createHandlers();
@ -558,7 +576,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
*/
@Override
public BlindData getBlindData(SigningPublicKey spk) {
return _blindCache.getData(spk);
return blindCache().getData(spk);
}
/**
@ -569,7 +587,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
public void setBlindData(BlindData bd) {
if (_log.shouldWarn())
_log.warn("Adding to blind cache: " + bd);
_blindCache.addToCache(bd);
blindCache().addToCache(bd);
}
/**
@ -578,7 +596,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
*/
@Override
public List<BlindData> getBlindData() {
return _blindCache.getData();
return blindCache().getData();
}
/**
@ -589,7 +607,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
*/
@Override
public boolean removeBlindData(SigningPublicKey spk) {
return _blindCache.removeBlindData(spk);
return blindCache().removeBlindData(spk);
}
/**
@ -599,7 +617,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
*/
@Override
public void routingKeyChanged() {
_blindCache.rollover();
blindCache().rollover();
if (_log.shouldInfo())
_log.info("UTC rollover, blind cache updated");
}
@ -620,7 +638,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
if (ls.isCurrent(Router.CLOCK_FUDGE_FACTOR)) {
return rv;
} else {
key = _blindCache.getHash(key);
key = blindCache().getHash(key);
fail(key);
}
} else if (type == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
@ -676,7 +694,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
} else {
//if (_log.shouldLog(Log.DEBUG))
// _log.debug("leaseSet not found locally, running search");
key = _blindCache.getHash(key);
key = blindCache().getHash(key);
search(key, onFindJob, onFailedLookupJob, timeoutMs, true, fromLocalDest);
}
//if (_log.shouldLog(Log.DEBUG))
@ -693,7 +711,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
*/
public void lookupLeaseSetRemotely(Hash key, Hash fromLocalDest) {
if (!_initialized) return;
key = _blindCache.getHash(key);
key = blindCache().getHash(key);
if (isNegativeCached(key))
return;
search(key, null, null, 20*1000, true, fromLocalDest);
@ -710,7 +728,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
public void lookupLeaseSetRemotely(Hash key, Job onFindJob, Job onFailedLookupJob,
long timeoutMs, Hash fromLocalDest) {
if (!_initialized) return;
key = _blindCache.getHash(key);
key = blindCache().getHash(key);
if (isNegativeCached(key))
return;
search(key, onFindJob, onFailedLookupJob, timeoutMs, true, fromLocalDest);
@ -728,7 +746,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
if (ls.isCurrent(Router.CLOCK_FUDGE_FACTOR)) {
return ls;
} else {
key = _blindCache.getHash(key);
key = blindCache().getHash(key);
fail(key);
// this was an interesting key, so either refetch it or simply explore with it
_exploreKeys.add(key);
@ -764,7 +782,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
_log.info("Negative cached, not searching dest: " + key);
_context.jobQueue().addJob(onFinishedJob);
} else {
key = _blindCache.getHash(key);
key = blindCache().getHash(key);
search(key, onFinishedJob, onFinishedJob, timeoutMs, true, fromLocalDest);
}
}
@ -1120,7 +1138,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
// set dest or key before validate() calls verifySignature() which
// will do the decryption
encls = (EncryptedLeaseSet) leaseSet;
BlindData bd = _blindCache.getReverseData(leaseSet.getSigningKey());
BlindData bd = blindCache().getReverseData(leaseSet.getSigningKey());
if (bd != null) {
if (_log.shouldWarn())
_log.warn("Found blind data for encls: " + bd);
@ -1162,7 +1180,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
// recursion
Destination dest = decls.getDestination();
store(dest.getHash(), decls);
_blindCache.setBlinded(dest);
blindCache().setBlinded(dest);
}
} else if (type == DatabaseEntry.KEY_TYPE_LS2 || type == DatabaseEntry.KEY_TYPE_META_LS2) {
// if it came in via garlic
@ -1170,7 +1188,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
if (ls2.isBlindedWhenPublished()) {
Destination dest = leaseSet.getDestination();
if (dest != null)
_blindCache.setBlinded(dest, null, null);
blindCache().setBlinded(dest, null, null);
}
}