diff options
author | Thomas Lenz <tlenz@iaik.tugraz.at> | 2018-07-12 16:16:29 +0200 |
---|---|---|
committer | Thomas Lenz <tlenz@iaik.tugraz.at> | 2018-07-12 16:16:29 +0200 |
commit | 132681b9f3e00158b1671f50b23517462aa54afd (patch) | |
tree | cda5e6b321a44fbb54a959693a4afe71eb25bd6a /id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth | |
parent | 3535ae9500b29d0b2d0f317ea7f47a6c25c6f70e (diff) | |
parent | 3b1130e2366138871a92a1f83124a27fa83885dd (diff) | |
download | moa-id-spss-132681b9f3e00158b1671f50b23517462aa54afd.tar.gz moa-id-spss-132681b9f3e00158b1671f50b23517462aa54afd.tar.bz2 moa-id-spss-132681b9f3e00158b1671f50b23517462aa54afd.zip |
Merge branch 'eIDAS_node_2.0_tests' into huge_refactoring
# Conflicts:
# id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java
# id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/BPKBuilder.java
# id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java
# id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java
# id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/OAAuthParameterDecorator.java
# id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/config/auth/data/DynamicOAAuthParameters.java
# id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/AuthenticationData.java
# id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java
# id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/builder/attributes/EncryptedBPKAttributeBuilder.java
# id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java
# id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java
# id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/metadata/SchemaValidationFilter.java
# id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml
# id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/module/test/TestRequestImpl.java
# id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/MOAIDAuthConstants.java
# id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/api/IOAAuthParameters.java
# id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/config/ConfigurationMigrationUtils.java
# id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/utils/KeyValueUtils.java
# id/server/modules/moa-id-module-bkaMobilaAuthSAML2Test/src/main/java/at/gv/egovernment/moa/id/auth/modules/bkamobileauthtests/BKAMobileAuthModule.java
# id/server/modules/moa-id-module-bkaMobilaAuthSAML2Test/src/main/java/at/gv/egovernment/moa/id/auth/modules/bkamobileauthtests/tasks/FirstBKAMobileAuthTask.java
# id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/JsonSecurityUtils.java
# id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/CreateQualeIDRequestTask.java
# id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/ReceiveQualeIDTask.java
# id/server/modules/module-monitoring/src/main/java/at/gv/egovernment/moa/id/monitoring/IdentityLinkTestModule.java
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth')
12 files changed, 1229 insertions, 63 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java index b60162f35..a13455972 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/AuthenticationDataBuilder.java @@ -28,8 +28,13 @@ import java.security.PrivateKey; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -87,6 +92,7 @@ import at.gv.util.client.szr.SZRClient; import at.gv.util.config.EgovUtilPropertiesConfiguration; import at.gv.util.wsdl.szr.SZRException; import at.gv.util.xsd.szr.PersonInfoType; +import iaik.x509.X509Certificate; /** * @author tlenz @@ -95,10 +101,30 @@ import at.gv.util.xsd.szr.PersonInfoType; @Service("AuthenticationDataBuilder") public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder { + public static final String CONFIGURATION_PROP_FOREIGN_BPK_ENC_KEYS = "configuration.foreignsectors.pubkey"; + @Autowired private IAuthenticationSessionStoreage authenticatedSessionStorage; @Autowired protected AuthConfiguration authConfig; @Autowired protected LoALevelMapper loaLevelMapper; + private Map<String, X509Certificate> encKeyMap = new HashMap<String, X509Certificate>(); + + @PostConstruct + private void initialize() { + Map<String, String> pubKeyMap = authConfig.getBasicMOAIDConfigurationWithPrefix(CONFIGURATION_PROP_FOREIGN_BPK_ENC_KEYS); + for (Entry<String, String> el : pubKeyMap.entrySet()) { + try { + encKeyMap.put(el.getKey(), new X509Certificate(Base64Utils.decode(el.getValue(), false))); + Logger.info("Load foreign bPK encryption certificate for sector: " + el.getKey()); + + } catch (Exception e) { + Logger.warn("Can NOT load foreign bPK encryption certificate for sector: \" + el.getKey()", e); + + } + + } + } + @Override public IAuthData buildAuthenticationData(IRequest pendingReq) throws EAAFAuthenticationException { try { @@ -108,8 +134,7 @@ public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder } catch (ConfigurationException | BuildException | WrongParametersException | DynamicOABuildException | EAAFBuilderException e) { Logger.warn("Can not build authentication data from session information"); - throw new EAAFAuthenticationException("TODO", new Object[]{}, - "Can not build authentication data from session information", e); + throw new EAAFAuthenticationException("TODO", new Object[]{}, e); } @@ -490,6 +515,9 @@ public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder } + //build foreign bPKs + generateForeignbPK(authData, oaParam.foreignbPKSectorsRequested()); + //#################################################################### //copy all generic authentication information, which are not processed before to authData Iterator<String> copyInterator = includedToGenericAuthData.iterator(); @@ -688,8 +716,7 @@ public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder } catch (MOAIDException e) { Logger.warn("Can not build OA specific IDL. Reason: " + e.getMessage(), e); - throw new EAAFParserException("TODO", null, - "Can not build OA specific IDL. Reason: " + e.getMessage(), e); + throw new EAAFParserException("TODO", null, e); } @@ -743,4 +770,58 @@ public class AuthenticationDataBuilder extends AbstractAuthenticationDataBuilder } + private void generateForeignbPK(MOAAuthenticationData authData, List<String> foreignSectors) { + if (foreignSectors != null && !foreignSectors.isEmpty()) { + Logger.debug("Sectors for foreign bPKs are configurated. Starting foreign bPK generation ... "); + for (String foreignSector : foreignSectors) { + Logger.trace("Process sector: " + foreignSector + " ... "); + if (encKeyMap.containsKey(foreignSector)) { + try { + String sector = null; + //splitt sector into VKZ and target + if (foreignSector.startsWith("wbpk")) { + Logger.trace("Find foreign private sector " + foreignSector); + sector = Constants.URN_PREFIX + ":" + foreignSector; + + } else { + String[] split = foreignSector.split("+"); + if (split.length != 2) { + Logger.warn("Foreign sector: " + foreignSector + " looks WRONG. IGNORE IT!"); + + } else { + Logger.trace("Find foreign public sector. VKZ: " + split[0] + " Target: " + split[1]); + sector = Constants.URN_PREFIX_CDID + "+" + split[1]; + + } + + } + + if (sector != null) { + Pair<String, String> bpk = new BPKBuilder().generateAreaSpecificPersonIdentifier( + authData.getIdentificationValue(), + authData.getIdentificationType(), + sector); + String foreignbPK = BPKBuilder.encryptBPK(bpk.getFirst(), bpk.getSecond(), encKeyMap.get(foreignSector).getPublicKey()); + authData.getEncbPKList().add("(" + foreignSector + "|" + foreignbPK + ")"); + Logger.debug("Foreign bPK for sector: " + foreignSector + " created."); + + } + + } catch (Exception e) { + Logger.warn("Foreign bPK generation FAILED for sector: " + foreignSector, e); + + } + + } else { + Logger.info("NO encryption cerfificate FOUND in configuration for sector: " + foreignSector); + Logger.info("Foreign bPK for sector: " + foreignSector + " is NOT possible"); + + } + } + + } else + Logger.debug("No foreign bPKs required for this service provider"); + + } + } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SignatureVerificationUtils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SignatureVerificationUtils.java index 9ca15c76f..27d983785 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SignatureVerificationUtils.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SignatureVerificationUtils.java @@ -22,6 +22,8 @@ */ package at.gv.egovernment.moa.id.auth.builder; +import java.util.List; + import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -74,10 +76,15 @@ public class SignatureVerificationUtils { } } - public IVerifiyXMLSignatureResponse verify(byte[] signature, String trustProfileID) throws MOAIDException { + public IVerifiyXMLSignatureResponse verify(byte[] signature, String trustProfileID) throws MOAIDException { + return verify(signature, trustProfileID, null); + + } + + public IVerifiyXMLSignatureResponse verify(byte[] signature, String trustProfileID, List<String> verifyTransformsInfoProfileID) throws MOAIDException { try { //build signature-verification request - Element domVerifyXMLSignatureRequest = build(signature, trustProfileID); + Element domVerifyXMLSignatureRequest = build(signature, trustProfileID, verifyTransformsInfoProfileID); //send signature-verification to MOA-SP Element domVerifyXMLSignatureResponse = SignatureVerificationInvoker.getInstance() @@ -112,7 +119,7 @@ public class SignatureVerificationUtils { * * @throws ParseException */ - private Element build(byte[] signature, String trustProfileID) + private Element build(byte[] signature, String trustProfileID, List<String> verifyTransformsInfoProfileID) throws ParseException { try { @@ -153,6 +160,20 @@ public class SignatureVerificationUtils { requestElem_.appendChild(signatureManifestCheckParamsElem); signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "false"); + //verify transformations + if (verifyTransformsInfoProfileID != null && !verifyTransformsInfoProfileID.isEmpty()) { + Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); + signatureManifestCheckParamsElem.appendChild(referenceInfoElem); + for (String element : verifyTransformsInfoProfileID) { + Element verifyTransformsInfoProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfileID"); + referenceInfoElem.appendChild(verifyTransformsInfoProfileIDElem); + verifyTransformsInfoProfileIDElem.appendChild(requestDoc_.createTextNode(element)); + + } + } + + + //hashinput data Element returnHashInputDataElem = requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); requestElem_.appendChild(returnHashInputDataElem); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java index d5ca89656..d2d39e9e6 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/invoke/SignatureVerificationInvoker.java @@ -52,10 +52,7 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import at.gv.egovernment.moa.id.auth.exception.ServiceException; -import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.api.ConnectionParameterInterface; -import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; -import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.spss.MOAException; import at.gv.egovernment.moa.spss.api.SignatureVerificationService; import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest; @@ -64,7 +61,6 @@ import at.gv.egovernment.moa.spss.api.xmlbind.VerifyXMLSignatureRequestParser; import at.gv.egovernment.moa.spss.api.xmlbind.VerifyXMLSignatureResponseBuilder; import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest; import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; -import at.gv.egovernment.moa.util.MiscUtil; import at.gv.egovernment.moaspss.logging.Logger; /** @@ -93,22 +89,22 @@ public class SignatureVerificationInvoker { } private SignatureVerificationInvoker() { - try { - AuthConfiguration authConfigProvider = AuthConfigurationProviderFactory.getInstance(); - ConnectionParameterInterface authConnParam = authConfigProvider.getMoaSpConnectionParameter(); +// try { +// AuthConfiguration authConfigProvider = AuthConfigurationProviderFactory.getInstance(); +// ConnectionParameterInterface authConnParam = authConfigProvider.getMoaSpConnectionParameter(); - if (authConnParam != null && MiscUtil.isNotEmpty(authConnParam.getUrl())) { - - - } else { +// if (authConnParam != null && MiscUtil.isNotEmpty(authConnParam.getUrl())) { +// +// +// } else { svs = SignatureVerificationService.getInstance(); - } +// } - } catch (ConfigurationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } +// } catch (ConfigurationException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } } @@ -144,35 +140,34 @@ public class SignatureVerificationInvoker { protected Element doCall(QName serviceName, Element request) throws ServiceException { ConnectionParameterInterface authConnParam = null; try { - AuthConfiguration authConfigProvider = AuthConfigurationProviderFactory.getInstance(); - authConnParam = authConfigProvider.getMoaSpConnectionParameter(); - //If the ConnectionParameter do NOT exist, we try to get the api to work.... - if (authConnParam != null && MiscUtil.isNotEmpty(authConnParam.getUrl())) { - - throw new ServiceException("service.00", new Object[]{"MOA-SP connection via Web-Service is not allowed any more!!!!!!"}); -// Service service = ServiceFactory.newInstance().createService(serviceName); -// Call call = service.createCall(); -// SOAPBodyElement body = new SOAPBodyElement(request); -// SOAPBodyElement[] params = new SOAPBodyElement[] { body }; -// Vector responses; -// SOAPBodyElement response; +// AuthConfiguration authConfigProvider = AuthConfigurationProviderFactory.getInstance(); +// authConnParam = authConfigProvider.getMoaSpConnectionParameter(); +// //If the ConnectionParameter do NOT exist, we try to get the api to work.... +// if (authConnParam != null && MiscUtil.isNotEmpty(authConnParam.getUrl())) { // -// Logger.debug("Connecting using auth url: " + authConnParam.getUrl() + ", service " + serviceName.getNamespaceURI() + " : " + serviceName.getLocalPart() + " : "+ serviceName.getPrefix()); -// call.setTargetEndpointAddress(authConnParam.getUrl()); -// responses = (Vector) call.invoke(serviceName, params); -// Logger.debug("Got responses: " + responses.size()); // TODO handle axis 302 response when incorrect service url is used -// response = (SOAPBodyElement) responses.get(0); -// return response.getAsDOM(); - } - else { - VerifyXMLSignatureRequest vsrequest = new VerifyXMLSignatureRequestParser().parse(request); - +// throw new ServiceException("service.00", new Object[]{"MOA-SP connection via Web-Service is not allowed any more!!!!!!"}); +//// Service service = ServiceFactory.newInstance().createService(serviceName); +//// Call call = service.createCall(); +//// SOAPBodyElement body = new SOAPBodyElement(request); +//// SOAPBodyElement[] params = new SOAPBodyElement[] { body }; +//// Vector responses; +//// SOAPBodyElement response; +//// +//// Logger.debug("Connecting using auth url: " + authConnParam.getUrl() + ", service " + serviceName.getNamespaceURI() + " : " + serviceName.getLocalPart() + " : "+ serviceName.getPrefix()); +//// call.setTargetEndpointAddress(authConnParam.getUrl()); +//// responses = (Vector) call.invoke(serviceName, params); +//// Logger.debug("Got responses: " + responses.size()); // TODO handle axis 302 response when incorrect service url is used +//// response = (SOAPBodyElement) responses.get(0); +//// return response.getAsDOM(); +// } +// else { + VerifyXMLSignatureRequest vsrequest = new VerifyXMLSignatureRequestParser().parse(request); VerifyXMLSignatureResponse vsresponse = svs.verifyXMLSignature(vsrequest); - Document result = new VerifyXMLSignatureResponseBuilder().build(vsresponse); - + Document result = new VerifyXMLSignatureResponseBuilder(true).build(vsresponse); + //Logger.setHierarchy("moa.id.auth"); return result.getDocumentElement(); - } +// } } catch (Exception ex) { if (authConnParam != null) { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/EvaluateSSOConsentsTaskImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/EvaluateSSOConsentsTaskImpl.java index 6e374995f..b976cba9e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/EvaluateSSOConsentsTaskImpl.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/EvaluateSSOConsentsTaskImpl.java @@ -82,7 +82,7 @@ public class EvaluateSSOConsentsTaskImpl extends AbstractAuthServletTask { boolean isValidSSOSession = ssoManager.isValidSSOSession(ssoId, pendingReq); //load MOA SSO-session from database - AuthenticationSession ssoMOSSession = authenticatedSessionStorage.getInternalSSOSession(pendingReq.getSSOSessionIdentifier()); + AuthenticationSession ssoMOSSession = authenticatedSessionStorage.getInternalSSOSession(pendingReq.getInternalSSOSessionIdentifier()); if (!(isValidSSOSession && ssoMOSSession.isAuthenticated() )) { Logger.info("Single Sign-On consents evaluator found NO valid SSO session. Stopping authentication process ..."); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/UserRestrictionTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/UserRestrictionTask.java new file mode 100644 index 000000000..7d9a2c28c --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/UserRestrictionTask.java @@ -0,0 +1,86 @@ +package at.gv.egovernment.moa.id.auth.modules.internal.tasks; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Autowired; + +import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext; +import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException; +import at.gv.egiz.eaaf.core.impl.data.Pair; +import at.gv.egiz.eaaf.core.impl.idp.auth.builder.BPKBuilder; +import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask; +import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionWrapper; +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; +import at.gv.egovernment.moa.id.config.auth.data.UserWhitelistStore; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; + +public class UserRestrictionTask extends AbstractAuthServletTask { + + public static final String CONFIG_PROPS_SP_LIST = "configuration.restrictions.sp.entityIds"; + public static final String CONFIG_PROPS_CSV_USER_FILE = "configuration.restrictions.sp.users.url"; + public static final String CONFIG_PROPS_CSV_USER_SECTOR = "configuration.restrictions.sp.users.sector"; + + @Autowired(required=true) UserWhitelistStore whitelist; + + @Override + public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) + throws TaskExecutionException { + try { + String spEntityId = pendingReq.getServiceProviderConfiguration().getUniqueIdentifier(); + List<String> restrictedSPs = KeyValueUtils.getListOfCSVValues(authConfig.getBasicConfiguration(CONFIG_PROPS_SP_LIST)); + if (restrictedSPs.contains(spEntityId)) { + Logger.debug("SP:" + spEntityId + " has a user restrication. Check users bPK ... "); + AuthenticationSessionWrapper moasession = new AuthenticationSessionWrapper(pendingReq.genericFullDataStorage()); + + //check if user idl is already loaded + if (moasession.getIdentityLink() == null) { + Logger.warn("PendingRequest contains NO IdentityLink. User restrictation NOT possible!"); + throw new MOAIDException("process.03", null); + + } + + //calculate whitelist bPK for current user + String bpkTarget = authConfig.getBasicConfiguration(CONFIG_PROPS_CSV_USER_SECTOR); + if (MiscUtil.isEmpty(bpkTarget)) { + Logger.info("NO bPK sector for user whitelist in configuration"); + throw new MOAIDException("config.05", new Object[] {CONFIG_PROPS_CSV_USER_SECTOR}); + + } + + Pair<String, String> pseudonym = new BPKBuilder().generateAreaSpecificPersonIdentifier( + moasession.getIdentityLink().getIdentificationValue(), + moasession.getIdentityLink().getIdentificationType(), + bpkTarget); + + + //check if user's bPK is whitelisted + if (!whitelist.isUserbPKInWhitelistDynamic(pseudonym.getFirst())) { + Logger.info("User's bPK is not whitelisted. Authentication process stops ..."); + Logger.trace("User's bPK: " + pseudonym.getFirst()); + throw new MOAIDException("auth.35", null); + + } + + Logger.debug("User was found in whitelist. Continue authentication process ... "); + + } else + Logger.trace("SP: " + spEntityId + " has no user restrication."); + + + } catch (MOAIDException e) { + throw new TaskExecutionException(pendingReq, e.getMessage(), e); + + } catch (Exception e) { + Logger.warn("RestartAuthProzessManagement has an internal error", e); + throw new TaskExecutionException(pendingReq, e.getMessage(), e); + + } + + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java index e6b4e9bb8..c66353846 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/parser/VerifyXMLSignatureResponseParser.java @@ -46,12 +46,11 @@ package at.gv.egovernment.moa.id.auth.parser; -import iaik.utils.Base64InputStream; -import iaik.x509.X509Certificate; - import java.io.ByteArrayInputStream; import java.io.InputStream; +import org.joda.time.DateTime; +import org.joda.time.format.ISODateTimeFormat; import org.w3c.dom.Element; import at.gv.egiz.eaaf.core.impl.utils.DOMUtils; @@ -60,6 +59,9 @@ import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; import at.gv.egovernment.moa.id.auth.exception.ParseException; import at.gv.egovernment.moa.id.commons.api.data.IVerifiyXMLSignatureResponse; import at.gv.egovernment.moa.util.Constants; +import at.gv.egovernment.moa.util.MiscUtil; +import iaik.utils.Base64InputStream; +import iaik.x509.X509Certificate; /** * Parses a <code><VerifyXMLSignatureResponse></code> returned by @@ -115,6 +117,9 @@ public class VerifyXMLSignatureResponseParser { private static final String CERTIFICATE_CHECK_CODE_XPATH = ROOT + MOA + "CertificateCheck/" + MOA + "Code"; + private static final String SIGNING_TIME_XPATH = + ROOT + MOA + "SigningTime"; + /** This is the root element of the XML-Document provided by the Security Layer Card*/ private Element verifyXMLSignatureResponse; @@ -200,7 +205,14 @@ public class VerifyXMLSignatureResponseParser { if (signatureManifestCheckCode != null) { respData.setSignatureManifestCheckCode(new Integer(signatureManifestCheckCode).intValue()); } - respData.setCertificateCheckCode(new Integer(XPathUtils.getElementValue(verifyXMLSignatureResponse,CERTIFICATE_CHECK_CODE_XPATH,"")).intValue()); + respData.setCertificateCheckCode(new Integer(XPathUtils.getElementValue(verifyXMLSignatureResponse,CERTIFICATE_CHECK_CODE_XPATH,"")).intValue()); + + String signingTimeElement = XPathUtils.getElementValue(verifyXMLSignatureResponse,SIGNING_TIME_XPATH,""); + if (MiscUtil.isNotEmpty(signingTimeElement)) { + DateTime datetime = ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(signingTimeElement); + respData.setSigningDateTime(datetime.toDate()); + + } } catch (Throwable t) { throw new ParseException("parser.01", null, t); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/IDPSingleLogOutServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/IDPSingleLogOutServlet.java index 448e2a0f5..c39d78d8b 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/IDPSingleLogOutServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/IDPSingleLogOutServlet.java @@ -164,6 +164,13 @@ public class IDPSingleLogOutServlet extends AbstractController { Logger.info("Restart Single LogOut process after timeout ... "); try { SLOInformationContainer sloContainer = transactionStorage.get(restartProcess, SLOInformationContainer.class); + if (sloContainer == null) { + Logger.info("No Single LogOut processing information with ID: " + restartProcess); + handleErrorNoRedirect(new MOAIDException("slo.03", null), req, resp, false); + return; + + } + if (sloContainer.hasFrontChannelOA()) sloContainer.putFailedOA("differntent OAs"); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/RedirectServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/RedirectServlet.java index c77542b4a..e5a8bb739 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/RedirectServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/RedirectServlet.java @@ -23,6 +23,7 @@ package at.gv.egovernment.moa.id.auth.servlet; import java.io.IOException; +import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -40,7 +41,6 @@ import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; import at.gv.egovernment.moa.id.commons.config.MOAIDConfigurationConstants; -import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; import at.gv.egovernment.moa.id.moduls.SSOManager; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; @@ -83,7 +83,10 @@ public class RedirectServlet { oa = authConfig.getServiceProviderConfiguration(url, IOAAuthParameters.class); String authURL = HTTPUtils.extractAuthURLFromRequest(req); - if (oa == null || !authConfig.getPublicURLPrefix().contains(authURL)) { + List<String> allowedPublicUrlPrefixes = authConfig.getPublicURLPrefix(); + + if ((oa == null && !checkRedirectToItself(url, allowedPublicUrlPrefixes)) + || !authConfig.getPublicURLPrefix().contains(authURL)) { resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Parameters not valid"); return; @@ -168,5 +171,17 @@ public class RedirectServlet { } } + + private boolean checkRedirectToItself(String url, List<String> allowedPublicUrlPrefixes) { + if (url != null) { + for (String el : allowedPublicUrlPrefixes) { + if (url.startsWith(el)) + return true; + + } + } + + return false; + } } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/interceptor/UniqueSessionIdentifierInterceptor.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/interceptor/UniqueSessionIdentifierInterceptor.java index 07b5242e0..5aa3a691f 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/interceptor/UniqueSessionIdentifierInterceptor.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/interceptor/UniqueSessionIdentifierInterceptor.java @@ -25,10 +25,14 @@ package at.gv.egovernment.moa.id.auth.servlet.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.text.StringEscapeUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; +import at.gv.egiz.eaaf.core.api.IRequest; +import at.gv.egiz.eaaf.core.api.IRequestStorage; import at.gv.egiz.eaaf.core.api.data.EAAFConstants; import at.gv.egiz.eaaf.core.impl.utils.Random; import at.gv.egiz.eaaf.core.impl.utils.TransactionIDUtils; @@ -41,7 +45,9 @@ import at.gv.egovernment.moa.util.MiscUtil; */ public class UniqueSessionIdentifierInterceptor implements HandlerInterceptor { - @Autowired private SSOManager ssomanager; + @Autowired private IRequestStorage requestStorage; + @Autowired(required=false) private SSOManager ssomanager; + /* (non-Javadoc) * @see org.springframework.web.servlet.HandlerInterceptor#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object) @@ -50,18 +56,35 @@ public class UniqueSessionIdentifierInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - //get SSO Cookie for Request - String ssoId = ssomanager.getSSOSessionID(request); + String uniqueSessionIdentifier = null; + + //if SSOManager is available, search SessionIdentifier in SSO session + if (ssomanager != null) { + String ssoId = ssomanager.getSSOSessionID(request); + uniqueSessionIdentifier = ssomanager.getUniqueSessionIdentifier(ssoId); + + } + + // search SessionIdentifier in PendingRequest if available + if (MiscUtil.isEmpty(uniqueSessionIdentifier)) { + String pendingReqId = StringEscapeUtils.escapeHtml4( + request.getParameter(EAAFConstants.PARAM_HTTP_TARGET_PENDINGREQUESTID)); + if (StringUtils.isNotEmpty(pendingReqId)) { + IRequest pendingReq = requestStorage.getPendingRequest(pendingReqId); + if (pendingReq != null) + uniqueSessionIdentifier = pendingReq.getUniqueSessionIdentifier(); + + } + } - //search for unique session identifier - String uniqueSessionIdentifier = ssomanager.getUniqueSessionIdentifier(ssoId); - if (MiscUtil.isEmpty(uniqueSessionIdentifier)) + //if NO SSOSession and no PendingRequest create new SessionIdentifier + if (StringUtils.isEmpty(uniqueSessionIdentifier)) uniqueSessionIdentifier = Random.nextHexRandom16(); TransactionIDUtils.setSessionId(uniqueSessionIdentifier); - request.setAttribute(EAAFConstants.UNIQUESESSIONIDENTIFIER, uniqueSessionIdentifier); - + request.setAttribute(EAAFConstants.UNIQUESESSIONIDENTIFIER, uniqueSessionIdentifier); return true; + } /* (non-Javadoc) diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/IdentityLinkValidator.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/IdentityLinkValidator.java new file mode 100644 index 000000000..604d224eb --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/IdentityLinkValidator.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +package at.gv.egovernment.moa.id.auth.validator; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; +import at.gv.egiz.eaaf.core.impl.idp.auth.data.IdentityLink; +import at.gv.egiz.eaaf.core.impl.utils.XPathUtils; +import at.gv.egovernment.moa.id.auth.exception.ValidateException; +import at.gv.egovernment.moa.util.Constants; + +/** + * This class is used to validate an {@link IdentityLink} + * returned by the security layer + * + * @author Stefan Knirsch + * @version $Id$ + */ +public class IdentityLinkValidator implements Constants { + + // + // XPath namespace prefix shortcuts + // + /** Xpath prefix for reaching PersonData Namespaces */ + private static final String PDATA = PD_PREFIX + ":"; + /** Xpath prefix for reaching SAML Namespaces */ + private static final String SAML = SAML_PREFIX + ":"; + /** Xpath prefix for reaching XML-DSIG Namespaces */ + private static final String DSIG = DSIG_PREFIX + ":"; + /** Xpath prefix for reaching ECDSA Namespaces */ + private static final String ECDSA = ECDSA_PREFIX + ":"; + /** Xpath expression to the root element */ + private static final String ROOT = ""; + /** Xpath expression to the SAML:SubjectConfirmationData element */ + private static final String SAML_SUBJECT_CONFIRMATION_DATA_XPATH = + ROOT + + SAML + + "AttributeStatement/" + + SAML + + "Subject/" + + SAML + + "SubjectConfirmation/" + + SAML + + "SubjectConfirmationData"; +/** Xpath expression to the PersonData:Person element */ + private static final String PERSON_XPATH = + SAML_SUBJECT_CONFIRMATION_DATA_XPATH + "/" + PDATA + "Person"; + /** Xpath expression to the SAML:Attribute element */ + private static final String ATTRIBUTE_XPATH = + ROOT + SAML + "AttributeStatement/" + SAML + "Attribute"; +// /** Xpath expression to the SAML:AttributeName attribute */ +// private static final String ATTRIBUTE_NAME_XPATH = +// ROOT + SAML + "AttributeStatement/" + SAML + "Attribute/@AttributeName"; +// /** Xpath expression to the SAML:AttributeNamespace attribute */ +// private static final String ATTRIBUTE_NAMESPACE_XPATH = +// ROOT +// + SAML +// + "AttributeStatement/" +// + SAML +// + "Attribute/@AttributeNamespace"; +// /** Xpath expression to the SAML:AttributeValue element */ +// private static final String ATTRIBUTE_VALUE_XPATH = +// ROOT +// + SAML +// + "AttributeStatement/" +// + SAML +// + "Attribute/" +// + SAML +// + "AttributeValue"; + + /** Singleton instance. <code>null</code>, if none has been created. */ + private static IdentityLinkValidator instance; + + /** + * Constructor for a singleton IdentityLinkValidator. + * @return a new IdentityLinkValidator instance + * @throws ValidateException if no instance can be created + */ + public static synchronized IdentityLinkValidator getInstance() + throws ValidateException { + if (instance == null) { + instance = new IdentityLinkValidator(); + } + return instance; + } + + /** + * Method validate. Validates the {@link IdentityLink} + * @param identityLink The identityLink to validate + * @throws ValidateException on any validation error + */ + public void validate(IIdentityLink identityLink) throws ValidateException { + + Element samlAssertion = identityLink.getSamlAssertion(); + //Search the SAML:ASSERTION Object (A2.054) + if (samlAssertion == null) { + throw new ValidateException("validator.00", null); + } + + // Check how many saml:Assertion/saml:AttributeStatement/ + // saml:Subject/ saml:SubjectConfirmation/ + // saml:SubjectConfirmationData/pr:Person of type + // PhysicalPersonType exist (A2.056) + NodeList nl = XPathUtils.selectNodeList(samlAssertion, PERSON_XPATH); + // If we have just one Person-Element we don't need to check the attributes + int counterPhysicalPersonType = 0; + if (nl.getLength() > 1) + for (int i = 0; i < nl.getLength(); i++) { + String xsiType = + ((Element) nl.item(i)) + .getAttributeNodeNS( + "http://www.w3.org/2001/XMLSchema-instance", + "type") + .getNodeValue(); + // We have to check if xsiType contains "PhysicalPersonType" + // An equal-check will fail because of the Namespace-prefix of the attribute value + if (xsiType.indexOf("PhysicalPersonType") > -1) + counterPhysicalPersonType++; + } + if (counterPhysicalPersonType > 1) + throw new ValidateException("validator.01", null); + + //Check the SAML:ATTRIBUTES + nl = XPathUtils.selectNodeList(samlAssertion, ATTRIBUTE_XPATH); + for (int i = 0; i < nl.getLength(); i++) { + String attributeName = + XPathUtils.getAttributeValue( + (Element) nl.item(i), + "@AttributeName", + null); + String attributeNS = + XPathUtils.getAttributeValue( + (Element) nl.item(i), + "@AttributeNamespace", + null); + if (attributeName.equals("CitizenPublicKey")) { + + if (attributeNS.equals("http://www.buergerkarte.at/namespaces/personenbindung/20020506#") || + attributeNS.equals("urn:publicid:gv.at:namespaces:identitylink:1.2")) { + Element attributeValue = + (Element) XPathUtils.selectSingleNode((Element) nl.item(i),nSMap, SAML + "AttributeValue/" + DSIG + "RSAKeyValue"); + if (attributeValue==null) + attributeValue = + (Element) XPathUtils.selectSingleNode((Element)nl.item(i), nSMap, SAML + "AttributeValue/" + ECDSA + "ECDSAKeyValue"); + if (attributeValue==null) + attributeValue = + (Element) XPathUtils.selectSingleNode((Element)nl.item(i), nSMap, SAML + "AttributeValue/" + DSIG + "DSAKeyValue"); + if (attributeValue == null) + throw new ValidateException("validator.02", null); + + } + else + throw new ValidateException("validator.03", new Object [] {attributeNS} ); + } + else + throw new ValidateException("validator.04", new Object [] {attributeName} ); + } + + //Check if dsig:Signature exists + Element dsigSignature = (Element) XPathUtils.selectSingleNode(samlAssertion,ROOT + DSIG + "Signature"); + if (dsigSignature==null) throw new ValidateException("validator.05", new Object[] {"in der Personenbindung"}); + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureRequestBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureRequestBuilder.java new file mode 100644 index 000000000..d1c67b06e --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureRequestBuilder.java @@ -0,0 +1,408 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +package at.gv.egovernment.moa.id.auth.validator; + +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; +import at.gv.egovernment.moa.id.auth.data.CreateXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.exception.BuildException; +import at.gv.egovernment.moa.id.auth.exception.ParseException; +import at.gv.egovernment.moa.util.Base64Utils; +import at.gv.egovernment.moa.util.Constants; + +/** + * Builder for the <code><VerifyXMLSignatureRequestBuilder></code> structure + * used for sending the DSIG-Signature of the Security Layer card for validating to MOA-SP. + * + * @author Stefan Knirsch + * @version $Id$ + */ +public class VerifyXMLSignatureRequestBuilder { + + /** shortcut for XMLNS namespace URI */ + private static final String XMLNS_NS_URI = Constants.XMLNS_NS_URI; + /** shortcut for MOA namespace URI */ + private static final String MOA_NS_URI = Constants.MOA_NS_URI; + /** The DSIG-Prefix */ + private static final String DSIG = Constants.DSIG_PREFIX + ":"; + + /** The document containing the <code>VerifyXMLsignatureRequest</code> */ + private Document requestDoc_; + /** the <code>VerifyXMLsignatureRequest</code> root element */ + private Element requestElem_; + + + /** + * Builds the body for a <code>VerifyXMLsignatureRequest</code> including the root + * element and namespace declarations. + * + * @throws BuildException If an error occurs on building the document. + */ + public VerifyXMLSignatureRequestBuilder() throws BuildException { + try { + DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + requestDoc_ = docBuilder.newDocument(); + requestElem_ = requestDoc_.createElementNS(MOA_NS_URI, "VerifyXMLSignatureRequest"); + requestElem_.setAttributeNS(XMLNS_NS_URI, "xmlns", MOA_NS_URI); + requestElem_.setAttributeNS(XMLNS_NS_URI, "xmlns:" + Constants.DSIG_PREFIX, Constants.DSIG_NS_URI); + requestDoc_.appendChild(requestElem_); + } catch (Throwable t) { + throw new BuildException( + "builder.00", + new Object[] {"VerifyXMLSignatureRequest", t.toString()}, + t); + } + } + + + /** + * Builds a <code><VerifyXMLSignatureRequest></code> + * from an IdentityLink with a known trustProfileID which + * has to exist in MOA-SP + * @param identityLink - The IdentityLink + * @param trustProfileID - a preconfigured TrustProfile at MOA-SP + * + * @return Element - The complete request as Dom-Element + * + * @throws ParseException + */ + public Element build(IIdentityLink identityLink, String trustProfileID) + throws ParseException + { + try { + // build the request + Element dateTimeElem = requestDoc_.createElementNS(MOA_NS_URI, "DateTime"); + requestElem_.appendChild(dateTimeElem); + Node dateTime = requestDoc_.createTextNode(identityLink.getIssueInstant()); + dateTimeElem.appendChild(dateTime); + Element verifiySignatureInfoElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); + requestElem_.appendChild(verifiySignatureInfoElem); + Element verifySignatureEnvironmentElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); + verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); + Element base64ContentElem = requestDoc_.createElementNS(MOA_NS_URI, "Base64Content"); + verifySignatureEnvironmentElem.appendChild(base64ContentElem); + // insert the base64 encoded identity link SAML assertion + String serializedAssertion = identityLink.getSerializedSamlAssertion(); + String base64EncodedAssertion = Base64Utils.encode(serializedAssertion.getBytes("UTF-8")); + //replace all '\r' characters by no char. + StringBuffer replaced = new StringBuffer(); + for (int i = 0; i < base64EncodedAssertion.length(); i ++) { + char c = base64EncodedAssertion.charAt(i); + if (c != '\r') { + replaced.append(c); + } + } + base64EncodedAssertion = replaced.toString(); + Node base64Content = requestDoc_.createTextNode(base64EncodedAssertion); + base64ContentElem.appendChild(base64Content); + // specify the signature location + Element verifySignatureLocationElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); + verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); + Node signatureLocation = requestDoc_.createTextNode(DSIG + "Signature"); + verifySignatureLocationElem.appendChild(signatureLocation); + // signature manifest params + Element signatureManifestCheckParamsElem = + requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); + requestElem_.appendChild(signatureManifestCheckParamsElem); + signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "false"); + // add the transforms + Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); + signatureManifestCheckParamsElem.appendChild(referenceInfoElem); + Element[] dsigTransforms = identityLink.getDsigReferenceTransforms(); + + for (int i = 0; i < dsigTransforms.length; i++) { + Element verifyTransformsInfoProfileElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfile"); + referenceInfoElem.appendChild(verifyTransformsInfoProfileElem); + verifyTransformsInfoProfileElem.appendChild(requestDoc_.importNode(dsigTransforms[i], true)); + } + Element returnHashInputDataElem = + requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); + requestElem_.appendChild(returnHashInputDataElem); + Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); + trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); + requestElem_.appendChild(trustProfileIDElem); + } catch (Throwable t) { + throw new ParseException("builder.00", + new Object[] { "VerifyXMLSignatureRequest (IdentityLink)" }, t); + } + + return requestElem_; + } + + /** + * Builds a <code><VerifyXMLSignatureRequest></code> + * from an IdentityLink with a known trustProfileID which + * has to exist in MOA-SP + * @param identityLink - The IdentityLink + * @param trustProfileID - a preconfigured TrustProfile at MOA-SP + * + * @return Element - The complete request as Dom-Element + * + * @throws ParseException + */ + public Element build(byte[]mandate, String trustProfileID) + throws ParseException + { + try { + // build the request +// Element dateTimeElem = requestDoc_.createElementNS(MOA_NS_URI, "DateTime"); +// requestElem_.appendChild(dateTimeElem); +// Node dateTime = requestDoc_.createTextNode(identityLink.getIssueInstant()); +// dateTimeElem.appendChild(dateTime); + Element verifiySignatureInfoElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); + requestElem_.appendChild(verifiySignatureInfoElem); + Element verifySignatureEnvironmentElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); + verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); + Element base64ContentElem = requestDoc_.createElementNS(MOA_NS_URI, "Base64Content"); + verifySignatureEnvironmentElem.appendChild(base64ContentElem); + // insert the base64 encoded identity link SAML assertion + //String serializedAssertion = identityLink.getSerializedSamlAssertion(); + //String base64EncodedAssertion = Base64Utils.encode(mandate.getBytes("UTF-8")); + String base64EncodedAssertion = Base64Utils.encode(mandate); + //replace all '\r' characters by no char. + StringBuffer replaced = new StringBuffer(); + for (int i = 0; i < base64EncodedAssertion.length(); i ++) { + char c = base64EncodedAssertion.charAt(i); + if (c != '\r') { + replaced.append(c); + } + } + base64EncodedAssertion = replaced.toString(); + Node base64Content = requestDoc_.createTextNode(base64EncodedAssertion); + base64ContentElem.appendChild(base64Content); + // specify the signature location + Element verifySignatureLocationElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); + verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); + Node signatureLocation = requestDoc_.createTextNode(DSIG + "Signature"); + verifySignatureLocationElem.appendChild(signatureLocation); + // signature manifest params + Element signatureManifestCheckParamsElem = + requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); + requestElem_.appendChild(signatureManifestCheckParamsElem); + signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "false"); +// // add the transforms +// Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); +// signatureManifestCheckParamsElem.appendChild(referenceInfoElem); +// Element[] dsigTransforms = identityLink.getDsigReferenceTransforms(); +// +// for (int i = 0; i < dsigTransforms.length; i++) { +// Element verifyTransformsInfoProfileElem = +// requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfile"); +// referenceInfoElem.appendChild(verifyTransformsInfoProfileElem); +// verifyTransformsInfoProfileElem.appendChild(requestDoc_.importNode(dsigTransforms[i], true)); +// } + Element returnHashInputDataElem = + requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); + requestElem_.appendChild(returnHashInputDataElem); + Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); + trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); + requestElem_.appendChild(trustProfileIDElem); + } catch (Throwable t) { + throw new ParseException("builder.00", + new Object[] { "VerifyXMLSignatureRequest (IdentityLink)" }, t); + } + + return requestElem_; + } + + + /** + * Builds a <code><VerifyXMLSignatureRequest></code> + * from the signed AUTH-Block with a known trustProfileID which + * has to exist in MOA-SP + * @param csr - signed AUTH-Block + * @param verifyTransformsInfoProfileID - allowed verifyTransformsInfoProfileID + * @param trustProfileID - a preconfigured TrustProfile at MOA-SP + * @return Element - The complete request as Dom-Element + * @throws ParseException + */ + public Element build( + CreateXMLSignatureResponse csr, + List<String> verifyTransformsInfoProfileID, + String trustProfileID) + throws BuildException { //samlAssertionObject + + try { + // build the request +// requestElem_.setAttributeNS(Constants.XMLNS_NS_URI, "xmlns:" +// + Constants.XML_PREFIX, Constants.XMLNS_NS_URI); + Element verifiySignatureInfoElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); + requestElem_.appendChild(verifiySignatureInfoElem); + Element verifySignatureEnvironmentElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); + verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); + Element xmlContentElem = requestDoc_.createElementNS(MOA_NS_URI, "XMLContent"); + verifySignatureEnvironmentElem.appendChild(xmlContentElem); + xmlContentElem.setAttribute(Constants.XML_PREFIX + ":space", "preserve"); + // insert the SAML assertion + xmlContentElem.appendChild(requestDoc_.importNode(csr.getSamlAssertion(), true)); + // specify the signature location + Element verifySignatureLocationElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); + verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); + Node signatureLocation = requestDoc_.createTextNode(DSIG + "Signature"); + verifySignatureLocationElem.appendChild(signatureLocation); + // signature manifest params + Element signatureManifestCheckParamsElem = + requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); + requestElem_.appendChild(signatureManifestCheckParamsElem); + signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "true"); + // add the transform profile IDs + Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); + signatureManifestCheckParamsElem.appendChild(referenceInfoElem); + +// for (int i = 0; i < verifyTransformsInfoProfileID.length; i++) { +// +// Element verifyTransformsInfoProfileIDElem = +// requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfileID"); +// referenceInfoElem.appendChild(verifyTransformsInfoProfileIDElem); +// verifyTransformsInfoProfileIDElem.appendChild( +// requestDoc_.createTextNode(verifyTransformsInfoProfileID[i])); +// } + + for (String element : verifyTransformsInfoProfileID) { + + Element verifyTransformsInfoProfileIDElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfileID"); + referenceInfoElem.appendChild(verifyTransformsInfoProfileIDElem); + verifyTransformsInfoProfileIDElem.appendChild( + requestDoc_.createTextNode(element)); + } + + Element returnHashInputDataElem = + requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); + requestElem_.appendChild(returnHashInputDataElem); + Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); + trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); + requestElem_.appendChild(trustProfileIDElem); + + } catch (Throwable t) { + throw new BuildException("builder.00", new Object[] { "VerifyXMLSignatureRequest" }, t); + } + + return requestElem_; + } + + /** + * Builds a <code><VerifyXMLSignatureRequest></code> + * from the signed data with a known trustProfileID which + * has to exist in MOA-SP + * @param csr - signed AUTH-Block + * @param trustProfileID - a preconfigured TrustProfile at MOA-SP + * @return Element - The complete request as Dom-Element + * @throws ParseException + */ + public Element buildDsig( + CreateXMLSignatureResponse csr, + String trustProfileID) + throws BuildException { //samlAssertionObject + + try { + // build the request +// requestElem_.setAttributeNS(Constants.XMLNS_NS_URI, "xmlns:" +// + Constants.XML_PREFIX, Constants.XMLNS_NS_URI); + + Element verifiySignatureInfoElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo"); + requestElem_.appendChild(verifiySignatureInfoElem); + Element verifySignatureEnvironmentElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment"); + verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem); + + Element xmlContentElem = requestDoc_.createElementNS(MOA_NS_URI, "XMLContent"); + verifySignatureEnvironmentElem.appendChild(xmlContentElem); + xmlContentElem.setAttribute(Constants.XML_PREFIX + ":space", "preserve"); + + // insert the dsig:Signature + xmlContentElem.appendChild(requestDoc_.importNode(csr.getDsigSignature(), true)); + // specify the signature location + Element verifySignatureLocationElem = + requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation"); + verifiySignatureInfoElem.appendChild(verifySignatureLocationElem); + Node signatureLocation = requestDoc_.createTextNode("/"+ DSIG + "Signature"); + verifySignatureLocationElem.appendChild(signatureLocation); + // signature manifest params + Element signatureManifestCheckParamsElem = + requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams"); + requestElem_.appendChild(signatureManifestCheckParamsElem); + signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "true"); + // add the transform profile IDs + Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo"); + signatureManifestCheckParamsElem.appendChild(referenceInfoElem); + + Element returnHashInputDataElem = + requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData"); + requestElem_.appendChild(returnHashInputDataElem); + Element trustProfileIDElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID"); + + trustProfileIDElem.appendChild(requestDoc_.createTextNode(trustProfileID)); + requestElem_.appendChild(trustProfileIDElem); + + } catch (Throwable t) { + throw new BuildException("builder.00", new Object[] { "VerifyXMLSignatureRequest" }, t); + } + + return requestElem_; + } + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java new file mode 100644 index 000000000..b9c15e75e --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java @@ -0,0 +1,308 @@ +/******************************************************************************* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +/* + * Copyright 2003 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + +package at.gv.egovernment.moa.id.auth.validator; + +import java.security.InvalidKeyException; +import java.security.PublicKey; +import java.security.interfaces.RSAPublicKey; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink; +import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.exception.ValidateException; +import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.commons.api.AuthConfiguration; +import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; +import at.gv.egovernment.moa.id.commons.api.data.IVerifiyXMLSignatureResponse; +import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException; +import at.gv.egovernment.moa.id.commons.utils.MOAIDMessageProvider; +import at.gv.egovernment.moa.logging.Logger; +import iaik.asn1.structures.Name; +import iaik.security.ec.common.ECPublicKey; +import iaik.utils.RFC2253NameParserException; +import iaik.x509.X509Certificate; +import iaik.x509.X509ExtensionInitException; + +/** + * This class is used to validate an {@link VerifyXMLSignatureResponse} + * returned by MOA-SPSS + * + * @author Stefan Knirsch + * @version $Id$ + */ +public class VerifyXMLSignatureResponseValidator { + + /** Identification string for checking identity link */ + public static final String CHECK_IDENTITY_LINK = "IdentityLink"; + /** Identification string for checking authentication block */ + public static final String CHECK_AUTH_BLOCK = "AuthBlock"; + + /** Singleton instance. <code>null</code>, if none has been created. */ + private static VerifyXMLSignatureResponseValidator instance; + + /** + * Constructor for a singleton VerifyXMLSignatureResponseValidator. + */ + public static synchronized VerifyXMLSignatureResponseValidator getInstance() + throws ValidateException { + if (instance == null) { + instance = new VerifyXMLSignatureResponseValidator(); + } + return instance; + } + + /** + * Validates a {@link VerifyXMLSignatureResponse} returned by MOA-SPSS. + * + * @param verifyXMLSignatureResponse the <code><VerifyXMLSignatureResponse></code> + * @param identityLinkSignersSubjectDNNames subject names configured + * @param whatToCheck is used to identify whether the identityLink or the Auth-Block is validated + * @param oaParam specifies whether the validation result of the + * manifest has to be ignored (identityLink validation if + * the OA is a business service) or not + * @throws ValidateException on any validation error + * @throws ConfigurationException + */ + public void validate(IVerifiyXMLSignatureResponse verifyXMLSignatureResponse, + List<String> identityLinkSignersSubjectDNNames, + String whatToCheck, + IOAAuthParameters oaParam, + AuthConfiguration authConfig) + throws ValidateException, ConfigurationException { + + if (verifyXMLSignatureResponse.getSignatureCheckCode() != 0) + throw new ValidateException("validator.06", new Object[] {whatToCheck}); + + if (verifyXMLSignatureResponse.getCertificateCheckCode() != 0) { + String checkFailedReason =""; + if (verifyXMLSignatureResponse.getCertificateCheckCode() == 1) + checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.21", null); + if (verifyXMLSignatureResponse.getCertificateCheckCode() == 2) + checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.22", null); + if (verifyXMLSignatureResponse.getCertificateCheckCode() == 3) + checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.23", null); + if (verifyXMLSignatureResponse.getCertificateCheckCode() == 4) + checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.24", null); + if (verifyXMLSignatureResponse.getCertificateCheckCode() == 5) + checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.25", null); + +// TEST CARDS + if (whatToCheck.equals(CHECK_IDENTITY_LINK)) + throw new ValidateException("validator.07", new Object[] { checkFailedReason } ); + else + throw new ValidateException("validator.19", new Object[] { checkFailedReason } ); + } + + //check QC + if (authConfig.isCertifiacteQCActive() && + !whatToCheck.equals(CHECK_IDENTITY_LINK) && + !verifyXMLSignatureResponse.isQualifiedCertificate()) { + + //check if testcards are active and certificate has an extension for test credentials + if (oaParam.isTestCredentialEnabled()) { + boolean foundTestCredentialOID = false; + try { + X509Certificate signerCert = verifyXMLSignatureResponse.getX509certificate(); + + List<String> validOIDs = new ArrayList<String>(); + if (oaParam.getTestCredentialOIDs() != null) + validOIDs.addAll(oaParam.getTestCredentialOIDs()); + else + validOIDs.add(MOAIDAuthConstants.TESTCREDENTIALROOTOID); + + Set<String> extentsions = signerCert.getCriticalExtensionOIDs(); + extentsions.addAll(signerCert.getNonCriticalExtensionOIDs()); + Iterator<String> extit = extentsions.iterator(); + while(extit.hasNext()) { + String certOID = extit.next(); + for (String el : validOIDs) { + if (certOID.startsWith(el)) + foundTestCredentialOID = true; + } + } + + } catch (Exception e) { + Logger.warn("Test credential OID extraction FAILED.", e); + + } + //throw Exception if not TestCredentialOID is found + if (!foundTestCredentialOID) + throw new ValidateException("validator.72", null); + + } else + throw new ValidateException("validator.71", null); + } + + // if OA is type is business service the manifest validation result has + // to be ignored + boolean ignoreManifestValidationResult = false; + if (whatToCheck.equals(CHECK_IDENTITY_LINK)) + ignoreManifestValidationResult = (oaParam.hasBaseIdInternalProcessingRestriction()) ? true + : false; + + if (ignoreManifestValidationResult) { + Logger.debug("OA type is business service, thus ignoring DSIG manifest validation result"); + } else { + if (verifyXMLSignatureResponse.isXmlDSIGManigest()) + if (verifyXMLSignatureResponse.getXmlDSIGManifestCheckCode() != 0) + throw new ValidateException("validator.08", null); + } + + + // Check the signature manifest only when verifying the signed AUTHBlock + if (whatToCheck.equals(CHECK_AUTH_BLOCK)) { + if (verifyXMLSignatureResponse.getSignatureManifestCheckCode() > 0) { + throw new ValidateException("validator.50", null); + } + } + + //Check whether the returned X509 SubjectName is in the MOA-ID configuration or not + if (identityLinkSignersSubjectDNNames != null) { + String subjectDN = ""; + X509Certificate x509Cert = verifyXMLSignatureResponse.getX509certificate(); + try { + subjectDN = ((Name) x509Cert.getSubjectDN()).getRFC2253String(); + } + catch (RFC2253NameParserException e) { + throw new ValidateException("validator.17", null); + } + //System.out.println("subjectDN: " + subjectDN); + // check the authorisation to sign the identity link + if (!identityLinkSignersSubjectDNNames.contains(subjectDN)) { + // subject DN check failed, try OID check: + try { + if (x509Cert.getExtension(MOAIDAuthConstants.IDENTITY_LINK_SIGNER_OID) == null) { + throw new ValidateException("validator.18", new Object[] { subjectDN }); + } else { + Logger.debug("Identity link signer cert accepted for signing identity link: " + + "subjectDN check failed, but OID check successfully passed."); + } + } catch (X509ExtensionInitException e) { + throw new ValidateException("validator.49", null); + } + } else { + Logger.debug("Identity link signer cert accepted for signing identity link: " + + "subjectDN check successfully passed."); + } + + } + } + + /** + * Method validateCertificate. + * @param verifyXMLSignatureResponse The VerifyXMLSignatureResponse + * @param idl The Identitylink + * @throws ValidateException + */ + public void validateCertificate( + IVerifiyXMLSignatureResponse verifyXMLSignatureResponse, + IIdentityLink idl) + throws ValidateException { + + X509Certificate x509Response = verifyXMLSignatureResponse.getX509certificate(); + PublicKey[] pubKeysIdentityLink = (PublicKey[]) idl.getPublicKey(); + + PublicKey pubKeySignature = x509Response.getPublicKey(); + checkIDLAgainstSignatureCertificate(pubKeysIdentityLink, pubKeySignature); + + } + + + public void checkIDLAgainstSignatureCertificate( PublicKey[] pubKeysIdentityLink, PublicKey pubKeySignature) throws ValidateException { + boolean found = false; + for (int i = 0; i < pubKeysIdentityLink.length; i++) { + PublicKey idlPubKey = pubKeysIdentityLink[i]; + //compare RSAPublicKeys + if ((idlPubKey instanceof java.security.interfaces.RSAPublicKey) && + (pubKeySignature instanceof java.security.interfaces.RSAPublicKey)) { + + RSAPublicKey rsaPubKeySignature = (RSAPublicKey) pubKeySignature; + RSAPublicKey rsakey = (RSAPublicKey) pubKeysIdentityLink[i]; + + if (rsakey.getModulus().equals(rsaPubKeySignature.getModulus()) + && rsakey.getPublicExponent().equals(rsaPubKeySignature.getPublicExponent())) + found = true; + } + + //compare ECDSAPublicKeys + if( ( (idlPubKey instanceof java.security.interfaces.ECPublicKey) || + (idlPubKey instanceof ECPublicKey)) && + ( (pubKeySignature instanceof java.security.interfaces.ECPublicKey) || + (pubKeySignature instanceof ECPublicKey) ) ) { + + try { + ECPublicKey ecdsaPubKeySignature = new ECPublicKey(pubKeySignature.getEncoded()); + ECPublicKey ecdsakey = new ECPublicKey(pubKeysIdentityLink[i].getEncoded()); + + if(ecdsakey.equals(ecdsaPubKeySignature)) + found = true; + + } catch (InvalidKeyException e) { + Logger.warn("ECPublicKey can not parsed into a iaik.ECPublicKey", e); + throw new ValidateException("validator.09", null); + } + + + + } + +// Logger.debug("IDL-Pubkey=" + idl.getPublicKey()[i].getClass().getName() +// + " Resp-Pubkey=" + pubKeySignature.getClass().getName()); + + } + + if (!found) { + + throw new ValidateException("validator.09", null); + + } + } + +} |