diff options
author | Scott Deboy <sdeboy@secondstryke.com> | 2013-06-18 14:34:38 -0700 |
---|---|---|
committer | Scott Deboy <sdeboy@secondstryke.com> | 2014-02-08 16:12:15 -0800 |
commit | 038bec784e528ce273169f178c35991fbc3bea92 (patch) | |
tree | be8a71c2c534db29ea7ee31f1207be9b976b0698 /ssl | |
parent | f407eec799f1f5d271b809875f016f680935567b (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.c | 4 | ||||
-rw-r--r-- | ssl/s3_clnt.c | 239 | ||||
-rw-r--r-- | ssl/s3_lib.c | 17 | ||||
-rw-r--r-- | ssl/s3_srvr.c | 238 | ||||
-rw-r--r-- | ssl/ssl.h | 124 | ||||
-rw-r--r-- | ssl/ssl3.h | 36 | ||||
-rw-r--r-- | ssl/ssl_cert.c | 22 | ||||
-rw-r--r-- | ssl/ssl_err.c | 12 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 85 | ||||
-rw-r--r-- | ssl/ssl_locl.h | 13 | ||||
-rw-r--r-- | ssl/ssl_rsa.c | 233 | ||||
-rw-r--r-- | ssl/ssl_sess.c | 11 | ||||
-rw-r--r-- | ssl/ssl_stat.c | 8 | ||||
-rw-r--r-- | ssl/ssltest.c | 141 | ||||
-rw-r--r-- | ssl/t1_lib.c | 193 | ||||
-rw-r--r-- | ssl/tls1.h | 14 |
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 @@ -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 -#define SSL_R_INVALID_AUDIT_PROOF 371 -#define SSL_R_INVALID_AUTHZ_DATA 374 #define SSL_R_INVALID_CHALLENGE_LENGTH 158 #define SSL_R_INVALID_COMMAND 280 #define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 @@ -3032,7 +3081,6 @@ void ERR_load_SSL_strings(void); #define SSL_R_UNEXPECTED_RECORD 245 #define SSL_R_UNINITIALIZED 276 #define SSL_R_UNKNOWN_ALERT_TYPE 246 -#define SSL_R_UNKNOWN_AUTHZ_DATA_TYPE 372 #define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247 #define SSL_R_UNKNOWN_CIPHER_RETURNED 248 #define SSL_R_UNKNOWN_CIPHER_TYPE 249 diff --git a/ssl/ssl3.h b/ssl/ssl3.h index e2a58c30cc..6e7bd0f62c 100644 - |