Index: c/ssl_private.h |
diff --git a/c/ssl_private.h b/c/ssl_private.h |
index c8de472ecd69507c597dc5562428006839c49026..526f3f91d2a5030310f83e93325ad1540192ae3d 100644 |
--- a/c/ssl_private.h |
+++ b/c/ssl_private.h |
@@ -1,3 +1,18 @@ |
+/* |
+ * Copyright 2016 The Netty Project |
+ * |
+ * The Netty Project 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. |
+ */ |
/* 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. |
@@ -14,12 +29,6 @@ |
* limitations under the License. |
*/ |
-/* |
- * |
- * @author Mladen Turk |
- * @version $Id: ssl_private.h 1658728 2015-02-10 14:45:19Z kkolinko $ |
- */ |
- |
#ifndef SSL_PRIVATE_H |
#define SSL_PRIVATE_H |
@@ -40,6 +49,8 @@ |
#endif |
#include "apr_thread_rwlock.h" |
+#include "apr_atomic.h" |
+#include <stdbool.h> |
/* OpenSSL headers */ |
#include <openssl/opensslv.h> |
@@ -52,6 +63,9 @@ |
#include <openssl/evp.h> |
#include <openssl/rand.h> |
#include <openssl/x509v3.h> |
+ |
+#define ERR_LEN 256 |
+ |
/* Avoid tripping over an engine build installed globally and detected |
* when the user points at an explicit non-engine flavor of OpenSSL |
*/ |
@@ -64,53 +78,15 @@ |
#define RAND_MAX INT_MAX |
#endif |
-#define SSL_ALGO_UNKNOWN (0) |
-#define SSL_ALGO_RSA (1<<0) |
-#define SSL_ALGO_DSA (1<<1) |
-#define SSL_ALGO_ALL (SSL_ALGO_RSA|SSL_ALGO_DSA) |
- |
-#define SSL_AIDX_RSA (0) |
-#define SSL_AIDX_DSA (1) |
-#define SSL_AIDX_MAX (2) |
- |
/* |
* Define IDs for the temporary RSA keys and DH params |
*/ |
-#define SSL_TMP_KEY_RSA_512 (0) |
-#define SSL_TMP_KEY_RSA_1024 (1) |
-#define SSL_TMP_KEY_RSA_2048 (2) |
-#define SSL_TMP_KEY_RSA_4096 (3) |
-#define SSL_TMP_KEY_DH_512 (4) |
-#define SSL_TMP_KEY_DH_1024 (5) |
-#define SSL_TMP_KEY_DH_2048 (6) |
-#define SSL_TMP_KEY_DH_4096 (7) |
-#define SSL_TMP_KEY_MAX (8) |
- |
-#define SSL_CRT_FORMAT_UNDEF (0) |
-#define SSL_CRT_FORMAT_ASN1 (1) |
-#define SSL_CRT_FORMAT_TEXT (2) |
-#define SSL_CRT_FORMAT_PEM (3) |
-#define SSL_CRT_FORMAT_NETSCAPE (4) |
-#define SSL_CRT_FORMAT_PKCS12 (5) |
-#define SSL_CRT_FORMAT_SMIME (6) |
-#define SSL_CRT_FORMAT_ENGINE (7) |
-/* XXX this stupid macro helps us to avoid |
- * adding yet another param to load_*key() |
- */ |
-#define SSL_KEY_FORMAT_IISSGC (8) |
- |
-/* |
- * Define the SSL options |
- */ |
-#define SSL_OPT_NONE (0) |
-#define SSL_OPT_RELSET (1<<0) |
-#define SSL_OPT_STDENVVARS (1<<1) |
-#define SSL_OPT_EXPORTCERTDATA (1<<3) |
-#define SSL_OPT_FAKEBASICAUTH (1<<4) |
-#define SSL_OPT_STRICTREQUIRE (1<<5) |
-#define SSL_OPT_OPTRENEGOTIATE (1<<6) |
-#define SSL_OPT_ALL (SSL_OPT_STDENVVARS|SSL_OPT_EXPORTCERTDATA|SSL_OPT_FAKEBASICAUTH|SSL_OPT_STRICTREQUIRE|SSL_OPT_OPTRENEGOTIATE) |
+#define SSL_TMP_KEY_DH_512 (1) |
+#define SSL_TMP_KEY_DH_1024 (2) |
+#define SSL_TMP_KEY_DH_2048 (3) |
+#define SSL_TMP_KEY_DH_4096 (4) |
+#define SSL_TMP_KEY_MAX (5) |
/* |
* Define the SSL Protocol options |
@@ -121,104 +97,50 @@ |
#define SSL_PROTOCOL_TLSV1 (1<<2) |
#define SSL_PROTOCOL_TLSV1_1 (1<<3) |
#define SSL_PROTOCOL_TLSV1_2 (1<<4) |
-#define SSL_PROTOCOL_ALL (SSL_PROTOCOL_SSLV2|SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1|SSL_PROTOCOL_TLSV1_1|SSL_PROTOCOL_TLSV1_2) |
+/* TLS_*method according to https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_new.html */ |
+#define SSL_PROTOCOL_TLS (SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1|SSL_PROTOCOL_TLSV1_1|SSL_PROTOCOL_TLSV1_2) |
+#define SSL_PROTOCOL_ALL (SSL_PROTOCOL_SSLV2|SSL_PROTOCOL_TLS) |
#define SSL_MODE_CLIENT (0) |
#define SSL_MODE_SERVER (1) |
#define SSL_MODE_COMBINED (2) |
-#define SSL_BIO_FLAG_RDONLY (1<<0) |
-#define SSL_BIO_FLAG_CALLBACK (1<<1) |
#define SSL_DEFAULT_CACHE_SIZE (256) |
#define SSL_DEFAULT_VHOST_NAME ("_default_:443") |
-#define SSL_MAX_STR_LEN (2048) |
-#define SSL_MAX_PASSWORD_LEN (256) |
-#define SSL_CVERIFY_UNSET (-1) |
-#define SSL_CVERIFY_NONE (0) |
-#define SSL_CVERIFY_OPTIONAL (1) |
-#define SSL_CVERIFY_REQUIRE (2) |
-#define SSL_CVERIFY_OPTIONAL_NO_CA (3) |
-#define SSL_VERIFY_PEER_STRICT (SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT) |
- |
-#define SSL_SHUTDOWN_TYPE_UNSET (0) |
-#define SSL_SHUTDOWN_TYPE_STANDARD (1) |
-#define SSL_SHUTDOWN_TYPE_UNCLEAN (2) |
-#define SSL_SHUTDOWN_TYPE_ACCURATE (3) |
+#define SSL_CVERIFY_IGNORED (-1) |
+#define SSL_CVERIFY_NONE (0) |
+#define SSL_CVERIFY_OPTIONAL (1) |
+#define SSL_CVERIFY_REQUIRED (2) |
#define SSL_TO_APR_ERROR(X) (APR_OS_START_USERERR + 1000 + X) |
-#define SSL_INFO_SESSION_ID (0x0001) |
-#define SSL_INFO_CIPHER (0x0002) |
-#define SSL_INFO_CIPHER_USEKEYSIZE (0x0003) |
-#define SSL_INFO_CIPHER_ALGKEYSIZE (0x0004) |
-#define SSL_INFO_CIPHER_VERSION (0x0005) |
-#define SSL_INFO_CIPHER_DESCRIPTION (0x0006) |
-#define SSL_INFO_PROTOCOL (0x0007) |
- |
-#define SSL_INFO_CLIENT_S_DN (0x0010) |
-#define SSL_INFO_CLIENT_I_DN (0x0020) |
-#define SSL_INFO_SERVER_S_DN (0x0040) |
-#define SSL_INFO_SERVER_I_DN (0x0080) |
- |
-#define SSL_INFO_DN_COUNTRYNAME (0x0001) |
-#define SSL_INFO_DN_STATEORPROVINCENAME (0x0002) |
-#define SSL_INFO_DN_LOCALITYNAME (0x0003) |
-#define SSL_INFO_DN_ORGANIZATIONNAME (0x0004) |
-#define SSL_INFO_DN_ORGANIZATIONALUNITNAME (0x0005) |
-#define SSL_INFO_DN_COMMONNAME (0x0006) |
-#define SSL_INFO_DN_TITLE (0x0007) |
-#define SSL_INFO_DN_INITIALS (0x0008) |
-#define SSL_INFO_DN_GIVENNAME (0x0009) |
-#define SSL_INFO_DN_SURNAME (0x000A) |
-#define SSL_INFO_DN_DESCRIPTION (0x000B) |
-#define SSL_INFO_DN_UNIQUEIDENTIFIER (0x000C) |
-#define SSL_INFO_DN_EMAILADDRESS (0x000D) |
- |
-#define SSL_INFO_CLIENT_MASK (0x0100) |
- |
-#define SSL_INFO_CLIENT_M_VERSION (0x0101) |
-#define SSL_INFO_CLIENT_M_SERIAL (0x0102) |
-#define SSL_INFO_CLIENT_V_START (0x0103) |
-#define SSL_INFO_CLIENT_V_END (0x0104) |
-#define SSL_INFO_CLIENT_A_SIG (0x0105) |
-#define SSL_INFO_CLIENT_A_KEY (0x0106) |
-#define SSL_INFO_CLIENT_CERT (0x0107) |
-#define SSL_INFO_CLIENT_V_REMAIN (0x0108) |
- |
-#define SSL_INFO_SERVER_MASK (0x0200) |
- |
-#define SSL_INFO_SERVER_M_VERSION (0x0201) |
-#define SSL_INFO_SERVER_M_SERIAL (0x0202) |
-#define SSL_INFO_SERVER_V_START (0x0203) |
-#define SSL_INFO_SERVER_V_END (0x0204) |
-#define SSL_INFO_SERVER_A_SIG (0x0205) |
-#define SSL_INFO_SERVER_A_KEY (0x0206) |
-#define SSL_INFO_SERVER_CERT (0x0207) |
-#define SSL_INFO_CLIENT_CERT_CHAIN (0x0400) |
- |
-#define SSL_VERIFY_ERROR_IS_OPTIONAL(errnum) \ |
- ((errnum == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) \ |
- || (errnum == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) \ |
- || (errnum == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) \ |
- || (errnum == X509_V_ERR_CERT_UNTRUSTED) \ |
- || (errnum == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE)) |
- |
-#define SSL_DEFAULT_PASS_PROMPT "Some of your private key files are encrypted for security reasons.\n" \ |
- "In order to read them you have to provide the pass phrases.\n" \ |
- "Enter password :" |
- |
-#define OCSP_STATUS_OK 0 |
-#define OCSP_STATUS_REVOKED 1 |
-#define OCSP_STATUS_UNKNOWN 2 |
- |
#define MAX_ALPN_NPN_PROTO_SIZE 65535 |
+extern const char* TCN_UNKNOWN_AUTH_METHOD; |
+ |
/* ECC: make sure we have at least 1.0.0 */ |
#if !defined(OPENSSL_NO_EC) && defined(TLSEXT_ECPOINTFORMAT_uncompressed) |
#define HAVE_ECC 1 |
#endif |
+/* OpenSSL 1.0.2 compatibility */ |
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) |
+#define TLS_method SSLv23_method |
+#define TLS_client_method SSLv23_client_method |
+#define TLS_server_method SSLv23_server_method |
+#define OPENSSL_VERSION SSLEAY_VERSION |
+#define OpenSSL_version SSLeay_version |
+#define OPENSSL_malloc_init CRYPTO_malloc_init |
+#define X509_REVOKED_get0_serialNumber(x) x->serialNumber |
+#define OpenSSL_version_num SSLeay |
+#define BIO_get_init(x) ((x)->init) |
+#define BIO_set_init(x,v) ((x)->init=(v)) |
+#define BIO_get_data(x) ((x)->ptr) |
+#define BIO_set_data(x,v) ((x)->ptr=(v)) |
+#define BIO_set_shutdown(x,v) ((x)->shutdown=(v)) |
+#define BIO_get_shutdown(x) ((x)->shutdown) |
+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ |
#define SSL_SELECTOR_FAILURE_NO_ADVERTISE 0 |
#define SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL 1 |
@@ -230,133 +152,114 @@ |
extern void *SSL_temp_keys[SSL_TMP_KEY_MAX]; |
-typedef struct { |
- /* client can have any number of cert/key pairs */ |
- const char *cert_file; |
- const char *cert_path; |
- STACK_OF(X509_INFO) *certs; |
-} ssl_pkc_t; |
+// HACK! |
+// LibreSSL 2.4.x doesn't support the X509_V_ERR_UNSPECIFIED so we introduce a work around to make sure a supported alert is used. |
+// This should be reverted when we support LibreSSL 2.5.x (which does support X509_V_ERR_UNSPECIFIED). |
+#ifndef X509_V_ERR_UNSPECIFIED |
+#define TCN_X509_V_ERR_UNSPECIFIED 99999 |
+#else |
+#define TCN_X509_V_ERR_UNSPECIFIED (X509_V_ERR_UNSPECIFIED) |
+#endif /*X509_V_ERR_UNSPECIFIED*/ |
typedef struct tcn_ssl_ctxt_t tcn_ssl_ctxt_t; |
typedef struct { |
- char password[SSL_MAX_PASSWORD_LEN]; |
- const char *prompt; |
- tcn_callback_t cb; |
-} tcn_pass_cb_t; |
- |
-extern tcn_pass_cb_t tcn_password_callback; |
- |
-typedef struct { |
unsigned char key_name[SSL_SESSION_TICKET_KEY_NAME_LEN]; |
unsigned char hmac_key[SSL_SESSION_TICKET_HMAC_KEY_LEN]; |
unsigned char aes_key[SSL_SESSION_TICKET_AES_KEY_LEN]; |
} tcn_ssl_ticket_key_t; |
+typedef struct { |
+ int verify_depth; |
+ int verify_mode; |
+} tcn_ssl_verify_config_t; |
+ |
struct tcn_ssl_ctxt_t { |
- apr_pool_t *pool; |
- SSL_CTX *ctx; |
- BIO *bio_os; |
- BIO *bio_is; |
+ apr_pool_t* pool; |
+ SSL_CTX* ctx; |
- unsigned char context_id[SHA_DIGEST_LENGTH]; |
+ /* Holds the alpn protocols, each of them prefixed with the len of the protocol */ |
+ unsigned char* alpn_proto_data; |
+ unsigned char* next_proto_data; |
- int protocol; |
- /* we are one or the other */ |
- int mode; |
- |
- /* certificate revocation list */ |
- X509_STORE *crl; |
- /* pointer to the context verify store */ |
- X509_STORE *store; |
- const char *cert_files[SSL_AIDX_MAX]; |
- const char *key_files[SSL_AIDX_MAX]; |
- X509 *certs[SSL_AIDX_MAX]; |
- EVP_PKEY *keys[SSL_AIDX_MAX]; |
- |
- int ca_certs; |
- int shutdown_type; |
- char *rand_file; |
- |
- const char *cipher_suite; |
/* for client or downstream server authentication */ |
- int verify_depth; |
- int verify_mode; |
- tcn_pass_cb_t *cb_data; |
+ char* password; |
+ |
+ apr_thread_rwlock_t* mutex; // Session ticket mutext |
+ tcn_ssl_ticket_key_t* ticket_keys; |
/* certificate verifier callback */ |
- jobject verifier; |
- jmethodID verifier_method; |
+ jobject verifier; |
+ jmethodID verifier_method; |
- unsigned char *next_proto_data; |
- unsigned int next_proto_len; |
- int next_selector_failure_behavior; |
+ jobject cert_requested_callback; |
+ jmethodID cert_requested_callback_method; |
- /* Holds the alpn protocols, each of them prefixed with the len of the protocol */ |
- unsigned char *alpn_proto_data; |
- unsigned int alpn_proto_len; |
- int alpn_selector_failure_behavior; |
+ tcn_ssl_verify_config_t verify_config; |
- apr_thread_rwlock_t *mutex; |
- tcn_ssl_ticket_key_t *ticket_keys; |
- unsigned int ticket_keys_len; |
-}; |
+ int protocol; |
+ /* we are one or the other */ |
+ int mode; |
- |
-typedef struct { |
- apr_pool_t *pool; |
- tcn_ssl_ctxt_t *ctx; |
- SSL *ssl; |
- X509 *peer; |
- int shutdown_type; |
- /* Track the handshake/renegotiation state for the connection so |
- * that all client-initiated renegotiations can be rejected, as a |
- * partial fix for CVE-2009-3555. |
- */ |
- enum { |
- RENEG_INIT = 0, /* Before initial handshake */ |
- RENEG_REJECT, /* After initial handshake; any client-initiated |
- * renegotiation should be rejected |
- */ |
- RENEG_ALLOW, /* A server-initated renegotiation is taking |
- * place (as dictated by configuration) |
- */ |
- RENEG_ABORT /* Renegotiation initiated by client, abort the |
- * connection |
- */ |
- } reneg_state; |
- apr_socket_t *sock; |
- apr_pollset_t *pollset; |
-} tcn_ssl_conn_t; |
+ unsigned int next_proto_len; |
+ int next_selector_failure_behavior; |
+ |
+ unsigned int alpn_proto_len; |
+ int alpn_selector_failure_behavior; |
+ unsigned int ticket_keys_len; |
+ unsigned int pad; |
+ |
+ /* TLS ticket key session resumption statistics */ |
+ |
+ // The client did not present a ticket and we issued a new one. |
+ apr_uint32_t ticket_keys_new; |
+ // The client presented a ticket derived from the primary key |
+ apr_uint32_t ticket_keys_resume; |
+ // The client presented a ticket derived from an older key, and we upgraded to the primary key. |
+ apr_uint32_t ticket_keys_renew; |
+ // The client presented a ticket that did not match any key in the list. |
+ apr_uint32_t ticket_keys_fail; |
+ |
+ unsigned char context_id[SHA_DIGEST_LENGTH]; |
+}; |
/* |
* Additional Functions |
*/ |
-void SSL_init_app_data2_3_idx(void); |
+void SSL_init_app_data_idx(void); |
// The app_data2 is used to store the tcn_ssl_ctxt_t pointer for the SSL instance. |
void *SSL_get_app_data2(SSL *); |
void SSL_set_app_data2(SSL *, void *); |
// The app_data3 is used to store the handshakeCount pointer for the SSL instance. |
void *SSL_get_app_data3(SSL *); |
void SSL_set_app_data3(SSL *, void *); |
-int SSL_password_prompt(tcn_pass_cb_t *); |
+// The app_data4 is used to store the tcn_ssl_verify_config_t pointer for the SSL instance. |
+// This will initially point back to the tcn_ssl_ctxt_t in tcn_ssl_ctxt_t. |
+void *SSL_get_app_data4(SSL *); |
+void SSL_set_app_data4(SSL *, void *); |
int SSL_password_callback(char *, int, int, void *); |
-void SSL_BIO_close(BIO *); |
-void SSL_BIO_doref(BIO *); |
DH *SSL_dh_get_tmp_param(int); |
-DH *SSL_dh_get_param_from_file(const char *); |
-RSA *SSL_callback_tmp_RSA(SSL *, int, int); |
DH *SSL_callback_tmp_DH(SSL *, int, int); |
-void SSL_callback_handshake(const SSL *, int, int); |
-int SSL_CTX_use_certificate_chain(SSL_CTX *, const char *, int); |
-int SSL_CTX_use_certificate_chain_bio(SSL_CTX *, BIO *, int); |
-int SSL_callback_SSL_verify(int, X509_STORE_CTX *); |
-int SSL_rand_seed(const char *file); |
+// The following provided callbacks will always return DH of a given length. |
+// See https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_set_tmp_dh_callback.html |
+DH *SSL_callback_tmp_DH_512(SSL *, int, int); |
+DH *SSL_callback_tmp_DH_1024(SSL *, int, int); |
+DH *SSL_callback_tmp_DH_2048(SSL *, int, int); |
+DH *SSL_callback_tmp_DH_4096(SSL *, int, int); |
+int SSL_CTX_use_certificate_chain(SSL_CTX *, const char *, bool); |
+int SSL_CTX_use_certificate_chain_bio(SSL_CTX *, BIO *, bool); |
+int SSL_CTX_use_client_CA_bio(SSL_CTX *, BIO *); |
+int SSL_use_certificate_chain_bio(SSL *, BIO *, bool); |
+X509 *load_pem_cert_bio(const char *, const BIO *); |
+EVP_PKEY *load_pem_key_bio(const char *, const BIO *); |
+int tcn_set_verify_config(tcn_ssl_verify_config_t* c, jint tcn_mode, jint depth); |
+int tcn_EVP_PKEY_up_ref(EVP_PKEY* pkey); |
+int tcn_X509_up_ref(X509* cert); |
int SSL_callback_next_protos(SSL *, const unsigned char **, unsigned int *, void *); |
int SSL_callback_select_next_proto(SSL *, unsigned char **, unsigned char *, const unsigned char *, unsigned int,void *); |
int SSL_callback_alpn_select_proto(SSL *, const unsigned char **, unsigned char *, const unsigned char *, unsigned int, void *); |
- |
+const char *SSL_cipher_authentication_method(const SSL_CIPHER *); |
#if defined(__GNUC__) || defined(__GNUG__) |
// only supported with GCC, this will be used to support different openssl versions at the same time. |