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 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.
\n" - "Instead use the HTTPS scheme to access " - "this URL, please.
\n" - "
Hint: " - "%s
", - 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.
\n Instead use the HTTPS scheme to " + "access this URL, please.
\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 +#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) {