Further TLS extension updates
Submitted by: Peter Sylvester
This commit is contained in:
parent
db6251ad54
commit
a13c20f603
4
CHANGES
4
CHANGES
@ -25,8 +25,6 @@
|
|||||||
SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG
|
SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG
|
||||||
- SSL_CTX_set_tlsext_servername_arg()
|
- SSL_CTX_set_tlsext_servername_arg()
|
||||||
SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_hostname()
|
SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_hostname()
|
||||||
SSL_CTRL_SET_TLSEXT_SERVERNAME_DONE
|
|
||||||
- SSL_set_tlsext_servername_done()
|
|
||||||
|
|
||||||
openssl s_client has a new '-servername' option.
|
openssl s_client has a new '-servername' option.
|
||||||
|
|
||||||
@ -34,6 +32,8 @@
|
|||||||
(subject to change); this allows testing the HostName extension for a
|
(subject to change); this allows testing the HostName extension for a
|
||||||
specific single host name ('-cert' and '-key' remain fallbacks for
|
specific single host name ('-cert' and '-key' remain fallbacks for
|
||||||
handshakes without HostName negotiation).
|
handshakes without HostName negotiation).
|
||||||
|
The option servername_warn allows to return a warning alert instead of
|
||||||
|
a fatal alert in case of servername mismatch.
|
||||||
|
|
||||||
[Peter Sylvester, Remy Allais, Christophe Renou]
|
[Peter Sylvester, Remy Allais, Christophe Renou]
|
||||||
|
|
||||||
|
@ -647,7 +647,7 @@ bad:
|
|||||||
#ifndef OPENSSL_NO_TLSEXT
|
#ifndef OPENSSL_NO_TLSEXT
|
||||||
if (servername != NULL)
|
if (servername != NULL)
|
||||||
{
|
{
|
||||||
if (!SSL_set_tlsext_hostname(con,servername))
|
if (!SSL_set_tlsext_host_name(con,servername))
|
||||||
{
|
{
|
||||||
BIO_printf(bio_err,"Unable to set TLS servername extension.\n");
|
BIO_printf(bio_err,"Unable to set TLS servername extension.\n");
|
||||||
ERR_print_errors(bio_err);
|
ERR_print_errors(bio_err);
|
||||||
|
@ -367,6 +367,7 @@ static void sv_usage(void)
|
|||||||
BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
|
BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
|
||||||
#ifndef OPENSSL_NO_TLSEXT
|
#ifndef OPENSSL_NO_TLSEXT
|
||||||
BIO_printf(bio_err," -servername host - servername for HostName TLS extension\n");
|
BIO_printf(bio_err," -servername host - servername for HostName TLS extension\n");
|
||||||
|
BIO_printf(bio_err," -servername_warn - on mismatch send warning (default fatal alert)\n");
|
||||||
BIO_printf(bio_err," -cert2 arg - certificate file to use for servername\n");
|
BIO_printf(bio_err," -cert2 arg - certificate file to use for servername\n");
|
||||||
BIO_printf(bio_err," (default is %s)\n",TEST_CERT2);
|
BIO_printf(bio_err," (default is %s)\n",TEST_CERT2);
|
||||||
BIO_printf(bio_err," -key2 arg - Private Key file to use for servername, in cert file if\n");
|
BIO_printf(bio_err," -key2 arg - Private Key file to use for servername, in cert file if\n");
|
||||||
@ -533,6 +534,7 @@ static int ebcdic_puts(BIO *bp, const char *str)
|
|||||||
typedef struct tlsextctx_st {
|
typedef struct tlsextctx_st {
|
||||||
char * servername;
|
char * servername;
|
||||||
BIO * biodebug;
|
BIO * biodebug;
|
||||||
|
int servername_warn;
|
||||||
} tlsextctx;
|
} tlsextctx;
|
||||||
|
|
||||||
|
|
||||||
@ -544,18 +546,16 @@ static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
|
|||||||
BIO_printf(p->biodebug,"Hostname in TLS extension: \"%s\"\n",servername);
|
BIO_printf(p->biodebug,"Hostname in TLS extension: \"%s\"\n",servername);
|
||||||
|
|
||||||
if (!p->servername)
|
if (!p->servername)
|
||||||
{
|
|
||||||
SSL_set_tlsext_servername_done(s,2);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
if (servername)
|
if (servername)
|
||||||
{
|
{
|
||||||
if (strcmp(servername,p->servername))
|
if (strcmp(servername,p->servername))
|
||||||
return 0;
|
return p->servername_warn;
|
||||||
if (ctx2)
|
if (ctx2) {
|
||||||
|
BIO_printf(p->biodebug,"Swiching server context.\n");
|
||||||
SSL_set_SSL_CTX(s,ctx2);
|
SSL_set_SSL_CTX(s,ctx2);
|
||||||
SSL_set_tlsext_servername_done(s,1);
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -597,7 +597,7 @@ int MAIN(int argc, char *argv[])
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_TLSEXT
|
#ifndef OPENSSL_NO_TLSEXT
|
||||||
tlsextctx tlsextcbp = {NULL, NULL};
|
tlsextctx tlsextcbp = {NULL, NULL, -1};
|
||||||
#endif
|
#endif
|
||||||
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
|
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
|
||||||
meth=SSLv23_server_method();
|
meth=SSLv23_server_method();
|
||||||
@ -846,6 +846,8 @@ int MAIN(int argc, char *argv[])
|
|||||||
if (--argc < 1) goto bad;
|
if (--argc < 1) goto bad;
|
||||||
tlsextcbp.servername= *(++argv);
|
tlsextcbp.servername= *(++argv);
|
||||||
}
|
}
|
||||||
|
else if (strcmp(*argv,"-servername_warn") == 0)
|
||||||
|
{ tlsextcbp.servername_warn = 0; }
|
||||||
else if (strcmp(*argv,"-cert2") == 0)
|
else if (strcmp(*argv,"-cert2") == 0)
|
||||||
{
|
{
|
||||||
if (--argc < 1) goto bad;
|
if (--argc < 1) goto bad;
|
||||||
@ -1553,6 +1555,7 @@ static int sv_body(char *hostname, int s, unsigned char *context)
|
|||||||
ret= -11;*/
|
ret= -11;*/
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((buf[0] == 'r') &&
|
if ((buf[0] == 'r') &&
|
||||||
((buf[1] == '\n') || (buf[1] == '\r')))
|
((buf[1] == '\n') || (buf[1] == '\r')))
|
||||||
{
|
{
|
||||||
|
@ -131,7 +131,6 @@ static ERR_STRING_DATA EC_str_functs[]=
|
|||||||
{ERR_FUNC(EC_F_EC_GROUP_GET_ORDER), "EC_GROUP_get_order"},
|
{ERR_FUNC(EC_F_EC_GROUP_GET_ORDER), "EC_GROUP_get_order"},
|
||||||
{ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS), "EC_GROUP_get_pentanomial_basis"},
|
{ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS), "EC_GROUP_get_pentanomial_basis"},
|
||||||
{ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS), "EC_GROUP_get_trinomial_basis"},
|
{ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS), "EC_GROUP_get_trinomial_basis"},
|
||||||
{ERR_FUNC(EC_F_EC_GROUP_GROUP2NID), "EC_GROUP_GROUP2NID"},
|
|
||||||
{ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"},
|
{ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"},
|
||||||
{ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"},
|
{ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"},
|
||||||
{ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "EC_GROUP_NEW_FROM_DATA"},
|
{ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "EC_GROUP_NEW_FROM_DATA"},
|
||||||
|
@ -1654,7 +1654,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
|
|||||||
ret = 1;
|
ret = 1;
|
||||||
if (parg == NULL)
|
if (parg == NULL)
|
||||||
break;
|
break;
|
||||||
if (strlen((char *)parg) > 255)
|
if (strlen((char *)parg) > TLSEXT_MAXLEN_host_name)
|
||||||
{
|
{
|
||||||
SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME);
|
SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1672,9 +1672,6 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
|
|||||||
}
|
}
|
||||||
s->options |= SSL_OP_NO_SSLv2; /* can't use extension w/ SSL 2.0 format */
|
s->options |= SSL_OP_NO_SSLv2; /* can't use extension w/ SSL 2.0 format */
|
||||||
break;
|
break;
|
||||||
case SSL_CTRL_SET_TLSEXT_SERVERNAME_DONE:
|
|
||||||
s->servername_done = larg;
|
|
||||||
break;
|
|
||||||
#endif /* !OPENSSL_NO_TLSEXT */
|
#endif /* !OPENSSL_NO_TLSEXT */
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -283,14 +283,16 @@ int ssl3_accept(SSL *s)
|
|||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
#ifndef OPENSSL_NO_TLSEXT
|
#ifndef OPENSSL_NO_TLSEXT
|
||||||
{
|
{
|
||||||
int al;
|
int al,warn;
|
||||||
if (ssl_check_tlsext(s,&al) <= 0)
|
warn = ssl_check_tlsext(s,&al);
|
||||||
{
|
if (warn == 0)
|
||||||
ssl3_send_alert(s,SSL3_AL_FATAL,al); /* XXX does this *have* to be fatal? */
|
ssl3_send_alert(s,SSL3_AL_WARNING,al);
|
||||||
|
else if (warn < 0) {
|
||||||
|
ssl3_send_alert(s,SSL3_AL_FATAL,al);
|
||||||
SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_CLIENTHELLO_TLS_EXT);
|
SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_CLIENTHELLO_TLS_EXT);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
s->new_session = 2;
|
s->new_session = 2;
|
||||||
|
@ -994,6 +994,9 @@ struct ssl_st
|
|||||||
2 : don't call servername callback, no ack in server hello
|
2 : don't call servername callback, no ack in server hello
|
||||||
*/
|
*/
|
||||||
SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
|
SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
|
||||||
|
#define session_ctx initial_ctx
|
||||||
|
#else
|
||||||
|
#define session_ctx ctx
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1114,7 +1117,7 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
|
|||||||
PEM_ASN1_write_bio_of(SSL_SESSION,i2d_SSL_SESSION,PEM_STRING_SSL_SESSION,bp,x,NULL,NULL,0,NULL,NULL)
|
PEM_ASN1_write_bio_of(SSL_SESSION,i2d_SSL_SESSION,PEM_STRING_SSL_SESSION,bp,x,NULL,NULL,0,NULL,NULL)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SSL_AD_REASON_OFFSET 1000 /* offset to get SSL_R_... value from SSL_AD_... /
|
#define SSL_AD_REASON_OFFSET 1000 /* offset to get SSL_R_... value from SSL_AD_... */
|
||||||
|
|
||||||
/* These alert types are for SSLv3 and TLSv1 */
|
/* These alert types are for SSLv3 and TLSv1 */
|
||||||
#define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY
|
#define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY
|
||||||
@ -1206,12 +1209,11 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
|
|||||||
|
|
||||||
#define SSL_CTRL_SET_MAX_SEND_FRAGMENT 52
|
#define SSL_CTRL_SET_MAX_SEND_FRAGMENT 52
|
||||||
|
|
||||||
/* see tls.h for macros based on these */
|
/* see tls1.h for macros based on these */
|
||||||
#ifndef OPENSSL_NO_TLSEXT
|
#ifndef OPENSSL_NO_TLSEXT
|
||||||
#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53
|
#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53
|
||||||
#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54
|
#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54
|
||||||
#define SSL_CTRL_SET_TLSEXT_HOSTNAME 55
|
#define SSL_CTRL_SET_TLSEXT_HOSTNAME 55
|
||||||
#define SSL_CTRL_SET_TLSEXT_SERVERNAME_DONE 56
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SSL_session_reused(ssl) \
|
#define SSL_session_reused(ssl) \
|
||||||
|
@ -1332,15 +1332,15 @@ const char *SSL_get_servername(const SSL *s, const int type)
|
|||||||
{
|
{
|
||||||
if (type != TLSEXT_NAMETYPE_host_name)
|
if (type != TLSEXT_NAMETYPE_host_name)
|
||||||
return NULL;
|
return NULL;
|
||||||
/* XXX cf. SSL_CTRL_GET_TLSEXT_HOSTNAME case in ssl3_ctrl (s3_lib.c) */
|
|
||||||
return s->session /*&&s->session->tlsext_hostname*/ ?
|
return s->session && !s->tlsext_hostname ?
|
||||||
s->session->tlsext_hostname :
|
s->session->tlsext_hostname :
|
||||||
s->tlsext_hostname;
|
s->tlsext_hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SSL_get_servername_type(const SSL *s)
|
int SSL_get_servername_type(const SSL *s)
|
||||||
{
|
{
|
||||||
if (s->session &&s->session->tlsext_hostname ? s->session->tlsext_hostname : s->tlsext_hostname)
|
if (s->session && (!s->tlsext_hostname ? s->session->tlsext_hostname : s->tlsext_hostname))
|
||||||
return TLSEXT_NAMETYPE_host_name;
|
return TLSEXT_NAMETYPE_host_name;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1930,14 +1930,14 @@ void ssl_update_cache(SSL *s,int mode)
|
|||||||
* and it would be rather hard to do anyway :-) */
|
* and it would be rather hard to do anyway :-) */
|
||||||
if (s->session->session_id_length == 0) return;
|
if (s->session->session_id_length == 0) return;
|
||||||
|
|
||||||
i=s->ctx->session_cache_mode;
|
i=s->session_ctx->session_cache_mode;
|
||||||
if ((i & mode) && (!s->hit)
|
if ((i & mode) && (!s->hit)
|
||||||
&& ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE)
|
&& ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE)
|
||||||
|| SSL_CTX_add_session(s->ctx,s->session))
|
|| SSL_CTX_add_session(s->session_ctx,s->session))
|
||||||
&& (s->ctx->new_session_cb != NULL))
|
&& (s->session_ctx->new_session_cb != NULL))
|
||||||
{
|
{
|
||||||
CRYPTO_add(&s->session->references,1,CRYPTO_LOCK_SSL_SESSION);
|
CRYPTO_add(&s->session->references,1,CRYPTO_LOCK_SSL_SESSION);
|
||||||
if (!s->ctx->new_session_cb(s,s->session))
|
if (!s->session_ctx->new_session_cb(s,s->session))
|
||||||
SSL_SESSION_free(s->session);
|
SSL_SESSION_free(s->session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1946,10 +1946,10 @@ void ssl_update_cache(SSL *s,int mode)
|
|||||||
((i & mode) == mode))
|
((i & mode) == mode))
|
||||||
{
|
{
|
||||||
if ( (((mode & SSL_SESS_CACHE_CLIENT)
|
if ( (((mode & SSL_SESS_CACHE_CLIENT)
|
||||||
?s->ctx->stats.sess_connect_good
|
?s->session_ctx->stats.sess_connect_good
|
||||||
:s->ctx->stats.sess_accept_good) & 0xff) == 0xff)
|
:s->session_ctx->stats.sess_accept_good) & 0xff) == 0xff)
|
||||||
{
|
{
|
||||||
SSL_CTX_flush_sessions(s->ctx,(unsigned long)time(NULL));
|
SSL_CTX_flush_sessions(s->session_ctx,(unsigned long)time(NULL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2452,6 +2452,10 @@ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl)
|
|||||||
|
|
||||||
SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx)
|
SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx)
|
||||||
{
|
{
|
||||||
|
if (ssl->ctx == ctx)
|
||||||
|
return ssl->ctx;
|
||||||
|
if (ctx == NULL)
|
||||||
|
ctx = ssl->initial_ctx;
|
||||||
if (ssl->cert != NULL)
|
if (ssl->cert != NULL)
|
||||||
ssl_cert_free(ssl->cert);
|
ssl_cert_free(ssl->cert);
|
||||||
ssl->cert = ssl_cert_dup(ctx->cert);
|
ssl->cert = ssl_cert_dup(ctx->cert);
|
||||||
|
@ -114,12 +114,6 @@
|
|||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
#include "ssl_locl.h"
|
#include "ssl_locl.h"
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_TLSEXT
|
|
||||||
#define session_ctx initial_ctx
|
|
||||||
#else
|
|
||||||
#define session_ctx ctx
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
|
static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
|
||||||
static void SSL_SESSION_list_add(SSL_CTX *ctx,SSL_SESSION *s);
|
static void SSL_SESSION_list_add(SSL_CTX *ctx,SSL_SESSION *s);
|
||||||
static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
|
static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
|
||||||
@ -242,7 +236,7 @@ int ssl_get_new_session(SSL *s, int session)
|
|||||||
if (s->session_ctx->session_timeout == 0)
|
if (s->session_ctx->session_timeout == 0)
|
||||||
ss->timeout=SSL_get_default_timeout(s);
|
ss->timeout=SSL_get_default_timeout(s);
|
||||||
else
|
else
|
||||||
ss->timeout=s->ctx->session_timeout;
|
ss->timeout=s->session_ctx->session_timeout;
|
||||||
|
|
||||||
if (s->session != NULL)
|
if (s->session != NULL)
|
||||||
{
|
{
|
||||||
@ -319,6 +313,16 @@ int ssl_get_new_session(SSL *s, int session)
|
|||||||
SSL_SESSION_free(ss);
|
SSL_SESSION_free(ss);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
#ifndef OPENSSL_NO_TLSEXT
|
||||||
|
if (s->tlsext_hostname) {
|
||||||
|
ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
|
||||||
|
if (ss->tlsext_hostname == NULL) {
|
||||||
|
SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR);
|
||||||
|
SSL_SESSION_free(ss);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
64
ssl/t1_lib.c
64
ssl/t1_lib.c
@ -193,15 +193,11 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
|||||||
{
|
{
|
||||||
int extdatalen=0;
|
int extdatalen=0;
|
||||||
unsigned char *ret = p;
|
unsigned char *ret = p;
|
||||||
if (s->hit || s->servername_done == 2)
|
|
||||||
return p;
|
|
||||||
ret+=2;
|
|
||||||
if (s->servername_done == 1)
|
|
||||||
s->servername_done = 2;
|
|
||||||
|
|
||||||
|
ret+=2;
|
||||||
if (ret>=limit) return NULL; /* this really never occurs, but ... */
|
if (ret>=limit) return NULL; /* this really never occurs, but ... */
|
||||||
|
|
||||||
if (s->session->tlsext_hostname != NULL)
|
if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL)
|
||||||
{
|
{
|
||||||
if (limit - p - 4 < 0) return NULL;
|
if (limit - p - 4 < 0) return NULL;
|
||||||
|
|
||||||
@ -222,6 +218,10 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
|
|||||||
unsigned short size;
|
unsigned short size;
|
||||||
unsigned short len;
|
unsigned short len;
|
||||||
unsigned char *data = *p;
|
unsigned char *data = *p;
|
||||||
|
#if 0
|
||||||
|
fprintf(stderr,"ssl_parse_clienthello_tlsext %s\n",s->session->tlsext_hostname?s->session->tlsext_hostname:"NULL");
|
||||||
|
#endif
|
||||||
|
s->servername_done = 0;
|
||||||
|
|
||||||
if (data >= (d+n-2))
|
if (data >= (d+n-2))
|
||||||
return 1;
|
return 1;
|
||||||
@ -238,6 +238,29 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
|
|||||||
if (data+size > (d+n))
|
if (data+size > (d+n))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
/* The servername extension is treated as follows:
|
||||||
|
|
||||||
|
- Only the hostname type is supported with a maximum length of 255.
|
||||||
|
- The servername is rejected if too long or if it contains zeros,
|
||||||
|
in which case an fatal alert is generated.
|
||||||
|
- The servername field is maintained together with the session cache.
|
||||||
|
- When a session is resumed, the servername call back invoked in order
|
||||||
|
to allow the application to position itself to the right context.
|
||||||
|
- The servername is acknowledged if it is new for a session or when
|
||||||
|
it is identical to a previously used for the same session.
|
||||||
|
Applications can control the behaviour. They can at any time
|
||||||
|
set a 'desirable' servername for a new SSL object. This can be the
|
||||||
|
case for example with HTTPS when a Host: header field is received and
|
||||||
|
a renegotiation is requested. In this case, a possible servername
|
||||||
|
presented in the new client hello is only acknowledged if it matches
|
||||||
|
the value of the Host: field.
|
||||||
|
- Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
|
||||||
|
if they provide for changing an explicit servername context for the session,
|
||||||
|
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)
|
if (type == TLSEXT_TYPE_server_name)
|
||||||
{
|
{
|
||||||
unsigned char *sdata = data;
|
unsigned char *sdata = data;
|
||||||
@ -259,16 +282,29 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
|
|||||||
case TLSEXT_NAMETYPE_host_name:
|
case TLSEXT_NAMETYPE_host_name:
|
||||||
if (s->session->tlsext_hostname == NULL)
|
if (s->session->tlsext_hostname == NULL)
|
||||||
{
|
{
|
||||||
if (len > 255 ||
|
if (len > TLSEXT_MAXLEN_host_name ||
|
||||||
((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL))
|
((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL))
|
||||||
{
|
{
|
||||||
*al = TLS1_AD_UNRECOGNIZED_NAME;
|
*al = TLS1_AD_UNRECOGNIZED_NAME;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(s->session->tlsext_hostname, sdata, len);
|
memcpy(s->session->tlsext_hostname, sdata, len);
|
||||||
s->session->tlsext_hostname[len]='\0';
|
s->session->tlsext_hostname[len]='\0';
|
||||||
|
if (strlen(s->session->tlsext_hostname) != len) {
|
||||||
|
OPENSSL_free(s->session->tlsext_hostname);
|
||||||
|
*al = TLS1_AD_UNRECOGNIZED_NAME;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
s->servername_done = 1;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_hostname %s\n",s->session->tlsext_hostname);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s->servername_done = strlen(s->session->tlsext_hostname) == len
|
||||||
|
&& strncmp(s->session->tlsext_hostname,sdata, len) == 0;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -356,14 +392,18 @@ int ssl_check_tlsext(SSL *s,int *al)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
*al = SSL_AD_UNRECOGNIZED_NAME;
|
*al = SSL_AD_UNRECOGNIZED_NAME;
|
||||||
if (s->servername_done == 0 && (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0))
|
if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
|
||||||
{
|
{
|
||||||
ret = s->ctx->tlsext_servername_callback(s, al, s->ctx->tlsext_servername_arg);
|
ret = s->ctx->tlsext_servername_callback(s, al, s->ctx->tlsext_servername_arg);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (s->servername_done == 1)
|
else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0)
|
||||||
s->servername_done = 2;
|
{
|
||||||
|
ret = s->initial_ctx->tlsext_servername_callback(s, al, s->initial_ctx->tlsext_servername_arg);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -170,10 +170,12 @@ extern "C" {
|
|||||||
|
|
||||||
#ifndef OPENSSL_NO_TLSEXT
|
#ifndef OPENSSL_NO_TLSEXT
|
||||||
|
|
||||||
|
#define TLSEXT_MAXLEN_host_name 255
|
||||||
|
|
||||||
const char *SSL_get_servername(const SSL *s, const int type) ;
|
const char *SSL_get_servername(const SSL *s, const int type) ;
|
||||||
int SSL_get_servername_type(const SSL *s) ;
|
int SSL_get_servername_type(const SSL *s) ;
|
||||||
|
|
||||||
#define SSL_set_tlsext_hostname(s,name) \
|
#define SSL_set_tlsext_host_name(s,name) \
|
||||||
SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name)
|
SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name)
|
||||||
|
|
||||||
#define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \
|
#define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user