summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorScott Deboy <sdeboy@secondstryke.com>2013-06-18 14:34:38 -0700
committerScott Deboy <sdeboy@secondstryke.com>2014-02-08 16:12:15 -0800
commit038bec784e528ce273169f178c35991fbc3bea92 (patch)
treebe8a71c2c534db29ea7ee31f1207be9b976b0698 /ssl
parentf407eec799f1f5d271b809875f016f680935567b (diff)
Add callbacks supporting generation and retrieval of supplemental data entries, facilitating RFC 5878 (TLS auth extensions)
Removed prior audit proof logic - audit proof support was implemented using the generic TLS extension API Tests exercising the new supplemental data registration and callback api can be found in ssltest.c. Implemented changes to s_server and s_client to exercise supplemental data callbacks via the -auth argument, as well as additional flags to exercise supplemental data being sent only during renegotiation. (cherry picked from commit 36086186a9b90cdad0d2cd0a598a10f03f8f4bcc) Conflicts: Configure apps/s_client.c apps/s_server.c ssl/ssl.h ssl/ssl3.h ssl/ssltest.c
Diffstat (limited to 'ssl')
-rw-r--r--ssl/s23_clnt.c4
-rw-r--r--ssl/s3_clnt.c239
-rw-r--r--ssl/s3_lib.c17
-rw-r--r--ssl/s3_srvr.c238
-rw-r--r--ssl/ssl.h124
-rw-r--r--ssl/ssl3.h36
-rw-r--r--ssl/ssl_cert.c22
-rw-r--r--ssl/ssl_err.c12
-rw-r--r--ssl/ssl_lib.c85
-rw-r--r--ssl/ssl_locl.h13
-rw-r--r--ssl/ssl_rsa.c233
-rw-r--r--ssl/ssl_sess.c11
-rw-r--r--ssl/ssl_stat.c8
-rw-r--r--ssl/ssltest.c141
-rw-r--r--ssl/t1_lib.c193
-rw-r--r--ssl/tls1.h14
16 files changed, 632 insertions, 758 deletions
diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c
index 710d4f228e..a101bce161 100644
--- a/ssl/s23_clnt.c
+++ b/ssl/s23_clnt.c
@@ -362,10 +362,10 @@ static int ssl23_client_hello(SSL *s)
if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL)
ssl2_compat = 0;
#endif
- if (s->ctx->tlsext_authz_server_audit_proof_cb != NULL)
- ssl2_compat = 0;
if (s->ctx->custom_cli_ext_records_count != 0)
ssl2_compat = 0;
+ if (s->ctx->cli_supp_data_records_count != 0)
+ ssl2_compat = 0;
}
#endif
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 9e3c847de9..d7178793ab 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -307,13 +307,6 @@ int ssl3_connect(SSL *s)
}
else
{
-#ifndef OPENSSL_NO_TLSEXT
- /* The server hello indicated that
- * an audit proof would follow. */
- if (s->s3->tlsext_authz_server_promised)
- s->state=SSL3_ST_CR_SUPPLEMENTAL_DATA_A;
- else
-#endif
s->state=SSL3_ST_CR_CERT_A;
}
s->init_num=0;
@@ -332,6 +325,12 @@ int ssl3_connect(SSL *s)
#ifndef OPENSSL_NO_TLSEXT
ret=ssl3_check_finished(s);
if (ret <= 0) goto end;
+ if (ret == 3)
+ {
+ s->state=SSL3_ST_CR_SUPPLEMENTAL_DATA_A;
+ s->init_num=0;
+ break;
+ }
if (ret == 2)
{
s->hit = 1;
@@ -410,10 +409,14 @@ int ssl3_connect(SSL *s)
}
}
#endif
+#ifndef OPENSSL_NO_TLSEXT
+ s->state=SSL3_ST_CW_SUPPLEMENTAL_DATA_A;
+#else
if (s->s3->tmp.cert_req)
s->state=SSL3_ST_CW_CERT_A;
else
s->state=SSL3_ST_CW_KEY_EXCH_A;
+#endif
s->init_num=0;
break;
@@ -520,6 +523,19 @@ int ssl3_connect(SSL *s)
break;
#endif
+#ifndef OPENSSL_NO_TLSEXT
+ case SSL3_ST_CW_SUPPLEMENTAL_DATA_A:
+ case SSL3_ST_CW_SUPPLEMENTAL_DATA_B:
+ ret = tls1_send_client_supplemental_data(s, &skip);
+ if (ret <= 0) goto end;
+ if (s->s3->tmp.cert_req)
+ s->state=SSL3_ST_CW_CERT_A;
+ else
+ s->state=SSL3_ST_CW_KEY_EXCH_A;
+ s->init_num=0;
+ break;
+#endif
+
case SSL3_ST_CW_FINISHED_A:
case SSL3_ST_CW_FINISHED_B:
ret=ssl3_send_finished(s,
@@ -1353,21 +1369,6 @@ int ssl3_get_server_certificate(SSL *s)
s->session->verify_result = s->verify_result;
x=NULL;
-#ifndef OPENSSL_NO_TLSEXT
- /* Check the audit proof. */
- if (s->ctx->tlsext_authz_server_audit_proof_cb)
- {
- ret = s->ctx->tlsext_authz_server_audit_proof_cb(s,
- s->ctx->tlsext_authz_server_audit_proof_cb_arg);
- if (ret <= 0)
- {
- al = SSL_AD_BAD_CERTIFICATE;
- SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_INVALID_AUDIT_PROOF);
- goto f_err;
- }
- }
-
-#endif
ret=1;
if (0)
{
@@ -3568,11 +3569,9 @@ int ssl3_check_finished(SSL *s)
{
int ok;
long n;
- /* If we have no ticket it cannot be a resumed session. */
- if (!s->session->tlsext_tick)
- return 1;
- /* this function is called when we really expect a Certificate
- * message, so permit appropriate message length */
+/* Read the message to see if it is supplemental data, regardless if there is a session ticket
+ this function is called when we really expect a Certificate
+ message, so permit appropriate message length */
n=s->method->ssl_get_message(s,
SSL3_ST_CR_CERT_A,
SSL3_ST_CR_CERT_B,
@@ -3581,6 +3580,14 @@ int ssl3_check_finished(SSL *s)
&ok);
if (!ok) return((int)n);
s->s3->tmp.reuse_message = 1;
+
+ if (s->s3->tmp.message_type == SSL3_MT_SUPPLEMENTAL_DATA)
+ {
+ return 3;
+ }
+ /* If we have no ticket it cannot be a resumed session. */
+ if (!s->session->tlsext_tick)
+ return 1;
if ((s->s3->tmp.message_type == SSL3_MT_FINISHED)
|| (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET))
return 2;
@@ -3608,15 +3615,99 @@ 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)
+ {
+ if (s->ctx->cli_supp_data_records_count)
+ {
+ unsigned char *p = NULL;
+ unsigned char *size_loc = NULL;
+ cli_supp_data_record *record = NULL;
+ size_t length = 0;
+ size_t i = 0;
+
+ for (i = 0; i < s->ctx->cli_supp_data_records_count; i++)
+ {
+ const unsigned char *out = NULL;
+ unsigned short outlen = 0;
+ int cb_retval = 0;
+ record = &s->ctx->cli_supp_data_records[i];
+
+ /* NULL callback or -1 omits supp data entry*/
+ if (!record->fn2)
+ continue;
+ cb_retval = record->fn2(s, record->supp_data_type,
+ &out, &outlen,
+ 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;
+ }
+ if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length)
+ {
+ SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
+ return 0;
+ }
+ //if first entry, write handshake message type
+ if (length == 0)
+ {
+ if (!BUF_MEM_grow_clean(s->init_buf, 4))
+ {
+ SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
+ return 0;
+ }
+ p = (unsigned char *)s->init_buf->data;
+ *(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
+ //update message length when all callbacks complete
+ size_loc = p;
+ //skip over handshake length field (3 bytes) and supp_data length field (3 bytes)
+ p += 3 + 3;
+ length += 1 +3 +3;
+ }
+ if (!BUF_MEM_grow(s->init_buf, outlen + 4))
+ {
+ SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
+ return 0;
+ }
+ s2n(record->supp_data_type, p);
+ s2n(outlen, p);
+ memcpy(p, out, outlen);
+ length += (outlen + 4);
+ p += outlen;
+ }
+ if (length > 0)
+ {
+ //write handshake length
+ l2n3(length - 4, size_loc);
+ //supp_data length
+ l2n3(length - 7, size_loc);
+ s->state = SSL3_ST_CW_SUPPLEMENTAL_DATA_B;
+ s->init_num = length;
+ s->init_off = 0;
+ return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+ }
+ }
+
+ //no supp data message sent
+ *skip = 1;
+ s->init_num = 0;
+ s->init_off = 0;
+ return 1;
+ }
+
int tls1_get_server_supplemental_data(SSL *s)
{
- int al;
+ int al = 0;
int ok;
- unsigned long supp_data_len, authz_data_len;
long n;
- unsigned short supp_data_type, authz_data_type, proof_len;
- const unsigned char *p;
- unsigned char *new_proof;
+ const unsigned char *p, *d;
+ unsigned short supp_data_entry_type = 0;
+ unsigned long supp_data_entry_len = 0;
+ unsigned long supp_data_len = 0;
+ size_t i;
+ int cb_retval = 0;
n=s->method->ssl_get_message(s,
SSL3_ST_CR_SUPPLEMENTAL_DATA_A,
@@ -3629,7 +3720,7 @@ int tls1_get_server_supplemental_data(SSL *s)
if (!ok) return((int)n);
p = (unsigned char *)s->init_msg;
-
+ d = p;
/* The message cannot be empty */
if (n < 3)
{
@@ -3637,72 +3728,26 @@ int tls1_get_server_supplemental_data(SSL *s)
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
goto f_err;
}
- /* Length of supplemental data */
- n2l3(p,supp_data_len);
- n -= 3;
- /* We must have at least one supplemental data entry
- * with type (1 byte) and length (2 bytes). */
- if (supp_data_len != (unsigned long) n || n < 4)
+ n2l3(p, supp_data_len);
+ while (p<d+supp_data_len)
{
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
- goto f_err;
- }
- /* Supplemental data type: must be authz_data */
- n2s(p,supp_data_type);
- n -= 2;
- if (supp_data_type != TLSEXT_SUPPLEMENTALDATATYPE_authz_data)
- {
- al = SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_UNKNOWN_SUPPLEMENTAL_DATA_TYPE);
- goto f_err;
- }
- /* Authz data length */
- n2s(p, authz_data_len);
- n -= 2;
- if (authz_data_len != (unsigned long) n || n < 1)
- {
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
- goto f_err;
- }
- /* Authz data type: must be audit_proof */
- authz_data_type = *(p++);
- n -= 1;
- if (authz_data_type != TLSEXT_AUTHZDATAFORMAT_audit_proof)
- {
- al=SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_UNKNOWN_AUTHZ_DATA_TYPE);
- goto f_err;
- }
- /* We have a proof: read its length */
- if (n < 2)
- {
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
- goto f_err;
- }
- n2s(p, proof_len);
- n -= 2;
- if (proof_len != (unsigned long) n)
- {
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
- goto f_err;
- }
- /* Store the proof */
- new_proof = OPENSSL_realloc(s->session->audit_proof,
- proof_len);
- if (new_proof == NULL)
- {
- SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,ERR_R_MALLOC_FAILURE);
- return 0;
+ n2s(p, supp_data_entry_type);
+ n2s(p, supp_data_entry_len);
+ //if there is a callback for this supp data type, send it
+ for (i=0; i < s->ctx->cli_supp_data_records_count; i++)
+ {
+ if (s->ctx->cli_supp_data_records[i].supp_data_type == supp_data_entry_type && s->ctx->cli_supp_data_records[i].fn1)
+ {
+ cb_retval = s->ctx->cli_supp_data_records[i].fn1(s, supp_data_entry_type, p, supp_data_entry_len, &al, s->ctx->cli_supp_data_records[i].arg);
+ if (cb_retval == 0)
+ {
+ SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA, ERR_R_SSL_LIB);
+ goto f_err;
+ }
+ }
+ }
+ p+=supp_data_entry_len;
}
- s->session->audit_proof_length = proof_len;
- s->session->audit_proof = new_proof;
- memcpy(s->session->audit_proof, p, proof_len);
-
- /* Got the proof, but can't verify it yet. */
return 1;
f_err:
ssl3_send_alert(s,SSL3_AL_FATAL,al);
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 372910f573..b03601d6ea 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -3029,8 +3029,6 @@ void ssl3_free(SSL *s)
SSL_SRP_CTX_free(s);
#endif
#ifndef OPENSSL_NO_TLSEXT
- if (s->s3->tlsext_authz_client_types != NULL)
- OPENSSL_free(s->s3->tlsext_authz_client_types);
if (s->s3->tlsext_custom_types != NULL)
OPENSSL_free(s->s3->tlsext_custom_types);
#endif
@@ -3078,11 +3076,6 @@ void ssl3_clear(SSL *s)
}
#endif
#ifndef OPENSSL_NO_TLSEXT
- if (s->s3->tlsext_authz_client_types != NULL)
- {
- OPENSSL_free(s->s3->tlsext_authz_client_types);
- s->s3->tlsext_authz_client_types = NULL;
- }
if (s->s3->tlsext_custom_types != NULL)
{
OPENSSL_free(s->s3->tlsext_custom_types);
@@ -3897,10 +3890,6 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
case SSL_CTRL_SET_CHAIN_CERT_STORE:
return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg);
- case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG:
- ctx->tlsext_authz_server_audit_proof_cb_arg = parg;
- break;
-
#endif /* !OPENSSL_NO_TLSEXT */
/* A Thawte special :-) */
@@ -4023,12 +4012,6 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
ctx->srp_ctx.SRP_give_srp_client_pwd_callback=(char *(*)(SSL *,void *))fp;
break;
#endif
-
- case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB:
- ctx->tlsext_authz_server_audit_proof_cb =
- (int (*)(SSL *, void *))fp;
- break;
-
#endif
default:
return(0);
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 8902303afd..3699524eb3 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -413,14 +413,8 @@ int ssl3_accept(SSL *s)
#ifndef OPENSSL_NO_TLSEXT
case SSL3_ST_SW_SUPPLEMENTAL_DATA_A:
case SSL3_ST_SW_SUPPLEMENTAL_DATA_B:
- /* We promised to send an audit proof in the hello. */
- if (s->s3->tlsext_authz_promised_to_client)
- {
- ret = tls1_send_server_supplemental_data(s);
- if (ret <= 0) goto end;
- }
- else
- skip = 1;
+ ret = tls1_send_server_supplemental_data(s, &skip);
+ if (ret <= 0) goto end;
s->state = SSL3_ST_SW_CERT_A;
s->init_num = 0;
@@ -595,7 +589,16 @@ int ssl3_accept(SSL *s)
s->state=s->s3->tmp.next_state;
break;
-
+#ifndef OPENSSL_NO_TLSEXT
+ case SSL3_ST_SR_SUPPLEMENTAL_DATA_A:
+ case SSL3_ST_SR_SUPPLEMENTAL_DATA_B:
+ ret=tls1_get_client_supplemental_data(s);
+ if (ret <= 0) goto end;
+ s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
+ s->state=SSL3_ST_SW_FLUSH;
+ s->init_num=0;
+ break;
+#endif
case SSL3_ST_SR_CERT_A:
case SSL3_ST_SR_CERT_B:
/* Check for second client hello (MS SGC) */
@@ -604,6 +607,10 @@ int ssl3_accept(SSL *s)
goto end;
if (ret == 2)
s->state = SSL3_ST_SR_CLNT_HELLO_C;
+#ifndef OPENSSL_NO_TLSEXT
+ else if (ret == 3)
+ s->state = SSL3_ST_SR_SUPPLEMENTAL_DATA_A;
+#endif
else {
if (s->s3->tmp.cert_request)
{
@@ -894,6 +901,12 @@ int ssl3_check_client_hello(SSL *s)
&ok);
if (!ok) return((int)n);
s->s3->tmp.reuse_message = 1;
+#ifndef OPENSSL_NO_TLSEXT
+ if (s->s3->tmp.message_type == SSL3_MT_SUPPLEMENTAL_DATA)
+ {
+ return 3;
+ }
+#endif
if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
{
/* We only allow the client to restart the handshake once per
@@ -3639,98 +3652,149 @@ int ssl3_get_next_proto(SSL *s)
}
# endif
-int tls1_send_server_supplemental_data(SSL *s)
+int tls1_send_server_supplemental_data(SSL *s, int *skip)
{
- size_t length = 0;
- const unsigned char *authz, *orig_authz;
- unsigned char *p;
- size_t authz_length, i;
-
- if (s->state != SSL3_ST_SW_SUPPLEMENTAL_DATA_A)
- return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+ if (s->ctx->srv_supp_data_records_count)
+ {
+ unsigned char *p = NULL;
+ unsigned char *size_loc = NULL;
+ srv_supp_data_record *record = NULL;
+ size_t length = 0;
+ size_t i = 0;
+
+ for (i = 0; i < s->ctx->srv_supp_data_records_count; i++)
+ {
+ const unsigned char *out = NULL;
+ unsigned short outlen = 0;
+ int cb_retval = 0;
+ record = &s->ctx->srv_supp_data_records[i];
+
+ /* NULL callback or -1 omits supp data entry */
+ if (!record->fn1)
+ continue;
+ cb_retval = record->fn1(s, record->supp_data_type,
+ &out, &outlen,
+ record->arg);
+ if (cb_retval == -1)
+ continue; /* skip this supp data entry */
+ if (cb_retval == 0)
+ {
+ SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
+ return 0;
+ }
+ if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length)
+ {
+ SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
+ return 0;
+ }
+ //write supp data entry...
+ //if first entry, write handshake message type
+ //jump back to write length at end
+ if (length == 0)
+ {
+ //1 byte message type + 3 bytes for message length
+ if (!BUF_MEM_grow_clean(s->init_buf, 4))
+ {
+ SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
+ return 0;
+ }
+ p = (unsigned char *)s->init_buf->data;
+ *(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
+ //hold on to length field to update later
+ size_loc = p;
+ //skip over handshake length field (3 bytes) and supp_data length field (3 bytes)
+ p += 3 + 3;
+ length += 1 +3 +3;
+ }
+ //2 byte supp data type + 2 byte length + outlen
+ if (!BUF_MEM_grow(s->init_buf, outlen + 4))
+ {
+ SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
+ return 0;
+ }
+ s2n(record->supp_data_type, p);
+ s2n(outlen, p);
+ memcpy(p, out, outlen);
+ //update length to supp data type (2 bytes) + supp data length (2 bytes) + supp data
+ length += (outlen + 4);
+ p += outlen;
+ }
+ if (length > 0)
+ {
+ //write handshake length
+ l2n3(length - 4, size_loc);
+ //supp_data length
+ l2n3(length - 7, size_loc);
+ s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B;
+ s->init_num = length;
+ s->init_off = 0;
- orig_authz = authz = ssl_get_authz_data(s, &authz_length);
- if (authz == NULL)
- {
- /* This should never occur. */
- return 0;
+ return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+ }
}
- /* First we walk over the authz data to see how long the handshake
- * message will be. */
- for (i = 0; i < authz_length; i++)
- {
- unsigned short len;
- unsigned char type;
+ //no supp data message sent
+ *skip = 1;
+ s->init_num = 0;
+ s->init_off = 0;
+ return 1;
+ }
- type = *(authz++);
- n2s(authz, len);
- /* n2s increments authz by 2*/
- i += 2;
+int tls1_get_client_supplemental_data(SSL *s)
+ {
+ int al = 0;
+ int cb_retval = 0;
+ int ok;
+ long n;
+ const unsigned char *p, *d;
+ unsigned short supp_data_entry_type = 0;
+ unsigned long supp_data_entry_len = 0;
+ unsigned long supp_data_len = 0;
+ size_t i = 0;
- if (memchr(s->s3->tlsext_authz_client_types,
- type,
- s->s3->tlsext_authz_client_types_len) != NULL)
- length += 1 /* authz type */ + 2 /* length */ + len;
+ n=s->method->ssl_get_message(s,
+ SSL3_ST_SR_SUPPLEMENTAL_DATA_A,
+ SSL3_ST_SR_SUPPLEMENTAL_DATA_B,
+ SSL3_MT_SUPPLEMENTAL_DATA,
+ /* use default limit */
+ TLSEXT_MAXLEN_supplemental_data,
+ &ok);
- authz += len;
- i += len;
- }
+ if (!ok) return((int)n);
- length += 1 /* handshake type */ +
- 3 /* handshake length */ +
- 3 /* supplemental data length */ +
- 2 /* supplemental entry type */ +
- 2 /* supplemental entry length */;
+ p = (unsigned char *)s->init_msg;
+ d = p;
- if (!BUF_MEM_grow_clean(s->init_buf, length))
+ /* The message cannot be empty */
+ if (n < 3)
{
- SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
- return 0;
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
+ goto f_err;
}
-
- p = (unsigned char *)s->init_buf->data;
- *(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
- /* Handshake length */
- l2n3(length - 4, p);
- /* Length of supplemental data */
- l2n3(length - 7, p);
- /* Supplemental data type */
- s2n(TLSEXT_SUPPLEMENTALDATATYPE_authz_data, p);
- /* Its length */
- s2n(length - 11, p);
-
- authz = orig_authz;
-
- /* Walk over the authz again and append the selected elements. */
- for (i = 0; i < authz_length; i++)
+ n2l3(p, supp_data_len);
+ while (p<d+supp_data_len)
{
- unsigned short len;
- unsigned char type;
-
- type = *(authz++);
- n2s(authz, len);
- /* n2s increments authz by 2 */
- i += 2;
-
- if (memchr(s->s3->tlsext_authz_client_types,
- type,
- s->s3->tlsext_authz_client_types_len) != NULL)
+ n2s(p, supp_data_entry_type);
+ n2s(p, supp_data_entry_len);
+ //if there is a callback for this supp data type, send it
+ for (i=0; i < s->ctx->srv_supp_data_records_count; i++)
{
- *(p++) = type;
- s2n(len, p);
- memcpy(p, authz, len);
- p += len;
+ if (s->ctx->srv_supp_data_records[i].supp_data_type == supp_data_entry_type && s->ctx->srv_supp_data_records[i].fn2)
+ {
+ cb_retval = s->ctx->srv_supp_data_records[i].fn2(s, supp_data_entry_type, p, supp_data_entry_len, &al, s->ctx->srv_supp_data_records[i].arg);
+ if (cb_retval == 0)
+ {
+ SSLerr(SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA, ERR_R_SSL_LIB);
+ goto f_err;
+ }
+ }
}
-
- authz += len;
- i += len;
+ p+=supp_data_entry_len;
}
-
- s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B;
- s->init_num = length;
- s->init_off = 0;
-
- return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+ return 1;
+f_err:
+ ssl3_send_alert(s,SSL3_AL_FATAL,al);
+ return -1;
}
#endif
diff --git a/ssl/ssl.h b/ssl/ssl.h
index a2f32d2c34..2f590fe5de 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -433,6 +433,58 @@ typedef struct {
custom_srv_ext_second_cb_fn fn2;
void *arg;
} custom_srv_ext_record;
+
+/* Callbacks and structures for handling Supplemental Data:
+ * srv_supp_data_first_cb_fn - server sends Supplemental Data
+ * srv_supp_data_second_cb_fn - server receives Supplemental Data
+ * cli_supp_data_first_cb_fn - client receives Supplemental Data
+ * cli_supp_data_second_cb_fn - client sends Supplemental Data
+ *
+ * All these functions return nonzero on success. Zero will terminate
+ * the handshake (and return a specific TLS Fatal alert, if the function
+ * declaration has an "al" parameter). -1 for the "sending" functions
+ * will result in no supplemental data entry being added to the
+ * supplemental data message for the provided supplemental data type.
+ *
+ * "supp_data_type" is a Supplemental Data Type from 0-65535.
+ * "in" is a pointer to TLS "supplemental_data_entry" being provided to the cb.
+ * "out" is used by the callback to return a pointer to "supplemental data"
+ * which OpenSSL will later copy into the TLS handshake. The contents
+ * of this buffer should not be changed until the handshake is complete.
+ * "inlen" and "outlen" are Supplemental Data lengths from 0-65535.
+ * "al" is a TLS "AlertDescription" from 0-255 which WILL be sent as a
+ * fatal TLS alert, if the callback returns zero.
+ */
+typedef int (*srv_supp_data_first_cb_fn)(SSL *s, unsigned short supp_data_type,
+ const unsigned char **out,
+ unsigned short *outlen, void *arg);
+typedef int (*srv_supp_data_second_cb_fn)(SSL *s, unsigned short supp_data_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg);
+
+typedef int (*cli_supp_data_first_cb_fn)(SSL *s, unsigned short supp_data_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg);
+typedef int (*cli_supp_data_second_cb_fn)(SSL *s, unsigned short supp_data_type,
+ const unsigned char **out,
+ unsigned short *outlen, void *arg);
+
+typedef struct {
+ unsigned short supp_data_type;
+ srv_supp_data_first_cb_fn fn1;
+ srv_supp_data_second_cb_fn fn2;
+ void *arg;
+} srv_supp_data_record;
+
+typedef struct {
+ unsigned short supp_data_type;
+ cli_supp_data_first_cb_fn fn1;
+ cli_supp_data_second_cb_fn fn2;
+ void *arg;
+} cli_supp_data_record;
+
#endif
#ifndef OPENSSL_NO_SSL_INTERN
@@ -597,13 +649,6 @@ struct ssl_session_st
#ifndef OPENSSL_NO_SRP
char *srp_username;
#endif
-#ifndef OPENSSL_NO_TLSEXT
- /* Used by client: the proof for this session.
- * We store it outside the sess_cert structure, since the proof
- * is received before the certificate. */
- unsigned char *audit_proof;
- size_t audit_proof_length;
-#endif
};
#endif
@@ -1149,8 +1194,6 @@ struct ssl_ctx_st
size_t tlsext_ellipticcurvelist_length;
unsigned char *tlsext_ellipticcurvelist;
# endif /* OPENSSL_NO_EC */
- int (*tlsext_authz_server_audit_proof_cb)(SSL *s, void *arg);
- void *tlsext_authz_server_audit_proof_cb_arg;
#endif
/* Arrays containing the callbacks for custom TLS Extensions. */
@@ -1158,6 +1201,12 @@ struct ssl_ctx_st
size_t custom_cli_ext_records_count;
custom_srv_ext_record *custom_srv_ext_records;
size_t custom_srv_ext_records_count;
+
+ /* Arrays containing the callbacks for Supplemental Data. */
+ cli_supp_data_record *cli_supp_data_records;
+ size_t cli_supp_data_records_count;
+ srv_supp_data_record *srv_supp_data_records;
+ size_t srv_supp_data_records_count;
};
#endif
@@ -1304,6 +1353,31 @@ int SSL_CTX_set_custom_cli_ext(SSL_CTX *ctx, unsigned short ext_type,
int SSL_CTX_set_custom_srv_ext(SSL_CTX *ctx, unsigned short ext_type,
custom_srv_ext_first_cb_fn fn1,
custom_srv_ext_second_cb_fn fn2, void *arg);
+
+/* Register callbacks to handle Supplemental Data as client or server.
+ *
+ * For SSL_CTX_set_srv_supp_data, a NULL srv_supp_data_first_cb_fn results in no supplemental data
+ * being sent by the server for that TLS extension.
+ * A NULL srv_supp_data_second_cb_fn results in no supplemental data
+ * being received by the server for that TLS extension.
+ *
+ * For SSL_CTX_set_cli_supp_data, a NULL cli_supp_data_first_cb_fn results in no supplemental data
+ * being received by the client for that TLS extension.
+ * A NULL cli_supp_data_second_cb_fn results in no supplemental data
+ * being sent by the client for that TLS extension.
+ *
+ * Returns nonzero on success. You cannot register twice for the same supp_data_type.
+ */
+int SSL_CTX_set_srv_supp_data(SSL_CTX *ctx,
+ unsigned short supp_data_type,
+ srv_supp_data_first_cb_fn fn1,
+ srv_supp_data_second_cb_fn fn2, void *arg);
+
+int SSL_CTX_set_cli_supp_data(SSL_CTX *ctx,
+ unsigned short supp_data_type,
+ cli_supp_data_first_cb_fn fn1,
+ cli_supp_data_second_cb_fn fn2, void *arg);
+
#endif
#define SSL_NOTHING 1
@@ -1825,9 +1899,6 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING 86
#define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS 87
#endif
-/* Callback for verifying audit proofs (client only) */
-#define SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB 95
-#define SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG 96
#endif /* OPENSSL_NO_TLSEXT */
#define DTLS_CTRL_GET_TIMEOUT 73
@@ -2099,17 +2170,6 @@ int SSL_use_certificate(SSL *ssl, X509 *x);
int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
#ifndef OPENSSL_NO_TLSEXT
-/* Set authz data for the current active cert. */
-int SSL_CTX_use_authz(SSL_CTX *ctx, unsigned char *authz, size_t authz_length);
-int SSL_use_authz(SSL *ssl, unsigned char *authz, size_t authz_length);
-/* Get the authz of type 'type' associated with the current active cert. */
-const unsigned char *SSL_CTX_get_authz_data(SSL_CTX *ctx, unsigned char type,
- size_t *data_length);
-#ifndef OPENSSL_NO_STDIO
-int SSL_CTX_use_authz_file(SSL_CTX *ctx, const char *file);
-int SSL_use_authz_file(SSL *ssl, const char *file);
-#endif
-
/* Set serverinfo data for the current active cert. */
int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
size_t serverinfo_length);
@@ -2163,10 +2223,6 @@ int SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
#ifndef OPENSSL_NO_BIO
int SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses);
#endif
-#ifndef OPENSSL_NO_TLSEXT
-unsigned char *SSL_SESSION_get_tlsext_authz_server_audit_proof(SSL_SESSION *s,
- size_t *proof_length);
-#endif
void SSL_SESSION_free(SSL_SESSION *ses);
int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
int SSL_set_session(SSL *to, SSL_SESSION *session);
@@ -2507,9 +2563,7 @@ void ERR_load_SSL_strings(void);
/* Error codes for the SSL functions. */
/* Function codes. */
-#define SSL_F_AUTHZ_FIND_DATA 330
-#define SSL_F_AUTHZ_VALIDATE 323
-#define SSL_F_CHECK_SUITEB_CIPHER_LIST 331
+#define SSL_F_CHECK_SUITEB_CIPHER_LIST 335
#define SSL_F_CLIENT_CERTIFICATE 100
#define SSL_F_CLIENT_FINISHED 167
#define SSL_F_CLIENT_HELLO 101
@@ -2552,7 +2606,6 @@ void ERR_load_SSL_strings(void);
#define SSL_F_GET_SERVER_HELLO 109
#define SSL_F_GET_SERVER_VERIFY 110
#define SSL_F_I2D_SSL_SESSION 111
-#define SSL_F_READ_AUTHZ 329
#define SSL_F_READ_N 112
#define SSL_F_REQUEST_CERTIFICATE 113
#define SSL_F_SERVER_FINISH 239
@@ -2658,7 +2711,6 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219
#define SSL_F_SSL_CTX_SET_SSL_VERSION 170
#define SSL_F_SSL_CTX_SET_TRUST 229
-#define SSL_F_SSL_CTX_USE_AUTHZ 324
#define SSL_F_SSL_CTX_USE_CERTIFICATE 171
#define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172
#define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE 220
@@ -2700,7 +2752,6 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_SESSION_PRINT_FP 190
#define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312
#define SSL_F_SSL_SESS_CERT_NEW 225
-#define SSL_F_SSL_SET_AUTHZ 325
#define SSL_F_SSL_SET_CERT 191
#define SSL_F_SSL_SET_CIPHER_LIST 271
#define SSL_F_SSL_SET_FD 192
@@ -2717,7 +2768,6 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_UNDEFINED_CONST_FUNCTION 243
#define SSL_F_SSL_UNDEFINED_FUNCTION 197
#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244
-#define SSL_F_SSL_USE_AUTHZ 328
#define SSL_F_SSL_USE_CERTIFICATE 198
#define SSL_F_SSL_USE_CERTIFICATE_ASN1 199
#define SSL_F_SSL_USE_CERTIFICATE_FILE 200
@@ -2737,18 +2787,19 @@ void ERR_load_SSL_strings(void);
#define SSL_F_TLS1_ENC 210
#define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314
#define SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA 326
+#define SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA 336
#define SSL_F_TLS1_HEARTBEAT 315
#define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT 275
#define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT 276
#define SSL_F_TLS1_PRF 284
#define SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA 327
+#define SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA 333
#define SSL_F_TLS1_SETUP_KEY_BLOCK 211
#define SSL_F_WRITE_PENDING 212
/* Reason codes. */
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272
-#define SSL_R_AUTHZ_DATA_TOO_LARGE 375
#define SSL_R_BAD_ALERT_RECORD 101
#define SSL_R_BAD_AUTHENTICATION_TYPE 102
#define SSL_R_BAD_CHANGE_CIPHER_SPEC 103
@@ -2841,8 +2892,6 @@ void ERR_load_SSL_strings(void);
#define SSL_R_ILLEGAL_PADDING 283
#define SSL_R_ILLEGAL_SUITEB_DIGEST 380
#define SSL_R_INCONSISTENT_COMPRESSION 340