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 @@
<Compile Include="src\crypto\tls\DefaultTlsAgreementCredentials.cs" />
<Compile Include="src\crypto\tls\DefaultTlsCipherFactory.cs" />
<Compile Include="src\crypto\tls\DefaultTlsClient.cs" />
+ <Compile Include="src\crypto\tls\DefaultTlsDHVerifier.cs" />
<Compile Include="src\crypto\tls\DefaultTlsEncryptionCredentials.cs" />
<Compile Include="src\crypto\tls\DefaultTlsServer.cs" />
<Compile Include="src\crypto\tls\DefaultTlsSignerCredentials.cs" />
@@ -1045,7 +1046,6 @@
<Compile Include="src\crypto\tls\PskTlsServer.cs" />
<Compile Include="src\crypto\tls\RecordStream.cs" />
<Compile Include="src\crypto\tls\SecurityParameters.cs" />
- <Compile Include="src\crypto\tls\ServerDHParams.cs" />
<Compile Include="src\crypto\tls\ServerName.cs" />
<Compile Include="src\crypto\tls\ServerNameList.cs" />
<Compile Include="src\crypto\tls\ServerOnlyTlsAuthentication.cs" />
@@ -1076,6 +1076,7 @@
<Compile Include="src\crypto\tls\TlsCredentials.cs" />
<Compile Include="src\crypto\tls\TlsDHKeyExchange.cs" />
<Compile Include="src\crypto\tls\TlsDHUtilities.cs" />
+ <Compile Include="src\crypto\tls\TlsDHVerifier.cs" />
<Compile Include="src\crypto\tls\TlsDeflateCompression.cs" />
<Compile Include="src\crypto\tls\TlsDheKeyExchange.cs" />
<Compile Include="src\crypto\tls\TlsDsaSigner.cs" />
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 @@
<Compile Include="src\crypto\tls\DefaultTlsAgreementCredentials.cs" />
<Compile Include="src\crypto\tls\DefaultTlsCipherFactory.cs" />
<Compile Include="src\crypto\tls\DefaultTlsClient.cs" />
+ <Compile Include="src\crypto\tls\DefaultTlsDHVerifier.cs" />
<Compile Include="src\crypto\tls\DefaultTlsEncryptionCredentials.cs" />
<Compile Include="src\crypto\tls\DefaultTlsServer.cs" />
<Compile Include="src\crypto\tls\DefaultTlsSignerCredentials.cs" />
@@ -1039,7 +1040,6 @@
<Compile Include="src\crypto\tls\PskTlsServer.cs" />
<Compile Include="src\crypto\tls\RecordStream.cs" />
<Compile Include="src\crypto\tls\SecurityParameters.cs" />
- <Compile Include="src\crypto\tls\ServerDHParams.cs" />
<Compile Include="src\crypto\tls\ServerName.cs" />
<Compile Include="src\crypto\tls\ServerNameList.cs" />
<Compile Include="src\crypto\tls\ServerOnlyTlsAuthentication.cs" />
@@ -1070,6 +1070,7 @@
<Compile Include="src\crypto\tls\TlsCredentials.cs" />
<Compile Include="src\crypto\tls\TlsDHKeyExchange.cs" />
<Compile Include="src\crypto\tls\TlsDHUtilities.cs" />
+ <Compile Include="src\crypto\tls\TlsDHVerifier.cs" />
<Compile Include="src\crypto\tls\TlsDeflateCompression.cs" />
<Compile Include="src\crypto\tls\TlsDheKeyExchange.cs" />
<Compile Include="src\crypto\tls\TlsDsaSigner.cs" />
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 @@
<Compile Include="src\crypto\tls\DefaultTlsAgreementCredentials.cs" />
<Compile Include="src\crypto\tls\DefaultTlsCipherFactory.cs" />
<Compile Include="src\crypto\tls\DefaultTlsClient.cs" />
+ <Compile Include="src\crypto\tls\DefaultTlsDHVerifier.cs" />
<Compile Include="src\crypto\tls\DefaultTlsEncryptionCredentials.cs" />
<Compile Include="src\crypto\tls\DefaultTlsServer.cs" />
<Compile Include="src\crypto\tls\DefaultTlsSignerCredentials.cs" />
@@ -1040,7 +1041,6 @@
<Compile Include="src\crypto\tls\PskTlsServer.cs" />
<Compile Include="src\crypto\tls\RecordStream.cs" />
<Compile Include="src\crypto\tls\SecurityParameters.cs" />
- <Compile Include="src\crypto\tls\ServerDHParams.cs" />
<Compile Include="src\crypto\tls\ServerName.cs" />
<Compile Include="src\crypto\tls\ServerNameList.cs" />
<Compile Include="src\crypto\tls\ServerOnlyTlsAuthentication.cs" />
@@ -1071,6 +1071,7 @@
<Compile Include="src\crypto\tls\TlsCredentials.cs" />
<Compile Include="src\crypto\tls\TlsDHKeyExchange.cs" />
<Compile Include="src\crypto\tls\TlsDHUtilities.cs" />
+ <Compile Include="src\crypto\tls\TlsDHVerifier.cs" />
<Compile Include="src\crypto\tls\TlsDeflateCompression.cs" />
<Compile Include="src\crypto\tls\TlsDheKeyExchange.cs" />
<Compile Include="src\crypto\tls\TlsDsaSigner.cs" />
diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj
index 7cd8de821..b6dfb3963 100644
--- a/crypto/crypto.csproj
+++ b/crypto/crypto.csproj
@@ -4869,6 +4869,11 @@
BuildAction = "Compile"
/>
<File
+ RelPath = "src\crypto\tls\DefaultTlsDHVerifier.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "src\crypto\tls\DefaultTlsEncryptionCredentials.cs"
SubType = "Code"
BuildAction = "Compile"
@@ -5084,11 +5089,6 @@
BuildAction = "Compile"
/>
<File
- RelPath = "src\crypto\tls\ServerDHParams.cs"
- SubType = "Code"
- BuildAction = "Compile"
- />
- <File
RelPath = "src\crypto\tls\ServerSrpParams.cs"
SubType = "Code"
BuildAction = "Compile"
@@ -5249,6 +5249,11 @@
BuildAction = "Compile"
/>
<File
+ RelPath = "src\crypto\tls\TlsDHVerifier.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "src\crypto\tls\TlsDsaSigner.cs"
SubType = "Code"
BuildAction = "Compile"
diff --git a/crypto/src/crypto/tls/DefaultTlsClient.cs b/crypto/src/crypto/tls/DefaultTlsClient.cs
index 32a86e503..154a2c94b 100644
--- a/crypto/src/crypto/tls/DefaultTlsClient.cs
+++ b/crypto/src/crypto/tls/DefaultTlsClient.cs
@@ -14,14 +14,22 @@ namespace Org.BouncyCastle.Crypto.Tls
public abstract class DefaultTlsClient
: AbstractTlsClient
{
+ protected TlsDHVerifier mDHVerifier;
+
public DefaultTlsClient()
- : base()
+ : this(new DefaultTlsCipherFactory())
{
}
public DefaultTlsClient(TlsCipherFactory cipherFactory)
- : base(cipherFactory)
+ : this(cipherFactory, new DefaultTlsDHVerifier())
+ {
+ }
+
+ public DefaultTlsClient(TlsCipherFactory cipherFactory, TlsDHVerifier dhVerifier)
+ : base(cipherFactory)
{
+ this.mDHVerifier = dhVerifier;
}
public override int[] GetCipherSuites()
@@ -85,12 +93,12 @@ namespace Org.BouncyCastle.Crypto.Tls
protected virtual TlsKeyExchange CreateDHKeyExchange(int keyExchange)
{
- return new TlsDHKeyExchange(keyExchange, mSupportedSignatureAlgorithms, null);
+ return new TlsDHKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mDHVerifier, null);
}
protected virtual TlsKeyExchange CreateDheKeyExchange(int keyExchange)
{
- return new TlsDheKeyExchange(keyExchange, mSupportedSignatureAlgorithms, null);
+ return new TlsDheKeyExchange(keyExchange, mSupportedSignatureAlgorithms, mDHVerifier, null);
}
protected virtual TlsKeyExchange CreateECDHKeyExchange(int keyExchange)
diff --git a/crypto/src/crypto/tls/DefaultTlsDHVerifier.cs b/crypto/src/crypto/tls/DefaultTlsDHVerifier.cs
new file mode 100644
index 000000000..ae26d04c3
--- /dev/null
+++ b/crypto/src/crypto/tls/DefaultTlsDHVerifier.cs
@@ -0,0 +1,101 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Crypto.Agreement;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Crypto.Tls
+{
+ public class DefaultTlsDHVerifier
+ : TlsDHVerifier
+ {
+ public static readonly int DefaultMinimumPrimeBits = 2048;
+
+ protected static readonly IList DefaultGroups = Platform.CreateArrayList();
+
+ private static void AddDefaultGroup(DHParameters dhParameters)
+ {
+ DefaultGroups.Add(dhParameters);
+ }
+
+ static DefaultTlsDHVerifier()
+ {
+ AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe2048);
+ AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe3072);
+ AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe4096);
+ AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe6144);
+ AddDefaultGroup(DHStandardGroups.rfc7919_ffdhe8192);
+
+ AddDefaultGroup(DHStandardGroups.rfc3526_1536);
+ AddDefaultGroup(DHStandardGroups.rfc3526_2048);
+ AddDefaultGroup(DHStandardGroups.rfc3526_3072);
+ AddDefaultGroup(DHStandardGroups.rfc3526_4096);
+ AddDefaultGroup(DHStandardGroups.rfc3526_6144);
+ AddDefaultGroup(DHStandardGroups.rfc3526_8192);
+ }
+
+ // IList is (DHParameters)
+ protected readonly IList mGroups;
+ protected readonly int mMinimumPrimeBits;
+
+ /// <summary>Accept various standard DH groups with 'P' at least <c>DefaultMinimumPrimeBits</c> bits.</summary>
+ public DefaultTlsDHVerifier()
+ : this(DefaultMinimumPrimeBits)
+ {
+ }
+
+ /// <summary>Accept various standard DH groups with 'P' at least the specified number of bits.</summary>
+ public DefaultTlsDHVerifier(int minimumPrimeBits)
+ : this(DefaultGroups, minimumPrimeBits)
+ {
+ }
+
+ /// <summary>Accept a custom set of group parameters, subject to a minimum bitlength for 'P'.</summary>
+ /// <param name="groups">An <c>IList</c> of acceptable <c>DHParameters</c>.</param>
+ /// <param name="minimumPrimeBits">The minimum acceptable bitlength of the 'P' parameter.</param>
+ 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
+{
+ /// <summary>An interface for verifying that Diffie-Hellman parameters are acceptable.</summary>
+ public interface TlsDHVerifier
+ {
+ /// <summary>Verify that the given <c>DHParameters</c> are acceptable.</summary>
+ /// <param name="dhParameters">The <c>DHParameters</c> to verify.</param>
+ /// <returns>true if (and only if) the specified parameters are acceptable.</returns>
+ 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)
{
|