X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fs3_srvr.c;h=b372a9a58c8e200cbe173c8c581a72b2de772eda;hp=632b924ef24066e316244087d3660fc21a4f0b20;hb=aeda172afd37e6f7b2f285b5f18a5978415cbc9b;hpb=09e4e4b98e40b4283d2405ba418d6e2876f4448d diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 632b924ef2..b372a9a58c 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -152,7 +152,6 @@ #define NETSCAPE_HANG_BUG #include -#include #include "ssl_locl.h" #include "kssl_lcl.h" #include @@ -181,7 +180,7 @@ static const SSL_METHOD *ssl3_get_server_method(int ver) } #ifndef OPENSSL_NO_SRP -static int ssl_check_srp_ext_ClientHello(SSL *s,int *al) +static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) { int ret = SSL_ERROR_NONE; @@ -403,9 +402,30 @@ int ssl3_accept(SSL *s) s->state=SSL3_ST_SW_CHANGE_A; #endif else - s->state=SSL3_ST_SW_CERT_A; - s->init_num=0; +#ifndef OPENSSL_NO_TLSEXT + s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_A; +#else + s->state = SSL3_ST_SW_CERT_A; +#endif + s->init_num = 0; + break; + +#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; + + s->state = SSL3_ST_SW_CERT_A; + s->init_num = 0; break; +#endif case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_B: @@ -3562,7 +3582,7 @@ int ssl3_send_cert_status(SSL *s) return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); } -# ifndef OPENSSL_NO_NPN +# ifndef OPENSSL_NO_NEXTPROTONEG /* ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. It * sets the next_proto member in s if found */ int ssl3_get_next_proto(SSL *s) @@ -3629,4 +3649,99 @@ int ssl3_get_next_proto(SSL *s) return 1; } # endif + +int tls1_send_server_supplemental_data(SSL *s) + { + 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); + + orig_authz = authz = ssl_get_authz_data(s, &authz_length); + if (authz == NULL) + { + /* This should never occur. */ + return 0; + } + + /* 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; + + 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) + length += 1 /* authz type */ + 2 /* length */ + len; + + authz += len; + i += len; + } + + length += 1 /* handshake type */ + + 3 /* handshake length */ + + 3 /* supplemental data length */ + + 2 /* supplemental entry type */ + + 2 /* supplemental entry length */; + + if (!BUF_MEM_grow_clean(s->init_buf, length)) + { + 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; + /* 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++) + { + 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) + { + *(p++) = type; + s2n(len, p); + memcpy(p, authz, len); + p += len; + } + + authz += len; + i += 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); + } #endif