TlsDHUtilities
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Tls.Crypto;
using Org.BouncyCastle.Utilities;
using System.IO;
namespace Org.BouncyCastle.Tls
{
public abstract class TlsDHUtilities
{
public static TlsDHConfig CreateNamedDHConfig(TlsContext context, int namedGroup)
{
if (namedGroup < 0 || NamedGroup.GetFiniteFieldBits(namedGroup) < 1)
return null;
bool padded = TlsUtilities.IsTlsV13(context);
return new TlsDHConfig(namedGroup, padded);
}
public static DHGroup GetDHGroup(TlsDHConfig dhConfig)
{
int namedGroup = dhConfig.NamedGroup;
if (namedGroup >= 0)
return GetNamedDHGroup(namedGroup);
return dhConfig.ExplicitGroup;
}
public static DHGroup GetNamedDHGroup(int namedGroup)
{
switch (namedGroup) {
case 256:
return DHStandardGroups.rfc7919_ffdhe2048;
case 257:
return DHStandardGroups.rfc7919_ffdhe3072;
case 258:
return DHStandardGroups.rfc7919_ffdhe4096;
case 259:
return DHStandardGroups.rfc7919_ffdhe6144;
case 260:
return DHStandardGroups.rfc7919_ffdhe8192;
default:
return null;
}
}
public static int GetMinimumFiniteFieldBits(int cipherSuite)
{
return IsDHCipherSuite(cipherSuite) ? 1 : 0;
}
public static bool IsDHCipherSuite(int cipherSuite)
{
switch (TlsUtilities.GetKeyExchangeAlgorithm(cipherSuite)) {
case 3:
case 5:
case 7:
case 9:
case 11:
case 14:
return true;
default:
return false;
}
}
public static int GetNamedGroupForDHParameters(BigInteger p, BigInteger g)
{
int[] array = new int[5] {
256,
257,
258,
259,
260
};
foreach (int num in array) {
DHGroup namedDHGroup = GetNamedDHGroup(num);
if (namedDHGroup != null && namedDHGroup.P.Equals(p) && namedDHGroup.G.Equals(g))
return num;
}
return -1;
}
public static DHGroup GetStandardGroupForDHParameters(BigInteger p, BigInteger g)
{
DHGroup[] array = new DHGroup[13] {
DHStandardGroups.rfc7919_ffdhe2048,
DHStandardGroups.rfc7919_ffdhe3072,
DHStandardGroups.rfc7919_ffdhe4096,
DHStandardGroups.rfc7919_ffdhe6144,
DHStandardGroups.rfc7919_ffdhe8192,
DHStandardGroups.rfc3526_1536,
DHStandardGroups.rfc3526_2048,
DHStandardGroups.rfc3526_3072,
DHStandardGroups.rfc3526_4096,
DHStandardGroups.rfc3526_6144,
DHStandardGroups.rfc3526_8192,
DHStandardGroups.rfc5996_768,
DHStandardGroups.rfc5996_1024
};
foreach (DHGroup dHGroup in array) {
if (dHGroup != null && dHGroup.P.Equals(p) && dHGroup.G.Equals(g))
return dHGroup;
}
return null;
}
public static TlsDHConfig ReceiveDHConfig(TlsContext context, TlsDHGroupVerifier dhGroupVerifier, Stream input)
{
BigInteger p = ReadDHParameter(input);
BigInteger g = ReadDHParameter(input);
int namedGroupForDHParameters = GetNamedGroupForDHParameters(p, g);
if (namedGroupForDHParameters < 0) {
DHGroup dHGroup = GetStandardGroupForDHParameters(p, g);
if (dHGroup == null)
dHGroup = new DHGroup(p, null, g, 0);
if (!dhGroupVerifier.Accept(dHGroup))
throw new TlsFatalAlert(71);
return new TlsDHConfig(dHGroup);
}
int[] clientSupportedGroups = context.SecurityParameters.ClientSupportedGroups;
if (clientSupportedGroups == null || Arrays.Contains(clientSupportedGroups, namedGroupForDHParameters))
return new TlsDHConfig(namedGroupForDHParameters, false);
throw new TlsFatalAlert(47);
}
public static BigInteger ReadDHParameter(Stream input)
{
return new BigInteger(1, TlsUtilities.ReadOpaque16(input, 1));
}
public static void WriteDHConfig(TlsDHConfig dhConfig, Stream output)
{
DHGroup dHGroup = GetDHGroup(dhConfig);
WriteDHParameter(dHGroup.P, output);
WriteDHParameter(dHGroup.G, output);
}
public static void WriteDHParameter(BigInteger x, Stream output)
{
TlsUtilities.WriteOpaque16(BigIntegers.AsUnsignedByteArray(x), output);
}
}
}