aboutsummaryrefslogtreecommitdiff
path: root/juick-server/src/main/java/com/juick/server/XMPPServer.java
diff options
context:
space:
mode:
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.java52
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();