diff options
Diffstat (limited to 'id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/VerifyQualifiedeIDTask.java')
-rw-r--r-- | id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/VerifyQualifiedeIDTask.java | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/VerifyQualifiedeIDTask.java b/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/VerifyQualifiedeIDTask.java new file mode 100644 index 000000000..b5c84d315 --- /dev/null +++ b/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/VerifyQualifiedeIDTask.java @@ -0,0 +1,180 @@ +package at.gv.egovernment.moa.id.auth.modules.sl20_auth.tasks; + +import java.io.ByteArrayInputStream; +import java.util.Calendar; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.opensaml.Configuration; +import org.opensaml.saml2.core.Assertion; +import org.opensaml.xml.XMLObject; +import org.opensaml.xml.io.Unmarshaller; +import org.opensaml.xml.io.UnmarshallerFactory; +import org.springframework.stereotype.Component; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + +import at.gv.egovernment.moa.id.advancedlogging.TransactionIDUtils; +import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; +import at.gv.egovernment.moa.id.auth.modules.sl20_auth.Constants; +import at.gv.egovernment.moa.id.auth.modules.sl20_auth.exceptions.SL20eIDDataValidationException; +import at.gv.egovernment.moa.id.auth.modules.sl20_auth.sl20.SL20Constants; +import at.gv.egovernment.moa.id.auth.modules.sl20_auth.sl20.verifier.QualifiedeIDVerifier; +import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser; +import at.gv.egovernment.moa.id.commons.api.data.IIdentityLink; +import at.gv.egovernment.moa.id.commons.api.data.IVerifiyXMLSignatureResponse; +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.protocols.pvp2x.utils.AssertionAttributeExtractor; +import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils; +import at.gv.egovernment.moa.util.Base64Utils; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.DateTimeUtils; +import at.gv.egovernment.moaspss.logging.Logger; + + +@Component("VerifyQualifiedeIDTask") +public class VerifyQualifiedeIDTask extends AbstractAuthServletTask { + + @Override + public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) + throws TaskExecutionException { + + Logger.debug("Verify qualified eID data from SL20 response .... "); + try { + //check if there was an error + TaskExecutionException sl20Error = pendingReq.getGenericData( + Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_IDENTIFIER_ERROR, + TaskExecutionException.class); + if (sl20Error != null) { + Logger.info("Found SL2.0 error after redirect ... "); + throw sl20Error; + + } + + //get data from pending request + String sl20ReqId = pendingReq.getGenericData( + Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_REQID, + String.class); + String idlB64 = pendingReq.getGenericData( + Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_IDL, + String.class); + String authBlockB64 = pendingReq.getGenericData( + Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_AUTHBLOCK, + String.class); + String ccsURL = pendingReq.getGenericData( + Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_CCSURL, + String.class); + String LoA = pendingReq.getGenericData( + Constants.PENDING_REQ_STORAGE_PREFIX + SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_LOA, + String.class); + + //parse eID data + IIdentityLink idl = new IdentityLinkAssertionParser(new ByteArrayInputStream(Base64Utils.decode(idlB64, false))).parseIdentityLink(); + IVerifiyXMLSignatureResponse authBlockVerificationResult = null; + try { + Assertion authBlock = parseAuthBlockToSaml2Assertion(authBlockB64); + AssertionAttributeExtractor authBlockExtractor = new AssertionAttributeExtractor(authBlock); + + + //validate eID data + QualifiedeIDVerifier.verifyIdentityLink(idl, pendingReq.getOnlineApplicationConfiguration(), authConfig); + authBlockVerificationResult = QualifiedeIDVerifier.verifyAuthBlock( + authBlockB64, pendingReq.getOnlineApplicationConfiguration(), authConfig); + QualifiedeIDVerifier.checkConsistencyOfeIDData(sl20ReqId, idl, authBlockExtractor, authBlockVerificationResult); + + //TODO: add LoA verification + + } catch (SL20eIDDataValidationException e) { + if (authConfig.getBasicMOAIDConfigurationBoolean(Constants.CONFIG_PROP_DISABLE_EID_VALIDATION, false)) { + Logger.warn("SL20 eID data validation IS DISABLED!!"); + Logger.warn("SL20 eID data IS NOT VALID!!! Reason: " + e.getMessage(), e); + + } else + throw e; + + } + + //add into session + defaultTaskInitialization(request, executionContext); + moasession.setIdentityLink(idl); + moasession.setBkuURL(ccsURL); + //TODO: from AuthBlock + if (authBlockVerificationResult != null) + moasession.setIssueInstant(DateTimeUtils.buildDateTimeUTC(authBlockVerificationResult.getSigningDateTime())); + else + moasession.setIssueInstant(DateTimeUtils.buildDateTimeUTC(Calendar.getInstance())); + + moasession.setQAALevel(LoA); + + //store pending request + requestStoreage.storePendingRequest(pendingReq); + + } catch (MOAIDException e) { + Logger.warn("ERROR:", e); + throw new TaskExecutionException(pendingReq, "SL2.0 Authentication FAILED. Msg: " + e.getMessage(), e); + + } catch (Exception e) { + Logger.warn("ERROR:", e); + Logger.warn("SL2.0 Authentication FAILED with a generic error.", e); + throw new TaskExecutionException(pendingReq, e.getMessage(), e); + + } finally { + TransactionIDUtils.removeTransactionId(); + TransactionIDUtils.removeSessionId(); + + } + } + + private Assertion parseAuthBlockToSaml2Assertion(String authblockB64) throws SL20eIDDataValidationException { + try { + //parse authBlock into SAML2 Assertion + byte[] authBlockBytes = Base64Utils.decode(authblockB64, false); + Element authBlockDOM = DOMUtils.parseXmlValidating(new ByteArrayInputStream(authBlockBytes)); + UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory(); + Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(authBlockDOM); + XMLObject samlAssertion = unmarshaller.unmarshall(authBlockDOM); + + //validate SAML2 Assertion + SAML2Utils.schemeValidation(samlAssertion); + + if (samlAssertion instanceof Assertion) + return (Assertion) samlAssertion; + else + throw new SL20eIDDataValidationException( + new Object[] { + SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_AUTHBLOCK, + "AuthBlock is NOT of type SAML2 Assertion" + }); + + } catch (SL20eIDDataValidationException e) { + throw e; + + } catch (SAXException e) { + Logger.info("Scheme validation of SAML2 AuthBlock FAILED. Reason: " + e.getMessage()); + throw new SL20eIDDataValidationException( + new Object[] { + SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_AUTHBLOCK, + e.getMessage() + }, + e); + + } catch (Exception e) { + Logger.info("Can not parse AuthBlock. Reason: " + e.getMessage()); + Logger.trace("FullAuthBlock: " + authblockB64); + throw new SL20eIDDataValidationException( + new Object[] { + SL20Constants.SL20_COMMAND_PARAM_EID_RESULT_AUTHBLOCK, + e.getMessage() + }, + e); + + } + + } + + + +} |