@@ -134,6 +134,14 @@ public class WolfSSLEngine extends SSLEngine {
134134 * inside SendAppData, of size SSLSession.getApplicationBufferSize() */
135135 private ByteBuffer staticAppDataBuf = null ;
136136
137+ /* Largest plaintext byte count written into staticAppDataBuf by the most
138+ * recent SendAppData() call. Used to bound the post-write zeroing range
139+ * so residual plaintext from a prior larger write is wiped even when the
140+ * current write is smaller. Bytes past max(sendSz, lastSendSz) never need
141+ * zeroing here: ByteBuffer.allocateDirect() zero-initializes the buffer,
142+ * and SendAppData() is the only writer of plaintext into it. */
143+ private int lastSendSz = 0 ;
144+
137145 /* Stashed decrypted data when output buffer too small.
138146 * Served on next unwrap() without calling ssl_read(). */
139147 private byte [] pendingAppData = null ;
@@ -780,14 +788,31 @@ private synchronized int SendAppData(ByteBuffer[] in, int ofst, int len)
780788 WolfSSLDebug .log (getClass (), WolfSSLDebug .INFO ,
781789 () -> "calling ssl.write() with size: " + tmpSendSz );
782790
783- synchronized (ioLock ) {
784- ret = this .ssl .write (dataArr , sendSz );
785- }
786- if (ret <= 0 ) {
787- /* error, reset in[] positions for next call */
788- for (i = ofst ; i < ofst + len ; i ++) {
789- in [i ].position (pos [i - ofst ]);
791+ try {
792+ synchronized (ioLock ) {
793+ ret = this .ssl .write (dataArr , sendSz );
790794 }
795+ if (ret <= 0 ) {
796+ /* error, reset in[] positions for next call */
797+ for (i = ofst ; i < ofst + len ; i ++) {
798+ in [i ].position (pos [i - ofst ]);
799+ }
800+ }
801+ } finally {
802+ /* Zero plaintext from heap and direct buffers even on exception.
803+ * Zero up to max(sendSz, lastSendSz) bytes so bytes from a prior
804+ * larger write are wiped if needed. */
805+ Arrays .fill (dataArr , (byte )0 );
806+ int zeroSz = Math .max (sendSz , this .lastSendSz );
807+ /* clear() resets position/limit only, does not zero bytes */
808+ this .staticAppDataBuf .clear ();
809+ /* Bulk put faster than a per-byte loop on DirectByteBuffer */
810+ this .staticAppDataBuf .put (dataArr , 0 , sendSz );
811+ /* Loop wipes [sendSz, lastSendSz) when previous write was larger */
812+ for (int j = sendSz ; j < zeroSz ; j ++) {
813+ this .staticAppDataBuf .put ((byte )0 );
814+ }
815+ this .lastSendSz = sendSz ;
791816 }
792817
793818 final int tmpRet = ret ;
@@ -1077,17 +1102,19 @@ else if (produced == 0) {
10771102 * @return number of available/remaining bytes in array of ByteBuffers
10781103 * @throws IllegalArgumentException if readonly buffer found
10791104 */
1080- private static synchronized int getTotalOutputSize (ByteBuffer [] out ,
1081- int ofst , int length ) {
1105+ private static int getTotalOutputSize (ByteBuffer [] out ,
1106+ int ofst , int length ) {
1107+
10821108 int i = 0 ;
10831109 int maxOutSz = 0 ;
10841110
10851111 for (i = 0 ; i < length ; i ++) {
1086- if (out [i + ofst ] == null || out [i + ofst ].isReadOnly ()) {
1112+ ByteBuffer buf = out [i + ofst ];
1113+ if (buf == null || buf .isReadOnly ()) {
10871114 throw new IllegalArgumentException (
10881115 "null or readonly out buffer found" );
10891116 }
1090- maxOutSz += out [ i + ofst ] .remaining ();
1117+ maxOutSz += buf .remaining ();
10911118 }
10921119
10931120 return maxOutSz ;
@@ -2301,7 +2328,9 @@ else if (!this.needInit && !this.handshakeFinished) {
23012328 this .handshakeStartedExplicitly = true ;
23022329
23032330 } catch (SocketTimeoutException e ) {
2304- e .printStackTrace ();
2331+ WolfSSLDebug .log (getClass (), WolfSSLDebug .ERROR ,
2332+ () -> "doHandshake() timed out in beginHandshake(): " +
2333+ e .getMessage ());
23052334 throw new SSLException (e );
23062335
23072336 } finally {
@@ -2813,11 +2842,16 @@ protected synchronized void finalize() throws Throwable {
28132842 this .ssl .freeSSL ();
28142843 this .ssl = null ;
28152844 }
2816- /* Clear our reference to static application direct ByteBuffer */
2845+ /* Zero only the byte range that held plaintext and drop our reference
2846+ * to the buffer. */
28172847 if (this .staticAppDataBuf != null ) {
28182848 this .staticAppDataBuf .clear ();
2849+ for (int j = 0 ; j < this .lastSendSz ; j ++) {
2850+ this .staticAppDataBuf .put ((byte )0 );
2851+ }
28192852 this .staticAppDataBuf = null ;
28202853 }
2854+ this .lastSendSz = 0 ;
28212855 super .finalize ();
28222856 }
28232857}
0 commit comments