diff options
Diffstat (limited to 'juick-server/src/main/java/com/juick/server/XMPPServer.java')
-rw-r--r-- | juick-server/src/main/java/com/juick/server/XMPPServer.java | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/juick-server/src/main/java/com/juick/server/XMPPServer.java b/juick-server/src/main/java/com/juick/server/XMPPServer.java index e2018213..643bc37b 100644 --- a/juick-server/src/main/java/com/juick/server/XMPPServer.java +++ b/juick-server/src/main/java/com/juick/server/XMPPServer.java @@ -33,6 +33,8 @@ import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Inject; import javax.net.ssl.*; +import java.security.InvalidAlgorithmParameterException; +import java.security.cert.*; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import java.io.FileInputStream; @@ -84,6 +86,9 @@ public class XMPPServer implements ConnectionListener, AutoCloseable { private final AtomicBoolean closeFlag = new AtomicBoolean(false); SSLContext sc; + CertificateFactory cf; + CertPathValidator cpv; + PKIXParameters params; private TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { @@ -91,8 +96,9 @@ public class XMPPServer implements ConnectionListener, AutoCloseable { public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) { } + public java.security.cert.X509Certificate[] getAcceptedIssuers() { - return null; + return new X509Certificate[0]; } } }; @@ -117,6 +123,16 @@ public class XMPPServer implements ConnectionListener, AutoCloseable { kmf.init(ks, keystorePassword.toCharArray()); sc = SSLContext.getInstance("TLSv1.2"); sc.init(kmf.getKeyManagers(), trustAllCerts, new SecureRandom()); + TrustManagerFactory trustManagerFactory = + TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + + Set<TrustAnchor> ca = new HashSet<>(); + trustManagerFactory.init((KeyStore)null); + Arrays.stream(trustManagerFactory.getTrustManagers()).forEach(t -> Arrays.stream(((X509TrustManager)t).getAcceptedIssuers()).forEach(cert -> ca.add(new TrustAnchor(cert, null)))); + params = new PKIXParameters(ca); + params.setRevocationEnabled(false); + cpv = CertPathValidator.getInstance("PKIX"); + cf = CertificateFactory.getInstance( "X.509" ); tlsConfigured = true; } catch (Exception e) { logger.warn("tls unavailable"); @@ -295,10 +311,22 @@ public class XMPPServer implements ConnectionListener, AutoCloseable { try { connection.setSocket(sc.getSocketFactory().createSocket(connection.getSocket(), connection.getSocket().getInetAddress().getHostAddress(), connection.getSocket().getPort(), true)); - ((SSLSocket) connection.getSocket()).setUseClientMode(false); - ((SSLSocket) connection.getSocket()).startHandshake(); + SSLSocket sslSocket = (SSLSocket) connection.getSocket(); + sslSocket.addHandshakeCompletedListener(handshakeCompletedEvent -> { + try { + CertPath certPath = cf.generateCertPath(Arrays.asList(handshakeCompletedEvent.getPeerCertificates())); + cpv.validate(certPath, params); + connection.setTrusted(true); + logger.info("connection from {} is trusted", connection.from); + } catch (SSLPeerUnverifiedException | CertificateException | CertPathValidatorException | InvalidAlgorithmParameterException e) { + logger.info("connection from {} is NOT trusted, falling back to dialback", connection.from); + } + }); + sslSocket.setUseClientMode(false); + sslSocket.setNeedClientAuth(true); + sslSocket.startHandshake(); connection.setSecured(true); - logger.debug("stream {} secured", connection.streamID); + logger.debug("stream from {} secured", connection.streamID); connection.restartParser(); } catch (XmlPullParserException | IOException sex) { logger.warn("stream {} ssl error {}", connection.streamID, sex); @@ -314,9 +342,21 @@ public class XMPPServer implements ConnectionListener, AutoCloseable { Socket socket = outConnections.get(connection).get(); socket = sc.getSocketFactory().createSocket(socket, socket.getInetAddress().getHostAddress(), socket.getPort(), true); - ((SSLSocket) socket).startHandshake(); + SSLSocket sslSocket = (SSLSocket) socket; + sslSocket.addHandshakeCompletedListener(handshakeCompletedEvent -> { + try { + CertPath certPath = cf.generateCertPath(Arrays.asList(handshakeCompletedEvent.getPeerCertificates())); + cpv.validate(certPath, params); + connection.setTrusted(true); + logger.info("connection to {} is trusted", connection.to); + } catch (SSLPeerUnverifiedException | CertificateException | CertPathValidatorException | InvalidAlgorithmParameterException e) { + logger.info("connection to {} is NOT trusted, falling back to dialback", connection.to); + } + }); + sslSocket.setNeedClientAuth(true); + sslSocket.startHandshake(); connection.setSecured(true); - logger.debug("stream {} secured", connection.getStreamID()); + logger.debug("stream to {} secured", connection.getStreamID()); connection.setInputStream(socket.getInputStream()); connection.setOutputStream(socket.getOutputStream()); connection.restartStream(); |