aboutsummaryrefslogtreecommitdiff
path: root/id/server/modules/moa-id-module-sl20_authentication/src/main/java
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2018-05-30 06:29:29 +0200
committerThomas Lenz <thomas.lenz@egiz.gv.at>2018-05-30 06:29:29 +0200
commit52ad604e54cb91073503d708cd0c50ff0121174a (patch)
tree3aaaebf8460d79fc99bca243827e4e0987ec4379 /id/server/modules/moa-id-module-sl20_authentication/src/main/java
parentdc2fb6695f44e3e01088e8a986ae1ac98b1743b1 (diff)
downloadmoa-id-spss-52ad604e54cb91073503d708cd0c50ff0121174a.tar.gz
moa-id-spss-52ad604e54cb91073503d708cd0c50ff0121174a.tar.bz2
moa-id-spss-52ad604e54cb91073503d708cd0c50ff0121174a.zip
add additional validation to SL20 module
Diffstat (limited to 'id/server/modules/moa-id-module-sl20_authentication/src/main/java')
-rw-r--r--id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/JsonSecurityUtils.java67
-rw-r--r--id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/verifier/QualifiedeIDVerifier.java132
-rw-r--r--id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/ReceiveQualeIDTask.java5
3 files changed, 193 insertions, 11 deletions
diff --git a/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/JsonSecurityUtils.java b/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/JsonSecurityUtils.java
index e0965c712..d00ef8a04 100644
--- a/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/JsonSecurityUtils.java
+++ b/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/JsonSecurityUtils.java
@@ -5,6 +5,9 @@ import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
import java.util.List;
import javax.annotation.PostConstruct;
@@ -14,6 +17,8 @@ import org.jose4j.jwa.AlgorithmConstraints.ConstraintType;
import org.jose4j.jwe.JsonWebEncryption;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
+import org.jose4j.jwx.JsonWebStructure;
+import org.jose4j.keys.resolvers.X509VerificationKeyResolver;
import org.jose4j.lang.JoseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -33,6 +38,7 @@ import at.gv.egovernment.moa.id.commons.utils.X509Utils;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.FileUtils;
import at.gv.egovernment.moa.util.KeyStoreUtils;
+import at.gv.egovernment.moa.util.MiscUtil;
@Service
public class JsonSecurityUtils implements IJOSETools{
@@ -44,6 +50,8 @@ public class JsonSecurityUtils implements IJOSETools{
private Key encPrivKey = null;
private X509Certificate[] encCertChain = null;
+ private List<X509Certificate> trustedCerts = new ArrayList<X509Certificate>();
+
@PostConstruct
protected void initalize() {
Logger.info("Initialize SL2.0 authentication security constrains ... ");
@@ -83,6 +91,21 @@ public class JsonSecurityUtils implements IJOSETools{
}
+ //load trusted certificates
+ Enumeration<String> aliases = keyStore.aliases();
+ while(aliases.hasMoreElements()) {
+ String el = aliases.nextElement();
+ Logger.trace("Process TrustStoreEntry: " + el);
+ if (keyStore.isCertificateEntry(el)) {
+ Certificate cert = keyStore.getCertificate(el);
+ if (cert != null && cert instanceof X509Certificate)
+ trustedCerts.add((X509Certificate) cert);
+ else
+ Logger.info("Can not process entry: " + el + ". Reason: " + cert.toString());
+
+ }
+ }
+
//some short validation
if (signPrivKey == null || !(signPrivKey instanceof PrivateKey)) {
Logger.info("Can NOT open privateKey for SL2.0 signing. KeyStore=" + getKeyStoreFilePath());
@@ -144,18 +167,42 @@ public class JsonSecurityUtils implements IJOSETools{
SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING.toArray(new String[SL20Constants.SL20_ALGORITHM_WHITELIST_SIGNING.size()])));
//load signinc certs
+ Key selectedKey = null;
List<X509Certificate> x5cCerts = jws.getCertificateChainHeaderValue();
- List<X509Certificate> sortedX5cCerts = null;
- if (x5cCerts == null || x5cCerts.size() < 1) {
- Logger.info("Signed SL2.0 response contains NO signature certificate");
- throw new SLCommandoParserException("Signed SL2.0 response contains NO signature certificate");
+ String x5t256 = jws.getX509CertSha256ThumbprintHeaderValue();
+ if (x5cCerts != null) {
+ Logger.debug("Found x509 certificate in JOSE header ... ");
+ Logger.trace("Sorting received X509 certificates ... ");
+ List<X509Certificate> sortedX5cCerts = X509Utils.sortCertificates(x5cCerts);
+
+ if (trustedCerts.contains(sortedX5cCerts.get(0))) {
+ selectedKey = sortedX5cCerts.get(0).getPublicKey();
+
+ } else {
+ Logger.info("Can NOT find JOSE certificate in truststore.");
+ Logger.debug("JOSE certificate: " + sortedX5cCerts.get(0).toString());
+
+ }
- }
- Logger.trace("Sorting received X509 certificates ... ");
- sortedX5cCerts = X509Utils.sortCertificates(x5cCerts);
-
+ } else if (MiscUtil.isNotEmpty(x5t256)) {
+ Logger.debug("Found x5t256 fingerprint in JOSE header .... ");
+ X509VerificationKeyResolver x509VerificationKeyResolver = new X509VerificationKeyResolver(trustedCerts);
+ selectedKey = x509VerificationKeyResolver.resolveKey(jws, Collections.<JsonWebStructure>emptyList());
+
+ } else {
+ Logger.info("Signed SL2.0 response contains NO signature certificate or NO certificate fingerprint");
+ throw new SLCommandoParserException("Signed SL2.0 response contains NO signature certificate or NO certificate fingerprint");
+
+ }
+
+ if (selectedKey == null) {
+ Logger.info("Can NOT select verification key for JWS. Signature verification FAILED.");
+ throw new SLCommandoParserException("Can NOT select verification key for JWS. Signature verification FAILED");
+
+ }
+
//set verification key
- jws.setKey(sortedX5cCerts.get(0).getPublicKey());
+ jws.setKey(selectedKey);
//validate signature
boolean valid = jws.verifySignature();
@@ -169,7 +216,7 @@ public class JsonSecurityUtils implements IJOSETools{
//load payLoad
JsonElement sl20Req = new JsonParser().parse(jws.getPayload());
- return new VerificationResult(sl20Req.getAsJsonObject(), sortedX5cCerts, valid) ;
+ return new VerificationResult(sl20Req.getAsJsonObject(), null, valid) ;
} catch (JoseException e) {
Logger.warn("SL2.0 commando signature validation FAILED", e);
diff --git a/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/verifier/QualifiedeIDVerifier.java b/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/verifier/QualifiedeIDVerifier.java
new file mode 100644
index 000000000..7d03a43ac
--- /dev/null
+++ b/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/verifier/QualifiedeIDVerifier.java
@@ -0,0 +1,132 @@
+package at.gv.egovernment.moa.id.auth.modules.sl20_auth.sl20.verifier;
+
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import javax.xml.bind.DatatypeConverter;
+import javax.xml.transform.TransformerException;
+
+import org.jaxen.SimpleNamespaceContext;
+import org.w3c.dom.Element;
+
+import at.gv.egovernment.moa.id.auth.builder.SignatureVerificationUtils;
+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.id.auth.exception.ServiceException;
+import at.gv.egovernment.moa.id.auth.exception.ValidateException;
+import at.gv.egovernment.moa.id.auth.invoke.SignatureVerificationInvoker;
+import at.gv.egovernment.moa.id.auth.parser.VerifyXMLSignatureResponseParser;
+import at.gv.egovernment.moa.id.auth.validator.IdentityLinkValidator;
+import at.gv.egovernment.moa.id.auth.validator.VerifyXMLSignatureRequestBuilder;
+import at.gv.egovernment.moa.id.auth.validator.VerifyXMLSignatureResponseValidator;
+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.IIdentityLink;
+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.api.exceptions.MOAIDException;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.spss.api.impl.VerifyXMLSignatureRequestImpl;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.XPathUtils;
+
+
+public class QualifiedeIDVerifier {
+
+ /** Xpath expression to the dsig:Signature element */
+ private static final String SIGNATURE_XPATH = Constants.DSIG_PREFIX + ":Signature";
+
+ private static final String XADES_1_1_1_SIGNINGTIME_PATH = "//" + Constants.XADES_1_1_1_NS_PREFIX + ":SigningTime";
+ private static final String XADES_1_3_2_SIGNINGTIME_PATH = "//" + Constants.XADES_1_3_2_NS_PREFIX + ":SigningTime";
+
+
+ private static final long MAX_DIFFERENCE_IN_MILLISECONDS = 600000; // 10min
+
+
+ private static SimpleNamespaceContext NS_CONTEXT;
+ static {
+ NS_CONTEXT = new SimpleNamespaceContext();
+ NS_CONTEXT.addNamespace(Constants.XADES_1_1_1_NS_PREFIX, Constants.XADES_1_1_1_NS_URI);
+ NS_CONTEXT.addNamespace(Constants.XADES_1_2_2_NS_PREFIX, Constants.XADES_1_2_2_NS_URI);
+ NS_CONTEXT.addNamespace(Constants.XADES_1_3_2_NS_PREFIX, Constants.XADES_1_3_2_NS_URI);
+ NS_CONTEXT.addNamespace(Constants.XADES_1_4_1_NS_PREFIX, Constants.XADES_1_4_1_NS_URI);
+ }
+
+ public static boolean verifyIdentityLink(IIdentityLink idl, IOAAuthParameters oaParam, AuthConfiguration authConfig) throws MOAIDException {
+ // validates the identity link
+ IdentityLinkValidator.getInstance().validate(idl);
+
+ // builds a <VerifyXMLSignatureRequest> for a call of MOA-SP
+ Element domVerifyXMLSignatureRequest = new VerifyXMLSignatureRequestBuilder()
+ .build(idl, authConfig.getMoaSpIdentityLinkTrustProfileID(oaParam.isUseIDLTestTrustStore()));
+
+ // invokes the call
+ Element domVerifyXMLSignatureResponse = SignatureVerificationInvoker.getInstance()
+ .verifyXMLSignature(domVerifyXMLSignatureRequest);
+
+ // parses the <VerifyXMLSignatureResponse>
+ IVerifiyXMLSignatureResponse verifyXMLSignatureResponse = new VerifyXMLSignatureResponseParser(domVerifyXMLSignatureResponse).parseData();
+
+ // validates the <VerifyXMLSignatureResponse>
+ VerifyXMLSignatureResponseValidator.getInstance().validate(
+ verifyXMLSignatureResponse,
+ authConfig.getIdentityLinkX509SubjectNames(),
+ VerifyXMLSignatureResponseValidator.CHECK_IDENTITY_LINK,
+ oaParam);
+
+
+ return false;
+
+ }
+
+ public static IVerifiyXMLSignatureResponse verifyAuthBlock(byte[] authblock, IOAAuthParameters oaParam, AuthConfiguration authConfig) throws MOAIDException {
+ String trustProfileId = authConfig.getMoaSpAuthBlockTrustProfileID(oaParam.isUseAuthBlockTestTestStore());
+ List<String> verifyTransformsInfoProfileID = null;
+
+ SignatureVerificationUtils sigVerify = new SignatureVerificationUtils();
+ IVerifiyXMLSignatureResponse sigVerifyResult = sigVerify.verify(authblock, trustProfileId , verifyTransformsInfoProfileID);
+
+ // validates the <VerifyXMLSignatureResponse>
+ VerifyXMLSignatureResponseValidator.getInstance().validate(sigVerifyResult,
+ null, VerifyXMLSignatureResponseValidator.CHECK_AUTH_BLOCK, oaParam);
+
+ return sigVerifyResult;
+
+ }
+
+ public static boolean checkIDLAgainstAuthblock(IVerifiyXMLSignatureResponse sigVerifyResult, IIdentityLink idl, byte[] authBlock) throws ValidateException {
+
+ try {
+ // compares the public keys from the identityLink with the AuthBlock
+ VerifyXMLSignatureResponseValidator.getInstance().validateCertificate(sigVerifyResult, idl);
+
+
+ // Compare AuthBlock Data with information stored in session, especially
+ // date and time
+ validateSigningDateTime(sigVerifyResult);
+
+ } catch ( ValidateException e) {
+ Logger.error("Signature verification error. ", e);
+ throw e;
+
+ }
+
+
+ return false;
+
+ }
+
+ private static boolean validateSigningDateTime( IVerifiyXMLSignatureResponse sigVerifyResult) throws ValidateException {
+ Date signingDate = sigVerifyResult.getSigningDateTime();
+
+
+
+ return false;
+ }
+
+}
diff --git a/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/ReceiveQualeIDTask.java b/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/ReceiveQualeIDTask.java
index 698546a4f..90e19326e 100644
--- a/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/ReceiveQualeIDTask.java
+++ b/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/tasks/ReceiveQualeIDTask.java
@@ -37,6 +37,7 @@ import at.gv.egovernment.moa.id.auth.modules.sl20_auth.sl20.SL20JSONBuilderUtils
import at.gv.egovernment.moa.id.auth.modules.sl20_auth.sl20.SL20JSONExtractorUtils;
import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser;
import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants;
+import at.gv.egovernment.moa.id.commons.api.data.IIdentityLink;
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.AbstractAuthProtocolModulController;
@@ -128,11 +129,13 @@ public class ReceiveQualeIDTask extends AbstractAuthServletTask {
//TODO: validate results
+ IIdentityLink idl = new IdentityLinkAssertionParser(new ByteArrayInputStream(Base64Utils.decode(idlB64, false))).parseIdentityLink();
+
//add into session
defaultTaskInitialization(request, executionContext);
- moasession.setIdentityLink(new IdentityLinkAssertionParser(new ByteArrayInputStream(Base64Utils.decode(idlB64, false))).parseIdentityLink());
+ moasession.setIdentityLink(idl);
moasession.setBkuURL(ccsURL);
//TODO: from AuthBlock
moasession.setIssueInstant(DateTimeUtils.buildDateTimeUTC(Calendar.getInstance()));