inputOutputHandler
Class PreviousMixConnectionHandler

java.lang.Object
  extended by java.lang.Thread
      extended by inputOutputHandler.PreviousMixConnectionHandler
All Implemented Interfaces:
java.lang.Runnable

final class PreviousMixConnectionHandler
extends java.lang.Thread

Handles communication with a previous mix (in the same cascade as this one). Waits for the previous mix to establish a permanent (TCP) connection, which is used to transmit the messages (Requests and Replyies) of all users connected to the cascade's fist mix (multiplex channel). (De-)multiplexes Requests/Replyies using an (encrypted) header (see addInterMixHeader()).

Note: Authentication is NOT implemented!

Author:
Karl-Peter Fuchs

Nested Class Summary
 
Nested classes/interfaces inherited from class java.lang.Thread
java.lang.Thread.State, java.lang.Thread.UncaughtExceptionHandler
 
Field Summary
private  java.net.InetAddress BIND_ADDRESS
          Address this PreviousMixConnectionHandler's socket shall be bound to.
private  ExternalInformationPortController externalInformationPort
          Reference on component ExternalInformationPort (Used to provide the cryptographic key used to encrypt/decrypt multiplex-headers to the previous mix.
private  java.util.concurrent.atomic.AtomicBoolean handleRepliesIsWaitingForConnection
          Indicates that method handleReplies() wants to send replies (to the previous mix), but the connection is lost (Used for synchronization, when connection is established again).
private  InputOutputHandlerController inputOutputHandler
          Reference on InputOutputHandlerController() (Used to get processed replies and add unprocessed requests).
private  int INTER_MIX_BLOCK_SIZE
          Block size of the cryptographic algorithm used to encrypt the multiplex-header.
private  javax.crypto.Cipher interMixDecryptCipherWithPreviousMix
          Cipher for decrypting multiplex-headers of requests.
private  javax.crypto.Cipher interMixEncryptCipherWithPreviousMix
          Cipher for encrypting multiplex-headers of replies.
private  javax.crypto.spec.IvParameterSpec interMixIVWithPreviousMix
          Initialization vector used to encrypt data between this mix and its predecessor.
private  javax.crypto.SecretKey interMixKeyWithPreviousMix
          Key used to encrypt data between this mix and its predecessor.
private static InternalInformationPortController internalInformationPort
          Reference on component InternalInformationPort.
private  boolean IS_LAST
          Indicates whether this mix is the lost of the cascade or not.
private static java.util.logging.Logger LOGGER
          Logger used to log and display information.
private  int NUMBER_OF_FURTHER_HOPS
          Number of further mixes between the mix this PreviousMixConnectionHandler belongs to and the receiver.
private  OutputStrategyController outputStrategy
          Reference on component OutputStrategy (Used to add ChannelReleaseMessages).
private  int PORT
          Port number this PreviousMixConnectionHandler runs on.
private  int POSITION_OF_MIX_IN_CASCADE
          The mix' position in the cascade this object belongs to. "1" means "first mix", "2" means "a middle mix" and "3" means "last mix" of cascade.
private  java.net.InetAddress PREVIOUS_MIX_ADDRESS
          Address of the previous mix in the cascade.
private  int PREVIOUS_MIX_PORT
          Port number of the previous mix in the cascade.
private  java.io.InputStream previousMixInputStream
          InputStream for communicating with previous mix.
private  java.io.OutputStream previousMixOutputStream
          OutputStream for communicating with previous mix.
private  java.net.Socket previousMixSocket
          Socket for communicating with previous mix.
private  java.net.ServerSocket serverSocket
          ServerSocket used to accept the previous mix' connection attempt.
private  UserDatabaseController userDatabase
          Reference on component UserDatabase (Used to add/remove users).
 
Fields inherited from class java.lang.Thread
MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY
 
Constructor Summary
protected PreviousMixConnectionHandler(InputOutputHandlerController inputOutputHandler, UserDatabaseController userDatabase, OutputStrategyController outputStrategy, ExternalInformationPortController externalInformationPort)
          Constructs a new PreviousMixConnectionHandler which handles communication with a previous mix (in the same cascade as this one).
 
Method Summary
protected  void acceptConnection()
          Makes this PreviousMixConnectionHandler wait for its predecessor to connect.
private  byte[] addInterMixHeader(Reply reply)
          Adds an (encrypted) header to a Reply containing an identifier for the suiting channel (the identifier is unique for any neighboured mixes).
private  User createNewUser(int userIdentifier)
          Creates a new User with the bypassed identifier.
private  byte[] decryptBlockWithHeader(byte[] blockWithHeader)
          Decrypts multiplex-header.
private  javax.crypto.spec.IvParameterSpec getInterMixIV(KeyGeneratorController keyGenerator)
          Generates an initialization vector, that can be used to encrypt multiplex-headers between this mix an its predecessor.
private  javax.crypto.SecretKey getInterMixKey(KeyGeneratorController keyGenerator)
          Generates a cryptographic key, that can be used to encrypt multiplex-headers between this mix an its predecessor.
private static java.lang.String getProperty(java.lang.String key)
          Simply used to shorten method calls (calls internalInformationPort.getProperty(key)).
private  void handleReplies()
          Waits for Replyies ready to be sent (to the previous mix).
private  boolean isAllowedToSendChannelMessage(User user)
          Indicates whether the bypassed user is allowed to send a message or not.
private  ChannelEstablishMessage readChannelEstablishMessage(byte[] blockWithHeader, User user)
          Reads a ChannelEstablishMessage from the previous mix, generates a ChannelEstablishMessage object and returns it.
private  ChannelMessage readChannelMessage(byte[] blockWithHeader, User user)
          Reads a ChannelMessage from the previous mix, generates a ChannelMessage object and returns it.
private  void resetInterMixCiphers()
          Resets the Ciphers used to encrypt data between this mix and its predecessor.
 void run()
          Receives messages from previous mix and passes them to the InputOutputHandler.
private  void setUpInterMixCiphers()
          Generates a cryptographic key, that is used to encrypt multiplex-headers between this mix an its predecessor and sets up suiting Ciphers.
private  void skipChannelEstablishMessage()
          Skips a ChannelEstablishMessage on the communication channel.
private  void skipChannelMessage()
          Skips a ChannelMessage on the communication channel.
private  void waitForConnection()
          Waits for the previous mix to establish a connection.
private  void waitForIncomingConnection()
          Waits for the previous mix to connect.
 
Methods inherited from class java.lang.Thread
activeCount, checkAccess, countStackFrames, currentThread, destroy, dumpStack, enumerate, getAllStackTraces, getContextClassLoader, getDefaultUncaughtExceptionHandler, getId, getName, getPriority, getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, resume, setContextClassLoader, setDaemon, setDefaultUncaughtExceptionHandler, setName, setPriority, setUncaughtExceptionHandler, sleep, sleep, start, stop, stop, suspend, toString, yield
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

internalInformationPort

private static InternalInformationPortController internalInformationPort
Reference on component InternalInformationPort. Used to display and/or log data and read general settings.


LOGGER

private static final java.util.logging.Logger LOGGER
Logger used to log and display information.


PORT

private final int PORT
Port number this PreviousMixConnectionHandler runs on.


BIND_ADDRESS

private final java.net.InetAddress BIND_ADDRESS
Address this PreviousMixConnectionHandler's socket shall be bound to.


POSITION_OF_MIX_IN_CASCADE

private final int POSITION_OF_MIX_IN_CASCADE
The mix' position in the cascade this object belongs to. "1" means "first mix", "2" means "a middle mix" and "3" means "last mix" of cascade.


INTER_MIX_BLOCK_SIZE

private final int INTER_MIX_BLOCK_SIZE
Block size of the cryptographic algorithm used to encrypt the multiplex-header.


PREVIOUS_MIX_ADDRESS

private final java.net.InetAddress PREVIOUS_MIX_ADDRESS
Address of the previous mix in the cascade.


PREVIOUS_MIX_PORT

private final int PREVIOUS_MIX_PORT
Port number of the previous mix in the cascade.


NUMBER_OF_FURTHER_HOPS

private final int NUMBER_OF_FURTHER_HOPS
Number of further mixes between the mix this PreviousMixConnectionHandler belongs to and the receiver.


IS_LAST

private final boolean IS_LAST
Indicates whether this mix is the lost of the cascade or not.


previousMixSocket

private java.net.Socket previousMixSocket
Socket for communicating with previous mix.


previousMixInputStream

private java.io.InputStream previousMixInputStream
InputStream for communicating with previous mix.


previousMixOutputStream

private java.io.OutputStream previousMixOutputStream
OutputStream for communicating with previous mix.


interMixEncryptCipherWithPreviousMix

private javax.crypto.Cipher interMixEncryptCipherWithPreviousMix
Cipher for encrypting multiplex-headers of replies.


interMixDecryptCipherWithPreviousMix

private javax.crypto.Cipher interMixDecryptCipherWithPreviousMix
Cipher for decrypting multiplex-headers of requests.


interMixKeyWithPreviousMix

private javax.crypto.SecretKey interMixKeyWithPreviousMix
Key used to encrypt data between this mix and its predecessor.


interMixIVWithPreviousMix

private javax.crypto.spec.IvParameterSpec interMixIVWithPreviousMix
Initialization vector used to encrypt data between this mix and its predecessor.


handleRepliesIsWaitingForConnection

private java.util.concurrent.atomic.AtomicBoolean handleRepliesIsWaitingForConnection
Indicates that method handleReplies() wants to send replies (to the previous mix), but the connection is lost (Used for synchronization, when connection is established again).

See Also:
handleReplies(), waitForIncomingConnection()

serverSocket

private java.net.ServerSocket serverSocket
ServerSocket used to accept the previous mix' connection attempt.


inputOutputHandler

private InputOutputHandlerController inputOutputHandler
Reference on InputOutputHandlerController() (Used to get processed replies and add unprocessed requests).

See Also:
InputOutputHandlerController.addUnprocessedRequest(message.Request), InputOutputHandlerController.getProcessedReply()

userDatabase

private UserDatabaseController userDatabase
Reference on component UserDatabase (Used to add/remove users).


outputStrategy

private OutputStrategyController outputStrategy
Reference on component OutputStrategy (Used to add ChannelReleaseMessages).


externalInformationPort

private ExternalInformationPortController externalInformationPort
Reference on component ExternalInformationPort (Used to provide the cryptographic key used to encrypt/decrypt multiplex-headers to the previous mix.

Constructor Detail

PreviousMixConnectionHandler

protected PreviousMixConnectionHandler(InputOutputHandlerController inputOutputHandler,
                                       UserDatabaseController userDatabase,
                                       OutputStrategyController outputStrategy,
                                       ExternalInformationPortController externalInformationPort)
Constructs a new PreviousMixConnectionHandler which handles communication with a previous mix (in the same cascade as this one). Waits for the previous mix to establish a permanent (TCP) connection, which is used to transmit the messages (Requests and Replyies) of all users connected to the cascade's fist mix (multiplex channel). (De-)multiplexes Requests/Replyies using an (encrypted) header (see addInterMixHeader()).

Requests are put in the InputOutputHandlerController's requestInputQueue (see InputOutputHandlerController.addUnprocessedRequest()). Replyies are taken from the InputOutputHandlerController's replyOutputQueue (see InputOutputHandlerController.getProcessedReply()).

Adds/removes user to/from UserDatabase.

Note: Authentication is NOT implemented!

Parameters:
inputOutputHandler - Reference on InputOutputHandlerController (Used to add messages).
userDatabase - Reference on component UserDatabase (Used to add/remove User)s.
outputStrategy - Reference on component OutputStrategy (Used to add ChannelReleaseMessages).
externalInformationPort - Reference on component ExternalInformationPort (Used to provide the cryptographic key used to encrypt/decrypt multiplex-headers to the previous mix.
Method Detail

acceptConnection

protected void acceptConnection()
Makes this PreviousMixConnectionHandler wait for its predecessor to connect.


handleReplies

private void handleReplies()
Waits for Replyies ready to be sent (to the previous mix).


waitForConnection

private void waitForConnection()
Waits for the previous mix to establish a connection.


addInterMixHeader

private byte[] addInterMixHeader(Reply reply)
Adds an (encrypted) header to a Reply containing an identifier for the suiting channel (the identifier is unique for any neighboured mixes).

Parameters:
reply - Reply without header.
Returns:
Reply with header.

run

public void run()
Receives messages from previous mix and passes them to the InputOutputHandler.

Specified by:
run in interface java.lang.Runnable
Overrides:
run in class java.lang.Thread
See Also:
InputOutputHandlerController.addUnprocessedRequest(message.Request)

waitForIncomingConnection

private void waitForIncomingConnection()
Waits for the previous mix to connect. Called when connection to previous mix is lost.


decryptBlockWithHeader

private byte[] decryptBlockWithHeader(byte[] blockWithHeader)
Decrypts multiplex-header.

Parameters:
blockWithHeader - Block of the Request containing the multiplex-header.
Returns:
Decrypted multiplex-header.

createNewUser

private User createNewUser(int userIdentifier)
                    throws java.io.IOException,
                           UserAlreadyExistingException
Creates a new User with the bypassed identifier.

Parameters:
userIdentifier - Used to identify to which user/channel a message belongs.
Returns:
New User.
Throws:
java.io.IOException - If an I/O error occurres.
UserAlreadyExistingException - If a User with the specified identifier is already existing (-> attack or collision).

skipChannelEstablishMessage

private void skipChannelEstablishMessage()
                                  throws java.io.IOException
Skips a ChannelEstablishMessage on the communication channel.

Throws:
java.io.IOException - If an I/O error occurres.

skipChannelMessage

private void skipChannelMessage()
                         throws java.io.IOException
Skips a ChannelMessage on the communication channel.

Throws:
java.io.IOException - If an I/O error occurres.

readChannelEstablishMessage

private ChannelEstablishMessage readChannelEstablishMessage(byte[] blockWithHeader,
                                                            User user)
                                                     throws java.io.IOException
Reads a ChannelEstablishMessage from the previous mix, generates a ChannelEstablishMessage object and returns it.

Parameters:
blockWithHeader - First part of the message (already received since overlapped by the block including the multiplex-header).
user - User the returned message belongs to.
Returns:
The received ChannelEstablishMessage;
Throws:
java.io.IOException - If an I/O error occurres.

readChannelMessage

private ChannelMessage readChannelMessage(byte[] blockWithHeader,
                                          User user)
                                   throws java.io.IOException
Reads a ChannelMessage from the previous mix, generates a ChannelMessage object and returns it.

Parameters:
blockWithHeader - First part of the message (already received since overlapped by the block including the multiplex-header).
user - User the returned message belongs to.
Returns:
The received ChannelMessage;
Throws:
java.io.IOException - If an I/O error occurres.

isAllowedToSendChannelMessage

private boolean isAllowedToSendChannelMessage(User user)
Indicates whether the bypassed user is allowed to send a message or not.

Parameters:
user - Reference on User who's authorization shall be checked.
Returns:
Whether the bypassed user is allowed to send a message or not.

setUpInterMixCiphers

private void setUpInterMixCiphers()
Generates a cryptographic key, that is used to encrypt multiplex-headers between this mix an its predecessor and sets up suiting Ciphers.


resetInterMixCiphers

private void resetInterMixCiphers()
Resets the Ciphers used to encrypt data between this mix and its predecessor. Must be called when connection was lost, since Ciphers might be out of sync in that case.


getInterMixIV

private javax.crypto.spec.IvParameterSpec getInterMixIV(KeyGeneratorController keyGenerator)
Generates an initialization vector, that can be used to encrypt multiplex-headers between this mix an its predecessor.

Parameters:
keyGenerator - Reference on component KeyGenerator (Used to generate the initialization vector).
Returns:
An initialization vector, that can be used to encrypt multiplex-headers between this mix an its predecessor.

getInterMixKey

private javax.crypto.SecretKey getInterMixKey(KeyGeneratorController keyGenerator)
Generates a cryptographic key, that can be used to encrypt multiplex-headers between this mix an its predecessor.

Parameters:
keyGenerator - Reference on component KeyGenerator (Used to generate the cryptographic key).
Returns:
A cryptographic key, that can be used to encrypt multiplex-headers between this mix an its predecessor.

getProperty

private static java.lang.String getProperty(java.lang.String key)
Simply used to shorten method calls (calls internalInformationPort.getProperty(key)). Returns the property with the specified key from the property file.

Parameters:
key - The property key.
Returns:
The property with the specified key in the property file.