TLS: Improve supported_groups compliance
2 files changed, 29 insertions, 16 deletions
diff --git a/crypto/src/tls/AbstractTlsServer.cs b/crypto/src/tls/AbstractTlsServer.cs
index f445ac18d..7e8c26ffd 100644
--- a/crypto/src/tls/AbstractTlsServer.cs
+++ b/crypto/src/tls/AbstractTlsServer.cs
@@ -69,37 +69,48 @@ namespace Org.BouncyCastle.Tls
protected virtual int GetMaximumNegotiableCurveBits()
{
+ int maxBits = 0;
int[] clientSupportedGroups = m_context.SecurityParameters.ClientSupportedGroups;
- if (clientSupportedGroups == null)
+ if (clientSupportedGroups != null)
+ {
+ for (int i = 0; i < clientSupportedGroups.Length; ++i)
+ {
+ maxBits = System.Math.Max(maxBits, NamedGroup.GetCurveBits(clientSupportedGroups[i]));
+ }
+ }
+ else
{
/*
* RFC 4492 4. A client that proposes ECC cipher suites may choose not to include these
- * extensions. In this case, the server is free to choose any one of the elliptic curves
- * or point formats [...].
+ * extensions. In this case, the server is free to choose any one of the elliptic curves or point
+ * formats [...].
*/
- return NamedGroup.GetMaximumCurveBits();
- }
-
- int maxBits = 0;
- for (int i = 0; i < clientSupportedGroups.Length; ++i)
- {
- maxBits = System.Math.Max(maxBits, NamedGroup.GetCurveBits(clientSupportedGroups[i]));
+ maxBits = NamedGroup.GetMaximumCurveBits();
}
return maxBits;
}
protected virtual int GetMaximumNegotiableFiniteFieldBits()
{
+ int maxBits = 0;
+ bool anyPeerFF = false;
int[] clientSupportedGroups = m_context.SecurityParameters.ClientSupportedGroups;
- if (clientSupportedGroups == null)
+ if (clientSupportedGroups != null)
{
- return NamedGroup.GetMaximumFiniteFieldBits();
+ for (int i = 0; i < clientSupportedGroups.Length; ++i)
+ {
+ anyPeerFF |= NamedGroup.IsFiniteField(clientSupportedGroups[i]);
+ maxBits = System.Math.Max(maxBits, NamedGroup.GetFiniteFieldBits(clientSupportedGroups[i]));
+ }
}
-
- int maxBits = 0;
- for (int i = 0; i < clientSupportedGroups.Length; ++i)
+ if (!anyPeerFF)
{
- maxBits = System.Math.Max(maxBits, NamedGroup.GetFiniteFieldBits(clientSupportedGroups[i]));
+ /*
+ * RFC 7919 4. If [...] the Supported Groups extension is either absent from the ClientHello
+ * entirely or contains no FFDHE groups (i.e., no codepoints between 256 and 511, inclusive), then
+ * the server [...] MAY select an FFDHE cipher suite and offer an FFDHE group of its choice [...].
+ */
+ maxBits = NamedGroup.GetMaximumFiniteFieldBits();
}
return maxBits;
}
diff --git a/crypto/src/tls/NamedGroup.cs b/crypto/src/tls/NamedGroup.cs
index 0035ef9f3..15671a837 100644
--- a/crypto/src/tls/NamedGroup.cs
+++ b/crypto/src/tls/NamedGroup.cs
@@ -358,6 +358,8 @@ namespace Org.BouncyCastle.Tls
|| (namedGroup == arbitrary_explicit_char2_curves);
}
+ public static bool IsFiniteField(int namedGroup) => (namedGroup & 0xFFFFFF00) == 0x00000100;
+
public static bool IsPrimeCurve(int namedGroup)
{
return (namedGroup >= secp160k1 && namedGroup <= curveSM2)
|