diff --git a/crypto/Readme.html b/crypto/Readme.html
index d5cda3032..674e775d1 100644
--- a/crypto/Readme.html
+++ b/crypto/Readme.html
@@ -31,6 +31,8 @@
<a href="#mozTocId3413">Notes:</a>
<ol>
<li>
+ <a href="#mozTocId85316">Release 1.8.2</a>
+ <li>
<a href="#mozTocId85315">Release 1.8.1</a>
<li>
<a href="#mozTocId85314">Release 1.8.0</a>
@@ -290,6 +292,13 @@ We state, where EC MQV has not otherwise been disabled or removed:
<hr style="WIDTH: 100%; HEIGHT: 2px">
<h3><a class="mozTocH3" name="mozTocId3413"></a>Notes:</h3>
+ <h4><a class="mozTocH4" name="mozTocId85316"></a>Release 1.8.2, Release Date TBD</h4>
+
+ <h5>Additional Features and Functionality</h5>
+ <ul>
+ <li>TLS: support for ClientHello Padding Extension (RFC 7685).</li>
+ </ul>
+
<h4><a class="mozTocH4" name="mozTocId85315"></a>Release 1.8.1, Monday December 28, 2015</h4>
<h5>Security Advisory</h5>
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
@@ -36,6 +36,12 @@ namespace Org.BouncyCastle.Crypto.Tls
}
/// <exception cref="IOException"></exception>
+ public static void AddPaddingExtension(IDictionary extensions, int dataLength)
+ {
+ extensions[ExtensionType.padding] = CreatePaddingExtension(dataLength);
+ }
+
+ /// <exception cref="IOException"></exception>
public static void AddServerNameExtension(IDictionary extensions, ServerNameList serverNameList)
{
extensions[ExtensionType.server_name] = CreateServerNameExtension(serverNameList);
@@ -67,6 +73,13 @@ namespace Org.BouncyCastle.Crypto.Tls
}
/// <exception cref="IOException"></exception>
+ public static int GetPaddingExtension(IDictionary extensions)
+ {
+ byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.padding);
+ return extensionData == null ? -1 : ReadPaddingExtension(extensionData);
+ }
+
+ /// <exception cref="IOException"></exception>
public static ServerNameList GetServerNameExtension(IDictionary extensions)
{
byte[] extensionData = TlsUtilities.GetExtensionData(extensions, ExtensionType.server_name);
@@ -136,6 +149,13 @@ namespace Org.BouncyCastle.Crypto.Tls
}
/// <exception cref="IOException"></exception>
+ public static byte[] CreatePaddingExtension(int dataLength)
+ {
+ TlsUtilities.CheckUint16(dataLength);
+ return new byte[dataLength];
+ }
+
+ /// <exception cref="IOException"></exception>
public static byte[] CreateServerNameExtension(ServerNameList serverNameList)
{
if (serverNameList == null)
@@ -220,6 +240,20 @@ namespace Org.BouncyCastle.Crypto.Tls
}
/// <exception cref="IOException"></exception>
+ 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;
+ }
+
+ /// <exception cref="IOException"></exception>
public static ServerNameList ReadServerNameExtension(byte[] extensionData)
{
if (extensionData == null)
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;
|