/* Licensed to the Apache Software Foundation (ASF) under one or more *contributorlicenseagreements.SeetheNOTICEfiledistributedwith *thisworkforadditionalinformationregardingcopyrightownership. *TheASFlicensesthisfiletoYouundertheApacheLicense,Version2.0 *(the"License");youmaynotusethisfileexceptincompliancewith *theLicense.YoumayobtainacopyoftheLicenseat * *http://www.apache.org/licenses/LICENSE-2.0 * *Unlessrequiredbyapplicablelaworagreedtoinwriting,software *distributedundertheLicenseisdistributedonan"ASIS"BASIS, *WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied. *SeetheLicenseforthespecificlanguagegoverningpermissionsand *limitationsundertheLicense.
*/
/* The #ifdef macros are only defined AFTER including the above *thereforewecannotincludethesesystemfilesatthetop:-(
*/ #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 #defineFALSE0 #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"
/* Use OpenSSL 3.x STORE for loading URI keys and certificates starting with *OpenSSL3.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
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;
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 *fortheconnectiontoblockclient-initiatedrenegotiations. *ForOpenSSL>=1.1.1,theSSL_OP_NO_RENEGOTIATIONflagisusedin
* 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 *allocatedoutofthe"process"poolandonlyasinglesuch *structureiscreatedandusedforthelifetimeoftheprocess. *(Theprocesspooliss->process->poolandisstoredinthe.pPool *field.)Mostmembersofthisstructurearelikewiseallocatedout *oftheprocesspool,butnotablysesscacheandsesscache_context *arenot. * *Thestructureistreatedasmostlyimmutableafterasingleconfig *parsehascompleted;thepost_confighook(ssl_init_Module)flips *thebFixedflagtotrueandsubsequentinvocationsoftheconfig *callbackshencedonothing. * *Thisoddlifetimestrategyisusedsothatencryptedprivatekeys *canbedecryptedonceatstartupandcontinuetobeusedacross *subsequentserverreloadswheretheinteractivepasswordpromptis *notpossible.
/* A hash table of pointers to ssl_asn1_t structures. The structures *areusedtostoreprivatekeysinrawDERformat(serializedOpenSSL *PrivateKeystructures).Thetableisindexedby(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]isapointertothe(STACK_OF(X509)*)stackwhich *holdsthecertchainforthe'n'thcertinthecertsstack,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 settingsforolderTLSprotocolversions.Sincewhichonetakes
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);
/* 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 *respectiveap_log_*errorfunctionsandtakeacertificateasan *additionalargument(whosedetailsareappendedtothelogmessage). *Theotherargumentsareinterpretedexactlyaswiththeirap_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. *Returnsnon-zeroonsuccessorzeroonfailure.Onfailure,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 *responderatthegivenURI.ReturnsthedecodedOCSPresponse *object,orNULLonerror(inwhichcase,errorswillhavebeen
* 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 *betreatedasunmutable,sinceitisstoredinprocess-global
* memory. */
DH *modssl_get_dh_params(unsigned keylen); #endif
/* Returns non-zero if the request was made over SSL/TLS. If sslconn *isnon-NULLandtherequestisusingSSL/TLS,sets*sslconntothe
* corresponding SSLConnRec structure for the connection. */ int modssl_request_is_tls(const request_rec *r, SSLConnRec **sslconn);