diff options
9 files changed, 560 insertions, 299 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/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java index bd2b3cab..955648c6 100644 --- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java +++ b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/credential/EaafKeyStoreFactory.java @@ -63,6 +63,7 @@ public class EaafKeyStoreFactory { public static final String ERRORCODE_06 = "internal.keystore.06"; public static final String ERRORCODE_07 = "internal.keystore.07"; public static final String ERRORCODE_10 = "internal.keystore.10"; + public static final String ERRORCODE_11 = "internal.keystore.11"; public static final String ERRORCODE_KEY_00 = "internal.key.00"; @@ -316,7 +317,7 @@ public class EaafKeyStoreFactory { } if (!ressource.exists()) { - throw new EaafConfigurationException(ERRORCODE_05, + throw new EaafConfigurationException(ERRORCODE_06, new Object[] { config.getFriendlyName(), "RessourceLoader does NOT find File at: " + ressource.getURI() }); 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..5b398bb0 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 @@ -12,8 +12,10 @@ internal.keystore.07=Validation of KeyStore: {0} failed. Reason: {1} internal.keystore.08=Can not access Key: {1} in KeyStore: {0} 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.keystore.11=KeyStore: {0} has a wrong configuration. Property: {0} Reason:{1} 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; } - + } |