added ES* and PS* support for signed objects

pull/819/merge
Justin Richer 2015-05-21 13:08:35 -04:00
parent 0d6775dfa8
commit 6be2b4f65e
6 changed files with 61 additions and 22 deletions

View File

@ -35,6 +35,8 @@ import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.ECDSASigner;
import com.nimbusds.jose.crypto.ECDSAVerifier;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import com.nimbusds.jose.crypto.RSASSASigner;
@ -100,7 +102,6 @@ public class DefaultJWTSigningAndValidationService implements JWTSigningAndValid
for (JWK key : keyStore.getKeys()) {
if (!Strings.isNullOrEmpty(key.getKeyID())) {
// use the key ID that's built into the key itself
// TODO (#641): deal with JWK thumbprints
this.keys.put(key.getKeyID(), key);
} else {
// create a random key id
@ -173,9 +174,14 @@ public class DefaultJWTSigningAndValidationService implements JWTSigningAndValid
} else if (jwk instanceof ECKey) {
// build EC signers & verifiers
// TODO: add support for EC keys
logger.warn("EC Keys are not yet supported.");
if (jwk.isPrivate()) {
ECDSASigner signer = new ECDSASigner(((ECKey) jwk).getD().decodeToBigInteger());
signers.put(id, signer);
}
ECDSAVerifier verifier = new ECDSAVerifier(((ECKey) jwk).getX().decodeToBigInteger(), ((ECKey) jwk).getY().decodeToBigInteger());
verifiers.put(id, verifier);
} else if (jwk instanceof OctetSequenceKey) {
// build HMAC signers & verifiers

View File

@ -479,15 +479,18 @@
<div class="controls">
<select>
<option value="default" <%-tokenEndpointAuthSigningAlg == null ? 'selected ' : ''%> data-i18n="client.client-form.signing.any">Any allowed</option>
<option value="HS256" <%-tokenEndpointAuthSigningAlg == "HS256" ? 'selected' : ''%> data-i18n="client.client-form.signing.hmac-256">HMAC using SHA-256 hash algorithm</option>
<option value="HS384" <%-tokenEndpointAuthSigningAlg == "HS384" ? 'selected' : ''%> data-i18n="client.client-form.signing.hmac-384">HMAC using SHA-384 hash algorithm</option>
<option value="HS512" <%-tokenEndpointAuthSigningAlg == "HS512" ? 'selected' : ''%> data-i18n="client.client-form.signing.hmac-512">HMAC using SHA-512 hash algorithm</option>
<option value="RS256" <%-tokenEndpointAuthSigningAlg == "RS256" ? 'selected' : ''%> data-i18n="client.client-form.signing.rsassa-256">RSASSA using SHA-256 hash algorithm</option>
<option value="RS384" <%-tokenEndpointAuthSigningAlg == "RS384" ? 'selected' : ''%> data-i18n="client.client-form.signing.rsassa-384">RSASSA using SHA-384 hash algorithm</option>
<option value="RS512" <%-tokenEndpointAuthSigningAlg == "RS512" ? 'selected' : ''%> data-i18n="client.client-form.signing.rsassa-512">RSASSA using SHA-512 hash algorithm</option>
<option value="ES256" <%-tokenEndpointAuthSigningAlg == "ES256" ? 'selected' : ''%> data-i18n="client.client-form.signing.ecdsa-256">ECDSA using P-256 curve and SHA-256 hash algorithm</option>
<option value="ES384" <%-tokenEndpointAuthSigningAlg == "ES384" ? 'selected' : ''%> data-i18n="client.client-form.signing.ecdsa-384">ECDSA using P-384 curve and SHA-384 hash algorithm</option>
<option value="ES512" <%-tokenEndpointAuthSigningAlg == "ES512" ? 'selected' : ''%> data-i18n="client.client-form.signing.ecdsa-512">ECDSA using P-512 curve and SHA-512 hash algorithm</option>
<option value="HS256" <%-tokenEndpointAuthSigningAlg == "HS256" ? 'selected' : ''%> data-i18n="client.client-form.signing.hs256">HMAC using SHA-256 hash algorithm</option>
<option value="HS384" <%-tokenEndpointAuthSigningAlg == "HS384" ? 'selected' : ''%> data-i18n="client.client-form.signing.hs384">HMAC using SHA-384 hash algorithm</option>
<option value="HS512" <%-tokenEndpointAuthSigningAlg == "HS512" ? 'selected' : ''%> data-i18n="client.client-form.signing.hs512">HMAC using SHA-512 hash algorithm</option>
<option value="RS256" <%-tokenEndpointAuthSigningAlg == "RS256" ? 'selected' : ''%> data-i18n="client.client-form.signing.rs256">RSASSA using SHA-256 hash algorithm</option>
<option value="RS384" <%-tokenEndpointAuthSigningAlg == "RS384" ? 'selected' : ''%> data-i18n="client.client-form.signing.rs384">RSASSA using SHA-384 hash algorithm</option>
<option value="RS512" <%-tokenEndpointAuthSigningAlg == "RS512" ? 'selected' : ''%> data-i18n="client.client-form.signing.rs512">RSASSA using SHA-512 hash algorithm</option>
<option value="PS256" <%-tokenEndpointAuthSigningAlg == "PS256" ? 'selected' : ''%> data-i18n="client.client-form.signing.ps256">RSASSA-PSS using SHA-256 and MGF1 with SHA-256</option>
<option value="PS384" <%-tokenEndpointAuthSigningAlg == "PS384" ? 'selected' : ''%> data-i18n="client.client-form.signing.ps384">RSASSA-PSS using SHA-384 and MGF1 with SHA-384</option>
<option value="PS512" <%-tokenEndpointAuthSigningAlg == "PS512" ? 'selected' : ''%> data-i18n="client.client-form.signing.ps512">RSASSA-PSS using SHA-512 and MGF1 with SHA-512</option>
<option value="ES256" <%-tokenEndpointAuthSigningAlg == "ES256" ? 'selected' : ''%> data-i18n="client.client-form.signing.es256">ECDSA using P-256 curve and SHA-256 hash algorithm</option>
<option value="ES384" <%-tokenEndpointAuthSigningAlg == "ES384" ? 'selected' : ''%> data-i18n="client.client-form.signing.es384">ECDSA using P-384 curve and SHA-384 hash algorithm</option>
<option value="ES512" <%-tokenEndpointAuthSigningAlg == "ES512" ? 'selected' : ''%> data-i18n="client.client-form.signing.es512">ECDSA using P-512 curve and SHA-512 hash algorithm</option>
</select>
</div>
</div>
@ -584,6 +587,9 @@
<option value="RS256" <%-requestObjectSigningAlg == "RS256" ? 'selected' : ''%> data-i18n="client.client-form.signing.rs256">RSASSA using SHA-256 hash algorithm</option>
<option value="RS384" <%-requestObjectSigningAlg == "RS384" ? 'selected' : ''%> data-i18n="client.client-form.signing.rs384">RSASSA using SHA-384 hash algorithm</option>
<option value="RS512" <%-requestObjectSigningAlg == "RS512" ? 'selected' : ''%> data-i18n="client.client-form.signing.rs512">RSASSA using SHA-512 hash algorithm</option>
<option value="PS256" <%-requestObjectSigningAlg == "PS256" ? 'selected' : ''%> data-i18n="client.client-form.signing.ps256">RSASSA-PSS using SHA-256 and MGF1 with SHA-256</option>
<option value="PS384" <%-requestObjectSigningAlg == "PS384" ? 'selected' : ''%> data-i18n="client.client-form.signing.ps384">RSASSA-PSS using SHA-384 and MGF1 with SHA-384</option>
<option value="PS512" <%-requestObjectSigningAlg == "PS512" ? 'selected' : ''%> data-i18n="client.client-form.signing.ps512">RSASSA-PSS using SHA-512 and MGF1 with SHA-512</option>
<option value="ES256" <%-requestObjectSigningAlg == "ES256" ? 'selected' : ''%> data-i18n="client.client-form.signing.es256">ECDSA using P-256 curve and SHA-256 hash algorithm</option>
<option value="ES384" <%-requestObjectSigningAlg == "ES384" ? 'selected' : ''%> data-i18n="client.client-form.signing.es384">ECDSA using P-384 curve and SHA-384 hash algorithm</option>
<option value="ES512" <%-requestObjectSigningAlg == "ES512" ? 'selected' : ''%> data-i18n="client.client-form.signing.es512">ECDSA using P-512 curve and SHA-512 hash algorithm</option>
@ -603,6 +609,9 @@
<option value="RS256" <%-userInfoSignedResponseAlg == "RS256" ? 'selected' : ''%> data-i18n="client.client-form.signing.rs256">RSASSA using SHA-256 hash algorithm</option>
<option value="RS384" <%-userInfoSignedResponseAlg == "RS384" ? 'selected' : ''%> data-i18n="client.client-form.signing.rs384">RSASSA using SHA-384 hash algorithm</option>
<option value="RS512" <%-userInfoSignedResponseAlg == "RS512" ? 'selected' : ''%> data-i18n="client.client-form.signing.rs512">RSASSA using SHA-512 hash algorithm</option>
<option value="PS256" <%-userInfoSignedResponseAlg == "PS256" ? 'selected' : ''%> data-i18n="client.client-form.signing.ps256">RSASSA-PSS using SHA-256 and MGF1 with SHA-256</option>
<option value="PS384" <%-userInfoSignedResponseAlg == "PS384" ? 'selected' : ''%> data-i18n="client.client-form.signing.ps384">RSASSA-PSS using SHA-384 and MGF1 with SHA-384</option>
<option value="PS512" <%-userInfoSignedResponseAlg == "PS512" ? 'selected' : ''%> data-i18n="client.client-form.signing.ps512">RSASSA-PSS using SHA-512 and MGF1 with SHA-512</option>
<option value="ES256" <%-userInfoSignedResponseAlg == "ES256" ? 'selected' : ''%> data-i18n="client.client-form.signing.es256">ECDSA using P-256 curve and SHA-256 hash algorithm</option>
<option value="ES384" <%-userInfoSignedResponseAlg == "ES384" ? 'selected' : ''%> data-i18n="client.client-form.signing.es384">ECDSA using P-384 curve and SHA-384 hash algorithm</option>
<option value="ES512" <%-userInfoSignedResponseAlg == "ES512" ? 'selected' : ''%> data-i18n="client.client-form.signing.es512">ECDSA using P-512 curve and SHA-512 hash algorithm</option>
@ -654,6 +663,9 @@
<option value="RS256" <%-idTokenSignedResponseAlg == "RS256" ? 'selected' : ''%> data-i18n="client.client-form.signing.rs256">RSASSA using SHA-256 hash algorithm</option>
<option value="RS384" <%-idTokenSignedResponseAlg == "RS384" ? 'selected' : ''%> data-i18n="client.client-form.signing.rs384">RSASSA using SHA-384 hash algorithm</option>
<option value="RS512" <%-idTokenSignedResponseAlg == "RS512" ? 'selected' : ''%> data-i18n="client.client-form.signing.rs512">RSASSA using SHA-512 hash algorithm</option>
<option value="PS256" <%-idTokenSignedResponseAlg == "PS256" ? 'selected' : ''%> data-i18n="client.client-form.signing.ps256">RSASSA-PSS using SHA-256 and MGF1 with SHA-256</option>
<option value="PS384" <%-idTokenSignedResponseAlg == "PS384" ? 'selected' : ''%> data-i18n="client.client-form.signing.ps384">RSASSA-PSS using SHA-384 and MGF1 with SHA-384</option>
<option value="PS512" <%-idTokenSignedResponseAlg == "PS512" ? 'selected' : ''%> data-i18n="client.client-form.signing.ps512">RSASSA-PSS using SHA-512 and MGF1 with SHA-512</option>
<option value="ES256" <%-idTokenSignedResponseAlg == "ES256" ? 'selected' : ''%> data-i18n="client.client-form.signing.es256">ECDSA using P-256 curve and SHA-256 hash algorithm</option>
<option value="ES384" <%-idTokenSignedResponseAlg == "ES384" ? 'selected' : ''%> data-i18n="client.client-form.signing.es384">ECDSA using P-384 curve and SHA-384 hash algorithm</option>
<option value="ES512" <%-idTokenSignedResponseAlg == "ES512" ? 'selected' : ''%> data-i18n="client.client-form.signing.es512">ECDSA using P-512 curve and SHA-512 hash algorithm</option>

View File

@ -288,8 +288,15 @@ public class DiscoveryEndpoint {
Collection<JWSAlgorithm> serverSigningAlgs = signService.getAllSigningAlgsSupported();
Collection<JWSAlgorithm> clientSymmetricSigningAlgs = Lists.newArrayList(JWSAlgorithm.HS256, JWSAlgorithm.HS384, JWSAlgorithm.HS512);
Collection<JWSAlgorithm> clientSymmetricAndAsymmetricSigningAlgs = Lists.newArrayList(JWSAlgorithm.HS256, JWSAlgorithm.HS384, JWSAlgorithm.HS512, JWSAlgorithm.RS256, JWSAlgorithm.RS384, JWSAlgorithm.RS512);
Collection<Algorithm> clientSymmetricAndAsymmetricSigningAlgsWithNone = Lists.newArrayList(JWSAlgorithm.HS256, JWSAlgorithm.HS384, JWSAlgorithm.HS512, JWSAlgorithm.RS256, JWSAlgorithm.RS384, JWSAlgorithm.RS512, Algorithm.NONE);
Collection<JWSAlgorithm> clientSymmetricAndAsymmetricSigningAlgs = Lists.newArrayList(JWSAlgorithm.HS256, JWSAlgorithm.HS384, JWSAlgorithm.HS512,
JWSAlgorithm.RS256, JWSAlgorithm.RS384, JWSAlgorithm.RS512,
JWSAlgorithm.ES256, JWSAlgorithm.ES384, JWSAlgorithm.ES512,
JWSAlgorithm.PS256, JWSAlgorithm.PS384, JWSAlgorithm.PS512);
Collection<Algorithm> clientSymmetricAndAsymmetricSigningAlgsWithNone = Lists.newArrayList(JWSAlgorithm.HS256, JWSAlgorithm.HS384, JWSAlgorithm.HS512,
JWSAlgorithm.RS256, JWSAlgorithm.RS384, JWSAlgorithm.RS512,
JWSAlgorithm.ES256, JWSAlgorithm.ES384, JWSAlgorithm.ES512,
JWSAlgorithm.PS256, JWSAlgorithm.PS384, JWSAlgorithm.PS512,
Algorithm.NONE);
ArrayList<String> grantTypes = Lists.newArrayList("authorization_code", "implicit", "urn:ietf:params:oauth:grant-type:jwt-bearer", "client_credentials", "urn:ietf:params:oauth:grant_type:redelegate");
Map<String, Object> m = new HashMap<String, Object>();

View File

@ -117,8 +117,16 @@ public class JWTBearerAuthenticationProvider implements AuthenticationProvider {
} else if (client.getTokenEndpointAuthMethod().equals(AuthMethod.PRIVATE_KEY) &&
(alg.equals(JWSAlgorithm.RS256)
|| alg.equals(JWSAlgorithm.RS384)
|| alg.equals(JWSAlgorithm.RS512))) {
|| alg.equals(JWSAlgorithm.RS512)
|| alg.equals(JWSAlgorithm.ES256)
|| alg.equals(JWSAlgorithm.ES384)
|| alg.equals(JWSAlgorithm.ES512)
|| alg.equals(JWSAlgorithm.PS256)
|| alg.equals(JWSAlgorithm.PS384)
|| alg.equals(JWSAlgorithm.PS512))) {
// it's a known public/private key algorithm
JWTSigningAndValidationService validator = validators.getValidator(client.getJwksUri());
if (validator == null) {

View File

@ -205,12 +205,18 @@ public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
if (alg.equals(JWSAlgorithm.RS256)
|| alg.equals(JWSAlgorithm.RS384)
|| alg.equals(JWSAlgorithm.RS512)) {
|| alg.equals(JWSAlgorithm.RS512)
|| alg.equals(JWSAlgorithm.ES256)
|| alg.equals(JWSAlgorithm.ES384)
|| alg.equals(JWSAlgorithm.ES512)
|| alg.equals(JWSAlgorithm.PS256)
|| alg.equals(JWSAlgorithm.PS384)
|| alg.equals(JWSAlgorithm.PS512)) {
// it's RSA, need to find the JWK URI and fetch the key
// it's a public key, need to find the JWK URI and fetch the key
if (client.getJwksUri() == null) {
throw new InvalidClientException("Client must have a JWKS URI registered to use signed request objects.");
throw new InvalidClientException("Client must have a JWKS registered to use signed request objects with a public key.");
}
// check JWT signature

View File

@ -74,15 +74,15 @@ public class IdTokenHashUtils {
//as the JWSAlgorithm to hash the token.
String hashAlg = null;
if (signingAlg.equals(JWSAlgorithm.HS256) || signingAlg.equals(JWSAlgorithm.ES256) || signingAlg.equals(JWSAlgorithm.RS256)) {
if (signingAlg.equals(JWSAlgorithm.HS256) || signingAlg.equals(JWSAlgorithm.ES256) || signingAlg.equals(JWSAlgorithm.RS256) || signingAlg.equals(JWSAlgorithm.PS256)) {
hashAlg = "SHA-256";
}
else if (signingAlg.equals(JWSAlgorithm.ES384) || signingAlg.equals(JWSAlgorithm.HS384) || signingAlg.equals(JWSAlgorithm.RS384)) {
else if (signingAlg.equals(JWSAlgorithm.ES384) || signingAlg.equals(JWSAlgorithm.HS384) || signingAlg.equals(JWSAlgorithm.RS384) || signingAlg.equals(JWSAlgorithm.PS384)) {
hashAlg = "SHA-384";
}
else if (signingAlg.equals(JWSAlgorithm.ES512) || signingAlg.equals(JWSAlgorithm.HS512) || signingAlg.equals(JWSAlgorithm.RS512)) {
else if (signingAlg.equals(JWSAlgorithm.ES512) || signingAlg.equals(JWSAlgorithm.HS512) || signingAlg.equals(JWSAlgorithm.RS512) || signingAlg.equals(JWSAlgorithm.PS512)) {
hashAlg = "SHA-512";
}