diff --git a/openid-connect-common/src/test/java/org/mitre/jwt/encryption/service/impl/TestDefaultJwtEncryptionAndDecryptionService.java b/openid-connect-common/src/test/java/org/mitre/jwt/encryption/service/impl/TestDefaultJwtEncryptionAndDecryptionService.java index 27ce739f4..190576e14 100644 --- a/openid-connect-common/src/test/java/org/mitre/jwt/encryption/service/impl/TestDefaultJwtEncryptionAndDecryptionService.java +++ b/openid-connect-common/src/test/java/org/mitre/jwt/encryption/service/impl/TestDefaultJwtEncryptionAndDecryptionService.java @@ -19,14 +19,18 @@ package org.mitre.jwt.encryption.service.impl; import static org.hamcrest.CoreMatchers.nullValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; import java.text.ParseException; +import java.util.LinkedList; +import java.util.List; import java.util.Map; import org.junit.Before; import org.junit.Test; +import org.mitre.jose.keystore.JWKSetKeyStore; import com.google.common.collect.ImmutableMap; import com.nimbusds.jose.EncryptionMethod; @@ -35,17 +39,23 @@ import com.nimbusds.jose.JWEAlgorithm; import com.nimbusds.jose.JWEHeader; import com.nimbusds.jose.JWEObject; import com.nimbusds.jose.jwk.JWK; -import com.nimbusds.jose.jwk.RSAKey; +import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.KeyUse; +import com.nimbusds.jose.jwk.OctetSequenceKey; +import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jose.util.Base64URL; +import com.nimbusds.jose.util.JSONObjectUtils; import com.nimbusds.jwt.EncryptedJWT; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.ReadOnlyJWTClaimsSet; + /** * @author wkim + * @author tsitkov * */ + public class TestDefaultJwtEncryptionAndDecryptionService { private String plainText = "The true sign of intelligence is not knowledge but imagination."; @@ -83,30 +93,80 @@ public class TestDefaultJwtEncryptionAndDecryptionService { "VTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ"), // d KeyUse.ENCRYPTION, null, JWEAlgorithm.RSA_OAEP, RSAkid, null, null, null); - // AES key wrap not yet tested - // private String AESkid = "aes123"; - // private JWK AESjwk = new OctetSequenceKey(new Base64URL("GawgguFyGrWKav7AX4VKUg"), Use.ENCRYPTION, JWEAlgorithm.A128KW, AESkid); - // - // private Map keys = new ImmutableMap.Builder(). - // put(RSAkid, RSAjwk).put(AESkid, AESjwk).build(); + private String RSAkid_2 = "rsa3210"; + private JWK RSAjwk_2 = new RSAKey( + new Base64URL("oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUW" + + "cJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S" + + "psk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2a" + + "sbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMS" + + "tPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2dj" + + "YgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw"), // n + new Base64URL("AQAB"), // e + new Base64URL("kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5N" + + "WV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD9" + + "3Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghk" + + "qDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vl" + + "t3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSnd" + + "VTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ"), // d + KeyUse.ENCRYPTION, null, JWEAlgorithm.RSA1_5, RSAkid_2, null, null, null); - private Map keys = new ImmutableMap.Builder(). - put(RSAkid, RSAjwk).build(); + private String AESkid = "aes123"; + private JWK AESjwk = new OctetSequenceKey( new Base64URL("GawgguFyGrWKav7AX4VKUg"), + KeyUse.ENCRYPTION, null, JWEAlgorithm.A128KW, + AESkid, null, null, null); + + + private Map keys = new ImmutableMap.Builder() + .put(RSAkid, RSAjwk) + .build(); + private Map keys_2 = new ImmutableMap.Builder() + .put(RSAkid, RSAjwk) + .put(RSAkid_2, RSAjwk_2) + .build(); + private Map keys_3 = new ImmutableMap.Builder() + .put(AESkid, AESjwk) + .build(); + private Map keys_4= new ImmutableMap.Builder() + .put(RSAkid, RSAjwk) + .put(RSAkid_2, RSAjwk_2) + .put(AESkid, AESjwk) + .build(); + + + private List keys_list = new LinkedList(); private DefaultJwtEncryptionAndDecryptionService service; + private DefaultJwtEncryptionAndDecryptionService service_2; + private DefaultJwtEncryptionAndDecryptionService service_3; + private DefaultJwtEncryptionAndDecryptionService service_4; + private DefaultJwtEncryptionAndDecryptionService service_ks; + @Before public void prepare() throws NoSuchAlgorithmException, InvalidKeySpecException, JOSEException { service = new DefaultJwtEncryptionAndDecryptionService(keys); + service_2 = new DefaultJwtEncryptionAndDecryptionService(keys_2); + service_3 = new DefaultJwtEncryptionAndDecryptionService(keys_3); + service_4 = new DefaultJwtEncryptionAndDecryptionService(keys_4); claimsSet.setIssuer(issuer); claimsSet.setSubject(subject); + + // Key Store + + keys_list.add(RSAjwk); + keys_list.add(AESjwk); + JWKSet jwkSet = new JWKSet(keys_list); + JWKSetKeyStore keyStore = new JWKSetKeyStore(jwkSet); + + service_ks = new DefaultJwtEncryptionAndDecryptionService(keyStore); } + @Test public void decrypt_RSA() throws ParseException { - + service.setDefaultDecryptionKeyId(RSAkid); service.setDefaultEncryptionKeyId(RSAkid); @@ -120,12 +180,16 @@ public class TestDefaultJwtEncryptionAndDecryptionService { assertEquals(plainText, result); } + @Test public void encryptThenDecrypt_RSA() throws ParseException { service.setDefaultDecryptionKeyId(RSAkid); service.setDefaultEncryptionKeyId(RSAkid); + assertEquals(RSAkid,service.getDefaultEncryptionKeyId()); + assertEquals(RSAkid,service.getDefaultDecryptionKeyId()); + JWEHeader header = new JWEHeader(JWEAlgorithm.RSA_OAEP, EncryptionMethod.A256GCM); EncryptedJWT jwt = new EncryptedJWT(header, claimsSet); @@ -143,4 +207,152 @@ public class TestDefaultJwtEncryptionAndDecryptionService { assertEquals(claimsSet.getSubject(), resultClaims.getSubject()); } + + // The same as encryptThenDecrypt_RSA() but relies on the key from the map + @Test + public void encryptThenDecrypt_nullID() throws ParseException { + + service.setDefaultDecryptionKeyId(null); + service.setDefaultEncryptionKeyId(null); + + assertEquals(RSAkid,service.getDefaultEncryptionKeyId()); + assertEquals(RSAkid,service.getDefaultDecryptionKeyId()); + + JWEHeader header = new JWEHeader(JWEAlgorithm.RSA_OAEP, EncryptionMethod.A256GCM); + + EncryptedJWT jwt = new EncryptedJWT(header, claimsSet); + + service.encryptJwt(jwt); + String serialized = jwt.serialize(); + + EncryptedJWT encryptedJwt = EncryptedJWT.parse(serialized); + assertThat(encryptedJwt.getJWTClaimsSet(), nullValue()); + service.decryptJwt(encryptedJwt); + + ReadOnlyJWTClaimsSet resultClaims = encryptedJwt.getJWTClaimsSet(); + + assertEquals(claimsSet.getIssuer(), resultClaims.getIssuer()); + assertEquals(claimsSet.getSubject(), resultClaims.getSubject()); + } + + + @Test(expected=IllegalStateException.class) + public void encrypt_nullID_oneKey() { + + service_2.setDefaultEncryptionKeyId(null); + assertEquals(null, service_2.getDefaultEncryptionKeyId()); + + JWEHeader header = new JWEHeader(JWEAlgorithm.RSA_OAEP, EncryptionMethod.A256GCM); + + EncryptedJWT jwt = new EncryptedJWT(header, claimsSet); + + service_2.encryptJwt(jwt); + assertEquals(null, service_2.getDefaultEncryptionKeyId()); + } + + + @Test(expected=IllegalStateException.class) + public void decrypt_nullID() throws ParseException { + + service_2.setDefaultEncryptionKeyId(RSAkid); + service_2.setDefaultDecryptionKeyId(null); + + assertEquals(RSAkid, service_2.getDefaultEncryptionKeyId()); + assertEquals(null, service_2.getDefaultDecryptionKeyId()); + + JWEHeader header = new JWEHeader(JWEAlgorithm.RSA_OAEP, EncryptionMethod.A256GCM); + + EncryptedJWT jwt = new EncryptedJWT(header, claimsSet); + service_2.encryptJwt(jwt); + String serialized = jwt.serialize(); + + EncryptedJWT encryptedJwt = EncryptedJWT.parse(serialized); + assertThat(encryptedJwt.getJWTClaimsSet(), nullValue()); + + assertEquals(null, service_2.getDefaultDecryptionKeyId()); + service_2.decryptJwt(encryptedJwt); + } + + + @Test + public void setThenGetDefAlg() throws ParseException { + + service.setDefaultAlgorithm(JWEAlgorithm.A128KW); + assertEquals(JWEAlgorithm.A128KW, service.getDefaultAlgorithm()); + + service.setDefaultAlgorithm(JWEAlgorithm.RSA_OAEP); + assertEquals(JWEAlgorithm.RSA_OAEP, service.getDefaultAlgorithm()); + } + + + @Test + public void runAfterPropertiesSet() throws NoSuchAlgorithmException, + InvalidKeySpecException, JOSEException { + + // TODO : Need more meaningful test here + service.afterPropertiesSet(); + } + + + @Test + public void getAllPubKeys() throws ParseException { + + Map keys2check = service_2.getAllPublicKeys(); + assertEquals( + JSONObjectUtils.getString(RSAjwk.toPublicJWK().toJSONObject(), "e"), + JSONObjectUtils.getString(keys2check.get(RSAkid).toJSONObject(), "e") + ); + assertEquals( + JSONObjectUtils.getString(RSAjwk_2.toPublicJWK().toJSONObject(), "e"), + JSONObjectUtils.getString(keys2check.get(RSAkid_2).toJSONObject(), "e") + ); + + assertTrue(service_3.getAllPublicKeys().isEmpty()); + } + + + @Test + public void getAllCryptoAlgsSupported() throws ParseException { + + assertTrue(service_4.getAllEncryptionAlgsSupported().contains(JWEAlgorithm.RSA_OAEP)); + assertTrue(service_4.getAllEncryptionAlgsSupported().contains(JWEAlgorithm.RSA1_5)); + assertTrue(service_4.getAllEncryptionAlgsSupported().contains(JWEAlgorithm.DIR)); + assertTrue(service_4.getAllEncryptionEncsSupported().contains(EncryptionMethod.A128CBC_HS256)); + assertTrue(service_4.getAllEncryptionEncsSupported().contains(EncryptionMethod.A128GCM)); + assertTrue(service_4.getAllEncryptionEncsSupported().contains(EncryptionMethod.A192CBC_HS384)); + assertTrue(service_4.getAllEncryptionEncsSupported().contains(EncryptionMethod.A192GCM)); + assertTrue(service_4.getAllEncryptionEncsSupported().contains(EncryptionMethod.A256GCM)); + assertTrue(service_4.getAllEncryptionEncsSupported().contains(EncryptionMethod.A256CBC_HS512)); + + assertTrue(service_ks.getAllEncryptionAlgsSupported().contains(JWEAlgorithm.RSA_OAEP)); + assertTrue(service_ks.getAllEncryptionAlgsSupported().contains(JWEAlgorithm.RSA1_5)); + assertTrue(service_ks.getAllEncryptionAlgsSupported().contains(JWEAlgorithm.DIR)); + assertTrue(service_ks.getAllEncryptionEncsSupported().contains(EncryptionMethod.A128CBC_HS256)); + assertTrue(service_ks.getAllEncryptionEncsSupported().contains(EncryptionMethod.A128GCM)); + assertTrue(service_ks.getAllEncryptionEncsSupported().contains(EncryptionMethod.A192CBC_HS384)); + assertTrue(service_ks.getAllEncryptionEncsSupported().contains(EncryptionMethod.A192GCM)); + assertTrue(service_ks.getAllEncryptionEncsSupported().contains(EncryptionMethod.A256GCM)); + assertTrue(service_ks.getAllEncryptionEncsSupported().contains(EncryptionMethod.A256CBC_HS512)); + } + + + @Test + public void getDefaultCryptoKeyId() throws ParseException { + + // Test set/getDefaultEn/DecryptionKeyId + + assertEquals(null, service_4.getDefaultEncryptionKeyId()); + assertEquals(null, service_4.getDefaultDecryptionKeyId()); + service_4.setDefaultEncryptionKeyId(RSAkid); + service_4.setDefaultDecryptionKeyId(AESkid); + assertEquals(RSAkid, service_4.getDefaultEncryptionKeyId()); + assertEquals(AESkid, service_4.getDefaultDecryptionKeyId()); + + assertEquals(null, service_ks.getDefaultEncryptionKeyId()); + assertEquals(null, service_ks.getDefaultDecryptionKeyId()); + service_ks.setDefaultEncryptionKeyId(RSAkid); + service_ks.setDefaultDecryptionKeyId(AESkid); + assertEquals( RSAkid, service_ks.getDefaultEncryptionKeyId()) ; + assertEquals(AESkid, service_ks.getDefaultDecryptionKeyId()); + } }