diff options
| author | Thomas Lenz <tlenz@iaik.tugraz.at> | 2015-09-14 13:29:32 +0200 | 
|---|---|---|
| committer | Thomas Lenz <tlenz@iaik.tugraz.at> | 2015-09-14 13:29:32 +0200 | 
| commit | 76bae60e9bda1acb7ee0e3d45ab187749d16bf82 (patch) | |
| tree | ba22e87aeee1330e70e702dcfb4612fd951e6c7a /id/server/modules | |
| parent | 1131cdf040e608c3f79dd8987ec3b8444fc9bf0d (diff) | |
| download | moa-id-spss-76bae60e9bda1acb7ee0e3d45ab187749d16bf82.tar.gz moa-id-spss-76bae60e9bda1acb7ee0e3d45ab187749d16bf82.tar.bz2 moa-id-spss-76bae60e9bda1acb7ee0e3d45ab187749d16bf82.zip | |
move citizen-card authentication and validation (Security-layer communication) to discrete module
Diffstat (limited to 'id/server/modules')
70 files changed, 11624 insertions, 16 deletions
| diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/pom.xml b/id/server/modules/moa-id-modul-citizencard_authentication/pom.xml new file mode 100644 index 000000000..32a3d0c28 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/pom.xml @@ -0,0 +1,25 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +  <modelVersion>4.0.0</modelVersion> +  <parent> +    <groupId>MOA.id.server.modules</groupId> +    <artifactId>moa-id-modules</artifactId> +    <version>${moa-id-version}</version> +  </parent> +  <artifactId>moa-id-modul-citizencard_authentication</artifactId> +   +  <packaging>jar</packaging> +	<name>MOA ID-Module Citizen-Card Authentication</name> + +	<properties> +		<repositoryPath>${basedir}/../../../../repository</repositoryPath> +	</properties> +   +  <dependencies> +  	<dependency> +  		<groupId>MOA.id.server</groupId> +  		<artifactId>moa-id-lib</artifactId> +  		<scope>test</scope> +  	</dependency> +  </dependencies> +     +</project>
\ No newline at end of file diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java new file mode 100644 index 000000000..0850bb676 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java @@ -0,0 +1,1371 @@ +package at.gv.egovernment.moa.id.auth; + + +import iaik.asn1.ObjectID; +import iaik.x509.X509Certificate; +import iaik.x509.X509ExtensionInitException; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.Principal; +import java.security.cert.CertificateException; +import java.util.Calendar; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import javax.servlet.http.HttpServletRequest; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.xpath.XPathAPI; +import org.opensaml.xml.util.Base64; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; +import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger; +import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.auth.builder.AuthenticationBlockAssertionBuilder; +import at.gv.egovernment.moa.id.auth.builder.BPKBuilder; +import at.gv.egovernment.moa.id.auth.builder.CreateXMLSignatureRequestBuilder; +import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder; +import at.gv.egovernment.moa.id.auth.builder.GetIdentityLinkFormBuilder; +import at.gv.egovernment.moa.id.auth.builder.InfoboxReadRequestBuilder; +import at.gv.egovernment.moa.id.auth.builder.VerifyXMLSignatureRequestBuilder; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import at.gv.egovernment.moa.id.auth.data.CreateXMLSignatureResponse; +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.data.VerifyXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; +import at.gv.egovernment.moa.id.auth.exception.BKUException; +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.id.auth.exception.ServiceException; +import at.gv.egovernment.moa.id.auth.exception.ValidateException; +import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; +import at.gv.egovernment.moa.id.auth.invoke.SignatureVerificationInvoker; +import at.gv.egovernment.moa.id.auth.parser.CreateXMLSignatureResponseParser; +import at.gv.egovernment.moa.id.auth.parser.InfoboxReadResponseParser; +import at.gv.egovernment.moa.id.auth.parser.VerifyXMLSignatureResponseParser; +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.VerifyXMLSignatureResponseValidator; +import at.gv.egovernment.moa.id.auth.validator.parep.ParepUtils; +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.auth.AuthConfiguration; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.data.MISMandate; +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; +import at.gv.egovernment.moa.id.util.XMLUtil; +import at.gv.egovernment.moa.logging.LogMsg; +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.FileUtils; +import at.gv.egovernment.moa.util.MiscUtil; +import at.gv.egovernment.moa.util.StringUtils; + +/** + * API for MOA ID Authentication Service.<br> {@link AuthenticationSession} is + * stored in a session store and retrieved by giving the session ID. + * + * @author Paul Ivancsics + * @version $Id: AuthenticationServer.java 1273 2012-02-27 14:50:18Z kstranacher + *          $ + */ +public class AuthenticationServer extends BaseAuthenticationServer { + +	/** +	 * single instance +	 */ +	private static AuthenticationServer instance; + +	/** +	 * Returns the single instance of <code>AuthenticationServer</code>. +	 * +	 * @return the single instance of <code>AuthenticationServer</code> +	 */ +	public static AuthenticationServer getInstance() { +		if (instance == null) +			instance = new AuthenticationServer(); +		return instance; +	} + +	/** +	 * Constructor for AuthenticationServer. +	 */ +	public AuthenticationServer() { +		super(); +	} + + +	/** +	 * Processes the beginning of an authentication session. +	 * <ul> +	 * <li>Starts an authentication session</li> +	 * <li>Creates an <code><InfoboxReadRequest></code></li> +	 * <li>Creates an HTML form for querying the identity link from the security +	 * layer implementation. <br> +	 * Form parameters include +	 * <ul> +	 * <li>the <code><InfoboxReadRequest></code></li> +	 * <li>the data URL where the security layer implementation sends it +	 * response to</li> +	 * </ul> +	 * </ul> +	 * +	 * @param authURL            URL of the servlet to be used as data URL +	 * @param target             "Geschäftsbereich" of the online application requested +	 * @param targetFriendlyName Friendly name of the target if the target is configured via +	 *                           configuration +	 * @param oaURL              online application URL requested +	 * @param bkuURL             URL of the "Bürgerkartenumgebung" to be used; may be +	 *                           <code>null</code>; in this case, the default location will be +	 *                           used +	 * @param useMandate         Indicates if mandate is used or not +	 * @param templateURL        URL providing an HTML template for the HTML form generated +	 * @param templateMandteURL  URL providing an HTML template for the HTML form generated +	 *                           (for signing in mandates mode) +	 * @param req                determines the protocol used +	 * @param sourceID +	 * @return HTML form +	 * @throws AuthenticationException +	 * @see GetIdentityLinkFormBuilder +	 * @see InfoboxReadRequestBuilder +	 */ +	public String startAuthentication(AuthenticationSession session, HttpServletRequest req) throws WrongParametersException, +	AuthenticationException, ConfigurationException, BuildException { + +		if (session == null) { +			throw new AuthenticationException("auth.18", new Object[]{}); +		} + +		//load OnlineApplication configuration +		OAAuthParameter oaParam = +				AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(session.getPublicOAURLPrefix()); +		if (oaParam == null) +			throw new AuthenticationException("auth.00", new Object[]{session.getPublicOAURLPrefix()}); + +		//load Template +		String template = null; +		if (session.getTemplateURL() != null) { +			try { + +				template = new String(FileUtils.readURL(session.getTemplateURL())); +			} catch (IOException ex) { +				throw new AuthenticationException("auth.03", new Object[]{ +						session.getTemplateURL(), ex.toString()}, ex); +			} +		} + +		String infoboxReadRequest = ""; + +		String domainIdentifier = AuthConfigurationProviderFactory.getInstance().getSSOTagetIdentifier().trim(); +		if (MiscUtil.isEmpty(domainIdentifier) && session.isSsoRequested()) { +			//do not use SSO if no Target is set +			Logger.warn("NO SSO-Target found in configuration. Single Sign-On is deaktivated!"); +			session.setSsoRequested(false); + +		} + +		if (session.isSsoRequested()) { +			Logger.info("SSO Login requested"); +			//load identityLink with SSO Target +			boolean isbuisness = false; + +			if (domainIdentifier.startsWith(PREFIX_WPBK)) { + +				isbuisness = true; + +			} else { +				isbuisness = false; + +			} + +			//build ReadInfobox request +			infoboxReadRequest = new InfoboxReadRequestBuilder().build( +					isbuisness, domainIdentifier); + +		} else { +			Logger.info("Non-SSO Login requested"); +			//build ReadInfobox request +			infoboxReadRequest = new InfoboxReadRequestBuilder().build( +					oaParam.getBusinessService(), oaParam +					.getIdentityLinkDomainIdentifier()); + +		} + + +		String dataURL = new DataURLBuilder().buildDataURL( +				session.getAuthURL(), REQ_VERIFY_IDENTITY_LINK, session +				.getSessionID()); + +		//removed in MOAID 2.0 +		String pushInfobox = ""; + +		//		VerifyInfoboxParameters verifyInfoboxParameters = oaParam +		//				.getVerifyInfoboxParameters(); +		//		if (verifyInfoboxParameters != null) { +		//			pushInfobox = verifyInfoboxParameters.getPushInfobox(); +		//			session.setPushInfobox(pushInfobox); +		//		} + +		//build CertInfo request +		//removed in MOA-ID 2.0 +		//		String certInfoRequest = new CertInfoVerifyXMLSignatureRequestBuilder() +		//				.build(); +		//		String certInfoDataURL = new DataURLBuilder() +		//				.buildDataURL(session.getAuthURL(), REQ_START_AUTHENTICATION, +		//						session.getSessionID()); + +		//get Applet Parameters +		String appletwidth = req.getParameter(PARAM_APPLET_WIDTH); +		String appletheigth = req.getParameter(PARAM_APPLET_HEIGTH); +		appletheigth = StringEscapeUtils.escapeHtml(appletheigth); +		appletwidth = StringEscapeUtils.escapeHtml(appletwidth); +		 +		//TODO: cleanup before MOA-ID 2.1 release +		try { +			String htmlForm = new GetIdentityLinkFormBuilder().build(template, +					session.getBkuURL(), infoboxReadRequest, dataURL, null, +					null, pushInfobox, oaParam, appletheigth, appletwidth); + +			return htmlForm; + +		} catch (BuildException e) { +			throw new BuildException("builder.07", null, e); + +		}      +	} + +	/** +	 * Processes an <code><InfoboxReadResponse></code> sent by the security layer implementation.<br> +	 * <ul> +	 * <li>Validates given <code><InfoboxReadResponse></code></li> +	 * <li>Parses identity link enclosed in <code><InfoboxReadResponse></code></li> +	 * <li>Verifies identity link by calling the MOA SP component</li> +	 * <li>Checks certificate authority of identity link</li> +	 * <li>Stores identity link in the session</li> +	 * <li>Verifies all additional infoboxes returned from the BKU</li> +	 * <li>Creates an authentication block to be signed by the user</li> +	 * <li>Creates and returns a <code><CreateXMLSignatureRequest></code> containg the authentication block, meant +	 * to be returned to the security layer implementation</li> +	 * </ul> +	 *  +	 * @param sessionID +	 *            ID of associated authentication session data +	 * @param infoboxReadResponseParameters +	 *            The parameters from the response returned from the BKU including the +	 *            <code><InfoboxReadResponse></code> +	 * @return String "found!" in case the identity link could be retrieved and successfully validated, {@code null} in +	 *         case the identity link could not be retrieved (indicates that the card did not contain an identity link +	 *         which might indicate a foreign identity). Note that failing to parse or failing to validate the identity +	 *         link results in an Exception being thrown. +	 * @throws BKUException +	 */ +	public String verifyIdentityLink(IRequest pendingReq, AuthenticationSession session, +			Map<String, String> infoboxReadResponseParameters) throws AuthenticationException, +			BuildException, ParseException, ConfigurationException, +			ValidateException, ServiceException, BKUException { + +		if (session == null) +			throw new AuthenticationException("auth.10", new Object[]{ +					REQ_VERIFY_IDENTITY_LINK, PARAM_SESSIONID}); + +		String xmlInfoboxReadResponse = (String) infoboxReadResponseParameters +				.get(PARAM_XMLRESPONSE); + +		if (isEmpty(xmlInfoboxReadResponse)) +			throw new AuthenticationException("auth.10", new Object[]{ +					REQ_VERIFY_IDENTITY_LINK, PARAM_XMLRESPONSE}); + +		AuthConfiguration authConf = AuthConfigurationProviderFactory +				.getInstance(); + +		// check if an identity link was found +		// Errorcode 2911 von Trustdesk BKU (nicht spezifikationskonform +		// (SL1.2)) +		// CharSequence se = "ErrorCode>2911".substring(0); +		// boolean b = xmlInfoboxReadResponse.contains(se); +		String se = "ErrorCode>2911"; +		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 auslaendische eID."); +			return null; +		} +		// spezifikationsgemaess (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 auslaendische eID."); +			return null; +		} + +		// parses the <InfoboxReadResponse> +		IdentityLink identityLink = new InfoboxReadResponseParser( +				xmlInfoboxReadResponse).parseIdentityLink(); +		// validates the identity link +		IdentityLinkValidator.getInstance().validate(identityLink); +		// builds a <VerifyXMLSignatureRequest> for a call of MOA-SP +		Element domVerifyXMLSignatureRequest = new VerifyXMLSignatureRequestBuilder() +		.build(identityLink, authConf +				.getMoaSpIdentityLinkTrustProfileID(pendingReq.getOnlineApplicationConfiguration().isUseIDLTestTrustStore())); + +		// invokes the call +		Element domVerifyXMLSignatureResponse = new SignatureVerificationInvoker() +		.verifyXMLSignature(domVerifyXMLSignatureRequest); +		// parses the <VerifyXMLSignatureResponse> +		VerifyXMLSignatureResponse verifyXMLSignatureResponse = new VerifyXMLSignatureResponseParser( +				domVerifyXMLSignatureResponse).parseData(); + +		OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance() +				.getOnlineApplicationParameter(session.getPublicOAURLPrefix()); + +		// validates the <VerifyXMLSignatureResponse> +		VerifyXMLSignatureResponseValidator.getInstance().validate( +				verifyXMLSignatureResponse, +				authConf.getIdentityLinkX509SubjectNames(), +				VerifyXMLSignatureResponseValidator.CHECK_IDENTITY_LINK, +				oaParam); + +		session.setIdentityLink(identityLink); +		// now validate the extended infoboxes +		 +		//Removed in MOA-ID 2.0 +		//verifyInfoboxes(session, infoboxReadResponseParameters, false); + +		MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),  +				pendingReq, MOAIDEventConstants.AUTHPROCESS_IDL_VALIDATED); +		 +		return "found!"; +	} + +	/** +	 * Processes an <code><InfoboxReadResponse></code> sent by the +	 * security layer implementation.<br> +	 * <ul> +	 * <li>Validates given <code><InfoboxReadResponse></code></li> +	 * <li>Parses identity link enclosed in +	 * <code><InfoboxReadResponse></code></li> +	 * <li>Verifies identity link by calling the MOA SP component</li> +	 * <li>Checks certificate authority of identity link</li> +	 * <li>Stores identity link in the session</li> +	 * <li>Verifies all additional infoboxes returned from the BKU</li> +	 * <li>Creates an authentication block to be signed by the user</li> +	 * <li>Creates and returns a <code><CreateXMLSignatureRequest></code> +	 * containg the authentication block, meant to be returned to the security +	 * layer implementation</li> +	 * </ul> +	 * +	 * @param sessionID                     ID of associated authentication session data +	 * @param infoboxReadResponseParameters The parameters from the response returned from the BKU +	 *                                      including the <code><InfoboxReadResponse></code> +	 * @return String representation of the +	 * <code><CreateXMLSignatureRequest></code> +	 */ +	public String verifyCertificate(AuthenticationSession session, +			X509Certificate certificate) throws AuthenticationException, +			BuildException, ParseException, ConfigurationException, +			ValidateException, ServiceException, MOAIDException { + +		if (session == null) +			throw new AuthenticationException("auth.10", new Object[]{ +					REQ_VERIFY_CERTIFICATE, PARAM_SESSIONID}); + +		// check if person is a Organwalter +		// if true - don't show bPK in AUTH Block +		try { +			for (ObjectID OWid : MOAIDAuthConstants.OW_LIST) { +				if (certificate.getExtension(OWid) != null) { +					session.setOW(true); +				} + +			} + +		} catch (X509ExtensionInitException e) { +			Logger.warn("Certificate extension is not readable."); +			session.setOW(false); +		} + +		AuthConfiguration authConf = AuthConfigurationProviderFactory +				.getInstance(); + +		OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance() +				.getOnlineApplicationParameter(session.getPublicOAURLPrefix()); + +		String returnvalue = getCreateXMLSignatureRequestAuthBlockOrRedirect(session, +				authConf, oaParam); + +		return returnvalue; +	} + +	/** +	 * Processes an <code>Mandate</code> sent by the MIS.<br> +	 * <ul> +	 * <li>Validates given <code>Mandate</code></li> +	 * <li>Verifies Mandate by calling the MOA SP component</li> +	 * <li>Creates an authentication block to be signed by the user</li> +	 * <li>Creates and returns a <code><CreateXMLSignatureRequest></code> +	 * containg the authentication block, meant to be returned to the security +	 * layer implementation</li> +	 * </ul> +	 * @param pendingReq  +	 * +	 * @param sessionID                     ID of associated authentication session data +	 * @param infoboxReadResponseParameters The parameters from the response returned from the BKU +	 *                                      including the <code><InfoboxReadResponse></code> +	 * @return String representation of the +	 * <code><CreateXMLSignatureRequest></code> +	 */ +	public void verifyMandate(AuthenticationSession session, MISMandate mandate) +			throws AuthenticationException, BuildException, ParseException, +			ConfigurationException, ValidateException, ServiceException { + +		if (session == null) +			throw new AuthenticationException("auth.10", new Object[]{ +					GET_MIS_SESSIONID, PARAM_SESSIONID}); + +		OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance() +				.getOnlineApplicationParameter(session.getPublicOAURLPrefix()); + +		try { +			// sets the extended SAML attributes for OID (Organwalter) +			setExtendedSAMLAttributeForMandatesOID(session, mandate, oaParam +					.getBusinessService()); + +			validateExtendedSAMLAttributeForMandates(session, mandate, oaParam.getBusinessService()); + + +		} catch (SAXException e) { +			throw new AuthenticationException("auth.15", +					new Object[]{GET_MIS_SESSIONID}, e); +		} catch (IOException e) { +			throw new AuthenticationException("auth.15", +					new Object[]{GET_MIS_SESSIONID}, e); +		} catch (ParserConfigurationException e) { +			throw new AuthenticationException("auth.15", +					new Object[]{GET_MIS_SESSIONID}, e); +		} catch (TransformerException e) { +			throw new AuthenticationException("auth.15", +					new Object[]{GET_MIS_SESSIONID}, e); +		} + +	} + +	/** +	 * @param session +	 * @param authConf +	 * @param oaParam +	 * @return +	 * @throws ConfigurationException +	 * @throws BuildException +	 * @throws ValidateException +	 */ +	public String getCreateXMLSignatureRequestAuthBlockOrRedirect( +			AuthenticationSession session, AuthConfiguration authConf, +			OAAuthParameter oaParam) throws ConfigurationException, +			BuildException, ValidateException { + +		//        // check for intermediate processing of the infoboxes +		//        if (session.isValidatorInputPending()) +		//            return "Redirect to Input Processor"; + +		if (authConf == null) +			authConf = AuthConfigurationProviderFactory.getInstance(); +		if (oaParam == null) +			oaParam = AuthConfigurationProviderFactory.getInstance() +			.getOnlineApplicationParameter( +					session.getPublicOAURLPrefix()); + +		// builds the AUTH-block +		String authBlock = buildAuthenticationBlock(session, oaParam); + +		// builds the <CreateXMLSignatureRequest> +		List<String> transformsInfos = authConf.getTransformsInfos(); + +		String createXMLSignatureRequest = new CreateXMLSignatureRequestBuilder() +		.build(authBlock, oaParam.getKeyBoxIdentifier(), +				transformsInfos); +		return createXMLSignatureRequest; +	} + +	/** +	 * Returns an CreateXMLSignatureRequest for signing the ERnP statement.<br> +	 * <ul> +	 * <li>Creates an CreateXMLSignatureRequest to be signed by the user</li> +	 * </ul> +	 * +	 * @param sessionID ID of associated authentication session data +	 * @param cert      The certificate from the user +	 * @return String representation of the +	 * <code><CreateXMLSignatureRequest></code> +	 */ +	public String createXMLSignatureRequestForeignID(AuthenticationSession session, +			X509Certificate cert) throws AuthenticationException, +			BuildException, ParseException, ConfigurationException, +			ValidateException, ServiceException { + +		if (session == null) +			throw new AuthenticationException("auth.10", new Object[]{ +					REQ_VERIFY_CERTIFICATE, PARAM_SESSIONID}); + +		AuthConfiguration authConf = AuthConfigurationProviderFactory +				.getInstance(); + +		OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance() +				.getOnlineApplicationParameter(session.getPublicOAURLPrefix()); + +		return getCreateXMLSignatureRequestForeigID(session, authConf, oaParam, +				cert); +	} + +	public String getCreateXMLSignatureRequestForeigID( +			AuthenticationSession session, AuthConfiguration authConf, +			OAAuthParameter oaParam, X509Certificate cert) +					throws ConfigurationException { + +		//        // check for intermediate processing of the infoboxes +		//        if (session.isValidatorInputPending()) +		//            return "Redirect to Input Processor"; + +		if (authConf == null) +			authConf = AuthConfigurationProviderFactory.getInstance(); +		if (oaParam == null) +			oaParam = AuthConfigurationProviderFactory.getInstance() +			.getOnlineApplicationParameter( +					session.getPublicOAURLPrefix()); + +		Principal subject = cert.getSubjectDN(); + +		String createXMLSignatureRequest = new CreateXMLSignatureRequestBuilder() +		.buildForeignID(subject.toString(), oaParam, session); +		return createXMLSignatureRequest; +	} + +//	/** +//	 * Processes an <code><CreateXMLSignatureResponse></code> sent by the +//	 * security layer implementation.<br> +//	 * <ul> +//	 * <li>Validates given <code><CreateXMLSignatureResponse></code></li> +//	 * <li>Parses response enclosed in +//	 * <code><CreateXMLSignatureResponse></code></li> +//	 * <li>Verifies signature by calling the MOA SP component</li> +//	 * <li>Returns the signer certificate</li> +//	 * </ul> +//	 * +//	 * @param sessionID                            ID of associated authentication session data +//	 * @param createXMLSignatureResponseParameters The parameters from the response returned from the BKU +//	 *                                             including the <code><CreateXMLSignatureResponse></code> +//	 * @throws BKUException +//	 */ +//	public X509Certificate verifyXMLSignature(String sessionID, +//			Map<String, String> createXMLSignatureResponseParameters) +//					throws AuthenticationException, BuildException, ParseException, +//					ConfigurationException, ValidateException, ServiceException, BKUException { +// +//		if (isEmpty(sessionID)) +//			throw new AuthenticationException("auth.10", new Object[]{ +//					REQ_GET_FOREIGN_ID, PARAM_SESSIONID}); +// +//		String xmlCreateXMLSignatureResponse = (String) createXMLSignatureResponseParameters +//				.get(PARAM_XMLRESPONSE); +// +//		if (isEmpty(xmlCreateXMLSignatureResponse)) +//			throw new AuthenticationException("auth.10", new Object[]{ +//					REQ_GET_FOREIGN_ID, PARAM_XMLRESPONSE}); +// +//		AuthConfiguration authConf = AuthConfigurationProviderFactory +//				.getInstance(); +// +//		// parses the <CreateXMLSignatureResponse> +//		CreateXMLSignatureResponseParser p = new CreateXMLSignatureResponseParser( +//				xmlCreateXMLSignatureResponse); +//		CreateXMLSignatureResponse createXMLSignatureResponse = p +//				.parseResponseDsig(); +// +//		// builds a <VerifyXMLSignatureRequest> for a call of MOA-SP +//		Element domVerifyXMLSignatureRequest = new VerifyXMLSignatureRequestBuilder() +//		.buildDsig(createXMLSignatureResponse, authConf +//				.getMoaSpAuthBlockTrustProfileID()); +// +//		// invokes the call +//		Element domVerifyXMLSignatureResponse = new SignatureVerificationInvoker() +//		.verifyXMLSignature(domVerifyXMLSignatureRequest); +// +//		// parses the <VerifyXMLSignatureResponse> +//		VerifyXMLSignatureResponse verifyXMLSignatureResponse = new VerifyXMLSignatureResponseParser( +//				domVerifyXMLSignatureResponse).parseData(); +// +//		return verifyXMLSignatureResponse.getX509certificate(); +// +//	} + +	/** +	 * Processes an <code><CreateXMLSignatureResponse></code> sent by the +	 * security layer implementation.<br> +	 * <ul> +	 * <li>Validates given <code><CreateXMLSignatureResponse></code></li> +	 * <li>Parses response enclosed in +	 * <code><CreateXMLSignatureResponse></code></li> +	 * <li>Verifies signature by calling the MOA SP component</li> +	 * <li>Returns the signer certificate</li> +	 * </ul> +	 * @param pendingReq  +	 * +	 * @param sessionID                     ID of associated authentication session data +	 * @param readInfoboxResponseParameters The parameters from the response returned from the BKU +	 *                                      including the <code><ReadInfoboxResponse></code> +	 * @throws BKUException +	 */ +	public X509Certificate getCertificate(IRequest pendingReq, String sessionID, +			Map<String, String> readInfoboxResponseParameters) throws AuthenticationException, +			BuildException, ParseException, ConfigurationException, +			ValidateException, ServiceException, BKUException { + +		if (isEmpty(sessionID)) +			throw new AuthenticationException("auth.10", new Object[]{ +					REQ_VERIFY_CERTIFICATE, PARAM_SESSIONID}); + +		String xmlReadInfoboxResponse = (String) readInfoboxResponseParameters +				.get(PARAM_XMLRESPONSE); + +		if (isEmpty(xmlReadInfoboxResponse)) +			throw new AuthenticationException("auth.10", new Object[]{ +					REQ_VERIFY_CERTIFICATE, PARAM_XMLRESPONSE}); + +		// parses the <CreateXMLSignatureResponse> +		InfoboxReadResponseParser p = new InfoboxReadResponseParser( +				xmlReadInfoboxResponse); +		X509Certificate cert = p.parseCertificate(); + +		MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),  +				pendingReq, MOAIDEventConstants.AUTHPROCESS_CERTIFICATE_VALIDATED); +		 +		return cert; + +	} + +	/** +	 * Builds an authentication block <code><saml:Assertion></code> from +	 * given session data. +	 * +	 * @param session authentication session +	 * @return <code><saml:Assertion></code> as a String +	 * @throws BuildException If an error occurs on serializing an extended SAML attribute +	 *                        to be appended to the AUTH-Block. +	 */ +	private String buildAuthenticationBlock(AuthenticationSession session, +			OAAuthParameter oaParam) throws BuildException { + +		IdentityLink identityLink = session.getIdentityLink(); +		String issuer = identityLink.getName(); +		String gebDat = identityLink.getDateOfBirth(); + +		String identificationValue = null; +		String identificationType = null; + +		//set empty AuthBlock BPK in case of OW or SSO or bpk is not requested +		if (session.isOW() || session.isSsoRequested() || oaParam.isRemovePBKFromAuthBlock()) { +			identificationType = ""; +			identificationValue = ""; + +		} else if (identityLink.getIdentificationType().equals(Constants.URN_PREFIX_BASEID)) { + +			if (oaParam.getBusinessService()) { + +				String bpkBase64 = new BPKBuilder().buildWBPK(identityLink +						.getIdentificationValue(), oaParam.getIdentityLinkDomainIdentifier()); +				identificationValue = bpkBase64; + +				if (oaParam.getIdentityLinkDomainIdentifier().startsWith(Constants.URN_PREFIX_WBPK + "+")) +					identificationType = oaParam.getIdentityLinkDomainIdentifier(); +				else +					identificationType = Constants.URN_PREFIX_WBPK + "+" + oaParam.getIdentityLinkDomainIdentifier(); + +			} else { +				String bpkBase64 = new BPKBuilder().buildBPK(identityLink +						.getIdentificationValue(), session.getTarget()); +				identificationValue = bpkBase64; +				identificationType = Constants.URN_PREFIX_CDID + "+" + session.getTarget(); +			} + + +		} else { +			identificationValue = identityLink.getIdentificationValue(); +			identificationType = identityLink.getIdentificationType(); + +		} + +		String issueInstant = DateTimeUtils.buildDateTimeUTC(Calendar +				.getInstance()); +		session.setIssueInstant(issueInstant); +		String authURL = session.getAuthURL(); +		String target = session.getTarget(); +		String targetFriendlyName = session.getTargetFriendlyName(); + +		// Bug #485 +		// (https://egovlabs.gv.at/tracker/index.php?func=detail&aid=485&group_id=6&atid=105) +		// String oaURL = session.getPublicOAURLPrefix(); + +		List<ExtendedSAMLAttribute> extendedSAMLAttributes = session.getExtendedSAMLAttributesAUTH(); + + +		if (session.isSsoRequested()) { +			String oaURL = new String(); +			try { +				oaURL = AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix(); + +				if (MiscUtil.isNotEmpty(oaURL)) +					oaURL = oaURL.replaceAll("&", "&"); + +			} catch (ConfigurationException e) { +			} +			String authBlock = new AuthenticationBlockAssertionBuilder() +			.buildAuthBlockSSO(issuer, issueInstant, authURL, target, +					targetFriendlyName, identificationValue, +					identificationType, oaURL, gebDat, +					extendedSAMLAttributes, session, oaParam); +			return authBlock; + +		} else { +			String oaURL = session.getPublicOAURLPrefix().replaceAll("&", "&"); +			String authBlock = new AuthenticationBlockAssertionBuilder() +			.buildAuthBlock(issuer, issueInstant, authURL, target, +					targetFriendlyName, identificationValue, +					identificationType, oaURL, gebDat, +					extendedSAMLAttributes, session, oaParam); +			return authBlock; +		} +	} + + +	/** +	 * Verifies the infoboxes (except of the identity link infobox) returned by +	 * the BKU by calling appropriate validator classes. +	 * +	 * @param session The actual authentication session. +	 * @param mandate The Mandate from the MIS +	 * @throws AuthenticationException +	 * @throws ConfigurationException +	 * @throws TransformerException +	 * @throws ParserConfigurationException +	 * @throws IOException +	 * @throws SAXException +	 */ +	private void validateExtendedSAMLAttributeForMandates( +			AuthenticationSession session, MISMandate mandate, +			boolean business) +					throws ValidateException, ConfigurationException, SAXException, +					IOException, ParserConfigurationException, TransformerException { + +		ExtendedSAMLAttribute[] extendedSAMLAttributes = addExtendedSamlAttributes( +				mandate, business, false); + +		int length = extendedSAMLAttributes.length; +		for (int i = 0; i < length; i++) { +			ExtendedSAMLAttribute samlAttribute = extendedSAMLAttributes[i]; + +			verifySAMLAttribute(samlAttribute, i, "MISService", +					"MISService"); + +		} +	} + +	/** +	 * Verifies the infoboxes (except of the identity link infobox) returned by +	 * the BKU by calling appropriate validator classes. +	 * +	 * @param session The actual authentication session. +	 * @param mandate The Mandate from the MIS +	 * @throws AuthenticationException +	 * @throws ConfigurationException +	 * @throws TransformerException +	 * @throws ParserConfigurationException +	 * @throws IOException +	 * @throws SAXException +	 */ +	private void setExtendedSAMLAttributeForMandatesOID( +			AuthenticationSession session, MISMandate mandate, boolean business) +					throws ValidateException, ConfigurationException, SAXException, +					IOException, ParserConfigurationException, TransformerException { + +		ExtendedSAMLAttribute[] extendedSamlAttributes = addExtendedSamlAttributesOID( +				mandate, business); + +		AddAdditionalSAMLAttributes(session, extendedSamlAttributes, +				"MISService", "MISService"); + +	} + +	/** +	 * Adds given SAML Attributes to the current session. They will be appended +	 * to the final SAML Assertion or the AUTH block. If the attributes are +	 * already in the list, they will be replaced. +	 * +	 * @param session                The current session +	 * @param extendedSAMLAttributes The SAML attributes to add +	 * @param identifier             The infobox identifier for debug purposes +	 * @param friendlyNam            The friendly name of the infobox for debug purposes +	 */ +	private static void AddAdditionalSAMLAttributes( +			AuthenticationSession session, +			ExtendedSAMLAttribute[] extendedSAMLAttributes, String identifier, +			String friendlyName) throws ValidateException { +		if (extendedSAMLAttributes == null) +			return; +		List<ExtendedSAMLAttribute> oaAttributes = session.getExtendedSAMLAttributesOA(); +		if (oaAttributes == null) +			oaAttributes = new Vector<ExtendedSAMLAttribute>(); +		List<ExtendedSAMLAttribute> authAttributes = session.getExtendedSAMLAttributesAUTH(); +		if (authAttributes == null) +			authAttributes = new Vector<ExtendedSAMLAttribute>(); +		int length = extendedSAMLAttributes.length; +		for (int i = 0; i < length; i++) { +			ExtendedSAMLAttribute samlAttribute = extendedSAMLAttributes[i]; + +			Object value = verifySAMLAttribute(samlAttribute, i, identifier, +					friendlyName); + +			if ((value instanceof String) || (value instanceof Element)) { +				switch (samlAttribute.getAddToAUTHBlock()) { +				case ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY: +					replaceExtendedSAMLAttribute(authAttributes, samlAttribute); +					break; +				case ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK: +					replaceExtendedSAMLAttribute(authAttributes, samlAttribute); +					replaceExtendedSAMLAttribute(oaAttributes, samlAttribute); +					break; +				case ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK: +					replaceExtendedSAMLAttribute(oaAttributes, samlAttribute); +					break; +				default: +					Logger +					.info("Invalid return value from method \"getAddToAUTHBlock()\" (" +							+ samlAttribute.getAddToAUTHBlock() +							+ ") in SAML attribute number " +							+ (i + 1) +							+ " for infobox " + identifier); +									throw new ValidateException("validator.47", new Object[]{ +											friendlyName, String.valueOf((i + 1))}); +				} +			} else { +				Logger +				.info("The type of SAML-Attribute number " +						+ (i + 1) +						+ " returned from " +						+ identifier +						+ "-infobox validator is not valid. Must be either \"java.Lang.String\"" +						+ " or \"org.w3c.dom.Element\""); +				throw new ValidateException("validator.46", new Object[]{ +						identifier, String.valueOf((i + 1))}); +			} +		} +		session.setExtendedSAMLAttributesAUTH(authAttributes); +		session.setExtendedSAMLAttributesOA(oaAttributes); +	} + +	/** +	 * Adds the AUTH block related SAML attributes to the validation result. +	 * This is needed always before the AUTH block is to be signed, because the +	 * name of the mandator has to be set +	 * +	 * @throws ParserConfigurationException +	 * @throws IOException +	 * @throws SAXException +	 * @throws TransformerException +	 */ + +	protected static ExtendedSAMLAttribute[] addExtendedSamlAttributes( +			MISMandate mandate, boolean business, boolean provideStammzahl) +					throws SAXException, IOException, ParserConfigurationException, +					TransformerException { +		Vector<ExtendedSAMLAttribute> extendedSamlAttributes = new Vector<ExtendedSAMLAttribute>(); + +		extendedSamlAttributes.clear(); + +		// Name +		Element domMandate = mandateToElement(mandate); +		Element nameSpaceNode = domMandate.getOwnerDocument().createElement( +				"NameSpaceNode"); +		nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.PD_POSTFIX, +				Constants.PD_NS_URI); +		nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.MANDATE_POSTFIX, +				SZRGWConstants.MANDATE_NS); + +		Element mandator = (Element) XPathAPI.selectSingleNode(domMandate, +				"//md:Mandate/md:Mandator", nameSpaceNode); + +		// Mandate +		extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl( +				EXT_SAML_MANDATE_RAW, domMandate, +				SZRGWConstants.MANDATE_NS, +				ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK)); + +		// (w)bpk +		String wbpk = ParepUtils.extractMandatorWbpk(mandator); +		if (!ParepUtils.isEmpty(wbpk)) { +			if (!ParepUtils.isPhysicalPerson(mandator)) { +				String idType = ParepUtils +						.extractMandatorIdentificationType(mandator); +				if (!ParepUtils.isEmpty(idType) +						&& idType.startsWith(Constants.URN_PREFIX_BASEID)) { +					extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl( +							EXT_SAML_MANDATE_CB_BASE_ID, +							ParepUtils.getRegisterString(idType) + ": " + wbpk, +							SZRGWConstants.MANDATE_NS, +							ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY)); +				} +			} else if (business) { +				extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl( +						EXT_SAML_MANDATE_WBPK, wbpk, +						SZRGWConstants.MANDATE_NS, +						ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY)); +			} +		} + +		ExtendedSAMLAttribute[] ret = new ExtendedSAMLAttribute[extendedSamlAttributes +		                                                        .size()]; +		extendedSamlAttributes.copyInto(ret); +		Logger.debug("ExtendedSAML Attributes: " + ret.length); +		return ret; + +	} + +	/** +	 * Adds the AUTH block related SAML attributes to the validation result. +	 * This is needed always before the AUTH block is to be signed, because the +	 * name of the mandator has to be set +	 * +	 * @throws ParserConfigurationException +	 * @throws IOException +	 * @throws SAXException +	 * @throws TransformerException +	 */ +	private static ExtendedSAMLAttribute[] addExtendedSamlAttributesOID( +			MISMandate mandate, boolean business) throws SAXException, +			IOException, ParserConfigurationException, TransformerException { + +		Vector<ExtendedSAMLAttribute> extendedSamlAttributes = new Vector<ExtendedSAMLAttribute>(); + +		extendedSamlAttributes.clear(); + +		// RepresentationType +		extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl( +				EXT_SAML_MANDATE_REPRESENTATIONTYPE, +				EXT_SAML_MANDATE_REPRESENTATIONTEXT, +				SZRGWConstants.MANDATE_NS, +				ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK)); + +		String oid = mandate.getProfRep(); + +		if (oid != null) { +			extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl( +					EXT_SAML_MANDATE_OID, oid, +					SZRGWConstants.MANDATE_NS, +					ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK)); +			String oidDescription = mandate.getTextualDescriptionOfOID(); +			extendedSamlAttributes.add(new ExtendedSAMLAttributeImpl( +					EXT_SAML_MANDATE_OIDTEXTUALDESCRIPTION, +					oidDescription, SZRGWConstants.MANDATE_NS, +					ExtendedSAMLAttribute.NOT_ADD_TO_AUTHBLOCK)); + +		} + +		ExtendedSAMLAttribute[] ret = new ExtendedSAMLAttribute[extendedSamlAttributes +		                                                        .size()]; +		extendedSamlAttributes.copyInto(ret); +		Logger.debug("ExtendedSAML Attributes: " + ret.length); +		return ret; + +	} + +	/** +	 * @param mandate +	 * @return +	 * @throws ParserConfigurationException +	 * @throws IOException +	 * @throws SAXException +	 */ +	private static Element mandateToElement(MISMandate mandate) +			throws SAXException, IOException, ParserConfigurationException { +		ByteArrayInputStream bais = new ByteArrayInputStream(mandate +				.getMandate()); +		Document doc = DOMUtils.parseDocumentSimple(bais); +		bais.close(); +		return doc.getDocumentElement(); +	} + +	protected static void replaceExtendedSAMLAttribute(List<ExtendedSAMLAttribute> attributes, +			ExtendedSAMLAttribute samlAttribute) { +		if (null == attributes) { +			attributes = new Vector<ExtendedSAMLAttribute>(); +		} else { +			String id = samlAttribute.getName(); +			int length = attributes.size(); +			for (int i = 0; i < length; i++) { +				ExtendedSAMLAttribute att = (ExtendedSAMLAttribute) attributes +						.get(i); +				if (id.equals(att.getName())) { +					// replace attribute +					attributes.set(i, samlAttribute); +					return; +				} +			} +			attributes.add(samlAttribute); +		} +	} + +	/** +	 * Processes a <code><CreateXMLSignatureResponse></code> sent by the +	 * security layer implementation.<br> +	 * <ul> +	 * <li>Validates given <code><CreateXMLSignatureResponse></code></li> +	 * <li>Parses <code><CreateXMLSignatureResponse></code> for error +	 * codes</li> +	 * <li>Parses authentication block enclosed in +	 * <code><CreateXMLSignatureResponse></code></li> +	 * <li>Verifies authentication block by calling the MOA SP component</li> +	 * <li>Creates authentication data</li> +	 * <li>Creates a corresponding SAML artifact</li> +	 * <li>Stores authentication data in the authentication data store indexed +	 * by the SAML artifact</li> +	 * <li>Deletes authentication session</li> +	 * <li><strike>Returns the SAML artifact, encoded BASE64</strike><br/>New id of the authenticated MOA session or {@code null} in case of mandate mode (???)</li> +	 * </ul> +	 * @param pendingReq  +	 * +	 * @param sessionID                         session ID of the running authentication session +	 * @param xmlCreateXMLSignatureReadResponse String representation of the +	 *                                          <code><CreateXMLSignatureResponse></code> +	 * @return <strike>SAML artifact needed for retrieving authentication data, encoded +	 * BASE64</strike><br/>New id of the authenticated MOA session or {@code null} in case of mandate mode (???) +	 * @throws BKUException +	 */ +	public void verifyAuthenticationBlock(IRequest pendingReq, AuthenticationSession session, +			String xmlCreateXMLSignatureReadResponse) +					throws AuthenticationException, BuildException, ParseException, +					ConfigurationException, ServiceException, ValidateException, BKUException { + +		if (session == null) +			throw new AuthenticationException("auth.10", new Object[]{ +					REQ_VERIFY_AUTH_BLOCK, PARAM_SESSIONID}); +		if (isEmpty(xmlCreateXMLSignatureReadResponse)) +			throw new AuthenticationException("auth.10", new Object[]{ +					REQ_VERIFY_AUTH_BLOCK, PARAM_XMLRESPONSE}); + +		AuthConfiguration authConf = AuthConfigurationProviderFactory +				.getInstance(); +		// parses <CreateXMLSignatureResponse> +		CreateXMLSignatureResponse csresp = new CreateXMLSignatureResponseParser( +				xmlCreateXMLSignatureReadResponse).parseResponse(); + +		try { +			String serializedAssertion = DOMUtils.serializeNode(csresp +					.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}); +		} +		// validates <CreateXMLSignatureResponse> +		if (session.isSsoRequested()) +			new CreateXMLSignatureResponseValidator().validateSSO(csresp, session); +		else +			new CreateXMLSignatureResponseValidator().validate(csresp, session); + +		// builds a <VerifyXMLSignatureRequest> for a MOA-SPSS call +		List<String> vtids = authConf.getMoaSpAuthBlockVerifyTransformsInfoIDs(); +		String tpid = authConf.getMoaSpAuthBlockTrustProfileID(pendingReq.getOnlineApplicationConfiguration().isUseAuthBlockTestTestStore()); +		Element domVsreq = new VerifyXMLSignatureRequestBuilder().build(csresp, +				vtids, tpid); +		// debug output + +		Element domVsresp = null; + +		//        try { +		// invokes the call +		domVsresp = new SignatureVerificationInvoker() +		.verifyXMLSignature(domVsreq); + +		// parses the <VerifyXMLSignatureResponse> +		VerifyXMLSignatureResponse vsresp = new VerifyXMLSignatureResponseParser( +				domVsresp).parseData(); + +		if (Logger.isTraceEnabled()) { +			if (domVsresp != null) { +				try { +					String xmlVerifyXMLSignatureResponse = DOMUtils +							.serializeNode(domVsresp, true); +					Logger.trace(new LogMsg(xmlCreateXMLSignatureReadResponse)); +					Logger.trace(new LogMsg(xmlVerifyXMLSignatureResponse)); +				} catch (Throwable t) { +					t.printStackTrace(); +					Logger.info(new LogMsg(t.getStackTrace())); +				} +			} +		} + +		OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance() +				.getOnlineApplicationParameter(session.getPublicOAURLPrefix()); + +		// validates the <VerifyXMLSignatureResponse> +		VerifyXMLSignatureResponseValidator.getInstance().validate(vsresp, +				null, VerifyXMLSignatureResponseValidator.CHECK_AUTH_BLOCK, +				oaParam); + +		// Compare AuthBlock Data with information stored in session, especially +		// date and time +		CreateXMLSignatureResponseValidator.getInstance().validateSigningDateTime(csresp); + +		try {         +			// compares the public keys from the identityLink with the AuthBlock +			VerifyXMLSignatureResponseValidator.getInstance().validateCertificate( +					vsresp, session.getIdentityLink()); + +		} catch ( ValidateException e) { +			Logger.error("Signature verification error. ", e); +			Logger.error("Signed Data: " + session.getAuthBlock()); +			try {        		 +				Logger.error("VerifyRequest: " + DOMUtils.serializeNode(domVsreq)); +				Logger.error("VerifyResponse: " + DOMUtils.serializeNode(domVsresp));				 +			} catch (TransformerException e1) { +				e1.printStackTrace(); + +			} catch (IOException e1) { +				e1.printStackTrace(); + +			} + +			throw e;  +		}        	 +		 +		session.setXMLVerifySignatureResponse(vsresp); +		session.setSignerCertificate(vsresp.getX509certificate()); +		vsresp.setX509certificate(null); +		session.setForeigner(false); + +		//set QAA Level four in case of card authentifcation +		session.setQAALevel(PVPConstants.STORK_QAA_1_4); +		 +		MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),  +				pendingReq, MOAIDEventConstants.AUTHPROCESS_AUTHBLOCK_VALIDATED); +		 +		MOAReversionLogger.getInstance().logPersonalInformationEvent(pendingReq, session.getIdentityLink()  +				); +	} + +	/** +	 * Processes a <code><CreateXMLSignatureResponse></code> sent by the +	 * security layer implementation.<br> +	 * <ul> +	 * <li>Validates given <code><CreateXMLSignatureResponse></code></li> +	 * <li>Parses <code><CreateXMLSignatureResponse></code> for error +	 * codes</li> +	 * <li>Parses authentication block enclosed in +	 * <code><CreateXMLSignatureResponse></code></li> +	 * <li>Verifies authentication block by calling the MOA SP component</li> +	 * <li>Creates authentication data</li> +	 * <li>Creates a corresponding SAML artifact</li> +	 * <li>Stores authentication data in the authentication data store indexed +	 * by the SAML artifact</li> +	 * <li>Deletes authentication session</li> +	 * <li>Returns the SAML artifact, encoded BASE64</li> +	 * </ul> +	 * +	 * @param sessionID                         session ID of the running authentication session +	 * @param xmlCreateXMLSignatureReadResponse String representation of the +	 *                                          <code><CreateXMLSignatureResponse></code> +	 * @return SAML artifact needed for retrieving authentication data, encoded +	 * BASE64 +	 */ + +	protected Element createIdentificationBPK(Element mandatePerson, +			String baseid, String target) throws BuildException { +		Element identificationBpK = mandatePerson.getOwnerDocument() +				.createElementNS(Constants.PD_NS_URI, "Identification"); +		Element valueBpK = mandatePerson.getOwnerDocument().createElementNS( +				Constants.PD_NS_URI, "Value"); + +		String bpkBase64 = new BPKBuilder().buildBPK(baseid, target); +		valueBpK.appendChild(mandatePerson.getOwnerDocument().createTextNode( +				bpkBase64)); +		Element typeBpK = mandatePerson.getOwnerDocument().createElementNS( +				Constants.PD_NS_URI, "Type"); +		typeBpK.appendChild(mandatePerson.getOwnerDocument().createTextNode( +				"urn:publicid:gv.at:cdid+bpk")); +		identificationBpK.appendChild(valueBpK); +		identificationBpK.appendChild(typeBpK); + +		return identificationBpK; + +	} + +	protected String getBaseId(Element mandatePerson) +			throws TransformerException, IOException { +		NodeList list = mandatePerson.getElementsByTagNameNS( +				Constants.PD_NS_URI, "Identification"); +		for (int i = 0; i < list.getLength(); i++) { +			Element identification = (Element) list.item(i); +			Element type = (Element) identification.getElementsByTagNameNS( +					Constants.PD_NS_URI, "Type").item(0); +			if (type.getTextContent().compareToIgnoreCase( +					"urn:publicid:gv.at:baseid") == 0) { +				Element value = (Element) identification +						.getElementsByTagNameNS(Constants.PD_NS_URI, "Value") +						.item(0); +				return value.getTextContent(); +			} +		} +		return null; + +	} + +	/** +	 * Gets the foreign authentication data.<br> +	 * <ul> +	 * <li><strong>Creates authentication data</strong></li> +	 * <li>Creates a corresponding SAML artifact</li> +	 * <li>Stores authentication data in the authentication data store indexed +	 * by the SAML artifact</li> +	 * <li>Deletes authentication session</li> +	 * <li><strike>Returns the SAML artifact, encoded BASE64</strike></li> +	 * </ul> +	 * +	 * @param sessionID session ID of the running authentication session +	 * @return String "new Session" +	 */ +	public void getForeignAuthenticationData(AuthenticationSession session) +			throws AuthenticationException, BuildException, ParseException, +			ConfigurationException, ServiceException, ValidateException { +		 +		if (session == null) +			throw new AuthenticationException("auth.10", new Object[]{ +					REQ_VERIFY_AUTH_BLOCK, PARAM_SESSIONID}); +		VerifyXMLSignatureResponse vsresp = new VerifyXMLSignatureResponse(); +		X509Certificate cert = session.getSignerCertificate(); +		vsresp.setX509certificate(cert); + +		session.setXMLVerifySignatureResponse(vsresp); +		session.setSignerCertificate(vsresp.getX509certificate()); +		vsresp.setX509certificate(null); +		session.setForeigner(true); +	} + +	/** +	 * Checks a parameter. +	 * +	 * @param param parameter +	 * @return true if the parameter is null or empty +	 */ +	private boolean isEmpty(String param) { +		return param == null || param.length() == 0; +	} + +	/** +	 * Checks the correctness of SAML attributes and returns its value. +	 * +	 * @param param        samlAttribute +	 * @param i            the number of the verified attribute for messages +	 * @param identifier   the infobox identifier for messages +	 * @param friendlyname the friendly name of the infobox for messages +	 * @return the SAML attribute value (Element or String) +	 */ +	protected static Object verifySAMLAttribute( +			ExtendedSAMLAttribute samlAttribute, int i, String identifier, +			String friendlyName) throws ValidateException { +		String name = samlAttribute.getName(); + +		if (name == null) { +			Logger.info("The name of SAML-Attribute number " + (i + 1) +					+ " returned from " + identifier +					+ "-infobox validator is null."); +			throw new ValidateException("validator.45", new Object[]{ +					friendlyName, "Name", String.valueOf((i + 1)), "null"}); +		} +		if (name == "") { +			Logger.info("The name of SAML-Attribute number " + (i + 1) +					+ " returned from " + identifier +					+ "-infobox validator is empty."); +			throw new ValidateException("validator.45", new Object[]{ +					friendlyName, "Name", String.valueOf((i + 1)), "leer"}); +		} +		if (samlAttribute.getNameSpace() == null) { +			Logger.info("The namespace of SAML-Attribute number " + (i + 1) +					+ " returned from " + identifier +					+ "-infobox validator is null."); +			throw new ValidateException("validator.45", +					new Object[]{friendlyName, "Namespace", +					String.valueOf((i + 1)), "null"}); +		} +		Object value = samlAttribute.getValue(); +		if (value == null) { +			Logger.info("The value of SAML-Attribute number " + (i + 1) +					+ " returned from " + identifier +					+ "-infobox validator is null."); +			throw new ValidateException("validator.45", new Object[]{ +					friendlyName, "Wert", String.valueOf((i + 1)), "null"}); +		} + +		return value; +	} + +	/** +	 * 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)); + +		X509Certificate cert; +		try { +			cert = new X509Certificate(is); +			return cert; + +		} catch (Throwable e) { +			throw new CertificateException(e); +			 +		} finally { +			try { +				is.close(); +				 +			} catch (IOException e) { +				Logger.warn("Close InputStream failed." , e); +				 +			} +			 +		} +	} + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationAssertionBuilder.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationAssertionBuilder.java new file mode 100644 index 000000000..89f42ab7d --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationAssertionBuilder.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +package at.gv.egovernment.moa.id.auth.builder; + +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Iterator; +import java.util.List; + +import javax.xml.transform.TransformerException; + +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute; +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.StringUtils; + +/** + * Base class for building authentication the AUTHBlock and final OA data SAML assertions. + * Encapsulates methods used by the two specific builders  + * {@link at.gv.egovernment.moa.id.auth.builder.AuthenticationBlockAssertionBuilder AuthenticationBlockAssertionBuilder} + * and + * {@link at.gv.egovernment.moa.id.auth.builder.AuthenticationDataAssertionBuilder AuthenticationDataAssertionBuilder} + *  + * @author Harald Bratko + */ +public class AuthenticationAssertionBuilder { +   +  /** the NewLine representation in Java*/ +  protected static String NL = "\n"; +   +  protected static String SAML_ATTRIBUTE = +  "   <saml:Attribute AttributeName=''{0}'' AttributeNamespace=''{1}''>" + NL + +  "     <saml:AttributeValue>{2}</saml:AttributeValue>" + NL + +  "   </saml:Attribute>"+ NL; +   +  protected static String SAML_ATTRIBUTE_NO_NAMESPACE = +	  "   <saml:Attribute AttributeName=''{0}''>" + NL + +	  "     <saml:AttributeValue>{1}</saml:AttributeValue>" + NL + +	  "   </saml:Attribute>"+ NL; + +  /** +   * Empty constructor +   */ +  public AuthenticationAssertionBuilder() { +  } +   +  /** +   * Builds the SAML attributes to be appended to the AUTHBlock or to the SAML assertion  +   * delivered to the online application. +   * The method traverses through the list of given SAML attribute objects and builds an  +   * XML structure (String representation) for each of the attributes.  +   *  +   * @param extendedSAMLAttributes The SAML attributes to be appended to the AUTHBlock or   +   *                               to the SAML assertion delivered to the online application. +   * @return                       A string representation including the XML structures of +   *                               the SAML attributes. +   *                                +   * @throws ParseException        If an error occurs on serializing an SAML attribute. +   */ +  protected String buildExtendedSAMLAttributes(List<ExtendedSAMLAttribute> extendedSAMLAttributes) throws ParseException +  { +    StringBuffer sb = new StringBuffer(); +    if (extendedSAMLAttributes!=null) { +      Iterator<ExtendedSAMLAttribute> it = extendedSAMLAttributes.iterator(); +      while (it.hasNext()) { +        ExtendedSAMLAttribute extendedSAMLAttribute = (ExtendedSAMLAttribute)it.next(); +        Object value = extendedSAMLAttribute.getValue(); +        String name = extendedSAMLAttribute.getName(); +        String namespace = extendedSAMLAttribute.getNameSpace(); +        if (value instanceof String) { +          sb.append(MessageFormat.format( SAML_ATTRIBUTE, new Object[] {name, namespace, value})); +           +        } else if (value instanceof List<?>) { +        	if (!((List<?>)value).isEmpty()) { +        		Object firstEl = ((List<?>)value).get(0); +        		if (firstEl instanceof String) { +        			sb.append(MessageFormat.format( SAML_ATTRIBUTE, new Object[] {name, namespace, ((String)firstEl)})); +        		} +        	} +        	        	 +        } else if (value instanceof Element) { +          try { +            String serializedValue = DOMUtils.serializeNode((Element)(value)); +            serializedValue = StringUtils.removeXMLDeclaration(serializedValue); +            sb.append(MessageFormat.format( SAML_ATTRIBUTE, new Object[] {name, namespace, serializedValue})); +          } catch (TransformerException e) { +            Logger.error("Error on serializing SAML attribute \"" + name +  +              " (namespace: \"" + namespace + "\"."); +            throw new ParseException("parser.05", new Object[] { name, namespace}); +          } catch (IOException e) { +            Logger.error("Error on serializing SAML attribute \"" + name +  +              " (namespace: \"" + namespace + "\"."); +            throw new ParseException("parser.05", new Object[] { name, namespace}); +          } +        } +      } +    } +   return sb.toString(); +  } +   +  +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilder.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilder.java new file mode 100644 index 000000000..760d28d5b --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilder.java @@ -0,0 +1,584 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ + + +package at.gv.egovernment.moa.id.auth.builder; + +import java.io.StringWriter; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.List; + +import javax.xml.bind.DatatypeConverter; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +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.ExtendedSAMLAttributeImpl; +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.config.TargetToSectorNameMapper; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.util.Random; +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.MiscUtil; +import at.gv.egovernment.moa.util.StringUtils; + +/** + * Builder for the authentication block <code><saml:Assertion></code> + * to be included in a <code><CreateXMLSignatureResponse></code>. + *  + * @author Paul Ivancsics + * @version $Id$ + */ +public class AuthenticationBlockAssertionBuilder extends AuthenticationAssertionBuilder implements Constants { + +  /** template for the Auth-Block */ +  private static String AUTH_BLOCK =  +    "<saml:Assertion xmlns:saml=''" + SAML_NS_URI + "''{0} MajorVersion=''1'' MinorVersion=''0'' AssertionID=''any'' Issuer=''{1}'' IssueInstant=''{2}''>" + NL + +    " <saml:AttributeStatement>" + NL + +    "   <saml:Subject>" + NL + +    "     <saml:NameIdentifier>{3}</saml:NameIdentifier>" + NL + +    "   </saml:Subject>" + NL + +    "{4}" +  +    "   <saml:Attribute AttributeName=''OA'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL + +    "     <saml:AttributeValue>{5}</saml:AttributeValue>" + NL + +    "   </saml:Attribute>" + NL + +    "   <saml:Attribute AttributeName=''Geburtsdatum'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL + +    "     <saml:AttributeValue>{6}</saml:AttributeValue>" + NL + +    "   </saml:Attribute>" + NL + +    "{7}" + +    "{8}" + +    "{9}" + +    " </saml:AttributeStatement>" + NL + +    "</saml:Assertion>"; +   +  private static String GESCHAEFTS_BEREICH_ATTRIBUTE = +    "   <saml:Attribute AttributeName=''Geschaeftsbereich'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL + +    "     <saml:AttributeValue>{0}</saml:AttributeValue>" + NL + +    "   </saml:Attribute>" + NL; +   +  private static String WBPK_ATTRIBUTE = +    "   <saml:Attribute AttributeName=''wbPK'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL + +    "     <saml:AttributeValue>" + NL + +    "       <pr:Identification>" + NL + +    "         <pr:Value>{0}</pr:Value>" + NL + +    "         <pr:Type>{1}</pr:Type>" + NL + +    "       </pr:Identification>" + NL + +    "     </saml:AttributeValue>" + NL + +    "   </saml:Attribute>" + NL; +   +  private static String SPECIAL_TEXT_ATTRIBUTE = +		    "   <saml:Attribute AttributeName=''SpecialText'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL + +		    "     <saml:AttributeValue>{0}</saml:AttributeValue>" + NL +   +		    "   </saml:Attribute>" + NL; +   +  private static String AUTHBLOCKTOKKEN_ATTRIBUTE = +		    "   <saml:Attribute AttributeName=''UniqueTokken'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL + +		    "     <saml:AttributeValue>{0}</saml:AttributeValue>" + NL +   +		    "   </saml:Attribute>" + NL; +   +   +  private static String PR_IDENTIFICATION_ATTRIBUTE =      +       "       <pr:Identification xmlns:pr=\"" + PD_NS_URI + "\">" + NL + +       "         <pr:Value>{0}</pr:Value>" + NL + +       "         <pr:Type>{1}</pr:Type>" + NL + +       "       </pr:Identification>" + NL; +   +  /** +   * The number of SAML attributes included in this AUTH-Block (without the extended SAML attributes). +   */ +  public static final int NUM_OF_SAML_ATTRIBUTES = 5; +  public static final int NUM_OF_SAML_ATTRIBUTES_SSO = 4; +   +  /** +   * Constructor for AuthenticationBlockAssertionBuilder. +   */ +  public AuthenticationBlockAssertionBuilder() { +    super(); +  } +   +  /** +   * Builds the authentication block <code><saml:Assertion></code>  +   *  +   * @param issuer authentication block issuer; <code>"GivenName FamilyName"</code> +   * @param issueInstant current timestamp +   * @param authURL URL of MOA-ID authentication component +   * @param target "Geschäftsbereich"; maybe <code>null</code> if the application +   *               is a business application +   * @param identityLinkValue the content of the <code><pr:Value></code> +   *                          child element of the <code><pr:Identification></code> +   *                          element derived from the Identitylink; this is the +   *                          value of the <code>wbPK</code>; +   *                          maybe <code>null</code> if the application is a public service +   * @param identityLinkType  the content of the <code><pr:Type></code> +   *                          child element of the <code><pr:Identification></code> +   *                          element derived from the Identitylink; this includes the +   *                          URN prefix and the identification number of the business +   *                          application used as input for wbPK computation; +   *                          maybe <code>null</code> if the application is a public service +   * @param oaURL public URL of online application requested +   * @param gebDat The date of birth from the identity link. +   * @param extendedSAMLAttributes The SAML attributes to be appended to the AUTHBlock. +   *  +   * @return String representation of authentication block  +   *          <code><saml:Assertion></code> built +   *           +   * @throws BuildException If an error occurs on serializing an extended SAML attribute  +   *                        to be appended to the AUTH-Block. +   */ +  public String buildAuthBlock( +    String issuer,  +    String issueInstant,  +    String authURL,  +    String target, +    String targetFriendlyName, +    String identityLinkValue,  +    String identityLinkType, +    String oaURL,  +    String gebDat, +    List<ExtendedSAMLAttribute> extendedSAMLAttributes, +    AuthenticationSession session, +    OAAuthParameter oaParam) +  throws BuildException +   +  { +    session.setSAMLAttributeGebeORwbpk(true); +    String gebeORwbpk = ""; +    String wbpkNSDeclaration = ""; +            +    if (target == null) { +    	 +      // OA is a business application +      if (!Constants.URN_PREFIX_HPI.equals(identityLinkType)) { +        // Only add wbPKs to AUTH-Block. HPIs can be added to the AUTH-Block by the corresponding Validator +         gebeORwbpk = MessageFormat.format(WBPK_ATTRIBUTE, new Object[] { identityLinkValue, identityLinkType }); +         wbpkNSDeclaration = " xmlns:pr=\"" + PD_NS_URI + "\""; +          +         //adding type of wbPK domain identifier         +        ExtendedSAMLAttribute idLinkDomainIdentifierTypeAttribute =  +             new ExtendedSAMLAttributeImpl("IdentityLinkDomainIdentifierType", oaParam.getIdentityLinkDomainIdentifierType(), Constants.MOA_NS_URI, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY); +             +        extendedSAMLAttributes.add(idLinkDomainIdentifierTypeAttribute); +          +      } else { +        // We do not have a wbPK, therefore no SAML-Attribute is provided +        session.setSAMLAttributeGebeORwbpk(false); +      } +       +    } else { +      // OA is a govermental application +      String sectorName = TargetToSectorNameMapper.getSectorNameViaTarget(target); +      if (StringUtils.isEmpty(sectorName)) { +    	  if (targetFriendlyName != null) +    		  sectorName = targetFriendlyName;  +      } +       +         +      //gebeORwbpk = MessageFormat.format(GESCHAEFTS_BEREICH_ATTRIBUTE, new Object[] { target }); +      gebeORwbpk = MessageFormat.format(GESCHAEFTS_BEREICH_ATTRIBUTE, new Object[] { target + " (" + sectorName + ")" }); +       +      //no business service, adding bPK + +      if (identityLinkValue != null) { +    	  Element bpkSamlValueElement; +    	  try { +    		  bpkSamlValueElement = DOMUtils.parseDocument(MessageFormat.format(PR_IDENTIFICATION_ATTRIBUTE, new Object[] { identityLinkValue, Constants.URN_PREFIX_BPK }), false, null, null).getDocumentElement(); +    	  } catch (Exception e) { +    		  Logger.error("Error on building AUTH-Block: " + e.getMessage()); +    		  throw new BuildException("builder.00", new Object[] { "AUTH-Block", e.toString()}); +    	  }  +	       +	//      String s = xmlToString(bpkSamlValueElement); +	//      System.out.println("bpkSamlValueElement: " + s); +	       +    	  ExtendedSAMLAttribute bpkAttribute =  +    		  new ExtendedSAMLAttributeImpl("bPK", bpkSamlValueElement, Constants.MOA_NS_URI, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY); +    	  extendedSAMLAttributes.add(bpkAttribute); +      } +       +      boolean useMandate = session.getUseMandate(); +      if (useMandate) { +    	  String mandateReferenceValue = Random.nextRandom(); +    	  // remove leading "-" +    	  if (mandateReferenceValue.startsWith("-")) +    		  mandateReferenceValue = mandateReferenceValue.substring(1); +    		  +    	  session.setMandateReferenceValue(mandateReferenceValue); +    		  +    	  ExtendedSAMLAttribute mandateReferenceValueAttribute =  +    		  new ExtendedSAMLAttributeImpl("mandateReferenceValue", mandateReferenceValue, Constants.MOA_NS_URI, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK); +    	             +    	  extendedSAMLAttributes.add(mandateReferenceValueAttribute); +      } +    	 +       + +     //gebeORwbpk = gebeORwbpk  + MessageFormat.format(BPK_ATTRIBUTE, new Object[] { identityLinkValue, identityLinkType }); +     wbpkNSDeclaration = " xmlns:pr=\"" + PD_NS_URI + "\""; +    } +     +    //adding friendly name of OA     +    String oaFriendlyName = StringUtils.isEmpty(oaParam.getFriendlyName()) ? "" : oaParam.getFriendlyName();  +     +    ExtendedSAMLAttribute oaFriendlyNameAttribute =  +         new ExtendedSAMLAttributeImpl("oaFriendlyName", oaFriendlyName, Constants.MOA_NS_URI, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY); +     +    extendedSAMLAttributes.add(oaFriendlyNameAttribute); +     +     +    String text = ""; +    try { +		OAAuthParameter oaparam = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(session.getPublicOAURLPrefix());		 +		if (MiscUtil.isNotEmpty(oaparam.getAditionalAuthBlockText())) { +			Logger.debug("Use addional AuthBlock Text from OA=" + oaparam.getPublicURLPrefix()); +			text = oaparam.getAditionalAuthBlockText(); +		} +		 +	} catch (ConfigurationException e) { +		Logger.warn("Addional AuthBlock Text can not loaded from OA!", e); +	} +     +   	String specialText =  MessageFormat.format(SPECIAL_TEXT_ATTRIBUTE,  +   			new Object[] { generateSpecialText(text, issuer, gebDat, issueInstant) }); +     +   	//generate unique AuthBlock tokken +   	String uniquetokken = Random.nextRandom(); +   	session.setAuthBlockTokken(uniquetokken); +   	 +    String assertion; +    try {    	 +      assertion = MessageFormat.format( +        AUTH_BLOCK, new Object[] {  +          wbpkNSDeclaration,  +          issuer,  +          issueInstant,  +          authURL,  +          gebeORwbpk,  +          oaURL,  +          gebDat, +          specialText, +          MessageFormat.format(AUTHBLOCKTOKKEN_ATTRIBUTE,  +         			new Object[] { uniquetokken }), +          buildExtendedSAMLAttributes(extendedSAMLAttributes)}); +    } catch (ParseException e) { +      Logger.error("Error on building AUTH-Block: " + e.getMessage()); +      throw new BuildException("builder.00", new Object[] { "AUTH-Block", e.toString()}); +    } +     +    return assertion; +     +  } +   +  /** +   * Builds the authentication block <code><saml:Assertion></code>  +   *  +   * @param issuer authentication block issuer; <code>"GivenName FamilyName"</code> +   * @param issueInstant current timestamp +   * @param authURL URL of MOA-ID authentication component +   * @param target "Geschäftsbereich"; maybe <code>null</code> if the application +   *               is a business application +   * @param identityLinkValue the content of the <code><pr:Value></code> +   *                          child element of the <code><pr:Identification></code> +   *                          element derived from the Identitylink; this is the +   *                          value of the <code>wbPK</code>; +   *                          maybe <code>null</code> if the application is a public service +   * @param identityLinkType  the content of the <code><pr:Type></code> +   *                          child element of the <code><pr:Identification></code> +   *                          element derived from the Identitylink; this includes the +   *                          URN prefix and the identification number of the business +   *                          application used as input for wbPK computation; +   *                          maybe <code>null</code> if the application is a public service +   * @param oaURL public URL of online application requested +   * @param gebDat The date of birth from the identity link. +   * @param extendedSAMLAttributes The SAML attributes to be appended to the AUTHBlock. +   *  +   * @return String representation of authentication block  +   *          <code><saml:Assertion></code> built +   *           +   * @throws BuildException If an error occurs on serializing an extended SAML attribute  +   *                        to be appended to the AUTH-Block. +   */ +  public String buildAuthBlockForeignID( +    String issuer,  +    String issueInstant,  +    String authURL,  +    String target, +    String identityLinkValue,  +    String identityLinkType, +    String oaURL,  +    String gebDat, +    List<ExtendedSAMLAttribute> extendedSAMLAttributes, +    AuthenticationSession session) +  throws BuildException +  { +    session.setSAMLAttributeGebeORwbpk(true); +    String gebeORwbpk = ""; +    String wbpkNSDeclaration = ""; +     +    //BZ.., reading OA parameters +    OAAuthParameter oaParam; +   try { +      oaParam = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter( +           session.getPublicOAURLPrefix()); +   } catch (ConfigurationException e) { +      Logger.error("Error on building AUTH-Block: " + e.getMessage()); +         throw new BuildException("builder.00", new Object[] { "AUTH-Block", e.toString()}); +   } +   //..BZ +     +     +    if (target == null) { +      // OA is a business application +      if (!Constants.URN_PREFIX_HPI.equals(identityLinkType)) { +        // Only add wbPKs to AUTH-Block. HPIs can be added to the AUTH-Block by the corresponding Validator +         gebeORwbpk = MessageFormat.format(WBPK_ATTRIBUTE, new Object[] { identityLinkValue, identityLinkType }); +         wbpkNSDeclaration = " xmlns:pr=\"" + PD_NS_URI + "\""; +          +         //BZ.., adding type of wbPK domain identifier         +        ExtendedSAMLAttribute idLinkDomainIdentifierTypeAttribute =  +             new ExtendedSAMLAttributeImpl("IdentityLinkDomainIdentifierType", oaParam.getIdentityLinkDomainIdentifierType(), Constants.MOA_NS_URI, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY); +             +        extendedSAMLAttributes.add(idLinkDomainIdentifierTypeAttribute); +        //..BZ +          +      } else { +        // We do not have a wbPK, therefore no SAML-Attribute is provided +        session.setSAMLAttributeGebeORwbpk(false); +      } +    } else { +      // OA is a govermental application +      //BZ.. +      String sectorName = TargetToSectorNameMapper.getSectorNameViaTarget(target);       +      //gebeORwbpk = MessageFormat.format(GESCHAEFTS_BEREICH_ATTRIBUTE, new Object[] { target }); +      gebeORwbpk = MessageFormat.format(GESCHAEFTS_BEREICH_ATTRIBUTE, new Object[] { target + " (" + sectorName + ")" }); +      //..BZ +       +      //BZ.., no business service, adding bPK +       +      Element bpkSamlValueElement; +      try { +         bpkSamlValueElement = DOMUtils.parseDocument(MessageFormat.format(PR_IDENTIFICATION_ATTRIBUTE, new Object[] { identityLinkValue, Constants.URN_PREFIX_BPK }), false, null, null).getDocumentElement(); +      } catch (Exception e) { +         Logger.error("Error on building AUTH-Block: " + e.getMessage()); +          throw new BuildException("builder.00", new Object[] { "AUTH-Block", e.toString()}); +      }  +             +      ExtendedSAMLAttribute bpkAttribute =  +          new ExtendedSAMLAttributeImpl("bPK", bpkSamlValueElement, Constants.MOA_NS_URI, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY); +          +     extendedSAMLAttributes.add(bpkAttribute); +      //gebeORwbpk = gebeORwbpk  + MessageFormat.format(BPK_ATTRIBUTE, new Object[] { identityLinkValue, identityLinkType }); +     wbpkNSDeclaration = " xmlns:pr=\"" + PD_NS_URI + "\""; +     //..BZ      +    } +     +    //BZ.., adding friendly name of OA     +    String oaFriendlyName = StringUtils.isEmpty(oaParam.getFriendlyName()) ? "" : oaParam.getFriendlyName();  +     +    ExtendedSAMLAttribute oaFriendlyNameAttribute =  +         new ExtendedSAMLAttributeImpl("oaFriendlyName", oaFriendlyName, Constants.MOA_NS_URI, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY); +     +    extendedSAMLAttributes.add(oaFriendlyNameAttribute); +    //..BZ +     +    String text = ""; +    try { +		OAAuthParameter oaparam = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(session.getPublicOAURLPrefix()); +		if (MiscUtil.isNotEmpty(oaparam.getAditionalAuthBlockText())) { +			Logger.debug("Use addional AuthBlock Text from OA=" + oaparam.getPublicURLPrefix()); +			text = oaparam.getAditionalAuthBlockText(); +		} +	} catch (ConfigurationException e) { +		Logger.warn("Addional AuthBlock Text can not loaded from OA!", e); +	} +     +   	String specialText =  MessageFormat.format(SPECIAL_TEXT_ATTRIBUTE,  +   			new Object[] { generateSpecialText(text, issuer, gebDat, issueInstant) }); +     +   	//generate unique AuthBlock tokken +   	String uniquetokken = Random.nextRandom(); +   	session.setAuthBlockTokken(uniquetokken); +   	 +    String assertion; +    try { +      assertion = MessageFormat.format( +        AUTH_BLOCK, new Object[] {  +          wbpkNSDeclaration,  +          issuer,  +          issueInstant,  +          authURL,  +          gebeORwbpk,  +          oaURL,  +          gebDat, +          specialText, +          MessageFormat.format(AUTHBLOCKTOKKEN_ATTRIBUTE,  +       			new Object[] { uniquetokken }), +          buildExtendedSAMLAttributes(extendedSAMLAttributes)}); +    } catch (ParseException e) { +      Logger.error("Error on building AUTH-Block: " + e.getMessage()); +      throw new BuildException("builder.00", new Object[] { "AUTH-Block", e.toString()}); +    } +     +    return assertion; +     +  } +   +  public static String generateSpecialText(String inputtext, String issuer, String gebDat, String issueInstant) { +	   	Calendar datetime = DatatypeConverter.parseDateTime(issueInstant); +	   	SimpleDateFormat dateformat = new SimpleDateFormat("dd.MM.yyyy"); +	   	SimpleDateFormat timeformat = new SimpleDateFormat("HH:mm:ss"); +	  +	   	String text = inputtext.replaceAll("#NAME#", issuer); +	    text = text.replaceAll("#BIRTHDAY#", gebDat); +	   	text = text.replaceAll("#DATE#", dateformat.format(datetime.getTime())); +	   	text = text.replaceAll("#TIME#", timeformat.format(datetime.getTime())); +	   	 +	   	return text; +  } +   +  public static String xmlToString(Node node) { +      try { +          Source source = new DOMSource(node); +          StringWriter stringWriter = new StringWriter(); +          Result result = new StreamResult(stringWriter); +          TransformerFactory factory = TransformerFactory.newInstance(); +          Transformer transformer = factory.newTransformer(); +          transformer.transform(source, result); +          return stringWriter.getBuffer().toString(); +      } catch (TransformerConfigurationException e) { +          e.printStackTrace(); +      } catch (TransformerException e) { +          e.printStackTrace(); +      } +      return null; +  } +   +  public String buildAuthBlockSSO( +		    String issuer,  +		    String issueInstant,  +		    String authURL,  +		    String target, +		    String targetFriendlyName, +		    String identityLinkValue,  +		    String identityLinkType, +		    String oaURL,  +		    String gebDat, +		    List<ExtendedSAMLAttribute> extendedSAMLAttributes, +		    AuthenticationSession session, +		    IOAAuthParameters oaParam) +		  throws BuildException +		  { +		    session.setSAMLAttributeGebeORwbpk(true); +		    String gebeORwbpk = ""; +		    String wbpkNSDeclaration = ""; +		            +		    if (target != null) { +		       +		      boolean useMandate = session.getUseMandate(); +		      if (useMandate) { +		    	  String mandateReferenceValue = Random.nextRandom(); +		    	  // remove leading "-" +		    	  if (mandateReferenceValue.startsWith("-")) +		    		  mandateReferenceValue = mandateReferenceValue.substring(1); +		    		  +		    	  session.setMandateReferenceValue(mandateReferenceValue); +		    		  +		    	  ExtendedSAMLAttribute mandateReferenceValueAttribute =  +		    		  new ExtendedSAMLAttributeImpl("mandateReferenceValue", mandateReferenceValue, Constants.MOA_NS_URI, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK); +		    	             +		    	  extendedSAMLAttributes.add(mandateReferenceValueAttribute); +		      } +		    } +		     +		    //adding friendly name of OA +		    String friendlyname; +			try { +				friendlyname = AuthConfigurationProviderFactory.getInstance().getSSOFriendlyName(); +	 +		    ExtendedSAMLAttribute oaFriendlyNameAttribute =  +		         new ExtendedSAMLAttributeImpl("oaFriendlyName", friendlyname, Constants.MOA_NS_URI, ExtendedSAMLAttribute.ADD_TO_AUTHBLOCK_ONLY); +		     +		    extendedSAMLAttributes.add(oaFriendlyNameAttribute); +		     +		     +		    String text = AuthConfigurationProviderFactory.getInstance().getSSOSpecialText(); +		     +		    if (MiscUtil.isEmpty(text)) +		    	text=""; +		   	String specialText =  MessageFormat.format(SPECIAL_TEXT_ATTRIBUTE,  +		   			new Object[] { generateSpecialText(text, issuer, gebDat, issueInstant) }); +	 +		   	//generate unique AuthBlock tokken +		   	String uniquetokken = Random.nextRandom(); +		   	session.setAuthBlockTokken(uniquetokken); +		 +		    String assertion; +    	 +		      assertion = MessageFormat.format( +		        AUTH_BLOCK, new Object[] {  +		          wbpkNSDeclaration,  +		          issuer,  +		          issueInstant,  +		          authURL,  +		          gebeORwbpk,  +		          oaURL,  +		          gebDat, +		          specialText, +		          MessageFormat.format(AUTHBLOCKTOKKEN_ATTRIBUTE,  +		         			new Object[] { uniquetokken }), +		          buildExtendedSAMLAttributes(extendedSAMLAttributes)}); +		       +			    return assertion; +		       +		    } catch (ParseException e) { +		    		Logger.error("Error on building AUTH-Block: " + e.getMessage()); +		    		throw new BuildException("builder.00", new Object[] { "AUTH-Block", e.toString()}); +		    		 +		    } catch (ConfigurationException e) { +			      Logger.error("Error on building AUTH-Block: " + e.getMessage()); +			      throw new BuildException("builder.00", new Object[] { "AUTH-Block", e.toString()}); +			} +		     + +		     +		  } +   +   +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/Builder.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/Builder.java new file mode 100644 index 000000000..ca9bf2080 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/Builder.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.builder; + +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.util.StringUtils; + +/** + * Base class for HTML/XML builders providing commonly useful functions. + *  + * @author Paul Ivancsics + * @version $Id$ + */ +public class Builder { +   +  /** +   * Replaces a given number of occurences of a special tag in an XML or HTML template by a value. +   * @param template html template +   * @param tag special tag +   * @param value value replacing the tag +   * @param expected specifies if the tag is expected to present; if <code>true</code> and the tag +   *                 is not present, an exception is thrown; if <code>false</code> and the tag is +   *                 not present, the original string is returned +   * @param maxreplacements Set -1 to replace each occurence of tag, or limit replacements by a given positive number   +   * @return XML or HTML code, the tag replaced +   * @throws BuildException when template does not contain the tag +   */ +  protected String replaceTag( +    String template,  +    String tag,  +    String value,  +    boolean expected,  +    int maxreplacements)  +  throws BuildException  +  { +    String result = template; +    int index = result.indexOf(tag); +    if (index < 0) { +      if (expected) { +    	// Substring not found but should +        throw new BuildException( +                "builder.01",  +                new Object[] {"<" + tag.substring(1, tag.length() - 1) + ">"}); +      } +    } else { +       // replace each occurence +       if (maxreplacements == -1) { +         return StringUtils.replaceAll(template, tag, value);        +       } else { +         int found = 1; +         while (index > -1 && (found <= maxreplacements)) { +           result = result.substring(0, index) + value + result.substring(index + tag.length()); +           index = result.indexOf(tag); +           if (index > -1) found += 1; +         } +       } +    } +    return result; +  } + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/CertInfoVerifyXMLSignatureRequestBuilder.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/CertInfoVerifyXMLSignatureRequestBuilder.java new file mode 100644 index 000000000..a904242e1 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/CertInfoVerifyXMLSignatureRequestBuilder.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.builder; + +import java.io.IOException; +import java.text.MessageFormat; + +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.FileUtils; + +/** + * Builder for the <code><VerifyXMLSignatureRequest></code> structure + * used for presenting certificate information in the secure viewer of the security layer implementation. + *  + * @author Paul Ivancsics + * @version $Id$ + */ +public class CertInfoVerifyXMLSignatureRequestBuilder extends Builder implements Constants { +   +  /** special tag in the VerifyXMLRequest template to be substituted for a <code><dsig:Signature></code> */ +  private static final String SIGNATURE_TAG = "<dsig:Signature/>"; +   +  /** private static String nl contains the NewLine representation in Java*/ +  private static final String nl = "\n"; + +  /** +   * XML template for the CertInfoVerifyXMLSignatureRequest to be built +   */  +  static final String CERTINFO_REQUEST = +    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + nl +                                                                   +    "<{0}:VerifyXMLSignatureRequest {2} xmlns:dsig=\"" + DSIG_NS_URI +  "\">" + nl + +    "  <{0}:SignatureInfo>" + nl + +    "    <{0}:SignatureEnvironment>" + nl + +    "      <{1}:XMLContent xml:space=\"preserve\"><dsig:Signature/></{1}:XMLContent>" + nl + +    "    </{0}:SignatureEnvironment>" + nl + +    "    <{0}:SignatureLocation>//dsig:Signature</{0}:SignatureLocation>" + nl + +    "  </{0}:SignatureInfo>" + nl + +    "</{0}:VerifyXMLSignatureRequest>"; + +  /** +   * Constructor +   */ +  public CertInfoVerifyXMLSignatureRequestBuilder() { +    super(); +  } +  /** +   * Builds the <code><VerifyXMLSignatureRequest></code> structure. +   * @return the XML structure +   * @throws BuildException +   */ +  public String build() throws BuildException { +     +    String sl10Prefix; +    String sl11Prefix; +    String slNsDeclaration; +         +//    if (slVersion12) { +             +      sl10Prefix = SL12_PREFIX; +      sl11Prefix = SL12_PREFIX; +      slNsDeclaration = "xmlns:" + SL12_PREFIX + "=\"" + SL12_NS_URI + "\""; +       +//    } else { +//       +//      sl10Prefix = SL10_PREFIX; +//      sl11Prefix = SL11_PREFIX; +//      slNsDeclaration = "xmlns:" + sl11Prefix + "=\"" + SL11_NS_URI + "\" xmlns:" + sl10Prefix + "=\"" + SL10_NS_URI + "\""; +//       +//    } +     +    String certInfoRequest = MessageFormat.format(CERTINFO_REQUEST, new Object[] {sl11Prefix, sl10Prefix, slNsDeclaration}); +    String resDsigSignature = "resources/xmldata/CertInfoDsigSignature.xml"; +     +     +    try { +      String dsigSignature = FileUtils.readResource(resDsigSignature, "UTF-8"); +      certInfoRequest = replaceTag(certInfoRequest, SIGNATURE_TAG, dsigSignature, true, 1); +      return certInfoRequest; +    } +    catch (IOException ex) { +      throw new BuildException("auth.04", new Object[] {resDsigSignature, ex.toString()}); +    } +  } + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureRequestBuilderForeign.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureRequestBuilderForeign.java new file mode 100644 index 000000000..76cf9addb --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureRequestBuilderForeign.java @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.builder; + +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; + +import at.gv.egovernment.moa.id.auth.exception.BuildException; + + +/** + * Builder for CreateXMLSignatureRequest to sign data from a foreign  + * eID card. + *   + */ + +public class CreateXMLSignatureRequestBuilderForeign extends Builder { + +  /** special tag in the XML template to be substituted for the KeyboxIdentifier */ +  private static final String KEYBOXID_TAG = "<KEYBOXID>"; +  /** special tag in the XML template to be substituted for the content */ +  private static final String XMLCONTENT_TAG = "<XMLContent>"; +  /** private static int all contains the representation to replace all tags*/ +  private static final int ALL = -1; + +//  /** default HTML template */ +//  private static final String DEFAULT_XML_TEMPLATE =  +//	  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +  +//	  "<sl:CreateXMLSignatureRequest xmlns:sl=\"http://www.buergerkarte.at/namespaces/securitylayer/1.2#\">" +  +//	  "<sl:KeyboxIdentifier>" + KEYBOXID_TAG + "</sl:KeyboxIdentifier>" +  +//	  "<sl:DataObjectInfo Structure=\"enveloping\">" +  +//	  "<sl:DataObject>" + +//	  "<sl:XMLContent>" + XMLCONTENT_TAG + "</sl:XMLContent>" + +//	  "</sl:DataObject>" +  +//	  "<sl:TransformsInfo>" +  +//	  "<sl:FinalDataMetaInfo>" +  +//	  "<sl:MimeType>text/plain</sl:MimeType>" +  +//	  "</sl:FinalDataMetaInfo>" +  +//	  "</sl:TransformsInfo>" +  +//	  "</sl:DataObjectInfo>" + +//	  "</sl:CreateXMLSignatureRequest>"; +   +  /** default HTML template */ +  private static final String DEFAULT_XHTML_TEMPLATE =  +	  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +  +	  "<sl:CreateXMLSignatureRequest xmlns:sl=\"http://www.buergerkarte.at/namespaces/securitylayer/1.2#\">" +  +	  "<sl:KeyboxIdentifier>" + KEYBOXID_TAG + "</sl:KeyboxIdentifier>" +  +	  "<sl:DataObjectInfo Structure=\"enveloping\">" +  +	  "<sl:DataObject>" + +	  "<sl:XMLContent>" + XMLCONTENT_TAG + "</sl:XMLContent>" + +	  "</sl:DataObject>" +  +	  "<sl:TransformsInfo>" +  +	  "<sl:FinalDataMetaInfo>" +  +	  "<sl:MimeType>application/xhtml+xml</sl:MimeType>" +  +	  "</sl:FinalDataMetaInfo>" +  +	  "</sl:TransformsInfo>" +  +	  "</sl:DataObjectInfo>" + +	  "</sl:CreateXMLSignatureRequest>"; +	   +  /** +   * Constructor for CreateXMLSignatureRequestBuilderForeign. +   */ +  public CreateXMLSignatureRequestBuilderForeign() { +    super(); +  } +  /** +   * Builds the XML request. +   *  +   * @param xmlRequest XML Request to be sent as a parameter in the form +   * @param bkuURL URL of the "Bürgerkartenumgebung" the form will be submitted to; +   *         may be <code>null</code>, in this case the default URL will be used +   * @param dataURL DataURL to be sent as a parameter in the form +   */ +  public String build( +    String keyboxIdentifier,  +    String xmlContent) +  throws BuildException  +  {       +  	String xmlRequest = DEFAULT_XHTML_TEMPLATE; +  	xmlRequest = replaceTag(xmlRequest, KEYBOXID_TAG, keyboxIdentifier, true, ALL); +    //htmlForm = replaceTag(htmlForm, XMLREQUEST_TAG, encodeParameter(xmlRequest), true, ALL); +    xmlRequest = replaceTag(xmlRequest, XMLCONTENT_TAG, xmlContent, true, ALL); +  	return xmlRequest; +  } +  /** +   * Encodes a string for inclusion as a parameter in the form. +   * Double quotes are substituted by <code>"&quot;"</code>. +   * @param s the string to be encoded +   * @return the string encoded +   * @throws BuildException on any exception encountered +   */ +  public static String encodeParameter(String s) throws BuildException { +    StringReader in = new StringReader(s); +    StringWriter out = new StringWriter(); +    try { +      for (int ch = in.read(); ch >= 0; ch = in.read()) { +        if (ch == '"') +          out.write("""); +        else if (ch == '<') +          out.write("<"); +        else if (ch == '>') +          out.write(">");  +        else if (ch == 'ä') +          out.write("ä"); +        else if (ch == 'ö') +          out.write("ö"); +        else if (ch == 'ü') +          out.write("ü"); +        else if (ch == 'Ä') +          out.write("Ä"); +        else if (ch == 'Ö') +          out.write("Ö"); +        else if (ch == 'Ü') +          out.write("Ü"); +        else if (ch == 'ß') +          out.write("ß"); +        else +          out.write(ch); +      } +    } +    catch (IOException ex) { +      throw new BuildException("builder.00", new Object[] {"CreateXMLSignatureRequest", ex.toString()}); +    } +    return out.toString(); +  } + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilder.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilder.java new file mode 100644 index 000000000..dc981ba33 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilder.java @@ -0,0 +1,246 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.builder; + +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Map; + +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; +import at.gv.egovernment.moa.id.util.FormBuildUtils; +import at.gv.egovernment.moa.util.MiscUtil; + +/** + * Builder for HTML form requesting the security layer implementation + * to get the identity link from smartcard by a <code><InfoboxReadRequest></code>. + *   + * @author Paul Ivancsics + * @version $Id$ + */ +public class GetIdentityLinkFormBuilder extends Builder { + /** private static String NL contains the NewLine representation in Java*/ +  private static final String nl = "\n"; +  /** special tag in the HTML template to be substituted for the BKU URL */ +  private static final String BKU_TAG = "<BKU>"; +  /** special tag in the HTML template to be substituted for the XML request */ +  private static final String XMLREQUEST_TAG = "<XMLRequest>"; +  /** special tag in the HTML template to be substituted for the data URL */ +  private static final String DATAURL_TAG = "<DataURL>"; +//  /** special tag in the HTML template to be substituted for certificate info XML request */ +//  private static final String CERTINFO_XMLREQUEST_TAG = "<CertInfoXMLRequest>"; +//  /** special tag in the HTML template to be substituted for the certificate info data URL */ +//  private static final String CERTINFO_DATAURL_TAG = "<CertInfoDataURL>"; +  /** special tag in the HTML template to be substituted for the infoboxes to be pushed from the BKU */ +  private static final String PUSHINFOBOX_TAG = "<PushInfobox>"; +  /** special tag in the HTML template to be substituted for the BKU URL */ +  /** private static int all contains the representation to replace all tags*/ +  private static final int ALL = -1; +   +  private static final String COLOR_TAG = "<COLOR>"; +  private static final String REDIRECTTARGETTAG = "<REDIRECTTARGET>"; +  private static final String APPLETWIDTH_TAG = "<APPLETWIDTH>"; +  private static final String APPLETHEIGHT_TAG = "<APPLETHEIGHT>"; + +  /** default HTML template */ +  private static final String DEFAULT_HTML_TEMPLATE =  +    "<html>" + nl + +    "<head>" + nl + +    "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">" + nl + +    "<title>Anmeldung mit Bürgerkarte</title>" + nl + +    "</head>" + nl + +    "<body>" + nl + +    "<form name=\"GetIdentityLinkForm\"" + nl + +    "      action=\"" + BKU_TAG + "\"" + nl + +    "      method=\"post\">" + nl + +    "  <input type=\"hidden\" " + nl + +    "         name=\"XMLRequest\"" + nl + +    "         value=\"" + XMLREQUEST_TAG + "\"/>" + nl + +    "  <input type=\"hidden\" " + nl + +    "         name=\"DataURL\"" + nl + +    "         value=\"" + DATAURL_TAG + "\"/>" + nl + +    "  <input type=\"hidden\" " + nl + +    "         name=\"PushInfobox\"" + nl + +    "         value=\"" + PUSHINFOBOX_TAG + "\"/>" + nl + +    "  <input type=\"submit\" value=\"Anmeldung mit Bürgerkarte\"/>" + nl + +    "</form>" + nl + +//    "<form name=\"CertificateInfoForm\"" + nl + +//    "      action=\"" + BKU_TAG + "\"" + nl + +//    "      method=\"post\">" + nl + +//    "  <input type=\"hidden\" " + nl + +//    "         name=\"XMLRequest\"" + nl + +//    "         value=\"" + CERTINFO_XMLREQUEST_TAG + "\"/>" + nl + +//    "  <input type=\"hidden\" " + nl + +//    "         name=\"DataURL\"" + nl + +//    "         value=\"" + CERTINFO_DATAURL_TAG + "\"/>" + nl + +////	"  <input type=\"submit\" value=\"Information zu Wurzelzertifikaten\"/>" + nl +     +//    "  <input type=\"hidden\" value=\"Information zu Wurzelzertifikaten\"/>" + nl + +//    "</form>" + nl + +    "</body>" + nl + +    "</html>"; +   +   +   +   +    /** +   * Constructor for GetIdentityLinkFormBuilder. +   */ +  public GetIdentityLinkFormBuilder() { +    super(); +  } +  /** +   * Builds the HTML form, including XML Request and data URL as parameters. +   *  +   * @param htmlTemplate template to be used for the HTML form; +   *         may be <code>null</code>, in this case a default layout will be produced +   * @param xmlRequest XML Request to be sent as a parameter in the form +   * @param bkuURL URL of the "Bürgerkartenumgebung" the form will be submitted to; +   *         may be <code>null</code>, in this case the default URL will be used +   * @param dataURL DataURL to be sent as a parameter in the form + * @param oaParam  + * @param appletwidth  + * @param appletheigth  +   */ +  public String build( +  	String htmlTemplate,  +    String bkuURL,  +    String xmlRequest,  +    String dataURL,  +    String certInfoXMLRequest,  +    String certInfoDataURL,  +    String pushInfobox, IOAAuthParameters oaParam,  +    String appletheigth, +    String appletwidth) +  throws BuildException  +  {       +  	String htmlForm = htmlTemplate == null ? DEFAULT_HTML_TEMPLATE : htmlTemplate; +    htmlForm = replaceTag(htmlForm, BKU_TAG, bkuURL, true, ALL); +    htmlForm = replaceTag(htmlForm, XMLREQUEST_TAG, encodeParameter(xmlRequest), true, ALL); +    htmlForm = replaceTag(htmlForm, DATAURL_TAG, dataURL, true, ALL); +    htmlForm = replaceTag(htmlForm, PUSHINFOBOX_TAG, pushInfobox, false, ALL); +//new:wird oben mitreplaced    htmlForm = replaceTag(htmlForm, BKU_TAG, bkuURL); +     +    //removed in MOA-ID 2.0 +//    htmlForm = replaceTag(htmlForm, CERTINFO_XMLREQUEST_TAG, encodeParameter(certInfoXMLRequest), true, ALL); +//    htmlForm = replaceTag(htmlForm, CERTINFO_DATAURL_TAG, certInfoDataURL, true, ALL); +     +    Map<String, String> map = null; +     +    if (oaParam != null) { +    	map = oaParam.getFormCustomizaten(); +    	htmlForm = replaceTag(htmlForm, COLOR_TAG, map.get(FormBuildUtils.MAIN_BACKGROUNDCOLOR), false, ALL); +    	htmlForm = replaceTag(htmlForm, REDIRECTTARGETTAG, map.get(FormBuildUtils.REDIRECTTARGET), false, ALL); +    	    	 +    } else { +    	htmlForm = replaceTag(htmlForm, COLOR_TAG, FormBuildUtils.getDefaultMap().get(FormBuildUtils.MAIN_BACKGROUNDCOLOR), false, ALL); +		htmlForm = replaceTag(htmlForm, REDIRECTTARGETTAG, FormBuildUtils.getDefaultMap().get(FormBuildUtils.REDIRECTTARGET), false, ALL); +    } +     +    if (map != null && MiscUtil.isNotEmpty(map.get(FormBuildUtils.APPLET_HEIGHT))) +    	htmlForm = replaceTag(htmlForm, APPLETHEIGHT_TAG, map.get(FormBuildUtils.APPLET_HEIGHT), false, ALL); +    else if (MiscUtil.isNotEmpty(appletheigth)) +    	htmlForm = replaceTag(htmlForm, APPLETHEIGHT_TAG, appletheigth, false, ALL); +    else +    	htmlForm = replaceTag(htmlForm, APPLETHEIGHT_TAG, "160", false, ALL); +     +    if (map != null && MiscUtil.isNotEmpty(map.get(FormBuildUtils.APPLET_WIDTH))) +    	htmlForm = replaceTag(htmlForm, APPLETWIDTH_TAG, map.get(FormBuildUtils.APPLET_WIDTH), false, ALL); +    else if (MiscUtil.isNotEmpty(appletwidth)) +    	htmlForm = replaceTag(htmlForm, APPLETWIDTH_TAG, appletwidth, false, ALL);  +    else +    	htmlForm = replaceTag(htmlForm, APPLETWIDTH_TAG, "250", false, ALL); + +  	return htmlForm; +  } +   +   +  +  /** +   * Encodes a string for inclusion as a parameter in the form. +   * Double quotes are substituted by <code>"&quot;"</code>. +   * @param s the string to be encoded +   * @return the string encoded +   * @throws BuildException on any exception encountered +   */ +  public static String encodeParameter(String s) throws BuildException { +    StringReader in = new StringReader(s); +    StringWriter out = new StringWriter(); +    try { +      for (int ch = in.read(); ch >= 0; ch = in.read()) { +        if (ch == '"') { +          out.write("""); +        } else if (ch == '<') { +          out.write("<"); +        } else if (ch == '>') { +          out.write(">"); +    	} else if (ch == 'ä') { +          out.write("ä"); +  		} else if (ch == 'ö') { +          out.write("ö"); +		} else if (ch == 'ü') { +          out.write("ü"); +		} else if (ch == 'Ä') { +          out.write("Ä"); +		} else if (ch == 'Ö') { +          out.write("Ö"); +		} else if (ch == 'Ü') { +          out.write("Ü"); +		} else if (ch == 'ß') { +          out.write("ß"); +		} else  { +          out.write(ch); +		} +      } +    } +    catch (IOException ex) { +      throw new BuildException("builder.00", new Object[] {"GetIdentityLinkForm", ex.toString()}); +    } +    return out.toString(); +  } + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/GetVerifyAuthBlockFormBuilder.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/GetVerifyAuthBlockFormBuilder.java new file mode 100644 index 000000000..45e5edf2c --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/GetVerifyAuthBlockFormBuilder.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.builder; + +import at.gv.egovernment.moa.id.auth.exception.BuildException; + +/** + * Builder for HTML form requesting a security layer request + *   + * @author Peter Danner + * @version $Id: GetIdentityLinkFormBuilder.java 769 2007-01-10 15:37:52Z peter.danner $ + */ +public class GetVerifyAuthBlockFormBuilder extends Builder { + /** private static String NL contains the NewLine representation in Java*/ +  private static final String nl = "\n"; +  /** special tag in the HTML template to be substituted for the BKU URL */ +  private static final String BKU_TAG = "<BKU>"; +  /** special tag in the HTML template to be substituted for the XML request */ +  private static final String XMLREQUEST_TAG = "<XMLRequest>"; +  /** special tag in the HTML template to be substituted for the data URL */ +  private static final String DATAURL_TAG = "<DataURL>"; +  /** special tag in the HTML template to be substituted for the infoboxes to be pushed from the BKU */ +  private static final String PUSHINFOBOX_TAG = "<PushInfobox>"; +  /** private static int all contains the representation to replace all tags*/ +  private static final int ALL = -1; + +  /** default HTML template */ +  private static final String DEFAULT_HTML_TEMPLATE =  +    "<html>" + nl + +    "  <head>" + nl + +    "    <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\"/>" + nl + +    "    <title>Signatur der Anmeldedaten</title>" + nl + +    "  </head>" + nl + +    "  <body onLoad=\"autoSubmit()\">" + nl + +    "    <script type=\"text/javascript\">" + nl + +    "      //<!-- "  +  nl + +    "      function autoSubmit() { " +  nl + +    "           document.VerifyAuthBlockForm.submitButton.disabled=true;" +  nl + +    "           document.VerifyAuthBlockForm.submit(); " +  nl + +    "      } //-->" + nl + +    "    </script>" + nl + +    "    <form name=\"VerifyAuthBlockForm\" action=\"" + BKU_TAG + "\" method=\"post\" enctype=\"application/x-www-form-urlencoded\">" + nl + +    "      <input type=\"hidden\" name=\"XMLRequest\" value=\"" + XMLREQUEST_TAG + "\"/>" + nl + +    "      <input type=\"hidden\" name=\"DataURL\" value=\"" + DATAURL_TAG + "\"/>" + nl + +    "      <input type=\"hidden\" name=\"PushInfobox\" value=\"" + PUSHINFOBOX_TAG + "\"/>" + nl + +    "      <input type=\"submit\" value=\"Signieren der Anmeldedaten\" id=\"submitButton\"/>" + nl + +    "    </form>" + nl + +    "  </body>" + nl + +    "</html>"; + +  /** +   * Constructor for GetVerifyAuthBlockFormBuilder. +   */ +  public GetVerifyAuthBlockFormBuilder() { +    super(); +  } +  /** +   * Builds the HTML form, including XML Request and data URL as parameters. +   *  +   * @param htmlTemplate template to be used for the HTML form; +   *         may be <code>null</code>, in this case a default layout will be produced +   * @param xmlRequest XML Request to be sent as a parameter in the form +   * @param bkuURL URL of the "Bürgerkartenumgebung" the form will be submitted to; +   *         may be <code>null</code>, in this case the default URL will be used +   * @param dataURL DataURL to be sent as a parameter in the form +   */ +  public String build( +  	String htmlTemplate,  +    String bkuURL,  +    String xmlRequest,  +    String dataURL,  +    String pushInfobox) +  throws BuildException  +  {       +  	String htmlForm = htmlTemplate == null ? DEFAULT_HTML_TEMPLATE : htmlTemplate; +    htmlForm = replaceTag(htmlForm, BKU_TAG, bkuURL, true, ALL); +    htmlForm = replaceTag(htmlForm, XMLREQUEST_TAG, GetIdentityLinkFormBuilder.encodeParameter(xmlRequest), true, ALL); +    htmlForm = replaceTag(htmlForm, DATAURL_TAG, dataURL, true, ALL); +    if (null==pushInfobox) pushInfobox=""; +    htmlForm = replaceTag(htmlForm, PUSHINFOBOX_TAG, pushInfobox, false, ALL); +  	return htmlForm; +  } + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilder.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilder.java new file mode 100644 index 000000000..81ef5e408 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilder.java @@ -0,0 +1,195 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.builder; + +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Constants; + +/** + * Builder for the <code><InfoboxReadRequest></code> structure + * used for requesting the identity link from the security layer implementation. + * + * @author Paul Ivancsics + * @version $Id$ + */ +public class InfoboxReadRequestBuilder implements Constants { + + +    /** +     * Constructor for InfoboxReadRequestBuilder. +     */ +    public InfoboxReadRequestBuilder() { +    } + + +    /** +     * Builds an <code><InfoboxReadRequest></code>. +     * +     * @param slVersion12                  specifies whether the Security Layer version is +     *                                     version 1.2 or not +     * @param businessService              specifies whether the online application is a +     *                                     business service or not +     * @param identityLinkDomainIdentifier the identification number of the business +     *                                     company; maybe <code>null</code> if the OA +     *                                     is a public service; must not be <code>null</code> +     *                                     if the OA is a business service +     * @return <code><InfoboxReadRequest></code> as String +     */ +    public String build(boolean businessService, String identityLinkDomainIdentifier) { +        Logger.info("Building InfoBoxReadRequest"); +        String slPrefix; +        String slNsDeclaration; + +//    if (slVersion12) { +        slPrefix = SL12_PREFIX; +        slNsDeclaration = SL12_NS_URI; +//    } else { +//      slPrefix = SL10_PREFIX; +//      slNsDeclaration = SL10_NS_URI; +//    } + +        StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); +        sb.append("<"); +        sb.append(slPrefix); +        sb.append(":InfoboxReadRequest xmlns:"); +        sb.append(slPrefix); +        sb.append("=\""); +        sb.append(slNsDeclaration); +        sb.append("\">"); +        sb.append("<"); +        sb.append(slPrefix); +        sb.append(":InfoboxIdentifier>IdentityLink</"); +        sb.append(slPrefix); +        sb.append(":InfoboxIdentifier>"); +        sb.append("<"); +        sb.append(slPrefix); +        sb.append(":BinaryFileParameters ContentIsXMLEntity=\"true\"/>"); +        if (businessService) { +            sb.append("<"); +            sb.append(slPrefix); +            sb.append(":BoxSpecificParameters>"); +            sb.append("<"); +            sb.append(slPrefix); +            sb.append(":IdentityLinkDomainIdentifier>"); +            sb.append(identityLinkDomainIdentifier); +            sb.append("</sl:IdentityLinkDomainIdentifier>"); +            sb.append("</"); +            sb.append(slPrefix); +            sb.append(":BoxSpecificParameters>"); +        } +        sb.append("</"); +        sb.append(slPrefix); +        sb.append(":InfoboxReadRequest>"); + +        return sb.toString(); + +    } + + +    /** +     * Builds an <code><InfoboxReadRequest></code>. +     * +     * @param slVersion12                  specifies whether the Security Layer version is +     *                                     version 1.2 or not +     * @param businessService              specifies whether the online application is a +     *                                     business service or not +     * @param identityLinkDomainIdentifier the identification number of the business +     *                                     company; maybe <code>null</code> if the OA +     *                                     is a public service; must not be <code>null</code> +     *                                     if the OA is a business service +     * @return <code><InfoboxReadRequest></code> as String +     * +     */ +    public String buildStorkReadRequest(String identityLinkDomainIdentifier) { +        Logger.info("Building Stork InfoBoxReadRequest for " + identityLinkDomainIdentifier); + +        String slPrefix; +        String slNsDeclaration; + +        slPrefix = SL12_PREFIX; +        slNsDeclaration = SL12_NS_URI; + +        StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); +        sb.append("<"); +        sb.append(slPrefix); +        sb.append(":InfoboxReadRequest xmlns:"); +        sb.append(slPrefix); +        sb.append("=\""); +        sb.append(slNsDeclaration); +        sb.append("\">"); +        sb.append("<"); +        sb.append(slPrefix); +        sb.append(":InfoboxIdentifier>IdentityLink</"); +        sb.append(slPrefix); +        sb.append(":InfoboxIdentifier>"); +        sb.append("<"); +        sb.append(slPrefix); +        sb.append(":BinaryFileParameters ContentIsXMLEntity=\"true\"/>"); + +        // append box parameters - necessary for stork? +        sb.append("<"); +        sb.append(slPrefix); +        sb.append(":BoxSpecificParameters>"); +        sb.append("<"); +        sb.append(slPrefix); +        sb.append(":IdentityLinkDomainIdentifier>"); +        sb.append(identityLinkDomainIdentifier); +        sb.append("</sl:IdentityLinkDomainIdentifier>"); +        sb.append("</"); +        sb.append(slPrefix); +        sb.append(":BoxSpecificParameters>"); +        // end appending box parameters + +        sb.append("</"); +        sb.append(slPrefix); +        sb.append(":InfoboxReadRequest>"); + +        return sb.toString(); + +    } + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilderCertificate.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilderCertificate.java new file mode 100644 index 000000000..bb3533664 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilderCertificate.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.builder; + +import at.gv.egovernment.moa.util.Constants; + +/** + * Builder for the <code><InfoboxReadRequest></code> structure + * used for requesting the identity link from the security layer implementation. + *  + * @author Paul Ivancsics + * @version $Id: InfoboxReadRequestBuilder.java 1087 2008-08-28 07:55:59Z mcentner $ + */ +public class InfoboxReadRequestBuilderCertificate implements Constants { + + +  /** +   * Constructor for InfoboxReadRequestBuilder. +   */ +  public InfoboxReadRequestBuilderCertificate() { +  } +    +   +  /** +   * Builds an <code><InfoboxReadRequest></code>. +   *  +   * @param slVersion12           specifies whether the Security Layer version is +   *                              version 1.2 or not +   * @param businessService       specifies whether the online application is a +   *                              business service or not +   * @param identityLinkDomainIdentifier  the identification number of the business  +   *                              company; maybe <code>null</code> if the OA +   *                              is a public service; must not be <code>null</code> +   *                              if the OA is a business service +   *  +   * @return <code><InfoboxReadRequest></code> as String +   */ +  public String build(boolean slVersion12) { +     +    String slPrefix; +    String slNsDeclaration; +     +    if (slVersion12) { +      slPrefix = SL12_PREFIX; +      slNsDeclaration = SL12_NS_URI; +    } else { +      slPrefix = SL10_PREFIX; +      slNsDeclaration = SL10_NS_URI; +    } +             +    StringBuffer sb = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); +    sb.append("<"); +    sb.append(slPrefix); +    sb.append(":InfoboxReadRequest xmlns:"); +    sb.append(slPrefix); +    sb.append("=\""); +    sb.append(slNsDeclaration); +    sb.append("\">"); +    sb.append("<"); +    sb.append(slPrefix); +    sb.append(":InfoboxIdentifier>Certificates</"); +    sb.append(slPrefix); +    sb.append(":InfoboxIdentifier>"); +    sb.append("<"); +    sb.append(slPrefix); +    sb.append(":AssocArrayParameters>"); +    sb.append("<"); +    sb.append(slPrefix); +    sb.append(":ReadValue Key=\"SecureSignatureKeypair\"/>"); +    sb.append("</"); +    sb.append(slPrefix); +    sb.append(":AssocArrayParameters>"); +    sb.append("</"); +    sb.append(slPrefix); +    sb.append(":InfoboxReadRequest>"); +     +    return sb.toString(); +        +  } + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/LoginConfirmationBuilder.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/LoginConfirmationBuilder.java new file mode 100644 index 000000000..31e4c0578 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/LoginConfirmationBuilder.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +package at.gv.egovernment.moa.id.auth.builder; + + +public class LoginConfirmationBuilder { +		/** private static String NL contains the NewLine representation in Java*/ +	  	private static final String nl = "\n"; +	 +	  	private static final String OA_URL_TAG = "<OA_URL>"; +	  	private static final String FORM_METHOD_TAG = "<FORM_METHOD_URL>"; +	  	private static final String ATTR_NAME_TAG = "<ATTR_NAME_URL>"; +	  	private static final String ATTR_VALUE_TAG = "<ATTR_VALUE_URL>"; +	  	private static final String ATTR_TEMP_TAG = "<ATTR_TEMP_URL>"; +	  	private static final String OA_TAG = "<OA_TAG>"; +	  	private static final String NAME_TAG = "<NAME_URL>"; +	  	 +	  	private static final String METHOD_GET = "GET"; +	  	private static final String METHOD_POST = "POST"; +	  	 +	   +	  	private static final String ATTR_TEMPLATE =  +	  			"  <input type=\"hidden\" " + nl + +	  		    "         name=\"" + ATTR_NAME_TAG + "\"" + nl + +	  		    "         value=\"" + ATTR_VALUE_TAG + "\"/>" + nl; +	  	 +	  	/** default HTML template */ +	  	private static final String DEFAULT_HTML_TEMPLATE =  +	    "<html>" + nl + +	    "<head>" + nl + +	    "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">" + nl + +	    "<title>Anmeldung mit Bürgerkarte</title>" + nl + +	    "</head>" + nl + +	    "<body>" + nl + +	    "<p>Wollen Sie sich als <b>"+NAME_TAG+"</b> bei <b>"+OA_TAG+ +	    "</b> anmelden?</p>" + nl + +	    "<form name=\"GetIdentityLinkForm\"" + nl + +	    "      action=\"" + OA_URL_TAG + "\"" + nl + +	    "      method=\"" + FORM_METHOD_TAG + "\">" + nl + +	    ATTR_TEMP_TAG + +	    "  <input type=\"submit\" value=\"Anmeldung durchführen\"/>" + nl + +	    "</form>" + nl + +	    "</body>" + nl + +	    "</html>"; +	  	 +	  	private String template; +	  	 +	  	public LoginConfirmationBuilder(){ +	  		init(METHOD_GET); +	  	} +	  	 +	  	public LoginConfirmationBuilder(String method) { +	  		init(method); +	  	} +	  	 +	  	public void init(String method) { +	  		if(method.equals(METHOD_POST)) { +	  			template = DEFAULT_HTML_TEMPLATE.replace(FORM_METHOD_TAG, METHOD_POST); +	  		} else { +	  			template = DEFAULT_HTML_TEMPLATE.replace(FORM_METHOD_TAG, METHOD_GET); +	  		} +	  	} +	  	 +	  	public void addParameter(String name, String value) { +	  		String attr_template = ATTR_TEMPLATE + ATTR_TEMP_TAG; +	  		//Logger.info("Attr Template: " + attr_template); +	  		attr_template = attr_template.replace(ATTR_NAME_TAG, name); +	  		//Logger.info("Attr Template: " + attr_template); +	  		attr_template = attr_template.replace(ATTR_VALUE_TAG, value); +	  		//Logger.info("Attr Template: " + attr_template); +	  		template = template.replace(ATTR_TEMP_TAG, attr_template); +	  		//Logger.info("Template: " + template); +	  	} +	  	 +	  	public String finish(String oaURL, String userName, String oa) { +	  		template = template.replace(NAME_TAG, userName); +	  		template = template.replace(OA_TAG, oa); +	  		template = template.replace(OA_URL_TAG, oaURL); +	  		return template.replace(ATTR_TEMP_TAG, ""); +	  	} +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/PersonDataBuilder.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/PersonDataBuilder.java new file mode 100644 index 000000000..333d8680c --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/PersonDataBuilder.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.builder; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import at.gv.egovernment.moa.id.auth.data.IdentityLink; +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.XPathUtils; + +/** + * Builder for the <code>lt;pr:Person></code> element to be inserted + * in the authentication data <code>lt;saml:Assertion></code>. + *  + * @author Paul Ivancsics + * @version $Id$ + */ +public class PersonDataBuilder { + +  /** +   * Constructor for PersonDataBuilder. +   */ +  public PersonDataBuilder() { +    super(); +  } +	/** +	 * Builds the <code><pr:Person></code> element.<br/> +	 * Utilizes the parsed <code><prPerson></code> from the identity link +	 * and the information regarding inclusion of <code>"Stammzahl"</code> in the  +	 * <code><pr:Person></code> data. +	 *  +	 * @param identityLink <code>IdentityLink</code> containing the +	 * 				 attribute <code>prPerson</code> +	 * @param provideStammzahl true if <code>"Stammzahl"</code> is to be included; +	 * 				 false otherwise +	 * @return the <code><pr:Person></code> element as a String +   * @throws BuildException on any error +	 */ +	public String build(IdentityLink identityLink, boolean provideStammzahl)  +		throws BuildException { +			 +    try { +      Element prPerson = (Element)identityLink.getPrPerson().cloneNode(true); +      if (! provideStammzahl) { +        Node prIdentification = XPathUtils.selectSingleNode(prPerson, "pr:Identification/pr:Value");        +        //remove IdentificationValue +        prIdentification.getFirstChild().setNodeValue(""); +      } +      String xmlString = DOMUtils.serializeNode(prPerson); +      return xmlString; +    } +    catch (Exception ex) { +    	throw new BuildException( +    		"builder.00",  +    		new Object[] {"PersonData", ex.toString()},  +    		ex); +    } +	} +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/SAMLResponseBuilder.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/SAMLResponseBuilder.java new file mode 100644 index 000000000..8b0d906fe --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/SAMLResponseBuilder.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.builder; + +import java.text.MessageFormat; + +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.StringUtils; + +/** + * Builder for the <code>lt;samlp:Response></code> used for passing + * result and status information from the <code>GetAuthenticationData</code> + * web service. + *  + * @author Paul Ivancsics + * @version $Id$ + */ +public class SAMLResponseBuilder implements Constants { +	/** XML - Template for samlp:Response */ +	private static final String RESPONSE =  +    "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + +    "<samlp:Response xmlns:samlp=\"" + SAMLP_NS_URI + "\" xmlns:saml=\"" + SAML_NS_URI + "\"" + +    " ResponseID=\"{0}\" InResponseTo=\"{1}\" MajorVersion=\"1\" MinorVersion=\"0\" IssueInstant=\"{2}\">" + +    "  <samlp:Status>" + +    "    <samlp:StatusCode Value=\"{3}\">" + +    "      {4}" + +    "    </samlp:StatusCode>" + +    "    <samlp:StatusMessage>{5}</samlp:StatusMessage>" + +    "  </samlp:Status>" + +    "  {6}" + +    "</samlp:Response>"; +  /** XML - Template for samlp:StatusCode */   +  private static final String SUB_STATUS_CODE =  +    "<samlp:StatusCode Value=\"{0}\"></samlp:StatusCode>"; +	 +  /** +   * Constructor for SAMLResponseBuilder. +   */ +  public SAMLResponseBuilder() { +    super(); +  } +  /** +   * Builds the SAML response. +   * @param responseID response ID +   * @param inResponseTo request ID of <code>lt;samlp:Request></code> responded to +   * @param issueInstant current timestamp +   * @param statusCode status code +   * @param subStatusCode sub-status code refining the status code; may be <code>null</code> +   * @param statusMessage status message +   * @param samlAssertion SAML assertion representing authentication data +   * @return SAML response as a DOM element +	 */ +  public Element build( +  	String responseID,  +  	String inResponseTo,  +  	String issueInstant,  +  	String statusCode,  +  	String subStatusCode,  +  	String statusMessage,  +  	String samlAssertion) +  	throws BuildException { +  	 +  	try { +	  	String xmlSubStatusCode =  +	  		subStatusCode == null ?  +	  		"" :  +	  		MessageFormat.format(SUB_STATUS_CODE, new Object[] {subStatusCode}); +	  	 +	  	String xmlResponse = MessageFormat.format(RESPONSE, new Object[] { +  			responseID,  +        inResponseTo,  +        issueInstant,  +        statusCode,  +        xmlSubStatusCode,  +        statusMessage,  +        StringUtils.removeXMLDeclaration(samlAssertion) }); +  		Element domResponse = DOMUtils.parseDocument(xmlResponse, false, ALL_SCHEMA_LOCATIONS, null).getDocumentElement(); +		  return domResponse; +  	} +  	catch (Throwable ex) { +  		throw new BuildException( +  			"builder.00", +  			new Object[] { "samlp:Response", ex.toString() }, +  			ex); +  	} +  } + + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/StartAuthenticationBuilder.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/StartAuthenticationBuilder.java new file mode 100644 index 000000000..5c1b12e0d --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/StartAuthenticationBuilder.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +package at.gv.egovernment.moa.id.auth.builder; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import at.gv.egovernment.moa.id.auth.AuthenticationServer; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; +import at.gv.egovernment.moa.logging.Logger; + +public class StartAuthenticationBuilder { + +	private static StartAuthenticationBuilder instance = null; +	 +	public static StartAuthenticationBuilder getInstance() { +		if (instance == null) { +			instance = new StartAuthenticationBuilder(); +		} +		return instance; +	} +	 +	 +	/** +	 * Depending on the selected citizen's country ({@code moasession.ccc}): +	 * <ul> +	 * <li><strong>Either</strong> creates an "IdentityLinkForm" with embedded {@code InfoBoxReadRequest} to be submitted to a citizen card +	 * environment for reading the subject's IdentityLink</li> +	 * </ul> +	 *  +	 * @return The IdentityLinkForm. +	 */ +	public String build(AuthenticationSession moasession, HttpServletRequest req, +			HttpServletResponse resp) throws WrongParametersException, MOAIDException { +		 +		if (moasession == null) { +			throw new AuthenticationException("auth.18", new Object[] { }); +		} +		   +    	//normal MOA-ID authentication +    	Logger.debug("Starting normal MOA-ID authentication"); +	    			    	    	 +    	String getIdentityLinkForm = AuthenticationServer.getInstance().startAuthentication(moasession, req);	    + +    	return getIdentityLinkForm; +	} +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/VerifyXMLSignatureRequestBuilder.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/VerifyXMLSignatureRequestBuilder.java new file mode 100644 index 000000000..d2ea53011 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/builder/VerifyXMLSignatureRequestBuilder.java @@ -0,0 +1,408 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.builder; + +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import at.gv.egovernment.moa.id.auth.data.CreateXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.data.IdentityLink; +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.util.Base64Utils; +import at.gv.egovernment.moa.util.Constants; + +/** + * Builder for the <code><VerifyXMLSignatureRequestBuilder></code> structure + * used for sending the DSIG-Signature of the Security Layer card for validating to MOA-SP. + *  + * @author Stefan Knirsch + * @version $Id$ + */ +public class VerifyXMLSignatureRequestBuilder { +   +  /** shortcut for XMLNS namespace URI */ +  private static final String XMLNS_NS_URI = Constants.XMLNS_NS_URI; +  /** shortcut for MOA namespace URI */ +  private static final String MOA_NS_URI = Constants.MOA_NS_URI; +  /** The DSIG-Prefix */ +  private static final String DSIG = Constants.DSIG_PREFIX + ":"; +   +  /** The document containing the <code>VerifyXMLsignatureRequest</code> */ +  private Document requestDoc_; +  /** the <code>VerifyXMLsignatureRequest</code> root element */ +  private Element requestElem_; +   +   +  /** +   * Builds the body for a <code>VerifyXMLsignatureRequest</code> including the root +   * element and namespace declarations. +   *  +   * @throws BuildException If an error occurs on building the document. +   */ +  public VerifyXMLSignatureRequestBuilder() throws BuildException { +    try { +      DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();         +      requestDoc_ = docBuilder.newDocument(); +      requestElem_ = requestDoc_.createElementNS(MOA_NS_URI, "VerifyXMLSignatureRequest"); +      requestElem_.setAttributeNS(XMLNS_NS_URI, "xmlns", MOA_NS_URI); +      requestElem_.setAttributeNS(XMLNS_NS_URI, "xmlns:" + Constants.DSIG_PREFIX, Constants.DSIG_NS_URI); +      requestDoc_.appendChild(requestElem_);        +    } catch (Throwable t) { +      throw new BuildException( +        "builder.00",  +        new Object[] {"VerifyXMLSignatureRequest", t.toString()},  +        t); +    } +  } +   +   +  /** +   * Builds a <code><VerifyXMLSignatureRequest></code> +   * from an IdentityLink with a known trustProfileID which  +   * has to exist in MOA-SP +   * @param identityLink - The IdentityLink +   * @param trustProfileID - a preconfigured TrustProfile at MOA-SP +   *  +   * @return Element - The complete request as Dom-Element +   *  +   * @throws ParseException +   */ +  public Element build(IdentityLink identityLink, String trustProfileID) +    throws ParseException  +  {  +    try { +      // build the request +      Element dateTimeElem = requestDoc_.createElementNS(MOA_NS_URI, "DateTime"); +      requestElem_.appendChild(dateTimeElem); +      Node dateTime = requestDoc_.createTextNode(identityLink.getIssueInstant()); +      dateTimeElem.appendChild(dateTime); +      Element verifiySignatureInfoElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); +      requestElem_.appendChild(verifiySignatureInfoElem); +      Element verifySignatureEnvironmentElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); +      verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); +      Element base64ContentElem = requestDoc_.createElementNS(MOA_NS_URI, "Base64Content"); +      verifySignatureEnvironmentElem.appendChild(base64ContentElem); +      // insert the base64 encoded identity link SAML assertion +      String serializedAssertion = identityLink.getSerializedSamlAssertion(); +      String base64EncodedAssertion = Base64Utils.encode(serializedAssertion.getBytes("UTF-8")); +      //replace all '\r' characters by no char. +      StringBuffer replaced = new StringBuffer(); +      for (int i = 0; i < base64EncodedAssertion.length(); i ++) { +        char c = base64EncodedAssertion.charAt(i); +        if (c != '\r') { +          replaced.append(c); +        } +      } +      base64EncodedAssertion = replaced.toString(); +      Node base64Content = requestDoc_.createTextNode(base64EncodedAssertion); +      base64ContentElem.appendChild(base64Content);       +      // specify the signature location +      Element verifySignatureLocationElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); +      verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); +      Node signatureLocation = requestDoc_.createTextNode(DSIG + "Signature"); +      verifySignatureLocationElem.appendChild(signatureLocation);       +      // signature manifest params +      Element signatureManifestCheckParamsElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); +      requestElem_.appendChild(signatureManifestCheckParamsElem); +      signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "false"); +      // add the transforms +      Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); +      signatureManifestCheckParamsElem.appendChild(referenceInfoElem); +      Element[] dsigTransforms = identityLink.getDsigReferenceTransforms(); +       +      for (int i = 0; i < dsigTransforms.length; i++) {         +        Element verifyTransformsInfoProfileElem =  +          requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfile"); +        referenceInfoElem.appendChild(verifyTransformsInfoProfileElem); +        verifyTransformsInfoProfileElem.appendChild(requestDoc_.importNode(dsigTransforms[i], true));         +      } +      Element returnHashInputDataElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); +      requestElem_.appendChild(returnHashInputDataElem); +      Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); +      trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); +      requestElem_.appendChild(trustProfileIDElem); +    } catch (Throwable t) { +      throw new ParseException("builder.00",  +        new Object[] { "VerifyXMLSignatureRequest (IdentityLink)" }, t); +    } + +    return requestElem_; +  } +   +  /** +   * Builds a <code><VerifyXMLSignatureRequest></code> +   * from an IdentityLink with a known trustProfileID which  +   * has to exist in MOA-SP +   * @param identityLink - The IdentityLink +   * @param trustProfileID - a preconfigured TrustProfile at MOA-SP +   *  +   * @return Element - The complete request as Dom-Element +   *  +   * @throws ParseException +   */ +  public Element build(byte[]mandate, String trustProfileID) +    throws ParseException  +  {  +    try { +      // build the request +//      Element dateTimeElem = requestDoc_.createElementNS(MOA_NS_URI, "DateTime"); +//      requestElem_.appendChild(dateTimeElem); +//      Node dateTime = requestDoc_.createTextNode(identityLink.getIssueInstant()); +//      dateTimeElem.appendChild(dateTime); +      Element verifiySignatureInfoElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); +      requestElem_.appendChild(verifiySignatureInfoElem); +      Element verifySignatureEnvironmentElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); +      verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); +      Element base64ContentElem = requestDoc_.createElementNS(MOA_NS_URI, "Base64Content"); +      verifySignatureEnvironmentElem.appendChild(base64ContentElem); +      // insert the base64 encoded identity link SAML assertion +      //String serializedAssertion = identityLink.getSerializedSamlAssertion(); +      //String base64EncodedAssertion = Base64Utils.encode(mandate.getBytes("UTF-8")); +      String base64EncodedAssertion = Base64Utils.encode(mandate); +      //replace all '\r' characters by no char. +      StringBuffer replaced = new StringBuffer(); +      for (int i = 0; i < base64EncodedAssertion.length(); i ++) { +        char c = base64EncodedAssertion.charAt(i); +        if (c != '\r') { +          replaced.append(c); +        } +      } +      base64EncodedAssertion = replaced.toString(); +      Node base64Content = requestDoc_.createTextNode(base64EncodedAssertion); +      base64ContentElem.appendChild(base64Content);       +      // specify the signature location +      Element verifySignatureLocationElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); +      verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); +      Node signatureLocation = requestDoc_.createTextNode(DSIG + "Signature"); +      verifySignatureLocationElem.appendChild(signatureLocation);       +      // signature manifest params +      Element signatureManifestCheckParamsElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); +      requestElem_.appendChild(signatureManifestCheckParamsElem); +      signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "false"); +//      // add the transforms +//      Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); +//      signatureManifestCheckParamsElem.appendChild(referenceInfoElem); +//      Element[] dsigTransforms = identityLink.getDsigReferenceTransforms(); +//       +//      for (int i = 0; i < dsigTransforms.length; i++) {         +//        Element verifyTransformsInfoProfileElem =  +//          requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfile"); +//        referenceInfoElem.appendChild(verifyTransformsInfoProfileElem); +//        verifyTransformsInfoProfileElem.appendChild(requestDoc_.importNode(dsigTransforms[i], true));         +//      } +      Element returnHashInputDataElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); +      requestElem_.appendChild(returnHashInputDataElem); +      Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); +      trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); +      requestElem_.appendChild(trustProfileIDElem); +    } catch (Throwable t) { +      throw new ParseException("builder.00",  +        new Object[] { "VerifyXMLSignatureRequest (IdentityLink)" }, t); +    } + +    return requestElem_; +  } +   +   +  /** +   * Builds a <code><VerifyXMLSignatureRequest></code> +   * from the signed AUTH-Block with a known trustProfileID which  +   * has to exist in MOA-SP +   * @param csr - signed AUTH-Block +   * @param verifyTransformsInfoProfileID - allowed verifyTransformsInfoProfileID  +   * @param trustProfileID - a preconfigured TrustProfile at MOA-SP +   * @return Element - The complete request as Dom-Element +   * @throws ParseException +   */ +  public Element build( +    CreateXMLSignatureResponse csr, +    List<String> verifyTransformsInfoProfileID, +    String trustProfileID) +    throws BuildException { //samlAssertionObject +     +    try { +      // build the request +//      requestElem_.setAttributeNS(Constants.XMLNS_NS_URI, "xmlns:"  +//        + Constants.XML_PREFIX, Constants.XMLNS_NS_URI); +      Element verifiySignatureInfoElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); +      requestElem_.appendChild(verifiySignatureInfoElem); +      Element verifySignatureEnvironmentElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); +      verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); +      Element xmlContentElem = requestDoc_.createElementNS(MOA_NS_URI, "XMLContent"); +      verifySignatureEnvironmentElem.appendChild(xmlContentElem); +      xmlContentElem.setAttribute(Constants.XML_PREFIX + ":space", "preserve"); +      // insert the SAML assertion +      xmlContentElem.appendChild(requestDoc_.importNode(csr.getSamlAssertion(), true));           +      // specify the signature location +      Element verifySignatureLocationElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); +      verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); +      Node signatureLocation = requestDoc_.createTextNode(DSIG + "Signature"); +      verifySignatureLocationElem.appendChild(signatureLocation);       +      // signature manifest params +      Element signatureManifestCheckParamsElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); +      requestElem_.appendChild(signatureManifestCheckParamsElem); +      signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "true"); +      // add the transform profile IDs +      Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); +        signatureManifestCheckParamsElem.appendChild(referenceInfoElem); +         +//      for (int i = 0; i < verifyTransformsInfoProfileID.length; i++) { +//    	   +//        Element verifyTransformsInfoProfileIDElem =  +//          requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfileID"); +//        referenceInfoElem.appendChild(verifyTransformsInfoProfileIDElem); +//        verifyTransformsInfoProfileIDElem.appendChild( +//          requestDoc_.createTextNode(verifyTransformsInfoProfileID[i]));         +//      } +       +        for (String element : verifyTransformsInfoProfileID) { +      	   +            Element verifyTransformsInfoProfileIDElem =  +              requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfileID"); +            referenceInfoElem.appendChild(verifyTransformsInfoProfileIDElem); +            verifyTransformsInfoProfileIDElem.appendChild( +              requestDoc_.createTextNode(element));         +          } +         +      Element returnHashInputDataElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); +      requestElem_.appendChild(returnHashInputDataElem); +      Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); +      trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); +      requestElem_.appendChild(trustProfileIDElem); + +    } catch (Throwable t) { +      throw new BuildException("builder.00", new Object[] { "VerifyXMLSignatureRequest" }, t); +    } + +    return requestElem_; +  } +   +  /** +   * Builds a <code><VerifyXMLSignatureRequest></code> +   * from the signed data with a known trustProfileID which  +   * has to exist in MOA-SP +   * @param csr - signed AUTH-Block +   * @param trustProfileID - a preconfigured TrustProfile at MOA-SP +   * @return Element - The complete request as Dom-Element +   * @throws ParseException +   */ +  public Element buildDsig( +    CreateXMLSignatureResponse csr, +    String trustProfileID) +    throws BuildException { //samlAssertionObject +     +    try { +      // build the request +//      requestElem_.setAttributeNS(Constants.XMLNS_NS_URI, "xmlns:"  +//        + Constants.XML_PREFIX, Constants.XMLNS_NS_URI); +      +      Element verifiySignatureInfoElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); +      requestElem_.appendChild(verifiySignatureInfoElem); +      Element verifySignatureEnvironmentElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); +      verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); +       +      Element xmlContentElem = requestDoc_.createElementNS(MOA_NS_URI, "XMLContent"); +      verifySignatureEnvironmentElem.appendChild(xmlContentElem); +      xmlContentElem.setAttribute(Constants.XML_PREFIX + ":space", "preserve"); +       +      // insert the dsig:Signature +      xmlContentElem.appendChild(requestDoc_.importNode(csr.getDsigSignature(), true));           +      // specify the signature location +      Element verifySignatureLocationElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); +      verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); +      Node signatureLocation = requestDoc_.createTextNode("/"+ DSIG + "Signature"); +      verifySignatureLocationElem.appendChild(signatureLocation);       +      // signature manifest params +      Element signatureManifestCheckParamsElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); +      requestElem_.appendChild(signatureManifestCheckParamsElem); +      signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "true"); +      // add the transform profile IDs +      Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); +        signatureManifestCheckParamsElem.appendChild(referenceInfoElem); +         +      Element returnHashInputDataElem =  +        requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); +      requestElem_.appendChild(returnHashInputDataElem); +      Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); +       +      trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); +      requestElem_.appendChild(trustProfileIDElem); + +    } catch (Throwable t) { +      throw new BuildException("builder.00", new Object[] { "VerifyXMLSignatureRequest" }, t); +    } + +    return requestElem_; +  } + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java new file mode 100644 index 000000000..72a7d3ba1 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.invoke; + +import java.util.Vector; + +import javax.xml.namespace.QName; +import javax.xml.rpc.Call; +import javax.xml.rpc.Service; +import javax.xml.rpc.ServiceFactory; + +import org.apache.axis.message.SOAPBodyElement; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.id.auth.exception.ServiceException; +import at.gv.egovernment.moa.id.config.ConnectionParameter; +import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.spss.api.SignatureVerificationService; +import at.gv.egovernment.moa.spss.api.xmlbind.VerifyXMLSignatureRequestParser; +import at.gv.egovernment.moa.spss.api.xmlbind.VerifyXMLSignatureResponseBuilder; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest; +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; +import at.gv.egovernment.moa.util.MiscUtil; + +/** + * Invoker of the <code>SignatureVerification</code> web service of MOA-SPSS.<br> + * Either invokes the web service, or calls the corresponding API, depending on configuration data. + *  + * @author Stefan Knirsch + * @version $Id$ + */ +public class SignatureVerificationInvoker { +  /** This QName Object identifies the SignatureVerification endpoint of the web service */ +  private static final QName SERVICE_QNAME = new QName("SignatureVerification"); + +  /** +   * Method verifyXMLSignature. +   * @param request to be sent +   * @return Element with the answer +   * @throws ServiceException if an error occurs +   */ +  public Element verifyXMLSignature(Element request) throws ServiceException { +    return doCall(SERVICE_QNAME, request); +  } + +  /** +   * Method doCall. +   * @param serviceName the name of the service +   * @param request the request to be sent +   * @return Element the answer +   * @throws ServiceException if an error occurs +   */ +  protected Element doCall(QName serviceName, Element request) throws ServiceException { +    ConnectionParameter authConnParam = null; +    try { +      Service service = ServiceFactory.newInstance().createService(serviceName); +      Call call = service.createCall(); +      SOAPBodyElement body = new SOAPBodyElement(request); +      SOAPBodyElement[] params = new SOAPBodyElement[] { body }; +      Vector responses; +      SOAPBodyElement response; + +      String endPoint; +      AuthConfiguration authConfigProvider = AuthConfigurationProviderFactory.getInstance(); +      authConnParam = authConfigProvider.getMoaSpConnectionParameter(); +      //If the ConnectionParameter do NOT exist, we try to get the api to work.... +      if (authConnParam != null && MiscUtil.isNotEmpty(authConnParam.getUrl())) { +        Logger.debug("Connecting using auth url: " + authConnParam.getUrl() + ", service " + serviceName.getNamespaceURI() + " : " + serviceName.getLocalPart() + " : "+ serviceName.getPrefix()); +        endPoint = authConnParam.getUrl(); +        call.setTargetEndpointAddress(endPoint); +        responses = (Vector) call.invoke(serviceName, params); +        Logger.debug("Got responses: " + responses.size()); // TODO handle axis 302 response when incorrect service url is used +        response = (SOAPBodyElement) responses.get(0); +        return response.getAsDOM(); +      } +      else { +        SignatureVerificationService svs = SignatureVerificationService.getInstance(); +        VerifyXMLSignatureRequest vsrequest = new VerifyXMLSignatureRequestParser().parse(request); +		 +        VerifyXMLSignatureResponse vsresponse = svs.verifyXMLSignature(vsrequest); +        Document result = new VerifyXMLSignatureResponseBuilder().build(vsresponse); + +        //Logger.setHierarchy("moa.id.auth"); +        return result.getDocumentElement(); +      } +    } +    catch (Exception ex) { +      if (authConnParam != null) { +	      throw new ServiceException("service.00", new Object[] { ex.toString()}, ex); +      } else { +        throw new ServiceException("service.03", new Object[] { ex.toString()}, ex); +      } +    } +  } +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/DefaultAuthModuleImpl.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/DefaultAuthModuleImpl.java new file mode 100644 index 000000000..8ae4a9999 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/DefaultAuthModuleImpl.java @@ -0,0 +1,28 @@ +package at.gv.egovernment.moa.id.auth.modules.internal; + +import org.apache.commons.lang3.StringUtils; + +import at.gv.egovernment.moa.id.auth.modules.AuthModule; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; + +/** + * Module descriptor + */ +public class DefaultAuthModuleImpl implements AuthModule { + +	@Override +	public int getPriority() { +		return 0; +	} + +	@Override +	public String selectProcess(ExecutionContext context) { +		return StringUtils.isBlank((String) context.get("ccc")) ? "DefaultAuthentication" : null; +	} + +	@Override +	public String[] getProcessDefinitions() { +		return new String[] { "classpath:at/gv/egovernment/moa/id/auth/modules/internal/DefaultAuthentication.process.xml" }; +	} + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/CertificateReadRequestTask.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/CertificateReadRequestTask.java new file mode 100644 index 000000000..7e1bf1fc7 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/CertificateReadRequestTask.java @@ -0,0 +1,103 @@ +package at.gv.egovernment.moa.id.auth.modules.internal.tasks; + +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.commons.lang3.BooleanUtils; + +import at.gv.egovernment.moa.id.auth.AuthenticationServer; +import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder; +import at.gv.egovernment.moa.id.auth.builder.InfoboxReadRequestBuilderCertificate; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; +import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; + +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; +import at.gv.egovernment.moa.id.util.CitizenCardServletUtils; +import at.gv.egovernment.moa.id.util.ParamValidatorUtils; +import at.gv.egovernment.moa.logging.Logger; + +/** + * Creates {@code InfoBoxReadRequest} in order to read the subject's certificates.<p/> + * In detail: + * <ul> + * <li>Renames the moa session id.</li> + * <li>Creates {@code InfoBoxReadRequest} in order to read the subject's certificates.</li> + * <li>Responds with {@code InfoBoxReadRequest} (for CCE), {@code DataURL} is {@code /VerifyCertificate}</li> + * </ul> + * Expects: + * <ul> + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}</li> + * </ul> + * Result: + * <ul> + * <li>Responds with {@code InfoBoxReadRequest} (for CCE), {@code DataURL} is {@code /VerifyCertificate}</li> + * </ul> + * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.VerifyIdentityLinkServlet}. + * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse) + * + */ +public class CertificateReadRequestTask extends AbstractAuthServletTask { + +	@Override +	public void execute(ExecutionContext executionContext, HttpServletRequest req, HttpServletResponse resp) +			throws TaskExecutionException { + +		// TODO[branch]: Foreign citizen or mandate mode; respond with IRR for certificates, dataURL = "/VerifyCertificate" +		Logger.info("Send InfoboxReadRequest to BKU to get signer certificate."); + +		setNoCachingHeaders(resp);		 +		try { +		 +			String sessionID = StringEscapeUtils.escapeHtml(req.getParameter(PARAM_SESSIONID)); +			 +			// check parameter +			if (!ParamValidatorUtils.isValidSessionID(sessionID)) { +				throw new WrongParametersException("CertificateReadRequestTask", PARAM_SESSIONID, "auth.12"); +			} + +			AuthenticationSession session = AuthenticationServer.getSession(sessionID); + +			boolean useMandate = session.getUseMandate(); +			boolean identityLinkAvailable = BooleanUtils.isTrue((Boolean) executionContext.get("identityLinkAvailable")); +			 +			if (!identityLinkAvailable && useMandate) { +				Logger.error("Online-Mandate Mode for foreign citizencs not supported."); +				throw new AuthenticationException("auth.13", null); +			} + +			// change MOASessionID +			AuthenticationSessionStoreage.changeSessionID(session); +			 +			// create the InfoboxReadRequest to get the certificate +			String infoboxReadRequest = new InfoboxReadRequestBuilderCertificate().build(true); + +			// build dataurl (to the VerifyCertificateSerlvet) +			String dataurl = new DataURLBuilder().buildDataURL(session.getAuthURL(), REQ_VERIFY_CERTIFICATE, +					session.getSessionID()); + +			CitizenCardServletUtils.writeCreateXMLSignatureRequest(resp, infoboxReadRequest, +					AuthenticationServer.REQ_PROCESS_VALIDATOR_INPUT, "VerifyIdentityLink", dataurl); +		 +		} catch (MOAIDException ex) { +			throw new TaskExecutionException(ex.getMessage(), ex); +					 +		} catch (IOException e) { +			throw new TaskExecutionException(e.getMessage(), e); +			 +		} finally { +			 +		}		 + +	} + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/CreateIdentityLinkFormTask.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/CreateIdentityLinkFormTask.java new file mode 100644 index 000000000..20f102571 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/CreateIdentityLinkFormTask.java @@ -0,0 +1,138 @@ +package at.gv.egovernment.moa.id.auth.modules.internal.tasks; + +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*; + +import java.io.PrintWriter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.ObjectUtils; + +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; +import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger; +import at.gv.egovernment.moa.id.advancedlogging.TransactionIDUtils; +import at.gv.egovernment.moa.id.auth.builder.StartAuthenticationBuilder; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; +import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; +import at.gv.egovernment.moa.id.auth.servlet.GenerateIFrameTemplateServlet; + +import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.moduls.RequestStorage; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; +import at.gv.egovernment.moa.util.StringUtils; + +/** + * Creates a http form including an embedded {@code InfoBoxReadRequest} for reading the identity link.<p/> + * In detail: + * <ul> + * <li>Renames the moa session id.</li> + * <li>Removes ExecutionContext property {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}.</li> + * <li>Creates the http form mentioned above.</li> + * <li>Returns the http form via HttpServletResponse.</li> + * </ul> + * Expects: + * <ul> + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID} <strong>or</strong></li> + * <li>ExecutionContext property {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID} (in case of legacy authentication without CCE selection, where the moa session is not provided by request parameter).</li> + * </ul> + * Result: + * <ul> + * <li>The identity link form via HttpServletResponse.</li> + * </ul> + * Possible branches: + * <ul> + * <li>In case of STORK authentication + * <ul> + * <li>Creates STORK auth SAML request.</li> + * <li>Creates and returns a form for submitting the SAML request to the CPEPS (post binding).</li> + * <li>Returns the form via HttpServletResponse.</li> + * </ul> + * </li> + * </ul> + * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.GenerateIFrameTemplateServlet}. + * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse) + * + */ +public class CreateIdentityLinkFormTask extends AbstractAuthServletTask { + +	@Override +	public void execute(ExecutionContext executionContext, HttpServletRequest req, HttpServletResponse resp) +			throws TaskExecutionException { + +		String moasessionid = StringEscapeUtils.escapeHtml(ObjectUtils.defaultIfNull(req.getParameter(PARAM_SESSIONID), (String) executionContext.get(PARAM_SESSIONID))); +		AuthenticationSession moasession = null; +		try { +			 +			if (MiscUtil.isEmpty(moasessionid)) { +				Logger.warn("MOASessionID is empty."); +				throw new MOAIDException("auth.18", new Object[] {}); +			} +			 +			try {			 +				moasession = AuthenticationSessionStoreage.getSession(moasessionid); + +				AuthenticationSessionStoreage.changeSessionID(moasession); +				executionContext.remove(PARAM_SESSIONID); +			 +			} catch (MOADatabaseException e) { +				Logger.info("MOASession with SessionID=" + moasessionid + " is not found in Database"); +				throw new MOAIDException("init.04", new Object[] { moasessionid }); + +			} catch (Throwable e) { +				Logger.info("No HTTP Session found!"); +				throw new MOAIDException("auth.18", new Object[] {}); +			} + +			StartAuthenticationBuilder startauth = StartAuthenticationBuilder.getInstance(); +			String getIdentityLinkForm = startauth.build(moasession, req, resp); + +			IRequest pendingReq = RequestStorage.getPendingRequest( +					(String) executionContext.get("pendingRequestID")); +			 +			if (BooleanUtils.isTrue((Boolean) executionContext.get("useMandate"))) +				MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),  +						pendingReq, MOAIDEventConstants.AUTHPROCESS_MANDATES_REQUESTED);			 +			MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),  +					pendingReq, MOAIDEventConstants.AUTHPROCESS_BKU_URL, moasession.getBkuURL()); +			 +			if (!StringUtils.isEmpty(getIdentityLinkForm)) { +				resp.setContentType("text/html;charset=UTF-8"); +				PrintWriter out = new PrintWriter(resp.getOutputStream()); +				out.print(getIdentityLinkForm); +				out.flush(); +				Logger.debug("Finished GET " + GenerateIFrameTemplateServlet.class); +			} +			 +		} catch (WrongParametersException ex) { +//			handleWrongParameters(ex, req, resp); +			throw new TaskExecutionException(ex.getMessage(), ex); +		} + +		catch (MOAIDException ex) { +//			handleError(null, ex, req, resp, pendingRequestID); +			throw new TaskExecutionException(ex.getMessage(), ex); + +		} catch (Exception e) { +			Logger.error("CreateIdentityLinkFormTask has an interal Error.", e); +			throw new TaskExecutionException(e.getMessage(), e); + +		} + +		finally { +			 +			TransactionIDUtils.removeTransactionId(); +			TransactionIDUtils.removeSessionId(); +		} +	} + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/FinalizeAuthenticationTask.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/FinalizeAuthenticationTask.java new file mode 100644 index 000000000..28bed7713 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/FinalizeAuthenticationTask.java @@ -0,0 +1,118 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules.internal.tasks; + +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.PARAM_SESSIONID; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +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.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; +import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.moduls.ModulUtils; +import at.gv.egovernment.moa.id.moduls.RequestStorage; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; + +/** + * @author tlenz + * + */ +public class FinalizeAuthenticationTask extends AbstractAuthServletTask { + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) +	 */ +	@Override +	public void execute(ExecutionContext executionContext, +			HttpServletRequest request, HttpServletResponse response) +			throws TaskExecutionException { +		 +		try { +			IRequest pendingReq = RequestStorage.getPendingRequest( +					(String) executionContext.get("pendingRequestID"));	 +		 +			//get Session from context +			String moasessionid = (String) executionContext.get(PARAM_SESSIONID); +			AuthenticationSession session = null;				 +			if (MiscUtil.isEmpty(moasessionid)) { +				Logger.warn("MOASessionID is empty."); +				throw new MOAIDException("auth.18", new Object[] {}); +			} +			 +			try {			 +				session = AuthenticationSessionStoreage.getSession(moasessionid); +				AuthenticationSessionStoreage.changeSessionID(session); +							 +			} catch (MOADatabaseException e) { +				Logger.info("MOASession with SessionID=" + moasessionid + " is not found in Database"); +				throw new MOAIDException("init.04", new Object[] { moasessionid }); + +			} catch (Throwable e) { +				Logger.info("No HTTP Session found!"); +				throw new MOAIDException("auth.18", new Object[] {}); +			 +			} finally { +				executionContext.remove(PARAM_SESSIONID); +			 +			} +		 +		 +			session.setAuthenticatedUsed(false); +			session.setAuthenticated(true); + + +			String oldsessionID = session.getSessionID(); + +			//Session is implicte stored in changeSessionID!!! +			String newMOASessionID = AuthenticationSessionStoreage.changeSessionID(session); +		 +			Logger.info("AuthProcess finished. Redirect to Protocol Dispatcher."); +			 +			String redirectURL = new DataURLBuilder().buildDataURL(session.getAuthURL(),  +					ModulUtils.buildAuthURL(session.getModul(), session.getAction(), pendingReq.getRequestID()), newMOASessionID); +				 +			response.setContentType("text/html"); +			response.setStatus(302); +			response.addHeader("Location", redirectURL);		 +			Logger.debug("REDIRECT TO: " + redirectURL); +			 +		} catch (MOAIDException e) { +			throw new TaskExecutionException(e.getMessage(), e); +			 +		} catch (Exception e) { +			Logger.warn("FinalizeAuthenticationTask has an internal error", e); +			throw new TaskExecutionException(e.getMessage(), e); +			 +		} + +	} + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GetForeignIDTask.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GetForeignIDTask.java new file mode 100644 index 000000000..b729f26e1 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GetForeignIDTask.java @@ -0,0 +1,192 @@ +package at.gv.egovernment.moa.id.auth.modules.internal.tasks; + +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.security.cert.CertificateException; +import java.util.Map; + +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.Element; + +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; +import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger; +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.CreateXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.data.IdentityLink; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; +import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; +import at.gv.egovernment.moa.id.auth.parser.CreateXMLSignatureResponseParser; +import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser; +import at.gv.egovernment.moa.id.client.SZRGWClientException; +import at.gv.egovernment.moa.id.client.utils.SZRGWClientUtils; +import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.moduls.ModulUtils; +import at.gv.egovernment.moa.id.moduls.RequestStorage; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; +import at.gv.egovernment.moa.id.util.ParamValidatorUtils; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.util.xsd.srzgw.CreateIdentityLinkResponse; + +/** + * Evaluates the {@code CreateXMLSignatureResponse}, extracts signature and certificate and asks the SZR Gateway for an identity link.<p/> + * In detail: + * <ul> + * <li>Renames the moa session id.</li> + * <li>Parses the CreateXMLSignatureResponse retrieved from POST parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE}.</li> + * <li>Extracts signature and signer certificate.</li> + * <li>Send request to SZR Gateway in order to get an identity link.</li> + * <li>Updates moa session (sets identity link, QAA level 4, authentication data and foreigner flag).</li> + * <li>Redirects back to {@code /dispatcher} in order to finalize authentication.</li> + * </ul> + * Expects: + * <ul> + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}</li> + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE} containing a {@code CreateXMLSignatureResponse}.</li> + * </ul> + * Result: + * <ul> + * <li>Identity link, QAA level 4 and foreigner flag put into moa session.</li> + * <li>Redirect to {@code /dispatcher}.</li> + * </ul> + * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.GetForeignIDServlet}. + * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse) + * + */ +public class GetForeignIDTask extends AbstractAuthServletTask { + +	@Override +	public void execute(ExecutionContext executionContext, HttpServletRequest req, HttpServletResponse resp) +			throws TaskExecutionException { + +		Logger.debug("POST GetForeignIDServlet"); + +		setNoCachingHeaders(resp); + +		Map<String, String> parameters; + +		try { +			parameters = getParameters(req); +			 +		} catch (FileUploadException | IOException e) { +			Logger.error("Parsing mulitpart/form-data request parameters failed: " + e.getMessage()); +			throw new TaskExecutionException("Parsing mulitpart/form-data request parameters failed", new IOException(e.getMessage())); +		} +		 +		String sessionID = StringEscapeUtils.escapeHtml(req.getParameter(PARAM_SESSIONID)); +		String pendingRequestID = null; +		String redirectURL = null; +		AuthenticationSession session = null; +		try { +			// check parameter +			if (!ParamValidatorUtils.isValidSessionID(sessionID)) { +				throw new WrongParametersException("GetForeignID", PARAM_SESSIONID, "auth.12"); +			} +			String xmlCreateXMLSignatureResponse = (String) parameters.get(PARAM_XMLRESPONSE); +			if (!ParamValidatorUtils.isValidXMLDocument(xmlCreateXMLSignatureResponse)) { +				throw new WrongParametersException("GetForeignID", PARAM_XMLRESPONSE, "auth.12"); +			} +			pendingRequestID = AuthenticationSessionStoreage.getPendingRequestID(sessionID); +			session = AuthenticationServer.getSession(sessionID); + +			IRequest pendingReq = RequestStorage.getPendingRequest( +					(String) executionContext.get("pendingRequestID"));			 +			MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),  +					pendingReq, MOAIDEventConstants.AUTHPROCESS_BKU_DATAURL_IP, req.getRemoteHost()); +			 +			// change MOASessionID +			sessionID = AuthenticationSessionStoreage.changeSessionID(session); + +			Logger.debug(xmlCreateXMLSignatureResponse); + +			CreateXMLSignatureResponse csresp = new CreateXMLSignatureResponseParser(xmlCreateXMLSignatureResponse) +					.parseResponseDsig(); + +			try { +				String serializedAssertion = DOMUtils.serializeNode(csresp.getDsigSignature()); +				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 }); + +			} +			 +			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); +			} + +			MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),  +					pendingReq, MOAIDEventConstants.AUTHPROCESS_FOREIGN_SZRGW_CONNECTED); +			 +			// make SZR request to the identity link +			CreateIdentityLinkResponse response = SZRGWClientUtils.getIdentityLink(signature); + +			if (null != response.getErrorResponse()) { +				// TODO fix exception parameter +				throw new SZRGWClientException("service.08", (String) response.getErrorResponse().getErrorCode(), +						(String) response.getErrorResponse().getInfo()); +			} else { +				IdentityLinkAssertionParser ilParser = new IdentityLinkAssertionParser(new ByteArrayInputStream( +						response.getIdentityLink())); +				IdentityLink identitylink = ilParser.parseIdentityLink(); +				session.setIdentityLink(identitylink); + +				// set QAA Level four in case of card authentifcation +				session.setQAALevel(PVPConstants.STORK_QAA_1_4); + +				AuthenticationServer.getInstance().getForeignAuthenticationData(session); + +				// session is implicit stored in changeSessionID!!!! +				String newMOASessionID = AuthenticationSessionStoreage.changeSessionID(session); + +				Logger.info("Changed MOASession " + sessionID + " to Session " + newMOASessionID); +				Logger.info("Daten angelegt zu MOASession " + newMOASessionID); +				 +				MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),  +						pendingReq, MOAIDEventConstants.AUTHPROCESS_FOREIGN_SZRGW_RECEIVED); +				 +				try { +					AuthenticationSessionStoreage.storeSession(session); +				} catch (MOADatabaseException e) { +					throw new MOAIDException("Session store error", null); +				} + +				//put session to context  +				executionContext.put(PARAM_SESSIONID, session.getSessionID()); +			} + +		} catch (MOAIDException ex) { +			throw new TaskExecutionException(ex.getMessage(), ex); + +		} catch (Exception e) { +			Logger.error("GetForeignIDServlet has an interal Error.", e); +			throw new TaskExecutionException(e.getMessage(), e); + +		} + +	} + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GetMISSessionIDTask.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GetMISSessionIDTask.java new file mode 100644 index 000000000..d85681b40 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GetMISSessionIDTask.java @@ -0,0 +1,184 @@ +package at.gv.egovernment.moa.id.auth.modules.internal.tasks; + +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*; +import iaik.pki.PKIException; + +import java.security.GeneralSecurityException; +import java.util.List; + +import javax.net.ssl.SSLSocketFactory; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.commons.lang.StringEscapeUtils; +import org.xml.sax.SAXException; + +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; +import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger; +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.exception.AuthenticationException; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; +import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; + +import at.gv.egovernment.moa.id.config.ConnectionParameter; +import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.id.data.MISMandate; +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.moduls.ModulUtils; +import at.gv.egovernment.moa.id.moduls.RequestStorage; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; +import at.gv.egovernment.moa.id.util.ParamValidatorUtils; +import at.gv.egovernment.moa.id.util.SSLUtils; +import at.gv.egovernment.moa.id.util.client.mis.simple.MISSimpleClient; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.DOMUtils; + +/** + * Retrieves a mandate from the online mandate issuing service.<p/> + * In detail: + * <ul> + * <li>Renames the moa session id.</li> + * <li>Retrieves the mandate referenced within the moa session from the online (external) mandate issuing service.</li> + * <li>Verifies the mandate.</li> + * <li>Puts mandate into moa session.</li> + * <li>Redirects back to {@code /dispatcher} in order to finalize the authentication.</li> + * </ul> + * Expects: + * <ul> + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}</li> + * </ul> + * Result: + * <ul> + * <li>Mandate put into moa session.</li> + * <li>Redirect to {@code /dispatcher}.</li> + * </ul> + * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.GetMISSessionIDServlet}. + * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse) + * + */ +public class GetMISSessionIDTask extends AbstractAuthServletTask { + +	@Override +	public void execute(ExecutionContext executionContext, HttpServletRequest req, HttpServletResponse resp) +			throws TaskExecutionException { +		 +		Logger.debug("POST GetMISSessionIDServlet"); + +		String sessionID = req.getParameter(PARAM_SESSIONID); + +		// escape parameter strings +		sessionID = StringEscapeUtils.escapeHtml(sessionID); + +		AuthenticationSession session = null; +		String pendingRequestID = null; +		try { +			// check parameter +			if (!ParamValidatorUtils.isValidSessionID(sessionID)) +				throw new WrongParametersException("VerifyCertificate", +						PARAM_SESSIONID, "auth.12"); + +			pendingRequestID = AuthenticationSessionStoreage.getPendingRequestID(sessionID); +			 +			session = AuthenticationServer.getSession(sessionID); + +			IRequest pendingReq = RequestStorage.getPendingRequest( +					(String) executionContext.get("pendingRequestID"));			 +			 +			//change MOASessionID +		    sessionID = AuthenticationSessionStoreage.changeSessionID(session); +			 +			String misSessionID = session.getMISSessionID(); + +			AuthConfiguration authConf = AuthConfigurationProviderFactory +					.getInstance(); +			ConnectionParameter connectionParameters = authConf +					.getOnlineMandatesConnectionParameter(); +			SSLSocketFactory sslFactory = SSLUtils.getSSLSocketFactory( +					AuthConfigurationProviderFactory.getInstance(), +					connectionParameters); + +			List<MISMandate> list = MISSimpleClient.sendGetMandatesRequest( +					connectionParameters.getUrl(), misSessionID, sslFactory); + +			if (list == null || list.size() == 0) { +				Logger.error("Keine Vollmacht gefunden."); +				throw new AuthenticationException("auth.15", null); +			} + +			MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),  +					pendingReq, MOAIDEventConstants.AUTHPROCESS_MANDATE_RECEIVED); + +			 +			// for now: list contains only one element +			MISMandate mandate = (MISMandate) list.get(0); + +			// TODO[tlenz]: UTF-8 ? +			String sMandate = new String(mandate.getMandate()); +			if (sMandate == null || sMandate.compareToIgnoreCase("") == 0) { +				Logger.error("Mandate is empty."); +				throw new AuthenticationException("auth.15", +						new Object[] { GET_MIS_SESSIONID }); +			} +						 +			//check if it is a parsable XML +			byte[] byteMandate = mandate.getMandate(); +			// TODO[tlenz]: UTF-8 ? +			String stringMandate = new String(byteMandate); +			DOMUtils.parseDocument(stringMandate, false, +					null, null).getDocumentElement(); +			 +			// extract RepresentationType +			AuthenticationServer.getInstance().verifyMandate(session, mandate); +			 +			session.setMISMandate(mandate); +			 +			//log mandate specific set of events +			MOAReversionLogger.getInstance().logMandateEventSet(pendingReq, mandate); +						 +			String oldsessionID = session.getSessionID(); +			 +			//Session is implicite stored in changeSessionID!!! +			String newMOASessionID = AuthenticationSessionStoreage.changeSessionID(session); +			 +			Logger.info("Changed MOASession " + oldsessionID + " to Session " + newMOASessionID); +			Logger.info("Daten angelegt zu MOASession " + newMOASessionID); + +			//put session to context  +			executionContext.put(PARAM_SESSIONID, session.getSessionID()); +			 + +		} catch (MOAIDException ex) { +			throw new TaskExecutionException(ex.getMessage(), ex); +			 +		} catch (GeneralSecurityException ex) { +			throw new TaskExecutionException(ex.getMessage(), ex); +			 +		} catch (PKIException e) { +			throw new TaskExecutionException(e.getMessage(), e); +			 +		} catch (SAXException e) { +			throw new TaskExecutionException(e.getMessage(), e); +			 +		} catch (ParserConfigurationException e) { +			throw new TaskExecutionException(e.getMessage(), e); +			 +	    } catch (Exception e) { +	    	Logger.error("MISMandateValidation has an interal Error.", e); +	    	throw new TaskExecutionException(e.getMessage(), e); +	        +	    } +	    finally { +	    	 +	    } +		 +	} + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/PrepareAuthBlockSignatureTask.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/PrepareAuthBlockSignatureTask.java new file mode 100644 index 000000000..469ca91a9 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/PrepareAuthBlockSignatureTask.java @@ -0,0 +1,101 @@ +package at.gv.egovernment.moa.id.auth.modules.internal.tasks; + +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.StringEscapeUtils; + +import at.gv.egovernment.moa.id.auth.AuthenticationServer; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; +import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; + +import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; +import at.gv.egovernment.moa.id.util.CitizenCardServletUtils; +import at.gv.egovernment.moa.id.util.ParamValidatorUtils; +import at.gv.egovernment.moa.logging.Logger; + +/** + * Creates {@code CreateXMLSignatureRequest} for auth block signature.<p/> + * In detail: + * <ul> + * <li>Renames the moa session id.</li> + * <li>Creates {@code CreateXMLSignatureRequest} for auth block signature.</li> + * <li>Responds with {@code CreateXMLSignatureRequest} (for CCE), {@code DataURL} is {@code /VerifyAuthBlock}</li> + * </ul> + * Expects: + * <ul> + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}</li> + * </ul> + * Result: + * <ul> + * <li>Responds with {@code CreateXMLSignatureRequest} (for CCE), {@code DataURL} is {@code /VerifyAuthBlock}</li> + * </ul> + * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.VerifyIdentityLinkServlet}. + * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse) + * + */ +public class PrepareAuthBlockSignatureTask extends AbstractAuthServletTask { + +	@Override +	public void execute(ExecutionContext executionContext, HttpServletRequest req, HttpServletResponse resp) +			throws TaskExecutionException { +		// note: code taken from at.gv.egovernment.moa.id.auth.servlet.VerifyIdentityLinkServlet + +		Logger.debug("Process IdentityLink"); + +		setNoCachingHeaders(resp); +		 +		String pendingRequestID = null; + +		try { +			 +			String sessionID = StringEscapeUtils.escapeHtml(req.getParameter(PARAM_SESSIONID)); +			 +			// check parameter +			if (!ParamValidatorUtils.isValidSessionID(sessionID)) { +				throw new WrongParametersException("VerifyIdentityLink", PARAM_SESSIONID, "auth.12"); +			} + +			pendingRequestID = AuthenticationSessionStoreage.getPendingRequestID(sessionID); + +			AuthenticationSession session = AuthenticationServer.getSession(sessionID); + +			// change MOASessionID +			sessionID = AuthenticationSessionStoreage.changeSessionID(session); +				 +			OAAuthParameter oaParam = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter( +					session.getPublicOAURLPrefix()); +			AuthConfiguration authConf = AuthConfigurationProviderFactory.getInstance(); + +			String createXMLSignatureRequest = AuthenticationServer.getInstance() +					.getCreateXMLSignatureRequestAuthBlockOrRedirect(session, authConf, oaParam); + +			AuthenticationSessionStoreage.storeSession(session); +			 +			CitizenCardServletUtils.writeCreateXMLSignatureRequestOrRedirect(resp, session, +					createXMLSignatureRequest, AuthenticationServer.REQ_PROCESS_VALIDATOR_INPUT, +					"VerifyIdentityLink"); + +		} catch (MOAIDException ex) { +			throw new TaskExecutionException(ex.getMessage(), ex); + +		} catch (Exception e) { +			Logger.error("IdentityLinkValidation has an interal Error.", e); +			throw new TaskExecutionException(e.getMessage(), e); +		} + +		finally { +			 +		} +	} + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/PrepareGetMISMandateTask.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/PrepareGetMISMandateTask.java new file mode 100644 index 000000000..099bc085c --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/PrepareGetMISMandateTask.java @@ -0,0 +1,207 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules.internal.tasks; + +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.GET_MIS_SESSIONID; +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.PARAM_SESSIONID; + +import java.util.List; + +import javax.net.ssl.SSLSocketFactory; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; +import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger; +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.exception.AuthenticationException; +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.id.auth.exception.MISSimpleClientException; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; +import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.id.config.ConnectionParameter; +import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.moduls.RequestStorage; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; +import at.gv.egovernment.moa.id.util.SSLUtils; +import at.gv.egovernment.moa.id.util.client.mis.simple.MISSessionId; +import at.gv.egovernment.moa.id.util.client.mis.simple.MISSimpleClient; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.MiscUtil; + +/** + * @author tlenz + * + */ +public class PrepareGetMISMandateTask extends AbstractAuthServletTask { + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) +	 */ +	@Override +	public void execute(ExecutionContext executionContext, +			HttpServletRequest request, HttpServletResponse response) +			throws TaskExecutionException { + +		//mandate Mode +		try { +			IRequest pendingReq = RequestStorage.getPendingRequest( +					(String) executionContext.get("pendingRequestID"));	 +			 +			//get Session from context +			String moasessionid = (String) executionContext.get(PARAM_SESSIONID); +			AuthenticationSession session = null;				 +			if (MiscUtil.isEmpty(moasessionid)) { +				Logger.warn("MOASessionID is empty."); +				throw new MOAIDException("auth.18", new Object[] {}); +			} +				 +			try {			 +				session = AuthenticationSessionStoreage.getSession(moasessionid); +				AuthenticationSessionStoreage.changeSessionID(session); +								 +			} catch (MOADatabaseException e) { +				Logger.info("MOASession with SessionID=" + moasessionid + " is not found in Database"); +				throw new MOAIDException("init.04", new Object[] { moasessionid }); + +			} catch (Throwable e) { +				Logger.info("No HTTP Session found!"); +				throw new MOAIDException("auth.18", new Object[] {}); +				 +			} finally { +				executionContext.remove(PARAM_SESSIONID); +				 +			} + +			 +		  AuthConfiguration authConf= AuthConfigurationProviderFactory.getInstance(); +			ConnectionParameter connectionParameters = authConf.getOnlineMandatesConnectionParameter();	 +			SSLSocketFactory sslFactory = SSLUtils.getSSLSocketFactory(AuthConfigurationProviderFactory.getInstance(), connectionParameters); +			 +			// get identitity link as byte[] +			Element elem = session.getIdentityLink().getSamlAssertion(); +			String s = DOMUtils.serializeNode(elem); +			 +			//System.out.println("IDL: " + s); +			 +			byte[] idl = s.getBytes("UTF-8"); +			 +			// redirect url +			// build redirect(to the GetMISSessionIdSerlvet) +			 +			//change MOASessionID before MIS request +			String newMOASessionID = AuthenticationSessionStoreage.changeSessionID(session); +			 +	        String redirectURL = new DataURLBuilder().buildDataURL( +			    session.getAuthURL(), +			    GET_MIS_SESSIONID, +			    newMOASessionID); +			 +	        String oaURL = session.getOAURLRequested(); +	        IOAAuthParameters oaParam = pendingReq.getOnlineApplicationConfiguration(); +	        if (oaParam == null) { +	        	oaParam = authConf.getOnlineApplicationParameter(oaURL); +	        	Logger.info("No Service info in PendingRequest --> load service info from configuration"); +	        	 +	        } +	         +	        List<String> profiles = oaParam.getMandateProfiles(); + +	        if (profiles == null) { +	      	  Logger.error("No Mandate/Profile for OA configured."); +	      	  throw new AuthenticationException("config.21", new Object[] { GET_MIS_SESSIONID}); +	        } +	         +	        String oaFriendlyName = oaParam.getFriendlyName(); +	        String mandateReferenceValue = session.getMandateReferenceValue(); +	        byte[] cert = session.getEncodedSignerCertificate(); +	        byte[] authBlock = session.getAuthBlock().getBytes("UTF-8"); +	         +	        //TODO: check in case of SSO!!! +	        String targetType = null;   +	        if(oaParam.getBusinessService()) { +	        	String id = oaParam.getIdentityLinkDomainIdentifier(); +	        	if (id.startsWith(AuthenticationSession.REGISTERANDORDNR_PREFIX_)) +	        		targetType = id; +	        	else +	        		targetType = AuthenticationSession.REGISTERANDORDNR_PREFIX_+session.getDomainIdentifier(); +	        	 +	        } else { +	        	targetType = AuthenticationSession.TARGET_PREFIX_ + oaParam.getTarget(); +	        } +	         +	        MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),  +					pendingReq, MOAIDEventConstants.AUTHPROCESS_MANDATE_SERVICE_REQUESTED, mandateReferenceValue); +	         +	        MISSessionId misSessionID = MISSimpleClient.sendSessionIdRequest( +	        		connectionParameters.getUrl(),  +	        		idl,  +	        		cert,  +	        		oaFriendlyName,  +	        		redirectURL,  +	        		mandateReferenceValue,  +	        		profiles,  +	        		targetType, +	        		authBlock, +	        		sslFactory); +	         +	        if (misSessionID == null) { +	      	  Logger.error("Fehler bei Anfrage an Vollmachten Service. MIS Session ID ist null."); +	      	  throw new MISSimpleClientException("Fehler bei Anfrage an Vollmachten Service."); +	        } +	         +	        String redirectMISGUI = misSessionID.getRedirectURL(); +	        session.setMISSessionID(misSessionID.getSessiondId()); +		 +			try { +				AuthenticationSessionStoreage.storeSession(session); +				 +			} catch (MOADatabaseException | BuildException e) { +				throw new MOAIDException("Session store error", null); +				 +			} +	        			 +			MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),  +					pendingReq, MOAIDEventConstants.AUTHPROCESS_MANDATE_REDIRECT); +			 +	        response.setStatus(302); +	    	response.addHeader("Location", redirectMISGUI); +	    	Logger.debug("REDIRECT TO: " + redirectMISGUI); +	    	 +		} catch (Exception e ) { +			throw new TaskExecutionException(e.getMessage(), e); +			 +		}  +	} + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/VerifyAuthenticationBlockTask.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/VerifyAuthenticationBlockTask.java new file mode 100644 index 000000000..35104bf3e --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/VerifyAuthenticationBlockTask.java @@ -0,0 +1,160 @@ +package at.gv.egovernment.moa.id.auth.modules.internal.tasks; + +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*; +import iaik.pki.PKIException; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.List; +import java.util.Map; + +import javax.net.ssl.SSLSocketFactory; +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.Element; + +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; +import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger; +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.exception.AuthenticationException; +import at.gv.egovernment.moa.id.auth.exception.MISSimpleClientException; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; +import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; + +import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.id.config.ConnectionParameter; +import at.gv.egovernment.moa.id.config.auth.AuthConfiguration; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.moduls.ModulUtils; +import at.gv.egovernment.moa.id.moduls.RequestStorage; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; +import at.gv.egovernment.moa.id.util.ParamValidatorUtils; +import at.gv.egovernment.moa.id.util.SSLUtils; +import at.gv.egovernment.moa.id.util.client.mis.simple.MISSessionId; +import at.gv.egovernment.moa.id.util.client.mis.simple.MISSimpleClient; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.DOMUtils; + +/** + * Verifies the signed authentication block (provided as {@code CreateXMLSignatureResponse}).<p/> + * In detail: + * <ul> + * <li>Renames the moa session id.</li> + * <li>Takes the {@code CreateXMLSignatureResponse} from POST parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE}.</li> + * <li>Verifies the {@code CreateXMLSignatureResponse}.</li> + * <li>Updates moa session.</li> + * <li>Redirects back to {@code /dispatcher} in order to finalize the authentication.</li> + * </ul> + * Expects: + * <ul> + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}</li> + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE} containing a {@code CreateXMLSignatureResponse}.</li> + * </ul> + * Result: + * <ul> + * <li>Authentication data put into moa session.</li> + * <li>Redirect to {@code /dispatcher}.</li> + * </ul> + * Possible branches: + * <ul> + * <li>In case of mandate mode + * <ul> + * <li>Creates a mandate session at the external mandate issuing service.</li> + * <li>Redirects the user's browser to the online mandate issuing service GUI.</li> + * </ul> + * </li> + * </ul> + * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.VerifyAuthenticationBlockServlet}. + * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse) + * + */ +public class VerifyAuthenticationBlockTask extends AbstractAuthServletTask { + +	@Override +	public void execute(ExecutionContext executionContext, HttpServletRequest req, HttpServletResponse resp) +			throws TaskExecutionException { + +		// note: code taken from at.gv.egovernment.moa.id.auth.servlet.VerifyAuthenticationBlockServlet +		 +		Logger.debug("POST VerifyAuthenticationBlock"); +		 +		String pendingRequestID = null;		 +		 +	    Map<String, String> parameters; +	    try  +	    { +	      parameters = getParameters(req); +	       +	    } catch (FileUploadException | IOException e)  +	    { +	      Logger.error("Parsing mulitpart/form-data request parameters failed: " + e.getMessage()); +	      throw new TaskExecutionException("Parsing mulitpart/form-data request parameters failed", new IOException(e.getMessage())); +	    } +	       +			String sessionID = req.getParameter(PARAM_SESSIONID); +			String createXMLSignatureResponse = (String)parameters.get(PARAM_XMLRESPONSE); + +			// escape parameter strings +			sessionID = StringEscapeUtils.escapeHtml(sessionID); +			pendingRequestID = AuthenticationSessionStoreage.getPendingRequestID(sessionID); +		   		 +			String redirectURL = null; +			try { +	         // check parameter +	         if (!ParamValidatorUtils.isValidSessionID(sessionID)) +	            throw new WrongParametersException("VerifyAuthenticationBlock", PARAM_SESSIONID, "auth.12"); +	         if (!ParamValidatorUtils.isValidXMLDocument(createXMLSignatureResponse)) +	            throw new WrongParametersException("VerifyAuthenticationBlock", PARAM_XMLRESPONSE, "auth.12"); + +				AuthenticationSession session = AuthenticationServer.getSession(sessionID); + +				IRequest pendingReq = RequestStorage.getPendingRequest( +						(String) executionContext.get("pendingRequestID"));			 +				MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),  +						pendingReq, MOAIDEventConstants.AUTHPROCESS_BKU_DATAURL_IP, req.getRemoteHost()); +								 +				//change MOASessionID +			    sessionID = AuthenticationSessionStoreage.changeSessionID(session); +				 +				AuthenticationServer.getInstance().verifyAuthenticationBlock(pendingReq, session, createXMLSignatureResponse); +				 +				//store all changes in session DAO +				AuthenticationSessionStoreage.storeSession(session); +				 +				//put session to context  +				executionContext.put(PARAM_SESSIONID, session.getSessionID()); +				 +			} +	     +			catch (MOAIDException ex) { +				throw new TaskExecutionException(ex.getMessage(), ex); +				 +			 +				 +		    } catch (Exception e) { +		    	Logger.error("AuthBlockValidation has an interal Error.", e); +		    	throw new TaskExecutionException(e.getMessage(), e); +		    	 +		    } +		        +			 +		    finally { +		    	 +		    }		 +		 +		 +		 +	} + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/VerifyCertificateTask.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/VerifyCertificateTask.java new file mode 100644 index 000000000..d99ba873d --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/VerifyCertificateTask.java @@ -0,0 +1,175 @@ +package at.gv.egovernment.moa.id.auth.modules.internal.tasks; + +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*; +import iaik.x509.X509Certificate; + +import java.io.IOException; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.lang.StringEscapeUtils; + +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; +import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger; +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.exception.AuthenticationException; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; +import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; + +import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.moduls.RequestStorage; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; +import at.gv.egovernment.moa.id.util.CitizenCardServletUtils; +import at.gv.egovernment.moa.id.util.ParamValidatorUtils; +import at.gv.egovernment.moa.id.util.ServletUtils; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.spss.util.CertificateUtils; + +/** + * Parses the certificate from {@code InfoBoxReadResponse} (via POST parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE}), creates the auth block to be signed and returns a {@code CreateXMLSignatureRequest} for auth block signature.<p/> + * In detail: + * <ul> + * <li>Renames the moa session id.</li> + * <li>Retrieves the certificate via {@code InfoBoxReadResponse} from POST parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE}.</li> + * <li>Verifies the certificate.</li> + * <li>Creates the auth block to be signed using information from the certificate (Organwalter, foreign citizen.</li> + * <li>Puts it in a {@code CreateXMLSignatureRequest}.</li> + * <li>Updates moa session.</li> + * <li>Responds with {@code CreateXMLSignatureRequest}.</li> + * </ul> + * Expects: + * <ul> + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}</li> + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_SESSIONID} containing a {@code InfoBoxReadResponse}.</li> + * </ul> + * Result: + * <ul> + * <li>{@code CreateXMLSignatureRequest} send as HttpServletResponse (for CCE).</li> + * </ul> + * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.VerifyCertificateServlet}. + * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse) + * + */ +public class VerifyCertificateTask extends AbstractAuthServletTask { + +	@Override +	public void execute(ExecutionContext executionContext, HttpServletRequest req, HttpServletResponse resp) +			throws TaskExecutionException { + +		// note: code taken from at.gv.egovernment.moa.id.auth.servlet.VerifyCertificateServlet + +		Logger.debug("POST VerifyCertificateServlet"); +				 +		Map<String, String> parameters; +	    try  +	    { +	      parameters = getParameters(req); +	    } catch (FileUploadException | IOException e)  +	    { +	      Logger.error("Parsing mulitpart/form-data request parameters failed: " + e.getMessage()); +	      throw new TaskExecutionException("Parsing mulitpart/form-data request parameters failed", new IOException(e.getMessage())); +	     } +	    String sessionID = req.getParameter(PARAM_SESSIONID); +	     +	    // escape parameter strings +		sessionID = StringEscapeUtils.escapeHtml(sessionID); +				 +	    AuthenticationSession session = null; +	    try { +	       // check parameter +	       if (!ParamValidatorUtils.isValidSessionID(sessionID)) +	          throw new WrongParametersException("VerifyCertificate", PARAM_SESSIONID, "auth.12"); +	        +	    	session = AuthenticationServer.getSession(sessionID); +	    	 +			IRequest pendingReq = RequestStorage.getPendingRequest( +					(String) executionContext.get("pendingRequestID"));			 +			MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),  +					pendingReq, MOAIDEventConstants.AUTHPROCESS_BKU_DATAURL_IP, req.getRemoteHost()); +	    		    	 +	        //change MOASessionID +	        sessionID = AuthenticationSessionStoreage.changeSessionID(session); +	    	 +    		X509Certificate cert = AuthenticationServer.getInstance().getCertificate(pendingReq, sessionID, parameters); +    		if (cert == null) { +    			Logger.error("Certificate could not be read."); +    			throw new AuthenticationException("auth.14", null);    		 +    		} +    		 +	    	boolean useMandate = session.getUseMandate(); +	    	 +	    	if (useMandate) { + +	    		// verify certificate for OrganWalter +	    		String createXMLSignatureRequestOrRedirect = AuthenticationServer.getInstance().verifyCertificate(session, cert); +	    		 +		    	try { +					AuthenticationSessionStoreage.storeSession(session); +				} catch (MOADatabaseException e) { +					throw new MOAIDException("session store error", null); +				} +	    		 +		    	// TODO[branch]: Mandate; respond with CXSR for authblock signature, dataURL "/VerifyAuthBlock" +		    	CitizenCardServletUtils.writeCreateXMLSignatureRequestOrRedirect(resp, session, createXMLSignatureRequestOrRedirect, AuthenticationServer.REQ_PROCESS_VALIDATOR_INPUT, "VerifyCertificate"); +	    		 +	    	} +	    	else { +	    					    	 +	    		String countrycode = CertificateUtils.getIssuerCountry(cert); +	    		if (countrycode != null) { +	    			if (countrycode.compareToIgnoreCase("AT") == 0) { +	    				Logger.error("Certificate issuer country code is \"AT\". Login not support in foreign identities mode."); +	    				throw new AuthenticationException("auth.22", null); +	    			} +	    		} +	    		 +	    		// Foreign Identities Modus	 +	    		MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),  +						pendingReq, MOAIDEventConstants.AUTHPROCESS_FOREIGN_FOUND); +	    		 +		    	String createXMLSignatureRequest = AuthenticationServer.getInstance().createXMLSignatureRequestForeignID(session, cert); +		      // build dataurl (to the GetForeignIDSerlvet) +		    	String dataurl = +	             new DataURLBuilder().buildDataURL( +	               session.getAuthURL(), +	               REQ_GET_FOREIGN_ID, +	               session.getSessionID()); +	        +		    	try { +					AuthenticationSessionStoreage.storeSession(session); +				} catch (MOADatabaseException e) { +					throw new MOAIDException("session store error", null); +				} +		    	 +	    		// TODO[branch]: Foreign citizen; respond with CXSR for authblock signature, dataURL "/GetForeignID" +		    	CitizenCardServletUtils.writeCreateXMLSignatureRequest(resp, createXMLSignatureRequest, AuthenticationServer.REQ_PROCESS_VALIDATOR_INPUT, "GetForeignID", dataurl); +		    	 +		    	Logger.debug("Send CreateXMLSignatureRequest to BKU"); +	    	}	    		    	  +	    } +	    catch (MOAIDException ex) { +	    	throw new TaskExecutionException(ex.getMessage(), ex); +	       +	    } catch (Exception e) { +	    	Logger.error("CertificateValidation has an interal Error.", e); +	    	throw new TaskExecutionException(e.getMessage(), e); +	    	 +	    } +	        +	     +	    finally { +	    	 +	    } + +	} + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/VerifyIdentityLinkTask.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/VerifyIdentityLinkTask.java new file mode 100644 index 000000000..50ef11f27 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/VerifyIdentityLinkTask.java @@ -0,0 +1,111 @@ +package at.gv.egovernment.moa.id.auth.modules.internal.tasks; + +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*; + +import java.io.IOException; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.StringEscapeUtils; + +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; +import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger; +import at.gv.egovernment.moa.id.auth.AuthenticationServer; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; +import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; + +import at.gv.egovernment.moa.id.moduls.IRequest; +import at.gv.egovernment.moa.id.moduls.RequestStorage; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; +import at.gv.egovernment.moa.id.util.ParamValidatorUtils; +import at.gv.egovernment.moa.logging.Logger; + +/** + * Verifies the identity link.<p/> + * In detail: + * <ul> + * <li>Renames the moa session id.</li> + * <li>Parses the identity link retrieved as {@code InfoBoxReadResponse} from POST parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE}.</li> + * <li>Verifies the identity link.</li> + * <li>Updates moa session.</li> + * <li>Puts boolean flag {@code identityLinkAvailable} into {@code ExecutionContext}.</li> + * </ul> + * Expects: + * <ul> + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}</li> + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE} containing a {@code InfoBoxReadResponse}.</li> + * </ul> + * Result: + * <ul> + * <li>Identity link put into moa session.</li> + * <li>Boolean flag {@code identityLinkAvailable} into {@code ExecutionContext}.</li> + * </ul> + * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.VerifyIdentityLinkServlet}. + * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse) + * + */ +public class VerifyIdentityLinkTask extends AbstractAuthServletTask { + +	@Override +	public void execute(ExecutionContext executionContext, HttpServletRequest req, HttpServletResponse resp) +			throws TaskExecutionException { + +		// note: code taken from at.gv.egovernment.moa.id.auth.servlet.VerifyIdentityLinkServlet + +		Logger.debug("POST VerifyIdentityLink"); + +		setNoCachingHeaders(resp); +		 +		Map<String, String> parameters; + +		try { +			parameters = getParameters(req); +		} catch (Exception e) { +			Logger.error("Parsing mulitpart/form-data request parameters failed: " + e.getMessage()); +			throw new TaskExecutionException("Parsing mulitpart/form-data request parameters failed", new IOException(e.getMessage())); +		} +		 +		try { +			 +			String sessionID = StringEscapeUtils.escapeHtml(req.getParameter(PARAM_SESSIONID)); +			// check parameter +			if (!ParamValidatorUtils.isValidSessionID(sessionID)) { +				throw new WrongParametersException("VerifyIdentityLink", PARAM_SESSIONID, "auth.12"); +			} +			AuthenticationSession session = AuthenticationServer.getSession(sessionID); + +			IRequest pendingReq = RequestStorage.getPendingRequest( +					(String) executionContext.get("pendingRequestID"));			 +			MOAReversionLogger.getInstance().logEvent(pendingReq.getOnlineApplicationConfiguration(),  +					pendingReq, MOAIDEventConstants.AUTHPROCESS_BKU_DATAURL_IP, req.getRemoteHost()); +			 +			boolean identityLinkAvailable = AuthenticationServer.getInstance().verifyIdentityLink(pendingReq, session, parameters) != null; +			AuthenticationSessionStoreage.storeSession(session); + +			executionContext.put("identityLinkAvailable", identityLinkAvailable); + +		} catch (ParseException ex) { +			throw new TaskExecutionException(ex.getMessage(), ex); + +		} catch (MOAIDException ex) { +			throw new TaskExecutionException(ex.getMessage(), ex); + +		} catch (Exception e) { +			Logger.error("IdentityLinkValidation has an interal Error.", e); +			throw new TaskExecutionException(e.getMessage(), e); +			 +		} + +		finally { +			 +		} +	} + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/CreateXMLSignatureResponseParser.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/CreateXMLSignatureResponseParser.java new file mode 100644 index 000000000..b39cf9e9b --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/CreateXMLSignatureResponseParser.java @@ -0,0 +1,285 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.parser; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.w3c.dom.traversal.NodeIterator; + +import at.gv.egovernment.moa.id.auth.data.CreateXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.data.SAMLAttribute; +import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; +import at.gv.egovernment.moa.id.auth.exception.BKUException; +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.XPathUtils; + +/** + * Parses an <code><InfoboxReadResponse></code> returned from + * the security layer + *  + * @author Stefan Knirsch + * @version $Id$ + */ + +public class CreateXMLSignatureResponseParser { +  // +  // XPath namespace prefix shortcuts +  // + +  /** Xpath prefix for reaching SAML Namespaces */ +  private static final String SAML = Constants.SAML_PREFIX + ":"; +  /** Xpath prefix for reaching XML-DSIG Namespaces */ +  private static final String DSIG = Constants.DSIG_PREFIX + ":"; +  /** Xpath expression to the root element */ +  private static final String ROOT = ":CreateXMLSignatureResponse/"; +  /** Xpath expression to the SAML:Assertion element */ +  private static final String SAML_ASSERTION_XPATH = ROOT + SAML + "Assertion"; +  /** Xpath expression to the SAML:NameIdentifier element */ +  private static final String SAML_SUBJECT_NAME_IDENTIFIER_XPATH = SAML_ASSERTION_XPATH + "/" + SAML + "AttributeStatement/" + SAML + "Subject/" + SAML + "NameIdentifier"; +  /** Xpath expression to the AttributeStatement element */ +  private static final String SAML_ATTRIBUTE_XPATH = SAML_ASSERTION_XPATH + "/" + SAML + "AttributeStatement/" + SAML + "Attribute"; +  /** Xpath expression to the AttributeValue element */ +  private static final String SAML_ATTRIBUTE_VALUE_XPATH = SAML + "AttributeValue"; +   +   +  /** This is the root element of the CreateXMLsignatureResponse */ +  private Element sigResponse_; + +  /** +   * Parses and validates the document given as string and extracts the  +   * root element. +   *  +   * @param xmlResponse <code><CreateXMLSignatureResponse></code> as String +   *  +   * @throws AuthenticationException if any authentication error occurs +   * @throws ParseException if an element cannot be parsed + * @throws   +   */ +  public CreateXMLSignatureResponseParser(String xmlResponse) throws AuthenticationException, ParseException,  BKUException{ +    try { +      InputStream s = new ByteArrayInputStream(xmlResponse.getBytes("UTF-8")); +      init(s); +    } +     +    catch (BKUException e) { +    	throw e; +    	 +    } catch (Throwable t) { +      throw new ParseException("parser.01", new Object[] { t.toString()}, t); +    } +  } + +  /** +   * Parses and validates the document given as stream and extracts the  +   * root element. +   *  +   * @param is <code><InfoboxReadResponse></code> as InputStream +   *  +   * @throws AuthenticationException If any authentication error occurs +   * @throws ParseException If an element cannot be parsed + * @throws BKUException  +   */ +  public CreateXMLSignatureResponseParser(InputStream is) throws AuthenticationException, ParseException, BKUException { +    init(is);  +  } + +  /** +  * Constructor for CreateXMLSignatureResponseParser. +  * The incoming Element will be used for further operations +  * @param xmlResponse <code><InfoboxReadResponse></code> as InputStream +  */ +  public CreateXMLSignatureResponseParser(Element xmlResponse) { +    sigResponse_ = xmlResponse; +  } +   +  /** +   * Initializes the parser. +   * Parses and validates the document given as stream and extracts the  +   * root element. +   *  +   * @param is  The CreateXMLSignatureResponse as stream. +   * @throws AuthenticationException if an authentication error occurs. +   * @throws ParseException If an error occurs on parsing the the document. + * @throws BKUException  +   */ +  private void init(InputStream is) throws AuthenticationException, ParseException, BKUException { +    try { +       +      Element responseElem = DOMUtils.parseXmlValidating(is); +       +      if ("CreateXMLSignatureResponse".equals(responseElem.getLocalName())) { +        sigResponse_ = responseElem; +      } else { +        ErrorResponseParser erp = new ErrorResponseParser(responseElem); +        throw new BKUException("auth.08",  +        		new Object[] { erp.getErrorCode(), erp.getErrorInfo()},  +        		erp.getErrorCode(),  +        		erp.getErrorInfo()); +      } +       +    } catch (BKUException e) { +    	throw e; +     +  	} catch (Throwable t) { +      throw new ParseException("parser.01", new Object[] { t.toString()}, t); +    } +  } +   +  /** +   * Unmarshalls the <@link sigResponse> to an  +   * <code><CreateXMLSignatureResponse></code> object. +   *  +   * @return a <code><CreateXMLSignatureResponse></code> object +   * @throws ParseException +   */ + +  public CreateXMLSignatureResponse parseResponseDsig() throws ParseException { +    CreateXMLSignatureResponse cResp; +    try { +      cResp = new CreateXMLSignatureResponse(); + +      NodeList list = sigResponse_.getElementsByTagNameNS(Constants.DSIG_NS_URI, "Signature"); +      Element dsigSignatureNode = (Element) list.item(0); +       +      Element dsigSignatureElement = (Element) dsigSignatureNode; +       +      cResp.setDsigSignature(dsigSignatureElement); +    } +    catch (Throwable t) { +      throw new ParseException("parser.01", new Object[] { t.toString()}, t); +    } +    return cResp; +  } + +  /** +   * Unmarshalls the <@link sigResponse> to an  +   * <code><CreateXMLSignatureResponse></code> object. +   *  +   * @return a <code><CreateXMLSignatureResponse></code> object +   * @throws ParseException +   */ + +  public CreateXMLSignatureResponse parseResponse() throws ParseException { +    CreateXMLSignatureResponse cResp; +    try { +      cResp = new CreateXMLSignatureResponse(); +      String slPrefix = XPathUtils.getSlPrefix(sigResponse_); +      cResp.setSamlNameIdentifier(XPathUtils.getElementValue(sigResponse_, "/" + slPrefix + SAML_SUBJECT_NAME_IDENTIFIER_XPATH, null)); +      cResp.setSamlAssertion((Element) XPathUtils.selectSingleNode(sigResponse_, "/" + slPrefix + SAML_ASSERTION_XPATH)); +      NodeIterator attrIter = XPathUtils.selectNodeIterator(sigResponse_, "/" + slPrefix + SAML_ATTRIBUTE_XPATH); +      Element samlAttr; +      List<SAMLAttribute> samlAttributes = new ArrayList<SAMLAttribute>(); +      while ((samlAttr = (Element) attrIter.nextNode()) != null) { +        String attrName = XPathUtils.getAttributeValue(samlAttr, "@AttributeName", ""); +        String attrNamespace = XPathUtils.getAttributeValue(samlAttr, "@AttributeNamespace", ""); +        Object attrValue; +        Element attrValueElem = (Element)XPathUtils.selectSingleNode(samlAttr, SAML_ATTRIBUTE_VALUE_XPATH); +        attrValue = DOMUtils.getElementFromNodeList(attrValueElem.getChildNodes()); +        if (attrValue == null) { +            if (null!=attrValueElem.getFirstChild()) { +          	  attrValue = attrValueElem.getFirstChild().getNodeValue(); +            } else { +          	  attrValue = ""; +            } +        } +        samlAttributes.add(new SAMLAttribute(attrName, attrNamespace, attrValue)); +      } +      SAMLAttribute[] result = new SAMLAttribute[samlAttributes.size()]; +      samlAttributes.toArray(result); +      cResp.setSamlAttributes(result); +       +      NodeList list = sigResponse_.getElementsByTagNameNS(Constants.DSIG_NS_URI, "Signature"); +      Element dsigSignatureNode = (Element) list.item(0);  +      cResp.setDsigSignature(dsigSignatureNode); +       +    } +    catch (Throwable t) { +      throw new ParseException("parser.01", new Object[] { t.toString()}, t); +    } +    return cResp; +  } +   +//  public CreateXMLSignatureResponse parseResponse() throws ParseException { +//    CreateXMLSignatureResponse cResp; +//    try { +//      cResp = new CreateXMLSignatureResponse(); +//      Element samlAssertion = (Element)sigResponse.getElementsByTagNameNS(Constants.SAML_NS_URI, "Assertion").item(0); +//      cResp.setSamlAssertion(samlAssertion); +//      Element samlAttributeStatement = (Element)samlAssertion.getElementsByTagNameNS(Constants.SAML_NS_URI, "AttributeStatement").item(0); +//      Element samlSubject = (Element)samlAttributeStatement.getElementsByTagNameNS(Constants.SAML_NS_URI, "Subject").item(0); +//      Element samlNameIdentifier = (Element)samlSubject.getElementsByTagNameNS(Constants.SAML_NS_URI, "NameIdentifier").item(0); +//      cResp.setSamlNameIdentifier(samlNameIdentifier.getFirstChild().getNodeValue()); +//      NodeList nl = samlAttributeStatement.getElementsByTagNameNS(Constants.SAML_NS_URI, "Attribute"); +//      List samlAttributes = new ArrayList(); +//      for (int i=0; i<nl.getLength(); i++) { +//        Element samlAttribute = (Element)nl.item(i); +//        String attrName = samlAttribute.getAttribute("AttributeName");   +//        String attrNamespace = samlAttribute.getAttribute("AttributeNamespace"); +//        String attrValue = ((Element)samlAttribute.getElementsByTagNameNS(Constants.SAML_NS_URI, "AttributeValue").item(0)).getFirstChild().getNodeValue(); +//        samlAttributes.add(new SAMLAttribute(attrName, attrNamespace, attrValue)); +//      } +//      SAMLAttribute[] result = new SAMLAttribute[samlAttributes.size()]; +//      samlAttributes.toArray(result); +//      cResp.setSamlAttributes(result); +//    } +//    catch (Throwable t) { +//      throw new ParseException("parser.01", new Object[] { t.toString()}, t); +//    } +//    return cResp; +//  } +   +   +  +   +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/ErrorResponseParser.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/ErrorResponseParser.java new file mode 100644 index 000000000..a09f0a2a8 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/ErrorResponseParser.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.parser; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import at.gv.egovernment.moa.id.auth.exception.ParseException; + +/** + * Parses an <code><ErrorResponse></code>. + *  + * @author Stefan Knirsch + * @version $Id$ + */ + +public class ErrorResponseParser { +   +  /** +   * The error code included in this error response. +   * <code>1000</code> is used as default value, if some problems occur on +   * evaluating the error response. +   */ +  private String errorCode_ = "1000"; +   +  /** +   * The error info included in this error response. +   * <code><Unklassifizierter Fehler.></code> is used as default value,  +   * if some problems occur on evaluating the error response. +   */ +  private String errorInfo_ = "Unklassifizierter Fehler."; + +   +  /** +   * This Constructor extracts the error code and error info included in this +   * error response.  +   *  +   * @param errorElement    The error element. This is the root element of +   *                        the error response. +   */ +  public ErrorResponseParser(Element errorElement) throws ParseException { +    if (errorElement != null) { +      String namespace = errorElement.getNamespaceURI(); +      NodeList nl = errorElement.getElementsByTagNameNS(namespace, "ErrorCode"); +      if (nl.getLength() == 1) { +        errorCode_ = ((Element)nl.item(0)).getFirstChild().getNodeValue(); +      } +      nl = errorElement.getElementsByTagNameNS(namespace, "Info"); +      if (nl.getLength() == 1) { +        errorInfo_ = ((Element)nl.item(0)).getFirstChild().getNodeValue(); +      } +    } +  } + +  /** +   * Returns the error code included in this error response. +   */ +  public String getErrorCode() { +    return errorCode_ ;     +  }		 + +  /** +   * Returns the information included in this error response. +   * @return The error infomation String +   */ +  public String getErrorInfo() { +    return errorInfo_ ; +  }    + + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/ExtendedInfoboxReadResponseParser.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/ExtendedInfoboxReadResponseParser.java new file mode 100644 index 000000000..390467bf8 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/ExtendedInfoboxReadResponseParser.java @@ -0,0 +1,203 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.parser; + +import java.util.Iterator; +import java.util.List; +import java.util.Vector; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.id.auth.data.InfoboxToken; +import at.gv.egovernment.moa.id.auth.data.InfoboxTokenImpl; +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; + +/** + * Parses and unmarshales <code>InfoboxReadResponse<code>. + * This parser is especially used for parsing additional responses (additional to that + * one  containing the <code>IdentityLink</code> retuned from the BKU as an answer of + * a <code><PushInfobox></code> request. + */ +public class ExtendedInfoboxReadResponseParser { + +  /** +   * Hide default constructor. +   */ +  private ExtendedInfoboxReadResponseParser() { +  } +   +  /** +   * Parses and unmarshales the given <code>infoboxReadResponse</code> to a list of  +   * {@link at.gv.egovernment.moa.id.auth.data.InfoboxToken InfoboxToken} objects. +   * The method parses the given <code>infoboxReadResponse</code>  +   *  +   * @param infoboxReadResponse The infobox read response to be unmarshaled. +   * @param infoboxName         The name of the infobox the reponse corresponds to. +   *  +   * @return  A list of {@link at.gv.egovernment.moa.id.auth.data.InfoboxToken InfoboxToken}  +   *          objects. Maybe empty. +   *                             +   * @throws ParseException     If an error occurs on parsing and unmarshaling the response. +   */ +  public static List parseInfoboxReadResponse(String infoboxReadResponse, String infoboxName)  +    throws ParseException +  { +    Element infoboxReadResponseElem = null; +    try { +      Document doc =  +        DOMUtils.parseDocument(infoboxReadResponse, true, Constants.ALL_SCHEMA_LOCATIONS, null); +      infoboxReadResponseElem = doc.getDocumentElement(); +    } catch (Exception e) { +      Logger.error("InfoboxReadResponse for \"" + infoboxName +  +        "\"-infobox could not be parsed successfully: " + e.getMessage()); +      throw new ParseException("parser.01", new Object[] {infoboxName + "-InfoboxReadResponse"}); +    }  +     +    Vector infoboxTokenList = new Vector(); +     +    if (infoboxReadResponseElem != null) { +      // avoid using namespace URI or prefix, because it might change within the response +      // (e.g.: sl11-namespace, some child sl10-namespace +      List infoboxReadResponseChildren = DOMUtils.getChildElements(infoboxReadResponseElem); +      String key = null; +      boolean primary = true; +      Element infoboxReadResponseChild = (Element)infoboxReadResponseChildren.get(0); +      String infoboxReadResponseChildName = infoboxReadResponseChild.getLocalName(); +      if (infoboxReadResponseChildName.equals("AssocArrayData")) { +        // get the <Pair> child elements from the <AssocArrayData> element +        List assocArrayPairs = DOMUtils.getChildElements(infoboxReadResponseChild); +        Iterator assocArrayPairIt = assocArrayPairs.iterator(); +        int pairCount = 0; +        // step through the <Pair> elemnts +        while (assocArrayPairIt.hasNext()) { +          Element assocArrayPair = (Element)assocArrayPairIt.next(); +          // check if the element actually a "Pair" element and not only a "key" +          if (assocArrayPair.getLocalName().equals("Key")) { +            // do not accept only a Key +            throw new ParseException("parser.07", new Object[] {infoboxName}); +          } +          key = assocArrayPair.getAttribute("Key"); +          if (pairCount > 0) { +            primary = false; +          } +          pairCount++;           +          infoboxTokenList.addAll(getTokenFromXMLOrBase64Content(assocArrayPair, infoboxName, key, primary)); +        } +         +      } else if (infoboxReadResponseChildName.equals("BinaryFileData")) { +        infoboxTokenList.addAll(getTokenFromXMLOrBase64Content(infoboxReadResponseChild, infoboxName, null, true)); +      } +    }           +    return infoboxTokenList;  +  } +   +  /** +   * Unmarshales the <code><XMLContent></code> or  +   * <code><Base64Content></code> child of the given element to a list of +   * infobox token. +   *  +   * @param contentParent   The elment including the <code><XMLContent></code> or  +   *                        <code><Base64Content></code> child to unmarshal the +   *                        infobox token from. +   * @param infoboxName     The name of the infobox. +   * @param key             The key of an <code>AssocArrayData-Pair</code>.  +   *                        Maybe <code>null</code>. +   * @param primary         Specifies whether this token is the first (e.g. in an  +   *                        AssocArrayData) token. +   *                         +   * @return                A infobox token list. +   *  +   * @throws ParseException If the <code>contentParent</code> has no <code><XMLContent></code>   +   *                        or <code><Base64Content></code> child or the +   *                        <code><XMLContent></code> is empty. +   */ +  public static List getTokenFromXMLOrBase64Content( +    Element contentParent,  +    String infoboxName,  +    String key,  +    boolean primary)  +  throws ParseException  +  { +    Vector tokenList = new Vector(); +    // get the <XMLContent> or <Base64Content>  +    List content = DOMUtils.getChildElements(contentParent); +    if (content.size() == 1) { +      Element contentElem = (Element)content.get(0); +      if (contentElem.getLocalName().equals("XMLContent")) { +        List xmlContentChildren = DOMUtils.getChildElements(contentElem);        +        if (xmlContentChildren.size() == 0) { +          throw new ParseException("parser.06", new Object[] {infoboxName, "Inhalt", "XMLContent"}); +        } +        int xmlCount = 0; +        Iterator contentIt = xmlContentChildren.iterator(); +        while (contentIt.hasNext()) { +          Element xmlToken = (Element)contentIt.next(); +          if (xmlCount > 0) { +            primary = false; +          } +          InfoboxToken infoboxToken = new InfoboxTokenImpl(key, primary, xmlToken); +          tokenList.add(infoboxToken); +          xmlCount++; +        } +      } else { +        String base64Token = contentElem.getFirstChild().getNodeValue(); +        InfoboxToken infoboxToken = new InfoboxTokenImpl(key, primary, base64Token); +        tokenList.add(infoboxToken); +      } +    } else { +      throw new ParseException("parser.06",  +        new Object[] {infoboxName, "XMLContent oder Base64Content", contentParent.getLocalName()}); +    } +    return tokenList; +  } +   +   +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/InfoboxReadResponseParser.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/InfoboxReadResponseParser.java new file mode 100644 index 000000000..28ce69e95 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/InfoboxReadResponseParser.java @@ -0,0 +1,274 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.parser; + +import iaik.x509.X509Certificate; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.security.cert.CertificateException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + +import org.apache.axis.encoding.Base64; +import org.apache.xpath.XPathAPI; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.id.auth.data.IdentityLink; +import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; +import at.gv.egovernment.moa.id.auth.exception.BKUException; +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.XPathUtils; + +/** + * Parses an <code><InfoboxReadResponse></code>. + *  + * @author Stefan Knirsch + * @version $Id$ + */ + +public class InfoboxReadResponseParser { + +  /** This is the root element of the XML-Document provided by the Security Layer Card*/ +  private Element infoBoxElem_; + +  /** +   * Parses and validates the document given as string and extracts the  +   * root element. +   *  +   * @param xmlResponse <code><InfoboxReadResponse></code> as String +   * @throws ParseException If an element cannot be parsed +   * @throws AuthenticationException If any authentication error occurs + * @throws BKUException  +   */ +  public InfoboxReadResponseParser(String xmlResponse) throws ParseException, AuthenticationException, BKUException { +     +    try { +      InputStream s = new ByteArrayInputStream(xmlResponse.getBytes("UTF-8")); +      init(s); +    } +     +    catch (BKUException e) { +    	throw e; +   +    } catch (Throwable t) { +      throw new ParseException("parser.01", new Object[] { t.toString()}, t); +    } +  } + +  /** +   * Parses and validates the document given as stream and extracts the  +   * root element. +   *  +   * @param is <code><InfoboxReadResponse></code> as InputStream +   * @throws ParseException If an element cannot be parsed +   * @throws AuthenticationException If any authentication error occurs + * @throws BKUException  +   */ +  public InfoboxReadResponseParser(InputStream is) throws ParseException, AuthenticationException, BKUException { +    init(is); +  } + +  /** +   * Initializes the parser. +   * Parses and validates the document given as stream and extracts the  +   * root element. +   *  +   * @param is  The InfoBoxReadResponse as stream. +   * @throws AuthenticationException If an authentication error occurs. +   * @throws ParseException If an error occurs on parsing the the document. + * @throws BKUException  +   */ +  private void init(InputStream is) throws AuthenticationException, ParseException, BKUException { +    try { +       +      Element responseElem = DOMUtils.parseXmlValidating(is); +       +      if ("InfoboxReadResponse".equals(responseElem.getLocalName())) { +        infoBoxElem_ = responseElem; +      } else { +        ErrorResponseParser erp = new ErrorResponseParser(responseElem); +        throw new BKUException("auth.08",  +        		new Object[] { erp.getErrorCode(), erp.getErrorInfo()}, +        		erp.getErrorCode(), +        		erp.getErrorInfo()); +      } +     +    } catch (BKUException e) { +    	throw e; +       +    } catch (Throwable t) { +    	throw new ParseException("parser.01", new Object[] { t.toString()}, t); +    } +  } + +   +   +  /** +   * Parses the embedded <code><saml:Assertion></code> element from <code><InfoboxReadResponse></code> +   * @return <code><saml:Assertion></code> as String +   * @throws ParseException on any parsing error +   */ +//  public String parseSAMLAssertion() throws ParseException { +//    try { +//       +//      String slPrefix = XPathUtils.getSlPrefix(infoBoxElem_); +//      StringBuffer sb = new StringBuffer("/");       +//      sb.append(slPrefix); +//      sb.append(":InfoboxReadResponse/"); +//      sb.append(slPrefix); +//      sb.append(":BinaryFileData/"); +//      sb.append(slPrefix); +//      sb.append(":XMLContent/"); +//      sb.append(Constants.SAML_PREFIX); +//      sb.append(":Assertion"); +//      String samlAssertionXPath = sb.toString(); +//      Element samlAssertion = (Element) XPathUtils.selectSingleNode(infoBoxElem_, samlAssertionXPath); +//      return DOMUtils.serializeNode(samlAssertion); +//       +//    } +//    catch (Throwable t) { +//      throw new ParseException("parser.01", new Object[] { t.toString()}, t); +//    } +//  } +   +  /** +   * Parses the embedded <code><saml:Assertion></code> element from <code><InfoboxReadResponse></code> +   * @return <code><saml:Assertion></code> as String +   * @throws ParseException on any parsing error +   */ +  public Element parseSAMLAssertion() throws ParseException { +    try { +       +      String slPrefix = XPathUtils.getSlPrefix(infoBoxElem_); +      StringBuffer sb = new StringBuffer("/");       +      sb.append(slPrefix); +      sb.append(":InfoboxReadResponse/"); +      sb.append(slPrefix); +      sb.append(":BinaryFileData/"); +      sb.append(slPrefix); +      sb.append(":XMLContent/"); +      sb.append(Constants.SAML_PREFIX); +      sb.append(":Assertion"); +      String samlAssertionXPath = sb.toString(); +      Element samlAssertion = (Element) XPathUtils.selectSingleNode(infoBoxElem_, samlAssertionXPath); +      return samlAssertion; +       +    } +    catch (Throwable t) { +      throw new ParseException("parser.01", new Object[] { t.toString()}, t); +    } +  } + +  /** +   * Parses the identity link from the <code><saml:Assertion></code> +   * @return Identity link +   * @throws ParseException on any parsing error +   */ + +//  public IdentityLink parseIdentityLink() throws ParseException { +//    String samlAssertionString = parseSAMLAssertion(); +//    IdentityLinkAssertionParser ilParser = new IdentityLinkAssertionParser(samlAssertionString); +//    return ilParser.parseIdentityLink(); +//  } +   +   /** +   * Parses the identity link from the <code><saml:Assertion></code> +   * @return Identity link +   * @throws ParseException on any parsing error +   */ +   public IdentityLink parseIdentityLink() throws ParseException { +    Element samlAssertion = parseSAMLAssertion(); +    IdentityLinkAssertionParser ilParser = new IdentityLinkAssertionParser(samlAssertion); +    return ilParser.parseIdentityLink(); +  } +    +   /** +    * Returns the certificate given in the InfoboxReadResponse +    * @return +    * @throws ParseException +    */ +   public X509Certificate parseCertificate() throws ParseException { +      try { +         DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); +         Document doc = builder.newDocument(); +          +         Element nameSpaceNode = doc.createElement("NameSpaceNode"); +         nameSpaceNode.setAttribute("xmlns:" + Constants.PD_PREFIX, Constants.PD_NS_URI); +         nameSpaceNode.setAttribute("xmlns:" + Constants.DSIG_PREFIX, Constants.DSIG_NS_URI); +         nameSpaceNode.setAttribute("xmlns:" + Constants.SL12_PREFIX, Constants.SL12_NS_URI); +          +         Element base64ContentElement = (Element)XPathAPI.selectSingleNode(infoBoxElem_.getParentNode(), "//sl:Base64Content[1]", nameSpaceNode); + +         if (base64ContentElement == null) { +            throw new ParseException("parser.01", new Object[] { "Could not find Base64Content for X509Certificate."}); +         } +          +         String base64Content = DOMUtils.getText(base64ContentElement); +          +         // Decode Base64 value to X509Certificate +         byte[] content = Base64.decode(base64Content); +         return new X509Certificate(content); +          +      } catch (ParserConfigurationException e) { +         throw new ParseException("parser.01", new Object[] { "Could not parse X509Certificate from InfoboxReadRequest."}, e); +      } catch (TransformerException e) { +         throw new ParseException("parser.01", new Object[] { "Could not parse X509Certificate from InfoboxReadRequest."}, e); +      } catch (CertificateException e) { +         throw new ParseException("parser.01", new Object[] { "Could not parse X509Certificate from InfoboxReadRequest."}, e); +      }  + +   } +   + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java new file mode 100644 index 000000000..7bce406e0 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java @@ -0,0 +1,211 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.parser; + +import iaik.utils.Base64InputStream; +import iaik.x509.X509Certificate; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.XPathUtils; + +/** + * Parses a <code><VerifyXMLSignatureResponse></code> returned by + * MOA-SPSS. + * This class implements the Singleton pattern + *  + * @author Stefan Knirsch + * @version $Id$ + */ + + +public class VerifyXMLSignatureResponseParser { +  // +  // XPath namespace prefix shortcuts +  // +  /** Xpath prefix for reaching MOA Namespaces */ +  private static final String MOA = Constants.MOA_PREFIX + ":"; +  /** Xpath prefix for reaching DSIG Namespaces */ +  private static final String DSIG = Constants.DSIG_PREFIX + ":"; +  /** Xpath expression to the root element */     +  private static final String ROOT = "/" + MOA + "VerifyXMLSignatureResponse/"; +   +    /** Xpath expression to the X509SubjectName element */   +  private static final String DSIG_SUBJECT_NAME_XPATH =  +      ROOT + MOA + "SignerInfo/" + DSIG + "X509Data/" +  +      DSIG + "X509SubjectName";         +  /** Xpath expression to the X509Certificate element */   +  private static final String DSIG_X509_CERTIFICATE_XPATH =  +      ROOT + MOA + "SignerInfo/" + DSIG + "X509Data/" +  +          DSIG + "X509Certificate";         +  /** Xpath expression to the PublicAuthority element */   +  private static final String PUBLIC_AUTHORITY_XPATH = +     ROOT + MOA + "SignerInfo/" + DSIG + "X509Data/" +  +      MOA + "PublicAuthority";         +  /** Xpath expression to the PublicAuthorityCode element */   +  private static final String PUBLIC_AUTHORITY_CODE_XPATH = +     PUBLIC_AUTHORITY_XPATH + "/" + MOA + "Code";         +  /** Xpath expression to the QualifiedCertificate element */   +   private static final String QUALIFIED_CERTIFICATE_XPATH = +     ROOT + MOA + "SignerInfo/" + DSIG + "X509Data/" +  +      MOA + "QualifiedCertificate";         +    +  /** Xpath expression to the SignatureCheckCode element */     +  private static final String SIGNATURE_CHECK_CODE_XPATH =  +   ROOT + MOA + "SignatureCheck/" + MOA + "Code"; +  /** Xpath expression to the XMLDSIGManifestCheckCode element */     +  private static final String XMLDSIG_MANIFEST_CHECK_CODE_XPATH =  +   ROOT + MOA + "XMLDSIGManifestCheck/" + MOA + "Code"; +  /** Xpath expression to the SignatureManifestCheckCode element */     +  private static final String SIGNATURE_MANIFEST_CHECK_CODE_XPATH =  +   ROOT + MOA + "SignatureManifestCheck/" + MOA + "Code"; +  /** Xpath expression to the CertificateCheckCode element */       +  private static final String CERTIFICATE_CHECK_CODE_XPATH =  +   ROOT + MOA + "CertificateCheck/" + MOA + "Code"; +   +     +  /** This is the root element of the XML-Document provided by the Security Layer Card*/ +  private Element verifyXMLSignatureResponse; + +  /** +   * Constructor for VerifyXMLSignatureResponseParser. +   * A DOM-representation of the incoming String will be created +   * @param xmlResponse <code><InfoboxReadResponse></code> as String +   * @throws ParseException on any parsing error +   */ +  public VerifyXMLSignatureResponseParser(String xmlResponse) throws ParseException{ +   try { +  InputStream s = new ByteArrayInputStream(xmlResponse.getBytes("UTF-8")); +   +  verifyXMLSignatureResponse = DOMUtils.parseXmlValidating(s);  +     } +     catch (Throwable t) { +      throw new ParseException("parser.01", new Object[] { t.toString() }, t); +    }  +  } +   +  /** +   * Constructor for VerifyXMLSignatureResponseParser. +   * A DOM-representation of the incoming Inputstream will be created +   * @param xmlResponse <code><InfoboxReadResponse></code> as InputStream +   * @throws Exception on any parsing error +   */ +  public VerifyXMLSignatureResponseParser(InputStream xmlResponse) throws Exception +  { +    try { +       verifyXMLSignatureResponse = DOMUtils.parseXmlValidating(xmlResponse);                         +    } +     catch (Throwable t) { +      throw new ParseException("parser.01", null, t); +    }  +  }  +   +   /** +   * Constructor for VerifyXMLSignatureResponseParser. +   * The incoming Element will be used for further operations +   * @param xmlResponse <code><InfoboxReadResponse></code> as Element +   */ +  public VerifyXMLSignatureResponseParser(Element xmlResponse) +  { +      verifyXMLSignatureResponse =xmlResponse;                         +   +  } +   +  /** +   * Parse identity link from <code><InfoboxReadResponse></code> +   * @return Identity link +   * @throws ParseException on any parsing error +   */ + +  public VerifyXMLSignatureResponse parseData() throws ParseException { + +    VerifyXMLSignatureResponse respData=new VerifyXMLSignatureResponse(); + +    try { +    	 +      String s = DOMUtils.serializeNode(verifyXMLSignatureResponse); +      respData.setXmlDsigSubjectName(XPathUtils.getElementValue(verifyXMLSignatureResponse,DSIG_SUBJECT_NAME_XPATH,"")); +      Element e = (Element)XPathUtils.selectSingleNode(verifyXMLSignatureResponse,QUALIFIED_CERTIFICATE_XPATH); +      respData.setQualifiedCertificate(e!=null); + +      Base64InputStream in = new Base64InputStream(new ByteArrayInputStream(XPathUtils.getElementValue( +        verifyXMLSignatureResponse,DSIG_X509_CERTIFICATE_XPATH,"").getBytes("UTF-8")),true); + +      respData.setX509certificate(new X509Certificate(in)); +      Element publicAuthority = (Element)XPathUtils.selectSingleNode(verifyXMLSignatureResponse,PUBLIC_AUTHORITY_XPATH); +      respData.setPublicAuthority(publicAuthority != null); +      respData.setPublicAuthorityCode(XPathUtils.getElementValue(verifyXMLSignatureResponse,PUBLIC_AUTHORITY_CODE_XPATH,"")); +      respData.setSignatureCheckCode(new Integer(XPathUtils.getElementValue(verifyXMLSignatureResponse,SIGNATURE_CHECK_CODE_XPATH,"")).intValue()); + +      String xmlDsigCheckCode = XPathUtils.getElementValue(verifyXMLSignatureResponse,XMLDSIG_MANIFEST_CHECK_CODE_XPATH,null); +      if (xmlDsigCheckCode!=null) {  +        respData.setXmlDSIGManigest(true); +        respData.setXmlDSIGManifestCheckCode(new Integer(xmlDsigCheckCode).intValue()); +      } else { +        respData.setXmlDSIGManigest(false); +      } +      String signatureManifestCheckCode = XPathUtils.getElementValue(verifyXMLSignatureResponse,SIGNATURE_MANIFEST_CHECK_CODE_XPATH,null); +      if (signatureManifestCheckCode != null) { +        respData.setSignatureManifestCheckCode(new Integer(signatureManifestCheckCode).intValue()); +      } +      respData.setCertificateCheckCode(new Integer(XPathUtils.getElementValue(verifyXMLSignatureResponse,CERTIFICATE_CHECK_CODE_XPATH,"")).intValue());              +    } +    catch (Throwable t) { +      throw new ParseException("parser.01", null, t); +    }         +    return respData; +  } +   +   +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/CreateXMLSignatureResponseValidator.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/CreateXMLSignatureResponseValidator.java new file mode 100644 index 000000000..e1ab0025e --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/CreateXMLSignatureResponseValidator.java @@ -0,0 +1,671 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.validator; + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.Iterator; +import java.util.List; + +import javax.xml.bind.DatatypeConverter; + +import org.jaxen.SimpleNamespaceContext; +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.id.auth.builder.AuthenticationBlockAssertionBuilder; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; +import at.gv.egovernment.moa.id.auth.data.CreateXMLSignatureResponse; +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.data.SAMLAttribute; +import at.gv.egovernment.moa.id.auth.exception.ValidateException; +import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.config.TargetToSectorNameMapper; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.MiscUtil; +import at.gv.egovernment.moa.util.StringUtils; +import at.gv.egovernment.moa.util.XPathUtils; + +/** + *  + * This class is used to validate an {@link CreateXMLSignatureResponse}  + * returned by the security layer. + * This class implements the Singleton pattern. + * @author Stefan Knirsch + * @version $Id$ + */ +public class CreateXMLSignatureResponseValidator { +   +  +  /** Xpath expression to the dsig:Signature element */ +  private static final String SIGNATURE_XPATH = Constants.DSIG_PREFIX + ":Signature"; +   +  private static final String XADES_1_1_1_SIGNINGTIME_PATH = "//" + Constants.XADES_1_1_1_NS_PREFIX + ":SigningTime"; +  private static final String XADES_1_3_2_SIGNINGTIME_PATH = "//" + Constants.XADES_1_3_2_NS_PREFIX + ":SigningTime"; +   +   +  private static final long MAX_DIFFERENCE_IN_MILLISECONDS = 600000; // 10min +   + /** Singleton instance. <code>null</code>, if none has been created. */ +  private static CreateXMLSignatureResponseValidator instance; + +  private static SimpleNamespaceContext NS_CONTEXT; +  static { +    NS_CONTEXT = new SimpleNamespaceContext(); +    NS_CONTEXT.addNamespace(Constants.XADES_1_1_1_NS_PREFIX, Constants.XADES_1_1_1_NS_URI); +    NS_CONTEXT.addNamespace(Constants.XADES_1_2_2_NS_PREFIX, Constants.XADES_1_2_2_NS_URI); +    NS_CONTEXT.addNamespace(Constants.XADES_1_3_2_NS_PREFIX, Constants.XADES_1_3_2_NS_URI); +    NS_CONTEXT.addNamespace(Constants.XADES_1_4_1_NS_PREFIX, Constants.XADES_1_4_1_NS_URI); +  } + +   +  /** +   * Constructor for a singleton CreateXMLSignatureResponseValidator. +   * @return an instance of CreateXMLSignatureResponseValidator +   * @throws ValidateException if no instance can be created +   */ +   public static synchronized CreateXMLSignatureResponseValidator getInstance()  +   throws ValidateException { +   if (instance == null) { +      instance = new CreateXMLSignatureResponseValidator(); +    } +    return instance; +  }  +   +   +  /** +   * The Method validate is used for validating an explicit {@link CreateXMLSignatureResponse} +   * @param createXMLSignatureResponse +   * @param session +   * @throws ValidateException +   */ +  public void validate(CreateXMLSignatureResponse createXMLSignatureResponse, AuthenticationSession session) +   throws ValidateException { +       +      // A3.056: more then one /saml:Assertion/saml:AttributeStatement/saml:Subject/saml:NameIdentifier +     +    String gbTarget = session.getTarget(); +    String oaURL = session.getPublicOAURLPrefix();  +    boolean businessService = session.getBusinessService(); +     +    IdentityLink identityLink = session.getIdentityLink(); +     +    Element samlAssertion = createXMLSignatureResponse.getSamlAssertion();  +    String issuer = samlAssertion.getAttribute("Issuer"); +    if (issuer == null) { +      // should not happen, because parser would dedect this +      throw new ValidateException("validator.32", null); +    } +    // replace ' in name with ' +    issuer = issuer.replaceAll("'", "'"); +     +    String issueInstant = samlAssertion.getAttribute("IssueInstant"); +    if (!issueInstant.equals(session.getIssueInstant())) { +      throw new ValidateException("validator.39", new Object[] {issueInstant, session.getIssueInstant()}); +    } +     +    String name = identityLink.getName(); +     +    if (!issuer.equals(name)) { +      throw new ValidateException("validator.33", new Object[] {issuer, name}); +    }      +        +    SAMLAttribute[] samlAttributes = createXMLSignatureResponse.getSamlAttributes(); + +    boolean foundOA = false; +    boolean foundGB = false; +    boolean foundWBPK = false; +    int offset = 0; +     +    // check number of SAML aatributes +    List<ExtendedSAMLAttribute> extendedSAMLAttributes = session.getExtendedSAMLAttributesAUTH(); +    int extendedSAMLAttributesNum = 0; +    if (extendedSAMLAttributes != null) { +      extendedSAMLAttributesNum = extendedSAMLAttributes.size(); +    } +    int expectedSAMLAttributeNumber =  +      AuthenticationBlockAssertionBuilder.NUM_OF_SAML_ATTRIBUTES + extendedSAMLAttributesNum; +    if (!session.getSAMLAttributeGebeORwbpk()) expectedSAMLAttributeNumber--; +    int actualSAMLAttributeNumber = samlAttributes.length; +    if (actualSAMLAttributeNumber != expectedSAMLAttributeNumber) { +      Logger.error("Wrong number of SAML attributes in CreateXMLSignatureResponse: expected " +  +        expectedSAMLAttributeNumber + ", but was " + actualSAMLAttributeNumber); +      throw new ValidateException( +        "validator.36",  +        new Object[] {String.valueOf(actualSAMLAttributeNumber), String.valueOf(expectedSAMLAttributeNumber)}); +    } +     +    SAMLAttribute samlAttribute; +    if (session.getSAMLAttributeGebeORwbpk()) { +      // check the first attribute ("Geschaeftsbereich" or "wbPK") +      samlAttribute = samlAttributes[0]; +      if (businessService) { +        if (!samlAttribute.getName().equals("wbPK")) { +          if (samlAttribute.getName().equals("Geschaeftsbereich")) { +            throw new ValidateException("validator.26", null); +          } else { +            throw new ValidateException( +            "validator.37",  +            new Object[] {samlAttribute.getName(), "wbPK", String.valueOf(1)}); +          } +        }           +        if (samlAttribute.getNamespace().equals("http://reference.e-government.gv.at/namespace/moa/20020822#")) {           +          foundWBPK = true; +          try { +            Element attrValue = (Element)samlAttribute.getValue(); +            String value = ((Element)attrValue.getElementsByTagNameNS(Constants.PD_NS_URI, "Value").item(0)).getFirstChild().getNodeValue(); +            String type =  ((Element)attrValue.getElementsByTagNameNS(Constants.PD_NS_URI, "Type").item(0)).getFirstChild().getNodeValue(); +            if (!value.equals(identityLink.getIdentificationValue())) { +              throw new ValidateException("validator.28", null);  +            } +            if (!type.equals(identityLink.getIdentificationType())) { +              throw new ValidateException("validator.28", null);  +            } +          } catch (Exception ex) { +            throw new ValidateException("validator.29", null); +          } +        } else { +          throw new ValidateException("validator.30", null); +        }     +      } else { +        if (!samlAttribute.getName().equals("Geschaeftsbereich")) { +          if (samlAttribute.getName().equals("wbPK")) { +            throw new ValidateException("validator.26", null); +          } else { +            throw new ValidateException( +            "validator.37",  +            new Object[] {samlAttribute.getName(), "Geschaeftsbereich", String.valueOf(1)}); +          } +        } +        if (samlAttribute.getNamespace().equals("http://reference.e-government.gv.at/namespace/moa/20020822#")) {           +          foundGB = true; +          String targetFriendlyName = session.getTargetFriendlyName(); +          String sectorName = TargetToSectorNameMapper.getSectorNameViaTarget(gbTarget); +          if (StringUtils.isEmpty(sectorName)) { +        	  if (targetFriendlyName != null) +        		  sectorName = targetFriendlyName;  +          } +          gbTarget = gbTarget + " (" + sectorName + ")"; +          //gbTarget = gbTarget + " (" + TargetToSectorNameMapper.getSectorNameViaTarget(gbTarget) + ")"; + +          if (!gbTarget.equals((String)samlAttribute.getValue())) { +            throw new ValidateException("validator.13", null);  +          }              +        } else { +          throw new ValidateException("validator.12", null); +        } +      } +    } else { +      offset--; +    } + +    // check the second attribute (must be "OA") +    samlAttribute = samlAttributes[1 + offset]; +    if (!samlAttribute.getName().equals("OA")) { +      throw new ValidateException( +          "validator.37",  +          new Object[] {samlAttribute.getName(), "OA", String.valueOf(2)}); +    } +    if (samlAttribute.getNamespace().equals("http://reference.e-government.gv.at/namespace/moa/20020822#")) { +      foundOA = true;             +      if (!oaURL.equals((String)samlAttribute.getValue())) {  // CHECKS für die AttributeVALUES fehlen noch              +        throw new ValidateException("validator.16", new Object[] {":gefunden wurde '" + oaURL + "', erwartet wurde '" + samlAttribute.getValue()});  +      }              +    } else { +      throw new ValidateException("validator.15", null); +    } +       +    // check the third attribute (must be "Geburtsdatum") +    samlAttribute = samlAttributes[2 + offset]; +    if (!samlAttribute.getName().equals("Geburtsdatum")) { +      throw new ValidateException( +          "validator.37",  +          new Object[] {samlAttribute.getName(), "Geburtsdatum", String.valueOf(3)}); +    } +    if (samlAttribute.getNamespace().equals("http://reference.e-government.gv.at/namespace/moa/20020822#")) { +      String samlDateOfBirth = (String)samlAttribute.getValue(); +      String dateOfBirth = identityLink.getDateOfBirth(); +      if (!samlDateOfBirth.equals(dateOfBirth)) { +        throw new ValidateException("validator.34", new Object[] {samlDateOfBirth, dateOfBirth}); +      } +    } else { +      throw new ValidateException("validator.35", null); +    } +      +    // check four attribute could be a special text +    samlAttribute = samlAttributes[3 + offset]; +    if (!samlAttribute.getName().equals("SpecialText")) { +      throw new ValidateException( +          "validator.37",  +          new Object[] {samlAttribute.getName(), "SpecialText", String.valueOf(4)}); +    } +    if (samlAttribute.getNamespace().equals("http://reference.e-government.gv.at/namespace/moa/20020822#")) { +      String samlSpecialText = (String)samlAttribute.getValue(); +      samlSpecialText = samlSpecialText.replaceAll("'", "'"); +       +      String text = ""; +      try { +		OAAuthParameter oaparam = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(session.getPublicOAURLPrefix()); +		if (MiscUtil.isNotEmpty(oaparam.getAditionalAuthBlockText())) { +			Logger.info("Use addional AuthBlock Text from OA=" + oaparam.getPublicURLPrefix()); +			text = oaparam.getAditionalAuthBlockText(); +		} +      } catch (ConfigurationException e) { +    	  Logger.warn("Addional AuthBlock Text can not loaded from OA!", e); +      } +       +       +      String specialText = AuthenticationBlockAssertionBuilder.generateSpecialText(text, issuer, identityLink.getDateOfBirth(), issueInstant); +      if (!samlSpecialText.equals(specialText)) { +        throw new ValidateException("validator.67", new Object[] {samlSpecialText, specialText}); +      } +    } else { +      throw new ValidateException("validator.35", null); +    } +     +     +    //check unique AuthBlock tokken +    samlAttribute = samlAttributes[4 + offset]; +    if (!samlAttribute.getName().equals("UniqueTokken")) { +      throw new ValidateException( +          "validator.37",  +          new Object[] {samlAttribute.getName(), "UniqueTokken", String.valueOf(5)}); +    } +    if (samlAttribute.getNamespace().equals("http://reference.e-government.gv.at/namespace/moa/20020822#")) { +      String uniquetokken = (String)samlAttribute.getValue(); +            +      if (!uniquetokken.equals(session.getAuthBlockTokken())) { +        throw new ValidateException("validator.70", new Object[] {uniquetokken, session.getAuthBlockTokken()}); +      } +    } else { +      throw new ValidateException("validator.35", null); +    } +     +     +    // now check the extended SAML attributes +    int i = AuthenticationBlockAssertionBuilder.NUM_OF_SAML_ATTRIBUTES + offset; +    if (extendedSAMLAttributes != null) { +      Iterator<ExtendedSAMLAttribute> it = extendedSAMLAttributes.iterator(); +      while (it.hasNext()) { +        ExtendedSAMLAttribute extendedSAMLAttribute = (ExtendedSAMLAttribute)it.next(); +        samlAttribute = samlAttributes[i]; +        String actualName = samlAttribute.getName(); +        String expectedName = extendedSAMLAttribute.getName(); +        if (!actualName.equals(expectedName)) { +          throw new ValidateException( +            "validator.38",  +            new Object[] {"Name", String.valueOf((i+1)), actualName, actualName, expectedName }); +        } +        String actualNamespace = samlAttribute.getNamespace(); +        String expectedNamespace = extendedSAMLAttribute.getNameSpace(); +        if (!actualNamespace.equals(expectedNamespace)) { +          throw new ValidateException( +            "validator.38",  +            new Object[] {"Namespace", String.valueOf((i+1)), actualName, actualNamespace, expectedNamespace, }); +        } +        Object expectedValue = extendedSAMLAttribute.getValue(); +        Object actualValue = samlAttribute.getValue(); +        try { +          if (expectedValue instanceof String) { +            // replace \r\n because text might be base64-encoded +            String expValue = StringUtils.replaceAll((String)expectedValue,"\r",""); +            expValue = StringUtils.replaceAll(expValue,"\n",""); +            String actValue = StringUtils.replaceAll((String)actualValue,"\r",""); +            actValue = StringUtils.replaceAll(actValue,"\n",""); +            if (!expValue.equals(actValue)) { +              throw new ValidateException( +              "validator.38",  +              new Object[] {"Wert", String.valueOf((i+1)), actualName, actualValue, expectedValue });           +            } +          } else if (expectedValue instanceof Element) { +            // only check the name of the element +            String actualElementName = ((Element)actualValue).getNodeName(); +            String expectedElementName = ((Element)expectedValue).getNodeName(); +            if (!(expectedElementName.equals(actualElementName))){ +              throw new ValidateException( +              "validator.38",  +              new Object[] {"Wert", String.valueOf((i+1)), actualName, actualElementName, expectedElementName});           +            } +          } else { +            // should not happen +            throw new ValidateException( +              "validator.38",  +              new Object[] {"Typ", String.valueOf((i+1)), expectedName, "java.lang.String oder org.wrc.dom.Element", expectedValue.getClass().getName()}); +          } +        } catch (ClassCastException e) { +          throw new ValidateException( +              "validator.38",  +              new Object[] {"Typ", String.valueOf((i+1)), expectedName, expectedValue.getClass().getName(), actualValue.getClass().getName()}); +        } +        i++; +      } +    } +     +     +    if (!foundOA) throw new ValidateException("validator.14", null);  +    if (businessService) { +      if (session.getSAMLAttributeGebeORwbpk() && !foundWBPK) throw new ValidateException("validator.31", null); +    } else { +      if (!foundGB) throw new ValidateException("validator.11", null); +    } +   +     //Check if dsig:Signature exists +//    NodeList nl = createXMLSignatureResponse.getSamlAssertion().getElementsByTagNameNS(Constants.DSIG_NS_URI, "Signature"); +//    if (nl.getLength() != 1) { +//      throw new ValidateException("validator.05", null); +//    } +    Element dsigSignature = (Element) XPathUtils.selectSingleNode(samlAssertion, SIGNATURE_XPATH); +    if (dsigSignature == null) {     +      throw new ValidateException("validator.05", new Object[] {"im AUTHBlock"}) ; +    } +  } +   +  /** +   * The Method validate is used for validating an explicit {@link CreateXMLSignatureResponse} +   * @param createXMLSignatureResponse +   * @param session +   * @throws ValidateException +   */ +  public void validateSSO(CreateXMLSignatureResponse createXMLSignatureResponse, AuthenticationSession session) +   throws ValidateException { +       +      // A3.056: more then one /saml:Assertion/saml:AttributeStatement/saml:Subject/saml:NameIdentifier +     +	String oaURL; +    try { +		oaURL = AuthConfigurationProviderFactory.getInstance().getPublicURLPrefix(); +	} catch (ConfigurationException e1) { +		oaURL = new String(); +	}  +     +    IdentityLink identityLink = session.getIdentityLink(); +     +    Element samlAssertion = createXMLSignatureResponse.getSamlAssertion();  +    String issuer = samlAssertion.getAttribute("Issuer"); +    if (issuer == null) { +      // should not happen, because parser would dedect this +      throw new ValidateException("validator.32", null); +    } +    // replace ' in name with ' +    issuer = issuer.replaceAll("'", "'"); +     +    String issueInstant = samlAssertion.getAttribute("IssueInstant"); +    if (!issueInstant.equals(session.getIssueInstant())) { +      throw new ValidateException("validator.39", new Object[] {issueInstant, session.getIssueInstant()}); +    } +     +    String name = identityLink.getName(); +     +    if (!issuer.equals(name)) { +      throw new ValidateException("validator.33", new Object[] {issuer, name}); +    }      +        +    SAMLAttribute[] samlAttributes = createXMLSignatureResponse.getSamlAttributes(); + +    boolean foundOA = false; +//    boolean foundGB = false; +//    boolean foundWBPK = false; +    int offset = 0; +     +    // check number of SAML aatributes +    List<ExtendedSAMLAttribute> extendedSAMLAttributes = session.getExtendedSAMLAttributesAUTH(); +    int extendedSAMLAttributesNum = 0; +    if (extendedSAMLAttributes != null) { +      extendedSAMLAttributesNum = extendedSAMLAttributes.size(); +    } +    int expectedSAMLAttributeNumber =  +      AuthenticationBlockAssertionBuilder.NUM_OF_SAML_ATTRIBUTES_SSO + extendedSAMLAttributesNum; +    if (!session.getSAMLAttributeGebeORwbpk()) expectedSAMLAttributeNumber--; +    int actualSAMLAttributeNumber = samlAttributes.length; +    if (actualSAMLAttributeNumber != expectedSAMLAttributeNumber) { +      Logger.error("Wrong number of SAML attributes in CreateXMLSignatureResponse: expected " +  +        expectedSAMLAttributeNumber + ", but was " + actualSAMLAttributeNumber); +      throw new ValidateException( +        "validator.36",  +        new Object[] {String.valueOf(actualSAMLAttributeNumber), String.valueOf(expectedSAMLAttributeNumber)}); +    } +     +    SAMLAttribute samlAttribute; +    if (!session.getSAMLAttributeGebeORwbpk()) { +      offset--; +    } + +    // check the first attribute (must be "OA") +    samlAttribute = samlAttributes[0 + offset]; +    if (!samlAttribute.getName().equals("OA")) { +      throw new ValidateException( +          "validator.37",  +          new Object[] {samlAttribute.getName(), "OA", String.valueOf(2)}); +    } +    if (samlAttribute.getNamespace().equals("http://reference.e-government.gv.at/namespace/moa/20020822#")) { +      foundOA = true;             +      if (!oaURL.equals((String)samlAttribute.getValue())) {  // CHECKS für die AttributeVALUES fehlen noch              +        throw new ValidateException("validator.16", new Object[] {":gefunden wurde '" + oaURL + "', erwartet wurde '" + samlAttribute.getValue()});  +      }              +    } else { +      throw new ValidateException("validator.15", null); +    } +       +    // check the third attribute (must be "Geburtsdatum") +    samlAttribute = samlAttributes[1 + offset]; +    if (!samlAttribute.getName().equals("Geburtsdatum")) { +      throw new ValidateException( +          "validator.37",  +          new Object[] {samlAttribute.getName(), "Geburtsdatum", String.valueOf(3)}); +    } +    if (samlAttribute.getNamespace().equals("http://reference.e-government.gv.at/namespace/moa/20020822#")) { +      String samlDateOfBirth = (String)samlAttribute.getValue(); +      String dateOfBirth = identityLink.getDateOfBirth(); +      if (!samlDateOfBirth.equals(dateOfBirth)) { +        throw new ValidateException("validator.34", new Object[] {samlDateOfBirth, dateOfBirth}); +      } +    } else { +      throw new ValidateException("validator.35", null); +    } +      +    // check four attribute could be a special text +    samlAttribute = samlAttributes[2 + offset]; +    if (!samlAttribute.getName().equals("SpecialText")) { +      throw new ValidateException( +          "validator.37",  +          new Object[] {samlAttribute.getName(), "SpecialText", String.valueOf(4)}); +    } +    if (samlAttribute.getNamespace().equals("http://reference.e-government.gv.at/namespace/moa/20020822#")) { +      String samlSpecialText = (String)samlAttribute.getValue(); +      samlSpecialText = samlSpecialText.replaceAll("'", "'"); +       +      String text = ""; +      try { +    	 if (MiscUtil.isNotEmpty(AuthConfigurationProviderFactory.getInstance().getSSOSpecialText())) { +    		text = AuthConfigurationProviderFactory.getInstance().getSSOSpecialText(); +			Logger.info("Use addional AuthBlock Text from SSO=" +text); +			 +    	 } +		else +			text = new String(); +      } catch (ConfigurationException e) { +    	  Logger.warn("Addional AuthBlock Text can not loaded from SSO!", e); +      } +       +       +      	String specialText = AuthenticationBlockAssertionBuilder.generateSpecialText(text, issuer, identityLink.getDateOfBirth(), issueInstant); +      	if (!samlSpecialText.equals(specialText)) { +      		throw new ValidateException("validator.67", new Object[] {samlSpecialText, specialText}); +      	} +    } else { +      throw new ValidateException("validator.35", null); +    } +     +    //check unique AuthBlock tokken +    samlAttribute = samlAttributes[3 + offset]; +    if (!samlAttribute.getName().equals("UniqueTokken")) { +      throw new ValidateException( +          "validator.37",  +          new Object[] {samlAttribute.getName(), "UniqueTokken", String.valueOf(5)}); +    } +    if (samlAttribute.getNamespace().equals("http://reference.e-government.gv.at/namespace/moa/20020822#")) { +      String uniquetokken = (String)samlAttribute.getValue(); +            +      if (!uniquetokken.equals(session.getAuthBlockTokken())) { +        throw new ValidateException("validator.70", new Object[] {uniquetokken, session.getAuthBlockTokken()}); +      } +    } else { +      throw new ValidateException("validator.35", null); +    } +     +     +    // now check the extended SAML attributes +    int i = AuthenticationBlockAssertionBuilder.NUM_OF_SAML_ATTRIBUTES_SSO + offset; +    if (extendedSAMLAttributes != null) { +      Iterator<ExtendedSAMLAttribute> it = extendedSAMLAttributes.iterator(); +      while (it.hasNext()) { +        ExtendedSAMLAttribute extendedSAMLAttribute = (ExtendedSAMLAttribute)it.next(); +        samlAttribute = samlAttributes[i]; +        String actualName = samlAttribute.getName(); +        String expectedName = extendedSAMLAttribute.getName(); +        if (!actualName.equals(expectedName)) { +          throw new ValidateException( +            "validator.38",  +            new Object[] {"Name", String.valueOf((i+1)), actualName, actualName, expectedName }); +        } +        String actualNamespace = samlAttribute.getNamespace(); +        String expectedNamespace = extendedSAMLAttribute.getNameSpace(); +        if (!actualNamespace.equals(expectedNamespace)) { +          throw new ValidateException( +            "validator.38",  +            new Object[] {"Namespace", String.valueOf((i+1)), actualName, actualNamespace, expectedNamespace, }); +        } +        Object expectedValue = extendedSAMLAttribute.getValue(); +        Object actualValue = samlAttribute.getValue(); +        try { +          if (expectedValue instanceof String) { +            // replace \r\n because text might be base64-encoded +            String expValue = StringUtils.replaceAll((String)expectedValue,"\r",""); +            expValue = StringUtils.replaceAll(expValue,"\n",""); +            String actValue = StringUtils.replaceAll((String)actualValue,"\r",""); +            actValue = StringUtils.replaceAll(actValue,"\n",""); +            if (!expValue.equals(actValue)) { +              throw new ValidateException( +              "validator.38",  +              new Object[] {"Wert", String.valueOf((i+1)), actualName, actualValue, expectedValue });           +            } +          } else if (expectedValue instanceof Element) { +            // only check the name of the element +            String actualElementName = ((Element)actualValue).getNodeName(); +            String expectedElementName = ((Element)expectedValue).getNodeName(); +            if (!(expectedElementName.equals(actualElementName))){ +              throw new ValidateException( +              "validator.38",  +              new Object[] {"Wert", String.valueOf((i+1)), actualName, actualElementName, expectedElementName});           +            } +          } else { +            // should not happen +            throw new ValidateException( +              "validator.38",  +              new Object[] {"Typ", String.valueOf((i+1)), expectedName, "java.lang.String oder org.wrc.dom.Element", expectedValue.getClass().getName()}); +          } +        } catch (ClassCastException e) { +          throw new ValidateException( +              "validator.38",  +              new Object[] {"Typ", String.valueOf((i+1)), expectedName, expectedValue.getClass().getName(), actualValue.getClass().getName()}); +        } +        i++; +      } +    } +     +     +    if (!foundOA) throw new ValidateException("validator.14", null);  +   +     //Check if dsig:Signature exists +//    NodeList nl = createXMLSignatureResponse.getSamlAssertion().getElementsByTagNameNS(Constants.DSIG_NS_URI, "Signature"); +//    if (nl.getLength() != 1) { +//      throw new ValidateException("validator.05", null); +//    } +    Element dsigSignature = (Element) XPathUtils.selectSingleNode(samlAssertion, SIGNATURE_XPATH); +    if (dsigSignature == null) {     +      throw new ValidateException("validator.05", new Object[] {"im AUTHBlock"}) ; +    } +  } +   +  public void validateSigningDateTime( CreateXMLSignatureResponse csresp) throws ValidateException { +	 +	  Element dsigSignatureElement = csresp.getDsigSignature(); +	  if (dsigSignatureElement == null) { +		  throw new ValidateException("validator.05", new Object[] {"im AUTHBlock"}) ; +	  } +	  else { +		  Element signingTimeElem = (Element) XPathUtils.selectSingleNode(dsigSignatureElement, NS_CONTEXT, XADES_1_1_1_SIGNINGTIME_PATH); +		  if (signingTimeElem == null) { +			  signingTimeElem = (Element) XPathUtils.selectSingleNode(dsigSignatureElement, NS_CONTEXT, XADES_1_3_2_SIGNINGTIME_PATH); +			  if (signingTimeElem == null) +				  throw new ValidateException("validator.68", null) ; +		  } +			   +			   +		  String signingTimeStr = signingTimeElem.getTextContent(); +		  if (signingTimeStr == null) +			  throw new ValidateException("validator.68", null) ; +			   +		  Calendar signingTimeCal = DatatypeConverter.parseDate(signingTimeStr); +		  Calendar serverTimeCal = new GregorianCalendar(); +		   +		  long diff = Math.abs(signingTimeCal.getTimeInMillis() - serverTimeCal.getTimeInMillis()); +		   +		  if (diff > MAX_DIFFERENCE_IN_MILLISECONDS) +			  throw new ValidateException("validator.69", new Object[] {"mehr als " + MAX_DIFFERENCE_IN_MILLISECONDS + " Millisekunden"}) ; + +		  Logger.debug("Compare \"" + signingTimeCal.getTime() + "\" (SigningTime) with \"" + serverTimeCal.getTime() + "\" (server time)"); +			 +		   +	  } +		   +  } +   +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/IdentityLinkValidator.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/IdentityLinkValidator.java new file mode 100644 index 000000000..fa6486afe --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/IdentityLinkValidator.java @@ -0,0 +1,209 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.validator; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import at.gv.egovernment.moa.id.auth.data.IdentityLink; +import at.gv.egovernment.moa.id.auth.exception.ValidateException; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.XPathUtils; + +/** + * This class is used to validate an {@link IdentityLink}  + * returned by the security layer + *  + * @author Stefan Knirsch + * @version $Id$ + */ +public class IdentityLinkValidator implements Constants { + +  // +  // XPath namespace prefix shortcuts +  // +  /** Xpath prefix for reaching PersonData Namespaces */ +  private static final String PDATA = PD_PREFIX + ":"; +  /** Xpath prefix for reaching SAML Namespaces */ +  private static final String SAML = SAML_PREFIX + ":"; +  /** Xpath prefix for reaching XML-DSIG Namespaces */ +  private static final String DSIG = DSIG_PREFIX + ":"; +  /** Xpath prefix for reaching ECDSA Namespaces */ +  private static final String ECDSA = ECDSA_PREFIX + ":"; +  /** Xpath expression to the root element */ +  private static final String ROOT = ""; +  /** Xpath expression to the SAML:SubjectConfirmationData element */ +  private static final String SAML_SUBJECT_CONFIRMATION_DATA_XPATH = +    ROOT +      + SAML +      + "AttributeStatement/" +      + SAML +      + "Subject/" +      + SAML +      + "SubjectConfirmation/" +      + SAML +      + "SubjectConfirmationData"; +/** Xpath expression to the PersonData:Person element */ +  private static final String PERSON_XPATH = +    SAML_SUBJECT_CONFIRMATION_DATA_XPATH + "/" + PDATA + "Person"; +  /** Xpath expression to the SAML:Attribute element */ +  private static final String ATTRIBUTE_XPATH = +    ROOT + SAML + "AttributeStatement/" + SAML + "Attribute"; +//  /** Xpath expression to the SAML:AttributeName attribute */ +//  private static final String ATTRIBUTE_NAME_XPATH = +//    ROOT + SAML + "AttributeStatement/" + SAML + "Attribute/@AttributeName"; +//  /** Xpath expression to the SAML:AttributeNamespace attribute */ +//  private static final String ATTRIBUTE_NAMESPACE_XPATH = +//    ROOT +//      + SAML +//      + "AttributeStatement/" +//      + SAML +//      + "Attribute/@AttributeNamespace"; +//  /** Xpath expression to the SAML:AttributeValue element */ +//  private static final String ATTRIBUTE_VALUE_XPATH = +//    ROOT +//      + SAML +//      + "AttributeStatement/" +//      + SAML +//      + "Attribute/" +//      + SAML +//      + "AttributeValue"; + +  /** Singleton instance. <code>null</code>, if none has been created. */ +  private static IdentityLinkValidator instance; + +  /** +   * Constructor for a singleton IdentityLinkValidator. +   * @return a new IdentityLinkValidator instance +   * @throws ValidateException if no instance can be created +   */ +  public static synchronized IdentityLinkValidator getInstance() +    throws ValidateException { +    if (instance == null) { +      instance = new IdentityLinkValidator(); +    } +    return instance; +  } + +  /** +   * Method validate. Validates the {@link IdentityLink}  +   * @param identityLink The identityLink to validate +   * @throws ValidateException on any validation error +   */ +  public void validate(IdentityLink identityLink) throws ValidateException { + +    Element samlAssertion = identityLink.getSamlAssertion(); +    //Search the SAML:ASSERTION Object (A2.054) +    if (samlAssertion == null) { +      throw new ValidateException("validator.00", null); +    } + +    // Check how many saml:Assertion/saml:AttributeStatement/ +    //      saml:Subject/ saml:SubjectConfirmation/ +    //      saml:SubjectConfirmationData/pr:Person of type +    //      PhysicalPersonType exist (A2.056) +    NodeList nl = XPathUtils.selectNodeList(samlAssertion, PERSON_XPATH); +    // If we have just one Person-Element we don't need to check the attributes +    int counterPhysicalPersonType = 0; +    if (nl.getLength() > 1) +      for (int i = 0; i < nl.getLength(); i++) { +        String xsiType = +          ((Element) nl.item(i)) +            .getAttributeNodeNS( +              "http://www.w3.org/2001/XMLSchema-instance", +              "type") +            .getNodeValue(); +        // We have to check if xsiType contains "PhysicalPersonType" +        // An equal-check will fail because of the Namespace-prefix of the attribute value +        if (xsiType.indexOf("PhysicalPersonType") > -1) +          counterPhysicalPersonType++; +      } +    if (counterPhysicalPersonType > 1) +      throw new ValidateException("validator.01", null); + +    //Check the SAML:ATTRIBUTES +    nl = XPathUtils.selectNodeList(samlAssertion, ATTRIBUTE_XPATH); +    for (int i = 0; i < nl.getLength(); i++) { +      String attributeName = +        XPathUtils.getAttributeValue( +          (Element) nl.item(i), +          "@AttributeName", +          null); +      String attributeNS = +        XPathUtils.getAttributeValue( +          (Element) nl.item(i), +          "@AttributeNamespace", +          null); +      if (attributeName.equals("CitizenPublicKey")) { +                 +        if (attributeNS.equals("http://www.buergerkarte.at/namespaces/personenbindung/20020506#") || +            attributeNS.equals("urn:publicid:gv.at:namespaces:identitylink:1.2")) { +          Element attributeValue =  +              (Element) XPathUtils.selectSingleNode((Element) nl.item(i),nSMap, SAML + "AttributeValue/" + DSIG + "RSAKeyValue");           +           if (attributeValue==null)  +             attributeValue =  +               (Element) XPathUtils.selectSingleNode((Element)nl.item(i), nSMap, SAML + "AttributeValue/" + ECDSA + "ECDSAKeyValue"); +           if (attributeValue==null)  +               attributeValue =  +                 (Element) XPathUtils.selectSingleNode((Element)nl.item(i), nSMap, SAML + "AttributeValue/" + DSIG + "DSAKeyValue"); +           if (attributeValue == null) +            throw new ValidateException("validator.02", null); +                       +        } +        else +          throw new ValidateException("validator.03", new Object [] {attributeNS} ); +      } +      else +        throw new ValidateException("validator.04", new Object [] {attributeName} ); +    } +     +    //Check if dsig:Signature exists +     Element dsigSignature = (Element) XPathUtils.selectSingleNode(samlAssertion,ROOT + DSIG + "Signature"); +     if (dsigSignature==null) throw new ValidateException("validator.05", new Object[] {"in der Personenbindung"}); +  } + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/InfoboxValidator.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/InfoboxValidator.java new file mode 100644 index 000000000..e6e2539c9 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/InfoboxValidator.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.validator; + +import java.util.Map; + +import org.w3c.dom.Element; + +import at.gv.egovernment.moa.id.auth.data.InfoboxValidationResult; +import at.gv.egovernment.moa.id.auth.data.InfoboxValidatorParams; +import at.gv.egovernment.moa.id.auth.exception.ValidateException; + +/** + * Validates an InfoboxReadResponse. + * An implementing class has to validate the content of the InfoboxReadResponse   + * according to the type specific rules and guidelines of the underlying  + * application. + */ +public interface InfoboxValidator { +   +  /** +   * This method validates an InfoboxReadResponse. +   * The method validates the content of the passed <code>infoboxReadResponse</code> +   * according to the type specific rules and guidelines of the underlying +   * application. +   * +   * @param params {@link at.gv.egovernment.moa.id.auth.data.InfoboxValidatorParams +   *                Parameters} needed by the validator. +   *  +   * @return InfoboxValidationResult structure (@link at.gv.egovernment.moa.id.auth.data.InfoboxValidationResult} +   *                             +   * @throws ValidateException  If an error occurs on validating the  +   *                            InfoboxReadResponse. +   */ +  public InfoboxValidationResult validate (InfoboxValidatorParams params) +    throws ValidateException; + +  /** +   * This method is used to do intermediate processing before signing the auth block. +   * If a infobox validator threw a form to gather user input, this method is used +   * to validate this input. In no further input is needed the form must be empty to  +   * proceed, and also a valid <code>InfoboxValidationResult</code> is necessary. +   * If more input is needed, the validator can build a new form and it is then shown  +   * to the citizen.  +   * The implementation of <code>InfoboxValidator</code> must hold its necessary  +   * data and configuration internally, if this method is called - the class is  +   * reused at this call +   * +   * @param parameters the parameters got returned by the input fields +   *  +   * @return InfoboxValidationResult structure (@link at.gv.egovernment.moa.id.auth.data.InfoboxValidationResult} +   *                             +   * @throws ValidateException  If an error occurs on validating the  +   *                            InfoboxReadResponse. +   */ +  public InfoboxValidationResult validate (Map parameters) +    throws ValidateException; + +  /** +   * This method is used to do post processing after signing the auth block. +   * The method validates the content of the <code>infoboxReadResponse</code  +   * against the passed <code>samlAssertion</code> if needed. +   * The implementation of <code>InfoboxValidator</code> must hold its necessary  +   * data and configuration internally, if this method is called - the class is  +   * reused at this call +   * +   * @param samlAssertion the SAML assertion needed by the validator +   *  +   * @return InfoboxValidationResult structure (@link at.gv.egovernment.moa.id.auth.data.InfoboxValidationResult} +   *                             +   * @throws ValidateException  If an error occurs on validating the  +   *                            InfoboxReadResponse. +   */ +  public InfoboxValidationResult validate (Element samlAssertion) +    throws ValidateException; +   +  /** +   * form for user interaction for intermediate processing of infobox validation +   *  +   * @return answer form of the servlet request. +   */ +  public String getForm(); +   +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java new file mode 100644 index 000000000..ac528c89d --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java @@ -0,0 +1,303 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.validator; + +import iaik.asn1.ObjectID; +import iaik.asn1.structures.Name; +import iaik.security.ecc.ecdsa.ECPublicKey; +import iaik.utils.RFC2253NameParserException; +import iaik.x509.X509Certificate; +import iaik.x509.X509ExtensionInitException; + +import java.security.InvalidKeyException; +import java.security.PublicKey; +import java.security.interfaces.RSAPublicKey; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.auth.data.IdentityLink; +import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.exception.ValidateException; +import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; +import at.gv.egovernment.moa.id.util.MOAIDMessageProvider; +import at.gv.egovernment.moa.logging.Logger; + +/** + * This class is used to validate an {@link VerifyXMLSignatureResponse}  + * returned by MOA-SPSS + *  + * @author Stefan Knirsch + * @version $Id$ + */ +public class VerifyXMLSignatureResponseValidator { +   +  /** Identification string for checking identity link */ +  public static final String CHECK_IDENTITY_LINK = "IdentityLink"; +  /** Identification string for checking authentication block */ +  public static final String CHECK_AUTH_BLOCK = "AuthBlock"; +   +  /** Singleton instance. <code>null</code>, if none has been created. */ +  private static VerifyXMLSignatureResponseValidator instance; + +  /** +   * Constructor for a singleton VerifyXMLSignatureResponseValidator. +   */ +  public static synchronized VerifyXMLSignatureResponseValidator getInstance() +    throws ValidateException { +    if (instance == null) { +      instance = new VerifyXMLSignatureResponseValidator(); +    } +    return instance; +  } + +  /** +   * Validates a {@link VerifyXMLSignatureResponse} returned by MOA-SPSS.  +   *  +   * @param verifyXMLSignatureResponse the <code><VerifyXMLSignatureResponse></code> +   * @param identityLinkSignersSubjectDNNames subject names configured +   * @param whatToCheck is used to identify whether the identityLink or the Auth-Block is validated +   * @param oaParam specifies whether the validation result of the  +   *                                       manifest has to be ignored (identityLink validation if +   *                                       the OA is a business service) or not +   * @throws ValidateException on any validation error + * @throws ConfigurationException  +   */ +  public void validate(VerifyXMLSignatureResponse verifyXMLSignatureResponse, +                       List<String> identityLinkSignersSubjectDNNames,  +                       String whatToCheck, +                       IOAAuthParameters oaParam) +    throws ValidateException, ConfigurationException { + +    if (verifyXMLSignatureResponse.getSignatureCheckCode() != 0) +      throw new ValidateException("validator.06", null); +       +    if (verifyXMLSignatureResponse.getCertificateCheckCode() != 0) { +			String checkFailedReason =""; +			if (verifyXMLSignatureResponse.getCertificateCheckCode() == 1)  +				checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.21", null); +			if (verifyXMLSignatureResponse.getCertificateCheckCode() == 2)  +				checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.22", null); +			if (verifyXMLSignatureResponse.getCertificateCheckCode() == 3)  +				checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.23", null); +			if (verifyXMLSignatureResponse.getCertificateCheckCode() == 4)  +				checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.24", null); +			if (verifyXMLSignatureResponse.getCertificateCheckCode() == 5)  +				checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.25", null); + +//     TEST CARDS +      if (whatToCheck.equals(CHECK_IDENTITY_LINK)) +        throw new ValidateException("validator.07", new Object[] { checkFailedReason } ); +      else +        throw new ValidateException("validator.19", new Object[] { checkFailedReason } ); +    } +     +    //check QC  +    if (AuthConfigurationProviderFactory.getInstance().isCertifiacteQCActive() && +    		!whatToCheck.equals(CHECK_IDENTITY_LINK) && +    		!verifyXMLSignatureResponse.isQualifiedCertificate()) { +    	    	 +    	//check if testcards are active and certificate has an extension for test credentials +    	if (oaParam.isTestCredentialEnabled()) { +        	boolean foundTestCredentialOID = false; +        	try { +        		X509Certificate signerCert = verifyXMLSignatureResponse.getX509certificate(); +    		 +        		List<String> validOIDs = new ArrayList<String>(); +        		if (oaParam.getTestCredentialOIDs() != null) +        			validOIDs.addAll(oaParam.getTestCredentialOIDs()); +        		else +        			validOIDs.add(MOAIDAuthConstants.TESTCREDENTIALROOTOID); +    		 +        		Set<String> extentsions = signerCert.getCriticalExtensionOIDs(); +        		extentsions.addAll(signerCert.getNonCriticalExtensionOIDs()); +        		Iterator<String> extit = extentsions.iterator(); +        		while(extit.hasNext()) { +        			String certOID = extit.next(); +        			for (String el : validOIDs) { +        				if (certOID.startsWith(el)) +        					foundTestCredentialOID = true; +        			}    			 +        		} +        		 +        	} catch (Exception e) { +        		Logger.warn("Test credential OID extraction FAILED.", e); +        		 +        	} +        	//throw Exception if not TestCredentialOID is found +        	if (!foundTestCredentialOID) +        		throw new ValidateException("validator.72", null); +    		 +    	} else    	 +    		throw new ValidateException("validator.71", null);         +    } +     +    // if OA is type is business service the manifest validation result has +    // to be ignored +    boolean ignoreManifestValidationResult = false; +    if (whatToCheck.equals(CHECK_IDENTITY_LINK))    	 +    	ignoreManifestValidationResult = (oaParam.getBusinessService()) ? true +            : false; +     +    if (ignoreManifestValidationResult) { +      Logger.debug("OA type is business service, thus ignoring DSIG manifest validation result"); +    } else { +      if (verifyXMLSignatureResponse.isXmlDSIGManigest()) +        if (verifyXMLSignatureResponse.getXmlDSIGManifestCheckCode() != 0) +          throw new ValidateException("validator.08", null); +    } +     +     +    // Check the signature manifest only when verifying the signed AUTHBlock +    if (whatToCheck.equals(CHECK_AUTH_BLOCK)) { +      if (verifyXMLSignatureResponse.getSignatureManifestCheckCode() > 0) { +        throw new ValidateException("validator.50", null); +      } +    } +         +    //Check whether the returned X509 SubjectName is in the MOA-ID configuration or not +    if (identityLinkSignersSubjectDNNames != null) { +      String subjectDN = ""; +      X509Certificate x509Cert = verifyXMLSignatureResponse.getX509certificate(); +      try { +        subjectDN = ((Name) x509Cert.getSubjectDN()).getRFC2253String(); +      } +      catch (RFC2253NameParserException e) { +        throw new ValidateException("validator.17", null); +      } +      //System.out.println("subjectDN: " + subjectDN); +      // check the authorisation to sign the identity link +      if (!identityLinkSignersSubjectDNNames.contains(subjectDN)) { +        // subject DN check failed, try OID check: +        try { +          if (x509Cert.getExtension(MOAIDAuthConstants.IDENTITY_LINK_SIGNER_OID) == null) { +            throw new ValidateException("validator.18", new Object[] { subjectDN }); +          } else { +            Logger.debug("Identity link signer cert accepted for signing identity link: " + +                         "subjectDN check failed, but OID check successfully passed."); +          } +        } catch (X509ExtensionInitException e) { +          throw new ValidateException("validator.49", null); +        } +      } else { +        Logger.debug("Identity link signer cert accepted for signing identity link: " + +                     "subjectDN check successfully passed."); +      } +       +    } +  } +   +  /** +   * Method validateCertificate. +   * @param verifyXMLSignatureResponse The VerifyXMLSignatureResponse +   * @param idl The Identitylink +   * @throws ValidateException +   */ +  public void validateCertificate( +    VerifyXMLSignatureResponse verifyXMLSignatureResponse, +    IdentityLink idl) +    throws ValidateException { + +    X509Certificate x509Response = verifyXMLSignatureResponse.getX509certificate(); +    PublicKey[] pubKeysIdentityLink = (PublicKey[]) idl.getPublicKey(); + +    PublicKey pubKeySignature = x509Response.getPublicKey(); + +    boolean found = false; +    for (int i = 0; i < pubKeysIdentityLink.length; i++) { +       +      //compare RSAPublicKeys +      if ((idl.getPublicKey()[i] instanceof java.security.interfaces.RSAPublicKey) &&   +      		(pubKeySignature instanceof java.security.interfaces.RSAPublicKey)) { + +          RSAPublicKey rsaPubKeySignature = (RSAPublicKey) pubKeySignature; +          RSAPublicKey rsakey = (RSAPublicKey) pubKeysIdentityLink[i]; +           +          if (rsakey.getModulus().equals(rsaPubKeySignature.getModulus()) +              && rsakey.getPublicExponent().equals(rsaPubKeySignature.getPublicExponent())) +          found = true;       +      } +       +      //compare ECDSAPublicKeys +      if( ( (idl.getPublicKey()[i] instanceof java.security.interfaces.ECPublicKey) ||  +    		  (idl.getPublicKey()[i] instanceof iaik.security.ecc.ecdsa.ECPublicKey)) &&  +         ( (pubKeySignature instanceof java.security.interfaces.ECPublicKey) ||  +        		(pubKeySignature instanceof iaik.security.ecc.ecdsa.ECPublicKey) ) ) { + +		try { +			ECPublicKey ecdsaPubKeySignature = new ECPublicKey(pubKeySignature.getEncoded()); +			ECPublicKey ecdsakey = new ECPublicKey(pubKeysIdentityLink[i].getEncoded()); +			 +	        if(ecdsakey.equals(ecdsaPubKeySignature)) +	              found = true; +			 +		} catch (InvalidKeyException e) { +			Logger.warn("ECPublicKey can not parsed into a iaik.ECPublicKey", e); +			throw new ValidateException("validator.09", null); +		} +           +           + +      } +       +//  		Logger.debug("IDL-Pubkey=" + idl.getPublicKey()[i].getClass().getName() +//  				+ "  Resp-Pubkey=" + pubKeySignature.getClass().getName()); +       +    } + +    if (!found) { +       	 +      throw new ValidateException("validator.09", null); +             +    } +  } + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/parep/ParepUtils.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/parep/ParepUtils.java new file mode 100644 index 000000000..1850ff671 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/parep/ParepUtils.java @@ -0,0 +1,762 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.validator.parep; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; + +import javax.xml.parsers.DocumentBuilderFactory; + +import org.apache.xml.serialize.OutputFormat; +import org.apache.xml.serialize.XMLSerializer; +import org.apache.xpath.XPathAPI; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import at.gv.egovernment.moa.id.auth.builder.BPKBuilder; +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.id.auth.exception.ValidateException; +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.logging.Logger; +import at.gv.egovernment.moa.util.BoolUtils; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.StringUtils; + +/** + * This class implements a set of utility methods. + *  + * @author <a href="mailto:peter.danner@egiz.gv.at">Peter Danner</a> + */ +public class ParepUtils { + +  /** +   * Determines whether a string is null or empty +   *  +   * @param str the string to check. +   * @return <code>true</code> if the string is null or empty, +   *         <code>false</code> otherwise. +   */ +  public static boolean isEmpty(String str) { +    return str == null || "".equals(str); +  } + +  /** +   * Reads a XML document from an input stream (namespace-aware). +   *  +   * @param is +   *          the input stream to read from. +   * @return the read XML document. +   * @throws SZRGWClientException +   *           if an error occurs reading the document from the input stream. +   */ +  public static Document readDocFromIs(InputStream is) throws SZRGWClientException { +    try { +      DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); +      f.setNamespaceAware(true); +      return f.newDocumentBuilder().parse(is); +    } catch (Exception e) { +      throw new SZRGWClientException(e); +    } +  } + +//  /* +//   *  +//   */ +//  public static String extractRepresentativeID(Element mandate) throws ValidateException { +//    try { +//      Element nameSpaceNode = mandate.getOwnerDocument().createElement("NameSpaceNode"); +//      nameSpaceNode.setAttribute("xmlns:md", SZRGWConstants.MANDATE_NS); +//      Node resultNode = XPathAPI.selectSingleNode(mandate, "//md:Mandate/attribute::MandateID", nameSpaceNode); +//      if (resultNode != null) { +//        // because following line is not ready for JDK 1.4.x we need to get the childnode;  +//        // return resultNode.getTextContent(); +//        Node textNode = resultNode.getFirstChild(); +//        if (textNode != null) { +//          return textNode.getNodeValue(); +//        } +//      } +//      return null; +//    } catch (Exception e) { +//      throw new ValidateException("validator.62", null); +//    } +//  } + + +  /** +   * Dumps all bytes from an input stream to the given output stream. +   *  +   * @param is +   *          the input stream to dump from. +   * @param os +   *          the output stream to dump to. +   * @throws IOException +   *           if an error occurs while dumping. +   */ +  public static void dumpInputOutputStream(InputStream is, OutputStream os) throws IOException { +    if (is == null) { +      return; +    } +    int ch; +    while ((ch = is.read()) != -1) { +      os.write(ch); +    } +  } + +  /** +   * Gets a string that represents the date a mandate was issued. +   *  +   * @param mandate +   *          the mandate to extract the issuing date from. +   * @return the issuing date of the given mandate. +   * @throws SZRGWClientException +   *           if an exception occurs extracting the issuing date of the +   *           mandate. +   */ +  public static String getMandateIssuedDate(Element mandate) throws SZRGWClientException { +    try { +      Element nameSpaceNode = mandate.getOwnerDocument().createElement("NameSpaceNode"); +      nameSpaceNode.setAttribute("xmlns:md", SZRGWConstants.MANDATE_NS); + +      Node dateNode = XPathAPI.selectSingleNode(mandate, "//md:Issued/md:Date/text()", nameSpaceNode); + +      if (dateNode == null) { +        throw new Exception("Date in Mandate-Issued not found."); +      } +      return dateNode.getNodeValue(); +    } catch (Exception e) { +      throw new SZRGWClientException(e); +    } +  } + +  /** +   * Gets a string that represents the place a mandate was issued. +   *  +   * @param mandate +   *          the mandate to extract the issuing place from. +   * @return the issuing place of the given mandate. +   * @throws SZRGWClientException +   *           if an exception occurs extracting the issuing place of the +   *           mandate. +   */ +  public static String getMandateIssuedPlace(Element mandate) throws SZRGWClientException { +    try { +      Element nameSpaceNode = mandate.getOwnerDocument().createElement("NameSpaceNode"); +      nameSpaceNode.setAttribute("xmlns:md", SZRGWConstants.MANDATE_NS); + +      Node placeNode = XPathAPI.selectSingleNode(mandate, "//md:Issued/md:Place/text()", nameSpaceNode); + +      if (placeNode == null) { +        throw new Exception("Place in Mandate-Issued not found."); +      } +      return placeNode.getNodeValue(); +    } catch (Exception e) { +      throw new SZRGWClientException(e); +    } +  } + +  /** +   * Extracts the textual description of the mandate. +   *  +   * @param mandate +   *          the mandate to extract the textual description from. +   * @return the textual description of the mandate. +   * @throws SZRGWClientException +   *           if an exception occurs extracting the textual description. +   */ +  public static String getMandateContent(Element mandate) throws SZRGWClientException { +    try { +      Element nameSpaceNode = mandate.getOwnerDocument().createElement("NameSpaceNode"); +      nameSpaceNode.setAttribute("xmlns:md", SZRGWConstants.MANDATE_NS); + +      Node contentNode = XPathAPI.selectSingleNode(mandate, "//md:SimpleMandateContent/md:TextualDescription/text()", nameSpaceNode); + +      if (contentNode == null) { +        throw new Exception("Content in Mandate not found."); +      } +      return contentNode.getNodeValue(); +    } catch (Exception e) { +      throw new SZRGWClientException(e); +    } +  } + +  /** +   * Extracts the md:Mandator element from a XML mandate element. +   *  +   * @param mandate +   *          the md:Mandate element to extract the md:Mandator from. +   * @return the md:Mandator element. +   * @throws SZRGWClientException +   *           if an error occurs extracting the md:Mandator element. +   */ +  public static Element extractMandator(Element mandate) throws ParseException { +    try { +       +      Element nameSpaceNode = mandate.getOwnerDocument().createElement("NameSpaceNode"); +      nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.MANDATE_POSTFIX, SZRGWConstants.MANDATE_NS); +      Element mandator = (Element) XPathAPI.selectSingleNode(mandate, "//" + SZRGWConstants.MANDATE_PREFIX + SZRGWConstants.MANDATOR, nameSpaceNode); +      if (mandator == null) { +        // if we got the Mandator itself +        if (mandate.getLocalName().equals(SZRGWConstants.MANDATOR)) return mandate; +      } +      if (mandator == null) +        return null; +      String nsPrefix = mandator.getPrefix(); +      String nsUri = mandator.getNamespaceURI(); +      Element mandatorClone = (Element) mandator.cloneNode(true); +      mandatorClone.setAttribute("xmlns:" + nsPrefix, nsUri); +      return mandatorClone; +    } catch (Exception e) { +      throw new ParseException(e.toString(), null); +    } +  } +   +  /** +   * Tells wether a mandator is a physical person or not. +   *  +   * @param mandator +   *          the XML md:Mandator element to extract from. +   * @return <code>true<code> if the mandator is a physical person, <code>false</code> otherwise. +   */ +  public static boolean isPhysicalPerson(Element mandator) { +    try { +      Element nameSpaceNode = mandator.getOwnerDocument().createElement("NameSpaceNode"); +      nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.PD_POSTFIX, Constants.PD_NS_URI); + +      DOMUtils.serializeNode(mandator); +       +      // check if physical person +      Element physicalPerson = (Element) XPathAPI.selectSingleNode(mandator, "descendant-or-self::pr:PhysicalPerson", nameSpaceNode); +       +       +      // Element physicalPerson = (Element)XPathAPI.selectSingleNode(mandator, +      // "descendant-or-self::pr:CorporateBody", nameSpaceNode); +      return physicalPerson != null; +    } catch (Exception e) { +      e.printStackTrace(); +      return false; +    } +  } + +  /** +   * Extracts the <code>pr:PhysicalPerson</code> or <code>pr:CorporateBody</code>  +   * element from a XML mandate element. +   *  +   * @param mandate +   *          the md:Mandate element to extract the person from. +   * @return the <code>pr:PhysicalPerson</code> or <code>pr:CorporateBody</code> element. +   * @throws ParseException +   *           if an error occurs extracting the element. +   */ +  public static Element extractPersonOfMandate(Element mandate) throws ParseException { +    try { +       +      Element nameSpaceNode = mandate.getOwnerDocument().createElement("NameSpaceNode"); +      nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.MANDATE_POSTFIX, SZRGWConstants.MANDATE_NS); +      nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.PD_POSTFIX, Constants.PD_NS_URI); +      Element person = (Element) XPathAPI.selectSingleNode(mandate, "//" + SZRGWConstants.MANDATE_PREFIX + SZRGWConstants.MANDATOR + "/pr:PhysicalPerson", nameSpaceNode); +      if (person == null) { +        person = (Element) XPathAPI.selectSingleNode(mandate, "//" + SZRGWConstants.MANDATE_PREFIX + SZRGWConstants.MANDATOR + "/pr:CorporateBody", nameSpaceNode); +      } +      if (person == null) return null; +      String nsPrefix = person.getPrefix(); +      String nsUri = person.getNamespaceURI(); +      Element personClone = (Element) person.cloneNode(true); +      personClone.setAttribute("xmlns:" + nsPrefix, nsUri); +      return personClone; +    } catch (Exception e) { +      //e.printStackTrace(); +      throw new ParseException(e.toString(), null); +    } +  } + +  /** +   * Benerates the </code>pr:Person</code> element form a  +   * <code>pr:PhysicalPerson</code> or <code>pr:CorporateBody</code>  +   * element of a XML mandate element. +   *  +   * @param mandate +   *          the md:Mandate element to extract the person from. +   * @return the <code>pr:Person</code> element. +   * @throws ParseException +   *           if an error occurs extracting the element. +   */ +  public static Element extractPrPersonOfMandate(Element mandate) throws ParseException { + +    try { +      Document document = ParepUtils.createEmptyDocument(); +      Element root = document.createElement(SZRGWConstants.PD_PREFIX + SZRGWConstants.PERSON); +      root.setAttribute("xmlns" + SZRGWConstants.PD_POSTFIX, Constants.PD_NS_URI); +      root.setAttribute("xmlns:" + Constants.XSI_PREFIX, Constants.XSI_NS_URI); + +      Element nameSpaceNode = mandate.getOwnerDocument().createElement("NameSpaceNode"); +      nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.MANDATE_POSTFIX, SZRGWConstants.MANDATE_NS); +      nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.PD_POSTFIX, Constants.PD_NS_URI); +      Element person = (Element) XPathAPI.selectSingleNode(mandate, "//"  +          + SZRGWConstants.MANDATE_PREFIX + SZRGWConstants.MANDATOR + "/" + SZRGWConstants.PD_PREFIX + SZRGWConstants.PHYSICALPERSON, nameSpaceNode); +      if (person == null) { +        person = (Element) XPathAPI.selectSingleNode(mandate, "//"  +            + SZRGWConstants.MANDATE_PREFIX + SZRGWConstants.MANDATOR + "/" + SZRGWConstants.PD_PREFIX + SZRGWConstants.CORPORATEBODY, nameSpaceNode); +      } +      if (person != null) { +        root.setAttribute(Constants.XSI_PREFIX + ":type", SZRGWConstants.PD_PREFIX + person.getLocalName()); +        if (person != null) { +          NodeList nl = person.getChildNodes(); +          for (int i = 0; i < nl.getLength(); i++) { +            Node testNode = nl.item(i); +            if (Node.ELEMENT_NODE == testNode.getNodeType()) { +              root.appendChild(document.importNode(testNode, true)); +            } +          } +        } +      } +       +      return root; +    } catch (Exception e) { +      //e.printStackTrace(); +      throw new ParseException(e.toString(), null); +    } +  } +   +  /** +   * Extracts the name of the mandator as a string representation. +   *  +   * @param mandator +   *          the XML md:Mandator element to extract from. +   * @return the mandator name as a string. +   */ +  public static String extractMandatorName(Element mandator) { +    try { +      Element nameSpaceNode = mandator.getOwnerDocument().createElement("NameSpaceNode"); +      nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.PD_POSTFIX, Constants.PD_NS_URI); + +      // first check if physical person +      Element name = (Element) XPathAPI.selectSingleNode(mandator, "descendant-or-self::pr:Name/pr:GivenName", nameSpaceNode); +      if (name != null) { +        String givenName = XPathAPI.selectSingleNode(mandator, "descendant-or-self::pr:Name/pr:GivenName/text()", nameSpaceNode).getNodeValue(); +        String familyName = XPathAPI.selectSingleNode(mandator, "descendant-or-self::pr:Name/pr:FamilyName/text()", nameSpaceNode).getNodeValue(); + +        return givenName + " " + familyName; +      } + +      // check if corporate body +      Node fullName = XPathAPI.selectSingleNode(mandator, "descendant-or-self::pr:FullName/text()", nameSpaceNode); +      if (fullName != null) { +        return fullName.getNodeValue(); +      } +      return ""; +    } catch (Exception e) { +      //e.printStackTrace(); +      return ""; +    } +  } + +  /** +   * Extracts specific text of an element of a given md:Mandator element. +   *  +   * @param mandator +   *          the XML md:Mandator to extract from. +   * @return the resulting text of the mandator element. +   */ +  public static String extractText(Element mandator, String xpath) { +    try { +      Element nameSpaceNode = mandator.getOwnerDocument().createElement("NameSpaceNode"); +      nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.PD_POSTFIX, Constants.PD_NS_URI); + +      Node textNode = XPathAPI.selectSingleNode(mandator, xpath, nameSpaceNode); +      if (textNode == null) +        return null; +      return textNode.getNodeValue(); +    } catch (Exception e) { +      e.printStackTrace(); +      return null; +    } +  } + +  /** +   * Extracts the date of birth of the mandator of a given md:Mandator element. +   *  +   * @param mandator +   *          the XML md:Mandator to extract from. +   * @return the dob of the mandator. +   */ +  public static String extractMandatorDateOfBirth(Element mandator) { +    try { +      Element nameSpaceNode = mandator.getOwnerDocument().createElement("NameSpaceNode"); +      nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.PD_POSTFIX, Constants.PD_NS_URI); + +      Node dobName = XPathAPI.selectSingleNode(mandator, "descendant-or-self::pr:DateOfBirth/text()", nameSpaceNode); +      if (dobName == null) +        return null; +      return dobName.getNodeValue(); +    } catch (Exception e) { +      e.printStackTrace(); +      return null; +    } +  } + +  /** +   * Extracts the full name of the mandators corporate body of a given +   * md:Mandator element. +   *  +   * @param mandator +   *          the XML md:Mandator to extract from. +   * @return the full name of the mandator. +   */ +  public static String extractMandatorFullName(Element mandator) { +    try { +      Element nameSpaceNode = mandator.getOwnerDocument().createElement("NameSpaceNode"); +      nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.PD_POSTFIX, Constants.PD_NS_URI); + +      Node fullName = XPathAPI.selectSingleNode(mandator, "descendant-or-self::pr:CorporateBody/pr:FullName/text()", nameSpaceNode); +      if (fullName == null) +        return null; +      return fullName.getNodeValue(); +    } catch (Exception e) { +      e.printStackTrace(); +      return null; +    } +  } + +  /** +   * Extracts the identification value of the mandator of a given mandate. +   *  +   * @param mandator +   *          the XML md:Mandator element. +   * @return the identification value. +   */ +  public static String extractMandatorWbpk(Element mandator) { +    try { +      Element nameSpaceNode = mandator.getOwnerDocument().createElement("NameSpaceNode"); +      nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.PD_POSTFIX, Constants.PD_NS_URI); + +      Node idValue = XPathAPI.selectSingleNode(mandator, "descendant-or-self::pr:Identification/pr:Value/text()", nameSpaceNode); +      if (idValue != null) { +        return idValue.getNodeValue(); +      } +      return ""; +    } catch (Exception e) { +      e.printStackTrace(); +      return ""; +    } +  } + +  /** +   * Extracts the identification type of the mandator of a given mandate. +   *  +   * @param mandator +   *          the XML md:Mandator element. +   * @return the identification type. +   */ +  public static String extractMandatorIdentificationType(Element mandator) { +    try { +      Element nameSpaceNode = mandator.getOwnerDocument().createElement("NameSpaceNode"); +      nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.PD_POSTFIX, Constants.PD_NS_URI); + +      Node idType = XPathAPI.selectSingleNode(mandator, "descendant-or-self::pr:Identification/pr:Type/text()", nameSpaceNode); +      if (idType != null) { +        return idType.getNodeValue(); +      } +      return ""; +    } catch (Exception e) { +      e.printStackTrace(); +      return ""; +    } +  } + +  /* +   *  +   */ +  public static String getIdentification(Element personElement, String element) throws ParseException { +    try { + +      Element nameSpaceNode = personElement.getOwnerDocument().createElement("NameSpaceNode"); +      nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.PD_POSTFIX, Constants.PD_NS_URI); + +      return XPathAPI.selectSingleNode(personElement, "descendant-or-self::pr:Identification/pr:" + element + "/text()", nameSpaceNode) +          .getNodeValue(); +    } catch (Exception e) { +      throw new ParseException(e.toString(), null); +    } +  } + +//  /* +//   *  +//   */ +//  private static Element extractRepresentative(Element mandate) throws SZRGWClientException { +//    try { +//      Element nameSpaceNode = mandate.getOwnerDocument().createElement("NameSpaceNode"); +//      nameSpaceNode.setAttribute("xmlns:md", SZRGWConstants.MANDATE_NS); +//      Element mandator = (Element) XPathAPI.selectSingleNode(mandate, "//md:Representative/child::*[1]", nameSpaceNode); +//      String nsPrefix = mandator.getPrefix(); +//      String nsUri = mandator.getNamespaceURI(); +// +//      Element mandatorClone = (Element) mandator.cloneNode(true); +//      mandatorClone.setAttribute("xmlns:" + nsPrefix, nsUri); +// +//      return mandatorClone; +//    } catch (Exception e) { +//      throw new SZRGWClientException(e); +//    } +//  } + +  /** +   * Serializes a XML element to a given output stream. +   *  +   * @param element +   *          the XML element to serialize. +   * @param out +   *          the output streamt o serialize to. +   * @throws IOException +   *           if an I/O error occurs during serialization. +   */ +  public static void serializeElement(Element element, OutputStream out) throws IOException { +    OutputFormat format = new OutputFormat(); +    format.setOmitXMLDeclaration(true); +    format.setEncoding("UTF-8"); +    format.setPreserveSpace(true); +    XMLSerializer serializer = new XMLSerializer(new OutputStreamWriter(out, "UTF-8"), format); +    serializer.serialize(element); +  } + +  public static void serializeElementAsDocument(Element element, OutputStream out) throws IOException { +    OutputFormat format = new OutputFormat(); +    format.setOmitXMLDeclaration(false); +    format.setEncoding("UTF-8"); +    format.setPreserveSpace(true); +    XMLSerializer serializer = new XMLSerializer(new OutputStreamWriter(out, "UTF-8"), format); +    serializer.serialize(element); +  } + +  public static void serializeElementWithoutEncoding(Element element, OutputStream out) throws IOException { +    OutputFormat format = new OutputFormat(); +    format.setOmitXMLDeclaration(true); +    format.setEncoding("UTF-8"); +    format.setPreserveSpace(true); +    XMLSerializer serializer = new XMLSerializer(new OutputStreamWriter(out), format); +    serializer.serialize(element); +  } + +  public static void saveStringToFile(String str, File file) throws IOException { +    FileOutputStream fos = new FileOutputStream(file); +    fos.write(str.getBytes()); +    fos.flush(); +    fos.close(); +  } + +  public static void saveBytesToFile(byte[] str, File file) throws IOException { +    FileOutputStream fos = new FileOutputStream(file); +    fos.write(str); +    fos.flush(); +    fos.close(); +  } + +  public static void saveElementToFile(Element elem, File file) throws IOException { +    FileOutputStream fos = new FileOutputStream(file); +    serializeElementWithoutEncoding(elem, fos); +    fos.flush(); +    fos.close(); +  } + +  /** +   * Creates an empty XML document. +   *  +   * @return a newly created empty XML document. +   * @throws SZRGWClientException +   *           if an error occurs creating the empty document. +   */ +  public static Document createEmptyDocument() throws SZRGWClientException { +    try { +      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); +      factory.setNamespaceAware(true); +      return factory.newDocumentBuilder().newDocument(); +    } catch (Exception e) { +      throw new SZRGWClientException(e); +    } +  } + + +  /** +   * Tells if the Validator of an Infobox is enabled. If the corresponding application +   * specific configuration element <code>EnableInfoboxValidator</code> is missing, a default value <code>true</code> is assumed +   *  +   * @param applicationSpecificParams +   *          the XML element of the infobox configuration. +   * @return the boolean value of the determination. +   * @throws ConfigurationException +   *           if an error occurs reading the configuration. +   */ +  public static boolean isValidatorEnabled(Element applicationSpecificParams) throws ConfigurationException { +    try { +      Element nameSpaceNode = applicationSpecificParams.getOwnerDocument().createElement("NameSpaceNode"); +      nameSpaceNode.setAttribute("xmlns:" + Constants.MOA_ID_CONFIG_PREFIX, Constants.MOA_ID_CONFIG_NS_URI); +       +      //ParepUtils.serializeElement(applicationSpecificParams, System.out); +      Node validatorEnabledNode = XPathAPI.selectSingleNode(applicationSpecificParams, Constants.MOA_ID_CONFIG_PREFIX +          + ":EnableInfoboxValidator/text()", nameSpaceNode); +      if (validatorEnabledNode != null) { +        return BoolUtils.valueOf(validatorEnabledNode.getNodeValue()); +      } +      return true; +    } catch (Exception e) { +      // e.printStackTrace(); +      throw new ConfigurationException("config.02", null); +    } +  } + +  /** +   * Delivers a String with the description of the register which is described  +   * through the identification Type of a corporate body of the persondata schema  +   *  +   * @param identificationType +   *          the identification type. +   * @return the register description. +   */ +  public static String getRegisterString(String identificationType) { +    String corporateBase = Constants.URN_PREFIX_BASEID + "+"; +    if (ParepUtils.isEmpty(identificationType) || !identificationType.startsWith(corporateBase)) return null; +    String register = identificationType.substring(corporateBase.length()); +    if (ParepUtils.isEmpty(register)) return null; +    if (register.equals("FN") || register.equals("XFN")) return "Firmenbuchnummer"; +    if (register.equals("VR") || register.equals("XZVR") || register.equals("XVR") || register.equals("ZVR")) return "Nummer im Vereinsregister"; +    if (register.equals("ERSB") || register.equals("XERSB")) return "Nummer im Ergänzungsregister für sonstige Betroffene"; +    return null; +  } +   +  /** +   * Hides Stammzahlen in the given element  +   *  +   * @param hideElement The element where Stammzahlen should be replaced. +   * @param businessApplication For decision whether to calc a bPK or wbPK. +   * @param target Target for calculating a bPK. +   * @param registerID Necessary string for calculating a wbPK (example <code>FN+4096i</code>). +   * @param blank Switch for behaviour. +   *          <code>true</code> if Stammzahlen are blinded. All occurences will be replaced by empty strings. +   *          <code>false</code> calculates (w)bPKs and changes also the <code>pr:Identifivation/pr:Type</code> elements. +   * @return The element where Stammzahlen are hidden. +   */ +  public static Element HideStammZahlen(Element hideElement, boolean businessApplication, String target, String registerID, boolean blank)  +    throws BuildException { +    try { +      if (hideElement != null) { +        Element nameSpaceNode = hideElement.getOwnerDocument().createElement("NameSpaceNode"); +        nameSpaceNode.setAttribute("xmlns" + SZRGWConstants.PD_POSTFIX, Constants.PD_NS_URI); +        NodeList identifications = XPathAPI.selectNodeList(hideElement, "descendant-or-self::pr:Identification", nameSpaceNode); +        for (int i = 0; i < identifications.getLength(); i++) { +          Element identificationElement = (Element) identifications.item(i); +          Node idTypeNode = XPathAPI.selectSingleNode(identificationElement, "descendant-or-self::pr:Identification/pr:Type/text()", nameSpaceNode); +          if (idTypeNode != null && Constants.URN_PREFIX_BASEID.equals(idTypeNode.getNodeValue())) { +            Node idValueNode = XPathAPI.selectSingleNode(identificationElement, "descendant-or-self::pr:Identification/pr:Value/text()", nameSpaceNode); +            if (idValueNode == null || ParepUtils.isEmpty(idValueNode.getNodeValue())) { +              Logger.error("HideStammZahlen: Problem beim Parsen des erhaltenen Elements - Value Element(-Inhalt) von pr:Identification nicht vorhanden."); +              throw new BuildException("builder.02", null); +            } +            if (blank) { +              idValueNode.setNodeValue(""); +            } else { +              String idValue = idValueNode.getNodeValue(); +              if (businessApplication) { +                // wbPK berechnen +                idTypeNode.setNodeValue(Constants.URN_PREFIX_WBPK + "+" + registerID); +                String bpkBase64 = new BPKBuilder().buildWBPK(idValueNode.getNodeValue(), registerID); +                idValueNode.setNodeValue(bpkBase64); + +              } else { +                // bPK berechnen +                idTypeNode.setNodeValue(Constants.URN_PREFIX_BPK); +                String bpkBase64 = new BPKBuilder().buildBPK(idValueNode.getNodeValue(), target); +                idValueNode.setNodeValue(bpkBase64); +              } +            } +          } +        } +      } +    } catch (Exception e) { +      throw new BuildException("builder.02", null); +    } +    return hideElement; +  } + +  /** +   * Replaces each substring of string <code>s</code> that matches the given +   * <code>search</code> string by the given <code>replace</code> string. +   *  +   * @param s         The string where the replacement should take place. +   * @param search    The pattern that should be replaced. +   * @param replace   The string that should replace all each <code>search</code> +   *                  string within <code>s</code>. +   * @return          A string where all occurrence of <code>search</code> are +   *                  replaced with <code>replace</code>. +   */ +  public static String replaceAll (String s, String search, String replace) { +    if (replace==null) replace = ""; +    return StringUtils.replaceAll(s, search, replace); +  } + +   +//  public static void main(String[] args) throws Exception { +//    Document mandate = readDocFromIs(new FileInputStream("c:/Doku/work/Organwalter/schemas/Vertretung_OW_Max_Mustermann.xml")); +//    Document mandate = readDocFromIs(new FileInputStream("c:/mandator.xml")); +//    Document mandate = readDocFromIs(new FileInputStream("c:/vertetervollmacht_1.2.40.0.10.3.1.xml")); +//    Element mandatorElement = extractMandator(mandate.getDocumentElement()); +//    System.out.println(extractMandatorName(mandatorElement)); +//    System.out.println(extractMandatorDateOfBirth(mandatorElement)); +//    System.out.println(extractMandatorWbpk(mandatorElement)); +//    //serializeElement(mandatorElement, System.out); +//      serializeElement((extractPrPersonOfMandate(mandate.getDocumentElement())), System.out); +//  } +   +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/parep/client/szrgw/SZRGWClientException.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/parep/client/szrgw/SZRGWClientException.java new file mode 100644 index 000000000..85c213169 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/parep/client/szrgw/SZRGWClientException.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.validator.parep.client.szrgw; + +/** + * This class implements the basic exception type for the SZR-gateway client + *  + * @author <a href="mailto:peter.danner@egiz.gv.at">Peter Danner</a> + */ +public class SZRGWClientException extends Exception { + +  /** +	 *  +	 */ +	private static final long serialVersionUID = 26538259471017714L; + +/* +   * see super constructor. +   */ +  public SZRGWClientException() { +    super(); +  } + +  /* +   * see super constructor. +   */ +  public SZRGWClientException(String arg0) { +    super(arg0); +  } + +  /* +   * see super construction. +   */ +  public SZRGWClientException(Throwable arg0) { +    super(arg0); +  } + +  /* +   * see super constructor +   */ +  public SZRGWClientException(String arg0, Throwable arg1) { +    super(arg0, arg1); +  } +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/parep/client/szrgw/SZRGWSecureSocketFactory.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/parep/client/szrgw/SZRGWSecureSocketFactory.java new file mode 100644 index 000000000..22b575489 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/parep/client/szrgw/SZRGWSecureSocketFactory.java @@ -0,0 +1,170 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.validator.parep.client.szrgw; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; + +import javax.net.ssl.SSLSocketFactory; + +import org.apache.commons.httpclient.params.HttpConnectionParams; +import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; + +/** + * This class implements a secure protocol socket factory + * for the Apache HTTP client. + *  + * @author <a href="mailto:peter.danner@egiz.gv.at">Peter Danner</a> + */ +public class SZRGWSecureSocketFactory implements SecureProtocolSocketFactory { + +  /** +   * The SSL socket factory. +   */ +  private SSLSocketFactory factory; +   +  /** +   * Creates a new Secure socket factory for the +   * Apache HTTP client. +   *  +   * @param factory the SSL socket factory to use. +   */ +  public SZRGWSecureSocketFactory(SSLSocketFactory factory) { +    this.factory = factory; +  } +   +   +  /** +   * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int) +   */ +  public Socket createSocket( +      String host, +      int port, +      InetAddress clientHost, +      int clientPort) +      throws IOException, UnknownHostException { + +      return this.factory.createSocket( +          host, +          port, +          clientHost, +          clientPort +      ); +  } + +  /** +   * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int) +   */ +  public Socket createSocket(String host, int port) +      throws IOException, UnknownHostException { +      return this.factory.createSocket( +          host, +          port +      ); +  } + +  /** +   * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean) +   */ +  public Socket createSocket( +      Socket socket, +      String host, +      int port, +      boolean autoClose) +      throws IOException, UnknownHostException { +      return this.factory.createSocket( +          socket, +          host, +          port, +          autoClose +      ); +  } +   +  /** +   * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int,org.apache.commons.httpclient.params.HttpConnectionParams) +   */ +  public Socket createSocket( +      String host, +      int port, +      InetAddress clientHost, +      int clientPort, +      HttpConnectionParams params) +      throws IOException, UnknownHostException, org.apache.commons.httpclient.ConnectTimeoutException { + +      Socket socket = createSocket(host, port, clientHost, clientPort); +      if (socket != null) { +          // socket.setKeepAlive(false); +          if (params.getReceiveBufferSize() >= 0) +              socket.setReceiveBufferSize(params.getReceiveBufferSize()); +          if (params.getSendBufferSize() >= 0) +              socket.setSendBufferSize(params.getSendBufferSize()); +          socket.setReuseAddress(true); +          if (params.getSoTimeout() >= 0) +              socket.setSoTimeout(params.getSoTimeout()); +      } +      return socket; +     +  } + +  /** +   * @see java.lang.Object#equals(java.lang.Object) +   */ +  public boolean equals(Object obj) { +      return ((obj != null) && obj.getClass().equals(SZRGWSecureSocketFactory.class)); +  } + +  /** +   * @see java.lang.Object#hashCode() +   */ +  public int hashCode() { +      return SZRGWSecureSocketFactory.class.hashCode(); +  } +   +} + diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/CitizenCardServletUtils.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/CitizenCardServletUtils.java new file mode 100644 index 000000000..276d6a105 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/CitizenCardServletUtils.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.util; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.URLEncoder; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; +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.exception.MOAIDException; +import at.gv.egovernment.moa.logging.Logger; + +/** + * @author <a href="mailto:peter.danner@egiz.gv.at">Peter Danner</a> + * + */ +public class CitizenCardServletUtils extends ServletUtils{ +   +  /** +   * Writes out whether the CreateXMLSignatureRequest or a Redirect for form input processing  +   * depending on the requests starting text. +   *  +   * @param resp The httpServletResponse +   * @param session The current AuthenticationSession +   * @param createXMLSignatureRequestOrRedirect The request +   * @param servletGoal The servlet to which the redirect should happen +   * @param servletName The servlet name for debug purposes +   * @throws MOAIDException +   * @throws IOException +   */ +  public static void writeCreateXMLSignatureRequestOrRedirect(HttpServletResponse resp, AuthenticationSession session, String createXMLSignatureRequestOrRedirect, String servletGoal, String servletName)  +  throws MOAIDException, +         IOException +  {  +    if (!createXMLSignatureRequestOrRedirect.startsWith("Redirect")) { +      resp.setStatus(307); +      String dataURL = new DataURLBuilder().buildDataURL( +        session.getAuthURL(), MOAIDAuthConstants.REQ_VERIFY_AUTH_BLOCK, session.getSessionID()); +      resp.addHeader("Location", dataURL); +       +      //TODO test impact of explicit setting charset with older versions of BKUs (HotSign) +      resp.setContentType("text/xml;charset=UTF-8"); +       +      OutputStream out = resp.getOutputStream(); +      out.write(createXMLSignatureRequestOrRedirect.getBytes("UTF-8")); +      out.flush(); +      out.close(); +      Logger.debug("Finished POST " + servletName); +       +    } else { +      String redirectURL = new DataURLBuilder().buildDataURL(session.getAuthURL(), servletGoal, session.getSessionID()); +      resp.setContentType("text/html"); +      resp.setStatus(302); +      resp.addHeader("Location", redirectURL); +      Logger.debug("REDIRECT TO: " + redirectURL); +       +    } +  } +  /** +   * Writes out whether the CreateXMLSignatureRequest or a Redirect for form input processing  +   * depending on the requests starting text. +   *  +   * @param resp The httpServletResponse +   * @param createXMLSignatureRequestOrRedirect The request +   * @param servletGoal The servlet to which the redirect should happen +   * @param servletName The servlet name for debug purposes +   * @throws MOAIDException +   * @throws IOException +   */ +  public static void writeCreateXMLSignatureRequest(HttpServletResponse resp, String createXMLSignatureRequestOrRedirect, String servletGoal, String servletName, String dataURL)  +  throws MOAIDException, +         IOException +  {  +      resp.setStatus(307); +      resp.addHeader("Location", dataURL); +       +      //TODO test impact of explicit setting charset with older versions of BKUs (HotSign) +      resp.setContentType("text/xml;charset=UTF-8"); +             +      OutputStream out = resp.getOutputStream(); +      out.write(createXMLSignatureRequestOrRedirect.getBytes("UTF-8")); +      out.flush(); +      out.close(); +      Logger.debug("Finished POST " + servletName); +     +  } + +  /** +   * Writes out whether the CreateXMLSignatureRequest or a Redirect for form input processing  +   * depending on the requests starting text. +   *  +   * @param resp The httpServletResponse +   * @param session The current AuthenticationSession +   * @param createXMLSignatureRequestOrRedirect The request +   * @param servletGoal The servlet to which the redirect should happen +   * @param servletName The servlet name for debug purposes +   * @throws MOAIDException +   * @throws IOException +   */ +  public static void writeCreateXMLSignatureRequestURLEncoded(HttpServletResponse resp, AuthenticationSession session, String createXMLSignatureRequestOrRedirect, String servletGoal, String servletName, String dataURL)  +  throws MOAIDException, +         IOException {  +	  resp.setStatus(200); +	  Logger.debug("ContentType set to: application/x-www-form-urlencoded"); +	 +	  resp.setContentType("application/x-www-form-urlencoded"); +	   +	  String content = "XMLRequest=" + URLEncoder.encode(createXMLSignatureRequestOrRedirect, "UTF-8") + "&" +  +	  					"DataURL=" + URLEncoder.encode(dataURL, "UTF-8"); +       +      OutputStream out = resp.getOutputStream(); +      out.write(content.getBytes("UTF-8")); +      out.flush(); +      out.close(); +      Logger.debug("Finished POST " + servletName); +     +  } +   +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSessionId.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSessionId.java new file mode 100644 index 000000000..69b546f78 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSessionId.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.util.client.mis.simple; + +public class MISSessionId { + +	private String sessiondId = null; +	private String redirectURL = null; +	 +	public String getSessiondId() { +  	return sessiondId; +  } +	public void setSessiondId(String sessiondId) { +  	this.sessiondId = sessiondId; +  } +	public String getRedirectURL() { +  	return redirectURL; +  } +	public void setRedirectURL(String redirectURL) { +  	this.redirectURL = redirectURL; +  } + +	 +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClient.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClient.java new file mode 100644 index 000000000..e346c8bee --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/util/client/mis/simple/MISSimpleClient.java @@ -0,0 +1,359 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.util.client.mis.simple; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.net.ssl.SSLSocketFactory; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.httpclient.HostConfiguration; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.xpath.XPathAPI; +import org.w3c.dom.DOMException; +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.auth.exception.MISSimpleClientException; +import at.gv.egovernment.moa.id.auth.validator.parep.client.szrgw.SZRGWSecureSocketFactory; +import at.gv.egovernment.moa.id.commons.utils.HttpClientWithProxySupport; +import at.gv.egovernment.moa.id.data.MISMandate; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.StringUtils; + + +public class MISSimpleClient { + +		 +	private final static String SOAP_NS = "http://schemas.xmlsoap.org/soap/envelope/"; +	private final static String MIS_NS = "http://reference.e-government.gv.at/namespace/mandates/mis/1.0/xsd"; +	 +	private static Element NS_NODE = null; +	 +		 +	static { +		try { +			NS_NODE = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument().createElement("test"); +			NS_NODE.setAttribute("xmlns:soap", SOAP_NS); +			NS_NODE.setAttribute("xmlns:mis", MIS_NS); +		} catch (Exception e) { +			Logger.warn("Error initializing namespace node.", e); +		} +	} +	 +	public static List<MISMandate> sendGetMandatesRequest(String webServiceURL, String sessionId, SSLSocketFactory sSLSocketFactory) throws MISSimpleClientException { +		if (webServiceURL == null) { +			throw new NullPointerException("Argument webServiceURL must not be null."); +		} +		if (sessionId == null) { +			throw new NullPointerException("Argument sessionId must not be null."); +		} +		 +		// ssl settings +		if (sSLSocketFactory != null) { +	        SZRGWSecureSocketFactory fac = new SZRGWSecureSocketFactory(sSLSocketFactory);  +	        Protocol.registerProtocol("https", new Protocol("https", fac, 443)); +		} + +		 +		try { +			Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); +			Element mirElement = doc.createElementNS(MIS_NS, "MandateIssueRequest"); +			Element sessionIdElement = doc.createElementNS(MIS_NS, "SessionID"); +			sessionIdElement.appendChild(doc.createTextNode(sessionId)); +			mirElement.appendChild(sessionIdElement); +	     +			// send soap request +			Element mandateIssueResponseElement = sendSOAPRequest(webServiceURL, mirElement); +	     +			// check for error +			checkForError(mandateIssueResponseElement); +	     +			// check for session id +			NodeList mandateElements  = XPathAPI.selectNodeList(mandateIssueResponseElement, "//mis:MandateIssueResponse/mis:Mandates/mis:Mandate", NS_NODE); +	     +			if (mandateElements == null || mandateElements.getLength() == 0) { +				throw new MISSimpleClientException("No mandates found in response."); +			} +	     +			ArrayList<MISMandate> foundMandates = new ArrayList<MISMandate>(); +			for (int i=0; i<mandateElements.getLength(); i++) { +				Element mandate = (Element) mandateElements.item(i); +								 +				MISMandate misMandate = new MISMandate(); +				if (mandate.hasAttribute("ProfessionalRepresentative")) { +//					System.out.println("OID: " + mandate.getAttribute("ProfessionalRepresentative")); +					misMandate.setProfRep(mandate.getAttribute("ProfessionalRepresentative")); +				} +				if (mandate.hasAttribute("OWbPK")) { +					misMandate.setOWbPK(mandate.getAttribute("OWbPK")); +//					System.out.println("OWBPK: " + mandate.getAttribute("OWbPK")); +				} +				 +				//misMandate.setMandate(Base64.decodeBase64(DOMUtils.getText(mandate))); +				misMandate.setMandate(Base64.decodeBase64(DOMUtils.getText(mandate).getBytes())); +				misMandate.setFullMandateIncluded(true); +				 +				foundMandates.add(misMandate); +			} +			return foundMandates; +		} catch (ParserConfigurationException e) { +			throw new MISSimpleClientException("service.06", e); +		} catch (DOMException e) { +			throw new MISSimpleClientException("service.06", e); +		} catch (TransformerException e) { +			throw new MISSimpleClientException("service.06", e); +		}  +	} +	 +	public static MISSessionId sendSessionIdRequest(String webServiceURL, byte[] idl, byte[] cert, String oaFriendlyName, String redirectURL, String referenceValue, List<String> mandateIdentifier, String targetType, byte[] authBlock, SSLSocketFactory sSLSocketFactory) throws MISSimpleClientException { +		if (webServiceURL == null) { +			throw new MISSimpleClientException("service.04"); +		} +		if (idl == null) { +			throw new NullPointerException("Argument idl must not be null."); +		} +		if (redirectURL == null) { +			throw new NullPointerException("Argument redirectURL must not be null."); +		} +		 +		// ssl settings +		if (sSLSocketFactory != null) { +	        SZRGWSecureSocketFactory fac = new SZRGWSecureSocketFactory(sSLSocketFactory);  +	        Protocol.registerProtocol("https", new Protocol("https", fac, 443)); +		} +		 +		try { +			Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); +			Element mirElement = doc.createElementNS(MIS_NS, "MandateIssueRequest"); +			Element idlElement = doc.createElementNS(MIS_NS, "IdentityLink"); +	     +			 +			idlElement.appendChild(doc.createTextNode(new String(Base64.encodeBase64(idl)))); +			mirElement.appendChild(idlElement); + +			if (cert != null && cert.length > 0) { +				Element certElement = doc.createElementNS(MIS_NS, "X509SignatureCertificate"); +				certElement.appendChild(doc.createTextNode(new String(Base64.encodeBase64(cert)))); +				//certElement.appendChild(doc.createTextNode(Base64.encodeBase64(cert))); +				//	    	certElement.appendChild(doc.createTextNode(new String(Base64.encodeBase64(cert)))); +				mirElement.appendChild(certElement); +			} +			 +			if (!StringUtils.isEmpty(oaFriendlyName)) { +				Element oaFriendlyNameElement = doc.createElementNS(MIS_NS, "OAFriendlyName"); +				oaFriendlyNameElement.appendChild(doc.createTextNode(oaFriendlyName)); +				mirElement.appendChild(oaFriendlyNameElement); +			} +			 +			Element redirectElement = doc.createElementNS(MIS_NS, "RedirectURL"); +			redirectElement.appendChild(doc.createTextNode(redirectURL)); +			mirElement.appendChild(redirectElement); +			 +			Element referenceValueElement = doc.createElementNS(MIS_NS, "ReferenceValue"); +			referenceValueElement.appendChild(doc.createTextNode(referenceValue)); +			mirElement.appendChild(referenceValueElement); +			 +			if (mandateIdentifier != null && mandateIdentifier.size() > 0) { +				Element filtersElement = doc.createElementNS(MIS_NS, "Filters"); +				Element mandateIdentifiersElement = doc.createElementNS(MIS_NS, "MandateIdentifiers"); +				for (int i=0; i<mandateIdentifier.size(); i++) { +					Element mandateIdentifierElement = doc.createElementNS(MIS_NS, "MandateIdentifier"); +					mandateIdentifierElement.appendChild(doc.createTextNode(mandateIdentifier.get(i))); +					mandateIdentifiersElement.appendChild(mandateIdentifierElement); +				} +				filtersElement.appendChild(mandateIdentifiersElement); +				mirElement.appendChild(filtersElement); +			} + +			//add Target element +			Element targetElement = doc.createElementNS(MIS_NS, "Target"); +			Element targetTypeElement = doc.createElementNS(MIS_NS, "Type"); +			targetTypeElement.appendChild(doc.createTextNode(targetType)); +			targetElement.appendChild(targetTypeElement); +			mirElement.appendChild(targetElement); +			 +			//add AuthBlock element +			Element authBlockElement = doc.createElementNS(MIS_NS, "authBlock"); +			authBlockElement.appendChild(doc.createTextNode(new String(Base64.encodeBase64(authBlock)))); +			mirElement.appendChild(authBlockElement); +						 +			// send soap request +			Element mandateIssueResponseElement = sendSOAPRequest(webServiceURL, mirElement); + +			// check for error +			checkForError(mandateIssueResponseElement); +	     +			// check for session id +			//String sessionId = ((Node) XPathAPI.selectSingleNode(mandateIssueResponseElement, "/mis:MandateIssueResponse/mis:SessionID/text()", NS_NODE)).getNodeValue(); +			Node sessionIdNode = ((Node) XPathAPI.selectSingleNode(mandateIssueResponseElement, "//mis:MandateIssueResponse/mis:SessionID/text()", NS_NODE)); +			if (sessionIdNode == null) { +				throw new MISSimpleClientException("SessionId not found in response."); +			} +			String sessionId = sessionIdNode.getNodeValue(); + +			Node guiRedirectURLNode = ((Node) XPathAPI.selectSingleNode(mandateIssueResponseElement, "//mis:MandateIssueResponse/mis:GuiRedirectURL/text()", NS_NODE)); +			if (guiRedirectURLNode == null) { +				throw new MISSimpleClientException("GuiRedirectURL not found in response."); +			} +			String guiRedirectURL = guiRedirectURLNode.getNodeValue(); +	     +			// create return object +			MISSessionId msid = new MISSessionId(); +			msid.setSessiondId(sessionId); +			msid.setRedirectURL(guiRedirectURL); +	     +			return msid; +		} catch (ParserConfigurationException e) { +			throw new MISSimpleClientException("service.06", e); +		} catch (DOMException e) { +			throw new MISSimpleClientException("service.06", e); +		} catch (TransformerException e) { +			throw new MISSimpleClientException("service.06", e); +		} +		 +	} +	 +	private static void checkForError(Element mandateIssueResponseElement) throws MISSimpleClientException { +		if (mandateIssueResponseElement == null) { +			throw new NullPointerException("Argument mandateIssueResponseElement must not be null."); +		} +		try { +		    Element errorElement = (Element) XPathAPI.selectSingleNode(mandateIssueResponseElement, "//mis:MandateIssueResponse/mis:Error", NS_NODE); +		    if (errorElement != null) { +		    	String code = ((Node) XPathAPI.selectSingleNode(mandateIssueResponseElement, "//mis:MandateIssueResponse/mis:Error/mis:Code/text()", NS_NODE)).getNodeValue(); +		    	String text = ((Node) XPathAPI.selectSingleNode(mandateIssueResponseElement, "//mis:MandateIssueResponse/mis:Error/mis:Text/text()", NS_NODE)).getNodeValue(); +		    	throw new MISSimpleClientException("service.05", code, text);	    } +		     +		} catch (TransformerException e) { +			throw new MISSimpleClientException("auth.15", e); +		} +	} +	 +	private static Element sendSOAPRequest(String webServiceURL, Element request) throws MISSimpleClientException { +		 +//		try { +//			System.out.println("REQUEST-MIS: \n"  + DOMUtils.serializeNode(request)); +//		} catch (TransformerException e1) { +//			e1.printStackTrace(); +//		} catch (IOException e1) { +//			e1.printStackTrace(); +//		} +		 +		if (webServiceURL == null) { +			throw new NullPointerException("Argument webServiceURL must not be null."); +		} +		if (request == null) { +			throw new NullPointerException("Argument request must not be null."); +		} +		try { +			HttpClient httpclient = HttpClientWithProxySupport.getHttpClient(); +			PostMethod post = new PostMethod(webServiceURL); +			StringRequestEntity re = new StringRequestEntity(DOMUtils.serializeNode(packIntoSOAP(request)),"text/xml", "UTF-8"); +			post.setRequestEntity(re); +			int responseCode = httpclient.executeMethod(post); +			 +			if (responseCode != 200) { +				throw new MISSimpleClientException("Invalid HTTP response code " + responseCode); +			} +			//Element elem = parse(post.getResponseBodyAsStream()); +			Document doc = DOMUtils.parseDocumentSimple(post.getResponseBodyAsStream()); +			return unpackFromSOAP(doc.getDocumentElement()); +			 +		} catch(IOException e) { +			throw new MISSimpleClientException("service.04", e); +			 +		} catch (TransformerException e) { +			throw new MISSimpleClientException("service.06", e); +			 +		} catch (SAXException e) { +			throw new MISSimpleClientException("service.06", e); +			 +		} catch (ParserConfigurationException e) { +			throw new MISSimpleClientException("service.06", e); +			 +		} catch (Exception e) { +			throw new MISSimpleClientException("service.06", e); +			 +		} +		 +	} +	 +	private static Element packIntoSOAP(Element element) throws MISSimpleClientException { +		try { +			Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); +			Element soapEnvelope = doc.createElement("Envelope"); +			soapEnvelope.setAttribute("xmlns", SOAP_NS); +			Element soapBody = doc.createElement("Body"); +			soapEnvelope.appendChild(soapBody); +			soapBody.appendChild(doc.importNode(element, true)); +			return soapEnvelope; +		} catch(ParserConfigurationException e) { +			throw new MISSimpleClientException("service.06", e); +		} +	} +	 +	private static Element unpackFromSOAP(Element element) throws MISSimpleClientException { +		try { +			return (Element) XPathAPI.selectSingleNode(element, "/soap:Envelope/soap:Body/child::*[position()=1]", NS_NODE); +		} catch(TransformerException e) { +			throw new MISSimpleClientException("service.06", e); +		} +	}	 +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.auth.modules.AuthModule b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.auth.modules.AuthModule new file mode 100644 index 000000000..865096055 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.auth.modules.AuthModule @@ -0,0 +1,2 @@ +# The default moaid process +at.gv.egovernment.moa.id.auth.modules.internal.DefaultAuthModuleImpl diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/resources/at/gv/egovernment/moa/id/auth/modules/internal/DefaultAuthentication.process.xml b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/resources/at/gv/egovernment/moa/id/auth/modules/internal/DefaultAuthentication.process.xml new file mode 100644 index 000000000..e9e95e922 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/resources/at/gv/egovernment/moa/id/auth/modules/internal/DefaultAuthentication.process.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> +<pd:ProcessDefinition id="DefaultAuthentication" xmlns:pd="http://reference.e-government.gv.at/namespace/moa/process/definition/v1"> + +<!-- +	- National authentication with Austrian Citizen Card and mobile signature with our without mandate. +	- Legacy authentication for foreign citizens using MOCCA supported signature cards. +--> +	<pd:Task id="createIdentityLinkForm"    class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.CreateIdentityLinkFormTask" /> +	<pd:Task id="verifyIdentityLink"        class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.VerifyIdentityLinkTask"        async="true" /> +	<pd:Task id="verifyAuthBlock"           class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.VerifyAuthenticationBlockTask" async="true" /> +	<pd:Task id="verifyCertificate"         class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.VerifyCertificateTask"         async="true" /> +	<pd:Task id="getMISMandate"           class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.GetMISSessionIDTask"           async="true" /> +	<pd:Task id="certificateReadRequest"    class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.CertificateReadRequestTask" /> +	<pd:Task id="prepareAuthBlockSignature" class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.PrepareAuthBlockSignatureTask" /> +	<pd:Task id="prepareGetMISMandate" 			class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.PrepareGetMISMandateTask" /> +	<pd:Task id="finalizeAuthentication" 		class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.FinalizeAuthenticationTask" /> +	<pd:Task id="getForeignID"              class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.GetForeignIDTask"              async="true" /> + +	<!-- Process is triggered either by GenerateIFrameTemplateServlet (upon bku selection) or by AuthenticationManager (upon legacy authentication start using legacy parameters. --> +	<pd:StartEvent id="start" /> +	 +	<pd:Transition from="start"                     to="createIdentityLinkForm" /> +	 +	<pd:Transition from="createIdentityLinkForm"    to="verifyIdentityLink" /> +	 +	<pd:Transition from="verifyIdentityLink"        to="certificateReadRequest" conditionExpression="!ctx['identityLinkAvailable'] || ctx['useMandate']" /> +	<pd:Transition from="verifyIdentityLink"        to="prepareAuthBlockSignature" /> +	 +	<pd:Transition from="prepareAuthBlockSignature" to="verifyAuthBlock" /> +	<!-- Note: verifyAuthBlock still creates a MIS session and redirects the user to the MIS gui. This should be separated from the auth block verification. --> +	 +	<pd:Transition from="certificateReadRequest"    to="verifyCertificate" /> +	<!-- Note: verifyCertificate still creates the auth block to be signed which should be separated from certificat verification. --> +	 +	<pd:Transition from="verifyCertificate"         to="verifyAuthBlock" conditionExpression="ctx['useMandate']" /> +	<pd:Transition from="verifyCertificate"         to="getForeignID" /> +	 +	<pd:Transition from="verifyAuthBlock"           to="prepareGetMISMandate" conditionExpression="ctx['useMandate']" /> +	<pd:Transition from="verifyAuthBlock"           to="finalizeAuthentication" /> +	 +	<pd:Transition from="prepareGetMISMandate"      to="getMISMandate" /> +		 +	<pd:Transition from="getMISMandate"           	to="finalizeAuthentication" /> +	<pd:Transition from="getForeignID"              to="finalizeAuthentication" /> +	 +	<pd:Transition from="finalizeAuthentication"    to="end" /> +		 +	<pd:EndEvent id="end" /> + +</pd:ProcessDefinition> diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/AllTests.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/AllTests.java new file mode 100644 index 000000000..d0d104d69 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/AllTests.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + *******************************************************************************/ +///* +// * 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 test.at.gv.egovernment.moa.id.auth.builder; +// +//import junit.awtui.TestRunner; +//import junit.framework.Test; +//import junit.framework.TestSuite; +// +///** +// * @author patrick +// * @version $Id$ +// */ +//public class AllTests { +// +//  public static Test suite() { +//    TestSuite suite = new TestSuite(); +// +////		suite.addTestSuite(AuthenticationBlockAssertionBuilderTest.class); +//		suite.addTestSuite(CreateXMLSignatureBuilderTest.class); +////    suite.addTestSuite(GetIdentityLinkFormBuilderTest.class); +////    suite.addTestSuite(InfoboxReadRequestBuilderTest.class); +////		suite.addTestSuite(PersonDataBuilderTest.class); +////		suite.addTestSuite(SAMLArtifactBuilderTest.class); +// +//    return suite; +//  } +// +//  public static void main(String[] args) { +//    try { +//      TestRunner.run(AllTests.class); +//    } catch (Exception e) { +//      e.printStackTrace(); +//    } +//  } +//} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilderTest.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilderTest.java new file mode 100644 index 000000000..4c2b3ec8a --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilderTest.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + *******************************************************************************/ +///* +// * 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 test.at.gv.egovernment.moa.id.auth.builder; +// +//import test.at.gv.egovernment.moa.id.UnitTestCase; +// +//import at.gv.egovernment.moa.id.auth.builder.AuthenticationBlockAssertionBuilder; +// +///** +// * @author Paul Ivancsics +// * @version $Id$ +// */ +//public class AuthenticationBlockAssertionBuilderTest extends UnitTestCase { +//	private static final String nl = "\n"; +//	private static final String ISSUER = "Hugo Mustermann"; +//	private static final String ISSUE_INSTANT = "2003-03-15T22:50:21+01:00"; +//	private static final String AUTH_URL = "https://auth.moa.gv.at/"; +//	private static final String TARGET = "Grundbuch"; +//	private static final String OA_URL = "https://grundbuch.gv.at/"; +//	private static final String GEB_DAT = "2004-01-02"; +//	 +//	// wird auch von CreateXMLSignatureBuilderTest verwendet ! +//	public static final String ASSERTION_SHOULD =  +//"<saml:Assertion xmlns:saml='urn:oasis:names:tc:SAML:1.0:assertion' MajorVersion='1' MinorVersion='0' AssertionID='any' Issuer='" + ISSUER + "' IssueInstant='" + ISSUE_INSTANT + "'>" + nl + +//"	<saml:AttributeStatement>" + nl + +//"		<saml:Subject>" + nl + +//"			<saml:NameIdentifier>" + AUTH_URL + "</saml:NameIdentifier>" + nl + +//"		</saml:Subject>" + nl + +//"		<saml:Attribute AttributeName='Gesch�ftsbereich' AttributeNamespace='http://reference.e-government.gv.at/namespace/moa/20020822#'>" + nl + +//"			<saml:AttributeValue>" + TARGET + "</saml:AttributeValue>" + nl + +//"		</saml:Attribute>" + nl + +//"		<saml:Attribute AttributeName='OA' AttributeNamespace='http://reference.e-government.gv.at/namespace/moa/20020822#'>" + nl + +//"			<saml:AttributeValue>" + OA_URL + "</saml:AttributeValue>" + nl + +//"		</saml:Attribute>" + nl + +//"	</saml:AttributeStatement>" + nl + +//"</saml:Assertion>"; +// +//  public AuthenticationBlockAssertionBuilderTest(String name) { +//    super(name); +//  } +// +//	public void testBuild() throws Exception { +//		AuthenticationBlockAssertionBuilder builder = new AuthenticationBlockAssertionBuilder(); +//		String assertionBuilt = builder.buildAuthBlock(ISSUER, ISSUE_INSTANT, AUTH_URL, TARGET, null,  "", "", OA_URL, GEB_DAT, null, null); +//		assertionBuilt = XML_DECL + assertionBuilt; +//		String assertionShould = XML_DECL + ASSERTION_SHOULD; +//		assertXmlEquals(assertionShould, assertionBuilt); +//	} +//} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureBuilderTest.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureBuilderTest.java new file mode 100644 index 000000000..c133602b1 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureBuilderTest.java @@ -0,0 +1,151 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + *******************************************************************************/ +///* +// * 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 test.at.gv.egovernment.moa.id.auth.builder; +// +//import at.gv.egovernment.moa.id.auth.builder.CreateXMLSignatureRequestBuilder; +// +//import test.at.gv.egovernment.moa.id.UnitTestCase; +// +///** +// * @author Paul Ivancsics +// * @version $Id$ +// */ +//public class CreateXMLSignatureBuilderTest extends UnitTestCase { +//	private static final String nl = "\n"; +//	public static final String TRANSFORMS_INFO =  +//		"			<sl10:TransformsInfo>" + nl + +//		"			  <dsig:Transforms>" + nl + +//		"         <dsig:Transform Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature'/>" + nl + +//		"     		<dsig:Transform Algorithm='http://www.w3.org/TR/1999/REC-xslt-19991116'>" + nl + +//"<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:saml='urn:oasis:names:tc:SAML:1.0:assertion' >" + nl + +//"<xsl:template match='/'>" + nl + +//"<html>" + nl + +//"<body>" + nl + +//"</body>" + nl + +//"</html>" + nl + +//"</xsl:template>" + nl + +//"</xsl:stylesheet>" + nl + +//		"    	    </dsig:Transform>" + nl + +//		"       </dsig:Transforms>" + nl + +//		"			  <sl10:FinalDataMetaInfo>" + nl + +//		"			    <sl10:MimeType>text/html</sl10:MimeType>" + nl + +//		"			  </sl10:FinalDataMetaInfo>" + nl + +//		"			</sl10:TransformsInfo>" + nl; +//	public static final String REQUEST_SHOULD =  +//"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + nl + +//"<sl11:CreateXMLSignatureRequest xmlns:dsig=\"http://www.w3.org/2000/09/xmldsig#\" xmlns:sl10=\"http://www.buergerkarte.at/namespaces/securitylayer/20020225#\" xmlns:sl11=\"http://www.buergerkarte.at/namespaces/securitylayer/20020831#\">" + nl + +//" <sl11:KeyboxIdentifier>SecureSignatureKeypair</sl11:KeyboxIdentifier>" + nl + +//" <sl11:DataObjectInfo Structure=\"detached\">" + nl + +//"  <sl10:DataObject Reference=\"\"/>" + nl + +//TRANSFORMS_INFO + +//" </sl11:DataObjectInfo>" + nl + +//" <sl11:SignatureInfo>" + nl + +//"  <sl11:SignatureEnvironment>" + nl + +//"   <sl10:XMLContent>" + AuthenticationBlockAssertionBuilderTest.ASSERTION_SHOULD + "</sl10:XMLContent>" + nl + +//"  </sl11:SignatureEnvironment>" + nl + +//"  <sl11:SignatureLocation Index=\"2\">/saml:Assertion</sl11:SignatureLocation>" + nl + +//" </sl11:SignatureInfo>" + nl + +//"</sl11:CreateXMLSignatureRequest>"; +//   +//   +//  public static final String TRANSFORMS_INFO_SL12 =  +//    "     <sl:TransformsInfo>" + nl + +//    "       <dsig:Transforms>" + nl + +//    "         <dsig:Transform Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature'/>" + nl + +//    "         <dsig:Transform Algorithm='http://www.w3.org/TR/1999/REC-xslt-19991116'>" + nl + +//"<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:saml='urn:oasis:names:tc:SAML:1.0:assertion' >" + nl + +//"<xsl:template match='/'>" + nl + +//"<html>" + nl + +//"<body>" + nl + +//"</body>" + nl + +//"</html>" + nl + +//"</xsl:template>" + nl + +//"</xsl:stylesheet>" + nl + +//    "         </dsig:Transform>" + nl + +//    "       </dsig:Transforms>" + nl + +//    "       <sl:FinalDataMetaInfo>" + nl + +//    "         <sl:MimeType>text/html</sl:MimeType>" + nl + +//    "       </sl:FinalDataMetaInfo>" + nl + +//    "     </sl:TransformsInfo>" + nl; +//  public static final String REQUEST_SHOULD_SL12 =  +//"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + nl + +//"<sl:CreateXMLSignatureRequest xmlns:dsig=\"http://www.w3.org/2000/09/xmldsig#\" xmlns:sl=\"http://www.buergerkarte.at/namespaces/securitylayer/1.2#\">" + nl + +//" <sl:KeyboxIdentifier>SecureSignatureKeypair</sl:KeyboxIdentifier>" + nl + +//" <sl:DataObjectInfo Structure=\"detached\">" + nl + +//"  <sl:DataObject Reference=\"\"/>" + nl + +//TRANSFORMS_INFO_SL12 + +//" </sl:DataObjectInfo>" + nl + +//" <sl:SignatureInfo>" + nl + +//"  <sl:SignatureEnvironment>" + nl + +//"   <sl:XMLContent>" + AuthenticationBlockAssertionBuilderTest.ASSERTION_SHOULD + "</sl:XMLContent>" + nl + +//"  </sl:SignatureEnvironment>" + nl + +//"  <sl:SignatureLocation Index=\"2\">/saml:Assertion</sl:SignatureLocation>" + nl + +//" </sl:SignatureInfo>" + nl + +//"</sl:CreateXMLSignatureRequest>"; +//   +//   +//   +//	 +//  public CreateXMLSignatureBuilderTest(String name) { +//    super(name); +//  } +// +//	public void testBuild() throws Exception { +//		// test build for Security Layer version 1.1 and 1.0 +//    String request = new CreateXMLSignatureRequestBuilder().build( +//			AuthenticationBlockAssertionBuilderTest.ASSERTION_SHOULD, "SecureSignatureKeypair", +//			new String[] {TRANSFORMS_INFO}, +//      false); +//		assertXmlEquals(REQUEST_SHOULD, request); +//    // test build for Security Layer version 1.2 +//    String requestSL12 = new CreateXMLSignatureRequestBuilder().build( +//      AuthenticationBlockAssertionBuilderTest.ASSERTION_SHOULD, "SecureSignatureKeypair", +//      new String[] {TRANSFORMS_INFO}, +//      true); +//    assertXmlEquals(REQUEST_SHOULD_SL12, requestSL12); +//	} +//} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilderTest.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilderTest.java new file mode 100644 index 000000000..7b364789b --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilderTest.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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 test.at.gv.egovernment.moa.id.auth.builder; + +import java.text.MessageFormat; + +import junit.framework.TestCase; + +import at.gv.egovernment.moa.id.auth.builder.CertInfoVerifyXMLSignatureRequestBuilder; +import at.gv.egovernment.moa.id.auth.builder.GetIdentityLinkFormBuilder; +import at.gv.egovernment.moa.id.auth.builder.InfoboxReadRequestBuilder; + +/** + * @author Paul Ivancsics + * @version $Id$ + */ +public class GetIdentityLinkFormBuilderTest extends TestCase { +  private static String nl = "\n"; +  public static String FORM =  +    "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">" + nl + +    "<html>" + nl + +    "<head>" + nl + +    "<title>Auslesen der Personenbindung</title>" + nl + +    "</head>" + nl + +    "<body>" + nl + +    "<form name=\"GetIdentityLinkForm\"" + nl + +    "      action=\"{0}\"" + nl + +    "      method=\"post\">" + nl + +    "  <input type=\"hidden\" " + nl + +    "         name=\"XMLRequest\"" + nl + +    "         value=\"{1}\"/>" + nl + +    "  <input type=\"hidden\" " + nl + +    "         name=\"DataURL\"" + nl + +    "         value=\"{2}\"/>" + nl + +    "  <input type=\"submit\" value=\"Auslesen der Personenbindung\"/>" + nl + +    "</form>" + nl + +    "<form name=\"CertificateInfoForm\"" + nl + +    "      action=\"{0}\"" + nl + +    "      method=\"post\">" + nl + +    "  <input type=\"hidden\" " + nl + +    "         name=\"XMLRequest\"" + nl + +    "         value=\"{3}\"/>" + nl + +    "  <input type=\"hidden\" " + nl + +    "         name=\"DataURL\"" + nl + +    "         value=\"{4}\"/>" + nl + +    "  <input type=\"submit\" value=\"Information zu Wurzelzertifikaten\"/>" + nl + +    "</form>" + nl + +    "</body>" + nl + +    "</html>"; +  public static String BKU =  +    "http://localhost:3495/http-security-layer-request"; + +	public void testBuild() throws Exception { +		String xmlRequest = new InfoboxReadRequestBuilder().build(false,  null); +		String dataURL = "https://1.2.3.4/auth/VerifyIdentityLink?MOASessionID=1234567"; +    String infoRequest = new CertInfoVerifyXMLSignatureRequestBuilder().build(); +    String infoDataURL = "https://1.2.3.4/auth/StartAuthentication?Target=gb&OA=https://oa.gv.at/"; +		String form = new GetIdentityLinkFormBuilder().build(null, null, xmlRequest, dataURL, infoRequest, infoDataURL, null, null, null, null); +		String formShould = MessageFormat.format( +			FORM, new Object[] { BKU, xmlRequest, dataURL, infoRequest, infoDataURL }); +		assertEquals(formShould, form); +	} +  public void testBuildCustomBKU() throws Exception { +    String xmlRequest = new InfoboxReadRequestBuilder().build(false, null); +    String dataURL = "https://1.2.3.4/auth/AuthServlet/StartAuthentication?MOASessionID=1234567"; +    String infoRequest = new CertInfoVerifyXMLSignatureRequestBuilder().build(); +    String infoDataURL = "https://1.2.3.4/auth/StartAuthentication?Target=gb&OA=https://oa.gv.at/"; +    String bkuURL = "http://bku.at/"; +    String form = new GetIdentityLinkFormBuilder().build(null, bkuURL, xmlRequest, dataURL, infoRequest, infoDataURL, null, null, null, null); +    String formShould = MessageFormat.format( +      FORM, new Object[] { bkuURL, xmlRequest, dataURL, infoRequest, infoDataURL }); +    assertEquals(formShould, form); +  } +	 +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilderTest.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilderTest.java new file mode 100644 index 000000000..ec15a209c --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilderTest.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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 test.at.gv.egovernment.moa.id.auth.builder; + +import org.w3c.dom.Document; +import test.at.gv.egovernment.moa.id.UnitTestCase; + +import at.gv.egovernment.moa.id.auth.builder.InfoboxReadRequestBuilder; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; + +/** + * @author Paul Ivancsics + * @version $Id$ + */ +public class InfoboxReadRequestBuilderTest extends UnitTestCase implements Constants { + +  public InfoboxReadRequestBuilderTest(String name) { +    super(name); +  } + +	public void testBuild() throws Exception { +		InfoboxReadRequestBuilder builder = new InfoboxReadRequestBuilder(); +		String xmlBuilt = builder.build(false, null); +		Document docBuilt = DOMUtils.parseDocument(xmlBuilt, false, ALL_SCHEMA_LOCATIONS, null); +		String xmlBuiltSerialized = DOMUtils.serializeNode(docBuilt); +		// xmlShould was generated by Hot:Sign Tester +		String xmlShould = "<?xml version='1.0' encoding='utf-8'?><sl10:InfoboxReadRequest xmlns:sl10='http://www.buergerkarte.at/namespaces/securitylayer/20020225#'><sl10:InfoboxIdentifier>IdentityLink</sl10:InfoboxIdentifier><sl10:BinaryFileParameters ContentIsXMLEntity='true'/></sl10:InfoboxReadRequest>"; +		assertXmlEquals(xmlShould, xmlBuiltSerialized); +	} +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/PersonDataBuilderTest.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/PersonDataBuilderTest.java new file mode 100644 index 000000000..b26fd4738 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/PersonDataBuilderTest.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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 test.at.gv.egovernment.moa.id.auth.builder; + +import at.gv.egovernment.moa.id.auth.builder.PersonDataBuilder; +import at.gv.egovernment.moa.id.auth.data.IdentityLink; +import at.gv.egovernment.moa.id.auth.parser.InfoboxReadResponseParser; +import at.gv.egovernment.moa.util.Constants; + +import test.at.gv.egovernment.moa.id.UnitTestCase; + +/** + * @author Paul Ivancsics + * @version $Id$ + */ +public class PersonDataBuilderTest extends UnitTestCase implements Constants { + +  /** +   * Constructor for PersonDataBuilderTest. +   */ +  public PersonDataBuilderTest(String arg) { +    super(arg); +  } +  public void testBuild() throws Exception { +		String xmlInfoboxReadResponse = readFile("data/test/xmldata/testperson1/InfoboxReadResponse.xml"); +		IdentityLink il = new InfoboxReadResponseParser(xmlInfoboxReadResponse).parseIdentityLink(); +		String xmlPersonData = new PersonDataBuilder().build(il, true); +		String xmlPersonDataShould = "<pr:Person xsi:type=\"pr:PhysicalPersonType\"><pr:Identification><pr:Value>123456789012</pr:Value><pr:Type>http://reference.e-government.gv.at/names/persondata/20020228#zmr-zahl</pr:Type></pr:Identification><pr:Name><pr:GivenName>Hermann</pr:GivenName><pr:FamilyName primary=\"undefined\">Muster</pr:FamilyName></pr:Name><pr:DateOfBirth>1968-10-22</pr:DateOfBirth></pr:Person>"; +		assertPersonDataEquals(xmlPersonDataShould, xmlPersonData); +  } +  public void testBuildNoZMRZahl() throws Exception { +		String xmlInfoboxReadResponse = readFile("data/test/xmldata/testperson1/InfoboxReadResponse.xml"); +		IdentityLink il = new InfoboxReadResponseParser(xmlInfoboxReadResponse).parseIdentityLink(); +		String xmlPersonData = new PersonDataBuilder().build(il, false); +		String xmlPersonDataShould = XML_DECL + "<pr:Person xsi:type=\"pr:PhysicalPersonType\"><pr:Name><pr:GivenName>Hermann</pr:GivenName><pr:FamilyName primary=\"undefined\">Muster</pr:FamilyName></pr:Name><pr:DateOfBirth>1968-10-22</pr:DateOfBirth></pr:Person>"; +		assertPersonDataEquals(xmlPersonDataShould, xmlPersonData); +  } +  private void assertPersonDataEquals(String s1, String s2) throws Exception { +  	String ss1 = insertPrNS(s1); +  	String ss2 = insertPrNS(s2); +		assertXmlEquals(ss1, ss2); +  } +  private String insertPrNS(String xmlPersonData) { +		int startNS = xmlPersonData.indexOf("Person") + "Person".length() + 1; +  	String s =  +  		xmlPersonData.substring(0, startNS) +  +  		"xmlns:pr=\"" + PD_NS_URI + "\" " +  +  		"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +  +  		xmlPersonData.substring(startNS); +  	return s; +  } + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/parser/AllTests.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/parser/AllTests.java new file mode 100644 index 000000000..d293ff347 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/parser/AllTests.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + *******************************************************************************/ +///* +// * 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 test.at.gv.egovernment.moa.id.auth.parser; +// +//import junit.awtui.TestRunner; +//import junit.framework.Test; +//import junit.framework.TestSuite; +// +///** +// * @author Paul Ivancsics +// * @version $Id$ +// */ +//public class AllTests { +// +//  public static Test suite() { +//    TestSuite suite = new TestSuite(); +// +//    suite.addTestSuite(IdentityLinkAssertionParserTest.class); +//    suite.addTestSuite(SAMLArtifactParserTest.class); +// +//    return suite; +//  } +// +//  public static void main(String[] args) { +//    try { +//      TestRunner.run(AllTests.class); +//    } catch (Exception e) { +//      e.printStackTrace(); +//    } +//  } +//} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/parser/IdentityLinkAssertionParserTest.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/parser/IdentityLinkAssertionParserTest.java new file mode 100644 index 000000000..977764878 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/parser/IdentityLinkAssertionParserTest.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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 test.at.gv.egovernment.moa.id.auth.parser; + +import iaik.security.rsa.RSAPublicKey; + +import java.io.FileOutputStream; +import java.io.RandomAccessFile; +import java.security.PublicKey; + +import org.w3c.dom.Document; + +import test.at.gv.egovernment.moa.id.UnitTestCase; +import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser; +import at.gv.egovernment.moa.id.auth.parser.InfoboxReadResponseParser; +import at.gv.egovernment.moa.id.util.ECDSAKeyValueConverter; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DOMUtils; + +/** + * @author Paul Ivancsics + * @version $Id$ + */ +public class IdentityLinkAssertionParserTest extends UnitTestCase { + +  IdentityLinkAssertionParser ilap; + +  public IdentityLinkAssertionParserTest(String name) { +    super(name); +  } + +  public void setUp() { +    try { +      RandomAccessFile s = +        new RandomAccessFile( +          "data/test/xmldata/testperson1/InfoboxReadResponse.xml", +          "r"); +      byte[] b = new byte[(int) s.length()]; +      s.read(b); +      String xmlInfoboxReadResponse = new String(b, "UTF-8"); + +		  InfoboxReadResponseParser irrp = new InfoboxReadResponseParser(xmlInfoboxReadResponse); +      ilap = new IdentityLinkAssertionParser(irrp.parseSAMLAssertion()); +    } +    catch (Exception e) { +      e.printStackTrace(); +    } +  } + +//  public void testParseIdentityLink() throws Exception { +//    IdentityLink idl = ilap.parseIdentityLink(); +//    System.out.println(idl.getGivenName()); +//    System.out.println(idl.getFamilyName()); +//    System.out.println(idl.getDateOfBirth()); +//    System.out.println(idl.getIdentificationValue()); +// +//    VerifyXMLSignatureRequestBuilder vx = new VerifyXMLSignatureRequestBuilder(); +//     +//  // Element zur�ck bekommen:  vx.build(idl.getSamlAssertion()); +//     +//    IdentityLinkValidator idVali = IdentityLinkValidator.getInstance(); +//    idVali.validate(idl); +//     +//  } + +//  public void testParseIdentityLinkECC() throws Exception { +//     RandomAccessFile s = +//        new RandomAccessFile( +//          "data/test/xmldata/IL.ResponseToRequest.01.ECDSA.xml", +//          "r"); +//      byte[] b = new byte[(int) s.length()]; +//      s.read(b); +//      String xmlInfoboxReadResponse = new String(b);  +//    InfoboxReadResponseParser irrp = new InfoboxReadResponseParser(xmlInfoboxReadResponse); +//    String SAML = irrp.parseSAMLAssertion(); +//    ilap = new IdentityLinkAssertionParser(SAML); +//    IdentityLink idl = ilap.parseIdentityLink(); +//    System.out.println(idl.getGivenName()); +//    System.out.println(idl.getFamilyName()); +//    System.out.println(idl.getDateOfBirth()); +//    System.out.println(idl.getIdentificationValue()); +// +//    VerifyXMLSignatureRequestBuilder vx = new VerifyXMLSignatureRequestBuilder(); +//     +//  // Element zur�ck bekommen:  vx.build(idl.getSamlAssertion()); +//     +//    IdentityLinkValidator idVali = IdentityLinkValidator.getInstance(); +//    idVali.validate(idl); +//     +//  } + + public void testRSAPublicKeys() throws Exception { + if (ilap.getPublicKeys()[0].getClass().getName().equals("iaik.security.rsa.RSAPublicKey")) + { +    +    for (int i = 0; i < ilap.getPublicKeys().length; i++) { +      RSAPublicKey result = (RSAPublicKey)ilap.getPublicKeys()[i]; +      System.out.println("RSA Public Key No" + i); +      System.out.println("Modulus: " + result.getModulus()); +      System.out.println("Exponent: " + result.getPublicExponent());       +    } +     + } + } + + public void testECDSAPublicKeys() throws Exception { +  + RandomAccessFile s = +        new RandomAccessFile( +          "data/test/xmldata/ECDSAKeyExample.xml", +          "r"); +      byte[] b = new byte[(int) s.length()]; +      s.read(b); +      String ecdsaKey = new String(b, "UTF-8"); +      Document e = DOMUtils.parseDocument(ecdsaKey,true,Constants.ALL_SCHEMA_LOCATIONS, null); +      PublicKey p = ECDSAKeyValueConverter.element2ECDSAPublicKey(e.getDocumentElement()); +     + } + + +  public void testDsigCertificates() throws Exception { + +    String[] result = ilap.getCertificates(); +    for (int i = 0; i < result.length; i++) { +       +      System.out.println("DSIG Certificate Length: " + result[i].length() + " No" + i + "\n" + result[i]); +      FileOutputStream raf = new FileOutputStream("data/test/certs/cert" + i + ".cer");       +        raf.write(result[i].getBytes()); +        raf.flush(); +        raf.close(); +   } + +  } + +} diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/parser/InfoboxReadResponseParserTest.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/parser/InfoboxReadResponseParserTest.java new file mode 100644 index 000000000..8d7dee597 --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/test/java/test/at/gv/egovernment/moa/id/auth/parser/InfoboxReadResponseParserTest.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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 test.at.gv.egovernment.moa.id.auth.parser; + +import java.io.RandomAccessFile; + +import test.at.gv.egovernment.moa.id.UnitTestCase; + +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.parser.InfoboxReadResponseParser; + +/** + * @author Paul Ivancsics + * @version $Id$ + */ +public class InfoboxReadResponseParserTest extends UnitTestCase { + +  IdentityLinkAssertionParser ilap; + +  public InfoboxReadResponseParserTest(String name) { +    super(name); +  } + +  public void setUp() { +  } + +  public void testParseInfoboxReadResponse() throws Exception { +         RandomAccessFile s = +        new RandomAccessFile( +          "data/test/xmldata/testperson1/InfoboxReadResponse.xml", +          "r"); +      byte[] b = new byte[(int) s.length()]; +      s.read(b); +      String xmlInfoboxReadResponse = new String(b, "UTF-8"); + +      InfoboxReadResponseParser irrp = new InfoboxReadResponseParser(xmlInfoboxReadResponse); +      ilap = new IdentityLinkAssertionParser(irrp.parseSAMLAssertion()); +     +    IdentityLink idl = ilap.parseIdentityLink(); +    System.out.println(idl.getGivenName()); +    System.out.println(idl.getFamilyName()); +    System.out.println(idl.getDateOfBirth()); +    System.out.println(idl.getIdentificationValue()); +     +  } + +  public void testParseInfoboxReadResponseError() throws Exception { +     RandomAccessFile s = +        new RandomAccessFile( +          "data/test/xmldata/ErrorResponse.xml", +          "r"); +      byte[] b = new byte[(int) s.length()]; +      s.read(b); +      String xmlInfoboxReadResponse = new String(b, "UTF-8"); + +      InfoboxReadResponseParser irrp = new InfoboxReadResponseParser(xmlInfoboxReadResponse); +      ilap = new IdentityLinkAssertionParser(irrp.parseSAMLAssertion()); +     +    IdentityLink idl = ilap.parseIdentityLink(); +    System.out.println(idl.getGivenName()); +    System.out.println(idl.getFamilyName()); +    System.out.println(idl.getDateOfBirth()); +    System.out.println(idl.getIdentificationValue()); +     +  } + + +} diff --git a/id/server/modules/moa-id-modules-saml1/pom.xml b/id/server/modules/moa-id-modules-saml1/pom.xml index a969098b6..26a082431 100644 --- a/id/server/modules/moa-id-modules-saml1/pom.xml +++ b/id/server/modules/moa-id-modules-saml1/pom.xml @@ -17,6 +17,12 @@  		<repositoryPath>${basedir}/../../../../repository</repositoryPath>  	</properties> +  <dependencies> +  	<dependency> +  		 <groupId>MOA.id.server.modules</groupId> +  		 <artifactId>moa-id-modul-citizencard_authentication</artifactId> +  	</dependency> +  </dependencies>  </project>
\ No newline at end of file diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/builder/SAMLArtifactBuilder.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/builder/SAMLArtifactBuilder.java new file mode 100644 index 000000000..eeca78e60 --- /dev/null +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/builder/SAMLArtifactBuilder.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.builder; + +import java.io.ByteArrayOutputStream; +import java.security.MessageDigest; + +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.id.auth.validator.parep.ParepUtils; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Base64Utils; + +/** + * Builder for the SAML artifact, as defined in the  + * Browser/Artifact profile of SAML. + *  + * @author Paul Ivancsics + * @version $Id$ + */ +public class SAMLArtifactBuilder { + +  /** +   * The generic configuration parameter for an alternative SourceID. +   */ +//  private static final String GENERIC_CONFIG_PARAM_SOURCEID = "AuthenticationServer.SourceID"; + +  /** +   * Constructor for SAMLArtifactBuilder. +   */ +  public SAMLArtifactBuilder() { +    super(); +  } +   +  /** +   * Builds the SAML artifact, encoded BASE64. +   * <ul> +   * <li><code>TypeCode</code>: <code>0x0001</code>.</li> +   * <li><code>SourceID</code>: SHA-1 hash of the authURL</li> +   * <li><code>AssertionHandle</code>: SHA-1 hash of the <code>MOASessionID</code></li> +   * </ul> +   * @param authURL URL auf the MOA-ID Auth component to be used for construction  +   *                 of <code>SourceID</code> +   * @param sessionID <code>MOASessionID</code> to be used for construction  +   *                   of <code>AssertionHandle</code> +   * @return the 42-byte SAML artifact, encoded BASE64 +   */ +  public String build(String authURL, String sessionID, String sourceIdParam) throws BuildException { +    try { +      MessageDigest md = MessageDigest.getInstance("SHA-1"); +      byte[] sourceID; +      // alternative sourceId +      String alternativeSourceID = AuthConfigurationProviderFactory.getInstance().getAlternativeSourceID(); +       +      // if sourceID is given in GET/POST param - use this as source id +      if (!ParepUtils.isEmpty(sourceIdParam)) { +          // if GET/POST parameter sourceID is set, use that sourceID instead of authURL; +          //sourceID = md.digest(sourceIdParam.getBytes()); +    	   +    	  // if sourceIdParam is too short (must have 20 characters) - add " " +    	  int length = sourceIdParam.length();  			 +  			if (length < 20) { +  				int l = 20 - length; +  				for (int i = 0; i < l; i++) { +  					sourceIdParam += " "; +  				}			 +  			} +  		 +    	  sourceID = sourceIdParam.getBytes(); +          Logger.info("Building SAMArtifact from sourceID \"" + sourceIdParam + "\" instead of authURL \"" + authURL + "\"."); +           +          byte[] assertionHandle = md.digest(sessionID.getBytes()); +          ByteArrayOutputStream out = new ByteArrayOutputStream(42); +          out.write(0); +          out.write(1); +          out.write(sourceID, 0, 20); +          out.write(assertionHandle, 0, 20); +          byte[] samlArtifact = out.toByteArray(); +          String samlArtifactBase64 = Base64Utils.encode(samlArtifact); +          return samlArtifactBase64;           +      } +       +      // if generic config parameter "AuthenticationServer.SourceID" is given, use that sourceID instead of authURL; +      if (!ParepUtils.isEmpty(alternativeSourceID)) { +          sourceID = md.digest(alternativeSourceID.getBytes());       +          Logger.info("Building SAMArtifact from sourceID \"" + alternativeSourceID + "\" instead of authURL \"" + authURL + "\"."); +           +          byte[] assertionHandle = md.digest(sessionID.getBytes()); +          ByteArrayOutputStream out = new ByteArrayOutputStream(42); +          out.write(0); +          out.write(1); +          out.write(sourceID, 0, 20); +          out.write(assertionHandle, 0, 20); +          byte[] samlArtifact = out.toByteArray(); +          String samlArtifactBase64 = Base64Utils.encode(samlArtifact); +          return samlArtifactBase64;           +      } +       +      // default: sourecID from authURL +      sourceID = md.digest(authURL.getBytes()); +      byte[] assertionHandle = md.digest(sessionID.getBytes()); +      ByteArrayOutputStream out = new ByteArrayOutputStream(42); +      out.write(0); +      out.write(1); +      out.write(sourceID, 0, 20); +      out.write(assertionHandle, 0, 20); +      byte[] samlArtifact = out.toByteArray(); +      String samlArtifactBase64 = Base64Utils.encode(samlArtifact); +      return samlArtifactBase64; +       +      //System.out.println("sourceID: " + new String(sourceID)); +       +       +    } +    catch (Throwable ex) { +      throw new BuildException( +        "builder.00",  +        new Object[] {"SAML Artifact, MOASessionID=" + sessionID, ex.toString()},  +        ex); +    } +  } + +} diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/parser/SAMLArtifactParser.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/parser/SAMLArtifactParser.java new file mode 100644 index 000000000..0e0b42cde --- /dev/null +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/auth/parser/SAMLArtifactParser.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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.auth.parser; + +import java.io.IOException; + +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.util.Base64Utils; + +/** + * Parser for a SAML artifact. + * @author Paul Ivancsics + * @version $Id$ + */ +public class SAMLArtifactParser { +  /** byte array containing the SamlArtifact bytes */ +  private byte[] samlArtifactBytes; + +  /** +   * Constructor +   * @param samlArtifact as String +   * @throws ParseException on any parsing error +   */ +  public SAMLArtifactParser(String samlArtifact) throws ParseException { +    try { +      samlArtifactBytes = Base64Utils.decode(samlArtifact, false); +    } +    catch (IOException ex) { +      throw new ParseException("parser.02", new Object[] {ex.toString()}, ex); +    } +  } +  /** +   * Parses the type code. +   * @return type code +   * @throws ParseException when SAML artifact is invalid +   */ +  public byte[] parseTypeCode() throws ParseException { +    try { +      byte[] typeCode = new byte[] {samlArtifactBytes[0], samlArtifactBytes[1]}; +      return typeCode; +    } +    catch (Throwable ex) { +      throw new ParseException("parser.02", new Object[] {ex.toString()}, ex); +    } +  } +  /** +   * Parses the assertion handle. +   * @return assertion handle +   * @throws ParseException when SAML artifact is invalid +   */ +  public String parseAssertionHandle() throws ParseException { +    try { +      return new String(samlArtifactBytes, 22, 20); +    } +    catch (Throwable ex) { +      throw new ParseException("parser.02", new Object[] {ex.toString()}, ex); +    } +  } + +} diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java index 2019b0d20..b94348856 100644 --- a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/GetArtifactAction.java @@ -31,7 +31,6 @@ import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;  import at.gv.egovernment.moa.id.auth.data.ExtendedSAMLAttribute;  import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;  import at.gv.egovernment.moa.id.auth.servlet.RedirectServlet; -import at.gv.egovernment.moa.id.auth.stork.STORKResponseProcessor;  import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;  import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;  import at.gv.egovernment.moa.id.data.IAuthData; @@ -73,7 +72,7 @@ public class GetArtifactAction implements IAction {  			// add other stork attributes to MOA assertion if available  			if(null != authData.getStorkAttributes()) { -				List<ExtendedSAMLAttribute> moaExtendedSAMLAttibutes = STORKResponseProcessor.addAdditionalSTORKAttributes(authData.getStorkAttributes()); +				List<ExtendedSAMLAttribute> moaExtendedSAMLAttibutes = SAML1AuthenticationServer.addAdditionalSTORKAttributes(authData.getStorkAttributes());  				authData.getExtendedSAMLAttributesOA().addAll(moaExtendedSAMLAttibutes);  				Logger.info("MOA assertion assembled and SAML Artifact generated.");  			} diff --git a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java index e70e71d49..eb869756e 100644 --- a/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java +++ b/id/server/modules/moa-id-modules-saml1/src/main/java/at/gv/egovernment/moa/id/protocols/saml1/SAML1AuthenticationServer.java @@ -25,6 +25,7 @@ package at.gv.egovernment.moa.id.protocols.saml1;  import java.io.ByteArrayOutputStream;  import java.io.IOException;  import java.util.List; +import java.util.Vector;  import javax.xml.bind.JAXBContext;  import javax.xml.bind.JAXBElement; @@ -33,9 +34,13 @@ import javax.xml.namespace.QName;  import javax.xml.parsers.ParserConfigurationException;  import javax.xml.transform.TransformerException; +import org.apache.commons.lang3.StringEscapeUtils;  import org.w3c.dom.Element;  import org.xml.sax.SAXException; +import eu.stork.peps.auth.commons.IPersonalAttributeList; +import eu.stork.peps.auth.commons.PersonalAttribute; +  import at.gv.egovernment.moa.id.auth.AuthenticationServer;  import at.gv.egovernment.moa.id.auth.builder.AuthenticationDataAssertionBuilder;  import at.gv.egovernment.moa.id.auth.builder.BPKBuilder; @@ -43,6 +48,7 @@ import at.gv.egovernment.moa.id.auth.builder.PersonDataBuilder;  import at.gv.egovernment.moa.id.auth.builder.SAMLArtifactBuilder;  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.ExtendedSAMLAttributeImpl;  import at.gv.egovernment.moa.id.auth.data.IdentityLink;  import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;  import at.gv.egovernment.moa.id.auth.exception.BuildException; @@ -120,6 +126,43 @@ public class SAML1AuthenticationServer extends AuthenticationServer {  	}  	/** +	 * Transforms additional STORK attributes to MOA Extended attributes +	 * @param iPersonalAttributeList STORK attribute list +	 * @return +	 */ +	public static List<ExtendedSAMLAttribute> addAdditionalSTORKAttributes(IPersonalAttributeList iPersonalAttributeList) { +		List<ExtendedSAMLAttribute> moaExtendedSAMLAttributeList = new Vector<ExtendedSAMLAttribute>(); +		 +		if(null == iPersonalAttributeList) +			return moaExtendedSAMLAttributeList; +		 +		Logger.trace("Adding the following attributes to MOA assertion: "); +		int count = 0; + +		for (PersonalAttribute attribute : iPersonalAttributeList) { +			Object attributeValue = attribute.getValue(); +			if (null == attributeValue) +				attributeValue = attribute.getComplexValue(); + +			// escape attributeValue +			attributeValue = StringEscapeUtils.escapeXml10(attributeValue.toString()); +			// and remove trailing and tailing brackets. Might break something but we never saw an array with more than one entry! +			attributeValue = ((String) attributeValue).substring(1, ((String) attributeValue).length() - 1); + +			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; +	} +	 +	 +	/**  	 * Retrieves <code>AuthenticationData</code> indexed by the SAML artifact.  	 * The <code>AuthenticationData</code> is deleted from the store upon end of  	 * this call. diff --git a/id/server/modules/moa-id-modules-saml1/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/SAMLArtifactBuilderTest.java b/id/server/modules/moa-id-modules-saml1/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/SAMLArtifactBuilderTest.java new file mode 100644 index 000000000..ebdec6d22 --- /dev/null +++ b/id/server/modules/moa-id-modules-saml1/src/test/java/test/at/gv/egovernment/moa/id/auth/builder/SAMLArtifactBuilderTest.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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 test.at.gv.egovernment.moa.id.auth.builder; + +import at.gv.egovernment.moa.id.auth.builder.SAMLArtifactBuilder; +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.util.Base64Utils; + +import test.at.gv.egovernment.moa.id.UnitTestCase; + +/** + * @author Paul Ivancsics + * @version $Id$ + */ +public class SAMLArtifactBuilderTest extends UnitTestCase { + +  private static final String AUTH_URL = "https://moa.gv.at/auth/"; +  private static final String SESSION_ID_1 = "123456"; +  private static final String SESSION_ID_2 = "123457"; +  private static final String SESSION_ID_3 = "1234567"; + +  private SAMLArtifactBuilder builder; +  private byte[] artifact1; +  private byte[] artifact2; +  private byte[] artifact3; + +  public SAMLArtifactBuilderTest(String name) { +    super(name); +  } +  protected void setUp() throws Exception { +  	builder = new SAMLArtifactBuilder(); +  	artifact1 = Base64Utils.decode(builder.build(AUTH_URL, SESSION_ID_1, null), false); +		artifact2 = Base64Utils.decode(builder.build(AUTH_URL, SESSION_ID_2, null), false); +		artifact3 = Base64Utils.decode(builder.build(AUTH_URL, SESSION_ID_3, null), false); +  } +     +  public void testBuildArtifactLength() throws BuildException { +		assertEquals(42, artifact1.length); +		assertEquals(42, artifact2.length); +		assertEquals(42, artifact3.length); +  } +  public void testBuildSameArtifact() throws Exception { +  	byte[] artifact1Clone = Base64Utils.decode(builder.build(AUTH_URL, SESSION_ID_1, null), false); +		assertEquals(new String(artifact1), new String(artifact1Clone)); +  } +  public void testBuildDifferentArtifacts() throws BuildException { +  	String msg = "SAML Artifacts should be different"; +		assertFalse(msg, new String(artifact1).equals(new String(artifact2))); +		assertFalse(msg, new String(artifact1).equals(new String(artifact3))); +		assertFalse(msg, new String(artifact3).equals(new String(artifact2))); +  } + + +} diff --git a/id/server/modules/moa-id-modules-saml1/src/test/java/test/at/gv/egovernment/moa/id/auth/parser/SAMLArtifactParserTest.java b/id/server/modules/moa-id-modules-saml1/src/test/java/test/at/gv/egovernment/moa/id/auth/parser/SAMLArtifactParserTest.java new file mode 100644 index 000000000..961c8d0b5 --- /dev/null +++ b/id/server/modules/moa-id-modules-saml1/src/test/java/test/at/gv/egovernment/moa/id/auth/parser/SAMLArtifactParserTest.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * 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 test.at.gv.egovernment.moa.id.auth.parser; + +import at.gv.egovernment.moa.id.auth.builder.SAMLArtifactBuilder; +import at.gv.egovernment.moa.id.auth.parser.SAMLArtifactParser; +import at.gv.egovernment.moa.id.util.Random; +import test.at.gv.egovernment.moa.id.UnitTestCase; + +/* + * @author Paul Ivancsics + * @version $Id$ + */ +public class SAMLArtifactParserTest extends UnitTestCase { +   +  private static String URL1 = "http://moa.gv.at/auth"; +  private static String URL2 = "https://moa.gv.at/auth"; +   +  public SAMLArtifactParserTest(String name) { +    super(name); +  } + +  public void testParseTypeCode() throws Exception { +    String sessionID = Random.nextRandom(); +    String samlArtifact = new SAMLArtifactBuilder().build(URL1, sessionID, null);  +    byte[] typeCode = new SAMLArtifactParser(samlArtifact).parseTypeCode(); +    assertEquals(typeCode[0], 0); +    assertEquals(typeCode[1], 1); +  } +  public void testParseAssertionHandleSameSessionID() throws Exception { +    // SAML artifacts for different authURL's but same sessionID MUST give same assertion handle +    String sessionID = Random.nextRandom(); +    String samlArtifact1 = new SAMLArtifactBuilder().build(URL1, sessionID, null); +    String samlArtifact2 = new SAMLArtifactBuilder().build(URL2, sessionID, null); +    String assertionHandle1 = new SAMLArtifactParser(samlArtifact1).parseAssertionHandle(); +    String assertionHandle2 = new SAMLArtifactParser(samlArtifact2).parseAssertionHandle(); +    assertEquals(assertionHandle1, assertionHandle2); +  } +  public void testParseAssertionHandleSameURL() throws Exception { +    // SAML artifacts for same authURL but different sessionID's MUST give different assertion handles +    String sessionID1 = Random.nextRandom(); +    String sessionID2 = Random.nextRandom(); +    String samlArtifact1 = new SAMLArtifactBuilder().build(URL1, sessionID1, null); +    String samlArtifact2 = new SAMLArtifactBuilder().build(URL1, sessionID2, null); +    String assertionHandle1 = new SAMLArtifactParser(samlArtifact1).parseAssertionHandle(); +    String assertionHandle2 = new SAMLArtifactParser(samlArtifact2).parseAssertionHandle(); +    assertFalse(assertionHandle1.equals(assertionHandle2)); +  } +  public void testParseAssertionHandleSameSAMLArtifact() throws Exception { +    // SAML artifact parsed twice MUST give same assertion handle each time +    String sessionID = Random.nextRandom(); +    String samlArtifact = new SAMLArtifactBuilder().build(URL1, sessionID, null); +    String assertionHandle1 = new SAMLArtifactParser(samlArtifact).parseAssertionHandle(); +    String assertionHandle2 = new SAMLArtifactParser(samlArtifact).parseAssertionHandle(); +    assertEquals(assertionHandle1, assertionHandle2); +  } +} diff --git a/id/server/modules/module-monitoring/pom.xml b/id/server/modules/module-monitoring/pom.xml index 60ab6b6c0..0718f9017 100644 --- a/id/server/modules/module-monitoring/pom.xml +++ b/id/server/modules/module-monitoring/pom.xml @@ -8,9 +8,7 @@  		<version>${moa-id-version}</version>  	</parent> -	<groupId>MOA.id.server.modules</groupId>  	<artifactId>moa-id-module-monitoring</artifactId> -	<version>${moa-id-version}</version>  	<packaging>jar</packaging>  	<name>MOA ID-Module Monitoring</name> @@ -19,4 +17,11 @@  		<repositoryPath>${basedir}/../../../../repository</repositoryPath>  	</properties> +	  <dependencies> +  	<dependency> +  		 <groupId>MOA.id.server.modules</groupId> +  		 <artifactId>moa-id-modul-citizencard_authentication</artifactId> +  	</dependency> +  </dependencies> +	  </project> diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/CreateStorkAuthRequestFormTask.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/CreateStorkAuthRequestFormTask.java index 06dfc95d3..a8792cd8f 100644 --- a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/CreateStorkAuthRequestFormTask.java +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/CreateStorkAuthRequestFormTask.java @@ -43,9 +43,8 @@ import eu.stork.peps.auth.commons.STORKAuthnRequest;  import eu.stork.peps.auth.engine.STORKSAMLEngine;
  import eu.stork.peps.exceptions.STORKSAMLEngineException;
 -import at.gv.egovernment.moa.id.auth.AuthenticationServer;
 +import at.gv.egovernment.moa.id.auth.BaseAuthenticationServer;
  import at.gv.egovernment.moa.id.auth.builder.CreateXMLSignatureRequestBuilder;
 -import at.gv.egovernment.moa.id.auth.builder.StartAuthenticationBuilder;
  import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
  import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
  import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
 @@ -62,7 +61,6 @@ import at.gv.egovernment.moa.id.config.stork.STORKConfig;  import at.gv.egovernment.moa.id.config.stork.StorkAttribute;
  import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
 -import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventLog;
  import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger;
  import at.gv.egovernment.moa.id.moduls.IRequest;
  import at.gv.egovernment.moa.id.moduls.RequestStorage;
 @@ -123,7 +121,7 @@ public class CreateStorkAuthRequestFormTask extends AbstractAuthServletTask {  			if (!ParamValidatorUtils.isValidSessionID(sessionID)) {
  				throw new WrongParametersException("CreateStorkAuthRequestFormTask", PARAM_SESSIONID, "auth.12");
  			}
 -			AuthenticationSession moasession = AuthenticationServer.getSession(sessionID);
 +			AuthenticationSession moasession = BaseAuthenticationServer.getSession(sessionID);
  			pendingRequestID = AuthenticationSessionStoreage.getPendingRequestID(sessionID);
  			IRequest pendingReq = RequestStorage.getPendingRequest(pendingRequestID);
 diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleLocalSignResponseTask.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleLocalSignResponseTask.java index a631489be..7b9fa3f12 100644 --- a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleLocalSignResponseTask.java +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleLocalSignResponseTask.java @@ -19,7 +19,7 @@ import org.apache.velocity.app.VelocityEngine;  import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
  import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger;
 -import at.gv.egovernment.moa.id.auth.AuthenticationServer;
 +import at.gv.egovernment.moa.id.auth.BaseAuthenticationServer;
  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.exception.AuthenticationException;
 @@ -112,7 +112,7 @@ public class PepsConnectorHandleLocalSignResponseTask extends AbstractPepsConnec  		try {
  			// load MOASession from database
 -			AuthenticationSession moaSession = AuthenticationServer.getSession(moaSessionID);
 +			AuthenticationSession moaSession = BaseAuthenticationServer.getSession(moaSessionID);
  			// change MOASessionID
  			moaSessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);
 diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleResponseWithoutSignatureTask.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleResponseWithoutSignatureTask.java index d16719b3b..304e5f495 100644 --- a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleResponseWithoutSignatureTask.java +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleResponseWithoutSignatureTask.java @@ -21,7 +21,7 @@ import org.apache.velocity.VelocityContext;  import org.apache.velocity.app.VelocityEngine;
  import org.opensaml.saml2.core.StatusCode;
 -import at.gv.egovernment.moa.id.auth.AuthenticationServer;
 +import at.gv.egovernment.moa.id.auth.BaseAuthenticationServer;
  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.exception.AuthenticationException;
 @@ -187,7 +187,7 @@ public class PepsConnectorHandleResponseWithoutSignatureTask extends AbstractPep  			pendingRequestID = AuthenticationSessionStoreage.getPendingRequestID(moaSessionID);
  			// load MOASession from database
 -			AuthenticationSession moaSession = AuthenticationServer.getSession(moaSessionID);
 +			AuthenticationSession moaSession = BaseAuthenticationServer.getSession(moaSessionID);
  			// change MOASessionID
  			moaSessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);
 diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorTask.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorTask.java index 01dad4ebb..b505605ab 100644 --- a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorTask.java +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorTask.java @@ -35,7 +35,8 @@ import org.w3c.dom.Node;  import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
  import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger;
 -import at.gv.egovernment.moa.id.auth.AuthenticationServer;
 +
 +import at.gv.egovernment.moa.id.auth.BaseAuthenticationServer;
  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.IdentityLink;
 @@ -225,7 +226,7 @@ public class PepsConnectorTask extends AbstractAuthServletTask {  			IRequest pendingReq = RequestStorage.getPendingRequest(pendingRequestID);
  			// load MOASession from database
 -			AuthenticationSession moaSession = AuthenticationServer.getSession(moaSessionID);
 +			AuthenticationSession moaSession = BaseAuthenticationServer.getSession(moaSessionID);
  			// change MOASessionID
  			moaSessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);
 diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKException.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKException.java new file mode 100644 index 000000000..79641d085 --- /dev/null +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKException.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/** + *  + */ +package at.gv.egovernment.moa.id.auth.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/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKResponseProcessor.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKResponseProcessor.java new file mode 100644 index 000000000..65a3637a9 --- /dev/null +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/auth/stork/STORKResponseProcessor.java @@ -0,0 +1,286 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/** + *  + */ +package at.gv.egovernment.moa.id.auth.stork; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Vector; + +import javax.activation.DataSource; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.stream.StreamSource; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringEscapeUtils; + +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.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser; +import at.gv.egovernment.moa.id.client.SZRGWClientException; +import at.gv.egovernment.moa.id.client.utils.SZRGWClientUtils; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.DateTimeUtils; +import at.gv.egovernment.moa.util.StringUtils; +import at.gv.util.xsd.srzgw.CreateIdentityLinkResponse; +import eu.stork.oasisdss.api.ApiUtils; +import eu.stork.oasisdss.api.LightweightSourceResolver; +import eu.stork.oasisdss.api.exceptions.ApiUtilsException; +import eu.stork.oasisdss.api.exceptions.UtilsException; +import eu.stork.oasisdss.profile.SignResponse; +import eu.stork.peps.auth.commons.IPersonalAttributeList; +import eu.stork.peps.auth.commons.PersonalAttribute; + +/** + *  + * 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"; +	 +	/** +	 * Checks for attribute. +	 * +	 * @param attributeName the attribute name +	 * @param attributeList the attribute list +	 * @return true, if successful +	 */ +	public static boolean hasAttribute(String attributeName, IPersonalAttributeList attributeList) { +		try { +			getAttributeValue(attributeName, attributeList); +			return true; +		} catch(STORKException e) { +			return false; +		} +	} + +	/** +	 * helper for reading attributes. Handles logging and error handling. +	 * +	 * @param attributeName the attribute name +	 * @param attributeList the attribute list +	 * @return the attribute value +	 * @throws STORKException the sTORK exception +	 */ +	private static String getAttributeValue(String attributeName, IPersonalAttributeList attributeList) throws STORKException { +		return getAttributeValue(attributeName, attributeList, true); +	} +	public static String getAttributeValue(String attributeName, IPersonalAttributeList attributeList, boolean throwException) throws STORKException { +		try { +			String result = attributeList.get(attributeName).getValue().get(0); +			Logger.trace(attributeName + " : " + result); +			return result; +		} catch(Exception e) { +			Logger.error(attributeName + " not found in response"); +			if(throwException) +				throw new STORKException(attributeName + " not found in response"); +			else +				return null; +		} +	} + +	/** +	 * Handels connection to SZR-GW and returns Identity Link on success. +	 * +	 * @param attributeList the attribute list +	 * @param oaFriendlyName the oa friendly name +	 * @param targetType the target type +	 * @param targetValue the target value +	 * @param filters the filters +	 * @param citizenSignature2  +	 * @return Identity Link +	 * @throws STORKException the sTORK exception +	 * @throws MOAIDException  +	 */ +	public static IdentityLink connectToSZRGateway(IPersonalAttributeList attributeList, String oaFriendlyName, String targetType, String targetValue, List<String> filters, String citizenSignature) throws STORKException, MOAIDException { +		Logger.trace("Calling SZR Gateway with the following attributes:"); + +		CreateIdentityLinkResponse identityLinkResponse = null; +		IdentityLink identityLink = null; +		try { +			Logger.trace("Starting call..."); + +			// if there is no signedDoc attribute, we cannot go on +			if(citizenSignature==null || citizenSignature.length()==0) +			{ +				String signResponseString = getAttributeValue("signedDoc", attributeList); +				 +				//Extract signature from SIgnResponse +				Source response1 = new StreamSource(new java.io.StringReader(signResponseString)); +				SignResponse dssSignResponse = ApiUtils.unmarshal(response1, SignResponse.class); +				citizenSignature = getCitizienSignatureFromSignResponse(dssSignResponse); +			} +			 +			String fiscalNumber = getAttributeValue("fiscalNumber", attributeList, false); +			 +			// if we have a signedDoc we test for a representation case +			// - according to stork samlengine and commons +			if(hasAttribute("mandate", attributeList)) { +				// we have a representation case +				String mandate = getAttributeValue("mandate", attributeList, false); +				 +				if(!hasAttribute("dateOfBirth", attributeList)) { +					// if we get here, we have a natural person representing a legal person +					String organizationAddress = getAttributeValue("canonicalRegisteredAddress", attributeList, false); +					String organizationType = getAttributeValue("translateableType", attributeList, false); +					 +					identityLinkResponse = SZRGWClientUtils.getIdentityLink(citizenSignature, null, null, mandate, organizationAddress, organizationType, targetType, targetValue, oaFriendlyName, filters, fiscalNumber); +				} else { +					// if we get here, we have a natural person representing another natural person +					String eIdentifier = getAttributeValue("eIdentifier", attributeList, false); +					String givenName = getAttributeValue("givenName", attributeList, false); +					String lastName = getAttributeValue("surname", attributeList, false); +					String dateOfBirth = getAttributeValue("dateOfBirth", attributeList, false); +					 +					// gender attribute is mandatory here because of some legal stuff +					String gender = getAttributeValue("gender", attributeList, false); +					 +					if (!StringUtils.isEmpty(dateOfBirth)) +						dateOfBirth = DateTimeUtils.formatPEPSDateToMOADate(dateOfBirth); + +					identityLinkResponse = SZRGWClientUtils.getIdentityLink(eIdentifier,  +							givenName, lastName, dateOfBirth, gender, citizenSignature, null, +							null, mandate, targetType, targetValue, oaFriendlyName, filters, fiscalNumber); +				} +			} +			// - according to stork spec +			else if(hasAttribute("mandateContent", attributeList) || hasAttribute("representative", attributeList) || hasAttribute("represented", attributeList)) { +				// we have a representation case +				String representative = getAttributeValue("representative", attributeList, false); +				String represented = getAttributeValue("represented", attributeList, false); +				String mandate = getAttributeValue("mandateContent", attributeList, false); +				 +				if(!hasAttribute("dateOfBirth", attributeList)) { +					// if we get here, we have a natural person representing a legal person +					String organizationAddress = getAttributeValue("canonicalRegisteredAddress", attributeList, false); +					String organizationType = getAttributeValue("translateableType", attributeList, false); +									 +					identityLinkResponse = SZRGWClientUtils.getIdentityLink(citizenSignature, representative, represented, mandate, organizationAddress, organizationType, targetType, targetValue, oaFriendlyName, filters, fiscalNumber); +				} else { +					// if we get here, we have a natural person representing another natural person +					String eIdentifier = getAttributeValue("eIdentifier", attributeList, false); +					String givenName = getAttributeValue("givenName", attributeList, false); +					String lastName = getAttributeValue("surname", attributeList, false); +					String dateOfBirth = getAttributeValue("dateOfBirth", attributeList, false); +			 +					// gender attribute is mandatory here because of some legal stuff +					String gender = getAttributeValue("gender", attributeList, false); +					 +					if (!StringUtils.isEmpty(dateOfBirth)) +						dateOfBirth = DateTimeUtils.formatPEPSDateToMOADate(dateOfBirth); + +					identityLinkResponse = SZRGWClientUtils.getIdentityLink(eIdentifier,  +							givenName, lastName, dateOfBirth, gender, citizenSignature, representative, +							represented, mandate, targetType, targetValue, oaFriendlyName, filters, fiscalNumber); +				} +			} else { +				// we do not have a representation case +				String eIdentifier = getAttributeValue("eIdentifier", attributeList, false); +				String givenName = getAttributeValue("givenName", attributeList, false); +				String lastName = getAttributeValue("surname", attributeList, false); +				String dateOfBirth = getAttributeValue("dateOfBirth", attributeList, false); +				if (!StringUtils.isEmpty(dateOfBirth)) +					dateOfBirth = DateTimeUtils.formatPEPSDateToMOADate(dateOfBirth); +				identityLinkResponse = SZRGWClientUtils.getIdentityLink(eIdentifier, givenName, lastName, dateOfBirth, citizenSignature, fiscalNumber); +			} +	    	 +	    	if (null != identityLinkResponse.getErrorResponse()){ +	    		throw new SZRGWClientException("service.08", (String)identityLinkResponse.getErrorResponse().getErrorCode(),  +	    				(String)identityLinkResponse.getErrorResponse().getInfo()); +	    	} +	    	else { +		    	IdentityLinkAssertionParser ilParser = new IdentityLinkAssertionParser(new ByteArrayInputStream(identityLinkResponse.getIdentityLink())); +		    	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 (ParseException e) { +			Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e); +			throw new MOAIDException("auth.25", null, e); +		} catch (ApiUtilsException e) { +			Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e); +			throw new MOAIDException("auth.25", null, e); +		} catch (IllegalArgumentException e) { +			Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e); +			throw new MOAIDException("auth.25", null, e); +		} catch (TransformerConfigurationException e) { +			Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e); +			throw new MOAIDException("auth.25", null, e); +		} catch (UtilsException e) { +			Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e); +			throw new MOAIDException("auth.25", null, e); +		} catch (TransformerException e) { +			Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e); +			throw new MOAIDException("auth.25", null, e); +		} catch (TransformerFactoryConfigurationError e) { +			Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e); +			throw new MOAIDException("auth.25", null, e); +		} catch (IOException e) { +			Logger.error("Error parsing IdentityLink received from SZR-Gateway: ", e); +			throw new MOAIDException("auth.25", null, e); +		}  +    		     +    	return identityLink; +		 +	} +		 +	private static String getCitizienSignatureFromSignResponse(SignResponse dssSignResponse) throws IllegalArgumentException, TransformerConfigurationException, UtilsException, TransformerException, TransformerFactoryConfigurationError, IOException, ApiUtilsException +	{ +		// fetch signed doc +		DataSource ds = LightweightSourceResolver.getDataSource(dssSignResponse); +		if(ds == null){ +			throw new ApiUtilsException("No datasource found in response"); +		}				 + +		InputStream incoming  = ds.getInputStream(); +		String citizenSignature = IOUtils.toString(incoming); +		incoming.close(); + +		return citizenSignature; +	} + +} diff --git a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java index 59db5797d..4d3c01bee 100644 --- a/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java +++ b/id/server/modules/module-stork/src/main/java/at/gv/egovernment/moa/id/protocols/stork2/AuthenticationRequest.java @@ -29,6 +29,7 @@ import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;  import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters;  import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;  import at.gv.egovernment.moa.id.data.IAuthData; +import at.gv.egovernment.moa.id.data.MISMandate;  import at.gv.egovernment.moa.id.data.SLOInformationImpl;  import at.gv.egovernment.moa.id.data.SLOInformationInterface;  import at.gv.egovernment.moa.id.moduls.IAction; @@ -36,7 +37,6 @@ import at.gv.egovernment.moa.id.moduls.IRequest;  import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;  import at.gv.egovernment.moa.id.storage.AssertionStorage;  import at.gv.egovernment.moa.id.util.VelocityProvider; -import at.gv.egovernment.moa.id.util.client.mis.simple.MISMandate;  import at.gv.egovernment.moa.logging.Logger;  import at.gv.egovernment.moa.util.MiscUtil;  import eu.stork.peps.auth.commons.*; diff --git a/id/server/modules/pom.xml b/id/server/modules/pom.xml index fcba9428b..db03326ea 100644 --- a/id/server/modules/pom.xml +++ b/id/server/modules/pom.xml @@ -24,10 +24,11 @@  		<module>module-monitoring</module>  		<module>moa-id-modules-saml1</module>  		<module>moa-id-module-openID</module> +		<module>moa-id-modul-citizencard_authentication</module>  	</modules>  	<dependencies> -		<dependency> + 		<dependency>  			<groupId>MOA.id.server</groupId>  			<artifactId>moa-id-lib</artifactId>  			<exclusions> | 
