diff options
Diffstat (limited to 'ssl/ssl_lib.c')
| -rw-r--r-- | ssl/ssl_lib.c | 140 | 
1 files changed, 127 insertions, 13 deletions
| diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 4e81922d7588..68eee77e6f01 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -125,9 +125,14 @@  #include <openssl/objects.h>  #include <openssl/lhash.h>  #include <openssl/x509v3.h> +#include <openssl/rand.h> +#include <openssl/ocsp.h>  #ifndef OPENSSL_NO_DH  #include <openssl/dh.h>  #endif +#ifndef OPENSSL_NO_ENGINE +#include <openssl/engine.h> +#endif  const char *SSL_version_str=OPENSSL_VERSION_TEXT; @@ -306,7 +311,19 @@ SSL *SSL_new(SSL_CTX *ctx)  	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);  	s->ctx=ctx; - +#ifndef OPENSSL_NO_TLSEXT +	s->tlsext_debug_cb = 0; +	s->tlsext_debug_arg = NULL; +	s->tlsext_ticket_expected = 0; +	s->tlsext_status_type = -1; +	s->tlsext_status_expected = 0; +	s->tlsext_ocsp_ids = NULL; +	s->tlsext_ocsp_exts = NULL; +	s->tlsext_ocsp_resp = NULL; +	s->tlsext_ocsp_resplen = -1; +	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX); +	s->initial_ctx=ctx; +#endif  	s->verify_result=X509_V_OK;  	s->method=ctx->method; @@ -492,7 +509,16 @@ 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); +	if (s->tlsext_ocsp_exts) +		sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, +						X509_EXTENSION_free); +	if (s->tlsext_ocsp_ids) +		sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free); +	if (s->tlsext_ocsp_resp) +		OPENSSL_free(s->tlsext_ocsp_resp); +#endif  	if (s->client_CA != NULL)  		sk_X509_NAME_pop_free(s->client_CA,X509_NAME_free); @@ -1201,7 +1227,6 @@ int SSL_set_cipher_list(SSL *s,const char *str)  char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)  	{  	char *p; -	const char *cp;  	STACK_OF(SSL_CIPHER) *sk;  	SSL_CIPHER *c;  	int i; @@ -1214,20 +1239,21 @@ char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)  	sk=s->session->ciphers;  	for (i=0; i<sk_SSL_CIPHER_num(sk); i++)  		{ -		/* Decrement for either the ':' or a '\0' */ -		len--; +		int n; +  		c=sk_SSL_CIPHER_value(sk,i); -		for (cp=c->name; *cp; ) +		n=strlen(c->name); +		if (n+1 > len)  			{ -			if (len-- <= 0) -				{ -				*p='\0'; -				return(buf); -				} -			else -				*(p++)= *(cp++); +			if (p != buf) +				--p; +			*p='\0'; +			return buf;  			} +		strcpy(p,c->name); +		p+=n;  		*(p++)=':'; +		len-=n+1;  		}  	p[-1]='\0';  	return(buf); @@ -1304,6 +1330,29 @@ err:  	return(NULL);  	} +#ifndef OPENSSL_NO_TLSEXT +/** return a servername extension value if provided in Client Hello, or NULL. + * So far, only host_name types are defined (RFC 3546). + */ + +const char *SSL_get_servername(const SSL *s, const int type) +	{ +	if (type != TLSEXT_NAMETYPE_host_name) +		return NULL; + +	return s->session && !s->tlsext_hostname ? +		s->session->tlsext_hostname : +		s->tlsext_hostname; +	} + +int SSL_get_servername_type(const SSL *s) +	{ +	if (s->session && (!s->tlsext_hostname ? s->session->tlsext_hostname : s->tlsext_hostname)) +		return TLSEXT_NAMETYPE_host_name; +	return -1; +	} +#endif +  unsigned long SSL_SESSION_hash(const SSL_SESSION *a)  	{  	unsigned long l; @@ -1347,6 +1396,14 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)  		return(NULL);  		} +#ifdef OPENSSL_FIPS +	if (FIPS_mode() && (meth->version < TLS1_VERSION))	 +		{ +		SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); +		return NULL; +		} +#endif +  	if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0)  		{  		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); @@ -1453,6 +1510,41 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)  	ret->extra_certs=NULL;  	ret->comp_methods=SSL_COMP_get_compression_methods(); +#ifndef OPENSSL_NO_TLSEXT +	ret->tlsext_servername_callback = 0; +	ret->tlsext_servername_arg = NULL; +	/* Setup RFC4507 ticket keys */ +	if ((RAND_pseudo_bytes(ret->tlsext_tick_key_name, 16) <= 0) +		|| (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <= 0) +		|| (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0)) +		ret->options |= SSL_OP_NO_TICKET; + +	ret->tlsext_status_cb = 0; +	ret->tlsext_status_arg = NULL; + +#endif + +#ifndef OPENSSL_NO_ENGINE +	ret->client_cert_engine = NULL; +#ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO +#define eng_strx(x)	#x +#define eng_str(x)	eng_strx(x) +	/* Use specific client engine automatically... ignore errors */ +	{ +	ENGINE *eng; +	eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); +	if (!eng) +		{ +		ERR_clear_error(); +		ENGINE_load_builtin_engines(); +		eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); +		} +	if (!eng || !SSL_CTX_set_client_cert_engine(ret, eng)) +		ERR_clear_error(); +	} +#endif +#endif +  	return(ret);  err:  	SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE); @@ -1523,6 +1615,10 @@ void SSL_CTX_free(SSL_CTX *a)  #else  	a->comp_methods = NULL;  #endif +#ifndef OPENSSL_NO_ENGINE +	if (a->client_cert_engine) +		ENGINE_finish(a->client_cert_engine); +#endif  	OPENSSL_free(a);  	} @@ -2402,6 +2498,24 @@ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl)  	return(ssl->ctx);  	} +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx) +	{ +	if (ssl->ctx == ctx) +		return ssl->ctx; +#ifndef OPENSSL_NO_TLSEXT +	if (ctx == NULL) +		ctx = ssl->initial_ctx; +#endif +	if (ssl->cert != NULL) +		ssl_cert_free(ssl->cert); +	ssl->cert = ssl_cert_dup(ctx->cert); +	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX); +	if (ssl->ctx != NULL) +		SSL_CTX_free(ssl->ctx); /* decrement reference count */ +	ssl->ctx = ctx; +	return(ssl->ctx); +	} +  #ifndef OPENSSL_NO_STDIO  int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)  	{ | 
