diff options
author | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2020-06-22 09:00:57 +0200 |
---|---|---|
committer | Thomas Lenz <thomas.lenz@egiz.gv.at> | 2020-06-22 09:00:57 +0200 |
commit | 2b4d9dc8fcde4cdd5a13d9524b3a80a59376b4b8 (patch) | |
tree | 1cf12e71b1a88f6efa664eb241915d91191fcf26 /eaaf_modules/eaaf_module_auth_sl20/src/test/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/AbstractJsonSecurityUtilsTest.java | |
parent | dde5479553eb954e41fc8fe85abf45cf579d3034 (diff) | |
download | EAAF-Components-2b4d9dc8fcde4cdd5a13d9524b3a80a59376b4b8.tar.gz EAAF-Components-2b4d9dc8fcde4cdd5a13d9524b3a80a59376b4b8.tar.bz2 EAAF-Components-2b4d9dc8fcde4cdd5a13d9524b3a80a59376b4b8.zip |
fix problem with JOSE encryption in combination with HSM-Facade
add jUnit test for JoseUtils
Diffstat (limited to 'eaaf_modules/eaaf_module_auth_sl20/src/test/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/AbstractJsonSecurityUtilsTest.java')
-rw-r--r-- | eaaf_modules/eaaf_module_auth_sl20/src/test/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/AbstractJsonSecurityUtilsTest.java | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/test/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/AbstractJsonSecurityUtilsTest.java b/eaaf_modules/eaaf_module_auth_sl20/src/test/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/AbstractJsonSecurityUtilsTest.java new file mode 100644 index 00000000..ebea35c6 --- /dev/null +++ b/eaaf_modules/eaaf_module_auth_sl20/src/test/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/AbstractJsonSecurityUtilsTest.java @@ -0,0 +1,292 @@ +package at.gv.egiz.eaaf.modules.auth.sl20.utils; + +import java.io.IOException; +import java.security.Key; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.Provider; +import java.security.Security; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; + +import org.apache.commons.lang3.RandomStringUtils; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.jose4j.jca.ProviderContext; +import org.jose4j.jwa.AlgorithmConstraints; +import org.jose4j.jwa.AlgorithmConstraints.ConstraintType; +import org.jose4j.jwe.ContentEncryptionAlgorithmIdentifiers; +import org.jose4j.jwe.JsonWebEncryption; +import org.jose4j.jwe.KeyManagementAlgorithmIdentifiers; +import org.jose4j.lang.JoseException; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.fasterxml.jackson.databind.JsonNode; + +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory; +import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreUtils; +import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration; +import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType; +import at.gv.egiz.eaaf.core.impl.data.Pair; +import at.gv.egiz.eaaf.core.test.dummy.DummyAuthConfigMap; +import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("/spring/test_eaaf_sl20_hsm.beans.xml") +public abstract class AbstractJsonSecurityUtilsTest { + + @Autowired protected DummyAuthConfigMap config; + @Autowired protected IJoseTools joseTools; + @Autowired protected EaafKeyStoreFactory keyStoreFactory; + + @BeforeClass + public static void classInitializer() { + Security.addProvider(new BouncyCastleProvider()); + + } + + protected abstract void setRsaSigningKey(); + + protected abstract void setEcSigningKey(); + + protected abstract void setRsaEncryptionKey(); + + protected abstract void setEcEncryptionKey(); + + protected abstract Pair<KeyStore, Provider> getEncryptionKeyStore() throws EaafException; + + protected abstract String getRsaKeyAlias(); + + protected abstract String getRsaKeyPassword(); + + protected abstract String getEcKeyAlias(); + + protected abstract String getEcKeyPassword(); + + + @Test + public void fullEncryptDecrypt() throws JoseException, EaafException { + String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}"; + + final JsonWebEncryption jwe = new JsonWebEncryption(); + jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.ECDH_ES_A256KW); + jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_128_GCM); + jwe.setKey(joseTools.getEncryptionCertificate().getPublicKey()); + jwe.setX509CertSha256ThumbprintHeaderValue(joseTools.getEncryptionCertificate()); + jwe.setPayload(payLoad); + + // set special provider if required + Pair<KeyStore, Provider> rsaEncKeyStore = getEncryptionKeyStore(); + if (rsaEncKeyStore.getSecond() != null) { + final ProviderContext providerCtx = new ProviderContext(); + providerCtx.getSuppliedKeyProviderContext().setSignatureProvider( + rsaEncKeyStore.getSecond().getName()); + jwe.setProviderContext(providerCtx); + + } + + String encData = jwe.getCompactSerialization(); + Assert.assertNotNull("JWE Encryption", encData); + + + JsonNode decData = joseTools.decryptPayload(encData); + Assert.assertNotNull("JWE Decryption", decData); + + } + + @Test + public void encryptionRsa() throws JoseException, EaafException { + String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}"; + Pair<KeyStore, Provider> rsaEncKeyStore = getEncryptionKeyStore(); + Pair<Key, X509Certificate[]> key = EaafKeyStoreUtils.getPrivateKeyAndCertificates( + rsaEncKeyStore.getFirst(), getRsaKeyAlias(), getRsaKeyPassword().toCharArray(), + true, "jUnit RSA JWE"); + + final JsonWebEncryption jwe = new JsonWebEncryption(); + jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.RSA_OAEP_256); + jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_128_GCM); + jwe.setKey(key.getSecond()[0].getPublicKey()); + jwe.setPayload(payLoad); + + // set special provider if required + if (rsaEncKeyStore.getSecond() != null) { + final ProviderContext providerCtx = new ProviderContext(); + providerCtx.getSuppliedKeyProviderContext().setSignatureProvider( + rsaEncKeyStore.getSecond().getName()); + jwe.setProviderContext(providerCtx); + + } + + String encData = jwe.getCompactSerialization(); + Assert.assertNotNull("JWE", encData); + + + } + + @Test + public void encryptionEc() throws JoseException, EaafException { + String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}"; + Pair<KeyStore, Provider> rsaEncKeyStore = getEncryptionKeyStore(); + Pair<Key, X509Certificate[]> key = EaafKeyStoreUtils.getPrivateKeyAndCertificates( + rsaEncKeyStore.getFirst(), getEcKeyAlias(), getEcKeyPassword().toCharArray(), + true, "jUnit RSA JWE"); + + final JsonWebEncryption jwe = new JsonWebEncryption(); + jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.ECDH_ES_A256KW); + jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_128_GCM); + jwe.setKey(key.getSecond()[0].getPublicKey()); + jwe.setPayload(payLoad); + + // set special provider if required + if (rsaEncKeyStore.getSecond() != null) { + final ProviderContext providerCtx = new ProviderContext(); + providerCtx.getSuppliedKeyProviderContext().setSignatureProvider( + rsaEncKeyStore.getSecond().getName()); + jwe.setProviderContext(providerCtx); + + } + + String encData = jwe.getCompactSerialization(); + + Assert.assertNotNull("JWE", encData); + + + } + + + @Test + public void noTrustedCert() throws CertificateEncodingException, KeyStoreException, + JoseException, IOException, EaafException { + setRsaSigningKey(); + setRsaEncryptionKey(); + + String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}"; + + String jws = joseTools.createSignature(payLoad); + Assert.assertNotNull("Signed msg", jws); + + try { + joseTools.validateSignature( + jws, + keyStoreFactory.buildNewKeyStore(getSigTrustStoreConfigOnlyEc()).getFirst(), + getDefaultAlgorithmConstrains()); + Assert.fail("Wrong JOSE Sig not detected"); + + } catch (JoseException e) { + Assert.assertEquals("Wrong errorCode", + "Can NOT select verification key for JWS. Signature verification FAILED", + e.getMessage()); + + } + } + + @Test + public void invalidSignature() throws CertificateEncodingException, KeyStoreException, + JoseException, IOException, EaafException { + setRsaSigningKey(); + setRsaEncryptionKey(); + + String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}"; + + String jws = joseTools.createSignature(payLoad); + Assert.assertNotNull("Signed msg", jws); + + String invalidJws = + jws.substring(0, jws.indexOf(".") + 5) + "dd" + jws.substring(jws.indexOf(".") + 6); + + try { + joseTools.validateSignature( + invalidJws, + keyStoreFactory.buildNewKeyStore(getSigTrustStoreConfigValid()).getFirst(), + getDefaultAlgorithmConstrains()); + Assert.fail("Wrong JOSE Sig not detected"); + + } catch (JoseException e) { + Assert.assertEquals("Wrong errorCode", + "JWS signature is invalid.", + e.getMessage()); + + } + + } + + @Test + public void validSigningRsa() throws CertificateEncodingException, KeyStoreException, + JoseException, IOException, EaafException { + setRsaSigningKey(); + setRsaEncryptionKey(); + + String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}"; + + String jws = joseTools.createSignature(payLoad); + Assert.assertNotNull("Signed msg", jws); + + VerificationResult verify = joseTools.validateSignature( + jws, + keyStoreFactory.buildNewKeyStore(getSigTrustStoreConfigValid()).getFirst(), + getDefaultAlgorithmConstrains()); + Assert.assertTrue("wrong verify state", verify.isValidSigned()); + Assert.assertNotNull("JWS Header", verify.getJoseHeader()); + Assert.assertNotNull("JWS Payload", verify.getPayload()); + Assert.assertNotNull("CertChain", verify.getCertChain()); + + + } + + @Test + public void validSigningEc() throws CertificateEncodingException, KeyStoreException, + JoseException, IOException, EaafException { + setEcSigningKey(); + setEcEncryptionKey(); + + String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}"; + + String jws = joseTools.createSignature(payLoad); + Assert.assertNotNull("Signed msg", jws); + + VerificationResult verify = joseTools.validateSignature( + jws, + keyStoreFactory.buildNewKeyStore(getSigTrustStoreConfigValid()).getFirst(), + getDefaultAlgorithmConstrains()); + Assert.assertTrue("wrong verify state", verify.isValidSigned()); + Assert.assertNotNull("JWS Header", verify.getJoseHeader()); + Assert.assertNotNull("JWS Payload", verify.getPayload()); + Assert.assertNotNull("CertChain", verify.getCertChain()); + + } + + protected KeyStoreConfiguration getSigTrustStoreConfigValid() { + KeyStoreConfiguration trustConfig = new KeyStoreConfiguration(); + trustConfig.setFriendlyName("jUnit TrustStore"); + trustConfig.setKeyStoreType(KeyStoreType.JKS); + trustConfig.setSoftKeyStoreFilePath("src/test/resources/data/junit.jks"); + trustConfig.setSoftKeyStorePassword("password"); + + return trustConfig; + + } + + protected KeyStoreConfiguration getSigTrustStoreConfigOnlyEc() { + KeyStoreConfiguration trustConfig = new KeyStoreConfiguration(); + trustConfig.setFriendlyName("jUnit TrustStore"); + trustConfig.setKeyStoreType(KeyStoreType.JKS); + trustConfig.setSoftKeyStoreFilePath("src/test/resources/data/junit_no_rsa.jks"); + trustConfig.setSoftKeyStorePassword("password"); + + return trustConfig; + + } + + private AlgorithmConstraints getDefaultAlgorithmConstrains() { + return new AlgorithmConstraints(ConstraintType.WHITELIST, + SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING + .toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING.size()])); + } + +} |