From 434fe9436340cb97e9a572e7447fe626dbc69391 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Mon, 9 Sep 2019 16:15:10 +0700 Subject: Support user cancellation of (D)TLS handshakes - see https://github.com/bcgit/bc-java/pull/549 --- crypto/src/crypto/tls/AbstractTlsPeer.cs | 17 +++++++++++++++++ crypto/src/crypto/tls/DatagramTransport.cs | 4 +--- crypto/src/crypto/tls/DtlsClientProtocol.cs | 1 + crypto/src/crypto/tls/DtlsRecordLayer.cs | 5 +++++ crypto/src/crypto/tls/DtlsReliableHandshake.cs | 3 +++ crypto/src/crypto/tls/DtlsServerProtocol.cs | 1 + crypto/src/crypto/tls/TlsClientProtocol.cs | 2 ++ crypto/src/crypto/tls/TlsCloseable.cs | 11 +++++++++++ crypto/src/crypto/tls/TlsPeer.cs | 5 +++++ crypto/src/crypto/tls/TlsProtocol.cs | 1 + crypto/src/crypto/tls/TlsServerProtocol.cs | 2 ++ 11 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 crypto/src/crypto/tls/TlsCloseable.cs (limited to 'crypto/src') 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; + + /// + 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 { /// int GetReceiveLimit(); @@ -16,8 +17,5 @@ namespace Org.BouncyCastle.Crypto.Tls /// void Send(byte[] buf, int off, int len); - - /// - 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 + { + /// + 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); + + /// + void Cancel(); + /// /// 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(); -- cgit 1.4.1