diff options
author | harald.bratko <harald.bratko@d688527b-c9ab-4aba-bd8d-4036d912da1d> | 2005-07-22 15:11:48 +0000 |
---|---|---|
committer | harald.bratko <harald.bratko@d688527b-c9ab-4aba-bd8d-4036d912da1d> | 2005-07-22 15:11:48 +0000 |
commit | c8223bd5aaf9466fb6c72fe8a5a13b1b105b7c17 (patch) | |
tree | b5ecda8d6df344cb3ebe245c24ccb012686d175d /id.server | |
parent | 44a961d0df8d9721b1bdb8185e3a68df762c5ba6 (diff) | |
download | moa-id-spss-c8223bd5aaf9466fb6c72fe8a5a13b1b105b7c17.tar.gz moa-id-spss-c8223bd5aaf9466fb6c72fe8a5a13b1b105b7c17.tar.bz2 moa-id-spss-c8223bd5aaf9466fb6c72fe8a5a13b1b105b7c17.zip |
updated for wbPK
git-svn-id: https://joinup.ec.europa.eu/svn/moa-idspss/trunk@398 d688527b-c9ab-4aba-bd8d-4036d912da1d
Diffstat (limited to 'id.server')
35 files changed, 1169 insertions, 366 deletions
diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/AuthenticationServer.java b/id.server/src/at/gv/egovernment/moa/id/auth/AuthenticationServer.java index 4c44e807c..8cb71402f 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/AuthenticationServer.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/AuthenticationServer.java @@ -1,6 +1,7 @@ package at.gv.egovernment.moa.id.auth; import iaik.pki.PKIException; +import iaik.x509.X509Certificate; import java.io.IOException; import java.security.GeneralSecurityException; @@ -12,6 +13,8 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; +import javax.xml.transform.TransformerException; + import org.w3c.dom.Element; import at.gv.egovernment.moa.id.AuthenticationException; @@ -47,6 +50,7 @@ import at.gv.egovernment.moa.id.auth.validator.VerifyXMLSignatureResponseValidat import at.gv.egovernment.moa.id.config.ConfigurationException; import at.gv.egovernment.moa.id.config.ConfigurationProvider; import at.gv.egovernment.moa.id.config.ConnectionParameter; +import at.gv.egovernment.moa.id.config.OAParameter; import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; import at.gv.egovernment.moa.id.data.AuthenticationData; @@ -55,7 +59,9 @@ import at.gv.egovernment.moa.id.util.MOAIDMessageProvider; import at.gv.egovernment.moa.id.util.Random; import at.gv.egovernment.moa.id.util.SSLUtils; import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.Base64Utils; 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.DateTimeUtils; import at.gv.egovernment.moa.util.FileUtils; @@ -139,8 +145,6 @@ public class AuthenticationServer implements MOAIDAuthConstants { throw new AuthenticationException("auth.07", new Object[] { authURL + "*" }); if (isEmpty(authURL)) throw new WrongParametersException("StartAuthentication", "AuthURL"); - if (isEmpty(target)) - throw new WrongParametersException("StartAuthentication", PARAM_TARGET); if (isEmpty(oaURL)) throw new WrongParametersException("StartAuthentication", PARAM_OA); @@ -154,6 +158,17 @@ public class AuthenticationServer implements MOAIDAuthConstants { AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(oaURL); if (oaParam == null) throw new AuthenticationException("auth.00", new Object[] { oaURL }); + + if (!oaParam.getBusinessService()) { + if (isEmpty(target)) + throw new WrongParametersException("StartAuthentication", PARAM_TARGET); + } else { + if (!isEmpty(target)) { + Logger.info("Ignoring target parameter thus application type is \"businessService\""); + } + target = null; + } + AuthenticationSession session = newSession(); Logger.info("MOASession " + session.getSessionID() + " angelegt"); session.setTarget(target); @@ -161,6 +176,7 @@ public class AuthenticationServer implements MOAIDAuthConstants { session.setPublicOAURLPrefix(oaParam.getPublicURLPrefix()); session.setAuthURL(authURL); session.setTemplateURL(templateURL); + session.setBusinessService(oaParam.getBusinessService()); String returnURL = new DataURLBuilder().buildDataURL(authURL, REQ_START_AUTHENTICATION, session.getSessionID()); String bkuSelectionType = AuthConfigurationProvider.getInstance().getBKUSelectionType(); @@ -258,28 +274,45 @@ public class AuthenticationServer implements MOAIDAuthConstants { AuthConfigurationProvider.FRONTEND_SERVLETS_ENABLE_HTTP_CONNECTION_PROPERTY); if ((!authURL.startsWith("https:")) && (false == BoolUtils.valueOf(boolStr))) throw new AuthenticationException("auth.07", new Object[] { authURL + "*" }); - if (isEmpty(target)) - throw new WrongParametersException("StartAuthentication", PARAM_TARGET); if (isEmpty(oaURL)) throw new WrongParametersException("StartAuthentication", PARAM_OA); } AuthenticationSession session; - if (sessionID != null) + OAAuthParameter oaParam; + if (sessionID != null) { session = getSession(sessionID); - else { - OAAuthParameter oaParam = + oaParam = + AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( + session.getPublicOAURLPrefix()); + } else { + oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(oaURL); if (oaParam == null) throw new AuthenticationException("auth.00", new Object[] { oaURL }); + if (!oaParam.getBusinessService()) { + if (isEmpty(target)) + throw new WrongParametersException("StartAuthentication", PARAM_TARGET); + } else { + target = null; + } session = newSession(); Logger.info("MOASession " + session.getSessionID() + " angelegt"); session.setTarget(target); session.setOAURLRequested(oaURL); session.setPublicOAURLPrefix(oaParam.getPublicURLPrefix()); session.setAuthURL(authURL); - session.setTemplateURL(templateURL); + session.setTemplateURL(templateURL); + session.setBusinessService(oaParam.getBusinessService()); + } + // BKU URL has not been set yet, even if session already exists + if (bkuURL == null) { + bkuURL = DEFAULT_BKU; } - String infoboxReadRequest = new InfoboxReadRequestBuilder().build(); + session.setBkuURL(bkuURL); + String infoboxReadRequest = + new InfoboxReadRequestBuilder().build(oaParam.getSlVersion12(), + oaParam.getBusinessService(), + oaParam.getIdentityLinkDomainIdentifier()); String dataURL = new DataURLBuilder().buildDataURL( session.getAuthURL(), @@ -296,7 +329,7 @@ public class AuthenticationServer implements MOAIDAuthConstants { ex); } } - String certInfoRequest = new CertInfoVerifyXMLSignatureRequestBuilder().build(); + String certInfoRequest = new CertInfoVerifyXMLSignatureRequestBuilder().build(oaParam.getSlVersion12()); String certInfoDataURL = new DataURLBuilder().buildDataURL( session.getAuthURL(), @@ -371,25 +404,38 @@ public class AuthenticationServer implements MOAIDAuthConstants { // debug output if(null != domVerifyXMLSignatureResponse) OutputXML2File.debugOutputXML2File("VerifyIdentityLinkResponse.xml", domVerifyXMLSignatureResponse, DEBUG_OUTPUT_HIERARCHY); + if (identityLink.getIdentificationType().equalsIgnoreCase(Constants.URN_PREFIX_BASEID)) { + } + + OAAuthParameter oaParam = + AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( + session.getPublicOAURLPrefix()); + + // if OA is type is business service the manifest validation result has to be ignored + boolean ignoreManifestValidationResult = oaParam.getBusinessService() ? true : false; + // validates the <VerifyXMLSignatureResponse> VerifyXMLSignatureResponseValidator.getInstance().validate( verifyXMLSignatureResponse, authConf.getIdentityLinkX509SubjectNames(), - VerifyXMLSignatureResponseValidator.CHECK_IDENTITY_LINK); + VerifyXMLSignatureResponseValidator.CHECK_IDENTITY_LINK, + ignoreManifestValidationResult); session.setIdentityLink(identityLink); // builds the AUTH-block String authBlock = buildAuthenticationBlock(session); - session.setAuthBlock(authBlock); +// session.setAuthBlock(authBlock); // builds the <CreateXMLSignatureRequest> - String[] transformInfos = authConf.getTransformsInfos(); - - OAAuthParameter oaParam = - AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( - session.getPublicOAURLPrefix()); - + String[] transformsInfos = oaParam.getTransformsInfos(); + if ((transformsInfos == null) || (transformsInfos.length == 0)) { + // no OA specific transforms specified, use default ones + transformsInfos = authConf.getTransformsInfos(); + } String createXMLSignatureRequest = - new CreateXMLSignatureRequestBuilder().build(authBlock, oaParam.getKeyBoxIdentifier(), transformInfos); + new CreateXMLSignatureRequestBuilder().build(authBlock, + oaParam.getKeyBoxIdentifier(), + transformsInfos, + oaParam.getSlVersion12()); return createXMLSignatureRequest; } /** @@ -401,12 +447,21 @@ public class AuthenticationServer implements MOAIDAuthConstants { IdentityLink identityLink = session.getIdentityLink(); String issuer = identityLink.getGivenName() + " " + identityLink.getFamilyName(); String gebDat = identityLink.getDateOfBirth(); + String identificationValue = identityLink.getIdentificationValue(); + String identificationType = identityLink.getIdentificationType(); String issueInstant = DateTimeUtils.buildDateTime(Calendar.getInstance()); String authURL = session.getAuthURL(); String target = session.getTarget(); String oaURL = session.getPublicOAURLPrefix(); - String authBlock = - new AuthenticationBlockAssertionBuilder().build(issuer, issueInstant, authURL, target, oaURL, gebDat); + String authBlock = new AuthenticationBlockAssertionBuilder().buildAuthBlock(issuer, + issueInstant, + authURL, + target, + identificationValue, + identificationType, + oaURL, + gebDat); + return authBlock; } /** @@ -450,13 +505,18 @@ public class AuthenticationServer implements MOAIDAuthConstants { AuthConfigurationProvider authConf = AuthConfigurationProvider.getInstance(); // parses <CreateXMLSignatureResponse> CreateXMLSignatureResponse csresp = - new CreateXMLSignatureResponseParser(xmlCreateXMLSignatureReadResponse).parseResponse(); + 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> - new CreateXMLSignatureResponseValidator().validate( - csresp, - session.getTarget(), - session.getPublicOAURLPrefix()); - // builds a <VerifyXMLSignatureRequest> for a MOA-SPSS call + new CreateXMLSignatureResponseValidator().validate(csresp, session); + // builds a <VerifyXMLSignatureRequest> for a MOA-SPSS call String[] vtids = authConf.getMoaSpAuthBlockVerifyTransformsInfoIDs(); String tpid = authConf.getMoaSpAuthBlockTrustProfileID(); Element domVsreq = new VerifyXMLSignatureRequestBuilder().build(csresp, vtids, tpid); @@ -474,7 +534,8 @@ public class AuthenticationServer implements MOAIDAuthConstants { VerifyXMLSignatureResponseValidator.getInstance().validate( vsresp, null, - VerifyXMLSignatureResponseValidator.CHECK_AUTH_BLOCK); + VerifyXMLSignatureResponseValidator.CHECK_AUTH_BLOCK, + true); // compares the public keys from the identityLink with the AuthBlock VerifyXMLSignatureResponseValidator.getInstance().validateCertificate( vsresp, @@ -507,36 +568,64 @@ public class AuthenticationServer implements MOAIDAuthConstants { IdentityLink identityLink = session.getIdentityLink(); AuthenticationData authData = new AuthenticationData(); + OAAuthParameter oaParam = + AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( + session.getPublicOAURLPrefix()); + boolean businessService = oaParam.getBusinessService(); authData.setMajorVersion(1); authData.setMinorVersion(0); authData.setAssertionID(Random.nextRandom()); authData.setIssuer(session.getAuthURL()); authData.setIssueInstant(DateTimeUtils.buildDateTime(Calendar.getInstance())); - String bpkBase64 = - new BPKBuilder().buildBPK( - identityLink.getIdentificationValue(), - session.getTarget()); - authData.setIdentificationType(identityLink.getIdentificationType()); - authData.setPBK(bpkBase64); + + authData.setIdentificationType(identityLink.getIdentificationType()); authData.setGivenName(identityLink.getGivenName()); authData.setFamilyName(identityLink.getFamilyName()); authData.setDateOfBirth(identityLink.getDateOfBirth()); authData.setQualifiedCertificate(verifyXMLSigResp.isQualifiedCertificate()); authData.setPublicAuthority(verifyXMLSigResp.isPublicAuthority()); authData.setPublicAuthorityCode(verifyXMLSigResp.getPublicAuthorityCode()); - OAAuthParameter oaParam = - AuthConfigurationProvider.getInstance().getOnlineApplicationParameter( - session.getPublicOAURLPrefix()); - String prPerson = new PersonDataBuilder().build(identityLink, oaParam.getProvideStammzahl()); - - try { + authData.setBkuURL(session.getBkuURL()); + boolean provideStammzahl = oaParam.getProvideStammzahl(); + if (provideStammzahl) { + authData.setIdentificationValue(identityLink.getIdentificationValue()); + } + String prPerson = new PersonDataBuilder().build(identityLink, provideStammzahl); + + try { + String signerCertificateBase64 = ""; + if (oaParam.getProvideCertifcate()) { + X509Certificate signerCertificate = verifyXMLSigResp.getX509certificate(); + if (signerCertificate != null) { + signerCertificateBase64 = Base64Utils.encode(signerCertificate.getEncoded()); + } else { + Logger.info("\"provideCertificate\" is \"true\", but no signer certificate available"); + } + } + authData.setSignerCertificate(signerCertificateBase64); + if (businessService) { + authData.setWPBK(identityLink.getIdentificationValue()); + } else { + // only compute bPK if online applcation is a public service + String bpkBase64 = + new BPKBuilder().buildBPK( + identityLink.getIdentificationValue(), + session.getTarget()); + authData.setPBK(bpkBase64); + } String ilAssertion = oaParam.getProvideIdentityLink() ? DOMUtils.serializeNode(identityLink.getSamlAssertion()) : ""; String authBlock = oaParam.getProvideAuthBlock() ? session.getAuthBlock() : ""; String samlAssertion = - new AuthenticationDataAssertionBuilder().build(authData, prPerson, authBlock, ilAssertion); + new AuthenticationDataAssertionBuilder().build(authData, + prPerson, + authBlock, + ilAssertion, + session.getBkuURL(), + signerCertificateBase64, + businessService); authData.setSamlAssertion(samlAssertion); return authData; } catch (Throwable ex) { diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java b/id.server/src/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java index ddba20049..15d21b4b9 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/MOAIDAuthConstants.java @@ -16,6 +16,8 @@ public interface MOAIDAuthConstants { public static final String PARAM_BKU = "bkuURI"; /** servlet parameter "BKUSelectionTemplate" */ public static final String PARAM_BKUTEMPLATE = "BKUSelectionTemplate"; + /** default BKU URL */ + public static final String DEFAULT_BKU = "http://localhost:3495/http-security-layer-request"; /** servlet parameter "returnURI" */ public static final String PARAM_RETURN = "returnURI"; /** servlet parameter "Template" */ diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilder.java b/id.server/src/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilder.java index 41f439d04..ec412deb3 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilder.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilder.java @@ -12,26 +12,39 @@ import at.gv.egovernment.moa.util.Constants; * @version $Id$ */ public class AuthenticationBlockAssertionBuilder implements Constants { - /** private static String nl contains the NewLine representation in Java*/ + /** the NewLine representation in Java*/ private static String nl = "\n"; - /** private static String AUTH_BLOCK contains an XML-Auth-Block-Template */ + /** template for the Auth-Block */ private static String AUTH_BLOCK = - "<saml:Assertion xmlns:saml=''" + SAML_NS_URI + "'' MajorVersion=''1'' MinorVersion=''0'' AssertionID=''any'' Issuer=''{0}'' IssueInstant=''{1}''>" + nl + - " <saml:AttributeStatement>" + nl + - " <saml:Subject>" + nl + - " <saml:NameIdentifier>{2}</saml:NameIdentifier>" + nl + - " </saml:Subject>" + nl + - " <saml:Attribute AttributeName=''Geschaeftsbereich'' AttributeNamespace=''" + MOA_NS_URI + "''>" + nl + - " <saml:AttributeValue>{3}</saml:AttributeValue>" + nl + - " </saml:Attribute>" + nl + - " <saml:Attribute AttributeName=''OA'' AttributeNamespace=''" + MOA_NS_URI + "''>" + nl + - " <saml:AttributeValue>{4}</saml:AttributeValue>" + nl + - " </saml:Attribute>" + nl + - " <saml:Attribute AttributeName=''Geburtsdatum'' AttributeNamespace=''" + MOA_NS_URI + "''>" + nl + - " <saml:AttributeValue>{5}</saml:AttributeValue>" + nl + - " </saml:Attribute>" + nl + - " </saml:AttributeStatement>" + nl + - "</saml:Assertion>"; + "<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 + + " </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; /** * Constructor for AuthenticationBlockAssertionBuilder. @@ -39,21 +52,56 @@ public class AuthenticationBlockAssertionBuilder implements Constants { public AuthenticationBlockAssertionBuilder() { super(); } + /** - * Builds the authentication block <code><saml:Assertion></code>. + * 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" + * @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 identiyLinkType 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 * @return String representation of authentication block * <code><saml:Assertion></code> built */ - public String build(String issuer, String issueInstant, String authURL, String target, String oaURL, String GebDat) { - String assertion = MessageFormat.format( - AUTH_BLOCK, new Object[] { issuer, issueInstant, authURL, target, oaURL, GebDat}); - return assertion; + public String buildAuthBlock(String issuer, + String issueInstant, + String authURL, + String target, + String identityLinkValue, + String identityLinkType, + String oaURL, + String GebDat) + { + + String gebeORwbpk = ""; + String wbpkNSDeclaration = ""; + if (target == null) { + // OA is a business application + gebeORwbpk = MessageFormat.format( + WBPK_ATTRIBUTE, new Object[] { identityLinkValue, identityLinkType }); + wbpkNSDeclaration = " xmlns:pr=\"" + PD_NS_URI + "\" xmlns:si=\"" + PD_NS_URI + "\""; + } else { + gebeORwbpk = MessageFormat.format( + GESCHAEFTS_BEREICH_ATTRIBUTE, new Object[] { target }); + } + + String assertion = MessageFormat.format( + AUTH_BLOCK, new Object[] { wbpkNSDeclaration, issuer, issueInstant, authURL, gebeORwbpk, oaURL, GebDat}); + return assertion; + } } diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataAssertionBuilder.java b/id.server/src/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataAssertionBuilder.java index eaf9aa0ae..cdb660010 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataAssertionBuilder.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataAssertionBuilder.java @@ -26,19 +26,23 @@ public class AuthenticationDataAssertionBuilder implements Constants { " MajorVersion=''1'' MinorVersion=''0'' AssertionID=''{0}'' Issuer=''{1}'' IssueInstant=''{2}''>" + NL + " <saml:AttributeStatement>" + NL + " <saml:Subject>" + NL + - " <saml:NameIdentifier NameQualifier=''urn:publicid:gv.at:cdid+bPK''>{3}</saml:NameIdentifier>" + NL + + " <saml:NameIdentifier NameQualifier=''{3}''>{4}</saml:NameIdentifier>" + NL + " <saml:SubjectConfirmation>" + NL + " <saml:ConfirmationMethod>" + MOA_NS_URI + "cm</saml:ConfirmationMethod>" + NL + - " <saml:SubjectConfirmationData>{4}{5}</saml:SubjectConfirmationData>" + NL + + " <saml:SubjectConfirmationData>{5}{6}</saml:SubjectConfirmationData>" + NL + " </saml:SubjectConfirmation>" + NL + " </saml:Subject>" + NL + " <saml:Attribute AttributeName=''PersonData'' AttributeNamespace=''" + PD_NS_URI + "''>" + NL + - " <saml:AttributeValue>{6}</saml:AttributeValue>" + NL + + " <saml:AttributeValue>{7}</saml:AttributeValue>" + NL + " </saml:Attribute>" + NL + " <saml:Attribute AttributeName=''isQualifiedCertificate'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL + - " <saml:AttributeValue>{7}</saml:AttributeValue>" + NL + + " <saml:AttributeValue>{8}</saml:AttributeValue>" + NL + " </saml:Attribute>" + NL + - "{8}" + + " <saml:Attribute AttributeName=''bkuURL'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL + + " <saml:AttributeValue>{9}</saml:AttributeValue>" + NL + + " </saml:Attribute>" + NL + + "{10}" + + "{11}" + " </saml:AttributeStatement>" + NL + "</saml:Assertion>"; /** @@ -49,6 +53,11 @@ public class AuthenticationDataAssertionBuilder implements Constants { " <saml:Attribute AttributeName=''isPublicAuthority'' AttributeNamespace=''urn:oid:1.2.40.0.10.1.1.1''>" + NL + " <saml:AttributeValue>{0}</saml:AttributeValue>" + NL + " </saml:Attribute>" + NL; + + private static final String SIGNER_CERTIFICATE_ATT = + " <saml:Attribute AttributeName=''SignerCertificate'' AttributeNamespace=''" + MOA_NS_URI + "''>" + NL + + " <saml:AttributeValue>{0}</saml:AttributeValue>" + NL + + " </saml:Attribute>" + NL; /** * Constructor for AuthenticationDataAssertionBuilder. @@ -67,6 +76,12 @@ public class AuthenticationDataAssertionBuilder implements Constants { * <code>lt;saml:SubjectConfirmationData></code> element; may include * the <code>"Stammzahl"</code> or not; may be empty * @param xmlIdentityLink the IdentityLink + * @param signerCertificateBase64 Base64 encoded certificate of the signer. Maybe + * an empty string if the signer certificate should not be provided. + * Will be ignored if the <code>businessService</code> parameter is + * set to <code>false</code>. + * @param businessService <code>true</code> if the online application is a + * business service, otherwise <code>false</code> * @return the <code><saml:Assertion></code> * @throws BuildException if an error occurs during the build process */ @@ -74,7 +89,10 @@ public class AuthenticationDataAssertionBuilder implements Constants { AuthenticationData authData, String xmlPersonData, String xmlAuthBlock, - String xmlIdentityLink) throws BuildException { + String xmlIdentityLink, + String bkuURL, + String signerCertificateBase64, + boolean businessService) throws BuildException { String isQualifiedCertificate = authData.isQualifiedCertificate() ? "true" : "false"; String publicAuthorityAttribute = ""; @@ -85,17 +103,38 @@ public class AuthenticationDataAssertionBuilder implements Constants { publicAuthorityAttribute = MessageFormat.format( PUBLIC_AUTHORITY_ATT, new Object[] { publicAuthorityIdentification }); } - + + + String signerCertificateAttribute = ""; + if (signerCertificateBase64 != "") { + signerCertificateAttribute = MessageFormat.format( + SIGNER_CERTIFICATE_ATT, new Object[] { signerCertificateBase64 }); + } + + String pkType; + String pkValue; + if (businessService) { + pkType = authData.getIdentificationType(); + pkValue = authData.getWPBK(); + + } else { + pkType = URN_PREFIX_BPK; + pkValue = authData.getPBK(); + } + String assertion = MessageFormat.format(AUTH_DATA, new Object[] { - authData.getAssertionID(), + authData.getAssertionID(), authData.getIssuer(), authData.getIssueInstant(), - authData.getPBK(), - removeXMLDeclaration(xmlAuthBlock), - removeXMLDeclaration(xmlIdentityLink), + pkType, + pkValue, + removeXMLDeclaration(xmlAuthBlock), + removeXMLDeclaration(xmlIdentityLink), removeXMLDeclaration(xmlPersonData), - isQualifiedCertificate, - publicAuthorityAttribute}); + isQualifiedCertificate, + bkuURL, + publicAuthorityAttribute, + signerCertificateAttribute}); return assertion; } diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/builder/CertInfoVerifyXMLSignatureRequestBuilder.java b/id.server/src/at/gv/egovernment/moa/id/auth/builder/CertInfoVerifyXMLSignatureRequestBuilder.java index 5ceb1d1c0..cb6c8b31b 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/builder/CertInfoVerifyXMLSignatureRequestBuilder.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/builder/CertInfoVerifyXMLSignatureRequestBuilder.java @@ -1,9 +1,13 @@ package at.gv.egovernment.moa.id.auth.builder; +import java.io.File; import java.io.IOException; +import java.text.MessageFormat; import at.gv.egovernment.moa.id.BuildException; +import at.gv.egovernment.moa.util.Constants; import at.gv.egovernment.moa.util.FileUtils; +import at.gv.egovernment.moa.util.StringUtils; /** * Builder for the <code><VerifyXMLSignatureRequest></code> structure @@ -12,10 +16,26 @@ import at.gv.egovernment.moa.util.FileUtils; * @author Paul Ivancsics * @version $Id$ */ -public class CertInfoVerifyXMLSignatureRequestBuilder extends Builder { +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:xml=\"" + XML_NS_URI + "\" 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 @@ -28,16 +48,30 @@ public class CertInfoVerifyXMLSignatureRequestBuilder extends Builder { * @return the XML structure * @throws BuildException */ - public String build() throws BuildException { - String resCertInfoRequest = "resources/xmldata/CertInfoVerifyXMLSignatureRequest.xml"; - String resDsigSignature = "resources/xmldata/CertInfoDsigSignature.xml"; - String certInfoRequest; - try { - certInfoRequest = FileUtils.readResource(resCertInfoRequest, "UTF-8"); - } - catch (IOException ex) { - throw new BuildException("auth.04", new Object[] {resCertInfoRequest, ex.toString()}); + public String build(boolean slVersion12) 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); diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureRequestBuilder.java b/id.server/src/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureRequestBuilder.java index 48320c4f5..51429251e 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureRequestBuilder.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureRequestBuilder.java @@ -3,6 +3,7 @@ package at.gv.egovernment.moa.id.auth.builder; import java.text.MessageFormat; import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.StringUtils; /** * Builder for the <code><CreateXMLSignatureRequest></code> structure @@ -17,22 +18,23 @@ public class CreateXMLSignatureRequestBuilder implements Constants { private static final String nl = "\n"; /** * XML template for the <code><moa:CreateXMLSignatureRequest></code> to be built - */ + */ private static final String CREATE_XML_SIGNATURE_REQUEST = - "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + nl + - "<sl11:CreateXMLSignatureRequest xmlns:dsig=''" + DSIG_NS_URI + "'' xmlns:sl10=''" + SL10_NS_URI + "'' xmlns:sl11=''" + SL11_NS_URI + "''>" + nl + - " <sl11:KeyboxIdentifier>{1}</sl11:KeyboxIdentifier>" + nl + - " <sl11:DataObjectInfo Structure=''detached''>" + nl + - " <sl10:DataObject Reference=''''/>" + nl + - "{2}" + - " </sl11:DataObjectInfo>" + nl + - " <sl11:SignatureInfo>" + nl + - " <sl11:SignatureEnvironment>" + nl + - " <sl10:XMLContent>{0}</sl10:XMLContent>" + nl + - " </sl11:SignatureEnvironment>" + nl + - " <sl11:SignatureLocation Index=''2''>/saml:Assertion</sl11:SignatureLocation>" + nl + - " </sl11:SignatureInfo>" + nl + - "</sl11:CreateXMLSignatureRequest>"; + "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + nl + + "<{3}:CreateXMLSignatureRequest xmlns:dsig=''" + DSIG_NS_URI + "'' {5}>" + nl + + " <{3}:KeyboxIdentifier>{1}</{3}:KeyboxIdentifier>" + nl + + " <{3}:DataObjectInfo Structure=''detached''>" + nl + + " <{4}:DataObject Reference=''''/>" + nl + + "{2}" + + " </{3}:DataObjectInfo>" + nl + + " <{3}:SignatureInfo>" + nl + + " <{3}:SignatureEnvironment>" + nl + + " <{4}:XMLContent>{0}</{4}:XMLContent>" + nl + + " </{3}:SignatureEnvironment>" + nl + + " <{3}:SignatureLocation Index=''2''>/saml:Assertion</{3}:SignatureLocation>" + nl + + " </{3}:SignatureInfo>" + nl + + "</{3}:CreateXMLSignatureRequest>"; + /** * Constructor for CreateXMLSignatureRequestBuilder. @@ -46,14 +48,46 @@ public class CreateXMLSignatureRequestBuilder implements Constants { * * @param authBlock String representation of XML authentication block * @param keyBoxIdentfier the key box identifier which will be used (e.g. CertifiedKeypair) + * @param slVersion12 specifies whether the Security Layer version number is 1.2 or not * @return String representation of <code><CreateXMLSignatureRequest></code> */ - public String build(String authBlock, String keyBoxIdentifier, String[] dsigTransformInfos) { - String dsigTransformInfosString = ""; - for (int i = 0; i < dsigTransformInfos.length; i++) + public String build(String authBlock, String keyBoxIdentifier, String[] dsigTransformInfos, boolean slVersion12) { + + String sl10Prefix; + String sl11Prefix; + String slNsDeclaration; + + String dsigTransformInfosString = ""; + for (int i = 0; i < dsigTransformInfos.length; i++) { dsigTransformInfosString += dsigTransformInfos[i]; + } + + if (slVersion12) { + + // replace the SecurityLayer namespace prefixes and URIs within the transforms + dsigTransformInfosString = StringUtils.changeSLVersion(dsigTransformInfosString, + SL10_PREFIX, SL12_PREFIX, + SL10_NS_URI, SL12_NS_URI); + sl10Prefix = SL12_PREFIX; + sl11Prefix = SL12_PREFIX; + slNsDeclaration = "xmlns:" + SL12_PREFIX + "='" + SL12_NS_URI + "'"; + + } else { + + sl10Prefix = SL10_PREFIX; + sl11Prefix = SL11_PREFIX; + slNsDeclaration = "xmlns:" + sl10Prefix + "='" + SL10_NS_URI + "' xmlns:" + sl11Prefix + "='" + SL11_NS_URI + "'"; + + } + String request = MessageFormat.format( - CREATE_XML_SIGNATURE_REQUEST, new Object[] { authBlock, keyBoxIdentifier, dsigTransformInfosString }); + CREATE_XML_SIGNATURE_REQUEST, new Object[] { authBlock, + keyBoxIdentifier, + dsigTransformInfosString, + sl11Prefix, + sl10Prefix, + slNsDeclaration }); + return request; } } diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilder.java b/id.server/src/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilder.java index dbc14804d..4fb5b0837 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilder.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilder.java @@ -27,8 +27,6 @@ public class GetIdentityLinkFormBuilder extends Builder { /** special tag in the HTML template to be substituted for the certificate info data URL */ private static final String CERTINFO_DATAURL_TAG = "<CertInfoDataURL>"; - /** default BKU URL */ - private static final String DEFAULT_BKU = "http://localhost:3495/http-security-layer-request"; /** default HTML template */ private static final String DEFAULT_HTML_TEMPLATE = "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">" + nl + @@ -84,11 +82,11 @@ public class GetIdentityLinkFormBuilder extends Builder { throws BuildException { String htmlForm = htmlTemplate == null ? DEFAULT_HTML_TEMPLATE : htmlTemplate; - String bku = bkuURL == null ? DEFAULT_BKU : bkuURL; - htmlForm = replaceTag(htmlForm, BKU_TAG, bku); +// String bku = bkuURL == null ? DEFAULT_BKU : bkuURL; + htmlForm = replaceTag(htmlForm, BKU_TAG, bkuURL); htmlForm = replaceTag(htmlForm, XMLREQUEST_TAG, encodeParameter(xmlRequest)); htmlForm = replaceTag(htmlForm, DATAURL_TAG, dataURL); - htmlForm = replaceTag(htmlForm, BKU_TAG, bku); + htmlForm = replaceTag(htmlForm, BKU_TAG, bkuURL); htmlForm = replaceTag(htmlForm, CERTINFO_XMLREQUEST_TAG, encodeParameter(certInfoXMLRequest)); htmlForm = replaceTag(htmlForm, CERTINFO_DATAURL_TAG, certInfoDataURL); return htmlForm; diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilder.java b/id.server/src/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilder.java index d3e100671..c2bafe43b 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilder.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilder.java @@ -11,29 +11,76 @@ import at.gv.egovernment.moa.util.Constants; */ public class InfoboxReadRequestBuilder implements Constants { - /** - * XML template for the <code><sl10:InfoboxReadRequest></code> to be built - */ - String INFOBOX_READ_REQUEST = - "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + - "<sl10:InfoboxReadRequest xmlns:sl10=\"" + SL10_NS_URI + "\">" + - "<sl10:InfoboxIdentifier>IdentityLink</sl10:InfoboxIdentifier>" + - "<sl10:BinaryFileParameters ContentIsXMLEntity=\"true\"/>" + - "</sl10:InfoboxReadRequest>"; /** * 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() { - String request = INFOBOX_READ_REQUEST; - return request; + public String build(boolean slVersion12, boolean businessService, String identityLinkDomainIdentifier) { + + 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(); + } } diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java b/id.server/src/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java index ba4a9e367..27d91bf1f 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/data/AuthenticationSession.java @@ -15,7 +15,8 @@ public class AuthenticationSession { */ private String sessionID; /** - * "Geschäftsbereich" the online application belongs to + * "Geschäftsbereich" the online application belongs to; maybe <code>null</code> + * if the online application is a business application */ private String target; /** @@ -34,6 +35,10 @@ public class AuthenticationSession { * HTML template URL */ private String templateURL; + /** + * URL of the BKU + */ + private String bkuURL; /** * identity link read from smartcard */ @@ -49,8 +54,13 @@ public class AuthenticationSession { /** * timestamp logging when identity link has been received */ - private Date timestampIdentityLink; - + private Date timestampIdentityLink; + /** + * Indicates whether the corresponding online application is a business + * service or not + */ + private boolean businessService; + /** * Constructor for AuthenticationSession. * @@ -108,6 +118,14 @@ public class AuthenticationSession { public String getPublicOAURLPrefix() { return oaPublicURLPrefix; } + + /** + * Returns the BKU URL. + * @return String + */ + public String getBkuURL() { + return bkuURL; + } /** * Returns the target. @@ -132,6 +150,14 @@ public class AuthenticationSession { public void setPublicOAURLPrefix(String url) { this.oaPublicURLPrefix = url; } + + /** + * Sets the bkuURL + * @param url The BKU URL to set + */ + public void setBkuURL(String url) { + this.bkuURL = url; + } /** * Sets the target. @@ -180,6 +206,23 @@ public class AuthenticationSession { public Date getTimestampIdentityLink() { return timestampIdentityLink; } + + /** + * Returns the businessService. + * @return <code>true</code> if the corresponding online application is + * a business application, otherwise <code>false</code> + */ + public boolean getBusinessService() { + return businessService; + } + + /** + * Sets the businessService variable. + * @param businessService the value for setting the businessService variable. + */ + public void setBusinessService(boolean businessService) { + this.businessService = businessService; + } /** * Returns the timestampStart. diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/data/SAMLAttribute.java b/id.server/src/at/gv/egovernment/moa/id/auth/data/SAMLAttribute.java index c787b2a81..76ba6366d 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/data/SAMLAttribute.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/data/SAMLAttribute.java @@ -9,17 +9,18 @@ package at.gv.egovernment.moa.id.auth.data; * */ public class SAMLAttribute { -/** the name to be stored */ -private String name; -/** the namespace to be stored */ -private String namespace; -/** the value to be stored */ -private String value; + + /** the name to be stored */ + private String name; + /** the namespace to be stored */ + private String namespace; + /** the value to be stored */ + private Object value; /** * Constructor for SAMLAttribute. */ - public SAMLAttribute(String name, String namespace, String value) { + public SAMLAttribute(String name, String namespace, Object value) { this.name = name; this.namespace = namespace; @@ -27,52 +28,52 @@ private String value; } -/** - * Returns the name. - * @return String - */ -public String getName() { - return name; -} - -/** - * Returns the namespace. - * @return String - */ -public String getNamespace() { - return namespace; -} - -/** - * Returns the value. - * @return String - */ -public String getValue() { - return value; -} - -/** - * Sets the name. - * @param name The name to set - */ -public void setName(String name) { - this.name = name; -} - -/** - * Sets the namespace. - * @param namespace The namespace to set - */ -public void setNamespace(String namespace) { - this.namespace = namespace; -} - -/** - * Sets the value. - * @param value The value to set - */ -public void setValue(String value) { - this.value = value; -} + /** + * Returns the name. + * @return String + */ + public String getName() { + return name; + } + + /** + * Returns the namespace. + * @return String + */ + public String getNamespace() { + return namespace; + } + + /** + * Returns the value. + * @return String + */ + public Object getValue() { + return value; + } + + /** + * Sets the name. + * @param name The name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * Sets the namespace. + * @param namespace The namespace to set + */ + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + /** + * Sets the value. + * @param value The value to set + */ + public void setValue(Object value) { + this.value = value; + } } diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/parser/CreateXMLSignatureResponseParser.java b/id.server/src/at/gv/egovernment/moa/id/auth/parser/CreateXMLSignatureResponseParser.java index 1079a48de..094fa091f 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/parser/CreateXMLSignatureResponseParser.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/parser/CreateXMLSignatureResponseParser.java @@ -6,9 +6,11 @@ import java.util.ArrayList; import java.util.List; import org.w3c.dom.Element; +import org.w3c.dom.Node; import org.w3c.dom.traversal.NodeIterator; -import at.gv.egovernment.moa.id.*; +import at.gv.egovernment.moa.id.AuthenticationException; +import at.gv.egovernment.moa.id.ParseException; import at.gv.egovernment.moa.id.auth.data.CreateXMLSignatureResponse; import at.gv.egovernment.moa.id.auth.data.SAMLAttribute; import at.gv.egovernment.moa.util.Constants; @@ -27,16 +29,13 @@ public class CreateXMLSignatureResponseParser { // // XPath namespace prefix shortcuts // - /** Xpath prefix for reaching SecurityLayer 1.0 Namespaces */ - private static final String SL10 = Constants.SL10_PREFIX + ":"; - /** Xpath prefix for reaching SecurityLayer 1.1 Namespaces */ - private static final String SL11 = Constants.SL11_PREFIX + ":"; + /** 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 = "/" + SL11 + "CreateXMLSignatureResponse/"; + 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 */ @@ -45,7 +44,8 @@ public class CreateXMLSignatureResponseParser { 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 XML-Document provided by the Security Layer Card */ private Element sigResponse; @@ -89,6 +89,7 @@ public class CreateXMLSignatureResponseParser { try { sigResponse = DOMUtils.parseXmlValidating(is); + } catch (Throwable t) { throw new ParseException("parser.01", new Object[] { t.toString()}, t); @@ -114,17 +115,23 @@ public class CreateXMLSignatureResponseParser { public CreateXMLSignatureResponse parseResponse() throws ParseException { CreateXMLSignatureResponse cResp; try { - cResp = new CreateXMLSignatureResponse(); - cResp.setSamlNameIdentifier(XPathUtils.getElementValue(sigResponse, SAML_SUBJECT_NAME_IDENTIFIER_XPATH, null)); - cResp.setSamlAssertion((Element) XPathUtils.selectSingleNode(sigResponse, SAML_ASSERTION_XPATH)); - NodeIterator attrIter = XPathUtils.selectNodeIterator(sigResponse, SAML_ATTRIBUTE_XPATH); + String slPrefix = sigResponse.getPrefix(); + 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 samlAttributes = new ArrayList(); while ((samlAttr = (Element) attrIter.nextNode()) != null) { String attrName = XPathUtils.getAttributeValue(samlAttr, "@AttributeName", ""); String attrNamespace = XPathUtils.getAttributeValue(samlAttr, "@AttributeNamespace", ""); - String attrValue = XPathUtils.getElementValue(samlAttr, SAML_ATTRIBUTE_VALUE_XPATH, ""); + Object attrValue; + if ("wbPK".equals(attrName)) { + Element attrValueElem = (Element)XPathUtils.selectSingleNode(samlAttr, SAML_ATTRIBUTE_VALUE_XPATH); + attrValue = DOMUtils.getElementFromNodeList(attrValueElem.getChildNodes()); + } else { + attrValue = XPathUtils.getElementValue(samlAttr, SAML_ATTRIBUTE_VALUE_XPATH, ""); + } samlAttributes.add(new SAMLAttribute(attrName, attrNamespace, attrValue)); } SAMLAttribute[] result = new SAMLAttribute[samlAttributes.size()]; @@ -136,5 +143,37 @@ public class CreateXMLSignatureResponseParser { } return cResp; } - + +// public CreateXMLSignatureResponse parseResponse1() 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/src/at/gv/egovernment/moa/id/auth/parser/ErrorResponseParser.java b/id.server/src/at/gv/egovernment/moa/id/auth/parser/ErrorResponseParser.java index 4fbc58977..a952b2066 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/parser/ErrorResponseParser.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/parser/ErrorResponseParser.java @@ -6,7 +6,6 @@ import java.io.InputStream; import org.w3c.dom.Element; import at.gv.egovernment.moa.id.ParseException; -import at.gv.egovernment.moa.util.Constants; import at.gv.egovernment.moa.util.DOMUtils; import at.gv.egovernment.moa.util.XPathUtils; @@ -18,20 +17,6 @@ import at.gv.egovernment.moa.util.XPathUtils; */ public class ErrorResponseParser { - // - // XPath namespace prefix shortcuts - // - /** Xpath prefix for reaching SecurityLayer 1.0 Namespaces */ - private static final String SL10 = Constants.SL10_PREFIX + ":"; - /** Xpath expression to the root element */ - private static final String ROOT = "/" + SL10 + "ErrorResponse/"; - /** Xpath expression to the ErrorCode element */ - private static final String ERROR_CODE_XPATH = - ROOT + SL10 + "ErrorCode"; - /** Xpath expression to the Info element */ - private static final String ERROR_INFO_XPATH = - ROOT + SL10 + "Info"; - /** This is the root element of the XML-Document provided by the Security Layer Card */ private Element errorElement; @@ -72,8 +57,16 @@ public class ErrorResponseParser { * @return String */ public String getErrorCode() { - - return XPathUtils.getElementValue(errorElement,ERROR_CODE_XPATH,null); + + String slPrefix = errorElement.getPrefix(); + StringBuffer sb = new StringBuffer("/"); + sb.append(slPrefix); + sb.append(":ErrorResponse/"); + sb.append(slPrefix); + sb.append(":ErrorCode"); + String errorCodeXPath = sb.toString(); + return XPathUtils.getElementValue(errorElement,errorCodeXPath,null); + } /** @@ -82,7 +75,15 @@ public class ErrorResponseParser { */ public String getErrorInfo() { - return XPathUtils.getElementValue(errorElement,ERROR_INFO_XPATH,null); + String slPrefix = errorElement.getPrefix(); + StringBuffer sb = new StringBuffer("/"); + sb.append(slPrefix); + sb.append(":ErrorResponse/"); + sb.append(slPrefix); + sb.append(":Info"); + String errorInfoXPath = sb.toString(); + return XPathUtils.getElementValue(errorElement,errorInfoXPath,null); + } diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/parser/InfoboxReadResponseParser.java b/id.server/src/at/gv/egovernment/moa/id/auth/parser/InfoboxReadResponseParser.java index 012a5b559..05272a695 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/parser/InfoboxReadResponseParser.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/parser/InfoboxReadResponseParser.java @@ -19,17 +19,17 @@ import at.gv.egovernment.moa.util.XPathUtils; */ public class InfoboxReadResponseParser { - // - // XPath namespace prefix shortcuts - // - /** Xpath prefix for reaching SecurityLayer 1.0 Namespaces */ - private static final String SL10 = Constants.SL10_PREFIX + ":"; - /** Xpath prefix for reaching SAML Namespaces */ - private static final String SAML = Constants.SAML_PREFIX + ":"; - /** Xpath expression to the root element */ - private static final String ROOT = "/" + SL10 + "InfoboxReadResponse/"; - /** Xpath expression to the SAML:Assertion element */ - private static final String SAML_ASSERTION_XPATH = ROOT + SL10 + "BinaryFileData/" + SL10 + "XMLContent/" + SAML + "Assertion"; +// // +// // XPath namespace prefix shortcuts +// // +// /** Xpath prefix for reaching SecurityLayer 1.0 Namespaces */ +// private static final String SL10 = Constants.SL10_PREFIX + ":"; +// /** Xpath prefix for reaching SAML Namespaces */ +// private static final String SAML = Constants.SAML_PREFIX + ":"; +// /** Xpath expression to the root element */ +// private static final String ROOT = "/" + SL10 + "InfoboxReadResponse/"; +// /** Xpath expression to the SAML:Assertion element */ +// private static final String SAML_ASSERTION_XPATH = ROOT + SL10 + "BinaryFileData/" + SL10 + "XMLContent/" + SAML + "Assertion"; /** This is the root element of the XML-Document provided by the Security Layer Card*/ private Element infoBoxElem; @@ -86,8 +86,21 @@ public class InfoboxReadResponseParser { */ public String parseSAMLAssertion() throws ParseException { try { - Element samlAssertion = (Element) XPathUtils.selectSingleNode(infoBoxElem, SAML_ASSERTION_XPATH); + + String slPrefix = infoBoxElem.getPrefix(); + 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); @@ -105,5 +118,6 @@ public class InfoboxReadResponseParser { IdentityLinkAssertionParser ilParser = new IdentityLinkAssertionParser(samlAssertionString); return ilParser.parseIdentityLink(); } + } diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java b/id.server/src/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java index e628cb997..e0f3fcaff 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java @@ -121,6 +121,7 @@ public class VerifyXMLSignatureResponseParser { */ public VerifyXMLSignatureResponse parseData() throws ParseException { + VerifyXMLSignatureResponse respData=new VerifyXMLSignatureResponse(); try { diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/servlet/SelectBKUServlet.java b/id.server/src/at/gv/egovernment/moa/id/auth/servlet/SelectBKUServlet.java index 50d3225d2..4dc69c70b 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/servlet/SelectBKUServlet.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/servlet/SelectBKUServlet.java @@ -78,8 +78,7 @@ public class SelectBKUServlet extends AuthServlet { resp.setContentType("text/html"); resp.sendRedirect(redirectURL); Logger.info("REDIRECT TO: " + redirectURL); - } - else { + } else { // bkuSelectionType==HTMLSelect String htmlForm = returnValue; resp.setContentType("text/html;charset=UTF-8"); diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java b/id.server/src/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java index 89748da3f..d0f11c3bf 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java @@ -58,7 +58,8 @@ public class VerifyAuthenticationBlockServlet extends AuthServlet { * <ul> * <li>Status: <code>302</code></li> * <li>Header <code>"Location"</code>: URL of the online application requested, with - * parameters <code>"Target"</code> and <code>"SAMLArtifact"</code> added</li> + * parameters <code>"Target"</code>(only if the online application is + * a public service) and <code>"SAMLArtifact"</code> added</li> * <li>Error status: <code>500</code> * </ul> * @see AuthenticationServer#verifyAuthenticationBlock @@ -80,7 +81,9 @@ public class VerifyAuthenticationBlockServlet extends AuthServlet { String samlArtifactBase64 = AuthenticationServer.getInstance().verifyAuthenticationBlock(sessionID, createXMLSignatureResponse); String redirectURL = session.getOAURLRequested(); - redirectURL = addURLParameter(redirectURL, PARAM_TARGET, session.getTarget()); + if (!session.getBusinessService()) { + redirectURL = addURLParameter(redirectURL, PARAM_TARGET, session.getTarget()); + } redirectURL = addURLParameter(redirectURL, PARAM_SAMLARTIFACT, URLEncoder.encode(samlArtifactBase64, "UTF-8")); redirectURL = resp.encodeRedirectURL(redirectURL); resp.setContentType("text/html"); diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/validator/CreateXMLSignatureResponseValidator.java b/id.server/src/at/gv/egovernment/moa/id/auth/validator/CreateXMLSignatureResponseValidator.java index 3c15b9ec4..2eafaa297 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/validator/CreateXMLSignatureResponseValidator.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/validator/CreateXMLSignatureResponseValidator.java @@ -2,6 +2,7 @@ package at.gv.egovernment.moa.id.auth.validator; import org.w3c.dom.Element; +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.SAMLAttribute; import at.gv.egovernment.moa.util.Constants; @@ -17,7 +18,7 @@ import at.gv.egovernment.moa.util.XPathUtils; */ public class CreateXMLSignatureResponseValidator { - /** Xpath prefix for reaching SecurityLayer 1.0 Namespaces */ + /** 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 + ":"; @@ -59,45 +60,78 @@ public class CreateXMLSignatureResponseValidator { * @param oaURL * @throws ValidateException */ - public void validate(CreateXMLSignatureResponse createXMLSignatureResponse, String gbTarget, String oaURL) + public void validate(CreateXMLSignatureResponse createXMLSignatureResponse, AuthenticationSession session) throws ValidateException { // A3.056: more then one /saml:Assertion/saml:AttributeStatement/saml:Subject/saml:NameIdentifier - - - XPathUtils.selectNodeList(createXMLSignatureResponse.getSamlAssertion(),SAML_SUBJECT_NAME_IDENTIFIER_XPATH); + + String gbTarget = session.getTarget(); + String oaURL = session.getPublicOAURLPrefix(); + boolean businessService = session.getBusinessService(); + +// XPathUtils.selectNodeList(createXMLSignatureResponse.getSamlAssertion(),SAML_SUBJECT_NAME_IDENTIFIER_XPATH); - SAMLAttribute[] samlattributes = createXMLSignatureResponse.getSamlAttributes(); + SAMLAttribute[] samlattributes = createXMLSignatureResponse.getSamlAttributes(); - boolean foundOA = false; - boolean foundGB = false; - for (int i = 0; i < samlattributes.length; i++) - { - if (samlattributes[i].getName().equals("Geschaeftsbereich")) - if (samlattributes[i].getNamespace().equals("http://reference.e-government.gv.at/namespace/moa/20020822#")) - - { - foundGB = true; - if (!gbTarget.equals(samlattributes[i].getValue())) - { - throw new ValidateException("validator.13", null); - } + boolean foundOA = false; + boolean foundGB = false; + boolean foundWBPK = false; + + for (int i = 0; i < samlattributes.length; i++) { + if (samlattributes[i].getName().equals("Geschaeftsbereich")) { + if (businessService) { + throw new ValidateException("validator.26", null); + } + if (samlattributes[i].getNamespace().equals("http://reference.e-government.gv.at/namespace/moa/20020822#")) { + foundGB = true; + if (!gbTarget.equals((String)samlattributes[i].getValue())) { + throw new ValidateException("validator.13", null); + } + } else { + throw new ValidateException("validator.12", null); + } + } + if (samlattributes[i].getName().equals("OA")) { + if (samlattributes[i].getNamespace().equals("http://reference.e-government.gv.at/namespace/moa/20020822#")) { + foundOA = true; + if (!oaURL.equals((String)samlattributes[i].getValue())) { // CHECKS für die AttributeVALUES fehlen noch + throw new ValidateException("validator.16", new Object[] {":gefunden wurde '" + oaURL + "', erwartet wurde '" + samlattributes[i].getValue()}); + } + } else { + throw new ValidateException("validator.15", null); + } + } + if (samlattributes[i].getName().equals("wbPK")) { + if (!businessService) { + throw new ValidateException("validator.27", null); + } + if (samlattributes[i].getNamespace().equals("http://reference.e-government.gv.at/namespace/moa/20020822#")) { + foundWBPK = true; + try { + Element attrValue = (Element)samlattributes[i].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(session.getIdentityLink().getIdentificationValue())) { + throw new ValidateException("validator.28", null); } - else throw new ValidateException("validator.12", null); - if (samlattributes[i].getName().equals("OA")) - if (samlattributes[i].getNamespace().equals("http://reference.e-government.gv.at/namespace/moa/20020822#")) - { - foundOA = true; - if (!oaURL.equals(samlattributes[i].getValue())) // CHECKS für die AttributeVALUES fehlen noch - { - throw new ValidateException("validator.16", new Object[] {":gefunden wurde '" + oaURL + "', erwartet wurde '" + samlattributes[i].getValue()}); - } - + if (!type.equals(session.getIdentityLink().getIdentificationType())) { + throw new ValidateException("validator.28", null); } - else throw new ValidateException("validator.15", null); - } - if (!foundOA) throw new ValidateException("validator.14", null); + } catch (Exception ex) { + throw new ValidateException("validator.29", null); + } + } else { + throw new ValidateException("validator.30", null); + } + } + } + + if (!foundOA) throw new ValidateException("validator.14", null); + if (businessService) { + if (!foundWBPK) throw new ValidateException("validator.31", null); + } else { if (!foundGB) throw new ValidateException("validator.11", null); + } //Check if dsig:Signature exists Element dsigSignature = (Element) XPathUtils.selectSingleNode(createXMLSignatureResponse.getSamlAssertion(),DSIG + "Signature"); diff --git a/id.server/src/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java b/id.server/src/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java index 5adbc5b3d..1127b3f43 100644 --- a/id.server/src/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java +++ b/id.server/src/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java @@ -11,6 +11,7 @@ import iaik.x509.X509Certificate; import at.gv.egovernment.moa.id.auth.data.IdentityLink; import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; import at.gv.egovernment.moa.id.util.MOAIDMessageProvider; +import at.gv.egovernment.moa.logging.Logger; /** * This class is used to validate an {@link VerifyXMLSignatureResponse} @@ -46,11 +47,15 @@ public class VerifyXMLSignatureResponseValidator { * @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 ignoreManifestValidationResult 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 */ - public void validate( - VerifyXMLSignatureResponse verifyXMLSignatureResponse, - String[] identityLinkSignersSubjectDNNames, String whatToCheck) + public void validate(VerifyXMLSignatureResponse verifyXMLSignatureResponse, + String[] identityLinkSignersSubjectDNNames, + String whatToCheck, + boolean ignoreManifestValidationResult) throws ValidateException { if (verifyXMLSignatureResponse.getSignatureCheckCode() != 0) @@ -74,9 +79,13 @@ public class VerifyXMLSignatureResponseValidator { else throw new ValidateException("validator.19", new Object[] { checkFailedReason } ); } - if (verifyXMLSignatureResponse.isXmlDSIGManigest()) - if (verifyXMLSignatureResponse.getXmlDSIGManifestCheckCode() != 0) - throw new ValidateException("validator.08", null); + 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 whether the returned X509 SubjectName is in the MOA-ID configuration or not if (identityLinkSignersSubjectDNNames != null) { String subjectDN = ""; diff --git a/id.server/src/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java b/id.server/src/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java index 53f763630..c399b72b7 100644 --- a/id.server/src/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java +++ b/id.server/src/at/gv/egovernment/moa/id/config/ConfigurationBuilder.java @@ -14,6 +14,7 @@ import java.util.Map; import org.w3c.dom.Attr; import org.w3c.dom.Element; +import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.traversal.NodeIterator; @@ -27,6 +28,8 @@ 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.FileUtils; +import at.gv.egovernment.moa.util.StringUtils; +import at.gv.egovernment.moa.util.XPathException; import at.gv.egovernment.moa.util.XPathUtils; /** @@ -73,7 +76,7 @@ public class ConfigurationBuilder { private static final String AUTH_BKU_XPATH = ROOT + CONF + "AuthComponent/" + CONF + "BKUSelection"; /** an XPATH-Expression */ - private static final String AUTH_SECLAYER_TRANSFORMS_INFO_FILENAME_XPATH = + public static final String AUTH_SECLAYER_TRANSFORMS_INFO_FILENAME_XPATH = ROOT + CONF + "AuthComponent/" + CONF + "SecurityLayer/" + CONF + "TransformsInfo/@filename"; /** an XPATH-Expression */ private static final String AUTH_MOA_SP_XPATH = @@ -102,6 +105,10 @@ public class ConfigurationBuilder { /** an XPATH-Expression */ private static final String OA_AUTH_COMPONENT_XPATH = CONF + "AuthComponent"; /** an XPATH-Expression */ + private static final String OA_AUTH_COMPONENT_IDENT_NUMBER_XPATH = CONF + "IdentificationNumber"; + /** an XPATH-Expression */ + private static final String OA_AUTH_COMPONENT_TRANSFORMS_INFO_FILENAME_XPATH = CONF + "TransformsInfo/@filename"; + /** an XPATH-Expression */ private static final String OA_PROXY_COMPONENT_XPATH = CONF + "ProxyComponent"; /** an XPATH-Expression */ private static final String OA_PROXY_COMPONENT_ABSOLUTE_XPATH = ROOT + CONF + "OnlineApplication/" + CONF + "ProxyComponent"; @@ -134,6 +141,9 @@ public class ConfigurationBuilder { private static final String OACONF_LOGIN_TYPE_XPATH = ROOTOA + CONF + "LoginType"; /** an XPATH-Expression */ + private static final String OACONF_BINDING_TYPE_XPATH = + ROOTOA + CONF + "Binding"; + /** an XPATH-Expression */ private static final String OACONF_PARAM_AUTH_PARAMETER_XPATH = ROOTOA + CONF + "ParamAuth/" + CONF + "Parameter"; /** an XPATH-Expression */ @@ -219,26 +229,50 @@ public class ConfigurationBuilder { /** * Build a string array with all filenames leading * to the Transforms Information for the Security Layer - * @return String[] of filenames to the Security Layer Transforms Information + * @param businessService <code>true</code> if the application is a + * business application, otherwise <code>false</code> + * @return String[] of filenames to the Security Layer Transforms Information + * or <code>null</code> if no transforms are included */ - public String[] buildTransformsInfoFileNames() { - + public String[] buildTransformsInfoFileNames(Node contextNode, String xpathExpr) { + List transformsInfoFileNames = new ArrayList(); - NodeIterator tiIter = - XPathUtils.selectNodeIterator( - getConfigElem(), - AUTH_SECLAYER_TRANSFORMS_INFO_FILENAME_XPATH); - Attr tiElem; - - while ((tiElem = (Attr) tiIter.nextNode()) != null) { - - String tiFileName = tiElem.getNodeValue(); - transformsInfoFileNames.add(tiFileName); + + try { + NodeIterator tiIter = XPathUtils.selectNodeIterator(contextNode, xpathExpr); + + Attr tiElem; + while ((tiElem = (Attr) tiIter.nextNode()) != null) { + String tiFileName = tiElem.getNodeValue(); + transformsInfoFileNames.add(tiFileName); + } + + String[] result = new String[transformsInfoFileNames.size()]; + transformsInfoFileNames.toArray(result); + + return result; + } catch (XPathException xpe) { + return new String[0]; } - String[] result = new String[transformsInfoFileNames.size()]; - transformsInfoFileNames.toArray(result); - - return result; + } + + + /** + * Loads the <code>transformsInfos</code> from files. + * @throws Exception on any exception thrown + */ + public String[] loadTransformsInfos(String[] transformsInfoFileNames) throws Exception { + + String[] transformsInfos = new String[transformsInfoFileNames.length]; + for (int i = 0; i < transformsInfoFileNames.length; i++) { + String fileURL = transformsInfoFileNames[i]; + + //if fileURL is relative to rootConfigFileDir make it absolute + fileURL = FileUtils.makeAbsoluteURL(fileURL, rootConfigFileDir); + String transformsInfo = FileUtils.readURL(fileURL, DEFAULT_ENCODING); + transformsInfos[i] = transformsInfo; + } + return transformsInfos; } /** @@ -311,6 +345,7 @@ public class ConfigurationBuilder { return result; } + /** * Return a string array containing all X509 Subject Names * of the Identity Link Signers @@ -343,7 +378,7 @@ public class ConfigurationBuilder { * with all relevant information for the authentication component of the online * application */ - public OAAuthParameter[] buildOnlineApplicationAuthParameters() { + public OAAuthParameter[] buildOnlineApplicationAuthParameters() throws ConfigurationException { List OA_set = new ArrayList(); NodeList OAIter = XPathUtils.selectNodeList(getConfigElem(), OA_XPATH); @@ -354,16 +389,60 @@ public class ConfigurationBuilder { (Element) XPathUtils.selectSingleNode(oAElem, OA_AUTH_COMPONENT_XPATH); OAAuthParameter oap = new OAAuthParameter(); - oap.setPublicURLPrefix(oAElem.getAttribute("publicURLPrefix")); + String publicURLPrefix = oAElem.getAttribute("publicURLPrefix"); + oap.setPublicURLPrefix(publicURLPrefix); oap.setKeyBoxIdentier(oAElem.getAttribute("keyBoxIdentifier")); + // get the type of the online application + String oaType = oAElem.getAttribute("type"); + oap.setOaType(oaType); + String slVersion = "1.1"; + if ("businessService".equalsIgnoreCase(oaType)) { + if (authComponent==null) { + Logger.error("Missing \"AuthComponent\" for OA of type \"businessService\""); + throw new ConfigurationException("config.02", null); + } + Element identificationNumberElem = + (Element) XPathUtils.selectSingleNode(authComponent, OA_AUTH_COMPONENT_IDENT_NUMBER_XPATH); + if (identificationNumberElem==null) { + Logger.error("Missing \"IdentificationNumber\" for OA of type \"businessService\""); + throw new ConfigurationException("config.02", null); + } + Element identificationNumberChild = DOMUtils.getElementFromNodeList(identificationNumberElem.getChildNodes()); + if (identificationNumberChild == null) { + Logger.error("Missing \"IdentificationNumber\" for OA of type \"businessService\""); + throw new ConfigurationException("config.02", null); + } + oap.setIdentityLinkDomainIdentifier(buildIdentityLinkDomainIdentifier(identificationNumberChild)); + + // if OA type is "businessSErvice" set slVersion to 1.2 and ignore parameter in config file + Logger.info("OA type is \"businessService\"; setting Security Layer version to 1.2"); + slVersion = "1.2"; + + } else { + + if (authComponent!=null) { + slVersion = authComponent.getAttribute("slVersion"); + } + + } + oap.setSlVersion(slVersion); //Check if there is an Auth-Block to read from configuration + if (authComponent!=null) { oap.setProvideStammzahl(BoolUtils.valueOf(authComponent.getAttribute("provideStammzahl"))); oap.setProvideAuthBlock(BoolUtils.valueOf(authComponent.getAttribute("provideAUTHBlock"))); oap.setProvideIdentityLink(BoolUtils.valueOf(authComponent.getAttribute("provideIdentityLink"))); - } + oap.setProvideCertificate(BoolUtils.valueOf(authComponent.getAttribute("provideCertificate"))); + // load OA specific transforms if present + String[] transformsInfoFileNames = buildTransformsInfoFileNames(authComponent, OA_AUTH_COMPONENT_TRANSFORMS_INFO_FILENAME_XPATH); + try { + oap.setTransformsInfos(loadTransformsInfos(transformsInfoFileNames)); + } catch (Exception ex) { + Logger.error("Error loading transforms specified for OA \"" + publicURLPrefix + "\"; using default transforms."); + } + } OA_set.add(oap); } OAAuthParameter[] result = @@ -438,6 +517,7 @@ public class ConfigurationBuilder { OAProxyParameter oap = new OAProxyParameter(); oap.setPublicURLPrefix(oAElem.getAttribute("publicURLPrefix")); + oap.setOaType(oAElem.getAttribute("type")); Element proxyComponentElem = (Element) XPathUtils.selectSingleNode(oAElem,OA_PROXY_COMPONENT_XPATH); if (proxyComponentElem != null) { oap.setConfigFileURL(XPathUtils.getAttributeValue(oAElem, OA_PROXY_URL_XPATH, null)); @@ -503,8 +583,12 @@ public class ConfigurationBuilder { OAConfiguration oaConfiguration = new OAConfiguration(); //The LoginType hast to be "stateless" or "stateful" to be valid + oaConfiguration.setLoginType( XPathUtils.getElementValue(root, OACONF_LOGIN_TYPE_XPATH, null)); + + oaConfiguration.setBinding( + XPathUtils.getElementValue(root, OACONF_BINDING_TYPE_XPATH, OAConfiguration.BINDUNG_FULL)); //Try to build the Parameter Auth Parameters NodeIterator paramAuthIter = @@ -672,6 +756,44 @@ public class ConfigurationBuilder { return ChainingModes.CHAIN_MODE; } } + + /** + * Builds the IdentityLinkDomainIdentifier as needed for providing it to the + * SecurityLayer for computation of the wbPK. + * <p>e.g.:<br> + * input element: + * <br> + * <code><pr:Firmenbuchnummer shortForm="FN">000468 i</pr:Firmenbuchnummer></code> + * <p> + * return value: <code>urn:publicid:gv.at+wbpk+FN468i</code> + * + * @param number The element holding the identification number of the business + * company. + * @return + */ + private String buildIdentityLinkDomainIdentifier(Element number) { + if (number == null) { + return null; + } + String identificationNumber = number.getFirstChild().getNodeValue(); + // remove all blanks + identificationNumber = StringUtils.removeBlanks(identificationNumber); + if (number.getLocalName().equals("Firmenbuchnummer")) { + // delete zeros from the beginning of the number + identificationNumber = StringUtils.deleteLeadingZeros(identificationNumber); + // remove hyphens + identificationNumber = StringUtils.removeToken(identificationNumber, "-"); + } + StringBuffer identityLinkDomainIdentifier = new StringBuffer(Constants.URN_PREFIX_WBPK); + identityLinkDomainIdentifier.append("+"); + String shortForm = number.getAttribute("ShortForm"); + if (!identificationNumber.startsWith(shortForm)) { + identityLinkDomainIdentifier.append(shortForm); + } + identityLinkDomainIdentifier.append("+"); + identityLinkDomainIdentifier.append(identificationNumber); + return identityLinkDomainIdentifier.toString(); + } /** * Method warn. diff --git a/id.server/src/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java b/id.server/src/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java index a722868e0..d354ba910 100644 --- a/id.server/src/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java +++ b/id.server/src/at/gv/egovernment/moa/id/config/auth/AuthConfigurationProvider.java @@ -88,12 +88,14 @@ public class AuthConfigurationProvider extends ConfigurationProvider { * multiple files can be given for different mime types */ private String[] transformsInfoFileNames; + /** * transformations for rendering in the secure viewer of the security layer implementation, * read from {@link transformsInfoFileNames}; * multiple transformation can be given for different mime types */ private String[] transformsInfos; + /** * parameters for connection to MOA SP component */ @@ -218,8 +220,8 @@ public class AuthConfigurationProvider extends ConfigurationProvider { bKUSelectable = (bKUConnectionParameter!=null); bKUSelectionType = builder.buildAuthBKUSelectionType(); genericConfiguration = builder.buildGenericConfiguration(); - transformsInfoFileNames = builder.buildTransformsInfoFileNames(); - loadTransformsInfos(); + transformsInfoFileNames = builder.buildTransformsInfoFileNames(builder.getConfigElem(), ConfigurationBuilder.AUTH_SECLAYER_TRANSFORMS_INFO_FILENAME_XPATH); + transformsInfos = builder.loadTransformsInfos(transformsInfoFileNames); moaSpConnectionParameter = builder.buildMoaSpConnectionParameter(); moaSpIdentityLinkTrustProfileID = builder.getMoaSpIdentityLinkTrustProfileID(); moaSpAuthBlockTrustProfileID = builder.getMoaSpAuthBlockTrustProfileID(); @@ -229,9 +231,9 @@ public class AuthConfigurationProvider extends ConfigurationProvider { defaultChainingMode = builder.getDefaultChainingMode(); chainingModes = builder.buildChainingModes(); trustedCACertificates = builder.getTrustedCACertificates(); - trustedCACertificates = FileUtils.makeAbsoluteURL(trustedCACertificates, rootConfigFileDir); } + trustedCACertificates = FileUtils.makeAbsoluteURL(trustedCACertificates, rootConfigFileDir); - catch (Throwable t) { + } catch (Throwable t) { throw new ConfigurationException("config.02", null, t); } } @@ -240,17 +242,35 @@ public class AuthConfigurationProvider extends ConfigurationProvider { * Loads the <code>transformsInfos</code> from files. * @throws Exception on any exception thrown */ - private void loadTransformsInfos() throws Exception { - - transformsInfos = new String[transformsInfoFileNames.length]; - for (int i = 0; i < transformsInfoFileNames.length; i++) { - String fileURL = transformsInfoFileNames[i]; +// private void loadTransformsInfos() throws Exception { +// +// transformsInfos = new String[transformsInfoFileNames.length]; +// for (int i = 0; i < transformsInfoFileNames.length; i++) { +// String fileURL = transformsInfoFileNames[i]; +// +// //if fileURL is relative to rootConfigFileDir make it absolute +// fileURL = FileUtils.makeAbsoluteURL(fileURL, rootConfigFileDir); +// String transformsInfo = FileUtils.readURL(fileURL, DEFAULT_ENCODING); +// transformsInfos[i] = transformsInfo; +// } +// } + + /** + * Loads the <code>transformsInfos</code> from files. + * @throws Exception on any exception thrown + */ + private String[] loadTransformsInfos(String[] transformsInfoFileNames) throws Exception { + + String[] transformsInfos = new String[transformsInfoFileNames.length]; + for (int i = 0; i < transformsInfoFileNames.length; i++) { + String fileURL = transformsInfoFileNames[i]; - //if fileURL is relative to rootConfigFileDir make it absolute - fileURL = FileUtils.makeAbsoluteURL(fileURL, rootConfigFileDir); - String transformsInfo = FileUtils.readURL(fileURL, DEFAULT_ENCODING); - transformsInfos[i] = transformsInfo; - } + //if fileURL is relative to rootConfigFileDir make it absolute + fileURL = FileUtils.makeAbsoluteURL(fileURL, rootConfigFileDir); + String transformsInfo = FileUtils.readURL(fileURL, DEFAULT_ENCODING); + transformsInfos[i] = transformsInfo; + } + return transformsInfos; } /** * Return a string array with all filenames leading diff --git a/id.server/src/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java b/id.server/src/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java index 223abc632..ad4dd4b62 100644 --- a/id.server/src/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java +++ b/id.server/src/at/gv/egovernment/moa/id/config/auth/OAAuthParameter.java @@ -1,5 +1,7 @@ package at.gv.egovernment.moa.id.config.auth; +import at.gv.egovernment.moa.id.config.OAParameter; + /** * Configuration parameters belonging to an online application, * to use with the MOA ID Auth component. @@ -7,17 +9,32 @@ package at.gv.egovernment.moa.id.config.auth; * @author Stefan Knirsch * @version $Id$ */ -public class OAAuthParameter { - - /** - * public URL prefix of the online application - */ - private String publicURLPrefix; - +public class OAAuthParameter extends OAParameter { + /** + * Sercurity Layer version + */ + private String slVersion; + /** + * true, if the Security Layer version is version 1.2, otherwise false + */ + private boolean slVersion12; + /** + * identityLinkDomainIdentifier + * (e.g <code>urn:publicid:gv.at+wbpk+FN468i</code> for a "Firmenbuchnummer") + * <br> + * only used within a business application context for providing it to the + * security layer as input for wbPK computation + */ + private String identityLinkDomainIdentifier; /** * key box Identifier (e.g. CertifiedKeypair, SecureSignatureKeypair) */ private String keyBoxIdentifier; + /** + * transformations for rendering in the secure viewer of the security layer + * implementation; multiple transformation can be given for different mime types + */ + private String[] transformsInfos; /** * determines whether "Stammzahl" is to be included in the authentication data */ @@ -30,7 +47,45 @@ public class OAAuthParameter { * determines whether identity link is to be included in the authentication data */ private boolean provideIdentityLink; - + /** + * determines whether the certificate is to be included in the authentication data + */ + private boolean provideCertificate; + + /** + * Returns <code>true</code> if the Security Layer version is version 1.2, + * otherwise <code>false</code>. + * @return <code>true</code> if the Security Layer version is version 1.2, + * otherwise <code>false</code> + */ + public boolean getSlVersion12() { + return slVersion12; + } + + /** + * Returns the security layer version. + * @return the security layer version. + */ + public String getSlVersion() { + return slVersion; + } + + /** + * Returns the identityLinkDomainIdentifier. + * @return the identityLinkDomainIdentifier. + */ + public String getIdentityLinkDomainIdentifier() { + return identityLinkDomainIdentifier; + } + + /** + * Returns the transformsInfos. + * @return the transformsInfos. + */ + public String[] getTransformsInfos() { + return transformsInfos; + } + /** * Returns the provideAuthBlock. * @return String @@ -54,15 +109,17 @@ public class OAAuthParameter { public boolean getProvideStammzahl() { return provideStammzahl; } - + /** - * Returns the publicURLPrefix. - * @return String + * Returns <code>true</code> if the certificate should be provided within the + * authentication data, otherwise <code>false</code>. + * @return <code>true</code> if the certificate should be provided, + * otherwise <code>false</code> */ - public String getPublicURLPrefix() { - return publicURLPrefix; + public boolean getProvideCertifcate() { + return provideCertificate; } - + /** * Returns the key box identifier. * @return String @@ -70,7 +127,32 @@ public class OAAuthParameter { public String getKeyBoxIdentifier() { return keyBoxIdentifier; } - + /** + * Sets the security layer version. + * Also sets {@link slVersion12} to <code>true</code> if the Security Layer + * version is 1.2. + * @param the security layer version to be used. + */ + public void setSlVersion(String slVersion) { + this.slVersion = slVersion; + if ("1.2".equals(slVersion)) { + this.slVersion12 = true; + } + } + /** + * Sets the IdentityLinkDomainIdentifier. + * @param the IdentityLinkDomainIdentifiern number of the online application. + */ + public void setIdentityLinkDomainIdentifier(String identityLinkDomainIdentifier) { + this.identityLinkDomainIdentifier = identityLinkDomainIdentifier; + } + /** + * Sets the transformsInfos. + * @param the transformsInfos to be used. + */ + public void setTransformsInfos(String[] transformsInfos) { + this.transformsInfos = transformsInfos; + } /** * Sets the provideAuthBlock. * @param provideAuthBlock The provideAuthBlock to set @@ -94,13 +176,13 @@ public class OAAuthParameter { public void setProvideStammzahl(boolean provideStammzahl) { this.provideStammzahl = provideStammzahl; } - + /** - * Sets the publicURLPrefix. - * @param publicURLPrefix The publicURLPrefix to set + * Sets the provideCertificate variable. + * @param provideCertificate The provideCertificate value to set */ - public void setPublicURLPrefix(String publicURLPrefix) { - this.publicURLPrefix = publicURLPrefix; + public void setProvideCertificate(boolean provideCertificate) { + this.provideCertificate = provideCertificate; } /** diff --git a/id.server/src/at/gv/egovernment/moa/id/config/proxy/OAConfiguration.java b/id.server/src/at/gv/egovernment/moa/id/config/proxy/OAConfiguration.java index c9a13fee5..ef7c7e323 100644 --- a/id.server/src/at/gv/egovernment/moa/id/config/proxy/OAConfiguration.java +++ b/id.server/src/at/gv/egovernment/moa/id/config/proxy/OAConfiguration.java @@ -27,6 +27,14 @@ public class OAConfiguration { /** Constant for an auth method */ public static final String PARAM_AUTH = "param"; + + /** Constant for binding */ + public static final String BINDUNG_USERNAME = "userName"; + /** Constant for binding */ + public static final String BINDUNG_FULL = "full"; + /** Constant for binding */ + public static final String BINDUNG_NONE = "none"; + /** login type: stateful or stateless */ String loginType; /** authentication type: basic, header, or param */ @@ -45,6 +53,8 @@ public class OAConfiguration { String basicAuthUserIDMapping; /** mapping for password to be used in case of authentication type <code>"basic-auth"</code> */ String basicAuthPasswordMapping; + /** Binding for basic authentication */ + String binding; /** * Returns the basicAuthPasswordMapping. @@ -87,6 +97,14 @@ public class OAConfiguration { } /** + * Returns the binding. + * @return String + */ + public String getBinding() { + return binding; + } + + /** * Sets the basicAuthPasswordMapping. * @param basicAuthPasswordMapping The basicAuthPasswordMapping to set */ @@ -141,5 +159,13 @@ public class OAConfiguration { public void setAuthType(String authLoginType) { this.authType = authLoginType; } + + /** + * Sets the binding. + * @param binding The binding to be set. + */ + public void setBinding (String binding) { + this.binding = binding; + } } diff --git a/id.server/src/at/gv/egovernment/moa/id/config/proxy/OAProxyParameter.java b/id.server/src/at/gv/egovernment/moa/id/config/proxy/OAProxyParameter.java index a16dcfa26..12b16c115 100644 --- a/id.server/src/at/gv/egovernment/moa/id/config/proxy/OAProxyParameter.java +++ b/id.server/src/at/gv/egovernment/moa/id/config/proxy/OAProxyParameter.java @@ -1,6 +1,7 @@ package at.gv.egovernment.moa.id.config.proxy; import at.gv.egovernment.moa.id.config.ConnectionParameter; +import at.gv.egovernment.moa.id.config.OAParameter; /** * Configuration parameters belonging to an online application, @@ -9,12 +10,12 @@ import at.gv.egovernment.moa.id.config.ConnectionParameter; * @author Stefan Knirsch * @version $Id$ */ -public class OAProxyParameter { +public class OAProxyParameter extends OAParameter { - /** - * public URL prefix of the online application - */ - private String publicURLPrefix; +// /** +// * public URL prefix of the online application +// */ +// private String publicURLPrefix; /** * URL of online application configuration file; * defaults to relative URL <code>/moaconfig.xml</code> @@ -100,21 +101,21 @@ public class OAProxyParameter { this.connectionParameter = proxyConnectionParameter; } - /** - * Returns the publicURLPrefix. - * @return String - */ - public String getPublicURLPrefix() { - return publicURLPrefix; - } - - /** - * Sets the publicURLPrefix. - * @param publicURLPrefix The publicURLPrefix to set - */ - public void setPublicURLPrefix(String url) { - this.publicURLPrefix = url; - } +// /** +// * Returns the publicURLPrefix. +// * @return String +// */ +// public String getPublicURLPrefix() { +// return publicURLPrefix; +// } +// +// /** +// * Sets the publicURLPrefix. +// * @param publicURLPrefix The publicURLPrefix to set +// */ +// public void setPublicURLPrefix(String url) { +// this.publicURLPrefix = url; +// } /** * Returns the connectionBuilderImpl. diff --git a/id.server/src/at/gv/egovernment/moa/id/data/AuthenticationData.java b/id.server/src/at/gv/egovernment/moa/id/data/AuthenticationData.java index 65fe9047d..8e0f3cbcf 100644 --- a/id.server/src/at/gv/egovernment/moa/id/data/AuthenticationData.java +++ b/id.server/src/at/gv/egovernment/moa/id/data/AuthenticationData.java @@ -44,6 +44,10 @@ public class AuthenticationData { */ private String bPK; /** + * private sector-specific personal identifier (wbPK) + */ + private String wbPK; + /** * given name of the user */ private String givenName; @@ -68,6 +72,14 @@ public class AuthenticationData { */ private String publicAuthorityCode; /** + * The base64 encoded signer certificate. + */ + private String signerCertificate; + /** + * URL of the BKU + */ + private String bkuURL; + /** * the corresponding <code>lt;saml:Assertion></code> */ private String samlAssertion; @@ -122,6 +134,14 @@ public class AuthenticationData { public String getPBK() { return bPK; } + + /** + * Returns the wbPK. + * @return String the wbPK. + */ + public String getWPBK() { + return wbPK; + } /** * Sets the minorVersion. @@ -162,6 +182,14 @@ public class AuthenticationData { public void setPBK(String bPK) { this.bPK = bPK; } + + /** + * Sets the wbPK. + * @param wbPK The wbPK to set + */ + public void setWPBK(String wbPK) { + this.wbPK = wbPK; + } /** * Returns the assertionID. @@ -234,6 +262,22 @@ public class AuthenticationData { public int getMajorVersion() { return majorVersion; } + + /** + * Returns the BKU URL. + * @return String + */ + public String getBkuURL() { + return bkuURL; + } + + /** + * Returns the signer certificate. + * @return String + */ + public String getSignerCertificate() { + return signerCertificate; + } /** * Sets the assertionID. @@ -306,6 +350,22 @@ public class AuthenticationData { public void setMajorVersion(int majorVersion) { this.majorVersion = majorVersion; } + + /** + * Sets the bkuURL + * @param url The BKU URL to set + */ + public void setBkuURL(String url) { + this.bkuURL = url; + } + + /** + * Sets the signer certificate + * @param url The signer certificate + */ + public void setSignerCertificate(String signerCertificate) { + this.signerCertificate = signerCertificate; + } /** * Returns the samlAssertion. diff --git a/id.server/src/at/gv/egovernment/moa/id/proxy/parser/AuthenticationDataAssertionParser.java b/id.server/src/at/gv/egovernment/moa/id/proxy/parser/AuthenticationDataAssertionParser.java index a78a8d587..9bbf13aca 100644 --- a/id.server/src/at/gv/egovernment/moa/id/proxy/parser/AuthenticationDataAssertionParser.java +++ b/id.server/src/at/gv/egovernment/moa/id/proxy/parser/AuthenticationDataAssertionParser.java @@ -3,6 +3,7 @@ package at.gv.egovernment.moa.id.proxy.parser; import org.w3c.dom.Element; import at.gv.egovernment.moa.id.ParseException; +import at.gv.egovernment.moa.id.auth.builder.BPKBuilder; import at.gv.egovernment.moa.id.data.AuthenticationData; import at.gv.egovernment.moa.util.BoolUtils; import at.gv.egovernment.moa.util.Constants; @@ -40,10 +41,12 @@ public class AuthenticationDataAssertionParser implements Constants { private static String ATTRIBUTESTATEMENT_XPATH = SAML + "AttributeStatement/"; /** Prefix for Element NameIdentifier in an Xpath-expression */ - private static String BPK_XPATH = + private static String PK_XPATH = ATTRIBUTESTATEMENT_XPATH + SAML + "Subject/" + SAML + "NameIdentifier"; + private static String NAME_QUALIFIER_XPATH = + PK_XPATH + "/@NameQualifier"; /** Prefix for Element Person in an Xpath-expression */ private static String PERSONDATA_XPATH = ATTRIBUTESTATEMENT_XPATH + @@ -59,7 +62,6 @@ public class AuthenticationDataAssertionParser implements Constants { PERSONDATA_XPATH + PR + "Identification/" + PR + "Type"; - /** Prefix for Element GivenName in an Xpath-expression */ private static String GIVEN_NAME_XPATH = PERSONDATA_XPATH + @@ -117,8 +119,12 @@ public class AuthenticationDataAssertionParser implements Constants { XPathUtils.getAttributeValue(samlAssertion, ISSUER_XPATH, "")); authData.setIssueInstant( XPathUtils.getAttributeValue(samlAssertion, ISSUE_INSTANT_XPATH, "")); - authData.setPBK( - XPathUtils.getElementValue(samlAssertion, BPK_XPATH, "")); + String pkValue = XPathUtils.getElementValue(samlAssertion, PK_XPATH, ""); + if (XPathUtils.getAttributeValue(samlAssertion, NAME_QUALIFIER_XPATH, "").equalsIgnoreCase(URN_PREFIX_BPK)) { + authData.setPBK(pkValue); + } else { + authData.setWPBK(pkValue); + } authData.setIdentificationValue( XPathUtils.getElementValue(samlAssertion, IDENTIFICATION_VALUE_XPATH, "")); authData.setIdentificationType( diff --git a/id.server/src/at/gv/egovernment/moa/id/proxy/servlet/ProxyServlet.java b/id.server/src/at/gv/egovernment/moa/id/proxy/servlet/ProxyServlet.java index f82ad93ed..7b077ebd9 100644 --- a/id.server/src/at/gv/egovernment/moa/id/proxy/servlet/ProxyServlet.java +++ b/id.server/src/at/gv/egovernment/moa/id/proxy/servlet/ProxyServlet.java @@ -79,7 +79,8 @@ public class ProxyServlet extends HttpServlet { Logger.debug("getRequestURL:" + req.getRequestURL().toString()); try { - if (req.getParameter(PARAM_SAMLARTIFACT) != null && req.getParameter(PARAM_TARGET) != null) { +// if (req.getParameter(PARAM_SAMLARTIFACT) != null && req.getParameter(PARAM_TARGET) != null) { + if (req.getParameter(PARAM_SAMLARTIFACT) != null) { // check if SAML Artifact was already used in this session (in case of page reload) HttpSession session = req.getSession(); diff --git a/id.server/src/test/abnahme/A/Test200VerifyIdentityLink.java b/id.server/src/test/abnahme/A/Test200VerifyIdentityLink.java index ed4410521..c3325349d 100644 --- a/id.server/src/test/abnahme/A/Test200VerifyIdentityLink.java +++ b/id.server/src/test/abnahme/A/Test200VerifyIdentityLink.java @@ -39,7 +39,7 @@ public class Test200VerifyIdentityLink extends AbnahmeTestCase { Element domVerifyXMLSignatureResponse = new SignatureVerificationInvoker().verifyXMLSignature(domVerifyXMLSignatureRequest); VerifyXMLSignatureResponseParser respParser = new VerifyXMLSignatureResponseParser(domVerifyXMLSignatureResponse); - VerifyXMLSignatureResponseValidator.getInstance().validate(respParser.parseData(), AuthConfigurationProvider.getInstance().getIdentityLinkX509SubjectNames(), VerifyXMLSignatureResponseValidator.CHECK_IDENTITY_LINK); + VerifyXMLSignatureResponseValidator.getInstance().validate(respParser.parseData(), AuthConfigurationProvider.getInstance().getIdentityLinkX509SubjectNames(), VerifyXMLSignatureResponseValidator.CHECK_IDENTITY_LINK, true); /* * HINWEIS: clearSamlAssertion löscht aus einer beliebiegen String-Repräsentation einer XML-Struktur @@ -320,7 +320,7 @@ public class Test200VerifyIdentityLink extends AbnahmeTestCase { // String createXMLSignatureResponse = readFile(TESTDATA_ROOT + "xmldata/standard/"+"CreateXMLSignatureResponse.xml"); // String samlArtifact = server.verifyAuthenticationBlock(sessionID, createXMLSignatureResponse); try { - VerifyXMLSignatureResponseValidator.getInstance().validate(respParser.parseData(), new String[] { "CN=TEST,OU=TEST,O=TEST,C=AT" }, VerifyXMLSignatureResponseValidator.CHECK_IDENTITY_LINK); + VerifyXMLSignatureResponseValidator.getInstance().validate(respParser.parseData(), new String[] { "CN=TEST,OU=TEST,O=TEST,C=AT" }, VerifyXMLSignatureResponseValidator.CHECK_IDENTITY_LINK, true); System.err.println(this.getName() + " hat KEINE FEHLER geworfen"); fail(this.getName() + " hat KEINE FEHLER geworfen"); } diff --git a/id.server/src/test/abnahme/A/Test300VerifyAuthBlock.java b/id.server/src/test/abnahme/A/Test300VerifyAuthBlock.java index de4fe8fbf..c7ee57f09 100644 --- a/id.server/src/test/abnahme/A/Test300VerifyAuthBlock.java +++ b/id.server/src/test/abnahme/A/Test300VerifyAuthBlock.java @@ -534,7 +534,7 @@ public class Test300VerifyAuthBlock extends AbnahmeTestCase { CreateXMLSignatureResponse csresp = new CreateXMLSignatureResponseParser(createXMLSignatureResponse).parseResponse(); // validates <CreateXMLSignatureResponse> - new CreateXMLSignatureResponseValidator().validate(csresp, session.getTarget(), session.getPublicOAURLPrefix()); + new CreateXMLSignatureResponseValidator().validate(csresp, session); // builds a <VerifyXMLSignatureRequest> for a MOA-SPSS call String[] vtids = authConf.getMoaSpAuthBlockVerifyTransformsInfoIDs(); String tpid = authConf.getMoaSpAuthBlockTrustProfileID(); @@ -544,7 +544,7 @@ public class Test300VerifyAuthBlock extends AbnahmeTestCase { // parses the <VerifyXMLSignatureResponse> VerifyXMLSignatureResponse vsresp = new VerifyXMLSignatureResponseParser(domVsresp).parseData(); // validates the <VerifyXMLSignatureResponse> - VerifyXMLSignatureResponseValidator.getInstance().validate(vsresp, null, VerifyXMLSignatureResponseValidator.CHECK_AUTH_BLOCK); + VerifyXMLSignatureResponseValidator.getInstance().validate(vsresp, null, VerifyXMLSignatureResponseValidator.CHECK_AUTH_BLOCK, true); // compares the public keys from the identityLink with the AuthBlock // builds authentication data and stores it together with a SAML artifact @@ -583,7 +583,7 @@ public class Test300VerifyAuthBlock extends AbnahmeTestCase { oaParam.getProvideIdentityLink() ? DOMUtils.serializeNode(identityLink.getSamlAssertion()) : ""; String authBlock = oaParam.getProvideAuthBlock() ? session.getAuthBlock() : ""; String samlAssertion = new AuthenticationDataAssertionBuilder().build( - authData, prPerson, authBlock, ilAssertion); + authData, prPerson, authBlock, ilAssertion, session.getBkuURL(), "", false); authData.setSamlAssertion(samlAssertion); return authData; } diff --git a/id.server/src/test/abnahme/A/Test400GetAuthenticationData.java b/id.server/src/test/abnahme/A/Test400GetAuthenticationData.java index b05e2b92c..e265905b8 100644 --- a/id.server/src/test/abnahme/A/Test400GetAuthenticationData.java +++ b/id.server/src/test/abnahme/A/Test400GetAuthenticationData.java @@ -4,7 +4,9 @@ import org.w3c.dom.Element; import test.abnahme.AbnahmeTestCase; import at.gv.egovernment.moa.id.AuthenticationException; +import at.gv.egovernment.moa.id.auth.AuthenticationServer; import at.gv.egovernment.moa.id.auth.builder.VerifyXMLSignatureRequestBuilder; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession; import at.gv.egovernment.moa.id.auth.data.IdentityLink; import at.gv.egovernment.moa.id.auth.invoke.SignatureVerificationInvoker; import at.gv.egovernment.moa.id.auth.parser.CreateXMLSignatureResponseParser; @@ -30,6 +32,7 @@ public class Test400GetAuthenticationData extends AbnahmeTestCase { protected void setUp() throws Exception { super.setUp(); String sessionID = startAuthentication(); + AuthenticationSession session = AuthenticationServer.getSession(sessionID); String infoboxReadResponse = readXmldata("InfoBoxReadResponse.xml"); server.verifyIdentityLink(sessionID, infoboxReadResponse); InfoboxReadResponseParser irrp = new InfoboxReadResponseParser(infoboxReadResponse); @@ -40,7 +43,7 @@ public class Test400GetAuthenticationData extends AbnahmeTestCase { //VerifyXMLSignatureResponseValidator.getInstance().validate(respParser.parseData(), AuthConfigurationProvider.getInstance().getIdentityLinkX509SubjectNames()); // System.out.println(createXMLSignatureRequest); String createXMLSignatureResponse = readXmldata("CreateXMLSignatureResponse.xml"); - CreateXMLSignatureResponseValidator.getInstance().validate(new CreateXMLSignatureResponseParser(createXMLSignatureResponse).parseResponse(), "gb", "https://localhost:9443/"); + CreateXMLSignatureResponseValidator.getInstance().validate(new CreateXMLSignatureResponseParser(createXMLSignatureResponse).parseResponse(), session); samlArtifact = server.verifyAuthenticationBlock(sessionID, createXMLSignatureResponse); } diff --git a/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/AllTests.java b/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/AllTests.java index 77dff29aa..2940f0ec7 100644 --- a/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/AllTests.java +++ b/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/AllTests.java @@ -13,12 +13,12 @@ public class AllTests { public static Test suite() { TestSuite suite = new TestSuite(); - suite.addTestSuite(AuthenticationBlockAssertionBuilderTest.class); +// suite.addTestSuite(AuthenticationBlockAssertionBuilderTest.class); suite.addTestSuite(CreateXMLSignatureBuilderTest.class); - suite.addTestSuite(GetIdentityLinkFormBuilderTest.class); - suite.addTestSuite(InfoboxReadRequestBuilderTest.class); - suite.addTestSuite(PersonDataBuilderTest.class); - suite.addTestSuite(SAMLArtifactBuilderTest.class); +// suite.addTestSuite(GetIdentityLinkFormBuilderTest.class); +// suite.addTestSuite(InfoboxReadRequestBuilderTest.class); +// suite.addTestSuite(PersonDataBuilderTest.class); +// suite.addTestSuite(SAMLArtifactBuilderTest.class); return suite; } diff --git a/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilderTest.java b/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilderTest.java index 0cc15e5da..fa67fa44f 100644 --- a/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilderTest.java +++ b/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/AuthenticationBlockAssertionBuilderTest.java @@ -39,7 +39,7 @@ public class AuthenticationBlockAssertionBuilderTest extends UnitTestCase { public void testBuild() throws Exception { AuthenticationBlockAssertionBuilder builder = new AuthenticationBlockAssertionBuilder(); - String assertionBuilt = builder.build(ISSUER, ISSUE_INSTANT, AUTH_URL, TARGET, OA_URL, GEB_DAT); + String assertionBuilt = builder.buildAuthBlock(ISSUER, ISSUE_INSTANT, AUTH_URL, TARGET, "", "", OA_URL, GEB_DAT); assertionBuilt = XML_DECL + assertionBuilt; String assertionShould = XML_DECL + ASSERTION_SHOULD; assertXmlEquals(assertionShould, assertionBuilt); diff --git a/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureBuilderTest.java b/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureBuilderTest.java index ebc61e5c4..1f4890dc9 100644 --- a/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureBuilderTest.java +++ b/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/CreateXMLSignatureBuilderTest.java @@ -44,15 +44,62 @@ TRANSFORMS_INFO + " <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 { - String request = new CreateXMLSignatureRequestBuilder().build( + // test build for Security Layer version 1.1 and 1.0 + String request = new CreateXMLSignatureRequestBuilder().build( AuthenticationBlockAssertionBuilderTest.ASSERTION_SHOULD, "SecureSignatureKeypair", - new String[] {TRANSFORMS_INFO}); + 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/src/test/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilderTest.java b/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilderTest.java index 9142a8e42..af452dc78 100644 --- a/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilderTest.java +++ b/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/GetIdentityLinkFormBuilderTest.java @@ -49,9 +49,9 @@ public class GetIdentityLinkFormBuilderTest extends TestCase { "http://localhost:3495/http-security-layer-request"; public void testBuild() throws Exception { - String xmlRequest = new InfoboxReadRequestBuilder().build(); + String xmlRequest = new InfoboxReadRequestBuilder().build(false, false, null); String dataURL = "https://1.2.3.4/auth/VerifyIdentityLink?MOASessionID=1234567"; - String infoRequest = new CertInfoVerifyXMLSignatureRequestBuilder().build(); + String infoRequest = new CertInfoVerifyXMLSignatureRequestBuilder().build(false); 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); String formShould = MessageFormat.format( @@ -59,9 +59,9 @@ public class GetIdentityLinkFormBuilderTest extends TestCase { assertEquals(formShould, form); } public void testBuildCustomBKU() throws Exception { - String xmlRequest = new InfoboxReadRequestBuilder().build(); + String xmlRequest = new InfoboxReadRequestBuilder().build(false, false, null); String dataURL = "https://1.2.3.4/auth/AuthServlet/StartAuthentication?MOASessionID=1234567"; - String infoRequest = new CertInfoVerifyXMLSignatureRequestBuilder().build(); + String infoRequest = new CertInfoVerifyXMLSignatureRequestBuilder().build(false); 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); diff --git a/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilderTest.java b/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilderTest.java index b65fc9ecf..24d01f96f 100644 --- a/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilderTest.java +++ b/id.server/src/test/at/gv/egovernment/moa/id/auth/builder/InfoboxReadRequestBuilderTest.java @@ -19,7 +19,7 @@ public class InfoboxReadRequestBuilderTest extends UnitTestCase implements Const public void testBuild() throws Exception { InfoboxReadRequestBuilder builder = new InfoboxReadRequestBuilder(); - String xmlBuilt = builder.build(); + String xmlBuilt = builder.build(false, false, null); Document docBuilt = DOMUtils.parseDocument(xmlBuilt, false, ALL_SCHEMA_LOCATIONS, null); String xmlBuiltSerialized = DOMUtils.serializeNode(docBuilt); // xmlShould was generated by Hot:Sign Tester diff --git a/id.server/src/test/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationTest.java b/id.server/src/test/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationTest.java index e56dcde91..0648163d5 100644 --- a/id.server/src/test/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationTest.java +++ b/id.server/src/test/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationTest.java @@ -84,7 +84,7 @@ System.setProperty( VerifyXMLSignatureResponseParser vParser = new VerifyXMLSignatureResponseParser(response); VerifyXMLSignatureResponse vData = vParser.parseData(); VerifyXMLSignatureResponseValidator vValidate = VerifyXMLSignatureResponseValidator.getInstance(); - vValidate.validate(vData, authConf.getIdentityLinkX509SubjectNames(), VerifyXMLSignatureResponseValidator.CHECK_IDENTITY_LINK); + vValidate.validate(vData, authConf.getIdentityLinkX509SubjectNames(), VerifyXMLSignatureResponseValidator.CHECK_IDENTITY_LINK, true); vValidate.validateCertificate(vData,idl); // check the result |