You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by rp...@apache.org on 2009/04/01 14:07:49 UTC
svn commit: r760866 - in /httpd/httpd/trunk: CHANGES
docs/manual/mod/mod_ssl.xml modules/proxy/mod_proxy_http.c
modules/ssl/mod_ssl.c modules/ssl/ssl_engine_config.c
modules/ssl/ssl_engine_io.c modules/ssl/ssl_private.h
Author: rpluem
Date: Wed Apr 1 12:07:47 2009
New Revision: 760866
URL: http://svn.apache.org/viewvc?rev=760866&view=rev
Log:
* Add SSLProxyCheckPeerExpire and SSLProxyCheckPeerCN directives to enable
stricter checking of remote server certificates.
(docs/manual/mod/mod_ssl.xml)
Documentation of SSLProxyCheckPeerExpire and SSLProxyCheckPeerCN.
(modules/proxy/mod_proxy_http.c)
Set the hostname of the request URL as note on the connection.
(modules/ssl/ssl_private.h)
Add proxy_ssl_check_peer_expire and proxy_ssl_check_peer_cn fields to
the SSLSrvConfigRec.
(modules/ssl/ssl_engine_config.c)
Directives stuff for SSLProxyCheckPeerExpire and SSLProxyCheckPeerCN.
(modules/ssl/ssl_engine_io.c)
Check whether the remote servers certificate is expired / if there is a
mismatch between the requested hostanme and the remote server certificates
CN field.
Be able to parse ASN1 times.
(modules/ssl/mod_ssl.c)
Directives stuff for SSLProxyCheckPeerExpire and SSLProxyCheckPeerCN.
Modified:
httpd/httpd/trunk/CHANGES
httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml
httpd/httpd/trunk/modules/proxy/mod_proxy_http.c
httpd/httpd/trunk/modules/ssl/mod_ssl.c
httpd/httpd/trunk/modules/ssl/ssl_engine_config.c
httpd/httpd/trunk/modules/ssl/ssl_engine_io.c
httpd/httpd/trunk/modules/ssl/ssl_private.h
Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=760866&r1=760865&r2=760866&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Wed Apr 1 12:07:47 2009
@@ -2,6 +2,10 @@
Changes with Apache 2.3.3
+ *) mod_ssl: Add SSLProxyCheckPeerExpire and SSLProxyCheckPeerCN directives
+ to enable stricter checking of remote server certificates.
+ [Ruediger Pluem]
+
*) ab: Fix a 100% CPU loop on platforms where a failed non-blocking connect
returns EINPROGRESS and a subsequent poll() returns only POLLERR.
Observed on HP-UX. [Eric Covener]
Modified: httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml?rev=760866&r1=760865&r2=760866&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml Wed Apr 1 12:07:47 2009
@@ -1502,6 +1502,48 @@
</directivesynopsis>
<directivesynopsis>
+<name>SSLProxyCheckPeerExpire</name>
+<description>Whether to check if remote server certificate is expired
+</description>
+<syntax>SSLProxyCheckPeerExpire on|off|optional</syntax>
+<default>SSLProxyCheckPeerExpire off</default>
+<contextlist><context>server config</context>
+<context>virtual host</context></contextlist>
+
+<usage>
+<p>
+This directive sets whether it is checked if the remote server certificate
+is expired or not. If the check fails a 502 status code (Bad Gateway) is
+sent.
+</p>
+<example><title>Example</title>
+SSLProxyCheckPeerExpire on
+</example>
+</usage>
+</directivesynopsis>
+
+<directivesynopsis>
+<name>SSLProxyCheckPeerCN</name>
+<description>Whether to check the remote server certificates CN field
+</description>
+<syntax>SSLProxyCheckPeerCN on|off|optional</syntax>
+<default>SSLProxyCheckPeerCN off</default>
+<contextlist><context>server config</context>
+<context>virtual host</context></contextlist>
+
+<usage>
+<p>
+This directive sets whether the remote server certificates CN field is
+compared against the hostname of the request URL. If both are not equal
+a 502 status code (Bad Gateway) is sent.
+</p>
+<example><title>Example</title>
+SSLProxyCheckPeerCN on
+</example>
+</usage>
+</directivesynopsis>
+
+<directivesynopsis>
<name>SSLProxyEngine</name>
<description>SSL Proxy Engine Operation Switch</description>
<syntax>SSLProxyEngine on|off</syntax>
Modified: httpd/httpd/trunk/modules/proxy/mod_proxy_http.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy_http.c?rev=760866&r1=760865&r2=760866&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/mod_proxy_http.c (original)
+++ httpd/httpd/trunk/modules/proxy/mod_proxy_http.c Wed Apr 1 12:07:47 2009
@@ -1964,6 +1964,15 @@
if ((status = ap_proxy_connection_create(proxy_function, backend,
c, r->server)) != OK)
goto cleanup;
+ /*
+ * On SSL connections set a note on the connection what CN is
+ * requested, such that mod_ssl can check if it is requested to do
+ * so.
+ */
+ if (is_ssl) {
+ apr_table_set(backend->connection->notes, "proxy-request-hostname",
+ uri->hostname);
+ }
}
/* Step Four: Send the Request */
Modified: httpd/httpd/trunk/modules/ssl/mod_ssl.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/mod_ssl.c?rev=760866&r1=760865&r2=760866&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/mod_ssl.c (original)
+++ httpd/httpd/trunk/modules/ssl/mod_ssl.c Wed Apr 1 12:07:47 2009
@@ -166,6 +166,10 @@
SSL_CMD_SRV(ProxyMachineCertificatePath, TAKE1,
"SSL Proxy: directory containing client certificates "
"(`/path/to/dir' - contains PEM encoded certificates)")
+ SSL_CMD_SRV(ProxyCheckPeerExpire, FLAG,
+ "SSL Proxy: check the peers certificate expiration date")
+ SSL_CMD_SRV(ProxyCheckPeerCN, FLAG,
+ "SSL Proxy: check the peers certificate CN")
/*
* Per-directory context configuration directives
Modified: httpd/httpd/trunk/modules/ssl/ssl_engine_config.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_config.c?rev=760866&r1=760865&r2=760866&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_config.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_config.c Wed Apr 1 12:07:47 2009
@@ -173,6 +173,8 @@
sc->session_cache_timeout = UNSET;
sc->cipher_server_pref = UNSET;
sc->ssl_log_level = SSL_LOG_UNSET;
+ sc->proxy_ssl_check_peer_expire = SSL_ENABLED_UNSET;
+ sc->proxy_ssl_check_peer_cn = SSL_ENABLED_UNSET;
modssl_ctx_init_proxy(sc, p);
@@ -266,6 +268,8 @@
cfgMergeInt(session_cache_timeout);
cfgMergeBool(cipher_server_pref);
cfgMerge(ssl_log_level, SSL_LOG_UNSET);
+ cfgMerge(proxy_ssl_check_peer_expire, SSL_ENABLED_UNSET);
+ cfgMerge(proxy_ssl_check_peer_cn, SSL_ENABLED_UNSET);
modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy);
@@ -1418,6 +1422,24 @@
return NULL;
}
+const char *ssl_cmd_SSLProxyCheckPeerExpire(cmd_parms *cmd, void *dcfg, int flag)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+ sc->proxy_ssl_check_peer_expire = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
+
+ return NULL;
+}
+
+const char *ssl_cmd_SSLProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+ sc->proxy_ssl_check_peer_cn = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
+
+ return NULL;
+}
+
void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
{
if (!ap_exists_config_define("DUMP_CERTS")) {
Modified: httpd/httpd/trunk/modules/ssl/ssl_engine_io.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_io.c?rev=760866&r1=760865&r2=760866&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_io.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_io.c Wed Apr 1 12:07:47 2009
@@ -28,6 +28,7 @@
core keeps dumping.''
-- Unknown */
#include "ssl_private.h"
+#include "apr_date.h"
/* _________________________________________________________________
**
@@ -1034,6 +1035,31 @@
}
/*
+ * Parse an ASN1time string as returned by ASN1_UTCTIME_print into an
+ * apr_time_t.
+ */
+static apr_time_t parseASN1time(apr_pool_t *p, const char *asn1time)
+{
+ char *asctime;
+
+ /*
+ * Little bit ugly hack:
+ * The ASN1time looks very similar to the asctime format which can be
+ * parsed by apr_date_parse_rfc:
+ * It misses the weekday at the beginning (which is ignored by
+ * apr_date_parse_rfc anyway) and it has a GMT at the end which
+ * does not into the asctime pattern. So add a dummy "Sun " before
+ * the ASN1time and remove the GMT string at the end.
+ */
+ asctime = apr_pstrcat(p, "Sun ", asn1time, NULL);
+ if (strlen(asctime) < 25) {
+ return APR_DATE_BAD;
+ }
+ asctime[24] = '\0';
+ return apr_date_parse_rfc(asctime);
+}
+
+/*
* The hook is NOT registered with ap_hook_process_connection. Instead, it is
* called manually from the churn () before it tries to read any data.
* There is some problem if I accept conn_rec *. Still investigating..
@@ -1060,6 +1086,9 @@
server = mySrvFromConn(c);
if (sslconn->is_proxy) {
+ const char *hostname_note;
+
+ sc = mySrvConfig(sslconn->server);
if ((n = SSL_connect(filter_ctx->pssl)) <= 0) {
ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
"SSL Proxy connect failed");
@@ -1069,6 +1098,47 @@
return MODSSL_ERROR_BAD_GATEWAY;
}
+ if (sc->proxy_ssl_check_peer_expire == SSL_ENABLED_TRUE) {
+ apr_time_t start_time;
+ apr_time_t end_time;
+ apr_time_t now;
+
+ start_time = parseASN1time(c->pool,
+ ssl_var_lookup(NULL, c->base_server,
+ c, NULL,
+ "SSL_CLIENT_V_START"));
+ end_time = parseASN1time(c->pool,
+ ssl_var_lookup(NULL, c->base_server,
+ c, NULL,
+ "SSL_CLIENT_V_END"));
+ now = apr_time_now();
+ if ((now > end_time) || (now < start_time)) {
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
+ "SSL Proxy: Peer certificate is expired");
+ /* ensure that the SSL structures etc are freed, etc: */
+ ssl_filter_io_shutdown(filter_ctx, c, 1);
+ return HTTP_BAD_GATEWAY;
+ }
+ }
+ if ((sc->proxy_ssl_check_peer_cn == SSL_ENABLED_TRUE)
+ && ((hostname_note =
+ apr_table_get(c->notes, "proxy-request-hostname")) != NULL)) {
+ const char *hostname;
+
+ hostname = ssl_var_lookup(NULL, c->base_server, c, NULL,
+ "SSL_CLIENT_S_DN_CN");
+ apr_table_unset(c->notes, "proxy-request-hostname");
+ if (strcasecmp(hostname, hostname_note)) {
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
+ "SSL Proxy: Peer certificate CN mismatch:"
+ " Certificate CN: %s Requested hostname: %s",
+ hostname, hostname_note);
+ /* ensure that the SSL structures etc are freed, etc: */
+ ssl_filter_io_shutdown(filter_ctx, c, 1);
+ return HTTP_BAD_GATEWAY;
+ }
+ }
+
return APR_SUCCESS;
}
Modified: httpd/httpd/trunk/modules/ssl/ssl_private.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_private.h?rev=760866&r1=760865&r2=760866&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_private.h (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_private.h Wed Apr 1 12:07:47 2009
@@ -477,6 +477,8 @@
modssl_ctx_t *server;
modssl_ctx_t *proxy;
ssl_log_level_e ssl_log_level;
+ ssl_enabled_t proxy_ssl_check_peer_expire;
+ ssl_enabled_t proxy_ssl_check_peer_cn;
};
/**
@@ -554,6 +556,8 @@
const char *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLProxyCheckPeerExpire(cmd_parms *cmd, void *dcfg, int flag);
+const char *ssl_cmd_SSLProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag);
const char *ssl_cmd_SSLOCSPOverrideResponder(cmd_parms *cmd, void *dcfg, int flag);
const char *ssl_cmd_SSLOCSPDefaultResponder(cmd_parms *cmd, void *dcfg, const char *arg);
Re: svn commit: r760866 - in /httpd/httpd/trunk: CHANGESdocs/manual/mod/mod_ssl.xml modules/proxy/mod_proxy_http.cmodules/ssl/mod_ssl.c modules/ssl/ssl_engine_config.cmodules/ssl/ssl_engine_io.c modules/ssl/ssl_private.h
Posted by "Plüm, Rüdiger, VF-Group" <ru...@vodafone.com>.
> -----Ursprüngliche Nachricht-----
> Von: Joe Orton
> Gesendet: Montag, 27. April 2009 18:09
> An: dev@httpd.apache.org
> Betreff: Re: svn commit: r760866 - in /httpd/httpd/trunk:
> CHANGESdocs/manual/mod/mod_ssl.xml
> modules/proxy/mod_proxy_http.cmodules/ssl/mod_ssl.c
> modules/ssl/ssl_engine_config.cmodules/ssl/ssl_engine_io.c
> modules/ssl/ssl_private.h
>
> On Wed, Apr 01, 2009 at 12:07:49PM -0000, rpluem@apache.org wrote:
> > Author: rpluem
> > Date: Wed Apr 1 12:07:47 2009
> > New Revision: 760866
> >
> > URL: http://svn.apache.org/viewvc?rev=760866&view=rev
> > Log:
> ...
> > + if (sc->proxy_ssl_check_peer_expire == SSL_ENABLED_TRUE) {
> > + apr_time_t start_time;
> > + apr_time_t end_time;
> > + apr_time_t now;
> > +
> > + start_time = parseASN1time(c->pool,
> > +
> ssl_var_lookup(NULL, c->base_server,
> > + c, NULL,
> > +
> "SSL_CLIENT_V_START"));
> > + end_time = parseASN1time(c->pool,
> > + ssl_var_lookup(NULL,
> c->base_server,
> > + c, NULL,
> > +
> "SSL_CLIENT_V_END"));
>
> You can (and should) use X509_get_notBefore(), X509_get_notAfter() to
> get the end/start times form sslconn->client_cert; can check
> for expiry
> using X509_cmp_current_time() on the returned values. Should
> require 1
> less ASN.1 date parser!
Done in r769809. Please crosscheck.
>
> Also maybe default these to "on" for the trunk?
>
Done in r769815.
Regards
Rüdiger
Re: svn commit: r760866 - in /httpd/httpd/trunk: CHANGES
docs/manual/mod/mod_ssl.xml modules/proxy/mod_proxy_http.c
modules/ssl/mod_ssl.c modules/ssl/ssl_engine_config.c modules/ssl/ssl_engine_io.c
modules/ssl/ssl_private.h
Posted by Eric Covener <co...@gmail.com>.
On Mon, Apr 27, 2009 at 12:08 PM, Joe Orton <jo...@redhat.com> wrote:
>>* Add SSLProxyCheckPeerExpire and SSLProxyCheckPeerCN directives
>> to enable stricter checking of remote server certificates.
> Also maybe default these to "on" for the trunk?
+1
--
Eric Covener
covener@gmail.com
Re: svn commit: r760866 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/mod_ssl.xml
modules/proxy/mod_proxy_http.c modules/ssl/mod_ssl.c modules/ssl/ssl_engine_config.c
modules/ssl/ssl_engine_io.c modules/ssl/ssl_private.h
Posted by Ruediger Pluem <rp...@apache.org>.
On 04/27/2009 06:08 PM, Joe Orton wrote:
> On Wed, Apr 01, 2009 at 12:07:49PM -0000, rpluem@apache.org wrote:
>> Author: rpluem
>> Date: Wed Apr 1 12:07:47 2009
>> New Revision: 760866
>>
>> URL: http://svn.apache.org/viewvc?rev=760866&view=rev
>> Log:
> ...
>> + if (sc->proxy_ssl_check_peer_expire == SSL_ENABLED_TRUE) {
>> + apr_time_t start_time;
>> + apr_time_t end_time;
>> + apr_time_t now;
>> +
>> + start_time = parseASN1time(c->pool,
>> + ssl_var_lookup(NULL, c->base_server,
>> + c, NULL,
>> + "SSL_CLIENT_V_START"));
>> + end_time = parseASN1time(c->pool,
>> + ssl_var_lookup(NULL, c->base_server,
>> + c, NULL,
>> + "SSL_CLIENT_V_END"));
>
> You can (and should) use X509_get_notBefore(), X509_get_notAfter() to
> get the end/start times form sslconn->client_cert; can check for expiry
> using X509_cmp_current_time() on the returned values. Should require 1
> less ASN.1 date parser!
Thanks for the pointer. Due to bad luck this is already backported :-(.
But I will have a look to improve this on trunk and propose it for backport
afterwards
> Also maybe default these to "on" for the trunk?
Makes sense. I will tackle this separately and after the first issue.
> Sorry, I'm about a month behind on reading svn commits now :( Joe
No problem. Comments are always welcome.
Regards
Rüdiger
Re: svn commit: r760866 - in /httpd/httpd/trunk: CHANGES
docs/manual/mod/mod_ssl.xml modules/proxy/mod_proxy_http.c
modules/ssl/mod_ssl.c modules/ssl/ssl_engine_config.c
modules/ssl/ssl_engine_io.c modules/ssl/ssl_private.h
Posted by Joe Orton <jo...@redhat.com>.
On Wed, Apr 01, 2009 at 12:07:49PM -0000, rpluem@apache.org wrote:
> Author: rpluem
> Date: Wed Apr 1 12:07:47 2009
> New Revision: 760866
>
> URL: http://svn.apache.org/viewvc?rev=760866&view=rev
> Log:
...
> + if (sc->proxy_ssl_check_peer_expire == SSL_ENABLED_TRUE) {
> + apr_time_t start_time;
> + apr_time_t end_time;
> + apr_time_t now;
> +
> + start_time = parseASN1time(c->pool,
> + ssl_var_lookup(NULL, c->base_server,
> + c, NULL,
> + "SSL_CLIENT_V_START"));
> + end_time = parseASN1time(c->pool,
> + ssl_var_lookup(NULL, c->base_server,
> + c, NULL,
> + "SSL_CLIENT_V_END"));
You can (and should) use X509_get_notBefore(), X509_get_notAfter() to
get the end/start times form sslconn->client_cert; can check for expiry
using X509_cmp_current_time() on the returned values. Should require 1
less ASN.1 date parser!
Also maybe default these to "on" for the trunk?
Sorry, I'm about a month behind on reading svn commits now :( Joe