package org.pac4j.jwt.config.signature;
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.ECDSASigner;
import com.nimbusds.jose.crypto.ECDSAVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import org.pac4j.core.exception.TechnicalException;
import org.pac4j.core.util.CommonHelper;
import java.security.KeyPair;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
/**
* Elliptic curve signature configuration: http://connect2id.com/products/nimbus-jose-jwt/examples/jwt-with-ec-signature
*
* @author Jerome Leleu
* @since 1.9.2
*/
public class ECSignatureConfiguration extends AbstractSignatureConfiguration {
private ECPublicKey publicKey;
private ECPrivateKey privateKey;
public ECSignatureConfiguration() {
algorithm = JWSAlgorithm.ES256;
}
public ECSignatureConfiguration(final KeyPair keyPair) {
this();
setKeyPair(keyPair);
}
public ECSignatureConfiguration(final KeyPair keyPair, final JWSAlgorithm algorithm) {
setKeyPair(keyPair);
this.algorithm = algorithm;
}
@Override
protected void internalInit() {
CommonHelper.assertNotNull("algorithm", algorithm);
if (!supports(this.algorithm)) {
throw new TechnicalException("Only the ES256, ES384 and ES512 algorithms are supported for elliptic curve signature");
}
}
@Override
public boolean supports(final JWSAlgorithm algorithm) {
return algorithm != null && ECDSAVerifier.SUPPORTED_ALGORITHMS.contains(algorithm);
}
@Override
public SignedJWT sign(JWTClaimsSet claims) {
init();
CommonHelper.assertNotNull("privateKey", privateKey);
try {
final JWSSigner signer = new ECDSASigner(this.privateKey);
final SignedJWT signedJWT = new SignedJWT(new JWSHeader(algorithm), claims);
signedJWT.sign(signer);
return signedJWT;
} catch (final JOSEException e) {
throw new TechnicalException(e);
}
}
@Override
public boolean verify(final SignedJWT jwt) throws JOSEException {
init();
CommonHelper.assertNotNull("publicKey", publicKey);
final JWSVerifier verifier = new ECDSAVerifier(this.publicKey);
return jwt.verify(verifier);
}
public void setKeyPair(final KeyPair keyPair) {
CommonHelper.assertNotNull("keyPair", keyPair);
this.privateKey = (ECPrivateKey) keyPair.getPrivate();
this.publicKey = (ECPublicKey) keyPair.getPublic();
}
public ECPublicKey getPublicKey() {
return publicKey;
}
public void setPublicKey(final ECPublicKey publicKey) {
this.publicKey = publicKey;
}
public ECPrivateKey getPrivateKey() {
return privateKey;
}
public void setPrivateKey(final ECPrivateKey privateKey) {
this.privateKey = privateKey;
}
@Override
public String toString() {
return CommonHelper.toString(this.getClass(), "keys", "[protected]", "algorithm", algorithm);
}
}