diff --git a/openid-connect-common/src/main/java/org/mitre/jwe/model/Jwe.java b/openid-connect-common/src/main/java/org/mitre/jwe/model/Jwe.java deleted file mode 100644 index ec1ef6890..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwe/model/Jwe.java +++ /dev/null @@ -1,120 +0,0 @@ -package org.mitre.jwe.model; - -import java.util.List; - -import org.apache.commons.codec.binary.Base64; -import org.mitre.jwt.model.Jwt; -import org.mitre.jwt.model.JwtHeader; - -import com.google.common.base.Splitter; -import com.google.common.collect.Lists; -import com.google.gson.JsonObject; - -/** - * - * - * Return the canonical encoded string of this JWE, the header in Base64, a period ".", the encrypted key in Base64, a period ".", - * the ciphertext in Base64, a period ".", and the signature, or integrity value, in Base64. - - * @author DERRYBERRY - * - */ -public class Jwe extends Jwt { - - private byte[] encryptedKey; - - private byte[] ciphertext; - - public Jwe() { - super(); - this.encryptedKey = null; - this.ciphertext = null; - } - - public Jwe(JweHeader header, byte[] encryptedKey, byte[] ciphertext, String integrityValue) { - super(header, null, integrityValue); - this.encryptedKey = encryptedKey; - this.ciphertext = ciphertext; - } - - /* - public Jwe(String headerBase64, String encryptedKeyBase64, String cipherTextBase64, String integrityValueBase64) { - byte[] decodedEncryptedKey = Base64.decodeBase64(encryptedKeyBase64.getBytes()); - byte[] decodedCipherText = Base64.decodeBase64(cipherTextBase64.getBytes()); - this.header = new JweHeader(headerBase64); - this.encryptedKey = decodedEncryptedKey; - this.ciphertext = decodedCipherText; - setSignature(integrityValueBase64); - } - */ - - public JweHeader getHeader() { - return (JweHeader) super.getHeader(); - } - - /** - * Set the header, wrapping it in a JweHeader if necessary - */ - public void setHeader(JwtHeader header) { - if (header instanceof JweHeader) { - super.setHeader(header); - } else { - super.setHeader(new JweHeader(header)); - } - } - - public byte[] getEncryptedKey() { - return encryptedKey; - } - - public void setEncryptedKey(byte[] encryptedKey) { - this.encryptedKey = encryptedKey; - } - - public byte[] getCiphertext() { - return ciphertext; - } - - public void setCiphertext(byte[] ciphertext) { - this.ciphertext = ciphertext; - } - - @Override - public String getSignatureBase() { - String h64 = new String(Base64.encodeBase64URLSafe(getHeader().toJsonString().getBytes())); - String e64 = new String(Base64.encodeBase64URLSafe(getEncryptedKey())); - String c64 = new String(Base64.encodeBase64URLSafe(getCiphertext())); - - return h64 + "." + e64 + "." + c64; - } - - - public static Jwe parse(String s) { - - // null string is a null token - if (s == null) { - return null; - } - - // split on the dots - List parts = Lists.newArrayList(Splitter.on(".").split(s)); - - if (parts.size() != 4) { - throw new IllegalArgumentException("Invalid JWE format."); - } - - String h64 = parts.get(0); - String e64 = parts.get(1); - String c64 = parts.get(2); - String i64 = parts.get(3); - - byte[] decodedEncryptedKey = Base64.decodeBase64(e64.getBytes()); - byte[] decodedCipherText = Base64.decodeBase64(c64.getBytes()); - - Jwe jwe = new Jwe(new JweHeader(h64), decodedEncryptedKey, decodedCipherText, i64); - - return jwe; - - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwe/model/JweHeader.java b/openid-connect-common/src/main/java/org/mitre/jwe/model/JweHeader.java deleted file mode 100644 index 94240c12d..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwe/model/JweHeader.java +++ /dev/null @@ -1,165 +0,0 @@ -package org.mitre.jwe.model; - -import java.util.Map.Entry; - -import org.mitre.jwt.model.JwtHeader; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -public class JweHeader extends JwtHeader{ - - public static final String INTEGRITY = "int"; - public static final String INITIALIZATION_VECTOR = "iv"; - public static final String EPHEMERAL_PUBLIC_KEY = "epk"; - public static final String COMPRESSION_ALGORITHM = "zip"; - public static final String JSON_SET_URL = "jku"; - public static final String JSON_WEB_KEY = "jwk"; - public static final String X509_URL = "x5u"; - public static final String X509_CERTIFICATE_THUMBPRINT = "x5t"; - public static final String X509_CERTIFICATE_CHAIN = "x5c"; - public static final String KEY_ID = "kid"; - public static final String KEY_DERIVATION_FUNCTION = "kdf"; - - public JweHeader(){ - super(); - } - - public JweHeader(JsonObject object){ - super(object); - } - - public JweHeader(String b64) { - super(b64); - } - - public JweHeader(JwtHeader jwtHeader) { - super(jwtHeader); - } - - /** - * Load all claims from the given json object into this object - */ - @Override - public void loadFromJsonObject(JsonObject json) { - - JsonObject pass = new JsonObject(); - - for (Entry element : json.entrySet()) { - if (element.getValue().isJsonNull()) { - pass.add(element.getKey(), element.getValue()); - } else if (element.getKey().equals(INTEGRITY)) { - this.setIntegrity(json.get(INTEGRITY).getAsString()); - } else if (element.getKey().equals(INITIALIZATION_VECTOR)) { - this.setIv(json.get(INITIALIZATION_VECTOR).getAsString()); - } else if (element.getKey().equals(EPHEMERAL_PUBLIC_KEY)) { - this.setEphemeralPublicKey(json.get(EPHEMERAL_PUBLIC_KEY).getAsString()); - } else if (element.getKey().equals(COMPRESSION_ALGORITHM)) { - this.setCompressionAlgorithm(json.get(COMPRESSION_ALGORITHM).getAsString()); - } else if (element.getKey().equals(JSON_SET_URL)) { - this.setJku(json.get(JSON_SET_URL).getAsString()); - } else if (element.getKey().equals(JSON_WEB_KEY)) { - this.setJsonWebKey(json.get(JSON_WEB_KEY).getAsString()); - } else if (element.getKey().equals(X509_URL)) { - this.setX509Url(json.get(X509_URL).getAsString()); - } else if (element.getKey().equals(X509_CERTIFICATE_THUMBPRINT)) { - this.setX509CertThumbprint(json.get(X509_CERTIFICATE_THUMBPRINT).getAsString()); - } else if (element.getKey().equals(X509_CERTIFICATE_CHAIN)) { - this.setX509CertChain(json.get(X509_CERTIFICATE_CHAIN).getAsString()); - } else if (element.getKey().equals(KEY_ID)) { - this.setKeyId(json.get(KEY_ID).getAsString()); - } else { - pass.add(element.getKey(), element.getValue()); - } - } - super.loadFromJsonObject(pass); - } - - public String getIntegrity() { - return getClaimAsString(INTEGRITY); - } - - public String getInitializationVector() { - return getClaimAsString(INITIALIZATION_VECTOR); - } - - public String getEphemeralPublicKey() { - return getClaimAsString(EPHEMERAL_PUBLIC_KEY); - } - - public String getCompressionAlgorithm() { - return getClaimAsString(COMPRESSION_ALGORITHM); - } - - public String getJsonSetUrl() { - return getClaimAsString(JSON_SET_URL); - } - - public String getJsonWebKey() { - return getClaimAsString(JSON_WEB_KEY); - } - - public String getX509Url() { - return getClaimAsString(X509_URL); - } - - public String getX509CertificateThumbprint() { - return getClaimAsString(X509_CERTIFICATE_THUMBPRINT); - } - - public String getX509CertificateChain() { - return getClaimAsString(X509_CERTIFICATE_CHAIN); - } - - public String getKeyId() { - return getClaimAsString(KEY_ID); - } - - public String getKeyDerivationFunction() { - return getClaimAsString(KEY_DERIVATION_FUNCTION); - } - - public void setIv(String iv) { - setClaim(INITIALIZATION_VECTOR, iv); - } - - public void setJku(String jku) { - setClaim(JSON_SET_URL, jku); - } - - public void setIntegrity(String integrity) { - setClaim(INTEGRITY, integrity); - } - - public void setEphemeralPublicKey(String epk) { - setClaim(EPHEMERAL_PUBLIC_KEY, epk); - } - - public void setCompressionAlgorithm(String zip) { - setClaim(COMPRESSION_ALGORITHM, zip); - } - - public void setJsonWebKey(String jwk) { - setClaim(JSON_WEB_KEY, jwk); - } - - public void setX509Url(String x5u) { - setClaim(X509_URL, x5u); - } - - public void setX509CertThumbprint(String x5t) { - setClaim(X509_CERTIFICATE_THUMBPRINT, x5t); - } - - public void setX509CertChain(String x5c) { - setClaim(X509_CERTIFICATE_CHAIN, x5c); - } - - public void setKeyId(String kid) { - setClaim(KEY_ID, kid); - } - - public void setKeyDerivationFunction(String kdf) { - setClaim(KEY_DERIVATION_FUNCTION, kdf); - } -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwk/model/AbstractJwk.java b/openid-connect-common/src/main/java/org/mitre/jwk/model/AbstractJwk.java deleted file mode 100644 index 851b6a08e..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwk/model/AbstractJwk.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.mitre.jwk.model; - -import com.google.gson.JsonObject; - -public abstract class AbstractJwk implements Jwk{ - - public static final String ALGORITHM = "alg"; - public static final String USE = "use"; - public static final String KEY_ID = "kid"; - - private String kid; - private String alg; - private String use; - - public AbstractJwk(JsonObject object){ - init(object); - } - - /* (non-Javadoc) - * @see org.mitre.jwk.model.Jwk2#getAlg() - */ - @Override - public String getAlg() { - return alg; - } - - public void setAlg(String alg) { - this.alg = alg; - } - - /* (non-Javadoc) - * @see org.mitre.jwk.model.Jwk2#getKid() - */ - @Override - public String getKid() { - return kid; - } - - public void setKid(String kid) { - this.kid = kid; - } - - /* (non-Javadoc) - * @see org.mitre.jwk.model.Jwk2#getUse() - */ - @Override - public String getUse() { - return use; - } - - public void setUse(String use) { - this.use = use; - } - - public JsonObject toJsonObject() { - JsonObject export = new JsonObject(); - export.addProperty(ALGORITHM, getAlg()); - export.addProperty(USE, getUse()); - export.addProperty(KEY_ID, getKid()); - return export; - } - - protected void init(JsonObject object){ - if(object.get(ALGORITHM) != null){ - setAlg(object.get(ALGORITHM).getAsString()); - } - if(object.get(KEY_ID) != null){ - setKid(object.get(KEY_ID).getAsString()); - } - if(object.get(USE) != null){ - setUse(object.get(USE).getAsString()); - } - } -} \ No newline at end of file diff --git a/openid-connect-common/src/main/java/org/mitre/jwk/model/EllipticCurveJwk.java b/openid-connect-common/src/main/java/org/mitre/jwk/model/EllipticCurveJwk.java deleted file mode 100644 index 950e2a916..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwk/model/EllipticCurveJwk.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.mitre.jwk.model; - -import java.math.BigInteger; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.PublicKey; -import java.security.spec.ECFieldF2m; -import java.security.spec.EllipticCurve; -import java.security.spec.InvalidKeySpecException; - -import org.apache.commons.codec.binary.Base64; -import org.bouncycastle.jce.ECNamedCurveTable; -import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; -import org.bouncycastle.math.ec.ECCurve; - -import com.google.gson.JsonObject; - -public class EllipticCurveJwk extends AbstractJwk { - - public static final String CURVE = "crv"; - public static final String X = "x"; - public static final String Y = "y"; - - private String crv; - private String x; - private String y; - - JsonObject object = new JsonObject(); - - public String getCrv() { - return crv; - } - - public void setCrv(String crv) { - this.crv = crv; - } - - public String getX() { - return x; - } - - public void setX(String x) { - this.x = x; - } - - public String getY() { - return y; - } - - public void setY(String y) { - this.y = y; - } - - public EllipticCurveJwk(JsonObject object) { - super(object); - } - - - - @Override - public JsonObject toJsonObject() { - JsonObject obj = super.toJsonObject(); - obj.addProperty(CURVE, getCrv()); - obj.addProperty(X, getX()); - obj.addProperty(Y, getY()); - return obj; - } - - public void init(JsonObject object){ - super.init(object); - setCrv(object.get(CURVE).getAsString()); - setX(object.get(X).getAsString()); - setY(object.get(Y).getAsString()); - } - - @Override - public PublicKey getKey() throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException { - // TODO Auto-generated method stub - - byte[] x_byte = Base64.decodeBase64(x); - BigInteger x_int = new BigInteger(x_byte); - byte[] y_byte = Base64.decodeBase64(y); - BigInteger y_int = new BigInteger(y_byte); - - ECNamedCurveParameterSpec curveSpec = ECNamedCurveTable.getParameterSpec(crv); - BigInteger orderOfGen = curveSpec.getH(); - int cofactor = Math.abs(curveSpec.getN().intValue()); - ECCurve crv = curveSpec.getCurve(); - BigInteger a = crv.getA().toBigInteger(); - BigInteger b = crv.getB().toBigInteger(); - int fieldSize = crv.getFieldSize(); - ECFieldF2m field = new ECFieldF2m(fieldSize); - EllipticCurve curve = new EllipticCurve(field, a, b); - //ECPoint.Fp point = new ECPoint.Fp(curve, arg1, arg2); - return null; - - //ECParameterSpec paramSpec = new ECParameterSpec(curve, point, orderOfGen, cofactor); - //ECPublicKeySpec spec = new ECPublicKeySpec(point, paramSpec); - //PublicKey key = new JCEECPublicKey("ECDCA", spec); - - //return key; - } -} \ No newline at end of file diff --git a/openid-connect-common/src/main/java/org/mitre/jwk/model/Jwk.java b/openid-connect-common/src/main/java/org/mitre/jwk/model/Jwk.java deleted file mode 100644 index 67edc2b15..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwk/model/Jwk.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.mitre.jwk.model; - -import java.security.Key; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.spec.InvalidKeySpecException; - -public interface Jwk { - - public abstract String getAlg(); - - public abstract String getKid(); - - public abstract String getUse(); - - public abstract Key getKey() throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException; - -} \ No newline at end of file diff --git a/openid-connect-common/src/main/java/org/mitre/jwk/model/Rsa.java b/openid-connect-common/src/main/java/org/mitre/jwk/model/Rsa.java deleted file mode 100644 index 9318d0a9f..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwk/model/Rsa.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.mitre.jwk.model; - -import java.math.BigInteger; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.RSAPublicKeySpec; - -import org.apache.commons.codec.binary.Base64; - -import com.google.gson.JsonObject; - -public class Rsa extends AbstractJwk{ - - public static final String MODULUS = "mod"; - public static final String EXPONENT = "exp"; - - private String mod; - private String exp; - - public String getMod() { - return mod; - } - - public void setMod(String mod) { - this.mod = mod; - } - - public String getExp() { - return exp; - } - - public void setExp(String exp) { - this.exp = exp; - } - - public Rsa(JsonObject object){ - super(object); - } - - public void init(JsonObject object){ - super.init(object); - setMod(object.get(MODULUS).getAsString()); - setExp(object.get(EXPONENT).getAsString()); - } - - - - @Override - public JsonObject toJsonObject() { - JsonObject export = super.toJsonObject(); - export.addProperty(MODULUS, getMod()); - export.addProperty(EXPONENT, getExp()); - return export; - - } - - @Override - public PublicKey getKey() throws NoSuchAlgorithmException, InvalidKeySpecException { - byte[] modulusByte = Base64.decodeBase64(mod); - BigInteger modulus = new BigInteger(modulusByte); - byte[] exponentByte = Base64.decodeBase64(exp); - BigInteger exponent = new BigInteger(exponentByte); - - RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, exponent); - KeyFactory factory = KeyFactory.getInstance("RSA"); - PublicKey pub = factory.generatePublic(spec); - - return pub; - } -} \ No newline at end of file diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweDecrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweDecrypter.java deleted file mode 100644 index 1136f6c9e..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweDecrypter.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.mitre.jwt.encryption; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -import com.google.common.primitives.Ints; - -public abstract class AbstractJweDecrypter implements JweDecrypter { - - long MAX_HASH_INPUTLEN = Long.MAX_VALUE; - long UNSIGNED_INT_MAX_VALUE = 4294967395L; - - public byte[] generateContentKey(byte[] cmk, int keyDataLen, byte[] type) throws NoSuchAlgorithmException { - - MessageDigest md = null; - //HUGE DISCLAIMER: this won't work on windows machines that don't have jce unlimited security files installed. - //without it, keys can't be over 128 bit in length, and SHA-128 doesn't work for message digest. - - //use keyDataLen to determine instance - md = MessageDigest.getInstance("SHA-" + Integer.toString(keyDataLen)); - - keyDataLen = keyDataLen / 8; - byte[] key = new byte[keyDataLen]; - int hashLen = md.getDigestLength(); - int reps = keyDataLen / hashLen; - if (reps > UNSIGNED_INT_MAX_VALUE) { - throw new IllegalArgumentException("Key derivation failed"); - } - int counter = 1; - byte[] counterInBytes = Ints.toByteArray(counter); - if ((counterInBytes.length + cmk.length + type.length) * 8 > MAX_HASH_INPUTLEN) { - throw new IllegalArgumentException("Key derivation failed"); - } - for (int i = 0; i <= reps; i++) { - md.reset(); - md.update(Ints.toByteArray(i + 1)); - md.update(cmk); - md.update(type); - byte[] hash = md.digest(); - if (i < reps) { - System.arraycopy(hash, 0, key, hashLen * i, hashLen); - } else { - System.arraycopy(hash, 0, key, hashLen * i, keyDataLen % hashLen); - } - } - return key; - - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweEncrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweEncrypter.java deleted file mode 100644 index 40156bd9b..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/AbstractJweEncrypter.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.mitre.jwt.encryption; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -import com.google.common.primitives.Ints; - -public abstract class AbstractJweEncrypter implements JweEncrypter { - - public MessageDigest md; - - public byte[] generateContentKey(byte[] cmk, int keyDataLen, byte[] type) throws NoSuchAlgorithmException { - //HUGE DISCLAIMER: this won't work on windows machines that don't have jce unlimited security files installed. - //without it, keys can't be over 128 bit in length, and SHA-128 doesn't work for message digest. - - //Use keyDataLen to determine instance - md = MessageDigest.getInstance("SHA-" + Integer.toString(keyDataLen)); - - long MAX_HASH_INPUTLEN = Long.MAX_VALUE; - long UNSIGNED_INT_MAX_VALUE = 4294967395L; - - keyDataLen = keyDataLen / 8; - byte[] key = new byte[keyDataLen]; - int hashLen = md.getDigestLength(); - int reps = keyDataLen / hashLen; - if (reps > UNSIGNED_INT_MAX_VALUE) { - throw new IllegalArgumentException("Key derivation failed"); - } - int counter = 1; - byte[] counterInBytes = Ints.toByteArray(counter); - if ((counterInBytes.length + cmk.length + type.length) * 8 > MAX_HASH_INPUTLEN) { - throw new IllegalArgumentException("Key derivation failed"); - } - for (int i = 0; i <= reps; i++) { - md.reset(); - md.update(Ints.toByteArray(i + 1)); - md.update(cmk); - md.update(type); - byte[] hash = md.digest(); - if (i < reps) { - System.arraycopy(hash, 0, key, hashLen * i, hashLen); - } else { - System.arraycopy(hash, 0, key, hashLen * i, keyDataLen % hashLen); - } - } - return key; - - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/JweAlgorithms.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/JweAlgorithms.java deleted file mode 100644 index 12135a1b4..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/JweAlgorithms.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.mitre.jwt.encryption; - -import org.apache.commons.lang.StringUtils; - -public enum JweAlgorithms { - - //Key Derivation Function Values - CS256("256"), - CS384("384"), - CS512("512"), - //Encryption Method Values - A128GCM("GCM"), - A256GCM("GCM"), - A128CBC("CBC"), - A256CBC("CBC"); - - - - private final String value; - - JweAlgorithms(String value) { - this.value = value; - } - - public static String getByName(String name) { - for (JweAlgorithms correspondingType : JweAlgorithms.values()) { - if (correspondingType.toString().equals(name)) { - return correspondingType.value; - } - } - throw new IllegalArgumentException( - "JweAlgorithm name " + name + " does not have a corresponding JweAlgorithm: expected one of [" + StringUtils.join(JweAlgorithms.values(), ", ") + "]"); - } - - public String getValue() { - return value; - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/JweDecrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/JweDecrypter.java deleted file mode 100644 index 807791922..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/JweDecrypter.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.mitre.jwt.encryption; - -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; - -import javax.crypto.BadPaddingException; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; - -import org.mitre.jwe.model.Jwe; - -public interface JweDecrypter { - - public Jwe decrypt(String encryptedJwe) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException; - - public byte[] decryptCipherText(Jwe jwe, byte[] cek) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException; - - public byte[] decryptEncryptionKey(Jwe jwe) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException; - - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/JweEncrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/JweEncrypter.java deleted file mode 100644 index 52c71ce03..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/JweEncrypter.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.mitre.jwt.encryption; - -import java.io.IOException; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.spec.InvalidKeySpecException; - -import javax.crypto.BadPaddingException; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; - -import org.mitre.jwe.model.Jwe; - -import com.google.gson.JsonIOException; -import com.google.gson.JsonSyntaxException; - - -public interface JweEncrypter { - - public byte[] encryptKey(Jwe jwe, byte[] cmk) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException; - - public byte[] encryptClaims(Jwe jwe, byte[] cik) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException; - - public Jwe encryptAndSign(Jwe jwe) throws NoSuchAlgorithmException, JsonIOException, JsonSyntaxException, IOException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException; - - public byte[] generateContentKey(byte[] cmk, int keyDataLen, byte[] type) throws NoSuchAlgorithmException; - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaDecrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaDecrypter.java deleted file mode 100644 index 9754a77dc..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaDecrypter.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.mitre.jwt.encryption.impl; - -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.commons.codec.binary.Base64; -import org.mitre.jwe.model.Jwe; -import org.mitre.jwt.encryption.AbstractJweDecrypter; -import org.mitre.jwt.encryption.JweAlgorithms; - - -public class RsaDecrypter extends AbstractJweDecrypter { - - private PublicKey publicKey; - private PrivateKey privateKey; - - @Override - public Jwe decrypt(String encryptedJwe) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException { - - Jwe jwe = Jwe.parse(encryptedJwe); - - String alg = jwe.getHeader().getAlgorithm(); - if(alg.equals("RSA1_5") || alg.equals("RSA-OAEP")) { - - //decrypt to get cmk to be used for cek and cik - jwe.setEncryptedKey(decryptEncryptionKey(jwe)); - - //generation of cek and cik - byte[] contentEncryptionKey = null; - //check what the key length is - String kdf = jwe.getHeader().getKeyDerivationFunction(); - String keyLength = JweAlgorithms.getByName(kdf); - int keyBitLength = Integer.parseInt(keyLength); - //generate cek and cik - contentEncryptionKey = generateContentKey(jwe.getEncryptedKey(), keyBitLength, "Encryption".getBytes()); - - //decrypt ciphertext to get claims - jwe.setCiphertext(decryptCipherText(jwe, contentEncryptionKey)); - - } else { - throw new IllegalArgumentException(jwe.getHeader().getEncryptionMethod() + " is not a valid decrypting algorithm"); - } - return jwe; - } - - @Override - public byte[] decryptCipherText(Jwe jwe, byte[] contentEncryptionKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException { - - byte[] iv = new byte[16]; - iv = Base64.decodeBase64(jwe.getHeader().getInitializationVector()); - - String encMethod = jwe.getHeader().getEncryptionMethod(); - //TODO: should also check for A128GCM and A256GCM, but Cipher.getInstance() does not support the GCM mode. For now, don't use them - if(encMethod.equals("A128CBC") || encMethod.equals("A256CBC")) { - - String mode = JweAlgorithms.getByName(encMethod); - - Cipher cipher = Cipher.getInstance("AES/" + mode + "/PKCS5Padding"); - cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(contentEncryptionKey, "AES"), new IvParameterSpec(iv)); - byte[] clearText = cipher.doFinal(jwe.getCiphertext()); - - return clearText; - - } else { - throw new IllegalArgumentException(jwe.getHeader().getEncryptionMethod() + " is not an implemented encryption method"); - } - - - } - - @Override - public byte[] decryptEncryptionKey(Jwe jwe) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { - - if(jwe.getHeader().getAlgorithm().equals("RSA1_5")){ - Cipher cipher = Cipher.getInstance("RSA"); - cipher.init(Cipher.DECRYPT_MODE, getPrivateKey()); - byte[] contentMasterKey = cipher.doFinal(jwe.getEncryptedKey()); - - return contentMasterKey; - } else { - throw new IllegalArgumentException(jwe.getHeader().getAlgorithm() + " is not an implemented algorithm"); - } - - } - - public PublicKey getPublicKey() { - return publicKey; - } - - public void setPublicKey(PublicKey publicKey) { - this.publicKey = publicKey; - } - - public PrivateKey getPrivateKey() { - return privateKey; - } - - public void setPrivateKey(PrivateKey privateKey) { - this.privateKey = privateKey; - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaEncrypter.java b/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaEncrypter.java deleted file mode 100644 index 592fb0584..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/encryption/impl/RsaEncrypter.java +++ /dev/null @@ -1,132 +0,0 @@ -package org.mitre.jwt.encryption.impl; - -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.spec.InvalidKeySpecException; -import java.util.Random; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.commons.codec.binary.Base64; -import org.mitre.jwe.model.Jwe; -import org.mitre.jwt.encryption.AbstractJweEncrypter; -import org.mitre.jwt.encryption.JweAlgorithms; -import org.mitre.jwt.signer.impl.HmacSigner; - -public class RsaEncrypter extends AbstractJweEncrypter { - - private PublicKey publicKey; - private PrivateKey privateKey; - - public Jwe encryptAndSign(Jwe jwe) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException { - - String alg = jwe.getHeader().getAlgorithm(); - String integrityAlg = jwe.getHeader().getIntegrity(); - - if(alg.equals("RSA1_5") || alg.equals("RSA-OAEP")) { - - //generate random content master key - - //check what the key length is - String kdf = jwe.getHeader().getKeyDerivationFunction(); - String keyLength = JweAlgorithms.getByName(kdf); - int keyBitLength = Integer.parseInt(keyLength); - - byte[] contentMasterKey = new byte[keyBitLength]; - new Random().nextBytes(contentMasterKey); - - byte[] contentEncryptionKey = null; - byte[] contentIntegrityKey = null; - - //generate cek and cik - contentEncryptionKey = generateContentKey(contentMasterKey, keyBitLength, "Encryption".getBytes()); - contentIntegrityKey = generateContentKey(contentMasterKey, keyBitLength, "Integrity".getBytes()); - - //encrypt claims and cmk to get ciphertext and encrypted key - jwe.setCiphertext(encryptClaims(jwe, contentEncryptionKey)); - jwe.setEncryptedKey(encryptKey(jwe, contentMasterKey)); - - //Signer must be hmac - if(integrityAlg.equals("HS256") || integrityAlg.equals("HS384") || integrityAlg.equals("HS512")){ - - HmacSigner hmacSigner = new HmacSigner(contentIntegrityKey); - jwe = (Jwe) hmacSigner.sign(jwe); - - } else { - throw new IllegalArgumentException(integrityAlg + " is not a valid integrity value algorithm for signing."); - } - - } else { - throw new IllegalArgumentException(alg + " is not a valid encrypting algorithm."); - } - - return jwe; - } - - public byte[] encryptKey(Jwe jwe, byte[] contentMasterKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { - - if(jwe.getHeader().getAlgorithm().equals("RSA1_5")){ - - Cipher cipher = Cipher.getInstance("RSA"); - cipher.init(Cipher.ENCRYPT_MODE, getPublicKey()); - byte[] encryptedKey = cipher.doFinal(contentMasterKey); - return encryptedKey; - - } else { - throw new IllegalArgumentException(jwe.getHeader().getAlgorithm() + " is not a supported algorithm"); - } - - } - - public byte[] encryptClaims(Jwe jwe, byte[] contentEncryptionKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException { - - byte[] iv = new byte[16]; - //look for iv value in header, if not there make one - if(jwe.getHeader().getInitializationVector() != null){ - iv = Base64.decodeBase64(jwe.getHeader().getInitializationVector()); - } else { - new Random().nextBytes(iv); - jwe.getHeader().setIv(Base64.encodeBase64String(iv)); - } - - String encMethod = jwe.getHeader().getEncryptionMethod(); - //TODO: should also check for A128GCM and A256GCM, but Cipher.getInstance() does not support the GCM mode. For now, don't use them - if(encMethod.equals("A128CBC") || encMethod.equals("A256CBC")) { - - String mode = JweAlgorithms.getByName(encMethod); - - Cipher cipher = Cipher.getInstance("AES/" + mode + "/PKCS5Padding"); - cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(contentEncryptionKey, "AES"), new IvParameterSpec(iv)); - byte[] cipherText = cipher.doFinal(jwe.getCiphertext()); - return cipherText; - - } else { - throw new IllegalArgumentException(jwe.getHeader().getEncryptionMethod() + " is not a supported encryption method"); - } - - } - - public PublicKey getPublicKey() { - return publicKey; - } - - public void setPublicKey(PublicKey publicKey) { - this.publicKey = publicKey; - } - - public PrivateKey getPrivateKey() { - return privateKey; - } - - public void setPrivateKey(PrivateKey privateKey) { - this.privateKey = privateKey; - } -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/model/ClaimSet.java b/openid-connect-common/src/main/java/org/mitre/jwt/model/ClaimSet.java deleted file mode 100644 index 56d4baf86..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/model/ClaimSet.java +++ /dev/null @@ -1,266 +0,0 @@ -/******************************************************************************* - * Copyright 2012 The MITRE Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ -package org.mitre.jwt.model; - -import java.io.ByteArrayInputStream; -import java.io.InputStreamReader; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.apache.commons.codec.binary.Base64; - -import com.google.common.collect.Lists; -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.JsonPrimitive; -import com.google.gson.reflect.TypeToken; - -/** - * Generic container for JSON-based claims. Backed with a {@link Map} that preserves - * insertion order. Several convenience methods for getting and setting claims in different - * formats. - * @author jricher - * - */ -public class ClaimSet { - - private String jsonString; - - // the LinkedHashMap preserves insertion order - private Map claims = new LinkedHashMap(); - - public ClaimSet() { - - } - - public ClaimSet(JsonObject json) { - loadFromJsonObject(json); - } - - public ClaimSet(String b64) { - loadFromBase64JsonObjectString(b64); - } - - public ClaimSet(ClaimSet claimSet) { - loadFromClaimSet(claimSet); - } - - /** - * Get an extension claim - */ - public Object getClaim(String key) { - return claims.get(key); - } - - /** - * Get a claim as a string - */ - public String getClaimAsString(String key) { - Object v = claims.get(key); - if (v != null) { - return v.toString(); - } else { - return null; - } - } - - /** - * Get a claim as a Date - */ - public Date getClaimAsDate(String key) { - Object v = claims.get(key); - if (v != null) { - if (v instanceof Date) { - return (Date) v; - } else if (v instanceof Long) { - return new Date((Long) v); - } else { - return null; - } - } else { - return null; - } - } - - // TODO: not convinced I like this construct - public List getClaimAsList(String key) { - Object v = claims.get(key); - if (v != null) { - if (v instanceof List) { - return (List) v; - } else { - // return a list of the singular element - return Lists.newArrayList(v); - } - } else { - return null; - } - } - - /** - * Set an extension claim - */ - public void setClaim(String key, Object value) { - invalidateString(); - claims.put(key, value); - } - - /** - * Set a primitive claim - */ - public void setClaim(String key, JsonPrimitive prim) { - invalidateString(); - if (prim == null) { - // in case we get here with a primitive null - claims.put(key, prim); - } else if (prim.isBoolean()) { - claims.put(key, prim.getAsBoolean()); - } else if (prim.isNumber()) { - claims.put(key, prim.getAsNumber()); - } else if (prim.isString()) { - claims.put(key, prim.getAsString()); - } - - } - - private void invalidateString() { - jsonString = null; - } - - /** - * Remove an extension claim - */ - public Object removeClaim(String key) { - invalidateString(); - return claims.remove(key); - } - - - /** - * Clear all claims from this ClaimSet - * @see java.util.Map#clear() - */ - public void clear() { - invalidateString(); - claims.clear(); - } - - /** - * Get a copy of this claim set as a JsonObject. The JsonObject is not - * backed by a live copy of this ClaimSet. - * @return a copy of the data in this header in a JsonObject - */ - public JsonObject getAsJsonObject() { - - Gson g = new Gson(); - - JsonObject o = new JsonObject(); - - - /* - * We step through the claims object and serialize the internal values as - * appropriate to JsonElements. - */ - - if (this.claims != null) { - for (Map.Entry claim : this.claims.entrySet()) { - if (claim.getValue() instanceof JsonElement) { - // raw JSON elements get passed through directly - o.add(claim.getKey(), (JsonElement)claim.getValue()); - } else if (claim.getValue() instanceof String) { - o.addProperty(claim.getKey(), (String)claim.getValue()); - } else if (claim.getValue() instanceof Number) { - o.addProperty(claim.getKey(), (Number)claim.getValue()); - } else if (claim.getValue() instanceof Boolean) { - o.addProperty(claim.getKey(), (Boolean)claim.getValue()); - } else if (claim.getValue() instanceof Character) { - o.addProperty(claim.getKey(), (Character)claim.getValue()); - } else if (claim.getValue() instanceof Date) { - // dates get serialized out as integers - o.addProperty(claim.getKey(), ((Date)claim.getValue()).getTime() / 1000L); - } else if (claim.getValue() instanceof List) { - o.add(claim.getKey(), g.toJsonTree(claim.getValue(), new TypeToken>(){}.getType())); - } else if (claim.getValue() != null) { - // try to put it in as a string - o.addProperty(claim.getKey(), g.toJson(claim.getValue())); - } else { - // otherwise add in as a null - o.add(claim.getKey(), null); - } - } - } - - return o; - } - - /** - * Load new claims from the given json object. Will replace any existing claims, but does not clear claim set. - * - * This function is intended to be overridden by subclasses for more exact data type and claim handling. - * - * @param json - */ - public void loadFromJsonObject(JsonObject json) { - for (Entry element : json.entrySet()) { - if (element.getValue().isJsonNull()) { - // nulls get stored as java nulls - setClaim(element.getKey(), null); - } else if (element.getValue().isJsonPrimitive()){ - // we handle all primitives in here - JsonPrimitive prim = element.getValue().getAsJsonPrimitive(); - setClaim(element.getKey(), prim); - } else { - setClaim(element.getKey(), element.getValue()); - } - } - } - - /** - * Load a new claims set from a Base64 encoded JSON Object string and caches the string used - */ - public void loadFromBase64JsonObjectString(String b64) { - byte[] b64decoded = Base64.decodeBase64(b64); - - JsonParser parser = new JsonParser(); - JsonObject json = parser.parse(new InputStreamReader(new ByteArrayInputStream(b64decoded))).getAsJsonObject(); - - loadFromJsonObject(json); - - // save the string we were passed in (decoded from base64) - jsonString = new String(b64decoded); - } - - public void loadFromClaimSet(ClaimSet claimSet) { - - loadFromJsonObject(claimSet.getAsJsonObject()); // we push to a JSON object and back to let subclasses override this - - jsonString = claimSet.toJsonString(); // preserve the string on input - - } - - public String toJsonString() { - if(jsonString == null) { - jsonString = this.getAsJsonObject().toString(); - } - return jsonString; - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/model/Jwt.java b/openid-connect-common/src/main/java/org/mitre/jwt/model/Jwt.java deleted file mode 100644 index 8d2af5ee1..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/model/Jwt.java +++ /dev/null @@ -1,163 +0,0 @@ -/******************************************************************************* - * Copyright 2012 The MITRE Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ -package org.mitre.jwt.model; - -import java.util.List; - -import org.apache.commons.codec.binary.Base64; - -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import com.google.common.collect.Lists; - -public class Jwt { - - private JwtHeader header; - - private JwtClaims claims; - - /** - * Base64Url encoded signature string - */ - private String signature; - - - - - public Jwt() { - setHeader(new JwtHeader()); - setClaims(new JwtClaims()); - setSignature(null); // unsigned by default - } - - - - /** - * Create a Jwt from existing components - * @param header - * @param claims - * @param signature - */ - public Jwt(JwtHeader header, JwtClaims claims, String signature) { - setHeader(header); - setClaims(claims); - setSignature(signature); - } - - - - /** - * @return the header - */ - public JwtHeader getHeader() { - return header; - } - - - - /** - * @param header the header to set - */ - public void setHeader(JwtHeader header) { - this.header = header; - } - - - - /** - * @return the claims - */ - public JwtClaims getClaims() { - return claims; - } - - - - /** - * @param claims the claims to set - */ - public void setClaims(JwtClaims claims) { - this.claims = claims; - } - - - - /** - * @return the signature - */ - public String getSignature() { - return signature; - } - - - - /** - * @param signature the signature to set - */ - public void setSignature(String signature) { - this.signature = signature; - } - - /** - * Return the canonical encoded string of this JWT, the header in Base64, a period ".", the claims in Base64, a period ".", and the signature in Base64. - */ - public String toString() { - return getSignatureBase() + "." + Strings.nullToEmpty(this.signature); - } - - /** - * The signature base of a JWT is the header in Base64, a period ".", and the claims in Base64. - */ - public String getSignatureBase() { - - String h64 = new String(Base64.encodeBase64URLSafe(header.toJsonString().getBytes())); - String c64 = new String(Base64.encodeBase64URLSafe(claims.toJsonString().getBytes())); - - return h64 + "." + c64; - } - - - /** - * Parse a wire-encoded JWT - */ - public static Jwt parse(String s) { - - // null string is a null token - if (s == null) { - return null; - } - - // split on the dots - List parts = Lists.newArrayList(Splitter.on(".").split(s)); - - if (parts.size() != 3) { - throw new IllegalArgumentException("Invalid JWT format."); - } - - String h64 = parts.get(0); - String c64 = parts.get(1); - String s64 = parts.get(2); - - // shuttle for return value - Jwt jwt = new Jwt(new JwtHeader(h64), new JwtClaims(c64), s64); - - // TODO: save the wire-encoded string in the Jwt object itself? - - return jwt; - - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/model/JwtClaims.java b/openid-connect-common/src/main/java/org/mitre/jwt/model/JwtClaims.java deleted file mode 100644 index 76a2e2672..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/model/JwtClaims.java +++ /dev/null @@ -1,256 +0,0 @@ -/******************************************************************************* - * Copyright 2012 The MITRE Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ -package org.mitre.jwt.model; - -import java.lang.reflect.Type; -import java.util.Date; -import java.util.List; -import java.util.Map.Entry; - -import com.google.common.collect.Lists; -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.reflect.TypeToken; - -public class JwtClaims extends ClaimSet { - - public static final String TYPE = "typ"; - public static final String JWT_ID = "jti"; - public static final String SUBJECT = "sub"; - public static final String AUDIENCE = "aud"; - public static final String ISSUER = "iss"; - public static final String ISSUED_AT = "iat"; - public static final String NOT_BEFORE = "nbf"; - public static final String EXPIRATION = "exp"; - public static final String NONCE = "nonce"; - - /** - * ISO8601 / RFC3339 Date Format - */ - //public static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz"); - - public JwtClaims() { - super(); - } - - public JwtClaims(JsonObject json) { - super(json); - } - - public JwtClaims(String b64) { - super(b64); - } - - public JwtClaims(JwtClaims jwtClaims) { - super(jwtClaims); - } - - @Override - public void loadFromJsonObject(JsonObject json) { - JsonObject pass = new JsonObject(); - - for (Entry element : json.entrySet()) { - if (element.getValue().isJsonNull()) { - pass.add(element.getKey(), element.getValue()); - } else if (element.getKey().equals(EXPIRATION)) { - setExpiration(new Date(element.getValue().getAsLong() * 1000L)); - } else if (element.getKey().equals(NOT_BEFORE)) { - setNotBefore(new Date(element.getValue().getAsLong() * 1000L)); - } else if (element.getKey().equals(ISSUED_AT)) { - setIssuedAt(new Date(element.getValue().getAsLong() * 1000L)); - } else if (element.getKey().equals(ISSUER)) { - setIssuer(element.getValue().getAsString()); - } else if (element.getKey().equals(AUDIENCE)) { - if (element.getValue().isJsonArray()) { - // it's an array of strings, set it as such - //setAudience(element.getValue().getAsJsonArray()); - Type collectionType = new TypeToken>(){}.getType(); - List values = new Gson().fromJson(element.getValue(), collectionType); - setAudience(values); - } else { - // it's a single value - setAudience(element.getValue().getAsString()); - } - } else if (element.getKey().equals(SUBJECT)) { - setSubject(element.getValue().getAsString()); - } else if (element.getKey().equals(JWT_ID)) { - setJwtId(element.getValue().getAsString()); - } else if (element.getKey().equals(TYPE)) { - setType(element.getValue().getAsString()); - } else if (element.getKey().equals(NONCE)){ - setNonce(element.getValue().getAsString()); - }else { - pass.add(element.getKey(), element.getValue()); - } - } - - // load all the generic claims into this object - super.loadFromJsonObject(pass); - } - - /** - * @return the expiration - */ - public Date getExpiration() { - return getClaimAsDate(EXPIRATION); - } - - /** - * @param expiration the expiration to set - */ - public void setExpiration(Date expiration) { - setClaim(EXPIRATION, expiration); - } - - /** - * @return the notBefore - */ - public Date getNotBefore() { - return getClaimAsDate(NOT_BEFORE); - } - - /** - * @param notBefore the notBefore to set - */ - public void setNotBefore(Date notBefore) { - setClaim(NOT_BEFORE, notBefore); - } - - /** - * @return the issuedAt - */ - public Date getIssuedAt() { - return getClaimAsDate(ISSUED_AT); - } - - /** - * @param issuedAt the issuedAt to set - */ - public void setIssuedAt(Date issuedAt) { - setClaim(ISSUED_AT, issuedAt); - } - - /** - * @return the issuer - */ - public String getIssuer() { - return getClaimAsString(ISSUER); - } - - /** - * @param issuer the issuer to set - */ - public void setIssuer(String issuer) { - setClaim(ISSUER, issuer); - } - - /** - * @return the audience - */ - public List getAudience() { - return (List) getClaimAsList(AUDIENCE); - } - - /** - * @param audience the audience to set - */ - public void setAudience(String audience) { - setClaim(AUDIENCE, Lists.newArrayList(audience)); - } - - - public void setAudience(List audience) { - setClaim(AUDIENCE, audience); - } - - /** - * @return the principal - */ - public String getSubject() { - return getClaimAsString(SUBJECT); - } - - /** - * @param principal the principal to set - */ - public void setSubject(String principal) { - setClaim(SUBJECT, principal); - } - - /** - * @return the jwtId - */ - public String getJwtId() { - return getClaimAsString(JWT_ID); - } - - /** - * @param jwtId the jwtId to set - */ - public void setJwtId(String jwtId) { - setClaim(JWT_ID, jwtId); - } - - /** - * @return the type - */ - public String getType() { - return getClaimAsString(TYPE); - } - - /** - * @param type the type to set - */ - public void setType(String type) { - setClaim(TYPE, type); - } - - /** - * @return the nonce - */ - public String getNonce() { - return getClaimAsString(NONCE); - } - - /** - * @param nonce the nonce to set - */ - public void setNonce(String nonce) { - setClaim(NONCE, nonce); - } - - /* (non-Javadoc) - * @see org.mitre.jwt.model.ClaimSet#getAsJsonObject() - */ - @Override - public JsonObject getAsJsonObject() { - JsonObject o = super.getAsJsonObject(); - - // special handling for audience claim - if (o.has(AUDIENCE) && o.get(AUDIENCE).isJsonArray()) { - JsonArray aud = o.get(AUDIENCE).getAsJsonArray(); - // overwrite single-sized arrays as a string - if (aud.size() == 1) { - o.addProperty(AUDIENCE, aud.get(0).getAsString()); - } - } - - return o; - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/model/JwtHeader.java b/openid-connect-common/src/main/java/org/mitre/jwt/model/JwtHeader.java deleted file mode 100644 index ebb5a2beb..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/model/JwtHeader.java +++ /dev/null @@ -1,137 +0,0 @@ -/******************************************************************************* - * Copyright 2012 The MITRE Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ -package org.mitre.jwt.model; - -import java.util.Map.Entry; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -public class JwtHeader extends ClaimSet { - - public static final String TYPE = "typ"; - public static final String ALGORITHM = "alg"; - public static final String ENCRYPTION_METHOD = "enc"; - public static final String CONTENT_TYPE = "cty"; - - /** - * Make an empty header - */ - public JwtHeader() { - super(); - } - - /** - * Build a header from a JSON object - * @param json - */ - public JwtHeader(JsonObject json) { - super(json); - } - - - public JwtHeader(String b64) { - super(b64); - } - - public JwtHeader(JwtHeader jwtHeader) { - super(jwtHeader); - } - - /** - * Load all claims from the given json object into this object - */ - @Override - public void loadFromJsonObject(JsonObject json) { - - JsonObject pass = new JsonObject(); - - for (Entry element : json.entrySet()) { - if (element.getValue().isJsonNull()) { - pass.add(element.getKey(), element.getValue()); - } else if (element.getKey().equals(TYPE)) { - this.setType(element.getValue().getAsString()); - } else if (element.getKey().equals(ALGORITHM)) { - this.setAlgorithm(element.getValue().getAsString()); - } else if (element.getKey().equals(ENCRYPTION_METHOD)) { - this.setEncryptionMethod(element.getValue().getAsString()); - } else if (element.getKey().equals(CONTENT_TYPE)) { - this.setContentType(element.getValue().getAsString()); - } else { - pass.add(element.getKey(), element.getValue()); - } - } - - // now load all the ones we didn't handle specially - super.loadFromJsonObject(pass); - } - - /** - * @return the type - */ - public String getType() { - return getClaimAsString(TYPE); - } - - - /** - * @param type the type to set - */ - public void setType(String type) { - setClaim(TYPE, type); - } - - - /** - * @return the algorithm - */ - public String getAlgorithm() { - return getClaimAsString(ALGORITHM); - } - - - /** - * @param algorithm the algorithm to set - */ - public void setAlgorithm(String algorithm) { - setClaim(ALGORITHM, algorithm); - } - - - /** - * @return the encryptionMethod - */ - public String getEncryptionMethod() { - return getClaimAsString(ENCRYPTION_METHOD); - } - - - /** - * @param encryptionMethod the encryptionMethod to set - */ - public void setEncryptionMethod(String encryptionMethod) { - setClaim(ENCRYPTION_METHOD, encryptionMethod); - } - - public static String getContentType() { - return CONTENT_TYPE; - } - - public void setContentType(String cty) { - setClaim(CONTENT_TYPE, cty); - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/AbstractJwtSigner.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/AbstractJwtSigner.java deleted file mode 100644 index 3263ee321..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/AbstractJwtSigner.java +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************************* - * Copyright 2012 The MITRE Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ -package org.mitre.jwt.signer; - -import java.security.NoSuchAlgorithmException; -import java.util.List; - -import org.mitre.jwt.model.Jwt; - -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import com.google.common.collect.Lists; - -public abstract class AbstractJwtSigner implements JwtSigner { - - private JwsAlgorithm algorithm; - - public AbstractJwtSigner(JwsAlgorithm algorithm) { - this.algorithm = algorithm; - } - - /** - * @return the algorithm - */ - public JwsAlgorithm getAlgorithm() { - return algorithm; - } - - /** - * @param algorithm the algorithm to set - */ - public void setAlgorithm(JwsAlgorithm algorithm) { - this.algorithm = algorithm; - } - - /** - * Ensures that the 'alg' of the given JWT matches the {@link #algorithm} of this signer - * and signs the jwt. - * - * @param jwt the jwt to sign - * @return the signed jwt - * @throws NoSuchAlgorithmException - */ - @Override - public Jwt sign(Jwt jwt) throws NoSuchAlgorithmException { - - //TODO: need a seperate check for Jwe. As is, it will change the alg param to be the enc param - /*if (!Objects.equal(algorithm, jwt.getHeader().getAlgorithm())) { - // algorithm type doesn't match - // TODO: should this be an error or should we just fix it in the incoming jwt? - // for now, we fix the Jwt - jwt.getHeader().setAlgorithm(algorithm.getJwaName()); - }*/ - - String sig = generateSignature(jwt.getSignatureBase()); - - jwt.setSignature(sig); - - return jwt; - } - - /* (non-Javadoc) - * @see org.mitre.jwt.JwtSigner#verify(java.lang.String) - */ - @Override - public boolean verify(String jwtString) throws NoSuchAlgorithmException { - // split on the dots - List parts = Lists.newArrayList(Splitter.on(".").split(jwtString)); - - if (parts.size() != 3) { - throw new IllegalArgumentException("Invalid JWT format."); - } - - String h64 = parts.get(0); - String c64 = parts.get(1); - String s64 = parts.get(2); - - String expectedSignature = generateSignature(h64 + "." + c64); - - return Strings.nullToEmpty(s64).equals(Strings.nullToEmpty(expectedSignature)); - - } - - - protected abstract String generateSignature(String signatureBase) throws NoSuchAlgorithmException; -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/JwsAlgorithm.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/JwsAlgorithm.java deleted file mode 100644 index e20ef8a57..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/JwsAlgorithm.java +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * Copyright 2012 The MITRE Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ -package org.mitre.jwt.signer; - -import java.util.HashMap; -import java.util.Map; - -/** - * Enum to translate between the JWS defined algorithm names and the JSE algorithm names - * - * @author jricher - * - */ -public enum JwsAlgorithm { - - // PLAINTEXT - NONE("plaintext", "none"), - - // HMAC - HS256("HMACSHA256", "HS256"), - HS384("HMACSHA384", "HS384"), - HS512("HMACSHA512", "HS512"), - // RSA - RS256("SHA256withRSA", "RS256"), - RS384("SHA384withRSA", "RS384"), - RS512("SHA512withRSA", "RS512"); - - - private static final Map jwaLookup = new HashMap(); - private static final Map jceLookup = new HashMap(); - static { - for (JwsAlgorithm alg : JwsAlgorithm.values()) { - jwaLookup.put(alg.getJwaName(), alg); - jceLookup.put(alg.getStandardName(), alg); - } - } - - /** - * Returns the Algorithm for the JWS-registered name - * - * @param name - * @return - */ - public static JwsAlgorithm getByJwaName(String name) { - return jwaLookup.get(name); - } - - public static JwsAlgorithm getByStandardName(String name) { - return jceLookup.get(name); - } - - private final String standardName; - private final String jwaName; - - /** - * Constructor of JwsAlgorithm - * - * @param standardName - */ - JwsAlgorithm(String standardName, String jwaName) { - this.standardName = standardName; - this.jwaName = jwaName; - } - - /** - * Return the Java standard JwsAlgorithm name - * - * @return - */ - public String getStandardName() { - return standardName; - } - - /** - * Return the JWA Standard name - * @return - */ - public String getJwaName() { - return jwaName; - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/JwtSigner.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/JwtSigner.java deleted file mode 100644 index a119371ab..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/JwtSigner.java +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - * Copyright 2012 The MITRE Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ -package org.mitre.jwt.signer; - -import java.security.NoSuchAlgorithmException; - -import org.mitre.jwt.model.Jwt; - -public interface JwtSigner { - - public JwsAlgorithm getAlgorithm(); - - public Jwt sign(Jwt jwt) throws NoSuchAlgorithmException; - - public boolean verify(String jwtString) throws NoSuchAlgorithmException; - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/HmacSigner.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/HmacSigner.java deleted file mode 100644 index 23689b719..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/HmacSigner.java +++ /dev/null @@ -1,192 +0,0 @@ -/******************************************************************************* - * Copyright 2012 The MITRE Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ -package org.mitre.jwt.signer.impl; - -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import java.security.GeneralSecurityException; -import java.security.NoSuchAlgorithmException; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.commons.codec.binary.Base64; -import org.mitre.jwt.signer.AbstractJwtSigner; -import org.mitre.jwt.signer.JwsAlgorithm; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.util.Assert; - -/** - * JWT Signer using either the HMAC SHA-256, SHA-384, SHA-512 hash algorithm - * - * @author AANGANES, nemonik - * - */ -public class HmacSigner extends AbstractJwtSigner implements InitializingBean { - - public static final String DEFAULT_PASSPHRASE = "changeit"; - - public static final JwsAlgorithm DEFAULT_ALGORITHM = JwsAlgorithm.HS256; - - private static Logger logger = LoggerFactory.getLogger(HmacSigner.class); - - private Mac mac; - - private String passphrase = DEFAULT_PASSPHRASE; - - /** - * Default constructor - */ - public HmacSigner() { - super(DEFAULT_ALGORITHM); - } - - /** - * Create HMAC singer with default algorithm and passphrase as raw bytes - * - * @param passphraseAsRawBytes - * The passphrase as raw bytes - */ - public HmacSigner(byte[] passphraseAsRawBytes) - throws NoSuchAlgorithmException { - this(DEFAULT_ALGORITHM.getJwaName(), new String(passphraseAsRawBytes, - Charset.forName("UTF-8"))); - } - - /** - * Create HMAC singer with default algorithm and passphrase - * - * @param passwordAsRawBytes - * The passphrase as raw bytes - */ - public HmacSigner(String passphrase) throws NoSuchAlgorithmException { - this(DEFAULT_ALGORITHM.getJwaName(), passphrase); - } - - /** - * Create HMAC singer with given algorithm and password as raw bytes - * - * @param algorithmName - * The Java standard name of the requested MAC algorithm - * @param passphraseAsRawBytes - * The passphrase as raw bytes - */ - public HmacSigner(String algorithmName, byte[] passphraseAsRawBytes) - throws NoSuchAlgorithmException { - this(algorithmName, new String(passphraseAsRawBytes, - Charset.forName("UTF-8"))); - } - - /** - * Create HMAC singer with given algorithm and passwords - * - * @param algorithmName - * The Java standard name of the requested MAC algorithm - * @param passphrase - * the passphrase - */ - public HmacSigner(String algorithmName, String passphrase) { - super(JwsAlgorithm.getByJwaName(algorithmName)); - - Assert.notNull(passphrase, "A passphrase must be supplied"); - - setPassphrase(passphrase); - - } - - /* - * (non-Javadoc) - * - * @see - * org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet(){ - initializeMac(); - } - - /* - * (non-Javadoc) - * - * @see - * org.mitre.jwt.signer.AbstractJwtSigner#generateSignature(java.lang.String - * ) - */ - @Override - public String generateSignature(String signatureBase) throws NoSuchAlgorithmException { - - initializeMac(); - - if (passphrase == null) { - throw new IllegalArgumentException("Passphrase cannot be null"); - } - - try { - mac.init(new SecretKeySpec(getPassphrase().getBytes(), mac - .getAlgorithm())); - - mac.update(signatureBase.getBytes("UTF-8")); - } catch (GeneralSecurityException e) { - logger.error("GeneralSecurityException in HmacSigner.java: ", e); - } catch (UnsupportedEncodingException e) { - logger.error("UnsupportedEncodingException in HmacSigner.java: ", e); - } - - byte[] sigBytes = mac.doFinal(); - - String sig = new String(Base64.encodeBase64URLSafe(sigBytes)); - - // strip off any padding - sig = sig.replace("=", ""); - - return sig; - } - - public String getPassphrase() { - return passphrase; - } - - public void setPassphrase(byte[] rawbytes) { - this.setPassphrase(new String(rawbytes, Charset.forName("UTF-8"))); - } - - public void setPassphrase(String passphrase) { - this.passphrase = passphrase; - } - - private void initializeMac() { - if (mac == null) { - try { - mac = Mac.getInstance(getAlgorithm().getStandardName()); - } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "HmacSigner [mac=" + mac + ", passphrase=" + passphrase + "]"; - } -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/PlaintextSigner.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/PlaintextSigner.java deleted file mode 100644 index 6de6f1428..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/PlaintextSigner.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * Copyright 2012 The MITRE Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ -package org.mitre.jwt.signer.impl; - -import org.mitre.jwt.signer.AbstractJwtSigner; -import org.mitre.jwt.signer.JwsAlgorithm; - -public class PlaintextSigner extends AbstractJwtSigner { - - public PlaintextSigner() { - super(JwsAlgorithm.NONE); - } - - @Override - protected String generateSignature(String signatureBase) { - return null; - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/RsaSigner.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/RsaSigner.java deleted file mode 100644 index 5466e700f..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/impl/RsaSigner.java +++ /dev/null @@ -1,291 +0,0 @@ -/******************************************************************************* - * Copyright 2012 The MITRE Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ -package org.mitre.jwt.signer.impl; - -import java.io.UnsupportedEncodingException; -import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.Signature; -import java.security.interfaces.RSAPrivateKey; -import java.util.List; - -import org.apache.commons.codec.binary.Base64; -import org.mitre.jwt.encryption.impl.KeyStore; -import org.mitre.jwt.signer.AbstractJwtSigner; -import org.mitre.jwt.signer.JwsAlgorithm; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.util.Assert; - -import com.google.common.base.Splitter; -import com.google.common.collect.Lists; - -/** - * JWT Signer using either the RSA SHA-256, SHA-384, SHA-512 hash algorithm - * - * @author AANGANES, nemonik - * - */ -public class RsaSigner extends AbstractJwtSigner implements InitializingBean { - - private static Logger logger = LoggerFactory.getLogger(RsaSigner.class); - - public static final String KEYPAIR_ALGORITHM = "RSA"; - public static final String DEFAULT_PASSWORD = "changeit"; - - public static final JwsAlgorithm DEFAULT_ALGORITHM = JwsAlgorithm.RS256; - - private KeyStore keystore; - private String alias; - private String password = DEFAULT_PASSWORD; - - private PrivateKey privateKey; - private PublicKey publicKey; - private Signature signer; - - /** - * Default constructor - */ - public RsaSigner() { - super(DEFAULT_ALGORITHM); - } - - /** - * Creates an RsaSigner from an algorithm name, a Java Keystore, an alias - * for the key pair, and the default password to access. Key pairs created - * with larger bit sizes obviously create larger signatures. - * - * @param algorithmName - * The algorithm name - * @param keystore - * A Java Keystore containing the key pair - * @param alias - * The alias for the key pair - * @throws GeneralSecurityException - */ - public RsaSigner(String algorithmName, KeyStore keystore, String alias) - throws GeneralSecurityException { - this(algorithmName, keystore, alias, DEFAULT_PASSWORD); - } - - /** - * Creates an RsaSigner from an algorithm name, a Java Keystore, an alias - * for the key pair, and the password to access. Key pairs created with - * larger bit sizes obviously create larger signatures. - * - * @param algorithmName - * The algorithm name - * @param keystore - * A Java Keystore containing the key pair - * @param alias - * The alias for the key pair - * @param password - * The password used to access and retrieve the key pair. - * @throws GeneralSecurityException - */ - public RsaSigner(String algorithmName, KeyStore keystore, String alias, String password) throws GeneralSecurityException { - super(JwsAlgorithm.getByJwaName(algorithmName)); - - setKeystore(keystore); - setAlias(alias); - setPassword(password); - - loadKeysFromKeystore(); - } - - /** - * Creates an RsaSigner from an algorithm name, and key pair. Key pairs - * created with larger bit sizes obviously create larger signatures. - * - * @param algorithmName - * The JWA algorithm name - * @param publicKey - * The public key - * @param privateKey - * The private key - */ - public RsaSigner(String algorithmName, PublicKey publicKey, PrivateKey privateKey) { - super(JwsAlgorithm.getByJwaName(algorithmName)); - - this.publicKey = publicKey; - this.privateKey = privateKey; - } - - /* - * (non-Javadoc) - * - * @see - * org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() throws NoSuchAlgorithmException, GeneralSecurityException { - initializeSigner(); - } - - /** - * Load the public and private keys from the keystore, identified with the configured alias and accessed with the configured password. - * @throws GeneralSecurityException - */ - private void loadKeysFromKeystore() { - Assert.notNull(keystore, "An keystore must be supplied"); - Assert.notNull(alias, "A alias must be supplied"); - Assert.notNull(password, "A password must be supplied"); - - KeyPair keyPair = null; - try { - keyPair = keystore.getKeyPairForAlias(alias, password); - } catch (GeneralSecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - Assert.notNull(keyPair, "Either alias and/or password is not correct for keystore"); - - publicKey = keyPair.getPublic(); - privateKey = keyPair.getPrivate(); - } - - /* - * (non-Javadoc) - * - * @see - * org.mitre.jwt.signer.AbstractJwtSigner#generateSignature(java.lang.String - * ) - */ - @Override - public String generateSignature(String signatureBase) throws NoSuchAlgorithmException { - - String sig = null; - - initializeSigner(); - - try { - signer.initSign(privateKey); - signer.update(signatureBase.getBytes("UTF-8")); - - byte[] sigBytes = signer.sign(); - - sig = (new String(Base64.encodeBase64URLSafe(sigBytes))).replace("=", ""); - } catch (GeneralSecurityException e) { - logger.error("GeneralSecurityException in RsaSigner.java: ", e); - } catch (UnsupportedEncodingException e) { - logger.error("UnsupportedEncodingException in RsaSigner.java: ", e); - } - - return sig; - } - - public String getAlias() { - return alias; - } - - public KeyStore getKeystore() { - return keystore; - } - - public String getPassword() { - return password; - } - - public PrivateKey getPrivateKey() { - return privateKey; - } - - public PublicKey getPublicKey() { - return publicKey; - } - - public void setAlias(String alias) { - this.alias = alias; - } - - public void setKeystore(KeyStore keyStore) { - this.keystore = keyStore; - } - - public void setPassword(String password) { - this.password = password; - } - - public void setPrivateKey(RSAPrivateKey privateKey) { - this.privateKey = privateKey; - } - - private void initializeSigner() throws NoSuchAlgorithmException{ - if (this.keystore != null && this.alias != null && this.password != null) { - // if it looks like we're configured with a keystore, load it here - loadKeysFromKeystore(); - } - - if (signer == null) { - signer = Signature.getInstance(getAlgorithm().getStandardName()); - } - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "RsaSigner [keystore=" + keystore + ", alias=" + alias - + ", password=" + password + ", privateKey=" + privateKey - + ", publicKey=" + publicKey + ", signer=" + signer + "]"; - } - - /* - * (non-Javadoc) - * - * @see org.mitre.jwt.signer.AbstractJwtSigner#verify(java.lang.String) - */ - @Override - public boolean verify(String jwtString) { - - boolean value = false; - - // split on the dots - List parts = Lists.newArrayList(Splitter.on(".").split( - jwtString)); - - if (parts.size() != 3) { - throw new IllegalArgumentException("Invalid JWT format."); - } - - String h64 = parts.get(0); - String c64 = parts.get(1); - String s64 = parts.get(2); - - String signingInput = h64 + "." + c64; - - try { - initializeSigner(); - signer.initVerify(publicKey); - signer.update(signingInput.getBytes("UTF-8")); - value = signer.verify(Base64.decodeBase64(s64)); - } catch (GeneralSecurityException e) { - logger.error("GeneralSecurityException in RsaSigner.java: ", e); - } catch (UnsupportedEncodingException e) { - logger.error("UnsupportedEncodingException in RsaSigner.java: ", e); - } - - return value; - } -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/JwtSigningAndValidationService.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/JwtSigningAndValidationService.java deleted file mode 100644 index 70a9f13b1..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/JwtSigningAndValidationService.java +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * Copyright 2012 The MITRE Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ -package org.mitre.jwt.signer.service; - -import java.security.NoSuchAlgorithmException; -import java.util.Map; - -import org.mitre.jwt.model.Jwt; -import org.mitre.jwt.signer.JwtSigner; - -public interface JwtSigningAndValidationService { - - /** - * Returns all public keys this service is configured with, indexed by key id - * - * @return - */ - public Map getAllSigners(); - - /** - * Checks the signature of the given JWT against all configured signers, - * returns true if at least one of the signers validates it. - * - * @param jwtString - * the string representation of the JWT as sent on the wire - * @return true if the signature is valid, false if not - * @throws NoSuchAlgorithmException - */ - public boolean validateSignature(String jwtString); - - - - /** - * Called to sign a jwt in place for a client that hasn't registered a preferred signing algorithm. - * Use the default algorithm to sign. - * - * @param jwt the jwt to sign - * @return the signed jwt - * @throws NoSuchAlgorithmException - */ - public void signJwt(Jwt jwt) throws NoSuchAlgorithmException; - - /** - * Sign a jwt using the selected algorithm. The algorithm is selected using the String parameter values specified - * in the JWT spec, section 6. I.E., "HS256" means HMAC with SHA-256 and corresponds to our HmacSigner class. - * - * @param jwt the jwt to sign - * @param alg the name of the algorithm to use, as specified in JWS s.6 - * @return the signed jwt - */ - //TODO: implement later; only need signJwt(Jwt jwt) for now - //public Jwt signJwt(Jwt jwt, String alg); - - /** - * TODO: method to sign a jwt using a specified algorithm and a key id - */ -} diff --git a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/DefaultJwtSigningAndValidationService.java b/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/DefaultJwtSigningAndValidationService.java deleted file mode 100644 index 6be7b5420..000000000 --- a/openid-connect-common/src/main/java/org/mitre/jwt/signer/service/impl/DefaultJwtSigningAndValidationService.java +++ /dev/null @@ -1,166 +0,0 @@ -/******************************************************************************* - * Copyright 2012 The MITRE Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ -package org.mitre.jwt.signer.service.impl; - -import java.security.NoSuchAlgorithmException; -import java.util.HashMap; -import java.util.Map; - -import org.mitre.jwt.model.Jwt; -import org.mitre.jwt.signer.JwtSigner; -import org.mitre.jwt.signer.service.JwtSigningAndValidationService; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; - -public class DefaultJwtSigningAndValidationService implements JwtSigningAndValidationService, InitializingBean { - - @Autowired - private ConfigurationPropertiesBean configBean; - - // map of identifier to signer - private Map signers = new HashMap(); - - private static Logger logger = LoggerFactory.getLogger(DefaultJwtSigningAndValidationService.class); - - /** - * default constructor - */ - public DefaultJwtSigningAndValidationService() { - } - - /** - * Create DefaultJwtSigningAndValidationService - * - * @param signer - * List of JwtSigners to associate with this service - */ - public DefaultJwtSigningAndValidationService(Map signer) { - setSigners(signer); - } - - /* - * (non-Javadoc) - * - * @see - * org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet(){ - // used for debugging... - if (!signers.isEmpty()) { - logger.info(this.toString()); - } - - logger.info("DefaultJwtSigningAndValidationService is open for business"); - - } - - /** - * - * Returns a copy of the collection of signers. - * - * @see - * org.mitre.jwt.signer.service.JwtSigningAndValidationService#getAllPublicKeys - * () - */ - @Override - public Map getAllSigners() { - - Map map = new HashMap(); - - map.putAll(signers); - - return map; - } - - /** - * Set the JwtSigners associated with this service - * - * @param signers - * List of JwtSigners to associate with this service - */ - public void setSigners(Map signers) { - this.signers = signers; - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "DefaultJwtSigningAndValidationService [signers=" + signers + "]"; - } - - /** - * @return the configBean - */ - public ConfigurationPropertiesBean getConfigBean() { - return configBean; - } - - /** - * @param configBean the configBean to set - */ - public void setConfigBean(ConfigurationPropertiesBean configBean) { - this.configBean = configBean; - } - - /** - * Sign a jwt in place using the configured default signer. - * @throws NoSuchAlgorithmException - */ - @Override - public void signJwt(Jwt jwt) throws NoSuchAlgorithmException { - String signerId = configBean.getDefaultJwtSigner(); - - JwtSigner signer = getSigners().get(signerId); - - // set the signing algorithm in the JWT - jwt.getHeader().setAlgorithm(signer.getAlgorithm().getJwaName()); - - signer.sign(jwt); - - } - - /** - * Return the JwtSigners associated with this service - * - * @return - */ - public Map getSigners() { - return signers; - } - - @Override - public boolean validateSignature(String jwtString) { - - for (JwtSigner signer : getSigners().values()) { - try { - if (signer.verify(jwtString)) { - return true; - } - } catch (NoSuchAlgorithmException e) { - // ignore, signer didn't verify signature, try the next one - e.printStackTrace(); - } - } - return false; - } - -}