| /* |
| * 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; |
| |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.concurrent.ConcurrentHashMap; |
| |
| public final class SSLContext { |
| |
| 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); |
| |
| /** |
| * Cipher Suite available for negotiation in SSL handshake. |
| * <br> |
| * This complex directive uses a colon-separated cipher-spec string consisting |
| * of OpenSSL cipher specifications to configure the Cipher Suite the client |
| * is permitted to negotiate in the SSL handshake phase. Notice that this |
| * directive can be used both in per-server and per-directory context. |
| * In per-server context it applies to the standard SSL handshake when a |
| * connection is established. In per-directory context it forces an SSL |
| * renegotiation with the reconfigured Cipher Suite after the HTTP request |
| * was read but before the HTTP response is sent. |
| * @param ctx Server or Client context to use. |
| * @param ciphers 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 ciphers) |
| 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 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 |
| */ |
| public static native long sessionAccept(long ctx); |
| public static native long sessionAcceptGood(long ctx); |
| public static native long sessionAcceptRenegotiate(long ctx); |
| public static native long sessionCacheFull(long ctx); |
| public static native long sessionCbHits(long ctx); |
| public static native long sessionConnect(long ctx); |
| public static native long sessionConnectGood(long ctx); |
| public static native long sessionConnectRenegotiate(long ctx); |
| public static native long sessionHits(long ctx); |
| public static native long sessionMisses(long ctx); |
| public static native long sessionNumber(long ctx); |
| 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); |
| |
| /** |
| * When tc-native encounters a SNI extension in the TLS handshake it will |
| * call this method to determine which OpenSSL SSLContext to use for the |
| * connection. |
| * |
| * @param currentCtx The OpenSSL SSLContext that the handshake started to |
| * use. This will be the default OpenSSL SSLContext for |
| * the endpoint associated with the socket. |
| * @param sniHostName The host name requested by the client |
| * |
| * @return The Java representation of the pointer to the OpenSSL SSLContext |
| * to use for the given host or zero if no SSLContext could be |
| * identified |
| */ |
| public static long sniCallBack(long currentCtx, String sniHostName) { |
| SNICallBack sniCallBack = sniCallBacks.get(Long.valueOf(currentCtx)); |
| if (sniCallBack == null) { |
| return 0; |
| } |
| // Can't be sure OpenSSL is going to provide the SNI value in lower case |
| // so convert it before looking up the SSLContext |
| String hostName = (sniHostName == null) ? null : sniHostName.toLowerCase(Locale.ENGLISH); |
| return sniCallBack.getSslContext(hostName); |
| } |
| |
| /** |
| * A map of default SSL Contexts to SNICallBack instances (in Tomcat these |
| * are instances of AprEndpoint) that will be used to determine the SSL |
| * Context to use bases on the SNI host name. It is structured this way |
| * since a Tomcat instance may have several TLS enabled endpoints that each |
| * have different SSL Context mappings for the same host name. |
| */ |
| private static final Map<Long,SNICallBack> sniCallBacks = new ConcurrentHashMap<>(); |
| |
| /** |
| * Interface implemented by components that will receive the call back to |
| * select an OpenSSL SSLContext based on the host name requested by the |
| * client. |
| */ |
| public interface SNICallBack { |
| |
| /** |
| * This callback is made during the TLS handshake when the client uses |
| * the SNI extension to request a specific TLS host. |
| * |
| * @param sniHostName The host name requested by the client - must be in |
| * lower case |
| * |
| * @return The Java representation of the pointer to the OpenSSL |
| * SSLContext to use for the given host or zero if no SSLContext |
| * could be identified |
| */ |
| long getSslContext(String sniHostName); |
| } |
| |
| /** |
| * 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); |
| } |