/* 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.
*/
/* The #ifdef macros are only defined AFTER including the above * therefore we cannot include these system files at the top :-(
*/ #if APR_HAVE_STDLIB_H #include <stdlib.h> #endif #if APR_HAVE_SYS_TIME_H #include <sys/time.h> #endif #if APR_HAVE_UNISTD_H #include <unistd.h> /* needed for STDIN_FILENO et.al., at least on FreeBSD */ #endif
#ifndefFALSE #defineFALSE 0 #endif
#ifndefTRUE #defineTRUE !FALSE #endif
#ifndefBOOL #defineBOOLunsignedint #endif
#include"ap_expr.h"
/* keep first for compat API */ #ifndef OPENSSL_API_COMPAT #define OPENSSL_API_COMPAT 0x10101000 /* for ENGINE_ API */ #endif #include"mod_ssl_openssl.h"
/* Avoid tripping over an engine build installed globally and detected * when the user points at an explicit non-engine flavor of OpenSSL
*/ #ifdefined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) \
&& (OPENSSL_VERSION_NUMBER < 0x30000000 \
|| (defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL < 30000)) \
&& !defined(OPENSSL_NO_ENGINE) #include <openssl/engine.h> #define MODSSL_HAVE_ENGINE_API 1 #endif #ifndef MODSSL_HAVE_ENGINE_API #define MODSSL_HAVE_ENGINE_API 0 #endif
/* Use OpenSSL 3.x STORE for loading URI keys and certificates starting with * OpenSSL 3.0
*/ #if OPENSSL_VERSION_NUMBER >= 0x30000000 #define MODSSL_HAVE_OPENSSL_STORE 1 #else #define MODSSL_HAVE_OPENSSL_STORE 0 #endif
#if (OPENSSL_VERSION_NUMBER < 0x0090801f) #error mod_ssl requires OpenSSL 0.9.8a or later #endif
/** * ...shifting sands of OpenSSL... * Note: when adding support for new OpenSSL features, avoid explicit * version number checks whenever possible, and use "feature-based" * detection instead (check for definitions of constants or functions)
*/ #if (OPENSSL_VERSION_NUMBER >= 0x10000000) #define MODSSL_SSL_CIPHER_CONST const #define MODSSL_SSL_METHOD_CONST const #else #define MODSSL_SSL_CIPHER_CONST #define MODSSL_SSL_METHOD_CONST #endif
#ifdefined(LIBRESSL_VERSION_NUMBER) /* Missing from LibreSSL */ #if LIBRESSL_VERSION_NUMBER < 0x2060000f #define SSL_CTRL_SET_MIN_PROTO_VERSION 123 #define SSL_CTRL_SET_MAX_PROTO_VERSION 124 #define SSL_CTX_set_min_proto_version(ctx, version) \
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL) #define SSL_CTX_set_max_proto_version(ctx, version) \
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL) #endif/* LIBRESSL_VERSION_NUMBER < 0x2060000f */ /* LibreSSL before 2.7 declares OPENSSL_VERSION_NUMBER == 2.0 but does not * include most changes from OpenSSL >= 1.1 (new functions, macros, * deprecations, ...), so we have to work around this...
*/ #if LIBRESSL_VERSION_NUMBER < 0x2070000f #define MODSSL_USE_OPENSSL_PRE_1_1_API 1 #else #define MODSSL_USE_OPENSSL_PRE_1_1_API 0 #endif #else/* defined(LIBRESSL_VERSION_NUMBER) */ #if OPENSSL_VERSION_NUMBER < 0x10100000L #define MODSSL_USE_OPENSSL_PRE_1_1_API 1 #else #define MODSSL_USE_OPENSSL_PRE_1_1_API 0 #endif #endif/* defined(LIBRESSL_VERSION_NUMBER) */
/** * The following features all depend on TLS extension support. * Within this block, check again for features (not version numbers).
*/ #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_set_tlsext_host_name)
#define HAVE_TLSEXT
/* ECC: make sure we have at least 1.0.0 */ #if !defined(OPENSSL_NO_EC) && defined(TLSEXT_ECPOINTFORMAT_uncompressed) #define HAVE_ECC #endif
/* OCSP stapling */ #if !defined(OPENSSL_NO_OCSP) && defined(SSL_CTX_set_tlsext_status_cb) #define HAVE_OCSP_STAPLING /* All exist but are no longer macros since OpenSSL 1.1.0 */ #if OPENSSL_VERSION_NUMBER < 0x10100000L /* backward compatibility with OpenSSL < 1.0 */ #ifndef sk_OPENSSL_STRING_num #define sk_OPENSSL_STRING_num sk_num #endif #ifndef sk_OPENSSL_STRING_value #define sk_OPENSSL_STRING_value sk_value #endif #ifndef sk_OPENSSL_STRING_pop #define sk_OPENSSL_STRING_pop sk_pop #endif #endif/* if OPENSSL_VERSION_NUMBER < 0x10100000L */ #endif/* if !defined(OPENSSL_NO_OCSP) && defined(SSL_CTX_set_tlsext_status_cb) */
/* those may be deprecated */ #ifndef X509_get_notBefore #define X509_get_notBefore X509_getm_notBefore #endif #ifndef X509_get_notAfter #define X509_get_notAfter X509_getm_notAfter #endif
/* The SSL_CTX_set_keylog_callback() API is present in 1.1.1+. * * OpenSSL 3.5+ also provides optional native handling of * $SSLKEYLOGFILE inside libssl, which duplicates the mod_ssl support. * The mod_ssl support is hence disabled for 3.5+, unless that OpenSSL * feature is itself disabled (and OPENSSL_NO_SSLKEYLOG is defined).
*/ #if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER) \
&& (OPENSSL_VERSION_NUMBER <= 0x30500000L || defined(OPENSSL_NO_SSLKEYLOG)) #define HAVE_OPENSSL_KEYLOG #endif
/* * For better backwards compatibility with the SSLCertificate[Key]File * and SSLPassPhraseDialog ("exec" type) directives in 2.4.7 and earlier
*/ #ifdef HAVE_ECC #define CERTKEYS_IDX_MAX 2 #else #define CERTKEYS_IDX_MAX 1 #endif
/** * Define the structure of an ASN.1 anything
*/ typedefstruct { longint nData; unsignedchar *cpData;
apr_time_t source_mtime;
} ssl_asn1_t;
typedefenum {
RENEG_INIT = 0, /* Before initial handshake */
RENEG_REJECT, /* After initial handshake; any client-initiated
* renegotiation should be rejected */
RENEG_ALLOW, /* A server-initiated renegotiation is taking
* place (as dictated by configuration) */
RENEG_ABORT /* Renegotiation initiated by client, abort the
* connection */
} modssl_reneg_state;
/** * Define the mod_ssl per-module configuration structure * (i.e. the global configuration for each httpd process)
*/
typedefstruct {
SSL *ssl; constchar *client_dn;
X509 *client_cert;
ssl_shutdown_type_e shutdown_type; constchar *verify_info; constchar *verify_error; int verify_depth; int disabled; enum {
NON_SSL_OK = 0, /* is SSL request, or error handling completed */
NON_SSL_SEND_REQLINE, /* Need to send the fake request line */
NON_SSL_SEND_HDR_SEP, /* Need to send the header separator */
NON_SSL_SET_ERROR_MSG /* Need to set the error message */
} non_ssl_request;
#ifndef SSL_OP_NO_RENEGOTIATION /* For OpenSSL < 1.1.1, track the handshake/renegotiation state * for the connection to block client-initiated renegotiations. * For OpenSSL >=1.1.1, the SSL_OP_NO_RENEGOTIATION flag is used in
* the SSL * options state with equivalent effect. */
modssl_reneg_state reneg_state; #endif
server_rec *server;
SSLDirConfigRec *dc;
constchar *cipher_suite; /* cipher suite used in last reneg */ int service_unavailable; /* thouugh we negotiate SSL, no requests will be served */ int vhost_found; /* whether we found vhost from SNI already */
} SSLConnRec;
/* BIG FAT WARNING: SSLModConfigRec has unusual memory lifetime: it is * allocated out of the "process" pool and only a single such * structure is created and used for the lifetime of the process. * (The process pool is s->process->pool and is stored in the .pPool * field.) Most members of this structure are likewise allocated out * of the process pool, but notably sesscache and sesscache_context * are not. * * The structure is treated as mostly immutable after a single config * parse has completed; the post_config hook (ssl_init_Module) flips * the bFixed flag to true and subsequent invocations of the config * callbacks hence do nothing. * * This odd lifetime strategy is used so that encrypted private keys * can be decrypted once at startup and continue to be used across * subsequent server reloads where the interactive password prompt is * not possible.
* It is really an ABI nightmare waiting to happen since DSOs are * reloaded across restarts, and nothing prevents the struct type * changing across such reloads, yet the cached structure will be * assumed to match regardless. * * This should really be fixed using a smaller structure which only * stores that which is absolutely necessary (the private keys, maybe * the random seed), and have that structure be strictly ABI-versioned * for safety.
*/ typedefstruct {
pid_t pid;
apr_pool_t *pPool; BOOL bFixed;
/* OpenSSL SSL_SESS_CACHE_* flags: */ long sesscache_mode;
/* The configured provider, and associated private data
* structure. */ const ap_socache_provider_t *sesscache;
ap_socache_instance_t *sesscache_context;
/* A hash table of pointers to ssl_asn1_t structures. The structures * are used to store private keys in raw DER format (serialized OpenSSL * PrivateKey structures). The table is indexed by (vhost-id,
* index), for example the string "vhost.example.com:443:0". */
apr_hash_t *tPrivateKey;
#ifdef HAVE_OCSP_STAPLING const ap_socache_provider_t *stapling_cache;
ap_socache_instance_t *stapling_cache_context;
apr_global_mutex_t *stapling_cache_mutex;
apr_global_mutex_t *stapling_refresh_mutex; #endif #ifdef HAVE_OPENSSL_KEYLOG /* Used for logging if SSLKEYLOGFILE is set at startup. */
apr_file_t *keylog_file; #endif
/** Structure representing configured filenames for certs and keys for
* a given vhost */ typedefstruct { /* Lists of configured certs and keys for this server */
apr_array_header_t *cert_files;
apr_array_header_t *key_files;
/** Certificates which specify the set of CA names which should be
* sent in the CertificateRequest message: */ constchar *ca_name_path; constchar *ca_name_file;
/* TLS service for this server is suspended */ int service_unavailable;
} modssl_pk_server_t;
typedefstruct { /** proxy can have any number of cert/key pairs */ constchar *cert_file; constchar *cert_path; constchar *ca_cert_file; /* certs is a stack of configured cert, key pairs. */
STACK_OF(X509_INFO) *certs; /* ca_certs contains ONLY chain certs for each item in certs. * ca_certs[n] is a pointer to the (STACK_OF(X509) *) stack which * holds the cert chain for the 'n'th cert in the certs stack, or
* NULL if no chain is configured. */
STACK_OF(X509) **ca_certs;
} modssl_pk_proxy_t;
/** stuff related to authentication that can also be per-dir */ typedefstruct { /** known/trusted CAs */ constchar *ca_cert_path; constchar *ca_cert_file;
constchar *cipher_suite;
/** for client or downstream server authentication */ int verify_depth;
ssl_verify_t verify_mode;
/** TLSv1.3 has its separate cipher list, separate from the settings for older TLS protocol versions. Since which one takes
effect is a matter of negotiation, we need separate settings */ constchar *tls13_ciphers;
} modssl_auth_ctx_t;
int ocsp_mask; BOOL ocsp_force_default; /* true if the default responder URL is
* used regardless of per-cert URL */ constchar *ocsp_responder; /* default responder URL */ long ocsp_resptime_skew; long ocsp_resp_maxage;
apr_interval_time_t ocsp_responder_timeout; BOOL ocsp_use_request_nonce;
apr_uri_t *proxy_uri;
BOOL ocsp_noverify; /* true if skipping OCSP certification verification like openssl -noverify */ /* Declare variables for using OCSP Responder Certs for OCSP verification */ int ocsp_verify_flags; /* Flags to use when verifying OCSP response */ constchar *ocsp_certs_file; /* OCSP other certificates filename */
STACK_OF(X509) *ocsp_certs; /* OCSP other certificates */
#ifdef HAVE_SSL_CONF_CMD
SSL_CONF_CTX *ssl_ctx_config; /* Configuration context */
apr_array_header_t *ssl_ctx_param; /* parameters to pass to SSL_CTX */ #endif
/** Apache API hooks */ int ssl_hook_Auth(request_rec *); int ssl_hook_UserCheck(request_rec *); int ssl_hook_Access(request_rec *); int ssl_hook_Fixup(request_rec *); int ssl_hook_ReadReq(request_rec *); int ssl_hook_Upgrade(request_rec *); void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s);
/* ssl_io_buffer_fill fills the setaside buffering of the HTTP request
* to allow an SSL renegotiation to take place. */ int ssl_io_buffer_fill(request_rec *r, apr_size_t maxlen);
/* Load public and/or private key from the configured ENGINE. Private * key returned as *pkey. certid can be NULL, in which case *pubkey
* is not altered. Errors logged on failure. */
apr_status_t modssl_load_engine_keypair(server_rec *s,
apr_pool_t *pconf, apr_pool_t *ptemp, constchar *vhostid, constchar *certid, constchar *keyid,
X509 **pubkey, EVP_PKEY **privkey);
/* Store the EVP_PKEY key (serialized into DER) in the hash table with
* key, returning the ssl_asn1_t structure pointer. */
ssl_asn1_t *ssl_asn1_table_set(apr_hash_t *table, constchar *key,
EVP_PKEY *pkey); /* Retrieve the ssl_asn1_t structure with given key from the hash. */
ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table, constchar *key); /* Remove and free the ssl_asn1_t structure with given key. */ void ssl_asn1_table_unset(apr_hash_t *table, constchar *key);
/** Mutex Support */ int ssl_mutex_init(server_rec *, apr_pool_t *); int ssl_mutex_reinit(server_rec *, apr_pool_t *); int ssl_mutex_on(server_rec *); int ssl_mutex_off(server_rec *);
int ssl_stapling_mutex_reinit(server_rec *, apr_pool_t *);
/* mutex type names for Mutex directive */ #define SSL_CACHE_MUTEX_TYPE "ssl-cache" #define SSL_STAPLING_CACHE_MUTEX_TYPE "ssl-stapling" #define SSL_STAPLING_REFRESH_MUTEX_TYPE "ssl-stapling-refresh"
/* ssl_log_xerror, ssl_log_cxerror and ssl_log_rxerror are wrappers for the * respective ap_log_*error functions and take a certificate as an * additional argument (whose details are appended to the log message). * The other arguments are interpreted exactly as with their ap_log_*error
* counterparts. */ void ssl_log_xerror(constchar *file, int line, int level,
apr_status_t rv, apr_pool_t *p, server_rec *s,
X509 *cert, constchar *format, ...)
__attribute__((format(printf,8,9)));
void ssl_log_cxerror(constchar *file, int line, int level,
apr_status_t rv, conn_rec *c, X509 *cert, constchar *format, ...)
__attribute__((format(printf,7,8)));
void ssl_log_rxerror(constchar *file, int line, int level,
apr_status_t rv, request_rec *r, X509 *cert, constchar *format, ...)
__attribute__((format(printf,7,8)));
#define SSLLOG_MARK __FILE__,__LINE__
/** Variables */
/* Register variables for the lifetime of the process pool 'p'. */ void ssl_var_register(apr_pool_t *p); char *ssl_var_lookup(apr_pool_t *, server_rec *, conn_rec *, request_rec *, char *);
apr_array_header_t *ssl_ext_list(apr_pool_t *p, conn_rec *c, int peer, constchar *extension);
void ssl_var_log_config_register(apr_pool_t *p);
/* Extract SSL_*_DN_* variables into table 't' from SSL object 'ssl',
* allocating from 'p': */ void modssl_var_extract_dns(apr_table_t *t, SSL *ssl, apr_pool_t *p);
/* Extract SSL_*_SAN_* variables (subjectAltName entries) into table 't'
* from SSL object 'ssl', allocating from 'p'. */ void modssl_var_extract_san_entries(apr_table_t *t, SSL *ssl, apr_pool_t *p);
#ifndef OPENSSL_NO_OCSP /* Perform OCSP validation of the current cert in the given context. * Returns non-zero on success or zero on failure. On failure, the
* context error code is set. */ int modssl_verify_ocsp(X509_STORE_CTX *ctx, SSLSrvConfigRec *sc,
server_rec *s, conn_rec *c, apr_pool_t *pool);
/* OCSP helper interface; dispatches the given OCSP request to the * responder at the given URI. Returns the decoded OCSP response * object, or NULL on error (in which case, errors will have been
* logged). Pool 'p' is used for temporary allocations. */
OCSP_RESPONSE *modssl_dispatch_ocsp_request(const apr_uri_t *uri,
apr_interval_time_t timeout,
OCSP_REQUEST *request,
conn_rec *c, apr_pool_t *p);
#if MODSSL_USE_OPENSSL_PRE_1_1_API /* Retrieve DH parameters for given key length. Return value should * be treated as unmutable, since it is stored in process-global
* memory. */
DH *modssl_get_dh_params(unsigned keylen); #endif
/* Returns non-zero if the request was made over SSL/TLS. If sslconn * is non-NULL and the request is using SSL/TLS, sets *sslconn to the
* corresponding SSLConnRec structure for the connection. */ int modssl_request_is_tls(const request_rec *r, SSLConnRec **sslconn);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.