aboutsummaryrefslogtreecommitdiff
path: root/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/JsonSecurityUtils.java
diff options
context:
space:
mode:
authorThomas Lenz <tlenz@iaik.tugraz.at>2018-07-12 16:16:29 +0200
committerThomas Lenz <tlenz@iaik.tugraz.at>2018-07-12 16:16:29 +0200
commit132681b9f3e00158b1671f50b23517462aa54afd (patch)
treecda5e6b321a44fbb54a959693a4afe71eb25bd6a /id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/JsonSecurityUtils.java
parent3535ae9500b29d0b2d0f317ea7f47a6c25c6f70e (diff)
parent3b1130e2366138871a92a1f83124a27fa83885dd (diff)
downloadmoa-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/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/JsonSecurityUtils.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.java124
1 files changed, 111 insertions, 13 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 92a08e411..42783468d 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
@@ -1,10 +1,15 @@
package at.gv.egovernment.moa.id.auth.modules.sl20_auth.sl20;
+import java.io.IOException;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
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 +19,9 @@ 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.X509Util;
+import org.jose4j.keys.resolvers.X509VerificationKeyResolver;
import org.jose4j.lang.JoseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -34,6 +42,8 @@ import at.gv.egovernment.moa.id.commons.api.AuthConfiguration;
import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException;
import at.gv.egovernment.moa.id.commons.utils.X509Utils;
import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Base64Utils;
+import at.gv.egovernment.moa.util.MiscUtil;
@Service
public class JsonSecurityUtils implements IJOSETools{
@@ -45,6 +55,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 ... ");
@@ -68,7 +80,7 @@ public class JsonSecurityUtils implements IJOSETools{
try {
encPrivKey = keyStore.getKey(getEncryptionKeyAlias(), getEncryptionKeyPassword().toCharArray());
if (encPrivKey != null) {
- Certificate[] certChainEncryption = keyStore.getCertificateChain(getSigningKeyAlias());
+ Certificate[] certChainEncryption = keyStore.getCertificateChain(getEncryptionKeyAlias());
encCertChain = new X509Certificate[certChainEncryption.length];
for (int i=0; i<certChainEncryption.length; i++) {
if (certChainEncryption[i] instanceof X509Certificate) {
@@ -84,6 +96,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());
@@ -121,7 +148,10 @@ public class JsonSecurityUtils implements IJOSETools{
//set signing information
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
jws.setKey(signPrivKey);
+
+ //TODO:
jws.setCertificateChainHeaderValue(signCertChain);
+ jws.setX509CertSha256ThumbprintHeaderValue(signCertChain[0]);
return jws.getCompactSerialization();
@@ -145,18 +175,47 @@ 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 ... ");
- sortedX5cCerts = X509Utils.sortCertificates(x5cCerts);
+ 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());
+ try {
+ Logger.debug("Cert: " + Base64Utils.encode(sortedX5cCerts.get(0).getEncoded()));
+ } catch (CertificateEncodingException | IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ } 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();
@@ -167,10 +226,12 @@ public class JsonSecurityUtils implements IJOSETools{
}
+
//load payLoad
+ Logger.debug("SL2.0 commando signature validation sucessfull");
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);
@@ -183,7 +244,7 @@ public class JsonSecurityUtils implements IJOSETools{
@Override
public JsonElement decryptPayload(String compactSerialization) throws SL20Exception {
- try {
+ try {
JsonWebEncryption receiverJwe = new JsonWebEncryption();
//set security constrains
@@ -196,12 +257,49 @@ public class JsonSecurityUtils implements IJOSETools{
//set payload
receiverJwe.setCompactSerialization(compactSerialization);
+
- //TODO: validate key from header against key from config
+ //validate key from header against key from config
+ List<X509Certificate> x5cCerts = receiverJwe.getCertificateChainHeaderValue();
+ String x5t256 = receiverJwe.getX509CertSha256ThumbprintHeaderValue();
+ if (x5cCerts != null) {
+ Logger.debug("Found x509 certificate in JOSE header ... ");
+ Logger.trace("Sorting received X509 certificates ... ");
+ List<X509Certificate> sortedX5cCerts = X509Utils.sortCertificates(x5cCerts);
- //decrypt payload
+ if (!sortedX5cCerts.get(0).equals(encCertChain[0])) {
+ Logger.info("Certificate from JOSE header does NOT match encryption certificate");
+ Logger.debug("JOSE certificate: " + sortedX5cCerts.get(0).toString());
+
+ try {
+ Logger.debug("Cert: " + Base64Utils.encode(sortedX5cCerts.get(0).getEncoded()));
+ } catch (CertificateEncodingException | IOException e) {
+ e.printStackTrace();
+ }
+ throw new SL20Exception("sl20.05", new Object[]{"Certificate from JOSE header does NOT match encryption certificate"});
+ }
+
+ } else if (MiscUtil.isNotEmpty(x5t256)) {
+ Logger.debug("Found x5t256 fingerprint in JOSE header .... ");
+ String certFingerPrint = X509Util.x5tS256(encCertChain[0]);
+ if (!certFingerPrint.equals(x5t256)) {
+ Logger.info("X5t256 from JOSE header does NOT match encryption certificate");
+ Logger.debug("X5t256 from JOSE header: " + x5t256 + " Encrytption cert: " + certFingerPrint);
+ throw new SL20Exception("sl20.05", new Object[]{"X5t256 from JOSE header does NOT match encryption certificate"});
+
+ }
+
+ } 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");
+
+ }
+
+ //set key
receiverJwe.setKey(encPrivKey);
+
+ //decrypt payload
return new JsonParser().parse(receiverJwe.getPlaintextString());
} catch (JoseException e) {