Mercurial > hg > monetdb-java
annotate src/main/java/org/monetdb/mcl/net/SecureSocket.java @ 864:b80758ef25db
Add missing license headers
author | Martin van Dinther <martin.van.dinther@monetdbsolutions.com> |
---|---|
date | Thu, 01 Feb 2024 17:45:49 +0100 (15 months ago) |
parents | 99ed7dbb2e05 |
children | 2543e24eb79a |
rev | line source |
---|---|
864
b80758ef25db
Add missing license headers
Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
parents:
842
diff
changeset
|
1 /* |
b80758ef25db
Add missing license headers
Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
parents:
842
diff
changeset
|
2 * SPDX-License-Identifier: MPL-2.0 |
b80758ef25db
Add missing license headers
Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
parents:
842
diff
changeset
|
3 * |
b80758ef25db
Add missing license headers
Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
parents:
842
diff
changeset
|
4 * This Source Code Form is subject to the terms of the Mozilla Public |
b80758ef25db
Add missing license headers
Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
parents:
842
diff
changeset
|
5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
b80758ef25db
Add missing license headers
Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
parents:
842
diff
changeset
|
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
b80758ef25db
Add missing license headers
Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
parents:
842
diff
changeset
|
7 * |
b80758ef25db
Add missing license headers
Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
parents:
842
diff
changeset
|
8 * Copyright 2024 MonetDB Foundation; |
b80758ef25db
Add missing license headers
Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
parents:
842
diff
changeset
|
9 * Copyright August 2008 - 2023 MonetDB B.V.; |
b80758ef25db
Add missing license headers
Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
parents:
842
diff
changeset
|
10 * Copyright 1997 - July 2008 CWI. |
b80758ef25db
Add missing license headers
Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
parents:
842
diff
changeset
|
11 */ |
b80758ef25db
Add missing license headers
Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
parents:
842
diff
changeset
|
12 |
799
117e7917325d
Prepare for implementing TLS
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff
changeset
|
13 package org.monetdb.mcl.net; |
117e7917325d
Prepare for implementing TLS
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff
changeset
|
14 |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
15 import javax.net.ssl.*; |
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
16 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
|
17 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
|
18 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
|
19 import java.lang.reflect.Method; |
799
117e7917325d
Prepare for implementing TLS
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff
changeset
|
20 import java.net.Socket; |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
21 import java.security.*; |
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
22 import java.security.cert.CertificateException; |
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
23 import java.security.cert.CertificateFactory; |
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
24 import java.security.cert.X509Certificate; |
804
361441253305
Send SNI (Server Name Indication)
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
801
diff
changeset
|
25 import java.util.Collections; |
799
117e7917325d
Prepare for implementing TLS
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff
changeset
|
26 |
117e7917325d
Prepare for implementing TLS
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff
changeset
|
27 public class SecureSocket { |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
28 private static final String[] ENABLED_PROTOCOLS = {"TLSv1.3"}; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
29 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
|
30 |
842
99ed7dbb2e05
Cache the system trust roots between invocations
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
840
diff
changeset
|
31 // Cache for the default SSL factory. It must load all trust roots |
99ed7dbb2e05
Cache the system trust roots between invocations
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
840
diff
changeset
|
32 // so it's worthwhile to cache. |
99ed7dbb2e05
Cache the system trust roots between invocations
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
840
diff
changeset
|
33 // Only access this through #getDefaultSocketFactory() |
99ed7dbb2e05
Cache the system trust roots between invocations
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
840
diff
changeset
|
34 private static SSLSocketFactory vanillaFactory = null; |
99ed7dbb2e05
Cache the system trust roots between invocations
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
840
diff
changeset
|
35 |
99ed7dbb2e05
Cache the system trust roots between invocations
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
840
diff
changeset
|
36 private static synchronized SSLSocketFactory getDefaultSocketFactory() { |
99ed7dbb2e05
Cache the system trust roots between invocations
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
840
diff
changeset
|
37 if (vanillaFactory == null) { |
99ed7dbb2e05
Cache the system trust roots between invocations
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
840
diff
changeset
|
38 vanillaFactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); |
99ed7dbb2e05
Cache the system trust roots between invocations
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
840
diff
changeset
|
39 } |
99ed7dbb2e05
Cache the system trust roots between invocations
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
840
diff
changeset
|
40 return vanillaFactory; |
99ed7dbb2e05
Cache the system trust roots between invocations
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
840
diff
changeset
|
41 } |
99ed7dbb2e05
Cache the system trust roots between invocations
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
840
diff
changeset
|
42 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
43 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
|
44 Target.Verify verify = validated.connectVerify(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
45 SSLSocketFactory socketFactory; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
46 boolean checkName = true; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
47 try { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
48 switch (verify) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
49 case System: |
842
99ed7dbb2e05
Cache the system trust roots between invocations
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
840
diff
changeset
|
50 socketFactory = getDefaultSocketFactory(); |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
51 break; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
52 case Cert: |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
53 KeyStore keyStore = keyStoreForCert(validated.getCert()); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
54 socketFactory = certBasedSocketFactory(keyStore); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
55 break; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
56 case Hash: |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
57 socketFactory = hashBasedSocketFactory(validated.connectCertHashDigits()); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
58 checkName = false; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
59 break; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
60 default: |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
61 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
|
62 } |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
63 return wrapSocket(inner, validated, socketFactory, checkName); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
64 } catch (CertificateException e) { |
840
a2b1ae53565e
Improve error messages
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
834
diff
changeset
|
65 throw new SSLException("TLS certificate rejected", e); |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
66 } |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
67 } |
805
2fee4b71baac
Set ALPN protocol if the runtime supports it
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
804
diff
changeset
|
68 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
69 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
|
70 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
|
71 sock.setUseClientMode(true); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
72 SSLParameters parameters = sock.getSSLParameters(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
73 |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
74 parameters.setProtocols(ENABLED_PROTOCOLS); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
75 |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
76 parameters.setServerNames(Collections.singletonList(new SNIHostName(validated.connectTcp()))); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
77 |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
78 if (checkName) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
79 parameters.setEndpointIdentificationAlgorithm("HTTPS"); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
80 } |
805
2fee4b71baac
Set ALPN protocol if the runtime supports it
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
804
diff
changeset
|
81 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
82 // Unfortunately, SSLParameters.setApplicationProtocols is only available |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
83 // 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
|
84 // 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
|
85 try { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
86 Method setApplicationProtocols = SSLParameters.class.getMethod("setApplicationProtocols", String[].class); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
87 setApplicationProtocols.invoke(parameters, (Object) APPLICATION_PROTOCOLS); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
88 } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException ignored) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
89 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
90 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
91 sock.setSSLParameters(parameters); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
92 sock.startHandshake(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
93 return sock; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
94 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
95 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
96 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
|
97 CertificateFactory factory = CertificateFactory.getInstance("X509"); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
98 try (FileInputStream s = new FileInputStream(path)) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
99 return (X509Certificate) factory.generateCertificate(s); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
100 } |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
101 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
102 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
103 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
|
104 TrustManagerFactory trustManagerFactory; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
105 try { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
106 trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
107 trustManagerFactory.init(store); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
108 } catch (NoSuchAlgorithmException | KeyStoreException e) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
109 throw new RuntimeException("Could not create TrustManagerFactory", e); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
110 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
111 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
112 SSLContext context; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
113 try { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
114 context = SSLContext.getInstance("TLS"); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
115 context.init(null, trustManagerFactory.getTrustManagers(), null); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
116 } catch (NoSuchAlgorithmException | KeyManagementException e) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
117 throw new RuntimeException("Could not create SSLContext", 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 |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
120 return context.getSocketFactory(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
121 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
122 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
123 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
|
124 try { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
125 X509Certificate cert = loadCertificate(path); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
126 KeyStore store = emptyKeyStore(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
127 store.setCertificateEntry("root", cert); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
128 return store; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
129 } catch (KeyStoreException e) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
130 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
|
131 } |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
132 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
133 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
134 private static KeyStore emptyKeyStore() throws IOException, CertificateException { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
135 KeyStore store; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
136 try { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
137 store = KeyStore.getInstance("PKCS12"); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
138 store.load(null, null); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
139 return store; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
140 } catch (KeyStoreException | NoSuchAlgorithmException e) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
141 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
|
142 } |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
143 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
144 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
145 private static SSLSocketFactory hashBasedSocketFactory(String hashDigits) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
146 TrustManager trustManager = new HashBasedTrustManager(hashDigits); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
147 try { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
148 SSLContext context = SSLContext.getInstance("TLS"); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
149 context.init(null, new TrustManager[]{trustManager}, null); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
150 return context.getSocketFactory(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
151 } catch (NoSuchAlgorithmException | KeyManagementException e) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
152 throw new RuntimeException("Could not create SSLContext", e); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
153 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
154 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
155 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
156 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
157 private static class HashBasedTrustManager implements X509TrustManager { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
158 private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
159 private final String hashDigits; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
160 |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
161 public HashBasedTrustManager(String hashDigits) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
162 this.hashDigits = hashDigits; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
163 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
164 |
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
165 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
166 @Override |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
167 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
|
168 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
|
169 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
170 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
171 @Override |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
172 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
|
173 X509Certificate cert = x509Certificates[0]; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
174 byte[] certBytes = cert.getEncoded(); |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
175 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
176 // for now it's always SHA256. |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
177 byte[] hashBytes; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
178 try { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
179 MessageDigest hasher = MessageDigest.getInstance("SHA-256"); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
180 hasher.update(certBytes); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
181 hashBytes = hasher.digest(); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
182 } catch (NoSuchAlgorithmException e) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
183 throw new RuntimeException("failed to instantiate hash digest"); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
184 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
185 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
186 // convert to hex digits |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
187 StringBuilder buffer = new StringBuilder(2 * hashBytes.length); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
188 for (byte b : hashBytes) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
189 int hi = (b & 0xF0) >> 4; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
190 int lo = b & 0x0F; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
191 buffer.append(HEXDIGITS[hi]); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
192 buffer.append(HEXDIGITS[lo]); |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
193 } |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
194 String certDigits = buffer.toString(); |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
195 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
196 if (!certDigits.startsWith(hashDigits)) { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
197 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
|
198 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
199 |
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
200 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
201 } |
801
88b3e8e89126
TLS seems to work
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
800
diff
changeset
|
202 |
834
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
203 @Override |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
204 public X509Certificate[] getAcceptedIssuers() { |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
205 return new X509Certificate[0]; |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
206 } |
5aa19bbed0d6
Comments and formatting
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
805
diff
changeset
|
207 } |
799
117e7917325d
Prepare for implementing TLS
Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
parents:
diff
changeset
|
208 } |