/*
* oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.
*
* Copyright (c) 2014, Gluu
*/
package org.xdi.oxauth.model.jws;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.xdi.oxauth.model.crypto.signature.SignatureAlgorithm;
import org.xdi.oxauth.model.exception.InvalidJwtException;
import org.xdi.oxauth.model.jwt.Jwt;
import org.xdi.oxauth.model.jwt.JwtClaimName;
import org.xdi.oxauth.model.util.Base64Util;
import org.xdi.oxauth.model.util.JwtUtil;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SignatureException;
/**
* @author Javier Rojas Blum
* @version July 31, 2016
*/
public abstract class AbstractJwsSigner implements JwsSigner {
private static final Logger LOG = Logger.getLogger(AbstractJwsSigner.class);
private SignatureAlgorithm signatureAlgorithm;
public AbstractJwsSigner(SignatureAlgorithm signatureAlgorithm) {
this.signatureAlgorithm = signatureAlgorithm;
}
@Override
public SignatureAlgorithm getSignatureAlgorithm() {
return signatureAlgorithm;
}
@Override
public Jwt sign(Jwt jwt) throws InvalidJwtException, SignatureException {
String signature = generateSignature(jwt.getSigningInput());
jwt.setEncodedSignature(signature);
return jwt;
}
@Override
public boolean validate(Jwt jwt) {
try {
String signingInput = jwt.getSigningInput();
String signature = jwt.getEncodedSignature();
return validateSignature(signingInput, signature);
} catch (InvalidJwtException e) {
LOG.error(e.getMessage(), e);
return false;
} catch (SignatureException e) {
LOG.error(e.getMessage(), e);
return false;
} catch (Exception e) {
LOG.error(e.getMessage(), e);
return false;
}
}
public boolean validateAuthorizationCode(String authorizationCode, Jwt idToken) {
return validateHash(authorizationCode, idToken.getClaims().getClaimAsString(JwtClaimName.CODE_HASH));
}
public boolean validateAccessToken(String accessToken, Jwt idToken) {
return validateHash(accessToken, idToken.getClaims().getClaimAsString(JwtClaimName.ACCESS_TOKEN_HASH));
}
private boolean validateHash(String tokenCode, String tokenHash) {
boolean result = false;
try {
if (signatureAlgorithm != null
&& StringUtils.isNotBlank(tokenCode)
&& StringUtils.isNotBlank(tokenHash)) {
byte[] digest = null;
if (signatureAlgorithm == SignatureAlgorithm.HS256 ||
signatureAlgorithm == SignatureAlgorithm.RS256 ||
signatureAlgorithm == SignatureAlgorithm.ES256) {
digest = JwtUtil.getMessageDigestSHA256(tokenCode);
} else if (signatureAlgorithm == SignatureAlgorithm.HS384 ||
signatureAlgorithm == SignatureAlgorithm.RS384 ||
signatureAlgorithm == SignatureAlgorithm.ES512) {
digest = JwtUtil.getMessageDigestSHA384(tokenCode);
} else if (signatureAlgorithm == SignatureAlgorithm.HS512 ||
signatureAlgorithm == SignatureAlgorithm.RS384 ||
signatureAlgorithm == SignatureAlgorithm.ES512) {
digest = JwtUtil.getMessageDigestSHA512(tokenCode);
}
if (digest != null) {
byte[] lefMostHalf = new byte[digest.length / 2];
System.arraycopy(digest, 0, lefMostHalf, 0, lefMostHalf.length);
String hash = Base64Util.base64urlencode(lefMostHalf);
result = hash.equals(tokenHash);
}
}
} catch (NoSuchProviderException e) {
LOG.error(e.getMessage(), e);
result = false;
} catch (NoSuchAlgorithmException e) {
LOG.error(e.getMessage(), e);
result = false;
} catch (Exception e) {
LOG.error(e.getMessage(), e);
result = false;
}
return result;
}
public abstract String generateSignature(String signingInput) throws SignatureException;
public abstract boolean validateSignature(String signingInput, String signature) throws SignatureException;
}