diff options
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java')
-rw-r--r-- | id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java | 322 |
1 files changed, 318 insertions, 4 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java index c719484fa..13e7cb0f1 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java @@ -24,12 +24,13 @@ package at.gv.egovernment.moa.id.config; -import iaik.ixsil.util.Utils; import iaik.pki.pathvalidation.ChainingModes; import iaik.utils.RFC2253NameParser; import iaik.utils.RFC2253NameParserException; import java.math.BigInteger; +import java.net.MalformedURLException; +import java.net.URL; import java.security.Principal; import java.util.ArrayList; import java.util.HashMap; @@ -39,20 +40,23 @@ import java.util.List; import java.util.Map; import java.util.Vector; +import org.opensaml.saml2.metadata.RequestedAttribute; +import org.opensaml.ws.message.encoder.MessageEncodingException; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.traversal.NodeIterator; -import com.sun.xml.internal.fastinfoset.stax.events.Util; - import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; import at.gv.egovernment.moa.id.auth.data.Schema; import at.gv.egovernment.moa.id.auth.data.SchemaImpl; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.config.auth.VerifyInfoboxParameter; import at.gv.egovernment.moa.id.config.auth.VerifyInfoboxParameters; +import at.gv.egovernment.moa.id.config.stork.CPEPS; +import at.gv.egovernment.moa.id.config.stork.SignatureCreationParameter; +import at.gv.egovernment.moa.id.config.stork.SignatureVerificationParameter; import at.gv.egovernment.moa.id.data.IssuerAndSerial; import at.gv.egovernment.moa.id.util.MOAIDMessageProvider; import at.gv.egovernment.moa.logging.Logger; @@ -63,6 +67,12 @@ import at.gv.egovernment.moa.util.FileUtils; import at.gv.egovernment.moa.util.StringUtils; import at.gv.egovernment.moa.util.XPathException; import at.gv.egovernment.moa.util.XPathUtils; +import eu.stork.vidp.messages.builder.STORKMessagesBuilder; +import eu.stork.vidp.messages.common.STORKConstants; +import eu.stork.vidp.messages.stork.QualityAuthenticationAssuranceLevel; +import eu.stork.vidp.messages.stork.RequestedAttributes; +import eu.stork.vidp.messages.util.SAMLUtil; +import eu.stork.vidp.messages.util.XMLUtil; /** * A class that builds configuration data from a DOM based representation. @@ -80,6 +90,12 @@ public class ConfigurationBuilder { protected static final String CONF = Constants.MOA_ID_CONFIG_PREFIX + ":"; /** an XPATH-Expression */ protected static final String DSIG = Constants.DSIG_PREFIX + ":"; + + /** an XPATH-Expression */ + protected static final String STORK = Constants.STORK_PREFIX + ":"; + + /** an XPATH-Expression */ + protected static final String STORKP= Constants.STORKP_PREFIX + ":"; // // chaining mode constants appearing in the configuration file @@ -220,8 +236,58 @@ public class ConfigurationBuilder { protected static final String VERIFY_INFOBOXES_INFOBOX_XPATH = CONF + "Infobox"; + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_CPEPS = + ROOT + CONF + "AuthComponent/" + CONF + "ForeignIdentities/" + CONF + "STORK/" + CONF + "C-PEPS"; + + /** STORK Config AttributeName */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_CPEPS_COUNTRY_CODE = "countryCode"; + + /** STORK Config AttributeName */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_CPEPS_URL = "URL"; + + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_SIGNATURE_CREATION_PARAMETER = + ROOT + CONF + "AuthComponent/" + CONF + "ForeignIdentities/" + CONF + "STORK/" + CONF + "SAMLSigningParameter/" + + CONF + "SignatureCreationParameter" ; + + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_CPEPS_REQUESTED_ATTRIBUTES = + STORK + "RequestedAttribute"; + + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_SIGNATURE_VERIFICATION_PARAMETER = + ROOT + CONF + "AuthComponent/" + CONF + "ForeignIdentities/" + CONF + "STORK/" + CONF + "SAMLSigningParameter/" + + CONF + "SignatureVerificationParameter"; + + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_KEYSTORE = + CONF + "KeyStore"; + + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_KEYNAME = + CONF + "KeyName"; + + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_KEYSTORE_PASSWORD = + CONF + "KeyStore/@password"; + + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_KEYNAME_PASSWORD = + CONF + "KeyName/@password"; + + /** STORK Config XPATH-Expression */ + public static final String AUTH_FOREIGN_IDENTITIES_STORK_TRUSTPROFILE_ID = + CONF + "TrustProfileID"; + /** STORK Config XPATH-Expression */ + public static final String OA_AUTH_COMPONENT_STORK_QAA = + CONF + "STORK/" + STORK + "QualityAuthenticationAssuranceLevel"; + /** STORK Config XPATH-Expression */ + public static final String OA_AUTH_COMPONENT_STORK_REQUESTED_ATTRIBUTE = + CONF + "STORK/" + STORKP + "RequestedAttributes/" + STORK + "RequestedAttribute"; + /** * main configuration file directory name used to configure MOA-ID */ @@ -615,6 +681,32 @@ public class ConfigurationBuilder { oap.setMandateProfiles(profiles); } } + + //add STORK Configuration specific to OA (RequestedAttributes, QAALevel) + QualityAuthenticationAssuranceLevel qaaLevel = buildOaSTORKQAALevel(authComponent); + if (qaaLevel != null) { + oap.setQaaLevel(qaaLevel); + Logger.debug("Using non-MOA-default STORK QAALevel for this OA " + "(" + oap.getPublicURLPrefix() + "): " + qaaLevel.getValue()); + } + + RequestedAttributes additionalRequestedAttributes = buildOaSTORKRequestedAttributes(authComponent); + + if(!additionalRequestedAttributes.getRequestedAttributes().isEmpty()) { + //we have additional STORK attributes to request for this OA + Logger.debug("Using non-MOA-default STORK RequestedAttributes for this OA " + "(" + oap.getPublicURLPrefix() + "): "); + for (RequestedAttribute addReqAttr : additionalRequestedAttributes.getRequestedAttributes()) { + if (!SAMLUtil.containsAttribute(oap.getRequestedAttributes().getRequestedAttributes(),addReqAttr.getName())) { + addReqAttr.detach(); + oap.getRequestedAttributes().getRequestedAttributes().add(addReqAttr); + Logger.debug("Requesting additional attribute: " + addReqAttr.getName() + ", isRequired: " + addReqAttr.isRequired()); + } + } + + } else { + //do nothing, only request default attributes + } + + } OA_set.add(oap); } @@ -633,7 +725,7 @@ public class ConfigurationBuilder { */ private int buildConditionLength(String length) { - if (Util.isEmptyString(length)) + if (StringUtils.isEmpty(length)) return -1; else return new Integer(length).intValue(); @@ -1035,6 +1127,228 @@ public class ConfigurationBuilder { return new VerifyInfoboxParameters(defaultIdentifiers, infoboxParameters); } } + + /** + * Creates a SignatureCreationParameter object from the MOA-ID configuration + * This configuration object contains KeyStore and Key data for signature creation (STORK SAML Signature Creation). + * + * @return KeyStore and Key data for signature creation (STORK SAML Signature Creation) + */ + public SignatureCreationParameter buildSTORKSignatureCreationParameter() { + + Logger.debug("Loading STORK signature creation parameters."); + + Element signatureCreationParameterElement = (Element)XPathUtils.selectSingleNode(configElem_, AUTH_FOREIGN_IDENTITIES_STORK_SIGNATURE_CREATION_PARAMETER); + if (signatureCreationParameterElement == null) { + Logger.debug("No STORK signature parameters found, " + AUTH_FOREIGN_IDENTITIES_STORK_SIGNATURE_CREATION_PARAMETER + "is missing."); + return null; + } + + SignatureCreationParameter signatureCreationParameter = new SignatureCreationParameter(); + + Element keyStoreElement = (Element)XPathUtils.selectSingleNode(signatureCreationParameterElement, AUTH_FOREIGN_IDENTITIES_STORK_KEYSTORE); + if (keyStoreElement==null) { + Logger.error(AUTH_FOREIGN_IDENTITIES_STORK_KEYSTORE + "is missing."); + return null; + } + + Element keyNameElement = (Element)XPathUtils.selectSingleNode(signatureCreationParameterElement, AUTH_FOREIGN_IDENTITIES_STORK_KEYNAME); + if (keyNameElement==null) { + Logger.error(AUTH_FOREIGN_IDENTITIES_STORK_KEYNAME + "is missing."); + return null; + } + + String keyStorePath = DOMUtils.getText(keyStoreElement); + if (StringUtils.isEmpty(keyStorePath)) { + Logger.error("No KeyStorePath for STORK SAML Signing Certificate provided!"); + return null; + } + signatureCreationParameter.setKeyStorePath(FileUtils.makeAbsoluteURL(keyStorePath, rootConfigFileDir_)); + Logger.trace("Found KeyStorePath for STORK SAML Signing Certificate: " + keyStorePath); + + String keyStorePassword = XPathUtils.getAttributeValue(signatureCreationParameterElement, AUTH_FOREIGN_IDENTITIES_STORK_KEYSTORE_PASSWORD, ""); + signatureCreationParameter.setKeyStorePassword(keyStorePassword); + + String keyName = DOMUtils.getText(keyNameElement); + if (StringUtils.isEmpty(keyName)) { + Logger.warn(AUTH_FOREIGN_IDENTITIES_STORK_KEYSTORE_PASSWORD + "is missing."); + return null; + } + signatureCreationParameter.setKeyName(keyName); + Logger.trace("Found KeyName for STORK SAML Signing Certificate: " + keyName); + + String keyPassword = XPathUtils.getAttributeValue(signatureCreationParameterElement, AUTH_FOREIGN_IDENTITIES_STORK_KEYNAME_PASSWORD, ""); + signatureCreationParameter.setKeyPassword(keyPassword); + + Logger.info("STORK signature creation parameters loaded."); + + return signatureCreationParameter; + + } + + /** + * Creates a SignatureVerificationParameter object from the MOA-ID configuration + * This configuration object contains the TrustProfile to be used for signature verification (STORK SAML Signature Verification) + * + * @return TrustProfileID for signature verification (STORK SAML Signature Verification) + */ + public SignatureVerificationParameter buildSTORKSignatureVerificationParameter() { + + Logger.debug("Loading STORK signature verification parameters."); + + Element signatureVerificationParameterElement = (Element)XPathUtils.selectSingleNode(configElem_, AUTH_FOREIGN_IDENTITIES_STORK_SIGNATURE_VERIFICATION_PARAMETER); + if (signatureVerificationParameterElement == null) { + Logger.debug("No STORK verification parameters found, " +AUTH_FOREIGN_IDENTITIES_STORK_SIGNATURE_VERIFICATION_PARAMETER + "is missing."); + return null; + } + + SignatureVerificationParameter signatureVerificationParameter = new SignatureVerificationParameter(); + + String trustProfileID = XPathUtils.getElementValue(signatureVerificationParameterElement, AUTH_FOREIGN_IDENTITIES_STORK_TRUSTPROFILE_ID, null); + if (StringUtils.isEmpty(trustProfileID)) { + Logger.error(AUTH_FOREIGN_IDENTITIES_STORK_TRUSTPROFILE_ID + "is missing."); + return null; + } + Logger.trace("Using the following MOA-SP TrustProfile for STORK SAML signature verification: " + trustProfileID); + signatureVerificationParameter.setTrustProfileID(trustProfileID); + + Logger.info("STORK signature verification parameters loaded."); + + return signatureVerificationParameter; + } + + /** + * Builds a C-PEPS object from configuration + * @param cpepsElement DOM Element of C-PEPS from configuration + * @return C-PEPS object + */ + public CPEPS buildSTORKCpeps(Element cpepsElement) { + + String countryCode = cpepsElement.getAttribute(AUTH_FOREIGN_IDENTITIES_STORK_CPEPS_COUNTRY_CODE); + String cpepsURLString = cpepsElement.getAttribute(AUTH_FOREIGN_IDENTITIES_STORK_CPEPS_URL); + if (StringUtils.isEmpty(countryCode)) { + Logger.error(AUTH_FOREIGN_IDENTITIES_STORK_CPEPS_COUNTRY_CODE + "is missing."); + return null; + } + if (StringUtils.isEmpty(cpepsURLString)) { + Logger.error(AUTH_FOREIGN_IDENTITIES_STORK_CPEPS_URL + "is missing."); + return null; + } + + URL cpepsURL; + try { + cpepsURL = new URL(cpepsURLString); + } catch (MalformedURLException e) { + Logger.error("Provided CPEPS-URL (" + cpepsURLString + ") for country " + countryCode + " is not a URL", e); + return null; + } + CPEPS cpeps = new CPEPS(countryCode, cpepsURL); + Logger.debug("Adding C-PEPS for country: " + cpeps.getCountryCode() + ", URL: " + cpeps.getPepsURL()); + + Element reqAttributeElement; + NodeIterator reqAttributeIterator = XPathUtils.selectNodeIterator(cpepsElement, AUTH_FOREIGN_IDENTITIES_STORK_CPEPS_REQUESTED_ATTRIBUTES); + + while ((reqAttributeElement = (Element) reqAttributeIterator.nextNode()) != null) { + RequestedAttribute requestedAttribute; + try { + requestedAttribute = (RequestedAttribute) SAMLUtil.unmarshallMessage(reqAttributeElement); + } catch (MessageEncodingException e) { + Logger.error("Provided RequestedAttributes for CPEPS from country " + countryCode + " is malformed.", e); + return null; + } + //only add if STORK attribute is correct + if (STORKConstants.FULL_STORK_ATTRIBUTE_SET.contains(requestedAttribute.getName())) { + cpeps.addCountrySpecificRequestedAttribute(requestedAttribute); + Logger.debug("Adding also country specific requested attribute for C-PEPS (" + countryCode + "): " + requestedAttribute.getName() + ", isRequired: " + requestedAttribute.isRequired()); + } else { + Logger.warn("Skipping addition of requested STORK Attribute, attribute unknown : " + requestedAttribute.getName()); + } + + } + + return cpeps; + } + + /** + * Builds the supported C-PEPS Map from configuration + * @return Map of C-PEPS + */ + public Map<String, CPEPS> buildSTORKcPEPSMap() { + + Logger.debug("Loading STORK C-PEPS information"); + + Map<String, CPEPS> cpepsMap = new HashMap<String, CPEPS>(); + + NodeIterator cpepsIterator = XPathUtils.selectNodeIterator(configElem_, AUTH_FOREIGN_IDENTITIES_STORK_CPEPS); + + Element cpepsElement; + CPEPS cpeps; + + while ((cpepsElement = (Element) cpepsIterator.nextNode()) != null) { + cpeps = buildSTORKCpeps(cpepsElement); + if (cpeps != null) { + cpepsMap.put(cpeps.getCountryCode(), cpeps); + } + } + + if(!cpepsMap.isEmpty()) { + Logger.info("STORK C-PEPS information loaded"); + } + + return cpepsMap; + + } + + /** + * Builds the required STORK QAALevel for this OA + * @param authComponentElement DOM Element of AuthComponent (from MOA configuration) + * @return STORK QAALevel for this OA + */ + public QualityAuthenticationAssuranceLevel buildOaSTORKQAALevel(Element authComponentElement) { + Element qaaLevelElement = (Element)XPathUtils.selectSingleNode(authComponentElement, OA_AUTH_COMPONENT_STORK_QAA); + + if (qaaLevelElement == null) return null; + + try { + QualityAuthenticationAssuranceLevel qaaLevel = (QualityAuthenticationAssuranceLevel) SAMLUtil.unmarshallMessage(qaaLevelElement); + return qaaLevel; + } catch (MessageEncodingException e) { + Logger.error("Could not build STORK QAALevel, using default."); + return null; + } + + } + + /** + * Builds the Requested Attributes specific for an OA + * @param authComponentElement DOM Element of AuthComponent (from MOA configuration) + * @return STORK RequestedAttributes for this OA + */ + public RequestedAttributes buildOaSTORKRequestedAttributes(Element authComponentElement) { + List<RequestedAttribute> reqAttributeList = new ArrayList<RequestedAttribute>(); + + + Element reqAttributeElement; + NodeIterator reqAttributeIterator = XPathUtils.selectNodeIterator(authComponentElement, OA_AUTH_COMPONENT_STORK_REQUESTED_ATTRIBUTE); + + while ((reqAttributeElement = (Element) reqAttributeIterator.nextNode()) != null) { + RequestedAttribute requestedAttribute; + try { + requestedAttribute = (RequestedAttribute) SAMLUtil.unmarshallMessage(reqAttributeElement); + } catch (MessageEncodingException e) { + Logger.error("Provided RequestedAttributes Online Application is malformed.", e); + return null; + } + //only add if STORK attribute is correct + if (STORKConstants.FULL_STORK_ATTRIBUTE_SET.contains(requestedAttribute.getName())) { + reqAttributeList.add(requestedAttribute); + } else { + Logger.warn("Skipping addition of requested STORK Attribute, attribute unknown : " + requestedAttribute.getName()); + } + } + + return STORKMessagesBuilder.buildRequestedAttributes(reqAttributeList); + } /** * Method warn. |