summary refs log tree commit diff
path: root/crypto/src
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-11-05 21:43:59 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-11-05 21:43:59 +0700
commit51628afb7a6a9979bcd736af04fd0e01656ef26d (patch)
treea7ffc3e79721168954cc7bf13790a9e74a47d8e3 /crypto/src
parentPreprocessor symbol cleanup (diff)
downloadBouncyCastle.NET-ed25519-51628afb7a6a9979bcd736af04fd0e01656ef26d.tar.xz
Add TlsPeer.IgnoreCorruptDtlsRecords
- property controls behaviour when bad_record_mac thrown for DTLS record.
- defaults to 'false' (don't ignore i.e. fail the connection)
- see https://github.com/bcgit/bc-csharp/pull/279
Diffstat (limited to 'crypto/src')
-rw-r--r--crypto/src/tls/AbstractTlsPeer.cs2
-rw-r--r--crypto/src/tls/DtlsClientProtocol.cs4
-rw-r--r--crypto/src/tls/DtlsServerProtocol.cs2
-rw-r--r--crypto/src/tls/DtlsTransport.cs9
-rw-r--r--crypto/src/tls/TlsPeer.cs7
-rw-r--r--crypto/src/tls/crypto/impl/TlsAeadCipher.cs9
-rw-r--r--crypto/src/tls/crypto/impl/TlsAeadCipherImpl.cs2
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcChaCha20Poly1305.cs6
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsAeadCipherImpl.cs5
9 files changed, 41 insertions, 5 deletions
diff --git a/crypto/src/tls/AbstractTlsPeer.cs b/crypto/src/tls/AbstractTlsPeer.cs
index 4e1b28e58..6d7c88f1b 100644
--- a/crypto/src/tls/AbstractTlsPeer.cs
+++ b/crypto/src/tls/AbstractTlsPeer.cs
@@ -157,5 +157,7 @@ namespace Org.BouncyCastle.Tls
         {
             return HeartbeatMode.peer_not_allowed_to_send;
         }
+
+        public virtual bool IgnoreCorruptDtlsRecords => false;
     }
 }
diff --git a/crypto/src/tls/DtlsClientProtocol.cs b/crypto/src/tls/DtlsClientProtocol.cs
index b8c09617a..0a4a711ae 100644
--- a/crypto/src/tls/DtlsClientProtocol.cs
+++ b/crypto/src/tls/DtlsClientProtocol.cs
@@ -173,7 +173,7 @@ namespace Org.BouncyCastle.Tls
                 recordLayer.InitHeartbeat(state.heartbeat,
                     HeartbeatMode.peer_allowed_to_send == state.heartbeatPolicy);
 
-                return new DtlsTransport(recordLayer);
+                return new DtlsTransport(recordLayer, state.client.IgnoreCorruptDtlsRecords);
             }
 
             InvalidateSession(state);
@@ -392,7 +392,7 @@ namespace Org.BouncyCastle.Tls
 
             recordLayer.InitHeartbeat(state.heartbeat, HeartbeatMode.peer_allowed_to_send == state.heartbeatPolicy);
 
-            return new DtlsTransport(recordLayer);
+            return new DtlsTransport(recordLayer, state.client.IgnoreCorruptDtlsRecords);
         }
 
         /// <exception cref="IOException"/>
diff --git a/crypto/src/tls/DtlsServerProtocol.cs b/crypto/src/tls/DtlsServerProtocol.cs
index b42f97b64..5edd5595e 100644
--- a/crypto/src/tls/DtlsServerProtocol.cs
+++ b/crypto/src/tls/DtlsServerProtocol.cs
@@ -381,7 +381,7 @@ namespace Org.BouncyCastle.Tls
 
             recordLayer.InitHeartbeat(state.heartbeat, HeartbeatMode.peer_allowed_to_send == state.heartbeatPolicy);
 
-            return new DtlsTransport(recordLayer);
+            return new DtlsTransport(recordLayer, state.server.IgnoreCorruptDtlsRecords);
         }
 
         /// <exception cref="IOException"/>
diff --git a/crypto/src/tls/DtlsTransport.cs b/crypto/src/tls/DtlsTransport.cs
index 1a6ec131f..6d481702f 100644
--- a/crypto/src/tls/DtlsTransport.cs
+++ b/crypto/src/tls/DtlsTransport.cs
@@ -8,10 +8,12 @@ namespace Org.BouncyCastle.Tls
         : DatagramTransport
     {
         private readonly DtlsRecordLayer m_recordLayer;
+        private readonly bool m_ignoreCorruptRecords;
 
-        internal DtlsTransport(DtlsRecordLayer recordLayer)
+        internal DtlsTransport(DtlsRecordLayer recordLayer, bool ignoreCorruptRecords)
         {
-            this.m_recordLayer = recordLayer;
+            m_recordLayer = recordLayer;
+            m_ignoreCorruptRecords = ignoreCorruptRecords;
         }
 
         /// <exception cref="IOException"/>
@@ -44,6 +46,9 @@ namespace Org.BouncyCastle.Tls
             }
             catch (TlsFatalAlert fatalAlert)
             {
+                if (m_ignoreCorruptRecords && AlertDescription.bad_record_mac == fatalAlert.AlertDescription)
+                    return -1;
+
                 m_recordLayer.Fail(fatalAlert.AlertDescription);
                 throw fatalAlert;
             }
diff --git a/crypto/src/tls/TlsPeer.cs b/crypto/src/tls/TlsPeer.cs
index ef2837135..04d66d38f 100644
--- a/crypto/src/tls/TlsPeer.cs
+++ b/crypto/src/tls/TlsPeer.cs
@@ -119,5 +119,12 @@ namespace Org.BouncyCastle.Tls
         /// </remarks>
         /// <returns>the <see cref="HeartbeatMode"/> value.</returns>
         short GetHeartbeatPolicy();
+
+        /// <summary>Indicates whether a DTLS connection should ignore corrupt records (bad_record_mac) instead of
+        /// failing the connection.</summary>
+        /// <remarks>Called only once at the start of a connection and applies throughout.</remarks>
+        /// <returns>The value <c>true</c> to ignore corrupt DTLS records, or <c>false</c> to fail the connection.
+        /// </returns>
+        bool IgnoreCorruptDtlsRecords { get; }
     }
 }
diff --git a/crypto/src/tls/crypto/impl/TlsAeadCipher.cs b/crypto/src/tls/crypto/impl/TlsAeadCipher.cs
index a53e1e835..594981210 100644
--- a/crypto/src/tls/crypto/impl/TlsAeadCipher.cs
+++ b/crypto/src/tls/crypto/impl/TlsAeadCipher.cs
@@ -351,12 +351,21 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl
                 outputPos = m_decryptCipher.DoFinal(ciphertext, encryptionOffset, encryptionLength, ciphertext,
                     encryptionOffset);
             }
+            catch (TlsFatalAlert fatalAlert)
+            {
+                if (AlertDescription.bad_record_mac == fatalAlert.AlertDescription)
+                {
+                    m_decryptCipher.Reset();
+                }
+                throw fatalAlert;
+            }
             catch (IOException e)
             {
                 throw e;
             }
             catch (Exception e)
             {
+                m_decryptCipher.Reset();
                 throw new TlsFatalAlert(AlertDescription.bad_record_mac, e);
             }
 
diff --git a/crypto/src/tls/crypto/impl/TlsAeadCipherImpl.cs b/crypto/src/tls/crypto/impl/TlsAeadCipherImpl.cs
index 4c69c0b72..0cd2923c2 100644
--- a/crypto/src/tls/crypto/impl/TlsAeadCipherImpl.cs
+++ b/crypto/src/tls/crypto/impl/TlsAeadCipherImpl.cs
@@ -41,5 +41,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl
         /// <returns>the amount of data written to output.</returns>
         /// <exception cref="IOException">in case of failure.</exception>
         int DoFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset);
+
+        void Reset();
     }
 }
diff --git a/crypto/src/tls/crypto/impl/bc/BcChaCha20Poly1305.cs b/crypto/src/tls/crypto/impl/bc/BcChaCha20Poly1305.cs
index f8e36a245..06a09bbb1 100644
--- a/crypto/src/tls/crypto/impl/bc/BcChaCha20Poly1305.cs
+++ b/crypto/src/tls/crypto/impl/bc/BcChaCha20Poly1305.cs
@@ -96,6 +96,12 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
             }
         }
 
+        public void Reset()
+        {
+            m_cipher.Reset();
+            m_mac.Reset();
+        }
+
         public void SetKey(byte[] key, int keyOff, int keyLen)
         {
             KeyParameter cipherKey = new KeyParameter(key, keyOff, keyLen);
diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsAeadCipherImpl.cs b/crypto/src/tls/crypto/impl/bc/BcTlsAeadCipherImpl.cs
index 0b2781326..4965c92bd 100644
--- a/crypto/src/tls/crypto/impl/bc/BcTlsAeadCipherImpl.cs
+++ b/crypto/src/tls/crypto/impl/bc/BcTlsAeadCipherImpl.cs
@@ -57,5 +57,10 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
 
             return len;
         }
+
+        public void Reset()
+        {
+            m_cipher.Reset();
+        }
     }
 }