This is an automated email from the ASF dual-hosted git repository.

vavrtom pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-broker-j.git


The following commit(s) were added to refs/heads/main by this push:
     new cb51d8d31e QPID-8667: [Broker-J] Database connection with client 
certificate authentication exposes keystore / truststore passwords (#236)
cb51d8d31e is described below

commit cb51d8d31efe24198190264b1bbde7923252810a
Author: Daniil Kirilyuk <[email protected]>
AuthorDate: Mon Jan 29 13:51:02 2024 +0100

    QPID-8667: [Broker-J] Database connection with client certificate 
authentication exposes keystore / truststore passwords (#236)
---
 .../logging/logback/jdbc/JDBCBrokerLogger.java     |  30 ++++++
 .../logging/logback/jdbc/JDBCBrokerLoggerImpl.java |  56 +++++++++++
 .../logback/jdbc/JDBCVirtualHostLogger.java        |  30 ++++++
 .../logback/jdbc/JDBCVirtualHostLoggerImpl.java    |  56 +++++++++++
 .../jdbc/hikaricp/HikariCPConnectionProvider.java  |  57 ++++++++++-
 .../HikariCPConnectionProviderFactory.java         |  17 +++-
 .../hikaricp/HikariCPConnectionProviderTest.java   |  30 +++++-
 .../jdbc/DefaultConnectionProviderFactory.java     |  14 ++-
 .../server/store/jdbc/GenericJDBCMessageStore.java |   5 +-
 .../store/jdbc/JDBCConnectionProviderFactory.java  |  16 ++-
 .../qpid/server/store/jdbc/JDBCSettings.java       |  14 +++
 .../qpid/server/store/jdbc/JDBCSystemConfig.java   |  30 ++++++
 .../server/store/jdbc/JDBCSystemConfigImpl.java    |  50 ++++++++++
 .../apache/qpid/server/store/jdbc/JdbcUtils.java   |   6 ++
 .../server/virtualhost/jdbc/JDBCVirtualHost.java   |  29 ++++++
 .../virtualhost/jdbc/JDBCVirtualHostImpl.java      |  56 +++++++++++
 .../virtualhostnode/jdbc/JDBCVirtualHostNode.java  |  30 ++++++
 .../jdbc/JDBCVirtualHostNodeImpl.java              |  56 +++++++++++
 .../qpid/management/store/pool/ConnectionPool.js   |  55 ++++++++---
 .../js/qpid/management/virtualhost/jdbc/add.js     |  58 ++++++-----
 .../js/qpid/management/virtualhost/jdbc/edit.js    |  61 +++++++++---
 .../main/java/resources/virtualhost/jdbc/add.html  | 109 ++++++++++++++++++++-
 .../main/java/resources/virtualhost/jdbc/edit.html | 106 +++++++++++++++++++-
 .../management/addVirtualHostNodeAndVirtualHost.js | 107 +++++++++++++-------
 24 files changed, 974 insertions(+), 104 deletions(-)

diff --git 
a/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCBrokerLogger.java
 
b/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCBrokerLogger.java
index b80913bbf1..603c3b5cff 100644
--- 
a/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCBrokerLogger.java
+++ 
b/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCBrokerLogger.java
@@ -22,6 +22,8 @@ package org.apache.qpid.server.logging.logback.jdbc;
 import org.apache.qpid.server.model.BrokerLogger;
 import org.apache.qpid.server.model.ManagedAttribute;
 import org.apache.qpid.server.model.ManagedContextDefault;
+import org.apache.qpid.server.security.FileKeyStore;
+import org.apache.qpid.server.security.FileTrustStore;
 import org.apache.qpid.server.store.jdbc.DefaultConnectionProviderFactory;
 import org.apache.qpid.server.store.jdbc.JDBCSettings;
 
@@ -52,4 +54,32 @@ public interface JDBCBrokerLogger<X extends 
JDBCBrokerLogger<X>> extends BrokerL
     @Override
     @ManagedAttribute
     String getTableNamePrefix();
+
+    @Override
+    @ManagedAttribute(description = "Optional keystore holding the key for 
secure database connection")
+    FileKeyStore<?> getKeyStore();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
keystore path property, " +
+            "property value is taken from the keystore")
+    String getKeyStorePathPropertyName();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
keystore password property, " +
+            "property value is taken from the keystore")
+    String getKeyStorePasswordPropertyName();
+
+    @Override
+    @ManagedAttribute(description = "Optional truststore holding the 
certificate for secure database connection")
+    FileTrustStore<?> getTrustStore();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
truststore path property, " +
+            "property value is taken from the truststore")
+    String getTrustStorePathPropertyName();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
truststore password property, " +
+            "property value is taken from the truststore")
+    String getTrustStorePasswordPropertyName();
 }
diff --git 
a/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCBrokerLoggerImpl.java
 
b/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCBrokerLoggerImpl.java
index 6af6c09ba0..72dcd4f6b6 100644
--- 
a/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCBrokerLoggerImpl.java
+++ 
b/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCBrokerLoggerImpl.java
@@ -37,6 +37,8 @@ import org.apache.qpid.server.model.ManagedAttributeField;
 import org.apache.qpid.server.model.ManagedObject;
 import org.apache.qpid.server.model.ManagedObjectFactoryConstructor;
 import org.apache.qpid.server.model.SystemConfig;
+import org.apache.qpid.server.security.FileKeyStore;
+import org.apache.qpid.server.security.FileTrustStore;
 import org.apache.qpid.server.store.jdbc.JDBCSettings;
 
 @SuppressWarnings("unused")
@@ -66,6 +68,24 @@ public class JDBCBrokerLoggerImpl extends 
AbstractBrokerLogger<JDBCBrokerLoggerI
     @ManagedAttributeField(afterSet = "restartAppenderIfExists")
     private String _tableNamePrefix;
 
+    @ManagedAttributeField(afterSet = "restartConnectionSourceIfExists")
+    private FileKeyStore<?> _keyStore;
+
+    @ManagedAttributeField(afterSet = "restartConnectionSourceIfExists")
+    private String _keyStorePathPropertyName;
+
+    @ManagedAttributeField(afterSet = "restartConnectionSourceIfExists")
+    private String _keyStorePasswordPropertyName;
+
+    @ManagedAttributeField(afterSet = "restartConnectionSourceIfExists")
+    private FileTrustStore<?> _trustStore;
+
+    @ManagedAttributeField(afterSet = "restartConnectionSourceIfExists")
+    private String _trustStorePathPropertyName;
+
+    @ManagedAttributeField(afterSet = "restartConnectionSourceIfExists")
+    private String _trustStorePasswordPropertyName;
+
     @ManagedObjectFactoryConstructor
     protected JDBCBrokerLoggerImpl(final Map<String, Object> attributes, 
Broker<?> broker)
     {
@@ -103,6 +123,42 @@ public class JDBCBrokerLoggerImpl extends 
AbstractBrokerLogger<JDBCBrokerLoggerI
         return _tableNamePrefix;
     }
 
+    @Override
+    public FileKeyStore<?> getKeyStore()
+    {
+        return _keyStore;
+    }
+
+    @Override
+    public String getKeyStorePathPropertyName()
+    {
+        return _keyStorePathPropertyName;
+    }
+
+    @Override
+    public String getKeyStorePasswordPropertyName()
+    {
+        return _keyStorePasswordPropertyName;
+    }
+
+    @Override
+    public FileTrustStore<?> getTrustStore()
+    {
+        return _trustStore;
+    }
+
+    @Override
+    public String getTrustStorePathPropertyName()
+    {
+        return _trustStorePathPropertyName;
+    }
+
+    @Override
+    public String getTrustStorePasswordPropertyName()
+    {
+        return _trustStorePasswordPropertyName;
+    }
+
     @Override
     protected ListenableFuture<Void> onClose()
     {
diff --git 
a/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCVirtualHostLogger.java
 
b/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCVirtualHostLogger.java
index bbac661403..446988131d 100644
--- 
a/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCVirtualHostLogger.java
+++ 
b/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCVirtualHostLogger.java
@@ -21,6 +21,8 @@ package org.apache.qpid.server.logging.logback.jdbc;
 
 import org.apache.qpid.server.model.ManagedAttribute;
 import org.apache.qpid.server.model.VirtualHostLogger;
+import org.apache.qpid.server.security.FileKeyStore;
+import org.apache.qpid.server.security.FileTrustStore;
 import org.apache.qpid.server.store.jdbc.DefaultConnectionProviderFactory;
 import org.apache.qpid.server.store.jdbc.JDBCSettings;
 
@@ -46,4 +48,32 @@ public interface JDBCVirtualHostLogger<X extends 
JDBCVirtualHostLogger<X>> exten
     @Override
     @ManagedAttribute
     String getTableNamePrefix();
+
+    @Override
+    @ManagedAttribute(description = "Optional keystore holding the key for 
secure database connection")
+    FileKeyStore<?> getKeyStore();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
keystore path property, " +
+            "property value is taken from the keystore")
+    String getKeyStorePathPropertyName();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
keystore password property, " +
+            "property value is taken from the keystore")
+    String getKeyStorePasswordPropertyName();
+
+    @Override
+    @ManagedAttribute(description = "Optional truststore holding the 
certificate for secure database connection")
+    FileTrustStore<?> getTrustStore();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
truststore path property, " +
+            "property value is taken from the truststore")
+    String getTrustStorePathPropertyName();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
truststore password property, " +
+            "property value is taken from the truststore")
+    String getTrustStorePasswordPropertyName();
 }
diff --git 
a/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCVirtualHostLoggerImpl.java
 
b/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCVirtualHostLoggerImpl.java
index 6eca1c27c0..ef45db9b62 100644
--- 
a/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCVirtualHostLoggerImpl.java
+++ 
b/broker-plugins/jdbc-logging-logback/src/main/java/org/apache/qpid/server/logging/logback/jdbc/JDBCVirtualHostLoggerImpl.java
@@ -33,6 +33,8 @@ import org.apache.qpid.server.model.ManagedAttributeField;
 import org.apache.qpid.server.model.ManagedObject;
 import org.apache.qpid.server.model.ManagedObjectFactoryConstructor;
 import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.security.FileKeyStore;
+import org.apache.qpid.server.security.FileTrustStore;
 import org.apache.qpid.server.store.jdbc.JDBCSettings;
 
 @SuppressWarnings("unused")
@@ -62,6 +64,24 @@ public class JDBCVirtualHostLoggerImpl extends 
AbstractVirtualHostLogger<JDBCVir
     @ManagedAttributeField(afterSet = "restartAppenderIfExists")
     private String _tableNamePrefix;
 
+    @ManagedAttributeField(afterSet = "restartConnectionSourceIfExists")
+    private FileKeyStore<?> _keyStore;
+
+    @ManagedAttributeField(afterSet = "restartConnectionSourceIfExists")
+    private String _keyStorePathPropertyName;
+
+    @ManagedAttributeField(afterSet = "restartConnectionSourceIfExists")
+    private String _keyStorePasswordPropertyName;
+
+    @ManagedAttributeField(afterSet = "restartConnectionSourceIfExists")
+    private FileTrustStore<?> _trustStore;
+
+    @ManagedAttributeField(afterSet = "restartConnectionSourceIfExists")
+    private String _trustStorePathPropertyName;
+
+    @ManagedAttributeField(afterSet = "restartConnectionSourceIfExists")
+    private String _trustStorePasswordPropertyName;
+
     @ManagedObjectFactoryConstructor
     protected JDBCVirtualHostLoggerImpl(final Map<String, Object> attributes, 
VirtualHost<?> virtualHost)
     {
@@ -99,6 +119,42 @@ public class JDBCVirtualHostLoggerImpl extends 
AbstractVirtualHostLogger<JDBCVir
         return _tableNamePrefix;
     }
 
+    @Override
+    public FileKeyStore<?> getKeyStore()
+    {
+        return _keyStore;
+    }
+
+    @Override
+    public String getKeyStorePathPropertyName()
+    {
+        return _keyStorePathPropertyName;
+    }
+
+    @Override
+    public String getKeyStorePasswordPropertyName()
+    {
+        return _keyStorePasswordPropertyName;
+    }
+
+    @Override
+    public FileTrustStore<?> getTrustStore()
+    {
+        return _trustStore;
+    }
+
+    @Override
+    public String getTrustStorePathPropertyName()
+    {
+        return _trustStorePathPropertyName;
+    }
+
+    @Override
+    public String getTrustStorePasswordPropertyName()
+    {
+        return _trustStorePasswordPropertyName;
+    }
+
     @Override
     protected void validateChange(ConfiguredObject<?> proxyForValidation, 
Set<String> changedAttributes)
     {
diff --git 
a/broker-plugins/jdbc-provider-hikari/src/main/java/org/apache/qpid/server/store/jdbc/hikaricp/HikariCPConnectionProvider.java
 
b/broker-plugins/jdbc-provider-hikari/src/main/java/org/apache/qpid/server/store/jdbc/hikaricp/HikariCPConnectionProvider.java
index 62b5c68e4c..1e046f6e2f 100644
--- 
a/broker-plugins/jdbc-provider-hikari/src/main/java/org/apache/qpid/server/store/jdbc/hikaricp/HikariCPConnectionProvider.java
+++ 
b/broker-plugins/jdbc-provider-hikari/src/main/java/org/apache/qpid/server/store/jdbc/hikaricp/HikariCPConnectionProvider.java
@@ -33,12 +33,21 @@ import java.util.stream.Collectors;
 
 import com.zaxxer.hikari.HikariConfig;
 import com.zaxxer.hikari.HikariDataSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.server.security.FileKeyStore;
+import org.apache.qpid.server.security.FileTrustStore;
 import org.apache.qpid.server.store.jdbc.ConnectionProvider;
 
 public class HikariCPConnectionProvider implements ConnectionProvider
 {
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(HikariCPConnectionProvider.class);
+    private static final String ADDING_DATASOURCE_PROPERTY = "Adding 
dataSource property '{}' with value '{}'";
+
     public static final int DEFAULT_MIN_IDLE = 20;
     public static final int DEFAULT_MAX_POOLSIZE = 40;
 
@@ -47,15 +56,28 @@ public class HikariCPConnectionProvider implements 
ConnectionProvider
     public HikariCPConnectionProvider(final String connectionUrl,
                                       final String username,
                                       final String password,
+                                      final KeyStore<?> keyStore,
+                                      final String keyStorePathPropertyName,
+                                      final String 
keyStorePasswordPropertyName,
+                                      final TrustStore<?> trustStore,
+                                      final String trustStorePathPropertyName,
+                                      final String 
trustStorePasswordPropertyName,
                                       final Map<String, String> 
providerAttributes)
     {
-        final HikariConfig config = createHikariCPConfig(connectionUrl, 
username, password, providerAttributes);
+        final HikariConfig config = createHikariCPConfig(connectionUrl, 
username, password, keyStore, keyStorePathPropertyName,
+                keyStorePasswordPropertyName, trustStore, 
trustStorePathPropertyName, trustStorePasswordPropertyName, providerAttributes);
         _dataSource = new HikariDataSource(config);
     }
 
     static HikariConfig createHikariCPConfig(final String connectionUrl,
                                              final String username,
                                              final String password,
+                                             final KeyStore<?> keyStore,
+                                             final String 
keyStorePathPropertyName,
+                                             final String 
keyStorePasswordPropertyName,
+                                             final TrustStore<?> trustStore,
+                                             final String 
trustStorePathPropertyName,
+                                             final String 
trustStorePasswordPropertyName,
                                              final Map<String, String> 
providerAttributes)
     {
         final Map<String, String> attributes = new 
HashMap<>(providerAttributes);
@@ -77,8 +99,41 @@ public class HikariCPConnectionProvider implements 
ConnectionProvider
             if (username != null)
             {
                 config.setUsername(username);
+            }
+            if (password != null)
+            {
                 config.setPassword(password);
             }
+            if (keyStore instanceof FileKeyStore)
+            {
+                if (keyStorePathPropertyName != null)
+                {
+                    final String path = ((FileKeyStore) keyStore).getPath();
+                    LOGGER.debug(ADDING_DATASOURCE_PROPERTY, 
keyStorePathPropertyName, path);
+                    config.addDataSourceProperty(keyStorePathPropertyName, 
path);
+                }
+                if (keyStorePasswordPropertyName != null)
+                {
+                    final String pwd = ((FileKeyStore) keyStore).getPassword() 
== null ? "null" : "******";
+                    LOGGER.debug(ADDING_DATASOURCE_PROPERTY, 
keyStorePasswordPropertyName, pwd);
+                    config.addDataSourceProperty(keyStorePasswordPropertyName, 
((FileKeyStore) keyStore).getPassword());
+                }
+            }
+            if (trustStore instanceof FileTrustStore)
+            {
+                if (trustStorePathPropertyName != null)
+                {
+                    final String path = ((FileTrustStore) 
trustStore).getPath();
+                    LOGGER.debug(ADDING_DATASOURCE_PROPERTY, 
trustStorePathPropertyName, path);
+                    config.addDataSourceProperty(trustStorePathPropertyName, 
((FileTrustStore) trustStore).getPath());
+                }
+                if (trustStorePasswordPropertyName != null)
+                {
+                    final String pwd = ((FileTrustStore) 
trustStore).getPassword() == null ? "null" : "******";
+                    LOGGER.debug(ADDING_DATASOURCE_PROPERTY, 
trustStorePasswordPropertyName, pwd);
+                    
config.addDataSourceProperty(trustStorePasswordPropertyName, ((FileTrustStore) 
trustStore).getPassword());
+                }
+            }
             return config;
         }
         catch (Exception e)
diff --git 
a/broker-plugins/jdbc-provider-hikari/src/main/java/org/apache/qpid/server/store/jdbc/hikaricp/HikariCPConnectionProviderFactory.java
 
b/broker-plugins/jdbc-provider-hikari/src/main/java/org/apache/qpid/server/store/jdbc/hikaricp/HikariCPConnectionProviderFactory.java
index fad7577b77..c553b4cc38 100644
--- 
a/broker-plugins/jdbc-provider-hikari/src/main/java/org/apache/qpid/server/store/jdbc/hikaricp/HikariCPConnectionProviderFactory.java
+++ 
b/broker-plugins/jdbc-provider-hikari/src/main/java/org/apache/qpid/server/store/jdbc/hikaricp/HikariCPConnectionProviderFactory.java
@@ -29,6 +29,8 @@ import java.util.stream.Collectors;
 
 import com.zaxxer.hikari.HikariConfig;
 
+import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.TrustStore;
 import org.apache.qpid.server.plugin.PluggableService;
 import org.apache.qpid.server.store.jdbc.ConnectionProvider;
 import org.apache.qpid.server.store.jdbc.JDBCConnectionProviderFactory;
@@ -64,9 +66,20 @@ public class HikariCPConnectionProviderFactory implements 
JDBCConnectionProvider
     }
 
     @Override
-    public ConnectionProvider getConnectionProvider(String connectionUrl, 
String username, String password, Map<String, String> providerAttributes)
+    public ConnectionProvider getConnectionProvider(
+            final String connectionUrl,
+            final String username,
+            final String password,
+            final KeyStore<?> keyStore,
+            final String keyStorePathPropertyName,
+            final String keyStorePasswordPropertyName,
+            final TrustStore<?> trustStore,
+            final String trustStorePathPropertyName,
+            final String trustStorePasswordPropertyName,
+            final Map<String, String> providerAttributes)
     {
-        return new HikariCPConnectionProvider(connectionUrl, username, 
password, providerAttributes);
+        return new HikariCPConnectionProvider(connectionUrl, username, 
password, keyStore, keyStorePathPropertyName,
+                keyStorePasswordPropertyName, trustStore, 
trustStorePathPropertyName, trustStorePasswordPropertyName, providerAttributes);
     }
 
     @Override
diff --git 
a/broker-plugins/jdbc-provider-hikari/src/test/java/org/apache/qpid/server/store/jdbc/hikaricp/HikariCPConnectionProviderTest.java
 
b/broker-plugins/jdbc-provider-hikari/src/test/java/org/apache/qpid/server/store/jdbc/hikaricp/HikariCPConnectionProviderTest.java
index f34eb19dc0..7b495c0601 100644
--- 
a/broker-plugins/jdbc-provider-hikari/src/test/java/org/apache/qpid/server/store/jdbc/hikaricp/HikariCPConnectionProviderTest.java
+++ 
b/broker-plugins/jdbc-provider-hikari/src/test/java/org/apache/qpid/server/store/jdbc/hikaricp/HikariCPConnectionProviderTest.java
@@ -23,6 +23,8 @@ package org.apache.qpid.server.store.jdbc.hikaricp;
 import static 
org.apache.qpid.server.store.jdbc.hikaricp.HikariCPConnectionProvider.DEFAULT_MAX_POOLSIZE;
 import static 
org.apache.qpid.server.store.jdbc.hikaricp.HikariCPConnectionProvider.DEFAULT_MIN_IDLE;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -30,6 +32,8 @@ import java.util.Map;
 import com.zaxxer.hikari.HikariConfig;
 import org.junit.jupiter.api.Test;
 
+import org.apache.qpid.server.security.FileKeyStore;
+import org.apache.qpid.server.security.FileTrustStore;
 import org.apache.qpid.test.utils.UnitTestBase;
 
 public class HikariCPConnectionProviderTest extends UnitTestBase
@@ -42,17 +46,33 @@ public class HikariCPConnectionProviderTest extends 
UnitTestBase
         attributes.put("qpid.jdbcstore.hikaricp.connectionTimeout", "1234");
         attributes.put("qpid.jdbcstore.hikaricp.connectionTestQuery", "select 
1");
 
-        String connectionUrl = "jdbc:mariadb://localhost:3306/test";
-        String username = "usr";
-        String password = "pwd";
-        HikariConfig config =
-                HikariCPConnectionProvider.createHikariCPConfig(connectionUrl, 
username, password, attributes);
+        final FileKeyStore<?> keyStore = mock(FileKeyStore.class);
+        when(keyStore.getPath()).thenReturn("/etc/cert/key.p12");
+        when(keyStore.getPassword()).thenReturn("12345678");
+        final String keyStorePathParam = "sslkey";
+        final String keyStorePasswordParam = "sslpassword";
+        final FileTrustStore<?> trustStore = mock(FileTrustStore.class);
+        when(trustStore.getPath()).thenReturn("/etc/cert/trust.p12");
+        when(trustStore.getPassword()).thenReturn("12345678");
+        final String trustStorePathParam = "sslcert";
+        final String trustStorePasswordParam = "certpassword";
+
+        final String connectionUrl = "jdbc:mariadb://localhost:3306/test";
+        final String username = "usr";
+        final String password = "pwd";
+        final HikariConfig config = 
HikariCPConnectionProvider.createHikariCPConfig(connectionUrl, username, 
password,
+                keyStore, keyStorePathParam, keyStorePasswordParam, 
trustStore, trustStorePathParam,
+                trustStorePasswordParam, attributes);
         assertEquals(connectionUrl, config.getJdbcUrl());
         assertEquals(username, config.getUsername());
         assertEquals(password, config.getPassword());
         assertEquals(123, config.getIdleTimeout(), "Unexpected idleTimeout");
         assertEquals(1234, config.getConnectionTimeout(), "Unexpected 
connectionTimeout");
         assertEquals("select 1", config.getConnectionTestQuery(), "Unexpected 
connectionTestQuery()");
+        assertEquals("/etc/cert/key.p12", 
config.getDataSourceProperties().get("sslkey"), "Unexpected sslkey");
+        assertEquals("12345678", 
config.getDataSourceProperties().get("sslpassword"), "Unexpected sslpassword");
+        assertEquals("/etc/cert/trust.p12", 
config.getDataSourceProperties().get("sslcert"), "Unexpected sslcert");
+        assertEquals("12345678", 
config.getDataSourceProperties().get("certpassword"), "Unexpected 
certpassword");
         assertEquals(DEFAULT_MAX_POOLSIZE, config.getMaximumPoolSize(), 
"Unexpected maximumPoolSize");
         assertEquals(DEFAULT_MIN_IDLE, config.getMinimumIdle(), "Unexpected 
minimumIdle");
     }
diff --git 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/DefaultConnectionProviderFactory.java
 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/DefaultConnectionProviderFactory.java
index e54673227d..5d22c92e36 100644
--- 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/DefaultConnectionProviderFactory.java
+++ 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/DefaultConnectionProviderFactory.java
@@ -20,6 +20,8 @@
  */
 package org.apache.qpid.server.store.jdbc;
 
+import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.TrustStore;
 import org.apache.qpid.server.plugin.PluggableFactoryLoader;
 import org.apache.qpid.server.plugin.PluggableService;
 
@@ -43,7 +45,17 @@ public class DefaultConnectionProviderFactory implements 
JDBCConnectionProviderF
     }
 
     @Override
-    public ConnectionProvider getConnectionProvider(String connectionUrl, 
String username, String password, Map<String, String> providerAttributes)
+    public ConnectionProvider getConnectionProvider(
+            String connectionUrl,
+            String username,
+            String password,
+            KeyStore<?> keyStore,
+            String keyStorePathPropertyName,
+            String keyStorePasswordPropertyName,
+            TrustStore<?> trustStore,
+            String trustStorePathPropertyName,
+            String trustStorePasswordPropertyName,
+            Map<String, String> providerAttributes)
     {
         return new DefaultConnectionProvider(connectionUrl, username, 
password);
     }
diff --git 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/GenericJDBCMessageStore.java
 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/GenericJDBCMessageStore.java
index 694ae5b4b7..4ff66b837c 100644
--- 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/GenericJDBCMessageStore.java
+++ 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/GenericJDBCMessageStore.java
@@ -99,7 +99,10 @@ public class GenericJDBCMessageStore extends 
GenericAbstractJDBCMessageStore
     {
         try
         {
-            _connectionProvider.close();
+            if (_connectionProvider != null)
+            {
+                _connectionProvider.close();
+            }
         }
         catch (SQLException e)
         {
diff --git 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCConnectionProviderFactory.java
 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCConnectionProviderFactory.java
index d37e864167..4ace538b15 100644
--- 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCConnectionProviderFactory.java
+++ 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCConnectionProviderFactory.java
@@ -24,6 +24,8 @@ import java.sql.SQLException;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.TrustStore;
 import org.apache.qpid.server.plugin.Pluggable;
 import org.apache.qpid.server.plugin.QpidServiceLoader;
 
@@ -32,12 +34,22 @@ public interface JDBCConnectionProviderFactory extends 
Pluggable
     @Override
     String getType();
 
-    ConnectionProvider getConnectionProvider(String connectionUrl, String 
username, String password, Map<String, String> providerAttributes)
+    ConnectionProvider getConnectionProvider(
+            String connectionUrl,
+            String username,
+            String password,
+            KeyStore<?> keyStore,
+            String keyStorePathPropertyName,
+            String keyStorePasswordPropertyName,
+            TrustStore<?> trustStore,
+            String trustStorePathPropertyName,
+            String trustStorePasswordPropertyName,
+            Map<String, String> providerAttributes)
             throws SQLException;
 
     Set<String> getProviderAttributeNames();
 
-    static final class FACTORIES
+    final class FACTORIES
     {
         private FACTORIES()
         {
diff --git 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSettings.java
 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSettings.java
index 01ee19697b..682e1bbc77 100644
--- 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSettings.java
+++ 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSettings.java
@@ -19,6 +19,8 @@
 
 package org.apache.qpid.server.store.jdbc;
 
+import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.TrustStore;
 import org.apache.qpid.server.store.Settings;
 
 public interface JDBCSettings extends Settings
@@ -38,4 +40,16 @@ public interface JDBCSettings extends Settings
     String getPassword();
 
     String getTableNamePrefix();
+
+    KeyStore<?> getKeyStore();
+
+    String getKeyStorePathPropertyName();
+
+    String getKeyStorePasswordPropertyName();
+
+    TrustStore<?> getTrustStore();
+
+    String getTrustStorePathPropertyName();
+
+    String getTrustStorePasswordPropertyName();
 }
diff --git 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfig.java
 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfig.java
index 6766328ad3..7ce171b1dd 100644
--- 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfig.java
+++ 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfig.java
@@ -23,6 +23,8 @@ package org.apache.qpid.server.store.jdbc;
 import org.apache.qpid.server.model.ManagedAttribute;
 import org.apache.qpid.server.model.ManagedContextDefault;
 import org.apache.qpid.server.model.SystemConfig;
+import org.apache.qpid.server.security.FileKeyStore;
+import org.apache.qpid.server.security.FileTrustStore;
 import org.apache.qpid.server.store.preferences.PreferenceStoreAttributes;
 import org.apache.qpid.server.store.preferences.PreferenceStoreProvider;
 
@@ -61,4 +63,32 @@ public interface JDBCSystemConfig<X extends 
JDBCSystemConfig<X>> extends SystemC
             validValuePattern = "[a-zA-Z_0-9]*")
     String getTableNamePrefix();
 
+    @Override
+    @ManagedAttribute(description = "Optional keystore holding the key for 
secure database connection")
+    FileKeyStore<?> getKeyStore();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
keystore path property, " +
+            "property value is taken from the keystore")
+    String getKeyStorePathPropertyName();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
keystore password property, " +
+            "property value is taken from the keystore")
+    String getKeyStorePasswordPropertyName();
+
+    @Override
+    @ManagedAttribute(description = "Optional truststore holding the 
certificate for secure database connection")
+    FileTrustStore<?> getTrustStore();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
truststore path property, " +
+            "property value is taken from the truststore")
+    String getTrustStorePathPropertyName();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
truststore password property, " +
+            "property value is taken from the truststore")
+    String getTrustStorePasswordPropertyName();
+
 }
diff --git 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfigImpl.java
 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfigImpl.java
index 2a21b96f89..8e1bbafa4b 100644
--- 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfigImpl.java
+++ 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfigImpl.java
@@ -30,6 +30,8 @@ import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.model.ManagedAttributeField;
 import org.apache.qpid.server.model.ManagedObject;
 import org.apache.qpid.server.model.SystemConfigFactoryConstructor;
+import org.apache.qpid.server.security.FileKeyStore;
+import org.apache.qpid.server.security.FileTrustStore;
 import org.apache.qpid.server.store.DurableConfigurationStore;
 import org.apache.qpid.server.store.preferences.PreferenceStore;
 
@@ -48,6 +50,18 @@ public class JDBCSystemConfigImpl extends 
AbstractSystemConfig<JDBCSystemConfigI
     private String _password;
     @ManagedAttributeField
     private String _tableNamePrefix;
+    @ManagedAttributeField
+    private FileKeyStore<?> _keyStore;
+    @ManagedAttributeField
+    private String _keyStorePathPropertyName;
+    @ManagedAttributeField
+    private String _keyStorePasswordPropertyName;
+    @ManagedAttributeField
+    private FileTrustStore<?> _trustStore;
+    @ManagedAttributeField
+    private String _trustStorePathPropertyName;
+    @ManagedAttributeField
+    private String _trustStorePasswordPropertyName;
 
     @SystemConfigFactoryConstructor
     public JDBCSystemConfigImpl(final TaskExecutor taskExecutor,
@@ -94,6 +108,42 @@ public class JDBCSystemConfigImpl extends 
AbstractSystemConfig<JDBCSystemConfigI
         return _tableNamePrefix;
     }
 
+    @Override
+    public FileKeyStore<?> getKeyStore()
+    {
+        return _keyStore;
+    }
+
+    @Override
+    public String getKeyStorePathPropertyName()
+    {
+        return _keyStorePathPropertyName;
+    }
+
+    @Override
+    public String getKeyStorePasswordPropertyName()
+    {
+        return _keyStorePasswordPropertyName;
+    }
+
+    @Override
+    public FileTrustStore<?> getTrustStore()
+    {
+        return _trustStore;
+    }
+
+    @Override
+    public String getTrustStorePathPropertyName()
+    {
+        return _trustStorePathPropertyName;
+    }
+
+    @Override
+    public String getTrustStorePasswordPropertyName()
+    {
+        return _trustStorePasswordPropertyName;
+    }
+
     @Override
     public PreferenceStore getPreferenceStore()
     {
diff --git 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JdbcUtils.java
 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JdbcUtils.java
index a23b3624e0..4a92b321f0 100644
--- 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JdbcUtils.java
+++ 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JdbcUtils.java
@@ -108,6 +108,12 @@ public class JdbcUtils
         return 
connectionProviderFactory.getConnectionProvider(settings.getConnectionUrl(),
                                                                
settings.getUsername(),
                                                                
settings.getPassword(),
+                                                               
settings.getKeyStore(),
+                                                               
settings.getKeyStorePathPropertyName(),
+                                                               
settings.getKeyStorePasswordPropertyName(),
+                                                               
settings.getTrustStore(),
+                                                               
settings.getTrustStorePathPropertyName(),
+                                                               
settings.getTrustStorePasswordPropertyName(),
                                                                
providerAttributes);
     }
 
diff --git 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhost/jdbc/JDBCVirtualHost.java
 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhost/jdbc/JDBCVirtualHost.java
index 7e7ee14b37..57986a58e7 100644
--- 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhost/jdbc/JDBCVirtualHost.java
+++ 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhost/jdbc/JDBCVirtualHost.java
@@ -21,6 +21,8 @@ package org.apache.qpid.server.virtualhost.jdbc;
 
 import org.apache.qpid.server.model.ManagedAttribute;
 import org.apache.qpid.server.model.ManagedContextDefault;
+import org.apache.qpid.server.security.FileKeyStore;
+import org.apache.qpid.server.security.FileTrustStore;
 import org.apache.qpid.server.store.jdbc.DefaultConnectionProviderFactory;
 import org.apache.qpid.server.store.jdbc.JDBCSettings;
 import org.apache.qpid.server.virtualhost.QueueManagingVirtualHost;
@@ -57,4 +59,31 @@ public interface JDBCVirtualHost<X extends 
JDBCVirtualHost<X>> extends QueueMana
             immutable = true)
     String getTableNamePrefix();
 
+    @Override
+    @ManagedAttribute(description = "Optional keystore holding the key for 
secure database connection")
+    FileKeyStore<?> getKeyStore();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
keystore path property, " +
+            "property value is taken from the keystore")
+    String getKeyStorePathPropertyName();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
keystore password property, " +
+            "property value is taken from the keystore")
+    String getKeyStorePasswordPropertyName();
+
+    @Override
+    @ManagedAttribute(description = "Optional truststore holding the 
certificate for secure database connection")
+    FileTrustStore<?> getTrustStore();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
truststore path property, " +
+            "property value is taken from the truststore")
+    String getTrustStorePathPropertyName();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
truststore password property, " +
+            "property value is taken from the truststore")
+    String getTrustStorePasswordPropertyName();
 }
diff --git 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhost/jdbc/JDBCVirtualHostImpl.java
 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhost/jdbc/JDBCVirtualHostImpl.java
index 33ff8992d2..7ccfeed768 100644
--- 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhost/jdbc/JDBCVirtualHostImpl.java
+++ 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhost/jdbc/JDBCVirtualHostImpl.java
@@ -28,6 +28,8 @@ import org.apache.qpid.server.model.ManagedAttributeField;
 import org.apache.qpid.server.model.ManagedObject;
 import org.apache.qpid.server.model.ManagedObjectFactoryConstructor;
 import org.apache.qpid.server.model.VirtualHostNode;
+import org.apache.qpid.server.security.FileKeyStore;
+import org.apache.qpid.server.security.FileTrustStore;
 import org.apache.qpid.server.store.MessageStore;
 import org.apache.qpid.server.store.jdbc.AbstractJDBCMessageStore;
 import org.apache.qpid.server.store.jdbc.GenericJDBCMessageStore;
@@ -58,6 +60,24 @@ public class JDBCVirtualHostImpl extends 
AbstractVirtualHost<JDBCVirtualHostImpl
     @ManagedAttributeField
     private String _tableNamePrefix;
 
+    @ManagedAttributeField
+    private FileKeyStore<?> _keyStore;
+
+    @ManagedAttributeField
+    private String _keyStorePathPropertyName;
+
+    @ManagedAttributeField
+    private String _keyStorePasswordPropertyName;
+
+    @ManagedAttributeField
+    private FileTrustStore<?> _trustStore;
+
+    @ManagedAttributeField
+    private String _trustStorePathPropertyName;
+
+    @ManagedAttributeField
+    private String _trustStorePasswordPropertyName;
+
     @ManagedObjectFactoryConstructor
     public JDBCVirtualHostImpl(final Map<String, Object> attributes,
                                final VirtualHostNode<?> virtualHostNode)
@@ -101,6 +121,42 @@ public class JDBCVirtualHostImpl extends 
AbstractVirtualHost<JDBCVirtualHostImpl
         return _tableNamePrefix;
     }
 
+    @Override
+    public FileKeyStore<?> getKeyStore()
+    {
+        return _keyStore;
+    }
+
+    @Override
+    public String getKeyStorePathPropertyName()
+    {
+        return _keyStorePathPropertyName;
+    }
+
+    @Override
+    public String getKeyStorePasswordPropertyName()
+    {
+        return _keyStorePasswordPropertyName;
+    }
+
+    @Override
+    public FileTrustStore<?> getTrustStore()
+    {
+        return _trustStore;
+    }
+
+    @Override
+    public String getTrustStorePathPropertyName()
+    {
+        return _trustStorePathPropertyName;
+    }
+
+    @Override
+    public String getTrustStorePasswordPropertyName()
+    {
+        return _trustStorePasswordPropertyName;
+    }
+
     @Override
     public JDBCDetails getJDBCDetails()
     {
diff --git 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNode.java
 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNode.java
index 8b4557e83c..2c8c5ebcf8 100644
--- 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNode.java
+++ 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNode.java
@@ -23,6 +23,8 @@ package org.apache.qpid.server.virtualhostnode.jdbc;
 import org.apache.qpid.server.model.ManagedAttribute;
 import org.apache.qpid.server.model.ManagedContextDefault;
 import org.apache.qpid.server.model.VirtualHostNode;
+import org.apache.qpid.server.security.FileKeyStore;
+import org.apache.qpid.server.security.FileTrustStore;
 import org.apache.qpid.server.store.jdbc.DefaultConnectionProviderFactory;
 import org.apache.qpid.server.store.jdbc.JDBCSettings;
 import org.apache.qpid.server.store.preferences.PreferenceStoreAttributes;
@@ -64,4 +66,32 @@ public interface JDBCVirtualHostNode<X extends 
JDBCVirtualHostNode<X>> extends V
             validValuePattern = "[a-zA-Z_0-9]*",
             immutable = true)
     String getTableNamePrefix();
+
+    @Override
+    @ManagedAttribute(description = "Optional keystore holding the key for 
secure database connection")
+    FileKeyStore<?> getKeyStore();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
keystore path property, " +
+            "property value is taken from the keystore")
+    String getKeyStorePathPropertyName();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
keystore password property, " +
+            "property value is taken from the keystore")
+    String getKeyStorePasswordPropertyName();
+
+    @Override
+    @ManagedAttribute(description = "Optional truststore holding the 
certificate for secure database connection")
+    FileTrustStore<?> getTrustStore();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
truststore path property, " +
+            "property value is taken from the truststore")
+    String getTrustStorePathPropertyName();
+
+    @Override
+    @ManagedAttribute(description = "Name of the database vendor specific 
truststore password property, " +
+            "property value is taken from the truststore")
+    String getTrustStorePasswordPropertyName();
 }
diff --git 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeImpl.java
 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeImpl.java
index 7c4efd4ea0..871f3e020b 100644
--- 
a/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeImpl.java
+++ 
b/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeImpl.java
@@ -31,6 +31,8 @@ import org.apache.qpid.server.model.ManagedAttributeField;
 import org.apache.qpid.server.model.ManagedObject;
 import org.apache.qpid.server.model.ManagedObjectFactoryConstructor;
 import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.security.FileKeyStore;
+import org.apache.qpid.server.security.FileTrustStore;
 import org.apache.qpid.server.store.DurableConfigurationStore;
 import org.apache.qpid.server.store.jdbc.GenericJDBCConfigurationStore;
 import org.apache.qpid.server.store.jdbc.JDBCContainer;
@@ -62,6 +64,24 @@ public class JDBCVirtualHostNodeImpl extends 
AbstractStandardVirtualHostNode<JDB
     @ManagedAttributeField
     private String _tableNamePrefix;
 
+    @ManagedAttributeField
+    private FileKeyStore<?> _keyStore;
+
+    @ManagedAttributeField
+    private String _keyStorePathPropertyName;
+
+    @ManagedAttributeField
+    private String _keyStorePasswordPropertyName;
+
+    @ManagedAttributeField
+    private FileTrustStore<?> _trustStore;
+
+    @ManagedAttributeField
+    private String _trustStorePathPropertyName;
+
+    @ManagedAttributeField
+    private String _trustStorePasswordPropertyName;
+
     @ManagedObjectFactoryConstructor
     public JDBCVirtualHostNodeImpl(Map<String, Object> attributes, Broker<?> 
parent)
     {
@@ -109,6 +129,42 @@ public class JDBCVirtualHostNodeImpl extends 
AbstractStandardVirtualHostNode<JDB
         return _tableNamePrefix;
     }
 
+    @Override
+    public FileKeyStore<?> getKeyStore()
+    {
+        return _keyStore;
+    }
+
+    @Override
+    public String getKeyStorePathPropertyName()
+    {
+        return _keyStorePathPropertyName;
+    }
+
+    @Override
+    public String getKeyStorePasswordPropertyName()
+    {
+        return _keyStorePasswordPropertyName;
+    }
+
+    @Override
+    public FileTrustStore<?> getTrustStore()
+    {
+        return _trustStore;
+    }
+
+    @Override
+    public String getTrustStorePathPropertyName()
+    {
+        return _trustStorePathPropertyName;
+    }
+
+    @Override
+    public String getTrustStorePasswordPropertyName()
+    {
+        return _trustStorePasswordPropertyName;
+    }
+
     @Override
     public JDBCDetails getJDBCDetails()
     {
diff --git 
a/broker-plugins/jdbc-store/src/main/java/resources/js/qpid/management/store/pool/ConnectionPool.js
 
b/broker-plugins/jdbc-store/src/main/java/resources/js/qpid/management/store/pool/ConnectionPool.js
index 79b9ee2749..8ad8125665 100644
--- 
a/broker-plugins/jdbc-store/src/main/java/resources/js/qpid/management/store/pool/ConnectionPool.js
+++ 
b/broker-plugins/jdbc-store/src/main/java/resources/js/qpid/management/store/pool/ConnectionPool.js
@@ -22,8 +22,10 @@ define(["qpid/common/util",
         "dojo/_base/array",
         "dojo/dom-construct",
         "dojo/dom",
+        "dojo/request/xhr",
+        "dojo/store/Memory",
         "dojo/string"],
-    function (util, registry, array, domConstruct, dom, string) {
+    function (util, registry, array, domConstruct, dom, xhr, Memory, string) {
 
         function ConnectionPool(container, management, modelObj)
         {
@@ -38,7 +40,7 @@ define(["qpid/common/util",
             if (data && data.hasOwnProperty("connectionPoolType")
                 && (!this.poolDetails || this.previousConnectionPoolType !== 
data.connectionPoolType))
             {
-                var that = this;
+                const that = this;
                 require(["qpid/management/store/pool/" + 
data.connectionPoolType.toLowerCase() + "/show"],
                     function (PoolDetails) {
                         that.poolDetails = 
that._createPoolDetails(PoolDetails);
@@ -53,7 +55,7 @@ define(["qpid/common/util",
         };
 
         ConnectionPool.prototype._createPoolDetails = function (PoolDetails) {
-            var widgets = registry.findWidgets(this.containerNode);
+            const widgets = registry.findWidgets(this.containerNode);
             array.forEach(widgets, function (item) {
                 item.destroyRecursive();
             });
@@ -72,27 +74,26 @@ define(["qpid/common/util",
             registry.byId(dialogIdPrefix + ".username")
                 .set("regExpGen", util.nameOrContextVarRegexp);
 
-            var passwordControl = registry.byId(dialogIdPrefix + ".password");
-            passwordControl.set("required", !data.data);
+            const passwordControl = registry.byId(dialogIdPrefix + 
".password");
 
-            var poolTypeControl = registry.byId(dialogIdPrefix + 
".connectionPoolType");
+            const poolTypeControl = registry.byId(dialogIdPrefix + 
".connectionPoolType");
 
-            var typeMetaData = data.metadata.getMetaData(data.category, 
data.type);
-            var values = ["NONE"];
+            const typeMetaData = data.metadata.getMetaData(data.category, 
data.type);
+            let values = ["NONE"];
             if (typeMetaData.attributes.hasOwnProperty("connectionPoolType")
                 && 
typeMetaData.attributes.connectionPoolType.hasOwnProperty("validValues"))
             {
                 values = 
typeMetaData.attributes.connectionPoolType.validValues;
             }
-            var store = util.makeTypeStore(values);
+            const store = util.makeTypeStore(values);
             poolTypeControl.set("store", store);
             poolTypeControl.set("value", "NONE");
 
-            var poolTypeFieldsDiv = dom.byId(dialogIdPrefix + 
".poolSpecificDiv");
+            const poolTypeFieldsDiv = dom.byId(dialogIdPrefix + 
".poolSpecificDiv");
             poolTypeControl.on("change", function (type) {
                 if (type && string.trim(type) !== "")
                 {
-                    var widgets = registry.findWidgets(poolTypeFieldsDiv);
+                    const widgets = registry.findWidgets(poolTypeFieldsDiv);
                     array.forEach(widgets, function (item) {
                         item.destroyRecursive();
                     });
@@ -108,6 +109,38 @@ define(["qpid/common/util",
                     });
                 }
             });
+
+            const keystoreWidget = registry.byId(dialogIdPrefix + ".keyStore");
+            if (keystoreWidget)
+            {
+                xhr("/api/latest/keystore", {handleAs: "json"})
+                    .then((keystores) => {
+                        const keystoresStore = new Memory({
+                            data: keystores.map(keystore => ({
+                                id: keystore.name,
+                                name: keystore.name
+                            }))
+                        });
+                        keystoreWidget.set("store", keystoresStore);
+                        keystoreWidget.startup();
+                    });
+            }
+
+            const truststoreWidget = registry.byId(dialogIdPrefix + 
".trustStore");
+            if (truststoreWidget)
+            {
+                xhr("/api/latest/truststore", {handleAs: "json"})
+                    .then((truststores) => {
+                        const truststoresStore = new Memory({
+                            data: truststores.map(truststore => ({
+                                id: truststore.name,
+                                name: truststore.name
+                            }))
+                        });
+                        truststoreWidget.set("store", truststoresStore);
+                        truststoreWidget.startup();
+                    });
+            }
         };
         return ConnectionPool;
     });
diff --git 
a/broker-plugins/jdbc-store/src/main/java/resources/js/qpid/management/virtualhost/jdbc/add.js
 
b/broker-plugins/jdbc-store/src/main/java/resources/js/qpid/management/virtualhost/jdbc/add.js
index 0c3b47feab..33857c4a67 100644
--- 
a/broker-plugins/jdbc-store/src/main/java/resources/js/qpid/management/virtualhost/jdbc/add.js
+++ 
b/broker-plugins/jdbc-store/src/main/java/resources/js/qpid/management/virtualhost/jdbc/add.js
@@ -23,6 +23,7 @@ define(["dojo/_base/xhr",
         "dojo/dom-construct",
         "dojo/json",
         "dojo/string",
+        "dojo/request/xhr",
         "dojo/store/Memory",
         "dijit/registry",
         "dojo/text!virtualhost/jdbc/add.html",
@@ -30,31 +31,27 @@ define(["dojo/_base/xhr",
         "dijit/form/ValidationTextBox",
         "dijit/form/CheckBox",
         "dojo/domReady!"],
-    function (xhr, array, parser, dom, domConstruct, json, string, Memory, 
registry, template, util)
+    function (xhr, array, parser, dom, domConstruct, json, string, _xhr, 
Memory, registry, template, util)
     {
         return {
             show: function (data)
             {
-                var that = this;
+                const that = this;
                 this.containerNode = domConstruct.create("div", {innerHTML: 
template}, data.containerNode);
-                parser.parse(this.containerNode)
-                    .then(function (instances)
-                    {
-                        that._postParse(data);
-                    });
+                parser.parse(this.containerNode).then((instances) => 
that._postParse(data));
             },
             _postParse: function (data)
             {
-                var that = this;
+                const that = this;
                 registry.byId("addVirtualHost.connectionUrl")
                     .set("regExpGen", util.jdbcUrlOrContextVarRegexp);
                 registry.byId("addVirtualHost.username")
                     .set("regExpGen", util.nameOrContextVarRegexp);
 
-                var typeMetaData = data.metadata.getMetaData("VirtualHost", 
"JDBC");
-                var poolTypes = 
typeMetaData.attributes.connectionPoolType.validValues;
-                var poolTypesData = [];
-                array.forEach(poolTypes, function (item)
+                const typeMetaData = data.metadata.getMetaData("VirtualHost", 
"JDBC");
+                const poolTypes = 
typeMetaData.attributes.connectionPoolType.validValues;
+                const poolTypesData = [];
+                array.forEach(poolTypes, (item) =>
                 {
                     poolTypesData.push({
                         id: item,
@@ -62,21 +59,18 @@ define(["dojo/_base/xhr",
                     });
                 });
 
-                var poolTypesStore = new Memory({data: poolTypesData});
-                var poolTypeControl = 
registry.byId("addVirtualHost.connectionPoolType");
+                const poolTypesStore = new Memory({data: poolTypesData});
+                const poolTypeControl = 
registry.byId("addVirtualHost.connectionPoolType");
                 poolTypeControl.set("store", poolTypesStore);
                 poolTypeControl.set("value", "NONE");
 
-                var poolTypeFieldsDiv = 
dom.byId("addVirtualHost.poolSpecificDiv");
-                poolTypeControl.on("change", function (type)
+                const poolTypeFieldsDiv = 
dom.byId("addVirtualHost.poolSpecificDiv");
+                poolTypeControl.on("change", (type) =>
                 {
-                    if (type && string.trim(type) != "")
+                    if (type && string.trim(type) !== "")
                     {
-                        var widgets = registry.findWidgets(poolTypeFieldsDiv);
-                        array.forEach(widgets, function (item)
-                        {
-                            item.destroyRecursive();
-                        });
+                        const widgets = 
registry.findWidgets(poolTypeFieldsDiv);
+                        array.forEach(widgets, (item) => 
item.destroyRecursive());
                         domConstruct.empty(poolTypeFieldsDiv);
                         require(["qpid/management/store/pool/" + 
type.toLowerCase() + "/add"], function (poolType)
                         {
@@ -88,6 +82,26 @@ define(["dojo/_base/xhr",
                     }
                 });
                 util.applyMetadataToWidgets(data.containerNode, "VirtualHost", 
data.type, data.metadata);
+
+                const keystoreWidget = 
registry.byId("addVirtualHost.keyStore");
+                _xhr("/api/latest/keystore", {handleAs: 
"json"}).then((keystores) =>
+                {
+                    const keystoresStore = new Memory({
+                        data: keystores.map(keystore => ({ id: keystore.name, 
name: keystore.name }))
+                    });
+                    keystoreWidget.set("store", keystoresStore);
+                    keystoreWidget.startup();
+                });
+
+                const truststoreWidget = 
registry.byId("addVirtualHost.trustStore");
+                _xhr("/api/latest/truststore", {handleAs: 
"json"}).then((truststores) =>
+                {
+                    const truststoresStore = new Memory({
+                        data: truststores.map(truststore => ({ id: 
truststore.name, name: truststore.name }))
+                    });
+                    truststoreWidget.set("store", truststoresStore);
+                    truststoreWidget.startup();
+                });
             }
         };
     });
diff --git 
a/broker-plugins/jdbc-store/src/main/java/resources/js/qpid/management/virtualhost/jdbc/edit.js
 
b/broker-plugins/jdbc-store/src/main/java/resources/js/qpid/management/virtualhost/jdbc/edit.js
index 2cbd3ac2e6..471fb7d490 100644
--- 
a/broker-plugins/jdbc-store/src/main/java/resources/js/qpid/management/virtualhost/jdbc/edit.js
+++ 
b/broker-plugins/jdbc-store/src/main/java/resources/js/qpid/management/virtualhost/jdbc/edit.js
@@ -20,18 +20,18 @@ define(["qpid/common/util",
         "dojo/_base/array",
         "dojo/json",
         "dojo/string",
+        "dojo/request/xhr",
         "dojo/store/Memory",
         "dojo/dom",
         "dojo/dom-construct",
         "dijit/registry",
-        "dojo/domReady!"], function (util, array, json, string, Memory, dom, 
domConstruct, registry)
+        "dojo/domReady!"], function (util, array, json, string, xhr, Memory, 
dom, domConstruct, registry)
 {
-
     return {
         show: function (data)
         {
-            var that = this;
-            util.parseHtmlIntoDiv(data.containerNode, 
"virtualhost/jdbc/edit.html", function ()
+            const that = this;
+            util.parseHtmlIntoDiv(data.containerNode, 
"virtualhost/jdbc/edit.html", () =>
             {
                 that._postParse(data)
             });
@@ -43,10 +43,10 @@ define(["qpid/common/util",
             registry.byId("editVirtualHost.username")
                 .set("regExpGen", util.nameOrContextVarRegexp);
 
-            var typeMetaData = data.metadata.getMetaData("VirtualHost", 
"JDBC");
-            var poolTypes = 
typeMetaData.attributes.connectionPoolType.validValues;
-            var poolTypesData = [];
-            array.forEach(poolTypes, function (item)
+            const typeMetaData = data.metadata.getMetaData("VirtualHost", 
"JDBC");
+            const poolTypes = 
typeMetaData.attributes.connectionPoolType.validValues;
+            const poolTypesData = [];
+            array.forEach(poolTypes, (item) =>
             {
                 poolTypesData.push({
                     id: item,
@@ -54,23 +54,23 @@ define(["qpid/common/util",
                 });
             });
 
-            var poolTypesStore = new Memory({data: poolTypesData});
-            var poolTypeControl = 
registry.byId("editVirtualHost.connectionPoolType");
+            const poolTypesStore = new Memory({data: poolTypesData});
+            const poolTypeControl = 
registry.byId("editVirtualHost.connectionPoolType");
             poolTypeControl.set("store", poolTypesStore);
             poolTypeControl.set("value", data.data.connectionPoolType);
 
-            var passwordControl = registry.byId("editVirtualHost.password");
+            const passwordControl = registry.byId("editVirtualHost.password");
             if (data.data.password)
             {
                 passwordControl.set("placeHolder", "*******");
             }
 
-            var poolTypeFieldsDiv = 
dom.byId("editVirtualHost.poolSpecificDiv");
+            const poolTypeFieldsDiv = 
dom.byId("editVirtualHost.poolSpecificDiv");
             poolTypeControl.on("change", function (type)
             {
-                if (type && string.trim(type) != "")
+                if (type && string.trim(type) !== "")
                 {
-                    var widgets = registry.findWidgets(poolTypeFieldsDiv);
+                    const widgets = registry.findWidgets(poolTypeFieldsDiv);
                     array.forEach(widgets, function (item)
                     {
                         item.destroyRecursive();
@@ -88,6 +88,39 @@ define(["qpid/common/util",
                 }
             });
 
+            const keystoreWidget = registry.byId("editVirtualHost.keyStore");
+            xhr("/api/latest/keystore", {handleAs: "json"}).then((keystores) =>
+            {
+                const keystoresStore = new Memory({
+                    data: keystores.map(keystore => ({ id: keystore.name, 
name: keystore.name }))
+                });
+                keystoreWidget.set("store", keystoresStore);
+                keystoreWidget.setValue(data.data.keyStore);
+                keystoreWidget.startup();
+            });
+
+            const keyStorePathPropertyNameWidget = 
registry.byId("editVirtualHost.keyStorePathPropertyName");
+            
keyStorePathPropertyNameWidget.setValue(data.data.keyStorePathPropertyName);
+
+            const keyStorePasswordPropertyNameWidget = 
registry.byId("editVirtualHost.keyStorePasswordPropertyName");
+            
keyStorePasswordPropertyNameWidget.setValue(data.data.keyStorePasswordPropertyName);
+
+            const truststoreWidget = 
registry.byId("editVirtualHost.trustStore");
+            xhr("/api/latest/truststore", {handleAs: 
"json"}).then((truststores) =>
+            {
+                const truststoresStore = new Memory({
+                    data: truststores.map(truststore => ({ id: 
truststore.name, name: truststore.name }))
+                });
+                truststoreWidget.set("store", truststoresStore);
+                truststoreWidget.setValue(data.data.trustStore);
+                truststoreWidget.startup();
+            });
+
+            const trustStorePathPropertyNameWidget = 
registry.byId("editVirtualHost.keyStorePathPropertyName");
+            
trustStorePathPropertyNameWidget.setValue(data.data.keyStorePathPropertyName);
+
+            const trustStorePasswordPropertyNameWidget = 
registry.byId("editVirtualHost.trustStorePasswordPropertyName");
+            
trustStorePasswordPropertyNameWidget.setValue(data.data.trustStorePasswordPropertyName);
 
             util.applyToWidgets(data.containerNode, "VirtualHost", 
data.data.type, data.data, data.metadata);
         }
diff --git 
a/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/jdbc/add.html 
b/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/jdbc/add.html
index 4a6f66248d..dd6781bbab 100644
--- 
a/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/jdbc/add.html
+++ 
b/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/jdbc/add.html
@@ -31,27 +31,27 @@
       </div>
     </div>
     <div class="clear">
-        <div class="formLabel-labelCell 
tableContainer-labelCell">Username*:</div>
+        <div class="formLabel-labelCell 
tableContainer-labelCell">Username:</div>
         <div class="formLabel-controlCell tableContainer-valueCell">
             <input type="text" id="addVirtualHost.username"
                    data-dojo-type="dijit/form/ValidationTextBox"
                    data-dojo-props="
                               name: 'username',
                               placeHolder: 'username',
-                              required: true,
+                              required: false,
                               missingMessage: 'Username must be supplied',
                               title: 'Enter username'" />
         </div>
     </div>
     <div class="clear">
-        <div class="formLabel-labelCell 
tableContainer-labelCell">Password*:</div>
+        <div class="formLabel-labelCell 
tableContainer-labelCell">Password:</div>
         <div class="formLabel-controlCell tableContainer-valueCell">
             <input type="password" id="addVirtualHost.password"
                    data-dojo-type="dijit/form/ValidationTextBox"
                    data-dojo-props="
                               name: 'password',
                               placeHolder: 'password',
-                              required: true,
+                              required: false,
                               missingMessage: 'Password must be supplied',
                               title: 'Enter password'" />
         </div>
@@ -83,6 +83,107 @@
                               title: 'Optional database table prefix so 
multiple VirtualHosts can share the same database'" />
         </div>
     </div>
+
+    <div class="clear">
+        <div class="formLabel-labelCell">
+            <label for="addVirtualHost.keyStore">Key Store:</label>
+        </div>
+        <div class="formLabel-controlCell">
+            <select id="addVirtualHost.keyStore"
+                data-dojo-type="dijit.form.FilteringSelect"
+                data-dojo-props="
+                    name: 'keyStore',
+                    label: 'Key Store:',
+                    searchAttr: 'name',
+                    placeHolder: 'keystore',
+                    value: '',
+                    required: false,
+                    promptMessage: 'Keystore that provides the SSL 
certificate',
+                    title: 'Select the keystore that provides the SSL 
certificate'">
+            </select>
+        </div>
+    </div>
+
+    <div class="clear">
+        <div class="formLabel-labelCell tableContainer-labelCell">Keystore 
Path Property Name:</div>
+        <div class="formLabel-controlCell tableContainer-valueCell">
+            <input type="text" id="addVirtualHost.keyStorePathPropertyName"
+                   data-dojo-type="dijit/form/ValidationTextBox"
+                   data-dojo-props="
+                              name: 'keyStorePathPropertyName',
+                              placeHolder: 'keystore path property name',
+                              required: false,
+                              regExp: '[a-zA-Z_0-9-]*',
+                              promptMessage: 'Name of the database vendor 
specific keystore path property',
+                              title: 'Name of the database vendor specific 
keystore path property'" />
+        </div>
+    </div>
+
+    <div class="clear">
+        <div class="formLabel-labelCell tableContainer-labelCell">Keystore 
Password Property Name:</div>
+        <div class="formLabel-controlCell tableContainer-valueCell">
+            <input type="text" id="addVirtualHost.keyStorePasswordPropertyName"
+                   data-dojo-type="dijit/form/ValidationTextBox"
+                   data-dojo-props="
+                              name: 'keyStorePasswordPropertyName',
+                              placeHolder: 'keystore password property name',
+                              required: false,
+                              regExp: '[a-zA-Z_0-9-]*',
+                              promptMessage: 'Name of the database vendor 
specific keystore password property',
+                              title: 'Name of the database vendor specific 
keystore password property'" />
+        </div>
+    </div>
+
+    <div class="clear">
+        <div class="formLabel-labelCell">
+            <label for="addVirtualHost.trustStore">Trust Store:</label>
+        </div>
+        <div class="formLabel-controlCell">
+            <select id="addVirtualHost.trustStore"
+                    data-dojo-type="dijit.form.FilteringSelect"
+                    data-dojo-props="
+                    name: 'truststore',
+                    label: 'Trust Store:',
+                    searchAttr: 'name',
+                    placeHolder: 'truststore',
+                    value: '',
+                    required: false,
+                    promptMessage: 'Trust store that records certificates',
+                    title: 'Select the trust store that will be used to record 
client certificates'">
+            </select>
+        </div>
+    </div>
+
+    <div class="clear">
+        <div class="formLabel-labelCell tableContainer-labelCell">Truststore 
Path Property Name:</div>
+        <div class="formLabel-controlCell tableContainer-valueCell">
+            <input type="text" id="addVirtualHost.trustStorePathPropertyName"
+                   data-dojo-type="dijit/form/ValidationTextBox"
+                   data-dojo-props="
+                              name: 'trustStorePathPropertyName',
+                              placeHolder: 'truststore path property name',
+                              required: false,
+                              regExp: '[a-zA-Z_0-9-]*',
+                              promptMessage: 'Name of the database vendor 
specific truststore path property',
+                              title: 'Name of the database vendor specific 
truststore path property'" />
+        </div>
+    </div>
+
+    <div class="clear">
+        <div class="formLabel-labelCell tableContainer-labelCell">Truststore 
Password Property Name:</div>
+        <div class="formLabel-controlCell tableContainer-valueCell">
+            <input type="text" 
id="addVirtualHost.trustStorePasswordPropertyName"
+                   data-dojo-type="dijit/form/ValidationTextBox"
+                   data-dojo-props="
+                              name: 'trustStorePasswordPropertyName',
+                              placeHolder: 'truststore password property name',
+                              required: false,
+                              regExp: '[a-zA-Z_0-9-]*',
+                              promptMessage: 'Name of the database vendor 
specific truststore password property',
+                              title: 'Name of the database vendor specific 
truststore password property'" />
+        </div>
+    </div>
+
     <div class="clear"></div>
     <div id="addVirtualHost.poolSpecificDiv"></div>
     <div class="infoMessage">The virtual host will have the same name as the 
node.</div>
diff --git 
a/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/jdbc/edit.html 
b/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/jdbc/edit.html
index 10212079eb..de84087f08 100644
--- 
a/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/jdbc/edit.html
+++ 
b/broker-plugins/jdbc-store/src/main/java/resources/virtualhost/jdbc/edit.html
@@ -32,20 +32,20 @@
       </div>
     </div>
     <div class="clear">
-        <div class="formLabel-labelCell 
tableContainer-labelCell">Username*:</div>
+        <div class="formLabel-labelCell 
tableContainer-labelCell">Username:</div>
         <div class="formLabel-controlCell tableContainer-valueCell">
             <input type="text" id="editVirtualHost.username"
                    data-dojo-type="dijit/form/ValidationTextBox"
                    data-dojo-props="
                               name: 'username',
                               placeHolder: 'username',
-                              required: true,
+                              required: false,
                               missingMessage: 'Username must be supplied',
                               title: 'Enter username'" />
         </div>
     </div>
     <div class="clear">
-        <div class="formLabel-labelCell 
tableContainer-labelCell">Password*:</div>
+        <div class="formLabel-labelCell 
tableContainer-labelCell">Password:</div>
         <div class="formLabel-controlCell tableContainer-valueCell">
             <input type="password" id="editVirtualHost.password"
                    data-dojo-type="dijit/form/ValidationTextBox"
@@ -72,6 +72,106 @@
       </div>
     </div>
 
+    <div class="clear">
+        <div class="formLabel-labelCell">
+            <label for="editVirtualHost.keyStore">Key Store:</label>
+        </div>
+        <div class="formLabel-controlCell">
+            <select id="editVirtualHost.keyStore"
+                    data-dojo-type="dijit.form.FilteringSelect"
+                    data-dojo-props="
+                    name: 'keyStore',
+                    label: 'Key Store:',
+                    searchAttr: 'name',
+                    placeHolder: 'keystore',
+                    value: '',
+                    required: false,
+                    promptMessage: 'Keystore that provides the SSL 
certificate',
+                    title: 'Select the keystore that provides the SSL 
certificate'">
+            </select>
+        </div>
+    </div>
+
+    <div class="clear">
+        <div class="formLabel-labelCell tableContainer-labelCell">Keystore 
Path Property Name:</div>
+        <div class="formLabel-controlCell tableContainer-valueCell">
+            <input type="text" id="editVirtualHost.keyStorePathPropertyName"
+                   data-dojo-type="dijit/form/ValidationTextBox"
+                   data-dojo-props="
+                              name: 'keyStorePathPropertyName',
+                              placeHolder: 'keystore path property name',
+                              required: false,
+                              regExp: '[a-zA-Z_0-9-]*',
+                              promptMessage: 'Name of the database vendor 
specific keystore path property',
+                              title: 'Name of the database vendor specific 
keystore path property'" />
+        </div>
+    </div>
+
+    <div class="clear">
+        <div class="formLabel-labelCell tableContainer-labelCell">Keystore 
Password Property Name:</div>
+        <div class="formLabel-controlCell tableContainer-valueCell">
+            <input type="text" 
id="editVirtualHost.keyStorePasswordPropertyName"
+                   data-dojo-type="dijit/form/ValidationTextBox"
+                   data-dojo-props="
+                              name: 'keyStorePasswordPropertyName',
+                              placeHolder: 'keystore password property name',
+                              required: false,
+                              regExp: '[a-zA-Z_0-9-]*',
+                              promptMessage: 'Name of the database vendor 
specific keystore password property',
+                              title: 'Name of the database vendor specific 
keystore password property'" />
+        </div>
+    </div>
+
+    <div class="clear">
+        <div class="formLabel-labelCell">
+            <label for="editVirtualHost.trustStore">Trust Store:</label>
+        </div>
+        <div class="formLabel-controlCell">
+            <select id="editVirtualHost.trustStore"
+                    data-dojo-type="dijit.form.FilteringSelect"
+                    data-dojo-props="
+                    name: 'trustStore',
+                    label: 'Trust Store:',
+                    searchAttr: 'name',
+                    placeHolder: 'truststore',
+                    value: '',
+                    required: false,
+                    promptMessage: 'Trust store that records certificates',
+                    title: 'Select the trust store that will be used to record 
client certificates'">
+            </select>
+        </div>
+    </div>
+
+    <div class="clear">
+        <div class="formLabel-labelCell tableContainer-labelCell">Truststore 
Path Property Name:</div>
+        <div class="formLabel-controlCell tableContainer-valueCell">
+            <input type="text" id="editVirtualHost.trustStorePathPropertyName"
+                   data-dojo-type="dijit/form/ValidationTextBox"
+                   data-dojo-props="
+                              name: 'trustStorePathPropertyName',
+                              placeHolder: 'truststore path property name',
+                              required: false,
+                              regExp: '[a-zA-Z_0-9-]*',
+                              promptMessage: 'Name of the database vendor 
specific truststore path property',
+                              title: 'Name of the database vendor specific 
truststore path property'" />
+        </div>
+    </div>
+
+    <div class="clear">
+        <div class="formLabel-labelCell tableContainer-labelCell">Truststore 
Password Property Name:</div>
+        <div class="formLabel-controlCell tableContainer-valueCell">
+            <input type="text" 
id="editVirtualHost.trustStorePasswordPropertyName"
+                   data-dojo-type="dijit/form/ValidationTextBox"
+                   data-dojo-props="
+                              name: 'trustStorePasswordPropertyName',
+                              placeHolder: 'truststore password property name',
+                              required: false,
+                              regExp: '[a-zA-Z_0-9-]*',
+                              promptMessage: 'Name of the database vendor 
specific truststore password property',
+                              title: 'Name of the database vendor specific 
truststore password property'" />
+        </div>
+    </div>
+
     <div class="clear"></div>
     <div id="editVirtualHost.poolSpecificDiv"></div>
 
diff --git 
a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHostNodeAndVirtualHost.js
 
b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHostNodeAndVirtualHost.js
index 811a1dc4b1..f89ab9d2c7 100644
--- 
a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHostNodeAndVirtualHost.js
+++ 
b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHostNodeAndVirtualHost.js
@@ -65,11 +65,10 @@ define(["dojo/_base/event",
               util,
               template)
     {
-
-        var addVirtualHostNodeAndVirtualHost = {
+        const addVirtualHostNodeAndVirtualHost = {
             init: function ()
             {
-                var that = this;
+                const that = this;
                 this.containerNode = domConstruct.create("div", {innerHTML: 
template});
                 parser.parse(this.containerNode)
                     .then(function (instances)
@@ -79,8 +78,8 @@ define(["dojo/_base/event",
             },
             _postParse: function ()
             {
-                var that = this;
-                var virtualHostNodeName = 
registry.byId("addVirtualHostNode.nodeName");
+                const that = this;
+                const virtualHostNodeName = 
registry.byId("addVirtualHostNode.nodeName");
                 virtualHostNodeName.set("regExpGen", 
util.virtualHostNameOrContextVarRegexp);
 
                 // Readers are HTML5
@@ -164,10 +163,10 @@ define(["dojo/_base/event",
                 this.virtualHostForm.reset();
                 this.virtualHostType.set("value", null);
 
-                var supportedVirtualHostNodeTypes = 
management.metadata.getTypesForCategory("VirtualHostNode");
+                const supportedVirtualHostNodeTypes = 
management.metadata.getTypesForCategory("VirtualHostNode");
                 supportedVirtualHostNodeTypes.sort();
 
-                var virtualHostNodeTypeStore = 
util.makeTypeStore(supportedVirtualHostNodeTypes);
+                const virtualHostNodeTypeStore = 
util.makeTypeStore(supportedVirtualHostNodeTypes);
                 this.virtualHostNodeType.set("store", 
virtualHostNodeTypeStore);
 
                 if (!this.virtualHostNodeContext)
@@ -177,21 +176,21 @@ define(["dojo/_base/event",
                         title: 'Context variables'
                     });
                     
this.virtualHostNodeContext.placeAt(dom.byId("addVirtualHostNode.context"));
-                    var that = this;
+                    const that = this;
                     this.virtualHostNodeContext.on("change", function (value)
                     {
-                        var inherited = 
that.virtualHostContext.inheritedActualValues;
-                        var effective = 
that.virtualHostContext.effectiveValues;
-                        var actuals = that.virtualHostContext.value;
-                        for (var key in value)
+                        const inherited = 
that.virtualHostContext.inheritedActualValues;
+                        const effective = 
that.virtualHostContext.effectiveValues;
+                        const actuals = that.virtualHostContext.value;
+                        for (let key in value)
                         {
                             if (!actuals || !(key in actuals))
                             {
-                                var val = value[key];
+                                const val = value[key];
                                 inherited[key] = val;
                                 if (!(key in effective))
                                 {
-                                    effective[key] = val.indexOf("${") == -1 ? 
val : "";
+                                    effective[key] = val.indexOf("${") === -1 
? val : "";
                                 }
                             }
                         }
@@ -208,7 +207,7 @@ define(["dojo/_base/event",
 
                 }
 
-                var that = this;
+                const that = this;
                 util.loadEffectiveAndInheritedActualData(management, {type: 
"broker"}, function(data)
                 {
                     that.virtualHostNodeContext.setData({},
@@ -243,16 +242,16 @@ define(["dojo/_base/event",
             },
             _vhnTypeChanged: function (type, typeFieldsContainer, urlStem)
             {
-                var validChildTypes = this.management ? 
this.management.metadata.validChildTypes("VirtualHostNode",
+                const validChildTypes = this.management ? 
this.management.metadata.validChildTypes("VirtualHostNode",
                     type,
                     "VirtualHost") : [];
                 validChildTypes.sort();
 
-                var virtualHostTypeStore = util.makeTypeStore(validChildTypes);
+                const virtualHostTypeStore = 
util.makeTypeStore(validChildTypes);
 
                 this.virtualHostType.set("store", virtualHostTypeStore);
                 this.virtualHostType.set("disabled", validChildTypes.length <= 
1);
-                if (validChildTypes.length == 1)
+                if (validChildTypes.length === 1)
                 {
                     this.virtualHostType.set("value", validChildTypes[0]);
                 }
@@ -261,7 +260,7 @@ define(["dojo/_base/event",
                     this.virtualHostType.reset();
                 }
 
-                var vhnTypeSelected = !(type == '');
+                const vhnTypeSelected = !(type == '');
                 this.virtualHostNodeUploadFields.style.display = 
vhnTypeSelected ? "block" : "none";
 
                 if (!vhnTypeSelected)
@@ -280,7 +279,7 @@ define(["dojo/_base/event",
                 this._destroyContainerWidgets(typeFieldsContainer);
                 if (category)
                 {
-                    var context = this["v" + category.substring(1) + 
"Context"];
+                    const context = this["v" + category.substring(1) + 
"Context"];
                     if (context)
                     {
                         context.removeDynamicallyAddedInheritedContext();
@@ -288,12 +287,12 @@ define(["dojo/_base/event",
                 }
                 if (type)
                 {
-                    var that = this;
+                    const that = this;
                     require([urlStem + type.toLowerCase() + "/add"], function 
(typeUI)
                     {
                         try
                         {
-                            var metadata = that.management.metadata;
+                            const metadata = that.management.metadata;
                             typeUI.show({
                                 containerNode: typeFieldsContainer,
                                 parent: that,
@@ -312,7 +311,7 @@ define(["dojo/_base/event",
             {
                 if (typeFieldsContainer)
                 {
-                    var widgets = registry.findWidgets(typeFieldsContainer);
+                    const widgets = registry.findWidgets(typeFieldsContainer);
                     array.forEach(widgets, function (item)
                     {
                         item.destroyRecursive();
@@ -333,7 +332,7 @@ define(["dojo/_base/event",
             _vhnFileChanged: function (evt)
             {
                 // We only ever expect a single file
-                var file = 
this.virtualHostNodeFile.domNode.children[0].files[0];
+                const file = 
this.virtualHostNodeFile.domNode.children[0].files[0];
 
                 this.addButton.set("disabled", true);
                 this.virtualHostNodeSelectedFileContainer.innerHTML = 
file.name;
@@ -344,8 +343,8 @@ define(["dojo/_base/event",
             },
             _vhnUploadFileComplete: function (evt)
             {
-                var reader = evt.target;
-                var result = reader.result;
+                const reader = evt.target;
+                const result = reader.result;
                 console.log("File read complete, contents " + result);
                 this.virtualHostInitialConfiguration = result;
                 this.addButton.set("disabled", false);
@@ -365,16 +364,15 @@ define(["dojo/_base/event",
             },
             _submit: function ()
             {
-
-                var uploadVHConfig = 
this.virtualHostNodeFileCheck.get("checked");
-                var virtualHostNodeData = undefined;
+                const uploadVHConfig = 
this.virtualHostNodeFileCheck.get("checked");
+                let virtualHostNodeData = undefined;
 
                 if (uploadVHConfig && 
this.virtualHostNodeFile.getFileList().length > 0
                     && this.virtualHostNodeForm.validate())
                 {
                     // VH config is being uploaded
                     virtualHostNodeData = 
util.getFormWidgetValues(this.virtualHostNodeForm);
-                    var virtualHostNodeContext = 
this.virtualHostNodeContext.get("value");
+                    const virtualHostNodeContext = 
this.virtualHostNodeContext.get("value");
                     if (virtualHostNodeContext)
                     {
                         virtualHostNodeData["context"] = 
virtualHostNodeContext;
@@ -386,19 +384,55 @@ define(["dojo/_base/event",
                 else if (!uploadVHConfig && 
this.virtualHostNodeForm.validate() && this.virtualHostForm.validate())
                 {
                     virtualHostNodeData = 
util.getFormWidgetValues(this.virtualHostNodeForm);
-                    var virtualHostNodeContext = 
this.virtualHostNodeContext.get("value");
+                    const virtualHostNodeContext = 
this.virtualHostNodeContext.get("value");
                     if (virtualHostNodeContext)
                     {
                         virtualHostNodeData["context"] = 
virtualHostNodeContext;
                     }
 
-                    var virtualHostData = 
util.getFormWidgetValues(this.virtualHostForm);
-                    var virtualHostContext = 
this.virtualHostContext.get("value");
+                    const virtualHostData = 
util.getFormWidgetValues(this.virtualHostForm);
+                    const virtualHostContext = 
this.virtualHostContext.get("value");
                     if (virtualHostContext)
                     {
                         virtualHostData["context"] = virtualHostContext;
                     }
 
+                    const keystore = 
dijit.registry.byId('addVirtualHost.keyStore').get('value');
+                    if (keystore)
+                    {
+                        virtualHostData["keyStore"] = keystore;
+                    }
+
+                    const keystorePathPropertyName = 
dijit.registry.byId("addVirtualHost.keyStorePathPropertyName").get("value");
+                    if (keystorePathPropertyName)
+                    {
+                        virtualHostData["keystorePathPropertyName"] = 
keystorePathPropertyName;
+                    }
+
+                    const keystorePasswordPropertyName = 
dijit.registry.byId("addVirtualHost.keyStorePasswordPropertyName").get("value");
+                    if (keystorePasswordPropertyName)
+                    {
+                        virtualHostData["keystorePasswordPropertyName"] = 
keystorePasswordPropertyName;
+                    }
+
+                    const truststore = 
dijit.registry.byId("addVirtualHost.trustStore").get("value");
+                    if (truststore)
+                    {
+                        virtualHostData["trustStore"] = truststore;
+                    }
+
+                    const truststorePathPropertyName = 
dijit.registry.byId("addVirtualHost.trustStorePathPropertyName").get("value");
+                    if (truststorePathPropertyName)
+                    {
+                        virtualHostData["truststorePathPropertyName"] = 
truststorePathPropertyName;
+                    }
+
+                    const truststorePasswordPropertyName = 
dijit.registry.byId("addVirtualHost.trustStorePasswordPropertyName").get("value");
+                    if (truststorePasswordPropertyName)
+                    {
+                        virtualHostData["truststorePasswordPropertyName"] = 
truststorePasswordPropertyName;
+                    }
+
                     //Default the VH name to be the same as the VHN name.
                     virtualHostData["name"] = virtualHostNodeData["name"];
 
@@ -411,12 +445,9 @@ define(["dojo/_base/event",
                     return;
                 }
 
-                var that = this;
+                const that = this;
                 that.management.create("virtualhostnode", {type: "broker"}, 
virtualHostNodeData)
-                    .then(function (x)
-                    {
-                        that.dialog.hide();
-                    });
+                    .then((x) => that.dialog.hide());
             }
         };
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to