JWSUtils uses JWSAlgorithm to match bit length; ConnectTokenEnhancer calls the util method now

pull/477/head
Amanda Anganes 12 years ago
parent 3a591dc1f4
commit 37580cc21e

@ -16,17 +16,10 @@
******************************************************************************/ ******************************************************************************/
package org.mitre.openid.connect.token; package org.mitre.openid.connect.token;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.mitre.jwt.signer.service.JwtSigningAndValidationService; import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
@ -35,6 +28,7 @@ import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
import org.mitre.oauth2.service.ClientDetailsEntityService; import org.mitre.oauth2.service.ClientDetailsEntityService;
import org.mitre.openid.connect.config.ConfigurationPropertiesBean; import org.mitre.openid.connect.config.ConfigurationPropertiesBean;
import org.mitre.openid.connect.service.ApprovedSiteService; import org.mitre.openid.connect.service.ApprovedSiteService;
import org.mitre.openid.connect.util.JWSUtils;
import org.mitre.openid.connect.web.AuthenticationTimeStamper; import org.mitre.openid.connect.web.AuthenticationTimeStamper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -42,7 +36,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.util.OAuth2Utils; import org.springframework.security.oauth2.common.util.OAuth2Utils;
import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.token.TokenEnhancer; import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
@ -163,39 +156,11 @@ public class ConnectTokenEnhancer implements TokenEnhancer {
Set<String> responseTypes = OAuth2Utils.parseParameterList(responseType); Set<String> responseTypes = OAuth2Utils.parseParameterList(responseType);
if (responseTypes.contains("token")) { if (responseTypes.contains("token")) {
// calculate the token hash // calculate the token hash
Base64URL at_hash = JWSUtils.getAccessTokenHash(signingAlg, token.getJwt().serialize().getBytes());
// get the right algorithm size //TODO: What should happen if the hash cannot be calculated?
// TODO: all this string parsing feels like a bad hack idClaims.setClaim("at_hash", at_hash);
String algName = signingAlg.getName();
Pattern re = Pattern.compile("^[HRE]S(\\d+)$");
Matcher match = re.matcher(algName);
if (match.matches()) {
String bits = match.group(1);
String hmacAlg = "HMACSHA" + bits;
try {
Mac mac = Mac.getInstance(hmacAlg);
mac.init(new SecretKeySpec(token.getJwt().serialize().getBytes(), hmacAlg));
byte[] at_hash_bytes = mac.doFinal();
byte[] at_hash_bytes_left = Arrays.copyOf(at_hash_bytes, at_hash_bytes.length / 2);
Base64URL at_hash = Base64URL.encode(at_hash_bytes_left);
idClaims.setClaim("at_hash", at_hash);
} catch (NoSuchAlgorithmException e) {
logger.error("No such algorithm error: ", e);
} catch (InvalidKeyException e) {
logger.error("Invalid key error: ", e);
}
}
} }
SignedJWT idToken = new SignedJWT(new JWSHeader(signingAlg), idClaims); SignedJWT idToken = new SignedJWT(new JWSHeader(signingAlg), idClaims);
//TODO: check for client's preferred signer alg and use that //TODO: check for client's preferred signer alg and use that

@ -3,8 +3,6 @@ package org.mitre.openid.connect.util;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Arrays; import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.crypto.Mac; import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
@ -27,22 +25,28 @@ public class JWSUtils {
public static Base64URL getAccessTokenHash(JWSAlgorithm signingAlg, byte[] tokenBytes) { public static Base64URL getAccessTokenHash(JWSAlgorithm signingAlg, byte[] tokenBytes) {
//Switch based on the given signing algorithm //Switch based on the given signing algorithm - use HMAC with the same bitnumber
//as the JWSAlgorithm to hash the token.
String algName = signingAlg.getName(); String hashAlg = null;
if (algName.equals(JWSAlgorithm.HS256)) { if (signingAlg.equals(JWSAlgorithm.HS256) || signingAlg.equals(JWSAlgorithm.ES256) || signingAlg.equals(JWSAlgorithm.RS256)) {
hashAlg = "HMACSHA256";
} }
Pattern re = Pattern.compile("^[HRE]S(\\d+)$"); else if (signingAlg.equals(JWSAlgorithm.ES384) || signingAlg.equals(JWSAlgorithm.HS384) || signingAlg.equals(JWSAlgorithm.RS384)) {
Matcher match = re.matcher(algName); hashAlg = "HMACSHA384";
if (match.matches()) { }
String bits = match.group(1);
String hmacAlg = "HMACSHA" + bits; else if (signingAlg.equals(JWSAlgorithm.ES512) || signingAlg.equals(JWSAlgorithm.HS512) || signingAlg.equals(JWSAlgorithm.RS512)) {
hashAlg = "HMACSHA512";
}
if (hashAlg != null) {
try { try {
Mac mac = Mac.getInstance(hmacAlg); Mac mac = Mac.getInstance(hashAlg);
mac.init(new SecretKeySpec(tokenBytes, hmacAlg)); mac.init(new SecretKeySpec(tokenBytes, hashAlg));
byte[] at_hash_bytes = mac.doFinal(); byte[] at_hash_bytes = mac.doFinal();
byte[] at_hash_bytes_left = Arrays.copyOf(at_hash_bytes, at_hash_bytes.length / 2); byte[] at_hash_bytes_left = Arrays.copyOf(at_hash_bytes, at_hash_bytes.length / 2);

Loading…
Cancel
Save