Joe Orton wrote:
>> the OpenSSL client (SNI extensions should never contain literal IPv4
>> addresses).
> 
> Good point - I've changed neon for future releases to only enable SNI if 
> the hostname is not a numeric IP address.

This logic should go into OpenSSL, I think... I know that this is
httpd-dev (not openssl-dev), but since Steve is listening anyway:
something like the attached patch? For the client side (i.e. in
ssl3_ctrl()), depending on how schoolmasterish OpenSSL should be towards
its users, the check could also be moved further down / be rejected with
INVALID_SERVERNAME.

Kaspar
Index: ssl/s3_lib.c
===================================================================
RCS file: /openssl-cvs/openssl/ssl/s3_lib.c,v
retrieving revision 1.130
diff -p -U 8 -r1.130 s3_lib.c
--- ssl/s3_lib.c        16 Oct 2009 15:24:07 -0000      1.130
+++ ssl/s3_lib.c        25 Oct 2009 16:04:06 -0000
@@ -148,16 +148,17 @@
  * OTHERWISE.
  */
 
 #include <stdio.h>
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 #include "kssl_lcl.h"
 #ifndef OPENSSL_NO_TLSEXT
+#include <openssl/x509v3.h>
 #ifndef OPENSSL_NO_EC
 #include "../crypto/ec/ec_lcl.h"
 #endif /* OPENSSL_NO_EC */
 #endif /* OPENSSL_NO_TLSEXT */
 #include <openssl/md5.h>
 #ifndef OPENSSL_NO_DH
 #include <openssl/dh.h>
 #endif
@@ -2382,22 +2383,25 @@ long ssl3_ctrl(SSL *s, int cmd, long lar
                return(ret);
                }
                break;
 #endif /* !OPENSSL_NO_ECDH */
 #ifndef OPENSSL_NO_TLSEXT
        case SSL_CTRL_SET_TLSEXT_HOSTNAME:
                if (larg == TLSEXT_NAMETYPE_host_name)
                        {
+                       unsigned char tmp[16];
                        if (s->tlsext_hostname != NULL) 
                                OPENSSL_free(s->tlsext_hostname);
                        s->tlsext_hostname = NULL;
 
                        ret = 1;
-                       if (parg == NULL) 
+                       if (parg == NULL ||
+                           /* silently ignore literal IP addresses */
+                           a2i_ipadd(tmp, (const char *)parg))
                                break;
                        if (strlen((char *)parg) > TLSEXT_MAXLEN_host_name)
                                {
                                SSLerr(SSL_F_SSL3_CTRL, 
SSL_R_SSL3_EXT_INVALID_SERVERNAME);
                                return 0;
                                }
                        if ((s->tlsext_hostname = BUF_strdup((char *)parg)) == 
NULL)
                                {
Index: ssl/t1_lib.c
===================================================================
RCS file: /openssl-cvs/openssl/ssl/t1_lib.c,v
retrieving revision 1.66
diff -p -U 8 -r1.66 t1_lib.c
--- ssl/t1_lib.c        4 Sep 2009 17:42:53 -0000       1.66
+++ ssl/t1_lib.c        25 Oct 2009 12:32:39 -0000
@@ -109,16 +109,19 @@
  *
  */
 
 #include <stdio.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
 #include <openssl/ocsp.h>
+#ifndef OPENSSL_NO_TLSEXT
+#include <openssl/x509v3.h>
+#endif
 #include "ssl_locl.h"
 
 const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT;
 
 #ifndef OPENSSL_NO_TLSEXT
 static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
                                const unsigned char *sess_id, int sesslen,
                                SSL_SESSION **psess);
@@ -618,16 +621,17 @@ int ssl_parse_clienthello_tlsext(SSL *s,
      i.e. when the session has been established with a servername extension. 
    - On session reconnect, the servername extension may be absent. 
 
 */      
 
                if (type == TLSEXT_TYPE_server_name)
                        {
                        unsigned char *sdata;
+                       unsigned char tmp[16];
                        int servname_type;
                        int dsize; 
                
                        if (size < 2) 
                                {
                                *al = SSL_AD_DECODE_ERROR;
                                return 0;
                                }
@@ -650,16 +654,22 @@ int ssl_parse_clienthello_tlsext(SSL *s,
                                        {
                                        *al = SSL_AD_DECODE_ERROR;
                                        return 0;
                                        }
                                if (s->servername_done == 0)
                                switch (servname_type)
                                        {
                                case TLSEXT_NAMETYPE_host_name:
+                                       if (a2i_ipadd(tmp, (const char *)sdata))
+                                               {
+                                               /* literal IP addresses are not 
permitted */
+                                               *al = SSL3_AD_ILLEGAL_PARAMETER;
+                                               return 0;
+                                               }
                                        if (s->session->tlsext_hostname == NULL)
                                                {
                                                if (len > 
TLSEXT_MAXLEN_host_name || 
                                                        
((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL))
                                                        {
                                                        *al = 
TLS1_AD_UNRECOGNIZED_NAME;
                                                        return 0;
                                                        }

Reply via email to