Changeset 82eea0a for router


Ignore:
Timestamp:
Mar 27, 2019 12:51:10 PM (13 months ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
ea127d3
Parents:
14492d72
Message:

NetDB: Cache blinding data for lookups and decryption (proposal #123)

Location:
router/java/src/net/i2p/router
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • router/java/src/net/i2p/router/NetworkDatabaseFacade.java

    r14492d72 r82eea0a  
    1414import java.util.Set;
    1515
     16import net.i2p.data.BlindData;
    1617import net.i2p.data.DatabaseEntry;
    1718import net.i2p.data.Destination;
    1819import net.i2p.data.Hash;
    1920import net.i2p.data.LeaseSet;
     21import net.i2p.data.SigningPublicKey;
    2022import net.i2p.data.router.RouterInfo;
    2123import net.i2p.router.networkdb.reseed.ReseedChecker;
     
    162164     */
    163165    public boolean isNegativeCachedForever(Hash key) { return false; }
     166   
     167    /**
     168     *  @param spk unblinded key
     169     *  @return BlindData or null
     170     *  @since 0.9.40
     171     */
     172    public BlindData getBlindData(SigningPublicKey spk) {
     173        return null;
     174    }
     175   
     176    /**
     177     *  @param bd new BlindData to put in the cache
     178     *  @since 0.9.40
     179     */
     180    public void setBlindData(BlindData bd) {}
    164181}
  • router/java/src/net/i2p/router/RouterVersion.java

    r14492d72 r82eea0a  
    1919    public final static String ID = "Monotone";
    2020    public final static String VERSION = CoreVersion.VERSION;
    21     public final static long BUILD = 1;
     21    public final static long BUILD = 2;
    2222
    2323    /** for example "-test" */
  • router/java/src/net/i2p/router/client/LookupDestJob.java

    r14492d72 r82eea0a  
    1010import net.i2p.data.Base32;
    1111import net.i2p.data.BlindData;
     12import net.i2p.data.DatabaseEntry;
    1213import net.i2p.data.Destination;
     14import net.i2p.data.EncryptedLeaseSet;
    1315import net.i2p.data.Hash;
    1416import net.i2p.data.LeaseSet;
     17import net.i2p.data.SigningPublicKey;
    1518import net.i2p.data.i2cp.DestReplyMessage;
    1619import net.i2p.data.i2cp.HostReplyMessage;
     
    3538    private final SessionId _sessID;
    3639    private final Hash _fromLocalDest;
     40    private final BlindData _blindData;
    3741
    3842    private static final long DEFAULT_TIMEOUT = 15*1000;
     
    7074        _sessID = sessID;
    7175        _fromLocalDest = fromLocalDest;
     76        BlindData bd = null;
    7277        if (name != null && name.length() >= 60) {
    7378            // convert a b32 lookup to a hash lookup
     
    8388                    } else if (b.length >= 35) {
    8489                        // encrypted LS2
     90                        // lookup the blinded hash
    8591                        try {
    86                             BlindData bd = Blinding.decode(context, b);
     92                            bd = Blinding.decode(context, b);
     93                            SigningPublicKey spk = bd.getUnblindedPubKey();
     94                            BlindData bd2 = getContext().netDb().getBlindData(spk);
     95                            if (bd2 != null) {
     96                                bd = bd2;
     97                            } else {
     98                                getContext().netDb().setBlindData(bd);
     99                            }
    87100                            h = bd.getBlindedHash();
    88101                            if (_log.shouldDebug())
     
    100113        _hash = h;
    101114        _name = name;
     115        _blindData = bd;
    102116    }
    103117   
     
    108122
    109123    public void runJob() {
     124        if (_blindData != null) {
     125            Destination d = _blindData.getDestination();
     126            if (d != null) {
     127                if (_log.shouldDebug())
     128                    _log.debug("Found cached b33 lookup " + _name + " to " + d);
     129                returnDest(d);
     130                return;
     131            }
     132        }
    110133        if (_name != null) {
    111134            // inline, ignore timeout
     
    122145        } else {
    123146            DoneJob done = new DoneJob(getContext());
     147            // TODO tell router this is an encrypted lookup, skip 38 or earlier ffs?
    124148            getContext().netDb().lookupDestination(_hash, done, _timeout, _fromLocalDest);
    125149        }
     
    133157        public void runJob() {
    134158            Destination dest = getContext().netDb().lookupDestinationLocally(_hash);
     159            if (dest == null && _blindData != null) {
     160                // TODO store and lookup original hash instead
     161                LeaseSet ls = getContext().netDb().lookupLeaseSetLocally(_hash);
     162                if (ls != null && ls.getType() == DatabaseEntry.KEY_TYPE_ENCRYPTED_LS2) {
     163                    // already decrypted
     164                    EncryptedLeaseSet encls = (EncryptedLeaseSet) ls;
     165                    LeaseSet decls = encls.getDecryptedLeaseSet();
     166                    if (decls != null) {
     167                        dest = decls.getDestination();
     168                    }
     169                }
     170            }
    135171            if (dest != null) {
    136172                if (_log.shouldDebug())
  • router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java

    r14492d72 r82eea0a  
    2222import net.i2p.crypto.SigAlgo;
    2323import net.i2p.crypto.SigType;
     24import net.i2p.data.BlindData;
    2425import net.i2p.data.Certificate;
    2526import net.i2p.data.DatabaseEntry;
     
    2728import net.i2p.data.DataHelper;
    2829import net.i2p.data.Destination;
     30import net.i2p.data.EncryptedLeaseSet;
    2931import net.i2p.data.Hash;
    3032import net.i2p.data.KeyCertificate;
    3133import net.i2p.data.LeaseSet;
    3234import net.i2p.data.LeaseSet2;
     35import net.i2p.data.SigningPublicKey;
    3336import net.i2p.data.i2np.DatabaseLookupMessage;
    3437import net.i2p.data.i2np.DatabaseStoreMessage;
     
    7477    private NegativeLookupCache _negativeCache;
    7578    protected final int _networkID;
     79    private final BlindCache _blindCache;
    7680
    7781    /**
     
    172176        _activeRequests = new HashMap<Hash, SearchJob>(8);
    173177        _reseedChecker = new ReseedChecker(context);
     178        _blindCache = new BlindCache(context);
    174179        context.statManager().createRateStat("netDb.lookupDeferred", "how many lookups are deferred?", "NetworkDatabase", new long[] { 60*60*1000 });
    175180        context.statManager().createRateStat("netDb.exploreKeySet", "how many keys are queued for exploration?", "NetworkDatabase", new long[] { 60*60*1000 });
     
    247252        _exploreKeys.clear(); // hope this doesn't cause an explosion, it shouldn't.
    248253        // _exploreKeys = null;
    249         _negativeCache.clear();
     254        if (_negativeCache != null)
     255            _negativeCache.clear();
     256        _blindCache.shutdown();
    250257    }
    251258   
     
    258265        _ds.restart();
    259266        _exploreKeys.clear();
     267        _blindCache.startup();
    260268
    261269        _initialized = true;
     
    288296        _dbDir = dbDir;
    289297        _negativeCache = new NegativeLookupCache(_context);
     298        _blindCache.startup();
    290299       
    291300        createHandlers();
     
    465474   
    466475    /**
     476     *  @param spk unblinded key
     477     *  @return BlindData or null
     478     *  @since 0.9.40
     479     */
     480    @Override
     481    public BlindData getBlindData(SigningPublicKey spk) {
     482        return _blindCache.getData(spk);
     483    }
     484   
     485    /**
     486     *  @param bd new BlindData to put in the cache
     487     *  @since 0.9.40
     488     */
     489    @Override
     490    public void setBlindData(BlindData bd) {
     491        if (_log.shouldWarn())
     492            _log.warn("Adding to blind cache: " + bd);
     493        _blindCache.addToCache(bd);
     494    }
     495   
     496    /**
    467497     *  @return RouterInfo, LeaseSet, or null, validated
    468498     *  @since 0.8.3
     
    477507        if (DatabaseEntry.isLeaseSet(type)) {
    478508            LeaseSet ls = (LeaseSet)rv;
    479             if (ls.isCurrent(Router.CLOCK_FUDGE_FACTOR))
     509            if (ls.isCurrent(Router.CLOCK_FUDGE_FACTOR)) {
    480510                return rv;
    481             else
     511            } else {
     512                key = _blindCache.getHash(key);
    482513                fail(key);
     514            }
    483515        } else if (type == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
    484516            try {
     
    534566            //if (_log.shouldLog(Log.DEBUG))
    535567            //    _log.debug("leaseSet not found locally, running search");
     568            key = _blindCache.getHash(key);
    536569            search(key, onFindJob, onFailedLookupJob, timeoutMs, true, fromLocalDest);
    537570        }
     
    550583    public void lookupLeaseSetRemotely(Hash key, Hash fromLocalDest) {
    551584        if (!_initialized) return;
     585        key = _blindCache.getHash(key);
    552586        search(key, null, null, 20*1000, true, fromLocalDest);
    553587    }
     
    565599                    return ls;
    566600                } else {
     601                    key = _blindCache.getHash(key);
    567602                    fail(key);
    568603                    // this was an interesting key, so either refetch it or simply explore with it
     
    600635            _context.jobQueue().addJob(onFinishedJob);
    601636        } else {
     637            key = _blindCache.getHash(key);
    602638            search(key, onFinishedJob, onFinishedJob, timeoutMs, true, fromLocalDest);
    603639        }
     
    893929            throw new IllegalArgumentException("LS Hash collision");
    894930
     931        EncryptedLeaseSet encls = null;
     932        if (leaseSet.getType() == DatabaseEntry.KEY_TYPE_ENCRYPTED_LS2) {
     933            // set dest or key before validate() calls verifySignature() which
     934            // will do the decryption
     935            BlindData bd = _blindCache.getReverseData(leaseSet.getSigningKey());
     936            if (bd != null) {
     937                if (_log.shouldWarn())
     938                    _log.warn("Found blind data for encls: " + bd);
     939                encls = (EncryptedLeaseSet) leaseSet;
     940                Destination dest = bd.getDestination();
     941                if (dest != null) {
     942                    encls.setDestination(dest);
     943                } else {
     944                    encls.setSigningKey(bd.getUnblindedPubKey());
     945                }
     946            } else {
     947                if (_log.shouldWarn())
     948                    _log.warn("No blind data found for encls: " + encls);
     949            }
     950        }
     951
     952
    895953        String err = validate(key, leaseSet);
    896954        if (err != null)
     
    899957        _ds.put(key, leaseSet);
    900958       
     959        if (encls != null) {
     960            // we now have decrypted it, store it as well
     961            LeaseSet decls = encls.getDecryptedLeaseSet();
     962            if (decls != null) {
     963                if (_log.shouldWarn())
     964                    _log.warn("Successfully decrypted encls: " + decls);
     965                // recursion
     966                Destination dest = decls.getDestination();
     967                store(dest.getHash(), decls);
     968                _blindCache.setBlinded(dest);
     969            }
     970        }
     971
    901972        // Iterate through the old failure / success count, copying over the old
    902973        // values (if any tunnels overlap between leaseSets).  no need to be
Note: See TracChangeset for help on using the changeset viewer.