/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * 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.conscrypt;

import java.io.IOException;
import java.security.Principal;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionBindingEvent;
import javax.net.ssl.SSLSessionBindingListener;
import javax.net.ssl.SSLSessionContext;
import javax.security.cert.CertificateException;

/**
 * Implementation of the class OpenSSLSessionImpl
 * based on OpenSSL.
 */
public class OpenSSLSessionImpl implements SSLSession {

    private long creationTime = 0;
    long lastAccessedTime = 0;
    final X509Certificate[] localCertificates;
    final X509Certificate[] peerCertificates;

    private boolean isValid = true;
    private final Map<String, Object> values = new HashMap<String, Object>();
    private volatile javax.security.cert.X509Certificate[] peerCertificateChain;
    protected long sslSessionNativePointer;
    private String peerHost;
    private int peerPort = -1;
    private String cipherSuite;
    private String protocol;
    private AbstractSessionContext sessionContext;
    private byte[] id;

    /**
     * Class constructor creates an SSL session context given the appropriate
     * SSL parameters.
     */
    protected OpenSSLSessionImpl(long sslSessionNativePointer, X509Certificate[] localCertificates,
            X509Certificate[] peerCertificates, String peerHost, int peerPort,
            AbstractSessionContext sessionContext) {
        this.sslSessionNativePointer = sslSessionNativePointer;
        this.localCertificates = localCertificates;
        this.peerCertificates = peerCertificates;
        this.peerHost = peerHost;
        this.peerPort = peerPort;
        this.sessionContext = sessionContext;
    }

    /**
     * Constructs a session from a byte[] containing DER data. This
     * allows loading the saved session.
     * @throws IOException
     */
    OpenSSLSessionImpl(byte[] derData,
            String peerHost, int peerPort,
            X509Certificate[] peerCertificates,
            AbstractSessionContext sessionContext)
            throws IOException {
        this(NativeCrypto.d2i_SSL_SESSION(derData),
             null,
             peerCertificates,
             peerHost,
             peerPort,
             sessionContext);
        // TODO move this check into native code so we can throw an error with more information
        if (this.sslSessionNativePointer == 0) {
            throw new IOException("Invalid session data");
        }
    }

    /**
     * Gets the identifier of the actual SSL session
     * @return array of sessions' identifiers.
     */
    @Override
    public byte[] getId() {
        if (id == null) {
            resetId();
        }
        return id;
    }

    /**
     * Reset the id field to the current value found in the native
     * SSL_SESSION. It can change during the lifetime of the session
     * because while a session is created during initial handshake,
     * with handshake_cutthrough, the SSL_do_handshake may return
     * before we have read the session ticket from the server side and
     * therefore have computed no id based on the SHA of the ticket.
     */
    void resetId() {
        id = NativeCrypto.SSL_SESSION_session_id(sslSessionNativePointer);
    }

    /**
     * Get the session object in DER format. This allows saving the session
     * data or sharing it with other processes.
     */
    byte[] getEncoded() {
        return NativeCrypto.i2d_SSL_SESSION(sslSessionNativePointer);
    }

    /**
     * Gets the creation time of the SSL session.
     * @return the session's creation time in milliseconds since the epoch
     */
    @Override
    public long getCreationTime() {
        if (creationTime == 0) {
            creationTime = NativeCrypto.SSL_SESSION_get_time(sslSessionNativePointer);
        }
        return creationTime;
    }

    /**
     * Returns the last time this concrete SSL session was accessed. Accessing
     * here is to mean that a new connection with the same SSL context data was
     * established.
     *
     * @return the session's last access time in milliseconds since the epoch
     */
    @Override
    public long getLastAccessedTime() {
        return (lastAccessedTime == 0) ? getCreationTime() : lastAccessedTime;
    }

    /**
     * Returns the largest buffer size for the application's data bound to this
     * concrete SSL session.
     * @return the largest buffer size
     */
    @Override
    public int getApplicationBufferSize() {
        return SSLRecordProtocol.MAX_DATA_LENGTH;
    }

    /**
     * Returns the largest SSL/TLS packet size one can expect for this concrete
     * SSL session.
     * @return the largest packet size
     */
    @Override
    public int getPacketBufferSize() {
        return SSLRecordProtocol.MAX_SSL_PACKET_SIZE;
    }

    /**
     * Returns the principal (subject) of this concrete SSL session used in the
     * handshaking phase of the connection.
     * @return a X509 certificate or null if no principal was defined
     */
    @Override
    public Principal getLocalPrincipal() {
        if (localCertificates != null && localCertificates.length > 0) {
            return localCertificates[0].getSubjectX500Principal();
        } else {
            return null;
        }
    }

    /**
     * Returns the certificate(s) of the principal (subject) of this concrete SSL
     * session used in the handshaking phase of the connection. The OpenSSL
     * native method supports only RSA certificates.
     * @return an array of certificates (the local one first and then eventually
     *         that of the certification authority) or null if no certificate
     *         were used during the handshaking phase.
     */
    @Override
    public Certificate[] getLocalCertificates() {
        return localCertificates;
    }

    /**
     * Returns the certificate(s) of the peer in this SSL session
     * used in the handshaking phase of the connection.
     * Please notice hat this method is superseded by
     * <code>getPeerCertificates()</code>.
     * @return an array of X509 certificates (the peer's one first and then
     *         eventually that of the certification authority) or null if no
     *         certificate were used during the SSL connection.
     * @throws SSLPeerUnverifiedException if either a non-X.509 certificate
     *         was used (i.e. Kerberos certificates) or the peer could not
     *         be verified.
     */
    @Override
    public javax.security.cert.X509Certificate[] getPeerCertificateChain()
            throws SSLPeerUnverifiedException {
        checkPeerCertificatesPresent();
        javax.security.cert.X509Certificate[] result = peerCertificateChain;
        if (result == null) {
            // single-check idiom
            peerCertificateChain = result = createPeerCertificateChain();
        }
        return result;
    }

    /**
     * Provide a value to initialize the volatile peerCertificateChain
     * field based on the native SSL_SESSION
     */
    private javax.security.cert.X509Certificate[] createPeerCertificateChain()
            throws SSLPeerUnverifiedException {
        try {
            javax.security.cert.X509Certificate[] chain
                    = new javax.security.cert.X509Certificate[peerCertificates.length];

            for (int i = 0; i < peerCertificates.length; i++) {
                byte[] encoded = peerCertificates[i].getEncoded();
                chain[i] = javax.security.cert.X509Certificate.getInstance(encoded);
            }
            return chain;
        } catch (CertificateEncodingException e) {
            SSLPeerUnverifiedException exception = new SSLPeerUnverifiedException(e.getMessage());
            exception.initCause(exception);
            throw exception;
        } catch (CertificateException e) {
            SSLPeerUnverifiedException exception = new SSLPeerUnverifiedException(e.getMessage());
            exception.initCause(exception);
            throw exception;
        }
    }

    /**
     * Return the identity of the peer in this SSL session
     * determined via certificate(s).
     * @return an array of X509 certificates (the peer's one first and then
     *         eventually that of the certification authority) or null if no
     *         certificate were used during the SSL connection.
     * @throws SSLPeerUnverifiedException if either a non-X.509 certificate
     *         was used (i.e. Kerberos certificates) or the peer could not
     *         be verified.
     */
    @Override
    public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
        checkPeerCertificatesPresent();
        return peerCertificates;
    }

    /**
     * Throw SSLPeerUnverifiedException on null or empty peerCertificates array
     */
    private void checkPeerCertificatesPresent() throws SSLPeerUnverifiedException {
        if (peerCertificates == null || peerCertificates.length == 0) {
            throw new SSLPeerUnverifiedException("No peer certificates");
        }
    }

    /**
     * The identity of the principal that was used by the peer during the SSL
     * handshake phase is returned by this method.
     * @return a X500Principal of the last certificate for X509-based
     *         cipher suites.
     * @throws SSLPeerUnverifiedException if either a non-X.509 certificate
     *         was used (i.e. Kerberos certificates) or the peer does not exist.
     *
     */
    @Override
    public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
        checkPeerCertificatesPresent();
        return peerCertificates[0].getSubjectX500Principal();
    }

    /**
     * The peer's host name used in this SSL session is returned. It is the host
     * name of the client for the server; and that of the server for the client.
     * It is not a reliable way to get a fully qualified host name: it is mainly
     * used internally to implement links for a temporary cache of SSL sessions.
     *
     * @return the host name of the peer, or {@code null} if no information is
     *         available.
     */
    @Override
    public String getPeerHost() {
        return peerHost;
    }

    /**
     * Returns the peer's port number for the actual SSL session. It is the port
     * number of the client for the server; and that of the server for the
     * client. It is not a reliable way to get a peer's port number: it is
     * mainly used internally to implement links for a temporary cache of SSL
     * sessions.
     *
     * @return the peer's port number, or {@code -1} if no one is available.
     */
    @Override
    public int getPeerPort() {
        return peerPort;
    }

    /**
     * Returns a string identifier of the crypto tools used in the actual SSL
     * session. For example AES_256_WITH_MD5.
     */
    @Override
    public String getCipherSuite() {
        if (cipherSuite == null) {
            String name = NativeCrypto.SSL_SESSION_cipher(sslSessionNativePointer);
            cipherSuite = NativeCrypto.OPENSSL_TO_STANDARD_CIPHER_SUITES.get(name);
            if (cipherSuite == null) {
                cipherSuite = name;
            }
        }
        return cipherSuite;
    }

    /**
     * Returns the standard version name of the SSL protocol used in all
     * connections pertaining to this SSL session.
     */
    @Override
    public String getProtocol() {
        if (protocol == null) {
            protocol = NativeCrypto.SSL_SESSION_get_version(sslSessionNativePointer);
        }
        return protocol;
    }

    /**
     * Returns the context to which the actual SSL session is bound. A SSL
     * context consists of (1) a possible delegate, (2) a provider and (3) a
     * protocol.
     * @return the SSL context used for this session, or null if it is
     * unavailable.
     */
    @Override
    public SSLSessionContext getSessionContext() {
        return sessionContext;
    }

    /**
     * Returns a boolean flag signaling whether a SSL session is valid
     * and available for resuming or joining or not.
     *
     * @return true if this session may be resumed.
     */
    @Override
    public boolean isValid() {
        if (!isValid) {
            return false;
        }
        // The session has't yet been invalidated -- check whether it timed out.

        SSLSessionContext context = sessionContext;
        if (context == null) {
            // Session not associated with a context -- no way to tell what its timeout should be.
            return true;
        }

        int timeoutSeconds = context.getSessionTimeout();
        if (timeoutSeconds == 0) {
            // Infinite timeout -- session still valid
            return true;
        }

        long creationTimestampMillis = getCreationTime();
        long ageSeconds = (System.currentTimeMillis() - creationTimestampMillis) / 1000;
        // NOTE: The age might be negative if something was/is wrong with the system clock. We time
        // out such sessions to be safe.
        if ((ageSeconds >= timeoutSeconds) || (ageSeconds < 0)) {
            // Session timed out -- no longer valid
            isValid = false;
            return false;
        }

        // Session still valid
        return true;
    }

    /**
     * It invalidates a SSL session forbidding any resumption.
     */
    @Override
    public void invalidate() {
        isValid = false;
        sessionContext = null;
    }

    /**
     * Returns the object which is bound to the the input parameter name.
     * This name is a sort of link to the data of the SSL session's application
     * layer, if any exists.
     *
     * @param name the name of the binding to find.
     * @return the value bound to that name, or null if the binding does not
     *         exist.
     * @throws IllegalArgumentException if the argument is null.
     */
    @Override
    public Object getValue(String name) {
        if (name == null) {
            throw new IllegalArgumentException("name == null");
        }
        return values.get(name);
    }

    /**
     * Returns an array with the names (sort of links) of all the data
     * objects of the application layer bound into the SSL session.
     *
     * @return a non-null (possibly empty) array of names of the data objects
     *         bound to this SSL session.
     */
    @Override
    public String[] getValueNames() {
        return values.keySet().toArray(new String[values.size()]);
    }

    /**
     * A link (name) with the specified value object of the SSL session's
     * application layer data is created or replaced. If the new (or existing)
     * value object implements the <code>SSLSessionBindingListener</code>
     * interface, that object will be notified in due course.
     *
     * @param name the name of the link (no null are
     *            accepted!)
     * @param value data object that shall be bound to
     *            name.
     * @throws IllegalArgumentException if one or both argument(s) is null.
     */
    @Override
    public void putValue(String name, Object value) {
        if (name == null || value == null) {
            throw new IllegalArgumentException("name == null || value == null");
        }
        Object old = values.put(name, value);
        if (value instanceof SSLSessionBindingListener) {
            ((SSLSessionBindingListener) value)
                    .valueBound(new SSLSessionBindingEvent(this, name));
        }
        if (old instanceof SSLSessionBindingListener) {
            ((SSLSessionBindingListener) old)
                    .valueUnbound(new SSLSessionBindingEvent(this, name));
        }
    }

    /**
     * Removes a link (name) with the specified value object of the SSL
     * session's application layer data.
     *
     * <p>If the value object implements the <code>SSLSessionBindingListener</code>
     * interface, the object will receive a <code>valueUnbound</code> notification.
     *
     * @param name the name of the link (no null are
     *            accepted!)
     * @throws IllegalArgumentException if the argument is null.
     */
    @Override
    public void removeValue(String name) {
        if (name == null) {
            throw new IllegalArgumentException("name == null");
        }
        Object old = values.remove(name);
        if (old instanceof SSLSessionBindingListener) {
            SSLSessionBindingListener listener = (SSLSessionBindingListener) old;
            listener.valueUnbound(new SSLSessionBindingEvent(this, name));
        }
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            NativeCrypto.SSL_SESSION_free(sslSessionNativePointer);
        } finally {
            super.finalize();
        }
    }
}
