From 3d0253fd6482ba5eead389248729f44099254db8 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Sun, 16 Apr 2023 22:16:32 +0700 Subject: FIx binary compatibility issues --- crypto/src/tls/DtlsRecordLayer.cs | 8 ++-- crypto/src/tls/RecordStream.cs | 4 +- crypto/src/tls/crypto/TlsCipher.cs | 1 + crypto/src/tls/crypto/impl/AbstractTlsCipher.cs | 56 ------------------------- crypto/src/tls/crypto/impl/TlsAeadCipher.cs | 28 ++++++++----- crypto/src/tls/crypto/impl/TlsBlockCipher.cs | 34 +++++++++++---- crypto/src/tls/crypto/impl/TlsCipherExt.cs | 10 +++++ crypto/src/tls/crypto/impl/TlsNullCipher.cs | 34 +++++++++++---- 8 files changed, 84 insertions(+), 91 deletions(-) delete mode 100644 crypto/src/tls/crypto/impl/AbstractTlsCipher.cs create mode 100644 crypto/src/tls/crypto/impl/TlsCipherExt.cs diff --git a/crypto/src/tls/DtlsRecordLayer.cs b/crypto/src/tls/DtlsRecordLayer.cs index a18210de2..efe9e7312 100644 --- a/crypto/src/tls/DtlsRecordLayer.cs +++ b/crypto/src/tls/DtlsRecordLayer.cs @@ -240,9 +240,9 @@ namespace Org.BouncyCastle.Tls var cipher = m_readEpoch.Cipher; int plaintextDecodeLimit; - if (cipher is AbstractTlsCipher abstractTlsCipher) + if (cipher is TlsCipherExt tlsCipherExt) { - plaintextDecodeLimit = abstractTlsCipher.GetPlaintextDecodeLimit(ciphertextLimit); + plaintextDecodeLimit = tlsCipherExt.GetPlaintextDecodeLimit(ciphertextLimit); } else { @@ -259,9 +259,9 @@ namespace Org.BouncyCastle.Tls int ciphertextLimit = m_transport.GetSendLimit() - m_writeEpoch.RecordHeaderLengthWrite; int plaintextEncodeLimit; - if (cipher is AbstractTlsCipher abstractTlsCipher) + if (cipher is TlsCipherExt tlsCipherExt) { - plaintextEncodeLimit = abstractTlsCipher.GetPlaintextEncodeLimit(ciphertextLimit); + plaintextEncodeLimit = tlsCipherExt.GetPlaintextEncodeLimit(ciphertextLimit); } else { diff --git a/crypto/src/tls/RecordStream.cs b/crypto/src/tls/RecordStream.cs index 5b5ceff34..739ee8d70 100644 --- a/crypto/src/tls/RecordStream.cs +++ b/crypto/src/tls/RecordStream.cs @@ -153,9 +153,9 @@ namespace Org.BouncyCastle.Tls var cipher = m_readCipher; int plaintextDecodeLimit; - if (cipher is AbstractTlsCipher abstractTlsCipher) + if (cipher is TlsCipherExt tlsCipherExt) { - plaintextDecodeLimit = abstractTlsCipher.GetPlaintextDecodeLimit(length); + plaintextDecodeLimit = tlsCipherExt.GetPlaintextDecodeLimit(length); } else { diff --git a/crypto/src/tls/crypto/TlsCipher.cs b/crypto/src/tls/crypto/TlsCipher.cs index 9b69923ec..5665cbb7e 100644 --- a/crypto/src/tls/crypto/TlsCipher.cs +++ b/crypto/src/tls/crypto/TlsCipher.cs @@ -23,6 +23,7 @@ namespace Org.BouncyCastle.Tls.Crypto /// Return the maximum size for the plaintext given ciphertextlimit bytes of ciphertext. /// the maximum number of bytes of ciphertext. /// the maximum size of the plaintext for ciphertextlimit bytes of input. + // TODO[api] Remove int GetPlaintextLimit(int ciphertextLimit); /// Encode the passed in plaintext using the current bulk cipher. diff --git a/crypto/src/tls/crypto/impl/AbstractTlsCipher.cs b/crypto/src/tls/crypto/impl/AbstractTlsCipher.cs deleted file mode 100644 index 5315eb965..000000000 --- a/crypto/src/tls/crypto/impl/AbstractTlsCipher.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; - -using Org.BouncyCastle.Utilities.IO.Compression; - -namespace Org.BouncyCastle.Tls.Crypto.Impl -{ - public abstract class AbstractTlsCipher - : TlsCipher - { - public abstract int GetCiphertextDecodeLimit(int plaintextLimit); - - public abstract int GetCiphertextEncodeLimit(int plaintextLength, int plaintextLimit); - - // TODO[api] Remove this method from TlsCipher - public virtual int GetPlaintextLimit(int ciphertextLimit) - { - return GetPlaintextEncodeLimit(ciphertextLimit); - } - - // TODO[api] Add to TlsCipher - public virtual int GetPlaintextDecodeLimit(int ciphertextLimit) - { - return GetPlaintextLimit(ciphertextLimit); - } - - // TODO[api] Add to TlsCipher - public virtual int GetPlaintextEncodeLimit(int ciphertextLimit) - { - return GetPlaintextLimit(ciphertextLimit); - } - - public abstract TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, - int headerAllocation, byte[] plaintext, int offset, int len); - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public abstract TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, - int headerAllocation, ReadOnlySpan plaintext); -#endif - - // TODO[api] Add span-based version? - public abstract TlsDecodeResult DecodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion, - byte[] ciphertext, int offset, int len); - - public virtual void RekeyDecoder() - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - public virtual void RekeyEncoder() - { - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - public abstract bool UsesOpaqueRecordType { get; } - } -} diff --git a/crypto/src/tls/crypto/impl/TlsAeadCipher.cs b/crypto/src/tls/crypto/impl/TlsAeadCipher.cs index f8f01f380..e34ca589d 100644 --- a/crypto/src/tls/crypto/impl/TlsAeadCipher.cs +++ b/crypto/src/tls/crypto/impl/TlsAeadCipher.cs @@ -7,7 +7,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl { /// A generic TLS 1.2 AEAD cipher. public class TlsAeadCipher - : AbstractTlsCipher + : TlsCipher, TlsCipherExt { public const int AEAD_CCM = 1; public const int AEAD_CHACHA20_POLY1305 = 2; @@ -145,14 +145,14 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl decryptCipher.Init(dummyNonce, macSize, null); } - public override int GetCiphertextDecodeLimit(int plaintextLimit) + public virtual int GetCiphertextDecodeLimit(int plaintextLimit) { int innerPlaintextLimit = plaintextLimit + (m_decryptUseInnerPlaintext ? 1 : 0); return innerPlaintextLimit + m_macSize + m_record_iv_length; } - public override int GetCiphertextEncodeLimit(int plaintextLength, int plaintextLimit) + public virtual int GetCiphertextEncodeLimit(int plaintextLength, int plaintextLimit) { plaintextLimit = System.Math.Min(plaintextLength, plaintextLimit); @@ -161,21 +161,27 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl return innerPlaintextLimit + m_macSize + m_record_iv_length; } - public override int GetPlaintextDecodeLimit(int ciphertextLimit) + // TODO[api] Remove + public virtual int GetPlaintextLimit(int ciphertextLimit) + { + return GetPlaintextEncodeLimit(ciphertextLimit); + } + + public virtual int GetPlaintextDecodeLimit(int ciphertextLimit) { int innerPlaintextLimit = ciphertextLimit - m_macSize - m_record_iv_length; return innerPlaintextLimit - (m_decryptUseInnerPlaintext ? 1 : 0); } - public override int GetPlaintextEncodeLimit(int ciphertextLimit) + public virtual int GetPlaintextEncodeLimit(int ciphertextLimit) { int innerPlaintextLimit = ciphertextLimit - m_macSize - m_record_iv_length; return innerPlaintextLimit - (m_encryptUseInnerPlaintext ? 1 : 0); } - public override TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, + public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, int headerAllocation, byte[] plaintext, int plaintextOffset, int plaintextLength) { #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -257,7 +263,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public override TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, + public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, int headerAllocation, ReadOnlySpan plaintext) { byte[] nonce = new byte[m_encryptNonce.Length + m_record_iv_length]; @@ -334,7 +340,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl } #endif - public override TlsDecodeResult DecodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion, + public virtual TlsDecodeResult DecodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion, byte[] ciphertext, int ciphertextOffset, int ciphertextLength) { if (GetPlaintextDecodeLimit(ciphertextLength) < 0) @@ -421,17 +427,17 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl return new TlsDecodeResult(ciphertext, encryptionOffset, plaintextLength, contentType); } - public override void RekeyDecoder() + public virtual void RekeyDecoder() { RekeyCipher(m_cryptoParams.SecurityParameters, m_decryptCipher, m_decryptNonce, !m_cryptoParams.IsServer); } - public override void RekeyEncoder() + public virtual void RekeyEncoder() { RekeyCipher(m_cryptoParams.SecurityParameters, m_encryptCipher, m_encryptNonce, m_cryptoParams.IsServer); } - public override bool UsesOpaqueRecordType + public virtual bool UsesOpaqueRecordType { get { return m_isTlsV13; } } diff --git a/crypto/src/tls/crypto/impl/TlsBlockCipher.cs b/crypto/src/tls/crypto/impl/TlsBlockCipher.cs index bc04caee1..479f00fc9 100644 --- a/crypto/src/tls/crypto/impl/TlsBlockCipher.cs +++ b/crypto/src/tls/crypto/impl/TlsBlockCipher.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl { /// A generic TLS 1.0-1.2 block cipher. This can be used for AES or 3DES for example. public class TlsBlockCipher - : AbstractTlsCipher + : TlsCipher, TlsCipherExt { protected readonly TlsCryptoParameters m_cryptoParams; protected readonly byte[] m_randomData; @@ -155,7 +155,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl } } - public override int GetCiphertextDecodeLimit(int plaintextLimit) + public virtual int GetCiphertextDecodeLimit(int plaintextLimit) { int blockSize = m_decryptCipher.GetBlockSize(); int macSize = m_readMac.Size; @@ -165,7 +165,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl return GetCiphertextLength(blockSize, macSize, maxPadding, innerPlaintextLimit); } - public override int GetCiphertextEncodeLimit(int plaintextLength, int plaintextLimit) + public virtual int GetCiphertextEncodeLimit(int plaintextLength, int plaintextLimit) { plaintextLimit = System.Math.Min(plaintextLength, plaintextLimit); @@ -177,7 +177,13 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl return GetCiphertextLength(blockSize, macSize, maxPadding, innerPlaintextLimit); } - public override int GetPlaintextDecodeLimit(int ciphertextLimit) + // TODO[api] Remove + public virtual int GetPlaintextLimit(int ciphertextLimit) + { + return GetPlaintextEncodeLimit(ciphertextLimit); + } + + public virtual int GetPlaintextDecodeLimit(int ciphertextLimit) { int blockSize = m_decryptCipher.GetBlockSize(); int macSize = m_readMac.Size; @@ -187,7 +193,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl return innerPlaintextLimit - (m_decryptUseInnerPlaintext ? 1 : 0); } - public override int GetPlaintextEncodeLimit(int ciphertextLimit) + public virtual int GetPlaintextEncodeLimit(int ciphertextLimit) { int blockSize = m_encryptCipher.GetBlockSize(); int macSize = m_writeMac.Size; @@ -197,7 +203,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl return innerPlaintextLimit - (m_encryptUseInnerPlaintext ? 1 : 0); } - public override TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, + public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, int headerAllocation, byte[] plaintext, int offset, int len) { #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -285,7 +291,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public override TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, + public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, int headerAllocation, ReadOnlySpan plaintext) { int blockSize = m_encryptCipher.GetBlockSize(); @@ -369,7 +375,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl } #endif - public override TlsDecodeResult DecodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion, + public virtual TlsDecodeResult DecodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion, byte[] ciphertext, int offset, int len) { int blockSize = m_decryptCipher.GetBlockSize(); @@ -475,7 +481,17 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl return new TlsDecodeResult(ciphertext, offset, plaintextLength, contentType); } - public override bool UsesOpaqueRecordType + public virtual void RekeyDecoder() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual void RekeyEncoder() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual bool UsesOpaqueRecordType { get { return false; } } diff --git a/crypto/src/tls/crypto/impl/TlsCipherExt.cs b/crypto/src/tls/crypto/impl/TlsCipherExt.cs new file mode 100644 index 000000000..8e2742a69 --- /dev/null +++ b/crypto/src/tls/crypto/impl/TlsCipherExt.cs @@ -0,0 +1,10 @@ +namespace Org.BouncyCastle.Tls.Crypto +{ + // TODO[api] Merge into TlsCipher + public interface TlsCipherExt + { + int GetPlaintextDecodeLimit(int ciphertextLimit); + + int GetPlaintextEncodeLimit(int ciphertextLimit); + } +} diff --git a/crypto/src/tls/crypto/impl/TlsNullCipher.cs b/crypto/src/tls/crypto/impl/TlsNullCipher.cs index 8e52f6374..fa40d7812 100644 --- a/crypto/src/tls/crypto/impl/TlsNullCipher.cs +++ b/crypto/src/tls/crypto/impl/TlsNullCipher.cs @@ -7,7 +7,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl { /// The NULL cipher. public class TlsNullCipher - : AbstractTlsCipher + : TlsCipher, TlsCipherExt { protected readonly TlsCryptoParameters m_cryptoParams; protected readonly TlsSuiteHmac m_readMac, m_writeMac; @@ -69,14 +69,14 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl } } - public override int GetCiphertextDecodeLimit(int plaintextLimit) + public virtual int GetCiphertextDecodeLimit(int plaintextLimit) { int innerPlaintextLimit = plaintextLimit + (m_decryptUseInnerPlaintext ? 1 : 0); return innerPlaintextLimit + m_readMac.Size; } - public override int GetCiphertextEncodeLimit(int plaintextLength, int plaintextLimit) + public virtual int GetCiphertextEncodeLimit(int plaintextLength, int plaintextLimit) { plaintextLimit = System.Math.Min(plaintextLength, plaintextLimit); @@ -85,21 +85,27 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl return innerPlaintextLimit + m_writeMac.Size; } - public override int GetPlaintextDecodeLimit(int ciphertextLimit) + // TODO[api] Remove + public virtual int GetPlaintextLimit(int ciphertextLimit) + { + return GetPlaintextEncodeLimit(ciphertextLimit); + } + + public virtual int GetPlaintextDecodeLimit(int ciphertextLimit) { int innerPlaintextLimit = ciphertextLimit - m_readMac.Size; return innerPlaintextLimit - (m_decryptUseInnerPlaintext ? 1 : 0); } - public override int GetPlaintextEncodeLimit(int ciphertextLimit) + public virtual int GetPlaintextEncodeLimit(int ciphertextLimit) { int innerPlaintextLimit = ciphertextLimit - m_writeMac.Size; return innerPlaintextLimit - (m_encryptUseInnerPlaintext ? 1 : 0); } - public override TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, + public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, int headerAllocation, byte[] plaintext, int offset, int len) { #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -129,7 +135,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public override TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, + public virtual TlsEncodeResult EncodePlaintext(long seqNo, short contentType, ProtocolVersion recordVersion, int headerAllocation, ReadOnlySpan plaintext) { int macSize = m_writeMac.Size; @@ -155,7 +161,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl } #endif - public override TlsDecodeResult DecodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion, + public virtual TlsDecodeResult DecodeCiphertext(long seqNo, short recordType, ProtocolVersion recordVersion, byte[] ciphertext, int offset, int len) { int macSize = m_readMac.Size; @@ -196,7 +202,17 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl return new TlsDecodeResult(ciphertext, offset, plaintextLength, contentType); } - public override bool UsesOpaqueRecordType + public virtual void RekeyDecoder() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual void RekeyEncoder() + { + throw new TlsFatalAlert(AlertDescription.internal_error); + } + + public virtual bool UsesOpaqueRecordType { get { return false; } } -- cgit 1.4.1