From aecd7ee0f7b3c26599b29c78eb52a32754e45443 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Fri, 4 Apr 2014 15:03:26 +0700 Subject: Use the TLS 1.0 PRF for the random block --- crypto/crypto.csproj | 10 ++++++++ crypto/src/crypto/tls/DefaultTlsClient.cs | 11 ++++++++ crypto/src/crypto/tls/ExporterLabel.cs | 40 +++++++++++++++++++++++++++++ crypto/src/crypto/tls/PskTlsClient.cs | 11 ++++++++ crypto/src/crypto/tls/SrpTlsClient.cs | 11 ++++++++ crypto/src/crypto/tls/TlsClient.cs | 1 + crypto/src/crypto/tls/TlsPeer.cs | 19 ++++++++++++++ crypto/src/crypto/tls/TlsProtocolHandler.cs | 28 +++++++++++++++++--- 8 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 crypto/src/crypto/tls/ExporterLabel.cs create mode 100644 crypto/src/crypto/tls/TlsPeer.cs diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj index f45215de4..fc38358c3 100644 --- a/crypto/crypto.csproj +++ b/crypto/crypto.csproj @@ -4353,6 +4353,11 @@ SubType = "Code" BuildAction = "Compile" /> + + /// Called at the start of a new TLS session, before any other methods. diff --git a/crypto/src/crypto/tls/TlsPeer.cs b/crypto/src/crypto/tls/TlsPeer.cs new file mode 100644 index 000000000..5b5c94a44 --- /dev/null +++ b/crypto/src/crypto/tls/TlsPeer.cs @@ -0,0 +1,19 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + public interface TlsPeer + { + /// + /// draft-mathewson-no-gmtunixtime-00 2. "If existing users of a TLS implementation may rely on + /// gmt_unix_time containing the current time, we recommend that implementors MAY provide the + /// ability to set gmt_unix_time as an option only, off by default." + /// + /// + /// true if the current time should be used in the gmt_unix_time field of + /// Random, or false if gmt_unix_time should contain a cryptographically + /// random value. + /// + bool ShouldUseGmtUnixTime(); + } +} diff --git a/crypto/src/crypto/tls/TlsProtocolHandler.cs b/crypto/src/crypto/tls/TlsProtocolHandler.cs index c538229dc..4707df3b5 100644 --- a/crypto/src/crypto/tls/TlsProtocolHandler.cs +++ b/crypto/src/crypto/tls/TlsProtocolHandler.cs @@ -816,9 +816,8 @@ namespace Org.BouncyCastle.Crypto.Tls * First, generate some random data. */ this.securityParameters = new SecurityParameters(); - this.securityParameters.clientRandom = new byte[32]; - random.NextBytes(securityParameters.clientRandom, 4, 28); - TlsUtilities.WriteGmtUnixTime(securityParameters.clientRandom, 0); + this.securityParameters.clientRandom = CreateRandomBlock(tlsClient.ShouldUseGmtUnixTime(), random, + ExporterLabel.client_random); this.tlsClientContext = new TlsClientContextImpl(random, securityParameters); this.tlsClient = tlsClient; @@ -1176,6 +1175,29 @@ namespace Org.BouncyCastle.Crypto.Tls } } + protected static byte[] CreateRandomBlock(bool useGMTUnixTime, SecureRandom random, string asciiLabel) + { + /* + * We use the TLS 1.0 PRF on the SecureRandom output, to guard against RNGs where the raw + * output could be used to recover the internal state. + */ + byte[] secret = new byte[32]; + random.NextBytes(secret); + + byte[] seed = new byte[8]; + // TODO Use high-resolution timer + TlsUtilities.WriteUint64(DateTimeUtilities.CurrentUnixMs(), seed, 0); + + byte[] result = TlsUtilities.PRF(secret, asciiLabel, seed, 32); + + if (useGMTUnixTime) + { + TlsUtilities.WriteGmtUnixTime(result, 0); + } + + return result; + } + internal void Flush() { rs.Flush(); -- cgit 1.5.1