All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xnio.ssl.JsseXnioSsl Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up with different versions on classes on the class path).

There is a newer version: 34.0.0.Final
Show newest version
/*
 * JBoss, Home of Professional Open Source.
 *
 * Copyright 2013 Red Hat, Inc. and/or its affiliates, and individual
 * contributors as indicated by the @author tags.
 *
 * 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.xnio.ssl;

import static java.security.AccessController.doPrivileged;
import static org.xnio.IoUtils.safeClose;
import static org.xnio._private.Messages.msg;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivilegedAction;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import org.xnio.BufferAllocator;
import org.xnio.ByteBufferSlicePool;
import org.xnio.ChannelListener;
import org.xnio.ChannelListeners;
import org.xnio.FutureResult;
import org.xnio.IoFuture;
import org.xnio.IoUtils;
import org.xnio.Option;
import org.xnio.OptionMap;
import org.xnio.Options;
import org.xnio.Pool;
import org.xnio.StreamConnection;
import org.xnio.Xnio;
import org.xnio.XnioExecutor;
import org.xnio.XnioIoThread;
import org.xnio.XnioWorker;
import org.xnio.channels.AcceptingChannel;
import org.xnio.channels.AssembledConnectedSslStreamChannel;
import org.xnio.channels.BoundChannel;
import org.xnio.channels.ConnectedSslStreamChannel;
import org.xnio.channels.ConnectedStreamChannel;

/**
 * An XNIO SSL provider based on JSSE.  Works with any XNIO provider.
 *
 * @author David M. Lloyd
 * @author Flavia Rainone
 */
public final class JsseXnioSsl extends XnioSsl {
    public static final boolean NEW_IMPL = doPrivileged((PrivilegedAction) () -> Boolean.valueOf(Boolean.parseBoolean(System.getProperty("org.xnio.ssl.new", "false")))).booleanValue();

    static final Pool bufferPool = new ByteBufferSlicePool(BufferAllocator.DIRECT_BYTE_BUFFER_ALLOCATOR, 21 * 1024, 21 * 1024 * 128);
    private final SSLContext sslContext;

    /**
     * Construct a new instance.
     *
     * @param xnio the XNIO instance to associate with
     * @param optionMap the options for this provider
     * @throws NoSuchProviderException if the given SSL provider is not found
     * @throws NoSuchAlgorithmException if the given SSL algorithm is not supported
     * @throws KeyManagementException if the SSL context could not be initialized
     */
    public JsseXnioSsl(final Xnio xnio, final OptionMap optionMap) throws NoSuchProviderException, NoSuchAlgorithmException, KeyManagementException {
        this(xnio, optionMap, JsseSslUtils.createSSLContext(optionMap));
    }

    /**
     * Construct a new instance.
     *
     * @param xnio the XNIO instance to associate with
     * @param optionMap the options for this provider
     * @param sslContext the SSL context to use for this instance
     */
    public JsseXnioSsl(final Xnio xnio, final OptionMap optionMap, final SSLContext sslContext) {
        super(xnio, sslContext, optionMap);
        this.sslContext = sslContext;
    }

    /**
     * Get the JSSE SSL context for this provider instance.
     *
     * @return the SSL context
     */
    @SuppressWarnings("unused")
    public SSLContext getSslContext() {
        return sslContext;
    }

    /**
     * Get the SSL engine for a given connection.
     *
     * @return the SSL engine
     */
    public static SSLEngine getSslEngine(SslConnection connection) {
        if (connection instanceof JsseSslStreamConnection) {
            return ((JsseSslStreamConnection) connection).getEngine();
        } else if (connection instanceof JsseSslConnection) {
            return ((JsseSslConnection) connection).getEngine();
        } else {
            throw msg.notFromThisProvider();
        }
    }

    @SuppressWarnings("deprecation")
    public IoFuture connectSsl(final XnioWorker worker, final InetSocketAddress bindAddress, final InetSocketAddress destination, final ChannelListener openListener, final ChannelListener bindListener, final OptionMap optionMap) {
        final FutureResult futureResult = new FutureResult(IoUtils.directExecutor());
        final IoFuture futureSslConnection = openSslConnection(worker, bindAddress, destination, new ChannelListener() {
                    public void handleEvent(final SslConnection sslConnection) {
                        final ConnectedSslStreamChannel assembledChannel = new AssembledConnectedSslStreamChannel(sslConnection, sslConnection.getSourceChannel(), sslConnection.getSinkChannel());
                        if (!futureResult.setResult(assembledChannel)) {
                            safeClose(assembledChannel);
                        } else {
                            ChannelListeners.invokeChannelListener(assembledChannel, openListener);
                        }
                    }
                }, bindListener, optionMap).addNotifier(new IoFuture.HandlingNotifier>() {
            public void handleCancelled(final FutureResult result) {
                result.setCancelled();
            }

            public void handleFailed(final IOException exception, final FutureResult result) {
                result.setException(exception);
            }
        }, futureResult);
        futureResult.getIoFuture().addNotifier(new IoFuture.HandlingNotifier>() {
            public void handleCancelled(final IoFuture result) {
                result.cancel();
            }
        }, futureSslConnection);
        futureResult.addCancelHandler(futureSslConnection);
        return futureResult.getIoFuture();
    }

    public IoFuture openSslConnection(final XnioWorker worker, final InetSocketAddress bindAddress, final InetSocketAddress destination, final ChannelListener openListener, final ChannelListener bindListener, final OptionMap optionMap) {
        return openSslConnection(worker.getIoThread(), bindAddress, destination, openListener, bindListener, optionMap);
    }

    public IoFuture openSslConnection(final XnioIoThread ioThread, final InetSocketAddress bindAddress, final InetSocketAddress destination, final ChannelListener openListener, final ChannelListener bindListener, final OptionMap optionMap) {
        final FutureResult futureResult = new FutureResult<>(ioThread);
        final IoFuture connection = ioThread.openStreamConnection(bindAddress, destination, new ChannelListener() {
            public void handleEvent(final StreamConnection connection) {
                final SSLEngine sslEngine = JsseSslUtils.createSSLEngine(sslContext, optionMap, destination);
                final boolean startTls = optionMap.get(Options.SSL_STARTTLS, false);
                final SslConnection wrappedConnection;
                try {
                    wrappedConnection = NEW_IMPL ? new JsseSslConnection(connection, sslEngine, bufferPool, bufferPool) : new JsseSslStreamConnection(connection, sslEngine, bufferPool, bufferPool, startTls);
                } catch (RuntimeException e) {
                    futureResult.setCancelled();
                    throw e;
                }
                if (NEW_IMPL && ! startTls) {
                    try {
                        wrappedConnection.startHandshake();
                    } catch (IOException e) {
                        if (futureResult.setException(e)) {
                            IoUtils.safeClose(connection);
                        }
                    }
                }
                if (! futureResult.setResult(wrappedConnection)) {
                    IoUtils.safeClose(connection);
                } else {
                    ChannelListeners.invokeChannelListener(wrappedConnection, openListener);
                }
            }
        }, bindListener, optionMap);
        connection.addNotifier(new IoFuture.HandlingNotifier>() {
            public void handleCancelled(final FutureResult attachment) {
                attachment.setCancelled();
            }

            public void handleFailed(final IOException exception, final FutureResult attachment) {
                attachment.setException(exception);
            }
        }, futureResult);
        futureResult.addCancelHandler(connection);
        return futureResult.getIoFuture();
    }

    @SuppressWarnings("deprecation")
    public AcceptingChannel createSslTcpServer(final XnioWorker worker, final InetSocketAddress bindAddress, final ChannelListener> acceptListener, final OptionMap optionMap) throws IOException {
        final AcceptingChannel server = createSslConnectionServer(worker, bindAddress, null, optionMap);
        final AcceptingChannel acceptingChannel = new AcceptingChannel() {
            public ConnectedSslStreamChannel accept() throws IOException {
                final SslConnection connection = server.accept();
                return connection == null ? null : new AssembledConnectedSslStreamChannel(connection, connection.getSourceChannel(), connection.getSinkChannel());
            }

            public ChannelListener.Setter> getAcceptSetter() {
                return ChannelListeners.getDelegatingSetter(server.getAcceptSetter(), this);
            }

            public ChannelListener.Setter> getCloseSetter() {
                return ChannelListeners.getDelegatingSetter(server.getCloseSetter(), this);
            }

            public SocketAddress getLocalAddress() {
                return server.getLocalAddress();
            }

            public  A getLocalAddress(final Class type) {
                return server.getLocalAddress(type);
            }

            public void suspendAccepts() {
                server.suspendAccepts();
            }

            public void resumeAccepts() {
                server.resumeAccepts();
            }

            public boolean isAcceptResumed() {
                return server.isAcceptResumed();
            }

            public void wakeupAccepts() {
                server.wakeupAccepts();
            }

            public void awaitAcceptable() throws IOException {
                server.awaitAcceptable();
            }

            public void awaitAcceptable(final long time, final TimeUnit timeUnit) throws IOException {
                server.awaitAcceptable(time, timeUnit);
            }

            public XnioWorker getWorker() {
                return server.getWorker();
            }

            @Deprecated
            public XnioExecutor getAcceptThread() {
                return server.getAcceptThread();
            }

            public XnioIoThread getIoThread() {
                return server.getIoThread();
            }

            public void close() throws IOException {
                server.close();
            }

            public boolean isOpen() {
                return server.isOpen();
            }

            public boolean supportsOption(final Option option) {
                return server.supportsOption(option);
            }

            public  T getOption(final Option option) throws IOException {
                return server.getOption(option);
            }

            public  T setOption(final Option option, final T value) throws IllegalArgumentException, IOException {
                return server.setOption(option, value);
            }
        };
        acceptingChannel.getAcceptSetter().set(acceptListener);
        return acceptingChannel;
    }

    public AcceptingChannel createSslConnectionServer(final XnioWorker worker, final InetSocketAddress bindAddress, final ChannelListener> acceptListener, final OptionMap optionMap) throws IOException {
       final JsseAcceptingSslStreamConnection server = new JsseAcceptingSslStreamConnection(sslContext, worker.createStreamConnectionServer(bindAddress,  null,  optionMap), optionMap, bufferPool, bufferPool, optionMap.get(Options.SSL_STARTTLS, false));
        if (acceptListener != null) server.getAcceptSetter().set(acceptListener);
        return server;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy