From a7a6aba45084e98996551712458b9e38ead2593c Mon Sep 17 00:00:00 2001 From: ROM-Knowledgeware Date: Wed, 22 Nov 2017 18:30:41 +0200 Subject: BouncyCastle.csproj: Added trailing slash to OutputPath for compatibility with MSBuild v2 Without this fix, MSBuild will name the output file 'net20BouncyCastle.dll'. This change is 100% compatible with newer versions of MSBuild. p.s. When setting the output path with the Visual Studio GUI (any version I tested) a trailing slash is being used. --- crypto/BouncyCastle.csproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crypto/BouncyCastle.csproj b/crypto/BouncyCastle.csproj index a5f149620..9e1150c00 100644 --- a/crypto/BouncyCastle.csproj +++ b/crypto/BouncyCastle.csproj @@ -16,8 +16,8 @@ true full false - bin\Debug\lib\net20 - obj\Debug\lib\net20 + bin\Debug\lib\net20\ + obj\Debug\lib\net20\ DEBUG;TRACE;INCLUDE_IDEA; prompt 4 @@ -25,8 +25,8 @@ true - bin\Release\lib\net20 - obj\Release\lib\net20 + bin\Release\lib\net20\ + obj\Release\lib\net20\ TRACE;INCLUDE_IDEA; doc\BouncyCastle.xml prompt -- cgit 1.5.1 From c0ee6b45d8764144f3a5b36d286e7520d35b63e7 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 24 Jul 2018 15:27:51 +0700 Subject: TLS: Use DH group whitelisting --- crypto/BouncyCastle.Android.csproj | 3 +- crypto/BouncyCastle.csproj | 3 +- crypto/BouncyCastle.iOS.csproj | 3 +- crypto/crypto.csproj | 15 ++-- crypto/src/crypto/tls/DefaultTlsClient.cs | 16 +++- crypto/src/crypto/tls/DefaultTlsDHVerifier.cs | 101 ++++++++++++++++++++++++++ crypto/src/crypto/tls/DefaultTlsServer.cs | 4 +- crypto/src/crypto/tls/PskTlsClient.cs | 15 +++- crypto/src/crypto/tls/PskTlsServer.cs | 2 +- crypto/src/crypto/tls/ServerDHParams.cs | 61 ---------------- crypto/src/crypto/tls/TlsDHKeyExchange.cs | 32 ++------ crypto/src/crypto/tls/TlsDHUtilities.cs | 43 +++++------ crypto/src/crypto/tls/TlsDHVerifier.cs | 15 ++++ crypto/src/crypto/tls/TlsDheKeyExchange.cs | 11 +-- crypto/src/crypto/tls/TlsPskKeyExchange.cs | 15 ++-- 15 files changed, 196 insertions(+), 143 deletions(-) create mode 100644 crypto/src/crypto/tls/DefaultTlsDHVerifier.cs delete mode 100644 crypto/src/crypto/tls/ServerDHParams.cs create mode 100644 crypto/src/crypto/tls/TlsDHVerifier.cs diff --git a/crypto/BouncyCastle.Android.csproj b/crypto/BouncyCastle.Android.csproj index a9ddae8d8..3c34c5e1b 100644 --- a/crypto/BouncyCastle.Android.csproj +++ b/crypto/BouncyCastle.Android.csproj @@ -1002,6 +1002,7 @@ + @@ -1045,7 +1046,6 @@ - @@ -1076,6 +1076,7 @@ + diff --git a/crypto/BouncyCastle.csproj b/crypto/BouncyCastle.csproj index 981cefbe6..f772ed002 100644 --- a/crypto/BouncyCastle.csproj +++ b/crypto/BouncyCastle.csproj @@ -996,6 +996,7 @@ + @@ -1039,7 +1040,6 @@ - @@ -1070,6 +1070,7 @@ + diff --git a/crypto/BouncyCastle.iOS.csproj b/crypto/BouncyCastle.iOS.csproj index c97d9bf65..f9cebdc86 100644 --- a/crypto/BouncyCastle.iOS.csproj +++ b/crypto/BouncyCastle.iOS.csproj @@ -997,6 +997,7 @@ + @@ -1040,7 +1041,6 @@ - @@ -1071,6 +1071,7 @@ + diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj index 7cd8de821..b6dfb3963 100644 --- a/crypto/crypto.csproj +++ b/crypto/crypto.csproj @@ -4868,6 +4868,11 @@ SubType = "Code" BuildAction = "Compile" /> + - + Accept various standard DH groups with 'P' at least DefaultMinimumPrimeBits bits. + public DefaultTlsDHVerifier() + : this(DefaultMinimumPrimeBits) + { + } + + /// Accept various standard DH groups with 'P' at least the specified number of bits. + public DefaultTlsDHVerifier(int minimumPrimeBits) + : this(DefaultGroups, minimumPrimeBits) + { + } + + /// Accept a custom set of group parameters, subject to a minimum bitlength for 'P'. + /// An IList of acceptable DHParameters. + /// The minimum acceptable bitlength of the 'P' parameter. + public DefaultTlsDHVerifier(IList groups, int minimumPrimeBits) + { + this.mGroups = groups; + this.mMinimumPrimeBits = minimumPrimeBits; + } + + public virtual bool Accept(DHParameters dhParameters) + { + return CheckMinimumPrimeBits(dhParameters) && CheckGroup(dhParameters); + } + + public virtual int MinimumPrimeBits + { + get { return mMinimumPrimeBits; } + } + + protected virtual bool AreGroupsEqual(DHParameters a, DHParameters b) + { + return a == b || (AreParametersEqual(a.P, b.P) && AreParametersEqual(a.G, b.G)); + } + + protected virtual bool AreParametersEqual(BigInteger a, BigInteger b) + { + return a == b || a.Equals(b); + } + + protected virtual bool CheckGroup(DHParameters dhParameters) + { + foreach (DHParameters group in mGroups) + { + if (AreGroupsEqual(dhParameters, group)) + { + return true; + } + } + return false; + } + + protected virtual bool CheckMinimumPrimeBits(DHParameters dhParameters) + { + return dhParameters.P.BitLength >= MinimumPrimeBits; + } + } +} diff --git a/crypto/src/crypto/tls/DefaultTlsServer.cs b/crypto/src/crypto/tls/DefaultTlsServer.cs index 97eaa079d..90f357687 100644 --- a/crypto/src/crypto/tls/DefaultTlsServer.cs +++ b/crypto/src/crypto/tls/DefaultTlsServer.cs @@ -138,12 +138,12 @@ namespace Org.BouncyCastle.Crypto.Tls protected virtual TlsKeyExchange CreateDHKeyExchange(int keyExchange) { - return new TlsDHKeyExchange(keyExchange, mSupportedSignatureAlgorithms, GetDHParameters()); + return new TlsDHKeyExchange(keyExchange, mSupportedSignatureAlgorithms, null, GetDHParameters()); } protected virtual TlsKeyExchange CreateDheKeyExchange(int keyExchange) { - return new TlsDheKeyExchange(keyExchange, mSupportedSignatureAlgorithms, GetDHParameters()); + return new TlsDheKeyExchange(keyExchange, mSupportedSignatureAlgorithms, null, GetDHParameters()); } protected virtual TlsKeyExchange CreateECDHKeyExchange(int keyExchange) diff --git a/crypto/src/crypto/tls/PskTlsClient.cs b/crypto/src/crypto/tls/PskTlsClient.cs index 2ef80dcfd..1dc119d7b 100644 --- a/crypto/src/crypto/tls/PskTlsClient.cs +++ b/crypto/src/crypto/tls/PskTlsClient.cs @@ -6,16 +6,23 @@ namespace Org.BouncyCastle.Crypto.Tls public class PskTlsClient : AbstractTlsClient { + protected TlsDHVerifier mDHVerifier; protected TlsPskIdentity mPskIdentity; public PskTlsClient(TlsPskIdentity pskIdentity) - : this(new DefaultTlsCipherFactory(), pskIdentity) + : this(new DefaultTlsCipherFactory(), pskIdentity) { } public PskTlsClient(TlsCipherFactory cipherFactory, TlsPskIdentity pskIdentity) - : base(cipherFactory) + : this(cipherFactory, new DefaultTlsDHVerifier(), pskIdentity) { + } + + public PskTlsClient(TlsCipherFactory cipherFactory, TlsDHVerifier dhVerifier, TlsPskIdentity pskIdentity) + : base(cipherFactory) + { + this.mDHVerifier = dhVerifier; this.mPskIdentity = pskIdentity; } @@ -63,8 +70,8 @@ namespace Org.BouncyCastle.Crypto.Tls protected virtual TlsKeyExchange CreatePskKeyExchange(int keyExchange) { - return new TlsPskKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mPskIdentity, null, null, mNamedCurves, - mClientECPointFormats, mServerECPointFormats); + return new TlsPskKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mPskIdentity, null, mDHVerifier, null, + mNamedCurves, mClientECPointFormats, mServerECPointFormats); } } } diff --git a/crypto/src/crypto/tls/PskTlsServer.cs b/crypto/src/crypto/tls/PskTlsServer.cs index b0fb67c04..a3778420d 100644 --- a/crypto/src/crypto/tls/PskTlsServer.cs +++ b/crypto/src/crypto/tls/PskTlsServer.cs @@ -87,7 +87,7 @@ namespace Org.BouncyCastle.Crypto.Tls protected virtual TlsKeyExchange CreatePskKeyExchange(int keyExchange) { return new TlsPskKeyExchange(keyExchange, mSupportedSignatureAlgorithms, null, mPskIdentityManager, - GetDHParameters(), mNamedCurves, mClientECPointFormats, mServerECPointFormats); + null, GetDHParameters(), mNamedCurves, mClientECPointFormats, mServerECPointFormats); } } } diff --git a/crypto/src/crypto/tls/ServerDHParams.cs b/crypto/src/crypto/tls/ServerDHParams.cs deleted file mode 100644 index b09262771..000000000 --- a/crypto/src/crypto/tls/ServerDHParams.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.IO; - -using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Math; - -namespace Org.BouncyCastle.Crypto.Tls -{ - public class ServerDHParams - { - protected readonly DHPublicKeyParameters mPublicKey; - - public ServerDHParams(DHPublicKeyParameters publicKey) - { - if (publicKey == null) - throw new ArgumentNullException("publicKey"); - - this.mPublicKey = publicKey; - } - - public virtual DHPublicKeyParameters PublicKey - { - get { return mPublicKey; } - } - - /** - * Encode this {@link ServerDHParams} to a {@link Stream}. - * - * @param output - * the {@link Stream} to encode to. - * @throws IOException - */ - public virtual void Encode(Stream output) - { - DHParameters dhParameters = mPublicKey.Parameters; - BigInteger Ys = mPublicKey.Y; - - TlsDHUtilities.WriteDHParameter(dhParameters.P, output); - TlsDHUtilities.WriteDHParameter(dhParameters.G, output); - TlsDHUtilities.WriteDHParameter(Ys, output); - } - - /** - * Parse a {@link ServerDHParams} from a {@link Stream}. - * - * @param input - * the {@link Stream} to parse from. - * @return a {@link ServerDHParams} object. - * @throws IOException - */ - public static ServerDHParams Parse(Stream input) - { - BigInteger p = TlsDHUtilities.ReadDHParameter(input); - BigInteger g = TlsDHUtilities.ReadDHParameter(input); - BigInteger Ys = TlsDHUtilities.ReadDHParameter(input); - - return new ServerDHParams( - TlsDHUtilities.ValidateDHPublicKey(new DHPublicKeyParameters(Ys, new DHParameters(p, g)))); - } - } -} diff --git a/crypto/src/crypto/tls/TlsDHKeyExchange.cs b/crypto/src/crypto/tls/TlsDHKeyExchange.cs index d179068bb..59d52265b 100644 --- a/crypto/src/crypto/tls/TlsDHKeyExchange.cs +++ b/crypto/src/crypto/tls/TlsDHKeyExchange.cs @@ -4,7 +4,6 @@ using System.IO; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; namespace Org.BouncyCastle.Crypto.Tls @@ -14,6 +13,7 @@ namespace Org.BouncyCastle.Crypto.Tls : AbstractTlsKeyExchange { protected TlsSigner mTlsSigner; + protected TlsDHVerifier mDHVerifier; protected DHParameters mDHParameters; protected AsymmetricKeyParameter mServerPublicKey; @@ -22,7 +22,7 @@ namespace Org.BouncyCastle.Crypto.Tls protected DHPrivateKeyParameters mDHAgreePrivateKey; protected DHPublicKeyParameters mDHAgreePublicKey; - public TlsDHKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, DHParameters dhParameters) + public TlsDHKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, TlsDHVerifier dhVerifier, DHParameters dhParameters) : base(keyExchange, supportedSignatureAlgorithms) { switch (keyExchange) @@ -42,6 +42,7 @@ namespace Org.BouncyCastle.Crypto.Tls throw new InvalidOperationException("unsupported key exchange algorithm"); } + this.mDHVerifier = dhVerifier; this.mDHParameters = dhParameters; } @@ -84,8 +85,8 @@ namespace Org.BouncyCastle.Crypto.Tls { try { - this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey((DHPublicKeyParameters)this.mServerPublicKey); - this.mDHParameters = ValidateDHParameters(mDHAgreePublicKey.Parameters); + this.mDHAgreePublicKey = (DHPublicKeyParameters)this.mServerPublicKey; + this.mDHParameters = mDHAgreePublicKey.Parameters; } catch (InvalidCastException e) { @@ -143,10 +144,8 @@ namespace Org.BouncyCastle.Crypto.Tls // DH_anon is handled here, DHE_* in a subclass - ServerDHParams dhParams = ServerDHParams.Parse(input); - - this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(dhParams.PublicKey); - this.mDHParameters = ValidateDHParameters(mDHAgreePublicKey.Parameters); + this.mDHParameters = TlsDHUtilities.ReceiveDHParameters(mDHVerifier, input); + this.mDHAgreePublicKey = new DHPublicKeyParameters(TlsDHUtilities.ReadDHParameter(input), mDHParameters); } public override void ValidateCertificateRequest(CertificateRequest certificateRequest) @@ -223,9 +222,7 @@ namespace Org.BouncyCastle.Crypto.Tls return; } - BigInteger Yc = TlsDHUtilities.ReadDHParameter(input); - - this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(new DHPublicKeyParameters(Yc, mDHParameters)); + this.mDHAgreePublicKey = new DHPublicKeyParameters(TlsDHUtilities.ReadDHParameter(input), mDHParameters); } public override byte[] GeneratePremasterSecret() @@ -242,18 +239,5 @@ namespace Org.BouncyCastle.Crypto.Tls throw new TlsFatalAlert(AlertDescription.internal_error); } - - protected virtual int MinimumPrimeBits - { - get { return 1024; } - } - - protected virtual DHParameters ValidateDHParameters(DHParameters parameters) - { - if (parameters.P.BitLength < MinimumPrimeBits) - throw new TlsFatalAlert(AlertDescription.insufficient_security); - - return TlsDHUtilities.ValidateDHParameters(parameters); - } } } diff --git a/crypto/src/crypto/tls/TlsDHUtilities.cs b/crypto/src/crypto/tls/TlsDHUtilities.cs index 6df61cbed..9567ee062 100644 --- a/crypto/src/crypto/tls/TlsDHUtilities.cs +++ b/crypto/src/crypto/tls/TlsDHUtilities.cs @@ -417,46 +417,43 @@ namespace Org.BouncyCastle.Crypto.Tls AsymmetricCipherKeyPair kp = GenerateDHKeyPair(random, dhParams); DHPublicKeyParameters dhPublic = (DHPublicKeyParameters)kp.Public; - new ServerDHParams(dhPublic).Encode(output); + WriteDHParameters(dhParams, output); + WriteDHParameter(dhPublic.Y, output); return (DHPrivateKeyParameters)kp.Private; } - public static DHParameters ValidateDHParameters(DHParameters parameters) + public static BigInteger ReadDHParameter(Stream input) { - BigInteger p = parameters.P; - BigInteger g = parameters.G; - - if (!p.IsProbablePrime(2)) - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - if (g.CompareTo(Two) < 0 || g.CompareTo(p.Subtract(Two)) > 0) - throw new TlsFatalAlert(AlertDescription.illegal_parameter); - - - return parameters; + return new BigInteger(1, TlsUtilities.ReadOpaque16(input)); } - public static DHPublicKeyParameters ValidateDHPublicKey(DHPublicKeyParameters key) + public static DHParameters ReadDHParameters(Stream input) { - DHParameters parameters = ValidateDHParameters(key.Parameters); - - BigInteger Y = key.Y; - if (Y.CompareTo(Two) < 0 || Y.CompareTo(parameters.P.Subtract(Two)) > 0) - throw new TlsFatalAlert(AlertDescription.illegal_parameter); + BigInteger p = ReadDHParameter(input); + BigInteger g = ReadDHParameter(input); - // TODO See RFC 2631 for more discussion of Diffie-Hellman validation - - return key; + return new DHParameters(p, g); } - public static BigInteger ReadDHParameter(Stream input) + public static DHParameters ReceiveDHParameters(TlsDHVerifier dhVerifier, Stream input) { - return new BigInteger(1, TlsUtilities.ReadOpaque16(input)); + DHParameters dhParameters = ReadDHParameters(input); + if (!dhVerifier.Accept(dhParameters)) + throw new TlsFatalAlert(AlertDescription.insufficient_security); + + return dhParameters; } public static void WriteDHParameter(BigInteger x, Stream output) { TlsUtilities.WriteOpaque16(BigIntegers.AsUnsignedByteArray(x), output); } + + public static void WriteDHParameters(DHParameters dhParameters, Stream output) + { + WriteDHParameter(dhParameters.P, output); + WriteDHParameter(dhParameters.G, output); + } } } diff --git a/crypto/src/crypto/tls/TlsDHVerifier.cs b/crypto/src/crypto/tls/TlsDHVerifier.cs new file mode 100644 index 000000000..867403c3c --- /dev/null +++ b/crypto/src/crypto/tls/TlsDHVerifier.cs @@ -0,0 +1,15 @@ +using System; + +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Crypto.Tls +{ + /// An interface for verifying that Diffie-Hellman parameters are acceptable. + public interface TlsDHVerifier + { + /// Verify that the given DHParameters are acceptable. + /// The DHParameters to verify. + /// true if (and only if) the specified parameters are acceptable. + bool Accept(DHParameters dhParameters); + } +} diff --git a/crypto/src/crypto/tls/TlsDheKeyExchange.cs b/crypto/src/crypto/tls/TlsDheKeyExchange.cs index cdd629247..402c74720 100644 --- a/crypto/src/crypto/tls/TlsDheKeyExchange.cs +++ b/crypto/src/crypto/tls/TlsDheKeyExchange.cs @@ -3,7 +3,6 @@ using System.Collections; using System.IO; using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities.IO; @@ -14,8 +13,8 @@ namespace Org.BouncyCastle.Crypto.Tls { protected TlsSignerCredentials mServerCredentials = null; - public TlsDheKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, DHParameters dhParameters) - : base(keyExchange, supportedSignatureAlgorithms, dhParameters) + public TlsDheKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, TlsDHVerifier dhVerifier, DHParameters dhParameters) + : base(keyExchange, supportedSignatureAlgorithms, dhVerifier, dhParameters) { } @@ -69,7 +68,8 @@ namespace Org.BouncyCastle.Crypto.Tls SignerInputBuffer buf = new SignerInputBuffer(); Stream teeIn = new TeeInputStream(input, buf); - ServerDHParams dhParams = ServerDHParams.Parse(teeIn); + this.mDHParameters = TlsDHUtilities.ReceiveDHParameters(mDHVerifier, teeIn); + this.mDHAgreePublicKey = new DHPublicKeyParameters(TlsDHUtilities.ReadDHParameter(teeIn), mDHParameters); DigitallySigned signed_params = ParseSignature(input); @@ -77,9 +77,6 @@ namespace Org.BouncyCastle.Crypto.Tls buf.UpdateSigner(signer); if (!signer.VerifySignature(signed_params.Signature)) throw new TlsFatalAlert(AlertDescription.decrypt_error); - - this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(dhParams.PublicKey); - this.mDHParameters = ValidateDHParameters(mDHAgreePublicKey.Parameters); } protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm, diff --git a/crypto/src/crypto/tls/TlsPskKeyExchange.cs b/crypto/src/crypto/tls/TlsPskKeyExchange.cs index 0af7f7a69..36ef09e85 100644 --- a/crypto/src/crypto/tls/TlsPskKeyExchange.cs +++ b/crypto/src/crypto/tls/TlsPskKeyExchange.cs @@ -4,7 +4,6 @@ using System.IO; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.IO; @@ -18,6 +17,7 @@ namespace Org.BouncyCastle.Crypto.Tls protected TlsPskIdentity mPskIdentity; protected TlsPskIdentityManager mPskIdentityManager; + protected TlsDHVerifier mDHVerifier; protected DHParameters mDHParameters; protected int[] mNamedCurves; protected byte[] mClientECPointFormats, mServerECPointFormats; @@ -37,7 +37,7 @@ namespace Org.BouncyCastle.Crypto.Tls protected byte[] mPremasterSecret; public TlsPskKeyExchange(int keyExchange, IList supportedSignatureAlgorithms, TlsPskIdentity pskIdentity, - TlsPskIdentityManager pskIdentityManager, DHParameters dhParameters, int[] namedCurves, + TlsPskIdentityManager pskIdentityManager, TlsDHVerifier dhVerifier, DHParameters dhParameters, int[] namedCurves, byte[] clientECPointFormats, byte[] serverECPointFormats) : base(keyExchange, supportedSignatureAlgorithms) { @@ -54,6 +54,7 @@ namespace Org.BouncyCastle.Crypto.Tls this.mPskIdentity = pskIdentity; this.mPskIdentityManager = pskIdentityManager; + this.mDHVerifier = dhVerifier; this.mDHParameters = dhParameters; this.mNamedCurves = namedCurves; this.mClientECPointFormats = clientECPointFormats; @@ -162,10 +163,8 @@ namespace Org.BouncyCastle.Crypto.Tls if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK) { - ServerDHParams serverDHParams = ServerDHParams.Parse(input); - - this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(serverDHParams.PublicKey); - this.mDHParameters = mDHAgreePublicKey.Parameters; + this.mDHParameters = TlsDHUtilities.ReceiveDHParameters(mDHVerifier, input); + this.mDHAgreePublicKey = new DHPublicKeyParameters(TlsDHUtilities.ReadDHParameter(input), mDHParameters); } else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK) { @@ -240,9 +239,7 @@ namespace Org.BouncyCastle.Crypto.Tls if (this.mKeyExchange == KeyExchangeAlgorithm.DHE_PSK) { - BigInteger Yc = TlsDHUtilities.ReadDHParameter(input); - - this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(new DHPublicKeyParameters(Yc, mDHParameters)); + this.mDHAgreePublicKey = new DHPublicKeyParameters(TlsDHUtilities.ReadDHParameter(input), mDHParameters); } else if (this.mKeyExchange == KeyExchangeAlgorithm.ECDHE_PSK) { -- cgit 1.5.1 From 0a55f215e35e16196068c33478dd280dbcd3421d Mon Sep 17 00:00:00 2001 From: Alex Reynolds Date: Fri, 3 Aug 2018 11:20:06 +0100 Subject: Add public constructors to PollRepContent --- crypto/src/asn1/cmp/PollRepContent.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/crypto/src/asn1/cmp/PollRepContent.cs b/crypto/src/asn1/cmp/PollRepContent.cs index f8bb098a2..ff75d7d6d 100644 --- a/crypto/src/asn1/cmp/PollRepContent.cs +++ b/crypto/src/asn1/cmp/PollRepContent.cs @@ -33,6 +33,25 @@ namespace Org.BouncyCastle.Asn1.Cmp throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); } + public PollRepContent( + DerInteger certReqId, + DerInteger checkAfter) + { + this.certReqId = certReqId; + this.checkAfter = checkAfter; + this.reason = null; + } + + public PollRepContent( + DerInteger certReqId, + DerInteger checkAfter, + PkiFreeText reason) + { + this.certReqId = certReqId; + this.checkAfter = checkAfter; + this.reason = reason; + } + public virtual DerInteger CertReqID { get { return certReqId; } -- cgit 1.5.1 From 3c6bc5b4b732713466d676fd07cd12120a50ed0d Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Mon, 6 Aug 2018 17:00:54 +0700 Subject: Add IgnoreX509NameOrdering property - see https://github.com/bcgit/bc-csharp/issues/136 --- crypto/src/x509/store/X509CertStoreSelector.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/crypto/src/x509/store/X509CertStoreSelector.cs b/crypto/src/x509/store/X509CertStoreSelector.cs index 3874edf1d..f92a4ac03 100644 --- a/crypto/src/x509/store/X509CertStoreSelector.cs +++ b/crypto/src/x509/store/X509CertStoreSelector.cs @@ -21,6 +21,7 @@ namespace Org.BouncyCastle.X509.Store private X509Certificate certificate; private DateTimeObject certificateValid; private ISet extendedKeyUsage; + private bool ignoreX509NameOrdering; private X509Name issuer; private bool[] keyUsage; private ISet policy; @@ -43,6 +44,7 @@ namespace Org.BouncyCastle.X509.Store this.certificate = o.Certificate; this.certificateValid = o.CertificateValid; this.extendedKeyUsage = o.ExtendedKeyUsage; + this.ignoreX509NameOrdering = o.IgnoreX509NameOrdering; this.issuer = o.Issuer; this.keyUsage = o.KeyUsage; this.policy = o.Policy; @@ -95,6 +97,12 @@ namespace Org.BouncyCastle.X509.Store set { extendedKeyUsage = CopySet(value); } } + public bool IgnoreX509NameOrdering + { + get { return ignoreX509NameOrdering; } + set { this.ignoreX509NameOrdering = value; } + } + public X509Name Issuer { get { return issuer; } @@ -140,7 +148,8 @@ namespace Org.BouncyCastle.X509.Store set { subject = value; } } - public string SubjectAsString + [Obsolete("Avoid working with X509Name objects in string form")] + public string SubjectAsString { get { return subject != null ? subject.ToString() : null; } } @@ -212,7 +221,7 @@ namespace Org.BouncyCastle.X509.Store } } - if (issuer != null && !issuer.Equivalent(c.IssuerDN, true)) + if (issuer != null && !issuer.Equivalent(c.IssuerDN, !ignoreX509NameOrdering)) return false; if (keyUsage != null) @@ -277,7 +286,7 @@ namespace Org.BouncyCastle.X509.Store if (serialNumber != null && !serialNumber.Equals(c.SerialNumber)) return false; - if (subject != null && !subject.Equivalent(c.SubjectDN, true)) + if (subject != null && !subject.Equivalent(c.SubjectDN, !ignoreX509NameOrdering)) return false; if (!MatchExtension(subjectKeyIdentifier, c, X509Extensions.SubjectKeyIdentifier)) -- cgit 1.5.1 From c5c97a3d43047a45c137ac061ac9dcdc95256131 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Mon, 6 Aug 2018 17:58:23 +0700 Subject: Add UseDerForCerts, UseDerForCrls properties - see https://github.com/bcgit/bc-csharp/pull/101 --- crypto/src/cms/CMSSignedDataGenerator.cs | 10 +++++++--- crypto/src/cms/CMSSignedDataStreamGenerator.cs | 8 ++++++-- crypto/src/cms/CMSSignedGenerator.cs | 14 ++++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/crypto/src/cms/CMSSignedDataGenerator.cs b/crypto/src/cms/CMSSignedDataGenerator.cs index f63ed874e..5aa5f92ab 100644 --- a/crypto/src/cms/CMSSignedDataGenerator.cs +++ b/crypto/src/cms/CMSSignedDataGenerator.cs @@ -513,15 +513,19 @@ namespace Org.BouncyCastle.Cms if (_certs.Count != 0) { - certificates = CmsUtilities.CreateBerSetFromList(_certs); + certificates = UseDerForCerts + ? CmsUtilities.CreateDerSetFromList(_certs) + : CmsUtilities.CreateBerSetFromList(_certs); } Asn1Set certrevlist = null; if (_crls.Count != 0) { - certrevlist = CmsUtilities.CreateBerSetFromList(_crls); - } + certrevlist = UseDerForCrls + ? CmsUtilities.CreateDerSetFromList(_crls) + : CmsUtilities.CreateBerSetFromList(_crls); + } Asn1OctetString octs = null; if (encapsulate) diff --git a/crypto/src/cms/CMSSignedDataStreamGenerator.cs b/crypto/src/cms/CMSSignedDataStreamGenerator.cs index d0ab7428a..1cea087f3 100644 --- a/crypto/src/cms/CMSSignedDataStreamGenerator.cs +++ b/crypto/src/cms/CMSSignedDataStreamGenerator.cs @@ -838,14 +838,18 @@ namespace Org.BouncyCastle.Cms if (outer._certs.Count > 0) { - Asn1Set certs = CmsUtilities.CreateBerSetFromList(outer._certs); + Asn1Set certs = outer.UseDerForCerts + ? CmsUtilities.CreateDerSetFromList(outer._certs) + : CmsUtilities.CreateBerSetFromList(outer._certs); WriteToGenerator(_sigGen, new BerTaggedObject(false, 0, certs)); } if (outer._crls.Count > 0) { - Asn1Set crls = CmsUtilities.CreateBerSetFromList(outer._crls); + Asn1Set crls = outer.UseDerForCrls + ? CmsUtilities.CreateDerSetFromList(outer._crls) + : CmsUtilities.CreateBerSetFromList(outer._crls); WriteToGenerator(_sigGen, new BerTaggedObject(false, 1, crls)); } diff --git a/crypto/src/cms/CMSSignedGenerator.cs b/crypto/src/cms/CMSSignedGenerator.cs index eec2e875b..249d70499 100644 --- a/crypto/src/cms/CMSSignedGenerator.cs +++ b/crypto/src/cms/CMSSignedGenerator.cs @@ -147,6 +147,8 @@ namespace Org.BouncyCastle.Cms internal IList _crls = Platform.CreateArrayList(); internal IList _signers = Platform.CreateArrayList(); internal IDictionary _digests = Platform.CreateHashtable(); + internal bool _useDerForCerts = false; + internal bool _useDerForCrls = false; protected readonly SecureRandom rand; @@ -251,6 +253,18 @@ namespace Org.BouncyCastle.Cms return Platform.CreateHashtable(_digests); } + public bool UseDerForCerts + { + get { return _useDerForCerts; } + set { this._useDerForCerts = value; } + } + + public bool UseDerForCrls + { + get { return _useDerForCrls; } + set { this._useDerForCrls = value; } + } + internal virtual void AddSignerCallback( SignerInformation si) { -- cgit 1.5.1 From f9523961d11f7e99eac3c79ba7dbef82ae325619 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 7 Aug 2018 13:39:53 +0700 Subject: TLS: Disable DHE_* ciphersuites in default clients --- crypto/src/crypto/tls/DefaultTlsClient.cs | 6 ------ crypto/src/crypto/tls/PskTlsClient.cs | 2 -- 2 files changed, 8 deletions(-) diff --git a/crypto/src/crypto/tls/DefaultTlsClient.cs b/crypto/src/crypto/tls/DefaultTlsClient.cs index 154a2c94b..64d29863b 100644 --- a/crypto/src/crypto/tls/DefaultTlsClient.cs +++ b/crypto/src/crypto/tls/DefaultTlsClient.cs @@ -42,12 +42,6 @@ namespace Org.BouncyCastle.Crypto.Tls CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, - CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, - CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA, - CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, - CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, - CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256, CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256, CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, diff --git a/crypto/src/crypto/tls/PskTlsClient.cs b/crypto/src/crypto/tls/PskTlsClient.cs index 1dc119d7b..d5fa43543 100644 --- a/crypto/src/crypto/tls/PskTlsClient.cs +++ b/crypto/src/crypto/tls/PskTlsClient.cs @@ -32,8 +32,6 @@ namespace Org.BouncyCastle.Crypto.Tls { CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CipherSuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, - CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, - CipherSuite.TLS_DHE_PSK_WITH_AES_128_CBC_SHA }; } -- cgit 1.5.1 From cc5062b8ca50bb1689fa5c65e15f25add789178a Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 7 Aug 2018 17:30:57 +0700 Subject: Add entry explaining DH changes --- crypto/Readme.html | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crypto/Readme.html b/crypto/Readme.html index 9f4705f00..153897914 100644 --- a/crypto/Readme.html +++ b/crypto/Readme.html @@ -296,6 +296,16 @@ We state, where EC MQV has not otherwise been disabled or removed:

Release 1.8.3, TBD

+
IMPORTANT
+
    +
  • + In this release, the TLS library has moved to a whitelisting approach for client-side validation of server-presented + Diffie-Hellman (DH) parameters. In the default configuration, if a ciphersuite using ephemeral DH is selected by the + server, the client will abort the handshake if the proposed DH group is not one of those specified in RFC 3526 or RFC 7919, + or if the DH prime is < 2048 bits. The client therefore no longer offers DH ciphersuites by default. +
  • +
+
Additional Features and Functionality
  • Further work has been done on improving SHA-3 performance.
  • -- cgit 1.5.1 From 17484948ae42b7d5fd75a4e96b31a8bb0cb47825 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 7 Aug 2018 20:17:18 +0700 Subject: Refactoring around Pkcs10CertificationRequest - see https://github.com/bcgit/bc-csharp/pull/123 --- crypto/src/crypto/operators/Asn1Signature.cs | 49 ++++++++++++++--------- crypto/src/pkcs/Pkcs10CertificationRequest.cs | 56 ++++++++++++++------------- 2 files changed, 60 insertions(+), 45 deletions(-) diff --git a/crypto/src/crypto/operators/Asn1Signature.cs b/crypto/src/crypto/operators/Asn1Signature.cs index e023c1d18..373ba0cee 100644 --- a/crypto/src/crypto/operators/Asn1Signature.cs +++ b/crypto/src/crypto/operators/Asn1Signature.cs @@ -325,7 +325,8 @@ namespace Org.BouncyCastle.Crypto.Operators /// Calculator factory class for signature generation in ASN.1 based profiles that use an AlgorithmIdentifier to preserve /// signature algorithm details. /// - public class Asn1SignatureFactory: ISignatureFactory + public class Asn1SignatureFactory + : ISignatureFactory { private readonly AlgorithmIdentifier algID; private readonly string algorithm; @@ -337,7 +338,8 @@ namespace Org.BouncyCastle.Crypto.Operators /// /// The name of the signature algorithm to use. /// The private key to be used in the signing operation. - public Asn1SignatureFactory (string algorithm, AsymmetricKeyParameter privateKey): this(algorithm, privateKey, null) + public Asn1SignatureFactory (string algorithm, AsymmetricKeyParameter privateKey) + : this(algorithm, privateKey, null) { } @@ -347,14 +349,21 @@ namespace Org.BouncyCastle.Crypto.Operators /// The name of the signature algorithm to use. /// The private key to be used in the signing operation. /// The source of randomness to be used in signature calculation. - public Asn1SignatureFactory (string algorithm, AsymmetricKeyParameter privateKey, SecureRandom random) + public Asn1SignatureFactory(string algorithm, AsymmetricKeyParameter privateKey, SecureRandom random) { - DerObjectIdentifier sigOid = X509Utilities.GetAlgorithmOid (algorithm); + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + if (privateKey == null) + throw new ArgumentNullException("privateKey"); + if (!privateKey.IsPrivate) + throw new ArgumentException("Key for signing must be private", "privateKey"); + + DerObjectIdentifier sigOid = X509Utilities.GetAlgorithmOid(algorithm); this.algorithm = algorithm; this.privateKey = privateKey; this.random = random; - this.algID = X509Utilities.GetSigAlgID (sigOid, algorithm); + this.algID = X509Utilities.GetSigAlgID(sigOid, algorithm); } public Object AlgorithmDetails @@ -365,16 +374,12 @@ namespace Org.BouncyCastle.Crypto.Operators public IStreamCalculator CreateCalculator() { ISigner sig = SignerUtilities.GetSigner(algorithm); - + ICipherParameters cp = privateKey; if (random != null) { - sig.Init(true, new ParametersWithRandom(privateKey, random)); + cp = new ParametersWithRandom(cp, random); } - else - { - sig.Init(true, privateKey); - } - + sig.Init(true, cp); return new SigCalculator(sig); } @@ -437,7 +442,8 @@ namespace Org.BouncyCastle.Crypto.Operators /// Verifier class for signature verification in ASN.1 based profiles that use an AlgorithmIdentifier to preserve /// signature algorithm details. /// - public class Asn1VerifierFactory: IVerifierFactory + public class Asn1VerifierFactory + : IVerifierFactory { private readonly AlgorithmIdentifier algID; private readonly AsymmetricKeyParameter publicKey; @@ -447,15 +453,22 @@ namespace Org.BouncyCastle.Crypto.Operators /// /// The name of the signature algorithm to use. /// The public key to be used in the verification operation. - public Asn1VerifierFactory (String algorithm, AsymmetricKeyParameter publicKey) + public Asn1VerifierFactory(string algorithm, AsymmetricKeyParameter publicKey) { - DerObjectIdentifier sigOid = X509Utilities.GetAlgorithmOid (algorithm); + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + if (publicKey == null) + throw new ArgumentNullException("publicKey"); + if (publicKey.IsPrivate) + throw new ArgumentException("Key for verifying must be public", "publicKey"); + + DerObjectIdentifier sigOid = X509Utilities.GetAlgorithmOid(algorithm); this.publicKey = publicKey; - this.algID = X509Utilities.GetSigAlgID (sigOid, algorithm); + this.algID = X509Utilities.GetSigAlgID(sigOid, algorithm); } - public Asn1VerifierFactory (AlgorithmIdentifier algorithm, AsymmetricKeyParameter publicKey) + public Asn1VerifierFactory(AlgorithmIdentifier algorithm, AsymmetricKeyParameter publicKey) { this.publicKey = publicKey; this.algID = algorithm; @@ -540,7 +553,7 @@ namespace Org.BouncyCastle.Crypto.Operators public IVerifierFactory CreateVerifierFactory(Object algorithmDetails) { - return new Asn1VerifierFactory ((AlgorithmIdentifier)algorithmDetails, publicKey); + return new Asn1VerifierFactory((AlgorithmIdentifier)algorithmDetails, publicKey); } /// diff --git a/crypto/src/pkcs/Pkcs10CertificationRequest.cs b/crypto/src/pkcs/Pkcs10CertificationRequest.cs index 24dc9b1cc..34bda3815 100644 --- a/crypto/src/pkcs/Pkcs10CertificationRequest.cs +++ b/crypto/src/pkcs/Pkcs10CertificationRequest.cs @@ -210,71 +210,73 @@ namespace Org.BouncyCastle.Pkcs /// Public Key to be included in cert reqest. /// ASN1Set of Attributes. /// Matching Private key for nominated (above) public key to be used to sign the request. - [Obsolete("Use constructor with an ISignatureFactory")] public Pkcs10CertificationRequest( string signatureAlgorithm, X509Name subject, AsymmetricKeyParameter publicKey, Asn1Set attributes, AsymmetricKeyParameter signingKey) + : this(new Asn1SignatureFactory(signatureAlgorithm, signingKey), subject, publicKey, attributes) { - if (signatureAlgorithm == null) - throw new ArgumentNullException("signatureAlgorithm"); - if (subject == null) - throw new ArgumentNullException("subject"); - if (publicKey == null) - throw new ArgumentNullException("publicKey"); - if (publicKey.IsPrivate) - throw new ArgumentException("expected public key", "publicKey"); - if (!signingKey.IsPrivate) - throw new ArgumentException("key for signing must be private", "signingKey"); - - init(new Asn1SignatureFactory(signatureAlgorithm, signingKey), subject, publicKey, attributes, signingKey); } /// /// Instantiate a Pkcs10CertificationRequest object with the necessary credentials. /// - ///The factory for signature calculators to sign the PKCS#10 request with. + ///The factory for signature calculators to sign the PKCS#10 request with. /// X509Name of subject eg OU="My unit." O="My Organisatioin" C="au" /// Public Key to be included in cert reqest. /// ASN1Set of Attributes. - /// Matching Private key for nominated (above) public key to be used to sign the request. + /// Ignored. + [Obsolete("Use constructor without 'signingKey' parameter (ignored here)")] public Pkcs10CertificationRequest( - ISignatureFactory signatureCalculatorFactory, + ISignatureFactory signatureFactory, X509Name subject, AsymmetricKeyParameter publicKey, Asn1Set attributes, AsymmetricKeyParameter signingKey) + : this(signatureFactory, subject, publicKey, attributes) { - if (signatureCalculatorFactory == null) - throw new ArgumentNullException("signatureCalculator"); + } + + /// + /// Instantiate a Pkcs10CertificationRequest object with the necessary credentials. + /// + ///The factory for signature calculators to sign the PKCS#10 request with. + /// X509Name of subject eg OU="My unit." O="My Organisatioin" C="au" + /// Public Key to be included in cert reqest. + /// ASN1Set of Attributes. + public Pkcs10CertificationRequest( + ISignatureFactory signatureFactory, + X509Name subject, + AsymmetricKeyParameter publicKey, + Asn1Set attributes) + { + if (signatureFactory == null) + throw new ArgumentNullException("signatureFactory"); if (subject == null) throw new ArgumentNullException("subject"); if (publicKey == null) throw new ArgumentNullException("publicKey"); if (publicKey.IsPrivate) throw new ArgumentException("expected public key", "publicKey"); - if (!signingKey.IsPrivate) - throw new ArgumentException("key for signing must be private", "signingKey"); - init(signatureCalculatorFactory, subject, publicKey, attributes, signingKey); + Init(signatureFactory, subject, publicKey, attributes); } - private void init( - ISignatureFactory signatureCalculator, + private void Init( + ISignatureFactory signatureFactory, X509Name subject, AsymmetricKeyParameter publicKey, - Asn1Set attributes, - AsymmetricKeyParameter signingKey) + Asn1Set attributes) { - this.sigAlgId = (AlgorithmIdentifier)signatureCalculator.AlgorithmDetails; + this.sigAlgId = (AlgorithmIdentifier)signatureFactory.AlgorithmDetails; SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey); this.reqInfo = new CertificationRequestInfo(subject, pubInfo, attributes); - IStreamCalculator streamCalculator = signatureCalculator.CreateCalculator(); + IStreamCalculator streamCalculator = signatureFactory.CreateCalculator(); byte[] reqInfoData = reqInfo.GetDerEncoded(); -- cgit 1.5.1 From c01bc530cbaa5f3d4db4cd155b7c9520e0df1617 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 7 Aug 2018 20:50:55 +0700 Subject: Update versions and release notes for 1.8.3 --- crypto/NBuild.build | 2 +- crypto/Readme.html | 2 +- crypto/src/AssemblyInfo.cs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crypto/NBuild.build b/crypto/NBuild.build index 89c557702..dd63df279 100644 --- a/crypto/NBuild.build +++ b/crypto/NBuild.build @@ -16,7 +16,7 @@ - + diff --git a/crypto/Readme.html b/crypto/Readme.html index 153897914..faad344cc 100644 --- a/crypto/Readme.html +++ b/crypto/Readme.html @@ -294,7 +294,7 @@ We state, where EC MQV has not otherwise been disabled or removed:

    Notes:

    -

    Release 1.8.3, TBD

    +

    Release 1.8.3, Tuesday August 7, 2018

    IMPORTANT
      diff --git a/crypto/src/AssemblyInfo.cs b/crypto/src/AssemblyInfo.cs index d95dca5ab..e1a8f6717 100644 --- a/crypto/src/AssemblyInfo.cs +++ b/crypto/src/AssemblyInfo.cs @@ -33,9 +33,9 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("1.8.2.0")] -[assembly: AssemblyFileVersion("1.8.18099.1")] -[assembly: AssemblyInformationalVersion("1.8.2")] +[assembly: AssemblyVersion("1.8.3.0")] +[assembly: AssemblyFileVersion("1.8.18219.1")] +[assembly: AssemblyInformationalVersion("1.8.3")] // // In order to sign your assembly you must specify a key to use. Refer to the -- cgit 1.5.1 From 8c0e3017783a5f41b2028eaffffe335a9046c859 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Sat, 11 Aug 2018 11:54:57 +0700 Subject: Further work to improve constant time in OAEP. --- crypto/Readme.html | 2 +- crypto/src/AssemblyInfo.cs | 2 +- crypto/src/crypto/encodings/OaepEncoding.cs | 15 ++++-- crypto/test/src/crypto/test/OAEPTest.cs | 79 +++++++++++++++++++++++++++-- 4 files changed, 89 insertions(+), 9 deletions(-) diff --git a/crypto/Readme.html b/crypto/Readme.html index faad344cc..72e97516f 100644 --- a/crypto/Readme.html +++ b/crypto/Readme.html @@ -294,7 +294,7 @@ We state, where EC MQV has not otherwise been disabled or removed:

      Notes:

      -

      Release 1.8.3, Tuesday August 7, 2018

      +

      Release 1.8.3, Saturday August 11, 2018

      IMPORTANT
        diff --git a/crypto/src/AssemblyInfo.cs b/crypto/src/AssemblyInfo.cs index e1a8f6717..5cc8fcd2f 100644 --- a/crypto/src/AssemblyInfo.cs +++ b/crypto/src/AssemblyInfo.cs @@ -34,7 +34,7 @@ using System.Runtime.InteropServices; // by using the '*' as shown below: [assembly: AssemblyVersion("1.8.3.0")] -[assembly: AssemblyFileVersion("1.8.18219.1")] +[assembly: AssemblyFileVersion("1.8.18223.1")] [assembly: AssemblyInformationalVersion("1.8.3")] // diff --git a/crypto/src/crypto/encodings/OaepEncoding.cs b/crypto/src/crypto/encodings/OaepEncoding.cs index 287876f12..92001589c 100644 --- a/crypto/src/crypto/encodings/OaepEncoding.cs +++ b/crypto/src/crypto/encodings/OaepEncoding.cs @@ -212,10 +212,17 @@ namespace Org.BouncyCastle.Crypto.Encodings // on encryption, we need to make sure our decrypted block comes back // the same size. // + bool wrongData = (block.Length < (2 * defHash.Length) + 1); - Array.Copy(data, 0, block, block.Length - data.Length, data.Length); - - bool shortData = (block.Length < (2 * defHash.Length) + 1); + if (data.Length <= block.Length) + { + Array.Copy(data, 0, block, block.Length - data.Length, data.Length); + } + else + { + Array.Copy(data, 0, block, 0, block.Length); + wrongData = true; + } // // unmask the seed. @@ -269,7 +276,7 @@ namespace Org.BouncyCastle.Crypto.Encodings start++; - if (defHashWrong | shortData | dataStartWrong) + if (defHashWrong | wrongData | dataStartWrong) { Arrays.Fill(block, 0); throw new InvalidCipherTextException("data wrong"); diff --git a/crypto/test/src/crypto/test/OAEPTest.cs b/crypto/test/src/crypto/test/OAEPTest.cs index bc1dd9292..204784cee 100644 --- a/crypto/test/src/crypto/test/OAEPTest.cs +++ b/crypto/test/src/crypto/test/OAEPTest.cs @@ -8,6 +8,7 @@ using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Encodings; using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; @@ -780,8 +781,10 @@ namespace Org.BouncyCastle.Crypto.Tests OaepVecTest(1027, 5, pubParam, privParam, seed_1027_5, input_1027_5, output_1027_5); OaepVecTest(1027, 6, pubParam, privParam, seed_1027_6, input_1027_6, output_1027_6); + TestForHighByteError("invalidCiphertextOaepTest 1024", 1024); + // - // OAEP - public encrypt, private decrypt differring hashes + // OAEP - public encrypt, private decrypt, differing hashes // IAsymmetricBlockCipher cipher = new OaepEncoding(new RsaEngine(), new Sha256Digest(), new Sha1Digest(), new byte[10]); @@ -822,8 +825,78 @@ namespace Org.BouncyCastle.Crypto.Tests } } - public static void Main( - string[] args) + private void TestForHighByteError(string label, int keySizeBits) + { + // draw a key of the size asked + BigInteger e = BigInteger.One.ShiftLeft(16).Add(BigInteger.One); + + IAsymmetricCipherKeyPairGenerator kpGen = new RsaKeyPairGenerator(); + + kpGen.Init(new RsaKeyGenerationParameters(e, new SecureRandom(), keySizeBits, 100)); + + AsymmetricCipherKeyPair kp = kpGen.GenerateKeyPair(); + + IAsymmetricBlockCipher cipher = new OaepEncoding(new RsaEngine()); + + // obtain a known good ciphertext + cipher.Init(true, new ParametersWithRandom(kp.Public, new VecRand(seed))); + byte[] m = { 42 }; + byte[] c = cipher.ProcessBlock(m, 0, m.Length); + int keySizeBytes = (keySizeBits + 7) / 8; + if (c.Length != keySizeBytes) + { + Fail(label + " failed ciphertext size"); + } + + BigInteger n = ((RsaPrivateCrtKeyParameters)kp.Private).Modulus; + + // decipher + cipher.Init(false, kp.Private); + byte[] r = cipher.ProcessBlock(c, 0, keySizeBytes); + if (r.Length != 1 || r[0] != 42) + { + Fail(label + " failed first decryption of test message"); + } + + // decipher again + r = cipher.ProcessBlock(c, 0, keySizeBytes); + if (r.Length != 1 || r[0] != 42) + { + Fail(label + " failed second decryption of test message"); + } + + // check hapazard incorrect ciphertexts + for (int i = keySizeBytes * 8; --i >= 0; ) + { + c[i / 8] ^= (byte)(1 << (i & 7)); + bool ko = true; + try + { + BigInteger cV = new BigInteger(1, c); + + // don't pass in c if it will be rejected trivially + if (cV.CompareTo(n) < 0) + { + r = cipher.ProcessBlock(c, 0, keySizeBytes); + } + else + { + ko = false; // size errors are picked up at start + } + } + catch (InvalidCipherTextException) + { + ko = false; + } + if (ko) + { + Fail(label + " invalid ciphertext caused no exception"); + } + c[i / 8] ^= (byte)(1 << (i & 7)); + } + } + + public static void Main(string[] args) { RunTest(new OaepTest()); } -- cgit 1.5.1