2 Unfortunately the java certificate store does not correctly access
3 the browser certificate store (firefox, chrome). We also tunnel VNC
4 traffic from other cluster nodes.
6 So we implement our own trust manager, and allow to pass the server
7 certificate (or CA who signed the server certificate) as applet
8 parameter "PVECert" (newline encoded as '|').
10 Index: tigervnc/java/src/com/tigervnc/vncviewer/X509Tunnel.java
11 ===================================================================
12 --- tigervnc.orig/java/src/com/tigervnc/vncviewer/X509Tunnel.java 2013-06-03 08:17:17.000000000 +0200
13 +++ tigervnc/java/src/com/tigervnc/vncviewer/X509Tunnel.java 2013-06-03 08:22:52.000000000 +0200
15 import javax.net.ssl.*;
16 import java.security.*;
17 import java.security.cert.*;
18 +import java.security.cert.Certificate;
19 +import java.security.cert.CertificateFactory;
22 public class X509Tunnel extends TLSTunnelBase
25 - public X509Tunnel (Socket sock_)
26 + Certificate pvecert;
28 + public X509Tunnel (Socket sock_, String certstr) throws CertificateException
32 + if (certstr != null) {
33 + CertificateFactory cf = CertificateFactory.getInstance("X.509");
34 + pvecert = cf.generateCertificate(new StringBufferInputStream(certstr));
38 protected void setParam (SSLSocket sock)
40 protected void initContext (SSLContext sc) throws java.security.
41 GeneralSecurityException
43 - TrustManager[] myTM = new TrustManager[]
45 - new MyX509TrustManager ()};
46 + TrustManager[] myTM;
48 + if (pvecert != null) {
49 + myTM = new TrustManager[] {
50 + new X509TrustManager() {
51 + public java.security.cert.X509Certificate[]
52 + getAcceptedIssuers() {
55 + public void checkClientTrusted(
56 + java.security.cert.X509Certificate[] certs,
57 + String authType) throws CertificateException {
58 + throw new CertificateException("no clients");
60 + public void checkServerTrusted(
61 + java.security.cert.X509Certificate[] certs,
62 + String authType) throws CertificateException {
64 + if (certs == null || certs.length < 1) {
65 + throw new CertificateException("no certs");
67 + PublicKey cakey = pvecert.getPublicKey();
71 + certs[0].verify(cakey);
73 + } catch (Exception e) {
77 + if (!ca_match && !pvecert.equals(certs[0])) {
78 + throw new CertificateException("certificate does not match");
84 + myTM = new TrustManager[] {
85 + new MyX509TrustManager ()
88 sc.init (null, myTM, null);
92 return tm.getAcceptedIssuers ();
97 Index: tigervnc/java/src/com/tigervnc/vncviewer/RfbProto.java
98 ===================================================================
99 --- tigervnc.orig/java/src/com/tigervnc/vncviewer/RfbProto.java 2013-06-03 08:17:17.000000000 +0200
100 +++ tigervnc/java/src/com/tigervnc/vncviewer/RfbProto.java 2013-06-03 08:19:05.000000000 +0200
104 void authenticateX509() throws Exception {
105 - X509Tunnel tunnel = new X509Tunnel(sock);
107 + X509Tunnel tunnel = new X509Tunnel(sock, viewer.PVECert);
111 Index: tigervnc/java/src/com/tigervnc/vncviewer/VncViewer.java
112 ===================================================================
113 --- tigervnc.orig/java/src/com/tigervnc/vncviewer/VncViewer.java 2013-06-03 08:19:03.000000000 +0200
114 +++ tigervnc/java/src/com/tigervnc/vncviewer/VncViewer.java 2013-06-03 08:19:05.000000000 +0200
116 int debugStatsExcludeUpdates;
117 int debugStatsMeasureUpdates;
121 // Reference to this applet for inter-applet communication.
122 public static java.applet.Applet refApplet;
125 fatalError(e.toString(), e);
134 // If the rfbThread is being stopped, ignore any exceptions,
135 // otherwise rethrow the exception so it can be handled.
139 void processNormalProtocol() throws Exception {
141 vc.processNormalProtocol();
145 socketFactory = readParameter("SocketFactory", false);
147 + String tmpcert = readParameter("PVECert", false);
148 + if (tmpcert != null) {
149 + PVECert = tmpcert.replace('|', '\n');
157 synchronized public void fatalError(String str, Exception e) {
160 if (rfb != null && rfb.closed()) {
161 // Not necessary to show error message if the error was caused
162 // by I/O problems after the rfb.close() method call.
163 @@ -1084,11 +1091,11 @@
164 public void enableInput(boolean enable) {
165 vc.enableInput(enable);
170 // Resize framebuffer if autoScale is enabled.
174 public void componentResized(ComponentEvent e) {
175 if (e.getComponent() == vncFrame) {
176 if (options.autoScale) {
177 @@ -1100,11 +1107,11 @@
184 // Ignore component events we're not interested in.
188 public void componentShown(ComponentEvent e) { }
189 public void componentMoved(ComponentEvent e) { }
190 public void componentHidden(ComponentEvent e) { }