summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2019-09-09 16:15:10 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2019-09-09 16:15:10 +0700
commit434fe9436340cb97e9a572e7447fe626dbc69391 (patch)
tree64105ac2eb9e404147ab6ad345243efa9e1e7032
parentPort of strict hex decoding from bc-java (diff)
downloadBouncyCastle.NET-ed25519-434fe9436340cb97e9a572e7447fe626dbc69391.tar.xz
Support user cancellation of (D)TLS handshakes
- see https://github.com/bcgit/bc-java/pull/549
-rw-r--r--crypto/BouncyCastle.Android.csproj1
-rw-r--r--crypto/BouncyCastle.csproj1
-rw-r--r--crypto/BouncyCastle.iOS.csproj1
-rw-r--r--crypto/crypto.csproj5
-rw-r--r--crypto/src/crypto/tls/AbstractTlsPeer.cs17
-rw-r--r--crypto/src/crypto/tls/DatagramTransport.cs4
-rw-r--r--crypto/src/crypto/tls/DtlsClientProtocol.cs1
-rw-r--r--crypto/src/crypto/tls/DtlsRecordLayer.cs5
-rw-r--r--crypto/src/crypto/tls/DtlsReliableHandshake.cs3
-rw-r--r--crypto/src/crypto/tls/DtlsServerProtocol.cs1
-rw-r--r--crypto/src/crypto/tls/TlsClientProtocol.cs2
-rw-r--r--crypto/src/crypto/tls/TlsCloseable.cs11
-rw-r--r--crypto/src/crypto/tls/TlsPeer.cs5
-rw-r--r--crypto/src/crypto/tls/TlsProtocol.cs1
-rw-r--r--crypto/src/crypto/tls/TlsServerProtocol.cs2
15 files changed, 57 insertions, 3 deletions
diff --git a/crypto/BouncyCastle.Android.csproj b/crypto/BouncyCastle.Android.csproj
index f30b48433..e20fa2b63 100644
--- a/crypto/BouncyCastle.Android.csproj
+++ b/crypto/BouncyCastle.Android.csproj
@@ -1158,6 +1158,7 @@
     <Compile Include="src\crypto\tls\TlsClientContext.cs" />
     <Compile Include="src\crypto\tls\TlsClientContextImpl.cs" />
     <Compile Include="src\crypto\tls\TlsClientProtocol.cs" />
+    <Compile Include="src\crypto\tls\TlsCloseable.cs" />
     <Compile Include="src\crypto\tls\TlsCompression.cs" />
     <Compile Include="src\crypto\tls\TlsContext.cs" />
     <Compile Include="src\crypto\tls\TlsCredentials.cs" />
diff --git a/crypto/BouncyCastle.csproj b/crypto/BouncyCastle.csproj
index be84564e2..ab8559472 100644
--- a/crypto/BouncyCastle.csproj
+++ b/crypto/BouncyCastle.csproj
@@ -1152,6 +1152,7 @@
     <Compile Include="src\crypto\tls\TlsClientContext.cs" />
     <Compile Include="src\crypto\tls\TlsClientContextImpl.cs" />
     <Compile Include="src\crypto\tls\TlsClientProtocol.cs" />
+    <Compile Include="src\crypto\tls\TlsCloseable.cs" />
     <Compile Include="src\crypto\tls\TlsCompression.cs" />
     <Compile Include="src\crypto\tls\TlsContext.cs" />
     <Compile Include="src\crypto\tls\TlsCredentials.cs" />
diff --git a/crypto/BouncyCastle.iOS.csproj b/crypto/BouncyCastle.iOS.csproj
index 53e8a5b00..8bb7fe7b0 100644
--- a/crypto/BouncyCastle.iOS.csproj
+++ b/crypto/BouncyCastle.iOS.csproj
@@ -1153,6 +1153,7 @@
     <Compile Include="src\crypto\tls\TlsClientContext.cs" />
     <Compile Include="src\crypto\tls\TlsClientContextImpl.cs" />
     <Compile Include="src\crypto\tls\TlsClientProtocol.cs" />
+    <Compile Include="src\crypto\tls\TlsCloseable.cs" />
     <Compile Include="src\crypto\tls\TlsCompression.cs" />
     <Compile Include="src\crypto\tls\TlsContext.cs" />
     <Compile Include="src\crypto\tls\TlsCredentials.cs" />
diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj
index ca6dba5ff..08e7b0ee1 100644
--- a/crypto/crypto.csproj
+++ b/crypto/crypto.csproj
@@ -5649,6 +5649,11 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "src\crypto\tls\TlsCloseable.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "src\crypto\tls\TlsCompression.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
diff --git a/crypto/src/crypto/tls/AbstractTlsPeer.cs b/crypto/src/crypto/tls/AbstractTlsPeer.cs
index 1bbea68c8..2081ce8e5 100644
--- a/crypto/src/crypto/tls/AbstractTlsPeer.cs
+++ b/crypto/src/crypto/tls/AbstractTlsPeer.cs
@@ -6,6 +6,23 @@ namespace Org.BouncyCastle.Crypto.Tls
     public abstract class AbstractTlsPeer
         :   TlsPeer
     {
+        private volatile TlsCloseable mCloseHandle;
+
+        /// <exception cref="IOException"/>
+        public virtual void Cancel()
+        {
+            TlsCloseable closeHandle = this.mCloseHandle;
+            if (null != closeHandle)
+            {
+                closeHandle.Close();
+            }
+        }
+
+        public virtual void NotifyCloseHandle(TlsCloseable closeHandle)
+        {
+            this.mCloseHandle = closeHandle;
+        }
+
         public virtual bool RequiresExtendedMasterSecret()
         {
             return false;
diff --git a/crypto/src/crypto/tls/DatagramTransport.cs b/crypto/src/crypto/tls/DatagramTransport.cs
index 524a8b181..42f958d46 100644
--- a/crypto/src/crypto/tls/DatagramTransport.cs
+++ b/crypto/src/crypto/tls/DatagramTransport.cs
@@ -4,6 +4,7 @@ using System.IO;
 namespace Org.BouncyCastle.Crypto.Tls
 {
     public interface DatagramTransport
+        : TlsCloseable
     {
         /// <exception cref="IOException"/>
         int GetReceiveLimit();
@@ -16,8 +17,5 @@ namespace Org.BouncyCastle.Crypto.Tls
 
         /// <exception cref="IOException"/>
         void Send(byte[] buf, int off, int len);
-
-        /// <exception cref="IOException"/>
-        void Close();
     }
 }
diff --git a/crypto/src/crypto/tls/DtlsClientProtocol.cs b/crypto/src/crypto/tls/DtlsClientProtocol.cs
index ce0c4c767..4c08bbcfc 100644
--- a/crypto/src/crypto/tls/DtlsClientProtocol.cs
+++ b/crypto/src/crypto/tls/DtlsClientProtocol.cs
@@ -35,6 +35,7 @@ namespace Org.BouncyCastle.Crypto.Tls
             client.Init(state.clientContext);
 
             DtlsRecordLayer recordLayer = new DtlsRecordLayer(transport, state.clientContext, client, ContentType.handshake);
+            client.NotifyCloseHandle(recordLayer);
 
             TlsSession sessionToResume = state.client.GetSessionToResume();
             if (sessionToResume != null && sessionToResume.IsResumable)
diff --git a/crypto/src/crypto/tls/DtlsRecordLayer.cs b/crypto/src/crypto/tls/DtlsRecordLayer.cs
index 39e018810..3cb0e78dd 100644
--- a/crypto/src/crypto/tls/DtlsRecordLayer.cs
+++ b/crypto/src/crypto/tls/DtlsRecordLayer.cs
@@ -47,6 +47,11 @@ namespace Org.BouncyCastle.Crypto.Tls
             SetPlaintextLimit(MAX_FRAGMENT_LENGTH);
         }
 
+        internal bool IsClosed
+        {
+            get { return mClosed; }
+        }
+
         internal virtual void SetPlaintextLimit(int plaintextLimit)
         {
             this.mPlaintextLimit = plaintextLimit;
diff --git a/crypto/src/crypto/tls/DtlsReliableHandshake.cs b/crypto/src/crypto/tls/DtlsReliableHandshake.cs
index 8715cd799..8fcc1d7c2 100644
--- a/crypto/src/crypto/tls/DtlsReliableHandshake.cs
+++ b/crypto/src/crypto/tls/DtlsReliableHandshake.cs
@@ -93,6 +93,9 @@ namespace Org.BouncyCastle.Crypto.Tls
                 {
                     for (;;)
                     {
+                        if (mRecordLayer.IsClosed)
+                            throw new TlsFatalAlert(AlertDescription.user_canceled);
+
                         Message pending = GetPendingMessage();
                         if (pending != null)
                             return pending;
diff --git a/crypto/src/crypto/tls/DtlsServerProtocol.cs b/crypto/src/crypto/tls/DtlsServerProtocol.cs
index 1095014cd..242e1bee5 100644
--- a/crypto/src/crypto/tls/DtlsServerProtocol.cs
+++ b/crypto/src/crypto/tls/DtlsServerProtocol.cs
@@ -45,6 +45,7 @@ namespace Org.BouncyCastle.Crypto.Tls
             server.Init(state.serverContext);
 
             DtlsRecordLayer recordLayer = new DtlsRecordLayer(transport, state.serverContext, server, ContentType.handshake);
+            server.NotifyCloseHandle(recordLayer);
 
             // TODO Need to handle sending of HelloVerifyRequest without entering a full connection
 
diff --git a/crypto/src/crypto/tls/TlsClientProtocol.cs b/crypto/src/crypto/tls/TlsClientProtocol.cs
index 17b756693..1fe5744d3 100644
--- a/crypto/src/crypto/tls/TlsClientProtocol.cs
+++ b/crypto/src/crypto/tls/TlsClientProtocol.cs
@@ -92,6 +92,8 @@ namespace Org.BouncyCastle.Crypto.Tls
             this.mTlsClient.Init(mTlsClientContext);
             this.mRecordStream.Init(mTlsClientContext);
 
+            tlsClient.NotifyCloseHandle(this);
+
             TlsSession sessionToResume = tlsClient.GetSessionToResume();
             if (sessionToResume != null && sessionToResume.IsResumable)
             {
diff --git a/crypto/src/crypto/tls/TlsCloseable.cs b/crypto/src/crypto/tls/TlsCloseable.cs
new file mode 100644
index 000000000..01625d7a0
--- /dev/null
+++ b/crypto/src/crypto/tls/TlsCloseable.cs
@@ -0,0 +1,11 @@
+using System;
+using System.IO;
+
+namespace Org.BouncyCastle.Crypto.Tls
+{
+    public interface TlsCloseable
+    {
+        /// <exception cref="IOException"/>
+        void Close();
+    }
+}
diff --git a/crypto/src/crypto/tls/TlsPeer.cs b/crypto/src/crypto/tls/TlsPeer.cs
index 993fdf93f..a1e99f3fd 100644
--- a/crypto/src/crypto/tls/TlsPeer.cs
+++ b/crypto/src/crypto/tls/TlsPeer.cs
@@ -5,6 +5,11 @@ namespace Org.BouncyCastle.Crypto.Tls
 {
     public interface TlsPeer
     {
+        void NotifyCloseHandle(TlsCloseable closehandle);
+
+        /// <exception cref="IOException"/>
+        void Cancel();
+
         /// <summary>
         /// This implementation supports RFC 7627 and will always negotiate the extended_master_secret
         /// extension where possible.
diff --git a/crypto/src/crypto/tls/TlsProtocol.cs b/crypto/src/crypto/tls/TlsProtocol.cs
index 388eb629f..cc6ae0259 100644
--- a/crypto/src/crypto/tls/TlsProtocol.cs
+++ b/crypto/src/crypto/tls/TlsProtocol.cs
@@ -9,6 +9,7 @@ using Org.BouncyCastle.Utilities;
 namespace Org.BouncyCastle.Crypto.Tls
 {
     public abstract class TlsProtocol
+        : TlsCloseable
     {
         /*
          * Our Connection states
diff --git a/crypto/src/crypto/tls/TlsServerProtocol.cs b/crypto/src/crypto/tls/TlsServerProtocol.cs
index e610b5950..1ba90cfdc 100644
--- a/crypto/src/crypto/tls/TlsServerProtocol.cs
+++ b/crypto/src/crypto/tls/TlsServerProtocol.cs
@@ -94,6 +94,8 @@ namespace Org.BouncyCastle.Crypto.Tls
             this.mTlsServer.Init(mTlsServerContext);
             this.mRecordStream.Init(mTlsServerContext);
 
+            tlsServer.NotifyCloseHandle(this);
+
             this.mRecordStream.SetRestrictReadVersion(false);
 
             BlockForHandshake();