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; }