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

com.fireflysource.net.tcp.secure.jdk.OpenJdkApplicationProtocolSelector Maven / Gradle / Ivy

There is a newer version: 5.0.2
Show newest version
package com.fireflysource.net.tcp.secure.jdk;

import com.fireflysource.common.slf4j.LazyLogger;
import com.fireflysource.common.string.StringUtils;
import com.fireflysource.common.sys.JavaVersion;
import com.fireflysource.common.sys.SystemLogger;
import com.fireflysource.net.tcp.secure.ApplicationProtocolSelector;

import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
import java.lang.reflect.Method;
import java.util.List;
import java.util.function.BiFunction;

public class OpenJdkApplicationProtocolSelector implements ApplicationProtocolSelector {

    private static final LazyLogger LOG = SystemLogger.create(OpenJdkApplicationProtocolSelector.class);
    private static Method setApplicationProtocols;
    private static Method setHandshakeApplicationProtocolSelector;
    private static Method getApplicationProtocol;

    private final String[] supportedProtocols;
    private final List supportedProtocolList;
    private final SSLEngine sslEngine;

    static {
        try {
            if (JavaVersion.VERSION.getPlatform() < 9) {
                setApplicationProtocols = org.openjsse.javax.net.ssl.SSLParameters.class.getMethod("setApplicationProtocols", String[].class);
                Class sslEngineImpl = Class.forName("org.openjsse.sun.security.ssl.SSLEngineImpl");
                setHandshakeApplicationProtocolSelector = sslEngineImpl.getMethod("setHandshakeApplicationProtocolSelector", BiFunction.class);
                getApplicationProtocol = sslEngineImpl.getMethod("getApplicationProtocol");
            } else {
                setApplicationProtocols = SSLParameters.class.getMethod("setApplicationProtocols", String[].class);
                setHandshakeApplicationProtocolSelector = SSLEngine.class.getMethod("setHandshakeApplicationProtocolSelector", BiFunction.class);
                getApplicationProtocol = SSLEngine.class.getMethod("getApplicationProtocol");
            }
            setApplicationProtocols.setAccessible(true);
            setHandshakeApplicationProtocolSelector.setAccessible(true);
            getApplicationProtocol.setAccessible(true);
        } catch (Exception e) {
            LOG.error("Init openjsse application protocol selector exception", e);
        }
    }

    public OpenJdkApplicationProtocolSelector(SSLEngine sslEngine, List supportedProtocolList) {
        this.supportedProtocolList = supportedProtocolList;
        supportedProtocols = this.supportedProtocolList.toArray(StringUtils.EMPTY_STRING_ARRAY);
        this.sslEngine = sslEngine;

        try {
            if (sslEngine.getUseClientMode()) {
                SSLParameters parameters;
                if (JavaVersion.VERSION.getPlatform() < 9) {
                    parameters = new org.openjsse.javax.net.ssl.SSLParameters();
                } else {
                    parameters = new SSLParameters();
                }
                setApplicationProtocols.invoke(parameters, new Object[]{supportedProtocols});
                sslEngine.setSSLParameters(parameters);

            } else {
                BiFunction, String> selector = (serverEngine, clientProtocols) -> {
                    if (clientProtocols != null) {
                        for (String p : supportedProtocols) {
                            if (clientProtocols.contains(p)) {
                                LOG.debug(() -> "ALPN local server selected protocol -> " + p);
                                return p;
                            }
                        }
                    }
                    return null;
                };
                setHandshakeApplicationProtocolSelector.invoke(sslEngine, selector);
            }
        } catch (Exception e) {
            LOG.error("Init openjsse application protocol selector exception", e);
        }
    }

    @Override
    public String getApplicationProtocol() {
        String protocol;
        try {
            protocol = (String) getApplicationProtocol.invoke(sslEngine);
        } catch (Exception e) {
            LOG.error("Get application protocol exception", e);
            protocol = null;
        }
        return protocol;
    }

    @Override
    public List getSupportedApplicationProtocols() {
        return supportedProtocolList;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy