提交 36086186 编写于 作者: S Scott Deboy 提交者: Ben Laurie

Add callbacks supporting generation and retrieval of supplemental data...

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.
上级 cda01d55
......@@ -4,6 +4,10 @@
Changes between 1.0.x and 1.1.0 [xx XXX xxxx]
*) Add callbacks supporting generation and retrieval of supplemental
data entries.
[Scott Deboy <sdeboy@apache.org>, Trevor Perrin and Ben Laurie]
*) Add EVP support for key wrapping algorithms, to avoid problems with
existing code the flag EVP_CIPHER_CTX_WRAP_ALLOW has to be set in
the EVP_CIPHER_CTX or an error is returned. Add AES and DES3 wrap
......
......@@ -593,6 +593,7 @@ my %table=(
"darwin64-ppc-cc","cc:-arch ppc64 -O3 -DB_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc64_asm}:osx64:dlfcn:darwin-shared:-fPIC -fno-common:-arch ppc64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"darwin-i386-cc","cc:-arch i386 -O3 -fomit-frame-pointer -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:".eval{my $asm=$x86_asm;$asm=~s/cast\-586\.o//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"debug-darwin-i386-cc","cc:-arch i386 -g3 -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:${x86_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"debug-darwin64-x86_64-cc","cc:-arch x86_64 -ggdb -g2 -O0 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"darwin64-x86_64-cc","cc:-arch x86_64 -O3 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"debug-darwin-ppc-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DB_ENDIAN -g -Wall -O::-D_REENTRANT:MACOSX::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
# iPhoneOS/iOS
......
......@@ -156,10 +156,6 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
STACK_OF(X509) *chain, int build_chain);
# ifndef OPENSSL_NO_TLSEXT
int set_cert_key_and_authz(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
unsigned char *authz, size_t authz_length);
# endif
int ssl_print_sigalgs(BIO *out, SSL *s);
int ssl_print_point_formats(BIO *out, SSL *s);
int ssl_print_curves(BIO *out, SSL *s, int noshared);
......
......@@ -876,6 +876,9 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *
case 16:
str_details1 = ", ClientKeyExchange";
break;
case 23:
str_details1 = ", SupplementalData";
break;
case 20:
str_details1 = ", Finished";
break;
......
......@@ -203,7 +203,6 @@ static int c_debug=0;
#ifndef OPENSSL_NO_TLSEXT
static int c_tlsextdebug=0;
static int c_status_req=0;
static int c_proof_debug=0;
#endif
static int c_msg=0;
static int c_showcerts=0;
......@@ -215,7 +214,8 @@ static void sc_usage(void);
static void print_stuff(BIO *berr,SSL *con,int full);
#ifndef OPENSSL_NO_TLSEXT
static int ocsp_resp_cb(SSL *s, void *arg);
static int audit_proof_cb(SSL *s, void *arg);
static int c_auth = 0;
static int c_auth_require_reneg = 0;
#endif
static BIO *bio_c_out=NULL;
static BIO *bio_c_msg=NULL;
......@@ -223,6 +223,35 @@ static int c_quiet=0;
static int c_ign_eof=0;
static int c_brief=0;
#ifndef OPENSSL_NO_TLSEXT
static const unsigned char *most_recent_supplemental_data;
static size_t most_recent_supplemental_data_length;
static int server_provided_server_authz = 0;
static int server_provided_client_authz = 0;
static const unsigned char auth_ext_data[]={TLSEXT_AUTHZDATAFORMAT_dtcp};
static int suppdata_cb(SSL *s, unsigned short supp_data_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg);
static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
const unsigned char **out,
unsigned short *outlen, void *arg);
static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, unsigned short *outlen,
void *arg);
static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg);
#endif
#ifndef OPENSSL_NO_PSK
/* Default PSK identity and key */
static char *psk_identity="Client_identity";
......@@ -362,14 +391,13 @@ static void sc_usage(void)
BIO_printf(bio_err," -tlsextdebug - hex dump of all TLS extensions received\n");
BIO_printf(bio_err," -status - request certificate status from server\n");
BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n");
BIO_printf(bio_err," -proof_debug - request an audit proof and print its hex dump\n");
BIO_printf(bio_err," -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n");
BIO_printf(bio_err," -auth - send and receive RFC 5878 TLS auth extensions and supplemental data\n");
BIO_printf(bio_err," -auth_require_reneg - Do not send TLS auth extensions until renegotiation\n");
# ifndef OPENSSL_NO_NEXTPROTONEG
BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
BIO_printf(bio_err," -alpn arg - enable ALPN extension, considering named protocols supported (comma-separated list)\n");
# endif
#ifndef OPENSSL_NO_TLSEXT
BIO_printf(bio_err," -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n");
#endif
#endif
BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
......@@ -823,8 +851,10 @@ static char *jpake_secret = NULL;
c_tlsextdebug=1;
else if (strcmp(*argv,"-status") == 0)
c_status_req=1;
else if (strcmp(*argv,"-proof_debug") == 0)
c_proof_debug=1;
else if (strcmp(*argv,"-auth") == 0)
c_auth = 1;
else if (strcmp(*argv,"-auth_require_reneg") == 0)
c_auth_require_reneg = 1;
#endif
#ifdef WATT32
else if (strcmp(*argv,"-wdebug") == 0)
......@@ -1399,9 +1429,12 @@ bad:
}
#endif
if (c_proof_debug)
SSL_CTX_set_tlsext_authz_server_audit_proof_cb(ctx,
audit_proof_cb);
if (c_auth)
{
SSL_CTX_set_custom_cli_ext(ctx, TLSEXT_TYPE_client_authz, authz_tlsext_generate_cb, authz_tlsext_cb, bio_err);
SSL_CTX_set_custom_cli_ext(ctx, TLSEXT_TYPE_server_authz, authz_tlsext_generate_cb, authz_tlsext_cb, bio_err);
SSL_CTX_set_cli_supp_data(ctx, TLSEXT_SUPPLEMENTALDATATYPE_authz_data, suppdata_cb, auth_suppdata_generate_cb, bio_err);
}
#endif
con=SSL_new(ctx);
......@@ -2395,26 +2428,76 @@ static int ocsp_resp_cb(SSL *s, void *arg)
return 1;
}
static int audit_proof_cb(SSL *s, void *arg)
static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg)
{
const unsigned char *proof;
size_t proof_len;
size_t i;
SSL_SESSION *sess = SSL_get_session(s);
proof = SSL_SESSION_get_tlsext_authz_server_audit_proof(sess,
&proof_len);
if (proof != NULL)
if (TLSEXT_TYPE_server_authz == ext_type)
{
BIO_printf(bio_c_out, "Audit proof: ");
for (i = 0; i < proof_len; ++i)
BIO_printf(bio_c_out, "%02X", proof[i]);
BIO_printf(bio_c_out, "\n");
server_provided_server_authz = (memchr(in,
TLSEXT_AUTHZDATAFORMAT_dtcp,
inlen) != NULL);
}
else
if (TLSEXT_TYPE_client_authz == ext_type)
{
server_provided_client_authz = (memchr(in,
TLSEXT_AUTHZDATAFORMAT_dtcp,
inlen) != NULL);
}
return 1;
}
static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, unsigned short *outlen,
void *arg)
{
if (c_auth)
{
BIO_printf(bio_c_out, "No audit proof found.\n");
if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s)))
{
*out = auth_ext_data;
*outlen = 1;
return 1;
}
}
//no auth extension to send
return -1;
}
static int suppdata_cb(SSL *s, unsigned short supp_data_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg)
{
if (supp_data_type == TLSEXT_SUPPLEMENTALDATATYPE_authz_data)
{
most_recent_supplemental_data = in;
most_recent_supplemental_data_length = inlen;
}
return 1;
}
static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
const unsigned char **out,
unsigned short *outlen, void *arg)
{
unsigned char *result;
if (c_auth && server_provided_client_authz && server_provided_server_authz)
{
if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s)))
{
result = OPENSSL_malloc(10);
memcpy(result, "5432154321", 10);
*out = result;
*outlen = 10;
return 1;
}
}
//no supplemental data to send
return -1;
}
#endif
......@@ -225,6 +225,18 @@ static DH *get_dh512(void);
static void s_server_init(void);
#endif
#ifndef OPENSSL_NO_TLSEXT
static const unsigned char auth_ext_data[]={TLSEXT_AUTHZDATAFORMAT_dtcp};
static const unsigned char *most_recent_supplemental_data;
static size_t most_recent_supplemental_data_length;
static int client_provided_server_authz = 0;
static int client_provided_client_authz = 0;
#endif
#ifndef OPENSSL_NO_DH
static unsigned char dh512_p[]={
0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
......@@ -316,10 +328,29 @@ static int cert_chain = 0;
#endif
#ifndef OPENSSL_NO_TLSEXT
static BIO *authz_in = NULL;
static const char *s_authz_file = NULL;
static int suppdata_cb(SSL *s, unsigned short supp_data_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg);
static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
const unsigned char **out,
unsigned short *outlen, void *arg);
static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, unsigned short *outlen,
void *arg);
static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg);
static BIO *serverinfo_in = NULL;
static const char *s_serverinfo_file = NULL;
static int c_auth = 0;
static int c_auth_require_reneg = 0;
#endif
#ifndef OPENSSL_NO_PSK
......@@ -480,10 +511,12 @@ static void sv_usage(void)
BIO_printf(bio_err," -Verify arg - turn on peer certificate verification, must have a cert.\n");
BIO_printf(bio_err," -cert arg - certificate file to use\n");
BIO_printf(bio_err," (default is %s)\n",TEST_CERT);
BIO_printf(bio_err," -authz arg - binary authz file for certificate\n");
#ifndef OPENSSL_NO_TLSEXT
BIO_printf(bio_err," -serverinfo arg - PEM serverinfo file for certificate\n");
BIO_printf(bio_err," -auth - send and receive RFC 5878 TLS auth extensions and supplemental data\n");
BIO_printf(bio_err," -auth_require_reneg - Do not send TLS auth extensions until renegotiation\n");
#endif
BIO_printf(bio_err," -no_resumption_on_reneg - set SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION flag\n");
BIO_printf(bio_err," -crl_check - check the peer certificate has not been revoked by its CA.\n" \
" The CRL(s) are appended to the certificate file\n");
BIO_printf(bio_err," -crl_check_all - check the peer certificate has not been revoked by its CA\n" \
......@@ -1023,6 +1056,7 @@ int MAIN(int argc, char *argv[])
EVP_PKEY *s_key = NULL, *s_dkey = NULL;
int no_cache = 0, ext_cache = 0;
int rev = 0, naccept = -1;
int c_no_resumption_on_reneg = 0;
#ifndef OPENSSL_NO_TLSEXT
EVP_PKEY *s_key2 = NULL;
X509 *s_cert2 = NULL;
......@@ -1137,17 +1171,24 @@ int MAIN(int argc, char *argv[])
else if (strcmp(*argv,"-crl_download") == 0)
crl_download = 1;
#ifndef OPENSSL_NO_TLSEXT
else if (strcmp(*argv,"-authz") == 0)
{
if (--argc < 1) goto bad;
s_authz_file = *(++argv);
}
else if (strcmp(*argv,"-serverinfo") == 0)
{
if (--argc < 1) goto bad;
s_serverinfo_file = *(++argv);
}
else if (strcmp(*argv,"-auth") == 0)
{
c_auth = 1;
}
#endif
else if (strcmp(*argv, "-no_resumption_on_reneg") == 0)
{
c_no_resumption_on_reneg = 1;
}
else if (strcmp(*argv,"-auth_require_reneg") == 0)
{
c_auth_require_reneg = 1;
}
else if (strcmp(*argv,"-certform") == 0)
{
if (--argc < 1) goto bad;
......@@ -1920,14 +1961,22 @@ bad:
}
#endif
if (c_no_resumption_on_reneg)
{
SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
}
if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain))
goto end;
#ifndef OPENSSL_NO_TLSEXT
if (s_authz_file != NULL && !SSL_CTX_use_authz_file(ctx, s_authz_file))
goto end;
if (s_serverinfo_file != NULL
&& !SSL_CTX_use_serverinfo_file(ctx, s_serverinfo_file))
goto end;
if (c_auth)
{
SSL_CTX_set_custom_srv_ext(ctx, TLSEXT_TYPE_client_authz, authz_tlsext_cb, authz_tlsext_generate_cb, bio_err);
SSL_CTX_set_custom_srv_ext(ctx, TLSEXT_TYPE_server_authz, authz_tlsext_cb, authz_tlsext_generate_cb, bio_err);
SSL_CTX_set_srv_supp_data(ctx, TLSEXT_SUPPLEMENTALDATATYPE_authz_data, auth_suppdata_generate_cb, suppdata_cb, bio_err);
}
#endif
#ifndef OPENSSL_NO_TLSEXT
if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2, NULL, build_chain))
......@@ -2105,8 +2154,6 @@ end:
X509_free(s_cert2);
if (s_key2)
EVP_PKEY_free(s_key2);
if (authz_in != NULL)
BIO_free(authz_in);
if (serverinfo_in != NULL)
BIO_free(serverinfo_in);
if (next_proto.data)
......@@ -3514,3 +3561,78 @@ static void free_sessions(void)
}
first = NULL;
}
#ifndef OPENSSL_NO_TLSEXT
static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg)
{
if (TLSEXT_TYPE_server_authz == ext_type)
{
client_provided_server_authz = (memchr(in,
TLSEXT_AUTHZDATAFORMAT_dtcp,
inlen) != NULL);
}
if (TLSEXT_TYPE_client_authz == ext_type)
{
client_provided_client_authz = (memchr(in,
TLSEXT_AUTHZDATAFORMAT_dtcp,
inlen) != NULL);
}
return 1;
}
static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, unsigned short *outlen,
void *arg)
{
if (c_auth && client_provided_client_authz && client_provided_server_authz)
{
if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s)))
{
*out = auth_ext_data;
*outlen = 1;
return 1;
}
}
//no auth extension to send
return -1;
}
static int suppdata_cb(SSL *s, unsigned short supp_data_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg)
{
if (supp_data_type == TLSEXT_SUPPLEMENTALDATATYPE_authz_data)
{
most_recent_supplemental_data = in;
most_recent_supplemental_data_length = inlen;
}
return 1;
}
static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
const unsigned char **out,
unsigned short *outlen, void *arg)
{
unsigned char *result;
if (c_auth && client_provided_client_authz && client_provided_server_authz)
{
if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s)))
{
result = OPENSSL_malloc(10);
memcpy(result, "1234512345", 10);
*out = result;
*outlen = 10;
return 1;
}
}
//no supplemental data to send
return -1;
}
#endif
......@@ -212,12 +212,12 @@
#undef tls1_send_server_supplemental_data
#define tls1_send_server_supplemental_data tls1_send_server_suppl_data
#undef tls1_send_client_supplemental_data
#define tls1_send_client_supplemental_data tls1_send_client_suppl_data
#undef tls1_get_server_supplemental_data
#define tls1_get_server_supplemental_data tls1_get_server_suppl_data
#undef SSL_SESSION_get_tlsext_authz_server_audit_proof
#define SSL_SESSION_get_tlsext_authz_server_audit_proof \
S_SES_get_tlsx_auz_srvr_aud_prf
#undef tls1_get_client_supplemental_data
#define tls1_get_client_supplemental_data tls1_get_client_suppl_data
/* Hack some long ENGINE names */
#undef ENGINE_get_default_BN_mod_exp_crt
......
......@@ -45,6 +45,8 @@ B<openssl> B<s_client>
[B<-sess_in filename>]
[B<-rand file(s)>]
[B<-serverinfo types>]
[B<-auth>]
[B<-auth_require_reneg>]
=head1 DESCRIPTION
......@@ -272,6 +274,15 @@ a list of comma-separated TLS Extension Types (numbers between 0 and
The server's response (if any) will be encoded and displayed as a PEM
file.
=item B<-auth>
send RFC 5878 client and server authorization extensions in the Client Hello as well as
supplemental data if the server also sent the authorization extensions in the Server Hello.
=item B<-auth_require_reneg>
only send RFC 5878 client and server authorization extensions during renegotiation.
=back
=head1 CONNECTED COMMANDS
......
......@@ -57,7 +57,9 @@ B<openssl> B<s_server>
[B<-id_prefix arg>]
[B<-rand file(s)>]
[B<-serverinfo file>]
[B<-auth>]
[B<-auth_require_reneg>]
[B<-no_resumption_on_reneg>]
=head1 DESCRIPTION
The B<s_server> command implements a generic SSL/TLS server which listens
......@@ -315,6 +317,20 @@ followed by "length" bytes of extension data). If the client sends
an empty TLS ClientHello extension matching the type, the corresponding
ServerHello extension will be returned.
=item B<-auth>
send RFC 5878 client and server authorization extensions in the Client Hello as well as
supplemental data if the server also sent the authorization extensions in the Server Hello.
=item B<-auth_require_reneg>
only send RFC 5878 client and server authorization extensions during renegotiation.
=item B<-no_resumption_on_reneg>
set SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION flag. Required in order to receive supplemental data
during renegotiation if auth and auth_require_reneg are set.
=back
=head1 CONNECTED COMMANDS
......
......@@ -340,10 +340,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
......
......@@ -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,
......@@ -1357,21 +1373,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)
{
......@@ -3563,11 +3564,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,
......@@ -3576,6 +3575,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;
......@@ -3603,15 +3610,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,
......@@ -3624,7 +3715,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)
{
......@@ -3632,72 +3723,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);
......
......@@ -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);
......@@ -3892,10 +3885,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 :-) */
......@@ -4005,12 +3994,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
case SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB:
{
......
......@@ -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
......@@ -3686,98 +3699,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
......@@ -596,13 +648,6 @@ struct ssl_session_st
#endif
#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
};
......@@ -1138,14 +1183,17 @@ 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;
/* Arrays containing the callbacks for custom TLS Extensions. */
custom_cli_ext_record *custom_cli_ext_records;
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
......@@ -1291,6 +1339,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
......@@ -1812,9 +1885,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
......@@ -2052,17 +2122,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);
......@@ -2116,10 +2175,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);
......@@ -2454,8 +2509,6 @@ 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 335
#define SSL_F_CLIENT_CERTIFICATE 100
#define SSL_F_CLIENT_FINISHED 167
......@@ -2499,7 +2552,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
......@@ -2605,7 +2657,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
......@@ -2646,7 +2697,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
......@@ -2663,7 +2713,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
......@@ -2683,18 +2732,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
......@@ -2786,8 +2836,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
......@@ -2975,7 +3023,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
......
......@@ -564,20 +564,6 @@ typedef struct ssl3_state_st
#endif
#ifndef OPENSSL_NO_TLSEXT
/* tlsext_authz_client_types contains an array of supported authz
* types, as advertised by the client. The array is sorted and
* does not contain any duplicates. */
unsigned char *tlsext_authz_client_types;
size_t tlsext_authz_client_types_len;
/* tlsext_authz_promised_to_client is true iff we're a server and we
* echoed the client's supplemental data extension and therefore must
* send a supplemental data handshake message. */
char tlsext_authz_promised_to_client;
/* tlsext_authz_server_promised is true iff we're a client and the
* server echoed our server_authz extension and therefore must send us
* a supplemental data handshake message. */
char tlsext_authz_server_promised;
/* tlsext_custom_types contains an array of TLS Extension types which
* were advertised by the client in its ClientHello, which were not
* otherwise handled by OpenSSL, and which the server has registered
......@@ -633,8 +619,10 @@ typedef struct ssl3_state_st
#define SSL3_ST_CR_CERT_REQ_B (0x151|SSL_ST_CONNECT)
#define SSL3_ST_CR_SRVR_DONE_A (0x160|SSL_ST_CONNECT)
#define SSL3_ST_CR_SRVR_DONE_B (0x161|SSL_ST_CONNECT)
#define SSL3_ST_CR_SUPPLEMENTAL_DATA_A (0x210|SSL_ST_CONNECT)
#define SSL3_ST_CR_SUPPLEMENTAL_DATA_B (0x211|SSL_ST_CONNECT)
#ifndef OPENSSL_NO_TLSEXT
#define SSL3_ST_CR_SUPPLEMENTAL_DATA_A (0x212|SSL_ST_CONNECT)
#define SSL3_ST_CR_SUPPLEMENTAL_DATA_B (0x213|SSL_ST_CONNECT)
#endif
/* write to server */
#define SSL3_ST_CW_CERT_A (0x170|SSL_ST_CONNECT)
#define SSL3_ST_CW_CERT_B (0x171|SSL_ST_CONNECT)
......@@ -649,6 +637,10 @@ typedef struct ssl3_state_st
#ifndef OPENSSL_NO_NEXTPROTONEG
#define SSL3_ST_CW_NEXT_PROTO_A (0x200|SSL_ST_CONNECT)
#define SSL3_ST_CW_NEXT_PROTO_B (0x201|SSL_ST_CONNECT)
#ifndef OPENSSL_NO_TLSEXT
#define SSL3_ST_CW_SUPPLEMENTAL_DATA_A (0x222|SSL_ST_CONNECT)
#define SSL3_ST_CW_SUPPLEMENTAL_DATA_B (0x223|SSL_ST_CONNECT)
#endif
#endif
#define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT)
#define SSL3_ST_CW_FINISHED_B (0x1B1|SSL_ST_CONNECT)
......@@ -674,6 +666,10 @@ typedef struct ssl3_state_st
#define SSL3_ST_SR_CLNT_HELLO_A (0x110|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT)
#ifndef OPENSSL_NO_TLSEXT
#define SSL3_ST_SR_SUPPLEMENTAL_DATA_A (0x212|SSL_ST_ACCEPT)
#define SSL3_ST_SR_SUPPLEMENTAL_DATA_B (0x213|SSL_ST_ACCEPT)
#endif
/* write to client */
#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)
......@@ -714,8 +710,10 @@ typedef struct ssl3_state_st
#define SSL3_ST_SW_SESSION_TICKET_B (0x1F1|SSL_ST_ACCEPT)
#define SSL3_ST_SW_CERT_STATUS_A (0x200|SSL_ST_ACCEPT)
#define SSL3_ST_SW_CERT_STATUS_B (0x201|SSL_ST_ACCEPT)
#define SSL3_ST_SW_SUPPLEMENTAL_DATA_A (0x220|SSL_ST_ACCEPT)
#define SSL3_ST_SW_SUPPLEMENTAL_DATA_B (0x221|SSL_ST_ACCEPT)
#ifndef OPENSSL_NO_TLSEXT
#define SSL3_ST_SW_SUPPLEMENTAL_DATA_A (0x222|SSL_ST_ACCEPT)
#define SSL3_ST_SW_SUPPLEMENTAL_DATA_B (0x223|SSL_ST_ACCEPT)
#endif
#define SSL3_MT_HELLO_REQUEST 0
#define SSL3_MT_CLIENT_HELLO 1
......@@ -729,7 +727,9 @@ typedef struct ssl3_state_st
#define SSL3_MT_CLIENT_KEY_EXCHANGE 16
#define SSL3_MT_FINISHED 20
#define SSL3_MT_CERTIFICATE_STATUS 22
#ifndef OPENSSL_NO_TLSEXT
#define SSL3_MT_SUPPLEMENTAL_DATA 23
#endif
#ifndef OPENSSL_NO_NEXTPROTONEG
#define SSL3_MT_NEXT_PROTO 67
#endif
......
......@@ -330,23 +330,6 @@ CERT *ssl_cert_dup(CERT *cert)
}
rpk->valid_flags = 0;
#ifndef OPENSSL_NO_TLSEXT
if (cert->pkeys[i].authz != NULL)
{
/* Just copy everything. */
ret->pkeys[i].authz_length =
cert->pkeys[i].authz_length;
ret->pkeys[i].authz =
OPENSSL_malloc(ret->pkeys[i].authz_length);
if (ret->pkeys[i].authz == NULL)
{
SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
return NULL;
}
memcpy(ret->pkeys[i].authz,
cert->pkeys[i].authz,
cert->pkeys[i].authz_length);
}
if (cert->pkeys[i].serverinfo != NULL)
{
/* Just copy everything. */
......@@ -479,11 +462,6 @@ void ssl_cert_clear_certs(CERT *c)
cpk->chain = NULL;
}
#ifndef OPENSSL_NO_TLSEXT
if (cpk->authz)
{
OPENSSL_free(cpk->authz);
cpk->authz = NULL;
}
if (cpk->serverinfo)
{
OPENSSL_free(cpk->serverinfo);
......
......@@ -70,8 +70,6 @@
static ERR_STRING_DATA SSL_str_functs[]=
{
{ERR_FUNC(SSL_F_AUTHZ_FIND_DATA), "AUTHZ_FIND_DATA"},
{ERR_FUNC(SSL_F_AUTHZ_VALIDATE), "AUTHZ_VALIDATE"},
{ERR_FUNC(SSL_F_CHECK_SUITEB_CIPHER_LIST), "CHECK_SUITEB_CIPHER_LIST"},
{ERR_FUNC(SSL_F_CLIENT_CERTIFICATE), "CLIENT_CERTIFICATE"},
{ERR_FUNC(SSL_F_CLIENT_FINISHED), "CLIENT_FINISHED"},
......@@ -115,7 +113,6 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_GET_SERVER_HELLO), "GET_SERVER_HELLO"},
{ERR_FUNC(SSL_F_GET_SERVER_VERIFY), "GET_SERVER_VERIFY"},
{ERR_FUNC(SSL_F_I2D_SSL_SESSION), "i2d_SSL_SESSION"},
{ERR_FUNC(SSL_F_READ_AUTHZ), "READ_AUTHZ"},
{ERR_FUNC(SSL_F_READ_N), "READ_N"},
{ERR_FUNC(SSL_F_REQUEST_CERTIFICATE), "REQUEST_CERTIFICATE"},
{ERR_FUNC(SSL_F_SERVER_FINISH), "SERVER_FINISH"},
......@@ -221,7 +218,6 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT), "SSL_CTX_set_session_id_context"},
{ERR_FUNC(SSL_F_SSL_CTX_SET_SSL_VERSION), "SSL_CTX_set_ssl_version"},
{ERR_FUNC(SSL_F_SSL_CTX_SET_TRUST), "SSL_CTX_set_trust"},
{ERR_FUNC(SSL_F_SSL_CTX_USE_AUTHZ), "SSL_CTX_use_authz"},
{ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE), "SSL_CTX_use_certificate"},
{ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1), "SSL_CTX_use_certificate_ASN1"},
{ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE), "SSL_CTX_use_certificate_chain_file"},
......@@ -262,7 +258,6 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"},
{ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT), "SSL_SESSION_set1_id_context"},
{ERR_FUNC(SSL_F_SSL_SESS_CERT_NEW), "ssl_sess_cert_new"},
{ERR_FUNC(SSL_F_SSL_SET_AUTHZ), "SSL_SET_AUTHZ"},
{ERR_FUNC(SSL_F_SSL_SET_CERT), "SSL_SET_CERT"},
{ERR_FUNC(SSL_F_SSL_SET_CIPHER_LIST), "SSL_set_cipher_list"},
{ERR_FUNC(SSL_F_SSL_SET_FD), "SSL_set_fd"},
......@@ -279,7 +274,6 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION), "ssl_undefined_const_function"},
{ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION), "ssl_undefined_function"},
{ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION), "ssl_undefined_void_function"},
{ERR_FUNC(SSL_F_SSL_USE_AUTHZ), "SSL_use_authz"},
{ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE), "SSL_use_certificate"},
{ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_ASN1), "SSL_use_certificate_ASN1"},
{ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_FILE), "SSL_use_certificate_file"},
......@@ -299,11 +293,13 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_TLS1_ENC), "tls1_enc"},
{ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL), "tls1_export_keying_material"},
{ERR_FUNC(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA), "tls1_get_server_supplemental_data"},
{ERR_FUNC(SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA), "tls1_get_client_supplemental_data"},
{ERR_FUNC(SSL_F_TLS1_HEARTBEAT), "tls1_heartbeat"},
{ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT), "TLS1_PREPARE_CLIENTHELLO_TLSEXT"},
{ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT), "TLS1_PREPARE_SERVERHELLO_TLSEXT"},
{ERR_FUNC(SSL_F_TLS1_PRF), "tls1_prf"},
{ERR_FUNC(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA), "tls1_send_server_supplemental_data"},
{ERR_FUNC(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA), "tls1_send_client_supplemental_data"},
{ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "tls1_setup_key_block"},
{ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"},
{0,NULL}
......@@ -313,7 +309,6 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{
{ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE) ,"app data in handshake"},
{ERR_REASON(SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT),"attempt to reuse session in different context"},
{ERR_REASON(SSL_R_AUTHZ_DATA_TOO_LARGE) ,"authz data too large"},
{ERR_REASON(SSL_R_BAD_ALERT_RECORD) ,"bad alert record"},
{ERR_REASON(SSL_R_BAD_AUTHENTICATION_TYPE),"bad authentication type"},
{ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC),"bad change cipher spec"},
......@@ -405,8 +400,6 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_ILLEGAL_PADDING) ,"illegal padding"},
{ERR_REASON(SSL_R_ILLEGAL_SUITEB_DIGEST) ,"illegal Suite B digest"},
{ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION),"inconsistent compression"},
{ERR_REASON(SSL_R_INVALID_AUDIT_PROOF) ,"invalid audit proof"},
{ERR_REASON(SSL_R_INVALID_AUTHZ_DATA) ,"invalid authz data"},
{ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"},
{ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"},
{ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"},
......@@ -594,7 +587,6 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_UNEXPECTED_RECORD) ,"unexpected record"},
{ERR_REASON(SSL_R_UNINITIALIZED) ,"uninitialized"},
{ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE) ,"unknown alert type"},
{ERR_REASON(SSL_R_UNKNOWN_AUTHZ_DATA_TYPE),"unknown authz data type"},
{ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE),"unknown certificate type"},
{ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED),"unknown cipher returned"},
{ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE) ,"unknown cipher type"},
......
......@@ -1840,6 +1840,66 @@ void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
else
*len = ssl->s3->alpn_selected_len;
}
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)
{
size_t i;
cli_supp_data_record* record;
/* Check for duplicates */
for (i=0; i < ctx->cli_supp_data_records_count; i++)
if (supp_data_type == ctx->cli_supp_data_records[i].supp_data_type)
return 0;
ctx->cli_supp_data_records = OPENSSL_realloc(ctx->cli_supp_data_records,
(ctx->cli_supp_data_records_count+1) * sizeof(cli_supp_data_record));
if (!ctx->cli_supp_data_records)
{
ctx->cli_supp_data_records_count = 0;
return 0;
}
ctx->cli_supp_data_records_count++;
record = &ctx->cli_supp_data_records[ctx->cli_supp_data_records_count - 1];
record->supp_data_type = supp_data_type;
record->fn1 = fn1;
record->fn2 = fn2;
record->arg = arg;
return 1;
}
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)
{
size_t i;
srv_supp_data_record* record;
/* Check for duplicates */
for (i=0; i < ctx->srv_supp_data_records_count; i++)
if (supp_data_type == ctx->srv_supp_data_records[i].supp_data_type)
return 0;
ctx->srv_supp_data_records = OPENSSL_realloc(ctx->srv_supp_data_records,
(ctx->srv_supp_data_records_count+1) * sizeof(srv_supp_data_record));
if (!ctx->srv_supp_data_records)
{
ctx->srv_supp_data_records_count = 0;
return 0;
}
ctx->srv_supp_data_records_count++;
record = &ctx->srv_supp_data_records[ctx->srv_supp_data_records_count - 1];
record->supp_data_type = supp_data_type;
record->fn1 = fn1;
record->fn2 = fn2;
record->arg = arg;
return 1;
}
#endif /* !OPENSSL_NO_TLSEXT */
int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
......@@ -2043,6 +2103,10 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
ret->custom_cli_ext_records_count = 0;
ret->custom_srv_ext_records = NULL;
ret->custom_srv_ext_records_count = 0;
ret->cli_supp_data_records = NULL;
ret->cli_supp_data_records_count = 0;
ret->srv_supp_data_records = NULL;
ret->srv_supp_data_records_count = 0;
#ifndef OPENSSL_NO_BUF_FREELISTS
ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT;
ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
......@@ -2184,6 +2248,8 @@ void SSL_CTX_free(SSL_CTX *a)
#ifndef OPENSSL_NO_TLSEXT
OPENSSL_free(a->custom_cli_ext_records);
OPENSSL_free(a->custom_srv_ext_records);
OPENSSL_free(a->cli_supp_data_records);
OPENSSL_free(a->srv_supp_data_records);
#endif
#ifndef OPENSSL_NO_ENGINE
if (a->client_cert_engine)
......@@ -2621,25 +2687,6 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd)
}
#ifndef OPENSSL_NO_TLSEXT
unsigned char *ssl_get_authz_data(SSL *s, size_t *authz_length)
{
CERT *c;
int i;
c = s->cert;
i = ssl_get_server_cert_index(s);
if (i == -1)
return NULL;
*authz_length = 0;
if (c->pkeys[i].authz == NULL)
return(NULL);
*authz_length = c->pkeys[i].authz_length;
return c->pkeys[i].authz;
}
int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo,
size_t *serverinfo_length)
{
......
......@@ -503,14 +503,6 @@ typedef struct cert_pkey_st
/* Chain for this certificate */
STACK_OF(X509) *chain;
#ifndef OPENSSL_NO_TLSEXT
/* authz/authz_length contain authz data for this certificate. The data
* is in wire format, specifically it's a series of records like:
* uint8_t authz_type; // (RFC 5878, AuthzDataFormat)
* uint16_t length;
* uint8_t data[length]; */
unsigned char *authz;
size_t authz_length;
/* serverinfo data for this certificate. The data is in TLS Extension
* wire format, specifically it's a series of records like:
* uint16_t extension_type; // (RFC 5246, 7.4.1.4, Extension)
......@@ -1009,7 +1001,6 @@ int ssl_undefined_void_function(void);
int ssl_undefined_const_function(const SSL *s);
CERT_PKEY *ssl_get_server_send_pkey(const SSL *s);
#ifndef OPENSSL_NO_TLSEXT
unsigned char *ssl_get_authz_data(SSL *s, size_t *authz_length);
int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo,
size_t *serverinfo_length);
#endif
......@@ -1275,8 +1266,10 @@ int ssl_prepare_clienthello_tlsext(SSL *s);
int ssl_prepare_serverhello_tlsext(SSL *s);
/* server only */
int tls1_send_server_supplemental_data(SSL *s);
int tls1_send_server_supplemental_data(SSL *s, int *skip);
int tls1_get_client_supplemental_data(SSL *s);
/* client only */
int tls1_send_client_supplemental_data(SSL *s, int *skip);
int tls1_get_server_supplemental_data(SSL *s);
#ifndef OPENSSL_NO_HEARTBEATS
......
......@@ -66,10 +66,6 @@
static int ssl_set_cert(CERT *c, X509 *x509);
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
#ifndef OPENSSL_NO_TLSEXT
static int ssl_set_authz(CERT *c, unsigned char *authz,
size_t authz_length);
#endif
int SSL_use_certificate(SSL *ssl, X509 *x)
{
if (x == NULL)
......@@ -463,6 +459,15 @@ static int ssl_set_cert(CERT *c, X509 *x)
X509_free(c->pkeys[i].x509);
CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
c->pkeys[i].x509=x;
#ifndef OPENSSL_NO_TLSEXT
/* Free the old serverinfo data, if it exists. */
if (c->pkeys[i].serverinfo != NULL)
{
OPENSSL_free(c->pkeys[i].serverinfo);
c->pkeys[i].serverinfo = NULL;
c->pkeys[i].serverinfo_length = 0;
}
#endif
c->key= &(c->pkeys[i]);
c->valid=0;
......@@ -802,50 +807,6 @@ end:
#endif
#ifndef OPENSSL_NO_TLSEXT
/* authz_validate returns true iff authz is well formed, i.e. that it meets the
* wire format as documented in the CERT_PKEY structure and that there are no
* duplicate entries. */
static char authz_validate(const unsigned char *authz, size_t length)
{
unsigned char types_seen_bitmap[32];
if (!authz)
return 1;
memset(types_seen_bitmap, 0, sizeof(types_seen_bitmap));
for (;;)
{
unsigned char type, byte, bit;
unsigned short len;
if (!length)
return 1;
type = *(authz++);
length--;
byte = type / 8;
bit = type & 7;
if (types_seen_bitmap[byte] & (1 << bit))
return 0;
types_seen_bitmap[byte] |= (1 << bit);
if (length < 2)
return 0;
len = ((unsigned short) authz[0]) << 8 |
((unsigned short) authz[1]);
authz += 2;
length -= 2;
if (length < len)
return 0;
authz += len;
length -= len;
}
}
static int serverinfo_find_extension(const unsigned char *serverinfo,
size_t serverinfo_length,
unsigned short extension_type,
......@@ -978,83 +939,6 @@ static int serverinfo_process_buffer(const unsigned char *serverinfo,
}
}
static const unsigned char *authz_find_data(const unsigned char *authz,
size_t authz_length,
unsigned char data_type,
size_t *data_length)
{
if (authz == NULL) return NULL;
if (!authz_validate(authz, authz_length))
{
SSLerr(SSL_F_AUTHZ_FIND_DATA,SSL_R_INVALID_AUTHZ_DATA);
return NULL;
}
for (;;)
{
unsigned char type;
unsigned short len;
if (!authz_length)
return NULL;
type = *(authz++);
authz_length--;
/* We've validated the authz data, so we don't have to
* check again that we have enough bytes left. */
len = ((unsigned short) authz[0]) << 8 |
((unsigned short) authz[1]);
authz += 2;
authz_length -= 2;
if (type == data_type)
{
*data_length = len;
return authz;
}
authz += len;
authz_length -= len;
}
/* No match */
return NULL;
}
static int ssl_set_authz(CERT *c, unsigned char *authz, size_t authz_length)
{
CERT_PKEY *current_key = c->key;
if (current_key == NULL)
return 0;
if (!authz_validate(authz, authz_length))
{
SSLerr(SSL_F_SSL_SET_AUTHZ,SSL_R_INVALID_AUTHZ_DATA);
return(0);
}
current_key->authz = OPENSSL_realloc(current_key->authz, authz_length);
if (current_key->authz == NULL)
{
SSLerr(SSL_F_SSL_SET_AUTHZ,ERR_R_MALLOC_FAILURE);
return 0;
}
current_key->authz_length = authz_length;
memcpy(current_key->authz, authz, authz_length);
return 1;
}
int SSL_CTX_use_authz(SSL_CTX *ctx, unsigned char *authz,
size_t authz_length)
{
if (authz == NULL)
{
SSLerr(SSL_F_SSL_CTX_USE_AUTHZ,ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (!ssl_cert_inst(&ctx->cert))
{
SSLerr(SSL_F_SSL_CTX_USE_AUTHZ,ERR_R_MALLOC_FAILURE);
return 0;
}
return ssl_set_authz(ctx->cert, authz, authz_length);
}
int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
size_t serverinfo_length)
{
......@@ -1098,106 +982,7 @@ int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
return 1;
}
int SSL_use_authz(SSL *ssl, unsigned char *authz, size_t authz_length)
{
if (authz == NULL)
{
SSLerr(SSL_F_SSL_USE_AUTHZ,ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (!ssl_cert_inst(&ssl->cert))
{
SSLerr(SSL_F_SSL_USE_AUTHZ,ERR_R_MALLOC_FAILURE);
return 0;
}
return ssl_set_authz(ssl->cert, authz, authz_length);
}
const unsigned char *SSL_CTX_get_authz_data(SSL_CTX *ctx, unsigned char type,
size_t *data_length)
{
CERT_PKEY *current_key;
if (ctx->cert == NULL)
return NULL;
current_key = ctx->cert->key;
if (current_key->authz == NULL)
return NULL;
return authz_find_data(current_key->authz,
current_key->authz_length, type, data_length);
}
#ifndef OPENSSL_NO_STDIO
/* read_authz returns a newly allocated buffer with authz data */
static unsigned char *read_authz(const char *file, size_t *authz_length)
{
BIO *authz_in = NULL;
unsigned char *authz = NULL;
/* Allow authzs up to 64KB. */
static const size_t authz_limit = 65536;
size_t read_length;
unsigned char *ret = NULL;
authz_in = BIO_new(BIO_s_file_internal());
if (authz_in == NULL)
{
SSLerr(SSL_F_READ_AUTHZ,ERR_R_BUF_LIB);
goto end;
}
if (BIO_read_filename(authz_in,file) <= 0)
{
SSLerr(SSL_F_READ_AUTHZ,ERR_R_SYS_LIB);
goto end;
}
authz = OPENSSL_malloc(authz_limit);
read_length = BIO_read(authz_in, authz, authz_limit);
if (read_length == authz_limit || read_length <= 0)
{
SSLerr(SSL_F_READ_AUTHZ,SSL_R_AUTHZ_DATA_TOO_LARGE);
OPENSSL_free(authz);
goto end;
}
*authz_length = read_length;
ret = authz;
end:
if (authz_in != NULL) BIO_free(authz_in);
return ret;
}
int SSL_CTX_use_authz_file(SSL_CTX *ctx, const char *file)
{
unsigned char *authz = NULL;
size_t authz_length = 0;
int ret;
authz = read_authz(file, &authz_length);
if (authz == NULL)
return 0;
ret = SSL_CTX_use_authz(ctx, authz, authz_length);
/* SSL_CTX_use_authz makes a local copy of the authz. */
OPENSSL_free(authz);
return ret;
}
int SSL_use_authz_file(SSL *ssl, const char *file)
{
unsigned char *authz = NULL;
size_t authz_length = 0;
int ret;
authz = read_authz(file, &authz_length);
if (authz == NULL)
return 0;
ret = SSL_use_authz(ssl, authz, authz_length);
/* SSL_use_authz makes a local copy of the authz. */
OPENSSL_free(authz);
return ret;
}
int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
{
unsigned char *serverinfo = NULL;
......
......@@ -746,8 +746,6 @@ void SSL_SESSION_free(SSL_SESSION *ss)
ss->tlsext_ellipticcurvelist_length = 0;
if (ss->tlsext_ellipticcurvelist != NULL) OPENSSL_free(ss->tlsext_ellipticcurvelist);
#endif /* OPENSSL_NO_EC */
if (ss->audit_proof != NULL) OPENSSL_free(ss->audit_proof);
ss->audit_proof_length = 0;
#endif
#ifndef OPENSSL_NO_PSK
if (ss->psk_identity_hint != NULL)
......@@ -869,15 +867,6 @@ int SSL_SESSION_set1_id_context(SSL_SESSION *s,const unsigned char *sid_ctx,
return 1;
}
#ifndef OPENSSL_NO_TLSEXT
unsigned char *SSL_SESSION_get_tlsext_authz_server_audit_proof(SSL_SESSION *s, size_t *proof_length)
{
if (s->audit_proof != NULL)
*proof_length = s->audit_proof_length;
return s->audit_proof;
}
#endif
long SSL_CTX_set_timeout(SSL_CTX *s, long t)
{
long l;
......
......@@ -210,6 +210,14 @@ case SSL3_ST_SR_KEY_EXCH_A: str="SSLv3 read client key exchange A"; break;
case SSL3_ST_SR_KEY_EXCH_B: str="SSLv3 read client key exchange B"; break;
case SSL3_ST_SR_CERT_VRFY_A: str="SSLv3 read certificate verify A"; break;
case SSL3_ST_SR_CERT_VRFY_B: str="SSLv3 read certificate verify B"; break;
case SSL3_ST_CW_SUPPLEMENTAL_DATA_A: str="SSLv3 client write supplemental data A"; break;
case SSL3_ST_CW_SUPPLEMENTAL_DATA_B: str="SSLv3 client write supplemental data B"; break;
case SSL3_ST_SW_SUPPLEMENTAL_DATA_A: str="SSLv3 server write supplemental data A"; break;
case SSL3_ST_SW_SUPPLEMENTAL_DATA_B: str="SSLv3 client write supplemental data B"; break;
case SSL3_ST_CR_SUPPLEMENTAL_DATA_A: str="SSLv3 client read supplemental data A"; break;
case SSL3_ST_CR_SUPPLEMENTAL_DATA_B: str="SSLv3 client read supplemental data B"; break;
case SSL3_ST_SR_SUPPLEMENTAL_DATA_A: str="SSLv3 server read supplemental data A"; break;
case SSL3_ST_SR_SUPPLEMENTAL_DATA_B: str="SSLv3 client read supplemental data B"; break;
#endif
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
......
......@@ -521,6 +521,16 @@ int custom_ext = 0;
/* This set based on extension callbacks */
int custom_ext_error = 0;
/*Not IETF assigned supplemental data types*/
#define CUSTOM_SUPP_DATA_TYPE_0 100
#define CUSTOM_SUPP_DATA_TYPE_1 101
#define CUSTOM_SUPP_DATA_TYPE_2 102
const char supp_data_0_string[] = "00000";
int suppdata = 0;
int suppdata_error = 0;
static int serverinfo_cli_cb(SSL* s, unsigned short ext_type,
const unsigned char* in, unsigned short inlen,
int* al, void* arg)
......@@ -726,6 +736,109 @@ static int custom_ext_3_srv_second_cb(SSL *s, unsigned short ext_type,
return 1; /* Send "defg" */
}
static int supp_data_0_srv_first_cb(SSL *s, unsigned short supp_data_type,
const unsigned char **out,
unsigned short *outlen, void *arg)
{
*out = (const unsigned char*)supp_data_0_string;
*outlen = strlen(supp_data_0_string);
if (arg != s)
suppdata_error = 1;
return 1;
}
static int supp_data_0_srv_second_cb(SSL *s, unsigned short supp_data_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg)
{
if (supp_data_type != CUSTOM_SUPP_DATA_TYPE_0)
suppdata_error = 1;
if (inlen != strlen(supp_data_0_string))
suppdata_error = 1;
if (memcmp(in, supp_data_0_string, inlen) != 0)
suppdata_error = 1;
if (arg != s)
suppdata_error = 1;
return 1;
}
static int supp_data_1_srv_first_cb(SSL *s, unsigned short supp_data_type,
const unsigned char **out,
unsigned short *outlen, void *arg)
{
return -1;
}
static int supp_data_1_srv_second_cb(SSL *s, unsigned short supp_data_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg)
{
suppdata_error = 1;
return 1;
}
static int supp_data_2_srv_second_cb(SSL *s, unsigned short supp_data_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg)
{
suppdata_error = 1;
return 1;
}
static int supp_data_0_cli_first_cb(SSL *s, unsigned short supp_data_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg)
{
if (supp_data_type != CUSTOM_SUPP_DATA_TYPE_0)
suppdata_error = 1;
if (inlen != strlen(supp_data_0_string))
suppdata_error = 1;
if (memcmp(in, supp_data_0_string, inlen) != 0)
suppdata_error = 1;
if (arg != s)
suppdata_error = 1;
return 1;
}
static int supp_data_0_cli_second_cb(SSL *s, unsigned short supp_data_type,
const unsigned char **out,
unsigned short *outlen, void *arg)
{
*out = (const unsigned char*)supp_data_0_string;
*outlen = strlen(supp_data_0_string);
if (arg != s)
suppdata_error = 1;
return 1;
}
static int supp_data_1_cli_first_cb(SSL *s, unsigned short supp_data_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg)
{
suppdata_error = 1;
return 1;
}
static int supp_data_1_cli_second_cb(SSL *s, unsigned short supp_data_type,
const unsigned char **out,
unsigned short *outlen, void *arg)
{
return -1;
}
static int supp_data_2_cli_first_cb(SSL *s, unsigned short supp_data_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg)
{
suppdata_error = 1;
return 1;
}
static char *cipher=NULL;
static int verbose=0;
......@@ -813,6 +926,7 @@ static void sv_usage(void)
fprintf(stderr," -alpn_client <string> - have client side offer ALPN\n");
fprintf(stderr," -alpn_server <string> - have server side offer ALPN\n");
fprintf(stderr," -alpn_expected <string> - the ALPN protocol that should be negotiated\n");
fprintf(stderr, "-suppdata - exercise supplemental data callbacks\n");
}
static void print_details(SSL *c_ssl, const char *prefix)
......@@ -1257,6 +1371,10 @@ int main(int argc, char *argv[])
if (--argc < 1) goto bad;
alpn_expected = *(++argv);
}
else if (strcmp(*argv,"-suppdata") == 0)
{
suppdata = 1;
}
else
{
fprintf(stderr,"unknown option %s\n",*argv);
......@@ -1646,6 +1764,23 @@ bad:
c_ssl=SSL_new(c_ctx);
s_ssl=SSL_new(s_ctx);
if (suppdata)
{
//TEST CASES
//client and server both send and receive, verify additional arg passed back
SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_0, supp_data_0_srv_first_cb, supp_data_0_srv_second_cb, s_ssl);
SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_0, supp_data_0_cli_first_cb, supp_data_0_cli_second_cb, c_ssl);
//-1 response from sending server/client doesn't receive, -1 response from sending client/server doesn't receive
SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_1, supp_data_1_srv_first_cb, supp_data_1_srv_second_cb, NULL);
SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_1, supp_data_1_cli_first_cb, supp_data_1_cli_second_cb, NULL);
//null sending server/client doesn't receive, null sending client/server doesn't receive
SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_2, /*supp_data_2_srv_first_cb*/NULL, supp_data_2_srv_second_cb, NULL);
SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_2, supp_data_2_cli_first_cb, /*supp_data_2_cli_second_cb*/NULL, NULL);
//alerts set to non-zero and zero return values not tested
}
#ifndef OPENSSL_NO_KRB5
if (c_ssl && c_ssl->kssl_ctx)
{
......@@ -2419,6 +2554,11 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count)
goto err;
}
#endif
if (suppdata_error < 0)
{
ret = 1;
goto err;
}
if (verify_serverinfo() < 0)
{
ret = 1;
......
......@@ -1445,26 +1445,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
ret += el;
}
/* Add TLS extension Server_Authz_DataFormats to the ClientHello */
/* 2 bytes for extension type */
/* 2 bytes for extension length */
/* 1 byte for the list length */
/* 1 byte for the list (we only support audit proofs) */
if (s->ctx->tlsext_authz_server_audit_proof_cb != NULL)
{
const unsigned short ext_len = 2;
const unsigned char list_len = 1;
if (limit < ret + 6)
return NULL;
s2n(TLSEXT_TYPE_server_authz, ret);
/* Extension length: 2 bytes */
s2n(ext_len, ret);
*(ret++) = list_len;
*(ret++) = TLSEXT_AUTHZDATAFORMAT_audit_proof;
}
/* Add custom TLS Extensions to ClientHello */
if (s->ctx->custom_cli_ext_records_count)
{
......@@ -1693,79 +1673,6 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
}
#endif
/* If the client supports authz then see whether we have any to offer
* to it. */
if (s->s3->tlsext_authz_client_types_len)
{
size_t authz_length;
/* By now we already know the new cipher, so we can look ahead
* to see whether the cert we are going to send
* has any authz data attached to it. */
const unsigned char* authz = ssl_get_authz_data(s, &authz_length);
const unsigned char* const orig_authz = authz;
size_t i;
unsigned authz_count = 0;
/* The authz data contains a number of the following structures:
* uint8_t authz_type
* uint16_t length
* uint8_t data[length]
*
* First we walk over it to find the number of authz elements. */
for (i = 0; i < authz_length; i++)
{
unsigned short length;
unsigned char type;
type = *(authz++);
if (memchr(s->s3->tlsext_authz_client_types,
type,
s->s3->tlsext_authz_client_types_len) != NULL)
authz_count++;
n2s(authz, length);
/* n2s increments authz by 2 */
i += 2;
authz += length;
i += length;
}
if (authz_count)
{
/* Add TLS extension server_authz to the ServerHello message
* 2 bytes for extension type
* 2 bytes for extension length
* 1 byte for the list length
* n bytes for the list */
const unsigned short ext_len = 1 + authz_count;
if ((long)(limit - ret - 4 - ext_len) < 0) return NULL;
s2n(TLSEXT_TYPE_server_authz, ret);
s2n(ext_len, ret);
*(ret++) = authz_count;
s->s3->tlsext_authz_promised_to_client = 1;
}
authz = orig_authz;
for (i = 0; i < authz_length; i++)
{
unsigned short length;
unsigned char type;
authz_count++;
type = *(authz++);
if (memchr(s->s3->tlsext_authz_client_types,
type,
s->s3->tlsext_authz_client_types_len) != NULL)
*(ret++) = type;
n2s(authz, length);
/* n2s increments authz by 2 */
i += 2;
authz += length;
i += length;
}
}
/* If custom types were sent in ClientHello, add ServerHello responses */
if (s->s3->tlsext_custom_types_count)
{
......@@ -2511,66 +2418,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
al))
return 0;
}
else if (type == TLSEXT_TYPE_server_authz)
{
unsigned char *sdata = data;
unsigned char server_authz_dataformatlist_length;
if (size == 0)
{
*al = TLS1_AD_DECODE_ERROR;
return 0;
}
server_authz_dataformatlist_length = *(sdata++);
if (server_authz_dataformatlist_length != size - 1)
{
*al = TLS1_AD_DECODE_ERROR;
return 0;
}
/* Successful session resumption uses the same authz
* information as the original session so we ignore this
* in the case of a session resumption. */
if (!s->hit)
{
if (s->s3->tlsext_authz_client_types != NULL)
OPENSSL_free(s->s3->tlsext_authz_client_types);
s->s3->tlsext_authz_client_types =
OPENSSL_malloc(server_authz_dataformatlist_length);
if (!s->s3->tlsext_authz_client_types)
{
*al = TLS1_AD_INTERNAL_ERROR;
return 0;
}
s->s3->tlsext_authz_client_types_len =
server_authz_dataformatlist_length;
memcpy(s->s3->tlsext_authz_client_types,
sdata,
server_authz_dataformatlist_length);
/* Sort the types in order to check for duplicates. */
qsort(s->s3->tlsext_authz_client_types,
server_authz_dataformatlist_length,
1 /* element size */,
byte_compare);
for (i = 0; i < server_authz_dataformatlist_length; i++)
{
if (i > 0 &&
s->s3->tlsext_authz_client_types[i] ==
s->s3->tlsext_authz_client_types[i-1])
{
*al = TLS1_AD_DECODE_ERROR;
return 0;
}
}
}
}
/* If this ClientHello extension was unhandled and this is
* a nonresumed connection, check whether the extension is a
* custom TLS Extension (has a custom_srv_ext_record), and if
......@@ -2936,46 +2783,6 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char
al))
return 0;
}
else if (type == TLSEXT_TYPE_server_authz)
{
/* We only support audit proofs. It's an error to send
* an authz hello extension if the client
* didn't request a proof. */
unsigned char *sdata = data;
unsigned char server_authz_dataformatlist_length;
if (!s->ctx->tlsext_authz_server_audit_proof_cb)
{
*al = TLS1_AD_UNSUPPORTED_EXTENSION;
return 0;
}
if (!size)
{
*al = TLS1_AD_DECODE_ERROR;
return 0;
}
server_authz_dataformatlist_length = *(sdata++);
if (server_authz_dataformatlist_length != size - 1)
{
*al = TLS1_AD_DECODE_ERROR;
return 0;
}
/* We only support audit proofs, so a legal ServerHello
* authz list contains exactly one entry. */
if (server_authz_dataformatlist_length != 1 ||
sdata[0] != TLSEXT_AUTHZDATAFORMAT_audit_proof)
{
*al = TLS1_AD_UNSUPPORTED_EXTENSION;
return 0;
}
s->s3->tlsext_authz_server_promised = 1;
}
/* If this extension type was not otherwise handled, but
* matches a custom_cli_ext_record, then send it to the c
* callback */
......
......@@ -299,9 +299,12 @@ extern "C" {
/* From RFC 5878 */
#define TLSEXT_SUPPLEMENTALDATATYPE_authz_data 16386
/* This is not IANA assigned. See
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#authorization-data-rules */
#define TLSEXT_AUTHZDATAFORMAT_audit_proof 182
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#authorization-data-rules
* http://tools.ietf.org/id/draft-dthakore-tls-authz-01.txt
*/
#define TLSEXT_AUTHZDATAFORMAT_dtcp 225
#define TLSEXT_MAXLEN_supplemental_data 1024*16 /* Let's limit to 16k */
......@@ -390,13 +393,6 @@ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg)
#define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
/* Used by clients to process audit proofs. */
#define SSL_CTX_set_tlsext_authz_server_audit_proof_cb(ctx, cb) \
SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB,(void (*)(void))cb)
#define SSL_CTX_set_tlsext_authz_server_audit_proof_cb_arg(ctx, arg) \
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG, 0, arg);
#ifndef OPENSSL_NO_HEARTBEATS
#define SSL_TLSEXT_HB_ENABLED 0x01
#define SSL_TLSEXT_HB_DONT_SEND_REQUESTS 0x02
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册