diff options
Diffstat (limited to 'java')
-rw-r--r-- | java/com/tigervnc/rfb/CSecurityTLS.java | 125 |
1 files changed, 101 insertions, 24 deletions
diff --git a/java/com/tigervnc/rfb/CSecurityTLS.java b/java/com/tigervnc/rfb/CSecurityTLS.java index 6f799bb4..a3246c5f 100644 --- a/java/com/tigervnc/rfb/CSecurityTLS.java +++ b/java/com/tigervnc/rfb/CSecurityTLS.java @@ -24,16 +24,21 @@ package com.tigervnc.rfb; import javax.net.ssl.*; -import java.security.*; -import java.security.cert.*; +import java.security.KeyManagementException; import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.security.MessageDigest; +import java.security.cert.*; import java.io.File; -import java.io.InputStream; import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.InputStream; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import javax.swing.JOptionPane; +import javax.xml.bind.DatatypeConverter; import com.tigervnc.rdr.*; import com.tigervnc.network.*; @@ -129,7 +134,7 @@ public class CSecurityTLS extends CSecurity { manager = new SSLEngineManager(engine, is, os); manager.doHandshake(); } catch(java.lang.Exception e) { - throw new Exception(e.toString()); + throw new Exception(e.getMessage()); } //checkSession(); @@ -200,19 +205,38 @@ public class CSecurityTLS extends CSecurity { MyX509TrustManager() throws java.security.GeneralSecurityException { - TrustManagerFactory tmf = - TrustManagerFactory.getInstance("PKIX"); KeyStore ks = KeyStore.getInstance("JKS"); CertificateFactory cf = CertificateFactory.getInstance("X.509"); try { ks.load(null, null); + String a = TrustManagerFactory.getDefaultAlgorithm(); + TrustManagerFactory tmf = TrustManagerFactory.getInstance(a); + tmf.init((KeyStore)null); + for (TrustManager m : tmf.getTrustManagers()) + if (m instanceof X509TrustManager) + for (X509Certificate c : ((X509TrustManager)m).getAcceptedIssuers()) + ks.setCertificateEntry(c.getSubjectX500Principal().getName(), c); + File castore = new File(FileUtils.getVncHomeDir()+"x509_savedcerts.pem"); + if (castore.exists() && castore.canRead()) { + InputStream caStream = new FileInputStream(castore); + Collection<? extends Certificate> cacerts = + cf.generateCertificates(caStream); + for (Certificate cert : cacerts) { + String dn = + ((X509Certificate)cert).getSubjectX500Principal().getName(); + ks.setCertificateEntry(dn, (X509Certificate)cert); + } + } File cacert = new File(cafile); - if (!cacert.exists() || !cacert.canRead()) - return; - InputStream caStream = new FileInputStream(cafile); - X509Certificate ca = (X509Certificate)cf.generateCertificate(caStream); - ks.setCertificateEntry("CA", ca); - PKIXBuilderParameters params = new PKIXBuilderParameters(ks, new X509CertSelector()); + if (cacert.exists() && cacert.canRead()) { + InputStream caStream = new FileInputStream(cafile); + Certificate cert = cf.generateCertificate(caStream); + String dn = + ((X509Certificate)cert).getSubjectX500Principal().getName(); + ks.setCertificateEntry(dn, (X509Certificate)cert); + } + PKIXBuilderParameters params = + new PKIXBuilderParameters(ks, new X509CertSelector()); File crlcert = new File(crlfile); if (!crlcert.exists() || !crlcert.canRead()) { params.setRevocationEnabled(false); @@ -224,13 +248,14 @@ public class CSecurityTLS extends CSecurity { params.addCertStore(store); params.setRevocationEnabled(true); } + tmf = TrustManagerFactory.getInstance("PKIX"); tmf.init(new CertPathTrustManagerParameters(params)); + tm = (X509TrustManager)tmf.getTrustManagers()[0]; } catch (java.io.FileNotFoundException e) { vlog.error(e.toString()); } catch (java.io.IOException e) { vlog.error(e.toString()); } - tm = (X509TrustManager)tmf.getTrustManagers()[0]; } public void checkClientTrusted(X509Certificate[] chain, String authType) @@ -242,20 +267,71 @@ public class CSecurityTLS extends CSecurity { public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + MessageDigest md = null; try { - tm.checkServerTrusted(chain, authType); + md = MessageDigest.getInstance("SHA-1"); + tm.checkServerTrusted(chain, authType); } catch (CertificateException e) { - Object[] answer = {"Proceed", "Exit"}; - int ret = JOptionPane.showOptionDialog(null, - e.getCause().getLocalizedMessage()+"\n"+ - "Continue connecting to this host?", - "Confirm certificate exception?", - JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, - null, answer, answer[0]); - if (ret == JOptionPane.NO_OPTION) - System.exit(1); + if (e.getCause() instanceof CertPathBuilderException) { + Object[] answer = {"YES", "NO"}; + X509Certificate cert = chain[0]; + md.update(cert.getEncoded()); + String thumbprint = + DatatypeConverter.printHexBinary(md.digest()); + thumbprint = thumbprint.replaceAll("..(?!$)", "$0 "); + int ret = JOptionPane.showOptionDialog(null, + "This certificate has been signed by an unknown authority\n"+ + "\n"+ + " Subject: "+cert.getSubjectX500Principal().getName()+"\n"+ + " Issuer: "+cert.getIssuerX500Principal().getName()+"\n"+ + " Serial Number: "+cert.getSerialNumber()+"\n"+ + " Version: "+cert.getVersion()+"\n"+ + " Signature Algorithm: "+cert.getPublicKey().getAlgorithm()+"\n"+ + " Not Valid Before: "+cert.getNotBefore()+"\n"+ + " Not Valid After: "+cert.getNotAfter()+"\n"+ + " SHA1 Fingerprint: "+thumbprint+"\n"+ + "\n"+ + "Do you want to save it and continue?", + "Certificate Issuer Unknown", + JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, + null, answer, answer[0]); + if (ret == JOptionPane.YES_OPTION) { + File vncDir = new File(FileUtils.getVncHomeDir()); + if (!vncDir.exists() && !vncDir.mkdir()) { + vlog.info("Certificate save failed, unable to create ~/.vnc"); + return; + } + for (int i = 0; i < chain.length; i++) { + byte[] der = chain[i].getEncoded(); + String pem = DatatypeConverter.printBase64Binary(der); + pem = pem.replaceAll("(.{64})", "$1\n"); + FileWriter fw = null; + try { + String castore = + FileUtils.getVncHomeDir()+"x509_savedcerts.pem"; + fw = new FileWriter(castore, true); + fw.write("-----BEGIN CERTIFICATE-----\n"); + fw.write(pem+"\n"); + fw.write("-----END CERTIFICATE-----\n"); + } catch (IOException ioe) { + throw new Exception(ioe.getCause().getMessage()); + } finally { + try { + if (fw != null) + fw.close(); + } catch(IOException ioe2) { + throw new Exception(ioe2.getCause().getMessage()); + } + } + } + } else { + System.exit(1); + } + } else { + throw new Exception(e.getCause().getMessage()); + } } catch (java.lang.Exception e) { - throw new Exception(e.toString()); + throw new Exception(e.getCause().getMessage()); } } @@ -263,6 +339,7 @@ public class CSecurityTLS extends CSecurity { { return tm.getAcceptedIssuers(); } + } public final int getType() { return anon ? Security.secTypeTLSNone : Security.secTypeX509None; } |