001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: package org.apache.axis2.transport.nhttp;
021:
022: import org.apache.commons.logging.LogFactory;
023: import org.apache.commons.logging.Log;
024: import org.apache.http.nio.reactor.IOEventDispatch;
025: import org.apache.http.nio.NHttpClientHandler;
026: import org.apache.http.impl.nio.reactor.SSLIOSessionHandler;
027: import org.apache.http.params.HttpParams;
028: import org.apache.axis2.AxisFault;
029: import org.apache.axis2.description.Parameter;
030: import org.apache.axis2.description.TransportOutDescription;
031: import org.apache.axiom.om.OMElement;
032:
033: import javax.net.ssl.*;
034: import javax.xml.namespace.QName;
035: import java.security.GeneralSecurityException;
036: import java.security.KeyStore;
037: import java.net.URL;
038: import java.net.SocketAddress;
039: import java.net.InetSocketAddress;
040: import java.io.IOException;
041:
042: public class HttpCoreNIOSSLSender extends HttpCoreNIOSender {
043:
044: private static final Log log = LogFactory
045: .getLog(HttpCoreNIOSSLSender.class);
046:
047: protected IOEventDispatch getEventDispatch(
048: NHttpClientHandler handler, SSLContext sslContext,
049: SSLIOSessionHandler sslIOSessionHandler, HttpParams params) {
050: return new SSLClientIOEventDispatch(handler, sslContext,
051: sslIOSessionHandler, params);
052: }
053:
054: /*
055: *
056: * Create the SSLContext to be used by this listener
057: * @param transportOut the Axis2 transport configuration
058: * @return the SSLContext to be used
059: */
060:
061: protected SSLContext getSSLContext(
062: TransportOutDescription transportOut) throws AxisFault {
063:
064: KeyManager[] keymanagers = null;
065: TrustManager[] trustManagers = null;
066:
067: Parameter keyParam = transportOut.getParameter("keystore");
068: Parameter trustParam = transportOut.getParameter("truststore");
069:
070: if (keyParam != null) {
071: OMElement ksEle = keyParam.getParameterElement()
072: .getFirstElement();
073: String location = ksEle.getFirstChildWithName(
074: new QName("Location")).getText();
075: String type = ksEle
076: .getFirstChildWithName(new QName("Type")).getText();
077: String storePassword = ksEle.getFirstChildWithName(
078: new QName("Password")).getText();
079: String keyPassword = ksEle.getFirstChildWithName(
080: new QName("KeyPassword")).getText();
081:
082: try {
083: KeyStore keyStore = KeyStore.getInstance(type);
084: URL url = getClass().getClassLoader().getResource(
085: location);
086: log.debug("Loading Key Store from URL : " + url);
087:
088: keyStore.load(url.openStream(), storePassword
089: .toCharArray());
090: KeyManagerFactory kmfactory = KeyManagerFactory
091: .getInstance(KeyManagerFactory
092: .getDefaultAlgorithm());
093: kmfactory.init(keyStore, keyPassword.toCharArray());
094: keymanagers = kmfactory.getKeyManagers();
095:
096: } catch (GeneralSecurityException gse) {
097: log.error("Error loading Key store : " + location, gse);
098: throw new AxisFault("Error loading Key store : "
099: + location, gse);
100: } catch (IOException ioe) {
101: log.error("Error opening Key store : " + location, ioe);
102: throw new AxisFault("Error opening Key store : "
103: + location, ioe);
104: }
105: }
106:
107: if (trustParam != null) {
108: OMElement tsEle = trustParam.getParameterElement()
109: .getFirstElement();
110: String location = tsEle.getFirstChildWithName(
111: new QName("Location")).getText();
112: String type = tsEle
113: .getFirstChildWithName(new QName("Type")).getText();
114: String storePassword = tsEle.getFirstChildWithName(
115: new QName("Password")).getText();
116:
117: try {
118: KeyStore trustStore = KeyStore.getInstance(type);
119: URL url = getClass().getClassLoader().getResource(
120: location);
121: log.debug("Loading Trust Key Store from URL : " + url);
122:
123: trustStore.load(url.openStream(), storePassword
124: .toCharArray());
125: TrustManagerFactory trustManagerfactory = TrustManagerFactory
126: .getInstance(TrustManagerFactory
127: .getDefaultAlgorithm());
128: trustManagerfactory.init(trustStore);
129: trustManagers = trustManagerfactory.getTrustManagers();
130:
131: } catch (GeneralSecurityException gse) {
132: log.error("Error loading Key store : " + location, gse);
133: throw new AxisFault("Error loading Key store : "
134: + location, gse);
135: } catch (IOException ioe) {
136: log.error("Error opening Key store : " + location, ioe);
137: throw new AxisFault("Error opening Key store : "
138: + location, ioe);
139: }
140: }
141:
142: try {
143: SSLContext sslcontext = SSLContext.getInstance("TLS");
144: sslcontext.init(keymanagers, trustManagers, null);
145: return sslcontext;
146:
147: } catch (GeneralSecurityException gse) {
148: log
149: .error(
150: "Unable to create SSL context with the given configuration",
151: gse);
152: throw new AxisFault(
153: "Unable to create SSL context with the given configuration",
154: gse);
155: }
156: }
157:
158: /*
159: *
160: * Create the SSLIOSessionHandler to initialize the host name verification at the following
161: * levels, through an Axis2 transport configuration parameter as follows:
162: * HostnameVerifier - Default, DefaultAndLocalhost, Strict, AllowAll
163: *
164: * @param transportOut the Axis2 transport configuration
165: * @return the SSLIOSessionHandler to be used
166: * @throws AxisFault if a configuration error occurs
167: */
168:
169: protected SSLIOSessionHandler getSSLIOSessionHandler(
170: TransportOutDescription transportOut) throws AxisFault {
171:
172: final Parameter hostnameVerifier = transportOut
173: .getParameter("HostnameVerifier");
174:
175: return new SSLIOSessionHandler() {
176:
177: public void initalize(SSLEngine sslengine, HttpParams params) {
178: }
179:
180: public void verify(SocketAddress remoteAddress,
181: SSLSession session) throws SSLException {
182:
183: String address = null;
184: if (remoteAddress instanceof InetSocketAddress) {
185: address = ((InetSocketAddress) remoteAddress)
186: .getHostName();
187: } else {
188: address = remoteAddress.toString();
189: }
190:
191: boolean valid = false;
192: if (hostnameVerifier != null) {
193: if ("Strict".equals(hostnameVerifier.getValue())) {
194: valid = HostnameVerifier.STRICT.verify(address,
195: session);
196: } else if ("AllowAll".equals(hostnameVerifier
197: .getValue())) {
198: valid = HostnameVerifier.ALLOW_ALL.verify(
199: address, session);
200: } else if ("DefaultAndLocalhost"
201: .equals(hostnameVerifier.getValue())) {
202: valid = HostnameVerifier.DEFAULT_AND_LOCALHOST
203: .verify(address, session);
204: }
205: } else {
206: valid = HostnameVerifier.DEFAULT.verify(address,
207: session);
208: }
209:
210: if (!valid) {
211: throw new SSLException(
212: "Host name verification failed for host : "
213: + address);
214: }
215: }
216: };
217: }
218: }
|