Date: Tue, 12 May 1998 18:25:18 -0700 (PDT)
From: Jan Luehe <Jan.Luehe@Eng>
Subject: Re: Possible bug in JCE 1.2
To: java-security-bugs@puffin.eng.sun.com, java-security@web1.javasoft.com,
Farzad:
> This might be a possible bug in JCE 1.2 or it might be my ignorance,
> but here is the situation.
>
> I have a client-server socket set up
> 1. the client reads a file
> 2. creates a socket connection to the server
> 3. creates a cipherOutputstream on the socket's outputStream
> and send the file's contents on it.
> at the server end
> 4. the server has a cipherInputStream which reads the transmitted data
> here is where the problem occurs
> a. the first read returns only 504 bytes
> seeing the traces, I've noticed that the packet sizes are 512, so is
> the first packet not containing the complete data ? or is the TCP
> packet not passed correctly to the higher level.
512 is the size of an internal buffer in CipherInputStream
that holds data that have been read from the
underlying input stream, but have not yet been processed by the
encapsulated cipher object. We read the data from the underlying
input stream in chunks of 512 bytes.
>From the first 512 bytes read, the encapsulated Cipher processes
the first 504 bytes and returns them to the application. It buffers
the last 8 bytes, which may be padding bytes (since "PKCS5Padding"
is specified in your program). 504 bytes are returned to the
application (see your program output).
If the next "read" operation from the underlying SocketInputStream
(inside of CipherInputStream) returns -1, the Cipher object
figures out the padding, strips off the padding bytes, and returns
the remaining (processed) data to the application.
Otherwise, we read the next 512 bytes into the internal buffer
in CipherInputStream and update the encapsulated Cipher object with
them. The Cipher object processes the 8 bytes previously buffered
along with the first 504 bytes of the data block just read, returns
the result of that operation (512 bytes), and buffers the
last 8 bytes of the data block.
512 bytes are returned to the application (see your program output).
This goes on and on, until no more data are read from the underlying
SocketInputStream.
Note that if you initialize the Cipher object with "NoPadding",
no bytes will be buffered by the Cipher object, i.e., the
512 bytes read will be processed and returned.
In that case, the first read operation by the server will return
512 (instead of 504!) bytes.
Note that in this case, the total length of the input data
(written by the client) must already be a multiple of 8!
> b. read never returns a -1 to signal end of transmission. hence the
> socket sits in an infinite loop waiting to the last packet.
You should do a close() operation on the CipherInputStream
(CipherOutputStream) when you are done reading from (writing to)
it.
Hope this helps,
Jan