/*
 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */


package sun.net.www.protocol.https;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.io.PrintStream;
import java.io.BufferedOutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.net.URL;
import java.net.UnknownHostException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.CookieHandler;
import java.security.Principal;
import java.security.cert.*;
import java.util.StringTokenizer;
import java.util.Vector;
import java.security.AccessController;

import javax.security.auth.x500.X500Principal;

import javax.net.ssl.*;
import sun.net.www.http.HttpClient;
import sun.security.action.*;

import sun.security.util.HostnameChecker;
import sun.security.ssl.SSLSocketImpl;


/**
 * This class provides HTTPS client URL support, building on the standard
 * "sun.net.www" HTTP protocol handler.  HTTPS is the same protocol as HTTP,
 * but differs in the transport layer which it uses:  <UL>
 *
 *      <LI>There's a <em>Secure Sockets Layer</em> between TCP
 *      and the HTTP protocol code.
 *
 *      <LI>It uses a different default TCP port.
 *
 *      <LI>It doesn't use application level proxies, which can see and
 *      manipulate HTTP user level data, compromising privacy.  It uses
 *      low level tunneling instead, which hides HTTP protocol and data
 *      from all third parties.  (Traffic analysis is still possible).
 *
 *      <LI>It does basic server authentication, to protect
 *      against "URL spoofing" attacks.  This involves deciding
 *      whether the X.509 certificate chain identifying the server
 *      is trusted, and verifying that the name of the server is
 *      found in the certificate.  (The application may enable an
 *      anonymous SSL cipher suite, and such checks are not done
 *      for anonymous ciphers.)
 *
 *      <LI>It exposes key SSL session attributes, specifically the
 *      cipher suite in use and the server's X509 certificates, to
 *      application software which knows about this protocol handler.
 *
 *      </UL>
 *
 * <P> System properties used include:  <UL>
 *
 *      <LI><em>https.proxyHost</em> ... the host supporting SSL
 *      tunneling using the conventional CONNECT syntax
 *
 *      <LI><em>https.proxyPort</em> ... port to use on proxyHost
 *
 *      <LI><em>https.cipherSuites</em> ... comma separated list of
 *      SSL cipher suite names to enable.
 *
 *      <LI><em>http.nonProxyHosts</em> ...
 *
 *      </UL>
 *
 * @author David Brownell
 * @author Bill Foote
 */

// final for export control reasons (access to APIs); remove with care
final class HttpsClient extends HttpClient
    implements HandshakeCompletedListener
{
    // STATIC STATE and ACCESSORS THERETO

    // HTTPS uses a different default port number than HTTP.
    private static final int    httpsPortNumber = 443;

    // default HostnameVerifier class canonical name
    private static final String defaultHVCanonicalName =
            "javax.net.ssl.HttpsURLConnection.DefaultHostnameVerifier";

    /** Returns the default HTTPS port (443) */
    @Override
    protected int getDefaultPort() { return httpsPortNumber; }

    private HostnameVerifier hv;
    private SSLSocketFactory sslSocketFactory;

    // HttpClient.proxyDisabled will always be false, because we don't
    // use an application-level HTTP proxy.  We might tunnel through
    // our http proxy, though.


    // INSTANCE DATA

    // last negotiated SSL session
    private SSLSession  session;

    private String [] getCipherSuites() {
        //
        // If ciphers are assigned, sort them into an array.
        //
        String ciphers [];
        String cipherString = AccessController.doPrivileged(
                new GetPropertyAction("https.cipherSuites"));

        if (cipherString == null || "".equals(cipherString)) {
            ciphers = null;
        } else {
            StringTokenizer     tokenizer;
            Vector<String>      v = new Vector<String>();

            tokenizer = new StringTokenizer(cipherString, ",");
            while (tokenizer.hasMoreTokens())
                v.addElement(tokenizer.nextToken());
            ciphers = new String [v.size()];
            for (int i = 0; i < ciphers.length; i++)
                ciphers [i] = v.elementAt(i);
        }
        return ciphers;
    }

    private String [] getProtocols() {
        //
        // If protocols are assigned, sort them into an array.
        //
        String protocols [];
        String protocolString = AccessController.doPrivileged(
                new GetPropertyAction("https.protocols"));

        if (protocolString == null || "".equals(protocolString)) {
            protocols = null;
        } else {
            StringTokenizer     tokenizer;
            Vector<String>      v = new Vector<String>();

            tokenizer = new StringTokenizer(protocolString, ",");
            while (tokenizer.hasMoreTokens())
                v.addElement(tokenizer.nextToken());
            protocols = new String [v.size()];
            for (int i = 0; i < protocols.length; i++) {
                protocols [i] = v.elementAt(i);
            }
        }
        return protocols;
    }

    private String getUserAgent() {
        String userAgent = java.security.AccessController.doPrivileged(
                new sun.security.action.GetPropertyAction("https.agent"));
        if (userAgent == null || userAgent.length() == 0) {
            userAgent = "JSSE";
        }
        return userAgent;
    }

    // should remove once HttpClient.newHttpProxy is putback
    private static Proxy newHttpProxy(String proxyHost, int proxyPort) {
        InetSocketAddress saddr = null;
        final String phost = proxyHost;
        final int pport = proxyPort < 0 ? httpsPortNumber : proxyPort;
        try {
            saddr = java.security.AccessController.doPrivileged(new
                java.security.PrivilegedExceptionAction<InetSocketAddress>() {
                public InetSocketAddress run() {
                    return new InetSocketAddress(phost, pport);
                }});
        } catch (java.security.PrivilegedActionException pae) {
        }
        return new Proxy(Proxy.Type.HTTP, saddr);
    }

    // CONSTRUCTOR, FACTORY


    /**
     * Create an HTTPS client URL.  Traffic will be tunneled through any
     * intermediate nodes rather than proxied, so that confidentiality
     * of data exchanged can be preserved.  However, note that all the
     * anonymous SSL flavors are subject to "person-in-the-middle"
     * attacks against confidentiality.  If you enable use of those
     * flavors, you may be giving up the protection you get through
     * SSL tunneling.
     *
     * Use New to get new HttpsClient. This constructor is meant to be
     * used only by New method. New properly checks for URL spoofing.
     *
     * @param URL https URL with which a connection must be established
     */
    private HttpsClient(SSLSocketFactory sf, URL url)
    throws IOException
    {
        // HttpClient-level proxying is always disabled,
        // because we override doConnect to do tunneling instead.
        this(sf, url, (String)null, -1);
    }

    /**
     *  Create an HTTPS client URL.  Traffic will be tunneled through
     * the specified proxy server.
     */
    HttpsClient(SSLSocketFactory sf, URL url, String proxyHost, int proxyPort)
        throws IOException {
        this(sf, url, proxyHost, proxyPort, -1);
    }

    /**
     *  Create an HTTPS client URL.  Traffic will be tunneled through
     * the specified proxy server, with a connect timeout
     */
    HttpsClient(SSLSocketFactory sf, URL url, String proxyHost, int proxyPort,
                int connectTimeout)
        throws IOException {
        this(sf, url,
             (proxyHost == null? null:
                HttpsClient.newHttpProxy(proxyHost, proxyPort)),
                connectTimeout);
    }

    /**
     *  Same as previous constructor except using a Proxy
     */
    HttpsClient(SSLSocketFactory sf, URL url, Proxy proxy,
                int connectTimeout)
        throws IOException {
        this.proxy = proxy;
        setSSLSocketFactory(sf);
        this.proxyDisabled = true;

        this.host = url.getHost();
        this.url = url;
        port = url.getPort();
        if (port == -1) {
            port = getDefaultPort();
        }
        setConnectTimeout(connectTimeout);
        // get the cookieHandler if there is any
        cookieHandler = java.security.AccessController.doPrivileged(
            new java.security.PrivilegedAction<CookieHandler>() {
                public CookieHandler run() {
                    return CookieHandler.getDefault();
                }
            });
        openServer();
    }


    // This code largely ripped off from HttpClient.New, and
    // it uses the same keepalive cache.

    static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv)
            throws IOException {
        return HttpsClient.New(sf, url, hv, true);
    }

    /** See HttpClient for the model for this method. */
    static HttpClient New(SSLSocketFactory sf, URL url,
            HostnameVerifier hv, boolean useCache) throws IOException {
        return HttpsClient.New(sf, url, hv, (String)null, -1, useCache);
    }

    /**
     * Get a HTTPS client to the URL.  Traffic will be tunneled through
     * the specified proxy server.
     */
    static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
                           String proxyHost, int proxyPort) throws IOException {
        return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, true);
    }

    static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
                           String proxyHost, int proxyPort, boolean useCache)
        throws IOException {
        return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, useCache, -1);
    }

    static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
                          String proxyHost, int proxyPort, boolean useCache,
                          int connectTimeout)
        throws IOException {

        return HttpsClient.New(sf, url, hv,
                               (proxyHost == null? null :
                                HttpsClient.newHttpProxy(proxyHost, proxyPort)),
                               useCache, connectTimeout);
    }

    static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv,
                          Proxy p, boolean useCache,
                          int connectTimeout)
        throws IOException {
        HttpsClient ret = null;
        if (useCache) {
            /* see if one's already around */
            ret = (HttpsClient) kac.get(url, sf);
            if (ret != null) {
                ret.cachedHttpClient = true;
            }
        }
        if (ret == null) {
            ret = new HttpsClient(sf, url, p, connectTimeout);
        } else {
            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                security.checkConnect(url.getHost(), url.getPort());
            }
            ret.url = url;
        }
        ret.setHostnameVerifier(hv);

        return ret;
    }

    // METHODS
    void setHostnameVerifier(HostnameVerifier hv) {
        this.hv = hv;
    }

    void setSSLSocketFactory(SSLSocketFactory sf) {
        sslSocketFactory = sf;
    }

    SSLSocketFactory getSSLSocketFactory() {
        return sslSocketFactory;
    }

    /**
     * The following method, createSocket, is defined in NetworkClient
     * and overridden here so that the socket facroty is used to create
     * new sockets.
     */
    @Override
    protected Socket createSocket() throws IOException {
        try {
            return sslSocketFactory.createSocket();
        } catch (SocketException se) {
            //
            // bug 6771432
            // javax.net.SocketFactory throws a SocketException with an
            // UnsupportedOperationException as its cause to indicate that
            // unconnected sockets have not been implemented.
            //
            Throwable t = se.getCause();
            if (t != null && t instanceof UnsupportedOperationException) {
                return super.createSocket();
            } else {
                throw se;
            }
        }
    }


    @Override
    public boolean needsTunneling() {
        return (proxy != null && proxy.type() != Proxy.Type.DIRECT
                && proxy.type() != Proxy.Type.SOCKS);
    }

    @Override
    public void afterConnect() throws IOException, UnknownHostException {
        if (!isCachedConnection()) {
            SSLSocket s = null;
            SSLSocketFactory factory = sslSocketFactory;
            try {
                if (!(serverSocket instanceof SSLSocket)) {
                    s = (SSLSocket)factory.createSocket(serverSocket,
                                                        host, port, true);
                } else {
                    s = (SSLSocket)serverSocket;
                    if (s instanceof SSLSocketImpl) {
                        ((SSLSocketImpl)s).setHost(host);
                    }
                }
            } catch (IOException ex) {
                // If we fail to connect through the tunnel, try it
                // locally, as a last resort.  If this doesn't work,
                // throw the original exception.
                try {
                    s = (SSLSocket)factory.createSocket(host, port);
                } catch (IOException ignored) {
                    throw ex;
                }
            }

            //
            // Force handshaking, so that we get any authentication.
            // Register a handshake callback so our session state tracks any
            // later session renegotiations.
            //
            String [] protocols = getProtocols();
            String [] ciphers = getCipherSuites();
            if (protocols != null) {
                s.setEnabledProtocols(protocols);
            }
            if (ciphers != null) {
                s.setEnabledCipherSuites(ciphers);
            }
            s.addHandshakeCompletedListener(this);

            // We have two hostname verification approaches. One is in
            // SSL/TLS socket layer, where the algorithm is configured with
            // SSLParameters.setEndpointIdentificationAlgorithm(), and the
            // hostname verification is done by X509ExtendedTrustManager when
            // the algorithm is "HTTPS". The other one is in HTTPS layer,
            // where the algorithm is customized by
            // HttpsURLConnection.setHostnameVerifier(), and the hostname
            // verification is done by HostnameVerifier when the default
            // rules for hostname verification fail.
            //
            // The relationship between two hostname verification approaches
            // likes the following:
            //
            //               |             EIA algorithm
            //               +----------------------------------------------
            //               |     null      |   HTTPS    |   LDAP/other   |
            // -------------------------------------------------------------
            //     |         |1              |2           |3               |
            // HNV | default | Set HTTPS EIA | use EIA    | HTTPS          |
            //     |--------------------------------------------------------
            //     | non -   |4              |5           |6               |
            //     | default | HTTPS/HNV     | use EIA    | HTTPS/HNV      |
            // -------------------------------------------------------------
            //
            // Abbreviation:
            //     EIA: the endpoint identification algorithm in SSL/TLS
            //           socket layer
            //     HNV: the hostname verification object in HTTPS layer
            // Notes:
            //     case 1. default HNV and EIA is null
            //           Set EIA as HTTPS, hostname check done in SSL/TLS
            //           layer.
            //     case 2. default HNV and EIA is HTTPS
            //           Use existing EIA, hostname check done in SSL/TLS
            //           layer.
            //     case 3. default HNV and EIA is other than HTTPS
            //           Use existing EIA, EIA check done in SSL/TLS
            //           layer, then do HTTPS check in HTTPS layer.
            //     case 4. non-default HNV and EIA is null
            //           No EIA, no EIA check done in SSL/TLS layer, then do
            //           HTTPS check in HTTPS layer using HNV as override.
            //     case 5. non-default HNV and EIA is HTTPS
            //           Use existing EIA, hostname check done in SSL/TLS
            //           layer. No HNV override possible. We will review this
            //           decision and may update the architecture for JDK 7.
            //     case 6. non-default HNV and EIA is other than HTTPS
            //           Use existing EIA, EIA check done in SSL/TLS layer,
            //           then do HTTPS check in HTTPS layer as override.
            boolean needToCheckSpoofing = true;
            String identification =
                s.getSSLParameters().getEndpointIdentificationAlgorithm();
            if (identification != null && identification.length() != 0) {
                if (identification.equalsIgnoreCase("HTTPS")) {
                    // Do not check server identity again out of SSLSocket,
                    // the endpoint will be identified during TLS handshaking
                    // in SSLSocket.
                    needToCheckSpoofing = false;
                }   // else, we don't understand the identification algorithm,
                    // need to check URL spoofing here.
            } else {
                boolean isDefaultHostnameVerifier = false;

                // We prefer to let the SSLSocket do the spoof checks, but if
                // the application has specified a HostnameVerifier (HNV),
                // we will always use that.
                if (hv != null) {
                    String canonicalName = hv.getClass().getCanonicalName();
                    if (canonicalName != null &&
                    canonicalName.equalsIgnoreCase(defaultHVCanonicalName)) {
                        isDefaultHostnameVerifier = true;
                    }
                } else {
                    // Unlikely to happen! As the behavior is the same as the
                    // default hostname verifier, so we prefer to let the
                    // SSLSocket do the spoof checks.
                    isDefaultHostnameVerifier = true;
                }

                if (isDefaultHostnameVerifier) {
                    // If the HNV is the default from HttpsURLConnection, we
                    // will do the spoof checks in SSLSocket.
                    SSLParameters paramaters = s.getSSLParameters();
                    paramaters.setEndpointIdentificationAlgorithm("HTTPS");
                    s.setSSLParameters(paramaters);

                    needToCheckSpoofing = false;
                }
            }

            s.startHandshake();
            session = s.getSession();
            // change the serverSocket and serverOutput
            serverSocket = s;
            try {
                serverOutput = new PrintStream(
                    new BufferedOutputStream(serverSocket.getOutputStream()),
                    false, encoding);
            } catch (UnsupportedEncodingException e) {
                throw new InternalError(encoding+" encoding not found");
            }

            // check URL spoofing if it has not been checked under handshaking
            if (needToCheckSpoofing) {
                checkURLSpoofing(hv);
            }
        } else {
            // if we are reusing a cached https session,
            // we don't need to do handshaking etc. But we do need to
            // set the ssl session
            session = ((SSLSocket)serverSocket).getSession();
        }
    }

    // Server identity checking is done according to RFC 2818: HTTP over TLS
    // Section 3.1 Server Identity
    private void checkURLSpoofing(HostnameVerifier hostnameVerifier)
            throws IOException {
        //
        // Get authenticated server name, if any
        //
        String host = url.getHost();

        // if IPv6 strip off the "[]"
        if (host != null && host.startsWith("[") && host.endsWith("]")) {
            host = host.substring(1, host.length()-1);
        }

        Certificate[] peerCerts = null;
        String cipher = session.getCipherSuite();
        try {
            HostnameChecker checker = HostnameChecker.getInstance(
                                                HostnameChecker.TYPE_TLS);

            // Use ciphersuite to determine whether Kerberos is present.
            if (cipher.startsWith("TLS_KRB5")) {
                if (!HostnameChecker.match(host, getPeerPrincipal())) {
                    throw new SSLPeerUnverifiedException("Hostname checker" +
                                " failed for Kerberos");
                }
            } else { // X.509

                // get the subject's certificate
                peerCerts = session.getPeerCertificates();

                X509Certificate peerCert;
                if (peerCerts[0] instanceof
                        java.security.cert.X509Certificate) {
                    peerCert = (java.security.cert.X509Certificate)peerCerts[0];
                } else {
                    throw new SSLPeerUnverifiedException("");
                }
                checker.match(host, peerCert);
            }

            // if it doesn't throw an exception, we passed. Return.
            return;

        } catch (SSLPeerUnverifiedException e) {

            //
            // client explicitly changed default policy and enabled
            // anonymous ciphers; we can't check the standard policy
            //
            // ignore
        } catch (java.security.cert.CertificateException cpe) {
            // ignore
        }

        if ((cipher != null) && (cipher.indexOf("_anon_") != -1)) {
            return;
        } else if ((hostnameVerifier != null) &&
                   (hostnameVerifier.verify(host, session))) {
            return;
        }

        serverSocket.close();
        session.invalidate();

        throw new IOException("HTTPS hostname wrong:  should be <"
                              + url.getHost() + ">");
    }

    @Override
    protected void putInKeepAliveCache() {
        kac.put(url, sslSocketFactory, this);
    }

    /*
     * Close an idle connection to this URL (if it exists in the cache).
     */
    @Override
    public void closeIdleConnection() {
        HttpClient http = kac.get(url, sslSocketFactory);
        if (http != null) {
            http.closeServer();
        }
    }

    /**
     * Returns the cipher suite in use on this connection.
     */
    String getCipherSuite() {
        return session.getCipherSuite();
    }

    /**
     * Returns the certificate chain the client sent to the
     * server, or null if the client did not authenticate.
     */
    public java.security.cert.Certificate [] getLocalCertificates() {
        return session.getLocalCertificates();
    }

    /**
     * Returns the certificate chain with which the server
     * authenticated itself, or throw a SSLPeerUnverifiedException
     * if the server did not authenticate.
     */
    java.security.cert.Certificate [] getServerCertificates()
            throws SSLPeerUnverifiedException
    {
        return session.getPeerCertificates();
    }

    /**
     * Returns the X.509 certificate chain with which the server
     * authenticated itself, or null if the server did not authenticate.
     */
    javax.security.cert.X509Certificate [] getServerCertificateChain()
            throws SSLPeerUnverifiedException
    {
        return session.getPeerCertificateChain();
    }

    /**
     * Returns the principal with which the server authenticated
     * itself, or throw a SSLPeerUnverifiedException if the
     * server did not authenticate.
     */
    Principal getPeerPrincipal()
            throws SSLPeerUnverifiedException
    {
        Principal principal;
        try {
            principal = session.getPeerPrincipal();
        } catch (AbstractMethodError e) {
            // if the provider does not support it, fallback to peer certs.
            // return the X500Principal of the end-entity cert.
            java.security.cert.Certificate[] certs =
                        session.getPeerCertificates();
            principal = ((X509Certificate)certs[0]).getSubjectX500Principal();
        }
        return principal;
    }

    /**
     * Returns the principal the client sent to the
     * server, or null if the client did not authenticate.
     */
    Principal getLocalPrincipal()
    {
        Principal principal;
        try {
            principal = session.getLocalPrincipal();
        } catch (AbstractMethodError e) {
            principal = null;
            // if the provider does not support it, fallback to local certs.
            // return the X500Principal of the end-entity cert.
            java.security.cert.Certificate[] certs =
                        session.getLocalCertificates();
            if (certs != null) {
                principal = ((X509Certificate)certs[0]).getSubjectX500Principal();
            }
        }
        return principal;
    }

    /**
     * This method implements the SSL HandshakeCompleted callback,
     * remembering the resulting session so that it may be queried
     * for the current cipher suite and peer certificates.  Servers
     * sometimes re-initiate handshaking, so the session in use on
     * a given connection may change.  When sessions change, so may
     * peer identities and cipher suites.
     */
    public void handshakeCompleted(HandshakeCompletedEvent event)
    {
        session = event.getSession();
    }

    /**
     * @return the proxy host being used for this client, or null
     *          if we're not going through a proxy
     */
    @Override
    public String getProxyHostUsed() {
        if (!needsTunneling()) {
            return null;
        } else {
            return super.getProxyHostUsed();
        }
    }

    /**
     * @return the proxy port being used for this client.  Meaningless
     *          if getProxyHostUsed() gives null.
     */
    @Override
    public int getProxyPortUsed() {
        return (proxy == null || proxy.type() == Proxy.Type.DIRECT ||
                proxy.type() == Proxy.Type.SOCKS)? -1:
            ((InetSocketAddress)proxy.address()).getPort();
    }
}
