@@ -252,8 +252,10 @@ private synchronized void confirmObjectIsActive()
252252 private native int getUsingNonblock (long ssl );
253253 private native int getFd (long ssl );
254254 private native int connect (long ssl , int timeout );
255- private native int write (long ssl , byte [] data , int length , int timeout );
256- private native int read (long ssl , byte [] data , int sz , int timeout );
255+ private native int write (long ssl , byte [] data , int offset , int length ,
256+ int timeout );
257+ private native int read (long ssl , byte [] data , int offset , int sz ,
258+ int timeout );
257259 private native int accept (long ssl , int timeout );
258260 private native void freeSSL (long ssl );
259261 private native int shutdownSSL (long ssl , int timeout );
@@ -728,7 +730,7 @@ public int write(byte[] data, int length)
728730 * is locked here, since we call select() inside native JNI we
729731 * could timeout waiting for corresponding read() operation to
730732 * occur if needed */
731- ret = write (getSessionPtr (), data , length , 0 );
733+ ret = write (getSessionPtr (), data , 0 , length , 0 );
732734
733735 if (ret == WOLFJNI_SELECT_FAIL ) {
734736 throw new SocketException ("Socket select() failed, errno = " +
@@ -778,14 +780,58 @@ public int write(byte[] data, int length, int timeout)
778780
779781 int ret ;
780782
783+ return write (data , 0 , length , timeout );
784+ }
785+
786+ /**
787+ * Write bytes from a byte array to the SSL connection, using socket
788+ * timeout value in milliseconds.
789+ * If necessary, <code>write()</code> will negotiate an SSL/TLS session
790+ * if the handshake has not already been performed yet by <code>connect
791+ * </code> or <code>accept</code>.
792+ * <p>
793+ * <code>write()</code> works with both blocking and non-blocking I/O.
794+ * When the underlying I/O is non-blocking, <code>write()</code> will
795+ * return when the underlying I/O could not satisfy the needs of <code>
796+ * write()</code> to continue. In this case, a call to <code>getError
797+ * </code> will yield either <b>SSL_ERROR_WANT_READ</b> or
798+ * <b>SSL_ERROR_WANT_WRITE</b>. The calling process must then repeat the
799+ * call to <code>write()</code> when the underlying I/O is ready.
800+ * <p>
801+ * If the underlying I/O is blocking, <code>write()</code> will only
802+ * return once the buffer <b>data</b> of size <b>length</b> has been
803+ * completely written or an error occurred.
804+ *
805+ * @param data data buffer which will be sent to peer
806+ * @param offset offset into data buffer to start writing from
807+ * @param length size, in bytes, of data to send to the peer
808+ * @param timeout read timeout, milliseconds.
809+ * @return the number of bytes written upon success. <code>0
810+ * </code>will be returned upon failure. <code>
811+ * SSL_FATAL_ERROR</code>upon failure when either an
812+ * error occurred or, when using non-blocking sockets,
813+ * the <b>SSL_ERROR_WANT_READ</b> or
814+ * <b>SSL_ERROR_WANT_WRITE</b> error was received and the
815+ * application needs to call <code>write()</code> again.
816+ * <code>BAD_FUNC_ARC</code> when bad arguments are used.
817+ * Use <code>getError</code> to get a specific error code.
818+ * @throws IllegalStateException WolfSSLContext has been freed
819+ * @throws SocketTimeoutException if socket timeout occurs
820+ * @throws SocketException Native socket select() failed
821+ */
822+ public int write (byte [] data , int offset , int length , int timeout )
823+ throws IllegalStateException , SocketTimeoutException , SocketException {
824+
825+ int ret ;
826+
781827 confirmObjectIsActive ();
782828
783829 /* not synchronizing on sslLock here since JNI write() locks
784830 * session mutex around native wolfSSL_write() call. If sslLock
785831 * is locked here, since we call select() inside native JNI we
786832 * could timeout waiting for corresponding read() operation to
787833 * occur if needed */
788- ret = write (getSessionPtr (), data , length , timeout );
834+ ret = write (getSessionPtr (), data , offset , length , timeout );
789835
790836 if (ret == WOLFJNI_TIMEOUT ) {
791837 throw new SocketTimeoutException ("Socket write timeout" );
@@ -845,7 +891,7 @@ public int read(byte[] data, int sz)
845891 * is locked here, since we call select() inside native JNI we
846892 * could timeout waiting for corresponding write() operation to
847893 * occur if needed */
848- ret = read (getSessionPtr (), data , sz , 0 );
894+ ret = read (getSessionPtr (), data , 0 , sz , 0 );
849895
850896 if (ret == WOLFJNI_SELECT_FAIL ) {
851897 throw new SocketException ("Socket select() failed, errno = " +
@@ -897,14 +943,60 @@ public int read(byte[] data, int sz, int timeout)
897943
898944 int ret ;
899945
946+ return read (data , 0 , sz , timeout );
947+ }
948+
949+ /**
950+ * Reads bytes from the SSL session and returns the read bytes as a byte
951+ * array, using socket timeout value in milliseconds.
952+ * The bytes read are removed from the internal receive buffer.
953+ * <p>
954+ * If necessary, <code>read()</code> will negotiate an SSL/TLS session
955+ * if the handshake has not already been performed yet by <code>connect()
956+ * </code> or <code>accept()</code>.
957+ * <p>
958+ * The SSL/TLS protocol uses SSL records which have a maximum size of
959+ * 16kB. As such, wolfSSL needs to read an entire SSL record internally
960+ * before it is able to process and decrypt the record. Because of this,
961+ * a call to <code>read()</code> will only be able to return the
962+ * maximum buffer size which has been decrypted at the time of calling.
963+ * There may be additional not-yet-decrypted data waiting in the internal
964+ * wolfSSL receive buffer which will be retrieved and decrypted with the
965+ * next call to <code>read()</code>.
966+ *
967+ * @param data buffer where the data read from the SSL connection
968+ * will be placed.
969+ * @param offset offset into data buffer for data to be placed.
970+ * @param sz number of bytes to read into <b><code>data</code></b>
971+ * @param timeout read timeout, milliseconds.
972+ * @return the number of bytes read upon success. <code>SSL_FAILURE
973+ * </code> will be returned upon failure which may be caused
974+ * by either a clean (close notify alert) shutdown or just
975+ * that the peer closed the connection. <code>
976+ * SSL_FATAL_ERROR</code> upon failure when either an error
977+ * occurred or, when using non-blocking sockets, the
978+ * <b>SSL_ERROR_WANT_READ</b> or <b>SSL_ERROR_WANT_WRITE</b>
979+ * error was received and the application needs to call
980+ * <code>read()</code> again. Use <code>getError</code> to
981+ * get a specific error code.
982+ * <code>BAD_FUNC_ARC</code> when bad arguments are used.
983+ * @throws IllegalStateException WolfSSLContext has been freed
984+ * @throws SocketTimeoutException if socket timeout occurs
985+ * @throws SocketException Native socket select() failed
986+ */
987+ public int read (byte [] data , int offset , int sz , int timeout )
988+ throws IllegalStateException , SocketTimeoutException , SocketException {
989+
990+ int ret ;
991+
900992 confirmObjectIsActive ();
901993
902994 /* not synchronizing on sslLock here since JNI read() locks
903995 * session mutex around native wolfSSL_read() call. If sslLock
904996 * is locked here, since we call select() inside native JNI we
905997 * could timeout waiting for corresponding write() operation to
906998 * occur if needed */
907- ret = read (getSessionPtr (), data , sz , timeout );
999+ ret = read (getSessionPtr (), data , offset , sz , timeout );
9081000
9091001 if (ret == WOLFJNI_TIMEOUT ) {
9101002 throw new SocketTimeoutException ("Socket read timeout" );
0 commit comments