diff options
author | Thomas Lenz <tlenz@iaik.tugraz.at> | 2017-02-07 12:31:33 +0100 |
---|---|---|
committer | Thomas Lenz <tlenz@iaik.tugraz.at> | 2017-02-07 12:31:33 +0100 |
commit | b4e3813e3f0fc900b5c2194bc6c06e4908a14797 (patch) | |
tree | 656d2fd224f51311e1c3f4f004ae3658f359bd15 | |
parent | 2b68b287aa55dc48e9f3a01bd42d6099bbe1deb2 (diff) | |
parent | ad56f27f4b66dccb424fdcad5bcb194ee87457b9 (diff) | |
download | moa-id-spss-b4e3813e3f0fc900b5c2194bc6c06e4908a14797.tar.gz moa-id-spss-b4e3813e3f0fc900b5c2194bc6c06e4908a14797.tar.bz2 moa-id-spss-b4e3813e3f0fc900b5c2194bc6c06e4908a14797.zip |
Merge branch 'eIDAS_node_implementation' into development_preview
5 files changed, 509 insertions, 13 deletions
diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java index 02c9a8f5d..6cb4d6add 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/Constants.java @@ -22,6 +22,7 @@ */ package at.gv.egovernment.moa.id.auth.modules.eidas; +import org.apache.xml.security.signature.XMLSignature; import org.opensaml.xml.encryption.EncryptionConstants; import org.opensaml.xml.signature.SignatureConstants; //import eu.eidas.auth.engine.core.validator.eidas.EIDASAttributes; @@ -45,7 +46,8 @@ public class Constants { public static final String eIDAS_SAML_ENGINE_NAME_ID_CLASS = "class"; //default implementations for eIDAS SAML-engine functionality - public static final String SAML_SIGNING_IMPLENTATION = "at.gv.egovernment.moa.id.auth.modules.eidas.config.MOASWSigner"; + //public static final String SAML_SIGNING_IMPLENTATION = "at.gv.egovernment.moa.id.auth.modules.eidas.config.MOASWSigner"; + public static final String SAML_SIGNING_IMPLENTATION = "at.gv.egovernment.moa.id.auth.modules.eidas.config.MOAExtendedSWSigner"; public static final String SAML_ENCRYPTION_IMPLENTATION = "at.gv.egovernment.moa.id.auth.modules.eidas.config.ModifiedEncryptionSW"; //configuration property keys @@ -133,16 +135,20 @@ public class Constants { public static final String METADATA_ALLOWED_ALG_DIGIST = - SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256 + ";" + - SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512 ; + SignatureConstants.ALGO_ID_DIGEST_SHA256 + ";" + + SignatureConstants.ALGO_ID_DIGEST_SHA512 ; public static final String METADATA_ALLOWED_ALG_SIGN = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256 + ";" + - SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512; + SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512 + ";" + + XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256_MGF1 + ";" + + XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512_MGF1; public static final String METADATA_ALLOWED_ALG_ENCRYPT = EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128_GCM + ";" + EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192_GCM + ";" + - EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256_GCM; + EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256_GCM + ";" + + EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128 + ";" + + EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256; } diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAExtendedSWSigner.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAExtendedSWSigner.java new file mode 100644 index 000000000..e08d302f6 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/config/MOAExtendedSWSigner.java @@ -0,0 +1,479 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules.eidas.config; + +import java.security.KeyStore; +import java.security.cert.X509Certificate; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.xml.security.signature.XMLSignature; +import org.opensaml.Configuration; +import org.opensaml.common.impl.SAMLObjectContentReference; +import org.opensaml.security.SAMLSignatureProfileValidator; +import org.opensaml.xml.io.MarshallingException; +import org.opensaml.xml.security.SecurityConfiguration; +import org.opensaml.xml.security.SecurityException; +import org.opensaml.xml.security.SecurityHelper; +import org.opensaml.xml.security.credential.Credential; +import org.opensaml.xml.security.keyinfo.KeyInfoGenerator; +import org.opensaml.xml.security.keyinfo.KeyInfoGeneratorFactory; +import org.opensaml.xml.security.keyinfo.KeyInfoGeneratorManager; +import org.opensaml.xml.security.keyinfo.NamedKeyInfoGeneratorManager; +import org.opensaml.xml.security.x509.X509Credential; +import org.opensaml.xml.signature.KeyInfo; +import org.opensaml.xml.signature.SignableXMLObject; +import org.opensaml.xml.signature.Signature; +import org.opensaml.xml.signature.SignatureException; +import org.opensaml.xml.signature.SignatureValidator; +import org.opensaml.xml.signature.Signer; +import org.opensaml.xml.validation.ValidationException; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.sun.istack.Nullable; + +import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.utils.MOAWhiteListConfigurator; +import at.gv.egovernment.moa.logging.Logger; +import eu.eidas.auth.commons.EidasErrorKey; +import eu.eidas.auth.engine.configuration.SamlEngineConfigurationException; +import eu.eidas.auth.engine.configuration.dom.ConfigurationAdapter; +import eu.eidas.auth.engine.configuration.dom.ConfigurationKey; +import eu.eidas.auth.engine.configuration.dom.KeyStoreSignatureConfigurator; +import eu.eidas.auth.engine.configuration.dom.SignatureConfiguration; +import eu.eidas.auth.engine.core.ProtocolSignerI; +import eu.eidas.auth.engine.core.impl.BouncyCastleBootstrap; +import eu.eidas.auth.engine.core.impl.CertificateValidator; +import eu.eidas.auth.engine.metadata.MetadataSignerI; +import eu.eidas.auth.engine.xml.opensaml.CertificateUtil; +import eu.eidas.engine.exceptions.EIDASSAMLEngineException; +import eu.eidas.samlengineconfig.CertificateConfigurationManager; +import eu.eidas.util.Preconditions; + +/** + * @author tlenz + * + */ +public class MOAExtendedSWSigner implements ProtocolSignerI, MetadataSignerI { + + private static final String DEFAULT_SIGNATURE_ALGORITHM = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"; + private static final ImmutableSet<String> ALLOWED_ALGORITHMS_FOR_SIGNING; + private static final ImmutableSet<String> ALLOWED_ALGORITHMS_FOR_VERIFYING; + private static final ImmutableSet<String> DEFAULT_ALGORITHM_WHITE_LIST; + private static final String DEFAULT_DIGEST_ALGORITHM = "http://www.w3.org/2001/04/xmlenc#sha512"; + private static final ImmutableMap<Object, Object> SIGNATURE_TO_DIGEST_ALGORITHM_MAP; + private final boolean checkedValidityPeriod; + private final boolean disallowedSelfSignedCertificate; + private final boolean responseSignAssertions; + private final ImmutableSet<String> signatureAlgorithmWhiteList; + private final X509Credential privateSigningCredential; + private final X509Credential publicSigningCredential; + private final X509Credential privateMetadataSigningCredential; + private final X509Credential publicMetadataSigningCredential; + private final ImmutableList<X509Credential> trustedCredentials; + private final String signatureAlgorithm; + + public MOAExtendedSWSigner(Map<String, String> properties) throws SamlEngineConfigurationException { + this(new KeyStoreSignatureConfigurator().getSignatureConfiguration(properties)); + + } + + /** + * @param configManager + * @throws SamlEngineConfigurationException + */ + public MOAExtendedSWSigner(CertificateConfigurationManager configManager) throws SamlEngineConfigurationException { + this(new KeyStoreSignatureConfigurator().getSignatureConfiguration( + ConfigurationAdapter.adapt(configManager).getInstances().get(Constants.eIDAS_SAML_ENGINE_NAME).getConfigurationEntries().get(ConfigurationKey.SIGNATURE_CONFIGURATION.getKey()).getParameters())); + + } + + protected MOAExtendedSWSigner(SignatureConfiguration signatureConfiguration) + throws SamlEngineConfigurationException { + this(signatureConfiguration.isCheckedValidityPeriod(), + signatureConfiguration.isDisallowedSelfSignedCertificate(), + signatureConfiguration.isResponseSignAssertions(), + signatureConfiguration.getSignatureKeyAndCertificate(), signatureConfiguration.getTrustedCertificates(), + signatureConfiguration.getSignatureAlgorithm(), signatureConfiguration.getSignatureAlgorithmWhiteList(), + signatureConfiguration.getMetadataSigningKeyAndCertificate()); + } + + protected MOAExtendedSWSigner(boolean checkedValidityPeriod, boolean disallowedSelfSignedCertificate, + boolean responseSignAssertions, KeyStore.PrivateKeyEntry signatureKeyAndCertificate, + ImmutableSet<X509Certificate> trustedCertificates, String signatureAlgorithmVal, + String signatureAlgorithmWhiteListStr, + KeyStore.PrivateKeyEntry metadataSigningKeyAndCertificate) + throws SamlEngineConfigurationException { + Preconditions.checkNotNull(signatureKeyAndCertificate, "signatureKeyAndCertificate"); + Preconditions.checkNotNull(trustedCertificates, "trustedCertificates"); + String signatureAlg = signatureAlgorithmVal; + + if (StringUtils.isBlank(signatureAlg)) + signatureAlg = DEFAULT_SIGNATURE_ALGORITHM; + + else { + signatureAlg = validateSigningAlgorithm(signatureAlg); + + } + + ImmutableSet signatureAlgorithmWhiteSet = MOAWhiteListConfigurator.getAllowedAlgorithms( + DEFAULT_ALGORITHM_WHITE_LIST, ALLOWED_ALGORITHMS_FOR_VERIFYING, signatureAlgorithmWhiteListStr); + + this.checkedValidityPeriod = checkedValidityPeriod; + this.disallowedSelfSignedCertificate = disallowedSelfSignedCertificate; + this.responseSignAssertions = responseSignAssertions; + this.trustedCredentials = CertificateUtil.getListOfCredential(trustedCertificates); + this.signatureAlgorithmWhiteList = signatureAlgorithmWhiteSet; + this.signatureAlgorithm = signatureAlg; + this.privateSigningCredential = CertificateUtil.createCredential(signatureKeyAndCertificate); + this.publicSigningCredential = CertificateUtil + .toCredential((X509Certificate) signatureKeyAndCertificate.getCertificate()); + + if (null != metadataSigningKeyAndCertificate) { + this.privateMetadataSigningCredential = CertificateUtil.createCredential(metadataSigningKeyAndCertificate); + this.publicMetadataSigningCredential = CertificateUtil + .toCredential((X509Certificate) metadataSigningKeyAndCertificate.getCertificate()); + } else { + this.privateMetadataSigningCredential = null; + this.publicMetadataSigningCredential = null; + } + } + + private static X509Certificate getSignatureCertificate(Signature signature) throws EIDASSAMLEngineException { + KeyInfo keyInfo = signature.getKeyInfo(); + return CertificateUtil.toCertificate(keyInfo); + } + + public static String validateDigestAlgorithm(String signatureAlgorithmName) + throws SamlEngineConfigurationException { + + if (StringUtils.isBlank(signatureAlgorithmName)) { + return DEFAULT_DIGEST_ALGORITHM; + + } + + //BUGFIX: toLowerCase from original eIDAS SAML-engine produce problems with MGF1 signature algorithms + String canonicalAlgorithm = signatureAlgorithmName.trim(); + String digestAlgorithm = (String) SIGNATURE_TO_DIGEST_ALGORITHM_MAP.get(canonicalAlgorithm); + if (null != digestAlgorithm) { + return digestAlgorithm; + + } + String msg = "Signing algorithm \"" + signatureAlgorithmName + + "\" does not contain an allowed digest algorithm"; + + Logger.error(msg); + throw new SamlEngineConfigurationException(msg); + + } + + public static String validateSigningAlgorithm(@Nullable String signatureAlgorithmName) + throws SamlEngineConfigurationException { + if ((signatureAlgorithmName == null) || (StringUtils.isBlank(signatureAlgorithmName))) { + return DEFAULT_SIGNATURE_ALGORITHM; + + } + + //BUGFIX:: toLowerCase from original eIDAS SAML-engine produce problems with MGF1 signature algorithms + String canonicalAlgorithm = signatureAlgorithmName.trim(); + if (ALLOWED_ALGORITHMS_FOR_SIGNING.contains(canonicalAlgorithm)) { + return canonicalAlgorithm; + + } + String msg = "Signing algorithm \"" + signatureAlgorithmName + "\" is not allowed"; + Logger.error(msg); + throw new SamlEngineConfigurationException(msg); + + } + + protected void checkCertificateIssuer(X509Certificate certificate) throws EIDASSAMLEngineException { + CertificateValidator.checkCertificateIssuer(this.disallowedSelfSignedCertificate, certificate); + + } + + protected void checkCertificateValidityPeriod(X509Certificate certificate) throws EIDASSAMLEngineException { + CertificateValidator.checkCertificateValidityPeriod(this.checkedValidityPeriod, certificate); + + } + + protected Signature createSignature(X509Credential credential) throws EIDASSAMLEngineException { + checkCertificateValidityPeriod(credential.getEntityCertificate()); + checkCertificateIssuer(credential.getEntityCertificate()); + Signature signature; + try { + Logger.debug("Creating an OpenSAML signature object"); + + signature = (Signature) Configuration.getBuilderFactory().getBuilder(Signature.DEFAULT_ELEMENT_NAME) + .buildObject(Signature.DEFAULT_ELEMENT_NAME); + + signature.setSigningCredential(credential); + + signature.setSignatureAlgorithm(getSignatureAlgorithm()); + + SecurityConfiguration secConfiguration = Configuration.getGlobalSecurityConfiguration(); + NamedKeyInfoGeneratorManager keyInfoManager = secConfiguration.getKeyInfoGeneratorManager(); + KeyInfoGeneratorManager keyInfoGenManager = keyInfoManager.getDefaultManager(); + KeyInfoGeneratorFactory keyInfoGenFac = keyInfoGenManager.getFactory(credential); + KeyInfoGenerator keyInfoGenerator = keyInfoGenFac.newInstance(); + + KeyInfo keyInfo = keyInfoGenerator.generate(credential); + + signature.setKeyInfo(keyInfo); + signature.setCanonicalizationAlgorithm("http://www.w3.org/2001/10/xml-exc-c14n#"); + } catch (SecurityException e) { + Logger.error("ERROR : Security exception: " + e, e); + throw new EIDASSAMLEngineException(e); + + } + return signature; + } + + public X509Credential getPublicMetadataSigningCredential() { + return this.publicMetadataSigningCredential; + + } + + public X509Credential getPublicSigningCredential() { + return this.publicSigningCredential; + + } + + protected String getSignatureAlgorithm() { + return this.signatureAlgorithm; + + } + + protected ImmutableSet<String> getSignatureAlgorithmWhiteList() { + return this.signatureAlgorithmWhiteList; + + } + + private X509Credential getTrustedCertificate(Signature signature, + List<? extends Credential> trustedCredentialList) throws EIDASSAMLEngineException { + X509Certificate cert = getSignatureCertificate(signature); + + X509Credential entityX509Cred = CertificateUtil.toCredential(cert); + + CertificateUtil.checkTrust(entityX509Cred, trustedCredentialList); + checkCertificateValidityPeriod(cert); + checkCertificateIssuer(cert); + return entityX509Cred; + + } + + protected ImmutableList<X509Credential> getTrustedCredentials() { + return this.trustedCredentials; + + } + + private boolean isAlgorithmAllowedForVerifying(String signatureAlgorithm) { + return ((StringUtils.isNotBlank(signatureAlgorithm)) + && (getSignatureAlgorithmWhiteList().contains(signatureAlgorithm.trim()))); + + } + + public <T extends SignableXMLObject> T sign(T signableObject) throws EIDASSAMLEngineException { + return sign(signableObject, this.privateSigningCredential); + + } + + protected <T extends SignableXMLObject> T sign(T signableObject, X509Credential signingCredential) + throws EIDASSAMLEngineException { + Logger.trace("Start Sign process."); + try { + Signature signature = createSignature(signingCredential); + signableObject.setSignature(signature); + + String digestAlgorithm = validateDigestAlgorithm(getSignatureAlgorithm()); + List contentReferences = signature.getContentReferences(); + if (CollectionUtils.isNotEmpty(contentReferences)) + ((SAMLObjectContentReference) contentReferences.get(0)).setDigestAlgorithm(digestAlgorithm); + + else { + Logger.error("Unable to set DigestMethodAlgorithm - algorithm " + digestAlgorithm + " not set"); + + } + + Logger.trace("Marshall samlToken."); + Configuration.getMarshallerFactory().getMarshaller(signableObject).marshall(signableObject); + + Logger.trace("Sign samlToken."); + Signer.signObject(signature); + + } catch (MarshallingException e) { + Logger.error("ERROR : MarshallingException: " + e, e); + throw new EIDASSAMLEngineException(e); + + } catch (SignatureException e) { + Logger.error("ERROR : Signature exception: " + e, e); + throw new EIDASSAMLEngineException(e); + + } + + return signableObject; + } + + public <T extends SignableXMLObject> T signMetadata(T signableObject) throws EIDASSAMLEngineException { + if (null == this.privateMetadataSigningCredential) { + throw new SamlEngineConfigurationException("No metadataSigningCredential configured"); + + } + return sign(signableObject, this.privateMetadataSigningCredential); + } + + public <T extends SignableXMLObject> T validateMetadataSignature(T signedMetadata) + throws EIDASSAMLEngineException { + return validateSignature(signedMetadata, null); + + } + + private SAMLSignatureProfileValidator validateSamlSignatureStructure(SignableXMLObject signableObject) + throws EIDASSAMLEngineException { + SAMLSignatureProfileValidator sigProfValidator = new SAMLSignatureProfileValidator(); + try { + sigProfValidator.validate(signableObject.getSignature()); + + } catch (ValidationException e) { + Logger.error("ERROR : ValidationException: signature isn't conform to SAML Signature profile: " + e, e); + throw new EIDASSAMLEngineException(e); + + } + return sigProfValidator; + } + + public <T extends SignableXMLObject> T validateSignature(T signedObject, + Collection<X509Certificate> trustedCertificateCollection) throws EIDASSAMLEngineException { + List trustedCreds; + if (CollectionUtils.isEmpty(trustedCertificateCollection)) + trustedCreds = getTrustedCredentials(); + + else { + trustedCreds = CertificateUtil.getListOfCredential(trustedCertificateCollection); + + } + return (T) validateSignatureWithCredentials(signedObject, trustedCreds); + } + + private <T extends SignableXMLObject> T validateSignatureWithCredentials(T signedObject, + List<? extends Credential> trustedCredentialList) throws EIDASSAMLEngineException { + Logger.debug("Start signature validation."); + + validateSamlSignatureStructure(signedObject); + + verifyCryptographicSignature(signedObject.getSignature(), trustedCredentialList); + + return signedObject; + + } + + private void verifyCryptographicSignature(Signature signature, + List<? extends Credential> trustedCredentialList) throws EIDASSAMLEngineException { + String signatureAlgorithmVal = signature.getSignatureAlgorithm(); + Logger.trace("Key algorithm " + SecurityHelper.getKeyAlgorithmFromURI(signatureAlgorithmVal)); + + if (!(isAlgorithmAllowedForVerifying(signatureAlgorithmVal))) { + Logger.error("ERROR : the algorithm " + signatureAlgorithmVal + " used by the signature is not allowed"); + throw new EIDASSAMLEngineException(EidasErrorKey.INVALID_SIGNATURE_ALGORITHM.errorCode()); + + } + + X509Credential entityX509Cred = getTrustedCertificate(signature, trustedCredentialList); + SignatureValidator sigValidator = new SignatureValidator(entityX509Cred); + + try { + sigValidator.validate(signature); + + } catch (ValidationException e) { + Logger.error("ERROR : Signature Validation Exception: " + e, e); + throw new EIDASSAMLEngineException(e); + + } + } + + public boolean isResponseSignAssertions() { + return this.responseSignAssertions; + } + + static { + BouncyCastleBootstrap.bootstrap(); + + ALLOWED_ALGORITHMS_FOR_SIGNING = ImmutableSet.of("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", + "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", + "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", + "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256", + "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384", + "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512", + + //Set other algorithms which are not supported by openSAML in default + XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256_MGF1, + XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512_MGF1); + + ALLOWED_ALGORITHMS_FOR_VERIFYING = ImmutableSet.of("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", + "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", + "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", + "http://www.w3.org/2001/04/xmldsig-more#rsa-ripemd160", + "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256", + "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384", + "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512", + + //Set other algorithms which are not supported by openSAML in default + XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1_MGF1, + XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA224_MGF1, + XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256_MGF1, + XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384_MGF1, + XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512_MGF1); + + DEFAULT_ALGORITHM_WHITE_LIST = ImmutableSet.of("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", + "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", + "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", + "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256", + "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384", + "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512", + + //Set other algorithms which are not supported by openSAML in default + XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256_MGF1); + + SIGNATURE_TO_DIGEST_ALGORITHM_MAP = ImmutableMap.builder() + .put("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", "http://www.w3.org/2001/04/xmlenc#sha256") + .put("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", + "http://www.w3.org/2001/04/xmldsig-more#sha384") + .put("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", "http://www.w3.org/2001/04/xmlenc#sha512") + .put("http://www.w3.org/2001/04/xmldsig-more#rsa-ripemd160", + "http://www.w3.org/2001/04/xmlenc#ripemd160") + .put("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256", "http://www.w3.org/2001/04/xmlenc#sha256") + .put("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384", + "http://www.w3.org/2001/04/xmldsig-more#sha384") + .put("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512", "http://www.w3.org/2001/04/xmlenc#sha512") + + //Set other algorithms which are not supported by openSAML in default + .put(XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256_MGF1, "http://www.w3.org/2001/04/xmlenc#sha256") + .put(XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512_MGF1, "http://www.w3.org/2001/04/xmlenc#sha512") + + .build(); + } +} diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAWhiteListConfigurator.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAWhiteListConfigurator.java index 7d647ff15..a2c6a3ad9 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAWhiteListConfigurator.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAWhiteListConfigurator.java @@ -22,7 +22,6 @@ */ package at.gv.egovernment.moa.id.auth.modules.eidas.utils; -import java.util.Locale; import java.util.regex.Pattern; import org.apache.commons.collections.CollectionUtils; @@ -48,6 +47,11 @@ public class MOAWhiteListConfigurator { } ImmutableSet.Builder<String> allowed = ImmutableSet.builder(); String[] wlAlgorithms = WHITE_LIST_SPLITTER.split(algorithmWhiteListValue); + + //BugFix: remove newlines from configuration + for (int i=0; i<wlAlgorithms.length; i++) + wlAlgorithms[i] = StringUtils.trimToNull(KeyValueUtils.removeAllNewlineFromString(wlAlgorithms[i])); + if (null != wlAlgorithms && wlAlgorithms.length > 0) { return getAllowedAlgorithms(defaultWhiteList, allowedValues, ImmutableSet.<String>copyOf(wlAlgorithms)); } @@ -72,7 +76,11 @@ public class MOAWhiteListConfigurator { candidateValue = StringUtils.trimToNull( KeyValueUtils.removeAllNewlineFromString(candidateValue)); if (StringUtils.isNotBlank(candidateValue)) { - String candidateAlgorithm = StringUtils.lowerCase(candidateValue, Locale.ENGLISH); + + //BUGFIX: eIDAS SAML-engine MPF1 signature schemes problem + String candidateAlgorithm = candidateValue; + //String candidateAlgorithm = StringUtils.lowerCase(candidateValue, Locale.ENGLISH); + if (allowedValues.contains(candidateAlgorithm)) { allowed.add(candidateValue); if (!modified && !candidateAlgorithm.equals(candidateValue)) { diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java index 171d5c8e2..8faaf1874 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/MOAeIDASMetadataGenerator.java @@ -477,7 +477,7 @@ public class MOAeIDASMetadataGenerator extends MetadataGenerator { X509Certificate decryptionCertificate = engine.getDecryptionCertificate(); if (null != decryptionCertificate) { - params.setEncryptionCredential(CertificateUtil.toCredential(decryptionCertificate)); + params.setSpEncryptionCredential(CertificateUtil.toCredential(decryptionCertificate)); } params.setSigningCredential(CertificateUtil.toCredential(engine.getSigningCertificate())); params.setIdpEngine(engine); @@ -542,7 +542,10 @@ public class MOAeIDASMetadataGenerator extends MetadataGenerator { Set<String> signatureMethods = EIDASUtil.parseSemicolonSeparatedList(params.getDigestMethods()); Set<String> digestMethods = new HashSet<String>(); for (String signatureMethod : signatureMethods) { - digestMethods.add(CertificateUtil.validateDigestAlgorithm(signatureMethod)); + + //BUGFIX: eIDAS implementation does not allow MGF1 signature schemes + digestMethods.add(signatureMethod); + //digestMethods.add(CertificateUtil.validateDigestAlgorithm(signatureMethod)); } for (String digestMethod : digestMethods) { final DigestMethod dm = (DigestMethod) BuilderFactoryUtil.buildXmlObject(DigestMethod.DEF_ELEMENT_NAME); @@ -581,7 +584,7 @@ public class MOAeIDASMetadataGenerator extends MetadataGenerator { generateDigest(eidasExtensions); if (!StringUtils.isEmpty(params.getSigningMethods())) { - Set<String> signMethods = EIDASUtil.parseSemicolonSeparatedList(params.getDigestMethods()); + Set<String> signMethods = EIDASUtil.parseSemicolonSeparatedList(params.getSigningMethods()); for (String signMethod : signMethods) { final SigningMethod sm = (SigningMethod) BuilderFactoryUtil.buildXmlObject(SigningMethod.DEF_ELEMENT_NAME); diff --git a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java index eb50c113f..70135c06f 100644 --- a/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java +++ b/id/server/modules/moa-id-module-eIDAS/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas/utils/SAMLEngineUtils.java @@ -30,8 +30,8 @@ import org.opensaml.xml.ConfigurationException; import org.opensaml.xml.XMLConfigurator; import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.config.MOAExtendedSWSigner; import at.gv.egovernment.moa.id.auth.modules.eidas.config.MOAIDCertificateManagerConfigurationImpl; -import at.gv.egovernment.moa.id.auth.modules.eidas.config.MOASWSigner; import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAEidasProtocolProcesser; import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider; import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASMetadataProviderDecorator; @@ -69,8 +69,8 @@ public class SAMLEngineUtils { metadataFetcher = new MOAeIDASMetadataProviderDecorator(moaeIDASMetadataProvider); //set metadata signer - metadataSigner = new MOASWSigner(configManager); - + metadataSigner = new MOAExtendedSWSigner(configManager); + //build eIDAS SAML eninge ProtocolEngineI engine = MOAProtocolEngineFactory.createProtocolEngine( Constants.eIDAS_SAML_ENGINE_NAME, |