summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2020-08-26 16:21:39 +0200
committerThomas Lenz <thomas.lenz@egiz.gv.at>2020-08-26 16:21:39 +0200
commitbe7b4a37fb0844e9f1b9ed91742af3d204f68f22 (patch)
tree29f7db190f647ab35905784c805cfefb9c73abba
parent4d49513b7c28197b6c767e79e510db18ba73acb5 (diff)
downloadEAAF-Components-be7b4a37fb0844e9f1b9ed91742af3d204f68f22.tar.gz
EAAF-Components-be7b4a37fb0844e9f1b9ed91742af3d204f68f22.tar.bz2
EAAF-Components-be7b4a37fb0844e9f1b9ed91742af3d204f68f22.zip
refactor JWS and JWE implementation in SL2.0 module to reuse JWS and JWE specific implementation in other classes
-rw-r--r--eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/exception/EaafKeyUsageException.java21
-rw-r--r--eaaf_core_utils/src/main/resources/messages/eaaf_utils_message.properties1
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java36
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/EventCodes.java2
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JoseUtils.java308
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java203
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/test/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/AbstractJsonSecurityUtilsTest.java250
-rw-r--r--eaaf_modules/eaaf_module_auth_sl20/src/test/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtilsHsmKeyTest.java34
8 files changed, 557 insertions, 298 deletions
diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/exception/EaafKeyUsageException.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/exception/EaafKeyUsageException.java
new file mode 100644
index 00000000..8b4e68a4
--- /dev/null
+++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/exception/EaafKeyUsageException.java
@@ -0,0 +1,21 @@
+package at.gv.egiz.eaaf.core.exception;
+
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+
+public class EaafKeyUsageException extends EaafException {
+
+ private static final long serialVersionUID = -2641273589744430903L;
+
+ public static final String ERROR_CODE_01 = "internal.key.01";
+
+ public EaafKeyUsageException(String errorCode, String... params) {
+ super(errorCode, new Object[] {params});
+
+ }
+
+ public EaafKeyUsageException(String errorCode, Throwable e, String... params) {
+ super(errorCode, new Object[] {params}, e);
+
+ }
+
+}
diff --git a/eaaf_core_utils/src/main/resources/messages/eaaf_utils_message.properties b/eaaf_core_utils/src/main/resources/messages/eaaf_utils_message.properties
index 572a3f5a..6f1b1f94 100644
--- a/eaaf_core_utils/src/main/resources/messages/eaaf_utils_message.properties
+++ b/eaaf_core_utils/src/main/resources/messages/eaaf_utils_message.properties
@@ -14,6 +14,7 @@ internal.keystore.09=Can not access Key: {1} in KeyStore: {0} Reason: {2}
internal.keystore.10=HSM-Facade NOT INITIALIZED. Find HSM-Facade class: {0} put that looks WRONG.
internal.key.00=Can not generate passphrase based symmetric-key: {0} Reason: {1}
+internal.key.01=Can not use key from Keystore: {0} Reason: {1}
internal.httpclient.00=HttpClient:{0} uses http Basic-Auth, but 'Username' is NOT set
internal.httpclient.01=HttpClient:{0} uses X509 client-auth, but 'KeyStoreConfig' is NOT set
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java
index 11fd41fb..74d67d01 100644
--- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/Constants.java
@@ -7,37 +7,41 @@ public class Constants {
public static final String CONFIG_PROP_VDA_AUTHBLOCK_TRANSFORMATION_ID = CONFIG_PROP_PREFIX
+ ".vda.authblock.transformation.id";
-
+
//KeyStore configuration
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_TYPE =
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_TYPE =
CONFIG_PROP_PREFIX + ".security.keystore.type";
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_NAME =
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_NAME =
CONFIG_PROP_PREFIX + ".security.keystore.name";
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_PATH =
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_PATH =
CONFIG_PROP_PREFIX + ".security.keystore.path";
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_PASSWORD =
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_PASSWORD =
CONFIG_PROP_PREFIX + ".security.keystore.password";
-
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS =
+
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS =
CONFIG_PROP_PREFIX + ".security.sign.alias";
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD =
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD =
CONFIG_PROP_PREFIX + ".security.sign.password";
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_ALIAS =
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_ALIAS =
CONFIG_PROP_PREFIX + ".security.encryption.alias";
- public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD =
+ public static final String CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD =
CONFIG_PROP_PREFIX + ".security.encryption.password";
//TrustStore configuration
- public static final String CONFIG_PROP_SECURITY_TRUSTSTORE_TYPE =
+ public static final String CONFIG_PROP_SECURITY_TRUSTSTORE_TYPE =
CONFIG_PROP_PREFIX + ".security.truststore.type";
- public static final String CONFIG_PROP_SECURITY_TRUSTSTORE_NAME =
+ public static final String CONFIG_PROP_SECURITY_TRUSTSTORE_NAME =
CONFIG_PROP_PREFIX + ".security.truststore.name";
- public static final String CONFIG_PROP_SECURITY_TRUSTSTORE_PATH =
+ public static final String CONFIG_PROP_SECURITY_TRUSTSTORE_PATH =
CONFIG_PROP_PREFIX + ".security.truststore.path";
- public static final String CONFIG_PROP_SECURITY_TRUSTSTORE_PASSWORD =
+ public static final String CONFIG_PROP_SECURITY_TRUSTSTORE_PASSWORD =
CONFIG_PROP_PREFIX + ".security.truststore.password";
-
-
+
+ public static final String CONFIG_PROP_SECURITY_SIG_ALG_RSA =
+ CONFIG_PROP_PREFIX + ".security.sigalg.rsa";
+ public static final String CONFIG_PROP_SECURITY_SIG_ALG_ECC =
+ CONFIG_PROP_PREFIX + ".security.sigalg.ecc";
+
public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT_ELEMENT = "default";
public static final String CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT = CONFIG_PROP_VDA_ENDPOINT_QUALeID
+ CONFIG_PROP_VDA_ENDPOINT_QUALeID_DEFAULT_ELEMENT;
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/EventCodes.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/EventCodes.java
index af155206..62779072 100644
--- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/EventCodes.java
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/EventCodes.java
@@ -12,5 +12,5 @@ public class EventCodes {
public static final int AUTHPROCESS_SL20_ENDPOINT_URL = 4112;
public static final int AUTHPROCESS_SL20_DATAURL_IP = 4113;
- public static final int AUTHPROCESS_SL20_CONSENT_VALID = 4113;
+ public static final int AUTHPROCESS_SL20_CONSENT_VALID = 4114;
}
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JoseUtils.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JoseUtils.java
new file mode 100644
index 00000000..d8c39931
--- /dev/null
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JoseUtils.java
@@ -0,0 +1,308 @@
+package at.gv.egiz.eaaf.modules.auth.sl20.utils;
+
+import java.io.IOException;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.annotation.Nonnull;
+
+import at.gv.egiz.eaaf.core.exception.EaafKeyUsageException;
+import at.gv.egiz.eaaf.core.exceptions.EaafException;
+import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreUtils;
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.core.impl.utils.X509Utils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.jose4j.jca.ProviderContext;
+import org.jose4j.jwa.AlgorithmConstraints;
+import org.jose4j.jws.AlgorithmIdentifiers;
+import org.jose4j.jws.JsonWebSignature;
+import org.jose4j.jwx.Headers;
+import org.jose4j.jwx.JsonWebStructure;
+import org.jose4j.keys.resolvers.X509VerificationKeyResolver;
+import org.jose4j.lang.JoseException;
+import org.springframework.util.Base64Utils;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * {@link JoseUtils} provides static methods JWS and JWE processing.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+public class JoseUtils {
+
+ /**
+ * Create a JWS signature.
+ *
+ * <p>
+ * Use {@link org.jose4j.jws.AlgorithmIdentifiers.RSA_PSS_USING_SHA256} in case
+ * of a RSA based key and
+ * {@link org.jose4j.jws.AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256}
+ * in case of an ECC based key.
+ * </p>
+ *
+ * @param keyStore KeyStore that should be used
+ * @param keyAlias Alias of the private key
+ * @param keyPassword Password to access the key
+ * @param payLoad PayLoad to sign
+ * @param addFullCertChain If true the full certificate chain will be
+ * added, otherwise only the
+ * X509CertSha256Fingerprint is added into JOSE
+ * header
+ * @param friendlyNameForLogging FriendlyName for the used KeyStore for logging
+ * purposes only
+ * @return Signed PayLoad in serialized form
+ * @throws EaafException In case of a key-access or key-usage error
+ * @throws JoseException In case of a JOSE error
+ */
+ public static String createSignature(@Nonnull Pair<KeyStore, Provider> keyStore,
+ @Nonnull final String keyAlias, @Nonnull final char[] keyPassword,
+ @Nonnull final String payLoad, boolean addFullCertChain,
+ @Nonnull String friendlyNameForLogging) throws EaafException, JoseException {
+ return createSignature(keyStore, keyAlias, keyPassword, payLoad, addFullCertChain, Collections.emptyMap(),
+ AlgorithmIdentifiers.RSA_PSS_USING_SHA256, AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256,
+ friendlyNameForLogging);
+
+ }
+
+ /**
+ * Create a JWS signature.
+ *
+ * <p>
+ * Use {@link org.jose4j.jws.AlgorithmIdentifiers.RSA_PSS_USING_SHA256} in case
+ * of a RSA based key and
+ * {@link org.jose4j.jws.AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256}
+ * in case of an ECC based key.
+ * </p>
+ *
+ * @param keyStore KeyStore that should be used
+ * @param keyAlias Alias of the private key
+ * @param keyPassword Password to access the key
+ * @param payLoad PayLoad to sign
+ * @param addFullCertChain If true the full certificate chain will be
+ * added, otherwise only the
+ * X509CertSha256Fingerprint is added into JOSE
+ * header
+ * @param joseHeaders HeaderName and HeaderValue that should be set
+ * into JOSE header
+ * @param friendlyNameForLogging FriendlyName for the used KeyStore for logging
+ * purposes only
+ * @return Signed PayLoad in serialized form
+ * @throws EaafException In case of a key-access or key-usage error
+ * @throws JoseException In case of a JOSE error
+ */
+ public static String createSignature(@Nonnull Pair<KeyStore, Provider> keyStore,
+ @Nonnull final String keyAlias, @Nonnull final char[] keyPassword,
+ @Nonnull final String payLoad, boolean addFullCertChain,
+ @Nonnull final Map<String, String> joseHeaders,
+ @Nonnull String friendlyNameForLogging) throws EaafException, JoseException {
+ return createSignature(keyStore, keyAlias, keyPassword, payLoad, addFullCertChain, joseHeaders,
+ AlgorithmIdentifiers.RSA_PSS_USING_SHA256, AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256,
+ friendlyNameForLogging);
+
+ }
+
+ /**
+ * Create a JWS signature.
+ *
+ * @param keyStore KeyStore that should be used
+ * @param keyAlias Alias of the private key
+ * @param keyPassword Password to access the key
+ * @param payLoad PayLoad to sign
+ * @param addFullCertChain If true the full certificate chain will be
+ * added, otherwise only the
+ * X509CertSha256Fingerprint is added into JOSE
+ * header
+ * @param joseHeaders HeaderName and HeaderValue that should be set
+ * into JOSE header
+ * @param rsaAlgToUse Signing algorithm that should be used in case
+ * of a signing key based on RSA
+ * @param eccAlgToUse Signing algorithm that should be used in case
+ * of a signing key based on ECC
+ * @param friendlyNameForLogging FriendlyName for the used KeyStore for logging
+ * purposes only
+ * @return Signed PayLoad in serialized form
+ * @throws EaafException In case of a key-access or key-usage error
+ * @throws JoseException In case of a JOSE error
+ */
+ public static String createSignature(@Nonnull Pair<KeyStore, Provider> keyStore,
+ @Nonnull final String keyAlias, @Nonnull final char[] keyPassword,
+ @Nonnull final String payLoad, boolean addFullCertChain,
+ @Nonnull final Map<String, String> joseHeaders,
+ @Nonnull final String rsaAlgToUse, @Nonnull final String eccAlgToUse,
+ @Nonnull String friendlyNameForLogging) throws EaafException, JoseException {
+
+ final JsonWebSignature jws = new JsonWebSignature();
+
+ // set payload
+ jws.setPayload(payLoad);
+
+ // set JOSE headers
+ for (final Entry<String, String> el : joseHeaders.entrySet()) {
+ log.trace("Set JOSE header: {} with value: {} into JWS", el.getKey(), el.getValue());
+ jws.setHeader(el.getKey(), el.getValue());
+
+ }
+
+ // set signing information
+ final Pair<Key, X509Certificate[]> signingCred = EaafKeyStoreUtils.getPrivateKeyAndCertificates(
+ keyStore.getFirst(), keyAlias, keyPassword, true, friendlyNameForLogging);
+ jws.setKey(signingCred.getFirst());
+ jws.setAlgorithmHeaderValue(getKeyOperationAlgorithmFromCredential(
+ jws.getKey(), rsaAlgToUse, eccAlgToUse, friendlyNameForLogging));
+
+ // set special provider if required
+ if (keyStore.getSecond() != null) {
+ log.trace("Injecting special Java Security Provider: {}", keyStore.getSecond().getName());
+ final ProviderContext providerCtx = new ProviderContext();
+ providerCtx.getSuppliedKeyProviderContext().setSignatureProvider(
+ keyStore.getSecond().getName());
+ jws.setProviderContext(providerCtx);
+
+ }
+
+ if (addFullCertChain) {
+ jws.setCertificateChainHeaderValue(signingCred.getSecond());
+
+ }
+
+ jws.setX509CertSha256ThumbprintHeaderValue(signingCred.getSecond()[0]);
+
+ return jws.getCompactSerialization();
+
+ }
+
+ /**
+ * Verify a JOSE signature.
+ *
+ * @param serializedContent Serialized content that should be verified
+ * @param trustedCerts Trusted certificates that should be used for
+ * verification
+ * @param constraints {@link AlgorithmConstraints} for verification
+ * @return {@link JwsResult} object
+ * @throws JoseException In case of a signature verification error
+ * @throws IOException In case of a general error
+ */
+ public static JwsResult validateSignature(@Nonnull final String serializedContent,
+ @Nonnull final List<X509Certificate> trustedCerts, @Nonnull final AlgorithmConstraints constraints)
+ throws JoseException, IOException {
+ final JsonWebSignature jws = new JsonWebSignature();
+ // set payload
+ jws.setCompactSerialization(serializedContent);
+
+ // set security constrains
+ jws.setAlgorithmConstraints(constraints);
+
+ // load signinc certs
+ Key selectedKey = null;
+ final List<X509Certificate> x5cCerts = jws.getCertificateChainHeaderValue();
+ final String x5t256 = jws.getX509CertSha256ThumbprintHeaderValue();
+ if (x5cCerts != null) {
+ log.debug("Found x509 certificate in JOSE header ... ");
+ log.trace("Sorting received X509 certificates ... ");
+ final List<X509Certificate> sortedX5cCerts = X509Utils.sortCertificates(x5cCerts);
+
+ if (trustedCerts.contains(sortedX5cCerts.get(0))) {
+ selectedKey = sortedX5cCerts.get(0).getPublicKey();
+
+ } else {
+ log.info("Can NOT find JOSE certificate in truststore.");
+ if (log.isDebugEnabled()) {
+ try {
+ log.debug("Cert: {}", Base64Utils.encodeToString(sortedX5cCerts.get(0).getEncoded()));
+
+ } catch (final CertificateEncodingException e) {
+ log.warn("Can not create DEBUG output", e);
+
+ }
+ }
+ }
+
+ } else if (StringUtils.isNotEmpty(x5t256)) {
+ log.debug("Found x5t256 fingerprint in JOSE header .... ");
+ final X509VerificationKeyResolver x509VerificationKeyResolver = new X509VerificationKeyResolver(
+ trustedCerts);
+ selectedKey = x509VerificationKeyResolver.resolveKey(jws, Collections.<JsonWebStructure>emptyList());
+
+ } else {
+ throw new JoseException("JWS contains NO signature certificate or NO certificate fingerprint");
+
+ }
+
+ if (selectedKey == null) {
+ throw new JoseException("Can NOT select verification key for JWS. Signature verification FAILED");
+
+ }
+
+ // set verification key
+ jws.setKey(selectedKey);
+
+ // load payLoad
+ return new JwsResult(
+ jws.verifySignature(),
+ jws.getUnverifiedPayload(),
+ jws.getHeaders(),
+ x5cCerts);
+
+ }
+
+ /**
+ * Select signature algorithm for a given credential.
+ *
+ * @param key {@link X509Credential} that will be used for
+ * key operations
+ * @param rsaSigAlgorithm RSA based algorithm that should be used in case
+ * of RSA credential
+ * @param ecSigAlgorithm EC based algorithm that should be used in case
+ * of RSA credential
+ * @param friendlyNameForLogging KeyStore friendlyName for logging purposes
+ * @return either the RSA based algorithm or the EC based algorithm
+ * @throws EaafKeyUsageException In case of an unsupported private-key type
+ */
+ private static String getKeyOperationAlgorithmFromCredential(Key key,
+ String rsaSigAlgorithm, String ecSigAlgorithm, String friendlyNameForLogging)
+ throws EaafKeyUsageException {
+ if (key instanceof RSAPrivateKey) {
+ return rsaSigAlgorithm;
+
+ } else if (key instanceof ECPrivateKey) {
+ return ecSigAlgorithm;
+
+ } else {
+ log.warn("Could NOT select the cryptographic algorithm from Private-Key type");
+ throw new EaafKeyUsageException(EaafKeyUsageException.ERROR_CODE_01,
+ friendlyNameForLogging,
+ "Can not select cryptographic algorithm");
+
+ }
+
+ }
+
+ private JoseUtils() {
+
+ }
+
+ @Getter
+ @AllArgsConstructor
+ public static class JwsResult {
+ final boolean valid;
+ final String payLoad;
+ final Headers fullJoseHeader;
+ final List<X509Certificate> x5cCerts;
+
+ }
+}
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java
index dae11370..10cfeafa 100644
--- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtils.java
@@ -7,24 +7,38 @@ import java.security.KeyStoreException;
import java.security.Provider;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.RSAPrivateKey;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.exception.EaafKeyAccessException;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+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.impl.utils.X509Utils;
+import at.gv.egiz.eaaf.modules.auth.sl20.Constants;
+import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult;
+import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception;
+import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20SecurityException;
+import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoBuildException;
+import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoParserException;
+import at.gv.egiz.eaaf.modules.auth.sl20.utils.JoseUtils.JwsResult;
+
import org.apache.commons.lang3.StringUtils;
import org.jose4j.jca.ProviderContext;
import org.jose4j.jwa.AlgorithmConstraints;
import org.jose4j.jwa.AlgorithmConstraints.ConstraintType;
import org.jose4j.jwe.JsonWebEncryption;
import org.jose4j.jws.AlgorithmIdentifiers;
-import org.jose4j.jws.JsonWebSignature;
-import org.jose4j.jwx.JsonWebStructure;
+import org.jose4j.jwx.HeaderParameterNames;
import org.jose4j.keys.X509Util;
-import org.jose4j.keys.resolvers.X509VerificationKeyResolver;
import org.jose4j.lang.JoseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,22 +50,6 @@ import org.springframework.util.Base64Utils;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonNode;
-import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
-import at.gv.egiz.eaaf.core.exception.EaafKeyAccessException;
-import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
-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.impl.utils.X509Utils;
-import at.gv.egiz.eaaf.modules.auth.sl20.Constants;
-import at.gv.egiz.eaaf.modules.auth.sl20.data.VerificationResult;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20Exception;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SL20SecurityException;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoBuildException;
-import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoParserException;
-
@Service
public class JsonSecurityUtils implements IJoseTools {
private static final Logger log = LoggerFactory.getLogger(JsonSecurityUtils.class);
@@ -127,41 +125,16 @@ public class JsonSecurityUtils implements IJoseTools {
@Override
public String createSignature(final String payLoad, boolean addFullCertChain) throws SlCommandoBuildException {
try {
- final JsonWebSignature jws = new JsonWebSignature();
-
- // set payload
- jws.setPayload(payLoad);
-
- // set basic header
- jws.setContentTypeHeaderValue(SL20Constants.SL20_CONTENTTYPE_SIGNED_COMMAND);
-
- // set signing information
- final Pair<Key, X509Certificate[]> signingCred = EaafKeyStoreUtils.getPrivateKeyAndCertificates(
- keyStore.getFirst(), getSigningKeyAlias(), getSigningKeyPassword(), true, FRIENDLYNAME_KEYSTORE);
- jws.setKey(signingCred.getFirst());
- jws.setAlgorithmHeaderValue(getKeyOperationAlgorithmFromCredential(jws.getKey(),
- AlgorithmIdentifiers.RSA_USING_SHA256, AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256));
-
- // set special provider if required
- if (keyStore.getSecond() != null) {
- log.trace("Injecting special Java Security Provider: {}", keyStore.getSecond().getName());
- final ProviderContext providerCtx = new ProviderContext();
- providerCtx.getSuppliedKeyProviderContext().setSignatureProvider(
- keyStore.getSecond().getName());
- jws.setProviderContext(providerCtx);
-
- }
-
- if (addFullCertChain) {
- jws.setCertificateChainHeaderValue(signingCred.getSecond());
-
- }
-
- jws.setX509CertSha256ThumbprintHeaderValue(signingCred.getSecond()[0]);
-
- return jws.getCompactSerialization();
+ return JoseUtils.createSignature(keyStore, getSigningKeyAlias(), getSigningKeyPassword(),
+ payLoad, addFullCertChain,
+ Collections.singletonMap(
+ HeaderParameterNames.CONTENT_TYPE,
+ SL20Constants.SL20_CONTENTTYPE_SIGNED_COMMAND),
+ getRsaSigningAlgorithm(),
+ getEccSigningAlgorithm(),
+ FRIENDLYNAME_KEYSTORE);
- } catch (final JoseException | EaafKeyAccessException e) {
+ } catch (final JoseException | EaafException e) {
log.warn("Can NOT sign SL2.0 command.", e);
throw new SlCommandoBuildException("Can NOT sign SL2.0 command.", e);
@@ -182,61 +155,12 @@ public class JsonSecurityUtils implements IJoseTools {
public VerificationResult validateSignature(@Nonnull final String serializedContent,
@Nonnull final List<X509Certificate> trustedCerts, @Nonnull final AlgorithmConstraints constraints)
throws JoseException, IOException {
- final JsonWebSignature jws = new JsonWebSignature();
- // set payload
- jws.setCompactSerialization(serializedContent);
-
- // set security constrains
- jws.setAlgorithmConstraints(constraints);
-
- // load signinc certs
- Key selectedKey = null;
- final List<X509Certificate> x5cCerts = jws.getCertificateChainHeaderValue();
- final String x5t256 = jws.getX509CertSha256ThumbprintHeaderValue();
- if (x5cCerts != null) {
- log.debug("Found x509 certificate in JOSE header ... ");
- log.trace("Sorting received X509 certificates ... ");
- final List<X509Certificate> sortedX5cCerts = X509Utils.sortCertificates(x5cCerts);
-
- if (trustedCerts.contains(sortedX5cCerts.get(0))) {
- selectedKey = sortedX5cCerts.get(0).getPublicKey();
-
- } else {
- log.info("Can NOT find JOSE certificate in truststore.");
- try {
- log.debug("Cert: " + Base64Utils.encodeToString(sortedX5cCerts.get(0).getEncoded()));
-
- } catch (final CertificateEncodingException e) {
- e.printStackTrace();
-
- }
-
- }
-
- } else if (StringUtils.isNotEmpty(x5t256)) {
- log.debug("Found x5t256 fingerprint in JOSE header .... ");
- final X509VerificationKeyResolver x509VerificationKeyResolver = new X509VerificationKeyResolver(
- trustedCerts);
- selectedKey = x509VerificationKeyResolver.resolveKey(jws, Collections.<JsonWebStructure>emptyList());
-
- } else {
- throw new JoseException("JWS contains NO signature certificate or NO certificate fingerprint");
-
- }
-
- if (selectedKey == null) {
- throw new JoseException("Can NOT select verification key for JWS. Signature verification FAILED");
-
- }
-
- // set verification key
- jws.setKey(selectedKey);
- // load payLoad
+ final JwsResult result = JoseUtils.validateSignature(serializedContent, trustedCerts, constraints);
return new VerificationResult(
- mapper.getMapper().readTree(jws.getHeaders().getFullHeaderAsJsonString()),
- mapper.getMapper().readTree(jws.getPayload()),
- x5cCerts, jws.verifySignature());
+ mapper.getMapper().readTree(result.getFullJoseHeader().getFullHeaderAsJsonString()),
+ mapper.getMapper().readTree(result.getPayLoad()),
+ result.getX5cCerts(), result.isValid());
}
@@ -244,7 +168,7 @@ public class JsonSecurityUtils implements IJoseTools {
@Nonnull
public VerificationResult validateSignature(@Nonnull final String serializedContent) throws SL20Exception {
try {
- final AlgorithmConstraints algConstraints = new AlgorithmConstraints(ConstraintType.WHITELIST,
+ final AlgorithmConstraints algConstraints = new AlgorithmConstraints(ConstraintType.PERMIT,
SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING
.toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING.size()]));
@@ -254,7 +178,7 @@ public class JsonSecurityUtils implements IJoseTools {
if (!result.isValidSigned()) {
log.info("JWS signature invalide. Stopping authentication process ...");
- log.debug("Received JWS msg: " + serializedContent);
+ log.debug("Received JWS msg: {}", serializedContent);
throw new SL20SecurityException("JWS signature invalide.");
}
@@ -281,11 +205,11 @@ public class JsonSecurityUtils implements IJoseTools {
// set security constrains
receiverJwe.setAlgorithmConstraints(
- new AlgorithmConstraints(ConstraintType.WHITELIST,
+ new AlgorithmConstraints(ConstraintType.PERMIT,
SL20Constants.SL20_ALGORITHM_WHITELIST_KEYENCRYPTION
.toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_KEYENCRYPTION.size()])));
receiverJwe.setContentEncryptionAlgorithmConstraints(
- new AlgorithmConstraints(ConstraintType.WHITELIST, SL20Constants.SL20_ALGORITHM_WHITELIST_ENCRYPTION
+ new AlgorithmConstraints(ConstraintType.PERMIT, SL20Constants.SL20_ALGORITHM_WHITELIST_ENCRYPTION
.toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_ENCRYPTION.size()])));
// set payload
@@ -304,7 +228,7 @@ public class JsonSecurityUtils implements IJoseTools {
receiverJwe.setProviderContext(providerCtx);
}
-
+
// validate key from header against key from config
final List<X509Certificate> x5cCerts = receiverJwe.getCertificateChainHeaderValue();
final String x5t256 = receiverJwe.getX509CertSha256ThumbprintHeaderValue();
@@ -331,7 +255,7 @@ public class JsonSecurityUtils implements IJoseTools {
final String certFingerPrint = X509Util.x5tS256(encryptionCred.getSecond()[0]);
if (!certFingerPrint.equals(x5t256)) {
log.info("X5t256 from JOSE header does NOT match encryption certificate");
- log.debug("X5t256 from JOSE header: " + x5t256 + " Encrytption cert: " + certFingerPrint);
+ log.debug("X5t256 from JOSE header: {} Encrytption cert: {}", x5t256, certFingerPrint);
throw new SL20Exception("sl20.05",
new Object[] { "X5t256 from JOSE header does NOT match encryption certificate" });
@@ -346,7 +270,7 @@ public class JsonSecurityUtils implements IJoseTools {
// set key
receiverJwe.setKey(encryptionCred.getFirst());
-
+
// decrypt payload
return mapper.getMapper().readTree(receiverJwe.getPlaintextString());
@@ -424,33 +348,6 @@ public class JsonSecurityUtils implements IJoseTools {
return config;
}
- /**
- * Select signature algorithm for a given credential.
- *
- * @param key {@link X509Credential} that will be used for key operations
- * @param rsaSigAlgorithm RSA based algorithm that should be used in
- * case of RSA credential
- * @param ecSigAlgorithm EC based algorithm that should be used in case
- * of RSA credential
- * @return either the RSA based algorithm or the EC based algorithm
- * @throws SlCommandoBuildException In case of an unsupported credential
- */
- private static String getKeyOperationAlgorithmFromCredential(Key key,
- String rsaSigAlgorithm, String ecSigAlgorithm) throws SlCommandoBuildException {
- if (key instanceof RSAPrivateKey) {
- return rsaSigAlgorithm;
-
- } else if (key instanceof ECPrivateKey) {
- return ecSigAlgorithm;
-
- } else {
- log.warn("Could NOT evaluate the Private-Key type from do select algorithm");
- throw new SlCommandoBuildException("Could NOT evaluate the Private-Key type from do select algorithm");
-
- }
-
- }
-
private String getSigningKeyAlias() {
String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS);
if (value != null) {
@@ -490,4 +387,26 @@ public class JsonSecurityUtils implements IJoseTools {
return null;
}
+ private String getRsaSigningAlgorithm() {
+ String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_SIG_ALG_RSA,
+ AlgorithmIdentifiers.RSA_PSS_USING_SHA256);
+ if (value != null) {
+ value = value.trim();
+ }
+
+ return value;
+
+ }
+
+ private String getEccSigningAlgorithm() {
+ String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_SIG_ALG_ECC,
+ AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256);
+ if (value != null) {
+ value = value.trim();
+ }
+
+ return value;
+
+ }
+
}
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
index ebea35c6..917ef1e0 100644
--- 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
@@ -9,8 +9,18 @@ import java.security.Security;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
+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;
+
import org.apache.commons.lang3.RandomStringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.jose4j.base64url.Base64Url;
import org.jose4j.jca.ProviderContext;
import org.jose4j.jwa.AlgorithmConstraints;
import org.jose4j.jwa.AlgorithmConstraints.ConstraintType;
@@ -28,15 +38,6 @@ 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 {
@@ -44,45 +45,45 @@ 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 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 getRsaKeyAlias();
+
protected abstract String getRsaKeyPassword();
-
- protected abstract String getEcKeyAlias();
-
+
+ protected abstract String getEcKeyAlias();
+
protected abstract String getEcKeyPassword();
-
-
+
+
@Test
- public void fullEncryptDecrypt() throws JoseException, EaafException {
- String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}";
-
+ public void fullEncryptDecrypt() throws JoseException, EaafException {
+ final 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();
+ final Pair<KeyStore, Provider> rsaEncKeyStore = getEncryptionKeyStore();
if (rsaEncKeyStore.getSecond() != null) {
final ProviderContext providerCtx = new ProviderContext();
providerCtx.getSuppliedKeyProviderContext().setSignatureProvider(
@@ -90,30 +91,30 @@ public abstract class AbstractJsonSecurityUtilsTest {
jwe.setProviderContext(providerCtx);
}
-
- String encData = jwe.getCompactSerialization();
+
+ final String encData = jwe.getCompactSerialization();
Assert.assertNotNull("JWE Encryption", encData);
-
-
- JsonNode decData = joseTools.decryptPayload(encData);
+
+
+ final 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(),
+ final String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}";
+ final Pair<KeyStore, Provider> rsaEncKeyStore = getEncryptionKeyStore();
+ final 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();
@@ -122,27 +123,27 @@ public abstract class AbstractJsonSecurityUtilsTest {
jwe.setProviderContext(providerCtx);
}
-
- String encData = jwe.getCompactSerialization();
+
+ final 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(),
+ final String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}";
+ final Pair<KeyStore, Provider> rsaEncKeyStore = getEncryptionKeyStore();
+ final 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();
@@ -151,142 +152,139 @@ public abstract class AbstractJsonSecurityUtilsTest {
jwe.setProviderContext(providerCtx);
}
-
- String encData = jwe.getCompactSerialization();
-
+
+ final String encData = jwe.getCompactSerialization();
+
Assert.assertNotNull("JWE", encData);
-
-
+
+
}
-
+
@Test
- public void noTrustedCert() throws CertificateEncodingException, KeyStoreException,
+ public void noTrustedCert() throws CertificateEncodingException, KeyStoreException,
JoseException, IOException, EaafException {
setRsaSigningKey();
setRsaEncryptionKey();
-
- String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}";
-
- String jws = joseTools.createSignature(payLoad);
+
+ final String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}";
+
+ final String jws = joseTools.createSignature(payLoad);
Assert.assertNotNull("Signed msg", jws);
-
+
try {
joseTools.validateSignature(
jws,
keyStoreFactory.buildNewKeyStore(getSigTrustStoreConfigOnlyEc()).getFirst(),
- getDefaultAlgorithmConstrains());
+ 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",
+
+ } catch (final 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,
+ public void invalidSignature() throws CertificateEncodingException, KeyStoreException,
JoseException, IOException, EaafException {
setRsaSigningKey();
setRsaEncryptionKey();
-
- String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}";
-
- String jws = joseTools.createSignature(payLoad);
+
+ final String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}";
+
+ final 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());
-
- }
-
+
+ final String invalidJws = jws.substring(0, jws.indexOf("."))
+ + "."
+ + Base64Url.encodeUtf8ByteRepresentation("{\"aac\":\"" + RandomStringUtils.randomAlphabetic(25) + "\"}")
+ + "."
+ + jws.substring(jws.lastIndexOf(".") + 1);
+
+
+ final VerificationResult result = joseTools.validateSignature(
+ invalidJws,
+ keyStoreFactory.buildNewKeyStore(getSigTrustStoreConfigValid()).getFirst(),
+ getDefaultAlgorithmConstrains());
+
+ Assert.assertFalse("wrong sig. verification state", result.isValidSigned());
+
}
-
+
@Test
- public void validSigningRsa() throws CertificateEncodingException, KeyStoreException,
+ public void validSigningRsa() throws CertificateEncodingException, KeyStoreException,
JoseException, IOException, EaafException {
setRsaSigningKey();
setRsaEncryptionKey();
-
- String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}";
-
- String jws = joseTools.createSignature(payLoad);
+
+ final String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}";
+
+ final String jws = joseTools.createSignature(payLoad);
Assert.assertNotNull("Signed msg", jws);
-
- VerificationResult verify = joseTools.validateSignature(
+
+ final VerificationResult verify = joseTools.validateSignature(
jws,
keyStoreFactory.buildNewKeyStore(getSigTrustStoreConfigValid()).getFirst(),
- getDefaultAlgorithmConstrains());
+ 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,
+ public void validSigningEc() throws CertificateEncodingException, KeyStoreException,
JoseException, IOException, EaafException {
setEcSigningKey();
setEcEncryptionKey();
-
- String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}";
-
- String jws = joseTools.createSignature(payLoad);
+
+ final String payLoad = "{\"aac\":\"" + RandomStringUtils.randomAlphanumeric(100) + "\"}";
+
+ final String jws = joseTools.createSignature(payLoad);
Assert.assertNotNull("Signed msg", jws);
-
- VerificationResult verify = joseTools.validateSignature(
+
+ final VerificationResult verify = joseTools.validateSignature(
jws,
keyStoreFactory.buildNewKeyStore(getSigTrustStoreConfigValid()).getFirst(),
- getDefaultAlgorithmConstrains());
+ 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();
+ final 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();
+ final 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()]));
}
-
+
}
diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/test/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtilsHsmKeyTest.java b/eaaf_modules/eaaf_module_auth_sl20/src/test/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtilsHsmKeyTest.java
index d9406b2d..4f8b2a23 100644
--- a/eaaf_modules/eaaf_module_auth_sl20/src/test/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtilsHsmKeyTest.java
+++ b/eaaf_modules/eaaf_module_auth_sl20/src/test/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/JsonSecurityUtilsHsmKeyTest.java
@@ -3,51 +3,59 @@ package at.gv.egiz.eaaf.modules.auth.sl20.utils;
import java.security.KeyStore;
import java.security.Provider;
-import org.apache.commons.lang3.StringUtils;
-import org.junit.runner.RunWith;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
import at.gv.egiz.eaaf.core.exceptions.EaafException;
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 org.apache.commons.lang3.StringUtils;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring/test_eaaf_sl20_hsm.beans.xml")
public class JsonSecurityUtilsHsmKeyTest extends AbstractJsonSecurityUtilsTest {
+ @Before
+ public void initialize() {
+ config.putConfigValue("modules.sl20.security.sigalg.rsa", "RS256");
+ config.putConfigValue("modules.sl20.security.sigalg.ecc", "ES256");
+
+ }
+
@Override
protected void setRsaSigningKey() {
config.putConfigValue("modules.sl20.security.sign.alias", "rsa-key-1");
-
+
}
@Override
protected void setEcSigningKey() {
config.putConfigValue("modules.sl20.security.sign.alias", "ec-key-1");
-
+
}
@Override
protected void setRsaEncryptionKey() {
config.putConfigValue("modules.sl20.security.encryption.alias", "rsa-key-1");
-
+
}
@Override
protected void setEcEncryptionKey() {
config.putConfigValue("modules.sl20.security.encryption.alias", "ec-key-1");
-
+
}
@Override
- protected Pair<KeyStore, Provider> getEncryptionKeyStore() throws EaafException {
- KeyStoreConfiguration keyConfig = new KeyStoreConfiguration();
+ protected Pair<KeyStore, Provider> getEncryptionKeyStore() throws EaafException {
+ final KeyStoreConfiguration keyConfig = new KeyStoreConfiguration();
keyConfig.setFriendlyName("Junit Enc Key Rsa");
keyConfig.setKeyStoreType(KeyStoreType.HSMFACADE);
keyConfig.setKeyStoreName("eid-junit");
-
+
return keyStoreFactory.buildNewKeyStore(keyConfig);
}
@@ -71,5 +79,5 @@ public class JsonSecurityUtilsHsmKeyTest extends AbstractJsonSecurityUtilsTest {
return StringUtils.EMPTY;
}
-
+
}