e249e1729b
- Upgrade to apache 2.4.2 ** ATTENTION, before installing this update YOU MUST READ http://httpd.apache.org/docs/2.4/upgrading.html CAREFULLY otherwise your server will most likely fail to start due to backward incompatible changes. * You can read the huge complete list of changes at http://httpd.apache.org/docs/2.4/new_features_2_4.html OBS-URL: https://build.opensuse.org/request/show/129508 OBS-URL: https://build.opensuse.org/package/show/Apache/apache2?expand=0&rev=370
1374 lines
50 KiB
Diff
1374 lines
50 KiB
Diff
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c
|
|
index fe7aeae..0ca336f 100644
|
|
--- a/modules/ssl/mod_ssl.c
|
|
+++ b/modules/ssl/mod_ssl.c
|
|
@@ -94,6 +94,15 @@ static const command_rec ssl_config_cmds[] = {
|
|
SSL_CMD_SRV(PKCS7CertificateFile, TAKE1,
|
|
"PKCS#7 file containing server certificate and chain"
|
|
" certificates ('/path/to/file' - PEM encoded)")
|
|
+ SSL_CMD_ALL(RSAAuthzFile, TAKE1,
|
|
+ "RFC 5878 Authz Extension file for RSA certificate "
|
|
+ "(`/path/to/file')")
|
|
+ SSL_CMD_ALL(DSAAuthzFile, TAKE1,
|
|
+ "RFC 5878 Authz Extension file for DSA certificate "
|
|
+ "(`/path/to/file')")
|
|
+ SSL_CMD_ALL(ECAuthzFile, TAKE1,
|
|
+ "RFC 5878 Authz Extension file for EC certificate "
|
|
+ "(`/path/to/file')")
|
|
#ifdef HAVE_TLS_SESSION_TICKETS
|
|
SSL_CMD_SRV(SessionTicketKeyFile, TAKE1,
|
|
"TLS session ticket encryption/decryption key file (RFC 5077) "
|
|
@@ -138,6 +147,9 @@ static const command_rec ssl_config_cmds[] = {
|
|
"('[+-][" SSL_PROTOCOLS "] ...' - see manual)")
|
|
SSL_CMD_SRV(HonorCipherOrder, FLAG,
|
|
"Use the server's cipher ordering preference")
|
|
+ SSL_CMD_SRV(Compression, FLAG,
|
|
+ "Enable SSL level compression"
|
|
+ "(`on', `off')")
|
|
SSL_CMD_SRV(InsecureRenegotiation, FLAG,
|
|
"Enable support for insecure renegotiation")
|
|
SSL_CMD_ALL(UserName, TAKE1,
|
|
@@ -145,6 +157,15 @@ static const command_rec ssl_config_cmds[] = {
|
|
SSL_CMD_SRV(StrictSNIVHostCheck, FLAG,
|
|
"Strict SNI virtual host checking")
|
|
|
|
+#ifndef OPENSSL_NO_SRP
|
|
+ SSL_CMD_SRV(SRPVerifierFile, TAKE1,
|
|
+ "SRP verifier file "
|
|
+ "('/path/to/file' - created by srptool)")
|
|
+ SSL_CMD_SRV(SRPUnknownUserSeed, TAKE1,
|
|
+ "SRP seed for unknown users (to avoid leaking a user's existence) "
|
|
+ "('some secret text')")
|
|
+#endif
|
|
+
|
|
/*
|
|
* Proxy configuration for remote SSL connections
|
|
*/
|
|
@@ -260,6 +281,18 @@ static const command_rec ssl_config_cmds[] = {
|
|
AP_END_CMD
|
|
};
|
|
|
|
+/* Implement 'modssl_run_npn_advertise_protos_hook'. */
|
|
+APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(
|
|
+ modssl, AP, int, npn_advertise_protos_hook,
|
|
+ (conn_rec *connection, apr_array_header_t *protos),
|
|
+ (connection, protos), OK, DECLINED);
|
|
+
|
|
+/* Implement 'modssl_run_npn_proto_negotiated_hook'. */
|
|
+APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(
|
|
+ modssl, AP, int, npn_proto_negotiated_hook,
|
|
+ (conn_rec *connection, const char *proto_name, apr_size_t proto_name_len),
|
|
+ (connection, proto_name, proto_name_len), OK, DECLINED);
|
|
+
|
|
/*
|
|
* the various processing hooks
|
|
*/
|
|
diff --git a/modules/ssl/mod_ssl.h b/modules/ssl/mod_ssl.h
|
|
index 48984e2..0280a68 100644
|
|
--- a/modules/ssl/mod_ssl.h
|
|
+++ b/modules/ssl/mod_ssl.h
|
|
@@ -63,5 +63,26 @@ APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *));
|
|
|
|
APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *));
|
|
|
|
+/** The npn_advertise_protos optional hook allows other modules to add entries
|
|
+ * to the list of protocol names advertised by the server during the Next
|
|
+ * Protocol Negotiation (NPN) portion of the SSL handshake. The hook callee is
|
|
+ * given the connection and an APR array; it should push one or more char*'s
|
|
+ * pointing to null-terminated strings (such as "http/1.1" or "spdy/2") onto
|
|
+ * the array and return OK, or do nothing and return DECLINED. */
|
|
+APR_DECLARE_EXTERNAL_HOOK(modssl, AP, int, npn_advertise_protos_hook,
|
|
+ (conn_rec *connection, apr_array_header_t *protos));
|
|
+
|
|
+/** The npn_proto_negotiated optional hook allows other modules to discover the
|
|
+ * name of the protocol that was chosen during the Next Protocol Negotiation
|
|
+ * (NPN) portion of the SSL handshake. Note that this may be the empty string
|
|
+ * (in which case modules should probably assume HTTP), or it may be a protocol
|
|
+ * that was never even advertised by the server. The hook callee is given the
|
|
+ * connection, a non-null-terminated string containing the protocol name, and
|
|
+ * the length of the string; it should do something appropriate (i.e. insert or
|
|
+ * remove filters) and return OK, or do nothing and return DECLINED. */
|
|
+APR_DECLARE_EXTERNAL_HOOK(modssl, AP, int, npn_proto_negotiated_hook,
|
|
+ (conn_rec *connection, const char *proto_name,
|
|
+ apr_size_t proto_name_len));
|
|
+
|
|
#endif /* __MOD_SSL_H__ */
|
|
/** @} */
|
|
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
|
|
index 6aab764..39f20f9 100644
|
|
--- a/modules/ssl/ssl_engine_config.c
|
|
+++ b/modules/ssl/ssl_engine_config.c
|
|
@@ -125,6 +125,10 @@ static void modssl_ctx_init(modssl_ctx_t *mctx)
|
|
mctx->crl_file = NULL;
|
|
mctx->crl_check_mode = SSL_CRLCHECK_UNSET;
|
|
|
|
+ mctx->rsa_authz_file = NULL;
|
|
+ mctx->dsa_authz_file = NULL;
|
|
+ mctx->ec_authz_file = NULL;
|
|
+
|
|
mctx->auth.ca_cert_path = NULL;
|
|
mctx->auth.ca_cert_file = NULL;
|
|
mctx->auth.cipher_suite = NULL;
|
|
@@ -149,6 +153,12 @@ static void modssl_ctx_init(modssl_ctx_t *mctx)
|
|
mctx->stapling_responder_timeout = UNSET;
|
|
mctx->stapling_force_url = NULL;
|
|
#endif
|
|
+
|
|
+#ifndef OPENSSL_NO_SRP
|
|
+ mctx->srp_vfile = NULL;
|
|
+ mctx->srp_unknown_user_seed = NULL;
|
|
+ mctx->srp_vbase = NULL;
|
|
+#endif
|
|
}
|
|
|
|
static void modssl_ctx_init_proxy(SSLSrvConfigRec *sc,
|
|
@@ -207,6 +217,9 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
|
|
#ifdef HAVE_FIPS
|
|
sc->fips = UNSET;
|
|
#endif
|
|
+#ifndef OPENSSL_NO_COMP
|
|
+ sc->compression = UNSET;
|
|
+#endif
|
|
|
|
modssl_ctx_init_proxy(sc, p);
|
|
|
|
@@ -248,6 +261,10 @@ static void modssl_ctx_cfg_merge(modssl_ctx_t *base,
|
|
cfgMerge(crl_file, NULL);
|
|
cfgMerge(crl_check_mode, SSL_CRLCHECK_UNSET);
|
|
|
|
+ cfgMergeString(rsa_authz_file);
|
|
+ cfgMergeString(dsa_authz_file);
|
|
+ cfgMergeString(ec_authz_file);
|
|
+
|
|
cfgMergeString(auth.ca_cert_path);
|
|
cfgMergeString(auth.ca_cert_file);
|
|
cfgMergeString(auth.cipher_suite);
|
|
@@ -271,6 +288,11 @@ static void modssl_ctx_cfg_merge(modssl_ctx_t *base,
|
|
cfgMergeInt(stapling_responder_timeout);
|
|
cfgMerge(stapling_force_url, NULL);
|
|
#endif
|
|
+
|
|
+#ifndef OPENSSL_NO_SRP
|
|
+ cfgMergeString(srp_vfile);
|
|
+ cfgMergeString(srp_unknown_user_seed);
|
|
+#endif
|
|
}
|
|
|
|
static void modssl_ctx_cfg_merge_proxy(modssl_ctx_t *base,
|
|
@@ -328,6 +350,9 @@ void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
|
|
#ifdef HAVE_FIPS
|
|
cfgMergeBool(fips);
|
|
#endif
|
|
+#ifndef OPENSSL_NO_COMP
|
|
+ cfgMergeBool(compression);
|
|
+#endif
|
|
|
|
modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy);
|
|
|
|
@@ -663,6 +688,23 @@ static const char *ssl_cmd_check_file(cmd_parms *parms,
|
|
|
|
}
|
|
|
|
+const char *ssl_cmd_SSLCompression(cmd_parms *cmd, void *dcfg, int flag)
|
|
+{
|
|
+#if !defined(OPENSSL_NO_COMP)
|
|
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
|
|
+#ifndef SSL_OP_NO_COMPRESSION
|
|
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
|
|
+ if (err)
|
|
+ return "This version of openssl does not support configuring "
|
|
+ "compression within <VirtualHost> sections.";
|
|
+#endif
|
|
+ sc->compression = flag ? TRUE : FALSE;
|
|
+ return NULL;
|
|
+#else
|
|
+ return "Setting Compression mode unsupported; not implemented by the SSL library";
|
|
+#endif
|
|
+}
|
|
+
|
|
const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag)
|
|
{
|
|
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
|
|
@@ -806,6 +848,54 @@ const char *ssl_cmd_SSLPKCS7CertificateFile(cmd_parms *cmd,
|
|
return NULL;
|
|
}
|
|
|
|
+const char *ssl_cmd_SSLRSAAuthzFile(cmd_parms *cmd,
|
|
+ void *dcfg,
|
|
+ const char *arg)
|
|
+{
|
|
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
|
|
+ const char *err;
|
|
+
|
|
+ if ((err = ssl_cmd_check_file(cmd, &arg))) {
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ sc->server->rsa_authz_file = arg;
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+const char *ssl_cmd_SSLDSAAuthzFile(cmd_parms *cmd,
|
|
+ void *dcfg,
|
|
+ const char *arg)
|
|
+{
|
|
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
|
|
+ const char *err;
|
|
+
|
|
+ if ((err = ssl_cmd_check_file(cmd, &arg))) {
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ sc->server->dsa_authz_file = arg;
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+const char *ssl_cmd_SSLECAuthzFile(cmd_parms *cmd,
|
|
+ void *dcfg,
|
|
+ const char *arg)
|
|
+{
|
|
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
|
|
+ const char *err;
|
|
+
|
|
+ if ((err = ssl_cmd_check_file(cmd, &arg))) {
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ sc->server->ec_authz_file = arg;
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
#ifdef HAVE_TLS_SESSION_TICKETS
|
|
const char *ssl_cmd_SSLSessionTicketKeyFile(cmd_parms *cmd,
|
|
void *dcfg,
|
|
@@ -1759,6 +1849,32 @@ const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *cmd, void *dcfg,
|
|
|
|
#endif /* HAVE_OCSP_STAPLING */
|
|
|
|
+#ifndef OPENSSL_NO_SRP
|
|
+
|
|
+const char *ssl_cmd_SSLSRPVerifierFile(cmd_parms *cmd, void *dcfg,
|
|
+ const char *arg)
|
|
+{
|
|
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
|
|
+ const char *err;
|
|
+
|
|
+ if ((err = ssl_cmd_check_file(cmd, &arg)))
|
|
+ return err;
|
|
+ /* SRP_VBASE_init takes char*, not const char* */
|
|
+ sc->server->srp_vfile = apr_pstrdup(cmd->pool, arg);
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+const char *ssl_cmd_SSLSRPUnknownUserSeed(cmd_parms *cmd, void *dcfg,
|
|
+ const char *arg)
|
|
+{
|
|
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
|
|
+ /* SRP_VBASE_new takes char*, not const char* */
|
|
+ sc->server->srp_unknown_user_seed = apr_pstrdup(cmd->pool, arg);
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+#endif /* OPENSSL_NO_SRP */
|
|
+
|
|
void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
|
|
{
|
|
apr_file_t *out = NULL;
|
|
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
|
|
index 5d81647..8cdc29a 100644
|
|
--- a/modules/ssl/ssl_engine_init.c
|
|
+++ b/modules/ssl/ssl_engine_init.c
|
|
@@ -349,7 +349,7 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
|
|
else {
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01885) "FIPS mode failed");
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
}
|
|
}
|
|
@@ -438,7 +438,7 @@ void ssl_init_Engine(server_rec *s, apr_pool_t *p)
|
|
"Init: Failed to load Crypto Device API `%s'",
|
|
mc->szCryptoDevice);
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
if (strEQ(mc->szCryptoDevice, "chil")) {
|
|
@@ -450,7 +450,7 @@ void ssl_init_Engine(server_rec *s, apr_pool_t *p)
|
|
"Init: Failed to enable Crypto Device API `%s'",
|
|
mc->szCryptoDevice);
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01890)
|
|
"Init: loaded Crypto Device API `%s'",
|
|
@@ -473,7 +473,7 @@ static void ssl_init_server_check(server_rec *s,
|
|
if (!mctx->pks->cert_files[0] && !mctx->pkcs7) {
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01891)
|
|
"No SSL Certificate set [hint: SSLCertificateFile]");
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
/*
|
|
@@ -489,7 +489,7 @@ static void ssl_init_server_check(server_rec *s,
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01892)
|
|
"Illegal attempt to re-initialise SSL for server "
|
|
"(SSLEngine On should go in the VirtualHost, not in global scope.)");
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
}
|
|
|
|
@@ -515,7 +515,7 @@ static void ssl_init_ctx_tls_extensions(server_rec *s,
|
|
"Unable to initialize TLS servername extension "
|
|
"callback (incompatible OpenSSL version?)");
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
#ifdef HAVE_OCSP_STAPLING
|
|
@@ -526,6 +526,38 @@ static void ssl_init_ctx_tls_extensions(server_rec *s,
|
|
modssl_init_stapling(s, p, ptemp, mctx);
|
|
}
|
|
#endif
|
|
+
|
|
+#ifndef OPENSSL_NO_SRP
|
|
+ /*
|
|
+ * TLS-SRP support
|
|
+ */
|
|
+ if (mctx->srp_vfile != NULL) {
|
|
+ int err;
|
|
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02308)
|
|
+ "Using SRP verifier file [%s]", mctx->srp_vfile);
|
|
+
|
|
+ if (!(mctx->srp_vbase = SRP_VBASE_new(mctx->srp_unknown_user_seed))) {
|
|
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02309)
|
|
+ "Unable to initialize SRP verifier structure "
|
|
+ "[%s seed]",
|
|
+ mctx->srp_unknown_user_seed ? "with" : "without");
|
|
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
+ ssl_die(s);
|
|
+ }
|
|
+
|
|
+ err = SRP_VBASE_init(mctx->srp_vbase, mctx->srp_vfile);
|
|
+ if (err != SRP_NO_ERROR) {
|
|
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02310)
|
|
+ "Unable to load SRP verifier file [error %d]", err);
|
|
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
+ ssl_die(s);
|
|
+ }
|
|
+
|
|
+ SSL_CTX_set_srp_username_callback(mctx->ssl_ctx,
|
|
+ ssl_callback_SRPServerParams);
|
|
+ SSL_CTX_set_srp_cb_arg(mctx->ssl_ctx, mctx);
|
|
+ }
|
|
+#endif
|
|
}
|
|
#endif
|
|
|
|
@@ -546,7 +578,7 @@ static void ssl_init_ctx_protocol(server_rec *s,
|
|
if (protocol == SSL_PROTOCOL_NONE) {
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02231)
|
|
"No SSL protocols available [hint: SSLProtocol]");
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
cp = apr_pstrcat(p,
|
|
@@ -622,6 +654,18 @@ static void ssl_init_ctx_protocol(server_rec *s,
|
|
}
|
|
#endif
|
|
|
|
+
|
|
+#ifndef OPENSSL_NO_COMP
|
|
+ if (sc->compression == FALSE) {
|
|
+#ifdef SSL_OP_NO_COMPRESSION
|
|
+ /* OpenSSL >= 1.0 only */
|
|
+ SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
|
|
+#elif OPENSSL_VERSION_NUMBER >= 0x00908000L
|
|
+ sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
|
|
+#endif
|
|
+ }
|
|
+#endif
|
|
+
|
|
#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
|
|
if (sc->insecure_reneg == TRUE) {
|
|
SSL_CTX_set_options(ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
|
|
@@ -681,6 +725,11 @@ static void ssl_init_ctx_callbacks(server_rec *s,
|
|
#endif
|
|
|
|
SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
|
|
+
|
|
+#ifdef HAVE_TLS_NPN
|
|
+ SSL_CTX_set_next_protos_advertised_cb(
|
|
+ ctx, ssl_callback_AdvertiseNextProtos, NULL);
|
|
+#endif
|
|
}
|
|
|
|
static void ssl_init_ctx_verify(server_rec *s,
|
|
@@ -731,7 +780,7 @@ static void ssl_init_ctx_verify(server_rec *s,
|
|
"Unable to configure verify locations "
|
|
"for client authentication");
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
if (mctx->pks && (mctx->pks->ca_name_file || mctx->pks->ca_name_path)) {
|
|
@@ -746,7 +795,7 @@ static void ssl_init_ctx_verify(server_rec *s,
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01896)
|
|
"Unable to determine list of acceptable "
|
|
"CA certificates for client authentication");
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
SSL_CTX_set_client_CA_list(ctx, ca_list);
|
|
@@ -791,7 +840,7 @@ static void ssl_init_ctx_cipher_suite(server_rec *s,
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01898)
|
|
"Unable to configure permitted SSL ciphers");
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
}
|
|
|
|
@@ -815,7 +864,7 @@ static void ssl_init_ctx_crl(server_rec *s,
|
|
"Host %s: CRL checking has been enabled, but "
|
|
"neither %sCARevocationFile nor %sCARevocationPath "
|
|
"is configured", mctx->sc->vhost_id, cfgp, cfgp);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
return;
|
|
}
|
|
@@ -829,7 +878,7 @@ static void ssl_init_ctx_crl(server_rec *s,
|
|
"Host %s: unable to configure X.509 CRL storage "
|
|
"for certificate revocation", mctx->sc->vhost_id);
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
switch (mctx->crl_check_mode) {
|
|
@@ -915,7 +964,7 @@ static void ssl_init_ctx_cert_chain(server_rec *s,
|
|
if (n < 0) {
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01903)
|
|
"Failed to configure CA certificate chain!");
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01904)
|
|
@@ -953,7 +1002,8 @@ static void ssl_init_ctx(server_rec *s,
|
|
static int ssl_server_import_cert(server_rec *s,
|
|
modssl_ctx_t *mctx,
|
|
const char *id,
|
|
- int idx)
|
|
+ int idx,
|
|
+ const char *authz_file)
|
|
{
|
|
SSLModConfigRec *mc = myModConfig(s);
|
|
ssl_asn1_t *asn1;
|
|
@@ -973,14 +1023,14 @@ static int ssl_server_import_cert(server_rec *s,
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02233)
|
|
"Unable to import %s server certificate", type);
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) <= 0) {
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02234)
|
|
"Unable to configure %s server certificate", type);
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
#ifdef HAVE_OCSP_STAPLING
|
|
@@ -992,6 +1042,24 @@ static int ssl_server_import_cert(server_rec *s,
|
|
}
|
|
#endif
|
|
|
|
+ if (authz_file) {
|
|
+#if !defined(OPENSSL_NO_TLSEXT) && OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
+ if (!SSL_CTX_use_authz_file(mctx->ssl_ctx, authz_file)) {
|
|
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
|
|
+ "Unable to initialize TLS authz extension");
|
|
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
|
|
+ ssl_die(s);
|
|
+ }
|
|
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, "Set %s authz_file to %s",
|
|
+ type, authz_file);
|
|
+#else
|
|
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
|
|
+ "Unable to initialize TLS authz extension: "
|
|
+ "OpenSSL version too low");
|
|
+ ssl_die(s);
|
|
+#endif
|
|
+ }
|
|
+
|
|
mctx->pks->certs[idx] = cert;
|
|
|
|
return TRUE;
|
|
@@ -1029,14 +1097,14 @@ static int ssl_server_import_key(server_rec *s,
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02237)
|
|
"Unable to import %s server private key", type);
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) <= 0) {
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02238)
|
|
"Unable to configure %s server private key", type);
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
/*
|
|
@@ -1174,10 +1242,13 @@ static void ssl_init_server_certs(server_rec *s,
|
|
ecc_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_ECC);
|
|
#endif
|
|
|
|
- have_rsa = ssl_server_import_cert(s, mctx, rsa_id, SSL_AIDX_RSA);
|
|
- have_dsa = ssl_server_import_cert(s, mctx, dsa_id, SSL_AIDX_DSA);
|
|
+ have_rsa = ssl_server_import_cert(s, mctx, rsa_id, SSL_AIDX_RSA,
|
|
+ mctx->rsa_authz_file);
|
|
+ have_dsa = ssl_server_import_cert(s, mctx, dsa_id, SSL_AIDX_DSA,
|
|
+ mctx->dsa_authz_file);
|
|
#ifndef OPENSSL_NO_EC
|
|
- have_ecc = ssl_server_import_cert(s, mctx, ecc_id, SSL_AIDX_ECC);
|
|
+ have_ecc = ssl_server_import_cert(s, mctx, ecc_id, SSL_AIDX_ECC,
|
|
+ mctx->ec_authz_file);
|
|
#endif
|
|
|
|
if (!(have_rsa || have_dsa
|
|
@@ -1188,7 +1259,7 @@ static void ssl_init_server_certs(server_rec *s,
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01910)
|
|
"Oops, no " KEYTYPES " server certificate found "
|
|
"for '%s:%d'?!", s->server_hostname, s->port);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
for (i = 0; i < SSL_AIDX_MAX; i++) {
|
|
@@ -1208,7 +1279,7 @@ static void ssl_init_server_certs(server_rec *s,
|
|
)) {
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01911)
|
|
"Oops, no " KEYTYPES " server private key found?!");
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
}
|
|
|
|
@@ -1238,7 +1309,7 @@ static void ssl_init_ticket_key(server_rec *s,
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02286)
|
|
"Failed to open ticket key file %s: (%d) %pm",
|
|
path, rv, &rv);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
rv = apr_file_read_full(fp, &buf[0], TLSEXT_TICKET_KEY_LEN, &len);
|
|
@@ -1247,7 +1318,7 @@ static void ssl_init_ticket_key(server_rec *s,
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02287)
|
|
"Failed to read %d bytes from %s: (%d) %pm",
|
|
TLSEXT_TICKET_KEY_LEN, path, rv, &rv);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
memcpy(ticket_key->key_name, buf, 16);
|
|
@@ -1260,7 +1331,7 @@ static void ssl_init_ticket_key(server_rec *s,
|
|
"Unable to initialize TLS session ticket key callback "
|
|
"(incompatible OpenSSL version?)");
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(02288)
|
|
@@ -1315,7 +1386,7 @@ static void ssl_init_proxy_certs(server_rec *s,
|
|
ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, APLOGNO(02252)
|
|
"incomplete client cert configured for SSL proxy "
|
|
"(missing or encrypted private key?)");
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
return;
|
|
}
|
|
}
|
|
@@ -1338,7 +1409,7 @@ static void ssl_init_proxy_certs(server_rec *s,
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02208)
|
|
"SSL proxy client cert initialization failed");
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
X509_STORE_load_locations(store, pkp->ca_cert_file, NULL);
|
|
@@ -1628,7 +1699,7 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02211)
|
|
"Failed to open Certificate Path `%s'",
|
|
ca_path);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
while ((apr_dir_read(&direntry, finfo_flags, dir)) == APR_SUCCESS) {
|
|
@@ -1675,6 +1746,13 @@ void ssl_init_Child(apr_pool_t *p, server_rec *s)
|
|
static void ssl_init_ctx_cleanup(modssl_ctx_t *mctx)
|
|
{
|
|
MODSSL_CFG_ITEM_FREE(SSL_CTX_free, mctx->ssl_ctx);
|
|
+
|
|
+#ifndef OPENSSL_NO_SRP
|
|
+ if (mctx->srp_vbase != NULL) {
|
|
+ SRP_VBASE_free(mctx->srp_vbase);
|
|
+ mctx->srp_vbase = NULL;
|
|
+ }
|
|
+#endif
|
|
}
|
|
|
|
static void ssl_init_ctx_cleanup_proxy(modssl_ctx_t *mctx)
|
|
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
|
|
index 2ffe21f..12c9c7f 100644
|
|
--- a/modules/ssl/ssl_engine_io.c
|
|
+++ b/modules/ssl/ssl_engine_io.c
|
|
@@ -28,6 +28,7 @@
|
|
core keeps dumping.''
|
|
-- Unknown */
|
|
#include "ssl_private.h"
|
|
+#include "mod_ssl.h"
|
|
#include "apr_date.h"
|
|
|
|
/* _________________________________________________________________
|
|
@@ -297,6 +298,7 @@ typedef struct {
|
|
apr_pool_t *pool;
|
|
char buffer[AP_IOBUFSIZE];
|
|
ssl_filter_ctx_t *filter_ctx;
|
|
+ int npn_finished; /* 1 if NPN has finished, 0 otherwise */
|
|
} bio_filter_in_ctx_t;
|
|
|
|
/*
|
|
@@ -813,12 +815,12 @@ static apr_status_t ssl_filter_write(ap_filter_t *f,
|
|
/* Just use a simple request. Any request will work for this, because
|
|
* we use a flag in the conn_rec->conn_vector now. The fake request just
|
|
* gets the request back to the Apache core so that a response can be sent.
|
|
- *
|
|
- * To avoid calling back for more data from the socket, use an HTTP/0.9
|
|
- * request, and tack on an EOS bucket.
|
|
+ * Since we use an HTTP/1.x request, we also have to inject the empty line
|
|
+ * that terminates the headers, or the core will read more data from the
|
|
+ * socket.
|
|
*/
|
|
#define HTTP_ON_HTTPS_PORT \
|
|
- "GET /" CRLF
|
|
+ "GET / HTTP/1.0" CRLF
|
|
|
|
#define HTTP_ON_HTTPS_PORT_BUCKET(alloc) \
|
|
apr_bucket_immortal_create(HTTP_ON_HTTPS_PORT, \
|
|
@@ -848,6 +850,7 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f,
|
|
{
|
|
SSLConnRec *sslconn = myConnConfig(f->c);
|
|
apr_bucket *bucket;
|
|
+ int send_eos = 1;
|
|
|
|
switch (status) {
|
|
case MODSSL_ERROR_HTTP_ON_HTTPS:
|
|
@@ -857,11 +860,12 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f,
|
|
"trying to send HTML error page");
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, sslconn->server);
|
|
|
|
- sslconn->non_ssl_request = 1;
|
|
+ sslconn->non_ssl_request = NON_SSL_SEND_HDR_SEP;
|
|
ssl_io_filter_disable(sslconn, f);
|
|
|
|
/* fake the request line */
|
|
bucket = HTTP_ON_HTTPS_PORT_BUCKET(f->c->bucket_alloc);
|
|
+ send_eos = 0;
|
|
break;
|
|
|
|
case MODSSL_ERROR_BAD_GATEWAY:
|
|
@@ -877,9 +881,10 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f,
|
|
}
|
|
|
|
APR_BRIGADE_INSERT_TAIL(bb, bucket);
|
|
- bucket = apr_bucket_eos_create(f->c->bucket_alloc);
|
|
- APR_BRIGADE_INSERT_TAIL(bb, bucket);
|
|
-
|
|
+ if (send_eos) {
|
|
+ bucket = apr_bucket_eos_create(f->c->bucket_alloc);
|
|
+ APR_BRIGADE_INSERT_TAIL(bb, bucket);
|
|
+ }
|
|
return APR_SUCCESS;
|
|
}
|
|
|
|
@@ -1282,6 +1287,13 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f,
|
|
}
|
|
|
|
if (!inctx->ssl) {
|
|
+ SSLConnRec *sslconn = myConnConfig(f->c);
|
|
+ if (sslconn->non_ssl_request == NON_SSL_SEND_HDR_SEP) {
|
|
+ apr_bucket *bucket = apr_bucket_immortal_create(CRLF, 2, f->c->bucket_alloc);
|
|
+ APR_BRIGADE_INSERT_TAIL(bb, bucket);
|
|
+ sslconn->non_ssl_request = NON_SSL_SET_ERROR_MSG;
|
|
+ return APR_SUCCESS;
|
|
+ }
|
|
return ap_get_brigade(f->next, bb, mode, block, readbytes);
|
|
}
|
|
|
|
@@ -1364,6 +1376,26 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f,
|
|
APR_BRIGADE_INSERT_TAIL(bb, bucket);
|
|
}
|
|
|
|
+#ifdef HAVE_TLS_NPN
|
|
+ /* By this point, Next Protocol Negotiation (NPN) should be completed (if
|
|
+ * our version of OpenSSL supports it). If we haven't already, find out
|
|
+ * which protocol was decided upon and inform other modules by calling
|
|
+ * npn_proto_negotiated_hook. */
|
|
+ if (!inctx->npn_finished) {
|
|
+ const unsigned char *next_proto = NULL;
|
|
+ unsigned next_proto_len = 0;
|
|
+
|
|
+ SSL_get0_next_proto_negotiated(
|
|
+ inctx->ssl, &next_proto, &next_proto_len);
|
|
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, f->c,
|
|
+ APLOGNO(02306) "SSL NPN negotiated protocol: '%*s'",
|
|
+ next_proto_len, (const char*)next_proto);
|
|
+ modssl_run_npn_proto_negotiated_hook(
|
|
+ f->c, (const char*)next_proto, next_proto_len);
|
|
+ inctx->npn_finished = 1;
|
|
+ }
|
|
+#endif
|
|
+
|
|
return APR_SUCCESS;
|
|
}
|
|
|
|
@@ -1845,6 +1877,7 @@ static void ssl_io_input_add_filter(ssl_filter_ctx_t *filter_ctx, conn_rec *c,
|
|
inctx->block = APR_BLOCK_READ;
|
|
inctx->pool = c->pool;
|
|
inctx->filter_ctx = filter_ctx;
|
|
+ inctx->npn_finished = 0;
|
|
}
|
|
|
|
/* The request_rec pointer is passed in here only to ensure that the
|
|
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
|
|
index 35b2a85..1b69d4c 100644
|
|
--- a/modules/ssl/ssl_engine_kernel.c
|
|
+++ b/modules/ssl/ssl_engine_kernel.c
|
|
@@ -29,6 +29,7 @@
|
|
time I was too famous.''
|
|
-- Unknown */
|
|
#include "ssl_private.h"
|
|
+#include "mod_ssl.h"
|
|
#include "util_md5.h"
|
|
|
|
static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn);
|
|
@@ -140,37 +141,16 @@ int ssl_hook_ReadReq(request_rec *r)
|
|
return DECLINED;
|
|
}
|
|
|
|
- if (sslconn->non_ssl_request) {
|
|
- const char *errmsg;
|
|
- char *thisurl;
|
|
- char *thisport = "";
|
|
- int port = ap_get_server_port(r);
|
|
-
|
|
- if (!ap_is_default_port(port, r)) {
|
|
- thisport = apr_psprintf(r->pool, ":%u", port);
|
|
- }
|
|
-
|
|
- thisurl = ap_escape_html(r->pool,
|
|
- apr_psprintf(r->pool, "https://%s%s/",
|
|
- ap_get_server_name_for_url(r),
|
|
- thisport));
|
|
-
|
|
- errmsg = apr_psprintf(r->pool,
|
|
- "Reason: You're speaking plain HTTP "
|
|
- "to an SSL-enabled server port.<br />\n"
|
|
- "Instead use the HTTPS scheme to access "
|
|
- "this URL, please.<br />\n"
|
|
- "<blockquote>Hint: "
|
|
- "<a href=\"%s\"><b>%s</b></a></blockquote>",
|
|
- thisurl, thisurl);
|
|
-
|
|
- apr_table_setn(r->notes, "error-notes", errmsg);
|
|
+ if (sslconn->non_ssl_request == NON_SSL_SET_ERROR_MSG) {
|
|
+ apr_table_setn(r->notes, "error-notes",
|
|
+ "Reason: You're speaking plain HTTP to an SSL-enabled "
|
|
+ "server port.<br />\n Instead use the HTTPS scheme to "
|
|
+ "access this URL, please.<br />\n");
|
|
|
|
/* Now that we have caught this error, forget it. we are done
|
|
* with using SSL on this request.
|
|
*/
|
|
- sslconn->non_ssl_request = 0;
|
|
-
|
|
+ sslconn->non_ssl_request = NON_SSL_OK;
|
|
|
|
return HTTP_BAD_REQUEST;
|
|
}
|
|
@@ -350,6 +330,19 @@ int ssl_hook_Access(request_rec *r)
|
|
return DECLINED;
|
|
}
|
|
|
|
+#ifndef OPENSSL_NO_SRP
|
|
+ /*
|
|
+ * Support for per-directory reconfigured SSL connection parameters
|
|
+ *
|
|
+ * We do not force any renegotiation if the user is already authenticated
|
|
+ * via SRP.
|
|
+ *
|
|
+ */
|
|
+ if (SSL_get_srp_username(ssl)) {
|
|
+ return DECLINED;
|
|
+ }
|
|
+#endif
|
|
+
|
|
/*
|
|
* Support for per-directory reconfigured SSL connection parameters.
|
|
*
|
|
@@ -1109,6 +1102,10 @@ static const char *ssl_hook_Fixup_vars[] = {
|
|
"SSL_SERVER_A_SIG",
|
|
"SSL_SESSION_ID",
|
|
"SSL_SESSION_RESUMED",
|
|
+#ifndef OPENSSL_NO_SRP
|
|
+ "SSL_SRP_USER",
|
|
+ "SSL_SRP_USERINFO",
|
|
+#endif
|
|
NULL
|
|
};
|
|
|
|
@@ -2093,7 +2090,7 @@ static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
|
|
|
|
return 0;
|
|
}
|
|
-#endif
|
|
+#endif /* OPENSSL_NO_TLSEXT */
|
|
|
|
#ifdef HAVE_TLS_SESSION_TICKETS
|
|
/*
|
|
@@ -2163,4 +2160,114 @@ int ssl_callback_SessionTicket(SSL *ssl,
|
|
/* OpenSSL is not expected to call us with modes other than 1 or 0 */
|
|
return -1;
|
|
}
|
|
-#endif
|
|
+#endif /* HAVE_TLS_SESSION_TICKETS */
|
|
+
|
|
+#ifdef HAVE_TLS_NPN
|
|
+/*
|
|
+ * This callback function is executed when SSL needs to decide what protocols
|
|
+ * to advertise during Next Protocol Negotiation (NPN). It must produce a
|
|
+ * string in wire format -- a sequence of length-prefixed strings -- indicating
|
|
+ * the advertised protocols. Refer to SSL_CTX_set_next_protos_advertised_cb
|
|
+ * in OpenSSL for reference.
|
|
+ */
|
|
+int ssl_callback_AdvertiseNextProtos(SSL *ssl, const unsigned char **data_out,
|
|
+ unsigned int *size_out, void *arg)
|
|
+{
|
|
+ conn_rec *c = (conn_rec*)SSL_get_app_data(ssl);
|
|
+ apr_array_header_t *protos;
|
|
+ int num_protos;
|
|
+ unsigned int size;
|
|
+ int i;
|
|
+ unsigned char *data;
|
|
+ unsigned char *start;
|
|
+
|
|
+ *data_out = NULL;
|
|
+ *size_out = 0;
|
|
+
|
|
+ /* If the connection object is not available, then there's nothing for us
|
|
+ * to do. */
|
|
+ if (c == NULL) {
|
|
+ return SSL_TLSEXT_ERR_OK;
|
|
+ }
|
|
+
|
|
+ /* Invoke our npn_advertise_protos hook, giving other modules a chance to
|
|
+ * add alternate protocol names to advertise. */
|
|
+ protos = apr_array_make(c->pool, 0, sizeof(char*));
|
|
+ modssl_run_npn_advertise_protos_hook(c, protos);
|
|
+ num_protos = protos->nelts;
|
|
+
|
|
+ /* We now have a list of null-terminated strings; we need to concatenate
|
|
+ * them together into a single string, where each protocol name is prefixed
|
|
+ * by its length. First, calculate how long that string will be. */
|
|
+ size = 0;
|
|
+ for (i = 0; i < num_protos; ++i) {
|
|
+ const char *string = APR_ARRAY_IDX(protos, i, const char*);
|
|
+ unsigned int length = strlen(string);
|
|
+ /* If the protocol name is too long (the length must fit in one byte),
|
|
+ * then log an error and skip it. */
|
|
+ if (length > 255) {
|
|
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02307)
|
|
+ "SSL NPN protocol name too long (length=%u): %s",
|
|
+ length, string);
|
|
+ continue;
|
|
+ }
|
|
+ /* Leave room for the length prefix (one byte) plus the protocol name
|
|
+ * itself. */
|
|
+ size += 1 + length;
|
|
+ }
|
|
+
|
|
+ /* If there is nothing to advertise (either because no modules added
|
|
+ * anything to the protos array, or because all strings added to the array
|
|
+ * were skipped), then we're done. */
|
|
+ if (size == 0) {
|
|
+ return SSL_TLSEXT_ERR_OK;
|
|
+ }
|
|
+
|
|
+ /* Now we can build the string. Copy each protocol name string into the
|
|
+ * larger string, prefixed by its length. */
|
|
+ data = apr_palloc(c->pool, size * sizeof(unsigned char));
|
|
+ start = data;
|
|
+ for (i = 0; i < num_protos; ++i) {
|
|
+ const char *string = APR_ARRAY_IDX(protos, i, const char*);
|
|
+ apr_size_t length = strlen(string);
|
|
+ if (length > 255)
|
|
+ continue;
|
|
+ *start = (unsigned char)length;
|
|
+ ++start;
|
|
+ memcpy(start, string, length * sizeof(unsigned char));
|
|
+ start += length;
|
|
+ }
|
|
+
|
|
+ /* Success. */
|
|
+ *data_out = data;
|
|
+ *size_out = size;
|
|
+ return SSL_TLSEXT_ERR_OK;
|
|
+}
|
|
+
|
|
+#endif /* HAVE_TLS_NPN */
|
|
+
|
|
+#ifndef OPENSSL_NO_SRP
|
|
+
|
|
+int ssl_callback_SRPServerParams(SSL *ssl, int *ad, void *arg)
|
|
+{
|
|
+ modssl_ctx_t *mctx = (modssl_ctx_t *)arg;
|
|
+ char *username = SSL_get_srp_username(ssl);
|
|
+ SRP_user_pwd *u;
|
|
+
|
|
+ if (username == NULL
|
|
+ || (u = SRP_VBASE_get_by_user(mctx->srp_vbase, username)) == NULL) {
|
|
+ *ad = SSL_AD_UNKNOWN_PSK_IDENTITY;
|
|
+ return SSL3_AL_FATAL;
|
|
+ }
|
|
+
|
|
+ if (SSL_set_srp_server_param(ssl, u->N, u->g, u->s, u->v, u->info) < 0) {
|
|
+ *ad = SSL_AD_INTERNAL_ERROR;
|
|
+ return SSL3_AL_FATAL;
|
|
+ }
|
|
+
|
|
+ /* reset all other options */
|
|
+ SSL_set_verify(ssl, SSL_VERIFY_NONE, ssl_callback_SSLVerify);
|
|
+ return SSL_ERROR_NONE;
|
|
+}
|
|
+
|
|
+#endif /* OPENSSL_NO_SRP */
|
|
diff --git a/modules/ssl/ssl_engine_log.c b/modules/ssl/ssl_engine_log.c
|
|
index 31861ca..3f6d6ed 100644
|
|
--- a/modules/ssl/ssl_engine_log.c
|
|
+++ b/modules/ssl/ssl_engine_log.c
|
|
@@ -63,12 +63,23 @@ static const char *ssl_log_annotation(const char *error)
|
|
return ssl_log_annotate[i].cpAnnotation;
|
|
}
|
|
|
|
-void ssl_die(void)
|
|
+void ssl_die(server_rec *s)
|
|
{
|
|
+ if (s != NULL && s->is_virtual && s->error_fname != NULL)
|
|
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, NULL, APLOGNO(02311)
|
|
+ "Fatal error initialising mod_ssl, exiting. "
|
|
+ "See %s for more information",
|
|
+ ap_server_root_relative(s->process->pool,
|
|
+ s->error_fname));
|
|
+ else
|
|
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, NULL, APLOGNO(02312)
|
|
+ "Fatal error initialising mod_ssl, exiting.");
|
|
+
|
|
/*
|
|
* This is used for fatal errors and here
|
|
* it is common module practice to really
|
|
* exit from the complete program.
|
|
+ * XXX: The config hooks should return errors instead of calling exit().
|
|
*/
|
|
exit(1);
|
|
}
|
|
diff --git a/modules/ssl/ssl_engine_pphrase.c b/modules/ssl/ssl_engine_pphrase.c
|
|
index 1fa4a2e..23ccaf4 100644
|
|
--- a/modules/ssl/ssl_engine_pphrase.c
|
|
+++ b/modules/ssl/ssl_engine_pphrase.c
|
|
@@ -196,7 +196,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
|
|
"Server should be SSL-aware but has no certificate "
|
|
"configured [Hint: SSLCertificateFile] (%s:%d)",
|
|
pServ->defn_name, pServ->defn_line_number);
|
|
- ssl_die();
|
|
+ ssl_die(pServ);
|
|
}
|
|
|
|
/* Bitmasks for all key algorithms configured for this server;
|
|
@@ -225,14 +225,14 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02201)
|
|
"Init: Can't open server certificate file %s",
|
|
szPath);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
if ((pX509Cert = SSL_read_X509(szPath, NULL, NULL)) == NULL) {
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02241)
|
|
"Init: Unable to read server certificate from"
|
|
" file %s", szPath);
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02202)
|
|
"Init: Read server certificate from '%s'",
|
|
@@ -249,7 +249,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
|
|
"Init: Multiple %s server certificates not "
|
|
"allowed", an);
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
algoCert |= at;
|
|
|
|
@@ -328,7 +328,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02243)
|
|
"Init: Can't open server private key file "
|
|
"%s",szPath);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
/*
|
|
@@ -425,7 +425,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
|
|
"Init: SSLPassPhraseDialog builtin is not "
|
|
"supported on Win32 (key file "
|
|
"%s)", szPath);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
#endif /* WIN32 */
|
|
|
|
@@ -464,7 +464,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
|
|
apr_file_printf(writetty, "**Stopped\n");
|
|
}
|
|
}
|
|
- ssl_die();
|
|
+ ssl_die(pServ);
|
|
}
|
|
|
|
/* If a cached private key was found, nothing more to do
|
|
@@ -479,7 +479,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
|
|
"file %s [Hint: Perhaps it is in a separate file? "
|
|
" See SSLCertificateKeyFile]", szPath);
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
/*
|
|
@@ -493,7 +493,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
|
|
"Init: Multiple %s server private keys not "
|
|
"allowed", an);
|
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
algoKey |= at;
|
|
|
|
diff --git a/modules/ssl/ssl_engine_vars.c b/modules/ssl/ssl_engine_vars.c
|
|
index febc176..8af1c26 100644
|
|
--- a/modules/ssl/ssl_engine_vars.c
|
|
+++ b/modules/ssl/ssl_engine_vars.c
|
|
@@ -395,6 +395,18 @@ static char *ssl_var_lookup_ssl(apr_pool_t *p, conn_rec *c, request_rec *r,
|
|
#endif
|
|
result = apr_pstrdup(p, flag ? "true" : "false");
|
|
}
|
|
+#ifndef OPENSSL_NO_SRP
|
|
+ else if (ssl != NULL && strcEQ(var, "SRP_USER")) {
|
|
+ if ((result = SSL_get_srp_username(ssl)) != NULL) {
|
|
+ result = apr_pstrdup(p, result);
|
|
+ }
|
|
+ }
|
|
+ else if (ssl != NULL && strcEQ(var, "SRP_USERINFO")) {
|
|
+ if ((result = SSL_get_srp_userinfo(ssl)) != NULL) {
|
|
+ result = apr_pstrdup(p, result);
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
|
|
return result;
|
|
}
|
|
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
|
|
index 1b5d042..63e401d 100644
|
|
--- a/modules/ssl/ssl_private.h
|
|
+++ b/modules/ssl/ssl_private.h
|
|
@@ -139,6 +139,11 @@
|
|
#define HAVE_FIPS
|
|
#endif
|
|
|
|
+#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_NEXTPROTONEG) \
|
|
+ && !defined(OPENSSL_NO_TLSEXT)
|
|
+#define HAVE_TLS_NPN
|
|
+#endif
|
|
+
|
|
#if (OPENSSL_VERSION_NUMBER >= 0x10000000)
|
|
#define MODSSL_SSL_CIPHER_CONST const
|
|
#define MODSSL_SSL_METHOD_CONST const
|
|
@@ -180,6 +185,20 @@
|
|
#define HAVE_TLSV1_X
|
|
#endif
|
|
|
|
+#if !defined(OPENSSL_NO_COMP) && !defined(SSL_OP_NO_COMPRESSION) \
|
|
+ && OPENSSL_VERSION_NUMBER < 0x00908000L
|
|
+#define OPENSSL_NO_COMP
|
|
+#endif
|
|
+
|
|
+/* SRP support came in OpenSSL 1.0.1 */
|
|
+#ifndef OPENSSL_NO_SRP
|
|
+#ifdef SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB
|
|
+#include <openssl/srp.h>
|
|
+#else
|
|
+#define OPENSSL_NO_SRP
|
|
+#endif
|
|
+#endif
|
|
+
|
|
/* mod_ssl headers */
|
|
#include "ssl_util_ssl.h"
|
|
|
|
@@ -454,7 +473,11 @@ typedef struct {
|
|
int verify_depth;
|
|
int is_proxy;
|
|
int disabled;
|
|
- int non_ssl_request;
|
|
+ enum {
|
|
+ NON_SSL_OK = 0, /* is SSL request, or error handling completed */
|
|
+ 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;
|
|
|
|
/* Track the handshake/renegotiation state for the connection so
|
|
* that all client-initiated renegotiations can be rejected, as a
|
|
@@ -638,6 +661,17 @@ typedef struct {
|
|
const char *stapling_force_url;
|
|
#endif
|
|
|
|
+#ifndef OPENSSL_NO_SRP
|
|
+ char *srp_vfile;
|
|
+ char *srp_unknown_user_seed;
|
|
+ SRP_VBASE *srp_vbase;
|
|
+#endif
|
|
+
|
|
+ /** RFC 5878 */
|
|
+ const char *rsa_authz_file;
|
|
+ const char *dsa_authz_file;
|
|
+ const char *ec_authz_file;
|
|
+
|
|
modssl_auth_ctx_t auth;
|
|
|
|
BOOL ocsp_enabled; /* true if OCSP verification enabled */
|
|
@@ -669,6 +703,9 @@ struct SSLSrvConfigRec {
|
|
#ifdef HAVE_FIPS
|
|
BOOL fips;
|
|
#endif
|
|
+#ifndef OPENSSL_NO_COMP
|
|
+ BOOL compression;
|
|
+#endif
|
|
};
|
|
|
|
/**
|
|
@@ -711,6 +748,9 @@ const char *ssl_cmd_SSLCryptoDevice(cmd_parms *, void *, const char *);
|
|
const char *ssl_cmd_SSLRandomSeed(cmd_parms *, void *, const char *, const char *, const char *);
|
|
const char *ssl_cmd_SSLEngine(cmd_parms *, void *, const char *);
|
|
const char *ssl_cmd_SSLCipherSuite(cmd_parms *, void *, const char *);
|
|
+const char *ssl_cmd_SSLRSAAuthzFile(cmd_parms *, void *, const char *);
|
|
+const char *ssl_cmd_SSLDSAAuthzFile(cmd_parms *, void *, const char *);
|
|
+const char *ssl_cmd_SSLECAuthzFile(cmd_parms *, void *, const char *);
|
|
const char *ssl_cmd_SSLCertificateFile(cmd_parms *, void *, const char *);
|
|
const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *, void *, const char *);
|
|
const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *, void *, const char *);
|
|
@@ -723,6 +763,7 @@ const char *ssl_cmd_SSLCARevocationPath(cmd_parms *, void *, const char *);
|
|
const char *ssl_cmd_SSLCARevocationFile(cmd_parms *, void *, const char *);
|
|
const char *ssl_cmd_SSLCARevocationCheck(cmd_parms *, void *, const char *);
|
|
const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag);
|
|
+const char *ssl_cmd_SSLCompression(cmd_parms *, void *, int flag);
|
|
const char *ssl_cmd_SSLVerifyClient(cmd_parms *, void *, const char *);
|
|
const char *ssl_cmd_SSLVerifyDepth(cmd_parms *, void *, const char *);
|
|
const char *ssl_cmd_SSLSessionCache(cmd_parms *, void *, const char *);
|
|
@@ -762,6 +803,11 @@ const char *ssl_cmd_SSLOCSPResponseMaxAge(cmd_parms *cmd, void *dcfg, const char
|
|
const char *ssl_cmd_SSLOCSPResponderTimeout(cmd_parms *cmd, void *dcfg, const char *arg);
|
|
const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag);
|
|
|
|
+#ifndef OPENSSL_NO_SRP
|
|
+const char *ssl_cmd_SSLSRPVerifierFile(cmd_parms *cmd, void *dcfg, const char *arg);
|
|
+const char *ssl_cmd_SSLSRPUnknownUserSeed(cmd_parms *cmd, void *dcfg, const char *arg);
|
|
+#endif
|
|
+
|
|
const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag);
|
|
|
|
/** module initialization */
|
|
@@ -807,6 +853,7 @@ int ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *);
|
|
int ssl_callback_SessionTicket(SSL *, unsigned char *, unsigned char *,
|
|
EVP_CIPHER_CTX *, HMAC_CTX *, int);
|
|
#endif
|
|
+int ssl_callback_AdvertiseNextProtos(SSL *ssl, const unsigned char **data, unsigned int *len, void *arg);
|
|
|
|
/** Session Cache Support */
|
|
void ssl_scache_init(server_rec *, apr_pool_t *);
|
|
@@ -838,6 +885,9 @@ void modssl_init_stapling(server_rec *, apr_pool_t *, apr_pool_t *, mods
|
|
void ssl_stapling_ex_init(void);
|
|
int ssl_stapling_init_cert(server_rec *s, modssl_ctx_t *mctx, X509 *x);
|
|
#endif
|
|
+#ifndef OPENSSL_NO_SRP
|
|
+int ssl_callback_SRPServerParams(SSL *, int *, void *);
|
|
+#endif
|
|
|
|
/** I/O */
|
|
void ssl_io_filter_init(conn_rec *, request_rec *r, SSL *);
|
|
@@ -902,7 +952,7 @@ int ssl_stapling_mutex_reinit(server_rec *, apr_pool_t *);
|
|
#define SSL_STAPLING_MUTEX_TYPE "ssl-stapling"
|
|
|
|
/** Logfile Support */
|
|
-void ssl_die(void);
|
|
+void ssl_die(server_rec *);
|
|
void ssl_log_ssl_error(const char *, int, int, server_rec *);
|
|
|
|
/* ssl_log_xerror, ssl_log_cxerror and ssl_log_rxerror are wrappers for the
|
|
diff --git a/modules/ssl/ssl_scache.c b/modules/ssl/ssl_scache.c
|
|
index 2c8d1bc..d32f8e1 100644
|
|
--- a/modules/ssl/ssl_scache.c
|
|
+++ b/modules/ssl/ssl_scache.c
|
|
@@ -63,7 +63,7 @@ void ssl_scache_init(server_rec *s, apr_pool_t *p)
|
|
if (rv) {
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01872)
|
|
"Could not initialize stapling cache. Exiting.");
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
}
|
|
#endif
|
|
@@ -88,7 +88,7 @@ void ssl_scache_init(server_rec *s, apr_pool_t *p)
|
|
if (rv) {
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01874)
|
|
"Could not initialize session cache. Exiting.");
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
}
|
|
|
|
diff --git a/modules/ssl/ssl_util.c b/modules/ssl/ssl_util.c
|
|
index 6b5a7de..475fe4d 100644
|
|
--- a/modules/ssl/ssl_util.c
|
|
+++ b/modules/ssl/ssl_util.c
|
|
@@ -76,8 +76,7 @@ apr_file_t *ssl_util_ppopen(server_rec *s, apr_pool_t *p, const char *cmd,
|
|
return NULL;
|
|
if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS)
|
|
return NULL;
|
|
- if ((proc = (apr_proc_t *)apr_pcalloc(p, sizeof(apr_proc_t))) == NULL)
|
|
- return NULL;
|
|
+ proc = apr_pcalloc(p, sizeof(apr_proc_t));
|
|
if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS)
|
|
return NULL;
|
|
return proc->out;
|
|
@@ -287,7 +286,7 @@ STACK_OF(X509) *ssl_read_pkcs7(server_rec *s, const char *pkcs7)
|
|
f = fopen(pkcs7, "r");
|
|
if (!f) {
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02212) "Can't open %s", pkcs7);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
p7 = PEM_read_PKCS7(f, NULL, NULL, NULL);
|
|
@@ -314,13 +313,13 @@ STACK_OF(X509) *ssl_read_pkcs7(server_rec *s, const char *pkcs7)
|
|
default:
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02213)
|
|
"Don't understand PKCS7 file %s", pkcs7);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
if (!certs) {
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02214)
|
|
"No certificates in %s", pkcs7);
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
|
|
fclose(f);
|
|
@@ -376,24 +375,11 @@ static struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file,
|
|
* allocated memory from a pool, create a subpool that we can blow
|
|
* away in the destruction callback.
|
|
*/
|
|
- rv = apr_pool_create(&p, dynlockpool);
|
|
- if (rv != APR_SUCCESS) {
|
|
- ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, dynlockpool,
|
|
- APLOGNO(02183) "Failed to create subpool for dynamic lock");
|
|
- return NULL;
|
|
- }
|
|
-
|
|
+ apr_pool_create(&p, dynlockpool);
|
|
ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, p,
|
|
"Creating dynamic lock");
|
|
|
|
- value = (struct CRYPTO_dynlock_value *)apr_palloc(p,
|
|
- sizeof(struct CRYPTO_dynlock_value));
|
|
- if (!value) {
|
|
- ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, 0, p,
|
|
- APLOGNO(02185) "Failed to allocate dynamic lock structure");
|
|
- return NULL;
|
|
- }
|
|
-
|
|
+ value = apr_palloc(p, sizeof(struct CRYPTO_dynlock_value));
|
|
value->pool = p;
|
|
/* Keep our own copy of the place from which we were created,
|
|
using our own pool. */
|
|
diff --git a/modules/ssl/ssl_util_ocsp.c b/modules/ssl/ssl_util_ocsp.c
|
|
index 94ef4cd..e5c5e58 100644
|
|
--- a/modules/ssl/ssl_util_ocsp.c
|
|
+++ b/modules/ssl/ssl_util_ocsp.c
|
|
@@ -153,7 +153,13 @@ static char *get_line(apr_bucket_brigade *bbout, apr_bucket_brigade *bbin,
|
|
return NULL;
|
|
}
|
|
|
|
- if (len && line[len-1] != APR_ASCII_LF) {
|
|
+ if (len == 0) {
|
|
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(02321)
|
|
+ "empty response from OCSP server");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if (line[len-1] != APR_ASCII_LF) {
|
|
ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01979)
|
|
"response header line too long from OCSP server");
|
|
return NULL;
|
|
diff --git a/modules/ssl/ssl_util_stapling.c b/modules/ssl/ssl_util_stapling.c
|
|
index 3ff08dc..89be7f5 100644
|
|
--- a/modules/ssl/ssl_util_stapling.c
|
|
+++ b/modules/ssl/ssl_util_stapling.c
|
|
@@ -662,12 +662,12 @@ void modssl_init_stapling(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp,
|
|
if (mc->stapling_cache == NULL) {
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01958)
|
|
"SSLStapling: no stapling cache available");
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
if (ssl_stapling_mutex_init(s, ptemp) == FALSE) {
|
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01959)
|
|
"SSLStapling: cannot initialise stapling mutex");
|
|
- ssl_die();
|
|
+ ssl_die(s);
|
|
}
|
|
/* Set some default values for parameters if they are not set */
|
|
if (mctx->stapling_resptime_skew == UNSET) {
|