jwe service accessor methods and private initializing method done.

pull/650/head
William Kim 11 years ago committed by Justin Richer
parent fc146433f9
commit 59f13a66b6

@ -16,6 +16,11 @@
******************************************************************************/ ******************************************************************************/
package org.mitre.jwt.encryption.service; package org.mitre.jwt.encryption.service;
import java.util.Collection;
import java.util.Map;
import com.nimbusds.jose.JWEAlgorithm;
import com.nimbusds.jose.jwk.JWK;
import com.nimbusds.jwt.EncryptedJWT; import com.nimbusds.jwt.EncryptedJWT;
/** /**
@ -24,7 +29,26 @@ import com.nimbusds.jwt.EncryptedJWT;
*/ */
public interface JwtEncryptionAndDecryptionService { public interface JwtEncryptionAndDecryptionService {
/**
* Encrypts the JWT in place with the default encrypter.
* @param jwt
*/
public void encryptJwt(EncryptedJWT jwt); public void encryptJwt(EncryptedJWT jwt);
/**
* Decrypts the JWT in place with the default decrypter.
* @param jwt
*/
public void decryptJwt(EncryptedJWT jwt); public void decryptJwt(EncryptedJWT jwt);
/**
* Get all public keys for this service, mapped by their Key ID
*/
public Map<String, JWK> getAllPublicKeys();
/**
* Get the list of all encryption algorithms supported by this service.
* @return
*/
public Collection<JWEAlgorithm> getAllEncryptionAlgsSupported();
} }

@ -16,17 +16,30 @@
******************************************************************************/ ******************************************************************************/
package org.mitre.jwt.encryption.service.impl; package org.mitre.jwt.encryption.service.impl;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import javax.annotation.PostConstruct;
import org.mitre.jose.keystore.JWKSetKeyStore;
import org.mitre.jwt.encryption.service.JwtEncryptionAndDecryptionService; import org.mitre.jwt.encryption.service.JwtEncryptionAndDecryptionService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.google.common.base.Strings;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWEAlgorithm;
import com.nimbusds.jose.JWEDecrypter; import com.nimbusds.jose.JWEDecrypter;
import com.nimbusds.jose.JWEEncrypter; import com.nimbusds.jose.JWEEncrypter;
import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.crypto.RSADecrypter;
import com.nimbusds.jose.crypto.RSAEncrypter;
import com.nimbusds.jose.jwk.JWK; import com.nimbusds.jose.jwk.JWK;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jwt.EncryptedJWT; import com.nimbusds.jwt.EncryptedJWT;
/** /**
@ -37,21 +50,92 @@ public class DefaultJwtEncryptionAndDecryptionService implements JwtEncryptionAn
private static Logger logger = LoggerFactory.getLogger(DefaultJwtEncryptionAndDecryptionService.class); private static Logger logger = LoggerFactory.getLogger(DefaultJwtEncryptionAndDecryptionService.class);
// map of identifier to encrypter // map of identifier to encrypter
private Map<String, JWEEncrypter> encrypters = new HashMap<String, JWEEncrypter>(); private Map<String, JWEEncrypter> encrypters = new HashMap<String, JWEEncrypter>();
// map of identifier to decrypter // map of identifier to decrypter
private Map<String, JWEDecrypter> decrypters = new HashMap<String, JWEDecrypter>(); private Map<String, JWEDecrypter> decrypters = new HashMap<String, JWEDecrypter>();
private String defaultEncryptionKeyId; private String defaultEncryptionKeyId;
private JWSAlgorithm defaultAlgorithm; private String defaultDecryptionKeyId;
private JWEAlgorithm defaultAlgorithm;
// map of identifier to key // map of identifier to key
private Map<String, JWK> keys = new HashMap<String, JWK>(); private Map<String, JWK> keys = new HashMap<String, JWK>();
/**
* Build this service based on the keys given. All public keys will be used to make encrypters,
* all private keys will be used to make decrypters.
*
* @param keys
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws JOSEException
*/
public DefaultJwtEncryptionAndDecryptionService(Map<String, JWK> keys) throws NoSuchAlgorithmException, InvalidKeySpecException, JOSEException {
this.keys = keys;
buildEncryptersAndDecrypters();
}
/**
* Build this service based on the given keystore. All keys must have a key
* id ({@code kid}) field in order to be used.
*
* @param keyStore
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws JOSEException
*/
public DefaultJwtEncryptionAndDecryptionService(JWKSetKeyStore keyStore) throws NoSuchAlgorithmException, InvalidKeySpecException, JOSEException {
// convert all keys in the keystore to a map based on key id
for (JWK key : keyStore.getKeys()) {
if (!Strings.isNullOrEmpty(key.getKeyID())) {
this.keys.put(key.getKeyID(), key);
} else {
throw new IllegalArgumentException("Tried to load a key from a keystore without a 'kid' field: " + key);
}
}
buildEncryptersAndDecrypters();
}
@PostConstruct
public void afterPropertiesSet() throws NoSuchAlgorithmException, InvalidKeySpecException{
if (keys == null) {
throw new IllegalArgumentException("Encryption and decryption service must have at least one key configured.");
}
// TODO call build..() again? see default signer service.
}
public String getDefaultEncryptionKeyId() {
return defaultEncryptionKeyId;
}
public void setDefaultEncryptionKeyId(String defaultEncryptionKeyId) {
this.defaultEncryptionKeyId = defaultEncryptionKeyId;
}
public String getDefaultDecryptionKeyId() {
return defaultDecryptionKeyId;
}
public void setDefaultDecryptionKeyId(String defaultDecryptionKeyId) {
this.defaultDecryptionKeyId = defaultDecryptionKeyId;
}
public JWEAlgorithm getDefaultAlgorithm() {
return defaultAlgorithm;
}
public void setDefaultAlgorithm(JWEAlgorithm defaultAlgorithm) {
this.defaultAlgorithm = defaultAlgorithm;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.mitre.jwt.encryption.service.JwtEncryptionAndDecryptionService#encryptJwt(com.nimbusds.jwt.EncryptedJWT) * @see org.mitre.jwt.encryption.service.JwtEncryptionAndDecryptionService#encryptJwt(com.nimbusds.jwt.EncryptedJWT)
*/ */
@ -70,4 +154,71 @@ public class DefaultJwtEncryptionAndDecryptionService implements JwtEncryptionAn
} }
/**
* Builds all the encrypters and decrypters for this service based on the key map.
* @throws
* @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException
* @throws JOSEException
*/
private void buildEncryptersAndDecrypters() throws NoSuchAlgorithmException, InvalidKeySpecException, JOSEException {
for (Map.Entry<String, JWK> jwkEntry : keys.entrySet()) {
String id = jwkEntry.getKey();
JWK jwk = jwkEntry.getValue();
if (jwk instanceof RSAKey) {
// build RSA encrypters and decrypters
RSAEncrypter encrypter = new RSAEncrypter(((RSAKey) jwk).toRSAPublicKey()); // there should always at least be the public key
encrypters.put(id, encrypter);
if (jwk.isPrivate()) { // we can decrypt!
RSADecrypter decrypter = new RSADecrypter(((RSAKey) jwk).toRSAPrivateKey());
decrypters.put(id, decrypter);
} else {
logger.warn("No private key for key #" + jwk.getKeyID());
}
// TODO: add support for EC keys
} else {
logger.warn("Unknown key type: " + jwk);
}
}
}
@Override
public Map<String, JWK> getAllPublicKeys() {
Map<String, JWK> pubKeys = new HashMap<String, JWK>();
// pull out all public keys
for (String keyId : keys.keySet()) {
JWK key = keys.get(keyId);
JWK pub = key.toPublicJWK();
if (pub != null) {
pubKeys.put(keyId, pub);
}
}
return pubKeys;
}
@Override
public Collection<JWEAlgorithm> getAllEncryptionAlgsSupported() {
Set<JWEAlgorithm> algs = new HashSet<JWEAlgorithm>();
for (JWEEncrypter enc : encrypters.values()) {
algs.addAll(enc.supportedAlgorithms());
}
for (JWEDecrypter dec : decrypters.values()) {
algs.addAll(dec.supportedAlgorithms());
}
return algs;
}
} }

Loading…
Cancel
Save