Mercurial > hg > monetdb-java
annotate src/main/java/org/monetdb/mcl/net/SecureSocket.java @ 834:5aa19bbed0d6 monetdbs
Comments and formatting
author | Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com> |
---|---|
date | Wed, 13 Dec 2023 15:39:47 +0100 (16 months ago) |
parents | 2fee4b71baac |
children | a2b1ae53565e |
rev | line source |
---|---|
799
117e7917325d
Prepare for implementing TLS
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff
changeset
|
1 package org.monetdb.mcl.net; |
117e7917325d
Prepare for implementing TLS
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff
changeset
|
2 |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
3 import javax.net.ssl.*; |
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
4 import java.io.FileInputStream; |
800
09f463444dde
TLS support in its most basic form
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
799
diff
changeset
|
5 import java.io.IOException; |
805
2fee4b71baac
Set ALPN protocol if the runtime supports it
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
804
diff
changeset
|
6 import java.lang.reflect.InvocationTargetException; |
2fee4b71baac
Set ALPN protocol if the runtime supports it
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
804
diff
changeset
|
7 import java.lang.reflect.Method; |
799
117e7917325d
Prepare for implementing TLS
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff
changeset
|
8 import java.net.Socket; |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
9 import java.security.*; |
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
10 import java.security.cert.CertificateException; |
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
11 import java.security.cert.CertificateFactory; |
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
12 import java.security.cert.X509Certificate; |
804
361441253305
Send SNI (Server Name Indication)
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
801
diff
changeset
|
13 import java.util.Collections; |
799
117e7917325d
Prepare for implementing TLS
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff
changeset
|
14 |
117e7917325d
Prepare for implementing TLS
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff
changeset
|
15 public class SecureSocket { |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
16 private static final String[] ENABLED_PROTOCOLS = {"TLSv1.3"}; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
17 private static final String[] APPLICATION_PROTOCOLS = {"mapi/9"}; |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
18 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
19 public static Socket wrap(Target.Validated validated, Socket inner) throws IOException { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
20 Target.Verify verify = validated.connectVerify(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
21 SSLSocketFactory socketFactory; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
22 boolean checkName = true; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
23 try { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
24 switch (verify) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
25 case System: |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
26 socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
27 break; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
28 case Cert: |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
29 KeyStore keyStore = keyStoreForCert(validated.getCert()); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
30 socketFactory = certBasedSocketFactory(keyStore); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
31 break; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
32 case Hash: |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
33 socketFactory = hashBasedSocketFactory(validated.connectCertHashDigits()); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
34 checkName = false; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
35 break; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
36 default: |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
37 throw new RuntimeException("unreachable: unexpected verification strategy " + verify.name()); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
38 } |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
39 return wrapSocket(inner, validated, socketFactory, checkName); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
40 } catch (CertificateException e) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
41 throw new SSLException(e.getMessage(), e); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
42 } |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
43 } |
805
2fee4b71baac
Set ALPN protocol if the runtime supports it
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
804
diff
changeset
|
44 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
45 private static SSLSocket wrapSocket(Socket inner, Target.Validated validated, SSLSocketFactory socketFactory, boolean checkName) throws IOException { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
46 SSLSocket sock = (SSLSocket) socketFactory.createSocket(inner, validated.connectTcp(), validated.connectPort(), true); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
47 sock.setUseClientMode(true); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
48 SSLParameters parameters = sock.getSSLParameters(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
49 |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
50 parameters.setProtocols(ENABLED_PROTOCOLS); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
51 |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
52 parameters.setServerNames(Collections.singletonList(new SNIHostName(validated.connectTcp()))); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
53 |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
54 if (checkName) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
55 parameters.setEndpointIdentificationAlgorithm("HTTPS"); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
56 } |
805
2fee4b71baac
Set ALPN protocol if the runtime supports it
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
804
diff
changeset
|
57 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
58 // Unfortunately, SSLParameters.setApplicationProtocols is only available |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
59 // since language level 9 and currently we're on 8. |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
60 // Still call it if it happens to be available. |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
61 try { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
62 Method setApplicationProtocols = SSLParameters.class.getMethod("setApplicationProtocols", String[].class); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
63 setApplicationProtocols.invoke(parameters, (Object) APPLICATION_PROTOCOLS); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
64 } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException ignored) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
65 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
66 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
67 sock.setSSLParameters(parameters); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
68 sock.startHandshake(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
69 return sock; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
70 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
71 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
72 private static X509Certificate loadCertificate(String path) throws CertificateException, IOException { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
73 CertificateFactory factory = CertificateFactory.getInstance("X509"); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
74 try (FileInputStream s = new FileInputStream(path)) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
75 return (X509Certificate) factory.generateCertificate(s); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
76 } |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
77 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
78 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
79 private static SSLSocketFactory certBasedSocketFactory(KeyStore store) throws IOException, CertificateException { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
80 TrustManagerFactory trustManagerFactory; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
81 try { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
82 trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
83 trustManagerFactory.init(store); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
84 } catch (NoSuchAlgorithmException | KeyStoreException e) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
85 throw new RuntimeException("Could not create TrustManagerFactory", e); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
86 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
87 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
88 SSLContext context; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
89 try { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
90 context = SSLContext.getInstance("TLS"); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
91 context.init(null, trustManagerFactory.getTrustManagers(), null); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
92 } catch (NoSuchAlgorithmException | KeyManagementException e) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
93 throw new RuntimeException("Could not create SSLContext", e); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
94 } |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
95 |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
96 return context.getSocketFactory(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
97 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
98 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
99 private static KeyStore keyStoreForCert(String path) throws IOException, CertificateException { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
100 try { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
101 X509Certificate cert = loadCertificate(path); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
102 KeyStore store = emptyKeyStore(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
103 store.setCertificateEntry("root", cert); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
104 return store; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
105 } catch (KeyStoreException e) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
106 throw new RuntimeException("Could not create KeyStore for certificate", e); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
107 } |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
108 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
109 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
110 private static KeyStore emptyKeyStore() throws IOException, CertificateException { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
111 KeyStore store; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
112 try { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
113 store = KeyStore.getInstance("PKCS12"); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
114 store.load(null, null); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
115 return store; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
116 } catch (KeyStoreException | NoSuchAlgorithmException e) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
117 throw new RuntimeException("Could not create KeyStore for certificate", e); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
118 } |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
119 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
120 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
121 private static SSLSocketFactory hashBasedSocketFactory(String hashDigits) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
122 TrustManager trustManager = new HashBasedTrustManager(hashDigits); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
123 try { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
124 SSLContext context = SSLContext.getInstance("TLS"); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
125 context.init(null, new TrustManager[]{trustManager}, null); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
126 return context.getSocketFactory(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
127 } catch (NoSuchAlgorithmException | KeyManagementException e) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
128 throw new RuntimeException("Could not create SSLContext", e); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
129 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
130 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
131 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
132 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
133 private static class HashBasedTrustManager implements X509TrustManager { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
134 private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
135 private final String hashDigits; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
136 |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
137 public HashBasedTrustManager(String hashDigits) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
138 this.hashDigits = hashDigits; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
139 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
140 |
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
141 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
142 @Override |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
143 public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
144 throw new RuntimeException("this TrustManager is only suitable for client side connections"); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
145 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
146 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
147 @Override |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
148 public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
149 X509Certificate cert = x509Certificates[0]; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
150 byte[] certBytes = cert.getEncoded(); |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
151 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
152 // for now it's always SHA256. |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
153 byte[] hashBytes; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
154 try { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
155 MessageDigest hasher = MessageDigest.getInstance("SHA-256"); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
156 hasher.update(certBytes); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
157 hashBytes = hasher.digest(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
158 } catch (NoSuchAlgorithmException e) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
159 throw new RuntimeException("failed to instantiate hash digest"); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
160 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
161 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
162 // convert to hex digits |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
163 StringBuilder buffer = new StringBuilder(2 * hashBytes.length); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
164 for (byte b : hashBytes) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
165 int hi = (b & 0xF0) >> 4; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
166 int lo = b & 0x0F; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
167 buffer.append(HEXDIGITS[hi]); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
168 buffer.append(HEXDIGITS[lo]); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
169 } |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
170 String certDigits = buffer.toString(); |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
171 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
172 if (!certDigits.startsWith(hashDigits)) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
173 throw new CertificateException("Certificate hash does not start with '" + hashDigits + "': " + certDigits); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
174 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
175 |
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
176 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
177 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
178 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
179 @Override |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
180 public X509Certificate[] getAcceptedIssuers() { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
181 return new X509Certificate[0]; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
182 } |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
183 } |
799
117e7917325d
Prepare for implementing TLS
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff
changeset
|
184 } |