From 00904716e6219662a4f8c20d2d116bdc193e8070 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Sat, 7 May 2016 15:49:22 +0700 Subject: Port of improved app data splitting support from Java --- crypto/src/crypto/tls/TlsProtocol.cs | 41 ++++++++++++++++++++++++++++++------ 1 file 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 @@ -33,6 +33,13 @@ namespace Org.BouncyCastle.Crypto.Tls protected const short CS_SERVER_FINISHED = 15; 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. */ @@ -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) -- cgit 1.4.1