From fa2727e5844733f29d9ba12f353579c112f0673d Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Mon, 17 Feb 2020 18:10:45 +0100 Subject: Update sign method to add parameter for JOSE x509c header Inject special Java Security Provider if KeyStore needs a specific one --- .../eaaf/modules/auth/sl20/utils/IJoseTools.java | 21 ++++-- .../modules/auth/sl20/utils/JsonSecurityUtils.java | 74 +++++++++++++++------- 2 files changed, 68 insertions(+), 27 deletions(-) (limited to 'eaaf_modules') diff --git a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJoseTools.java b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJoseTools.java index 6ee53a9d..f04555dc 100644 --- a/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJoseTools.java +++ b/eaaf_modules/eaaf_module_auth_sl20/src/main/java/at/gv/egiz/eaaf/modules/auth/sl20/utils/IJoseTools.java @@ -8,25 +8,38 @@ import java.util.List; import javax.annotation.Nonnull; +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.SlCommandoBuildException; + import org.jose4j.jwa.AlgorithmConstraints; import org.jose4j.lang.JoseException; import com.fasterxml.jackson.databind.JsonNode; -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.SlCommandoBuildException; - public interface IJoseTools { /** * Create a JWS signature. * + *

This method adds the certificate chain into JOSE header.

+ * * @param payLoad Payload to sign * @throws SlCommandoBuildException In case of a signature creation error */ String createSignature(String payLoad) throws SlCommandoBuildException; + /** + * Create a JWS signature. + * + * @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 + * @return Signed PayLoad in serialized form + * @throws SlCommandoBuildException SlCommandoBuildException In case of a signature creation error + */ + String createSignature(String payLoad, boolean addFullCertChain) throws SlCommandoBuildException; + /** * Validates a signed SL2.0 message. * 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 1668752a..1b1f090f 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 @@ -30,6 +30,7 @@ import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoBuildException; import at.gv.egiz.eaaf.modules.auth.sl20.exceptions.SlCommandoParserException; 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; @@ -56,8 +57,10 @@ public class JsonSecurityUtils implements IJoseTools { private static final String FRIENDLYNAME_KEYSTORE = "SL2.0 KeyStore"; private static final String FRIENDLYNAME_TRUSTSTORE = "SL2.0 TrustStore"; - @Autowired(required = true) IConfiguration authConfig; - @Autowired(required = true) EaafKeyStoreFactory keystoreFactory; + @Autowired(required = true) + IConfiguration authConfig; + @Autowired(required = true) + EaafKeyStoreFactory keystoreFactory; private Pair keyStore; private Pair trustStore; @@ -68,17 +71,17 @@ public class JsonSecurityUtils implements IJoseTools { protected void initalize() throws SL20Exception { log.info("Initialize SL2.0 authentication security constrains ... "); try { - //load KeyStore + // load KeyStore final KeyStoreConfiguration keyStoreConfig = buildKeyStoreConfiguration(); keyStore = keystoreFactory.buildNewKeyStore(keyStoreConfig); - //load TrustStore + // load TrustStore final KeyStoreConfiguration trustStoreConfig = buildTrustStoreConfiguration(); trustStore = keystoreFactory.buildNewKeyStore(trustStoreConfig); - //validate KeyStore entries + // validate KeyStore entries EaafKeyStoreUtils.getPrivateKeyAndCertificates(keyStore.getFirst(), getSigningKeyAlias(), - getSigningKeyPassword(), true, FRIENDLYNAME_KEYSTORE); + getSigningKeyPassword(), true, FRIENDLYNAME_KEYSTORE); final Pair encCredentials = EaafKeyStoreUtils.getPrivateKeyAndCertificates(keyStore.getFirst(), getEncryptionKeyAlias(), getEncryptionKeyPassword(), false, FRIENDLYNAME_TRUSTSTORE); @@ -87,8 +90,9 @@ public class JsonSecurityUtils implements IJoseTools { } - //validate TrustStore - final List trustedCerts = EaafKeyStoreUtils.readCertsFromKeyStore(trustStore.getFirst()); + // validate TrustStore + final List trustedCerts = EaafKeyStoreUtils.readCertsFromKeyStore(trustStore + .getFirst()); if (trustedCerts.isEmpty()) { log.info("No certificates in TrustStore: {}. Signature validation will FAIL!", FRIENDLYNAME_TRUSTSTORE); @@ -106,7 +110,7 @@ public class JsonSecurityUtils implements IJoseTools { } catch (final Exception e) { log.error("SL2.0 security constrains initialization FAILED."); - throw new SL20Exception("sl20.11", new Object[] {e.getMessage()}, e); + throw new SL20Exception("sl20.11", new Object[] { e.getMessage() }, e); } @@ -114,6 +118,12 @@ public class JsonSecurityUtils implements IJoseTools { @Override public String createSignature(final String payLoad) throws SlCommandoBuildException { + return createSignature(payLoad, true); + + } + + @Override + public String createSignature(final String payLoad, boolean addFullCertChain) throws SlCommandoBuildException { try { final JsonWebSignature jws = new JsonWebSignature(); @@ -127,11 +137,23 @@ public class JsonSecurityUtils implements IJoseTools { jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); final Pair signingCred = EaafKeyStoreUtils.getPrivateKeyAndCertificates( keyStore.getFirst(), getSigningKeyAlias(), getSigningKeyPassword(), true, FRIENDLYNAME_KEYSTORE); - jws.setKey(signingCred.getFirst()); - // TODO: - jws.setCertificateChainHeaderValue(signingCred.getSecond()); + // 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(); @@ -190,7 +212,8 @@ public class JsonSecurityUtils implements IJoseTools { } else if (StringUtils.isNotEmpty(x5t256)) { log.debug("Found x5t256 fingerprint in JOSE header .... "); - final X509VerificationKeyResolver x509VerificationKeyResolver = new X509VerificationKeyResolver(trustedCerts); + final X509VerificationKeyResolver x509VerificationKeyResolver = new X509VerificationKeyResolver( + trustedCerts); selectedKey = x509VerificationKeyResolver.resolveKey(jws, Collections.emptyList()); } else { @@ -220,7 +243,8 @@ public class JsonSecurityUtils implements IJoseTools { .toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING.size()])); final VerificationResult result = - validateSignature(serializedContent, EaafKeyStoreUtils.readCertsFromKeyStore(trustStore.getFirst()), algConstraints); + validateSignature(serializedContent, EaafKeyStoreUtils.readCertsFromKeyStore(trustStore.getFirst()), + algConstraints); if (!result.isValidSigned()) { log.info("JWS signature invalide. Stopping authentication process ..."); @@ -251,8 +275,9 @@ public class JsonSecurityUtils implements IJoseTools { // set security constrains receiverJwe.setAlgorithmConstraints( - new AlgorithmConstraints(ConstraintType.WHITELIST, SL20Constants.SL20_ALGORITHM_WHITELIST_KEYENCRYPTION - .toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_KEYENCRYPTION.size()]))); + new AlgorithmConstraints(ConstraintType.WHITELIST, + 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 .toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_ENCRYPTION.size()]))); @@ -261,7 +286,8 @@ public class JsonSecurityUtils implements IJoseTools { receiverJwe.setCompactSerialization(compactSerialization); final Pair encryptionCred = EaafKeyStoreUtils.getPrivateKeyAndCertificates( - keyStore.getFirst(), getEncryptionKeyAlias(), getEncryptionKeyPassword(), true, FRIENDLYNAME_KEYSTORE); + keyStore.getFirst(), getEncryptionKeyAlias(), getEncryptionKeyPassword(), true, + FRIENDLYNAME_KEYSTORE); // validate key from header against key from config final List x5cCerts = receiverJwe.getCertificateChainHeaderValue(); @@ -357,7 +383,7 @@ public class JsonSecurityUtils implements IJoseTools { config.setSoftKeyStorePassword( authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_PASSWORD)); - //validate configuration state + // validate configuration state config.validate(); return config; @@ -378,13 +404,12 @@ public class JsonSecurityUtils implements IJoseTools { config.setSoftKeyStorePassword( authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_TRUSTSTORE_PASSWORD)); - //validate configuration state + // validate configuration state config.validate(); return config; } - private String getSigningKeyAlias() { String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_ALIAS); if (value != null) { @@ -395,7 +420,8 @@ public class JsonSecurityUtils implements IJoseTools { } private char[] getSigningKeyPassword() { - final String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD); + final String value = authConfig.getBasicConfiguration( + Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_SIGN_PASSWORD); if (value != null) { return value.trim().toCharArray(); } @@ -404,7 +430,8 @@ public class JsonSecurityUtils implements IJoseTools { } private String getEncryptionKeyAlias() { - String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_ALIAS); + String value = authConfig.getBasicConfiguration( + Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_ALIAS); if (value != null) { value = value.trim(); } @@ -413,7 +440,8 @@ public class JsonSecurityUtils implements IJoseTools { } private char[] getEncryptionKeyPassword() { - final String value = authConfig.getBasicConfiguration(Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD); + final String value = authConfig.getBasicConfiguration( + Constants.CONFIG_PROP_SECURITY_KEYSTORE_KEY_ENCRYPTION_PASSWORD); if (value != null) { return value.trim().toCharArray(); } -- cgit v1.2.3