cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: [PATCH] support for server name indication (RFC 4366)

From: Kaspar Brand <curl-lib.2008_at_velox.ch>
Date: Sat, 23 Feb 2008 10:01:34 +0100

Yang Tse wrote:
> 2008/2/14, Peter Sylvester wrote:
>
>> A question is whether it hurts to set the SNI extension by default. As
>> indicated in the RFC, it seems that there are no TLS server in the wild
>> that are heavily broken at that point, maybe an option --nosni would
>> be sufficient; --nosni would in fact also be active if ssl2 is not
>> disabled. I think starting disabling ssl2 by default is also a good thing
>> today.
>
> Yes and the option to disable it is also needed at this point just in
> case the library providing the actual client SNI implementation
> happens to have any strange quirk. After all it is still released with
> it disabled as default. ;-)

We're still trying to answer these questions initially posted to the
list by Guenter on 12 February, I think:

> - should it be enabled or disabled by default
> - if we disable SNI at runtime, should it be sparate for SNI only,
> or just for all TLS extensions?

I had another look at the three SSL/TLS toolkits currently supported for
libcurl, specifically their behavior when TLS extensions come into play.
For details see my findings below; based on them, my recommendation
would be:

1) enable TLS extensions by default

2) in the (lib)curl documentation, point out the fact that
   forcing SSLv3 allows to disable TLS extensions (except for OpenSSL,
   which should be fixed independently)

3) don't go into all sorts of contortions in order to allow tuning
   single TLS extensions (in some cases, you simply don't have the
   choice of turning off an extension - e.g for ECC)

As far as compatibility with "older" SSL/TLS toolkits is concerned, note
that the latest SSLv3 draft (published in Novemberr 1996) already stated:

> Forward compatibility note:
> In the interests of forward compatibility, it is
> permitted for a client hello message to include
> extra data after the compression methods. This data
> must be included in the handshake hashes, but must
> otherwise be ignored.

Working around buggy TLS toolkits (or even SSL, for that matter) is
clearly something outside the scope of libcurl, IMO. And I doubt it's a
real problem any more these days - take Firefox 2 as an example, it has
been sending out SNI extensions by default since its release in October
2006, and I'm not aware of major issues having occured due to this behavior.

Kaspar

TLS extension support in toolkits used by libcurl
-------------------------------------------------

(see also http://www.iana.org/assignments/tls-extensiontype-values
 for the official registry of TLS extensions)

OpenSSL (0.9.8g, if compiled with "enable-tlsext"):
- server_name
- SessionTicket TLS

OpenSSL adds extensions to the ClientHello as soon as SSLv2 is disabled,
i.e. even for SSLv3 (this should be changed in the toolkit itself, IMO).
The server_name extension can be "disabled" by not setting it initially,
while there's an explicit option (SSL_OP_NO_TICKET) that disables the
session ticket extension.

GnuTLS (2.2.2):
- server_name
- max_fragment_length
- cert_type
- srp

GnuTLS adds extensions to the ClientHello as soon as version is
>= TLS 1.0 (i.e. {3, 1} in the record header). Forcing SSLv3 *would*
disable all extensions, but setting CURL_SSLVERSION_SSLv3 is not handled
correctly in the current code. Patch for lib/gtls.c attached.

NSS (3.11.9):
- server_name
- if compiled with ECC support, additionally:
  . elliptic_curves
  . ec_point_formats

NSS adds extensions to the ClientHello for TLS versions >= 1.0 (similar
to GnuTLS). Forcing SSLv3 will disable all extensions.

Index: lib/gtls.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/gtls.c,v
retrieving revision 1.43
diff -u -p -r1.43 gtls.c
--- lib/gtls.c 20 Feb 2008 10:01:28 -0000 1.43
+++ lib/gtls.c 23 Feb 2008 08:12:22 -0000
@@ -233,7 +233,7 @@ Curl_gtls_connect(struct connectdata *co
   if(!gtls_inited)
     _Curl_gtls_init();
 
- /* GnuTLS only supports TLSv1 (and SSLv3?) */
+ /* GnuTLS only supports SSLv3 and TLSv1 */
   if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
     failf(data, "GnuTLS does not support SSLv2");
     return CURLE_SSL_CONNECT_ERROR;
@@ -280,6 +280,13 @@ Curl_gtls_connect(struct connectdata *co
   if(rc < 0)
     return CURLE_SSL_CONNECT_ERROR;
 
+ if(data->set.ssl.version == CURL_SSLVERSION_SSLv3) {
+ int protocol_priority[] = { GNUTLS_SSL3, 0 };
+ gnutls_protocol_set_priority(session, protocol_priority);
+ if(rc < 0)
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
   /* Sets the priority on the certificate types supported by gnutls. Priority
      is higher for types specified before others. After specifying the types
      you want, you must append a 0. */
Received on 2008-02-23