[java-oidc-common] branch main updated: Improve readability of signature signing algorithm to credential lookup
Phil Smart
philip.smart at jisc.ac.uk
Mon Feb 20 12:31:00 UTC 2023
This is an automated email from the git hooks/post-receive script.
philsmart pushed a commit to branch main
in repository java-oidc-common.
View the commit online:
http://git.shibboleth.net/view/?p=java-oidc-common.git;a=commit;h=8561fd7385e54bf6800dad9d63c58e02c760666c
The following commit(s) were added to refs/heads/main by this push:
new 8561fd7 Improve readability of signature signing algorithm to credential lookup
8561fd7 is described below
commit 8561fd7385e54bf6800dad9d63c58e02c760666c
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Mon Feb 20 12:30:57 2023 +0000
Improve readability of signature signing algorithm to credential lookup
---
.../security/credential/JWACredentialSupport.java | 23 ++++++--
.../BasicSignatureSigningParametersResolver.java | 69 +++++++++++++++-------
2 files changed, 67 insertions(+), 25 deletions(-)
diff --git a/oidc-common-crypto-api/src/main/java/net/shibboleth/oidc/security/credential/JWACredentialSupport.java b/oidc-common-crypto-api/src/main/java/net/shibboleth/oidc/security/credential/JWACredentialSupport.java
index afc2d44..56a4d04 100644
--- a/oidc-common-crypto-api/src/main/java/net/shibboleth/oidc/security/credential/JWACredentialSupport.java
+++ b/oidc-common-crypto-api/src/main/java/net/shibboleth/oidc/security/credential/JWACredentialSupport.java
@@ -54,21 +54,34 @@ public final class JWACredentialSupport {
* Is the EC key supplied compatible with the EC Curve required by the algorithm given.
*
* @param key the key to check compatibility for
- * @param algorithm the algorithm to match compatibility against
+ * @param algorithm the JWS algorithm to match compatibility against
*
* @return true if compatible, false otherwise.
*
* @throws JOSEException if there is an issue deriving algorithms
*/
public static boolean keySupportsCurve(@Nonnull final ECKey key,
- @Nonnull @NotEmpty final String algorithm) throws JOSEException {
+ @Nonnull @NotEmpty final JWSAlgorithm algorithm) throws JOSEException {
final JWSAlgorithm algCompatibleWithCredentialCurve =
ECDSA.resolveAlgorithm(Curve.forECParameterSpec(key.getParams()));
- final JWSAlgorithm alg = JWSAlgorithm.parse(algorithm);
-
- return algCompatibleWithCredentialCurve == alg;
+ return algCompatibleWithCredentialCurve == algorithm;
+ }
+
+ /**
+ * Is the EC key supplied compatible with the EC Curve required by the algorithm given.
+ *
+ * @param key the key to check compatibility for
+ * @param algorithm the string algorithm to match compatibility against
+ *
+ * @return true if compatible, false otherwise.
+ *
+ * @throws JOSEException if there is an issue deriving algorithms
+ */
+ public static boolean keySupportsCurve(@Nonnull final ECKey key,
+ @Nonnull @NotEmpty final String algorithm) throws JOSEException {
+ return keySupportsCurve(key, JWSAlgorithm.parse(algorithm));
}
}
diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jose/impl/BasicSignatureSigningParametersResolver.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jose/impl/BasicSignatureSigningParametersResolver.java
index 0e33854..f9ebd62 100644
--- a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jose/impl/BasicSignatureSigningParametersResolver.java
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jose/impl/BasicSignatureSigningParametersResolver.java
@@ -19,6 +19,8 @@ package net.shibboleth.oidc.security.jose.impl;
import java.security.Key;
import java.security.interfaces.ECKey;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.RSAPrivateKey;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -37,6 +39,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSAlgorithm;
import net.shibboleth.oidc.security.CredentialConversionUtil;
import net.shibboleth.oidc.security.credential.JWACredentialSupport;
@@ -205,16 +208,31 @@ public class BasicSignatureSigningParametersResolver
final List<String> algorithms = getEffectiveSignatureAlgorithms(criteria, includeExcludePredicate);
log.trace("Resolved effective signature algorithms: {}", algorithms);
+ findCompatibleAlgorithmAndCredential(algorithms, credentials, params);
+
+ }
+
+ /**
+ * Loop through the algorithms and find the first compatible credential. Add the compatible algorithm and credential
+ * to the signing parameters.
+ *
+ * @param algorithms the algorithms to find compatible from
+ * @param credentials the credentials to find compatibility with
+ * @param params the parameters to add a compatible algorithm and credential too.
+ */
+ protected void findCompatibleAlgorithmAndCredential(final List<String> algorithms,
+ final List<Credential> credentials, @Nonnull final SignatureSigningParameters params) {
+
// Pick the first credential that matches one of the supported algorithms. Take algorithm priority.
for (final String algorithm : algorithms) {
for (final Credential credential : credentials) {
if (log.isTraceEnabled()) {
final Key key = CredentialSupport.extractSigningKey(credential);
- log.trace("Evaluating credential '{}' of type '{}' against algorithm: {}",
+ log.trace("Evaluating signing credential '{}' of type '{}' against algorithm: {}",
CredentialConversionUtil.resolveKid(credential), key != null ? key.getAlgorithm() : "n/a",
algorithm);
}
- if (credentialSupportsAlgorithm(credential, algorithm)) {
+ if (credentialSupportsSigningAlgorithm(credential, algorithm)) {
if (log.isTraceEnabled()) {
log.trace("Credential '{}' passed eval against algorithm: {}",
CredentialConversionUtil.resolveKid(credential), algorithm);
@@ -243,34 +261,45 @@ public class BasicSignatureSigningParametersResolver
}
/**
- * Evaluate whether the specified credential is supported for use with the specified algorithm URI.
+ * Evaluate whether the specified credential is supported for use with the specified signing algorithm.
*
- * <p>If EC key type, the curve is also checked against the algorithm for compatibility.</p>
+ * <p>First, the key type is checked against the algorithm family, then the algorithm and key length are checked.
+ * If the key is an EC type, the curve is also checked against the algorithm.</p>
*
* @param credential the credential to evaluate
* @param algorithm the algorithm URI to evaluate
* @return true if credential may be used with the supplied algorithm URI, false otherwise
*/
- protected boolean credentialSupportsAlgorithm(@Nonnull final Credential credential,
+ protected boolean credentialSupportsSigningAlgorithm(@Nonnull final Credential credential,
@Nonnull @NotEmpty final String algorithm) {
- final boolean credentialSupportAlgorithm = AlgorithmSupport.credentialSupportsAlgorithmForSigning(credential,
- getAlgorithmRegistry().get(algorithm));
-
- // Check private key only as for signing operation. Only check if initial compatibility is established
- if (credentialSupportAlgorithm && JWACredentialSupport.isECKeyType(credential.getPrivateKey())) {
- try {
- return JWACredentialSupport.keySupportsCurve((ECKey)credential.getPrivateKey(), algorithm);
- } catch (final JOSEException e) {
- log.trace("Algorithm '{}' and EC credential '{}' threw an error while checking for compatibility, "
- + "credential can not be used", algorithm, CredentialConversionUtil.resolveKid(credential), e);
- return false;
- }
+ try {
+ final JWSAlgorithm supportedAlgorithm = JWSAlgorithm.parse(algorithm);
+ final Key key = CredentialSupport.extractSigningKey(credential);
+
+ boolean credSupportsAlgorithm = false;
+ if (JWSAlgorithm.Family.HMAC_SHA.contains(supportedAlgorithm) && credential.getSecretKey() != null) {
+ credSupportsAlgorithm = true;
+ } else if (JWSAlgorithm.Family.RSA.contains(supportedAlgorithm)
+ && credential.getPrivateKey() instanceof RSAPrivateKey) {
+ credSupportsAlgorithm = true;
+ } else if (JWSAlgorithm.Family.EC.contains(supportedAlgorithm)
+ && credential.getPrivateKey() instanceof ECPrivateKey
+ && JWACredentialSupport.keySupportsCurve((ECKey)credential.getPrivateKey(), supportedAlgorithm)) {
+ credSupportsAlgorithm = true;
+ }
+
+ return credSupportsAlgorithm && AlgorithmSupport.checkKeyAlgorithmAndLength(key,
+ getAlgorithmRegistry().get(algorithm));
+
+ } catch (final JOSEException e) {
+ log.trace("Algorithm '{}' and EC credential '{}' threw an error while checking for compatibility, "
+ + "credential can not be used", algorithm,
+ CredentialConversionUtil.resolveKid(credential), e);
+ return false;
}
- return credentialSupportAlgorithm;
}
-
-
+
/**
* Get the effective list of signing credentials to consider.
*
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list