From 651ac04de1249a97a63c3b54ada4ba468aca9787 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Wed, 3 Feb 2016 17:29:12 +0700 Subject: Implement RFC 7685 in TLS --- crypto/Readme.html | 9 ++++++ crypto/src/crypto/tls/AbstractTlsClient.cs | 5 ++++ crypto/src/crypto/tls/DtlsServerProtocol.cs | 3 ++ crypto/src/crypto/tls/TlsExtensionsUtilities.cs | 34 +++++++++++++++++++++++ crypto/src/crypto/tls/TlsServerProtocol.cs | 3 ++ crypto/test/src/crypto/tls/test/MockDtlsClient.cs | 1 + crypto/test/src/crypto/tls/test/MockTlsClient.cs | 1 + 7 files changed, 56 insertions(+) (limited to 'crypto') diff --git a/crypto/Readme.html b/crypto/Readme.html index d5cda3032..674e775d1 100644 --- a/crypto/Readme.html +++ b/crypto/Readme.html @@ -30,6 +30,8 @@
  • Notes:
      +
    1. + Release 1.8.2
    2. Release 1.8.1
    3. @@ -290,6 +292,13 @@ We state, where EC MQV has not otherwise been disabled or removed:

      Notes:

      +

      Release 1.8.2, Release Date TBD

      + +
      Additional Features and Functionality
      +
        +
      • TLS: support for ClientHello Padding Extension (RFC 7685).
      • +
      +

      Release 1.8.1, Monday December 28, 2015

      Security Advisory
      diff --git a/crypto/src/crypto/tls/AbstractTlsClient.cs b/crypto/src/crypto/tls/AbstractTlsClient.cs index ee7a93803..be4702e5e 100644 --- a/crypto/src/crypto/tls/AbstractTlsClient.cs +++ b/crypto/src/crypto/tls/AbstractTlsClient.cs @@ -198,6 +198,11 @@ namespace Org.BouncyCastle.Crypto.Tls { CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.ec_point_formats); } + + /* + * RFC 7685 3. The server MUST NOT echo the extension. + */ + CheckForUnexpectedServerExtension(serverExtensions, ExtensionType.padding); } } diff --git a/crypto/src/crypto/tls/DtlsServerProtocol.cs b/crypto/src/crypto/tls/DtlsServerProtocol.cs index 171984b6f..d05af193c 100644 --- a/crypto/src/crypto/tls/DtlsServerProtocol.cs +++ b/crypto/src/crypto/tls/DtlsServerProtocol.cs @@ -618,6 +618,9 @@ namespace Org.BouncyCastle.Crypto.Tls if (state.clientExtensions != null) { + // NOTE: Validates the padding extension data, if present + TlsExtensionsUtilities.GetPaddingExtension(state.clientExtensions); + state.server.ProcessClientExtensions(state.clientExtensions); } } diff --git a/crypto/src/crypto/tls/TlsExtensionsUtilities.cs b/crypto/src/crypto/tls/TlsExtensionsUtilities.cs index 46851b66c..7f6a26ef2 100644 --- a/crypto/src/crypto/tls/TlsExtensionsUtilities.cs +++ b/crypto/src/crypto/tls/TlsExtensionsUtilities.cs @@ -35,6 +35,12 @@ namespace Org.BouncyCastle.Crypto.Tls extensions[ExtensionType.max_fragment_length] = CreateMaxFragmentLengthExtension(maxFragmentLength); } + /// + public static void AddPaddingExtension(IDictionary extensions, int dataLength) + { + extensions[ExtensionType.padding] = CreatePaddingExtension(dataLength); + } + /// public static void AddServerNameExtension(IDictionary extensions, ServerNameList serverNameList) { @@ -66,6 +72,13 @@ namespace Org.BouncyCastle.Crypto.Tls return extensionData == null ? (short)-1 : (short)ReadMaxFragmentLengthExtension(extensionData); } + /// + public static int GetPaddingExtension(IDictionary extensions) + { + byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.padding); + return extensionData == null ? -1 : ReadPaddingExtension(extensionData); + } + /// public static ServerNameList GetServerNameExtension(IDictionary extensions) { @@ -135,6 +148,13 @@ namespace Org.BouncyCastle.Crypto.Tls return new byte[]{ maxFragmentLength }; } + /// + public static byte[] CreatePaddingExtension(int dataLength) + { + TlsUtilities.CheckUint16(dataLength); + return new byte[dataLength]; + } + /// public static byte[] CreateServerNameExtension(ServerNameList serverNameList) { @@ -219,6 +239,20 @@ namespace Org.BouncyCastle.Crypto.Tls return extensionData[0]; } + /// + public static int ReadPaddingExtension(byte[] extensionData) + { + if (extensionData == null) + throw new ArgumentNullException("extensionData"); + + for (int i = 0; i < extensionData.Length; ++i) + { + if (extensionData[i] != 0) + throw new TlsFatalAlert(AlertDescription.illegal_parameter); + } + return extensionData.Length; + } + /// public static ServerNameList ReadServerNameExtension(byte[] extensionData) { diff --git a/crypto/src/crypto/tls/TlsServerProtocol.cs b/crypto/src/crypto/tls/TlsServerProtocol.cs index 1b790c9e0..38f2befea 100644 --- a/crypto/src/crypto/tls/TlsServerProtocol.cs +++ b/crypto/src/crypto/tls/TlsServerProtocol.cs @@ -612,6 +612,9 @@ namespace Org.BouncyCastle.Crypto.Tls if (mClientExtensions != null) { + // NOTE: Validates the padding extension data, if present + TlsExtensionsUtilities.GetPaddingExtension(mClientExtensions); + mTlsServer.ProcessClientExtensions(mClientExtensions); } } diff --git a/crypto/test/src/crypto/tls/test/MockDtlsClient.cs b/crypto/test/src/crypto/tls/test/MockDtlsClient.cs index e87617e30..8d76c97b2 100644 --- a/crypto/test/src/crypto/tls/test/MockDtlsClient.cs +++ b/crypto/test/src/crypto/tls/test/MockDtlsClient.cs @@ -74,6 +74,7 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests * NOTE: If you are copying test code, do not blindly set these extensions in your own client. */ TlsExtensionsUtilities.AddMaxFragmentLengthExtension(clientExtensions, MaxFragmentLength.pow2_9); + TlsExtensionsUtilities.AddPaddingExtension(clientExtensions, mContext.SecureRandom.Next(16)); TlsExtensionsUtilities.AddTruncatedHMacExtension(clientExtensions); } return clientExtensions; diff --git a/crypto/test/src/crypto/tls/test/MockTlsClient.cs b/crypto/test/src/crypto/tls/test/MockTlsClient.cs index 747369da2..d8deabf96 100644 --- a/crypto/test/src/crypto/tls/test/MockTlsClient.cs +++ b/crypto/test/src/crypto/tls/test/MockTlsClient.cs @@ -64,6 +64,7 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests * NOTE: If you are copying test code, do not blindly set these extensions in your own client. */ TlsExtensionsUtilities.AddMaxFragmentLengthExtension(clientExtensions, MaxFragmentLength.pow2_9); + TlsExtensionsUtilities.AddPaddingExtension(clientExtensions, mContext.SecureRandom.Next(16)); TlsExtensionsUtilities.AddTruncatedHMacExtension(clientExtensions); } return clientExtensions; -- cgit 1.5.1