diff options
Diffstat (limited to 'modules/ssl')
-rw-r--r-- | modules/ssl/mod_ssl.c | 4 | ||||
-rw-r--r-- | modules/ssl/mod_ssl.mak | 4 | ||||
-rw-r--r-- | modules/ssl/ssl_engine_config.c | 39 | ||||
-rw-r--r-- | modules/ssl/ssl_engine_init.c | 12 | ||||
-rw-r--r-- | modules/ssl/ssl_engine_io.c | 42 | ||||
-rw-r--r-- | modules/ssl/ssl_engine_kernel.c | 22 | ||||
-rw-r--r-- | modules/ssl/ssl_private.h | 14 |
7 files changed, 107 insertions, 30 deletions
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c index 219e3337..f8e71b33 100644 --- a/modules/ssl/mod_ssl.c +++ b/modules/ssl/mod_ssl.c @@ -119,7 +119,7 @@ static const command_rec ssl_config_cmds[] = { SSL_CMD_SRV(CARevocationFile, TAKE1, "SSL CA Certificate Revocation List (CRL) file " "('/path/to/file' - PEM encoded)") - SSL_CMD_SRV(CARevocationCheck, TAKE1, + SSL_CMD_SRV(CARevocationCheck, RAW_ARGS, "SSL CA Certificate Revocation List (CRL) checking mode") SSL_CMD_ALL(VerifyClient, TAKE1, "SSL Client verify type " @@ -197,7 +197,7 @@ static const command_rec ssl_config_cmds[] = { SSL_CMD_SRV(ProxyCARevocationFile, TAKE1, "SSL Proxy: CA Certificate Revocation List (CRL) file " "('/path/to/file' - PEM encoded)") - SSL_CMD_SRV(ProxyCARevocationCheck, TAKE1, + SSL_CMD_SRV(ProxyCARevocationCheck, RAW_ARGS, "SSL Proxy: CA Certificate Revocation List (CRL) checking mode") SSL_CMD_SRV(ProxyMachineCertificateFile, TAKE1, "SSL Proxy: file containing client certificates " diff --git a/modules/ssl/mod_ssl.mak b/modules/ssl/mod_ssl.mak index 6826ba5c..a3bd304a 100644 --- a/modules/ssl/mod_ssl.mak +++ b/modules/ssl/mod_ssl.mak @@ -470,14 +470,14 @@ SOURCE=..\..\build\win32\httpd.rc "$(INTDIR)\mod_ssl.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0x409 /fo"$(INTDIR)\mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /i "\local0\asf\build\httpd-2.4\build\win32" /d "NDEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache" $(SOURCE) + $(RSC) /l 0x409 /fo"$(INTDIR)\mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache" $(SOURCE) !ELSEIF "$(CFG)" == "mod_ssl - Win32 Debug" "$(INTDIR)\mod_ssl.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0x409 /fo"$(INTDIR)\mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /i "\local0\asf\build\httpd-2.4\build\win32" /d "_DEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache" $(SOURCE) + $(RSC) /l 0x409 /fo"$(INTDIR)\mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache" $(SOURCE) !ENDIF diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c index a3d5af52..129a01ff 100644 --- a/modules/ssl/ssl_engine_config.c +++ b/modules/ssl/ssl_engine_config.c @@ -121,7 +121,7 @@ static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p) mctx->crl_path = NULL; mctx->crl_file = NULL; - mctx->crl_check_mode = SSL_CRLCHECK_UNSET; + mctx->crl_check_mask = UNSET; mctx->auth.ca_cert_path = NULL; mctx->auth.ca_cert_file = NULL; @@ -271,7 +271,7 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p, cfgMerge(crl_path, NULL); cfgMerge(crl_file, NULL); - cfgMerge(crl_check_mode, SSL_CRLCHECK_UNSET); + cfgMergeInt(crl_check_mask); cfgMergeString(auth.ca_cert_path); cfgMergeString(auth.ca_cert_file); @@ -1000,23 +1000,38 @@ const char *ssl_cmd_SSLCARevocationFile(cmd_parms *cmd, static const char *ssl_cmd_crlcheck_parse(cmd_parms *parms, const char *arg, - ssl_crlcheck_t *mode) + int *mask) { - if (strcEQ(arg, "none")) { - *mode = SSL_CRLCHECK_NONE; + const char *w; + + w = ap_getword_conf(parms->temp_pool, &arg); + if (strcEQ(w, "none")) { + *mask = SSL_CRLCHECK_NONE; } - else if (strcEQ(arg, "leaf")) { - *mode = SSL_CRLCHECK_LEAF; + else if (strcEQ(w, "leaf")) { + *mask = SSL_CRLCHECK_LEAF; } - else if (strcEQ(arg, "chain")) { - *mode = SSL_CRLCHECK_CHAIN; + else if (strcEQ(w, "chain")) { + *mask = SSL_CRLCHECK_CHAIN; } else { return apr_pstrcat(parms->temp_pool, parms->cmd->name, - ": Invalid argument '", arg, "'", + ": Invalid argument '", w, "'", NULL); } + while (*arg) { + w = ap_getword_conf(parms->temp_pool, &arg); + if (strcEQ(w, "no_crl_for_cert_ok")) { + *mask |= SSL_CRLCHECK_NO_CRL_FOR_CERT_OK; + } + else { + return apr_pstrcat(parms->temp_pool, parms->cmd->name, + ": Invalid argument '", w, "'", + NULL); + } + } + return NULL; } @@ -1026,7 +1041,7 @@ const char *ssl_cmd_SSLCARevocationCheck(cmd_parms *cmd, { SSLSrvConfigRec *sc = mySrvConfig(cmd->server); - return ssl_cmd_crlcheck_parse(cmd, arg, &sc->server->crl_check_mode); + return ssl_cmd_crlcheck_parse(cmd, arg, &sc->server->crl_check_mask); } static const char *ssl_cmd_verify_parse(cmd_parms *parms, @@ -1540,7 +1555,7 @@ const char *ssl_cmd_SSLProxyCARevocationCheck(cmd_parms *cmd, { SSLSrvConfigRec *sc = mySrvConfig(cmd->server); - return ssl_cmd_crlcheck_parse(cmd, arg, &sc->proxy->crl_check_mode); + return ssl_cmd_crlcheck_parse(cmd, arg, &sc->proxy->crl_check_mask); } const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd, diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c index 797fbd12..9adca48a 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c @@ -787,14 +787,20 @@ static apr_status_t ssl_init_ctx_crl(server_rec *s, X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx); unsigned long crlflags = 0; char *cfgp = mctx->pkp ? "SSLProxy" : "SSL"; + int crl_check_mode; + + if (mctx->crl_check_mask == UNSET) { + mctx->crl_check_mask = SSL_CRLCHECK_NONE; + } + crl_check_mode = mctx->crl_check_mask & ~SSL_CRLCHECK_FLAGS; /* * Configure Certificate Revocation List (CRL) Details */ if (!(mctx->crl_file || mctx->crl_path)) { - if (mctx->crl_check_mode == SSL_CRLCHECK_LEAF || - mctx->crl_check_mode == SSL_CRLCHECK_CHAIN) { + if (crl_check_mode == SSL_CRLCHECK_LEAF || + crl_check_mode == SSL_CRLCHECK_CHAIN) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01899) "Host %s: CRL checking has been enabled, but " "neither %sCARevocationFile nor %sCARevocationPath " @@ -816,7 +822,7 @@ static apr_status_t ssl_init_ctx_crl(server_rec *s, return ssl_die(s); } - switch (mctx->crl_check_mode) { + switch (crl_check_mode) { case SSL_CRLCHECK_LEAF: crlflags = X509_V_FLAG_CRL_CHECK; break; diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c index 77c48482..ea231932 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -1092,6 +1092,9 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx) if (sslconn->is_proxy) { #ifdef HAVE_TLSEXT apr_ipsubnet_t *ip; +#ifdef HAVE_TLS_ALPN + const char *alpn_note; +#endif #endif const char *hostname_note = apr_table_get(c->notes, "proxy-request-hostname"); @@ -1101,6 +1104,41 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx) sc = mySrvConfig(server); #ifdef HAVE_TLSEXT +#ifdef HAVE_TLS_ALPN + alpn_note = apr_table_get(c->notes, "proxy-request-alpn-protos"); + if (alpn_note) { + char *protos, *s, *p, *last; + apr_size_t len; + + s = protos = apr_pcalloc(c->pool, strlen(alpn_note)+1); + p = apr_pstrdup(c->pool, alpn_note); + while ((p = apr_strtok(p, ", ", &last))) { + len = last - p - (*last? 1 : 0); + if (len > 255) { + ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03309) + "ALPN proxy protocol identifier too long: %s", + p); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, server); + return APR_EGENERAL; + } + *s++ = (unsigned char)len; + while (len--) { + *s++ = *p++; + } + p = NULL; + } + ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, + "setting alpn protos from '%s', protolen=%d", + alpn_note, (int)(s - protos)); + if (protos != s && SSL_set_alpn_protos(filter_ctx->pssl, + (unsigned char *)protos, + s - protos)) { + ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(03310) + "error setting alpn protos from '%s'", alpn_note); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_WARNING, server); + } + } +#endif /* defined HAVE_TLS_ALPN */ /* * Enable SNI for backend requests. Make sure we don't do it for * pure SSLv3 connections, and also prevent IP addresses @@ -1151,6 +1189,8 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx) } } if ((sc->proxy_ssl_check_peer_name != SSL_ENABLED_FALSE) && + ((sc->proxy_ssl_check_peer_cn != SSL_ENABLED_FALSE) || + (sc->proxy_ssl_check_peer_name == SSL_ENABLED_TRUE)) && hostname_note) { apr_table_unset(c->notes, "proxy-request-hostname"); if (!cert @@ -1162,7 +1202,7 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx) "for hostname %s", hostname_note); } } - else if ((sc->proxy_ssl_check_peer_cn != SSL_ENABLED_FALSE) && + else if ((sc->proxy_ssl_check_peer_cn == SSL_ENABLED_TRUE) && hostname_note) { const char *hostname; int match = 0; diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index 17fd7db3..8b6149d8 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -727,6 +727,7 @@ int ssl_hook_Access(request_rec *r) * on this connection. */ apr_table_setn(r->notes, "ssl-renegotiate-forbidden", "verify-client"); + SSL_set_verify(ssl, verify_old, ssl_callback_SSLVerify); return HTTP_FORBIDDEN; } /* optimization */ @@ -1553,22 +1554,24 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx) SSLDirConfigRec *dc = r ? myDirConfig(r) : NULL; SSLConnRec *sslconn = myConnConfig(conn); modssl_ctx_t *mctx = myCtxConfig(sslconn, sc); + int crl_check_mode = mctx->crl_check_mask & ~SSL_CRLCHECK_FLAGS; /* Get verify ingredients */ int errnum = X509_STORE_CTX_get_error(ctx); int errdepth = X509_STORE_CTX_get_error_depth(ctx); int depth, verify; + /* * Log verification information */ ssl_log_cxerror(SSLLOG_MARK, APLOG_DEBUG, 0, conn, X509_STORE_CTX_get_current_cert(ctx), APLOGNO(02275) "Certificate Verification, depth %d, " - "CRL checking mode: %s", errdepth, - mctx->crl_check_mode == SSL_CRLCHECK_CHAIN ? - "chain" : (mctx->crl_check_mode == SSL_CRLCHECK_LEAF ? - "leaf" : "none")); + "CRL checking mode: %s (%x)", errdepth, + crl_check_mode == SSL_CRLCHECK_CHAIN ? "chain" : + crl_check_mode == SSL_CRLCHECK_LEAF ? "leaf" : "none", + mctx->crl_check_mask); /* * Check for optionally acceptable non-verifiable issuer situation @@ -1617,6 +1620,17 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx) X509_STORE_CTX_set_error(ctx, -1); } + if (!ok && errnum == X509_V_ERR_UNABLE_TO_GET_CRL + && (mctx->crl_check_mask & SSL_CRLCHECK_NO_CRL_FOR_CERT_OK)) { + ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, conn, + "Certificate Verification: Temporary error (%d): %s: " + "optional therefore we're accepting the certificate", + errnum, X509_verify_cert_error_string(errnum)); + X509_STORE_CTX_set_error(ctx, X509_V_OK); + errnum = X509_V_OK; + ok = TRUE; + } + #ifndef OPENSSL_NO_OCSP /* * Perform OCSP-based revocation checks diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index 70b3ac22..7f6f9fd9 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -343,13 +343,15 @@ typedef enum { || (errnum == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE)) /** - * CRL checking modes + * CRL checking mask (mode | flags) */ typedef enum { - SSL_CRLCHECK_UNSET = UNSET, - SSL_CRLCHECK_NONE = 0, - SSL_CRLCHECK_LEAF = 1, - SSL_CRLCHECK_CHAIN = 2 + SSL_CRLCHECK_NONE = (0), + SSL_CRLCHECK_LEAF = (1 << 0), + SSL_CRLCHECK_CHAIN = (1 << 1), + +#define SSL_CRLCHECK_FLAGS (~0x3) + SSL_CRLCHECK_NO_CRL_FOR_CERT_OK = (1 << 2) } ssl_crlcheck_t; /** @@ -607,7 +609,7 @@ typedef struct { /** certificate revocation list */ const char *crl_path; const char *crl_file; - ssl_crlcheck_t crl_check_mode; + int crl_check_mask; #ifdef HAVE_OCSP_STAPLING /** OCSP stapling options */ |