0

I have read a lot of the questions/replies to java socket programming, but none of them apply to my current issue.

I have written a basic java ssl socket program, whose sole purpose (for the moment) is to establish an ssl connection between the client and server and send one signed message by the client. If the message gets verified by the server, it should reply accordingly with (true!) or otherwise with (false!).

I get stuck after the handshake pase, when the client sends a "message" to the server and waits for the server to respond. Meanwhile the server does not process the message the client sent, so it can't respond and there I am waiting for either of them go it over with.

Can you tell me where I made a mistake?

In order not to display huge amounts of not relevant code I have not included the value object SignedMessage nor the Utils class. The methods used from the utils class are for serialization and deserialization and for converting a String to an array of bytes. I know that I could have used String.getBytes(), but I liked to have the conversion done by hand. All mentioned methods have been tested and work fine.

the ServerThread run method code

public void run() {
    try {
        InputStream in = sslSocket.getInputStream();
        OutputStream out = sslSocket.getOutputStream();

        //if I write some output here the program works well, but this is not what I want to do 
        //out.write('!');

        //BASE64 DECODING
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        int ch;
        while((ch = in.read()) != -1)
            bos.write(ch);

        ByteArrayOutputStream decoded = new ByteArrayOutputStream();
        Base64Encoder encoder = new Base64Encoder();
        encoder.decode(bos.toByteArray(), 0, bos.toByteArray().length, decoded);

        //reconstructing the the SignedMessage object

        SignedMessage signedMessage = (SignedMessage) Utils.deserializeObject(decoded.toByteArray());

        if(checkSignature(signedMessage.getMessage().getBytes("UTF-8"), signedMessage.getSignature(), signedMessage.getCertificate())){
            System.out.println(String.valueOf(signedMessage.getMessage()));

            //this i where I would like to write out the answer, but the code never get executed
            out.write(Utils.toByteArray("TRUE!"));
            out.flush();
        }
        else {
            out.write(Utils.toByteArray("false!"));
        }

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            sslSocket.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    System.out.println("Thread closed");
}

This is the Client code which does the communication

static void doProtocol(SSLSocket sslSocket) throws IOException, UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException  {

    OutputStream     out = sslSocket.getOutputStream();
    InputStream      in = sslSocket.getInputStream();

    byte[] signature = generateSignature(Utils.toByteArray(Message), (PrivateKey) clientStore.getKey(Utils.CLIENT_NAME, Utils.CLIENT_PASSWORD), 
            clientStore.getCertificate(Utils.CLIENT_NAME).getPublicKey().getAlgorithm());

    //BASE64 ENCODING
    byte[] object = Utils.serializeObject(new SignedMessage(Message, signature, clientStore.getCertificate(Utils.CLIENT_NAME)));

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    Base64Encoder encoder = new Base64Encoder();
    encoder.encode(object, 0, object.length, bos);

    out.write(bos.toByteArray());
    out.flush();

    int ch;
    while((ch = in.read()) != '!')
        bos.write(ch);

    System.out.println("Sesion closed");
}
proton
  • 3
  • 2
  • looks like your server thread runs, tries to read from the socket, and then ends? thus only processing the handshake? – Karl-Bjørnar Øie May 26 '11 at 12:58
  • The point is that I want the server thread to check if the message the client sent is valid or not and make it's answer based on that information. When I debug the code, the server never gets to the point where it analyses the client message because the client get stuck trying to read the server reply. – proton May 26 '11 at 13:02
  • You won't read EOS until the peer closes the connection. But I don't see why all the ByteArrayOutputStreams, encoders/decoders, etc. You could do all that with ObjectInput/OutputStreams wrapped directly around the socket streams and save yourself a lot of timeand space. – user207421 May 26 '11 at 13:10

1 Answers1

3

this

while((ch = in.read()) != -1)
        bos.write(ch);

blocks forever. This actually will unblock when the stream (connection) is closed. So it's up to you to identify end of message. I mean that end of message does not mean end of stream. So After you've received your message you will infinitely wait for smth else from the channel. As you actually did here

while((ch = in.read()) != '!')
    bos.write(ch);
Oleg
  • 798
  • 3
  • 7