Search in sources :

Example 26 with SigType

use of net.i2p.crypto.SigType in project i2p.i2p by i2p.

the class CreateRouterInfoJob method getSigTypeConfig.

/**
 *  The configured SigType to expect on read-in
 *  @since 0.9.16
 */
public static SigType getSigTypeConfig(RouterContext ctx) {
    SigType cstype = DEFAULT_SIGTYPE;
    String sstype = ctx.getProperty(PROP_ROUTER_SIGTYPE);
    if (sstype != null) {
        SigType ntype = SigType.parseSigType(sstype);
        if (ntype != null)
            cstype = ntype;
    }
    // fallback?
    if (cstype != SigType.DSA_SHA1 && !cstype.isAvailable())
        cstype = SigType.DSA_SHA1;
    return cstype;
}
Also used : SigType(net.i2p.crypto.SigType)

Example 27 with SigType

use of net.i2p.crypto.SigType in project i2p.i2p by i2p.

the class LoadRouterInfoJob method loadRouterInfo.

/**
 *  Loads router.info and either router.keys.dat or router.keys.
 *
 *  See CreateRouterInfoJob for file formats
 */
private void loadRouterInfo() {
    RouterInfo info = null;
    File rif = new File(getContext().getRouterDir(), CreateRouterInfoJob.INFO_FILENAME);
    boolean infoExists = rif.exists();
    File rkf = new File(getContext().getRouterDir(), CreateRouterInfoJob.KEYS_FILENAME);
    boolean keysExist = rkf.exists();
    File rkf2 = new File(getContext().getRouterDir(), CreateRouterInfoJob.KEYS2_FILENAME);
    boolean keys2Exist = rkf2.exists();
    InputStream fis1 = null;
    try {
        // so pretend the RI isn't there if there is no keyfile
        if (infoExists && (keys2Exist || keysExist)) {
            fis1 = new BufferedInputStream(new FileInputStream(rif));
            info = new RouterInfo();
            info.readBytes(fis1);
            // Catch this here before it all gets worse
            if (!info.isValid())
                throw new DataFormatException("Our RouterInfo has a bad signature");
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Reading in routerInfo from " + rif.getAbsolutePath() + " and it has " + info.getAddresses().size() + " addresses");
            // don't reuse if family name changed
            if (DataHelper.eq(info.getOption(FamilyKeyCrypto.OPT_NAME), getContext().getProperty(FamilyKeyCrypto.PROP_FAMILY_NAME))) {
                _us = info;
            } else {
                _log.logAlways(Log.WARN, "NetDb family name changed");
            }
        }
        if (keys2Exist || keysExist) {
            KeyData kd = readKeyData(rkf, rkf2);
            PublicKey pubkey = kd.routerIdentity.getPublicKey();
            SigningPublicKey signingPubKey = kd.routerIdentity.getSigningPublicKey();
            PrivateKey privkey = kd.privateKey;
            SigningPrivateKey signingPrivKey = kd.signingPrivateKey;
            SigType stype = signingPubKey.getType();
            // check if the sigtype config changed
            SigType cstype = CreateRouterInfoJob.getSigTypeConfig(getContext());
            boolean sigTypeChanged = stype != cstype;
            if (sigTypeChanged && getContext().getProperty(CreateRouterInfoJob.PROP_ROUTER_SIGTYPE) == null) {
                // TODO reduce to ~3 (i.e. increase probability) in future release
                if (getContext().random().nextInt(4) > 0) {
                    sigTypeChanged = false;
                    if (_log.shouldWarn())
                        _log.warn("Deferring RI rekey from " + stype + " to " + cstype);
                }
            }
            if (sigTypeChanged || shouldRebuild(privkey)) {
                if (_us != null) {
                    Hash h = _us.getIdentity().getHash();
                    _log.logAlways(Log.WARN, "Deleting old router identity " + h.toBase64());
                    // the netdb hasn't started yet, but we want to delete the RI
                    File f = PersistentDataStore.getRouterInfoFile(getContext(), h);
                    f.delete();
                    // the banlist can be called at any time
                    getContext().banlist().banlistRouterForever(h, "Our previous identity");
                    _us = null;
                }
                if (sigTypeChanged)
                    _log.logAlways(Log.WARN, "Rebuilding RouterInfo with new signature type " + cstype);
                // windows... close before deleting
                if (fis1 != null) {
                    try {
                        fis1.close();
                    } catch (IOException ioe) {
                    }
                    fis1 = null;
                }
                rif.delete();
                rkf.delete();
                rkf2.delete();
                return;
            }
            getContext().keyManager().setKeys(pubkey, privkey, signingPubKey, signingPrivKey);
        }
    } catch (IOException ioe) {
        _log.log(Log.CRIT, "Error reading the router info from " + rif.getAbsolutePath() + " and the keys from " + rkf.getAbsolutePath(), ioe);
        _us = null;
        // windows... close before deleting
        if (fis1 != null) {
            try {
                fis1.close();
            } catch (IOException ioe2) {
            }
            fis1 = null;
        }
        rif.delete();
        rkf.delete();
        rkf2.delete();
    } catch (DataFormatException dfe) {
        _log.log(Log.CRIT, "Corrupt router info or keys at " + rif.getAbsolutePath() + " / " + rkf.getAbsolutePath(), dfe);
        _us = null;
        // windows... close before deleting
        if (fis1 != null) {
            try {
                fis1.close();
            } catch (IOException ioe) {
            }
            fis1 = null;
        }
        rif.delete();
        rkf.delete();
        rkf2.delete();
    } finally {
        if (fis1 != null)
            try {
                fis1.close();
            } catch (IOException ioe) {
            }
    }
}
Also used : SigningPublicKey(net.i2p.data.SigningPublicKey) PrivateKey(net.i2p.data.PrivateKey) SigningPrivateKey(net.i2p.data.SigningPrivateKey) RouterInfo(net.i2p.data.router.RouterInfo) BufferedInputStream(java.io.BufferedInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) SigningPublicKey(net.i2p.data.SigningPublicKey) PublicKey(net.i2p.data.PublicKey) IOException(java.io.IOException) Hash(net.i2p.data.Hash) FileInputStream(java.io.FileInputStream) SigType(net.i2p.crypto.SigType) SigningPrivateKey(net.i2p.data.SigningPrivateKey) DataFormatException(net.i2p.data.DataFormatException) BufferedInputStream(java.io.BufferedInputStream) File(java.io.File) RouterPrivateKeyFile(net.i2p.data.router.RouterPrivateKeyFile)

Example 28 with SigType

use of net.i2p.crypto.SigType in project i2p.i2p by i2p.

the class UDPTransport method bid.

public TransportBid bid(RouterInfo toAddress, long dataSize) {
    if (dataSize > OutboundMessageState.MAX_MSG_SIZE) {
        // NTCP max is lower, so msg will get dropped
        return null;
    }
    Hash to = toAddress.getIdentity().calculateHash();
    PeerState peer = getPeerState(to);
    if (peer != null) {
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("bidding on a message to an established peer: " + peer);
        if (preferUDP())
            return _cachedBid[FAST_PREFERRED_BID];
        else
            return _cachedBid[FAST_BID];
    } else {
        // If we don't have a port, all is lost
        if (_reachabilityStatus == Status.HOSED) {
            markUnreachable(to);
            return null;
        }
        // Validate his SSU address
        RouterAddress addr = getTargetAddress(toAddress);
        if (addr == null) {
            markUnreachable(to);
            return null;
        }
        // Check for supported sig type
        SigType type = toAddress.getIdentity().getSigType();
        if (type == null || !type.isAvailable()) {
            markUnreachable(to);
            return null;
        }
        // Can we connect to them if we are not DSA?
        RouterInfo us = _context.router().getRouterInfo();
        if (us != null) {
            RouterIdentity id = us.getIdentity();
            if (id.getSigType() != SigType.DSA_SHA1) {
                String v = toAddress.getVersion();
                if (VersionComparator.comp(v, MIN_SIGTYPE_VERSION) < 0) {
                    markUnreachable(to);
                    return null;
                }
            }
        }
        if (!allowConnection())
            return _cachedBid[TRANSIENT_FAIL_BID];
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("bidding on a message to an unestablished peer: " + to);
        // Try to maintain at least 5 peers (30 for v6) so we can determine our IP address and
        // we have a selection to run peer tests with.
        // If we are firewalled, and we don't have enough peers that volunteered to
        // also introduce us, also bid aggressively so we are preferred over NTCP.
        // (Otherwise we only talk UDP to those that are firewalled, and we will
        // never get any introducers)
        int count = _peersByIdent.size();
        if (alwaysPreferUDP()) {
            return _cachedBid[SLOW_PREFERRED_BID];
        } else if (count < _min_peers || (_haveIPv6Address && count < _min_v6_peers) || (introducersRequired() && _introManager.introducerCount() < MIN_INTRODUCER_POOL)) {
            // TODO After some time, decide that UDP is blocked/broken and return TRANSIENT_FAIL_BID?
            if (_context.random().nextInt(4) == 0)
                return _cachedBid[SLOWEST_BID];
            else
                return _cachedBid[SLOW_PREFERRED_BID];
        } else if (preferUDP()) {
            return _cachedBid[SLOW_BID];
        } else if (haveCapacity()) {
            if (addr.getCost() > DEFAULT_COST)
                return _cachedBid[SLOWEST_COST_BID];
            else
                return _cachedBid[SLOWEST_BID];
        } else {
            if (addr.getCost() > DEFAULT_COST)
                return _cachedBid[NEAR_CAPACITY_COST_BID];
            else
                return _cachedBid[NEAR_CAPACITY_BID];
        }
    }
}
Also used : RouterInfo(net.i2p.data.router.RouterInfo) RouterIdentity(net.i2p.data.router.RouterIdentity) RouterAddress(net.i2p.data.router.RouterAddress) Hash(net.i2p.data.Hash) SigType(net.i2p.crypto.SigType)

Example 29 with SigType

use of net.i2p.crypto.SigType in project i2p.i2p by i2p.

the class FamilyKeyCrypto method verify.

/**
 *  Verify the family in a RouterInfo, name already retrieved
 *  @since 0.9.28
 */
private boolean verify(RouterInfo ri, String name) {
    Hash h = ri.getHash();
    String ssig = ri.getOption(OPT_SIG);
    if (ssig == null) {
        if (_log.shouldInfo())
            _log.info("No sig for " + h + ' ' + name);
        return false;
    }
    String nameAndSig = _verified.get(h);
    String riNameAndSig = name + ssig;
    if (nameAndSig != null) {
        if (nameAndSig.equals(riNameAndSig))
            return true;
        // name or sig changed
        _verified.remove(h);
    }
    SigningPublicKey spk;
    if (name.equals(_fname)) {
        // us
        spk = _pubkey;
    } else {
        if (_negativeCache.contains(h))
            return false;
        spk = loadCert(name);
        if (spk == null) {
            // look for a b64 key in the RI
            String skey = ri.getOption(OPT_KEY);
            if (skey != null) {
                int colon = skey.indexOf(':');
                // switched from ';' to ':' during dev, remove this later
                if (colon < 0)
                    colon = skey.indexOf(';');
                if (colon > 0) {
                    try {
                        int code = Integer.parseInt(skey.substring(0, colon));
                        SigType type = SigType.getByCode(code);
                        if (type != null) {
                            byte[] bkey = Base64.decode(skey.substring(colon + 1));
                            if (bkey != null) {
                                spk = new SigningPublicKey(type, bkey);
                            }
                        }
                    } catch (NumberFormatException e) {
                        if (_log.shouldInfo())
                            _log.info("Bad b64 family key: " + ri, e);
                    } catch (IllegalArgumentException e) {
                        if (_log.shouldInfo())
                            _log.info("Bad b64 family key: " + ri, e);
                    } catch (ArrayIndexOutOfBoundsException e) {
                        if (_log.shouldInfo())
                            _log.info("Bad b64 family key: " + ri, e);
                    }
                }
            }
            if (spk == null) {
                _negativeCache.add(h);
                if (_log.shouldInfo())
                    _log.info("No cert or valid key for " + h + ' ' + name);
                return false;
            }
        }
    }
    if (!spk.getType().isAvailable()) {
        _negativeCache.add(h);
        if (_log.shouldInfo())
            _log.info("Unsupported crypto for sig for " + h);
        return false;
    }
    byte[] bsig = Base64.decode(ssig);
    if (bsig == null) {
        _negativeCache.add(h);
        if (_log.shouldInfo())
            _log.info("Bad sig for " + h + ' ' + name + ' ' + ssig);
        return false;
    }
    Signature sig;
    try {
        sig = new Signature(spk.getType(), bsig);
    } catch (IllegalArgumentException iae) {
        // wrong size (type mismatch)
        _negativeCache.add(h);
        if (_log.shouldInfo())
            _log.info("Bad sig for " + ri, iae);
        return false;
    }
    byte[] nb = DataHelper.getUTF8(name);
    byte[] b = new byte[nb.length + Hash.HASH_LENGTH];
    System.arraycopy(nb, 0, b, 0, nb.length);
    System.arraycopy(ri.getHash().getData(), 0, b, nb.length, Hash.HASH_LENGTH);
    boolean rv = _context.dsa().verifySignature(sig, b, spk);
    if (rv)
        _verified.put(h, riNameAndSig);
    else
        _negativeCache.add(h);
    if (_log.shouldInfo())
        _log.info("Verified? " + rv + " for " + h + ' ' + name + ' ' + ssig);
    return rv;
}
Also used : SigningPublicKey(net.i2p.data.SigningPublicKey) Signature(net.i2p.data.Signature) Hash(net.i2p.data.Hash) SigType(net.i2p.crypto.SigType)

Example 30 with SigType

use of net.i2p.crypto.SigType in project i2p.i2p by i2p.

the class KademliaNetworkDatabaseFacade method processStoreFailure.

/**
 *  If the validate fails, call this
 *  to determine if it was because of unsupported crypto.
 *
 *  If so, this will banlist-forever the router hash or permanently negative cache the dest hash,
 *  and then throw the exception. Otherwise it does nothing.
 *
 *  @throws UnsupportedCryptoException if that's why it failed.
 *  @since 0.9.16
 */
private void processStoreFailure(Hash h, DatabaseEntry entry) throws UnsupportedCryptoException {
    if (entry.getHash().equals(h)) {
        if (entry.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
            LeaseSet ls = (LeaseSet) entry;
            Destination d = ls.getDestination();
            Certificate c = d.getCertificate();
            if (c.getCertificateType() == Certificate.CERTIFICATE_TYPE_KEY) {
                try {
                    KeyCertificate kc = c.toKeyCertificate();
                    SigType type = kc.getSigType();
                    if (type == null || !type.isAvailable() || type.getBaseAlgorithm() == SigAlgo.RSA) {
                        failPermanently(d);
                        String stype = (type != null) ? type.toString() : Integer.toString(kc.getSigTypeCode());
                        if (_log.shouldLog(Log.WARN))
                            _log.warn("Unsupported sig type " + stype + " for destination " + h);
                        throw new UnsupportedCryptoException("Sig type " + stype);
                    }
                } catch (DataFormatException dfe) {
                }
            }
        } else if (entry.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
            RouterInfo ri = (RouterInfo) entry;
            RouterIdentity id = ri.getIdentity();
            Certificate c = id.getCertificate();
            if (c.getCertificateType() == Certificate.CERTIFICATE_TYPE_KEY) {
                try {
                    KeyCertificate kc = c.toKeyCertificate();
                    SigType type = kc.getSigType();
                    if (type == null || !type.isAvailable()) {
                        String stype = (type != null) ? type.toString() : Integer.toString(kc.getSigTypeCode());
                        _context.banlist().banlistRouterForever(h, "Unsupported signature type " + stype);
                        if (_log.shouldLog(Log.WARN))
                            _log.warn("Unsupported sig type " + stype + " for router " + h);
                        throw new UnsupportedCryptoException("Sig type " + stype);
                    }
                } catch (DataFormatException dfe) {
                }
            }
        }
    }
    if (_log.shouldLog(Log.WARN))
        _log.warn("Verify fail, cause unknown: " + entry);
}
Also used : LeaseSet(net.i2p.data.LeaseSet) Destination(net.i2p.data.Destination) KeyCertificate(net.i2p.data.KeyCertificate) DataFormatException(net.i2p.data.DataFormatException) RouterInfo(net.i2p.data.router.RouterInfo) RouterIdentity(net.i2p.data.router.RouterIdentity) SigType(net.i2p.crypto.SigType) Certificate(net.i2p.data.Certificate) KeyCertificate(net.i2p.data.KeyCertificate)

Aggregations

SigType (net.i2p.crypto.SigType)44 IOException (java.io.IOException)18 DataFormatException (net.i2p.data.DataFormatException)15 Signature (net.i2p.data.Signature)14 Destination (net.i2p.data.Destination)12 SigningPublicKey (net.i2p.data.SigningPublicKey)11 File (java.io.File)6 GeneralSecurityException (java.security.GeneralSecurityException)6 Properties (java.util.Properties)6 Hash (net.i2p.data.Hash)6 PrivateKey (net.i2p.data.PrivateKey)6 SigningPrivateKey (net.i2p.data.SigningPrivateKey)6 PublicKey (net.i2p.data.PublicKey)5 SimpleDataStructure (net.i2p.data.SimpleDataStructure)5 RouterInfo (net.i2p.data.router.RouterInfo)5 ByteArrayOutputStream (java.io.ByteArrayOutputStream)4 I2PException (net.i2p.I2PException)4 RouterIdentity (net.i2p.data.router.RouterIdentity)4 Log (net.i2p.util.Log)4 ByteArrayInputStream (java.io.ByteArrayInputStream)3