Search in sources :

Example 11 with SimpleDataStructure

use of net.i2p.data.SimpleDataStructure in project i2p.i2p by i2p.

the class TunnelConfig method getConfig.

/**
 * Based on all provided data, create a set of configuration parameters
 * suitable for use in a TunnelController.  This will replace (not add to)
 * any existing parameters, so this should return a comprehensive mapping.
 */
public Properties getConfig() {
    Properties config = new Properties();
    updateConfigGeneric(config);
    if ((TunnelController.isClient(_type) && !TunnelController.TYPE_STREAMR_CLIENT.equals(_type)) || TunnelController.TYPE_STREAMR_SERVER.equals(_type)) {
        // streamrserver uses interface
        if (_reachableBy != null)
            config.setProperty(TunnelController.PROP_INTFC, _reachableBy);
        else
            config.setProperty(TunnelController.PROP_INTFC, "");
    } else {
        // streamrclient uses targetHost
        if (_targetHost != null)
            config.setProperty(TunnelController.PROP_TARGET_HOST, _targetHost);
    }
    if (TunnelController.isClient(_type)) {
        // generic client stuff
        if (_port >= 0)
            config.setProperty(TunnelController.PROP_LISTEN_PORT, Integer.toString(_port));
        config.setProperty(TunnelController.PROP_SHARED, _sharedClient + "");
        for (String p : _booleanClientOpts) config.setProperty(OPT + p, "" + _booleanOptions.contains(p));
        for (String p : _otherClientOpts) {
            if (_otherOptions.containsKey(p))
                config.setProperty(OPT + p, _otherOptions.get(p));
        }
    } else {
        // generic server stuff
        if (_targetPort >= 0)
            config.setProperty(TunnelController.PROP_TARGET_PORT, Integer.toString(_targetPort));
        // see TunnelController.setConfig()
        _booleanOptions.add(TunnelController.PROP_LIMITS_SET);
        for (String p : _booleanServerOpts) config.setProperty(OPT + p, "" + _booleanOptions.contains(p));
        for (String p : _otherServerOpts) {
            if (_otherOptions.containsKey(p))
                config.setProperty(OPT + p, _otherOptions.get(p));
        }
    }
    // override bundle setting set above
    if (!TunnelController.isClient(_type) && !TunnelController.TYPE_HTTP_SERVER.equals(_type) && !TunnelController.TYPE_STREAMR_SERVER.equals(_type)) {
        config.setProperty(TunnelController.OPT_BUNDLE_REPLY, "true");
    }
    // generic proxy stuff
    if (TunnelController.TYPE_HTTP_CLIENT.equals(_type) || TunnelController.TYPE_CONNECT.equals(_type) || TunnelController.TYPE_SOCKS.equals(_type) || TunnelController.TYPE_SOCKS_IRC.equals(_type)) {
        for (String p : _booleanProxyOpts) config.setProperty(OPT + p, "" + _booleanOptions.contains(p));
        if (_proxyList != null)
            config.setProperty(TunnelController.PROP_PROXIES, _proxyList);
    }
    // Proxy auth including migration to MD5
    if (TunnelController.TYPE_HTTP_CLIENT.equals(_type) || TunnelController.TYPE_CONNECT.equals(_type)) {
        // Migrate even if auth is disabled
        // go get the old from custom options that updateConfigGeneric() put in there
        String puser = OPT + I2PTunnelHTTPClientBase.PROP_USER;
        String user = config.getProperty(puser);
        String ppw = OPT + I2PTunnelHTTPClientBase.PROP_PW;
        String pw = config.getProperty(ppw);
        if (user != null && pw != null && user.length() > 0 && pw.length() > 0) {
            String pmd5 = OPT + I2PTunnelHTTPClientBase.PROP_PROXY_DIGEST_PREFIX + user + I2PTunnelHTTPClientBase.PROP_PROXY_DIGEST_SUFFIX;
            if (config.getProperty(pmd5) == null) {
                // not in there, migrate
                String realm = _type.equals(TunnelController.TYPE_HTTP_CLIENT) ? I2PTunnelHTTPClient.AUTH_REALM : I2PTunnelConnectClient.AUTH_REALM;
                String hex = PasswordManager.md5Hex(realm, user, pw);
                if (hex != null) {
                    config.setProperty(pmd5, hex);
                    config.remove(puser);
                    config.remove(ppw);
                }
            }
        }
        // New user/password
        String auth = _otherOptions.get(I2PTunnelHTTPClientBase.PROP_AUTH);
        if (auth != null && !auth.equals("false")) {
            if (_newProxyUser != null && _newProxyPW != null && _newProxyUser.length() > 0 && _newProxyPW.length() > 0) {
                String pmd5 = OPT + I2PTunnelHTTPClientBase.PROP_PROXY_DIGEST_PREFIX + _newProxyUser + I2PTunnelHTTPClientBase.PROP_PROXY_DIGEST_SUFFIX;
                String realm = _type.equals(TunnelController.TYPE_HTTP_CLIENT) ? I2PTunnelHTTPClient.AUTH_REALM : I2PTunnelConnectClient.AUTH_REALM;
                String hex = PasswordManager.md5Hex(realm, _newProxyUser, _newProxyPW);
                if (hex != null)
                    config.setProperty(pmd5, hex);
            }
        }
    }
    if (TunnelController.TYPE_IRC_CLIENT.equals(_type) || TunnelController.TYPE_STD_CLIENT.equals(_type) || TunnelController.TYPE_STREAMR_CLIENT.equals(_type)) {
        if (_targetDestination != null)
            config.setProperty(TunnelController.PROP_DEST, _targetDestination);
    } else if (TunnelController.TYPE_HTTP_SERVER.equals(_type) || TunnelController.TYPE_HTTP_BIDIR_SERVER.equals(_type)) {
        if (_spoofedHost != null)
            config.setProperty(TunnelController.PROP_SPOOFED_HOST, _spoofedHost);
        for (String p : _httpServerOpts) if (_otherOptions.containsKey(p))
            config.setProperty(OPT + p, _otherOptions.get(p));
    }
    if (TunnelController.TYPE_HTTP_BIDIR_SERVER.equals(_type)) {
        if (_port >= 0)
            config.setProperty(TunnelController.PROP_LISTEN_PORT, Integer.toString(_port));
        if (_reachableBy != null)
            config.setProperty(TunnelController.PROP_INTFC, _reachableBy);
        else if (_targetHost != null)
            config.setProperty(TunnelController.PROP_INTFC, _targetHost);
        else
            config.setProperty(TunnelController.PROP_INTFC, "");
    }
    if (TunnelController.TYPE_IRC_CLIENT.equals(_type)) {
        boolean dcc = _booleanOptions.contains(I2PTunnelIRCClient.PROP_DCC);
        config.setProperty(OPT + I2PTunnelIRCClient.PROP_DCC, "" + dcc);
        // add some sane server options since they aren't in the GUI (yet)
        if (dcc) {
            config.setProperty(OPT + PROP_MAX_CONNS_MIN, "3");
            config.setProperty(OPT + PROP_MAX_CONNS_HOUR, "10");
            config.setProperty(OPT + PROP_MAX_TOTAL_CONNS_MIN, "5");
            config.setProperty(OPT + PROP_MAX_TOTAL_CONNS_HOUR, "25");
        }
    }
    if (!TunnelController.isClient(_type) || _booleanOptions.contains("persistentClientKey")) {
        // As of 0.9.17, add a persistent random key if not present
        String p = OPT + "inbound.randomKey";
        if (!config.containsKey(p)) {
            byte[] rk = new byte[32];
            _context.random().nextBytes(rk);
            config.setProperty(p, Base64.encode(rk));
            p = OPT + "outbound.randomKey";
            _context.random().nextBytes(rk);
            config.setProperty(p, Base64.encode(rk));
        }
        // As of 0.9.18, add persistent leaseset keys if not present
        // but only if we know the sigtype
        p = OPT + "i2cp.leaseSetSigningPrivateKey";
        if (_dest != null && !config.containsKey(p)) {
            try {
                SigType type = _dest.getSigType();
                SimpleDataStructure[] keys = KeyGenerator.getInstance().generateSigningKeys(type);
                config.setProperty(p, type.name() + ':' + keys[1].toBase64());
                p = OPT + "i2cp.leaseSetPrivateKey";
                keys = KeyGenerator.getInstance().generatePKIKeys();
                config.setProperty(p, "ELGAMAL_2048:" + keys[1].toBase64());
            } catch (GeneralSecurityException gse) {
            // so much for that
            }
        }
    }
    return config;
}
Also used : GeneralSecurityException(java.security.GeneralSecurityException) Properties(java.util.Properties) SimpleDataStructure(net.i2p.data.SimpleDataStructure) SigType(net.i2p.crypto.SigType)

Example 12 with SimpleDataStructure

use of net.i2p.data.SimpleDataStructure in project i2p.i2p by i2p.

the class RouterInfo method readBytes.

/**
 *  If verifySig is true,
 *  this validates the signature while reading in,
 *  and throws a DataFormatException if the sig is invalid.
 *  This is faster than reserializing to validate later.
 *
 *  @throws IllegalStateException if RouterInfo was already read in
 *  @since 0.9
 */
public void readBytes(InputStream in, boolean verifySig) throws DataFormatException, IOException {
    if (_signature != null)
        throw new IllegalStateException();
    _identity = new RouterIdentity();
    _identity.readBytes(in);
    // can't set the digest until we know the sig type
    InputStream din;
    MessageDigest digest;
    if (verifySig) {
        SigType type = _identity.getSigningPublicKey().getType();
        if (type != SigType.EdDSA_SHA512_Ed25519) {
            // This won't work for EdDSA
            digest = _identity.getSigningPublicKey().getType().getDigestInstance();
            // TODO any better way?
            digest.update(_identity.toByteArray());
            din = new DigestInputStream(in, digest);
        } else {
            digest = null;
            din = in;
        }
    } else {
        digest = null;
        din = in;
    }
    // avoid thrashing objects
    // Date when = DataHelper.readDate(in);
    // if (when == null)
    // _published = 0;
    // else
    // _published = when.getTime();
    _published = DataHelper.readLong(din, 8);
    int numAddresses = (int) DataHelper.readLong(din, 1);
    for (int i = 0; i < numAddresses; i++) {
        RouterAddress address = new RouterAddress();
        address.readBytes(din);
        _addresses.add(address);
    }
    int numPeers = (int) DataHelper.readLong(din, 1);
    if (numPeers == 0) {
        _peers = null;
    } else {
        _peers = new HashSet<Hash>(numPeers);
        for (int i = 0; i < numPeers; i++) {
            Hash peerIdentityHash = new Hash();
            peerIdentityHash.readBytes(din);
            _peers.add(peerIdentityHash);
        }
    }
    DataHelper.readProperties(din, _options);
    _signature = new Signature(_identity.getSigningPublicKey().getType());
    _signature.readBytes(in);
    if (verifySig) {
        SigType type = _identity.getSigningPublicKey().getType();
        if (type != SigType.EdDSA_SHA512_Ed25519) {
            // This won't work for EdDSA
            SimpleDataStructure hash = _identity.getSigningPublicKey().getType().getHashInstance();
            hash.setData(digest.digest());
            _isValid = DSAEngine.getInstance().verifySignature(_signature, hash, _identity.getSigningPublicKey());
            _validated = true;
        } else {
            doValidate();
        }
        if (!_isValid) {
            throw new DataFormatException("Bad sig");
        }
    }
// _log.debug("Read routerInfo: " + toString());
}
Also used : DigestInputStream(java.security.DigestInputStream) DigestInputStream(java.security.DigestInputStream) InputStream(java.io.InputStream) Hash(net.i2p.data.Hash) SHA1Hash(net.i2p.crypto.SHA1Hash) SigType(net.i2p.crypto.SigType) DataFormatException(net.i2p.data.DataFormatException) Signature(net.i2p.data.Signature) MessageDigest(java.security.MessageDigest) SimpleDataStructure(net.i2p.data.SimpleDataStructure)

Example 13 with SimpleDataStructure

use of net.i2p.data.SimpleDataStructure in project i2p.i2p by i2p.

the class TunnelController method createAltPrivateKey.

/**
 * Creates alternate Destination with the same encryption keys as the primary Destination,
 * but a different signing key.
 *
 * Must have already called createPrivateKey() successfully.
 * Does nothing unless option OPT_ALT_PKF is set with the privkey file name.
 * Does nothing if the file already exists.
 *
 * @return success
 * @since 0.9.30
 */
private boolean createAltPrivateKey() {
    if (PREFERRED_SIGTYPE == SigType.DSA_SHA1)
        return false;
    File keyFile = getPrivateKeyFile();
    if (keyFile == null)
        return false;
    if (!keyFile.exists())
        return false;
    File altFile = getAlternatePrivateKeyFile();
    if (altFile == null)
        return false;
    if (altFile.equals(keyFile))
        return false;
    if (altFile.exists())
        return true;
    PrivateKeyFile pkf = new PrivateKeyFile(keyFile);
    FileOutputStream out = null;
    try {
        Destination dest = pkf.getDestination();
        if (dest == null)
            return false;
        if (dest.getSigType() != SigType.DSA_SHA1)
            return false;
        PublicKey pub = dest.getPublicKey();
        PrivateKey priv = pkf.getPrivKey();
        SimpleDataStructure[] signingKeys = KeyGenerator.getInstance().generateSigningKeys(PREFERRED_SIGTYPE);
        SigningPublicKey signingPubKey = (SigningPublicKey) signingKeys[0];
        SigningPrivateKey signingPrivKey = (SigningPrivateKey) signingKeys[1];
        KeyCertificate cert = new KeyCertificate(signingPubKey);
        Destination d = new Destination();
        d.setPublicKey(pub);
        d.setSigningPublicKey(signingPubKey);
        d.setCertificate(cert);
        int len = signingPubKey.length();
        if (len < 128) {
            byte[] pad = new byte[128 - len];
            RandomSource.getInstance().nextBytes(pad);
            d.setPadding(pad);
        } else if (len > 128) {
        // copy of excess data handled in KeyCertificate constructor
        }
        out = new SecureFileOutputStream(altFile);
        d.writeBytes(out);
        priv.writeBytes(out);
        signingPrivKey.writeBytes(out);
        try {
            out.close();
        } catch (IOException ioe) {
        }
        String destStr = d.toBase64();
        log("Alternate private key created and saved in " + altFile.getAbsolutePath());
        log("You should backup this file in a secure place.");
        log("New alternate destination: " + destStr);
        String b32 = d.toBase32();
        log("Base32: " + b32);
        File backupDir = new SecureFile(I2PAppContext.getGlobalContext().getConfigDir(), KEY_BACKUP_DIR);
        if (backupDir.isDirectory() || backupDir.mkdir()) {
            String name = b32 + '-' + I2PAppContext.getGlobalContext().clock().now() + ".dat";
            File backup = new File(backupDir, name);
            if (FileUtil.copy(altFile, backup, false, true)) {
                SecureFileOutputStream.setPerms(backup);
                log("Alternate private key backup saved to " + backup.getAbsolutePath());
            }
        }
        return true;
    } catch (GeneralSecurityException e) {
        log("Error creating keys " + e);
        return false;
    } catch (I2PSessionException e) {
        log("Error creating keys " + e);
        return false;
    } catch (I2PException e) {
        log("Error creating keys " + e);
        return false;
    } catch (IOException e) {
        log("Error creating keys " + e);
        return false;
    } catch (RuntimeException e) {
        log("Error creating keys " + e);
        return false;
    } finally {
        if (out != null)
            try {
                out.close();
            } catch (IOException ioe) {
            }
    }
}
Also used : I2PException(net.i2p.I2PException) Destination(net.i2p.data.Destination) SigningPublicKey(net.i2p.data.SigningPublicKey) PrivateKey(net.i2p.data.PrivateKey) SigningPrivateKey(net.i2p.data.SigningPrivateKey) SecureFile(net.i2p.util.SecureFile) SigningPublicKey(net.i2p.data.SigningPublicKey) PublicKey(net.i2p.data.PublicKey) GeneralSecurityException(java.security.GeneralSecurityException) PrivateKeyFile(net.i2p.data.PrivateKeyFile) IOException(java.io.IOException) SigningPrivateKey(net.i2p.data.SigningPrivateKey) KeyCertificate(net.i2p.data.KeyCertificate) SecureFileOutputStream(net.i2p.util.SecureFileOutputStream) FileOutputStream(java.io.FileOutputStream) I2PSessionException(net.i2p.client.I2PSessionException) SecureFileOutputStream(net.i2p.util.SecureFileOutputStream) SecureFile(net.i2p.util.SecureFile) PrivateKeyFile(net.i2p.data.PrivateKeyFile) File(java.io.File) SimpleDataStructure(net.i2p.data.SimpleDataStructure)

Example 14 with SimpleDataStructure

use of net.i2p.data.SimpleDataStructure in project i2p.i2p by i2p.

the class KeyGenerator method generateSigningKeys.

/**
 *  Generic signature type, supports DSA, RSA, ECDSA, EdDSA
 *  @since 0.9.9
 */
public SimpleDataStructure[] generateSigningKeys(SigType type) throws GeneralSecurityException {
    if (type == SigType.DSA_SHA1)
        return generateSigningKeys();
    KeyPair kp;
    if (type.getBaseAlgorithm() == SigAlgo.EdDSA) {
        net.i2p.crypto.eddsa.KeyPairGenerator kpg = new net.i2p.crypto.eddsa.KeyPairGenerator();
        kpg.initialize(type.getParams(), _context.random());
        kp = kpg.generateKeyPair();
    } else {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance(type.getBaseAlgorithm().getName());
        try {
            kpg.initialize(type.getParams(), _context.random());
            kp = kpg.generateKeyPair();
        } catch (ProviderException pe) {
            // java.security.ProviderException: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_DOMAIN_PARAMS_INVALID
            // This is a RuntimeException, thx Sun
            // Fails for P-192 only, on Ubuntu
            Log log = _context.logManager().getLog(KeyGenerator.class);
            String pname = kpg.getProvider().getName();
            if ("BC".equals(pname)) {
                if (log.shouldLog(Log.WARN))
                    log.warn("BC KPG failed for " + type, pe);
                throw new GeneralSecurityException("BC KPG for " + type, pe);
            }
            if (!ECConstants.isBCAvailable())
                throw new GeneralSecurityException(pname + " KPG failed for " + type, pe);
            if (log.shouldLog(Log.WARN))
                log.warn(pname + " KPG failed for " + type + ", trying BC");
            try {
                kpg = KeyPairGenerator.getInstance(type.getBaseAlgorithm().getName(), "BC");
                kpg.initialize(type.getParams(), _context.random());
                kp = kpg.generateKeyPair();
            } catch (ProviderException pe2) {
                if (log.shouldLog(Log.WARN))
                    log.warn("BC KPG failed for " + type + " also", pe2);
                // throw original exception
                throw new GeneralSecurityException(pname + " KPG for " + type, pe);
            } catch (GeneralSecurityException gse) {
                if (log.shouldLog(Log.WARN))
                    log.warn("BC KPG failed for " + type + " also", gse);
                // throw original exception
                throw new GeneralSecurityException(pname + " KPG for " + type, pe);
            }
        }
    }
    java.security.PublicKey pubkey = kp.getPublic();
    java.security.PrivateKey privkey = kp.getPrivate();
    SimpleDataStructure[] keys = new SimpleDataStructure[2];
    keys[0] = SigUtil.fromJavaKey(pubkey, type);
    keys[1] = SigUtil.fromJavaKey(privkey, type);
    return keys;
}
Also used : KeyPair(java.security.KeyPair) ProviderException(java.security.ProviderException) Log(net.i2p.util.Log) GeneralSecurityException(java.security.GeneralSecurityException) KeyPairGenerator(java.security.KeyPairGenerator) SimpleDataStructure(net.i2p.data.SimpleDataStructure)

Aggregations

SimpleDataStructure (net.i2p.data.SimpleDataStructure)14 GeneralSecurityException (java.security.GeneralSecurityException)7 SigningPrivateKey (net.i2p.data.SigningPrivateKey)7 SigningPublicKey (net.i2p.data.SigningPublicKey)7 PrivateKey (net.i2p.data.PrivateKey)6 PublicKey (net.i2p.data.PublicKey)6 IOException (java.io.IOException)5 SigType (net.i2p.crypto.SigType)5 MessageDigest (java.security.MessageDigest)4 DataFormatException (net.i2p.data.DataFormatException)4 Signature (net.i2p.data.Signature)4 SecureFileOutputStream (net.i2p.util.SecureFileOutputStream)4 FileOutputStream (java.io.FileOutputStream)3 InputStream (java.io.InputStream)3 DigestInputStream (java.security.DigestInputStream)3 I2PException (net.i2p.I2PException)3 KeyCertificate (net.i2p.data.KeyCertificate)3 NativeBigInteger (net.i2p.util.NativeBigInteger)3 BufferedInputStream (java.io.BufferedInputStream)2 BufferedOutputStream (java.io.BufferedOutputStream)2