AMQP-484: Selectable SSL Algo

JIRA: https://jira.spring.io/browse/AMQP-484

(must remain at SSLv3 when backporting to 1.4.x)

Also add overridable method for additional context customization.

AMQP-484: Javadoc Polishing

Change `TLSv1.1` to the `SSLv3` by default
This commit is contained in:
Gary Russell
2015-03-16 20:54:27 +02:00
committed by Artem Bilan
parent 684c58d0da
commit 8d65032fd5
3 changed files with 118 additions and 9 deletions

View File

@@ -31,22 +31,30 @@ import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.ExceptionHandler;
import com.rabbitmq.client.SaslConfig;
import com.rabbitmq.client.SocketConfigurator;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.ExceptionHandler;
import com.rabbitmq.client.SaslConfig;
import com.rabbitmq.client.SocketConfigurator;
/**
* Factory bean to create a RabbitMQ ConnectionFactory, delegating most
* setter methods and optionally enabling SSL, with or without
* certificate validation.
* certificate validation. When {@link #setSslPropertiesLocation(Resource) sslPropertiesLocation}
* is not null, the default implementation loads a {@code PKCS12} keystore and a
* {@code JKS} truststore using the supplied properties and intializes {@code SunX509} key
* and trust manager factories. These are then used to initialize an {@link SSLContext}
* using the {@link #setSslAlgorithm(String) sslAlgorithm} (default TLSv1.1).
* <p>
* Override {@link #createSSLContext()} to create and/or perform further modification of the context.
* <p>
* Override {@link #setUpSSL()} to take complete control over setting up SSL.
*
* @author Gary Russell
*
@@ -54,12 +62,14 @@ import org.springframework.util.StringUtils;
*/
public class RabbitConnectionFactoryBean extends AbstractFactoryBean<ConnectionFactory> {
private final ConnectionFactory connectionFactory = new ConnectionFactory();
protected final ConnectionFactory connectionFactory = new ConnectionFactory();
private boolean useSSL;
private Resource sslPropertiesLocation;
private volatile String sslAlgorithm = "SSLv3";
/**
* Whether or not the factory should be configured to use SSL.
* @param useSSL true to use SSL.
@@ -68,6 +78,30 @@ public class RabbitConnectionFactoryBean extends AbstractFactoryBean<ConnectionF
this.useSSL = useSSL;
}
/**
* @return true to use ssl.
* @since 1.4.4.
*/
protected boolean isUseSSL() {
return useSSL;
}
/**
* Set the algorithm to use; default SSLv3.
* @param sslAlgorithm the algorithm.
*/
public void setSslAlgorithm(String sslAlgorithm) {
this.sslAlgorithm = sslAlgorithm;
}
/**
* @return the ssl algorithm.
* @since 1.4.4
*/
protected String getSslAlgorithm() {
return sslAlgorithm;
}
/**
* When {@link #setUseSSL(boolean)} is true, the SSL properties to use (optional).
* Resource referencing a properties file with the following properties:
@@ -83,6 +117,14 @@ public class RabbitConnectionFactoryBean extends AbstractFactoryBean<ConnectionF
this.sslPropertiesLocation = sslPropertiesLocation;
}
/**
* @return the properties location.
* @since 1.4.4
*/
protected Resource getSslPropertiesLocation() {
return sslPropertiesLocation;
}
/**
* @param host the host.
* @see com.rabbitmq.client.ConnectionFactory#setHost(java.lang.String)
@@ -246,7 +288,12 @@ public class RabbitConnectionFactoryBean extends AbstractFactoryBean<ConnectionF
return this.connectionFactory;
}
private void setUpSSL() throws Exception {
/**
* Override this method to take complete control over the SSL setup.
* @throws Exception an Exception.
* @since 1.4.4
*/
protected void setUpSSL() throws Exception {
if (this.sslPropertiesLocation == null) {
this.connectionFactory.useSslProtocol();
}
@@ -279,10 +326,21 @@ public class RabbitConnectionFactoryBean extends AbstractFactoryBean<ConnectionF
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(tks);
SSLContext context = SSLContext.getInstance("SSLv3");
SSLContext context = createSSLContext();
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
this.connectionFactory.useSslProtocol(context);
}
}
/**
* Override this method to create and/or configure the {@link SSLContext} used
* by the {@link ConnectionFactory}.
* @return The {@link SSLContext}.
* @throws NoSuchAlgorithmException if the algorithm is not available.
* @since 1.4.4
*/
protected SSLContext createSSLContext() throws NoSuchAlgorithmException {
return SSLContext.getInstance(this.sslAlgorithm);
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.amqp.rabbit.connection;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* @author Gary Russell
* @since 1.4.4
*
*/
public class SSLConnectionTests {
@Test @Ignore
public void test() throws Exception {
RabbitConnectionFactoryBean fb = new RabbitConnectionFactoryBean();
fb.setUseSSL(true);
fb.setSslPropertiesLocation(new ClassPathResource("ssl.properties"));
fb.afterPropertiesSet();
ConnectionFactory cf = fb.getObject();
Connection conn = cf.newConnection();
Channel chan = conn.createChannel();
chan.close();
conn.close();
}
}

View File

@@ -0,0 +1,4 @@
keyStore=file:/path/to/client/keycert.p12
trustStore=file:/path/to/client/truststore
keyStore.passPhrase=secret
trustStore.passPhrase=secret