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;
// pick up any remaining data for delivery
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 ));
}
}
}