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();
|