Re: Fwd: [us...@httpd] SSLRequire UTF-8 characters

2010-12-22 Thread Kaspar Brand
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

2010-12-20 Thread Stefan Fritsch
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

2010-12-19 Thread Stefan Fritsch
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

2010-12-19 Thread Kaspar Brand
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

2010-12-18 Thread Stefan Fritsch
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

2010-11-29 Thread Dr Stephen Henson
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

2010-11-23 Thread Kaspar Brand
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

2010-11-20 Thread Stefan Fritsch

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

2010-11-19 Thread Joe Orton
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

2010-11-18 Thread Kaspar Brand
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

2010-11-17 Thread Igor Galić


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/