AMQP-626: Add keystore\truststore type setters
JIRA: https://jira.spring.io/browse/AMQP-626 Fixes GH-436 (https://github.com/spring-projects/spring-amqp/issues/436) Currently the `RabbitConnectionFactoryBean` has hard-coded keystore/truststore types. * Add setters for keystore/truststore types and leave previously-hardcoded as default values. * Add `keyStore.type` and `trustStore.type` properties for the `ssl.properties` resource
This commit is contained in:
committed by
Artem Bilan
parent
83c499f1cf
commit
208775dd2e
@@ -57,6 +57,7 @@ import com.rabbitmq.client.SocketConfigurator;
|
||||
* Override {@link #setUpSSL()} to take complete control over setting up SSL.
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @author Heath Abelson
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
@@ -70,8 +71,16 @@ public class RabbitConnectionFactoryBean extends AbstractFactoryBean<ConnectionF
|
||||
|
||||
private static final String TRUST_STORE_PASS_PHRASE = "trustStore.passPhrase";
|
||||
|
||||
private static final String KEY_STORE_TYPE = "keyStore.type";
|
||||
|
||||
private static final String TRUST_STORE_TYPE = "trustStore.type";
|
||||
|
||||
private static final String TLS_V1_1 = "TLSv1.1";
|
||||
|
||||
private static final String KEY_STORE_DEFAULT_TYPE = "PKCS12";
|
||||
|
||||
private static final String TRUST_STORE_DEFAULT_TYPE = "JKS";
|
||||
|
||||
protected final ConnectionFactory connectionFactory = new ConnectionFactory();
|
||||
|
||||
private final Properties sslProperties = new Properties();
|
||||
@@ -88,6 +97,10 @@ public class RabbitConnectionFactoryBean extends AbstractFactoryBean<ConnectionF
|
||||
|
||||
private volatile String trustStorePassphrase;
|
||||
|
||||
private volatile String keyStoreType;
|
||||
|
||||
private volatile String trustStoreType;
|
||||
|
||||
private volatile String sslAlgorithm = TLS_V1_1;
|
||||
|
||||
private volatile boolean sslAlgorithmSet;
|
||||
@@ -225,6 +238,64 @@ public class RabbitConnectionFactoryBean extends AbstractFactoryBean<ConnectionF
|
||||
this.trustStorePassphrase = trustStorePassphrase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key store type - this defaults to PKCS12 if not overridden by
|
||||
* {@link #setSslPropertiesLocation(Resource)} or {@link #setKeyStoreType}
|
||||
* @return the key store type.
|
||||
* @since 1.6.2
|
||||
*/
|
||||
protected String getKeyStoreType() {
|
||||
if (this.keyStoreType == null && this.sslProperties.getProperty(KEY_STORE_TYPE) == null) {
|
||||
return KEY_STORE_DEFAULT_TYPE;
|
||||
}
|
||||
else if (this.keyStoreType != null) {
|
||||
return this.keyStoreType;
|
||||
}
|
||||
else {
|
||||
return this.sslProperties.getProperty(KEY_STORE_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the key store type - overrides
|
||||
* the property in {@link #setSslPropertiesLocation(Resource)}.
|
||||
* @param keyStoreType the key store type.
|
||||
* @see java.security.KeyStore#getInstance(String)
|
||||
* @since 1.6.2
|
||||
*/
|
||||
public void setKeyStoreType(String keyStoreType) {
|
||||
this.keyStoreType = keyStoreType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the trust store type - this defaults to JKS if not overridden by
|
||||
* {@link #setSslPropertiesLocation(Resource)} or {@link #setTrustStoreType}
|
||||
* @return the trust store type.
|
||||
* @since 1.6.2
|
||||
*/
|
||||
protected String getTrustStoreType() {
|
||||
if (this.trustStoreType == null && this.sslProperties.getProperty(TRUST_STORE_TYPE) == null) {
|
||||
return TRUST_STORE_DEFAULT_TYPE;
|
||||
}
|
||||
else if (this.trustStoreType != null) {
|
||||
return this.trustStoreType;
|
||||
}
|
||||
else {
|
||||
return this.sslProperties.getProperty(TRUST_STORE_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the trust store type - overrides
|
||||
* the property in {@link #setSslPropertiesLocation(Resource)}.
|
||||
* @param trustStoreType the trust store type.
|
||||
* @see java.security.KeyStore#getInstance(String)
|
||||
* @since 1.6.2
|
||||
*/
|
||||
public void setTrustStoreType(String trustStoreType) {
|
||||
this.trustStoreType = trustStoreType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param host the host.
|
||||
* @see com.rabbitmq.client.ConnectionFactory#setHost(java.lang.String)
|
||||
@@ -417,18 +488,20 @@ public class RabbitConnectionFactoryBean extends AbstractFactoryBean<ConnectionF
|
||||
Assert.state(StringUtils.hasText(keyStorePassword), KEY_STORE_PASS_PHRASE + " property required");
|
||||
String trustStorePassword = getTrustStorePassphrase();
|
||||
Assert.state(StringUtils.hasText(trustStorePassword), TRUST_STORE_PASS_PHRASE + " property required");
|
||||
String keyStoreType = getKeyStoreType();
|
||||
String trustStoreType = getTrustStoreType();
|
||||
Resource keyStore = resolver.getResource(keyStoreName);
|
||||
Resource trustStore = resolver.getResource(trustStoreName);
|
||||
char[] keyPassphrase = keyStorePassword.toCharArray();
|
||||
char[] trustPassphrase = trustStorePassword.toCharArray();
|
||||
|
||||
KeyStore ks = KeyStore.getInstance("PKCS12");
|
||||
KeyStore ks = KeyStore.getInstance(keyStoreType);
|
||||
ks.load(keyStore.getInputStream(), keyPassphrase);
|
||||
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
|
||||
kmf.init(ks, keyPassphrase);
|
||||
|
||||
KeyStore tks = KeyStore.getInstance("JKS");
|
||||
KeyStore tks = KeyStore.getInstance(trustStoreType);
|
||||
tks.load(trustStore.getInputStream(), trustPassphrase);
|
||||
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.amqp.rabbit.connection;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@@ -35,6 +36,7 @@ import com.rabbitmq.client.ConnectionFactory;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @author Heath Abelson
|
||||
* @since 1.4.4
|
||||
*
|
||||
*/
|
||||
@@ -79,4 +81,56 @@ public class SSLConnectionTests {
|
||||
verify(rabbitCf).useSslProtocol();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeDefault() throws Exception {
|
||||
RabbitConnectionFactoryBean fb = new RabbitConnectionFactoryBean();
|
||||
assertEquals("PKCS12", fb.getKeyStoreType());
|
||||
assertEquals("JKS", fb.getTrustStoreType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeProps() throws Exception {
|
||||
RabbitConnectionFactoryBean fb = new RabbitConnectionFactoryBean();
|
||||
fb.setSslPropertiesLocation(new ClassPathResource("ssl.properties"));
|
||||
fb.afterPropertiesSet();
|
||||
try {
|
||||
fb.setUpSSL();
|
||||
//Here we make sure the exception is thrown because setUpSSL() will fail.
|
||||
// But we only care about having it load the props
|
||||
fail("setupSSL should fail");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertEquals("foo", fb.getKeyStoreType());
|
||||
assertEquals("bar", fb.getTrustStoreType());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeSettersNoProps() throws Exception {
|
||||
RabbitConnectionFactoryBean fb = new RabbitConnectionFactoryBean();
|
||||
fb.setKeyStoreType("alice");
|
||||
fb.setTrustStoreType("bob");
|
||||
assertEquals("alice", fb.getKeyStoreType());
|
||||
assertEquals("bob", fb.getTrustStoreType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeSettersOverrideProps() throws Exception {
|
||||
RabbitConnectionFactoryBean fb = new RabbitConnectionFactoryBean();
|
||||
fb.setSslPropertiesLocation(new ClassPathResource("ssl.properties"));
|
||||
fb.afterPropertiesSet();
|
||||
fb.setKeyStoreType("alice");
|
||||
fb.setTrustStoreType("bob");
|
||||
try {
|
||||
fb.setUpSSL();
|
||||
// Here we make sure the exception is thrown because setUpSSL() will fail.
|
||||
//But we only care about having it load the props
|
||||
fail("setupSSL should fail");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertEquals("alice", fb.getKeyStoreType());
|
||||
assertEquals("bob", fb.getTrustStoreType());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,3 +2,5 @@ keyStore=file:/path/to/client/keycert.p12
|
||||
trustStore=file:/path/to/client/truststore
|
||||
keyStore.passPhrase=secret
|
||||
trustStore.passPhrase=secret
|
||||
keyStore.type=foo
|
||||
trustStore.type=bar
|
||||
|
||||
Reference in New Issue
Block a user