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 java.io.IOException;
023: import java.net.SocketAddress;
024: import java.net.URL;
025: import java.security.GeneralSecurityException;
026: import java.security.KeyStore;
027:
028: import javax.net.ssl.KeyManager;
029: import javax.net.ssl.KeyManagerFactory;
030: import javax.net.ssl.SSLContext;
031: import javax.net.ssl.SSLEngine;
032: import javax.net.ssl.SSLException;
033: import javax.net.ssl.SSLSession;
034: import javax.net.ssl.TrustManager;
035: import javax.net.ssl.TrustManagerFactory;
036: import javax.xml.namespace.QName;
037:
038: import org.apache.axiom.om.OMElement;
039: import org.apache.axis2.AxisFault;
040: import org.apache.axis2.context.ConfigurationContext;
041: import org.apache.axis2.description.Parameter;
042: import org.apache.axis2.description.TransportInDescription;
043: import org.apache.commons.logging.Log;
044: import org.apache.commons.logging.LogFactory;
045: import org.apache.http.impl.nio.reactor.SSLIOSessionHandler;
046: import org.apache.http.nio.NHttpServiceHandler;
047: import org.apache.http.nio.reactor.IOEventDispatch;
048: import org.apache.http.params.HttpParams;
049:
050: public class HttpCoreNIOSSLListener extends HttpCoreNIOListener {
051:
052: private static final Log log = LogFactory
053: .getLog(HttpCoreNIOSSLListener.class);
054:
055: protected IOEventDispatch getEventDispatch(
056: NHttpServiceHandler handler, SSLContext sslContext,
057: SSLIOSessionHandler sslIOSessionHandler, HttpParams params) {
058: return new SSLServerIOEventDispatch(handler, sslContext,
059: sslIOSessionHandler, params);
060: }
061:
062: /**
063: * Return the EPR prefix for services made available over this transport
064: * @return
065: */
066: protected String getServiceEPRPrefix(ConfigurationContext cfgCtx,
067: String host, int port) {
068: return "https://"
069: + host
070: + (port == 443 ? "" : ":" + port)
071: + (!cfgCtx.getServiceContextPath().startsWith("/") ? "/"
072: : "")
073: + cfgCtx.getServiceContextPath()
074: + (!cfgCtx.getServiceContextPath().endsWith("/") ? "/"
075: : "");
076: }
077:
078: /**
079: * Create the SSLContext to be used by this listener
080: * @param transportIn the Axis2 transport description
081: * @return the SSLContext to be used
082: */
083: protected SSLContext getSSLContext(
084: TransportInDescription transportIn) throws AxisFault {
085:
086: KeyManager[] keymanagers = null;
087: TrustManager[] trustManagers = null;
088:
089: Parameter keyParam = transportIn.getParameter("keystore");
090: Parameter trustParam = transportIn.getParameter("truststore");
091:
092: if (keyParam != null) {
093: OMElement ksEle = keyParam.getParameterElement()
094: .getFirstElement();
095: String location = ksEle.getFirstChildWithName(
096: new QName("Location")).getText();
097: String type = ksEle
098: .getFirstChildWithName(new QName("Type")).getText();
099: String storePassword = ksEle.getFirstChildWithName(
100: new QName("Password")).getText();
101: String keyPassword = ksEle.getFirstChildWithName(
102: new QName("KeyPassword")).getText();
103:
104: try {
105: KeyStore keyStore = KeyStore.getInstance(type);
106: URL url = getClass().getClassLoader().getResource(
107: location);
108: log.debug("Loading Key Store from URL : " + url);
109:
110: keyStore.load(url.openStream(), storePassword
111: .toCharArray());
112: KeyManagerFactory kmfactory = KeyManagerFactory
113: .getInstance(KeyManagerFactory
114: .getDefaultAlgorithm());
115: kmfactory.init(keyStore, keyPassword.toCharArray());
116: keymanagers = kmfactory.getKeyManagers();
117:
118: } catch (GeneralSecurityException gse) {
119: log.error("Error loading Key store : " + location, gse);
120: throw new AxisFault("Error loading Key store : "
121: + location, gse);
122: } catch (IOException ioe) {
123: log.error("Error opening Key store : " + location, ioe);
124: throw new AxisFault("Error opening Key store : "
125: + location, ioe);
126: }
127: }
128:
129: if (trustParam != null) {
130: OMElement tsEle = trustParam.getParameterElement()
131: .getFirstElement();
132: String location = tsEle.getFirstChildWithName(
133: new QName("Location")).getText();
134: String type = tsEle
135: .getFirstChildWithName(new QName("Type")).getText();
136: String storePassword = tsEle.getFirstChildWithName(
137: new QName("Password")).getText();
138:
139: try {
140: KeyStore trustStore = KeyStore.getInstance(type);
141: URL url = getClass().getClassLoader().getResource(
142: location);
143: log.debug("Loading Trust Key Store from URL : " + url);
144:
145: trustStore.load(url.openStream(), storePassword
146: .toCharArray());
147: TrustManagerFactory trustManagerfactory = TrustManagerFactory
148: .getInstance(TrustManagerFactory
149: .getDefaultAlgorithm());
150: trustManagerfactory.init(trustStore);
151: trustManagers = trustManagerfactory.getTrustManagers();
152:
153: } catch (GeneralSecurityException gse) {
154: log.error("Error loading Key store : " + location, gse);
155: throw new AxisFault("Error loading Key store : "
156: + location, gse);
157: } catch (IOException ioe) {
158: log.error("Error opening Key store : " + location, ioe);
159: throw new AxisFault("Error opening Key store : "
160: + location, ioe);
161: }
162: }
163:
164: try {
165: SSLContext sslcontext = SSLContext.getInstance("TLS");
166: sslcontext.init(keymanagers, trustManagers, null);
167: return sslcontext;
168:
169: } catch (GeneralSecurityException gse) {
170: log
171: .error(
172: "Unable to create SSL context with the given configuration",
173: gse);
174: throw new AxisFault(
175: "Unable to create SSL context with the given configuration",
176: gse);
177: }
178: }
179:
180: /**
181: * Create the SSLIOSessionHandler to initialize the SSL session / engine, and request for
182: * client authentication at the following levels, through an Axis2 transport configuration
183: * parameter as follows:
184: * SSLVerifyClient - none, optional, require
185: *
186: * @param transportIn the Axis2 transport configuration
187: * @return the SSLIOSessionHandler to be used
188: * @throws AxisFault if a configuration error occurs
189: */
190: protected SSLIOSessionHandler getSSLIOSessionHandler(
191: TransportInDescription transportIn) throws AxisFault {
192:
193: final Parameter clientAuth = transportIn
194: .getParameter("SSLVerifyClient");
195:
196: return new SSLIOSessionHandler() {
197:
198: public void initalize(SSLEngine sslengine, HttpParams params) {
199: if (clientAuth != null) {
200: if ("optional".equals(clientAuth.getValue())) {
201: sslengine.setWantClientAuth(true);
202: } else if ("require".equals(clientAuth.getValue())) {
203: sslengine.setNeedClientAuth(true);
204: }
205: }
206: }
207:
208: public void verify(SocketAddress removeAddress,
209: SSLSession session) throws SSLException {
210: }
211: };
212: }
213: }
|