summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crypto/src/crypto/tls/TlsProtocol.cs41
1 files changed, 35 insertions, 6 deletions
diff --git a/crypto/src/crypto/tls/TlsProtocol.cs b/crypto/src/crypto/tls/TlsProtocol.cs
index 6e3bbbbdf..6d5c93f40 100644
--- a/crypto/src/crypto/tls/TlsProtocol.cs
+++ b/crypto/src/crypto/tls/TlsProtocol.cs
@@ -34,6 +34,13 @@ namespace Org.BouncyCastle.Crypto.Tls
         protected const short CS_END = 16;
 
         /*
+         * Different modes to handle the known IV weakness
+         */
+        protected const short ADS_MODE_1_Nsub1 = 0; // 1/n-1 record splitting
+        protected const short ADS_MODE_0_N = 1; // 0/n record splitting
+        protected const short ADS_MODE_0_N_FIRSTONLY = 2; // 0/n record splitting on first data fragment only
+
+        /*
          * Queues for data from some protocols.
          */
         private ByteQueue mApplicationDataQueue = new ByteQueue();
@@ -52,7 +59,8 @@ namespace Org.BouncyCastle.Crypto.Tls
         private volatile bool mClosed = false;
         private volatile bool mFailedWithError = false;
         private volatile bool mAppDataReady = false;
-        private volatile bool mSplitApplicationDataRecords = true;
+        private volatile bool mAppDataSplitEnabled = true;
+        private volatile int mAppDataSplitMode = ADS_MODE_1_Nsub1;
         private byte[] mExpectedVerifyData = null;
 
         protected TlsSession mTlsSession = null;
@@ -175,7 +183,7 @@ namespace Org.BouncyCastle.Crypto.Tls
             {
                 this.mRecordStream.FinaliseHandshake();
 
-                this.mSplitApplicationDataRecords = !TlsUtilities.IsTlsV11(Context);
+                this.mAppDataSplitEnabled = !TlsUtilities.IsTlsV11(Context);
 
                 /*
                  * If this was an initial handshake, we are now ready to send and receive application data.
@@ -556,16 +564,29 @@ namespace Org.BouncyCastle.Crypto.Tls
                  * NOTE: Actually, implementations appear to have settled on 1/n-1 record splitting.
                  */
 
-                if (this.mSplitApplicationDataRecords)
+                if (this.mAppDataSplitEnabled)
                 {
                     /*
                      * Protect against known IV attack!
                      * 
                      * DO NOT REMOVE THIS CODE, EXCEPT YOU KNOW EXACTLY WHAT YOU ARE DOING HERE.
                      */
-                    SafeWriteRecord(ContentType.application_data, buf, offset, 1);
-                    ++offset;
-                    --len;
+                    switch (mAppDataSplitMode)
+                    {
+                    case ADS_MODE_0_N:
+                        SafeWriteRecord(ContentType.application_data, TlsUtilities.EmptyBytes, 0, 0);
+                        break;
+                    case ADS_MODE_0_N_FIRSTONLY:
+                        this.mAppDataSplitEnabled = false;
+                        SafeWriteRecord(ContentType.application_data, TlsUtilities.EmptyBytes, 0, 0);
+                        break;
+                    case ADS_MODE_1_Nsub1:
+                    default:
+                        SafeWriteRecord(ContentType.application_data, buf, offset, 1);
+                        ++offset;
+                        --len;
+                        break;
+                    }
                 }
 
                 if (len > 0)
@@ -579,6 +600,14 @@ namespace Org.BouncyCastle.Crypto.Tls
             }
         }
 
+        protected virtual void SetAppDataSplitMode(int appDataSplitMode)
+        {
+            if (appDataSplitMode < ADS_MODE_1_Nsub1 || appDataSplitMode > ADS_MODE_0_N_FIRSTONLY)
+                throw new ArgumentException("Illegal appDataSplitMode mode: " + appDataSplitMode, "appDataSplitMode");
+
+            this.mAppDataSplitMode = appDataSplitMode;
+        }
+
         protected virtual void WriteHandshakeMessage(byte[] buf, int off, int len)
         {
             while (len > 0)