summaryrefslogtreecommitdiff
path: root/eaaf_core_utils
diff options
context:
space:
mode:
authorThomas <>2021-10-21 14:41:59 +0200
committerThomas <>2021-10-21 14:41:59 +0200
commit005a974e5ce0ff43c1f86e478dcd53f4e13823a4 (patch)
tree019f990a0e16c4e1b184e24212c96ba4b47a1f5c /eaaf_core_utils
parent1f8fc2851db3a03b9d3d731a568a7fcfe3846d74 (diff)
downloadEAAF-Components-005a974e5ce0ff43c1f86e478dcd53f4e13823a4.tar.gz
EAAF-Components-005a974e5ce0ff43c1f86e478dcd53f4e13823a4.tar.bz2
EAAF-Components-005a974e5ce0ff43c1f86e478dcd53f4e13823a4.zip
add jUnit tests for bPK and HSM-Facade encryption
Diffstat (limited to 'eaaf_core_utils')
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/builder/BpkBuilderTest.java73
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/EncryptionTask.java156
-rw-r--r--eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/KeyOperationPerformanceTest.java154
-rw-r--r--eaaf_core_utils/src/test/resources/spring/test_eaaf_pvp_lazy.beans.xml9
4 files changed, 392 insertions, 0 deletions
diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/builder/BpkBuilderTest.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/builder/BpkBuilderTest.java
index ccd452c5..bccab09f 100644
--- a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/builder/BpkBuilderTest.java
+++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/builder/BpkBuilderTest.java
@@ -1,12 +1,20 @@
package at.gv.egiz.eaaf.core.test.builder;
+import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.spec.ECGenParameterSpec;
import org.apache.commons.lang3.RandomStringUtils;
+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.Before;
import org.junit.Test;
@@ -34,11 +42,76 @@ public class BpkBuilderTest {
@Before
public void initialize() throws NoSuchAlgorithmException, NoSuchProviderException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
+ keyGen.initialize(2048);
keyPair = keyGen.generateKeyPair();
}
@Test
+ public void encBpkTextualLength() throws EaafBuilderException, InvalidKeyException, NoSuchAlgorithmException,
+ NoSuchProviderException, InvalidAlgorithmParameterException, JoseException {
+ String bpk = "MDEyMzQ1Njc4OWFiY2RIZg+CU";
+ String target = EaafConstants.URN_PREFIX_CDID + "AA";
+
+ printResult("Legacy RSA 1024:", BpkBuilder.encryptBpk(bpk, target, generateRsaPubKey(1024)));
+ printResult("Legacy RSA 2048:", BpkBuilder.encryptBpk(bpk, target, generateRsaPubKey(2048)));
+ printResult("Legacy RSA 3072:", BpkBuilder.encryptBpk(bpk, target, generateRsaPubKey(3072)));
+ printResult("Legacy RSA 4096:", BpkBuilder.encryptBpk(bpk, target, generateRsaPubKey(4096)));
+
+
+ bpk = "V1::urn:publicid:gv.at:cdid+BW::MDEyMzQ1Njc 4OW FiY2RIZg+CU&g=::2004-01-22T20:57:12";
+
+ printResult("RSA 2048:", createJsonEnc(generateRsaPubKey(2048), bpk, target,
+ KeyManagementAlgorithmIdentifiers.RSA_OAEP_256));
+ printResult("RSA 3072:", createJsonEnc(generateRsaPubKey(3072), bpk, target,
+ KeyManagementAlgorithmIdentifiers.RSA_OAEP_256));
+ printResult("RSA 4096:", createJsonEnc(generateRsaPubKey(4048), bpk, target,
+ KeyManagementAlgorithmIdentifiers.RSA_OAEP_256));
+
+ printResult("ECC 256:", createJsonEnc(generateEcPubKey("secp256r1"), bpk, target,
+ KeyManagementAlgorithmIdentifiers.ECDH_ES_A128KW));
+ printResult("ECC 384:", createJsonEnc(generateEcPubKey("secp384r1"), bpk, target,
+ KeyManagementAlgorithmIdentifiers.ECDH_ES_A128KW));
+ printResult("ECC 521:", createJsonEnc(generateEcPubKey("secp521r1"), bpk, target,
+ KeyManagementAlgorithmIdentifiers.ECDH_ES_A128KW));
+
+ System.out.println("Finished!");
+ }
+
+ private void printResult(String prefix, String body) {
+ System.out.println(prefix + " " + body.length() + " full:" + body);
+
+ }
+
+ private String createJsonEnc(PublicKey pubKey, String bpk, String target, String keyWrapAlg) throws JoseException {
+ JsonWebEncryption enc = new JsonWebEncryption();
+ enc.setKey(pubKey);
+ enc.setPayload(bpk);
+ enc.setAlgorithmHeaderValue(keyWrapAlg);
+ enc.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_128_GCM);
+ enc.setKeyIdHeaderValue("myFirstKey");
+ enc.setContentTypeHeaderValue(target);
+ return enc.getCompactSerialization();
+
+ }
+
+ private PublicKey generateRsaPubKey(int size) throws NoSuchAlgorithmException {
+ KeyPairGenerator keyGen3 = KeyPairGenerator.getInstance("RSA");
+ keyGen3.initialize(size);
+ return keyGen3.generateKeyPair().getPublic();
+
+ }
+
+ private PublicKey generateEcPubKey(String curve) throws NoSuchAlgorithmException,
+ NoSuchProviderException, InvalidAlgorithmParameterException {
+ KeyPairGenerator generator = KeyPairGenerator.getInstance("EC");
+ ECGenParameterSpec ecSpec = new ECGenParameterSpec(curve);
+ generator.initialize(ecSpec, new SecureRandom());
+ return generator.generateKeyPair().getPublic();
+
+ }
+
+ @Test
public void encBpkWrongTarget() throws InvalidKeyException {
String bpk = RandomStringUtils.randomAlphanumeric(25);
String target = RandomStringUtils.randomAlphanumeric(25);
diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/EncryptionTask.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/EncryptionTask.java
new file mode 100644
index 00000000..ac456c13
--- /dev/null
+++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/EncryptionTask.java
@@ -0,0 +1,156 @@
+package at.gv.egiz.eaaf.core.test.credentials;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import java.security.Provider;
+import java.util.concurrent.CompletableFuture;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Assert;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.AsyncResult;
+
+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.SymmetricKeyConfiguration;
+import at.gv.egiz.eaaf.core.impl.credential.SymmetricKeyConfiguration.SymmetricKeyType;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.core.impl.utils.Random;
+import at.gv.egiz.eaaf.core.test.dummy.DummyAuthConfigMap;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Getter
+public class EncryptionTask implements Runnable {
+
+ private static final String HSM_FACASE_HOST = "eid.a-sit.at";
+ private static final String HSM_FACASE_PORT = "9050";
+ private static final String HSM_FACASE_SSL_TRUST = "src/test/resources/data/hsm_facade_trust_root.crt";
+ private static final String HSM_FACASE_USERNAME = "authhandler-junit";
+ private static final String HSM_FACASE_PASSWORD = "supersecret123";
+ private static final String PATH_TO_SOFTWARE_KEYSTORE_JKS_WITH_TRUSTED_CERTS =
+ "src/test/resources/data/junit.jks";
+ private static final String PATH_TO_SOFTWARE_KEYSTORE_JKS =
+ "src/test/resources/data/junit_without_trustcerts.jks";
+ private static final String PATH_TO_SOFTWARE_KEYSTORE_PKCS12 =
+ "src/test/resources/data/junit_without_trustcerts.p12";
+ private static final String SOFTWARE_KEYSTORE_PASSWORD = "password";
+
+ private static final String HSM_FACADE_KEY_ALIAS = "authhandler-sign";
+
+ private static final String CIPHER_MODE = "AES/GCM/NoPadding";
+ private static final int GCM_NONCE_LENGTH = 12; // in bytes
+ private static final int GCM_TAG_LENGTH = 16; // in bytes
+
+ protected static final String KEYNAME = "AES";
+
+ @Autowired
+ private DummyAuthConfigMap mapConfig;
+ @Autowired
+ private ApplicationContext context;
+
+ String keyName;
+ int rounds;
+ private Exception error;
+
+ public EncryptionTask(ApplicationContext context2, DummyAuthConfigMap mapConfig2,
+ String keyName, int rounds) {
+ this.context = context2;
+ this.mapConfig = mapConfig2;
+
+ this.keyName = keyName;
+ this.rounds = rounds;
+
+ }
+
+ @Override
+ public void run() {
+ run(this.keyName, this.rounds);
+
+ }
+
+ @Async
+ public CompletableFuture<String> run(String keyName, int rounds) {
+ try {
+ Pair<SecretKey, Provider> key = loadSymmetricKey(keyName);
+ Assert.assertNotNull("Key container is null", key);
+
+ for(int i = 0; i < rounds; i++) {
+
+ log.info("Starting threat: {} Round: {}", Thread.currentThread().getName(), i);
+
+ byte[] data = RandomStringUtils.randomAlphanumeric(1024*64).getBytes();
+ Pair<byte[], byte[]> enc = encryptData(key.getFirst(), data);
+
+ byte[] checkData = decryptData(enc, key.getFirst());
+ log.info("Finishing threat: {} Round: {}", Thread.currentThread().getName(), i);
+
+
+ assertArrayEquals("plaintext not match", data, checkData);
+
+
+
+ }
+
+ } catch (Exception e) {
+ this.error = e;
+ throw new RuntimeException(e);
+
+ }
+
+ return new AsyncResult<>("finished").completable();
+
+ }
+
+ private byte[] decryptData(Pair<byte[], byte[]> enc, SecretKey secret) throws Exception {
+ final GCMParameterSpec iv = new GCMParameterSpec(GCM_TAG_LENGTH * 8, enc.getSecond());
+ final Cipher cipher = Cipher.getInstance(CIPHER_MODE);
+ cipher.init(Cipher.DECRYPT_MODE, secret, iv);
+ return cipher.doFinal(enc.getFirst());
+
+ }
+
+
+
+ private Pair<byte[], byte[]> encryptData(SecretKey secret, byte[] toEncrypt) throws Exception {
+ final byte[] nonce = Random.nextBytes(GCM_NONCE_LENGTH);
+ final GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, nonce);
+ final Cipher cipher = Cipher.getInstance(CIPHER_MODE);
+ cipher.init(Cipher.ENCRYPT_MODE, secret, spec);
+
+ final byte[] encdata = cipher.doFinal(toEncrypt);
+ final byte[] iv = cipher.getIV();
+
+ return Pair.newInstance(encdata, iv);
+
+ }
+
+ private Pair<SecretKey, Provider> loadSymmetricKey(String keyName) throws EaafException {
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_HOST, HSM_FACASE_HOST);
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_PORT, HSM_FACASE_PORT);
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_SSLTRUST, HSM_FACASE_SSL_TRUST);
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_USERNAME, HSM_FACASE_USERNAME);
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_PASSWORD, HSM_FACASE_PASSWORD);
+
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertTrue("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ SymmetricKeyConfiguration keyConfig = new SymmetricKeyConfiguration();
+ keyConfig.setFriendlyName("jUnit test");
+ keyConfig.setKeyType(SymmetricKeyType.HSMFACADE);
+ keyConfig.setKeyStoreName("authhandler");
+ keyConfig.setKeyAlias(keyName);
+
+ return keyStoreFactory.buildNewSymmetricKey(keyConfig);
+ }
+
+
+
+}
diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/KeyOperationPerformanceTest.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/KeyOperationPerformanceTest.java
new file mode 100644
index 00000000..c907301d
--- /dev/null
+++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/credentials/KeyOperationPerformanceTest.java
@@ -0,0 +1,154 @@
+package at.gv.egiz.eaaf.core.test.credentials;
+
+import static org.junit.Assert.assertFalse;
+
+import java.security.Provider;
+import java.security.Security;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.crypto.SecretKey;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.annotation.DirtiesContext.ClassMode;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import at.asitplus.hsmfacade.provider.HsmFacadeProvider;
+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.SymmetricKeyConfiguration;
+import at.gv.egiz.eaaf.core.impl.credential.SymmetricKeyConfiguration.SymmetricKeyType;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.core.test.dummy.DummyAuthConfigMap;
+import lombok.extern.slf4j.Slf4j;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("/spring/test_eaaf_pvp_lazy.beans.xml")
+@DirtiesContext(classMode = ClassMode.BEFORE_EACH_TEST_METHOD)
+@Slf4j
+public class KeyOperationPerformanceTest {
+
+ private static final String HSM_FACASE_HOST = "eid.a-sit.at";
+ private static final String HSM_FACASE_PORT = "9050";
+ private static final String HSM_FACASE_SSL_TRUST = "src/test/resources/data/hsm_facade_trust_root.crt";
+ private static final String HSM_FACASE_USERNAME = "authhandler-junit";
+ private static final String HSM_FACASE_PASSWORD = "supersecret123";
+ private static final String PATH_TO_SOFTWARE_KEYSTORE_JKS_WITH_TRUSTED_CERTS =
+ "src/test/resources/data/junit.jks";
+ private static final String PATH_TO_SOFTWARE_KEYSTORE_JKS =
+ "src/test/resources/data/junit_without_trustcerts.jks";
+ private static final String PATH_TO_SOFTWARE_KEYSTORE_PKCS12 =
+ "src/test/resources/data/junit_without_trustcerts.p12";
+ private static final String SOFTWARE_KEYSTORE_PASSWORD = "password";
+
+ private static final String HSM_FACADE_KEY_ALIAS = "authhandler-sign";
+
+ private static final String CIPHER_MODE = "AES/GCM/NoPadding";
+ private static final int GCM_NONCE_LENGTH = 12; // in bytes
+ private static final int GCM_TAG_LENGTH = 16; // in bytes
+
+ protected static final String KEYNAME = "AES";
+
+
+ private static final String AES_KEY_1 = "aes-key-1";
+ private static final String AES_KEY_2 = "aes-key-2";
+
+ private static final List<String> ALL_AES_KEYS = Arrays.asList(AES_KEY_1, AES_KEY_2);
+
+ @Autowired
+ private DummyAuthConfigMap mapConfig;
+ @Autowired
+ private ApplicationContext context;
+
+ /**
+ * jUnit test set-up.
+ */
+ @Before
+ public void testSetup() {
+ mapConfig.clearAllConfig();
+ Security.removeProvider(HsmFacadeProvider.getInstance().getName());
+
+ }
+
+ @Ignore
+ @Test
+ public void symmetricHsmFacadeKeyLoad() throws EaafException {
+ Pair<SecretKey, Provider> key = loadSymmetricKey(AES_KEY_1);
+ Assert.assertNotNull("Key container is null", key);
+ Assert.assertNotNull("Key is null", key.getFirst());
+ Assert.assertNotNull("Provider is null", key.getFirst());
+
+ }
+
+
+ @Ignore
+ @Test
+ public void symmetricHsmFacadeKeyOperations() throws Exception {
+ Pair<SecretKey, Provider> key = loadSymmetricKey(AES_KEY_1);
+ Assert.assertNotNull("Key container is null", key);
+ new EncryptionTask(context, mapConfig, AES_KEY_2, 15).run(AES_KEY_2, 15);
+
+ }
+
+ @Test
+ public void symmetricHsmFacadeMultithreatKeyOperations() throws Exception {
+ Pair<SecretKey, Provider> key = loadSymmetricKey(AES_KEY_1);
+ Assert.assertNotNull("Key container is null", key);
+
+ int threads = 30;
+
+ ArrayList<EncryptionTask> taskList = new ArrayList<EncryptionTask>();
+ ArrayList<Thread> threadList = new ArrayList<Thread>();
+ for(int i=0; i < threads; i++){
+ EncryptionTask task = new EncryptionTask(context, mapConfig, ALL_AES_KEYS.get(i % 2), 20);
+ taskList.add(task);
+ Thread t = new Thread(task);
+ threadList.add(t);
+ t.start();
+ }
+
+ // wait until they are all done
+ log.trace("Wait for mandate sources .... ");
+ for(int i=0; i<threadList.size(); i++){
+ threadList.get(i).join();
+ }
+ log.trace("Mandate sources collection finished ");
+
+
+ assertFalse("Find Thread with error", taskList.stream()
+ .filter(el -> el.getError() != null)
+ .findFirst()
+ .isPresent());
+
+
+ }
+
+ private Pair<SecretKey, Provider> loadSymmetricKey(String keyName) throws EaafException {
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_HOST, HSM_FACASE_HOST);
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_PORT, HSM_FACASE_PORT);
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_SSLTRUST, HSM_FACASE_SSL_TRUST);
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_USERNAME, HSM_FACASE_USERNAME);
+ mapConfig.putConfigValue(EaafKeyStoreFactory.CONFIG_PROP_HSM_FACADE_CLIENT_PASSWORD, HSM_FACASE_PASSWORD);
+
+ final EaafKeyStoreFactory keyStoreFactory = context.getBean(EaafKeyStoreFactory.class);
+ Assert.assertTrue("HSM Facade state wrong", keyStoreFactory.isHsmFacadeInitialized());
+
+ SymmetricKeyConfiguration keyConfig = new SymmetricKeyConfiguration();
+ keyConfig.setFriendlyName("jUnit test");
+ keyConfig.setKeyType(SymmetricKeyType.HSMFACADE);
+ keyConfig.setKeyStoreName("authhandler");
+ keyConfig.setKeyAlias(keyName);
+
+ return keyStoreFactory.buildNewSymmetricKey(keyConfig);
+ }
+
+}
diff --git a/eaaf_core_utils/src/test/resources/spring/test_eaaf_pvp_lazy.beans.xml b/eaaf_core_utils/src/test/resources/spring/test_eaaf_pvp_lazy.beans.xml
index 4af34b51..672efe5d 100644
--- a/eaaf_core_utils/src/test/resources/spring/test_eaaf_pvp_lazy.beans.xml
+++ b/eaaf_core_utils/src/test/resources/spring/test_eaaf_pvp_lazy.beans.xml
@@ -20,4 +20,13 @@
<bean id="eaafUtilsMessageSource"
class="at.gv.egiz.eaaf.core.impl.logging.EaafUtilsMessageSource" />
+ <bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
+ <property name="corePoolSize" value="5" />
+ <property name="maxPoolSize" value="25" />
+ <property name="queueCapacity" value="100" />
+ </bean>
+
+ <bean class="at.gv.egiz.eaaf.core.test.credentials.EncryptionTask"
+ scope="prototype"/>
+
</beans> \ No newline at end of file