import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.math.BigInteger;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
import java.util.Arrays;
import javax.net.ssl.SNIHostName;
import javax.net.ssl.SNIServerName;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLEngineResult.Status;
import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLParameters;
+import javax.net.ssl.TrustManagerFactory;
import javax.security.cert.X509Certificate;
+import org.cacert.gigi.dbObjects.Certificate;
+import org.cacert.gigi.dbObjects.Domain;
+import org.cacert.gigi.dbObjects.User;
+
public class SSLPinger extends DomainPinger {
+ public static final String[] TYPES = new String[] {
+ "xmpp", "server-xmpp", "smtp", "imap"
+ };
+
+ private KeyStore truststore;
+
+ public SSLPinger(KeyStore truststore) {
+ this.truststore = truststore;
+ }
+
@Override
- public void ping(String domain, String configuration, String expToken) {
- try {
- SocketChannel sch = SocketChannel.open();
+ public String ping(Domain domain, String configuration, User u) {
+ try (SocketChannel sch = SocketChannel.open()) {
String[] parts = configuration.split(":", 2);
- sch.connect(new InetSocketAddress(domain, Integer.parseInt(parts[0])));
+ sch.connect(new InetSocketAddress(domain.getSuffix(), Integer.parseInt(parts[0])));
if (parts.length == 2) {
switch (parts[1]) {
case "xmpp":
- startXMPP(sch, false, domain);
+ startXMPP(sch, false, domain.getSuffix());
break;
case "server-xmpp":
- startXMPP(sch, true, domain);
+ startXMPP(sch, true, domain.getSuffix());
break;
case "smtp":
startSMTP(sch);
}
}
- test(sch, domain);
+ return test(sch, domain.getSuffix(), u);
} catch (IOException e) {
- e.printStackTrace();
+ return "Connecton failed";
}
}
}
}
- private void test(SocketChannel sch, String domain) {
+ private String test(SocketChannel sch, String domain, User subject) {
try {
- SSLContext sc = SSLContext.getDefault();
+ SSLContext sc = SSLContext.getInstance("SSL");
+ try {
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
+ tmf.init(truststore);
+ sc.init(null, tmf.getTrustManagers(), new SecureRandom());
+ } catch (KeyManagementException e) {
+ e.printStackTrace();
+ } catch (KeyStoreException e) {
+ e.printStackTrace();
+ }
SSLEngine se = sc.createSSLEngine();
ByteBuffer enc_in = ByteBuffer.allocate(se.getSession().getPacketBufferSize());
ByteBuffer enc_out = ByteBuffer.allocate(se.getSession().getPacketBufferSize());
}
}
- System.out.println("completed");
- System.out.println(se.getSession().getCipherSuite());
X509Certificate[] peerCertificateChain = se.getSession().getPeerCertificateChain();
- for (X509Certificate x509Certificate : peerCertificateChain) {
- System.out.println(x509Certificate.getSubjectDN().getName());
+ X509Certificate first = peerCertificateChain[0];
+
+ BigInteger serial = first.getSerialNumber();
+ Certificate c = Certificate.getBySerial(serial.toString(16));
+ if (c.getOwner().getId() != subject.getId()) {
+ return "Owner mismatch";
}
+ return PING_SUCCEDED;
} catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
+ // e.printStackTrace(); TODO log for user debugging?
+ return "Security failed";
} catch (SSLException e) {
- e.printStackTrace();
+ // e.printStackTrace(); TODO log for user debugging?
+ return "Security failed";
} catch (IOException e) {
- e.printStackTrace();
+ // e.printStackTrace(); TODO log for user debugging?
+ return "Connection closed";
}
}
}