Merge branch '102_stable_tlsext_suppdata_changes' of git://github.com/scottdeboy/openssl into scottdeboy-102_stable_tlsext_suppdata_changes

This commit is contained in:
Ben Laurie 2014-02-09 19:17:42 +00:00
commit e32cbae224
25 changed files with 1084 additions and 1065 deletions

View File

@ -31,6 +31,10 @@
MGF1 digest and OAEP label.
[Steve Henson]
*) 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

View File

@ -593,7 +593,10 @@ 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_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$x86_64_asm;$asm=~s/rc4\-[^:]+//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -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
"iphoneos-cross","llvm-gcc:-O3 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fomit-frame-pointer -fno-common::-D_REENTRANT:iOS:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
@ -2008,7 +2011,7 @@ BEGIN
VALUE "ProductVersion", "$version\\0"
// Optional:
//VALUE "Comments", "\\0"
VALUE "LegalCopyright", "Copyright © 1998-2005 The OpenSSL Project. Copyright © 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
VALUE "LegalCopyright", "Copyright © 1998-2005 The OpenSSL Project. Copyright © 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
//VALUE "LegalTrademarks", "\\0"
//VALUE "PrivateBuild", "\\0"
//VALUE "SpecialBuild", "\\0"

View File

@ -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);

View File

@ -879,6 +879,9 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *
case 20:
str_details1 = ", Finished";
break;
case 23:
str_details1 = ", SupplementalData";
break;
}
}
}

View File

@ -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,37 @@ static int c_quiet=0;
static int c_ign_eof=0;
static int c_brief=0;
#ifndef OPENSSL_NO_TLSEXT
static unsigned char *generated_supp_data = NULL;
static const unsigned char *most_recent_supplemental_data = NULL;
static size_t most_recent_supplemental_data_length = 0;
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, int *al, void *arg);
static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, unsigned short *outlen,
int *al, 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";
@ -365,15 +396,14 @@ 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");
#endif
# ifndef OPENSSL_NO_NEXTPROTONEG
BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
# endif
BIO_printf(bio_err," -alpn arg - enable ALPN extension, considering named protocols supported (comma-separated list)\n");
#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");
BIO_printf(bio_err," -keymatexport label - Export keying material using label\n");
@ -822,8 +852,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)
@ -1397,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);
@ -1743,6 +1778,13 @@ SSL_set_tlsext_status_ids(con, ids);
"CONNECTION ESTABLISHED\n");
print_ssl_summary(bio_err, con);
}
/*handshake is complete - free the generated supp data allocated in the callback */
if (generated_supp_data)
{
OPENSSL_free(generated_supp_data);
generated_supp_data = NULL;
}
print_stuff(bio_c_out,con,full_log);
if (full_log > 0) full_log--;
@ -2392,26 +2434,74 @@ 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);
if (TLSEXT_TYPE_server_authz == ext_type)
server_provided_server_authz
= (memchr(in, TLSEXT_AUTHZDATAFORMAT_dtcp, inlen) != NULL);
proof = SSL_SESSION_get_tlsext_authz_server_audit_proof(sess,
&proof_len);
if (proof != NULL)
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,
int *al, void *arg)
{
if (c_auth)
{
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");
/*if auth_require_reneg flag is set, only send extensions if
renegotiation has occurred */
if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s)))
{
*out = auth_ext_data;
*outlen = 1;
return 1;
}
}
else
/* 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)
{
BIO_printf(bio_c_out, "No audit proof found.\n");
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, int *al, void *arg)
{
if (c_auth && server_provided_client_authz && server_provided_server_authz)
{
/*if auth_require_reneg flag is set, only send supplemental data if
renegotiation has occurred */
if (!c_auth_require_reneg
|| (c_auth_require_reneg && SSL_num_renegotiations(s)))
{
generated_supp_data = OPENSSL_malloc(10);
memcpy(generated_supp_data, "5432154321", 10);
*out = generated_supp_data;
*outlen = 10;
return 1;
}
}
/* no supplemental data to send */
return -1;
}
#endif

View File

@ -224,6 +224,20 @@ 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 unsigned char *generated_supp_data = NULL;
static const unsigned char *most_recent_supplemental_data = NULL;
static size_t most_recent_supplemental_data_length = 0;
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,
@ -315,10 +329,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, int *al, void *arg);
static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, unsigned short *outlen,
int *al, 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
@ -482,10 +515,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" \
@ -1018,6 +1053,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;
@ -1132,17 +1168,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;
@ -1918,17 +1961,23 @@ 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))
{
ERR_print_errors(bio_err);
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))
@ -2097,8 +2146,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);
# ifndef OPENSSL_NO_NEXTPROTONEG
@ -2631,6 +2678,13 @@ static int init_ssl_connection(SSL *con)
i=SSL_accept(con);
}
#endif
/*handshake is complete - free the generated supp data allocated in the callback */
if (generated_supp_data)
{
OPENSSL_free(generated_supp_data);
generated_supp_data = NULL;
}
if (i <= 0)
{
if (BIO_sock_should_retry(i))
@ -3494,3 +3548,77 @@ 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,
int *al, void *arg)
{
if (c_auth && client_provided_client_authz && client_provided_server_authz)
{
/*if auth_require_reneg flag is set, only send extensions if
renegotiation has occurred */
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, int *al, void *arg)
{
if (c_auth && client_provided_client_authz && client_provided_server_authz)
{
/*if auth_require_reneg flag is set, only send supplemental data if
renegotiation has occurred */
if (!c_auth_require_reneg
|| (c_auth_require_reneg && SSL_num_renegotiations(s)))
{
generated_supp_data = OPENSSL_malloc(10);
memcpy(generated_supp_data, "1234512345", 10);
*out = generated_supp_data;
*outlen = 10;
return 1;
}
}
/* no supplemental data to send */
return -1;
}
#endif

View File

@ -207,12 +207,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
#undef ssl3_cbc_record_digest_supported
#define ssl3_cbc_record_digest_supported ssl3_cbc_record_digest_support

View File

@ -44,6 +44,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
@ -245,6 +247,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

View File

@ -55,7 +55,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
@ -285,6 +287,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

View File

@ -299,6 +299,7 @@ static int ssl23_client_hello(SSL *s)
unsigned long l;
int ssl2_compat;
int version = 0, version_major, version_minor;
int al = 0;
#ifndef OPENSSL_NO_COMP
int j;
SSL_COMP *comp;
@ -362,10 +363,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
@ -553,8 +554,9 @@ static int ssl23_client_hello(SSL *s)
SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
return -1;
}
if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, &al)) == NULL)
{
ssl3_send_alert(s,SSL3_AL_FATAL,al);
SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
return -1;
}

View File

@ -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,
@ -673,6 +689,7 @@ int ssl3_client_hello(SSL *s)
unsigned char *p,*d;
int i;
unsigned long l;
int al = 0;
#ifndef OPENSSL_NO_COMP
int j;
SSL_COMP *comp;
@ -875,8 +892,9 @@ int ssl3_client_hello(SSL *s)
SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
goto err;
}
if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, &al)) == NULL)
{
ssl3_send_alert(s,SSL3_AL_FATAL,al);
SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
goto err;
}
@ -1353,21 +1371,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 +3571,11 @@ 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 +3584,12 @@ 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,28 +3617,120 @@ 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)
{
int al = 0;
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, &al,
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);
goto f_err;
}
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;
f_err:
ssl3_send_alert(s,SSL3_AL_FATAL,al);
return 0;
}
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,
SSL3_ST_CR_SUPPLEMENTAL_DATA_B,
SSL3_MT_SUPPLEMENTAL_DATA,
/* use default limit */
TLSEXT_MAXLEN_supplemental_data,
&ok);
SSL3_ST_CR_SUPPLEMENTAL_DATA_A,
SSL3_ST_CR_SUPPLEMENTAL_DATA_B,
SSL3_MT_SUPPLEMENTAL_DATA,
/* use default limit */
TLSEXT_MAXLEN_supplemental_data,
&ok);
if (!ok) return((int)n);
p = (unsigned char *)s->init_msg;
d = p;
/* The message cannot be empty */
if (n < 3)
{
@ -3637,72 +3738,29 @@ 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;
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;
}
/* 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;
}
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);

View File

@ -3029,10 +3029,8 @@ 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);
if (s->s3->serverinfo_client_tlsext_custom_types != NULL)
OPENSSL_free(s->s3->serverinfo_client_tlsext_custom_types);
#endif
OPENSSL_cleanse(s->s3,sizeof *s->s3);
OPENSSL_free(s->s3);
@ -3078,17 +3076,12 @@ void ssl3_clear(SSL *s)
}
#endif
#ifndef OPENSSL_NO_TLSEXT
if (s->s3->tlsext_authz_client_types != NULL)
if (s->s3->serverinfo_client_tlsext_custom_types != NULL)
{
OPENSSL_free(s->s3->tlsext_authz_client_types);
s->s3->tlsext_authz_client_types = NULL;
OPENSSL_free(s->s3->serverinfo_client_tlsext_custom_types);
s->s3->serverinfo_client_tlsext_custom_types = NULL;
}
if (s->s3->tlsext_custom_types != NULL)
{
OPENSSL_free(s->s3->tlsext_custom_types);
s->s3->tlsext_custom_types = NULL;
}
s->s3->tlsext_custom_types_count = 0;
s->s3->serverinfo_client_tlsext_custom_types_count = 0;
#ifndef OPENSSL_NO_EC
s->s3->is_probably_safari = 0;
#endif /* !OPENSSL_NO_EC */
@ -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);

View File

@ -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,10 @@ 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
@ -1488,6 +1499,7 @@ int ssl3_send_server_hello(SSL *s)
unsigned char *buf;
unsigned char *p,*d;
int i,sl;
int al = 0;
unsigned long l;
if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
@ -1556,8 +1568,9 @@ int ssl3_send_server_hello(SSL *s)
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT);
return -1;
}
if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, &al)) == NULL)
{
ssl3_send_alert(s, SSL3_AL_FATAL, al);
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
return -1;
}
@ -3639,98 +3652,156 @@ 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);
orig_authz = authz = ssl_get_authz_data(s, &authz_length);
if (authz == NULL)
int al = 0;
if (s->ctx->srv_supp_data_records_count)
{
/* This should never occur. */
return 0;
}
unsigned char *p = NULL;
unsigned char *size_loc = NULL;
srv_supp_data_record *record = NULL;
size_t length = 0;
size_t i = 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)
for (i = 0; i < s->ctx->srv_supp_data_records_count; i++)
{
*(p++) = type;
s2n(len, p);
memcpy(p, authz, len);
p += len;
}
const unsigned char *out = NULL;
unsigned short outlen = 0;
int cb_retval = 0;
record = &s->ctx->srv_supp_data_records[i];
authz += len;
i += len;
/* NULL callback or -1 omits supp data entry */
if (!record->fn1)
continue;
cb_retval = record->fn1(s, record->supp_data_type,
&out, &outlen, &al, 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);
goto f_err;
}
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;
return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
}
}
s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B;
s->init_num = length;
/* no supp data message sent */
*skip = 1;
s->init_num = 0;
s->init_off = 0;
return 1;
f_err:
ssl3_send_alert(s,SSL3_AL_FATAL,al);
return 0;
}
return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
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;
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);
if (!ok) return((int)n);
p = (unsigned char *)s->init_msg;
d = p;
/* The message cannot be empty */
if (n < 3)
{
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
goto f_err;
}
n2l3(p, supp_data_len);
while (p<d+supp_data_len)
{
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++)
{
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;
}
}
}
p+=supp_data_entry_len;
}
return 1;
f_err:
ssl3_send_alert(s,SSL3_AL_FATAL,al);
return -1;
}
#endif

130
ssl/ssl.h
View File

@ -406,11 +406,11 @@ typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, S
*/
typedef int (*custom_cli_ext_first_cb_fn)(SSL *s, unsigned short ext_type,
const unsigned char **out,
unsigned short *outlen, void *arg);
unsigned short *outlen, int *al, void *arg);
typedef int (*custom_cli_ext_second_cb_fn)(SSL *s, unsigned short ext_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg);
void *arg);
typedef int (*custom_srv_ext_first_cb_fn)(SSL *s, unsigned short ext_type,
const unsigned char *in,
@ -418,7 +418,7 @@ typedef int (*custom_srv_ext_first_cb_fn)(SSL *s, unsigned short ext_type,
void *arg);
typedef int (*custom_srv_ext_second_cb_fn)(SSL *s, unsigned short ext_type,
const unsigned char **out,
unsigned short *outlen, void *arg);
unsigned short *outlen, int *al, void *arg);
typedef struct {
unsigned short ext_type;
@ -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, int *al, 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, int *al, 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
};
@ -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

View File

@ -560,28 +560,12 @@ 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
* a custom_srv_ext_record to handle.
/* serverinfo_client_tlsext_custom_types contains an array of TLS Extension types which
* were advertised by the client in its ClientHello and leveraged by ServerInfo TLS extension callbacks.
* The array does not contain any duplicates, and is in the same order
* as the types were received in the client hello. */
unsigned short *tlsext_custom_types;
size_t tlsext_custom_types_count; /* how many tlsext_custom_types */
unsigned short *serverinfo_client_tlsext_custom_types;
size_t serverinfo_client_tlsext_custom_types_count; /* how many serverinfo_client_tlsext_custom_types */
#ifndef OPENSSL_NO_EC
/* This is set to true if we believe that this is a version of Safari
@ -628,8 +612,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)
@ -644,6 +630,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)
@ -670,6 +660,10 @@ typedef struct ssl3_state_st
#define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CLNT_HELLO_D (0x115|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)
@ -710,8 +704,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
@ -725,7 +721,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

View File

@ -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);

View File

@ -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"},
@ -263,7 +259,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"},
@ -280,7 +275,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"},
@ -300,11 +294,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}
@ -314,7 +310,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"},
@ -407,8 +402,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"},
@ -598,7 +591,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"},

View File

@ -1862,6 +1862,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,
@ -2065,6 +2125,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));
@ -2206,6 +2270,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)
@ -2643,25 +2709,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)
{

View File

@ -505,14 +505,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)
@ -1014,7 +1006,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
@ -1272,8 +1263,8 @@ int tls1_shared_list(SSL *s,
const unsigned char *l1, size_t l1len,
const unsigned char *l2, size_t l2len,
int nmatch);
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit);
unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit);
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al);
unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al);
int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n);
int ssl_check_clienthello_tlsext_late(SSL *s);
int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n);
@ -1281,8 +1272,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

View File

@ -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)
@ -798,50 +794,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,
@ -896,20 +848,61 @@ static int serverinfo_srv_first_cb(SSL *s, unsigned short ext_type,
unsigned short inlen, int *al,
void *arg)
{
size_t i = 0;
if (inlen != 0)
{
*al = SSL_AD_DECODE_ERROR;
return 0;
}
/* if already in list, error out */
for (i = 0; i < s->s3->serverinfo_client_tlsext_custom_types_count; i++)
{
if (s->s3->serverinfo_client_tlsext_custom_types[i] == ext_type)
{
*al = SSL_AD_DECODE_ERROR;
return 0;
}
}
s->s3->serverinfo_client_tlsext_custom_types_count++;
s->s3->serverinfo_client_tlsext_custom_types = OPENSSL_realloc(
s->s3->serverinfo_client_tlsext_custom_types,
s->s3->serverinfo_client_tlsext_custom_types_count * 2);
if (s->s3->serverinfo_client_tlsext_custom_types == NULL)
{
s->s3->serverinfo_client_tlsext_custom_types_count = 0;
*al = TLS1_AD_INTERNAL_ERROR;
return 0;
}
s->s3->serverinfo_client_tlsext_custom_types[
s->s3->serverinfo_client_tlsext_custom_types_count - 1] = ext_type;
return 1;
}
static int serverinfo_srv_second_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, unsigned short *outlen,
void *arg)
const unsigned char **out, unsigned short *outlen,
int *al, void *arg)
{
const unsigned char *serverinfo = NULL;
size_t serverinfo_length = 0;
size_t i = 0;
unsigned int match = 0;
/* Did the client send a TLS extension for this type? */
for (i = 0; i < s->s3->serverinfo_client_tlsext_custom_types_count; i++)
{
if (s->s3->serverinfo_client_tlsext_custom_types[i] == ext_type)
{
match = 1;
break;
}
}
if (!match)
{
/* extension not sent by client...don't send extension */
return -1;
}
/* Is there serverinfo data for the chosen server cert? */
if ((ssl_get_server_cert_serverinfo(s, &serverinfo,
@ -917,7 +910,7 @@ static int serverinfo_srv_second_cb(SSL *s, unsigned short ext_type,
{
/* Find the relevant extension from the serverinfo */
int retval = serverinfo_find_extension(serverinfo, serverinfo_length,
ext_type, out, outlen);
ext_type, out, outlen);
if (retval == 0)
return 0; /* Error */
if (retval == -1)
@ -974,83 +967,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)
{
@ -1094,106 +1010,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;

View File

@ -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;

View File

@ -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)

View File

@ -446,6 +446,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)
@ -479,7 +489,7 @@ static int verify_serverinfo()
static int custom_ext_0_cli_first_cb(SSL *s, unsigned short ext_type,
const unsigned char **out,
unsigned short *outlen, void *arg)
unsigned short *outlen, int *al, void *arg)
{
if (ext_type != CUSTOM_EXT_TYPE_0)
custom_ext_error = 1;
@ -491,13 +501,12 @@ static int custom_ext_0_cli_second_cb(SSL *s, unsigned short ext_type,
unsigned short inlen, int *al,
void *arg)
{
custom_ext_error = 1; /* Shouldn't be called */
return 0;
return 1;
}
static int custom_ext_1_cli_first_cb(SSL *s, unsigned short ext_type,
const unsigned char **out,
unsigned short *outlen, void *arg)
unsigned short *outlen, int *al, void *arg)
{
if (ext_type != CUSTOM_EXT_TYPE_1)
custom_ext_error = 1;
@ -511,13 +520,12 @@ static int custom_ext_1_cli_second_cb(SSL *s, unsigned short ext_type,
unsigned short inlen, int *al,
void *arg)
{
custom_ext_error = 1; /* Shouldn't be called */
return 0;
return 1;
}
static int custom_ext_2_cli_first_cb(SSL *s, unsigned short ext_type,
const unsigned char **out,
unsigned short *outlen, void *arg)
unsigned short *outlen, int *al, void *arg)
{
if (ext_type != CUSTOM_EXT_TYPE_2)
custom_ext_error = 1;
@ -540,7 +548,7 @@ static int custom_ext_2_cli_second_cb(SSL *s, unsigned short ext_type,
static int custom_ext_3_cli_first_cb(SSL *s, unsigned short ext_type,
const unsigned char **out,
unsigned short *outlen, void *arg)
unsigned short *outlen, int *al, void *arg)
{
if (ext_type != CUSTOM_EXT_TYPE_3)
custom_ext_error = 1;
@ -563,28 +571,27 @@ static int custom_ext_3_cli_second_cb(SSL *s, unsigned short ext_type,
return 1;
}
/* custom_ext_0_cli_first_cb returns -1 - the server won't receive a callback for this extension */
static int custom_ext_0_srv_first_cb(SSL *s, unsigned short ext_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg)
{
custom_ext_error = 1;
return 0; /* Shouldn't be called */
return 1;
}
/* 'generate' callbacks are always called, even if the 'receive' callback isn't called */
static int custom_ext_0_srv_second_cb(SSL *s, unsigned short ext_type,
const unsigned char **out,
unsigned short *outlen, void *arg)
unsigned short *outlen, int *al, void *arg)
{
custom_ext_error = 1;
return 0; /* Shouldn't be called */
return -1; /* Don't send an extension */
}
static int custom_ext_1_srv_first_cb(SSL *s, unsigned short ext_type,
const unsigned char *in,
unsigned short inlen, int *al,
void *arg)
const unsigned char *in,
unsigned short inlen, int *al,
void *arg)
{
if (ext_type != CUSTOM_EXT_TYPE_1)
custom_ext_error = 1;
@ -598,7 +605,7 @@ static int custom_ext_1_srv_first_cb(SSL *s, unsigned short ext_type,
static int custom_ext_1_srv_second_cb(SSL *s, unsigned short ext_type,
const unsigned char **out,
unsigned short *outlen, void *arg)
unsigned short *outlen, int *al, void *arg)
{
return -1; /* Don't send an extension */
}
@ -620,7 +627,7 @@ static int custom_ext_2_srv_first_cb(SSL *s, unsigned short ext_type,
static int custom_ext_2_srv_second_cb(SSL *s, unsigned short ext_type,
const unsigned char **out,
unsigned short *outlen, void *arg)
unsigned short *outlen, int *al, void *arg)
{
*out = NULL;
*outlen = 0;
@ -644,13 +651,116 @@ static int custom_ext_3_srv_first_cb(SSL *s, unsigned short ext_type,
static int custom_ext_3_srv_second_cb(SSL *s, unsigned short ext_type,
const unsigned char **out,
unsigned short *outlen, void *arg)
unsigned short *outlen, int *al, void *arg)
{
*out = (const unsigned char*)custom_ext_srv_string;
*outlen = strlen(custom_ext_srv_string);
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, int *al, 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, int *al, 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, int *al, 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, int *al, 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;
@ -726,11 +836,6 @@ static void sv_usage(void)
" (default is sect163r2).\n");
#endif
fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
#ifndef OPENSSL_NO_TLSEXT
fprintf(stderr," -server_authz arg - binary authz file for certificate\n");
fprintf(stderr," -c_support_proof - indicate client support for server_authz audit proofs\n");
fprintf(stderr," -c_require_proof - fail if no audit proof is sent\n");
#endif
fprintf(stderr," -serverinfo_file file - have server use this file\n");
fprintf(stderr," -serverinfo_sct - have client offer and expect SCT\n");
fprintf(stderr," -serverinfo_tack - have client offer and expect TACK\n");
@ -738,6 +843,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)
@ -867,56 +973,6 @@ int opaque_prf_input_cb(SSL *ssl, void *peerinput, size_t len, void *arg_)
}
#endif
#ifndef OPENSSL_NO_TLSEXT
struct audit_proof_cb_arg_st
{
unsigned char *expected_proof;
size_t expected_proof_length;
int require;
};
struct audit_proof_cb_arg_st c_expected = { NULL, 0, 0 };
static int audit_proof_cb(SSL *s, void *arg)
{
const unsigned char *proof;
size_t proof_len;
SSL_SESSION *sess = SSL_get_session(s);
struct audit_proof_cb_arg_st *cb_arg = (struct audit_proof_cb_arg_st*)arg;
proof = SSL_SESSION_get_tlsext_authz_server_audit_proof(sess,
&proof_len);
if (proof != NULL)
{
if (proof_len == cb_arg->expected_proof_length &&
cb_arg->expected_proof != NULL &&
memcmp(proof, cb_arg->expected_proof, proof_len) == 0)
{
BIO_printf(bio_stdout, "Audit proof OK (%lu bytes).\n",
(long)proof_len);
return 1;
}
else
{
BIO_printf(bio_stdout, "Audit proof mismatch.\n");
/* Cause handshake failure. */
return 0;
}
}
else /* proof == NULL */
{
BIO_printf(bio_stdout, "No audit proof found.\n");
if (cb_arg->require)
{
/* Cause handshake failure. */
return 0;
}
return 1;
}
}
#endif
int main(int argc, char *argv[])
{
char *CApath=NULL,*CAfile=NULL;
@ -968,11 +1024,6 @@ int main(int argc, char *argv[])
#ifdef OPENSSL_FIPS
int fips_mode=0;
#endif
#ifndef OPENSSL_NO_TLSEXT
char *s_authz_file = NULL;
int c_support_proof = 0;
int c_require_proof = 0;
#endif
verbose = 0;
debug = 0;
@ -1191,24 +1242,6 @@ int main(int argc, char *argv[])
{
test_cipherlist = 1;
}
#ifndef OPENSSL_NO_TLSEXT
else if(strcmp(*argv,"-server_authz") == 0)
{
if (--argc < 1) goto bad;
s_authz_file = *(++argv);
tls1 = 1;
}
else if (strcmp(*argv,"-c_support_proof") == 0)
{
c_support_proof = 1;
tls1 = 1;
}
else if (strcmp(*argv,"-c_require_proof") == 0)
{
c_require_proof = 1;
tls1 = 1;
}
#endif
else if (strcmp(*argv,"-serverinfo_sct") == 0)
{
serverinfo_sct = 1;
@ -1241,6 +1274,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);
@ -1274,15 +1311,6 @@ bad:
"to avoid protocol mismatch.\n");
EXIT(1);
}
if (c_require_proof && s_authz_file == NULL && !force)
{
fprintf(stderr, "This case cannot work. -c_require_proof "
"requires an audit proof, but none was supplied. "
"Use -f to perform the test anyway (and\n-d to see "
"what happens), or use -server_authz to supply an "
"audit proof.\n");
EXIT(1);
}
#ifdef OPENSSL_FIPS
if(fips_mode)
@ -1554,34 +1582,6 @@ bad:
SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb);
}
#endif
#ifndef OPENSSL_NO_TLSEXT
if (s_authz_file != NULL)
{
if(!SSL_CTX_use_authz_file(s_ctx, s_authz_file))
{
BIO_printf(bio_err, "Unable to set authz data\n");
goto end;
}
}
if (c_support_proof || c_require_proof)
{
size_t proof_length;
const unsigned char *proof = SSL_CTX_get_authz_data(s_ctx,
TLSEXT_AUTHZDATAFORMAT_audit_proof, &proof_length);
if (proof != NULL)
{
/* Store a local copy. */
c_expected.expected_proof = OPENSSL_malloc(proof_length);
c_expected.expected_proof_length = proof_length;
memcpy(c_expected.expected_proof, proof, proof_length);
}
c_expected.require = c_require_proof;
SSL_CTX_set_tlsext_authz_server_audit_proof_cb(c_ctx,
audit_proof_cb);
SSL_CTX_set_tlsext_authz_server_audit_proof_cb_arg(c_ctx,
&c_expected);
}
#endif
if (serverinfo_sct)
SSL_CTX_set_custom_cli_ext(c_ctx, SCT_EXT_TYPE, NULL,
@ -1647,6 +1647,40 @@ 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)
{
@ -1717,10 +1751,6 @@ end:
#endif
#ifndef OPENSSL_NO_ENGINE
ENGINE_cleanup();
#endif
#ifndef OPENSSL_NO_TLSEXT
if (c_expected.expected_proof != NULL)
OPENSSL_free(c_expected.expected_proof);
#endif
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
@ -2411,7 +2441,11 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count)
if (verbose)
print_details(c_ssl, "DONE: ");
if (suppdata_error < 0)
{
ret = 1;
goto err;
}
if (verify_serverinfo() < 0)
{
ret = 1;

View File

@ -1089,20 +1089,7 @@ void ssl_set_client_disabled(SSL *s)
c->valid = 1;
}
/* byte_compare is a compare function for qsort(3) that compares bytes. */
static int byte_compare(const void *in_a, const void *in_b)
{
unsigned char a = *((const unsigned char*) in_a);
unsigned char b = *((const unsigned char*) in_b);
if (a > b)
return 1;
else if (a < b)
return -1;
return 0;
}
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al)
{
int extdatalen=0;
unsigned char *ret = p;
@ -1448,26 +1435,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)
{
@ -1486,7 +1453,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
{
int cb_retval = 0;
cb_retval = record->fn1(s, record->ext_type,
&out, &outlen,
&out, &outlen, al,
record->arg);
if (cb_retval == 0)
return NULL; /* error */
@ -1539,10 +1506,12 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
return ret;
}
unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al)
{
int extdatalen=0;
unsigned char *ret = p;
size_t i;
custom_srv_ext_record *record;
#ifndef OPENSSL_NO_NEXTPROTONEG
int next_proto_neg_seen;
#endif
@ -1726,118 +1695,30 @@ 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)
for (i = 0; i < s->ctx->custom_srv_ext_records_count; i++)
{
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;
const unsigned char *out = NULL;
unsigned short outlen = 0;
int cb_retval = 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;
record = &s->ctx->custom_srv_ext_records[i];
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)
{
size_t i;
for (i = 0; i < s->s3->tlsext_custom_types_count; i++)
{
size_t j;
custom_srv_ext_record *record;
for (j = 0; j < s->ctx->custom_srv_ext_records_count; j++)
{
record = &s->ctx->custom_srv_ext_records[j];
if (s->s3->tlsext_custom_types[i] == record->ext_type)
{
const unsigned char *out = NULL;
unsigned short outlen = 0;
int cb_retval = 0;
/* NULL callback or -1 omits extension */
if (!record->fn2)
break;
cb_retval = record->fn2(s, record->ext_type,
&out, &outlen,
record->arg);
if (cb_retval == 0)
return NULL; /* error */
if (cb_retval == -1)
break; /* skip this extension */
if (limit < ret + 4 + outlen)
return NULL;
s2n(record->ext_type, ret);
s2n(outlen, ret);
memcpy(ret, out, outlen);
ret += outlen;
break;
}
}
}
/* NULL callback or -1 omits extension */
if (!record->fn2)
continue;
cb_retval = record->fn2(s, record->ext_type,
&out, &outlen, al,
record->arg);
if (cb_retval == 0)
return NULL; /* error */
if (cb_retval == -1)
continue; /* skip this extension */
if (limit < ret + 4 + outlen)
return NULL;
s2n(record->ext_type, ret);
s2n(outlen, ret);
memcpy(ret, out, outlen);
ret += outlen;
}
if (s->s3->alpn_selected)
@ -2031,12 +1912,12 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
#endif
/* Clear observed custom extensions */
s->s3->tlsext_custom_types_count = 0;
if (s->s3->tlsext_custom_types != NULL)
s->s3->serverinfo_client_tlsext_custom_types_count = 0;
if (s->s3->serverinfo_client_tlsext_custom_types != NULL)
{
OPENSSL_free(s->s3->tlsext_custom_types);
s->s3->tlsext_custom_types = NULL;
}
OPENSSL_free(s->s3->serverinfo_client_tlsext_custom_types);
s->s3->serverinfo_client_tlsext_custom_types = NULL;
}
if (s->s3->alpn_selected)
{
@ -2545,66 +2426,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
@ -2620,35 +2441,8 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
record = &s->ctx->custom_srv_ext_records[i];
if (type == record->ext_type)
{
size_t j;
/* Error on duplicate TLS Extensions */
for (j = 0; j < s->s3->tlsext_custom_types_count; j++)
{
if (type == s->s3->tlsext_custom_types[j])
{
*al = TLS1_AD_DECODE_ERROR;
return 0;
}
}
/* NULL callback still notes the extension */
if (record->fn1 && !record->fn1(s, type, data, size, al, record->arg))
return 0;
/* Add the (non-duplicated) entry */
s->s3->tlsext_custom_types_count++;
s->s3->tlsext_custom_types = OPENSSL_realloc(
s->s3->tlsext_custom_types,
s->s3->tlsext_custom_types_count * 2);
if (s->s3->tlsext_custom_types == NULL)
{
s->s3->tlsext_custom_types = 0;
*al = TLS1_AD_INTERNAL_ERROR;
return 0;
}
s->s3->tlsext_custom_types[
s->s3->tlsext_custom_types_count - 1] = type;
}
}
}
@ -2970,46 +2764,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 */

View File

@ -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
/* DTCP Authorization Type
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#authorization-data-rules
* http://tools.ietf.org/id/draft-dthakore-tls-authz-04.txt
*/
#define TLSEXT_AUTHZDATAFORMAT_dtcp 66
#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