Skip to content

Commit d8f2612

Browse files
committed
BCJSSE: Support for signature_algorithms_cert configuration
- see #1729
1 parent b1e2223 commit d8f2612

File tree

5 files changed

+187
-41
lines changed

5 files changed

+187
-41
lines changed

tls/src/main/java/org/bouncycastle/jsse/BCSSLParameters.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ private static <T> List<T> copyList(Collection<T> list)
4141
private int maximumPacketSize = 0;
4242
private String[] applicationProtocols = TlsUtils.EMPTY_STRINGS;
4343
private String[] signatureSchemes = null;
44+
private String[] signatureSchemesCert = null;
4445
private String[] namedGroups = null;
4546

4647
public BCSSLParameters()
@@ -261,6 +262,30 @@ public void setSignatureSchemes(String[] signatureSchemes)
261262
this.signatureSchemes = check;
262263
}
263264

265+
public String[] getSignatureSchemesCert()
266+
{
267+
return TlsUtils.clone(signatureSchemesCert);
268+
}
269+
270+
public void setSignatureSchemesCert(String[] signatureSchemesCert)
271+
{
272+
String[] check = null;
273+
274+
if (signatureSchemesCert != null)
275+
{
276+
check = TlsUtils.clone(signatureSchemesCert);
277+
for (String entry : check)
278+
{
279+
if (TlsUtils.isNullOrEmpty(entry))
280+
{
281+
throw new IllegalArgumentException("'signatureSchemesCert' entries cannot be null or empty strings");
282+
}
283+
}
284+
}
285+
286+
this.signatureSchemesCert = check;
287+
}
288+
264289
public String[] getNamedGroups()
265290
{
266291
return TlsUtils.clone(namedGroups);

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ private static <T> List<T> copyList(Collection<T> list)
4444
private int maximumPacketSize = 0;
4545
private String[] applicationProtocols = TlsUtils.EMPTY_STRINGS;
4646
private String[] signatureSchemes = null;
47+
private String[] signatureSchemesCert = null;
4748
private String[] namedGroups = null;
4849

4950
private BCApplicationProtocolSelector<SSLEngine> engineAPSelector;
@@ -72,6 +73,7 @@ ProvSSLParameters copy()
7273
p.maximumPacketSize = maximumPacketSize;
7374
p.applicationProtocols = applicationProtocols;
7475
p.signatureSchemes = signatureSchemes;
76+
p.signatureSchemesCert = signatureSchemesCert;
7577
p.namedGroups = namedGroups;
7678
p.engineAPSelector = engineAPSelector;
7779
p.socketAPSelector = socketAPSelector;
@@ -257,6 +259,16 @@ public void setSignatureSchemes(String[] signatureSchemes)
257259
this.signatureSchemes = TlsUtils.clone(signatureSchemes);
258260
}
259261

262+
public String[] getSignatureSchemesCert()
263+
{
264+
return TlsUtils.clone(signatureSchemesCert);
265+
}
266+
267+
public void setSignatureSchemesCert(String[] signatureSchemesCert)
268+
{
269+
this.signatureSchemesCert = TlsUtils.clone(signatureSchemesCert);
270+
}
271+
260272
public String[] getNamedGroups()
261273
{
262274
return TlsUtils.clone(namedGroups);

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

Lines changed: 102 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ class SignatureSchemeInfo
3737
private static final String PROPERTY_CLIENT_SIGNATURE_SCHEMES = "jdk.tls.client.SignatureSchemes";
3838
private static final String PROPERTY_SERVER_SIGNATURE_SCHEMES = "jdk.tls.server.SignatureSchemes";
3939

40+
private static final String PROPERTY_CLIENT_SIGNATURE_SCHEMES_CERT = "org.bouncycastle.jsse.client.SignatureSchemesCert";
41+
private static final String PROPERTY_SERVER_SIGNATURE_SCHEMES_CERT = "org.bouncycastle.jsse.server.SignatureSchemesCert";
42+
4043
// NOTE: Not all of these are necessarily enabled/supported; it will be checked at runtime
4144
private enum All
4245
{
@@ -148,23 +151,22 @@ static class PerConnection
148151
private final AtomicReference<List<SignatureSchemeInfo>> peerSigSchemes;
149152
private final AtomicReference<List<SignatureSchemeInfo>> peerSigSchemesCert;
150153

151-
PerConnection(List<SignatureSchemeInfo> localSigSchemes)
154+
PerConnection(List<SignatureSchemeInfo> localSigSchemes, List<SignatureSchemeInfo> localSigSchemesCert)
152155
{
153-
// TODO[tls13] No JSSE API to configure localSigSchemesCert?)
154156
this.localSigSchemes = localSigSchemes;
155-
this.localSigSchemesCert = null;
157+
this.localSigSchemesCert = localSigSchemesCert;
156158
this.peerSigSchemes = new AtomicReference<List<SignatureSchemeInfo>>();
157159
this.peerSigSchemesCert = new AtomicReference<List<SignatureSchemeInfo>>();
158160
}
159161

160162
String[] getLocalJcaSignatureAlgorithms()
161163
{
162-
return getJcaSignatureAlgorithms(getLocalJcaSigSchemesCert());
164+
return getJcaSignatureAlgorithms(getLocalSigSchemesCert());
163165
}
164166

165167
String[] getLocalJcaSignatureAlgorithmsBC()
166168
{
167-
return getJcaSignatureAlgorithmsBC(getLocalJcaSigSchemesCert());
169+
return getJcaSignatureAlgorithmsBC(getLocalSigSchemesCert());
168170
}
169171

170172
Vector<SignatureAndHashAlgorithm> getLocalSignatureAndHashAlgorithms()
@@ -177,21 +179,38 @@ Vector<SignatureAndHashAlgorithm> getLocalSignatureAndHashAlgorithmsCert()
177179
return getSignatureAndHashAlgorithms(localSigSchemesCert);
178180
}
179181

182+
List<SignatureSchemeInfo> getLocalSigSchemes()
183+
{
184+
return localSigSchemes;
185+
}
186+
187+
List<SignatureSchemeInfo> getLocalSigSchemesCert()
188+
{
189+
return localSigSchemesCert != null ? localSigSchemesCert : getLocalSigSchemes();
190+
}
191+
180192
String[] getPeerJcaSignatureAlgorithms()
181193
{
182-
return getJcaSignatureAlgorithms(getPeerJcaSigSchemesCert());
194+
return getJcaSignatureAlgorithms(getPeerSigSchemesCert());
183195
}
184196

185197
String[] getPeerJcaSignatureAlgorithmsBC()
186198
{
187-
return getJcaSignatureAlgorithmsBC(getPeerJcaSigSchemesCert());
199+
return getJcaSignatureAlgorithmsBC(getPeerSigSchemesCert());
188200
}
189201

190-
Iterable<SignatureSchemeInfo> getPeerSigSchemes()
202+
List<SignatureSchemeInfo> getPeerSigSchemes()
191203
{
192204
return peerSigSchemes.get();
193205
}
194206

207+
List<SignatureSchemeInfo> getPeerSigSchemesCert()
208+
{
209+
List<SignatureSchemeInfo> sigSchemesCert = peerSigSchemesCert.get();
210+
211+
return sigSchemesCert != null ? sigSchemesCert : getPeerSigSchemes();
212+
}
213+
195214
boolean hasLocalSignatureScheme(SignatureSchemeInfo signatureSchemeInfo)
196215
{
197216
return localSigSchemes.contains(signatureSchemeInfo);
@@ -202,30 +221,22 @@ void notifyPeerData(List<SignatureSchemeInfo> sigSchemes, List<SignatureSchemeIn
202221
peerSigSchemes.set(sigSchemes);
203222
peerSigSchemesCert.set(sigSchemesCert);
204223
}
205-
206-
private List<SignatureSchemeInfo> getLocalJcaSigSchemesCert()
207-
{
208-
return localSigSchemesCert == null ? localSigSchemes : localSigSchemesCert;
209-
}
210-
211-
private List<SignatureSchemeInfo> getPeerJcaSigSchemesCert()
212-
{
213-
List<SignatureSchemeInfo> sigSchemesCert = peerSigSchemesCert.get();
214-
215-
return sigSchemesCert == null ? peerSigSchemes.get() : sigSchemesCert;
216-
}
217224
}
218225

219226
static class PerContext
220227
{
221228
private final Map<Integer, SignatureSchemeInfo> index;
222229
private final int[] candidatesClient, candidatesServer;
230+
private final int[] candidatesCertClient, candidatesCertServer;
223231

224-
PerContext(Map<Integer, SignatureSchemeInfo> index, int[] candidatesClient, int[] candidatesServer)
232+
PerContext(Map<Integer, SignatureSchemeInfo> index, int[] candidatesClient, int[] candidatesServer,
233+
int[] candidatesCertClient, int[] candidatesCertServer)
225234
{
226235
this.index = index;
227236
this.candidatesClient = candidatesClient;
228237
this.candidatesServer = candidatesServer;
238+
this.candidatesCertClient = candidatesCertClient;
239+
this.candidatesCertServer = candidatesCertServer;
229240
}
230241
}
231242

@@ -235,7 +246,7 @@ static PerConnection createPerConnectionClient(PerContext perContext, ProvSSLPar
235246
ProtocolVersion latest = ProtocolVersion.getLatestTLS(activeProtocolVersions);
236247
if (!TlsUtils.isSignatureAlgorithmsExtensionAllowed(latest))
237248
{
238-
return new PerConnection(null);
249+
return new PerConnection(null, null);
239250
}
240251

241252
ProtocolVersion earliest = ProtocolVersion.getEarliestTLS(activeProtocolVersions);
@@ -248,7 +259,7 @@ static PerConnection createPerConnectionServer(PerContext perContext, ProvSSLPar
248259
{
249260
if (!TlsUtils.isSignatureAlgorithmsExtensionAllowed(negotiatedVersion))
250261
{
251-
return new PerConnection(null);
262+
return new PerConnection(null, null);
252263
}
253264

254265
return createPerConnection(perContext, true, sslParameters, negotiatedVersion, negotiatedVersion, namedGroups);
@@ -257,47 +268,96 @@ static PerConnection createPerConnectionServer(PerContext perContext, ProvSSLPar
257268
private static PerConnection createPerConnection(PerContext perContext, boolean isServer, ProvSSLParameters sslParameters,
258269
ProtocolVersion earliest, ProtocolVersion latest, NamedGroupInfo.PerConnection namedGroups)
259270
{
260-
String[] signatureSchemes = sslParameters.getSignatureSchemes();
261-
262271
int[] candidates;
263-
if (signatureSchemes == null)
264272
{
265-
candidates = isServer ? perContext.candidatesServer : perContext.candidatesClient;
273+
String[] signatureSchemes = sslParameters.getSignatureSchemes();
274+
275+
if (signatureSchemes == null)
276+
{
277+
candidates = isServer ? perContext.candidatesServer : perContext.candidatesClient;
278+
279+
if (candidates == null)
280+
{
281+
candidates = CANDIDATES_DEFAULT;
282+
}
283+
}
284+
else
285+
{
286+
candidates = createCandidates(perContext.index, signatureSchemes, "SSLParameters.signatureSchemes");
287+
}
266288
}
267-
else
289+
290+
int[] candidatesCert;
268291
{
269-
candidates = createCandidates(perContext.index, signatureSchemes, "SSLParameters.signatureSchemes");
292+
String[] signatureSchemesCert = sslParameters.getSignatureSchemesCert();
293+
294+
if (signatureSchemesCert == null)
295+
{
296+
candidatesCert = isServer ? perContext.candidatesCertServer : perContext.candidatesCertClient;
297+
}
298+
else
299+
{
300+
candidatesCert = createCandidates(perContext.index, signatureSchemesCert,
301+
"SSLParameters.signatureSchemesCert");
302+
}
270303
}
271304

272305
BCAlgorithmConstraints algorithmConstraints = sslParameters.getAlgorithmConstraints();
273306
boolean post13Active = TlsUtils.isTLSv13(latest);
274307
boolean pre13Active = !TlsUtils.isTLSv13(earliest);
275308

276-
int count = candidates.length;
277-
ArrayList<SignatureSchemeInfo> localSigSchemes = new ArrayList<SignatureSchemeInfo>(count);
278-
for (int i = 0; i < count; ++i)
309+
ArrayList<SignatureSchemeInfo> localSigSchemes;
279310
{
280-
Integer candidate = Integers.valueOf(candidates[i]);
281-
SignatureSchemeInfo signatureSchemeInfo = perContext.index.get(candidate);
311+
int count = candidates.length;
312+
localSigSchemes = new ArrayList<SignatureSchemeInfo>(count);
313+
for (int i = 0; i < count; ++i)
314+
{
315+
Integer candidate = Integers.valueOf(candidates[i]);
316+
SignatureSchemeInfo signatureSchemeInfo = perContext.index.get(candidate);
282317

283-
if (null != signatureSchemeInfo
284-
&& signatureSchemeInfo.isActiveCerts(algorithmConstraints, post13Active, pre13Active, namedGroups))
318+
if (null != signatureSchemeInfo
319+
&& signatureSchemeInfo.isActiveCerts(algorithmConstraints, post13Active, pre13Active, namedGroups))
320+
{
321+
localSigSchemes.add(signatureSchemeInfo);
322+
}
323+
}
324+
localSigSchemes.trimToSize();
325+
}
326+
327+
ArrayList<SignatureSchemeInfo> localSigSchemesCert = null;
328+
if (candidatesCert != null)
329+
{
330+
int count = candidatesCert.length;
331+
localSigSchemesCert = new ArrayList<SignatureSchemeInfo>(count);
332+
for (int i = 0; i < count; ++i)
285333
{
286-
localSigSchemes.add(signatureSchemeInfo);
334+
Integer candidate = Integers.valueOf(candidatesCert[i]);
335+
SignatureSchemeInfo signatureSchemeInfo = perContext.index.get(candidate);
336+
337+
if (null != signatureSchemeInfo
338+
&& signatureSchemeInfo.isActiveCerts(algorithmConstraints, post13Active, pre13Active, namedGroups))
339+
{
340+
localSigSchemesCert.add(signatureSchemeInfo);
341+
}
287342
}
343+
localSigSchemesCert.trimToSize();
288344
}
289-
localSigSchemes.trimToSize();
290-
return new PerConnection(localSigSchemes);
345+
346+
return new PerConnection(localSigSchemes, localSigSchemesCert);
291347
}
292348

293349
static PerContext createPerContext(boolean isFipsContext, JcaTlsCrypto crypto,
294350
NamedGroupInfo.PerContext namedGroups)
295351
{
296352
Map<Integer, SignatureSchemeInfo> index = createIndex(isFipsContext, crypto, namedGroups);
353+
297354
int[] candidatesClient = createCandidatesFromProperty(index, PROPERTY_CLIENT_SIGNATURE_SCHEMES);
298355
int[] candidatesServer = createCandidatesFromProperty(index, PROPERTY_SERVER_SIGNATURE_SCHEMES);
299356

300-
return new PerContext(index, candidatesClient, candidatesServer);
357+
int[] candidatesCertClient = createCandidatesFromProperty(index, PROPERTY_CLIENT_SIGNATURE_SCHEMES_CERT);
358+
int[] candidatesCertServer = createCandidatesFromProperty(index, PROPERTY_SERVER_SIGNATURE_SCHEMES_CERT);
359+
360+
return new PerContext(index, candidatesClient, candidatesServer, candidatesCertClient, candidatesCertServer);
301361
}
302362

303363
private static String[] getJcaSignatureAlgorithms(Collection<SignatureSchemeInfo> infos)
@@ -458,7 +518,7 @@ private static int[] createCandidatesFromProperty(Map<Integer, SignatureSchemeIn
458518
String[] names = PropertyUtils.getStringArraySystemProperty(propertyName);
459519
if (null == names)
460520
{
461-
return CANDIDATES_DEFAULT;
521+
return null;
462522
}
463523

464524
return createCandidates(index, names, propertyName);
@@ -649,6 +709,7 @@ public String toString()
649709
return all.text;
650710
}
651711

712+
// TODO Refactor to use this in non-cert contexts (careful for signatureSchemesCert defaulting case)
652713
// private boolean isActive(BCAlgorithmConstraints algorithmConstraints, boolean post13Active, boolean pre13Active,
653714
// NamedGroupInfo.PerConnection namedGroupInfos)
654715
// {

tls/src/main/jdk1.5/org/bouncycastle/jsse/provider/SSLParametersUtil.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ static BCSSLParameters getParameters(ProvSSLParameters prov)
8383
ssl.setEnableRetransmissions(prov.getEnableRetransmissions());
8484
ssl.setMaximumPacketSize(prov.getMaximumPacketSize());
8585
ssl.setSignatureSchemes(prov.getSignatureSchemes());
86+
ssl.setSignatureSchemesCert(prov.getSignatureSchemesCert());
8687
ssl.setNamedGroups(prov.getNamedGroups());
8788

8889
return ssl;
@@ -177,6 +178,13 @@ static SSLParameters getSSLParameters(ProvSSLParameters prov)
177178
set(ssl, setNamedGroups, prov.getNamedGroups());
178179
}
179180

181+
// Unsupported as of JDK 21
182+
183+
// if (null != setSignatureSchemesCert)
184+
// {
185+
// set(ssl, setSignatureSchemesCert, prov.getSignatureSchemesCert());
186+
// }
187+
180188
return ssl;
181189
}
182190

@@ -276,6 +284,13 @@ static BCSSLParameters importSSLParameters(SSLParameters ssl)
276284
bc.setNamedGroups((String[])get(ssl, getNamedGroups));
277285
}
278286

287+
// Unsupported as of JDK 21
288+
289+
// if (null != getSignatureSchemesCert)
290+
// {
291+
// bc.setSignatureSchemesCert((String[])get(ssl, getSignatureSchemesCert));
292+
// }
293+
279294
return bc;
280295
}
281296

@@ -342,6 +357,8 @@ static void setParameters(ProvSSLParameters prov, BCSSLParameters ssl)
342357
prov.setSignatureSchemes(ssl.getSignatureSchemes());
343358

344359
prov.setNamedGroups(ssl.getNamedGroups());
360+
361+
prov.setSignatureSchemesCert(ssl.getSignatureSchemesCert());
345362
}
346363

347364
static void setSSLParameters(ProvSSLParameters prov, SSLParameters ssl)
@@ -449,6 +466,13 @@ static void setSSLParameters(ProvSSLParameters prov, SSLParameters ssl)
449466
{
450467
prov.setNamedGroups((String[])get(ssl, getNamedGroups));
451468
}
469+
470+
// Unsupported as of JDK 21
471+
472+
// if (null != getSignatureSchemesCert)
473+
// {
474+
// prov.setSignatureSchemesCert((String[])get(ssl, getSignatureSchemesCert));
475+
// }
452476
}
453477

454478
private static Object get(Object obj, Method method)

0 commit comments

Comments
 (0)