From 5a1eca23a9b35541b7b1955b83b47e0af983d5dd Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Wed, 5 Feb 2020 09:02:13 +0100 Subject: add Trusted-Certificates method to AbstractCredentialProvider add jUnit tests for AbstractCredentialProvider change method names in AbstractCredentialProvider --- .../impl/utils/AbstractCredentialProvider.java | 151 +++++++++++++-------- 1 file changed, 91 insertions(+), 60 deletions(-) (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java') diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java index 336741a0..13124114 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/utils/AbstractCredentialProvider.java @@ -23,10 +23,14 @@ import java.io.IOException; import java.io.InputStream; import java.security.KeyStore; import java.security.KeyStoreException; -import java.security.PrivateKey; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.RSAPrivateKey; - +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; + +import javax.annotation.Nonnull; import javax.annotation.PostConstruct; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; @@ -40,26 +44,24 @@ import at.gv.egiz.eaaf.modules.pvp2.exception.SamlSigningException; import at.gv.egiz.eaaf.modules.pvp2.impl.opensaml.EaafKeyStoreX509CredentialAdapter; import org.apache.commons.lang3.StringUtils; -import org.opensaml.security.credential.Credential; import org.opensaml.security.credential.UsageType; -import org.opensaml.xmlsec.signature.Signature; -import org.opensaml.xmlsec.signature.support.SignatureConstants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; +import lombok.extern.slf4j.Slf4j; + +@Slf4j public abstract class AbstractCredentialProvider { + private static final String TRUSTED_CERTIFICATES_OPERATION = "Trusted Certificate Entries"; + @Autowired protected ResourceLoader resourceLoader; @Autowired protected IConfiguration basicConfig; - private static final Logger log = LoggerFactory.getLogger(AbstractCredentialProvider.class); - private KeyStore keyStore = null; /** @@ -76,6 +78,7 @@ public abstract class AbstractCredentialProvider { * @return URL to the keyStore * @throws EaafException In case of an invalid filepath */ + @Nonnull public abstract String getKeyStoreFilePath() throws EaafException; /** @@ -133,23 +136,16 @@ public abstract class AbstractCredentialProvider { * @return Credentials * @throws CredentialsNotAvailableException In case of a credential error */ - public EaafX509Credential getIdpMetaDataSigningCredential() throws CredentialsNotAvailableException { + public EaafX509Credential getMetaDataSigningCredential() throws CredentialsNotAvailableException { try { final EaafKeyStoreX509CredentialAdapter credentials = new EaafKeyStoreX509CredentialAdapter(keyStore, getMetadataKeyAlias(), getMetadataKeyPassword().toCharArray(), getFriendlyName()); - credentials.setUsageType(UsageType.SIGNING); - credentials.setSignatureAlgorithmForSigning(Saml2Utils.getSignatureAlgorithm( - credentials, - basicConfig.getBasicConfiguration( - PvpConstants.CONFIG_PROP_SEC_SIGNING_RSA_ALG, - PvpConstants.DEFAULT_SIGNING_METHODE_RSA), - basicConfig.getBasicConfiguration( - PvpConstants.CONFIG_PROP_SEC_SIGNING_RSA_ALG, - PvpConstants.DEFAULT_SIGNING_METHODE_EC))); + credentials.setSignatureAlgorithmForSigning(selectSigningAlgorithm(credentials)); + credentials.setKeyEncryptionAlgorithmForDataEncryption(selectKeyEncryptionAlgorithm(credentials)); return credentials; - } catch (final SamlSigningException e) { + } catch (final Exception e) { throw new CredentialsNotAvailableException("internal.pvp.01", new Object[] { getFriendlyName(), getMetadataKeyAlias() }, e); @@ -157,26 +153,19 @@ public abstract class AbstractCredentialProvider { } /** - * Get Credentials to sign Assertion. + * Get Credentials to sign SAML2 messages, like AuthnRequest, Response, + * Assertions as some examples. * * @return Credentials * @throws CredentialsNotAvailableException In case of a credential error */ - public EaafX509Credential getIdpAssertionSigningCredential() throws CredentialsNotAvailableException { + public EaafX509Credential getMessageSigningCredential() throws CredentialsNotAvailableException { try { final EaafKeyStoreX509CredentialAdapter credentials = new EaafKeyStoreX509CredentialAdapter(keyStore, getSignatureKeyAlias(), getSignatureKeyPassword().toCharArray(), getFriendlyName()); - credentials.setUsageType(UsageType.SIGNING); - credentials.setSignatureAlgorithmForSigning(Saml2Utils.getSignatureAlgorithm( - credentials, - basicConfig.getBasicConfiguration( - PvpConstants.CONFIG_PROP_SEC_SIGNING_RSA_ALG, - PvpConstants.DEFAULT_SIGNING_METHODE_RSA), - basicConfig.getBasicConfiguration( - PvpConstants.CONFIG_PROP_SEC_SIGNING_RSA_ALG, - PvpConstants.DEFAULT_SIGNING_METHODE_EC))); - + credentials.setSignatureAlgorithmForSigning(selectSigningAlgorithm(credentials)); + credentials.setKeyEncryptionAlgorithmForDataEncryption(selectKeyEncryptionAlgorithm(credentials)); return credentials; } catch (final Exception e) { @@ -187,51 +176,70 @@ public abstract class AbstractCredentialProvider { } /** - * Get Credentials to encrypt assertion. + * Get Credentials to encrypt messages, like Assertion as example. * * @return Credentials * @throws CredentialsNotAvailableException In case of a credential error */ - public EaafX509Credential getIdpAssertionEncryptionCredential() + public EaafX509Credential getMessageEncryptionCredential() throws CredentialsNotAvailableException { // if no encryption key is configured return null if (StringUtils.isEmpty(getEncryptionKeyAlias())) { return null; } - final EaafKeyStoreX509CredentialAdapter credentials = new EaafKeyStoreX509CredentialAdapter(keyStore, - getEncryptionKeyAlias(), getEncryptionKeyPassword().toCharArray(), getFriendlyName()); - credentials.setUsageType(UsageType.ENCRYPTION); - return credentials; + try { + final EaafKeyStoreX509CredentialAdapter credentials = new EaafKeyStoreX509CredentialAdapter(keyStore, + getEncryptionKeyAlias(), getEncryptionKeyPassword().toCharArray(), getFriendlyName()); + credentials.setUsageType(UsageType.ENCRYPTION); + credentials.setSignatureAlgorithmForSigning(selectSigningAlgorithm(credentials)); + credentials.setKeyEncryptionAlgorithmForDataEncryption(selectKeyEncryptionAlgorithm(credentials)); + return credentials; + + } catch (final Exception e) { + throw new CredentialsNotAvailableException("internal.pvp.01", + new Object[] { getFriendlyName(), getEncryptionKeyAlias() }, e); + + } } /** - * Get an XML signature object. + * Get a List of trusted {@link X509Certificate} that are available in this + * KeyStore. * - * @param credentials Credentials for signing - * @return OpenSAML Signature object + * @return List of trusted {@link X509Certificate}, or an emptry {@link List} if + * no certificates are available + * @throws CredentialsNotAvailableException In case of a KeyStore error */ - @Deprecated - public static Signature getIdpSignature(final Credential credentials) { - final PrivateKey privatekey = credentials.getPrivateKey(); - final Signature signer = Saml2Utils.createSamlObject(Signature.class); - - if (privatekey instanceof RSAPrivateKey) { - signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); - - } else if (privatekey instanceof ECPrivateKey) { - signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA256); - - } else { - log.warn("Could NOT evaluate the Private-Key type from " + credentials.getEntityId() - + " credential."); + @Nonnull + public List getTrustedCertificates() + throws CredentialsNotAvailableException { + final List result = new ArrayList<>(); + try { + final Enumeration aliases = keyStore.aliases(); + while (aliases.hasMoreElements()) { + final String el = aliases.nextElement(); + log.trace("Process TrustStoreEntry: " + el); + if (keyStore.isCertificateEntry(el)) { + final Certificate cert = keyStore.getCertificate(el); + if (cert != null && cert instanceof X509Certificate) { + result.add((X509Certificate) cert); + + } else { + log.info("Can not process entry: {}. Reason: {}", + el, cert != null ? cert.getType() : "cert is null"); + + } + } + } + } catch (final KeyStoreException e) { + throw new CredentialsNotAvailableException("internal.pvp.01", + new Object[] { getFriendlyName(), TRUSTED_CERTIFICATES_OPERATION }, e); } - signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); - signer.setSigningCredential(credentials); - return signer; + return Collections.unmodifiableList(result); } @@ -254,7 +262,30 @@ public abstract class AbstractCredentialProvider { throw e; } + } + + private String selectSigningAlgorithm(EaafKeyStoreX509CredentialAdapter credentials) + throws SamlSigningException { + return Saml2Utils.getKeyOperationAlgorithmFromCredential( + credentials, + basicConfig.getBasicConfiguration( + PvpConstants.CONFIG_PROP_SEC_SIGNING_RSA_ALG, + PvpConstants.DEFAULT_SIGNING_METHODE_RSA), + basicConfig.getBasicConfiguration( + PvpConstants.CONFIG_PROP_SEC_SIGNING_EC_ALG, + PvpConstants.DEFAULT_SIGNING_METHODE_EC)); + } + private String selectKeyEncryptionAlgorithm(EaafKeyStoreX509CredentialAdapter credentials) + throws SamlSigningException { + return Saml2Utils.getKeyOperationAlgorithmFromCredential( + credentials, + basicConfig.getBasicConfiguration( + PvpConstants.CONFIG_PROP_SEC_ENCRYPTION_KEY_RSA_ALG, + PvpConstants.DEFAULT_ASYM_ENCRYPTION_METHODE_RSA), + basicConfig.getBasicConfiguration( + PvpConstants.CONFIG_PROP_SEC_ENCRYPTION_KEY_EC_ALG, + PvpConstants.DEFAULT_ASYM_ENCRYPTION_METHODE_EC)); } } -- cgit v1.2.3