From fee8fea9a8b73640fcbb8aaa8d3b6203a6a0c5eb Mon Sep 17 00:00:00 2001 From: EXTERNALCOREWORKS Date: Thu, 9 May 2019 14:01:19 -0600 Subject: [PATCH] FIPS support !: enhancing the winrm4j library to support TLS using Bouncycastle (in addition to the common JKS) as the provider. On winrm4j 0.6.1, new changes were introduced by your team: Due to this issue: https://github.com/cloudsoft/winrm4j/issues/80 Commits: https://github.com/cloudsoft/winrm4j/pull/92 https://github.com/cloudsoft/winrm4j/pull/93 Which allowed us to propagate the: * SSLContext (which mostly contains the protocols and as well as the security provider being defined, either JKS or bouncycastle or whatever, vital for FIPS compliance) and the * SSLSocketFactory (which contains the cipher suites to use, vital for FIPS compliance). So when we tried to do it by just passing over both the SSLContext and the SSLSocketFactory, we encountered the following open issue which we had already reported to your team: https://github.com/cloudsoft/winrm4j/issues/97 So in order to fix it: -Based on the SSLSocketFactory (if present), we are just propagating out of it, the cipher suites to the Apache cxf TLSClientParameters class which later on will use such ciphers along with the provider for the secure communication. - Based on the SSLContext, we are passing over the whole SSLContext to the TLSClientParameters, but we are also passing the protocols in the Apache CXF TLSClientParameters, so that the communication can be established successfully and FIPS compliant. There could be better ways to propagate only those parameters (like allowing to pass the ciphers and protocols as new params besides the SSLContext and the SSLSocketFactory), but the fact that how it got implement in 0.6.1 was not stable enough is true, meaning that by incorporating this changes, the client application should only care to propagate both the SSLContext and the SSLSocketFactory and the winrm4j library will use only what's really needed :). Hope you can absorb this changes that will benefit a lot your API, there is no single API similar like yours (like overthere or so) that actually supports FIPS, so this will be a great WIN for your software. --- .../cloudsoft/winrm4j/client/WinRmClient.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/client/src/main/java/io/cloudsoft/winrm4j/client/WinRmClient.java b/client/src/main/java/io/cloudsoft/winrm4j/client/WinRmClient.java index 42a868b..dcd303f 100644 --- a/client/src/main/java/io/cloudsoft/winrm4j/client/WinRmClient.java +++ b/client/src/main/java/io/cloudsoft/winrm4j/client/WinRmClient.java @@ -266,7 +266,7 @@ private static void initializeClientAndService(WinRm winrm, WinRmClientBuilder b bp.getRequestContext().put(AuthSchemeProvider.class.getName(), authSchemeRegistry); AsyncHTTPConduit httpClient = (AsyncHTTPConduit) client.getConduit(); - + if (disableCertificateChecks) { TLSClientParameters tlsClientParameters = new TLSClientParameters(); tlsClientParameters.setDisableCNCheck(true); @@ -291,8 +291,19 @@ public X509Certificate[] getAcceptedIssuers() { if (hostnameVerifier != null || sslSocketFactory != null || sslContext != null) { TLSClientParameters tlsClientParameters = new TLSClientParameters(); tlsClientParameters.setHostnameVerifier(hostnameVerifier); - tlsClientParameters.setSSLSocketFactory(sslSocketFactory); - tlsClientParameters.setSslContext(sslContext); + if(sslSocketFactory != null) { + if(sslSocketFactory.getDefaultCipherSuites()!=null && Arrays.asList(sslSocketFactory.getDefaultCipherSuites()).size()>0) { + tlsClientParameters.setCipherSuites(Arrays.asList(sslSocketFactory.getDefaultCipherSuites())); + } + } + if(sslContext != null) { + tlsClientParameters.setSslContext(sslContext); + SSLParameters sslparams =sslContext.getDefaultSSLParameters(); + //To make sure that the protocols are correctly set in the cxf context + if(sslparams.getProtocols() !=null && sslparams.getProtocols().length>0) { + tlsClientParameters.setSecureSocketProtocol(String.join(",", sslparams.getProtocols())); + } + } httpClient.setTlsClientParameters(tlsClientParameters); } HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();