001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.activemq.broker;
019
020 import java.io.IOException;
021 import java.net.URI;
022 import java.security.KeyManagementException;
023 import java.security.SecureRandom;
024
025 import javax.net.ssl.KeyManager;
026 import javax.net.ssl.TrustManager;
027
028 import org.apache.activemq.transport.TransportFactory;
029 import org.apache.activemq.transport.TransportServer;
030 import org.apache.activemq.transport.tcp.SslTransportFactory;
031
032 /**
033 * A BrokerService that allows access to the key and trust managers used by SSL
034 * connections. There is no reason to use this class unless SSL is being used
035 * AND the key and trust managers need to be specified from within code. In
036 * fact, if the URI passed to this class does not have an "ssl" scheme, this
037 * class will pass all work on to its superclass.
038 *
039 * @author sepandm@gmail.com (Sepand)
040 */
041 public class SslBrokerService extends BrokerService {
042 /**
043 * Adds a new transport connector for the given bind address. If the
044 * transport created uses SSL, it will also use the key and trust managers
045 * provided. Otherwise, this is the same as calling addConnector.
046 *
047 * @param bindAddress The address to bind to.
048 * @param km The KeyManager to be used.
049 * @param tm The trustmanager to be used.
050 * @param random The source of randomness for the generator.
051 * @return the newly connected and added transport connector.
052 * @throws Exception
053 */
054
055 public TransportConnector addSslConnector(String bindAddress, KeyManager[] km, TrustManager[] tm, SecureRandom random) throws Exception {
056 return addSslConnector(new URI(bindAddress), km, tm, random);
057 }
058
059 /**
060 * Adds a new transport connector for the given bind address. If the
061 * transport created uses SSL, it will also use the key and trust managers
062 * provided. Otherwise, this is the same as calling addConnector.
063 *
064 * @param bindAddress The URI to bind to.
065 * @param km The KeyManager to be used.
066 * @param tm The trustmanager to be used.
067 * @param random The source of randomness for the generator.
068 * @return the newly created and added transport connector.
069 * @throws Exception
070 */
071 public TransportConnector addSslConnector(URI bindAddress, KeyManager[] km, TrustManager[] tm, SecureRandom random) throws Exception {
072 return addConnector(createSslTransportServer(bindAddress, km, tm, random));
073 }
074
075 /**
076 * Creates a TransportServer that uses the given key and trust managers. The
077 * last three parameters will be eventually passed to SSLContext.init.
078 *
079 * @param brokerURI The URI to bind to.
080 * @param km The KeyManager to be used.
081 * @param tm The trustmanager to be used.
082 * @param random The source of randomness for the generator.
083 * @return A new TransportServer that uses the given managers.
084 * @throws IOException If cannot handle URI.
085 * @throws KeyManagementException Passed on from SSL.
086 */
087 protected TransportServer createSslTransportServer(URI brokerURI, KeyManager[] km, TrustManager[] tm, SecureRandom random) throws IOException, KeyManagementException {
088
089 if (brokerURI.getScheme().equals("ssl")) {
090 // If given an SSL URI, use an SSL TransportFactory and configure
091 // it to use the given key and trust managers.
092 SslTransportFactory transportFactory = new SslTransportFactory();
093
094 SslContext ctx = new SslContext(km, tm, random);
095 SslContext.setCurrentSslContext(ctx);
096 try {
097 return transportFactory.doBind(brokerURI);
098 } finally {
099 SslContext.setCurrentSslContext(null);
100 }
101
102 } else {
103 // Else, business as usual.
104 return TransportFactory.bind(this, brokerURI);
105 }
106 }
107 }