aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/at/gv/egiz/moazs/msg/MsgClientFactory.java33
-rw-r--r--src/main/java/at/gv/egiz/moazs/util/SSLContextCreator.java55
-rw-r--r--src/main/resources/ssl/server/ca-chain.cert.pem70
-rw-r--r--src/main/resources/ssl/server/server.localhost.cert.pem35
-rw-r--r--src/main/resources/ssl/server/server.localhost.key.pem30
-rw-r--r--src/main/resources/ssl/server/server.localhost.key.pem.password1
-rw-r--r--src/main/resources/ssl/trusted-cas-bundle.pem37
-rw-r--r--src/test/java/at/gv/egiz/moazs/MsgClientTest.java103
8 files changed, 336 insertions, 28 deletions
diff --git a/src/main/java/at/gv/egiz/moazs/msg/MsgClientFactory.java b/src/main/java/at/gv/egiz/moazs/msg/MsgClientFactory.java
index 389fa5c..e55debc 100644
--- a/src/main/java/at/gv/egiz/moazs/msg/MsgClientFactory.java
+++ b/src/main/java/at/gv/egiz/moazs/msg/MsgClientFactory.java
@@ -4,6 +4,7 @@ import at.gv.egiz.moazs.util.FileUtils;
import at.gv.egiz.moazs.util.SSLContextCreator;
import at.gv.zustellung.app2mzs.xsd.ClientType;
import at.gv.zustellung.app2mzs.xsd.KeyStoreType;
+import at.gv.zustellung.app2mzs.xsd.SSLType;
import at.gv.zustellung.msg.xsd.App2ZusePort;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
@@ -32,7 +33,9 @@ public class MsgClientFactory {
private final FileUtils fileUtils;
@Autowired
- public MsgClientFactory(StoreSOAPBodyBinaryInRepositoryInterceptor storeResponseInterceptor, SSLContextCreator creator, FileUtils fileUtils) {
+ public MsgClientFactory(StoreSOAPBodyBinaryInRepositoryInterceptor storeResponseInterceptor,
+ SSLContextCreator creator,
+ FileUtils fileUtils) {
this.storeResponseInterceptor = storeResponseInterceptor;
this.sslContextCreator = creator;
this.fileUtils = fileUtils;
@@ -44,7 +47,6 @@ public class MsgClientFactory {
* @param params for the client, such as service url and ssl parameters.
* @return the msg client
*/
- //TODO evaluate and honor laxhostnameverification and trustall parameter!
public App2ZusePort create(ClientType params) {
var factory = new JaxWsClientFactoryBean();
@@ -62,11 +64,7 @@ public class MsgClientFactory {
http.setClient(httpClientPolicy);
if (params.getURL().startsWith("https")) {
- var keystore = resolveKeyStorePath(params.getSSL().getKeyStore());
- var truststore = resolveKeyStorePath(params.getSSL().getTrustStore());
- SSLContext sslContext = sslContextCreator.createSSLContext(keystore, truststore);
- var tlsParams = new TLSClientParameters();
- tlsParams.setSSLSocketFactory(sslContext.getSocketFactory());
+ TLSClientParameters tlsParams = setupTLSParams(params.getSSL());
http.setTlsClientParameters(tlsParams);
log.info("SSLContext initialized. ");
}
@@ -74,6 +72,27 @@ public class MsgClientFactory {
return ((App2ZusePort)proxy);
}
+ private TLSClientParameters setupTLSParams(SSLType ssl) {
+
+ var tlsParams = new TLSClientParameters();
+ var keystore = resolveKeyStorePath(ssl.getKeyStore());
+
+ SSLContext sslContext;
+ if (ssl.isTrustAll()) {
+ sslContext = sslContextCreator.createUnsafeSSLContext(keystore);
+ } else {
+ var truststore = resolveKeyStorePath(ssl.getTrustStore());
+ sslContext = sslContextCreator.createSSLContext(keystore, truststore);
+ }
+ tlsParams.setSSLSocketFactory(sslContext.getSocketFactory());
+
+ if (ssl.isLaxHostNameVerification()) {
+ tlsParams.setDisableCNCheck(true);
+ }
+
+ return tlsParams;
+ }
+
private KeyStoreType resolveKeyStorePath(@Nullable KeyStoreType store) {
if (store == null) return null;
diff --git a/src/main/java/at/gv/egiz/moazs/util/SSLContextCreator.java b/src/main/java/at/gv/egiz/moazs/util/SSLContextCreator.java
index b4d66d1..302bbf0 100644
--- a/src/main/java/at/gv/egiz/moazs/util/SSLContextCreator.java
+++ b/src/main/java/at/gv/egiz/moazs/util/SSLContextCreator.java
@@ -6,6 +6,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.X509TrustManager;
import javax.net.ssl.*;
import java.io.IOException;
@@ -15,23 +18,46 @@ import static at.gv.egiz.moazs.MoaZSException.moaZSException;
import static java.lang.String.format;
@Component
+ /**
+ * Adapted from at.asitplus.eidas.specific.modules.authmodule_eIDASv2.szr.SZRClient
+ */
public class SSLContextCreator {
private static final Logger log = LoggerFactory.getLogger(SSLContextCreator.class);
+ private static final String SSL_WARN_MAN_IN_THE_MIDDLE_MSG =
+ "HTTP Client trusts ANY server certificate and is therefore vulnerable to Man-In-The-Middle attacks. " +
+ "Use this configuration for testing purposes only and NOT IN PRODUCTION. ";
+
/**
* Creates an SSL Context.
- * Adapted from at.asitplus.eidas.specific.modules.authmodule_eIDASv2.szr.SZRClient
*
* @param keystore (if null, use no key store)
* @param truststore (if null, use default trust store)
* @throws at.gv.egiz.moazs.MoaZSException
*/
public SSLContext createSSLContext(@Nullable KeyStoreType keystore, @Nullable KeyStoreType truststore) {
+ return createSSLContext(keystore, false, truststore);
+ }
+
+ /**
+ * Creates an SSL Context that trusts all certificates. Don't use in production.
+ *
+ * @param keystore (if null, use no key store)
+ * @throws at.gv.egiz.moazs.MoaZSException
+ */
+ public SSLContext createUnsafeSSLContext(@Nullable KeyStoreType keystore) {
+ log.warn(SSL_WARN_MAN_IN_THE_MIDDLE_MSG);
+ return createSSLContext(keystore, true, null);
+ }
+
+ private SSLContext createSSLContext(@Nullable KeyStoreType keystore, boolean trustAll, @Nullable KeyStoreType truststore) {
try {
SSLContext context = SSLContext.getInstance("TLS");
KeyManager[] keyManager = initKeyManager(keystore);
- TrustManager[] trustManager = initTrustManager(truststore);
+ TrustManager[] trustManager = trustAll
+ ? new TrustManager[]{new TrustAllManager()}
+ : initTrustManager(truststore);
context.init(keyManager, trustManager, new SecureRandom());
return context;
} catch (NoSuchAlgorithmException | KeyManagementException e) {
@@ -79,4 +105,29 @@ public class SSLContextCreator {
}
}
+ /**
+ * Class implementing a trust manager that trusts all certificates.
+ *
+ * @author Arne Tauber
+ */
+ public static class TrustAllManager implements X509TrustManager {
+
+ private static Logger log = LoggerFactory.getLogger(TrustAllManager.class);
+
+ public X509Certificate[] getAcceptedIssuers() {
+ return new X509Certificate[0];
+ }
+
+ public void checkClientTrusted(X509Certificate[] arg0, String arg1)
+ throws CertificateException {
+ log.debug("Automatically accepting client certificate as trusted.");
+ }
+
+ public void checkServerTrusted(X509Certificate[] arg0, String arg1)
+ throws CertificateException {
+ log.debug("Automatically accepting server certificate as trusted.");
+ }
+ }
+
+
}
diff --git a/src/main/resources/ssl/server/ca-chain.cert.pem b/src/main/resources/ssl/server/ca-chain.cert.pem
new file mode 100644
index 0000000..56953f0
--- /dev/null
+++ b/src/main/resources/ssl/server/ca-chain.cert.pem
@@ -0,0 +1,70 @@
+-----BEGIN CERTIFICATE-----
+MIIGEjCCA/qgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwgZMxCzAJBgNVBAYTAkFU
+MRAwDgYDVQQIDAdBdXN0cmlhMQ0wCwYDVQQKDARJQUlLMQ0wCwYDVQQLDARFR0la
+MSMwIQYDVQQDDBpFR0laIENSQUJFTlNURUlORVIgUk9PVCBDQTEvMC0GCSqGSIb3
+DQEJARYgY2hyaXN0b2YucmFiZW5zdGVpbmVyQGVnaXouZ3YuYXQwHhcNMTkwNDIz
+MTQzMzAzWhcNMjkwNDIwMTQzMzAzWjCBmzELMAkGA1UEBhMCQVQxEDAOBgNVBAgM
+B0F1c3RyaWExDTALBgNVBAoMBElBSUsxDTALBgNVBAsMBEVHSVoxKzApBgNVBAMM
+IkVHSVogQ1JBQkVOU1RFSU5FUiBJTlRFUk1FRElBVEUgQ0ExLzAtBgkqhkiG9w0B
+CQEWIGNocmlzdG9mLnJhYmVuc3RlaW5lckBlZ2l6Lmd2LmF0MIICIjANBgkqhkiG
+9w0BAQEFAAOCAg8AMIICCgKCAgEA3Y+ImG7TZmK7M4DxRaCbjtHA4jspyEDh2zjW
+Nu+nsxUMO2NxRZGNbOjEfVISP67gCd0RIf9AfBZ74qxGQjz/rEVMJP34ISfTV3yG
+p8krBrB1LFSRBoqDRs1ts8N+EgpslSQoJST/BvlqiIwVjQnK5KzbsBwabOWetNyq
+znHDQrHd9WSXTIeovPd067LR4o5A9x5T9MDbGCj6rak2QfcRB6F5yPvWah2J+c+w
+bDjojdFijSVRndBJiOik28gTG9rTLSJtg/HKIBmOsebrKe6va4FI/wwlw/yYcN/r
+xX3ErcJ3dI/DrS4+E8CqoDfvhwav+Px2qRcpZzVTWghqGdtvsmQFU1pBAddenSzJ
+cgHPkIVNHwRrE/r/vgmGWBXVsh8SEXaLcaTAhhLJ772TkI3lOui8VaXvRFj83qcF
+swqHQqFTsyysPTl2PNdgjsEGuyj68Sx8qkzj2pNIMACa+ouPiZC8cLewzG3q2igc
+hYBTOhIHckkxvvuL2ueG/4PFehEcyapBGzXzTTCZ2V3/mnobW1aR8x8H8Cg83Gli
+8Y0GAzG7GcQveKb1KJgUcSiRz98rWozmVev7hC9FL1Cg9eMVJ/sn7QVbcsF8chhP
+ESf82yj3LA3pbvjK6jBDEPeOjPbaTPqWe7l2oJCG2oQm6Uc8yh6rd+xlY1W5euav
+rY3zty8CAwEAAaNmMGQwHQYDVR0OBBYEFKedsAzhL4QgOr0g86GQcv50TxnzMB8G
+A1UdIwQYMBaAFIrz9UKOcwWk0qs9IS+T4YX+ozmLMBIGA1UdEwEB/wQIMAYBAf8C
+AQAwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQAj/xRC70726/au
+AFTYGgfGbPDb0lAfFl+SZCSjQgeMumCMinARNTcaX6xJovoBoUFsLHdwATS0+XEh
+q6aN7SO5fjvbHj/XV9opWBEBrquq2sUVJ0Sx2GPdvhXSr7qA8mheiHk8RFei3XRU
+g3qrLrGVo6esHcYchdFVTg7/09x2YWI9e8uV/HnFBhaxSCzuZBiUB/OagYUv+qEz
+LCceV3iwWdmZVIXj+f8WD7uP1tOCT5UJ/O0ds9BTGnB5ENOqvH1+FUy/iy9QUbr8
+HsFggVHtQM6pxwgXsPGgJkkHtLkPaTvDz8XfmYXljaI4MI/0PH3yq/ID4XyUyTBk
+olj4VAlNR7xcKXneS6OZj03CMG4slCCSeBVgNXeeMjPF8HdtMbvLMqdmHTFoiR4M
+Hwn2fKSJuyyJndFPCGKrFhvulCehagDm1B/gjj3aX8050tH9Gweyng+WGQFldbL6
+YLv7lYvju7lsNIOzd0KA94tdEYLRR5wHgBqW7BIWi66jM+rOPQVhDSPhNzYQ2RsM
+Hp9Hjfkgwf2M7ogt34rabpJ4ye8aRhOtZ2G03Cm6hCbB6sZAcCYZsYaoY8t/54rk
+2jgL53mILwDNFJpFXtqwron8jZDa8LrP6jzV/HzLKWnXDnRq/O86jyEedCCY0EfK
+rAo93z1tRTDtZ1PjlYHtixqjErPc0Q==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGGTCCBAGgAwIBAgIUEzQUFWuzrC0F4mODQYgPZ/Lhq04wDQYJKoZIhvcNAQEL
+BQAwgZMxCzAJBgNVBAYTAkFUMRAwDgYDVQQIDAdBdXN0cmlhMQ0wCwYDVQQKDARJ
+QUlLMQ0wCwYDVQQLDARFR0laMSMwIQYDVQQDDBpFR0laIENSQUJFTlNURUlORVIg
+Uk9PVCBDQTEvMC0GCSqGSIb3DQEJARYgY2hyaXN0b2YucmFiZW5zdGVpbmVyQGVn
+aXouZ3YuYXQwHhcNMTkwNDIzMTQwNTU2WhcNMzkwNDE4MTQwNTU2WjCBkzELMAkG
+A1UEBhMCQVQxEDAOBgNVBAgMB0F1c3RyaWExDTALBgNVBAoMBElBSUsxDTALBgNV
+BAsMBEVHSVoxIzAhBgNVBAMMGkVHSVogQ1JBQkVOU1RFSU5FUiBST09UIENBMS8w
+LQYJKoZIhvcNAQkBFiBjaHJpc3RvZi5yYWJlbnN0ZWluZXJAZWdpei5ndi5hdDCC
+AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMclj0pHf7LxLXEvtz+P7mxI
+5U5Lx0xDiEY4XeLn75jis3IQotv3zmUz8Mvv9rkAT7y9JMJyJPBUPo2iWCO/dtm+
+qYlCy4fNPGvGPyjE05TM+JhG8bijpgO2EEZmKv48by+UUzioX8H/to5n8xNzDu8C
+bibBddbGyfQ9E7PkR2VhdW8PkUrqJCxeG/xiwS0h1U2v++4ZKQpS78rj75KNEExx
+t8spzZFyKV3i5mTkW2Exp5OSr07SpadjlRqkYWkdZsAPnaK4L4KQ+rrL9qXb/fzK
+syD2LkAHimV3s19IZjGVbdwCtgacDZlME3zNfGxIC0hAeJsSXJJN2FMO3SrnXv2b
+CDJT3SOCF+PMhmv41PGMswQxnCtPvB9659y/Cr/tHkY5bhQiR4XamZie7IkxpsMa
+WpV4jCY9iz1L8OsM62DVRsztDWw1w1j2dyWyODNbxaI7fEWg9klUW7GgEDYBeJ2h
+9kfgwZXiMZkw/7+0VHU97a7AKmpCXP3kH6n1z3MAgaf+Dd4Gq7RXB+4HEZ31uiNO
+OqrnayFs2td/X7cl/0ioNLnJ/hbaOmHsGDQo5W0WyXg9bVkLtezajVwTCKkRdUnn
+kAXL0y+x/aRc2CycE7tlC0SHtBDTVjdx5CWeulynBMMiMWZwb+HR9id/rnifp3Vk
+/CPA+eyjiVtt8uXXozLFAgMBAAGjYzBhMB0GA1UdDgQWBBSK8/VCjnMFpNKrPSEv
+k+GF/qM5izAfBgNVHSMEGDAWgBSK8/VCjnMFpNKrPSEvk+GF/qM5izAPBgNVHRMB
+Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAp/fR
+A+cZlMw0jtiFRYy7096dadgjefIcQVgZYNTL3zuPrXyRIHMp4dTlNnREkobmzkcy
+jWN/I41hm2SHt86+E1c7n/wd1KE1oefqoRkhQws84718zlLBkL/iMwluzE4ZzqiE
+RPxBFv23QqFLzaZpqan4ic9zlkqW1d8IZ9kt9vctAxUIju4hXqozUfaYIjIThutU
+wkIgN1A6e6qugFYB9jkhijnMw0HJeP19JbBUNGp9bP3GiSEc+S1ydddU2492rDQj
+NQKvUMvGUhoUdxbbcUhxs6i6Gfct5bCXRN+r7d+mpwFrpN9xv0a0a7y5GNZk//2S
+0qsqQwVEHYa0fDxsBFLnM7i2EY6+eo9mMccOgn0Jk8z+IIU3OCHgRs3df8R0zWbd
+2FSeqrHTTtgcnmfEx3TMZnuuLfOCIwczl/4DP6M5Z6xwp/MKXzUWFy5SP1wkLe9i
+KiTaYeYLiVZb4AluW8TdhkBjj87gA1gCqqGIAyQ6+40LGplt7Wt5pY2XGWqQQLcq
+qfutUjWQM+HOQEDsodrPu8DR07Q613XdrfMuJGHXDh7a+6xD0nRhpkR9JacoY1h/
+UTObjMFCIwIZ8bYniFLgmJhKlMiuhgNuGsEoSMsFHVDrCsEXZOKkoL8OmRu/V4zo
+2vewbMLL/jvutkmtS8E+R1lt+J6iEI5EYJHONrw=
+-----END CERTIFICATE-----
diff --git a/src/main/resources/ssl/server/server.localhost.cert.pem b/src/main/resources/ssl/server/server.localhost.cert.pem
new file mode 100644
index 0000000..2ecd8e1
--- /dev/null
+++ b/src/main/resources/ssl/server/server.localhost.cert.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+MIIGADCCA+igAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwgZsxCzAJBgNVBAYTAkFU
+MRAwDgYDVQQIDAdBdXN0cmlhMQ0wCwYDVQQKDARJQUlLMQ0wCwYDVQQLDARFR0la
+MSswKQYDVQQDDCJFR0laIENSQUJFTlNURUlORVIgSU5URVJNRURJQVRFIENBMS8w
+LQYJKoZIhvcNAQkBFiBjaHJpc3RvZi5yYWJlbnN0ZWluZXJAZWdpei5ndi5hdDAe
+Fw0xOTA1MjAwODM4MjlaFw0yMDA1MjkwODM4MjlaMIGGMQswCQYDVQQGEwJBVDEQ
+MA4GA1UECAwHQXVzdHJpYTENMAsGA1UECgwESUFJSzENMAsGA1UECwwERUdJWjES
+MBAGA1UEAwwJbG9jYWxob3N0MTMwMQYJKoZIhvcNAQkBFiRjaHJpc3RvZi5yYWJl
+bnN0ZWluZXJAaWFpay50dWdyYXouYXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQC0yVt0MgEhQ4a+k2pCeWZa1oSoWnQ3XpCI5089ShGYzFPm+9YkfoSe
+Ml3Wyf0v7zUbjz1vHzqyH1LZ35wE5ZzftrasTg294tW+9iYeDpywxnN/dOMpDqWH
+J7Nylgo3YKPvKkH+9Oa9V0/NaFX/z6B1ukdvtaVbf2bu+pOE0AKthWq/0MNy62fK
+L0K/ARwgh05pwnrYGVwL6eI1tTzbFH30uj7udRwqcl3iiLQKHtcqd7NDjWIoTlZW
+0Ze9KLeBYkkiZ/HFpxokFDW5fnv0vQOQ+Jb3mUH42eRLo8oRqrnR+3UESr3bOILV
+jpU1tdtfgauEF8hWpefQvOgBabBpwFW5AgMBAAGjggFfMIIBWzAJBgNVHRMEAjAA
+MBEGCWCGSAGG+EIBAQQEAwIGQDAzBglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5l
+cmF0ZWQgU2VydmVyIENlcnRpZmljYXRlMB0GA1UdDgQWBBTtrFcxPt8JRBaGyDOH
+SFggJvTo3TCBwQYDVR0jBIG5MIG2gBSnnbAM4S+EIDq9IPOhkHL+dE8Z86GBmaSB
+ljCBkzELMAkGA1UEBhMCQVQxEDAOBgNVBAgMB0F1c3RyaWExDTALBgNVBAoMBElB
+SUsxDTALBgNVBAsMBEVHSVoxIzAhBgNVBAMMGkVHSVogQ1JBQkVOU1RFSU5FUiBS
+T09UIENBMS8wLQYJKoZIhvcNAQkBFiBjaHJpc3RvZi5yYWJlbnN0ZWluZXJAZWdp
+ei5ndi5hdIICEAEwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMB
+MA0GCSqGSIb3DQEBCwUAA4ICAQB7NXX2Rqf6WwPCob3ioq+CI/+2DLW0vB8S+Vl3
+AVzy2RlEfmD7OOTZvGhvthNfLADoroXDNz1NgoHfAcyvd+AJYP4iiw4A/YaYuVa4
+fa+ZIqD6ak1n/TAvE+4fSNTAvj7l4nAouKsfBMTNls7fJo30jOkix1FGElsroe2r
+pm/xYP23qDWBdKQbgU/1YYi6TjZZjZSL+LXKhMcSTr8uqZLQsg+P5g3Z9NPcM1u/
+NuH8SwPOt4o7S4ThH5bwQmcVcLB1CWACmWKLuo1n+fgOCKoHCtolX/BdtFJFOWzH
+htqftSSemhfC6/mcldIg/llJfNkCEoC3ReQfejhyMThgXBTCtVUHhI1K+AZnRJJa
+16gUXPYzTKpNzV/vxRJA5YfNYI8ndmNGuw+Ke4BWK5bNNbJ++cpN7CXe1CEVMi4J
+46DEq5lWW30k34KsUb88yUEt3kcyi+mDDORU6v2WOWB43CEitT/cnmoYtOqPQ1ji
+s60hgSwz7ogFQMp7W0n5IGSbQZar3djDlb7fDMYBWbaSqML5rz6lkw3hatyNz7Kx
+vS2tvmqXXz91pfbbVHBi2bAFk/pM00DqTgu6SjfwwV53XUp9dtVfhG/3ywhotr9L
+A1cXPbEcZUcQ/IjW2bmsmvyEXZ/YMFKxWW1JzWZ8jPDiPWNe+OxIkS6DnS7QjMVv
+skoBYw==
+-----END CERTIFICATE-----
diff --git a/src/main/resources/ssl/server/server.localhost.key.pem b/src/main/resources/ssl/server/server.localhost.key.pem
new file mode 100644
index 0000000..d9f7bc2
--- /dev/null
+++ b/src/main/resources/ssl/server/server.localhost.key.pem
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-256-CBC,BDACF14FCC41ACDBB5A24B955FB2884F
+
+BI+J5A05Bhu+7sqTkGH3ZqtD6Ax9U0NyeAZaA+UTPhQK/P4o1x3iWXqQ8TPcUpi+
+VYUcVOlwvaBRDCqcaJ7317FOKumhT7x9YjjMpvITPWpevz5Zo/TfNelONVe4SeFg
+IVO+syH8UzIcRAwW+tvtmOf/iEnOB0bUewm5cZ634LnPRQdTIIOzfqulCfHgGiGK
+1waXomgrBdZPNVQcY/EMWTXjL6h8CY6Ue+RMQzrTTZCOL51PdMMGHqFyKQ534b7n
+/hJFhO4Trhh1rCLHhMlhvilwiSmfiLLNNzIxu3rPc8WSrR6QhadaFz4bsayTlwJf
+BcpNeKUhewi2Drq9vcUg7oxSwSabOSFgxo0009oOB0GTU69KjMVKs+z4TykZiuh1
+GveIUlwbxOIuCENa9/Xw3VmvfRglx5vV5pxmWOHUsR5Pzq1Lg1VwDis0EcQWghTg
+caO6mahFrduP+IdjrXXkUSfDQGxVMprv3aqpQSp4kYbEjhP/xdfWcBrOt48Dor5k
+TlfeJhxwASdeo/O367oWhqXRxJSmz7y4BcXqFZQTNWhxLXGxJqI7+T8HF9arv8Fn
+KZPKyGY1GGBIMaf+xv6Fl9243LP1XuGu/fbLOcxh54poaV9+2KgzM8riPVrHaTdB
+O/f4rz6yrP4OY3deGnZh7/PtawARtosXv+3nFjHrYVOdG01P/iQZO6gpxuPyVuuc
+puy5lY4f9wQU1nBdvs+NpPL01K6HyIo9c8l/gDFA4Z4n0barSf+DbFYvTg/8bWFN
+cfuR1UtXRm7nwMNUmbo+v9UlEN1ez7YXOmYAJloW+x/3Cc1Xu4orOPTxWDKS9gFc
+IBsY9xZYWwDwP5yxYY0dKo7gwFROxZoJlvFHYdRgwwA6e6hm9ehNsmWouLQrB09d
+eD7jI4mcKT7AoTfbkzfoQm8WzG2MdhqfXYgxVx0Ek615Zzp3YOcuhhqMvy2tI7/7
+bGiT0rDTcZm+Sso4bpX6OBPeR5KGh5SfrnfmIxqd7+V/4w8H3pY0g2Rh92YyD1UA
+rt58b4HxJz4b1EYSCe8dV9MjhVFztGesfnwvgx5XGJWTY87hj6BBqoyOW3f5CwaO
+GRf+GV5p/QndFl7jcmVZH/5v9eJpvK6sneXC28zjEue6ximzZx8leN4UeebAKLMP
++PZwUEtz/ZpCgVldthNH5Q44It+5YhqFch3R/TvuVVHmtVcUkDQiPyn6b7tLdOcM
+JzxAkaS5Ddye/CFNcVD+BiVwJU9ms+aT4qXV2fXTpYwYckE/gQ/wDt1XcUqfUZLq
+HTmlMYW9pSTDUQP0EGk8nic0bhv3x45xIrBXCog2gg6eXRyYXi9rQXMRJzVr0SGn
+GBKtM7/qhOGUzXrhqUx46YvdUApnxbeKqvYtN0k9VuMNP7a+ejVk5HYCuzNhNYyP
+ZKaLW7JbbjVjsSqRviHjeNtsqdnaRb4DP+MC1kkMsO5zLg53ztCRIitxJHmh9svb
+qtFsyf3N3LkJOqmysDBGUunFSD4BSoNxITJ5rJAO+biCoolC/xrkheI+InCT9zS+
+aMQVJNP47CMeZlsHa+0Jsoa9lKT1i+hQy5qPXeoUiWiBBQSN08aORyEpGyh1vTxC
+-----END RSA PRIVATE KEY-----
diff --git a/src/main/resources/ssl/server/server.localhost.key.pem.password b/src/main/resources/ssl/server/server.localhost.key.pem.password
new file mode 100644
index 0000000..22166b6
--- /dev/null
+++ b/src/main/resources/ssl/server/server.localhost.key.pem.password
@@ -0,0 +1 @@
+_gT7pZK),.^(+e4F \ No newline at end of file
diff --git a/src/main/resources/ssl/trusted-cas-bundle.pem b/src/main/resources/ssl/trusted-cas-bundle.pem
new file mode 100644
index 0000000..cb3f138
--- /dev/null
+++ b/src/main/resources/ssl/trusted-cas-bundle.pem
@@ -0,0 +1,37 @@
+EGIZ CRABENSTEINER ROOT CA:
+
+-----BEGIN CERTIFICATE-----
+MIIGGTCCBAGgAwIBAgIUEzQUFWuzrC0F4mODQYgPZ/Lhq04wDQYJKoZIhvcNAQEL
+BQAwgZMxCzAJBgNVBAYTAkFUMRAwDgYDVQQIDAdBdXN0cmlhMQ0wCwYDVQQKDARJ
+QUlLMQ0wCwYDVQQLDARFR0laMSMwIQYDVQQDDBpFR0laIENSQUJFTlNURUlORVIg
+Uk9PVCBDQTEvMC0GCSqGSIb3DQEJARYgY2hyaXN0b2YucmFiZW5zdGVpbmVyQGVn
+aXouZ3YuYXQwHhcNMTkwNDIzMTQwNTU2WhcNMzkwNDE4MTQwNTU2WjCBkzELMAkG
+A1UEBhMCQVQxEDAOBgNVBAgMB0F1c3RyaWExDTALBgNVBAoMBElBSUsxDTALBgNV
+BAsMBEVHSVoxIzAhBgNVBAMMGkVHSVogQ1JBQkVOU1RFSU5FUiBST09UIENBMS8w
+LQYJKoZIhvcNAQkBFiBjaHJpc3RvZi5yYWJlbnN0ZWluZXJAZWdpei5ndi5hdDCC
+AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMclj0pHf7LxLXEvtz+P7mxI
+5U5Lx0xDiEY4XeLn75jis3IQotv3zmUz8Mvv9rkAT7y9JMJyJPBUPo2iWCO/dtm+
+qYlCy4fNPGvGPyjE05TM+JhG8bijpgO2EEZmKv48by+UUzioX8H/to5n8xNzDu8C
+bibBddbGyfQ9E7PkR2VhdW8PkUrqJCxeG/xiwS0h1U2v++4ZKQpS78rj75KNEExx
+t8spzZFyKV3i5mTkW2Exp5OSr07SpadjlRqkYWkdZsAPnaK4L4KQ+rrL9qXb/fzK
+syD2LkAHimV3s19IZjGVbdwCtgacDZlME3zNfGxIC0hAeJsSXJJN2FMO3SrnXv2b
+CDJT3SOCF+PMhmv41PGMswQxnCtPvB9659y/Cr/tHkY5bhQiR4XamZie7IkxpsMa
+WpV4jCY9iz1L8OsM62DVRsztDWw1w1j2dyWyODNbxaI7fEWg9klUW7GgEDYBeJ2h
+9kfgwZXiMZkw/7+0VHU97a7AKmpCXP3kH6n1z3MAgaf+Dd4Gq7RXB+4HEZ31uiNO
+OqrnayFs2td/X7cl/0ioNLnJ/hbaOmHsGDQo5W0WyXg9bVkLtezajVwTCKkRdUnn
+kAXL0y+x/aRc2CycE7tlC0SHtBDTVjdx5CWeulynBMMiMWZwb+HR9id/rnifp3Vk
+/CPA+eyjiVtt8uXXozLFAgMBAAGjYzBhMB0GA1UdDgQWBBSK8/VCjnMFpNKrPSEv
+k+GF/qM5izAfBgNVHSMEGDAWgBSK8/VCjnMFpNKrPSEvk+GF/qM5izAPBgNVHRMB
+Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAp/fR
+A+cZlMw0jtiFRYy7096dadgjefIcQVgZYNTL3zuPrXyRIHMp4dTlNnREkobmzkcy
+jWN/I41hm2SHt86+E1c7n/wd1KE1oefqoRkhQws84718zlLBkL/iMwluzE4ZzqiE
+RPxBFv23QqFLzaZpqan4ic9zlkqW1d8IZ9kt9vctAxUIju4hXqozUfaYIjIThutU
+wkIgN1A6e6qugFYB9jkhijnMw0HJeP19JbBUNGp9bP3GiSEc+S1ydddU2492rDQj
+NQKvUMvGUhoUdxbbcUhxs6i6Gfct5bCXRN+r7d+mpwFrpN9xv0a0a7y5GNZk//2S
+0qsqQwVEHYa0fDxsBFLnM7i2EY6+eo9mMccOgn0Jk8z+IIU3OCHgRs3df8R0zWbd
+2FSeqrHTTtgcnmfEx3TMZnuuLfOCIwczl/4DP6M5Z6xwp/MKXzUWFy5SP1wkLe9i
+KiTaYeYLiVZb4AluW8TdhkBjj87gA1gCqqGIAyQ6+40LGplt7Wt5pY2XGWqQQLcq
+qfutUjWQM+HOQEDsodrPu8DR07Q613XdrfMuJGHXDh7a+6xD0nRhpkR9JacoY1h/
+UTObjMFCIwIZ8bYniFLgmJhKlMiuhgNuGsEoSMsFHVDrCsEXZOKkoL8OmRu/V4zo
+2vewbMLL/jvutkmtS8E+R1lt+J6iEI5EYJHONrw=
+-----END CERTIFICATE-----
diff --git a/src/test/java/at/gv/egiz/moazs/MsgClientTest.java b/src/test/java/at/gv/egiz/moazs/MsgClientTest.java
index 7c9bf7d..bd68d9d 100644
--- a/src/test/java/at/gv/egiz/moazs/MsgClientTest.java
+++ b/src/test/java/at/gv/egiz/moazs/MsgClientTest.java
@@ -4,9 +4,9 @@ import at.gv.egiz.moazs.msg.MsgClientFactory;
import at.gv.egiz.moazs.msg.StoreSOAPBodyBinaryInRepositoryInterceptor;
import at.gv.egiz.moazs.scheme.Marshaller;
import at.gv.zustellung.app2mzs.xsd.ClientType;
+import at.gv.zustellung.app2mzs.xsd.KeyStoreType;
import at.gv.zustellung.msg.xsd.DeliveryRequestType;
import at.gv.zustellung.msg.xsd.ObjectFactory;
-import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -20,6 +20,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;
+import static at.gv.zustellung.app2mzs.xsd.ClientType.clientTypeBuilder;
import static at.gv.zustellung.app2mzs.xsd.KeyStoreType.keyStoreTypeBuilder;
import static at.gv.zustellung.app2mzs.xsd.SSLType.SSLTypeBuilder;
@@ -43,14 +44,19 @@ public class MsgClientTest {
private static final ObjectFactory OF = new ObjectFactory();
- // this test requires that a zusemsg service runs under httpServiceUri!
// tmp disabled. todo: set up integration tests
+
+ // Requirements:
+ // - run zusemsg service under httpServiceURL
// @Test
public void sendValidMessage() throws IOException {
var request = loadFromFile("validDeliveryRequest.xml");
- var httpServiceUri = "http://localhost:8081/services/DeliveryRequest";
- var clientParams = generateClientParams(httpServiceUri);
+ var httpServiceURL = "http://localhost:8081/services/DeliveryRequest";
+ var clientParams = clientTypeBuilder()
+ .withURL(httpServiceURL)
+ .build();
+
var client = factory.create(clientParams);
try{
@@ -61,20 +67,79 @@ public class MsgClientTest {
}
}
+ // Requirements:
+ // - run zusemsg service under httpsServiceURL
+ // - server trusts client cert (by trusting CA bundle in ssl/trusted-cas-bundle.pem)
+ // - server uses the server certificate in ssl/server/server.localhost.*.pem
+ // - server sends certificate chain ssl/server/ca-chain.cert.pem
+ //@Test
+ public void sendOverSSLWithClientAuthentication() throws IOException {
+
+ var request = loadFromFile("validDeliveryRequest.xml");
+ var httpsServiceURL = "https://localhost/zusemsg/services/DeliveryRequest";
+
+ var clientParams = generateSSLClientParams(httpsServiceURL, false, false);
+ var client = factory.create(clientParams);
+
+ var status = client.delivery(request);
+ log.info("status: " + msgMarshaller.marshallXml(OF.createDeliveryRequestStatus(status)));
+ }
+
+ // Requirements:
+ // - run zusemsg service under httpsServiceURL
+ // - server trusts client cert (by trusting CA bundle in ssl/trusted-cas-bundle.pem)
+ // - server uses the server certificate in ssl/server/server.localhost.*.pem
+ // - server sends certificate chain ssl/server/ca-chain.cert.pem
//@Test
- public void sendValidMessageSSL() throws IOException {
+ public void sendOverSSLWithTrustAll() throws IOException {
var request = loadFromFile("validDeliveryRequest.xml");
var sslServiceUri = "https://localhost/zusemsg/services/DeliveryRequest";
- var clientParams = generateSSLClientParams(sslServiceUri);
+
+ var clientParams = generateSSLClientParams(sslServiceUri, true, false);
+ var client = factory.create(clientParams);
+
+ var status = client.delivery(request);
+ log.info("status: " + msgMarshaller.marshallXml(OF.createDeliveryRequestStatus(status)));
+ }
+
+ // Requirements:
+ // - run zusemsg service under httpsServiceURL (e.g. by adding notlocalhost to /etc/hosts)
+ // - server trusts client cert (by trusting CA bundle in ssl/trusted-cas-bundle.pem)
+ // - server uses the server certificate in ssl/server/server.localhost.*.pem
+ // - server sends certificate chain ssl/server/ca-chain.cert.pem
+ //@Test
+ public void sendOverSSLWithLaxHostnameVerification() throws IOException {
+
+ var request = loadFromFile("validDeliveryRequest.xml");
+ var sslServiceUri = "https://notlocalhost/zusemsg/services/DeliveryRequest";
+
+ var clientParams = generateSSLClientParams(sslServiceUri, false, true);
var client = factory.create(clientParams);
var status = client.delivery(request);
log.info("status: " + msgMarshaller.marshallXml(OF.createDeliveryRequestStatus(status)));
+ }
+
+ //Requirements:
+ // - run zusemsg service under httpsServiceURL (e.g. by adding notlocalhost to /etc/hosts)
+ // - server trusts client cert (by trusting CA bundle in ssl/trusted-cas-bundle.pem)
+ // - server uses the server certificate in ssl/server/server.localhost.*.pem
+ // - server sends certificate chain ssl/server/ca-chain.cert.pem
+ //@Test(expected=SOAPFaultException.class)
+ public void rejectBecauseHostNameVerificationFails() throws IOException {
+
+ var request = loadFromFile("validDeliveryRequest.xml");
+ var sslServiceUri = "https://notlocalhost/zusemsg/services/DeliveryRequest";
+ var clientParams = generateSSLClientParams(sslServiceUri, false, false);
+ var client = factory.create(clientParams);
+
+ var status = client.delivery(request);
+ log.info("status: " + msgMarshaller.marshallXml(OF.createDeliveryRequestStatus(status)));
}
- private ClientType generateSSLClientParams(String sslServiceUri) {
+ private ClientType generateSSLClientParams(String sslServiceUri, boolean trustAll, boolean laxHostNameVerification) {
var keystore = keyStoreTypeBuilder()
.withFileName("ssl/client.cert.key.p12")
@@ -82,20 +147,16 @@ public class MsgClientTest {
.withPassword("123456")
.build();
- var truststore = keyStoreTypeBuilder()
- .withFileName("ssl/truststore.jks")
- .withPassword("123456")
- .withFileType("JKS")
- .build();
+ var truststore = trustAll ? null : generateTrustLocalhostStore();
var sslParams = SSLTypeBuilder()
- .withLaxHostNameVerification(false)
- .withTrustAll(false)
+ .withLaxHostNameVerification(laxHostNameVerification)
+ .withTrustAll(trustAll)
.withKeyStore(keystore)
.withTrustStore(truststore)
.build();
- return ClientType.clientTypeBuilder()
+ return clientTypeBuilder()
.withURL(sslServiceUri)
.withSSL(sslParams)
.withReceiveTimeout(BigInteger.ZERO)
@@ -104,6 +165,14 @@ public class MsgClientTest {
}
+ private KeyStoreType generateTrustLocalhostStore() {
+ return keyStoreTypeBuilder()
+ .withFileName("ssl/truststore.jks")
+ .withPassword("123456")
+ .withFileType("JKS")
+ .build();
+ }
+
private DeliveryRequestType loadFromFile(String fileName) throws IOException {
try (var inputStream = new BufferedInputStream(new FileInputStream(basePath + fileName))) {
var request = (JAXBElement<DeliveryRequestType>) msgMarshaller.unmarshallXml(inputStream);
@@ -111,8 +180,4 @@ public class MsgClientTest {
}
}
- private ClientType generateClientParams(String url) {
- return ClientType.clientTypeBuilder().withURL(url).build();
- }
-
}