summaryrefslogtreecommitdiffstats
path: root/ssl/t1_lib.c
diff options
context:
space:
mode:
authorScott Deboy <sdeboy@secondstryke.com>2013-09-12 12:03:40 -0700
committerScott Deboy <sdeboy@secondstryke.com>2014-02-08 16:17:24 -0800
commitfc213217e8db600093bb7976a11e738c8b4bb948 (patch)
tree43f435fb75a0e7b583765aa44d63933e566472ee /ssl/t1_lib.c
parent7198c5af1fe3c9d2b38fb2c3654ab83488fcf457 (diff)
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 ac20719d994729970eb3b775c7bffa81f0e9f960) Conflicts: ssl/t1_lib.c
Diffstat (limited to 'ssl/t1_lib.c')
-rw-r--r--ssl/t1_lib.c103
1 files changed, 31 insertions, 72 deletions
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 291f4ab00f..f3f6f82184 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -1102,7 +1102,7 @@ static int byte_compare(const void *in_a, const void *in_b)
return 0;
}
-unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
+unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al)
{
int extdatalen=0;
unsigned char *ret = p;
@@ -1466,7 +1466,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
{
int cb_retval = 0;
cb_retval = record->fn1(s, record->ext_type,
- &out, &outlen,
+ &out, &outlen, al,
record->arg);
if (cb_retval == 0)
return NULL; /* error */
@@ -1519,10 +1519,12 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
return ret;
}
-unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
+unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al)
{
int extdatalen=0;
unsigned char *ret = p;
+ size_t i;
+ custom_srv_ext_record *record;
#ifndef OPENSSL_NO_NEXTPROTONEG
int next_proto_neg_seen;
#endif
@@ -1706,45 +1708,29 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
}
#endif
- /* If custom types were sent in ClientHello, add ServerHello responses */
- if (s->s3->tlsext_custom_types_count)
+ for (i = 0; i < s->ctx->custom_srv_ext_records_count; i++)
{
- size_t i;
-
- for (i = 0; i < s->s3->tlsext_custom_types_count; i++)
- {
- size_t j;
- custom_srv_ext_record *record;
-
- for (j = 0; j < s->ctx->custom_srv_ext_records_count; j++)
- {
- record = &s->ctx->custom_srv_ext_records[j];
- if (s->s3->tlsext_custom_types[i] == record->ext_type)
- {
- const unsigned char *out = NULL;
- unsigned short outlen = 0;
- int cb_retval = 0;
-
- /* NULL callback or -1 omits extension */
- if (!record->fn2)
- break;
- cb_retval = record->fn2(s, record->ext_type,
- &out, &outlen,
- record->arg);
- if (cb_retval == 0)
- return NULL; /* error */
- if (cb_retval == -1)
- break; /* skip this extension */
- if (limit < ret + 4 + outlen)
- return NULL;
- s2n(record->ext_type, ret);
- s2n(outlen, ret);
- memcpy(ret, out, outlen);
- ret += outlen;
- break;
- }
- }
- }
+ record = &s->ctx->custom_srv_ext_records[i];
+ const unsigned char *out = NULL;
+ unsigned short outlen = 0;
+ int cb_retval = 0;
+
+ /* NULL callback or -1 omits extension */
+ if (!record->fn2)
+ break;
+ cb_retval = record->fn2(s, record->ext_type,
+ &out, &outlen, al,
+ record->arg);
+ if (cb_retval == 0)
+ return NULL; /* error */
+ if (cb_retval == -1)
+ break; /* skip this extension */
+ if (limit < ret + 4 + outlen)
+ return NULL;
+ s2n(record->ext_type, ret);
+ s2n(outlen, ret);
+ memcpy(ret, out, outlen);
+ ret += outlen;
}
if (s->s3->alpn_selected)
@@ -1938,11 +1924,11 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
#endif
/* Clear observed custom extensions */
- s->s3->tlsext_custom_types_count = 0;
- if (s->s3->tlsext_custom_types != NULL)
+ s->s3->serverinfo_client_tlsext_custom_types_count = 0;
+ 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;
}
if (s->s3->alpn_selected)
@@ -2467,35 +2453,8 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
record = &s->ctx->custom_srv_ext_records[i];
if (type == record->ext_type)
{
- size_t j;
-
- /* Error on duplicate TLS Extensions */
- for (j = 0; j < s->s3->tlsext_custom_types_count; j++)
- {
- if (type == s->s3->tlsext_custom_types[j])
- {
- *al = TLS1_AD_DECODE_ERROR;
- return 0;
- }
- }
-
- /* NULL callback still notes the extension */
if (record->fn1 && !record->fn1(s, type, data, size, al, record->arg))
return 0;
-
- /* Add the (non-duplicated) entry */
- s->s3->tlsext_custom_types_count++;
- s->s3->tlsext_custom_types = OPENSSL_realloc(
- s->s3->tlsext_custom_types,
- s->s3->tlsext_custom_types_count * 2);
- if (s->s3->tlsext_custom_types == NULL)
- {
- s->s3->tlsext_custom_types = 0;
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- s->s3->tlsext_custom_types[
- s->s3->tlsext_custom_types_count - 1] = type;
}
}
}