Search in sources :

Example 31 with PublicKey

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

the class RouterIdentityTest method testCalculatedHash.

@Test
public void testCalculatedHash() throws Exception {
    RouterIdentity ident = new RouterIdentity();
    Certificate cert = (Certificate) (new CertificateTest()).createDataStructure();
    ident.setCertificate(cert);
    PublicKey pk = (PublicKey) (new PublicKeyTest()).createDataStructure();
    ident.setPublicKey(pk);
    SigningPublicKey k = (SigningPublicKey) (new SigningPublicKeyTest()).createDataStructure();
    ident.setSigningPublicKey(k);
    ident.calculateHash();
    ident.calculateHash();
    ident.calculateHash();
    ident.calculateHash();
    ident.calculateHash();
}
Also used : SigningPublicKey(net.i2p.data.SigningPublicKey) SigningPublicKeyTest(net.i2p.data.SigningPublicKeyTest) SigningPublicKey(net.i2p.data.SigningPublicKey) PublicKey(net.i2p.data.PublicKey) PublicKeyTest(net.i2p.data.PublicKeyTest) SigningPublicKeyTest(net.i2p.data.SigningPublicKeyTest) CertificateTest(net.i2p.data.CertificateTest) Certificate(net.i2p.data.Certificate) StructureTest(net.i2p.data.StructureTest) CertificateTest(net.i2p.data.CertificateTest) Test(org.junit.Test) PublicKeyTest(net.i2p.data.PublicKeyTest) SigningPublicKeyTest(net.i2p.data.SigningPublicKeyTest)

Example 32 with PublicKey

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

the class KeyGenerator method getPublicKey.

/**
 * Convert a PrivateKey to its corresponding PublicKey
 * @param priv PrivateKey object
 * @return the corresponding PublicKey object
 * @throws IllegalArgumentException on bad key
 */
public static PublicKey getPublicKey(PrivateKey priv) {
    BigInteger a = new NativeBigInteger(1, priv.toByteArray());
    BigInteger aalpha = CryptoConstants.elgg.modPow(a, CryptoConstants.elgp);
    PublicKey pub = new PublicKey();
    try {
        pub.setData(SigUtil.rectify(aalpha, PublicKey.KEYSIZE_BYTES));
    } catch (InvalidKeyException ike) {
        throw new IllegalArgumentException(ike);
    }
    return pub;
}
Also used : NativeBigInteger(net.i2p.util.NativeBigInteger) SigningPublicKey(net.i2p.data.SigningPublicKey) RSAPublicKey(java.security.interfaces.RSAPublicKey) EdDSAPublicKey(net.i2p.crypto.eddsa.EdDSAPublicKey) ECPublicKey(java.security.interfaces.ECPublicKey) PublicKey(net.i2p.data.PublicKey) BigInteger(java.math.BigInteger) NativeBigInteger(net.i2p.util.NativeBigInteger) InvalidKeyException(java.security.InvalidKeyException)

Example 33 with PublicKey

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

the class RequestLeaseSetMessageHandler method signLeaseSet.

/**
 *  Finish creating and signing the new LeaseSet
 *  @since 0.9.7
 */
protected synchronized void signLeaseSet(LeaseSet leaseSet, I2PSessionImpl session) {
    Destination dest = session.getMyDestination();
    // also, if this session is connected to multiple routers, include other leases here
    leaseSet.setDestination(dest);
    // reuse the old keys for the client
    LeaseInfo li = _existingLeaseSets.get(dest);
    if (li == null) {
        // [enctype:]b64 of private key
        String spk = session.getOptions().getProperty("i2cp.leaseSetPrivateKey");
        // [sigtype:]b64 of private key
        String sspk = session.getOptions().getProperty("i2cp.leaseSetSigningPrivateKey");
        PrivateKey privKey = null;
        SigningPrivateKey signingPrivKey = null;
        if (spk != null && sspk != null) {
            boolean useOldKeys = true;
            int colon = sspk.indexOf(':');
            SigType type = dest.getSigType();
            if (colon > 0) {
                String stype = sspk.substring(0, colon);
                SigType t = SigType.parseSigType(stype);
                if (t == type)
                    sspk = sspk.substring(colon + 1);
                else
                    useOldKeys = false;
            }
            colon = spk.indexOf(':');
            // just ignore for now, no other types supported
            if (colon >= 0)
                spk = spk.substring(colon + 1);
            if (useOldKeys) {
                try {
                    signingPrivKey = new SigningPrivateKey(type);
                    signingPrivKey.fromBase64(sspk);
                } catch (DataFormatException iae) {
                    useOldKeys = false;
                    signingPrivKey = null;
                }
            }
            if (useOldKeys) {
                try {
                    privKey = new PrivateKey();
                    privKey.fromBase64(spk);
                } catch (DataFormatException iae) {
                    privKey = null;
                }
            }
        }
        if (privKey == null && !_existingLeaseSets.isEmpty()) {
            // look for keypair from another dest using same pubkey
            PublicKey pk = dest.getPublicKey();
            for (Map.Entry<Destination, LeaseInfo> e : _existingLeaseSets.entrySet()) {
                if (pk.equals(e.getKey().getPublicKey())) {
                    privKey = e.getValue().getPrivateKey();
                    if (_log.shouldLog(Log.DEBUG))
                        _log.debug("Creating new leaseInfo keys for " + dest + " with private key from " + e.getKey());
                    break;
                }
            }
        }
        if (privKey != null) {
            if (signingPrivKey != null) {
                li = new LeaseInfo(privKey, signingPrivKey);
                if (_log.shouldLog(Log.DEBUG))
                    _log.debug("Creating new leaseInfo keys for " + dest + " WITH configured private keys");
            } else {
                li = new LeaseInfo(privKey, dest);
            }
        } else {
            li = new LeaseInfo(dest);
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Creating new leaseInfo keys for " + dest + " without configured private keys");
        }
        _existingLeaseSets.put(dest, li);
    } else {
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("Caching the old leaseInfo keys for " + dest);
    }
    leaseSet.setEncryptionKey(li.getPublicKey());
    leaseSet.setSigningKey(li.getSigningPublicKey());
    // SubSession options aren't updated via the gui, so use the primary options
    Properties opts;
    if (session instanceof SubSession)
        opts = ((SubSession) session).getPrimaryOptions();
    else
        opts = session.getOptions();
    boolean encrypt = Boolean.parseBoolean(opts.getProperty("i2cp.encryptLeaseSet"));
    String sk = opts.getProperty("i2cp.leaseSetKey");
    Hash h = dest.calculateHash();
    if (encrypt && sk != null) {
        SessionKey key = new SessionKey();
        try {
            key.fromBase64(sk);
            leaseSet.encrypt(key);
            _context.keyRing().put(h, key);
        } catch (DataFormatException dfe) {
            _log.error("Bad leaseset key: " + sk);
            _context.keyRing().remove(h);
        }
    } else {
        _context.keyRing().remove(h);
    }
    try {
        leaseSet.sign(session.getPrivateKey());
        // Workaround for unparsable serialized signing private key for revocation
        // Send him a dummy DSA_SHA1 private key since it's unused anyway
        // See CreateLeaseSetMessage.doReadMessage()
        SigningPrivateKey spk = li.getSigningPrivateKey();
        if (!_context.isRouterContext() && spk.getType() != SigType.DSA_SHA1) {
            byte[] dummy = new byte[SigningPrivateKey.KEYSIZE_BYTES];
            _context.random().nextBytes(dummy);
            spk = new SigningPrivateKey(dummy);
        }
        session.getProducer().createLeaseSet(session, leaseSet, spk, li.getPrivateKey());
        session.setLeaseSet(leaseSet);
    } catch (DataFormatException dfe) {
        session.propogateError("Error signing the leaseSet", dfe);
    } catch (I2PSessionException ise) {
        if (session.isClosed()) {
            // race, closed while signing leaseset
            // EOFExceptions are logged at WARN level (see I2PSessionImpl.propogateError())
            // so the user won't see this
            EOFException eof = new EOFException("Session closed while signing leaseset");
            eof.initCause(ise);
            session.propogateError("Session closed while signing leaseset", eof);
        } else {
            session.propogateError("Error sending the signed leaseSet", ise);
        }
    }
}
Also used : Destination(net.i2p.data.Destination) PrivateKey(net.i2p.data.PrivateKey) SigningPrivateKey(net.i2p.data.SigningPrivateKey) SigningPublicKey(net.i2p.data.SigningPublicKey) PublicKey(net.i2p.data.PublicKey) Properties(java.util.Properties) Hash(net.i2p.data.Hash) SigType(net.i2p.crypto.SigType) SigningPrivateKey(net.i2p.data.SigningPrivateKey) DataFormatException(net.i2p.data.DataFormatException) SessionKey(net.i2p.data.SessionKey) EOFException(java.io.EOFException) I2PSessionException(net.i2p.client.I2PSessionException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Map(java.util.Map)

Example 34 with PublicKey

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

the class OutboundClientMessageOneShotJob method send.

/**
 * Send the message to the specified tunnel by creating a new garlic message containing
 * the (already created) payload clove as well as a new delivery status message.  This garlic
 * message is sent out one of our tunnels, destined for the lease (tunnel+router) specified, and the delivery
 * status message is targetting one of our free inbound tunnels as well.  We use a new
 * reply selector to keep an eye out for that delivery status message's token
 */
private void send() {
    synchronized (this) {
        if (_finished != Result.NONE) {
            if (_log.shouldLog(Log.WARN))
                _log.warn(OutboundClientMessageOneShotJob.this.getJobId() + ": SEND-AFTER-" + _finished);
            return;
        }
    }
    long now = getContext().clock().now();
    if (now >= _overallExpiration) {
        dieFatal(MessageStatusMessage.STATUS_SEND_FAILURE_EXPIRED);
        return;
    }
    _outTunnel = selectOutboundTunnel(_to);
    if (_outTunnel == null) {
        if (_log.shouldLog(Log.WARN))
            _log.warn(getJobId() + ": Could not find any outbound tunnels to send the payload through... this might take a while");
        getContext().statManager().addRateData("client.dispatchNoTunnels", now - _start);
        dieFatal(MessageStatusMessage.STATUS_SEND_FAILURE_NO_TUNNELS);
        return;
    }
    // boolean wantACK = _wantACK || existingTags <= 30 || getContext().random().nextInt(100) < 5;
    // what's the point of 5% random? possible improvements or replacements:
    // DONE (getNextLease() is called before this): wantACK if we changed their inbound lease (getNextLease() sets _wantACK)
    // DONE (selectOutboundTunnel() moved above here): wantACK if we changed our outbound tunnel (selectOutboundTunnel() sets _wantACK)
    // DONE (added new cache): wantACK if we haven't in last 1m (requires a new static cache probably)
    Long lastReplyRequestSent = _cache.lastReplyRequestCache.get(_hashPair);
    boolean shouldRequestReply = lastReplyRequestSent == null || lastReplyRequestSent.longValue() < now - REPLY_REQUEST_INTERVAL;
    int sendFlags = _clientMessage.getFlags();
    // Per-message flag > 0 overrides per-session option
    int tagsRequired = SendMessageOptions.getTagThreshold(sendFlags);
    boolean wantACK = _wantACK || shouldRequestReply || GarlicMessageBuilder.needsTags(getContext(), _leaseSet.getEncryptionKey(), _from.calculateHash(), tagsRequired);
    LeaseSet replyLeaseSet;
    // Per-message flag == false overrides session option which is default true
    String allow = _clientMessage.getSenderConfig().getOptions().getProperty(BUNDLE_REPLY_LEASESET);
    boolean allowLeaseBundle = SendMessageOptions.getSendLeaseSet(sendFlags) && (allow == null || Boolean.parseBoolean(allow));
    if (allowLeaseBundle) {
        // If we want an ack, bundle a leaseSet...
        // replyLeaseSet = getReplyLeaseSet(wantACK);
        // Only when necessary. We don't need to force.
        // ACKs find their own way back, they don't need a leaseset.
        replyLeaseSet = getReplyLeaseSet(false);
        // ... and vice versa  (so we know he got it)
        if (replyLeaseSet != null)
            wantACK = true;
    } else {
        replyLeaseSet = null;
    }
    long token;
    if (wantACK) {
        _cache.lastReplyRequestCache.put(_hashPair, Long.valueOf(now));
        token = getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE);
        _inTunnel = selectInboundTunnel();
    } else {
        token = -1;
    }
    PayloadGarlicConfig clove = buildClove();
    if (clove == null) {
        dieFatal(MessageStatusMessage.STATUS_SEND_FAILURE_UNSUPPORTED_ENCRYPTION);
        return;
    }
    // if (_log.shouldLog(Log.DEBUG))
    // _log.debug(getJobId() + ": Clove built to " + _toString);
    PublicKey key = _leaseSet.getEncryptionKey();
    SessionKey sessKey = new SessionKey();
    Set<SessionTag> tags = new HashSet<SessionTag>();
    // Per-message flag > 0 overrides per-session option
    int tagsToSend = SendMessageOptions.getTagsToSend(sendFlags);
    GarlicMessage msg = OutboundClientMessageJobHelper.createGarlicMessage(getContext(), token, _overallExpiration, key, clove, _from.calculateHash(), _to, _inTunnel, tagsToSend, tagsRequired, sessKey, tags, wantACK, replyLeaseSet);
    if (msg == null) {
        // we dont receive the reply? hmm...)
        if (_log.shouldLog(Log.WARN))
            _log.warn(getJobId() + ": Unable to create the garlic message (no tunnels left or too lagged) to " + _toString);
        getContext().statManager().addRateData("client.dispatchNoTunnels", now - _start);
        dieFatal(MessageStatusMessage.STATUS_SEND_FAILURE_NO_TUNNELS);
        return;
    }
    // if (_log.shouldLog(Log.DEBUG))
    // _log.debug(getJobId() + ": send() - token expected " + token + " to " + _toString);
    SendSuccessJob onReply = null;
    SendTimeoutJob onFail = null;
    ReplySelector selector = null;
    if (wantACK) {
        TagSetHandle tsh = null;
        if (!tags.isEmpty()) {
            SessionKeyManager skm = getContext().clientManager().getClientSessionKeyManager(_from.calculateHash());
            if (skm != null)
                tsh = skm.tagsDelivered(_leaseSet.getEncryptionKey(), sessKey, tags);
        }
        onReply = new SendSuccessJob(getContext(), sessKey, tsh);
        onFail = new SendTimeoutJob(getContext(), sessKey, tsh);
        long expiration = Math.max(_overallExpiration, _start + REPLY_TIMEOUT_MS_MIN);
        selector = new ReplySelector(token, expiration);
    }
    if (_log.shouldLog(Log.DEBUG))
        _log.debug(getJobId() + ": Sending msg out " + _outTunnel.getSendTunnelId(0) + " to " + _toString + " at " + _lease.getTunnelId() + " on " + _lease.getGateway());
    DispatchJob dispatchJob = new DispatchJob(getContext(), msg, selector, onReply, onFail);
    // if (false) // dispatch may take 100+ms, so toss it in its own job
    // getContext().jobQueue().addJob(dispatchJob);
    // else
    dispatchJob.runJob();
    getContext().statManager().addRateData("client.dispatchPrepareTime", now - _start);
    if (!wantACK)
        getContext().statManager().addRateData("client.dispatchNoACK", 1);
}
Also used : PublicKey(net.i2p.data.PublicKey) SessionKeyManager(net.i2p.crypto.SessionKeyManager) TagSetHandle(net.i2p.crypto.TagSetHandle) LeaseSet(net.i2p.data.LeaseSet) SessionKey(net.i2p.data.SessionKey) GarlicMessage(net.i2p.data.i2np.GarlicMessage) SessionTag(net.i2p.data.SessionTag) HashSet(java.util.HashSet)

Example 35 with PublicKey

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

the class MessageWrapper method wrap.

/**
 *  Garlic wrap a message from a client or this router, destined for a router,
 *  to hide the contents from the OBEP.
 *  Caller must call acked() or fail() on the returned object.
 *
 *  @param from must be a local client with a session key manager,
 *              or null to use the router's session key manager
 *  @return null on encrypt failure
 */
static WrappedMessage wrap(RouterContext ctx, I2NPMessage m, Hash from, RouterInfo to) {
    PayloadGarlicConfig payload = new PayloadGarlicConfig();
    payload.setCertificate(Certificate.NULL_CERT);
    payload.setId(ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE));
    payload.setPayload(m);
    payload.setRecipient(to);
    payload.setDeliveryInstructions(DeliveryInstructions.LOCAL);
    payload.setExpiration(m.getMessageExpiration());
    SessionKeyManager skm;
    if (from != null)
        skm = ctx.clientManager().getClientSessionKeyManager(from);
    else
        skm = ctx.sessionKeyManager();
    if (skm == null)
        return null;
    SessionKey sentKey = new SessionKey();
    Set<SessionTag> sentTags = new HashSet<SessionTag>();
    GarlicMessage msg = GarlicMessageBuilder.buildMessage(ctx, payload, sentKey, sentTags, NETDB_TAGS_TO_DELIVER, NETDB_LOW_THRESHOLD, skm);
    if (msg == null)
        return null;
    TagSetHandle tsh = null;
    PublicKey sentTo = to.getIdentity().getPublicKey();
    if (!sentTags.isEmpty())
        tsh = skm.tagsDelivered(sentTo, sentKey, sentTags);
    // _log.debug("Sent to: " + to.getIdentity().getHash() + " with key: " + sentKey + " and tags: " + sentTags.size());
    return new WrappedMessage(msg, skm, sentTo, sentKey, tsh);
}
Also used : PayloadGarlicConfig(net.i2p.router.message.PayloadGarlicConfig) SessionKey(net.i2p.data.SessionKey) PublicKey(net.i2p.data.PublicKey) SessionKeyManager(net.i2p.crypto.SessionKeyManager) GarlicMessage(net.i2p.data.i2np.GarlicMessage) 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