diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2020-07-30 13:12:24 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2020-07-30 13:12:24 +0700 |
commit | 1e7a8381bcd0f1fdd6b9434494ad59e5a793f1d6 (patch) | |
tree | 3aeb31f56574eef8e9ff9cd8b1c9fdf1b6d2b715 | |
parent | DTLS: Improved retransmission timer (diff) | |
download | BouncyCastle.NET-ed25519-1e7a8381bcd0f1fdd6b9434494ad59e5a793f1d6.tar.xz |
DTLS: Support handshake timeout
-rw-r--r-- | crypto/Readme.html | 6 | ||||
-rw-r--r-- | crypto/src/crypto/tls/AbstractTlsPeer.cs | 5 | ||||
-rw-r--r-- | crypto/src/crypto/tls/DtlsClientProtocol.cs | 3 | ||||
-rw-r--r-- | crypto/src/crypto/tls/DtlsRecordLayer.cs | 7 | ||||
-rw-r--r-- | crypto/src/crypto/tls/DtlsReliableHandshake.cs | 13 | ||||
-rw-r--r-- | crypto/src/crypto/tls/DtlsServerProtocol.cs | 4 | ||||
-rw-r--r-- | crypto/src/crypto/tls/TlsPeer.cs | 9 |
7 files changed, 36 insertions, 11 deletions
diff --git a/crypto/Readme.html b/crypto/Readme.html index 6d1bc7421..5ad32246c 100644 --- a/crypto/Readme.html +++ b/crypto/Readme.html @@ -307,6 +307,12 @@ We state, where EC MQV has not otherwise been disabled or removed: <h5>Defects Fixed</h5> <ul> <li>ChaCha20Poly1305 could fail for large (>~2GB) files. This has been fixed.</li> + <li>DTLS: Fixed infinite loop on IO exceptions.</li> + </ul> + <h5>Additional Features and Functionality</h5> + <ul> + <li>DTLS: Retransmission timers now properly apply to flights monolithically.</li> + <li>DTLS: Added support for an overall handshake timeout.</li> </ul> <h5>Additional Notes</h5> <ul> diff --git a/crypto/src/crypto/tls/AbstractTlsPeer.cs b/crypto/src/crypto/tls/AbstractTlsPeer.cs index 2081ce8e5..e7bfc1742 100644 --- a/crypto/src/crypto/tls/AbstractTlsPeer.cs +++ b/crypto/src/crypto/tls/AbstractTlsPeer.cs @@ -23,6 +23,11 @@ namespace Org.BouncyCastle.Crypto.Tls this.mCloseHandle = closeHandle; } + public virtual int GetHandshakeTimeoutMillis() + { + return 0; + } + public virtual bool RequiresExtendedMasterSecret() { return false; diff --git a/crypto/src/crypto/tls/DtlsClientProtocol.cs b/crypto/src/crypto/tls/DtlsClientProtocol.cs index 4c08bbcfc..fe6381dfa 100644 --- a/crypto/src/crypto/tls/DtlsClientProtocol.cs +++ b/crypto/src/crypto/tls/DtlsClientProtocol.cs @@ -82,7 +82,8 @@ namespace Org.BouncyCastle.Crypto.Tls internal virtual DtlsTransport ClientHandshake(ClientHandshakeState state, DtlsRecordLayer recordLayer) { SecurityParameters securityParameters = state.clientContext.SecurityParameters; - DtlsReliableHandshake handshake = new DtlsReliableHandshake(state.clientContext, recordLayer); + DtlsReliableHandshake handshake = new DtlsReliableHandshake(state.clientContext, recordLayer, + state.client.GetHandshakeTimeoutMillis()); byte[] clientHelloBody = GenerateClientHello(state, state.client); diff --git a/crypto/src/crypto/tls/DtlsRecordLayer.cs b/crypto/src/crypto/tls/DtlsRecordLayer.cs index c1a26b14f..5f3ec9e9c 100644 --- a/crypto/src/crypto/tls/DtlsRecordLayer.cs +++ b/crypto/src/crypto/tls/DtlsRecordLayer.cs @@ -152,12 +152,7 @@ namespace Org.BouncyCastle.Crypto.Tls { long currentTimeMillis = DateTimeUtilities.CurrentUnixMs(); - Timeout timeout = null; - if (waitMillis > 0) - { - timeout = new Timeout(waitMillis, currentTimeMillis); - } - + Timeout timeout = Timeout.ForWaitMillis(waitMillis, currentTimeMillis); byte[] record = null; while (waitMillis >= 0) diff --git a/crypto/src/crypto/tls/DtlsReliableHandshake.cs b/crypto/src/crypto/tls/DtlsReliableHandshake.cs index 3eeb8a61e..4fc351376 100644 --- a/crypto/src/crypto/tls/DtlsReliableHandshake.cs +++ b/crypto/src/crypto/tls/DtlsReliableHandshake.cs @@ -16,6 +16,7 @@ namespace Org.BouncyCastle.Crypto.Tls private const int MaxResendMillis = 60000; private readonly DtlsRecordLayer mRecordLayer; + private readonly Timeout mHandshakeTimeout; private TlsHandshakeHash mHandshakeHash; @@ -28,9 +29,10 @@ namespace Org.BouncyCastle.Crypto.Tls private int mMessageSeq = 0, mNextReceiveSeq = 0; - internal DtlsReliableHandshake(TlsContext context, DtlsRecordLayer transport) + internal DtlsReliableHandshake(TlsContext context, DtlsRecordLayer transport, int timeoutMillis) { this.mRecordLayer = transport; + this.mHandshakeTimeout = Timeout.ForWaitMillis(timeoutMillis); this.mHandshakeHash = new DeferredHash(); this.mHandshakeHash.Init(context); } @@ -85,7 +87,6 @@ namespace Org.BouncyCastle.Crypto.Tls internal Message ReceiveMessage() { - // TODO Add support for "overall" handshake timeout long currentTimeMillis = DateTimeUtilities.CurrentUnixMs(); if (mResendTimeout == null) @@ -107,7 +108,15 @@ namespace Org.BouncyCastle.Crypto.Tls if (pending != null) return pending; + int handshakeMillis = Timeout.GetWaitMillis(mHandshakeTimeout, currentTimeMillis); + if (handshakeMillis < 0) + throw new TlsFatalAlert(AlertDescription.handshake_failure); + int waitMillis = System.Math.Max(1, Timeout.GetWaitMillis(mResendTimeout, currentTimeMillis)); + if (handshakeMillis > 0) + { + waitMillis = System.Math.Min(waitMillis, handshakeMillis); + } int receiveLimit = mRecordLayer.GetReceiveLimit(); if (buf == null || buf.Length < receiveLimit) diff --git a/crypto/src/crypto/tls/DtlsServerProtocol.cs b/crypto/src/crypto/tls/DtlsServerProtocol.cs index 242e1bee5..b4ed75198 100644 --- a/crypto/src/crypto/tls/DtlsServerProtocol.cs +++ b/crypto/src/crypto/tls/DtlsServerProtocol.cs @@ -83,8 +83,8 @@ namespace Org.BouncyCastle.Crypto.Tls internal virtual DtlsTransport ServerHandshake(ServerHandshakeState state, DtlsRecordLayer recordLayer) { SecurityParameters securityParameters = state.serverContext.SecurityParameters; - DtlsReliableHandshake handshake = new DtlsReliableHandshake(state.serverContext, recordLayer); - + DtlsReliableHandshake handshake = new DtlsReliableHandshake(state.serverContext, recordLayer, + state.server.GetHandshakeTimeoutMillis()); DtlsReliableHandshake.Message clientMessage = handshake.ReceiveMessage(); // NOTE: DTLSRecordLayer requires any DTLS version, we don't otherwise constrain this diff --git a/crypto/src/crypto/tls/TlsPeer.cs b/crypto/src/crypto/tls/TlsPeer.cs index a1e99f3fd..817871b14 100644 --- a/crypto/src/crypto/tls/TlsPeer.cs +++ b/crypto/src/crypto/tls/TlsPeer.cs @@ -11,6 +11,15 @@ namespace Org.BouncyCastle.Crypto.Tls void Cancel(); /// <summary> + /// Specify the timeout, in milliseconds, to use for the complete handshake process. + /// </summary> + /// <remarks> + /// Negative values are not allowed. A timeout of zero means an infinite timeout (i.e. the + /// handshake will never time out). NOTE: Currently only respected by DTLS protocols. + /// </remarks> + int GetHandshakeTimeoutMillis(); + + /// <summary> /// This implementation supports RFC 7627 and will always negotiate the extended_master_secret /// extension where possible. /// </summary> |