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 import java.util.Arrays; 025 026 import javax.net.ssl.KeyManager; 027 import javax.net.ssl.TrustManager; 028 029 import org.apache.activemq.transport.TransportFactory; 030 import org.apache.activemq.transport.TransportServer; 031 import org.apache.activemq.transport.tcp.SslTransportFactory; 032 033 /** 034 * A BrokerService that allows access to the key and trust managers used by SSL 035 * connections. There is no reason to use this class unless SSL is being used 036 * AND the key and trust managers need to be specified from within code. In 037 * fact, if the URI passed to this class does not have an "ssl" scheme, this 038 * class will pass all work on to its superclass. 039 * 040 * @author sepandm@gmail.com (Sepand) 041 */ 042 public class SslBrokerService extends BrokerService { 043 /** 044 * Adds a new transport connector for the given bind address. If the 045 * transport created uses SSL, it will also use the key and trust managers 046 * provided. Otherwise, this is the same as calling addConnector. 047 * 048 * @param bindAddress The address to bind to. 049 * @param km The KeyManager to be used. 050 * @param tm The trustmanager to be used. 051 * @param random The source of randomness for the generator. 052 * @return the newly connected and added transport connector. 053 * @throws Exception 054 */ 055 056 public TransportConnector addSslConnector(String bindAddress, KeyManager[] km, TrustManager[] tm, SecureRandom random) throws Exception { 057 return addSslConnector(new URI(bindAddress), km, tm, random); 058 } 059 060 /** 061 * Adds a new transport connector for the given bind address. If the 062 * transport created uses SSL, it will also use the key and trust managers 063 * provided. Otherwise, this is the same as calling addConnector. 064 * 065 * @param bindAddress The URI to bind to. 066 * @param km The KeyManager to be used. 067 * @param tm The trustmanager to be used. 068 * @param random The source of randomness for the generator. 069 * @return the newly created and added transport connector. 070 * @throws Exception 071 */ 072 public TransportConnector addSslConnector(URI bindAddress, KeyManager[] km, TrustManager[] tm, SecureRandom random) throws Exception { 073 return addConnector(createSslTransportServer(bindAddress, km, tm, random)); 074 } 075 076 /** 077 * Creates a TransportServer that uses the given key and trust managers. The 078 * last three parameters will be eventually passed to SSLContext.init. 079 * 080 * @param brokerURI The URI to bind to. 081 * @param km The KeyManager to be used. 082 * @param tm The trustmanager to be used. 083 * @param random The source of randomness for the generator. 084 * @return A new TransportServer that uses the given managers. 085 * @throws IOException If cannot handle URI. 086 * @throws KeyManagementException Passed on from SSL. 087 */ 088 protected TransportServer createSslTransportServer(URI brokerURI, KeyManager[] km, TrustManager[] tm, SecureRandom random) throws IOException, KeyManagementException { 089 090 if (brokerURI.getScheme().equals("ssl")) { 091 // If given an SSL URI, use an SSL TransportFactory and configure 092 // it to use the given key and trust managers. 093 SslTransportFactory transportFactory = new SslTransportFactory(); 094 095 SslContext ctx = new SslContext(km, tm, random); 096 SslContext.setCurrentSslContext(ctx); 097 try { 098 return transportFactory.doBind(brokerURI); 099 } finally { 100 SslContext.setCurrentSslContext(null); 101 } 102 103 } else { 104 // Else, business as usual. 105 return TransportFactory.bind(this, brokerURI); 106 } 107 } 108 }