Skip to content

Commit 80f81a5

Browse files
committed
Followup changes for custom DH groups
1 parent 22513e7 commit 80f81a5

File tree

4 files changed

+89
-36
lines changed

4 files changed

+89
-36
lines changed

CONTRIBUTORS.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@
547547
<li>Seung Yeon &lt;https://github.com/seungyeonpark&gt; - addition of Memoable method implementations to CertPathValidationContext and CertificatePoliciesValidation.</li>
548548
<li>yuhh0328 &lt;https://github.com/yuhh0328&gt; - initial patch for adding ML-KEM support to TLS.</li>
549549
<li>Jan Oupick&yacute; &lt;https://github.com/Honzaik&gt; - update to draft 13 of composite PQC signatures.</li>
550+
<li>Karsten Otto &lt;https://github.com/ottoka&gt; - finished the support for jdk.tls.server.defaultDHEParameters.</li>
550551
</ul>
551552
</body>
552553
</html>

docs/releasenotes.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,18 @@ <h2>1.0 Introduction</h2>
1919
<h2>2.0 Release History</h2>
2020

2121
<a id="r1rv79"><h3>2.1.1 Version</h3></a>
22+
Release: 1.79<br/>
2223
Date:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2024, TBD.
2324
<h3>2.1.2 Defects Fixed</h3>
2425
<ul>
2526
</ul>
27+
<h3>2.1.3 Additional Features and Functionality</h3>
28+
<ul>
29+
<li>BCJSSE: Added support for security property "jdk.tls.server.defaultDHEParameters" (disabled in FIPS mode).</li>
30+
</ul>
2631

2732
<a id="r1rv78d1"><h3>2.2.1 Version</h3></a>
33+
Release: 1.78.1<br/>
2834
Date:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2024, 18th April.
2935
<h3>2.2.2 Defects Fixed</h3>
3036
<ul>

tls/src/main/java/org/bouncycastle/jsse/provider/NamedGroupInfo.java

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,28 @@ static class PerContext
165165
}
166166
}
167167

168+
static class DefaultedResult
169+
{
170+
private final int result;
171+
private final boolean defaulted;
172+
173+
DefaultedResult(int result, boolean defaulted)
174+
{
175+
this.result = result;
176+
this.defaulted = defaulted;
177+
}
178+
179+
int getResult()
180+
{
181+
return result;
182+
}
183+
184+
boolean isDefaulted()
185+
{
186+
return defaulted;
187+
}
188+
}
189+
168190
static PerConnection createPerConnectionClient(PerContext perContext, ProvSSLParameters sslParameters,
169191
ProtocolVersion[] activeProtocolVersions)
170192
{
@@ -227,7 +249,7 @@ static PerContext createPerContext(boolean isFipsContext, JcaTlsCrypto crypto)
227249
return new PerContext(index, candidates);
228250
}
229251

230-
static int getMaximumBitsServerECDH(PerConnection perConnection)
252+
static DefaultedResult getMaximumBitsServerECDH(PerConnection perConnection)
231253
{
232254
int maxBits = 0;
233255
List<NamedGroupInfo> peer = perConnection.getPeer();
@@ -257,10 +279,10 @@ static int getMaximumBitsServerECDH(PerConnection perConnection)
257279
maxBits = Math.max(maxBits, namedGroupInfo.getBitsECDH());
258280
}
259281
}
260-
return maxBits;
282+
return new DefaultedResult(maxBits, peer == null);
261283
}
262284

263-
static int getMaximumBitsServerFFDHE(PerConnection perConnection)
285+
static DefaultedResult getMaximumBitsServerFFDHE(PerConnection perConnection)
264286
{
265287
int maxBits = 0;
266288
boolean anyPeerFF = false;
@@ -294,7 +316,7 @@ static int getMaximumBitsServerFFDHE(PerConnection perConnection)
294316
maxBits = Math.max(maxBits, namedGroupInfo.getBitsFFDHE());
295317
}
296318
}
297-
return maxBits;
319+
return new DefaultedResult(maxBits, !anyPeerFF);
298320
}
299321

300322
static NamedGroupInfo getNamedGroup(PerContext perContext, int namedGroup)
@@ -329,7 +351,7 @@ static boolean hasLocal(PerConnection perConnection, int namedGroup)
329351
return perConnection.local.containsKey(namedGroup);
330352
}
331353

332-
static int selectServerECDH(PerConnection perConnection, int minimumBitsECDH)
354+
static DefaultedResult selectServerECDH(PerConnection perConnection, int minimumBitsECDH)
333355
{
334356
List<NamedGroupInfo> peer = perConnection.getPeer();
335357
if (peer != null)
@@ -341,7 +363,7 @@ static int selectServerECDH(PerConnection perConnection, int minimumBitsECDH)
341363
int namedGroup = namedGroupInfo.getNamedGroup();
342364
if (perConnection.local.containsKey(namedGroup))
343365
{
344-
return namedGroup;
366+
return new DefaultedResult(namedGroup, false);
345367
}
346368
}
347369
}
@@ -357,14 +379,14 @@ static int selectServerECDH(PerConnection perConnection, int minimumBitsECDH)
357379
{
358380
if (namedGroupInfo.getBitsECDH() >= minimumBitsECDH)
359381
{
360-
return namedGroupInfo.getNamedGroup();
382+
return new DefaultedResult(namedGroupInfo.getNamedGroup(), true);
361383
}
362384
}
363385
}
364-
return -1;
386+
return new DefaultedResult(-1, peer == null);
365387
}
366388

367-
static int selectServerFFDHE(PerConnection perConnection, int minimumBitsFFDHE)
389+
static DefaultedResult selectServerFFDHE(PerConnection perConnection, int minimumBitsFFDHE)
368390
{
369391
boolean anyPeerFF = false;
370392
List<NamedGroupInfo> peer = perConnection.getPeer();
@@ -379,7 +401,7 @@ static int selectServerFFDHE(PerConnection perConnection, int minimumBitsFFDHE)
379401
{
380402
if (perConnection.local.containsKey(namedGroup))
381403
{
382-
return namedGroup;
404+
return new DefaultedResult(namedGroup, false);
383405
}
384406
}
385407
}
@@ -395,11 +417,11 @@ static int selectServerFFDHE(PerConnection perConnection, int minimumBitsFFDHE)
395417
{
396418
if (namedGroupInfo.getBitsFFDHE() >= minimumBitsFFDHE)
397419
{
398-
return namedGroupInfo.getNamedGroup();
420+
return new DefaultedResult(namedGroupInfo.getNamedGroup(), true);
399421
}
400422
}
401423
}
402-
return -1;
424+
return new DefaultedResult(-1, !anyPeerFF);
403425
}
404426

405427
private static void addNamedGroup(boolean isFipsContext, JcaTlsCrypto crypto, boolean disableChar2,

tls/src/main/java/org/bouncycastle/jsse/provider/ProvTlsServer.java

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.bouncycastle.tls.ClientCertificateType;
3232
import org.bouncycastle.tls.DefaultTlsServer;
3333
import org.bouncycastle.tls.KeyExchangeAlgorithm;
34+
import org.bouncycastle.tls.NamedGroup;
3435
import org.bouncycastle.tls.ProtocolName;
3536
import org.bouncycastle.tls.ProtocolVersion;
3637
import org.bouncycastle.tls.SecurityParameters;
@@ -62,10 +63,6 @@ class ProvTlsServer
6263
// TODO[jsse] Integrate this into NamedGroupInfo
6364
private static final int provEphemeralDHKeySize = PropertyUtils.getIntegerSystemProperty("jdk.tls.ephemeralDHKeySize", 2048, 1024, 8192);
6465

65-
/*
66-
* TODO[jsse] Does this selection override the restriction from 'jdk.tls.ephemeralDHKeySize'?
67-
* TODO[fips] Probably should be ignored in fips mode?
68-
*/
6966
private static final DHGroup[] provServerDefaultDHEParameters = getDefaultDHEParameters();
7067

7168
private static final boolean provServerEnableCA = PropertyUtils
@@ -100,7 +97,7 @@ private static DHGroup[] getDefaultDHEParameters()
10097
return null;
10198
}
10299

103-
ArrayList<DHGroup> result = new ArrayList<DHGroup>();
100+
ArrayList<DHGroup> dhGroups = new ArrayList<DHGroup>();
104101
int outerComma = -1;
105102
do
106103
{
@@ -134,7 +131,7 @@ private static DHGroup[] getDefaultDHEParameters()
134131
DHGroup dhGroup = TlsDHUtils.getStandardGroupForDHParameters(p, g);
135132
if (null != dhGroup)
136133
{
137-
result.add(dhGroup);
134+
dhGroups.add(dhGroup);
138135
}
139136
else if (!p.isProbablePrime(120))
140137
{
@@ -143,7 +140,7 @@ else if (!p.isProbablePrime(120))
143140
}
144141
else
145142
{
146-
result.add(new DHGroup(p, null, g, 0));
143+
dhGroups.add(new DHGroup(p, null, g, 0));
147144
}
148145
}
149146
catch (Exception e)
@@ -154,15 +151,15 @@ else if (!p.isProbablePrime(120))
154151
outerComma = closeBrace + 1;
155152
if (outerComma >= limit)
156153
{
157-
result.sort(new Comparator<DHGroup>()
154+
DHGroup[] result = dhGroups.toArray(new DHGroup[dhGroups.size()]);
155+
java.util.Arrays.sort(result, new Comparator<DHGroup>()
158156
{
159-
@Override
160157
public int compare(DHGroup a, DHGroup b)
161158
{
162159
return a.getP().bitLength() - b.getP().bitLength();
163160
}
164161
});
165-
return result.toArray(new DHGroup[result.size()]);
162+
return result;
166163
}
167164
}
168165
while (',' == input.charAt(outerComma));
@@ -268,13 +265,29 @@ protected String getDetailMessageNoCipherSuite()
268265
@Override
269266
protected int getMaximumNegotiableCurveBits()
270267
{
271-
return NamedGroupInfo.getMaximumBitsServerECDH(jsseSecurityParameters.namedGroups);
268+
NamedGroupInfo.DefaultedResult maxBitsResult = NamedGroupInfo.getMaximumBitsServerECDH(
269+
jsseSecurityParameters.namedGroups);
270+
271+
int maxBits = maxBitsResult.getResult();
272+
273+
return maxBits;
272274
}
273275

274276
@Override
275277
protected int getMaximumNegotiableFiniteFieldBits()
276278
{
277-
int maxBits = NamedGroupInfo.getMaximumBitsServerFFDHE(jsseSecurityParameters.namedGroups);
279+
NamedGroupInfo.DefaultedResult maxBitsResult = NamedGroupInfo.getMaximumBitsServerFFDHE(
280+
jsseSecurityParameters.namedGroups);
281+
282+
int maxBits = maxBitsResult.getResult();
283+
284+
if (maxBitsResult.isDefaulted() &&
285+
!TlsUtils.isNullOrEmpty(provServerDefaultDHEParameters) &&
286+
!manager.getContextData().getContext().isFips())
287+
{
288+
DHGroup largest = provServerDefaultDHEParameters[provServerDefaultDHEParameters.length - 1];
289+
maxBits = Math.max(maxBits, largest.getP().bitLength());
290+
}
278291

279292
return maxBits >= provEphemeralDHKeySize ? maxBits : 0;
280293
}
@@ -336,28 +349,39 @@ protected boolean selectCipherSuite(int cipherSuite) throws IOException
336349
@Override
337350
public TlsDHConfig getDHConfig() throws IOException
338351
{
339-
if (provServerDefaultDHEParameters != null)
340-
{
341-
int minimumFiniteFieldBits = Math.max(
342-
TlsDHUtils.getMinimumFiniteFieldBits(selectedCipherSuite), provEphemeralDHKeySize);
352+
int minimumFiniteFieldBits = TlsDHUtils.getMinimumFiniteFieldBits(selectedCipherSuite);
353+
minimumFiniteFieldBits = Math.max(minimumFiniteFieldBits, provEphemeralDHKeySize);
354+
355+
NamedGroupInfo.DefaultedResult namedGroupResult = NamedGroupInfo.selectServerFFDHE(
356+
jsseSecurityParameters.namedGroups, minimumFiniteFieldBits);
343357

344-
for (DHGroup group: provServerDefaultDHEParameters)
358+
int namedGroup = namedGroupResult.getResult();
359+
360+
if (namedGroupResult.isDefaulted() &&
361+
!TlsUtils.isNullOrEmpty(provServerDefaultDHEParameters) &&
362+
!manager.getContextData().getContext().isFips())
363+
{
364+
for (DHGroup dhGroup : provServerDefaultDHEParameters)
345365
{
346-
if (group.getP().bitLength() >= minimumFiniteFieldBits)
366+
int bits = dhGroup.getP().bitLength();
367+
if (bits >= minimumFiniteFieldBits)
347368
{
348-
return new TlsDHConfig(group);
369+
if (namedGroup < 0 || bits <= NamedGroup.getFiniteFieldBits(namedGroup))
370+
{
371+
return new TlsDHConfig(dhGroup);
372+
}
373+
break;
349374
}
350375
}
351376
}
352-
return super.getDHConfig();
377+
378+
return TlsDHUtils.createNamedDHConfig(context, namedGroup);
353379
}
354380

355381
@Override
356382
protected int selectDH(int minimumFiniteFieldBits)
357383
{
358-
minimumFiniteFieldBits = Math.max(minimumFiniteFieldBits, provEphemeralDHKeySize);
359-
360-
return NamedGroupInfo.selectServerFFDHE(jsseSecurityParameters.namedGroups, minimumFiniteFieldBits);
384+
throw new UnsupportedOperationException();
361385
}
362386

363387
@Override
@@ -369,7 +393,7 @@ protected int selectDHDefault(int minimumFiniteFieldBits)
369393
@Override
370394
protected int selectECDH(int minimumCurveBits)
371395
{
372-
return NamedGroupInfo.selectServerECDH(jsseSecurityParameters.namedGroups, minimumCurveBits);
396+
return NamedGroupInfo.selectServerECDH(jsseSecurityParameters.namedGroups, minimumCurveBits).getResult();
373397
}
374398

375399
@Override

0 commit comments

Comments
 (0)