Search in sources :

Example 6 with MessageException

use of com.biglybt.pif.messaging.MessageException in project BiglyBT by BiglySoftware.

the class SESTSConnectionImpl method send.

@Override
public void send(PooledByteBuffer message) throws MessageException {
    if (failed) {
        throw (new MessageException("Connection failed"));
    }
    try {
        if (crypto_complete.isReleasedForever()) {
            sendContent(message);
        } else {
            synchronized (this) {
                if (pending_message == null) {
                    pending_message = message;
                }
            }
        }
        crypto_complete.reserve();
        // if the pending message couldn't be piggy backed it'll still be allocated
        boolean send_it = false;
        synchronized (this) {
            if (pending_message == message) {
                pending_message = null;
                send_it = true;
            }
        }
        if (send_it) {
            sendContent(message);
        }
    } catch (Throwable e) {
        setFailed();
        if (e instanceof MessageException) {
            throw ((MessageException) e);
        } else {
            throw (new MessageException("Send failed", e));
        }
    }
}
Also used : MessageException(com.biglybt.pif.messaging.MessageException)

Example 7 with MessageException

use of com.biglybt.pif.messaging.MessageException in project BiglyBT by BiglySoftware.

the class SESTSConnectionImpl method setupBlockCrypto.

protected void setupBlockCrypto() throws MessageException {
    if (!failed) {
        if (block_crypto == SESecurityManager.BLOCK_ENCRYPTION_NONE) {
            return;
        }
        try {
            byte[] shared_secret = sts_engine.getSharedSecret();
            SecretKeySpec secret_key_spec1 = new SecretKeySpec(shared_secret, 0, 16, "AES");
            SecretKeySpec secret_key_spec2 = new SecretKeySpec(shared_secret, 8, 16, "AES");
            AlgorithmParameterSpec param_spec1 = new IvParameterSpec(AES_IV1);
            AlgorithmParameterSpec param_spec2 = new IvParameterSpec(AES_IV2);
            Cipher cipher1 = Cipher.getInstance("AES/CBC/PKCS5Padding");
            Cipher cipher2 = Cipher.getInstance("AES/CBC/PKCS5Padding");
            if (connection.isIncoming()) {
                cipher1.init(Cipher.ENCRYPT_MODE, secret_key_spec1, param_spec1);
                cipher2.init(Cipher.DECRYPT_MODE, secret_key_spec2, param_spec2);
                incoming_cipher = cipher2;
                outgoing_cipher = cipher1;
            } else {
                cipher1.init(Cipher.DECRYPT_MODE, secret_key_spec1, param_spec1);
                cipher2.init(Cipher.ENCRYPT_MODE, secret_key_spec2, param_spec2);
                incoming_cipher = cipher1;
                outgoing_cipher = cipher2;
            }
        } catch (Throwable e) {
            throw (new MessageException("Failed to setup block encryption", e));
        }
    }
}
Also used : MessageException(com.biglybt.pif.messaging.MessageException) SecretKeySpec(javax.crypto.spec.SecretKeySpec) IvParameterSpec(javax.crypto.spec.IvParameterSpec) Cipher(javax.crypto.Cipher) AlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec)

Example 8 with MessageException

use of com.biglybt.pif.messaging.MessageException in project BiglyBT by BiglySoftware.

the class SESTSConnectionImpl method receiveContent.

protected void receiveContent(PooledByteBuffer message) throws MessageException {
    boolean buffer_handled = false;
    try {
        if (incoming_cipher != null) {
            try {
                byte[] enc = message.toByteArray();
                byte[] plain = incoming_cipher.doFinal(enc);
                PooledByteBuffer temp = new PooledByteBufferImpl(plain);
                message.returnToPool();
                buffer_handled = true;
                message = temp;
            } catch (Throwable e) {
                throw (new MessageException("Failed to decrypt data", e));
            }
        } else if (block_crypto != SESecurityManager.BLOCK_ENCRYPTION_NONE) {
            throw (new MessageException("Crypto isn't setup"));
        }
        List listeners_ref = listeners.getList();
        MessageException last_error = null;
        for (int i = 0; i < listeners_ref.size(); i++) {
            PooledByteBuffer message_to_deliver;
            if (i == 0) {
                message_to_deliver = message;
            } else {
                // unlikely we'll ever have > 1 receiver....
                message_to_deliver = new PooledByteBufferImpl(message.toByteArray());
            }
            try {
                ((GenericMessageConnectionListener) listeners_ref.get(i)).receive(this, message_to_deliver);
                if (message_to_deliver == message) {
                    buffer_handled = true;
                }
            } catch (Throwable e) {
                message_to_deliver.returnToPool();
                if (message_to_deliver == message) {
                    buffer_handled = true;
                }
                if (e instanceof MessageException) {
                    last_error = (MessageException) e;
                } else {
                    last_error = new MessageException("Failed to process message", e);
                }
            }
        }
        if (last_error != null) {
            throw (last_error);
        }
    } finally {
        if (!buffer_handled) {
            message.returnToPool();
        }
    }
}
Also used : GenericMessageConnectionListener(com.biglybt.pif.messaging.generic.GenericMessageConnectionListener) PooledByteBufferImpl(com.biglybt.pifimpl.local.utils.PooledByteBufferImpl) MessageException(com.biglybt.pif.messaging.MessageException) PooledByteBuffer(com.biglybt.pif.utils.PooledByteBuffer) ArrayList(java.util.ArrayList) List(java.util.List) GenericMessageEndpoint(com.biglybt.pif.messaging.generic.GenericMessageEndpoint)

Example 9 with MessageException

use of com.biglybt.pif.messaging.MessageException in project BiglyBT by BiglySoftware.

the class SESTSConnectionImpl method receive.

public void receive(PooledByteBuffer message) throws MessageException {
    try {
        boolean forward = false;
        boolean crypto_completed = false;
        ByteBuffer out_buffer = null;
        synchronized (this) {
            if (crypto_complete.isReleasedForever()) {
                forward = true;
            } else {
                // basic sts flow:
                // a -> puba -> b
                // a <- pubb <- b
                // a -> auta -> b
                // a <- autb <- b
                // a -> data -> b
                // optimised
                // a -> puba 		 -> b
                // a <- pubb + auta <- b
                // a -> autb + data -> b
                // therefore can be one or two messages in the payload
                // 1 crypto
                // 2 crypto (pub + auth)
                // crypto + data
                // initial a ->puba -> is done on first data send so data is ready for phase 3
                ByteBuffer in_buffer = ByteBuffer.wrap(message.toByteArray());
                message.returnToPool();
                if (!sent_keys) {
                    // we've received
                    // a -> puba -> b
                    // reply with
                    // a <- puba + auta <- b
                    out_buffer = ByteBuffer.allocate(64 * 1024);
                    // write our keys
                    sts_engine.getKeys(out_buffer);
                    sent_keys = true;
                    // read their keys
                    sts_engine.putKeys(in_buffer);
                    // write our auth
                    sts_engine.getAuth(out_buffer);
                    sent_auth = true;
                } else if (!sent_auth) {
                    out_buffer = ByteBuffer.allocate(64 * 1024);
                    // we've received
                    // a <- puba + auta <- b
                    // reply with
                    // a -> autb + data -> b
                    // read their keys
                    sts_engine.putKeys(in_buffer);
                    // write our auth
                    sts_engine.getAuth(out_buffer);
                    sent_auth = true;
                    // read their auth
                    sts_engine.putAuth(in_buffer);
                    // check we wanna talk to this person
                    byte[] rem_key = sts_engine.getRemotePublicKey();
                    if (!key_locator.accept(SESTSConnectionImpl.this, new SEPublicKeyImpl(my_public_key.getType(), rem_key))) {
                        throw (new MessageException("remote public key not accepted"));
                    }
                    setupBlockCrypto();
                    if (pending_message != null) {
                        byte[] pending_bytes = pending_message.toByteArray();
                        int pending_size = pending_bytes.length;
                        if (outgoing_cipher != null) {
                            pending_size = ((pending_size + AES_KEY_SIZE_BYTES - 1) / AES_KEY_SIZE_BYTES) * AES_KEY_SIZE_BYTES;
                            if (pending_size == 0) {
                                pending_size = AES_KEY_SIZE_BYTES;
                            }
                        }
                        if (out_buffer.remaining() >= pending_size) {
                            if (outgoing_cipher != null) {
                                out_buffer.put(outgoing_cipher.doFinal(pending_bytes));
                            } else {
                                out_buffer.put(pending_bytes);
                            }
                            // don't deallocate the pending message, the original caller does this
                            pending_message = null;
                        }
                    }
                    crypto_completed = true;
                } else {
                    // we've received
                    // a -> autb + data -> b
                    // read their auth
                    sts_engine.putAuth(in_buffer);
                    // check we wanna talk to this person
                    byte[] rem_key = sts_engine.getRemotePublicKey();
                    if (!key_locator.accept(SESTSConnectionImpl.this, new SEPublicKeyImpl(my_public_key.getType(), rem_key))) {
                        // this is just here to prevent unwanted spew  during closedown process
                        connection.closing();
                        throw (new MessageException("remote public key not accepted"));
                    }
                    setupBlockCrypto();
                    crypto_completed = true;
                    if (in_buffer.hasRemaining()) {
                        message = new PooledByteBufferImpl(new DirectByteBuffer(in_buffer.slice()));
                        forward = true;
                    }
                }
            }
        }
        if (out_buffer != null) {
            out_buffer.flip();
            connection.send(new PooledByteBufferImpl(new DirectByteBuffer(out_buffer)));
        }
        if (crypto_completed) {
            cryptoComplete();
        }
        if (forward) {
            receiveContent(message);
        }
    } catch (Throwable e) {
        reportFailed(e);
        if (e instanceof MessageException) {
            throw ((MessageException) e);
        } else {
            throw (new MessageException("Receive failed", e));
        }
    }
}
Also used : PooledByteBufferImpl(com.biglybt.pifimpl.local.utils.PooledByteBufferImpl) MessageException(com.biglybt.pif.messaging.MessageException) PooledByteBuffer(com.biglybt.pif.utils.PooledByteBuffer) ByteBuffer(java.nio.ByteBuffer)

Example 10 with MessageException

use of com.biglybt.pif.messaging.MessageException in project BiglyBT by BiglySoftware.

the class GenericMessageConnectionImpl method receive.

protected void receive(GenericMessage message) {
    boolean handled = false;
    for (int i = 0; i < listeners.size(); i++) {
        PooledByteBuffer buffer = new PooledByteBufferImpl(message.getPayload());
        try {
            ((GenericMessageConnectionListener) listeners.get(i)).receive(this, buffer);
            handled = true;
        } catch (Throwable f) {
            buffer.returnToPool();
            if (!(f instanceof MessageException)) {
                Debug.printStackTrace(f);
            }
        }
    }
    if (!handled && !(closed || closing)) {
        Debug.out("GenericMessage: incoming message not handled");
    }
}
Also used : GenericMessageConnectionListener(com.biglybt.pif.messaging.generic.GenericMessageConnectionListener) PooledByteBufferImpl(com.biglybt.pifimpl.local.utils.PooledByteBufferImpl) MessageException(com.biglybt.pif.messaging.MessageException) PooledByteBuffer(com.biglybt.pif.utils.PooledByteBuffer) GenericMessageEndpoint(com.biglybt.pif.messaging.generic.GenericMessageEndpoint)

Aggregations

MessageException (com.biglybt.pif.messaging.MessageException)14 GenericMessageEndpoint (com.biglybt.pif.messaging.generic.GenericMessageEndpoint)6 PooledByteBuffer (com.biglybt.pif.utils.PooledByteBuffer)5 PooledByteBufferImpl (com.biglybt.pifimpl.local.utils.PooledByteBufferImpl)4 GenericMessageConnectionListener (com.biglybt.pif.messaging.generic.GenericMessageConnectionListener)3 InetSocketAddress (java.net.InetSocketAddress)3 ByteBuffer (java.nio.ByteBuffer)3 NATTraversalObserver (com.biglybt.core.nat.NATTraversalObserver)1 NATTraverser (com.biglybt.core.nat.NATTraverser)1 NetworkConnection (com.biglybt.core.networkmanager.NetworkConnection)1 NetworkManager (com.biglybt.core.networkmanager.NetworkManager)1 TransportHelper (com.biglybt.core.networkmanager.impl.TransportHelper)1 MessageStreamDecoder (com.biglybt.core.peermanager.messaging.MessageStreamDecoder)1 MessageStreamEncoder (com.biglybt.core.peermanager.messaging.MessageStreamEncoder)1 MessageStreamFactory (com.biglybt.core.peermanager.messaging.MessageStreamFactory)1 CryptoManagerException (com.biglybt.core.security.CryptoManagerException)1 SHA1Simple (com.biglybt.core.util.SHA1Simple)1 GenericMessageConnection (com.biglybt.pif.messaging.generic.GenericMessageConnection)1 GenericMessageHandler (com.biglybt.pif.messaging.generic.GenericMessageHandler)1 GenericMessageRegistration (com.biglybt.pif.messaging.generic.GenericMessageRegistration)1