/*
 *  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.
 */
package org.apache.tomcat.jni;

/**
 * JNI bindings for OpenSSL SSL_CTX operations.
 */
public final class SSLContext {

    /**
     * Default constructor. This class provides only static methods.
     */
    public SSLContext() {
        super();
    }

    /**
     * Default session ID context value.
     */
    public static final byte[] DEFAULT_SESSION_ID_CONTEXT = new byte[] { 'd', 'e', 'f', 'a', 'u', 'l', 't' };

    /**
     * Create a new SSL context.
     *
     * @param pool     The pool to use.
     * @param protocol The SSL protocol to use. It can be any combination of the following:
     *
     *                     <PRE>
     * {@link SSL#SSL_PROTOCOL_SSLV2}
     * {@link SSL#SSL_PROTOCOL_SSLV3}
     * {@link SSL#SSL_PROTOCOL_TLSV1}
     * {@link SSL#SSL_PROTOCOL_TLSV1_1}
     * {@link SSL#SSL_PROTOCOL_TLSV1_2}
     * {@link SSL#SSL_PROTOCOL_TLSV1_3}
     * {@link SSL#SSL_PROTOCOL_ALL} ( == all TLS versions, no SSL)
     * </PRE>
     *
     * @param mode     SSL mode to use
     *
     *                     <PRE>
     * SSL_MODE_CLIENT
     * SSL_MODE_SERVER
     * SSL_MODE_COMBINED
     *                     </PRE>
     *
     * @return The Java representation of a pointer to the newly created SSL Context
     *
     * @throws Exception If the SSL Context could not be created
     */
    public static native long make(long pool, int protocol, int mode) throws Exception;

    /**
     * Free the resources used by the Context
     *
     * @param ctx Server or Client context to free.
     *
     * @return APR Status code.
     */
    public static native int free(long ctx);

    /**
     * Set OpenSSL Option.
     *
     * @param ctx     Server or Client context to use.
     * @param options See SSL.SSL_OP_* for option flags.
     */
    public static native void setOptions(long ctx, int options);

    /**
     * Get OpenSSL Option.
     *
     * @param ctx Server or Client context to use.
     *
     * @return options See SSL.SSL_OP_* for option flags.
     */
    public static native int getOptions(long ctx);

    /**
     * Clears OpenSSL Options.
     *
     * @param ctx     Server or Client context to use.
     * @param options See SSL.SSL_OP_* for option flags.
     */
    public static native void clearOptions(long ctx, int options);

    /**
     * Returns all cipher suites that are enabled for negotiation in an SSL handshake.
     *
     * @param ctx Server or Client context to use.
     *
     * @return ciphers
     */
    public static native String[] getCiphers(long ctx);

    /**
     * Set the TLSv1.2 and below ciphers available for negotiation the in TLS handshake.
     * <p>
     * This complex directive uses a colon-separated cipher-spec string consisting of OpenSSL cipher specifications to
     * configure the ciphers the client is permitted to negotiate in the TLS handshake phase.
     *
     * @param ctx        Server or Client context to use.
     * @param cipherList An OpenSSL cipher specification.
     *
     * @return <code>true</code> if the operation was successful
     *
     * @throws Exception An error occurred
     */
    public static native boolean setCipherSuite(long ctx, String cipherList) throws Exception;

    /**
     * Set the TLSv1.3 cipher suites available for negotiation the in TLS handshake.
     * <p>
     * This uses a colon-separated list of TLSv1.3 cipher suite names in preference order.
     *
     * @param ctx          Server or Client context to use.
     * @param cipherSuites An OpenSSL cipher suite list.
     *
     * @return <code>true</code> if the operation was successful
     *
     * @throws Exception An error occurred
     */
    public static native boolean setCipherSuitesEx(long ctx, String cipherSuites) throws Exception;

    /**
     * Set File of concatenated PEM-encoded CA CRLs or directory of PEM-encoded CA Certificates for Client Auth <br>
     * This directive sets the all-in-one file where you can assemble the Certificate Revocation Lists (CRL) of
     * Certification Authorities (CA) whose clients you deal with. These are used for Client Authentication. Such a file
     * is simply the concatenation of the various PEM-encoded CRL files, in order of preference. <br>
     * The files in this directory have to be PEM-encoded and are accessed through hash filenames. So usually you can't
     * just place the Certificate files there: you also have to create symbolic links named hash-value.N. And you should
     * always make sure this directory contains the appropriate symbolic links. Use the Makefile which comes with
     * mod_ssl to accomplish this task.
     *
     * @param ctx  Server or Client context to use.
     * @param file File of concatenated PEM-encoded CA CRLs for Client Auth.
     * @param path Directory of PEM-encoded CA Certificates for Client Auth.
     *
     * @return <code>true</code> if the operation was successful
     *
     * @throws Exception An error occurred
     */
    public static native boolean setCARevocation(long ctx, String file, String path) throws Exception;

    /**
     * Set File of PEM-encoded Server CA Certificates <br>
     * This directive sets the optional all-in-one file where you can assemble the certificates of Certification
     * Authorities (CA) which form the certificate chain of the server certificate. This starts with the issuing CA
     * certificate of the server certificate and can range up to the root CA certificate. Such a file is simply the
     * concatenation of the various PEM-encoded CA Certificate files, usually in certificate chain order. <br>
     * But be careful: Providing the certificate chain works only if you are using a single (either RSA or DSA) based
     * server certificate. If you are using a coupled RSA+DSA certificate pair, this will work only if actually both
     * certificates use the same certificate chain. Else the browsers will be confused in this situation.
     *
     * @param ctx       Server or Client context to use.
     * @param file      File of PEM-encoded Server CA Certificates.
     * @param skipfirst Skip first certificate if chain file is inside certificate file.
     *
     * @return <code>true</code> if the operation was successful
     */
    public static native boolean setCertificateChainFile(long ctx, String file, boolean skipfirst);

    /**
     * Set Certificate <br>
     * Point setCertificateFile at a PEM encoded certificate. If the certificate is encrypted, then you will be prompted
     * for a pass phrase. Note that a kill -HUP will prompt again. A test certificate can be generated with 'make
     * certificate' under built time. Keep in mind that if you've both a RSA and a DSA certificate you can configure
     * both in parallel (to also allow the use of DSA ciphers, etc.) <br>
     * If the key is not combined with the certificate, use key param to point at the key file. Keep in mind that if
     * you've both a RSA and a DSA private key you can configure both in parallel (to also allow the use of DSA ciphers,
     * etc.)
     *
     * @param ctx      Server or Client context to use.
     * @param cert     Certificate file.
     * @param key      Private Key file to use if not in cert.
     * @param password Certificate password. If null and certificate is encrypted, password prompt will be displayed.
     * @param idx      Certificate index SSL_AIDX_RSA or SSL_AIDX_DSA.
     *
     * @return <code>true</code> if the operation was successful
     *
     * @throws Exception An error occurred
     */
    public static native boolean setCertificate(long ctx, String cert, String key, String password, int idx)
            throws Exception;

    /**
     * Set the size of the internal session cache. http://www.openssl.org/docs/ssl/SSL_CTX_sess_set_cache_size.html
     *
     * @param ctx  Server or Client context to use.
     * @param size The cache size
     *
     * @return the value set
     */
    public static native long setSessionCacheSize(long ctx, long size);

    /**
     * Get the size of the internal session cache. http://www.openssl.org/docs/ssl/SSL_CTX_sess_get_cache_size.html
     *
     * @param ctx Server or Client context to use.
     *
     * @return the size
     */
    public static native long getSessionCacheSize(long ctx);

    /**
     * Set the timeout for the internal session cache in seconds.
     * http://www.openssl.org/docs/ssl/SSL_CTX_set_timeout.html
     *
     * @param ctx            Server or Client context to use.
     * @param timeoutSeconds Timeout value
     *
     * @return the value set
     */
    public static native long setSessionCacheTimeout(long ctx, long timeoutSeconds);

    /**
     * Get the timeout for the internal session cache in seconds.
     * http://www.openssl.org/docs/ssl/SSL_CTX_set_timeout.html
     *
     * @param ctx Server or Client context to use.
     *
     * @return the timeout
     */
    public static native long getSessionCacheTimeout(long ctx);

    /**
     * Set the mode of the internal session cache and return the previous used mode.
     *
     * @param ctx  Server or Client context to use.
     * @param mode The mode to set
     *
     * @return the value set
     */
    public static native long setSessionCacheMode(long ctx, long mode);

    /**
     * Get the mode of the current used internal session cache.
     *
     * @param ctx Server or Client context to use.
     *
     * @return the value set
     */
    public static native long getSessionCacheMode(long ctx);

    /*
     * Session resumption statistics methods. http://www.openssl.org/docs/ssl/SSL_CTX_sess_number.html
     */

    /**
     * Returns the total number of session attempts accepted by the server.
     *
     * @param ctx Server or Client context to use.
     *
     * @return The number of accepted sessions
     */
    public static native long sessionAccept(long ctx);

    /**
     * Returns the number of sessions actually reused on the server side.
     *
     * @param ctx Server or Client context to use.
     *
     * @return The number of good session accepts
     */
    public static native long sessionAcceptGood(long ctx);

    /**
     * Returns the number of session renegotiations on the server side.
     *
     * @param ctx Server or Client context to use.
     *
     * @return The number of session renegotiations accepted
     */
    public static native long sessionAcceptRenegotiate(long ctx);

    /**
     * Returns the number of times the session cache grew to the maximum allowed size and therefore further entries
     * could not be inserted.
     *
     * @param ctx Server or Client context to use.
     *
     * @return The number of times the session cache was full
     */
    public static native long sessionCacheFull(long ctx);

    /**
     * Returns the number of sessions that were resumed by the callback.
     *
     * @param ctx Server or Client context to use.
     *
     * @return The number of session callback hits
     */
    public static native long sessionCbHits(long ctx);

    /**
     * Returns the total number of session connection attempts by the client.
     *
     * @param ctx Server or Client context to use.
     *
     * @return The number of session connects
     */
    public static native long sessionConnect(long ctx);

    /**
     * Returns the number of sessions that were actually reused on the client side.
     *
     * @param ctx Server or Client context to use.
     *
     * @return The number of good session connects
     */
    public static native long sessionConnectGood(long ctx);

    /**
     * Returns the number of session renegotiations on the client side.
     *
     * @param ctx Server or Client context to use.
     *
     * @return The number of session renegotiations connected
     */
    public static native long sessionConnectRenegotiate(long ctx);

    /**
     * Returns the number of sessions that were actually reused (hits).
     *
     * @param ctx Server or Client context to use.
     *
     * @return The number of session hits
     */
    public static native long sessionHits(long ctx);

    /**
     * Returns the number of sessions that were not found in the cache (misses).
     *
     * @param ctx Server or Client context to use.
     *
     * @return The number of session misses
     */
    public static native long sessionMisses(long ctx);

    /**
     * Returns the total number of sessions currently in the cache.
     *
     * @param ctx Server or Client context to use.
     *
     * @return The total number of sessions
     */
    public static native long sessionNumber(long ctx);

    /**
     * Returns the number of sessions that have timed out.
     *
     * @param ctx Server or Client context to use.
     *
     * @return The number of session timeouts
     */
    public static native long sessionTimeouts(long ctx);

    /**
     * Set TLS session keys. This allows us to share keys across TFEs.
     *
     * @param ctx  Server or Client context to use.
     * @param keys Some session keys
     */
    public static native void setSessionTicketKeys(long ctx, byte[] keys);

    /**
     * Set File and Directory of concatenated PEM-encoded CA Certificates for Client Auth <br>
     * This directive sets the all-in-one file where you can assemble the Certificates of Certification Authorities (CA)
     * whose clients you deal with. These are used for Client Authentication. Such a file is simply the concatenation of
     * the various PEM-encoded Certificate files, in order of preference. This can be used alternatively and/or
     * additionally to path. <br>
     * The files in this directory have to be PEM-encoded and are accessed through hash filenames. So usually you can't
     * just place the Certificate files there: you also have to create symbolic links named hash-value.N. And you should
     * always make sure this directory contains the appropriate symbolic links. Use the Makefile which comes with
     * mod_ssl to accomplish this task.
     *
     * @param ctx  Server or Client context to use.
     * @param file File of concatenated PEM-encoded CA Certificates for Client Auth.
     * @param path Directory of PEM-encoded CA Certificates for Client Auth.
     *
     * @return <code>true</code> if the operation was successful
     *
     * @throws Exception An error occurred
     */
    public static native boolean setCACertificate(long ctx, String file, String path) throws Exception;

    /**
     * Set Type of Client Certificate verification and Maximum depth of CA Certificates in Client Certificate
     * verification. <br>
     * This directive sets the Certificate verification level for the Client Authentication. Notice that this directive
     * can be used both in per-server and per-directory context. In per-server context it applies to the client
     * authentication process used in the standard SSL handshake when a connection is established. In per-directory
     * context it forces an SSL renegotiation with the reconfigured client verification level after the HTTP request was
     * read but before the HTTP response is sent. <br>
     * The following levels are available for level:
     *
     * <PRE>
     * SSL_CVERIFY_NONE           - No client Certificate is required at all
     * SSL_CVERIFY_OPTIONAL       - The client may present a valid Certificate
     * SSL_CVERIFY_REQUIRE        - The client has to present a valid Certificate
     * SSL_CVERIFY_OPTIONAL_NO_CA - The client may present a valid Certificate
     *                              but it need not to be (successfully) verifiable
     * </PRE>
     *
     * <br>
     * The depth actually is the maximum number of intermediate certificate issuers, i.e. the number of CA certificates
     * which are max allowed to be followed while verifying the client certificate. A depth of 0 means that self-signed
     * client certificates are accepted only, the default depth of 1 means the client certificate can be self-signed or
     * has to be signed by a CA which is directly known to the server (i.e. the CA's certificate is under
     * <code>setCACertificatePath</code>), etc.
     *
     * @param ctx   Server or Client context to use.
     * @param level Type of Client Certificate verification.
     * @param depth Maximum depth of CA Certificates in Client Certificate verification.
     */
    public static native void setVerify(long ctx, int level, int depth);

    /**
     * Allow to hook {@link CertificateVerifier} into the handshake processing. This will call
     * {@code SSL_CTX_set_cert_verify_callback} and so replace the default verification callback used by openssl
     *
     * @param ctx      Server or Client context to use.
     * @param verifier the verifier to call during handshake.
     */
    public static native void setCertVerifyCallback(long ctx, CertificateVerifier verifier);

    /**
     * Set application layer protocol for application layer protocol negotiation extension
     *
     * @param ctx                     Server context to use.
     * @param alpnProtos              protocols in priority order
     * @param selectorFailureBehavior see {@link SSL#SSL_SELECTOR_FAILURE_NO_ADVERTISE} and
     *                                    {@link SSL#SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL}
     */
    public static native void setAlpnProtos(long ctx, String[] alpnProtos, int selectorFailureBehavior);

    /**
     * Set the context within which session be reused (server side only)
     * http://www.openssl.org/docs/ssl/SSL_CTX_set_session_id_context.html
     *
     * @param ctx    Server context to use.
     * @param sidCtx can be any kind of binary data, it is therefore possible to use e.g. the name of the application
     *                   and/or the hostname and/or service name
     *
     * @return {@code true} if success, {@code false} otherwise.
     */
    public static native boolean setSessionIdContext(long ctx, byte[] sidCtx);

    /**
     * Set CertificateRaw <br>
     * Use keystore a certificate and key to fill the BIOP
     *
     * @param ctx        Server or Client context to use.
     * @param cert       Byte array with the certificate in DER encoding.
     * @param key        Byte array with the Private Key file in PEM format.
     * @param sslAidxRsa Certificate index SSL_AIDX_RSA or SSL_AIDX_DSA.
     *
     * @return {@code true} if success, {@code false} otherwise.
     */
    public static native boolean setCertificateRaw(long ctx, byte[] cert, byte[] key, int sslAidxRsa);

    /**
     * Add a certificate to the certificate chain. Certs should be added in order starting with the issuer of the host
     * certs and working up the certificate chain to the CA. <br>
     * Use keystore a certificate chain to fill the BIOP
     *
     * @param ctx  Server or Client context to use.
     * @param cert Byte array with the certificate in DER encoding.
     *
     * @return {@code true} if success, {@code false} otherwise.
     */
    public static native boolean addChainCertificateRaw(long ctx, byte[] cert);

    /**
     * Add a CA certificate we accept as issuer for peer certs
     *
     * @param ctx  Server or Client context to use.
     * @param cert Byte array with the certificate in DER encoding.
     *
     * @return {@code true} if success, {@code false} otherwise.
     */
    public static native boolean addClientCACertificateRaw(long ctx, byte[] cert);
}
