diff options
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(); - } - } |