summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2014-04-04 15:03:26 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2014-04-04 15:03:26 +0700
commitaecd7ee0f7b3c26599b29c78eb52a32754e45443 (patch)
tree9212cc6f61dadda3eb71b9b107819d81853801a1
parentOptimize Curve25519 point operations (diff)
downloadBouncyCastle.NET-ed25519-aecd7ee0f7b3c26599b29c78eb52a32754e45443.tar.xz
Use the TLS 1.0 PRF for the random block
-rw-r--r--crypto/crypto.csproj10
-rw-r--r--crypto/src/crypto/tls/DefaultTlsClient.cs11
-rw-r--r--crypto/src/crypto/tls/ExporterLabel.cs40
-rw-r--r--crypto/src/crypto/tls/PskTlsClient.cs11
-rw-r--r--crypto/src/crypto/tls/SrpTlsClient.cs11
-rw-r--r--crypto/src/crypto/tls/TlsClient.cs1
-rw-r--r--crypto/src/crypto/tls/TlsPeer.cs19
-rw-r--r--crypto/src/crypto/tls/TlsProtocolHandler.cs28
8 files changed, 128 insertions, 3 deletions
diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj
index f45215de4..fc38358c3 100644
--- a/crypto/crypto.csproj
+++ b/crypto/crypto.csproj
@@ -4354,6 +4354,11 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "src\crypto\tls\ExporterLabel.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "src\crypto\tls\ExtensionType.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -4559,6 +4564,11 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "src\crypto\tls\TlsPeer.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "src\crypto\tls\TlsProtocolHandler.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
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
     {
         /// <summary>
         /// 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
+    {
+        /// <summary>
+        /// 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."
+        /// </summary>
+        /// <returns>
+        /// <code>true</code> if the current time should be used in the gmt_unix_time field of
+        /// Random, or <code>false</code> if gmt_unix_time should contain a cryptographically
+        /// random value.
+        /// </returns>
+        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();