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