Re: Fwd: [us...@httpd] SSLRequire UTF-8 characters
On 20.12.2010 22:28, Stefan Fritsch wrote: The problem is that ssl_var_lookup can be called for an open connection before the request_rec is created. In the current trunk, this does not seem to be done for the SSL_*_DN variables, but it is done for other variables like SSL_CLIENT_S_DN_CN. So the question is: Do we accept that modules which may call ssl_var_lookup for SSL_*_DN without request_rec may get the result in an unexpected format? My answer is yes - I consider it acceptable (if others disagree, please say so). I can't think of many cases where processing SSL_{CLIENT,SERVER}_{I,S}_DN *before* having read the request is really useful, especially not outside mod_ssl. Looking at what other modules make use of ssl_var_lookup, we actually find that all of them call it at a time when the request_rec is indeed available: mod_rewrite: result = rewrite_ssl_lookup(r-pool, r-server, r-connection, r, var + 4); mod_headers: const char *val = header_ssl_lookup(r-pool, r-server, r-connection, r, name); mod_proxy_ajp: if ((envvar = ap_proxy_ssl_val(r-pool, r-server, r-connection, r, AJP13_SSL_CLIENT_CERT_INDICATOR)) For testing purposes, I have created the attached sample cert, which includes a few, umm, special features - to allow testing the rendering of the SSL_CLIENT_S_DN_* variables, in particular. It's a PKCS#12 file with an empty password, so the cert can be imported into a browser for client authentication test. To get a better picture of what's included in the DN, openssl x509 -nameopt sep_multiline,show_type ... can be used. Kaspar httpd-user-testcert.p12 Description: Binary data
Re: Fwd: [us...@httpd] SSLRequire UTF-8 characters
On Monday 20 December 2010, Kaspar Brand wrote: Instead of an SSLOption (which would require a request_rec to lookup), I have implemented a per-vhost option for restoring compatibility. Could we pass the request_rec from ssl_var_lookup() to ssl_var_lookup_ssl(), and from there on to ssl_var_lookup_ssl_cert() etc.? SSLOptions seems like the best place to me for such an option, it's where I would expect it to find as an httpd user. The problem is that ssl_var_lookup can be called for an open connection before the request_rec is created. In the current trunk, this does not seem to be done for the SSL_*_DN variables, but it is done for other variables like SSL_CLIENT_S_DN_CN. So the question is: Do we accept that modules which may call ssl_var_lookup for SSL_*_DN without request_rec may get the result in an unexpected format? I would name the option LegacyDNStringFormat (instead of ...VarFormat). Can we reject such certificates somehow? Should we close the connection if we see such a thing in ssl_var_lookup_ssl_cert? Or should we try to escape the 0-byte in the variable? The latter. I suggest using ASN1_STRING_print_ex() with ASN1_STRFLGS_RFC2253 ~ASN1_STRFLGS_ESC_MSB (will escape them as \0). OK, makes sense.
Re: Fwd: [us...@httpd] SSLRequire UTF-8 characters
On Sunday 19 December 2010, Dr Stephen Henson wrote: On 29/11/2010 19:34, Dr Stephen Henson wrote: You can get a UTF8String from most string types using ASN1_STRING_to_UTF8(). This should be adequate for most purposes: it doesn't handle the more bizarre TeletexString shift conversions but those are rarely encountered in practice. I should have also included a note of warning about ASN1_STRING_to_UTF8(). You cannot safely assume that the result will be a null terminated string as many ASN1 string types can include embedded nulls: this can have security implications in some cases. You mean someone could make a certificate with a CN of foo.apache.org\0evil.com but the CN variable would then only contain foo.apache.org? I think we can safely assume that any certificate that contains an embedded null after converting to UTF8 is malicious. Can we reject such certificates somehow? Should we close the connection if we see such a thing in ssl_var_lookup_ssl_cert? Or should we try to escape the 0-byte in the variable?
Re: Fwd: [us...@httpd] SSLRequire UTF-8 characters
On 19.12.2010 01:58, Stefan Fritsch wrote: emailaddress=test-...@httpd.apache.org,CN=ca,OU=httpd-test,O=ASF,L=San Francisco,ST=California,C=US Is this what we want? We could use XN_FLAG_DN_REV to keep the old order. I haven't tried UTF8 characters, yet. Thanks, Stefan, for working on this. My idea with using XN_FLAG_RFC2253 was that this is the only kind of standardized X.509 DN string rendering - so I would not add XN_FLAG_DN_REV to the mix, as RFC 2253 (section 2.1) defines the order shown above. Instead of an SSLOption (which would require a request_rec to lookup), I have implemented a per-vhost option for restoring compatibility. Could we pass the request_rec from ssl_var_lookup() to ssl_var_lookup_ssl(), and from there on to ssl_var_lookup_ssl_cert() etc.? SSLOptions seems like the best place to me for such an option, it's where I would expect it to find as an httpd user. I would name the option LegacyDNStringFormat (instead of ...VarFormat). Can we reject such certificates somehow? Should we close the connection if we see such a thing in ssl_var_lookup_ssl_cert? Or should we try to escape the 0-byte in the variable? The latter. I suggest using ASN1_STRING_print_ex() with ASN1_STRFLGS_RFC2253 ~ASN1_STRFLGS_ESC_MSB (will escape them as \0). Kaspar
Re: Fwd: [us...@httpd] SSLRequire UTF-8 characters
On Monday 29 November 2010, Dr Stephen Henson wrote: On 24/11/2010 07:07, Kaspar Brand wrote: On 20.11.2010 20:24, Stefan Fritsch wrote: On Fri, 19 Nov 2010, Joe Orton wrote: We could support this better by having a new set of exports: SSL_{CLIENT,SERVER}_{I,S}_UTF8DN_*(_n)? (or something similarly named) which works the same as _DN_ but exports the attributes as a UTF-8 byte seequence regardless of the underlying ASN.1 type; this would be a relatively simple hack. Or have a (per vhost) directive that enables conversion for all SSL_*_S_DN_* and SSL_*_S_DN to UTF8. IMHO, this could even be enabled by default in 2.4. I prefer the latter approach, yes (there's already an awful lot of SSL_* something variables). Given the fact that mod_ssl's current behavior with non-ASCII characters (i.e., outside the 0-127 range) is mostly undefined and/or sometimes even erroneous (a BMPString in the subject or issuer DN will end up as an empty SSL_*_*_DN_* variable, due to the initial null byte), I would suggest the following solution: - for all SSL_{CLIENT,SERVER}_{I,S}_DN_* variables, use UTF-8 by default (i.e., adapt ssl_engine_vars.c:ssl_var_lookup_ssl_cert_dn() to convert TeletexString, UniversalString and BMPString types to UTF8String) - for SSL_{CLIENT,SERVER}_{I,S}_DN, don't use X509_NAME_oneline() any more and switch to X509_NAME_print_ex() instead. What flags should be used is probably debatable - I would recommend to go with XN_FLAG_RFC2253 (note that using XN_FLAG_ONELINE with X509_NAME_print_ex doesn't produce the same string as X509_NAME_oneline, so this will break backward compatibility in any case) - add another parameter to the SSLOptions directive which allows re-enabling the old string rendering for SSL_{CLIENT,SERVER}_{I,S}_DN (so the new default would be to rely on X509_NAME_print_ex - even for 2.2 -, but people could restore the current behavior through this option) It's a very good idea to avoid X509_NAME_oneline() wherever possible as it is highly broken, can produce ambiguous output (of the Bobby Tables variety) and at other times be just plain wrong (BMPStrings is one of many examples). We have to retain it in OpenSSL for backwards compatibility though. I'd throw it out tomorrow if I could get away with it. You can get a UTF8String from most string types using ASN1_STRING_to_UTF8(). This should be adequate for most purposes: it doesn't handle the more bizarre TeletexString shift conversions but those are rarely encountered in practice. I have come up with the attached patch which more or less implements Kaspar's suggestions. I am using XN_FLAG_RFC2253 ~ASN1_STRFLGS_ESC_MSB as flags for X509_NAME_print_ex() for SSL_{CLIENT,SERVER}_{I,S}_DN. This changes /C=US/ST=California/L=San Francisco/O=ASF/OU=httpd- test/CN=ca/emailaddress=test-...@httpd.apache.org into emailaddress=test-...@httpd.apache.org,CN=ca,OU=httpd-test,O=ASF,L=San Francisco,ST=California,C=US Is this what we want? We could use XN_FLAG_DN_REV to keep the old order. I haven't tried UTF8 characters, yet. Instead of an SSLOption (which would require a request_rec to lookup), I have implemented a per-vhost option for restoring compatibility. diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c index 3d090cb..fc36f6c 100644 --- a/modules/ssl/mod_ssl.c +++ b/modules/ssl/mod_ssl.c @@ -128,6 +128,8 @@ static const command_rec ssl_config_cmds[] = { Use the server's cipher ordering preference) SSL_CMD_SRV(InsecureRenegotiation, FLAG, Enable support for insecure renegotiation) +SSL_CMD_SRV(LegacyDNVarFormat, FLAG, +Use legacy format for SSL_{CLIENT,SERVER}_{I,S}_DN variables) SSL_CMD_ALL(UserName, TAKE1, Set user name to SSL variable value) SSL_CMD_SRV(StrictSNIVHostCheck, FLAG, diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c index 4bccfe7..de4b621 100644 --- a/modules/ssl/ssl_engine_config.c +++ b/modules/ssl/ssl_engine_config.c @@ -186,6 +186,7 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p) sc-session_cache_timeout = UNSET; sc-cipher_server_pref = UNSET; sc-insecure_reneg = UNSET; +sc-legacy_dn_format = UNSET; sc-proxy_ssl_check_peer_expire = SSL_ENABLED_UNSET; sc-proxy_ssl_check_peer_cn = SSL_ENABLED_UNSET; #ifndef OPENSSL_NO_TLSEXT @@ -298,6 +299,7 @@ void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv) cfgMergeInt(session_cache_timeout); cfgMergeBool(cipher_server_pref); cfgMergeBool(insecure_reneg); +cfgMergeBool(legacy_dn_format); cfgMerge(proxy_ssl_check_peer_expire, SSL_ENABLED_UNSET); cfgMerge(proxy_ssl_check_peer_cn, SSL_ENABLED_UNSET); #ifndef OPENSSL_NO_TLSEXT @@ -669,6 +671,13 @@ const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd,
Re: Fwd: [us...@httpd] SSLRequire UTF-8 characters
On 24/11/2010 07:07, Kaspar Brand wrote: On 20.11.2010 20:24, Stefan Fritsch wrote: On Fri, 19 Nov 2010, Joe Orton wrote: We could support this better by having a new set of exports: SSL_{CLIENT,SERVER}_{I,S}_UTF8DN_*(_n)? (or something similarly named) which works the same as _DN_ but exports the attributes as a UTF-8 byte seequence regardless of the underlying ASN.1 type; this would be a relatively simple hack. Or have a (per vhost) directive that enables conversion for all SSL_*_S_DN_* and SSL_*_S_DN to UTF8. IMHO, this could even be enabled by default in 2.4. I prefer the latter approach, yes (there's already an awful lot of SSL_* something variables). Given the fact that mod_ssl's current behavior with non-ASCII characters (i.e., outside the 0-127 range) is mostly undefined and/or sometimes even erroneous (a BMPString in the subject or issuer DN will end up as an empty SSL_*_*_DN_* variable, due to the initial null byte), I would suggest the following solution: - for all SSL_{CLIENT,SERVER}_{I,S}_DN_* variables, use UTF-8 by default (i.e., adapt ssl_engine_vars.c:ssl_var_lookup_ssl_cert_dn() to convert TeletexString, UniversalString and BMPString types to UTF8String) - for SSL_{CLIENT,SERVER}_{I,S}_DN, don't use X509_NAME_oneline() any more and switch to X509_NAME_print_ex() instead. What flags should be used is probably debatable - I would recommend to go with XN_FLAG_RFC2253 (note that using XN_FLAG_ONELINE with X509_NAME_print_ex doesn't produce the same string as X509_NAME_oneline, so this will break backward compatibility in any case) - add another parameter to the SSLOptions directive which allows re-enabling the old string rendering for SSL_{CLIENT,SERVER}_{I,S}_DN (so the new default would be to rely on X509_NAME_print_ex - even for 2.2 -, but people could restore the current behavior through this option) It's a very good idea to avoid X509_NAME_oneline() wherever possible as it is highly broken, can produce ambiguous output (of the Bobby Tables variety) and at other times be just plain wrong (BMPStrings is one of many examples). We have to retain it in OpenSSL for backwards compatibility though. I'd throw it out tomorrow if I could get away with it. You can get a UTF8String from most string types using ASN1_STRING_to_UTF8(). This should be adequate for most purposes: it doesn't handle the more bizarre TeletexString shift conversions but those are rarely encountered in practice. Steve. -- Dr Stephen N. Henson. Senior Technical/Cryptography Advisor, Open Source Software Institute: www.oss-institute.org OpenSSL Core team: www.openssl.org
Re: Fwd: [us...@httpd] SSLRequire UTF-8 characters
On 20.11.2010 20:24, Stefan Fritsch wrote: On Fri, 19 Nov 2010, Joe Orton wrote: We could support this better by having a new set of exports: SSL_{CLIENT,SERVER}_{I,S}_UTF8DN_*(_n)? (or something similarly named) which works the same as _DN_ but exports the attributes as a UTF-8 byte seequence regardless of the underlying ASN.1 type; this would be a relatively simple hack. Or have a (per vhost) directive that enables conversion for all SSL_*_S_DN_* and SSL_*_S_DN to UTF8. IMHO, this could even be enabled by default in 2.4. I prefer the latter approach, yes (there's already an awful lot of SSL_* something variables). Given the fact that mod_ssl's current behavior with non-ASCII characters (i.e., outside the 0-127 range) is mostly undefined and/or sometimes even erroneous (a BMPString in the subject or issuer DN will end up as an empty SSL_*_*_DN_* variable, due to the initial null byte), I would suggest the following solution: - for all SSL_{CLIENT,SERVER}_{I,S}_DN_* variables, use UTF-8 by default (i.e., adapt ssl_engine_vars.c:ssl_var_lookup_ssl_cert_dn() to convert TeletexString, UniversalString and BMPString types to UTF8String) - for SSL_{CLIENT,SERVER}_{I,S}_DN, don't use X509_NAME_oneline() any more and switch to X509_NAME_print_ex() instead. What flags should be used is probably debatable - I would recommend to go with XN_FLAG_RFC2253 (note that using XN_FLAG_ONELINE with X509_NAME_print_ex doesn't produce the same string as X509_NAME_oneline, so this will break backward compatibility in any case) - add another parameter to the SSLOptions directive which allows re-enabling the old string rendering for SSL_{CLIENT,SERVER}_{I,S}_DN (so the new default would be to rely on X509_NAME_print_ex - even for 2.2 -, but people could restore the current behavior through this option) Kaspar
Re: Fwd: [us...@httpd] SSLRequire UTF-8 characters
On Fri, 19 Nov 2010, Joe Orton wrote: On Fri, Nov 19, 2010 at 07:13:01AM +0100, Kaspar Brand wrote: On 17.11.2010 15:53, Igor Galić wrote: it might be appropriate to ping dev@ with this problem I'm not sure if it's a bug or a feature. I'd call it a missing feature... the problem is that mod_ssl treats all values of any DN attribute (subject or issuer) as a sequence of 8-bit characters. Worth noting that the handling of SSL_*_S_DN is different to the handling of the individual attributes, SSL_*_S_DN_* - the _DN string is rendered as an escaped string whereas the attributes are exported as a sequence of raw bytes. That is all kind of messy (not to mention undocumented)... - Myles Bunbury (Myles) myles.bunb...@alcatel-lucent.com wrote: After some investigation, I discovered that this line does successfully pick up the certificate: SSLRequire (%{SSL_CLIENT_S_DN} =~ m#^/.*CN= \\x1C\\x00W\\x00e\\x00i\\x00r\\x00d \\x1d\\...@\\x00\\xbf\\x063\\x01\\xfd \\xAC\\x00.\\x00c\\x00o\\x00m.*$#i) We could support this better by having a new set of exports: SSL_{CLIENT,SERVER}_{I,S}_UTF8DN_*(_n)? (or something similarly named) which works the same as _DN_ but exports the attributes as a UTF-8 byte seequence regardless of the underlying ASN.1 type; this would be a relatively simple hack. Or have a (per vhost) directive that enables conversion for all SSL_*_S_DN_* and SSL_*_S_DN to UTF8. IMHO, this could even be enabled by default in 2.4.
Re: Fwd: [us...@httpd] SSLRequire UTF-8 characters
On Fri, Nov 19, 2010 at 07:13:01AM +0100, Kaspar Brand wrote: On 17.11.2010 15:53, Igor Galić wrote: it might be appropriate to ping dev@ with this problem I'm not sure if it's a bug or a feature. I'd call it a missing feature... the problem is that mod_ssl treats all values of any DN attribute (subject or issuer) as a sequence of 8-bit characters. Worth noting that the handling of SSL_*_S_DN is different to the handling of the individual attributes, SSL_*_S_DN_* - the _DN string is rendered as an escaped string whereas the attributes are exported as a sequence of raw bytes. That is all kind of messy (not to mention undocumented)... - Myles Bunbury (Myles) myles.bunb...@alcatel-lucent.com wrote: After some investigation, I discovered that this line does successfully pick up the certificate: SSLRequire (%{SSL_CLIENT_S_DN} =~ m#^/.*CN= \\x1C\\x00W\\x00e\\x00i\\x00r\\x00d \\x1d\\...@\\x00\\xbf\\x063\\x01\\xfd \\xAC\\x00.\\x00c\\x00o\\x00m.*$#i) We could support this better by having a new set of exports: SSL_{CLIENT,SERVER}_{I,S}_UTF8DN_*(_n)? (or something similarly named) which works the same as _DN_ but exports the attributes as a UTF-8 byte seequence regardless of the underlying ASN.1 type; this would be a relatively simple hack. Regards, Joe
Re: Fwd: [us...@httpd] SSLRequire UTF-8 characters
On 17.11.2010 15:53, Igor Galić wrote: it might be appropriate to ping dev@ with this problem I'm not sure if it's a bug or a feature. I'd call it a missing feature... the problem is that mod_ssl treats all values of any DN attribute (subject or issuer) as a sequence of 8-bit characters. - Myles Bunbury (Myles) myles.bunb...@alcatel-lucent.com wrote: After some investigation, I discovered that this line does successfully pick up the certificate: SSLRequire (%{SSL_CLIENT_S_DN} =~ m#^/.*CN= \\x1C\\x00W\\x00e\\x00i\\x00r\\x00d \\x1d\\...@\\x00\\xbf\\x063\\x01\\xfd \\xAC\\x00.\\x00c\\x00o\\x00m.*$#i) While that works for this particular case, I'm trying to develop something where the regex string will be constructed based on an arbitrary certificate supplied at runtime. Questions: 1) Is it possible to configure httpd to match UTF-8 characters without all the escaping? It depends on whether that CN attribute is really encoded as an ASN.1 UTF8String. The form quoted above actually suggests that it is a BMPString instead (aka UTF-16BE), which aways uses two octets to encode a character - also for those in the 0-255 range (ASCII, ISO-8859-x). That's the reason why there are quite a few \\x00's in your expression. In theory, you could try inserting literal null bytes into the httpd config file, but I'm not sure if mod_ssl (or the parser for SSLRequire, more specifically) would be able to handle them properly. 2) If all the \\x escaping is necessary, why are there 3 spaces in the escaped string when they're not present in the certificate? (One space is after CN=, one after \\x00d, and one after \\xFD.) Because that's how the following characters are encoded in UTF-16: “ U+201C ” U+201D € U+20AC (cf. http://www.unicode.org/charts/PDF/U2000.pdf, 0x20 is SPACE) Kaspar
Fwd: [us...@httpd] SSLRequire UTF-8 characters
Hi Myles, it might be appropriate to ping dev@ with this problem I'm not sure if it's a bug or a feature. So long, i - Myles Bunbury (Myles) myles.bunb...@alcatel-lucent.com wrote: Which version of OpenSSL do you have? openssl-0.9.8e-12.el5_4.6 xmlsec1-openssl-1.2.9-8.1.1 What locale is your system running on? $LANG = en_US.UTF-8 - Forwarded Message - From: Myles Bunbury (Myles) myles.bunb...@alcatel-lucent.com To: us...@httpd.apache.org Sent: Thursday, 11 November, 2010 9:33:37 PM Subject: [us...@httpd] SSLRequire UTF-8 characters I'm trying to setup a DN filter against a certificate that has UTF-8 characters in it. The Subject DN for the incoming certificate is: C=CA,ST=Province,L=City,O=Company,OU=Unit,cn=“weird...@¿سǽ€.com The filter I'm trying to use in the httpd configuration file is: SSLRequire (%{SSL_CLIENT_S_DN} =~ m#^/.*cn=“weird...@¿سǽ€.*$#i) This pattern does work for me for other certificates that do not contain UTF-* characters. After some investigation, I discovered that this line does successfully pick up the certificate: SSLRequire (%{SSL_CLIENT_S_DN} =~ m#^/.*CN= \\x1C\\x00W\\x00e\\x00i\\x00r\\x00d \\x1d\\...@\\x00\\xbf\\x063\\x01\\xfd \\xAC\\x00.\\x00c\\x00o\\x00m.*$#i) While that works for this particular case, I'm trying to develop something where the regex string will be constructed based on an arbitrary certificate supplied at runtime. Questions: 1) Is it possible to configure httpd to match UTF-8 characters without all the escaping? 2) If all the \\x escaping is necessary, why are there 3 spaces in the escaped string when they're not present in the certificate? (One space is after CN=, one after \\x00d, and one after \\xFD.) Other relevant info: Apache httpd v2.2.16 PCRE v6.6-2.el5_1.7 I also tried PCRE v8.10, but I did not note any change in behaviour. -- Igor Galić Tel: +43 (0) 664 886 22 883 Mail: i.ga...@brainsware.org URL: http://brainsware.org/