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/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 +++++++++++++++++--- 7 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 crypto/src/crypto/tls/ExporterLabel.cs create mode 100644 crypto/src/crypto/tls/TlsPeer.cs (limited to 'crypto/src') diff --git a/crypto/src/crypto/tls/DefaultTlsClient.cs b/crypto/src/crypto/tls/DefaultTlsClient.cs index a5fbe8235..d59fae164 100644 --- a/crypto/src/crypto/tls/DefaultTlsClient.cs +++ b/crypto/src/crypto/tls/DefaultTlsClient.cs @@ -36,6 +36,17 @@ namespace Org.BouncyCastle.Crypto.Tls this.context = context; } + public virtual bool ShouldUseGmtUnixTime() + { + /* + * draft-mathewson-no-gmtunixtime-00 2. For the reasons we discuss above, we recommend that + * TLS implementors MUST by default set the entire value the ClientHello.Random and + * ServerHello.Random fields, including gmt_unix_time, to a cryptographically random + * sequence. + */ + return false; + } + public virtual int[] GetCipherSuites() { return new int[] { diff --git a/crypto/src/crypto/tls/ExporterLabel.cs b/crypto/src/crypto/tls/ExporterLabel.cs new file mode 100644 index 000000000..e26f15dc7 --- /dev/null +++ b/crypto/src/crypto/tls/ExporterLabel.cs @@ -0,0 +1,40 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /** + * RFC 5705 + */ + public class ExporterLabel + { + /* + * BC-specific + */ + internal const string client_random = "client random"; + internal const string server_random = "server random"; + + /* + * RFC 5246 + */ + public const string client_finished = "client finished"; + public const string server_finished = "server finished"; + public const string master_secret = "master secret"; + public const string key_expansion = "key expansion"; + + /* + * RFC 5216 + */ + public const string client_EAP_encryption = "client EAP encryption"; + + /* + * RFC 5281 + */ + public const string ttls_keying_material = "ttls keying material"; + public const string ttls_challenge = "ttls challenge"; + + /* + * RFC 5764 + */ + public const string dtls_srtp = "EXTRACTOR-dtls_srtp"; + } +} diff --git a/crypto/src/crypto/tls/PskTlsClient.cs b/crypto/src/crypto/tls/PskTlsClient.cs index 6011daada..e60688155 100644 --- a/crypto/src/crypto/tls/PskTlsClient.cs +++ b/crypto/src/crypto/tls/PskTlsClient.cs @@ -30,6 +30,17 @@ namespace Org.BouncyCastle.Crypto.Tls this.context = context; } + public virtual bool ShouldUseGmtUnixTime() + { + /* + * draft-mathewson-no-gmtunixtime-00 2. For the reasons we discuss above, we recommend that + * TLS implementors MUST by default set the entire value the ClientHello.Random and + * ServerHello.Random fields, including gmt_unix_time, to a cryptographically random + * sequence. + */ + return false; + } + public virtual int[] GetCipherSuites() { return new int[] { diff --git a/crypto/src/crypto/tls/SrpTlsClient.cs b/crypto/src/crypto/tls/SrpTlsClient.cs index f9c8ccc74..3769fc85d 100644 --- a/crypto/src/crypto/tls/SrpTlsClient.cs +++ b/crypto/src/crypto/tls/SrpTlsClient.cs @@ -35,6 +35,17 @@ namespace Org.BouncyCastle.Crypto.Tls this.context = context; } + public virtual bool ShouldUseGmtUnixTime() + { + /* + * draft-mathewson-no-gmtunixtime-00 2. For the reasons we discuss above, we recommend that + * TLS implementors MUST by default set the entire value the ClientHello.Random and + * ServerHello.Random fields, including gmt_unix_time, to a cryptographically random + * sequence. + */ + return false; + } + public virtual int[] GetCipherSuites() { return new int[] { diff --git a/crypto/src/crypto/tls/TlsClient.cs b/crypto/src/crypto/tls/TlsClient.cs index 9e7937c94..a4cdc647d 100644 --- a/crypto/src/crypto/tls/TlsClient.cs +++ b/crypto/src/crypto/tls/TlsClient.cs @@ -5,6 +5,7 @@ using System.IO; namespace Org.BouncyCastle.Crypto.Tls { public interface TlsClient + : TlsPeer { /// /// 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.4.1