diff options
Diffstat (limited to 'main/openssl/ssl/ssl_lib.c')
| -rw-r--r-- | main/openssl/ssl/ssl_lib.c | 265 | 
1 files changed, 227 insertions, 38 deletions
diff --git a/main/openssl/ssl/ssl_lib.c b/main/openssl/ssl/ssl_lib.c index b169ba93..74523862 100644 --- a/main/openssl/ssl/ssl_lib.c +++ b/main/openssl/ssl/ssl_lib.c @@ -176,7 +176,10 @@ SSL3_ENC_METHOD ssl3_undef_enc_method={  	0,	/* client_finished_label_len */  	NULL,	/* server_finished_label */  	0,	/* server_finished_label_len */ -	(int (*)(int))ssl_undefined_function +	(int (*)(int))ssl_undefined_function, +	(int (*)(SSL *, unsigned char *, size_t, const char *, +		 size_t, const unsigned char *, size_t, +		 int use_context)) ssl_undefined_function,  	};  int SSL_clear(SSL *s) @@ -202,9 +205,9 @@ int SSL_clear(SSL *s)         * needed because SSL_clear is not called when doing renegotiation) */  	/* This is set if we are doing dynamic renegotiation so keep  	 * the old cipher.  It is sort of a SSL_clear_lite :-) */ -	if (s->new_session) return(1); +	if (s->renegotiate) return(1);  #else -	if (s->new_session) +	if (s->renegotiate)  		{  		SSLerr(SSL_F_SSL_CLEAR,ERR_R_INTERNAL_ERROR);  		return 0; @@ -357,6 +360,17 @@ SSL *SSL_new(SSL_CTX *ctx)  # ifndef OPENSSL_NO_NEXTPROTONEG  	s->next_proto_negotiated = NULL;  # endif + +	if (s->ctx->alpn_client_proto_list) +		{ +		s->alpn_client_proto_list = +			OPENSSL_malloc(s->ctx->alpn_client_proto_list_len); +		if (s->alpn_client_proto_list == NULL) +			goto err; +		memcpy(s->alpn_client_proto_list, s->ctx->alpn_client_proto_list, +		       s->ctx->alpn_client_proto_list_len); +		s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len; +		}  #endif  	s->verify_result=X509_V_OK; @@ -576,6 +590,10 @@ void SSL_free(SSL *s)  		sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);  	if (s->tlsext_ocsp_resp)  		OPENSSL_free(s->tlsext_ocsp_resp); +	if (s->tlsext_channel_id_private) +		EVP_PKEY_free(s->tlsext_channel_id_private); +	if (s->alpn_client_proto_list) +		OPENSSL_free(s->alpn_client_proto_list);  #endif  	if (s->client_CA != NULL) @@ -595,6 +613,11 @@ void SSL_free(SSL *s)  		OPENSSL_free(s->next_proto_negotiated);  #endif +#ifndef OPENSSL_NO_SRTP +        if (s->srtp_profiles) +            sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles); +#endif +  	OPENSSL_free(s);  	} @@ -1017,10 +1040,21 @@ int SSL_shutdown(SSL *s)  int SSL_renegotiate(SSL *s)  	{ -	if (s->new_session == 0) -		{ -		s->new_session=1; -		} +	if (s->renegotiate == 0) +		s->renegotiate=1; + +	s->new_session=1; + +	return(s->method->ssl_renegotiate(s)); +	} + +int SSL_renegotiate_abbreviated(SSL *s) +	{ +	if (s->renegotiate == 0) +		s->renegotiate=1; + +	s->new_session=0; +  	return(s->method->ssl_renegotiate(s));  	} @@ -1028,7 +1062,7 @@ int SSL_renegotiate_pending(SSL *s)  	{  	/* becomes true when negotiation is requested;  	 * false again once a handshake has finished */ -	return (s->new_session != 0); +	return (s->renegotiate != 0);  	}  long SSL_ctrl(SSL *s,int cmd,long larg,void *parg) @@ -1063,6 +1097,11 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)  		s->max_cert_list=larg;  		return(l);  	case SSL_CTRL_SET_MTU: +#ifndef OPENSSL_NO_DTLS1 +		if (larg < (long)dtls1_min_mtu()) +			return 0; +#endif +  		if (SSL_version(s) == DTLS1_VERSION ||  		    SSL_version(s) == DTLS1_BAD_VER)  			{ @@ -1390,6 +1429,10 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,  	for (i=0; i<sk_SSL_CIPHER_num(sk); i++)  		{  		c=sk_SSL_CIPHER_value(sk,i); +		/* Skip TLS v1.2 only ciphersuites if lower than v1.2 */ +		if ((c->algorithm_ssl & SSL_TLSV1_2) &&  +			(TLS1_get_client_version(s) < TLS1_2_VERSION)) +			continue;  #ifndef OPENSSL_NO_KRB5  		if (((c->algorithm_mkey & SSL_kKRB5) || (c->algorithm_auth & SSL_aKRB5)) &&  		    nokrb5) @@ -1407,7 +1450,7 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,  	/* If p == q, no ciphers and caller indicates an error. Otherwise  	 * add SCSV if not renegotiating.  	 */ -	if (p != q && !s->new_session) +	if (p != q && !s->renegotiate)  		{  		static SSL_CIPHER scsv =  			{ @@ -1454,7 +1497,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,  			(p[n-1] == (SSL3_CK_SCSV & 0xff)))  			{  			/* SCSV fatal if renegotiating */ -			if (s->new_session) +			if (s->renegotiate)  				{  				SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);  				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);  @@ -1627,10 +1670,93 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, unsigned  	ctx->next_proto_select_cb = cb;  	ctx->next_proto_select_cb_arg = arg;  	} -  # endif + +/* SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|. + * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit + * length-prefixed strings). + * + * Returns 0 on success. */ +int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char* protos, +			    unsigned protos_len) +	{ +	if (ctx->alpn_client_proto_list) +		OPENSSL_free(ctx->alpn_client_proto_list); + +	ctx->alpn_client_proto_list = OPENSSL_malloc(protos_len); +	if (!ctx->alpn_client_proto_list) +		return 1; +	memcpy(ctx->alpn_client_proto_list, protos, protos_len); +	ctx->alpn_client_proto_list_len = protos_len; + +	return 0; +	} + +/* SSL_set_alpn_protos sets the ALPN protocol list on |ssl| to |protos|. + * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit + * length-prefixed strings). + * + * Returns 0 on success. */ +int SSL_set_alpn_protos(SSL *ssl, const unsigned char* protos, +			unsigned protos_len) +	{ +	if (ssl->alpn_client_proto_list) +		OPENSSL_free(ssl->alpn_client_proto_list); + +	ssl->alpn_client_proto_list = OPENSSL_malloc(protos_len); +	if (!ssl->alpn_client_proto_list) +		return 1; +	memcpy(ssl->alpn_client_proto_list, protos, protos_len); +	ssl->alpn_client_proto_list_len = protos_len; + +	return 0; +	} + +/* SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is called + * during ClientHello processing in order to select an ALPN protocol from the + * client's list of offered protocols. */ +void SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx, +				int (*cb) (SSL *ssl, +					   const unsigned char **out, +					   unsigned char *outlen, +					   const unsigned char *in, +					   unsigned int inlen, +					   void *arg), +				void *arg) +	{ +	ctx->alpn_select_cb = cb; +	ctx->alpn_select_cb_arg = arg; +	} + +/* SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|. + * On return it sets |*data| to point to |*len| bytes of protocol name (not + * including the leading length-prefix byte). If the server didn't respond with + * a negotiated protocol then |*len| will be zero. */ +void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, +			    unsigned *len) +	{ +	*data = NULL; +	if (ssl->s3) +		*data = ssl->s3->alpn_selected; +	if (*data == NULL) +		*len = 0; +	else +		*len = ssl->s3->alpn_selected_len; +	}  #endif +int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, +	const char *label, size_t llen, const unsigned char *p, size_t plen, +	int use_context) +	{ +	if (s->version < TLS1_VERSION) +		return -1; + +	return s->method->ssl3_enc->export_keying_material(s, out, olen, label, +							   llen, p, plen, +							   use_context); +	} +  static unsigned long ssl_session_hash(const SSL_SESSION *a)  	{  	unsigned long l; @@ -1674,6 +1800,14 @@ SSL_CTX *SSL_CTX_new(const 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); @@ -1777,7 +1911,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)  	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data);  	ret->extra_certs=NULL; -	ret->comp_methods=SSL_COMP_get_compression_methods(); +	/* No compression for DTLS */ +	if (meth->version != DTLS1_VERSION) +		ret->comp_methods=SSL_COMP_get_compression_methods();  	ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; @@ -1803,6 +1939,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)  	ret->psk_client_callback=NULL;  	ret->psk_server_callback=NULL;  #endif +#ifndef OPENSSL_NO_SRP +	SSL_CTX_SRP_CTX_init(ret); +#endif  #ifndef OPENSSL_NO_BUF_FREELISTS  	ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT;  	ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); @@ -1931,10 +2070,18 @@ void SSL_CTX_free(SSL_CTX *a)  	a->comp_methods = NULL;  #endif +#ifndef OPENSSL_NO_SRTP +        if (a->srtp_profiles) +                sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles); +#endif +  #ifndef OPENSSL_NO_PSK  	if (a->psk_identity_hint)  		OPENSSL_free(a->psk_identity_hint);  #endif +#ifndef OPENSSL_NO_SRP +	SSL_CTX_SRP_CTX_free(a); +#endif  #ifndef OPENSSL_NO_ENGINE  	if (a->client_cert_engine)  		ENGINE_finish(a->client_cert_engine); @@ -1947,6 +2094,13 @@ void SSL_CTX_free(SSL_CTX *a)  		ssl_buf_freelist_free(a->rbuf_freelist);  #endif +#ifndef OPENSSL_NO_TLSEXT +	if (a->tlsext_channel_id_private) +		EVP_PKEY_free(a->tlsext_channel_id_private); +	if (a->alpn_client_proto_list != NULL) +		OPENSSL_free(a->alpn_client_proto_list); +#endif +  	OPENSSL_free(a);  	} @@ -2188,12 +2342,13 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)  #ifndef OPENSSL_NO_EC -int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs) +int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)  	{  	unsigned long alg_k, alg_a;  	EVP_PKEY *pkey = NULL;  	int keysize = 0;  	int signature_nid = 0, md_nid = 0, pk_nid = 0; +	const SSL_CIPHER *cs = s->s3->tmp.new_cipher;  	alg_k = cs->algorithm_mkey;  	alg_a = cs->algorithm_auth; @@ -2223,7 +2378,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs)  			SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT);  			return 0;  			} -		if (alg_k & SSL_kECDHe) +		if ((alg_k & SSL_kECDHe) && TLS1_get_version(s) < TLS1_2_VERSION)  			{  			/* signature alg must be ECDSA */  			if (pk_nid != NID_X9_62_id_ecPublicKey) @@ -2232,7 +2387,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs)  				return 0;  				}  			} -		if (alg_k & SSL_kECDHr) +		if ((alg_k & SSL_kECDHr) && TLS1_get_version(s) < TLS1_2_VERSION)  			{  			/* signature alg must be RSA */ @@ -2259,7 +2414,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs)  #endif  /* THIS NEEDS CLEANING UP */ -X509 *ssl_get_server_send_cert(SSL *s) +CERT_PKEY *ssl_get_server_send_pkey(const SSL *s)  	{  	unsigned long alg_k,alg_a;  	CERT *c; @@ -2314,15 +2469,23 @@ X509 *ssl_get_server_send_cert(SSL *s)  		i=SSL_PKEY_GOST01;  	else /* if (alg_a & SSL_aNULL) */  		{ -		SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,ERR_R_INTERNAL_ERROR); +		SSLerr(SSL_F_SSL_GET_SERVER_SEND_PKEY,ERR_R_INTERNAL_ERROR);  		return(NULL);  		} -	if (c->pkeys[i].x509 == NULL) return(NULL); -	return(c->pkeys[i].x509); +	return c->pkeys + i; +	} + +X509 *ssl_get_server_send_cert(const SSL *s) +	{ +	CERT_PKEY *cpk; +	cpk = ssl_get_server_send_pkey(s); +	if (!cpk) +		return NULL; +	return cpk->x509;  	} -EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher) +EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd)  	{  	unsigned long alg_a;  	CERT *c; @@ -2330,26 +2493,37 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher)  	alg_a = cipher->algorithm_auth;  	c=s->cert; +	/* SHA1 is the default for all signature algorithms up to TLS 1.2, +	 * except RSA which is handled specially in s3_srvr.c */ +	if (pmd) +		*pmd = EVP_sha1(); +  	if ((alg_a & SSL_aDSS) && -		(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL)) -		return(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey); +	    (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL)) +		{ +		if (pmd && s->s3 && s->s3->digest_dsa) +			*pmd = s->s3->digest_dsa; +		return c->pkeys[SSL_PKEY_DSA_SIGN].privatekey; +		}  	else if (alg_a & SSL_aRSA)  		{ +		if (pmd && s->s3 && s->s3->digest_rsa) +			*pmd = s->s3->digest_rsa;  		if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL) -			return(c->pkeys[SSL_PKEY_RSA_SIGN].privatekey); -		else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) -			return(c->pkeys[SSL_PKEY_RSA_ENC].privatekey); -		else -			return(NULL); +			return c->pkeys[SSL_PKEY_RSA_SIGN].privatekey; +		if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) +			return c->pkeys[SSL_PKEY_RSA_ENC].privatekey;  		}  	else if ((alg_a & SSL_aECDSA) &&  	         (c->pkeys[SSL_PKEY_ECC].privatekey != NULL)) -		return(c->pkeys[SSL_PKEY_ECC].privatekey); -	else /* if (alg_a & SSL_aNULL) */  		{ -		SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR); -		return(NULL); +		if (pmd && s->s3 && s->s3->digest_ecdsa) +			*pmd = s->s3->digest_ecdsa; +		return c->pkeys[SSL_PKEY_ECC].privatekey;  		} + +	SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR); +	return(NULL);  	}  void ssl_update_cache(SSL *s,int mode) @@ -2574,7 +2748,11 @@ SSL_METHOD *ssl_bad_method(int ver)  static const char *ssl_get_version(int version)  	{ -	if (version == TLS1_VERSION) +	if (version == TLS1_2_VERSION) +		return("TLSv1.2"); +	else if (version == TLS1_1_VERSION) +		return("TLSv1.1"); +	else if (version == TLS1_VERSION)  		return("TLSv1");  	else if (version == SSL3_VERSION)  		return("SSLv3"); @@ -2602,12 +2780,8 @@ const char* SSL_authentication_method(const SSL* ssl)  		{  	case SSL2_VERSION:  		return SSL_TXT_RSA; -	case SSL3_VERSION: -	case TLS1_VERSION: -	case DTLS1_VERSION: -		return SSL_CIPHER_authentication_method(ssl->s3->tmp.new_cipher);  	default: -		return "UNKNOWN"; +		return SSL_CIPHER_authentication_method(ssl->s3->tmp.new_cipher);  		}  	} @@ -2695,6 +2869,7 @@ SSL *SSL_dup(SSL *s)  	ret->in_handshake = s->in_handshake;  	ret->handshake_func = s->handshake_func;  	ret->server = s->server; +	ret->renegotiate = s->renegotiate;  	ret->new_session = s->new_session;  	ret->quiet_shutdown = s->quiet_shutdown;  	ret->shutdown=s->shutdown; @@ -2960,6 +3135,11 @@ int SSL_state(const SSL *ssl)  	return(ssl->state);  	} +void SSL_set_state(SSL *ssl, int state) +	{ +	ssl->state = state; +	} +  void SSL_set_verify_result(SSL *ssl,long arg)  	{  	ssl->verify_result=arg; @@ -3231,6 +3411,16 @@ void ssl_clear_hash_ctx(EVP_MD_CTX **hash)  	*hash=NULL;  } +void SSL_set_debug(SSL *s, int debug) +	{ +	s->debug = debug; +	} + +int SSL_cache_hit(SSL *s) +	{ +	return s->hit; +	} +  #if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16)  #include "../crypto/bio/bss_file.c"  #endif @@ -3239,4 +3429,3 @@ IMPLEMENT_STACK_OF(SSL_CIPHER)  IMPLEMENT_STACK_OF(SSL_COMP)  IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER,  				    ssl_cipher_id); -  | 
