Skip to content
Permalink
Browse files

[CONJ-678] permit to indicate truststore/keystore type, not relying o…

…n java default type

(cherry picked from commit 04251f9)
  • Loading branch information...
rusher committed Jan 24, 2019
1 parent 48829cd commit b6a7fa5fbc9faaa7e3ad7f325ae6226d741ea55b
@@ -2,7 +2,7 @@ version: '2.1'
services:
db:
image: $DB
command: --max-connections=500 --max-allowed-packet=$PACKET --innodb-log-file-size=$INNODB_LOG_FILE_SIZE --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --ssl-ca=/etc/sslcert/ca.crt --ssl-cert=/etc/sslcert/server.crt --ssl-key=/etc/sslcert/server.key --bind-address=0.0.0.0 $ADDITIONAL_CONF
command: --max-connections=500 --max-allowed-packet=$PACKET --innodb-log-file-size=$INNODB_LOG_FILE_SIZE --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --ssl-ca=/etc/sslcert/ca.crt --ssl-cert=/etc/sslcert/server.crt --ssl-key=/etc/sslcert/server.key --bind-address=0.0.0.0 --performance-schema=ON $ADDITIONAL_CONF
ports:
- 3305:3306
volumes:
@@ -396,7 +396,7 @@ private KeyManager loadClientCerts(String keyStoreUrl, String keyStorePassword,
inStream = new FileInputStream(keyStoreUrl);
}

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
KeyStore ks = KeyStore.getInstance(options.keyStoreType != null ? options.keyStoreType : KeyStore.getDefaultType());
ks.load(inStream, keyStorePasswordChars);
char[] keyStoreChars =
(keyPassword == null) ? keyStorePasswordChars : keyPassword.toCharArray();
@@ -52,13 +52,13 @@

package org.mariadb.jdbc.internal.protocol.tls;

import org.mariadb.jdbc.internal.util.Options;
import org.mariadb.jdbc.internal.util.SqlStates;
import static org.mariadb.jdbc.internal.util.SqlStates.CONNECTION_EXCEPTION;

import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.io.*;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
@@ -70,145 +70,162 @@
import java.sql.SQLException;
import java.util.Collection;
import java.util.UUID;

import static org.mariadb.jdbc.internal.util.SqlStates.CONNECTION_EXCEPTION;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import org.mariadb.jdbc.internal.util.Options;
import org.mariadb.jdbc.internal.util.SqlStates;

public class MariaDbX509TrustManager implements X509TrustManager {
private X509TrustManager trustManager;

/**
* MyX509TrustManager.
*
* @param options parsed url options
* @throws SQLException exception
*/
public MariaDbX509TrustManager(Options options) throws SQLException {
//if trustServerCertificate is true, will have a X509TrustManager implementation that validate all.
if (options.trustServerCertificate) return;

KeyStore ks;

private X509TrustManager trustManager;

/**
* MyX509TrustManager.
*
* @param options parsed url options
* @throws SQLException exception
*/
public MariaDbX509TrustManager(Options options) throws SQLException {
//if trustServerCertificate is true, will have a X509TrustManager implementation that validate all.
if (options.trustServerCertificate) {
return;
}

KeyStore ks;
try {
ks = KeyStore.getInstance(options.trustStoreType != null ? options.trustStoreType : KeyStore.getDefaultType());
} catch (GeneralSecurityException generalSecurityEx) {
throw new SQLException("Failed to create keystore instance",
SqlStates.CONNECTION_EXCEPTION.getSqlState(), generalSecurityEx);
}

InputStream inStream = null;
try {
if (options.trustStore != null) {
// use the provided keyStore
try {
ks = KeyStore.getInstance(KeyStore.getDefaultType());
String trustStore = options.trustStore;

try {
inStream = new URL(trustStore).openStream();
} catch (IOException ioexception) {
inStream = new FileInputStream(trustStore);
}
ks.load(inStream,
options.trustStorePassword == null ? null : options.trustStorePassword.toCharArray());

} catch (GeneralSecurityException generalSecurityEx) {
throw new SQLException("Failed to create keystore instance", SqlStates.CONNECTION_EXCEPTION.getSqlState(), generalSecurityEx);
throw new SQLException("Failed to create trustStore instance",
CONNECTION_EXCEPTION.getSqlState(), generalSecurityEx);
} catch (FileNotFoundException fileNotFoundEx) {
throw new SQLException("Failed to find trustStore file. trustStore=" + options.trustStore,
CONNECTION_EXCEPTION.getSqlState(), fileNotFoundEx);
} catch (IOException ioEx) {
throw new SQLException("Failed to read trustStore file. trustStore=" + options.trustStore,
CONNECTION_EXCEPTION.getSqlState(), ioEx);
}

InputStream inStream = null;
try {
if (options.trustStore != null) {
// use the provided keyStore
try {
String trustStore = options.trustStore;

try {
inStream = new URL(trustStore).openStream();
} catch (IOException ioexception) {
inStream = new FileInputStream(trustStore);
}
ks.load(inStream,
options.trustStorePassword == null ? null : options.trustStorePassword.toCharArray());

} catch (GeneralSecurityException generalSecurityEx) {
throw new SQLException("Failed to create trustStore instance",
CONNECTION_EXCEPTION.getSqlState(), generalSecurityEx);
} catch (FileNotFoundException fileNotFoundEx) {
throw new SQLException("Failed to find trustStore file. trustStore=" + options.trustStore,
CONNECTION_EXCEPTION.getSqlState(), fileNotFoundEx);
} catch (IOException ioEx) {
throw new SQLException("Failed to read trustStore file. trustStore=" + options.trustStore,
CONNECTION_EXCEPTION.getSqlState(), ioEx);
}
} else {
// generate a keyStore from the provided cert
if (options.serverSslCert.startsWith("-----BEGIN CERTIFICATE-----")) {
inStream = new ByteArrayInputStream(options.serverSslCert.getBytes());
} else if (options.serverSslCert.startsWith("classpath:")) {
// Load it from a classpath relative file
String classpathFile = options.serverSslCert.substring("classpath:".length());
inStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(classpathFile);
} else {
try {
inStream = new FileInputStream(options.serverSslCert);
} catch (FileNotFoundException fileNotFoundEx) {
throw new SQLException("Failed to find serverSslCert file. serverSslCert=" + options.serverSslCert,
CONNECTION_EXCEPTION.getSqlState(), fileNotFoundEx);
}
}

try {
// Note: KeyStore requires it be loaded even if you don't load anything into it
// (will be initialized with "javax.net.ssl.trustStore") values.
ks.load(null);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Collection<? extends Certificate> caList = cf.generateCertificates(inStream);
for (Certificate ca : caList) {
ks.setCertificateEntry(UUID.randomUUID().toString(), ca);
}
} catch (IOException ioEx) {
throw new SQLException("Failed load keyStore", CONNECTION_EXCEPTION.getSqlState(), ioEx);
} catch (GeneralSecurityException generalSecurityEx) {
throw new SQLException("Failed to store certificate from serverSslCert into a keyStore",
CONNECTION_EXCEPTION.getSqlState(), generalSecurityEx);
}

}
} finally {
if (inStream != null) {
try {
inStream.close();
} catch (IOException ioEx) {
//ignore error
}
}
} else {
// generate a keyStore from the provided cert
if (options.serverSslCert.startsWith("-----BEGIN CERTIFICATE-----")) {
inStream = new ByteArrayInputStream(options.serverSslCert.getBytes());
} else if (options.serverSslCert.startsWith("classpath:")) {
// Load it from a classpath relative file
String classpathFile = options.serverSslCert.substring("classpath:".length());
inStream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(classpathFile);
} else {
try {
inStream = new FileInputStream(options.serverSslCert);
} catch (FileNotFoundException fileNotFoundEx) {
throw new SQLException(
"Failed to find serverSslCert file. serverSslCert=" + options.serverSslCert,
CONNECTION_EXCEPTION.getSqlState(), fileNotFoundEx);
}
}

try {
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
for (TrustManager tm : tmf.getTrustManagers()) {
if (tm instanceof X509TrustManager) {
trustManager = (X509TrustManager) tm;
break;
}
}
} catch (NoSuchAlgorithmException noSuchAlgorithmEx) {
throw new SQLException("Failed to create TrustManagerFactory default instance",
CONNECTION_EXCEPTION.getSqlState(), noSuchAlgorithmEx);
// Note: KeyStore requires it be loaded even if you don't load anything into it
// (will be initialized with "javax.net.ssl.trustStore") values.
ks.load(null);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Collection<? extends Certificate> caList = cf.generateCertificates(inStream);
for (Certificate ca : caList) {
ks.setCertificateEntry(UUID.randomUUID().toString(), ca);
}
} catch (IOException ioEx) {
throw new SQLException("Failed load keyStore", CONNECTION_EXCEPTION.getSqlState(), ioEx);
} catch (GeneralSecurityException generalSecurityEx) {
throw new SQLException("Failed to initialize trust manager", CONNECTION_EXCEPTION.getSqlState(), generalSecurityEx);
throw new SQLException("Failed to store certificate from serverSslCert into a keyStore",
CONNECTION_EXCEPTION.getSqlState(), generalSecurityEx);
}

if (trustManager == null) {
throw new SQLException("No X509TrustManager found");
}
} finally {
if (inStream != null) {
try {
inStream.close();
} catch (IOException ioEx) {
//ignore error
}
}
}

/**
* Check client trusted.
*
* @param x509Certificates certificate
* @param string string
* @throws CertificateException exception
*/
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String string) throws CertificateException {
if (trustManager == null) return;
trustManager.checkClientTrusted(x509Certificates, string);
try {
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
for (TrustManager tm : tmf.getTrustManagers()) {
if (tm instanceof X509TrustManager) {
trustManager = (X509TrustManager) tm;
break;
}
}
} catch (NoSuchAlgorithmException noSuchAlgorithmEx) {
throw new SQLException("Failed to create TrustManagerFactory default instance",
CONNECTION_EXCEPTION.getSqlState(), noSuchAlgorithmEx);
} catch (GeneralSecurityException generalSecurityEx) {
throw new SQLException("Failed to initialize trust manager",
CONNECTION_EXCEPTION.getSqlState(), generalSecurityEx);
}

/**
* Check server trusted.
*
* @param x509Certificates certificate
* @param string string
* @throws CertificateException exception
*/
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String string) throws CertificateException {
if (trustManager == null) return;
trustManager.checkServerTrusted(x509Certificates, string);
if (trustManager == null) {
throw new SQLException("No X509TrustManager found");
}

public X509Certificate[] getAcceptedIssuers() {
return null;
}

/**
* Check client trusted.
*
* @param x509Certificates certificate
* @param string string
* @throws CertificateException exception
*/
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String string)
throws CertificateException {
if (trustManager == null) {
return;
}
trustManager.checkClientTrusted(x509Certificates, string);
}

/**
* Check server trusted.
*
* @param x509Certificates certificate
* @param string string
* @throws CertificateException exception
*/
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String string)
throws CertificateException {
if (trustManager == null) {
return;
}
trustManager.checkServerTrusted(x509Certificates, string);
}

public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
@@ -5,21 +5,24 @@

public class OptionUtils {

public static final Map<String, DefaultOptions> OPTIONS_MAP;
public static final Map<String, DefaultOptions> OPTIONS_MAP;

static {
OPTIONS_MAP = new HashMap<String, DefaultOptions>();
for (DefaultOptions defaultOption : DefaultOptions.values()) {
OPTIONS_MAP.put(defaultOption.getOptionName(), defaultOption);
}
//add alias
OPTIONS_MAP.put("createDB", DefaultOptions.CREATE_DATABASE_IF_NOT_EXISTS);
OPTIONS_MAP.put("useSSL", DefaultOptions.USE_SSL);
OPTIONS_MAP.put("profileSQL", DefaultOptions.PROFILE_SQL);
OPTIONS_MAP.put("enabledSSLCipherSuites", DefaultOptions.ENABLED_SSL_CIPHER_SUITES);
OPTIONS_MAP.put("trustCertificateKeyStorePassword", DefaultOptions.TRUST_CERTIFICATE_KEYSTORE_PASSWORD);
OPTIONS_MAP.put("trustCertificateKeyStoreUrl", DefaultOptions.TRUSTSTORE);
OPTIONS_MAP.put("clientCertificateKeyStorePassword", DefaultOptions.KEYSTORE_PASSWORD);
OPTIONS_MAP.put("clientCertificateKeyStoreUrl", DefaultOptions.KEYSTORE);
static {
OPTIONS_MAP = new HashMap<>();
for (DefaultOptions defaultOption : DefaultOptions.values()) {
OPTIONS_MAP.put(defaultOption.getOptionName(), defaultOption);
}
//add alias
OPTIONS_MAP.put("createDB", DefaultOptions.CREATE_DATABASE_IF_NOT_EXISTS);
OPTIONS_MAP.put("useSSL", DefaultOptions.USE_SSL);
OPTIONS_MAP.put("profileSQL", DefaultOptions.PROFILE_SQL);
OPTIONS_MAP.put("enabledSSLCipherSuites", DefaultOptions.ENABLED_SSL_CIPHER_SUITES);
OPTIONS_MAP.put("trustCertificateKeyStorePassword",
DefaultOptions.TRUST_CERTIFICATE_KEYSTORE_PASSWORD);
OPTIONS_MAP.put("trustCertificateKeyStoreUrl", DefaultOptions.TRUSTSTORE);
OPTIONS_MAP.put("clientCertificateKeyStorePassword", DefaultOptions.KEYSTORE_PASSWORD);
OPTIONS_MAP.put("clientCertificateKeyStoreUrl", DefaultOptions.KEYSTORE);
OPTIONS_MAP.put("trustCertificateKeyStoreType", DefaultOptions.TRUST_STORE_TYPE);
OPTIONS_MAP.put("clientCertificateKeyStoreType", DefaultOptions.KEY_STORE_TYPE);
}
}
@@ -68,6 +68,8 @@
public boolean trustServerCertificate;
public String serverSslCert;
public String trustStore;
public String trustStoreType;
public String keyStoreType;
public String trustStorePassword;
public String keyStore;
public String keyStorePassword;

0 comments on commit b6a7fa5

Please sign in to comment.
You can’t perform that action at this time.