Commit fc213217 authored by Scott Deboy's avatar Scott Deboy
Browse files

Update custom TLS extension and supplemental data 'generate' callbacks to support sending an alert.

If multiple TLS extensions are expected but not received, the TLS extension and supplemental data 'generate' callbacks are the only chance for the receive-side to trigger a specific TLS alert during the handshake.

Removed logic which no-op'd TLS extension generate callbacks (as the generate callbacks need to always be called in order to trigger alerts), and updated the serverinfo-specific custom TLS extension callbacks to track which custom TLS extensions were received by the client, where no-ops for 'generate' callbacks are appropriate.

(cherry picked from commit ac20719d)
Conflicts:
	ssl/t1_lib.c
parent 7198c5af
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -242,11 +242,11 @@ static int suppdata_cb(SSL *s, unsigned short supp_data_type,

static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
				     const unsigned char **out,
				     unsigned short *outlen, void *arg);
                                     unsigned short *outlen, int *al, void *arg);

static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
				    const unsigned char **out, unsigned short *outlen,
				    void *arg);
                                    int *al, void *arg);

static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
			   const unsigned char *in,
@@ -2458,7 +2458,7 @@ static int authz_tlsext_cb(SSL *s, unsigned short ext_type,

static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
				    const unsigned char **out, unsigned short *outlen,
				    void *arg)
                                    int *al, void *arg)
	{
	if (c_auth)
		{
@@ -2490,7 +2490,7 @@ static int suppdata_cb(SSL *s, unsigned short supp_data_type,

static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
				     const unsigned char **out,
				     unsigned short *outlen, void *arg)
                                     unsigned short *outlen, int *al, void *arg)
	{
	if (c_auth && server_provided_client_authz && server_provided_server_authz)
		{
+4 −4
Original line number Diff line number Diff line
@@ -336,11 +336,11 @@ static int suppdata_cb(SSL *s, unsigned short supp_data_type,

static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
				     const unsigned char **out,
				     unsigned short *outlen, void *arg);
                                     unsigned short *outlen, int *al, void *arg);

static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
				    const unsigned char **out, unsigned short *outlen,
				    void *arg);
                                    int *al, void *arg);

static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
			   const unsigned char *in,
@@ -3576,7 +3576,7 @@ static int authz_tlsext_cb(SSL *s, unsigned short ext_type,

static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
				    const unsigned char **out, unsigned short *outlen,
				    void *arg)
                                    int *al, void *arg)
	{
	if (c_auth && client_provided_client_authz && client_provided_server_authz)
		{
@@ -3609,7 +3609,7 @@ static int suppdata_cb(SSL *s, unsigned short supp_data_type,

static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
				     const unsigned char **out,
				     unsigned short *outlen, void *arg)
                                     unsigned short *outlen, int *al, void *arg)
	{
	if (c_auth && client_provided_client_authz && client_provided_server_authz)
		{
+2 −1
Original line number Diff line number Diff line
@@ -553,8 +553,9 @@ static int ssl23_client_hello(SSL *s)
				SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
				return -1;
				}
			if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
                        if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, &al)) == NULL)
				{
                                ssl3_send_alert(s,SSL3_AL_FATAL,al);
				SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
				return -1;
				}
+10 −4
Original line number Diff line number Diff line
@@ -891,8 +891,9 @@ int ssl3_client_hello(SSL *s)
			SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
			goto err;
			}
		if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
                if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, &al)) == NULL)
			{
                        ssl3_send_alert(s,SSL3_AL_FATAL,al);
			SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
			goto err;
			}
@@ -3617,6 +3618,7 @@ int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
#ifndef OPENSSL_NO_TLSEXT
int tls1_send_client_supplemental_data(SSL *s, int *skip)
	{
        int al = 0;
	if (s->ctx->cli_supp_data_records_count)
		{
		unsigned char *p = NULL;
@@ -3636,14 +3638,14 @@ int tls1_send_client_supplemental_data(SSL *s, int *skip)
			if (!record->fn2)
				continue;
			cb_retval = record->fn2(s, record->supp_data_type,
				&out, &outlen,
                                &out, &outlen, &al,
				record->arg);
			if (cb_retval == -1)
				continue; /* skip this supp data entry */
			if (cb_retval == 0)
				{
				SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
				return 0;
                                goto f_err;
				}
			if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length)
				{
@@ -3695,6 +3697,10 @@ int tls1_send_client_supplemental_data(SSL *s, int *skip)
	s->init_num = 0;
	s->init_off = 0;
	return 1;

f_err:
        ssl3_send_alert(s,SSL3_AL_FATAL,al);
        return 0;
}

int tls1_get_server_supplemental_data(SSL *s)
+6 −6
Original line number Diff line number Diff line
@@ -3029,8 +3029,8 @@ void ssl3_free(SSL *s)
	SSL_SRP_CTX_free(s);
#endif
#ifndef OPENSSL_NO_TLSEXT
	if (s->s3->tlsext_custom_types != NULL)
		OPENSSL_free(s->s3->tlsext_custom_types);
        if (s->s3->serverinfo_client_tlsext_custom_types != NULL)
                OPENSSL_free(s->s3->serverinfo_client_tlsext_custom_types);
#endif
	OPENSSL_cleanse(s->s3,sizeof *s->s3);
	OPENSSL_free(s->s3);
@@ -3076,12 +3076,12 @@ void ssl3_clear(SSL *s)
		}
#endif
#ifndef OPENSSL_NO_TLSEXT
	if (s->s3->tlsext_custom_types != NULL)
        if (s->s3->serverinfo_client_tlsext_custom_types != NULL)
		{
		OPENSSL_free(s->s3->tlsext_custom_types);
		s->s3->tlsext_custom_types = NULL;
                OPENSSL_free(s->s3->serverinfo_client_tlsext_custom_types);
                s->s3->serverinfo_client_tlsext_custom_types = NULL;
		}
	s->s3->tlsext_custom_types_count = 0;	
        s->s3->serverinfo_client_tlsext_custom_types_count = 0;
#ifndef OPENSSL_NO_EC
	s->s3->is_probably_safari = 0;
#endif /* !OPENSSL_NO_EC */
Loading