aboutsummaryrefslogtreecommitdiff
path: root/id/server/idserverlib/src/main/java/at/gv/egovernment
diff options
context:
space:
mode:
authorkstranacher_eGovL <kstranacher_eGovL@d688527b-c9ab-4aba-bd8d-4036d912da1d>2012-07-12 11:27:13 +0000
committerkstranacher_eGovL <kstranacher_eGovL@d688527b-c9ab-4aba-bd8d-4036d912da1d>2012-07-12 11:27:13 +0000
commit1626ac9867cd5406b83e73651080e33c11fb98d1 (patch)
tree56bea0f086133bcd27017e2bfc205245a6e683b9 /id/server/idserverlib/src/main/java/at/gv/egovernment
parenta86a5fe1cfe7b0104d6524517414c7d5b5d2a2bb (diff)
downloadmoa-id-spss-1626ac9867cd5406b83e73651080e33c11fb98d1.tar.gz
moa-id-spss-1626ac9867cd5406b83e73651080e33c11fb98d1.tar.bz2
moa-id-spss-1626ac9867cd5406b83e73651080e33c11fb98d1.zip
Integration of STORK
git-svn-id: https://joinup.ec.europa.eu/svn/moa-idspss/trunk@1285 d688527b-c9ab-4aba-bd8d-4036d912da1d
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment')
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java394
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java2
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java4
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureRequestBuilder.java49
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java25
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AuthServlet.java64
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetForeignIDServlet.java143
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetMISSessionIDServlet.java16
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java227
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/StartAuthenticationServlet.java80
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java15
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/AssertionVerifier.java56
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/CredentialProvider.java50
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/KeyStoreCredentialProvider.java126
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/PEPSConnectorAssertionVerifier.java241
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/PEPSConnectorResponseVerifier.java153
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/ResponseVerifier.java44
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKAuthnRequestProcessor.java170
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKException.java42
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKResponseProcessor.java405
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/VelocityProvider.java88
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java322
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java28
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java60
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/CPEPS.java98
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java90
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/SignatureCreationParameter.java112
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/SignatureVerificationParameter.java35
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPUtils.java46
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParamValidatorUtils.java141
30 files changed, 3046 insertions, 280 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java
index a58f5fce2..a57ab5262 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java
@@ -29,8 +29,12 @@ import iaik.x509.X509Certificate;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.Principal;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
@@ -41,18 +45,24 @@ import java.util.Map;
import java.util.Set;
import java.util.Vector;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import org.apache.xpath.XPathAPI;
+import org.opensaml.saml2.metadata.RequestedAttribute;
+import org.opensaml.xml.util.Base64;
+import org.opensaml.xml.util.XMLHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import at.gv.egovernment.moa.id.AuthenticationException;
import at.gv.egovernment.moa.id.BuildException;
+import at.gv.egovernment.moa.id.MOAIDException;
import at.gv.egovernment.moa.id.ParseException;
import at.gv.egovernment.moa.id.ServiceException;
import at.gv.egovernment.moa.id.auth.builder.AuthenticationBlockAssertionBuilder;
@@ -83,6 +93,9 @@ import at.gv.egovernment.moa.id.auth.parser.InfoboxReadResponseParser;
import at.gv.egovernment.moa.id.auth.parser.SAMLArtifactParser;
import at.gv.egovernment.moa.id.auth.parser.VerifyXMLSignatureResponseParser;
import at.gv.egovernment.moa.id.auth.servlet.AuthServlet;
+import at.gv.egovernment.moa.id.auth.servlet.PEPSConnectorServlet;
+import at.gv.egovernment.moa.id.auth.stork.STORKAuthnRequestProcessor;
+import at.gv.egovernment.moa.id.auth.stork.STORKException;
import at.gv.egovernment.moa.id.auth.validator.CreateXMLSignatureResponseValidator;
import at.gv.egovernment.moa.id.auth.validator.IdentityLinkValidator;
import at.gv.egovernment.moa.id.auth.validator.InfoboxValidator;
@@ -90,6 +103,9 @@ import at.gv.egovernment.moa.id.auth.validator.ValidateException;
import at.gv.egovernment.moa.id.auth.validator.VerifyXMLSignatureResponseValidator;
import at.gv.egovernment.moa.id.auth.validator.parep.ParepUtils;
import at.gv.egovernment.moa.id.auth.validator.parep.ParepValidator;
+import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.CreateIdentityLinkResponse;
+import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWClient;
+import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWClientException;
import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWConstants;
import at.gv.egovernment.moa.id.config.ConfigurationException;
import at.gv.egovernment.moa.id.config.ConfigurationProvider;
@@ -98,6 +114,8 @@ import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
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.STORKConfig;
import at.gv.egovernment.moa.id.data.AuthenticationData;
import at.gv.egovernment.moa.id.util.HTTPUtils;
import at.gv.egovernment.moa.id.util.MOAIDMessageProvider;
@@ -113,6 +131,15 @@ import at.gv.egovernment.moa.util.DOMUtils;
import at.gv.egovernment.moa.util.DateTimeUtils;
import at.gv.egovernment.moa.util.FileUtils;
import at.gv.egovernment.moa.util.StringUtils;
+import eu.stork.mw.messages.saml.STORKAuthnRequest;
+import eu.stork.vidp.messages.builder.STORKMessagesBuilder;
+import eu.stork.vidp.messages.common.STORKConstants;
+import eu.stork.vidp.messages.exception.SAMLException;
+import eu.stork.vidp.messages.exception.SAMLValidationException;
+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;
/**
* API for MOA ID Authentication Service.<br> {@link AuthenticationSession} is
@@ -543,16 +570,16 @@ public class AuthenticationServer implements MOAIDAuthConstants {
int b = xmlInfoboxReadResponse.indexOf(se);
if (b != -1) { // no identity link found
Logger
- .info("Es konnte keine Personenbindung auf der Karte gefunden werden. Versuche Anmeldung als ausländische eID.");
+ .info("Es konnte keine Personenbindung auf der Karte gefunden werden. Versuche Anmeldung als ausl�ndische eID.");
return null;
}
- // spezifikationsgemäßer (SL1.2) Errorcode
+ // spezifikationsgem��er (SL1.2) Errorcode
se = "ErrorCode>4002";
// b = xmlInfoboxReadResponse.contains(se);
b = xmlInfoboxReadResponse.indexOf(se);
if (b != -1) { // Unbekannter Infoboxbezeichner
Logger
- .info("Unbekannter Infoboxbezeichner. Versuche Anmeldung als ausländische eID.");
+ .info("Unbekannter Infoboxbezeichner. Versuche Anmeldung als ausl�ndische eID.");
return null;
}
@@ -1732,7 +1759,7 @@ public class AuthenticationServer implements MOAIDAuthConstants {
// builds authentication data and stores it together with a SAML
// artifact
AuthenticationData authData = buildAuthenticationData(session, vsresp,
- useUTC);
+ useUTC, false);
if (session.getUseMandate()) {
// mandate mode
@@ -2037,17 +2064,7 @@ public class AuthenticationServer implements MOAIDAuthConstants {
AuthenticationSession session = getSession(sessionID);
// AuthConfigurationProvider authConf =
// AuthConfigurationProvider.getInstance();
- try {
- String serializedAssertion = DOMUtils.serializeNode(session
- .getIdentityLink().getSamlAssertion());
- session.setAuthBlock(serializedAssertion);
- } catch (TransformerException e) {
- throw new ParseException("parser.04", new Object[] {
- REQ_VERIFY_AUTH_BLOCK, PARAM_XMLRESPONSE });
- } catch (IOException e) {
- throw new ParseException("parser.04", new Object[] {
- REQ_VERIFY_AUTH_BLOCK, PARAM_XMLRESPONSE });
- }
+
// post processing of the infoboxes
Iterator iter = session.getInfoboxValidatorIterator();
boolean formpending = false;
@@ -2097,7 +2114,7 @@ public class AuthenticationServer implements MOAIDAuthConstants {
boolean useCondition = oaParam.getUseCondition();
int conditionLength = oaParam.getConditionLength();
AuthenticationData authData = buildAuthenticationData(session, vsresp,
- useUTC);
+ useUTC, true);
String samlAssertion = new AuthenticationDataAssertionBuilder().build(
authData, session.getAssertionPrPerson(), session
@@ -2141,6 +2158,9 @@ public class AuthenticationServer implements MOAIDAuthConstants {
* authentication session
* @param verifyXMLSigResp
* VerifyXMLSignatureResponse from MOA-SP
+ * @param useUTC uses correct UTC time format
+ * @param useUTC indicates that authenticated citizen is a foreigner
+ * @param isForeigner indicates whether Austrian (false) or foreigner (true) authenticates
* @return AuthenticationData object
* @throws ConfigurationException
* while accessing configuration data
@@ -2149,7 +2169,7 @@ public class AuthenticationServer implements MOAIDAuthConstants {
*/
private AuthenticationData buildAuthenticationData(
AuthenticationSession session,
- VerifyXMLSignatureResponse verifyXMLSigResp, boolean useUTC)
+ VerifyXMLSignatureResponse verifyXMLSigResp, boolean useUTC, boolean isForeigner)
throws ConfigurationException, BuildException {
IdentityLink identityLink = session.getIdentityLink();
@@ -2196,21 +2216,44 @@ public class AuthenticationServer implements MOAIDAuthConstants {
}
}
authData.setSignerCertificate(signerCertificateBase64);
- if (businessService) {
- authData.setWBPK(identityLink.getIdentificationValue());
+ if(!isForeigner) {
+ //we have Austrian citizen
+ if (businessService) {
+ authData.setWBPK(identityLink.getIdentificationValue());
+ } else {
+ authData.setBPK(identityLink.getIdentificationValue());
+
+ // BZ.., calculation of bPK already before sending AUTHBlock
+ /*
+ * if(identityLink.getIdentificationType().equals(Constants.
+ * URN_PREFIX_BASEID)) { // only compute bPK if online
+ * application is a public service and we have the Stammzahl
+ * String bpkBase64 = new BPKBuilder().buildBPK(
+ * identityLink.getIdentificationValue(), session.getTarget());
+ * authData.setBPK(bpkBase64); }
+ */
+
+ }
} else {
- authData.setBPK(identityLink.getIdentificationValue());
-
- // BZ.., calculation of bPK already before sending AUTHBlock
- /*
- * if(identityLink.getIdentificationType().equals(Constants.
- * URN_PREFIX_BASEID)) { // only compute bPK if online
- * application is a public service and we have the Stammzahl
- * String bpkBase64 = new BPKBuilder().buildBPK(
- * identityLink.getIdentificationValue(), session.getTarget());
- * authData.setBPK(bpkBase64); }
- */
-
+ //we have foreigner, thus we have to calculate bPK and wbPK now (after receiving identity link from SZR-GW
+ if (businessService) {
+ //since we have foreigner, wbPK is not calculated in BKU
+ if(identityLink.getIdentificationType().equals(Constants.URN_PREFIX_BASEID)) {
+ String wbpkBase64 = new BPKBuilder().buildWBPK(identityLink.getIdentificationValue(), session.getDomainIdentifier());
+ authData.setWBPK(wbpkBase64);
+ }
+
+ } else {
+
+ if(identityLink.getIdentificationType().equals(Constants.URN_PREFIX_BASEID)) {
+ // only compute bPK if online application is a public service and we have the Stammzahl
+ String bpkBase64 = new BPKBuilder().buildBPK(identityLink.getIdentificationValue(), session.getTarget());
+ authData.setBPK(bpkBase64);
+ }
+
+
+ }
+
}
String ilAssertion = oaParam.getProvideIdentityLink() ? identityLink
.getSerializedSamlAssertion()
@@ -2227,8 +2270,7 @@ public class AuthenticationServer implements MOAIDAuthConstants {
session.setAssertionBusinessService(businessService);
session.setAssertionIlAssertion(ilAssertion);
session.setAssertionPrPerson(prPerson);
- session
- .setAssertionSignerCertificateBase64(signerCertificateBase64);
+ session.setAssertionSignerCertificateBase64(signerCertificateBase64);
return authData;
@@ -2482,4 +2524,288 @@ public class AuthenticationServer implements MOAIDAuthConstants {
return value;
}
+
+ /**
+ * Does the request to the SZR-GW
+ * @param signature XMLDSIG signature
+ * @return Identity link assertion
+ * @throws SZRGWClientException
+ */
+ public CreateIdentityLinkResponse getIdentityLink(String PEPSIdentifier, String PEPSFirstname, String PEPSFamilyname, String PEPSDateOfBirth, Element signature) throws SZRGWClientException {
+
+ SZRGWClient client = new SZRGWClient();
+
+ try {
+ AuthConfigurationProvider authConf = AuthConfigurationProvider.getInstance();
+ ConnectionParameter connectionParameters = authConf.getForeignIDConnectionParameter();
+
+ client.setAddress(connectionParameters.getUrl());
+ if (connectionParameters.getUrl().toLowerCase().startsWith("https:")) {
+ Logger.debug("Initialisiere SSL Verbindung");
+ try {
+ client.setSSLSocketFactory(SSLUtils.getSSLSocketFactory(AuthConfigurationProvider.getInstance(), connectionParameters));
+ } catch (IOException e) {
+ Logger.error("Could not initialize SSL Factory", e);
+ throw new SZRGWClientException("Could not initialize SSL Factory");
+ } catch (GeneralSecurityException e) {
+ Logger.error("Could not initialize SSL Factory", e);
+ throw new SZRGWClientException("Could not initialize SSL Factory");
+ } catch (PKIException e) {
+ Logger.error("Could not initialize SSL Factory", e);
+ throw new SZRGWClientException("Could not initialize SSL Factory");
+ }
+ }
+ Logger.info("Starte Kommunikation mit dem Stammzahlenregister Gateway(" + connectionParameters.getUrl() + ")...");
+ }
+ catch (ConfigurationException e) {
+ Logger.warn(e);
+ Logger.warn(MOAIDMessageProvider.getInstance().getMessage("config.12", null ));
+ }
+
+ // create request
+ CreateIdentityLinkResponse response = null;
+ Element request = null;
+ try {
+ Document doc = client.buildGetIdentityLinkRequest(PEPSIdentifier, PEPSFirstname, PEPSFamilyname, PEPSDateOfBirth, signature);
+ request = doc.getDocumentElement();
+
+ // send request
+ response = client.createIdentityLinkResponse(request);
+ } catch (SZRGWClientException e) {
+ // give him a second try - Nach dem Starten des Tomcat wird beim ersten Mal das Client-Zertifikat offenbar vom HTTPClient nicht mitgeschickt.
+ try {
+ response = client.createIdentityLinkResponse(request);
+ }
+ catch (SZRGWClientException e1) {
+ throw new SZRGWClientException(e1);
+ }
+ }
+
+
+ return response;
+
+ }
+
+ /**
+ * Starts a MOA-ID authentication process using STORK
+ * @param req HttpServletRequest
+ * @param resp HttpServletResponse
+ * @param ccc Citizen country code
+ * @param oaURL URL of the online application
+ * @param target Target parameter
+ * @param targetFriendlyName Friendly Name of Target
+ * @param authURL Authentication URL
+ * @param sourceID SourceID parameter
+ * @throws MOAIDException
+ * @throws AuthenticationException
+ * @throws WrongParametersException
+ * @throws ConfigurationException
+ */
+ public static void startSTORKAuthentication(
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ String ccc,
+ String oaURL,
+ String target,
+ String targetFriendlyName,
+ String authURL,
+ String sourceID) throws MOAIDException, AuthenticationException, WrongParametersException, ConfigurationException {
+
+ //read configuration paramters of OA
+ OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(oaURL);
+ if (oaParam == null)
+ throw new AuthenticationException("auth.00", new Object[] { oaURL });
+
+ if (!oaParam.getBusinessService()) {
+ if (StringUtils.isEmpty(target))
+ throw new WrongParametersException("StartAuthentication", PARAM_TARGET, "auth.05");
+ } else {
+ target = null;
+ }
+
+ //create MOA session
+ AuthenticationSession moaSession = newSession();
+ Logger.info("MOASession " + moaSession.getSessionID() + " angelegt");
+ moaSession.setTarget(target);
+ moaSession.setTargetFriendlyName(targetFriendlyName);
+ moaSession.setOAURLRequested(oaURL);
+ moaSession.setPublicOAURLPrefix(oaParam.getPublicURLPrefix());
+ moaSession.setAuthURL(authURL);
+ moaSession.setBusinessService(oaParam.getBusinessService());
+ moaSession.setDomainIdentifier(oaParam.getIdentityLinkDomainIdentifier());
+ if (sourceID != null)
+ moaSession.setSourceID(sourceID);
+
+ //Start of STORK Processing
+ STORKConfig storkConfig = AuthConfigurationProvider.getInstance().getStorkConfig();
+
+ CPEPS cpeps = storkConfig.getCPEPS(ccc);
+
+ Logger.debug("Preparing to assemble STORK AuthnRequest witht the following values:");
+ String destination = cpeps.getPepsURL().toExternalForm();
+ Logger.debug("C-PEPS URL: " + destination);
+
+ String acsURL = HTTPUtils.getBaseURL(req) + PEPSConnectorServlet.PEPSCONNECTOR_SERVLET_URL_PATTERN;
+ Logger.debug("MOA Assertion Consumer URL (PEPSConnctor): " + acsURL);
+
+ String providerName= oaParam.getFriendlyName();
+ String issuerValue = HTTPUtils.getBaseURL(req);
+ Logger.debug("Issuer value: " + issuerValue);
+
+ QualityAuthenticationAssuranceLevel qaaLevel = STORKMessagesBuilder.buildQualityAuthenticationAssuranceLevel(oaParam.getQaaLevel().getValue());
+ Logger.debug("QAALevel: " + qaaLevel.getValue());
+
+ RequestedAttributes requestedAttributes;
+
+ requestedAttributes = oaParam.getRequestedAttributes();
+ requestedAttributes.detach();
+ List<RequestedAttribute> reqAttributeList = new ArrayList<RequestedAttribute>();
+ List<RequestedAttribute> oaReqAttributeList = new ArrayList<RequestedAttribute>(oaParam.getRequestedAttributes().getRequestedAttributes());
+ //check if country specific attributes must be additionally requested
+ if (!cpeps.getCountrySpecificRequestedAttributes().isEmpty()) {
+ //add country specific attributes to be requested (Hierarchy: default oa attributes > country specific attributes > oa specific attributes
+ Logger.debug("We have addtional country specific attributes to be requested from the C-PEPS of country: " + ccc);
+ Logger.debug("The following attributes are requested for this specific country:");
+ List<RequestedAttribute> countrySpecificReqAttributeList = new ArrayList<RequestedAttribute>(cpeps.getCountrySpecificRequestedAttributes());
+ for (RequestedAttribute csReqAttr : countrySpecificReqAttributeList) {
+ csReqAttr.detach();
+ if (!STORKConstants.DEFAULT_STORK_REQUESTED_ATTRIBUTE_SET.contains(csReqAttr.getName())) {
+ //this country specific attribute does not override default attribute
+ if (SAMLUtil.containsAttribute(oaReqAttributeList, csReqAttr.getName())) {
+ //the same attribute is requested for OA, applying hierachy
+ //remove oa attribute
+ oaReqAttributeList.remove(SAMLUtil.getAttribute(oaReqAttributeList, csReqAttr.getName()));
+ //add country specific attribute instead
+ Logger.debug("Requested Attribute (" + csReqAttr.getName() + ") is also requested by OA but we use Country Specific value instead");
+ }
+ oaReqAttributeList.add(csReqAttr);
+ Logger.debug("Country specific requested attribute: " + csReqAttr.getName() + ", isRequired: " + csReqAttr.isRequired());
+ } else {
+ Logger.debug("Country specific requested attribute: " + csReqAttr.getName() + ", isRequired: " + csReqAttr.isRequired() + " tries to overwrite default requested and required attributes, hence we skip it.");
+ }
+
+ }
+ reqAttributeList.addAll(oaReqAttributeList);
+ } else {
+ //no country specific requested attributes
+ reqAttributeList.addAll(oaReqAttributeList);
+ }
+
+ reqAttributeList = (List<RequestedAttribute>) SAMLUtil.releaseDOM(reqAttributeList);
+ requestedAttributes = STORKMessagesBuilder.buildRequestedAttributes(reqAttributeList);
+
+ if (Logger.isDebugEnabled()) {
+ Logger.debug("The following attributes are requested for this OA:");
+ for (RequestedAttribute logReqAttr : reqAttributeList) {
+ Logger.debug("OA specific requested attribute: " + logReqAttr.getName() + ", isRequired: " + logReqAttr.isRequired());
+
+ }
+ }
+
+ String spSector = StringUtils.isEmpty(target) ? "Business" : target;
+ String spInstitution = StringUtils.isEmpty(oaParam.getFriendlyName()) ? "UNKNOWN" : oaParam.getFriendlyName();
+ String spApplication = spInstitution;
+ String spCountry = "AT";
+
+ String textToBeSigned =
+ CreateXMLSignatureRequestBuilder.buildForeignIDTextToBeSigned("wie im Signaturzertifikat (as in my signature certificate)", oaParam, moaSession);
+
+ //generate AuthnRquest
+ STORKAuthnRequest storkAuthnRequest = STORKAuthnRequestProcessor.generateSTORKAuthnRequest(
+ destination,
+ acsURL,
+ providerName,
+ issuerValue,
+ qaaLevel,
+ requestedAttributes,
+ spSector,
+ spInstitution,
+ spApplication,
+ spCountry,
+ textToBeSigned,
+ "application/xhtml+xml");
+
+ Logger.debug("STORK AuthnRequest succesfully assembled.");
+
+ //sign AuthnRequest
+ String keyStorePath = storkConfig.getSignatureCreationParameter().getKeyStorePath();
+ String keyStorePassword = storkConfig.getSignatureCreationParameter().getKeyStorePassword();
+ String keyName = storkConfig.getSignatureCreationParameter().getKeyName();
+ String keyPassword = storkConfig.getSignatureCreationParameter().getKeyPassword();
+
+ Logger.debug("Starting signing process of STORK AuthnRequest.");
+ Logger.trace("Using the following Keystore and Key for that:");
+ Logger.trace("KeyStore: " + keyStorePath);
+ Logger.trace("KeyName: " + keyName);
+
+ try {
+ storkAuthnRequest = STORKAuthnRequestProcessor.signSTORKAuthnRequest(storkAuthnRequest, keyStorePath, keyStorePassword, keyName, keyPassword);
+ } catch (SAMLException e) {
+ Logger.error("Could not sign STORK SAML AuthnRequest.", e);
+ throw new MOAIDException("stork.00", null);
+ }
+
+ Logger.info("STORK AuthnRequest successfully signed!");
+
+ //validate AuthnRequest
+ try {
+ STORKAuthnRequestProcessor.validateSTORKAuthnRequest(storkAuthnRequest);
+ } catch (SAMLValidationException e) {
+ Logger.error("STORK SAML AuthnRequest not valid.", e);
+ throw new MOAIDException("stork.01", null);
+ }
+
+ Logger.debug("STORK AuthnRequest successfully internally validated.");
+
+ //send
+ moaSession.setStorkAuthnRequest(storkAuthnRequest);
+ HttpSession httpSession = req.getSession();
+ httpSession.setAttribute("MOA-Session-ID", moaSession.getSessionID());
+
+ Logger.debug("Preparing to send STORK AuthnRequest.");
+
+ try {
+ STORKAuthnRequestProcessor.sendSTORKAuthnRequest(req, resp, storkAuthnRequest);
+ } catch (Exception e) {
+ Logger.error("Error sending STORK SAML AuthnRequest.", e);
+ httpSession.invalidate();
+ throw new MOAIDException("stork.02", new Object[] { destination });
+ }
+
+ Logger.info("STORK AuthnRequest successfully sent to: " + storkAuthnRequest.getDestination());
+ Logger.debug("STORKAuthnRequest sent (pretty print): ");
+ Logger.debug(XMLHelper.prettyPrintXML(storkAuthnRequest.getDOM()));
+ Logger.trace("STORKAuthnRequest sent (original): ");
+ Logger.trace(XMLUtil.printXML(storkAuthnRequest.getDOM()));
+
+ }
+
+ /**
+ * Extracts an X509 Certificate out of an XML signagture element
+ * @param signedXML XML signature element
+ * @return X509Certificate
+ * @throws CertificateException
+ */
+ public static X509Certificate getCertificateFromXML(Element signedXML) throws CertificateException {
+
+ NodeList nList = signedXML.getElementsByTagNameNS(Constants.DSIG_NS_URI, "X509Certificate");
+
+ String base64CertString = XMLUtil.getFirstTextValueFromNodeList(nList);
+
+ if (StringUtils.isEmpty(base64CertString)) {
+ String msg = "XML does not contain a X509Certificate element.";
+ Logger.error(msg);
+ throw new CertificateException(msg);
+ }
+
+ InputStream is = new ByteArrayInputStream(Base64.decode(base64CertString));
+
+ CertificateFactory cf;
+ X509Certificate cert = null;
+ cf = CertificateFactory.getInstance("X.509");
+ cert = (X509Certificate)cf.generateCertificate(is);
+
+ return cert;
+ }
+
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java
index f3be98ef0..7d5835f20 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java
@@ -47,6 +47,8 @@ public interface MOAIDAuthConstants {
public static final String PARAM_SOURCEID = "sourceID";
/** servlet parameter &quot;BKUSelectionTemplate&quot; */
public static final String PARAM_BKUTEMPLATE = "BKUSelectionTemplate";
+ /** servlet parameter &quot;CCC (Citizen Country Code)&quot; */
+ public static final String PARAM_CCC = "CCC";
/** servlet parameter &quot;BKUSelectionTemplate&quot; */
public static final String PARAM_INPUT_PROCESSOR_SIGN_TEMPLATE = "InputProcessorSignTemplate";
/** default BKU URL */
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java
index b6ba5871d..fa9789530 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java
@@ -56,7 +56,7 @@ public class BPKBuilder {
target.length() == 0))
{
throw new BuildException("builder.00",
- new Object[] {"BPK", "Unvollständige Parameterangaben: identificationValue=" +
+ new Object[] {"BPK", "Unvollständige Parameterangaben: identificationValue=" +
identificationValue + ",target=" + target});
}
String basisbegriff = identificationValue + "+" + Constants.URN_PREFIX_CDID + "+" + target;
@@ -86,7 +86,7 @@ public class BPKBuilder {
registerAndOrdNr.length() == 0))
{
throw new BuildException("builder.00",
- new Object[] {"wbPK", "Unvollständige Parameterangaben: identificationValue=" +
+ new Object[] {"wbPK", "Unvollständige Parameterangaben: identificationValue=" +
identificationValue + ",Register+Registernummer=" + registerAndOrdNr});
}
String basisbegriff = identificationValue + "+" + Constants.URN_PREFIX_WBPK + "+" + registerAndOrdNr;
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureRequestBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureRequestBuilder.java
index 9c696f245..2da7db2b2 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureRequestBuilder.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureRequestBuilder.java
@@ -129,7 +129,31 @@ public class CreateXMLSignatureRequestBuilder implements Constants {
* @return String representation of <code>&lt;CreateXMLSignatureRequest&gt;</code>
*/
public String buildForeignID(String subject, OAAuthParameter oaParam, AuthenticationSession session) {
+
+ String request = "";
+ request += "<sl:CreateXMLSignatureRequest xmlns:sl=\"http://www.buergerkarte.at/namespaces/securitylayer/1.2#\">";
+ request += "<sl:KeyboxIdentifier>SecureSignatureKeypair</sl:KeyboxIdentifier>";
+ request += "<sl:DataObjectInfo Structure=\"enveloping\">";
+ request += "<sl:DataObject>";
+ request += "<sl:XMLContent>";
+
+ request += buildForeignIDTextToBeSigned(subject, oaParam, session);
+ request += "</sl:XMLContent>";
+ request += "</sl:DataObject>";
+ request += "<sl:TransformsInfo>";
+ request += "<sl:FinalDataMetaInfo>";
+ request += "<sl:MimeType>application/xhtml+xml</sl:MimeType>";
+ request += "</sl:FinalDataMetaInfo>";
+ request += "</sl:TransformsInfo>";
+ request += "</sl:DataObjectInfo>";
+ request += "</sl:CreateXMLSignatureRequest>";
+
+ return request;
+ }
+
+ public static String buildForeignIDTextToBeSigned(String subject, OAAuthParameter oaParam, AuthenticationSession session) {
+
String target = session.getTarget();
String sectorName = TargetToSectorNameMapper.getSectorNameViaTarget(target);
@@ -137,14 +161,9 @@ public class CreateXMLSignatureRequestBuilder implements Constants {
String date = DateTimeUtils.buildDate(cal);
String time = DateTimeUtils.buildTime(cal);
- String request = "";
- request += "<sl:CreateXMLSignatureRequest xmlns:sl=\"http://www.buergerkarte.at/namespaces/securitylayer/1.2#\">";
- request += "<sl:KeyboxIdentifier>SecureSignatureKeypair</sl:KeyboxIdentifier>";
- request += "<sl:DataObjectInfo Structure=\"enveloping\">";
- request += "<sl:DataObject>";
- request += "<sl:XMLContent>";
-
- request += "<html xmlns=\"http://www.w3.org/1999/xhtml\">";
+ String request = "";
+ request += "<html xmlns=\"http://www.w3.org/1999/xhtml\">"; //application/xhtml+xml text/html
+ //request += "<meta http-equiv=\"content-type\" content=\"application/xhtml+xml; charset=UTF-8\">";
request += "<head>";
request += "<title>Signatur der Anmeldedaten</title>";
request += "<style type=\"text/css\" media=\"screen\">";
@@ -263,17 +282,9 @@ public class CreateXMLSignatureRequestBuilder implements Constants {
request += "</body>";
request += "</html>";
-
- request += "</sl:XMLContent>";
- request += "</sl:DataObject>";
- request += "<sl:TransformsInfo>";
- request += "<sl:FinalDataMetaInfo>";
- request += "<sl:MimeType>application/xhtml+xml</sl:MimeType>";
- request += "</sl:FinalDataMetaInfo>";
- request += "</sl:TransformsInfo>";
- request += "</sl:DataObjectInfo>";
- request += "</sl:CreateXMLSignatureRequest>";
-
+
return request;
+
}
+
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java
index 5a18b720b..e861c62fa 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java
@@ -24,6 +24,8 @@
package at.gv.egovernment.moa.id.auth.data;
+
+
import iaik.x509.X509Certificate;
import java.util.ArrayList;
@@ -37,6 +39,7 @@ import at.gv.egovernment.moa.id.auth.validator.parep.ParepUtils;
import at.gv.egovernment.moa.id.data.AuthenticationData;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.Constants;
+import eu.stork.mw.messages.saml.STORKAuthnRequest;
/**
* Session data to be stored between <code>AuthenticationServer</code> API calls.
@@ -204,7 +207,10 @@ public class AuthenticationSession {
*/
private String pushInfobox;
-
+ /**
+ * The STORK AuthRequest to be sent to the C-PEPS
+ */
+ private STORKAuthnRequest storkAuthnRequest;
/**
* Constructor for AuthenticationSession.
@@ -814,6 +820,23 @@ public class AuthenticationSession {
public void setMandateReferenceValue(String mandateReferenceValue) {
this.mandateReferenceValue = mandateReferenceValue;
}
+
+ /**
+ * Gets the STORK SAML AuthnRequest
+ * @return STORK SAML AuthnRequest
+ */
+ public STORKAuthnRequest getStorkAuthnRequest() {
+ return storkAuthnRequest;
+ }
+
+ /**
+ * Sets the STORK SAML AuthnRequest
+ * @param storkAuthnRequest STORK SAML AuthnRequest
+ */
+ public void setStorkAuthnRequest(STORKAuthnRequest storkAuthnRequest) {
+ this.storkAuthnRequest = storkAuthnRequest;
+ }
+
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AuthServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AuthServlet.java
index a19618dc2..16041f8cb 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AuthServlet.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/AuthServlet.java
@@ -46,10 +46,18 @@ import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import at.gv.egovernment.moa.id.AuthenticationException;
+import at.gv.egovernment.moa.id.auth.AuthenticationServer;
import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
import at.gv.egovernment.moa.id.auth.WrongParametersException;
+import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.BoolUtils;
import at.gv.egovernment.moa.util.URLDecoder;
+import at.gv.egovernment.moa.util.URLEncoder;
/**
* Base class for MOA-ID Auth Servlets, providing standard error handling
@@ -65,7 +73,16 @@ public class AuthServlet extends HttpServlet implements MOAIDAuthConstants {
*
*/
private static final long serialVersionUID = -6929905344382283738L;
+
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ Logger.debug("GET " + this.getServletName());
+
+ this.setNoCachingHeadersInHttpRespone(req, resp);
+}
/**
* Handles an error. <br>>
* <ul>
@@ -260,4 +277,51 @@ public class AuthServlet extends HttpServlet implements MOAIDAuthConstants {
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
}
+
+ /**
+ * Set response headers to avoid caching
+ * @param request HttpServletRequest
+ * @param response HttpServletResponse
+ */
+ protected void setNoCachingHeadersInHttpRespone(HttpServletRequest request, HttpServletResponse response) {
+ response.setHeader(MOAIDAuthConstants.HEADER_EXPIRES,MOAIDAuthConstants.HEADER_VALUE_EXPIRES);
+ response.setHeader(MOAIDAuthConstants.HEADER_PRAGMA,MOAIDAuthConstants.HEADER_VALUE_PRAGMA);
+ response.setHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL);
+ response.addHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL_IE);
+
+ }
+
+ /**
+ * Adds a parameter to a URL.
+ * @param url the URL
+ * @param paramname parameter name
+ * @param paramvalue parameter value
+ * @return the URL with parameter added
+ */
+ protected static String addURLParameter(String url, String paramname, String paramvalue) {
+ String param = paramname + "=" + paramvalue;
+ if (url.indexOf("?") < 0)
+ return url + "?" + param;
+ else
+ return url + "&" + param;
+ }
+
+ /**
+ * Checks if HTTP requests are allowed
+ * @param authURL requestURL
+ * @throws AuthenticationException if HTTP requests are not allowed
+ * @throws ConfigurationException
+ */
+ protected void checkIfHTTPisAllowed(String authURL) throws AuthenticationException, ConfigurationException {
+ // check if HTTP Connection may be allowed (through
+ // FRONTEND_SERVLETS_ENABLE_HTTP_CONNECTION_PROPERTY)
+ String boolStr = AuthConfigurationProvider.getInstance().getGenericConfigurationParameter(
+ AuthConfigurationProvider.FRONTEND_SERVLETS_ENABLE_HTTP_CONNECTION_PROPERTY);
+ if ((!authURL.startsWith("https:"))
+ && (false == BoolUtils.valueOf(boolStr)))
+ throw new AuthenticationException("auth.07",
+ new Object[] { authURL + "*" });
+
+ }
+
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetForeignIDServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetForeignIDServlet.java
index 246a47699..bf7a0f714 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetForeignIDServlet.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetForeignIDServlet.java
@@ -24,19 +24,17 @@
package at.gv.egovernment.moa.id.auth.servlet;
-import iaik.pki.PKIException;
-
import java.io.IOException;
-import java.security.GeneralSecurityException;
+import java.security.cert.CertificateException;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.xml.transform.TransformerException;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.lang.StringEscapeUtils;
-import org.w3c.dom.Document;
import org.w3c.dom.Element;
import at.gv.egovernment.moa.id.MOAIDException;
@@ -50,15 +48,10 @@ import at.gv.egovernment.moa.id.auth.data.IdentityLink;
import at.gv.egovernment.moa.id.auth.parser.CreateXMLSignatureResponseParser;
import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser;
import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.CreateIdentityLinkResponse;
-import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWClient;
import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWClientException;
-import at.gv.egovernment.moa.id.config.ConfigurationException;
-import at.gv.egovernment.moa.id.config.ConnectionParameter;
-import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
-import at.gv.egovernment.moa.id.util.MOAIDMessageProvider;
import at.gv.egovernment.moa.id.util.ParamValidatorUtils;
-import at.gv.egovernment.moa.id.util.SSLUtils;
import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.DOMUtils;
import at.gv.egovernment.moa.util.URLEncoder;
/**
@@ -89,14 +82,7 @@ public class GetForeignIDServlet extends AuthServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
- Logger.debug("GET GetForeignIDServlet");
-
- resp.setHeader(MOAIDAuthConstants.HEADER_EXPIRES,MOAIDAuthConstants.HEADER_VALUE_EXPIRES);
- resp.setHeader(MOAIDAuthConstants.HEADER_PRAGMA,MOAIDAuthConstants.HEADER_VALUE_PRAGMA);
- resp.setHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL);
- resp.addHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL_IE);
-
-
+ super.doGet(req, resp);
}
/**
@@ -160,10 +146,17 @@ public class GetForeignIDServlet extends AuthServlet {
CreateXMLSignatureResponse csresp =
new CreateXMLSignatureResponseParser(xmlCreateXMLSignatureResponse).parseResponseDsig();
- Element signature = csresp.getDsigSignature();
+ Element signature = csresp.getDsigSignature();
+
+ try {
+ session.setSignerCertificate(AuthenticationServer.getCertificateFromXML(signature));
+ } catch (CertificateException e) {
+ Logger.error("Could not extract certificate from CreateXMLSignatureResponse");
+ throw new MOAIDException("auth.14", null);
+ }
// make SZR request to the identity link
- CreateIdentityLinkResponse response = getIdentityLink(signature);
+ CreateIdentityLinkResponse response = AuthenticationServer.getInstance().getIdentityLink(null, null, null, null, signature);
if (response.isError()) {
@@ -173,28 +166,30 @@ public class GetForeignIDServlet extends AuthServlet {
Element samlAssertion = response.getAssertion();
-// try {
-// System.out.println(DOMUtils.serializeNode(samlAssertion));
-// } catch (TransformerException e) {
-// e.printStackTrace();
-// }
+ try {
+ System.out.println("PB: " + DOMUtils.serializeNode(samlAssertion));
+ } catch (TransformerException e) {
+ e.printStackTrace();
+ }
IdentityLinkAssertionParser ilParser = new IdentityLinkAssertionParser(samlAssertion);
IdentityLink identitylink = ilParser.parseIdentityLink();
session.setIdentityLink(identitylink);
String samlArtifactBase64 =
- AuthenticationServer.getInstance().getForeignAuthenticationData(sessionID);
- if (!samlArtifactBase64.equals("Redirect to Input Processor")) {
- redirectURL = session.getOAURLRequested();
- if (!session.getBusinessService()) {
- redirectURL = addURLParameter(redirectURL, PARAM_TARGET, URLEncoder.encode(session.getTarget(), "UTF-8"));
- }
- redirectURL = addURLParameter(redirectURL, PARAM_SAMLARTIFACT, URLEncoder.encode(samlArtifactBase64, "UTF-8"));
- redirectURL = resp.encodeRedirectURL(redirectURL);
- } else {
- redirectURL = new DataURLBuilder().buildDataURL(session.getAuthURL(), AuthenticationServer.REQ_PROCESS_VALIDATOR_INPUT, session.getSessionID());
+ AuthenticationServer.getInstance().getForeignAuthenticationData(sessionID);
+ if (!samlArtifactBase64.equals("Redirect to Input Processor")) {
+ redirectURL = session.getOAURLRequested();
+ if (!session.getBusinessService()) {
+ redirectURL = addURLParameter(redirectURL, PARAM_TARGET, URLEncoder.encode(session.getTarget(), "UTF-8"));
+ }
+ redirectURL = addURLParameter(redirectURL, PARAM_SAMLARTIFACT, URLEncoder.encode(samlArtifactBase64, "UTF-8"));
+ redirectURL = resp.encodeRedirectURL(redirectURL);
+
+ } else {
+ redirectURL = new DataURLBuilder().buildDataURL(session.getAuthURL(), AuthenticationServer.REQ_PROCESS_VALIDATOR_INPUT, session.getSessionID());
}
+
resp.setContentType("text/html");
resp.setStatus(302);
resp.addHeader("Location", redirectURL);
@@ -210,84 +205,12 @@ public class GetForeignIDServlet extends AuthServlet {
}
}
- /**
- * Adds a parameter to a URL.
- * @param url the URL
- * @param paramname parameter name
- * @param paramvalue parameter value
- * @return the URL with parameter added
- */
- private static String addURLParameter(String url, String paramname, String paramvalue) {
- String param = paramname + "=" + paramvalue;
- if (url.indexOf("?") < 0)
- return url + "?" + param;
- else
- return url + "&" + param;
- }
- /**
- * Does the request to the SZR-GW
- * @param signature XMLDSIG signature
- * @return Identity link assertion
- * @throws SZRGWClientException
- */
- private CreateIdentityLinkResponse getIdentityLink(Element signature) throws SZRGWClientException {
-
- SZRGWClient client = new SZRGWClient();
-
- try {
- AuthConfigurationProvider authConf = AuthConfigurationProvider.getInstance();
- ConnectionParameter connectionParameters = authConf.getForeignIDConnectionParameter();
-
- client.setAddress(connectionParameters.getUrl());
- if (connectionParameters.getUrl().toLowerCase().startsWith("https:")) {
- Logger.debug("Initialisiere SSL Verbindung");
- try {
- client.setSSLSocketFactory(SSLUtils.getSSLSocketFactory(AuthConfigurationProvider.getInstance(), connectionParameters));
- } catch (IOException e) {
- Logger.error("Could not initialize SSL Factory", e);
- throw new SZRGWClientException("Could not initialize SSL Factory");
- } catch (GeneralSecurityException e) {
- Logger.error("Could not initialize SSL Factory", e);
- throw new SZRGWClientException("Could not initialize SSL Factory");
- } catch (PKIException e) {
- Logger.error("Could not initialize SSL Factory", e);
- throw new SZRGWClientException("Could not initialize SSL Factory");
- }
- }
- Logger.info("Starte Kommunikation mit dem Stammzahlenregister Gateway(" + connectionParameters.getUrl() + ")...");
- }
- catch (ConfigurationException e) {
- Logger.warn(e);
- Logger.warn(MOAIDMessageProvider.getInstance().getMessage("config.12", null ));
- }
-
- // create request
- CreateIdentityLinkResponse response = null;
- Element request = null;
- try {
- Document doc = client.buildGetIdentityLinkRequest(null, null, null, null, signature);
- request = doc.getDocumentElement();
-
- // send request
- response = client.createIdentityLinkResponse(request);
- } catch (SZRGWClientException e) {
- // give him a second try - Nach dem Starten des Tomcat wird beim ersten Mal das Client-Zertifikat offenbar vom HTTPClient nicht mitgeschickt.
- try {
- response = client.createIdentityLinkResponse(request);
- }
- catch (SZRGWClientException e1) {
- throw new SZRGWClientException(e1);
- }
- }
-
-
- return response;
-
- }
+
+
/**
- * Builds the szrgw:GetIdentityLinkRequest für the SZR-GW
+ * Builds the szrgw:GetIdentityLinkRequest f�r the SZR-GW
* @param givenname
* @param familyname
* @param birthday
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetMISSessionIDServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetMISSessionIDServlet.java
index 9d26ded8a..74b2f80b9 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetMISSessionIDServlet.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetMISSessionIDServlet.java
@@ -206,20 +206,6 @@ public class GetMISSessionIDServlet extends AuthServlet {
}
}
- /**
- * Adds a parameter to a URL.
- * @param url the URL
- * @param paramname parameter name
- * @param paramvalue parameter value
- * @return the URL with parameter added
- */
- private static String addURLParameter(String url, String paramname, String paramvalue) {
- String param = paramname + "=" + paramvalue;
- if (url.indexOf("?") < 0)
- return url + "?" + param;
- else
- return url + "&" + param;
- }
-
+
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java
new file mode 100644
index 000000000..4ec894d47
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java
@@ -0,0 +1,227 @@
+package at.gv.egovernment.moa.id.auth.servlet;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.xml.util.XMLHelper;
+import org.w3c.dom.Element;
+
+import at.gv.egovernment.moa.id.AuthenticationException;
+import at.gv.egovernment.moa.id.MOAIDException;
+import at.gv.egovernment.moa.id.auth.AuthenticationServer;
+import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute;
+import at.gv.egovernment.moa.id.auth.data.IdentityLink;
+import at.gv.egovernment.moa.id.auth.stork.STORKException;
+import at.gv.egovernment.moa.id.auth.stork.STORKResponseProcessor;
+import at.gv.egovernment.moa.id.util.HTTPUtils;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.StringUtils;
+import at.gv.egovernment.moa.util.URLEncoder;
+import eu.stork.mw.messages.saml.STORKAuthnRequest;
+import eu.stork.mw.messages.saml.STORKResponse;
+import eu.stork.vidp.messages.util.XMLUtil;
+
+/**
+ * Endpoint for receiving STORK response messages
+ */
+public class PEPSConnectorServlet extends AuthServlet {
+ private static final long serialVersionUID = 1L;
+
+ public static final String PEPSCONNECTOR_SERVLET_URL_PATTERN = "/PEPSConnector";
+
+
+ /**
+ * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
+ */
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ super.doGet(request, response);
+ }
+
+ /**
+ * Handles the reception of a STORK response message
+ * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
+ */
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+
+ try {
+
+ Logger.info("PEPSConnector Servlet invoked, expecting C-PEPS message.");
+ Logger.debug("This ACS endpoint is: " + HTTPUtils.getBaseURL(request));
+
+ super.setNoCachingHeadersInHttpRespone(request, response);
+ Logger.trace("No Caching headers set for HTTP response");
+
+ //check if https or only http
+ super.checkIfHTTPisAllowed(request.getRequestURL().toString());
+
+ Logger.debug("Trying to find MOA Session-ID");
+ HttpSession httpSession = request.getSession();
+ String moaSessionID = (String) httpSession.getAttribute("MOA-Session-ID");
+
+ if (StringUtils.isEmpty(moaSessionID)) {
+ //No authentication session has been started before
+ Logger.error("MOA-SessionID was not found, no previous AuthnRequest had been started");
+ throw new AuthenticationException("auth.02", new Object[] { moaSessionID });
+ } else {
+ //We know user and MOA takes over session handling, invalidate HttpSession
+ httpSession.invalidate();
+ }
+
+ Logger.info("Found MOA sessionID: " + moaSessionID);
+
+ Logger.debug("Beginning to extract SAMLResponse out of HTTP Request");
+
+ //extract STORK Response from HTTP Request
+ STORKResponse storkResponse = null;
+ try {
+ storkResponse = STORKResponseProcessor.receiveSTORKRepsonse(request, response);
+ } catch (STORKException e) {
+ Logger.error("Unable to retrieve STORK Response", e);
+ throw new MOAIDException("stork.04", null);
+ }
+
+ Logger.info("STORK SAML Response message succesfully extracted");
+ Logger.debug("STORK response (pretty print): ");
+ Logger.debug(XMLHelper.prettyPrintXML(storkResponse.getDOM()));
+ Logger.trace("STORK response (original): ");
+ Logger.trace(XMLUtil.printXML(storkResponse.getDOM()));
+
+ Logger.debug("Starting validation of SAML response");
+ //verify SAML response
+ try {
+ STORKResponseProcessor.verifySTORKResponse(storkResponse);
+ } catch (STORKException e) {
+ Logger.error("Failed to verify STORK SAML Response", e);
+ throw new MOAIDException("stork.05", null);
+ }
+
+ Logger.info("SAML response succesfully verified!");
+
+ String statusCodeValue = storkResponse.getStatus().getStatusCode().getValue();
+
+ if (!statusCodeValue.equals(StatusCode.SUCCESS_URI)) {
+ Logger.error("Received ErrorResponse from PEPS: " + statusCodeValue);
+ throw new MOAIDException("stork.06", new Object[] { statusCodeValue });
+ }
+
+ Logger.info("Got SAML response with authentication success message.");
+
+ //check if authentication request was created before
+ AuthenticationSession moaSession = AuthenticationServer.getSession(moaSessionID);
+
+ Logger.debug("MOA session is still valid");
+
+ STORKAuthnRequest storkAuthnRequest = moaSession.getStorkAuthnRequest();
+
+ if (storkAuthnRequest == null) {
+ Logger.error("Could not find any preceeding STORK AuthnRequest to this MOA session: " + moaSessionID);
+ throw new MOAIDException("stork.07", null);
+ }
+
+ Logger.debug("Found a preceeding STORK AuthnRequest to this MOA session: " + moaSessionID);
+
+ Logger.debug("Starting validation of SAML assertion");
+ //verify SAML assertion
+ Assertion storkAssertion = storkResponse.getAssertions().get(0);
+ try {
+ STORKResponseProcessor.verifySTORKAssertion(
+ storkAssertion, //assertion
+ request.getRemoteAddr(), //IP address of user
+ storkAuthnRequest.getID(), //ID of STORK AuthnRequest
+ request.getRequestURL().toString(), //destination
+ HTTPUtils.getBaseURL(request), //audience
+ storkAuthnRequest.getRequestedAttributes()); //Requested Attributes
+ } catch (STORKException e) {
+ Logger.error("Failed to verify STORK SAML Assertion", e);
+ throw new MOAIDException("stork.08", null);
+ }
+
+ Logger.info("SAML assertion succesfully verified!");
+
+ Logger.debug("Starting extraction of signedDoc attribute");
+ //extract signed doc element and citizen signature
+ Element citizenSignature = null;
+ try {
+
+ citizenSignature = STORKResponseProcessor.extractCitizenSignature(storkAssertion);
+ moaSession.setAuthBlock(DOMUtils.serializeNode(citizenSignature));
+ moaSession.setSignerCertificate(AuthenticationServer.getCertificateFromXML(citizenSignature));
+
+ } catch (Exception e) {
+ Logger.error("Could not extract citizen signature from C-PEPS", e);
+ throw new MOAIDException("stork.09", null);
+ }
+ Logger.debug("Foregin Citizen signature successfully extracted from STORK Assertion (signedDoc)");
+ Logger.debug("Citizen signature will be verified by SZR Gateway!");
+
+ Logger.debug("Starting connecting SZR Gateway");
+ //contact SZR Gateway
+ IdentityLink identityLink = null;
+ try {
+ identityLink = STORKResponseProcessor.connectToSZRGateway(citizenSignature, storkAssertion.getAttributeStatements().get(0).getAttributes());
+ } catch (STORKException e) {
+ Logger.error("Error connecting SZR Gateway", e);
+ throw new MOAIDException("stork.10", null);
+ }
+ Logger.debug("SZR communication was successfull");
+
+ if (identityLink == null) {
+ Logger.error("SZR Gateway did not return an identity link.");
+ throw new MOAIDException("stork.10", null);
+ }
+ Logger.info("Received Identity Link from SZR Gateway");
+ moaSession.setIdentityLink(identityLink);
+
+ Logger.debug("Adding addtional STORK attributes to MOA assertion");
+ //add other stork attributes to MOA assertion
+ List<ExtendedSAMLAttribute> moaExtendedSAMLAttibutes = STORKResponseProcessor.addAdditionalSTORKAttributes(storkAssertion.getAttributeStatements().get(0).getAttributes());
+ moaSession.setExtendedSAMLAttributesOA(moaExtendedSAMLAttibutes);
+
+ //We don't have BKUURL, setting from null to "Not applicable"
+ moaSession.setBkuURL("Not applicable (STORK Authentication)");
+
+ Logger.debug("Starting to assemble MOA assertion");
+ //produce MOA-Assertion and artifact
+ String samlArtifactBase64 =
+ AuthenticationServer.getInstance().getForeignAuthenticationData(moaSessionID);
+ Logger.info("MOA assertion assembled and SAML Artifact generated.");
+
+ //redirect
+ String redirectURL = null;
+ if (!samlArtifactBase64.equals("Redirect to Input Processor")) {
+ redirectURL = moaSession.getOAURLRequested();
+ if (!moaSession.getBusinessService()) {
+ redirectURL = addURLParameter(redirectURL, PARAM_TARGET, URLEncoder.encode(moaSession.getTarget(), "UTF-8"));
+ }
+ redirectURL = addURLParameter(redirectURL, PARAM_SAMLARTIFACT, URLEncoder.encode(samlArtifactBase64, "UTF-8"));
+ redirectURL = response.encodeRedirectURL(redirectURL);
+ } else {
+ redirectURL = new DataURLBuilder().buildDataURL(moaSession.getAuthURL(), AuthenticationServer.REQ_PROCESS_VALIDATOR_INPUT, moaSession.getSessionID());
+ }
+ response.setContentType("text/html");
+ response.setStatus(302);
+ response.addHeader("Location", redirectURL);
+ Logger.info("REDIRECT TO: " + redirectURL);
+
+
+
+ } catch (AuthenticationException e) {
+ handleError(null, e, request, response);
+ } catch (MOAIDException e) {
+ handleError(null, e, request, response);
+ }
+
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/StartAuthenticationServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/StartAuthenticationServlet.java
index 355e85ce5..012ed4c14 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/StartAuthenticationServlet.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/StartAuthenticationServlet.java
@@ -26,6 +26,7 @@ package at.gv.egovernment.moa.id.auth.servlet;
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.List;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
@@ -33,18 +34,29 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringEscapeUtils;
+import org.opensaml.saml2.metadata.RequestedAttribute;
import at.gv.egovernment.moa.id.AuthenticationException;
import at.gv.egovernment.moa.id.MOAIDException;
import at.gv.egovernment.moa.id.auth.AuthenticationServer;
import at.gv.egovernment.moa.id.auth.MOAIDAuthInitializer;
import at.gv.egovernment.moa.id.auth.WrongParametersException;
+import at.gv.egovernment.moa.id.auth.stork.STORKAuthnRequestProcessor;
import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.config.stork.CPEPS;
+import at.gv.egovernment.moa.id.config.stork.STORKConfig;
+import at.gv.egovernment.moa.id.util.HTTPUtils;
import at.gv.egovernment.moa.id.util.MOAIDMessageProvider;
import at.gv.egovernment.moa.id.util.ParamValidatorUtils;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.StringUtils;
+import eu.stork.mw.messages.saml.STORKAuthnRequest;
+import eu.stork.vidp.messages.builder.STORKMessagesBuilder;
+import eu.stork.vidp.messages.exception.SAMLException;
+import eu.stork.vidp.messages.exception.SAMLValidationException;
+import eu.stork.vidp.messages.stork.QualityAuthenticationAssuranceLevel;
+import eu.stork.vidp.messages.stork.RequestedAttributes;
/**
* Servlet requested for starting a MOA ID authentication session.
@@ -77,7 +89,7 @@ public class StartAuthenticationServlet extends AuthServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
- Logger.debug("GET StartAuthentication");
+ Logger.debug("GET StartAuthentication");
String authURL = req.getScheme() + "://" + req.getServerName();
if ((req.getScheme().equalsIgnoreCase("https") && req.getServerPort()!=443) || (req.getScheme().equalsIgnoreCase("http") && req.getServerPort()!=80)) {
authURL = authURL.concat(":" + req.getServerPort());
@@ -91,6 +103,7 @@ public class StartAuthenticationServlet extends AuthServlet {
String templateURL = req.getParameter(PARAM_TEMPLATE);
String sessionID = req.getParameter(PARAM_SESSIONID);
String useMandate = req.getParameter(PARAM_USEMANDATE);
+ String ccc = req.getParameter(PARAM_CCC);
// escape parameter strings
target = StringEscapeUtils.escapeHtml(target);
@@ -100,11 +113,9 @@ public class StartAuthenticationServlet extends AuthServlet {
templateURL = StringEscapeUtils.escapeHtml(templateURL);
sessionID = StringEscapeUtils.escapeHtml(sessionID);
useMandate = StringEscapeUtils.escapeHtml(useMandate);
+ ccc = StringEscapeUtils.escapeHtml(ccc);
- resp.setHeader(HEADER_EXPIRES,HEADER_VALUE_EXPIRES);
- resp.setHeader(HEADER_PRAGMA,HEADER_VALUE_PRAGMA);
- resp.setHeader(HEADER_CACHE_CONTROL,HEADER_VALUE_CACHE_CONTROL);
- resp.addHeader(HEADER_CACHE_CONTROL,HEADER_VALUE_CACHE_CONTROL_IE);
+ setNoCachingHeadersInHttpRespone(req, resp);
try {
@@ -121,35 +132,56 @@ public class StartAuthenticationServlet extends AuthServlet {
throw new WrongParametersException("StartAuthentication", PARAM_USEMANDATE, "auth.12");
if (!ParamValidatorUtils.isValidSourceID(sourceID))
throw new WrongParametersException("StartAuthentication", PARAM_SOURCEID, "auth.12");
+ if (!ParamValidatorUtils.isValidCCC(ccc))
+ throw new WrongParametersException("StartAuthentication", PARAM_CCC, "auth.12");
+
+
OAAuthParameter oaParam =
AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(oaURL);
if (oaParam == null)
throw new AuthenticationException("auth.00", new Object[] { oaURL });
-
+
// get target and target friendly name from config
String targetConfig = oaParam.getTarget();
- String targetFriendlyNameConfig = oaParam.getTargetFriendlyName();
+ String targetFriendlyNameConfig = oaParam.getTargetFriendlyName();
+
+ String targetFriendlyName = null;
+
+ if (StringUtils.isEmpty(targetConfig)) {
+ // no target attribut is given in OA config
+ // target is used from request
+ // check parameter
+ if (!ParamValidatorUtils.isValidTarget(target))
+ throw new WrongParametersException("StartAuthentication", PARAM_TARGET, "auth.12");
+ } else {
+ // use target from config
+ target = targetConfig;
+ targetFriendlyName = targetFriendlyNameConfig;
+ }
+
+ STORKConfig storkConfig = AuthConfigurationProvider.getInstance().getStorkConfig();
- String getIdentityLinkForm = null;
- if (StringUtils.isEmpty(targetConfig)) {
- // no target attribut is given in OA config
- // target is used from request
- // check parameter
- if (!ParamValidatorUtils.isValidTarget(target))
- throw new WrongParametersException("StartAuthentication", PARAM_TARGET, "auth.12");
+ Logger.info("Starting authentication for a citizen of country: " + (StringUtils.isEmpty(ccc) ? "AT" : ccc));
+ // STORK or normal authentication
+ if (storkConfig.isSTORKAuthentication(ccc)) {
+ //STORK authentication
+ Logger.trace("Found C-PEPS configuration for citizen of country: " + ccc);
+ Logger.debug("Starting STORK authentication");
- getIdentityLinkForm = AuthenticationServer.getInstance().startAuthentication(authURL, target, null, oaURL, templateURL, bkuURL, useMandate, sessionID, req.getScheme(), sourceID);
- }
- else {
- // use target from config
- getIdentityLinkForm = AuthenticationServer.getInstance().startAuthentication(authURL, targetConfig, targetFriendlyNameConfig, oaURL, templateURL, bkuURL, useMandate, sessionID, req.getScheme(), sourceID);
+ AuthenticationServer.startSTORKAuthentication(req, resp, ccc, oaURL, target, targetFriendlyName, authURL, sourceID);
+
+ } else {
+ //normal MOA-ID authentication
+ Logger.debug("Starting normal MOA-ID authentication");
+
+ String getIdentityLinkForm = AuthenticationServer.getInstance().startAuthentication(authURL, target, targetFriendlyName, oaURL, templateURL, bkuURL, useMandate, sessionID, req.getScheme(), sourceID);
+
+ resp.setContentType("text/html;charset=UTF-8");
+ PrintWriter out = new PrintWriter(resp.getOutputStream());
+ out.print(getIdentityLinkForm);
+ out.flush();
}
-
- resp.setContentType("text/html;charset=UTF-8");
- PrintWriter out = new PrintWriter(resp.getOutputStream());
- out.print(getIdentityLinkForm);
- out.flush();
Logger.debug("Finished GET StartAuthentication");
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java
index f15f839d7..fbf700365 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java
@@ -326,19 +326,6 @@ public class VerifyAuthenticationBlockServlet extends AuthServlet {
// handleError(null, e, req, resp);
// }
// }
- /**
- * Adds a parameter to a URL.
- * @param url the URL
- * @param paramname parameter name
- * @param paramvalue parameter value
- * @return the URL with parameter added
- */
- private static String addURLParameter(String url, String paramname, String paramvalue) {
- String param = paramname + "=" + paramvalue;
- if (url.indexOf("?") < 0)
- return url + "?" + param;
- else
- return url + "&" + param;
- }
+
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/AssertionVerifier.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/AssertionVerifier.java
new file mode 100644
index 000000000..7ffe59fd9
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/AssertionVerifier.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2011 by Graz University of Technology, Austria
+ * The Austrian STORK Modules have been developed by the E-Government
+ * Innovation Center EGIZ, a joint initiative of the Federal Chancellery
+ * Austria 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.stork;
+
+import java.util.List;
+
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.metadata.RequestedAttribute;
+
+/**
+ * Interface to be implemented for verifying SAML assertions
+ *
+ * @author bzwattendorfer
+ *
+ */
+public interface AssertionVerifier {
+
+ /**
+ * Verifies a given assertion
+ * @param assertion SAML assertion
+ * @param reqIPAddress IP address of the client
+ * @param authnRequestID ID of the corresponding authentication request for verification
+ * @param recipient recipient for verification
+ * @param audience audience for verification
+ * @param reqAttrList RequestedAttribute list for verification
+ * @throws SecurityException
+ */
+ public void verify(Assertion assertion, String reqIPAddress, String authnRequestID, String recipient, String audience, List<RequestedAttribute> reqAttrList) throws SecurityException;
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/CredentialProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/CredentialProvider.java
new file mode 100644
index 000000000..b95ab6218
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/CredentialProvider.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2011 by Graz University of Technology, Austria
+ * The Austrian STORK Modules have been developed by the E-Government
+ * Innovation Center EGIZ, a joint initiative of the Federal Chancellery
+ * Austria 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.stork;
+
+import org.opensaml.xml.security.credential.Credential;
+
+import eu.stork.vidp.messages.exception.SAMLException;
+
+/**
+ * Interface supporting different kinds of Credentials
+ *
+ * @author bzwattendorfer
+ *
+ */
+public interface CredentialProvider {
+
+ /**
+ * Gets appropriate credentials
+ * @return Credential object
+ * @throws SAMLException
+ */
+ public Credential getCredential() throws SAMLException;
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/KeyStoreCredentialProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/KeyStoreCredentialProvider.java
new file mode 100644
index 000000000..467210b4d
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/KeyStoreCredentialProvider.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2011 by Graz University of Technology, Austria
+ * The Austrian STORK Modules have been developed by the E-Government
+ * Innovation Center EGIZ, a joint initiative of the Federal Chancellery
+ * Austria 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.stork;
+
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+import org.opensaml.xml.security.credential.Credential;
+import org.opensaml.xml.security.x509.BasicX509Credential;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egovernment.moa.util.KeyStoreUtils;
+import at.gv.egovernment.moa.util.StringUtils;
+import eu.stork.vidp.messages.exception.SAMLException;
+
+/**
+ * Provides credentials from a KeyStore
+ * @author bzwattendorfer
+ *
+ */
+public class KeyStoreCredentialProvider implements CredentialProvider {
+
+ private final static Logger log = LoggerFactory.getLogger(KeyStoreCredentialProvider.class);
+
+ /** KeyStore Path */
+ private String keyStorePath;
+
+ /** KeyStore Password */
+ private String keyStorePassword;
+
+ /** Specific Key Name as Credential */
+ private String keyName;
+
+ /** Key password */
+ private String keyPassword;
+
+ /**
+ * Creates a KeyStoreCredentialProvider object
+ * @param keyStorePath KeyStore Path
+ * @param keyStorePassword KeyStore Password
+ * @param keyName KeyName of the key to be retrieved
+ * @param keyPassword Password for the Key
+ */
+ public KeyStoreCredentialProvider(String keyStorePath,
+ String keyStorePassword, String keyName, String keyPassword) {
+ super();
+ this.keyStorePath = keyStorePath;
+ this.keyStorePassword = keyStorePassword;
+ this.keyName = keyName;
+ this.keyPassword = keyPassword;
+ }
+
+
+ /**
+ * Gets the credential object from the KeyStore
+ */
+ public Credential getCredential() throws SAMLException {
+ log.trace("Retrieving credentials for signing SAML Response.");
+
+ if (StringUtils.isEmpty(this.keyStorePath))
+ throw new SAMLException("No keyStorePath specified");
+
+ //KeyStorePassword optional
+ //if (StringUtils.isEmpty(this.keyStorePassword))
+ // throw new SAMLException("No keyStorePassword specified");
+
+ if (StringUtils.isEmpty(this.keyName))
+ throw new SAMLException("No keyName specified");
+
+ //KeyStorePassword optional
+ //if (StringUtils.isEmpty(this.keyPassword))
+ // throw new SAMLException("No keyPassword specified");
+
+ KeyStore ks;
+ try {
+ ks = KeyStoreUtils.loadKeyStore(this.keyStorePath, this.keyStorePassword);
+ } catch (Exception e) {
+ log.error("Failed to load keystore information", e);
+ throw new SAMLException(e);
+ }
+
+ //return new KeyStoreX509CredentialAdapter(ks, keyName, keyPwd.toCharArray());
+ BasicX509Credential credential = null;
+ try {
+ java.security.cert.X509Certificate certificate = (X509Certificate) ks.getCertificate(this.keyName);
+ PrivateKey privateKey = (PrivateKey) ks.getKey(this.keyName, this.keyPassword.toCharArray());
+ credential = new BasicX509Credential();
+ credential.setEntityCertificate(certificate);
+ credential.setPrivateKey(privateKey);
+
+ } catch (Exception e) {
+ log.error("Error retrieving signing credentials.", e);
+ throw new SAMLException(e);
+ }
+
+ return credential;
+
+ }
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/PEPSConnectorAssertionVerifier.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/PEPSConnectorAssertionVerifier.java
new file mode 100644
index 000000000..3048ccbee
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/PEPSConnectorAssertionVerifier.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2011 by Graz University of Technology, Austria
+ * The Austrian STORK Modules have been developed by the E-Government
+ * Innovation Center EGIZ, a joint initiative of the Federal Chancellery
+ * Austria 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.stork;
+
+import java.util.List;
+
+import org.joda.time.DateTime;
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.core.Audience;
+import org.opensaml.saml2.core.AudienceRestriction;
+import org.opensaml.saml2.core.Conditions;
+import org.opensaml.saml2.core.SubjectConfirmation;
+import org.opensaml.saml2.core.SubjectConfirmationData;
+import org.opensaml.saml2.metadata.RequestedAttribute;
+
+import at.gv.egovernment.moa.logging.Logger;
+import eu.stork.vidp.messages.saml.STORKAttribute;
+import eu.stork.vidp.messages.util.SAMLUtil;
+
+/**
+ * Verifies the SAML assertion according to the STORK specification
+ * @author bzwattendorfer
+ *
+ */
+public class PEPSConnectorAssertionVerifier implements AssertionVerifier {
+
+ private static final int CLOCK_SKEW_MINUTES = 5;
+
+ private static final boolean IS_USERS_CLIENT_IP_ADDRESS_TO_VERIFY = false;
+
+ /* (non-Javadoc)
+ * @see eu.stork.mw.peps.connector.validation.AssertionVerifier#verifyAssertion(org.opensaml.saml2.core.Assertion, java.lang.String, java.lang.String, java.lang.String)
+ */
+ public void verify(Assertion assertion, String reqIPAddress,
+ String authnRequestID, String recipient, String audience, List<RequestedAttribute> reqAttrList) throws SecurityException {
+
+ //SAML assertion need not to be signed, skipping signature validation
+
+ verifySubjectConfirmation(assertion, reqIPAddress, authnRequestID, recipient);
+
+ Logger.debug("SubjectConfirmationData successfully verified");
+
+ verifyConditions(assertion, audience);
+
+ Logger.debug("Conditions successfully verified");
+ }
+
+
+ private void verifySubjectConfirmation(Assertion assertion, String reqAddress, String requestID, String recipient) throws SecurityException {
+ for (SubjectConfirmation sc : assertion.getSubject().getSubjectConfirmations()) {
+ verifySubjectConfirmationData(sc.getSubjectConfirmationData(), reqAddress, requestID, recipient);
+ }
+
+ }
+
+ private void verifySubjectConfirmationData(SubjectConfirmationData scData, String reqAddress, String requestID, String recipient) throws SecurityException {
+ //NotBefore not allowed in SSO profile
+ verifyNotOnOrAfter(scData.getNotOnOrAfter());
+
+ Logger.trace("NotOnOrAfter successfully verified");
+
+ if(IS_USERS_CLIENT_IP_ADDRESS_TO_VERIFY) {
+ verifyClientAddress(scData, reqAddress);
+ Logger.trace("User's client IP address successfully verified.");
+ } else {
+ Logger.warn("User's client IP address will not be verified.");
+ }
+
+ verifyRecipient(scData, recipient);
+ Logger.trace("Recipient successfully verified");
+
+ verifyInResponseTo(scData, requestID);
+ Logger.trace("InResponseTo successfully verified");
+
+ }
+
+ private void verifyNotBefore(DateTime notBefore) throws SecurityException {
+ if (notBefore.minusMinutes(CLOCK_SKEW_MINUTES).isAfterNow()) {
+ String msg = "Subject/Assertion not yet valid, Timestamp: ";
+ Logger.error(msg + notBefore);
+ throw new SecurityException(msg);
+ }
+
+ Logger.trace("Subject/Assertion already valid, notBefore: " + notBefore);
+
+ }
+
+ private void verifyNotOnOrAfter(DateTime notOnOrAfter) throws SecurityException {
+ if (notOnOrAfter.plusMinutes(CLOCK_SKEW_MINUTES).isBeforeNow()) {
+ String msg = "Subject/Assertion no longer valid.";
+ Logger.error(msg);
+ throw new SecurityException(msg);
+ }
+
+ Logger.trace("Subject/Assertion still valid, notOnOrAfter: " + notOnOrAfter);
+ }
+
+ private void verifyClientAddress(SubjectConfirmationData scData, String reqAddress) throws SecurityException {
+ if (!reqAddress.equals(scData.getAddress())) {
+ String msg = "Response coming from wrong Client-Address";
+ Logger.error("Response coming from wrong Client-Address " + reqAddress + ", expected " + scData.getAddress());
+ throw new SecurityException(msg);
+ }
+
+ }
+
+ private void verifyInResponseTo(SubjectConfirmationData scData, String requestID) throws SecurityException {
+ if (!scData.getInResponseTo().equals(requestID)) {
+ String msg = "Assertion issued for wrong request";
+ Logger.error(msg);
+ throw new SecurityException(msg);
+ }
+ }
+
+ private void verifyRecipient(SubjectConfirmationData scData, String reqRecipient) throws SecurityException {
+ if (!scData.getRecipient().equals(reqRecipient)) {
+ String msg = "Assertion intended for another recipient";
+ Logger.error("Assertion intended for recipient " + scData.getRecipient() + "but expected " + reqRecipient);
+ throw new SecurityException(msg);
+ }
+
+ }
+
+ private void verifyAudience(AudienceRestriction audienceRestriction, String reqAudience) throws SecurityException {
+ for (Audience audience : audienceRestriction.getAudiences()) {
+ if (audience.getAudienceURI().equals(reqAudience))
+ return;
+ }
+ String msg = "Assertion sent to wrong audience";
+ Logger.error("Assertion intended for wrong audience, expected " + reqAudience);
+ throw new SecurityException(msg);
+ }
+
+ private void verifyOneTimeUse(String assertionID) {
+ //not necessarily required to check since notBefore and notOnOrAfter are verified
+ //check response Store for already existing assertion
+
+ }
+
+ private void verifyConditions(Assertion assertion, String reqAudience) throws SecurityException {
+ Conditions conditions = assertion.getConditions();
+
+ verifyNotBefore(conditions.getNotBefore());
+ Logger.trace("NotBefore successfully verified");
+
+ verifyNotOnOrAfter(conditions.getNotOnOrAfter());
+ Logger.trace("NotOnOrAfter successfully verified");
+
+ verifyAudience(conditions.getAudienceRestrictions().get(0), reqAudience);
+
+ Logger.trace("Audience successfully verified");
+
+ }
+
+ public static void validateRequiredAttributes(
+ List<RequestedAttribute> reqAttrList,
+ List<Attribute> attrList)
+ throws STORKException {
+
+ Logger.debug("Starting required attribute validation");
+
+ if (reqAttrList == null || reqAttrList.isEmpty()) {
+ Logger.error("Requested Attributes list is empty.");
+ throw new STORKException("No attributes have been requested");
+ }
+
+ if (attrList == null || attrList.isEmpty()) {
+ Logger.error("STORK AttributeStatement is empty.");
+ throw new STORKException("No attributes have been received");
+ }
+
+ Logger.trace("These attributes have been requested and received: ");
+ int count = 0;
+ for (RequestedAttribute reqAttr : reqAttrList) {
+ Logger.trace("Requested attribute: " + reqAttr.getName() + " isRequired: " + reqAttr.isRequired());
+ for(Attribute attr : attrList) {
+ if (verifyRequestedAttribute(reqAttr, attr))
+ count++;
+ }
+ }
+
+ int numRequiredReqAttr = getNumberOfRequiredAttributes(reqAttrList);
+ Logger.trace("Number of requested required attributes: " + numRequiredReqAttr);
+ Logger.trace("Number of received required attributes: " + count);
+
+ if (count != numRequiredReqAttr) {
+ Logger.error("Not all required attributes have been received");
+ throw new STORKException("Not all required attributes have been received");
+ }
+ Logger.debug("Received all required attributes!");
+
+ }
+
+ private static boolean verifyRequestedAttribute(RequestedAttribute reqAttr, Attribute attr) {
+
+ if ((reqAttr.getName()).equals(attr.getName())) {
+ if (reqAttr.isRequired() && SAMLUtil.getStatusFromAttribute(attr).equals(STORKAttribute.ALLOWED_ATTRIBUTE_STATUS_AVAIL)) {
+ Logger.trace("Received required attribute " + attr.getName() + " status: " + SAMLUtil.getStatusFromAttribute(attr));
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static int getNumberOfRequiredAttributes(List<RequestedAttribute> reqAttrList) {
+ int count = 0;
+ for (RequestedAttribute reqAttr : reqAttrList)
+ if (reqAttr.isRequired()) count++;
+
+ return count;
+ }
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/PEPSConnectorResponseVerifier.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/PEPSConnectorResponseVerifier.java
new file mode 100644
index 000000000..2deeb2aae
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/PEPSConnectorResponseVerifier.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2011 by Graz University of Technology, Austria
+ * The Austrian STORK Modules have been developed by the E-Government
+ * Innovation Center EGIZ, a joint initiative of the Federal Chancellery
+ * Austria 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.stork;
+
+
+import org.w3c.dom.Element;
+
+import at.gv.egovernment.moa.id.BuildException;
+import at.gv.egovernment.moa.id.ParseException;
+import at.gv.egovernment.moa.id.ServiceException;
+import at.gv.egovernment.moa.id.auth.AuthenticationServer;
+import at.gv.egovernment.moa.id.auth.builder.VerifyXMLSignatureRequestBuilder;
+import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse;
+import at.gv.egovernment.moa.id.auth.invoke.SignatureVerificationInvoker;
+import at.gv.egovernment.moa.id.auth.parser.VerifyXMLSignatureResponseParser;
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Constants;
+import eu.stork.mw.messages.saml.STORKResponse;
+import eu.stork.vidp.messages.exception.SAMLValidationException;
+import eu.stork.vidp.messages.util.SAMLUtil;
+import eu.stork.vidp.messages.util.XMLUtil;
+
+/**
+ * Verifies the SMAL response according to the STORK specification
+ * @author bzwattendorfer
+ *
+ */
+public class PEPSConnectorResponseVerifier implements ResponseVerifier {
+
+
+ /* (non-Javadoc)
+ * @see eu.stork.mw.peps.connector.validation.ResponseVerifier#verify(org.opensaml.saml2.core.Response)
+ */
+ public void verify(STORKResponse response) throws SecurityException {
+
+ verifySignature(response);
+ Logger.debug("Signature of SAML response valid.");
+
+ verifyStandardValidation(response);
+
+ Logger.debug("SAML response format valid.");
+
+ }
+
+
+ private void verifySignature(STORKResponse response) throws SecurityException {
+ //validate Signature
+ try {
+ if (response.isSigned()) {
+
+ String trustProfileID = AuthConfigurationProvider.getInstance().getStorkConfig().getSignatureVerificationParameter().getTrustProfileID();
+
+ Logger.debug("Invoking MOA-SP with TrustProfileID: " + trustProfileID);
+
+ // builds a <VerifyXMLSignatureRequest> for a call of MOA-SP
+ Element domVerifyXMLSignatureRequest = new VerifyXMLSignatureRequestBuilder()
+ .build(XMLUtil.printXML(response.getDOM()).getBytes(), trustProfileID);
+
+ Logger.trace("VerifyXMLSignatureRequest for MOA-SP succesfully built");
+
+ Logger.trace("Calling MOA-SP");
+ // invokes the call
+ Element domVerifyXMLSignatureResponse = new SignatureVerificationInvoker()
+ .verifyXMLSignature(domVerifyXMLSignatureRequest);
+
+ // parses the <VerifyXMLSignatureResponse>
+ VerifyXMLSignatureResponse verifyXMLSignatureResponse = new VerifyXMLSignatureResponseParser(
+ domVerifyXMLSignatureResponse).parseData();
+
+ Logger.trace("Received VerifyXMLSignatureResponse from MOA-SP");
+
+ if (verifyXMLSignatureResponse.getSignatureCheckCode() != 0) {
+ String msg = "Signature of SAMLResponse not valid";
+ Logger.error(msg);
+ throw new SecurityException(msg);
+ }
+
+ Logger.debug("Signature of SAML response successfully verified");
+
+ if (verifyXMLSignatureResponse.getCertificateCheckCode() != 0) {
+ String msg = "Certificate of SAMLResponse not valid";
+ Logger.error(msg);
+ throw new SecurityException(msg);
+ }
+
+ Logger.debug("Signing certificate of SAML response succesfully verified");
+
+ } else {
+ String msg = "SAML Response is not signed.";
+ throw new SecurityException(msg);
+ }
+
+ } catch (ConfigurationException e) {
+ String msg = "Unable to load STORK configuration for STORK SAML Response signature verification.";
+ Logger.error(msg, e);
+ throw new SecurityException(msg, e);
+ } catch (ParseException e) {
+ String msg = "Unable to parse VerifyXMLSignature Request or Response.";
+ Logger.error(msg, e);
+ throw new SecurityException(msg, e);
+ } catch (BuildException e) {
+ String msg = "Unable to parse VerifyXMLSignature Request or Response.";
+ Logger.error(msg, e);
+ throw new SecurityException(msg, e);
+ } catch (ServiceException e) {
+ String msg = "Unable to invoke MOA-SP.";
+ Logger.error(msg, e);
+ throw new SecurityException(msg, e);
+ }
+
+ }
+
+ private void verifyStandardValidation(STORKResponse response) throws SecurityException {
+ try {
+ SAMLUtil.verifySAMLObjectStandardValidation(response, "saml2-core-schema-and-stork-validator");
+ } catch (SAMLValidationException e) {
+ String msg ="SAML Response received not valid.";
+ throw new SecurityException(msg, e);
+ }
+
+ }
+
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/ResponseVerifier.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/ResponseVerifier.java
new file mode 100644
index 000000000..848937824
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/ResponseVerifier.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2011 by Graz University of Technology, Austria
+ * The Austrian STORK Modules have been developed by the E-Government
+ * Innovation Center EGIZ, a joint initiative of the Federal Chancellery
+ * Austria 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.stork;
+
+import eu.stork.mw.messages.saml.STORKResponse;
+
+/**
+ * Interface to be implemented for SAML response verification
+ * @author bzwattendorfer
+ *
+ */
+public interface ResponseVerifier {
+
+ /**
+ * Verifies a STORK response
+ * @param response STORK response
+ * @throws SecurityException
+ */
+ public void verify(STORKResponse response) throws SecurityException;
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKAuthnRequestProcessor.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKAuthnRequestProcessor.java
new file mode 100644
index 000000000..ff30919bc
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKAuthnRequestProcessor.java
@@ -0,0 +1,170 @@
+/**
+ *
+ */
+package at.gv.egovernment.moa.id.auth.stork;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.velocity.app.VelocityEngine;
+import org.opensaml.common.binding.BasicSAMLMessageContext;
+import org.opensaml.saml2.binding.encoding.HTTPPostEncoder;
+import org.opensaml.saml2.metadata.AssertionConsumerService;
+import org.opensaml.saml2.metadata.Endpoint;
+import org.opensaml.saml2.metadata.RequestedAttribute;
+import org.opensaml.ws.transport.http.HTTPOutTransport;
+import org.opensaml.ws.transport.http.HttpServletResponseAdapter;
+import org.opensaml.xml.security.credential.Credential;
+
+import at.gv.egovernment.moa.id.auth.servlet.PEPSConnectorServlet;
+import at.gv.egovernment.moa.id.util.HTTPUtils;
+import at.gv.egovernment.moa.logging.Logger;
+import eu.stork.mw.messages.saml.STORKAuthnRequest;
+import eu.stork.vidp.messages.builder.STORKMessagesBuilder;
+import eu.stork.vidp.messages.exception.SAMLException;
+import eu.stork.vidp.messages.exception.SAMLValidationException;
+import eu.stork.vidp.messages.stork.QualityAuthenticationAssuranceLevel;
+import eu.stork.vidp.messages.stork.RequestedAttributes;
+import eu.stork.vidp.messages.util.SAMLUtil;
+
+/**
+ * Class handling all necessary functionality for STORK AuthnRequest processing
+ *
+ * @author bzwattendorfer
+ *
+ */
+public class STORKAuthnRequestProcessor {
+
+ /**
+ * Creates a STORK AuthnRequest
+ * @param destination Destination URL
+ * @param acsURL Assertion Consumer Service URL
+ * @param providerName SP Provider Name
+ * @param issuerValue Issuer Name
+ * @param qaaLevel STORK QAALevel to be requested
+ * @param requestedAttributes Requested Attributes to be requested
+ * @param spSector Sp Sector
+ * @param spInstitution SP Institution
+ * @param spApplication SP Application
+ * @param spCountry SP Country
+ * @param textToBeSigned text to be included in signedDoc element
+ * @param mimeType mimeType for the text to be signed in signedDoc
+ * @return STORK AuthnRequest
+ */
+ public static STORKAuthnRequest generateSTORKAuthnRequest(
+ String destination,
+ String acsURL,
+ String providerName,
+ String issuerValue,
+ QualityAuthenticationAssuranceLevel qaaLevel,
+ RequestedAttributes requestedAttributes,
+ String spSector,
+ String spInstitution,
+ String spApplication,
+ String spCountry,
+ String textToBeSigned,
+ String mimeType) {
+
+
+ STORKAuthnRequest storkAuthnRequest =
+ STORKMessagesBuilder.buildSTORKAuthnRequest(
+ destination,
+ acsURL,
+ providerName,
+ issuerValue,
+ qaaLevel,
+ requestedAttributes,
+ spSector,
+ spInstitution,
+ spApplication,
+ spCountry);
+
+ STORKMessagesBuilder.buildAndAddSignatureRequestToAuthnRequest(storkAuthnRequest, textToBeSigned, mimeType, true);
+
+ Logger.debug("Added signedDoc attribute to STORK AuthnRequest");
+
+ return storkAuthnRequest;
+
+ }
+
+ /**
+ * Signs a STORK AuthnRequest
+ * @param storkAuthnRequest STORK AuthRequest to sign
+ * @param keyStorePath KeyStorePath to the signing key
+ * @param keyStorePassword KeyStore Password
+ * @param keyName Signing key name
+ * @param keyPassword Signing key password
+ * @return Signed STORK AuthnRequest
+ * @throws SAMLException
+ */
+ public static STORKAuthnRequest signSTORKAuthnRequest(
+ STORKAuthnRequest storkAuthnRequest,
+ String keyStorePath,
+ String keyStorePassword,
+ String keyName,
+ String keyPassword) throws SAMLException {
+
+ Logger.trace("Building Credential Provider for signing process");
+
+ CredentialProvider credentialProvider = new KeyStoreCredentialProvider(keyStorePath, keyStorePassword, keyName, keyPassword);
+
+ Credential credential = credentialProvider.getCredential();
+
+ Logger.trace("Credentials found");
+
+ SAMLUtil.signSAMLObject(storkAuthnRequest, credential);
+
+ return storkAuthnRequest;
+ }
+
+ /**
+ * Validates a STORK AuthnRequest
+ * @param storkAuthnRequest STORK AuthnRequest to validate
+ * @throws SAMLValidationException
+ */
+ public static void validateSTORKAuthnRequest(STORKAuthnRequest storkAuthnRequest) throws SAMLValidationException {
+
+ SAMLUtil.verifySAMLObjectStandardValidation(storkAuthnRequest, "saml2-core-schema-and-stork-validator");
+
+ }
+
+ /**
+ * Sends a STORK AuthnRequest (Endpoint taken out of AuthnRequest)
+ * @param request HttpServletRequest
+ * @param response HttpServletResponse
+ * @param storkAuthnRequest STORK AuthnRequest to send
+ * @throws Exception
+ */
+ public static void sendSTORKAuthnRequest(HttpServletRequest request, HttpServletResponse response, STORKAuthnRequest storkAuthnRequest) throws Exception {
+
+ Logger.trace("Create endpoint...");
+ Endpoint endpoint = STORKMessagesBuilder.buildSAMLObject(AssertionConsumerService.DEFAULT_ELEMENT_NAME);
+ endpoint.setBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST");
+ endpoint.setLocation(storkAuthnRequest.getDestination());
+
+
+ Logger.trace("Prepare SAMLMessageContext...");
+ HTTPOutTransport outTransport = new HttpServletResponseAdapter(response, request.isSecure());
+ BasicSAMLMessageContext<?, STORKAuthnRequest, ?> samlMessageContext = new BasicSAMLMessageContext();
+ samlMessageContext.setOutboundMessageTransport(outTransport);
+ samlMessageContext.setPeerEntityEndpoint(endpoint);
+
+ Logger.trace("Set STORK SAML AuthnRequest to SAMLMessageContext...");
+ samlMessageContext.setOutboundSAMLMessage(storkAuthnRequest);
+
+ Logger.trace("Initialize VelocityEngine...");
+
+ VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
+
+// HTTPPostEncoder encoder = new HTTPPostEncoder(velocityEngine, "/templates/saml2-post-binding.vm");
+ HTTPPostEncoder encoder = new HTTPPostEncoder(velocityEngine, "/saml2-post-binding-moa.vm");
+
+ Logger.trace("HTTP-Post encode SAMLMessageContext...");
+ encoder.encode(samlMessageContext);
+ }
+
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKException.java
new file mode 100644
index 000000000..5b737603b
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKException.java
@@ -0,0 +1,42 @@
+/**
+ *
+ */
+package at.gv.egovernment.moa.id.auth.stork;
+
+
+/**
+ * Exception thrown if error occurs in STORK processing
+ * @author bzwattendorfer
+ *
+ */
+public class STORKException extends Exception{
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public STORKException() {
+ super();
+
+ }
+
+ public STORKException(String message, Throwable cause) {
+ super(message, cause);
+
+ }
+
+ public STORKException(String message) {
+ super(message);
+
+ }
+
+ public STORKException(Throwable cause) {
+ super(cause);
+
+ }
+
+
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKResponseProcessor.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKResponseProcessor.java
new file mode 100644
index 000000000..c98ca87b9
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKResponseProcessor.java
@@ -0,0 +1,405 @@
+/**
+ *
+ */
+package at.gv.egovernment.moa.id.auth.stork;
+
+import iaik.x509.X509Certificate;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.util.List;
+import java.util.Vector;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.namespace.QName;
+import javax.xml.transform.TransformerException;
+
+import org.opensaml.common.binding.BasicSAMLMessageContext;
+import org.opensaml.saml2.binding.decoding.HTTPPostDecoder;
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.metadata.RequestedAttribute;
+import org.opensaml.saml2.metadata.SurName;
+import org.opensaml.ws.transport.http.HTTPInTransport;
+import org.opensaml.ws.transport.http.HTTPOutTransport;
+import org.opensaml.ws.transport.http.HttpServletRequestAdapter;
+import org.opensaml.ws.transport.http.HttpServletResponseAdapter;
+import org.opensaml.xml.XMLObject;
+import org.opensaml.xml.schema.XSAny;
+import org.opensaml.xml.schema.XSString;
+import org.opensaml.xml.util.Base64;
+import org.opensaml.xml.util.XMLHelper;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import at.gv.egovernment.moa.id.ParseException;
+import at.gv.egovernment.moa.id.auth.AuthenticationServer;
+import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute;
+import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttributeImpl;
+import at.gv.egovernment.moa.id.auth.data.IdentityLink;
+import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser;
+import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.CreateIdentityLinkResponse;
+import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWClientException;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.DateTimeUtils;
+import at.gv.egovernment.moa.util.StringUtils;
+import eu.stork.mw.messages.saml.STORKResponse;
+import eu.stork.vidp.messages.common.STORKConstants;
+import eu.stork.vidp.messages.util.SAMLUtil;
+import eu.stork.vidp.messages.util.XMLUtil;
+
+/**
+ *
+ * Handles all functionality for the processing of a STORK response
+ * @author bzwattendorfer
+ *
+ */
+public class STORKResponseProcessor {
+
+ /** OASIS DSS Namespace */
+ public static final String OASIS_DSS_NS = "urn:oasis:names:tc:dss:1.0:core:schema";
+
+ /** OASIS DSS Success Message */
+ public static final String OASIS_DSS_SUCCESS_MSG = "urn:oasis:names:tc:dss:1.0:resultmajor:Success";
+
+ /**
+ * Extracts a STORK response from a HTTP message
+ * @param request HttpServletRequest
+ * @param response HttpServletResponse
+ * @return STORK Response
+ * @throws STORKException
+ */
+ public static STORKResponse receiveSTORKRepsonse(HttpServletRequest request, HttpServletResponse response) throws STORKException {
+
+ HTTPInTransport httpInTransport = new HttpServletRequestAdapter(request);
+ HTTPOutTransport httpOutTransport = new HttpServletResponseAdapter(response, request.isSecure());
+
+ httpInTransport.getPeerAddress();
+
+ String samlResponseString = request.getParameter("SAMLResponse");
+
+ if (StringUtils.isEmpty(samlResponseString)) {
+ Logger.error("SAMLResponse not found in request.");
+ throw new STORKException("SAMLResponse not found in request.");
+ }
+
+ BasicSAMLMessageContext samlMessageContext = new BasicSAMLMessageContext();
+
+ samlMessageContext.setInboundMessageTransport(httpInTransport);
+ samlMessageContext.setOutboundMessageTransport(httpOutTransport);
+
+ HTTPPostDecoder postDecoder = new HTTPPostDecoder();
+
+ try {
+ postDecoder.decode(samlMessageContext);
+ } catch (Exception e) {
+ Logger.error("Error decoding SAMLResponse message", e);
+ throw new STORKException("Error decoding SAMLResponse message", e);
+ }
+
+ if (!(samlMessageContext.getInboundSAMLMessage() instanceof STORKResponse)) {
+ Logger.error("Message received is not a SAMLResponse message");
+ throw new STORKException("Message received is not a SAMLResponse message");
+ }
+
+ STORKResponse samlResponse = (STORKResponse) samlMessageContext.getInboundSAMLMessage();
+
+ return samlResponse;
+ }
+
+ /**
+ * Verifies a STORK response according STORK specification
+ * @param storkResponse STORK Response to verify
+ * @throws STORKException if validation fails
+ */
+ public static void verifySTORKResponse(STORKResponse storkResponse) throws STORKException {
+
+ ResponseVerifier responseVerifier = new PEPSConnectorResponseVerifier();
+ try {
+ responseVerifier.verify(storkResponse);
+ } catch (SecurityException e) {
+ Logger.error("Error validating response message from PEPS.", e);
+ throw new STORKException("Error validating response message from PEPS.");
+ }
+
+ }
+
+ /**
+ * Verifies a STORK assertion
+ * @param assertion STORK assertion
+ * @param ipAddress Client IP address
+ * @param authnRequestID ID of the AuthnRequest
+ * @param recipient recipient for verification
+ * @param audience audience for verification
+ * @param reqAttributeList RequestedAttribute list for verification
+ * @throws STORKException
+ */
+ public static void verifySTORKAssertion(
+ Assertion assertion,
+ String ipAddress,
+ String authnRequestID,
+ String recipient,
+ String audience,
+ List<RequestedAttribute> reqAttributeList) throws STORKException {
+
+ //validate Assertion
+ AssertionVerifier assertionVerifier = new PEPSConnectorAssertionVerifier();
+ try {
+ assertionVerifier.verify(assertion, ipAddress, authnRequestID, recipient, audience, reqAttributeList);
+
+ //verify if all required attributes are present
+ PEPSConnectorAssertionVerifier.validateRequiredAttributes(reqAttributeList, assertion.getAttributeStatements().get(0).getAttributes());
+
+ } catch (SecurityException e) {
+ Logger.error("Error verifying assertion from PEPS", e);
+ throw new STORKException("Error validating assertion received from PEPS.");
+ }
+
+ }
+
+ /**
+ * Extracts the citizen signature from the signedDoc element present in the STORK assertion
+ * @param storkAssertion STORK assertion
+ * @return citizen signature as XML
+ * @throws STORKException
+ */
+ public static Element extractCitizenSignature(Assertion storkAssertion) throws STORKException {
+
+ Logger.debug("Processing DSS signature response from PEPS");
+
+ Element signatureResponse = getSignedDocAttributeValue(storkAssertion);
+
+ if (signatureResponse == null) {
+ String msg = "Could not find DSS signature response in SAML assertion";
+ Logger.error(msg);
+ throw new STORKException(msg);
+ }
+
+ Logger.debug("Found DSS signature in SAML assertion");
+
+ Logger.debug("DSS Signature creation response received from PEPS (pretty print):");
+ Logger.debug(XMLHelper.prettyPrintXML(signatureResponse));
+ Logger.trace("DSS Signature creation response received from PEPS (original):");
+ Logger.trace(XMLUtil.printXML(signatureResponse));
+
+ Element signature = getSignature(signatureResponse);
+
+ if (signature == null) {
+ String msg = "Could not find citizen signature in SAML assertion";
+ Logger.error(msg);
+ throw new STORKException(msg);
+ }
+
+ Logger.debug("Found foreign citizen signature in SAML assertion (pretty print):");
+ Logger.debug(XMLHelper.prettyPrintXML(signature));
+ Logger.trace("Found foreign citizen signature in SAML assertion (original):");
+ Logger.trace(XMLUtil.printXML(signature));
+
+ return signature;
+ }
+
+ /**
+ * Extracts the signedDoc attribute from a STORK assertion as XML
+ * @param storkAssertion STORK assertion
+ * @return Value of signedDoc attribute
+ * @throws STORKException
+ */
+ private static Element getSignedDocAttributeValue(Assertion storkAssertion) throws STORKException {
+
+ XMLObject xmlObj = SAMLUtil.getAttributeValue(storkAssertion.getAttributeStatements().get(0).getAttributes(), STORKConstants.STORK_ATTRIBUTE_SIGNEDDOC);
+
+
+ if (xmlObj instanceof XSAny)
+ return getSignedDocAttributeValueFromAny((XSAny) xmlObj);
+ else if (xmlObj instanceof XSString)
+ return getSignedDocAttributValueFromString((XSString) xmlObj);
+ else
+ return null;
+
+ }
+
+ /**
+ * Get signedDoc as XML if provided as anyType
+ * @param any AttributeValue as anyType
+ * @return signedDoc as XML
+ */
+ private static Element getSignedDocAttributeValueFromAny(XSAny any) {
+ if (!any.getUnknownXMLObjects(new QName(OASIS_DSS_NS, "SignResponse")).isEmpty()) {
+ XMLObject xmlObj = any.getUnknownXMLObjects(new QName(OASIS_DSS_NS, "SignResponse")).get(0);
+ return xmlObj.getDOM();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get signedDoc as XML if provided as String
+ * @param string AttributeValue as String
+ * @return signedDoc as XML
+ * @throws STORKException
+ */
+ private static Element getSignedDocAttributValueFromString(XSString string) throws STORKException {
+ try {
+ return XMLUtil.stringToDOM(string.getValue());
+ } catch (Exception e) {
+ Logger.error("Error building DOM", e);
+ throw new STORKException(e);
+
+ }
+ }
+
+ /**
+ * Extracts the signature value out of a DSS response
+ * @param signatureResponse DSS signature response
+ * @return signature
+ * @throws STORKException
+ */
+ private static Element getSignature(Element signatureResponse) throws STORKException {
+
+ NodeList nList = signatureResponse.getElementsByTagNameNS(OASIS_DSS_NS, "ResultMajor");
+
+ String resultMajor = XMLUtil.getFirstTextValueFromNodeList(nList);
+
+ if (StringUtils.isEmpty(resultMajor)) {
+ String msg = "DSS response not correct, ResultMajor element missing.";
+ Logger.error(msg);
+ throw new STORKException(msg);
+ }
+
+ Logger.trace("ResultMajor of DSS response: " + resultMajor);
+
+ if (!OASIS_DSS_SUCCESS_MSG.equals(resultMajor)) {
+ String msg = "DSS response not correct, ResultMajor is " + resultMajor;
+ Logger.error(msg);
+ throw new STORKException(msg);
+ }
+
+ NodeList nList2 = signatureResponse.getElementsByTagNameNS(OASIS_DSS_NS, "Base64Signature");;
+
+ String base64SigString = XMLUtil.getFirstTextValueFromNodeList(nList2);
+
+ if (StringUtils.isEmpty(base64SigString)) {
+ String msg = "DSS response not correct, Base64Signature element missing.";
+ Logger.error(msg);
+ throw new STORKException(msg);
+ }
+
+ Logger.trace("Base64Signature element of DSS response: " + base64SigString);
+
+ String sigString = new String(Base64.decode(base64SigString));
+
+ try {
+ return XMLUtil.stringToDOM(sigString);
+ } catch (Exception e) {
+ String msg = "Unable to extract signature from DSS response";
+ Logger.error(msg);
+ throw new STORKException(msg);
+ }
+
+
+ }
+
+ /**
+ * Handels connection to SZR-GW and returns Identity Link on success
+ * @param citizenSignature Citizen signature
+ * @param attributeList Received attribute List in assertion
+ * @return Identity Link
+ * @throws STORKException
+ */
+ public static IdentityLink connectToSZRGateway(Element citizenSignature, List<Attribute> attributeList) throws STORKException {
+ Logger.trace("Calling SZR Gateway with the following attributes:");
+
+ String fiscalNumber = SAMLUtil.getAttributeStringValue(attributeList, STORKConstants.STORK_ATTRIBUTE_FISCALNUMBER);
+ Logger.trace(STORKConstants.STORK_ATTRIBUTE_FISCALNUMBER + " : " + fiscalNumber);
+
+ String givenName = SAMLUtil.getAttributeStringValue(attributeList, STORKConstants.STORK_ATTRIBUTE_GIVENNAME);
+ Logger.trace(STORKConstants.STORK_ATTRIBUTE_GIVENNAME+ " : " + givenName);
+
+ String lastName = SAMLUtil.getAttributeStringValue(attributeList, STORKConstants.STORK_ATTRIBUTE_SURNAME);
+ Logger.trace(STORKConstants.STORK_ATTRIBUTE_SURNAME+ " : " + lastName);
+
+ String dateOfBirth = SAMLUtil.getAttributeStringValue(attributeList, STORKConstants.STORK_ATTRIBUTE_DATEOFBIRTH);
+ Logger.trace(STORKConstants.STORK_ATTRIBUTE_DATEOFBIRTH + " : " + dateOfBirth);
+
+ if (!StringUtils.isEmpty(dateOfBirth)) {
+ dateOfBirth = DateTimeUtils.formatPEPSDateToMOADate(dateOfBirth);
+ }
+
+ CreateIdentityLinkResponse response;
+ IdentityLink identityLink = null;
+ try {
+ Logger.trace("Starting call...");
+ response = AuthenticationServer.getInstance().getIdentityLink(fiscalNumber, givenName, lastName, dateOfBirth, citizenSignature);
+ if (response.isError()) {
+ Logger.error("Receveid ErrorResponse from SZR Gateway.");
+ throw new SZRGWClientException(response.getError());
+ }
+ else {
+ Logger.trace("Receveid Success Response from SZR Gateway.");
+ Element samlAssertion = response.getAssertion();
+
+ IdentityLinkAssertionParser ilParser = new IdentityLinkAssertionParser(samlAssertion);
+ identityLink = ilParser.parseIdentityLink();
+
+
+ Logger.debug("Received Identity Link from SZR Gateway");
+ //TODO: is this ok?
+// if (StringUtils.isEmpty(identityLink.getDateOfBirth())) {
+// identityLink.setDateOfBirth("9999-12-31");
+// }
+
+ }
+ } catch (SZRGWClientException e) {
+ Logger.error("Error connecting SZR-Gateway: ", e);
+ throw new STORKException("Error connecting SZR-Gateway: ", e);
+ } catch (ParseException e) {
+ Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e);
+ throw new STORKException("Error parsing IdentityLink received from SZR-Gateway: ", e);
+ }
+
+ return identityLink;
+
+ }
+
+
+ /**
+ * Transforms additional STORK attributes to MOA Extended attributes
+ * @param storkAttributeList STORK attribute list
+ * @return
+ */
+ public static List<ExtendedSAMLAttribute> addAdditionalSTORKAttributes(List<Attribute> storkAttributeList) {
+ List<ExtendedSAMLAttribute> moaExtendedSAMLAttributeList = new Vector<ExtendedSAMLAttribute>();
+
+ Logger.trace("Adding the following attributes to MOA assertion: ");
+ int count = 0;
+ //only add attributes different than eIdentifier, given name, surname, dateOfBirth, signedDoc
+ for (Attribute attribute : storkAttributeList) {
+ //attribute is not in default returned attribute set
+ if (!STORKConstants.DEFAULT_STORK_RETURNED_ATTRIBUTE_SET.contains(attribute.getName())) {
+
+ String attributeValue = null;
+ if (!attribute.getAttributeValues().isEmpty()) {
+ //we have attribute value
+ attributeValue = SAMLUtil.getStringValueFromXMLObject(attribute.getAttributeValues().get(0));
+ }
+ ExtendedSAMLAttribute extendedSAMLAttribute =
+ new ExtendedSAMLAttributeImpl(attribute.getName(), attributeValue, Constants.STORK_NS_URI, 0);
+ moaExtendedSAMLAttributeList.add(extendedSAMLAttribute);
+ count++;
+ Logger.trace("Additional attribute: " + attribute.getName());
+ }
+ }
+
+
+ Logger.debug("Added " + count + " STORK attribute(s) to the MOA assertion.");
+
+ return moaExtendedSAMLAttributeList;
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/VelocityProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/VelocityProvider.java
new file mode 100644
index 000000000..29478718f
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/stork/VelocityProvider.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2011 by Graz University of Technology, Austria
+ * The Austrian STORK Modules have been developed by the E-Government
+ * Innovation Center EGIZ, a joint initiative of the Federal Chancellery
+ * Austria 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.stork;
+
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
+
+/**
+ * Gets a Velocity Engine
+ *
+ * @author bzwattendorfer
+ *
+ */
+public class VelocityProvider {
+
+ /**
+ * Gets velocityEngine from Classpath
+ * @return VelocityEngine
+ * @throws Exception
+ */
+ public static VelocityEngine getClassPathVelocityEngine() throws Exception {
+ VelocityEngine velocityEngine = getBaseVelocityEngine();
+ velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
+ velocityEngine.setProperty("classpath.resource.loader.class",
+ "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+
+ velocityEngine.init();
+
+ return velocityEngine;
+ }
+
+ /**
+ * Gets VelocityEngine from File
+ * @param rootPath File Path to template file
+ * @return VelocityEngine
+ * @throws Exception
+ */
+ public static VelocityEngine getFileVelocityEngine(String rootPath) throws Exception {
+ VelocityEngine velocityEngine = getBaseVelocityEngine();
+ velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "file");
+ velocityEngine.setProperty("file.resource.loader.class",
+ "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
+ velocityEngine.setProperty("file.resource.loader.path", rootPath);
+
+ velocityEngine.init();
+
+ return velocityEngine;
+ }
+
+ /**
+ * Gets a basic VelocityEngine
+ * @return VelocityEngine
+ */
+ private static VelocityEngine getBaseVelocityEngine() {
+ VelocityEngine velocityEngine = new VelocityEngine();
+ velocityEngine.setProperty(RuntimeConstants.ENCODING_DEFAULT, "UTF-8");
+ velocityEngine.setProperty(RuntimeConstants.OUTPUT_ENCODING, "UTF-8");
+
+ return velocityEngine;
+ }
+
+}
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.
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java
index 04b92f209..b6ffb0c59 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java
@@ -35,13 +35,17 @@ import java.util.List;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
+import eu.stork.vidp.messages.common.STORKBootstrap;
+
import at.gv.egovernment.moa.id.config.ConfigurationBuilder;
import at.gv.egovernment.moa.id.config.ConfigurationException;
import at.gv.egovernment.moa.id.config.ConfigurationProvider;
import at.gv.egovernment.moa.id.config.ConnectionParameter;
+import at.gv.egovernment.moa.id.config.stork.STORKConfig;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.DOMUtils;
import at.gv.egovernment.moa.util.FileUtils;
+import at.gv.egovernment.moa.util.StringUtils;
import at.gv.egovernment.moa.util.XPathUtils;
/**
@@ -183,6 +187,11 @@ public class AuthConfigurationProvider extends ConfigurationProvider {
*/
private List trustedBKUs;
+ /**
+ * Holds general information for STORK (e.g. C-PEPS connection parameter, SAML signing parameters, etc.)
+ */
+ private STORKConfig storkConfig;
+
/**
* Return the single instance of configuration data.
*
@@ -263,7 +272,12 @@ public class AuthConfigurationProvider extends ConfigurationProvider {
} catch (MalformedURLException t) {
throw new ConfigurationException("config.03", null, t);
}
-
+
+ //Initialize OpenSAML for STORK
+ Logger.trace("Starting initialization of OpenSAML...");
+ STORKBootstrap.bootstrap();
+ Logger.debug("OpenSAML successfully initialized");
+
// build the internal datastructures
builder = new ConfigurationBuilder(configElem, rootConfigFileDir);
bKUConnectionParameter = builder.buildAuthBKUConnectionParameter();
@@ -293,6 +307,7 @@ public class AuthConfigurationProvider extends ConfigurationProvider {
trustedCACertificates = builder.getTrustedCACertificates();
trustedCACertificates = FileUtils.makeAbsoluteURL(trustedCACertificates, rootConfigFileDir);
trustedBKUs = builder.getTrustedBKUs();
+ storkConfig = new STORKConfig(builder.buildSTORKSignatureCreationParameter(),builder.buildSTORKSignatureVerificationParameter(), builder.buildSTORKcPEPSMap());
} catch (Throwable t) {
throw new ConfigurationException("config.02", null, t);
@@ -370,6 +385,7 @@ public class AuthConfigurationProvider extends ConfigurationProvider {
}
return null;
}
+
/**
* Return a string with a url-reference to the VerifyAuthBlock trust
@@ -484,4 +500,14 @@ public class AuthConfigurationProvider extends ConfigurationProvider {
return defaultVerifyInfoboxParameters;
}
+ /**
+ * Retruns the STORK Configuration
+ * @return STORK Configuration
+ */
+ public STORKConfig getStorkConfig() {
+ return storkConfig;
+ }
+
+
+
} \ No newline at end of file
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java
index 2959d9208..091a01bf7 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java
@@ -24,7 +24,15 @@
package at.gv.egovernment.moa.id.config.auth;
+import java.util.ArrayList;
+
+import org.opensaml.saml2.metadata.RequestedAttribute;
+
import at.gv.egovernment.moa.id.config.OAParameter;
+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;
/**
* Configuration parameters belonging to an online application,
@@ -117,12 +125,28 @@ public class OAAuthParameter extends OAParameter {
private String mandateProfiles;
/**
- * BZ
+ *
* Type for authentication number (e.g. Firmenbuchnummer)
*/
private String identityLinkDomainIdentifierType;
/**
+ * STORK QAA Level, Default = 4
+ */
+ private QualityAuthenticationAssuranceLevel qaaLevel = STORKMessagesBuilder.buildQualityAuthenticationAssuranceLevel(4);
+
+ /**
+ * STORK RequestedAttributes for Online Application
+ * Default RequestedAttributes are: eIdentifier, givenName, surname, dateOfBirth
+ */
+ private RequestedAttributes requestedAttributes = STORKMessagesBuilder.buildRequestedAttributes(
+ STORKMessagesBuilder.buildRequestedAttribute(STORKConstants.STORK_ATTRIBUTE_EIDENTIFIER, true, null),
+ STORKMessagesBuilder.buildRequestedAttribute(STORKConstants.STORK_ATTRIBUTE_GIVENNAME, true, null),
+ STORKMessagesBuilder.buildRequestedAttribute(STORKConstants.STORK_ATTRIBUTE_SURNAME, true, null),
+ STORKMessagesBuilder.buildRequestedAttribute(STORKConstants.STORK_ATTRIBUTE_DATEOFBIRTH, false, null));
+
+
+/**
* Returns <code>true</code> if the Security Layer version is version 1.2,
* otherwise <code>false</code>.
* @return <code>true</code> if the Security Layer version is version 1.2,
@@ -441,4 +465,38 @@ public class OAAuthParameter extends OAParameter {
return this.mandateProfiles;
}
+ /**
+ * Returns the defined STORK QAALevel
+ * @return STORK QAALevel
+ */
+ public QualityAuthenticationAssuranceLevel getQaaLevel() {
+ return qaaLevel;
+ }
+
+ /**
+ * Sets the STORK QAALevel
+ * @param qaaLevel
+ */
+ public void setQaaLevel(QualityAuthenticationAssuranceLevel qaaLevel) {
+ this.qaaLevel = qaaLevel;
+ }
+
+ /**
+ * Returns the desired STORK Requested Attributes
+ * @return STORK Requested Attributes
+ */
+ public RequestedAttributes getRequestedAttributes() {
+ return requestedAttributes;
+ }
+
+ /**
+ * Sets the desired STORK Requested Attributes
+ * @param requestedAttributes
+ */
+ public void setRequestedAttributes(RequestedAttributes requestedAttributes) {
+ this.requestedAttributes = requestedAttributes;
+ }
+
+
+
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/CPEPS.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/CPEPS.java
new file mode 100644
index 000000000..a5b160454
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/CPEPS.java
@@ -0,0 +1,98 @@
+/**
+ *
+ */
+package at.gv.egovernment.moa.id.config.stork;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opensaml.saml2.metadata.RequestedAttribute;
+
+/**
+ * Encpasulates C-PEPS information according MOA configuration
+ *
+ * @author bzwattendorfer
+ *
+ */
+public class CPEPS {
+
+ /** Country Code of C-PEPS */
+ private String countryCode;
+
+ /** URL of C-PEPS */
+ private URL pepsURL;
+
+ /** Specific attributes to be requested for this C-PEPS */
+ private List<RequestedAttribute> countrySpecificRequestedAttributes = new ArrayList<RequestedAttribute>();
+
+ /**
+ * Constructs a C-PEPS
+ * @param countryCode ISO Country Code of C-PEPS
+ * @param pepsURL URL of C-PEPS
+ */
+ public CPEPS(String countryCode, URL pepsURL) {
+ super();
+ this.countryCode = countryCode;
+ this.pepsURL = pepsURL;
+ }
+
+ /**
+ * Gets the country code of this C-PEPS
+ * @return ISO country code
+ */
+ public String getCountryCode() {
+ return countryCode;
+ }
+
+ /**
+ * Sets the country code of this C-PEPS
+ * @param countryCode ISO country code
+ */
+ public void setCountryCode(String countryCode) {
+ this.countryCode = countryCode;
+ }
+
+ /**
+ * Gets the URL of this C-PEPS
+ * @return C-PEPS URL
+ */
+ public URL getPepsURL() {
+ return pepsURL;
+ }
+
+ /**
+ * Sets the C-PEPS URL
+ * @param pepsURL C-PEPS URL
+ */
+ public void setPepsURL(URL pepsURL) {
+ this.pepsURL = pepsURL;
+ }
+
+ /**
+ * Gets the country specific attributes of this C-PEPS
+ * @return List of country specific attributes
+ */
+ public List<RequestedAttribute> getCountrySpecificRequestedAttributes() {
+ return countrySpecificRequestedAttributes;
+ }
+
+ /**
+ * Sets the country specific attributes
+ * @param countrySpecificRequestedAttributes List of country specific requested attributes
+ */
+ public void setCountrySpecificRequestedAttributes(
+ List<RequestedAttribute> countrySpecificRequestedAttributes) {
+ this.countrySpecificRequestedAttributes = countrySpecificRequestedAttributes;
+ }
+
+ /**
+ * Adds a Requested attribute to the country specific attribute List
+ * @param countrySpecificRequestedAttribute Additional country specific requested attribute to add
+ */
+ public void addCountrySpecificRequestedAttribute(RequestedAttribute countrySpecificRequestedAttribute) {
+ this.countrySpecificRequestedAttributes.add(countrySpecificRequestedAttribute);
+ }
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java
new file mode 100644
index 000000000..485a44421
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/STORKConfig.java
@@ -0,0 +1,90 @@
+/**
+ *
+ */
+package at.gv.egovernment.moa.id.config.stork;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import at.gv.egovernment.moa.util.StringUtils;
+
+/**
+ * Encapsulates several STORK configuration parameters according MOA configuration
+ *
+ * @author bzwattendorfer
+ *
+ */
+public class STORKConfig {
+
+ /** STORK SAML signature creation parameters */
+ private SignatureCreationParameter signatureCreationParameter;
+
+ /** STORK SAML signature verification parameters */
+ private SignatureVerificationParameter signatureVerificationParameter;
+
+ /** Map of supported C-PEPSs */
+ private Map<String, CPEPS> cpepsMap = new HashMap<String, CPEPS>();
+
+
+ /**
+ * Constructs a STORK Config object
+ * @param signatureCreationParameter STORK SAML Signature creation parameters
+ * @param signatureVerificationParameter STORK SAML Signature verification parameters
+ * @param cpepsMap Map of supported C-PEPS
+ */
+ public STORKConfig(SignatureCreationParameter signatureCreationParameter,
+ SignatureVerificationParameter signatureVerificationParameter,
+ Map<String, CPEPS> cpepsMap) {
+ super();
+ this.signatureCreationParameter = signatureCreationParameter;
+ this.signatureVerificationParameter = signatureVerificationParameter;
+ this.cpepsMap = cpepsMap;
+ }
+
+ public SignatureCreationParameter getSignatureCreationParameter() {
+ return signatureCreationParameter;
+ }
+
+ public void setSignatureCreationParameter(
+ SignatureCreationParameter signatureCreationParameter) {
+ this.signatureCreationParameter = signatureCreationParameter;
+ }
+
+ public SignatureVerificationParameter getSignatureVerificationParameter() {
+ return signatureVerificationParameter;
+ }
+
+ public void setSignatureVerificationParameter(
+ SignatureVerificationParameter signatureVerificationParameter) {
+ this.signatureVerificationParameter = signatureVerificationParameter;
+ }
+
+ public Map<String, CPEPS> getCpepsMap() {
+ return cpepsMap;
+ }
+
+ public void setCpepsMap(Map<String, CPEPS> cpepsMap) {
+ this.cpepsMap = cpepsMap;
+ }
+
+ public boolean isSTORKAuthentication(String ccc) {
+
+ if (StringUtils.isEmpty(ccc) || this.cpepsMap.isEmpty())
+ return false;
+
+ if (this.cpepsMap.containsKey(ccc.toUpperCase()))
+ return true;
+ else
+ return false;
+
+ }
+
+ public CPEPS getCPEPS(String ccc) {
+ if (isSTORKAuthentication(ccc))
+ return this.cpepsMap.get(ccc);
+ else
+ return null;
+ }
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/SignatureCreationParameter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/SignatureCreationParameter.java
new file mode 100644
index 000000000..1f66b7752
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/SignatureCreationParameter.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2003 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.config.stork;
+
+/**
+ * Encapsulates signature creation parameters according MOA configuration
+ *
+ * @author bzwattendorfer
+ *
+ */
+public class SignatureCreationParameter {
+
+ /** KeyStore Path */
+ private String keyStorePath;
+
+ /** KeyStore Password */
+ private String keyStorePassword;
+
+ /** Signing Key Name */
+ private String keyName;
+
+ /** Signing Key Password */
+ private String keyPassword;
+
+ /**
+ * Gets the KeyStore Path
+ * @return File Path to KeyStore
+ */
+ public String getKeyStorePath() {
+ return keyStorePath;
+ }
+
+ /**
+ * Sets the KeyStore Path
+ * @param keyStorePath Path to KeyStore
+ */
+ public void setKeyStorePath(String keyStorePath) {
+ this.keyStorePath = keyStorePath;
+ }
+
+ /**
+ * Gets the KeyStore Password
+ * @return Password to KeyStore
+ */
+ public String getKeyStorePassword() {
+ return keyStorePassword;
+ }
+
+ /**
+ * Sets the KeyStore Password
+ * @param keyStorePassword Password to KeyStore
+ */
+ public void setKeyStorePassword(String keyStorePassword) {
+ this.keyStorePassword = keyStorePassword;
+ }
+
+ /**
+ * Gets the Signing Key Name
+ * @return Siging Key Name
+ */
+ public String getKeyName() {
+ return keyName;
+ }
+
+ /**
+ * Sets the Signing Key Name
+ * @param keyName Signing Key Name
+ */
+ public void setKeyName(String keyName) {
+ this.keyName = keyName;
+ }
+
+ /**
+ * Gets the Signing Key Password
+ * @return Signing Key Password
+ */
+ public String getKeyPassword() {
+ return keyPassword;
+ }
+
+ /**
+ * Sets the Signing Key Password
+ * @param keyPassword Signing Key Password
+ */
+ public void setKeyPassword(String keyPassword) {
+ this.keyPassword = keyPassword;
+ }
+
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/SignatureVerificationParameter.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/SignatureVerificationParameter.java
new file mode 100644
index 000000000..2d8402e4d
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/stork/SignatureVerificationParameter.java
@@ -0,0 +1,35 @@
+/**
+ *
+ */
+package at.gv.egovernment.moa.id.config.stork;
+
+/**
+ * Encapsulates Signature Verification data for STORK according MOA configuration
+ *
+ * @author bzwattendorfer
+ *
+ */
+public class SignatureVerificationParameter {
+
+ /** ID of the MOA-SP TrustProfile to be used for STORK SAML signature verification */
+ private String trustProfileID;
+
+ /**
+ * Gets the MOA-SP TrustProfileID
+ * @return TrustProfileID of MOA-SP for STORK signature verification
+ */
+ public String getTrustProfileID() {
+ return trustProfileID;
+ }
+
+ /**
+ * Sets the MOA-SP TrustProfileID
+ * @param trustProfileID TrustProfileID of MOA-SP for STORK signature verification
+ */
+ public void setTrustProfileID(String trustProfileID) {
+ this.trustProfileID = trustProfileID;
+ }
+
+
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPUtils.java
index 7b29051f3..a148aa690 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPUtils.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/HTTPUtils.java
@@ -40,9 +40,13 @@ import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
+import javax.servlet.http.HttpServletRequest;
+
import org.apache.regexp.RE;
import org.apache.regexp.RESyntaxException;
+import at.gv.egovernment.moa.util.StringUtils;
+
/**
*
* @author Rudolf Schamberger
@@ -88,5 +92,47 @@ public class HTTPUtils {
conn.disconnect();
return buffer.toString();
}
+
+ /**
+ * Helper method to retrieve server URL including context path
+ * @param request HttpServletRequest
+ * @return Server URL including context path (e.g. http://localhost:8443/moa-id-auth
+ */
+ public static String getBaseURL(HttpServletRequest request) {
+ StringBuffer buffer = new StringBuffer(getServerURL(request));
+
+ // add context path if available
+ String contextPath = request.getContextPath();
+ if (!StringUtils.isEmpty(contextPath)) {
+ buffer.append(contextPath);
+ }
+
+ return buffer.toString();
+ }
+
+ /**
+ * Helper method to retrieve server URL
+ * @param request HttpServletRequest
+ * @return Server URL (e.g. http://localhost:8443)
+ */
+ public static String getServerURL(HttpServletRequest request) {
+ StringBuffer buffer = new StringBuffer();
+
+ // get protocol
+ String protocol = request.getScheme();
+ buffer.append(protocol).append("://");
+
+ // server name
+ buffer.append(request.getServerName());
+
+ // add port if necessary
+ int port = request.getServerPort();
+ if ((protocol.equals("http") && port != 80) || (protocol.equals("https") && port != 443)) {
+ buffer.append(':');
+ buffer.append(port);
+ }
+
+ return buffer.toString();
+ }
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParamValidatorUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParamValidatorUtils.java
index 790651adf..0862371dd 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParamValidatorUtils.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/ParamValidatorUtils.java
@@ -43,6 +43,7 @@ import org.xml.sax.SAXException;
import at.gv.egovernment.moa.id.config.ConfigurationException;
import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.StringUtils;
public class ParamValidatorUtils {
@@ -54,10 +55,10 @@ public class ParamValidatorUtils {
*/
public static boolean isValidTarget(String target) {
- Logger.debug("Überprüfe Parameter Target");
+ Logger.debug("�berpr�fe Parameter Target");
// if non parameter is given return true
- if (target == null) {
+ if (StringUtils.isEmpty(target)) {
Logger.debug("Parameter Target ist null");
return true;
}
@@ -67,27 +68,57 @@ public class ParamValidatorUtils {
Matcher matcher = pattern.matcher(target);
boolean b = matcher.matches();
if (b) {
- Logger.debug("Parameter Target erfolgreich überprüft");
+ Logger.debug("Parameter Target erfolgreich �berpr�ft");
return true;
}
else {
- Logger.error("Fehler Überprüfung Parameter Target. Target entspricht nicht den Kriterien (nur Zeichen a-z, A-Z und -, sowie 1-5 Zeichen lang)");
+ Logger.error("Fehler �berpr�fung Parameter Target. Target entspricht nicht den Kriterien (nur Zeichen a-z, A-Z und -, sowie 1-5 Zeichen lang)");
return false;
}
}
/**
+ * Checks if the given ccc parameter is valid
+ * @param ccc HTTP parameter from request
+ * @return true if ccc is valid
+ */
+ public static boolean isValidCCC(String ccc) {
+
+ Logger.debug("�berpr�fe Parameter CCC");
+
+ // if non parameter is given return true
+ if (StringUtils.isEmpty(ccc)) {
+ Logger.debug("Parameter CCC ist null");
+ return true;
+ }
+
+
+ Pattern pattern = Pattern.compile("[a-zA-Z]{2}");
+ Matcher matcher = pattern.matcher(ccc);
+ boolean b = matcher.matches();
+ if (b) {
+ Logger.debug("Parameter CCC erfolgreich �berpr�ft");
+ return true;
+ }
+ else {
+ Logger.error("Fehler �berpr�fung Parameter CCC. CCC entspricht nicht den Kriterien (nur Zeichen a-z, A-Z, sowie 2 Zeichen lang)");
+ return false;
+ }
+
+ }
+
+ /**
* Checks if the given target is valid
* @param sourceID HTTP parameter from request
* @return
*/
public static boolean isValidSourceID(String sourceID) {
- Logger.debug("Überprüfe Parameter sourceID");
+ Logger.debug("�berpr�fe Parameter sourceID");
// if non parameter is given return true
- if (sourceID == null) {
+ if (StringUtils.isEmpty(sourceID)) {
Logger.debug("Parameter Target ist null");
return true;
}
@@ -97,11 +128,11 @@ public class ParamValidatorUtils {
Matcher matcher = pattern.matcher(sourceID);
boolean b = matcher.matches();
if (b) {
- Logger.debug("Parameter sourceID erfolgreich überprüft");
+ Logger.debug("Parameter sourceID erfolgreich �berpr�ft");
return true;
}
else {
- Logger.error("Fehler Überprüfung Parameter sourceID. SourceID entspricht nicht den Kriterien (nur Zeichen a-z, A-Z, - und _, sowie 1-20 Zeichen lang)");
+ Logger.error("Fehler �berpr�fung Parameter sourceID. SourceID entspricht nicht den Kriterien (nur Zeichen a-z, A-Z, - und _, sowie 1-20 Zeichen lang)");
return false;
}
@@ -114,21 +145,21 @@ public class ParamValidatorUtils {
*/
public static boolean isValidUseMandate(String usemandate) {
- Logger.debug("Überprüfe Parameter useMandate");
+ Logger.debug("�berpr�fe Parameter useMandate");
// if non parameter is given return true
- if (usemandate== null) {
+ if (StringUtils.isEmpty(usemandate)) {
Logger.debug("Parameter useMandate ist null");
return true;
}
if (usemandate.compareToIgnoreCase("true") == 0 || usemandate.compareToIgnoreCase("false") == 0) {
- Logger.debug("Parameter useMandate erfolgreich überprüft");
+ Logger.debug("Parameter useMandate erfolgreich �berpr�ft");
return true;
}
else {
- Logger.error("Fehler Überprüfung Parameter useMandate. useMandate ist weder 'true' noch 'false')");
+ Logger.error("Fehler �berpr�fung Parameter useMandate. useMandate ist weder 'true' noch 'false')");
return false;
}
@@ -144,10 +175,10 @@ public class ParamValidatorUtils {
* @return
*/
public static boolean isValidBKUURI(String bkuURI) {
- Logger.debug("Überprüfe Parameter bkuURI");
+ Logger.debug("�berpr�fe Parameter bkuURI");
// if non parameter is given return true
- if (bkuURI == null) {
+ if (StringUtils.isEmpty(bkuURI)) {
Logger.debug("Parameter bkuURI ist null");
return true;
}
@@ -163,20 +194,20 @@ public class ParamValidatorUtils {
bkuURI.compareToIgnoreCase("http://localhost:3495/http-security-layer-request") == 0 ||
bkuURI.compareToIgnoreCase("http://127.0.0.1:3495/http-security-layer-request") == 0 ||
bkuURI.compareToIgnoreCase("https://127.0.0.1:3496/https-security-layer-request") == 0) {
- Logger.debug("Parameter bkuURI erfolgreich überprüft");
+ Logger.debug("Parameter bkuURI erfolgreich �berpr�ft");
return true;
}
else {
- Logger.debug("Parameter bkuURI ist keine lokale BKU. Überprüfe Liste der vertrauenswürdigen BKUs.");
+ Logger.debug("Parameter bkuURI ist keine lokale BKU. �berpr�fe Liste der vertrauensw�rdigen BKUs.");
AuthConfigurationProvider authConf = AuthConfigurationProvider.getInstance();
List trustedBKUs = authConf.getTrustedBKUs();
boolean b = trustedBKUs.contains(bkuURI);
if (b) {
- Logger.debug("Parameter bkuURI erfolgreich überprüft");
+ Logger.debug("Parameter bkuURI erfolgreich �berpr�ft");
return true;
}
else {
- Logger.error("Fehler Überprüfung Parameter bkuURI. bkuURI ist nicht auf Liste der vertrauenswürdigen BKUs (Konfigurationselement: MOA-IDConfiguration/TrustedBKUs)");
+ Logger.error("Fehler �berpr�fung Parameter bkuURI. bkuURI ist nicht auf Liste der vertrauensw�rdigen BKUs (Konfigurationselement: MOA-IDConfiguration/TrustedBKUs)");
return false;
}
}
@@ -184,16 +215,16 @@ public class ParamValidatorUtils {
}
else {
- Logger.error("Fehler Überprüfung Parameter bkuURI. bkuURI beginnt nicht mit http or https");
+ Logger.error("Fehler �berpr�fung Parameter bkuURI. bkuURI beginnt nicht mit http or https");
return false;
}
} catch (MalformedURLException e) {
- Logger.error("Fehler Überprüfung Parameter bkuURI", e);
+ Logger.error("Fehler �berpr�fung Parameter bkuURI", e);
return false;
} catch (ConfigurationException e) {
- Logger.error("Fehler Überprüfung Parameter bkuURI", e);
+ Logger.error("Fehler �berpr�fung Parameter bkuURI", e);
return false;
}
}
@@ -243,7 +274,7 @@ public class ParamValidatorUtils {
//
// System.out.println("ret: " + ret);
//
-// Logger.error("Fehler Überprüfung Parameter bkuURI. Antwortcode von BKU ist nicht 200.");
+// Logger.error("Fehler �berpr�fung Parameter bkuURI. Antwortcode von BKU ist nicht 200.");
// return false;
// }
//
@@ -257,26 +288,26 @@ public class ParamValidatorUtils {
//
//// NodeList l = doc.getElementsByTagNameNS(Constants.SL12_NS_URI, "ErrorResponse");
//// if (l.getLength() != 0) {
-//// Logger.error("Fehler Überprüfung Parameter bkuURI. ErrorResponse von BKU empfangen.");
+//// Logger.error("Fehler �berpr�fung Parameter bkuURI. ErrorResponse von BKU empfangen.");
//// return false;
//// }
//
-// Logger.debug("Parameter Template bkuURI erfolgreich überprüft");
+// Logger.debug("Parameter Template bkuURI erfolgreich �berpr�ft");
// return true;
//
//// } catch (SAXException e) {
-//// Logger.error("Fehler Überprüfung Parameter bkuURI.", e);
+//// Logger.error("Fehler �berpr�fung Parameter bkuURI.", e);
//// return false;
// } catch (IOException e) {
-// Logger.error("Fehler Überprüfung Parameter bkuURI.", e);
+// Logger.error("Fehler �berpr�fung Parameter bkuURI.", e);
// return false;
// } catch (ParserConfigurationException e) {
-// Logger.error("Fehler Überprüfung Parameter bkuURI.", e);
+// Logger.error("Fehler �berpr�fung Parameter bkuURI.", e);
// return false;
// }
// }
// else {
-// Logger.error("Fehler Überprüfung Parameter bkuURI. bkuURI ist null.");
+// Logger.error("Fehler �berpr�fung Parameter bkuURI. bkuURI ist null.");
// return false;
// }
//
@@ -313,10 +344,10 @@ public class ParamValidatorUtils {
*/
public static boolean isValidTemplate(HttpServletRequest req, String template) {
- Logger.debug("Überprüfe Parameter Template bzw. bkuSelectionTemplateURL");
+ Logger.debug("�berpr�fe Parameter Template bzw. bkuSelectionTemplateURL");
// if non parameter is given return true
- if (template == null) {
+ if (StringUtils.isEmpty(template)) {
Logger.debug("Parameter Template bzw. bkuSelectionTemplateURL ist null");
return true;
}
@@ -334,37 +365,37 @@ public class ParamValidatorUtils {
if (template.startsWith(httpName) || template.startsWith(httpsName)) {
new URL(template);
- Logger.debug("Parameter Template bzw. bkuSelectionTemplateURL erfolgreich überprüft");
+ Logger.debug("Parameter Template bzw. bkuSelectionTemplateURL erfolgreich �berpr�ft");
return true;
}
else {
- Logger.error("Fehler Überprüfung Parameter Template bzw. bkuSelectionTemplateURL. Parameter liegt nicht am gleichen Server wie die MOA-Instanz (" + req.getServerName() + ")");
+ Logger.error("Fehler �berpr�fung Parameter Template bzw. bkuSelectionTemplateURL. Parameter liegt nicht am gleichen Server wie die MOA-Instanz (" + req.getServerName() + ")");
return false;
}
}
else {
- Logger.error("Fehler Überprüfung Parameter Template bzw. bkuSelectionTemplateURL. Paramter beginnt nicht mit http oder https.");
+ Logger.error("Fehler �berpr�fung Parameter Template bzw. bkuSelectionTemplateURL. Paramter beginnt nicht mit http oder https.");
return false;
}
} catch (MalformedURLException e) {
- Logger.error("Fehler Überprüfung Parameter Template bzw. bkuSelectionTemplateURL.", e);
+ Logger.error("Fehler �berpr�fung Parameter Template bzw. bkuSelectionTemplateURL.", e);
return false;
}
}
/**
- * Checks if the given template is valid
+ * Checks if the given sessionID is valid
* @param target HTTP parameter from request
* @return
*/
public static boolean isValidSessionID(String sessionID) {
- Logger.debug("Überprüfe Parameter MOASessionId");
+ Logger.debug("�berpr�fe Parameter MOASessionId");
// if non parameter is given return true
- if (sessionID == null) {
+ if (StringUtils.isEmpty(sessionID)) {
Logger.debug("Parameter MOASessionId ist null");
return true;
}
@@ -374,11 +405,11 @@ public class ParamValidatorUtils {
Matcher matcher = pattern.matcher(sessionID);
boolean b = matcher.matches();
if (b) {
- Logger.debug("Parameter MOASessionId erfolgreich überprüft");
+ Logger.debug("Parameter MOASessionId erfolgreich �berpr�ft");
return true;
}
else {
- Logger.error("Fehler Überprüfung Parameter MOASessionId. MOASessionId entspricht nicht den Kriterien (nur Zeichen 0-9 und -)");
+ Logger.error("Fehler �berpr�fung Parameter MOASessionId. MOASessionId entspricht nicht den Kriterien (nur Zeichen 0-9 und -)");
return false;
}
@@ -394,9 +425,9 @@ public class ParamValidatorUtils {
* @return
*/
public static boolean isValidOA(String oa) {
- Logger.debug("Überprüfe Parameter oa");
+ Logger.debug("�berpr�fe Parameter oa");
// if non parameter is given return true
- if (oa == null) {
+ if (StringUtils.isEmpty(oa)) {
Logger.debug("Parameter oa ist null");
return true;
}
@@ -407,16 +438,16 @@ public class ParamValidatorUtils {
// check if template url starts with http or https
if (oa.startsWith("http") || oa.startsWith("https")) {
new URL(oa);
- Logger.debug("Parameter oa erfolgreich überprüft");
+ Logger.debug("Parameter oa erfolgreich �berpr�ft");
return true;
}
else {
- Logger.error("Fehler Überprüfung Parameter oa. oa beginnt nicht mit http or https");
+ Logger.error("Fehler �berpr�fung Parameter oa. oa beginnt nicht mit http or https");
return false;
}
} catch (MalformedURLException e) {
- Logger.error("Fehler Überprüfung Parameter oa", e);
+ Logger.error("Fehler �berpr�fung Parameter oa", e);
return false;
}
@@ -429,10 +460,10 @@ public class ParamValidatorUtils {
*/
public static boolean isValidSignUrl(String signurl) {
- Logger.debug("Überprüfe Parameter signurl");
+ Logger.debug("�berpr�fe Parameter signurl");
// if non parameter is given return true
- if (signurl == null) {
+ if (StringUtils.isEmpty(signurl)) {
Logger.debug("Parameter signurl ist null");
return true;
}
@@ -443,16 +474,16 @@ public class ParamValidatorUtils {
// check if signurl starts with http or https
if (signurl.startsWith("http") || signurl.startsWith("https")) {
new URL(signurl);
- Logger.debug("Parameter signurl erfolgreich überprüft");
+ Logger.debug("Parameter signurl erfolgreich �berpr�ft");
return true;
}
else {
- Logger.error("Fehler Überprüfung Parameter signurl. signurl beginnt nicht mit http or https");
+ Logger.error("Fehler �berpr�fung Parameter signurl. signurl beginnt nicht mit http or https");
return false;
}
} catch (MalformedURLException e) {
- Logger.error("Fehler Überprüfung Parameter signurl", e);
+ Logger.error("Fehler �berpr�fung Parameter signurl", e);
return false;
}
@@ -508,27 +539,27 @@ public class ParamValidatorUtils {
public static boolean isValidXMLDocument(String document) {
- if (document == null)
+ if (StringUtils.isEmpty(document))
return false;
- Logger.debug("Überprüfe Parameter XMLDocument");
+ Logger.debug("Überprüfe Parameter XMLDocument");
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(document));
builder.parse(is);
- Logger.debug("Parameter XMLDocument erfolgreich überprüft");
+ Logger.debug("Parameter XMLDocument erfolgreich überprüft");
return true;
} catch (ParserConfigurationException e) {
- Logger.error("Fehler Überprüfung Parameter XMLDocument", e);
+ Logger.error("Fehler Überprüfung Parameter XMLDocument", e);
return false;
} catch (SAXException e) {
- Logger.error("Fehler Überprüfung Parameter XMLDocument", e);
+ Logger.error("Fehler Überprüfung Parameter XMLDocument", e);
return false;
} catch (IOException e) {
- Logger.error("Fehler Überprüfung Parameter XMLDocument", e);
+ Logger.error("Fehler Überprüfung Parameter XMLDocument", e);
return false;
}