Search in sources :

Example 11 with PublicKey

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

the class GarlicMessageBuilder method buildMessage.

/**
 * called by netdb and above
 *
 * @param ctx scope
 * @param config how/what to wrap
 * @param wrappedKey output parameter that will be filled with the sessionKey used
 * @param wrappedTags Output parameter that will be filled with the sessionTags used.
 *                          If non-empty on return you must call skm.tagsDelivered() when sent
 *                          and then call skm.tagsAcked() or skm.failTags() later.
 * @param numTagsToDeliver only if the estimated available tags are below the threshold.
 *                               Set to zero to disable tag delivery. You must set to zero if you are not
 *                               equipped to confirm delivery and call skm.tagsAcked() or failTags() later.
 *                               If this is always 0, it forces ElGamal every time.
 * @param lowTagsThreshold the threshold
 * @param skm non-null
 * @throws IllegalArgumentException on error
 */
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags, int numTagsToDeliver, int lowTagsThreshold, SessionKeyManager skm) {
    Log log = ctx.logManager().getLog(GarlicMessageBuilder.class);
    PublicKey key = config.getRecipientPublicKey();
    if (key == null) {
        if (config.getRecipient() == null) {
            throw new IllegalArgumentException("Null recipient specified");
        } else if (config.getRecipient().getIdentity() == null) {
            throw new IllegalArgumentException("Null recipient.identity specified");
        } else if (config.getRecipient().getIdentity().getPublicKey() == null) {
            throw new IllegalArgumentException("Null recipient.identity.publicKey specified");
        } else
            key = config.getRecipient().getIdentity().getPublicKey();
    }
    if (log.shouldLog(Log.INFO))
        log.info("Encrypted with public key to expire on " + new Date(config.getExpiration()));
    SessionKey curKey = skm.getCurrentOrNewKey(key);
    SessionTag curTag = null;
    curTag = skm.consumeNextAvailableTag(key, curKey);
    if (log.shouldLog(Log.DEBUG)) {
        int availTags = skm.getAvailableTags(key, curKey);
        log.debug("Available tags for encryption: " + availTags + " low threshold: " + lowTagsThreshold);
    }
    if (numTagsToDeliver > 0 && skm.shouldSendTags(key, curKey, lowTagsThreshold)) {
        for (int i = 0; i < numTagsToDeliver; i++) wrappedTags.add(new SessionTag(true));
        if (log.shouldLog(Log.INFO))
            log.info("Too few tags available so we're including " + numTagsToDeliver);
    }
    wrappedKey.setData(curKey.getData());
    return buildMessage(ctx, config, wrappedKey, wrappedTags, key, curKey, curTag);
}
Also used : Log(net.i2p.util.Log) PublicKey(net.i2p.data.PublicKey) SessionKey(net.i2p.data.SessionKey) SessionTag(net.i2p.data.SessionTag) Date(java.util.Date)

Example 12 with PublicKey

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

the class CreateRouterInfoJob method createRouterInfo.

/**
 *  Writes 6 files: router.info (standard RI format),
 *  router.keys.dat, and 4 individual key files under keyBackup/
 *
 *  router.keys.dat file format: This is the
 *  same "eepPriv.dat" format used by the client code,
 *  as documented in PrivateKeyFile.
 *
 *  Old router.keys file format: Note that this is NOT the
 *  same "eepPriv.dat" format used by the client code.
 *<pre>
 *   - Private key (256 bytes)
 *   - Signing Private key (20 bytes)
 *   - Public key (256 bytes)
 *   - Signing Public key (128 bytes)
 *  Total 660 bytes
 *</pre>
 *
 *  Caller must hold Router.routerInfoFileLock.
 */
RouterInfo createRouterInfo() {
    SigType type = getSigTypeConfig(getContext());
    RouterInfo info = new RouterInfo();
    OutputStream fos1 = null;
    try {
        info.setAddresses(getContext().commSystem().createAddresses());
        // not necessary, in constructor
        // info.setPeers(new HashSet());
        info.setPublished(getCurrentPublishDate(getContext()));
        Object[] keypair = getContext().keyGenerator().generatePKIKeypair();
        PublicKey pubkey = (PublicKey) keypair[0];
        PrivateKey privkey = (PrivateKey) keypair[1];
        SimpleDataStructure[] signingKeypair = getContext().keyGenerator().generateSigningKeys(type);
        SigningPublicKey signingPubKey = (SigningPublicKey) signingKeypair[0];
        SigningPrivateKey signingPrivKey = (SigningPrivateKey) signingKeypair[1];
        RouterIdentity ident = new RouterIdentity();
        Certificate cert = createCertificate(getContext(), signingPubKey);
        ident.setCertificate(cert);
        ident.setPublicKey(pubkey);
        ident.setSigningPublicKey(signingPubKey);
        byte[] padding;
        int padLen = SigningPublicKey.KEYSIZE_BYTES - signingPubKey.length();
        if (padLen > 0) {
            padding = new byte[padLen];
            getContext().random().nextBytes(padding);
            ident.setPadding(padding);
        } else {
            padding = null;
        }
        info.setIdentity(ident);
        Properties stats = getContext().statPublisher().publishStatistics(ident.getHash());
        info.setOptions(stats);
        info.sign(signingPrivKey);
        if (!info.isValid())
            throw new DataFormatException("RouterInfo we just built is invalid: " + info);
        // remove router.keys
        (new File(getContext().getRouterDir(), KEYS_FILENAME)).delete();
        // write router.info
        File ifile = new File(getContext().getRouterDir(), INFO_FILENAME);
        fos1 = new BufferedOutputStream(new SecureFileOutputStream(ifile));
        info.writeBytes(fos1);
        // write router.keys.dat
        File kfile = new File(getContext().getRouterDir(), KEYS2_FILENAME);
        PrivateKeyFile pkf = new PrivateKeyFile(kfile, pubkey, signingPubKey, cert, privkey, signingPrivKey, padding);
        pkf.write();
        // set or overwrite old random keys
        Map<String, String> map = new HashMap<String, String>(2);
        byte[] rk = new byte[32];
        getContext().random().nextBytes(rk);
        map.put(Router.PROP_IB_RANDOM_KEY, Base64.encode(rk));
        getContext().random().nextBytes(rk);
        map.put(Router.PROP_OB_RANDOM_KEY, Base64.encode(rk));
        getContext().router().saveConfig(map, null);
        getContext().keyManager().setKeys(pubkey, privkey, signingPubKey, signingPrivKey);
        if (_log.shouldLog(Log.INFO))
            _log.info("Router info created and stored at " + ifile.getAbsolutePath() + " with private keys stored at " + kfile.getAbsolutePath() + " [" + info + "]");
        getContext().router().eventLog().addEvent(EventLog.REKEYED, ident.calculateHash().toBase64());
    } catch (GeneralSecurityException gse) {
        _log.log(Log.CRIT, "Error building the new router information", gse);
    } catch (DataFormatException dfe) {
        _log.log(Log.CRIT, "Error building the new router information", dfe);
    } catch (IOException ioe) {
        _log.log(Log.CRIT, "Error writing out the new router information", ioe);
    } finally {
        if (fos1 != null)
            try {
                fos1.close();
            } catch (IOException ioe) {
            }
    }
    return info;
}
Also used : PrivateKey(net.i2p.data.PrivateKey) SigningPrivateKey(net.i2p.data.SigningPrivateKey) HashMap(java.util.HashMap) RouterInfo(net.i2p.data.router.RouterInfo) SecureFileOutputStream(net.i2p.util.SecureFileOutputStream) BufferedOutputStream(java.io.BufferedOutputStream) OutputStream(java.io.OutputStream) Properties(java.util.Properties) SimpleDataStructure(net.i2p.data.SimpleDataStructure) BufferedOutputStream(java.io.BufferedOutputStream) SigningPublicKey(net.i2p.data.SigningPublicKey) SigningPublicKey(net.i2p.data.SigningPublicKey) PublicKey(net.i2p.data.PublicKey) RouterIdentity(net.i2p.data.router.RouterIdentity) GeneralSecurityException(java.security.GeneralSecurityException) PrivateKeyFile(net.i2p.data.PrivateKeyFile) IOException(java.io.IOException) SigType(net.i2p.crypto.SigType) SigningPrivateKey(net.i2p.data.SigningPrivateKey) DataFormatException(net.i2p.data.DataFormatException) SecureFileOutputStream(net.i2p.util.SecureFileOutputStream) PrivateKeyFile(net.i2p.data.PrivateKeyFile) File(java.io.File) Certificate(net.i2p.data.Certificate) KeyCertificate(net.i2p.data.KeyCertificate)

Example 13 with PublicKey

use of net.i2p.data.PublicKey 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 14 with PublicKey

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

the class SessionEncryptionTest method testNoSessions1.

public void testNoSessions1() throws Exception {
    Object[] keys = KeyGenerator.getInstance().generatePKIKeypair();
    PublicKey pubKey = (PublicKey) keys[0];
    PrivateKey privKey = (PrivateKey) keys[1];
    SessionKeyManager skm = new TransientSessionKeyManager(_context);
    SessionKey curKey = skm.createSession(pubKey);
    byte[] msg = DataHelper.getASCII("msg 1");
    byte[] emsg = _context.elGamalAESEngine().encrypt(msg, pubKey, curKey, null, null, 64);
    byte[] dmsg = _context.elGamalAESEngine().decrypt(emsg, privKey, skm);
    assertTrue(DataHelper.eq(dmsg, msg));
}
Also used : PrivateKey(net.i2p.data.PrivateKey) PublicKey(net.i2p.data.PublicKey) SessionKey(net.i2p.data.SessionKey) SessionKeyManager(net.i2p.crypto.SessionKeyManager)

Example 15 with PublicKey

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

the class SessionEncryptionTest method testSessions.

/**
 *  Run     tagsIncluded    useTag  rekey
 *  1       yes (2)         no      no
 *  2       no              yes     no
 *  3       yes (2)         yes     no
 *  4       no              yes     no
 *  5       no              yes     no
 */
public void testSessions() throws Exception {
    Object[] keys = KeyGenerator.getInstance().generatePKIKeypair();
    PublicKey pubKey = (PublicKey) keys[0];
    PrivateKey privKey = (PrivateKey) keys[1];
    SessionKeyManager skm = new TransientSessionKeyManager(_context);
    SessionKey curKey = skm.createSession(pubKey);
    SessionTag tag1 = new SessionTag(true);
    SessionTag tag2 = new SessionTag(true);
    SessionTag tag3 = new SessionTag(true);
    SessionTag tag4 = new SessionTag(true);
    HashSet<SessionTag> firstTags = new HashSet<SessionTag>();
    firstTags.add(tag1);
    firstTags.add(tag2);
    HashSet<SessionTag> secondTags = new HashSet<SessionTag>();
    secondTags.add(tag3);
    secondTags.add(tag4);
    byte[] msg1 = DataHelper.getASCII("msg 1");
    byte[] msg2 = DataHelper.getASCII("msg 2");
    byte[] msg3 = DataHelper.getASCII("msg 3");
    byte[] msg4 = DataHelper.getASCII("msg 4");
    byte[] msg5 = DataHelper.getASCII("msg 5");
    byte[] emsg1 = _context.elGamalAESEngine().encrypt(msg1, pubKey, curKey, firstTags, null, 64);
    byte[] dmsg1 = _context.elGamalAESEngine().decrypt(emsg1, privKey, skm);
    assertTrue(DataHelper.eq(dmsg1, msg1));
    TagSetHandle tsh = skm.tagsDelivered(pubKey, curKey, firstTags);
    skm.tagsAcked(pubKey, curKey, tsh);
    curKey = skm.getCurrentKey(pubKey);
    SessionTag curTag = skm.consumeNextAvailableTag(pubKey, curKey);
    assertNotNull(curTag);
    byte[] emsg2 = _context.elGamalAESEngine().encrypt(msg2, pubKey, curKey, null, curTag, 64);
    byte[] dmsg2 = _context.elGamalAESEngine().decrypt(emsg2, privKey, skm);
    assertTrue(DataHelper.eq(dmsg2, msg2));
    curKey = skm.getCurrentKey(pubKey);
    curTag = skm.consumeNextAvailableTag(pubKey, curKey);
    assertNotNull(curTag);
    assertNotNull(curKey);
    byte[] emsg3 = _context.elGamalAESEngine().encrypt(msg3, pubKey, curKey, secondTags, curTag, 64);
    byte[] dmsg3 = _context.elGamalAESEngine().decrypt(emsg3, privKey, skm);
    assertTrue(DataHelper.eq(dmsg3, msg3));
    tsh = skm.tagsDelivered(pubKey, curKey, secondTags);
    skm.tagsAcked(pubKey, curKey, tsh);
    curKey = skm.getCurrentKey(pubKey);
    curTag = skm.consumeNextAvailableTag(pubKey, curKey);
    assertNotNull(curTag);
    assertNotNull(curKey);
    byte[] emsg4 = _context.elGamalAESEngine().encrypt(msg4, pubKey, curKey, null, curTag, 64);
    byte[] dmsg4 = _context.elGamalAESEngine().decrypt(emsg4, privKey, skm);
    assertTrue(DataHelper.eq(dmsg4, msg4));
    curKey = skm.getCurrentKey(pubKey);
    curTag = skm.consumeNextAvailableTag(pubKey, curKey);
    assertNotNull(curTag);
    assertNotNull(curKey);
    byte[] emsg5 = _context.elGamalAESEngine().encrypt(msg5, pubKey, curKey, null, curTag, 64);
    byte[] dmsg5 = _context.elGamalAESEngine().decrypt(emsg5, privKey, skm);
    assertTrue(DataHelper.eq(dmsg5, msg5));
}
Also used : PrivateKey(net.i2p.data.PrivateKey) PublicKey(net.i2p.data.PublicKey) SessionKey(net.i2p.data.SessionKey) SessionKeyManager(net.i2p.crypto.SessionKeyManager) SessionTag(net.i2p.data.SessionTag) HashSet(java.util.HashSet) TagSetHandle(net.i2p.crypto.TagSetHandle)

Aggregations

PublicKey (net.i2p.data.PublicKey)36 PrivateKey (net.i2p.data.PrivateKey)23 SessionKey (net.i2p.data.SessionKey)14 SigningPublicKey (net.i2p.data.SigningPublicKey)13 DataFormatException (net.i2p.data.DataFormatException)8 SigningPrivateKey (net.i2p.data.SigningPrivateKey)8 HashSet (java.util.HashSet)7 SessionKeyManager (net.i2p.crypto.SessionKeyManager)7 SessionTag (net.i2p.data.SessionTag)7 IOException (java.io.IOException)6 SimpleDataStructure (net.i2p.data.SimpleDataStructure)6 Certificate (net.i2p.data.Certificate)5 Hash (net.i2p.data.Hash)5 ByteArrayOutputStream (java.io.ByteArrayOutputStream)4 GeneralSecurityException (java.security.GeneralSecurityException)4 SigType (net.i2p.crypto.SigType)4 TagSetHandle (net.i2p.crypto.TagSetHandle)4 CertificateTest (net.i2p.data.CertificateTest)4 PublicKeyTest (net.i2p.data.PublicKeyTest)4 SigningPublicKeyTest (net.i2p.data.SigningPublicKeyTest)4