From: Bodo Möller Date: Wed, 11 Jan 2006 06:10:40 +0000 (+0000) Subject: More TLS extension related changes. X-Git-Tag: OpenSSL_0_9_8k^2~1593 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=241520e66d3ece1054beae93ff96978d0299cae4 More TLS extension related changes. Submitted by: Peter Sylvester --- diff --git a/CHANGES b/CHANGES index f4014aeefc..c3a7848930 100644 --- a/CHANGES +++ b/CHANGES @@ -26,14 +26,15 @@ - SSL_CTX_set_tlsext_servername_arg() SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_hostname() - openssl s_client has a new '-servername' option. - - openssl s_server has new options '-servername', '-cert2', and '-key2' - (subject to change); this allows testing the HostName extension for a - specific single host name ('-cert' and '-key' remain fallbacks for - handshakes without HostName negotiation). - The option servername_warn allows to return a warning alert instead of - a fatal alert in case of servername mismatch. + openssl s_client has a new '-servername ...' option. + + openssl s_server has new options '-servername_host ...', '-cert2 ...', + '-key2 ...', '-servername_fatal' (subject to change). This allows + testing the HostName extension for a specific single host name ('-cert' + and '-key' remain fallbacks for handshakes without HostName + negotiation). If the unrecogninzed_name alert has to be sent, this by + default is a warning; it becomes fatal with the '-servername_fatal' + option. [Peter Sylvester, Remy Allais, Christophe Renou] diff --git a/apps/s_cb.c b/apps/s_cb.c index 9a35d46adc..573f98cea6 100644 --- a/apps/s_cb.c +++ b/apps/s_cb.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -504,6 +504,21 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void * case 100: str_details2 = " no_renegotiation"; break; + case 110: + str_details2 = " unsupported_extension"; + break; + case 111: + str_details2 = " certificate_unobtainable"; + break; + case 112: + str_details2 = " unrecognized_name"; + break; + case 113: + str_details2 = " bad_certificate_status_response"; + break; + case 114: + str_details2 = " bad_certificate_hash_value"; + break; } } } diff --git a/apps/s_client.c b/apps/s_client.c index 47cd9d93d5..50e27a0732 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -245,7 +245,7 @@ static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg) else BIO_printf(bio_err,"Can't use SSL_get_servername\n"); - return 1; + return SSL_TLSEXT_ERR_OK; } #endif diff --git a/apps/s_server.c b/apps/s_server.c index e07f3dd20e..583bfccd5c 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -367,7 +367,7 @@ static void sv_usage(void) BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); #ifndef OPENSSL_NO_TLSEXT 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," -servername_fatal - on mismatch send fatal alert (default warning alert)\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," -key2 arg - Private Key file to use for servername, in cert file if\n"); @@ -534,7 +534,7 @@ static int ebcdic_puts(BIO *bp, const char *str) typedef struct tlsextctx_st { char * servername; BIO * biodebug; - int servername_warn; + int extension_error; } tlsextctx; @@ -546,18 +546,19 @@ static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg) BIO_printf(p->biodebug,"Hostname in TLS extension: \"%s\"\n",servername); if (!p->servername) - return 1; + return SSL_TLSEXT_ERR_NOACK; if (servername) { if (strcmp(servername,p->servername)) - return p->servername_warn; - if (ctx2) { + return p->extension_error; + if (ctx2) + { BIO_printf(p->biodebug,"Swiching server context.\n"); SSL_set_SSL_CTX(s,ctx2); } } - return 1; + return SSL_TLSEXT_ERR_OK; } #endif @@ -597,7 +598,7 @@ int MAIN(int argc, char *argv[]) #endif #ifndef OPENSSL_NO_TLSEXT - tlsextctx tlsextcbp = {NULL, NULL, -1}; + tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING}; #endif #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) meth=SSLv23_server_method(); @@ -846,8 +847,8 @@ int MAIN(int argc, char *argv[]) if (--argc < 1) goto bad; tlsextcbp.servername= *(++argv); } - else if (strcmp(*argv,"-servername_warn") == 0) - { tlsextcbp.servername_warn = 0; } + else if (strcmp(*argv,"-servername_fatal") == 0) + { tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL; } else if (strcmp(*argv,"-cert2") == 0) { if (--argc < 1) goto bad; diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c index 66ecbc7eed..ab291928a1 100644 --- a/ssl/s23_clnt.c +++ b/ssl/s23_clnt.c @@ -565,6 +565,7 @@ static int ssl23_get_server_hello(SSL *s) (p[5] == SSL3_MT_SERVER_HELLO)) { /* we have sslv3 or tls1 */ + have_sslv3_or_tls1: if (!ssl_init_wbio_buffer(s,1)) goto err; @@ -623,6 +624,9 @@ static int ssl23_get_server_hello(SSL *s) cb(s,SSL_CB_READ_ALERT,j); } + if (p[5] == SSL3_AL_WARNING) + goto have_sslv3_or_tls1; + s->rwstate=SSL_NOTHING; SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_AD_REASON_OFFSET+p[6]); goto err; diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 578285230d..d50f588b94 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -258,12 +258,19 @@ int ssl3_connect(SSL *s) #ifndef OPENSSL_NO_TLSEXT { int al; - if (ssl_check_tlsext(s,&al) <= 0) + switch (ssl_check_tlsext(s,&al)) { - ssl3_send_alert(s,SSL3_AL_FATAL,al); /* XXX does this *have* to be fatal? */ + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s,SSL3_AL_FATAL,al); SSLerr(SSL_F_SSL3_CONNECT,SSL_R_SERVERHELLO_TLS_EXT); ret = -1; goto end; + + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s,SSL3_AL_WARNING,al); + + default: + ; } } #endif diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index c83505c0a5..28d425a468 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -283,16 +283,21 @@ int ssl3_accept(SSL *s) if (ret <= 0) goto end; #ifndef OPENSSL_NO_TLSEXT { - int al,warn; - warn = ssl_check_tlsext(s,&al); - if (warn == 0) - ssl3_send_alert(s,SSL3_AL_WARNING,al); - else if (warn < 0) { + int al; + switch (ssl_check_tlsext(s,&al)) + { + case SSL_TLSEXT_ERR_ALERT_FATAL: ssl3_send_alert(s,SSL3_AL_FATAL,al); SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_CLIENTHELLO_TLS_EXT); ret = -1; goto end; - } + + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s,SSL3_AL_WARNING,al); + + default: + break; + } } #endif s->new_session = 2; diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index cea8b8e851..1aa5e90bbf 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -389,22 +389,17 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in int ssl_check_tlsext(SSL *s,int *al) { - int ret; + int ret=SSL_TLSEXT_ERR_NOACK; *al = SSL_AD_UNRECOGNIZED_NAME; - if (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); - if (ret <= 0) - return ret; - } - else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) - { + else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) ret = s->initial_ctx->tlsext_servername_callback(s, al, s->initial_ctx->tlsext_servername_arg); - if (ret <= 0) - return ret; - } - - return 1; + + if (ret == SSL_TLSEXT_ERR_NOACK) + s->servername_done=0; + return ret; } #endif diff --git a/ssl/tls1.h b/ssl/tls1.h index 8e56379963..0a9c1ea500 100644 --- a/ssl/tls1.h +++ b/ssl/tls1.h @@ -180,12 +180,15 @@ SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name) #define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \ SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb) + +#define SSL_TLSEXT_ERR_OK 0 +#define SSL_TLSEXT_ERR_ALERT_WARNING 1 +#define SSL_TLSEXT_ERR_ALERT_FATAL 2 +#define SSL_TLSEXT_ERR_NOACK 3 + #define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg) -#define SSL_set_tlsext_servername_done(s,t) \ -SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_SERVERNAME_DONE,t, NULL) - #endif