Fixes for TLS server_name extension
Submitted by: Peter Sylvester
This commit is contained in:
parent
e8e5b46e2b
commit
1aeb3da83f
11
CHANGES
11
CHANGES
@ -4,9 +4,13 @@
|
||||
|
||||
Changes between 0.9.8a and 0.9.9 [xx XXX xxxx]
|
||||
|
||||
*) Add support for TLS extensions, specifically for the HostName extension
|
||||
so far. The SSL_SESSION, SSL_CTX, and SSL data structures now have new
|
||||
members for HostName support.
|
||||
*) Add initial support for TLS extensions, specifically for the server_name
|
||||
extension so far. The SSL_SESSION, SSL_CTX, and SSL data structures now
|
||||
have new members for a host name. The SSL data structure has an
|
||||
additional member SSL_CTX *initial_ctx so that new sessions can be
|
||||
stored in that context to allow for session resumption, even after the
|
||||
SSL has been switched to a new SSL_CTX in reaction to a client's
|
||||
server_name extension.
|
||||
|
||||
New functions (subject to change):
|
||||
|
||||
@ -21,7 +25,6 @@
|
||||
SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG
|
||||
- SSL_CTX_set_tlsext_servername_arg()
|
||||
SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_hostname()
|
||||
SSL_CTRL_GET_TLSEXT_HOSTNAME [similar to SSL_get_servername()]
|
||||
SSL_CTRL_SET_TLSEXT_SERVERNAME_DONE
|
||||
- SSL_set_tlsext_servername_done()
|
||||
|
||||
|
@ -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 SSL_ERROR_NONE;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -540,24 +540,24 @@ static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
|
||||
{
|
||||
tlsextctx * p = (tlsextctx *) arg;
|
||||
const char * servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
|
||||
if (servername)
|
||||
if (servername && p->biodebug)
|
||||
BIO_printf(p->biodebug,"Hostname in TLS extension: \"%s\"\n",servername);
|
||||
|
||||
if (!p->servername)
|
||||
{
|
||||
SSL_set_tlsext_servername_done(s,2);
|
||||
return SSL_ERROR_NONE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (servername)
|
||||
{
|
||||
if (strcmp(servername,p->servername))
|
||||
return TLS1_AD_UNRECOGNIZED_NAME;
|
||||
return 0;
|
||||
if (ctx2)
|
||||
SSL_set_SSL_CTX(s,ctx2);
|
||||
SSL_set_tlsext_servername_done(s,1);
|
||||
}
|
||||
return SSL_ERROR_NONE;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -845,7 +845,6 @@ int MAIN(int argc, char *argv[])
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
tlsextcbp.servername= *(++argv);
|
||||
/* meth=TLSv1_server_method(); */
|
||||
}
|
||||
else if (strcmp(*argv,"-cert2") == 0)
|
||||
{
|
||||
|
13
ssl/s3_lib.c
13
ssl/s3_lib.c
@ -1644,19 +1644,6 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
|
||||
break;
|
||||
#endif /* !OPENSSL_NO_ECDH */
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
case SSL_CTRL_GET_TLSEXT_HOSTNAME:
|
||||
if (larg != TLSEXT_NAMETYPE_host_name)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE);
|
||||
return(0);
|
||||
}
|
||||
/* XXX cf. SSL_get_servername() (ssl_lib.c) */
|
||||
if (s->session && s->session->tlsext_hostname)
|
||||
*((char **) parg) = s->session->tlsext_hostname;
|
||||
else
|
||||
*((char **) parg) = s->tlsext_hostname;
|
||||
ret = 1;
|
||||
break;
|
||||
case SSL_CTRL_SET_TLSEXT_HOSTNAME:
|
||||
if (larg == TLSEXT_NAMETYPE_host_name)
|
||||
{
|
||||
|
@ -993,6 +993,7 @@ struct ssl_st
|
||||
1 : prepare 2, allow last ack just after in server callback.
|
||||
2 : don't call servername callback, no ack in server hello
|
||||
*/
|
||||
SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -1201,11 +1202,12 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
|
||||
#define SSL_CTRL_SET_MAX_SEND_FRAGMENT 52
|
||||
|
||||
/* see tls.h for macros based on these */
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53
|
||||
#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54
|
||||
#define SSL_CTRL_SET_TLSEXT_HOSTNAME 55
|
||||
#define SSL_CTRL_GET_TLSEXT_HOSTNAME 56
|
||||
#define SSL_CTRL_SET_TLSEXT_SERVERNAME_DONE 57
|
||||
#define SSL_CTRL_SET_TLSEXT_SERVERNAME_DONE 56
|
||||
#endif
|
||||
|
||||
#define SSL_session_reused(ssl) \
|
||||
SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL)
|
||||
|
@ -307,6 +307,10 @@ SSL *SSL_new(SSL_CTX *ctx)
|
||||
|
||||
CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
|
||||
s->ctx=ctx;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
|
||||
s->initial_ctx=ctx;
|
||||
#endif
|
||||
|
||||
s->verify_result=X509_V_OK;
|
||||
|
||||
@ -493,6 +497,9 @@ void SSL_free(SSL *s)
|
||||
/* Free up if allocated */
|
||||
|
||||
if (s->ctx) SSL_CTX_free(s->ctx);
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s->initial_ctx) SSL_CTX_free(s->initial_ctx);
|
||||
#endif
|
||||
|
||||
if (s->client_CA != NULL)
|
||||
sk_X509_NAME_pop_free(s->client_CA,X509_NAME_free);
|
||||
|
@ -114,6 +114,12 @@
|
||||
#include <openssl/rand.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_add(SSL_CTX *ctx,SSL_SESSION *s);
|
||||
static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
|
||||
@ -233,7 +239,7 @@ int ssl_get_new_session(SSL *s, int session)
|
||||
if ((ss=SSL_SESSION_new()) == NULL) return(0);
|
||||
|
||||
/* If the context has a default timeout, use it */
|
||||
if (s->ctx->session_timeout == 0)
|
||||
if (s->session_ctx->session_timeout == 0)
|
||||
ss->timeout=SSL_get_default_timeout(s);
|
||||
else
|
||||
ss->timeout=s->ctx->session_timeout;
|
||||
@ -276,8 +282,8 @@ int ssl_get_new_session(SSL *s, int session)
|
||||
CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
|
||||
if(s->generate_session_id)
|
||||
cb = s->generate_session_id;
|
||||
else if(s->ctx->generate_session_id)
|
||||
cb = s->ctx->generate_session_id;
|
||||
else if(s->session_ctx->generate_session_id)
|
||||
cb = s->session_ctx->generate_session_id;
|
||||
CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
|
||||
/* Choose a session ID */
|
||||
tmp = ss->session_id_length;
|
||||
@ -347,10 +353,10 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len)
|
||||
goto err;
|
||||
memcpy(data.session_id,session_id,len);
|
||||
|
||||
if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
|
||||
if (!(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
|
||||
{
|
||||
CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
|
||||
ret=(SSL_SESSION *)lh_retrieve(s->ctx->sessions,&data);
|
||||
ret=(SSL_SESSION *)lh_retrieve(s->session_ctx->sessions,&data);
|
||||
if (ret != NULL)
|
||||
/* don't allow other threads to steal it: */
|
||||
CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION);
|
||||
@ -361,13 +367,13 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len)
|
||||
{
|
||||
int copy=1;
|
||||
|
||||
s->ctx->stats.sess_miss++;
|
||||
s->session_ctx->stats.sess_miss++;
|
||||
ret=NULL;
|
||||
if (s->ctx->get_session_cb != NULL
|
||||
&& (ret=s->ctx->get_session_cb(s,session_id,len,©))
|
||||
if (s->session_ctx->get_session_cb != NULL
|
||||
&& (ret=s->session_ctx->get_session_cb(s,session_id,len,©))
|
||||
!= NULL)
|
||||
{
|
||||
s->ctx->stats.sess_cb_hit++;
|
||||
s->session_ctx->stats.sess_cb_hit++;
|
||||
|
||||
/* Increment reference count now if the session callback
|
||||
* asks us to do so (note that if the session structures
|
||||
@ -379,10 +385,10 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len)
|
||||
|
||||
/* Add the externally cached session to the internal
|
||||
* cache as well if and only if we are supposed to. */
|
||||
if(!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE))
|
||||
if(!(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE))
|
||||
/* The following should not return 1, otherwise,
|
||||
* things are very strange */
|
||||
SSL_CTX_add_session(s->ctx,ret);
|
||||
SSL_CTX_add_session(s->session_ctx,ret);
|
||||
}
|
||||
if (ret == NULL)
|
||||
goto err;
|
||||
@ -447,13 +453,13 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len)
|
||||
|
||||
if (ret->timeout < (long)(time(NULL) - ret->time)) /* timeout */
|
||||
{
|
||||
s->ctx->stats.sess_timeout++;
|
||||
s->session_ctx->stats.sess_timeout++;
|
||||
/* remove it from the cache */
|
||||
SSL_CTX_remove_session(s->ctx,ret);
|
||||
SSL_CTX_remove_session(s->session_ctx,ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
s->ctx->stats.sess_hit++;
|
||||
s->session_ctx->stats.sess_hit++;
|
||||
|
||||
/* ret->time=time(NULL); */ /* rezero timeout? */
|
||||
/* again, just leave the session
|
||||
|
16
ssl/tls1.h
16
ssl/tls1.h
@ -158,9 +158,6 @@ extern "C" {
|
||||
#define TLSEXT_TYPE_trusted_ca_keys 3
|
||||
#define TLSEXT_TYPE_truncated_hmac 4
|
||||
#define TLSEXT_TYPE_status_request 5
|
||||
#if 0
|
||||
#define TLSEXT_TYPE_srp 6
|
||||
#endif
|
||||
|
||||
/* NameType value from RFC 3546 */
|
||||
#define TLSEXT_NAMETYPE_host_name 0
|
||||
@ -181,19 +178,6 @@ 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)
|
||||
|
||||
#if 0
|
||||
# if 0
|
||||
|
||||
#define SSL_get_tlsext_hostname(s,psn) \
|
||||
SSL_ctrl(s,SSL_CTRL_GET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name, (void *)psn)
|
||||
# else
|
||||
/* XXX this looks weird for a macro, define a function instead? */
|
||||
* or just used SSL_get_servername() directly ... */
|
||||
#define SSL_get_tlsext_hostname(s,psn) \
|
||||
(*psn = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name),*psn != NULL)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user