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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }