/*
 * ====================================================================
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */

package org.apache.http.nio.conn.ssl;

import java.io.IOException;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.security.auth.x500.X500Principal;

import org.apache.http.HttpHost;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.StrictHostnameVerifier;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.conn.util.PublicSuffixMatcherLoader;
import org.apache.http.nio.conn.SchemeIOSessionStrategy;
import org.apache.http.nio.reactor.IOSession;
import org.apache.http.nio.reactor.ssl.SSLIOSession;
import org.apache.http.nio.reactor.ssl.SSLMode;
import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.Args;
import org.apache.http.util.Asserts;
import org.apache.http.util.TextUtils;

/**
 * TLS/SSL transport level security strategy.
 *
 * @since 4.0
 */
public class SSLIOSessionStrategy implements SchemeIOSessionStrategy {

    @Deprecated
    public static final X509HostnameVerifier ALLOW_ALL_HOSTNAME_VERIFIER =
            new AllowAllHostnameVerifier();

    @Deprecated
    public static final X509HostnameVerifier BROWSER_COMPATIBLE_HOSTNAME_VERIFIER =
            new BrowserCompatHostnameVerifier();

    @Deprecated
    public static final X509HostnameVerifier STRICT_HOSTNAME_VERIFIER =
            new StrictHostnameVerifier();

    private static String[] split(final String s) {
        if (TextUtils.isBlank(s)) {
            return null;
        }
        return s.split(" *, *");
    }

    /**
     * @since 4.1
     */
    public static HostnameVerifier getDefaultHostnameVerifier() {
        return new DefaultHostnameVerifier(PublicSuffixMatcherLoader.getDefault());
    }

    public static SSLIOSessionStrategy getDefaultStrategy() {
        return new SSLIOSessionStrategy(
                SSLContexts.createDefault(),
                getDefaultHostnameVerifier());
    }

    public static SSLIOSessionStrategy getSystemDefaultStrategy() {
        return new SSLIOSessionStrategy(
                SSLContexts.createSystemDefault(),
                split(System.getProperty("https.protocols")),
                split(System.getProperty("https.cipherSuites")),
                getDefaultHostnameVerifier());
    }

    private final SSLContext sslContext;
    private final String[] supportedProtocols;
    private final String[] supportedCipherSuites;
    private final HostnameVerifier hostnameVerifier;

    /**
     * @deprecated (4.1) use {@link SSLIOSessionStrategy#SSLIOSessionStrategy(
     *   javax.net.ssl.SSLContext, String[], String[], javax.net.ssl.HostnameVerifier)}
     */
    @Deprecated
    public SSLIOSessionStrategy(
            final SSLContext sslContext,
            final String[] supportedProtocols,
            final String[] supportedCipherSuites,
            final X509HostnameVerifier hostnameVerifier) {
        this(sslContext, supportedProtocols, supportedCipherSuites, (HostnameVerifier) hostnameVerifier);
    }

    /**
     * @deprecated (4.1)
     */
    @Deprecated
    public SSLIOSessionStrategy(
            final SSLContext sslcontext,
            final X509HostnameVerifier hostnameVerifier) {
        this(sslcontext, null, null, (HostnameVerifier) hostnameVerifier);
    }

    /**
     * @since 4.1
     */
    public SSLIOSessionStrategy(
            final SSLContext sslContext,
            final String[] supportedProtocols,
            final String[] supportedCipherSuites,
            final HostnameVerifier hostnameVerifier) {
        super();
        this.sslContext = Args.notNull(sslContext, "SSL context");
        this.supportedProtocols = supportedProtocols;
        this.supportedCipherSuites = supportedCipherSuites;
        this.hostnameVerifier = hostnameVerifier != null ? hostnameVerifier : getDefaultHostnameVerifier();
    }

    /**
     * @since 4.1
     */
    public SSLIOSessionStrategy(
            final SSLContext sslcontext,
            final HostnameVerifier hostnameVerifier) {
        this(sslcontext, null, null, hostnameVerifier);
    }

    public SSLIOSessionStrategy(final SSLContext sslcontext) {
        this(sslcontext, null, null, getDefaultHostnameVerifier());
    }

    @Override
    public SSLIOSession upgrade(final HttpHost host, final IOSession iosession) throws IOException {
        Asserts.check(!(iosession instanceof SSLIOSession), "I/O session is already upgraded to TLS/SSL");
        final SSLIOSession ssliosession = new SSLIOSession(
            iosession,
            SSLMode.CLIENT,
            host,
            this.sslContext,
            new SSLSetupHandler() {

                @Override
                public void initalize(
                        final SSLEngine sslengine) throws SSLException {
                    if (supportedProtocols != null) {
                        sslengine.setEnabledProtocols(supportedProtocols);
                    }
                    if (supportedCipherSuites != null) {
                        sslengine.setEnabledCipherSuites(supportedCipherSuites);
                    }
                    initializeEngine(sslengine);
                }

                @Override
                public void verify(
                        final IOSession iosession,
                        final SSLSession sslsession) throws SSLException {
                    verifySession(host, iosession, sslsession);
                }

        });
        iosession.setAttribute(SSLIOSession.SESSION_KEY, ssliosession);
        ssliosession.initialize();
        return ssliosession;
    }

    protected void initializeEngine(final SSLEngine engine) {
    }

    protected void verifySession(
            final HttpHost host,
            final IOSession iosession,
            final SSLSession sslsession) throws SSLException {
        if (!this.hostnameVerifier.verify(host.getHostName(), sslsession)) {
            final Certificate[] certs = sslsession.getPeerCertificates();
            final X509Certificate x509 = (X509Certificate) certs[0];
            final X500Principal x500Principal = x509.getSubjectX500Principal();
            throw new SSLPeerUnverifiedException("Host name '" + host.getHostName() + "' does not match " +
                    "the certificate subject provided by the peer (" + x500Principal.toString() + ")");
        }
    }

    @Override
    public boolean isLayeringRequired() {
        return true;
    }

}
