X-Git-Url: https://code.wpia.club/?a=blobdiff_plain;f=src%2Forg%2Fcacert%2Fgigi%2Fping%2FSSLPinger.java;h=505a6b349767a3856aec5504413016e554aa16ba;hb=07f74d10bddc819f4524e2e0c1a2815eb4e7ec79;hp=81eabbe97ed8d794bc0ec30f9cf5d8e309c15d9a;hpb=e409ba881965634f63f0b67824bc93dda4ec4327;p=gigi.git diff --git a/src/org/cacert/gigi/ping/SSLPinger.java b/src/org/cacert/gigi/ping/SSLPinger.java index 81eabbe9..505a6b34 100644 --- a/src/org/cacert/gigi/ping/SSLPinger.java +++ b/src/org/cacert/gigi/ping/SSLPinger.java @@ -8,10 +8,10 @@ import java.net.InetSocketAddress; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; +import java.security.GeneralSecurityException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Arrays; @@ -19,16 +19,23 @@ import javax.net.ssl.SNIHostName; import javax.net.ssl.SNIServerName; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; -import javax.net.ssl.TrustManagerFactory; +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.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; +import javax.security.cert.CertificateException; import javax.security.cert.X509Certificate; +import org.cacert.gigi.dbObjects.CACertificate; import org.cacert.gigi.dbObjects.Certificate; +import org.cacert.gigi.dbObjects.CertificateOwner; import org.cacert.gigi.dbObjects.Domain; -import org.cacert.gigi.dbObjects.User; + +import sun.security.x509.AVA; +import sun.security.x509.X500Name; public class SSLPinger extends DomainPinger { @@ -43,12 +50,13 @@ public class SSLPinger extends DomainPinger { } @Override - public String ping(Domain domain, String configuration, User u) { + public void ping(Domain domain, String configuration, CertificateOwner u, int confId) { try (SocketChannel sch = SocketChannel.open()) { - String[] parts = configuration.split(":", 2); - sch.connect(new InetSocketAddress(domain.getSuffix(), Integer.parseInt(parts[0]))); - if (parts.length == 2) { - switch (parts[1]) { + sch.socket().setSoTimeout(5000); + String[] parts = configuration.split(":", 4); + sch.socket().connect(new InetSocketAddress(domain.getSuffix(), Integer.parseInt(parts[2])), 5000); + if (parts.length == 4) { + switch (parts[3]) { case "xmpp": startXMPP(sch, false, domain.getSuffix()); break; @@ -64,9 +72,14 @@ public class SSLPinger extends DomainPinger { } } - return test(sch, domain.getSuffix(), u); + String key = parts[0]; + String value = parts[1]; + String res = test(sch, domain.getSuffix(), u, value); + enterPingResult(confId, res, res, null); + return; } catch (IOException e) { - return "Connecton failed"; + enterPingResult(confId, "error", "connection Failed", null); + return; } } @@ -76,7 +89,7 @@ public class SSLPinger extends DomainPinger { InputStream is = s.getInputStream(); OutputStream os = s.getOutputStream(); scanFor(is, "\n"); - os.write("ENABLE STARTTLS\r\n".getBytes()); + os.write("ENABLE STARTTLS\r\n".getBytes("UTF-8")); os.flush(); scanFor(is, "\n"); } @@ -85,9 +98,9 @@ public class SSLPinger extends DomainPinger { Socket s = sch.socket(); InputStream is = s.getInputStream(); OutputStream os = s.getOutputStream(); - os.write(("").getBytes()); + os.write(("").getBytes("UTF-8")); os.flush(); - os.write("".getBytes()); + os.write("".getBytes("UTF-8")); os.flush(); scanFor(is, ""); @@ -109,13 +122,13 @@ public class SSLPinger extends DomainPinger { Socket s = sch.socket(); InputStream is = s.getInputStream(); readSMTP(is); - s.getOutputStream().write("EHLO ssl.pinger\r\n".getBytes()); + s.getOutputStream().write("EHLO ssl.pinger\r\n".getBytes("UTF-8")); s.getOutputStream().flush(); readSMTP(is); - s.getOutputStream().write("HELP\r\n".getBytes()); + s.getOutputStream().write("HELP\r\n".getBytes("UTF-8")); s.getOutputStream().flush(); readSMTP(is); - s.getOutputStream().write("STARTTLS\r\n".getBytes()); + s.getOutputStream().write("STARTTLS\r\n".getBytes("UTF-8")); s.getOutputStream().flush(); readSMTP(is); } @@ -145,13 +158,35 @@ public class SSLPinger extends DomainPinger { } } - private String test(SocketChannel sch, String domain, User subject) { + private String test(SocketChannel sch, String domain, CertificateOwner subject, String tok) { + System.out.println("SSL- connecting"); + try { + sch.socket().setSoTimeout(5000); SSLContext sc = SSLContext.getInstance("SSL"); try { TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509"); tmf.init(truststore); - sc.init(null, tmf.getTrustManagers(), new SecureRandom()); + sc.init(null, new TrustManager[] { + new X509TrustManager() { + + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException { + java.security.cert.X509Certificate c = chain[0]; + if ( !c.getExtendedKeyUsage().contains("1.3.6.1.5.5.7.3.1")) { + throw new java.security.cert.CertificateException("Illegal EKU"); + } + } + + @Override + public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {} + } + }, new SecureRandom()); } catch (KeyManagementException e) { e.printStackTrace(); } catch (KeyStoreException e) { @@ -203,17 +238,41 @@ public class SSLPinger extends DomainPinger { } } + System.out.println("SSL- connected"); X509Certificate[] peerCertificateChain = se.getSession().getPeerCertificateChain(); X509Certificate first = peerCertificateChain[0]; + if (first.getIssuerDN().equals(first.getSubjectDN())) { + first.verify(first.getPublicKey()); + X500Name p = (X500Name) first.getSubjectDN(); + X500Name n = new X500Name(p.getEncoded()); + for (AVA i : n.allAvas()) { + if (i.getObjectIdentifier().equals((Object) X500Name.orgUnitName_oid)) { + String toke = i.getDerValue().getAsString(); + if (tok.equals(toke)) { + return PING_SUCCEDED; + } else { + return "Self-signed certificate is wrong"; + } + } + } + } BigInteger serial = first.getSerialNumber(); Certificate c = Certificate.getBySerial(serial.toString(16)); - if (c.getOwnerId() != subject.getId()) { + if (c == null) { + return "Certificate not found: Serial " + serial.toString(16) + " missing."; + } + CACertificate p = c.getParent(); + if ( !first.getIssuerDN().equals(p.getCertificate().getSubjectDN())) { + return "Broken certificate supplied"; + } + first.verify(p.getCertificate().getPublicKey()); + if (c.getOwner().getId() != subject.getId()) { return "Owner mismatch"; } return PING_SUCCEDED; - } catch (NoSuchAlgorithmException e) { - // e.printStackTrace(); TODO log for user debugging? + } catch (GeneralSecurityException e) { + // e.printStackTrace(); return "Security failed"; } catch (SSLException e) { // e.printStackTrace(); TODO log for user debugging? @@ -221,6 +280,9 @@ public class SSLPinger extends DomainPinger { } catch (IOException e) { // e.printStackTrace(); TODO log for user debugging? return "Connection closed"; + } catch (CertificateException e) { + // e.printStackTrace(); + return "Security failed"; } } }