From: Scott Deboy Date: Tue, 18 Jun 2013 21:34:38 +0000 (-0700) Subject: Add callbacks supporting generation and retrieval of supplemental data entries, facil... X-Git-Tag: OpenSSL_1_0_2-beta1~41^2~12 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=038bec784e528ce273169f178c35991fbc3bea92;p=oweals%2Fopenssl.git Add callbacks supporting generation and retrieval of supplemental data entries, facilitating RFC 5878 (TLS auth extensions) Removed prior audit proof logic - audit proof support was implemented using the generic TLS extension API Tests exercising the new supplemental data registration and callback api can be found in ssltest.c. Implemented changes to s_server and s_client to exercise supplemental data callbacks via the -auth argument, as well as additional flags to exercise supplemental data being sent only during renegotiation. (cherry picked from commit 36086186a9b90cdad0d2cd0a598a10f03f8f4bcc) Conflicts: Configure apps/s_client.c apps/s_server.c ssl/ssl.h ssl/ssl3.h ssl/ssltest.c --- diff --git a/CHANGES b/CHANGES index 0b49a88c91..45d7596ac1 100644 --- a/CHANGES +++ b/CHANGES @@ -31,6 +31,10 @@ MGF1 digest and OAEP label. [Steve Henson] + *) Add callbacks supporting generation and retrieval of supplemental + data entries. + [Scott Deboy , 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 diff --git a/Configure b/Configure index 80ec25a62b..70bfe14e37 100755 --- a/Configure +++ b/Configure @@ -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" diff --git a/apps/s_apps.h b/apps/s_apps.h index ce5a763da8..f46d1ebe45 100644 --- a/apps/s_apps.h +++ b/apps/s_apps.h @@ -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); diff --git a/apps/s_cb.c b/apps/s_cb.c index 78f1d93c6c..040ffaf186 100644 --- a/apps/s_cb.c +++ b/apps/s_cb.c @@ -876,6 +876,9 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void * case 16: str_details1 = ", ClientKeyExchange"; break; + case 23: + str_details1 = ", SupplementalData"; + break; case 20: str_details1 = ", Finished"; break; diff --git a/apps/s_client.c b/apps/s_client.c index 3d607ea90d..715e063a65 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -203,7 +203,6 @@ static int c_debug=0; #ifndef OPENSSL_NO_TLSEXT static int c_tlsextdebug=0; static int c_status_req=0; -static int c_proof_debug=0; #endif static int c_msg=0; static int c_showcerts=0; @@ -215,7 +214,8 @@ static void sc_usage(void); static void print_stuff(BIO *berr,SSL *con,int full); #ifndef OPENSSL_NO_TLSEXT static int ocsp_resp_cb(SSL *s, void *arg); -static int audit_proof_cb(SSL *s, void *arg); +static int c_auth = 0; +static int c_auth_require_reneg = 0; #endif static BIO *bio_c_out=NULL; static BIO *bio_c_msg=NULL; @@ -223,6 +223,35 @@ static int c_quiet=0; static int c_ign_eof=0; static int c_brief=0; +#ifndef OPENSSL_NO_TLSEXT + +static const unsigned char *most_recent_supplemental_data; +static size_t most_recent_supplemental_data_length; + +static int server_provided_server_authz = 0; +static int server_provided_client_authz = 0; + +static const unsigned char auth_ext_data[]={TLSEXT_AUTHZDATAFORMAT_dtcp}; + +static int suppdata_cb(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg); + +static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type, + const unsigned char **out, + unsigned short *outlen, void *arg); + +static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type, + const unsigned char **out, unsigned short *outlen, + void *arg); + +static int authz_tlsext_cb(SSL *s, unsigned short ext_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg); +#endif + #ifndef OPENSSL_NO_PSK /* Default PSK identity and key */ static char *psk_identity="Client_identity"; @@ -365,15 +394,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 +850,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 +1427,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); @@ -2392,26 +2425,76 @@ static int ocsp_resp_cb(SSL *s, void *arg) return 1; } -static int audit_proof_cb(SSL *s, void *arg) +static int authz_tlsext_cb(SSL *s, unsigned short ext_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) { - const unsigned char *proof; - size_t proof_len; - size_t i; - SSL_SESSION *sess = SSL_get_session(s); - - proof = SSL_SESSION_get_tlsext_authz_server_audit_proof(sess, - &proof_len); - if (proof != NULL) + if (TLSEXT_TYPE_server_authz == ext_type) { - BIO_printf(bio_c_out, "Audit proof: "); - for (i = 0; i < proof_len; ++i) - BIO_printf(bio_c_out, "%02X", proof[i]); - BIO_printf(bio_c_out, "\n"); + server_provided_server_authz = (memchr(in, + TLSEXT_AUTHZDATAFORMAT_dtcp, + inlen) != NULL); } - else + + if (TLSEXT_TYPE_client_authz == ext_type) + { + server_provided_client_authz = (memchr(in, + TLSEXT_AUTHZDATAFORMAT_dtcp, + inlen) != NULL); + } + + return 1; + } + +static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type, + const unsigned char **out, unsigned short *outlen, + void *arg) + { + if (c_auth) + { + 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) { - 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, void *arg) + { + unsigned char *result; + if (c_auth && server_provided_client_authz && server_provided_server_authz) + { + if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s))) + { + result = OPENSSL_malloc(10); + memcpy(result, "5432154321", 10); + *out = result; + *outlen = 10; + return 1; + } + } + //no supplemental data to send + return -1; + } + #endif diff --git a/apps/s_server.c b/apps/s_server.c index 6aa4161b64..42e2133308 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -224,6 +224,18 @@ static DH *get_dh512(void); static void s_server_init(void); #endif +#ifndef OPENSSL_NO_TLSEXT + +static const unsigned char auth_ext_data[]={TLSEXT_AUTHZDATAFORMAT_dtcp}; + +static const unsigned char *most_recent_supplemental_data; +static size_t most_recent_supplemental_data_length; + +static int client_provided_server_authz = 0; +static int client_provided_client_authz = 0; + +#endif + #ifndef OPENSSL_NO_DH static unsigned char dh512_p[]={ 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, @@ -315,10 +327,29 @@ static int cert_chain = 0; #endif #ifndef OPENSSL_NO_TLSEXT -static BIO *authz_in = NULL; -static const char *s_authz_file = NULL; +static int suppdata_cb(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg); + +static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type, + const unsigned char **out, + unsigned short *outlen, void *arg); + +static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type, + const unsigned char **out, unsigned short *outlen, + void *arg); + +static int authz_tlsext_cb(SSL *s, unsigned short ext_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg); + static BIO *serverinfo_in = NULL; static const char *s_serverinfo_file = NULL; + +static int c_auth = 0; +static int c_auth_require_reneg = 0; #endif #ifndef OPENSSL_NO_PSK @@ -482,10 +513,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 +1051,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 +1166,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 +1959,25 @@ 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 @@ -3494,3 +3541,78 @@ static void free_sessions(void) } first = NULL; } + +#ifndef OPENSSL_NO_TLSEXT +static int authz_tlsext_cb(SSL *s, unsigned short ext_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + if (TLSEXT_TYPE_server_authz == ext_type) + { + client_provided_server_authz = (memchr(in, + TLSEXT_AUTHZDATAFORMAT_dtcp, + inlen) != NULL); + } + + if (TLSEXT_TYPE_client_authz == ext_type) + { + client_provided_client_authz = (memchr(in, + TLSEXT_AUTHZDATAFORMAT_dtcp, + inlen) != NULL); + } + + return 1; + } + +static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type, + const unsigned char **out, unsigned short *outlen, + void *arg) + { + if (c_auth && client_provided_client_authz && client_provided_server_authz) + { + if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s))) + { + *out = auth_ext_data; + *outlen = 1; + return 1; + } + } + //no auth extension to send + return -1; + } + +static int suppdata_cb(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + if (supp_data_type == TLSEXT_SUPPLEMENTALDATATYPE_authz_data) + { + most_recent_supplemental_data = in; + most_recent_supplemental_data_length = inlen; + } + return 1; + } + +static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type, + const unsigned char **out, + unsigned short *outlen, void *arg) + { + unsigned char *result; + if (c_auth && client_provided_client_authz && client_provided_server_authz) + { + if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s))) + { + result = OPENSSL_malloc(10); + memcpy(result, "1234512345", 10); + *out = result; + *outlen = 10; + return 1; + } + } + //no supplemental data to send + return -1; + } +#endif + diff --git a/crypto/symhacks.h b/crypto/symhacks.h index 66733a302b..5774d24561 100644 --- a/crypto/symhacks.h +++ b/crypto/symhacks.h @@ -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 diff --git a/doc/apps/s_client.pod b/doc/apps/s_client.pod index 8755930cec..ab3547d321 100644 --- a/doc/apps/s_client.pod +++ b/doc/apps/s_client.pod @@ -44,6 +44,8 @@ B B [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 diff --git a/doc/apps/s_server.pod b/doc/apps/s_server.pod index c1b40321c6..b0d5d28428 100644 --- a/doc/apps/s_server.pod +++ b/doc/apps/s_server.pod @@ -55,7 +55,9 @@ B B [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 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 diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c index 710d4f228e..a101bce161 100644 --- a/ssl/s23_clnt.c +++ b/ssl/s23_clnt.c @@ -362,10 +362,10 @@ static int ssl23_client_hello(SSL *s) if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL) ssl2_compat = 0; #endif - if (s->ctx->tlsext_authz_server_audit_proof_cb != NULL) - ssl2_compat = 0; if (s->ctx->custom_cli_ext_records_count != 0) ssl2_compat = 0; + if (s->ctx->cli_supp_data_records_count != 0) + ssl2_compat = 0; } #endif diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 9e3c847de9..d7178793ab 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -307,13 +307,6 @@ int ssl3_connect(SSL *s) } else { -#ifndef OPENSSL_NO_TLSEXT - /* The server hello indicated that - * an audit proof would follow. */ - if (s->s3->tlsext_authz_server_promised) - s->state=SSL3_ST_CR_SUPPLEMENTAL_DATA_A; - else -#endif s->state=SSL3_ST_CR_CERT_A; } s->init_num=0; @@ -332,6 +325,12 @@ int ssl3_connect(SSL *s) #ifndef OPENSSL_NO_TLSEXT ret=ssl3_check_finished(s); if (ret <= 0) goto end; + if (ret == 3) + { + s->state=SSL3_ST_CR_SUPPLEMENTAL_DATA_A; + s->init_num=0; + break; + } if (ret == 2) { s->hit = 1; @@ -410,10 +409,14 @@ int ssl3_connect(SSL *s) } } #endif +#ifndef OPENSSL_NO_TLSEXT + s->state=SSL3_ST_CW_SUPPLEMENTAL_DATA_A; +#else if (s->s3->tmp.cert_req) s->state=SSL3_ST_CW_CERT_A; else s->state=SSL3_ST_CW_KEY_EXCH_A; +#endif s->init_num=0; break; @@ -520,6 +523,19 @@ int ssl3_connect(SSL *s) break; #endif +#ifndef OPENSSL_NO_TLSEXT + case SSL3_ST_CW_SUPPLEMENTAL_DATA_A: + case SSL3_ST_CW_SUPPLEMENTAL_DATA_B: + ret = tls1_send_client_supplemental_data(s, &skip); + if (ret <= 0) goto end; + if (s->s3->tmp.cert_req) + s->state=SSL3_ST_CW_CERT_A; + else + s->state=SSL3_ST_CW_KEY_EXCH_A; + s->init_num=0; + break; +#endif + case SSL3_ST_CW_FINISHED_A: case SSL3_ST_CW_FINISHED_B: ret=ssl3_send_finished(s, @@ -1353,21 +1369,6 @@ int ssl3_get_server_certificate(SSL *s) s->session->verify_result = s->verify_result; x=NULL; -#ifndef OPENSSL_NO_TLSEXT - /* Check the audit proof. */ - if (s->ctx->tlsext_authz_server_audit_proof_cb) - { - ret = s->ctx->tlsext_authz_server_audit_proof_cb(s, - s->ctx->tlsext_authz_server_audit_proof_cb_arg); - if (ret <= 0) - { - al = SSL_AD_BAD_CERTIFICATE; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_INVALID_AUDIT_PROOF); - goto f_err; - } - } - -#endif ret=1; if (0) { @@ -3568,11 +3569,9 @@ int ssl3_check_finished(SSL *s) { int ok; long n; - /* If we have no ticket it cannot be a resumed session. */ - if (!s->session->tlsext_tick) - return 1; - /* this function is called when we really expect a Certificate - * message, so permit appropriate message length */ +/* Read the message to see if it is supplemental data, regardless if there is a session ticket + this function is called when we really expect a Certificate + message, so permit appropriate message length */ n=s->method->ssl_get_message(s, SSL3_ST_CR_CERT_A, SSL3_ST_CR_CERT_B, @@ -3581,6 +3580,14 @@ int ssl3_check_finished(SSL *s) &ok); if (!ok) return((int)n); s->s3->tmp.reuse_message = 1; + + if (s->s3->tmp.message_type == SSL3_MT_SUPPLEMENTAL_DATA) + { + return 3; + } + /* If we have no ticket it cannot be a resumed session. */ + if (!s->session->tlsext_tick) + return 1; if ((s->s3->tmp.message_type == SSL3_MT_FINISHED) || (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET)) return 2; @@ -3608,15 +3615,99 @@ int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) } #ifndef OPENSSL_NO_TLSEXT +int tls1_send_client_supplemental_data(SSL *s, int *skip) + { + if (s->ctx->cli_supp_data_records_count) + { + unsigned char *p = NULL; + unsigned char *size_loc = NULL; + cli_supp_data_record *record = NULL; + size_t length = 0; + size_t i = 0; + + for (i = 0; i < s->ctx->cli_supp_data_records_count; i++) + { + const unsigned char *out = NULL; + unsigned short outlen = 0; + int cb_retval = 0; + record = &s->ctx->cli_supp_data_records[i]; + + /* NULL callback or -1 omits supp data entry*/ + if (!record->fn2) + continue; + cb_retval = record->fn2(s, record->supp_data_type, + &out, &outlen, + record->arg); + if (cb_retval == -1) + continue; /* skip this supp data entry */ + if (cb_retval == 0) + { + SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); + return 0; + } + if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length) + { + SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); + return 0; + } + //if first entry, write handshake message type + if (length == 0) + { + if (!BUF_MEM_grow_clean(s->init_buf, 4)) + { + SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); + return 0; + } + p = (unsigned char *)s->init_buf->data; + *(p++) = SSL3_MT_SUPPLEMENTAL_DATA; + //update message length when all callbacks complete + size_loc = p; + //skip over handshake length field (3 bytes) and supp_data length field (3 bytes) + p += 3 + 3; + length += 1 +3 +3; + } + if (!BUF_MEM_grow(s->init_buf, outlen + 4)) + { + SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); + return 0; + } + s2n(record->supp_data_type, p); + s2n(outlen, p); + memcpy(p, out, outlen); + length += (outlen + 4); + p += outlen; + } + if (length > 0) + { + //write handshake length + l2n3(length - 4, size_loc); + //supp_data length + l2n3(length - 7, size_loc); + s->state = SSL3_ST_CW_SUPPLEMENTAL_DATA_B; + s->init_num = length; + s->init_off = 0; + return ssl3_do_write(s, SSL3_RT_HANDSHAKE); + } + } + + //no supp data message sent + *skip = 1; + s->init_num = 0; + s->init_off = 0; + return 1; + } + int tls1_get_server_supplemental_data(SSL *s) { - int al; + int al = 0; int ok; - unsigned long supp_data_len, authz_data_len; long n; - unsigned short supp_data_type, authz_data_type, proof_len; - const unsigned char *p; - unsigned char *new_proof; + const unsigned char *p, *d; + unsigned short supp_data_entry_type = 0; + unsigned long supp_data_entry_len = 0; + unsigned long supp_data_len = 0; + size_t i; + int cb_retval = 0; n=s->method->ssl_get_message(s, SSL3_ST_CR_SUPPLEMENTAL_DATA_A, @@ -3629,7 +3720,7 @@ int tls1_get_server_supplemental_data(SSL *s) if (!ok) return((int)n); p = (unsigned char *)s->init_msg; - + d = p; /* The message cannot be empty */ if (n < 3) { @@ -3637,72 +3728,26 @@ int tls1_get_server_supplemental_data(SSL *s) SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH); goto f_err; } - /* Length of supplemental data */ - n2l3(p,supp_data_len); - n -= 3; - /* We must have at least one supplemental data entry - * with type (1 byte) and length (2 bytes). */ - if (supp_data_len != (unsigned long) n || n < 4) + n2l3(p, supp_data_len); + while (psession->audit_proof, - proof_len); - if (new_proof == NULL) - { - SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,ERR_R_MALLOC_FAILURE); - return 0; + n2s(p, supp_data_entry_type); + n2s(p, supp_data_entry_len); + //if there is a callback for this supp data type, send it + for (i=0; i < s->ctx->cli_supp_data_records_count; i++) + { + if (s->ctx->cli_supp_data_records[i].supp_data_type == supp_data_entry_type && s->ctx->cli_supp_data_records[i].fn1) + { + cb_retval = s->ctx->cli_supp_data_records[i].fn1(s, supp_data_entry_type, p, supp_data_entry_len, &al, s->ctx->cli_supp_data_records[i].arg); + if (cb_retval == 0) + { + SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA, ERR_R_SSL_LIB); + goto f_err; + } + } + } + p+=supp_data_entry_len; } - s->session->audit_proof_length = proof_len; - s->session->audit_proof = new_proof; - memcpy(s->session->audit_proof, p, proof_len); - - /* Got the proof, but can't verify it yet. */ return 1; f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 372910f573..b03601d6ea 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -3029,8 +3029,6 @@ void ssl3_free(SSL *s) SSL_SRP_CTX_free(s); #endif #ifndef OPENSSL_NO_TLSEXT - if (s->s3->tlsext_authz_client_types != NULL) - OPENSSL_free(s->s3->tlsext_authz_client_types); if (s->s3->tlsext_custom_types != NULL) OPENSSL_free(s->s3->tlsext_custom_types); #endif @@ -3078,11 +3076,6 @@ void ssl3_clear(SSL *s) } #endif #ifndef OPENSSL_NO_TLSEXT - if (s->s3->tlsext_authz_client_types != NULL) - { - OPENSSL_free(s->s3->tlsext_authz_client_types); - s->s3->tlsext_authz_client_types = NULL; - } if (s->s3->tlsext_custom_types != NULL) { OPENSSL_free(s->s3->tlsext_custom_types); @@ -3897,10 +3890,6 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) case SSL_CTRL_SET_CHAIN_CERT_STORE: return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg); - case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG: - ctx->tlsext_authz_server_audit_proof_cb_arg = parg; - break; - #endif /* !OPENSSL_NO_TLSEXT */ /* A Thawte special :-) */ @@ -4023,12 +4012,6 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void)) ctx->srp_ctx.SRP_give_srp_client_pwd_callback=(char *(*)(SSL *,void *))fp; break; #endif - - case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB: - ctx->tlsext_authz_server_audit_proof_cb = - (int (*)(SSL *, void *))fp; - break; - #endif default: return(0); diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 8902303afd..3699524eb3 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -413,14 +413,8 @@ int ssl3_accept(SSL *s) #ifndef OPENSSL_NO_TLSEXT case SSL3_ST_SW_SUPPLEMENTAL_DATA_A: case SSL3_ST_SW_SUPPLEMENTAL_DATA_B: - /* We promised to send an audit proof in the hello. */ - if (s->s3->tlsext_authz_promised_to_client) - { - ret = tls1_send_server_supplemental_data(s); - if (ret <= 0) goto end; - } - else - skip = 1; + ret = tls1_send_server_supplemental_data(s, &skip); + if (ret <= 0) goto end; s->state = SSL3_ST_SW_CERT_A; s->init_num = 0; @@ -595,7 +589,16 @@ int ssl3_accept(SSL *s) s->state=s->s3->tmp.next_state; break; - +#ifndef OPENSSL_NO_TLSEXT + case SSL3_ST_SR_SUPPLEMENTAL_DATA_A: + case SSL3_ST_SR_SUPPLEMENTAL_DATA_B: + ret=tls1_get_client_supplemental_data(s); + if (ret <= 0) goto end; + s->s3->tmp.next_state=SSL3_ST_SR_CERT_A; + s->state=SSL3_ST_SW_FLUSH; + s->init_num=0; + break; +#endif case SSL3_ST_SR_CERT_A: case SSL3_ST_SR_CERT_B: /* Check for second client hello (MS SGC) */ @@ -604,6 +607,10 @@ int ssl3_accept(SSL *s) goto end; if (ret == 2) s->state = SSL3_ST_SR_CLNT_HELLO_C; +#ifndef OPENSSL_NO_TLSEXT + else if (ret == 3) + s->state = SSL3_ST_SR_SUPPLEMENTAL_DATA_A; +#endif else { if (s->s3->tmp.cert_request) { @@ -894,6 +901,12 @@ int ssl3_check_client_hello(SSL *s) &ok); if (!ok) return((int)n); s->s3->tmp.reuse_message = 1; +#ifndef OPENSSL_NO_TLSEXT + if (s->s3->tmp.message_type == SSL3_MT_SUPPLEMENTAL_DATA) + { + return 3; + } +#endif if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO) { /* We only allow the client to restart the handshake once per @@ -3639,98 +3652,149 @@ int ssl3_get_next_proto(SSL *s) } # endif -int tls1_send_server_supplemental_data(SSL *s) +int tls1_send_server_supplemental_data(SSL *s, int *skip) { - size_t length = 0; - const unsigned char *authz, *orig_authz; - unsigned char *p; - size_t authz_length, i; - - if (s->state != SSL3_ST_SW_SUPPLEMENTAL_DATA_A) - return ssl3_do_write(s, SSL3_RT_HANDSHAKE); + if (s->ctx->srv_supp_data_records_count) + { + unsigned char *p = NULL; + unsigned char *size_loc = NULL; + srv_supp_data_record *record = NULL; + size_t length = 0; + size_t i = 0; + + for (i = 0; i < s->ctx->srv_supp_data_records_count; i++) + { + const unsigned char *out = NULL; + unsigned short outlen = 0; + int cb_retval = 0; + record = &s->ctx->srv_supp_data_records[i]; + + /* NULL callback or -1 omits supp data entry */ + if (!record->fn1) + continue; + cb_retval = record->fn1(s, record->supp_data_type, + &out, &outlen, + record->arg); + if (cb_retval == -1) + continue; /* skip this supp data entry */ + if (cb_retval == 0) + { + SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); + return 0; + } + if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length) + { + SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); + return 0; + } + //write supp data entry... + //if first entry, write handshake message type + //jump back to write length at end + if (length == 0) + { + //1 byte message type + 3 bytes for message length + if (!BUF_MEM_grow_clean(s->init_buf, 4)) + { + SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); + return 0; + } + p = (unsigned char *)s->init_buf->data; + *(p++) = SSL3_MT_SUPPLEMENTAL_DATA; + //hold on to length field to update later + size_loc = p; + //skip over handshake length field (3 bytes) and supp_data length field (3 bytes) + p += 3 + 3; + length += 1 +3 +3; + } + //2 byte supp data type + 2 byte length + outlen + if (!BUF_MEM_grow(s->init_buf, outlen + 4)) + { + SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); + return 0; + } + s2n(record->supp_data_type, p); + s2n(outlen, p); + memcpy(p, out, outlen); + //update length to supp data type (2 bytes) + supp data length (2 bytes) + supp data + length += (outlen + 4); + p += outlen; + } + if (length > 0) + { + //write handshake length + l2n3(length - 4, size_loc); + //supp_data length + l2n3(length - 7, size_loc); + s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B; + s->init_num = length; + s->init_off = 0; - orig_authz = authz = ssl_get_authz_data(s, &authz_length); - if (authz == NULL) - { - /* This should never occur. */ - return 0; + return ssl3_do_write(s, SSL3_RT_HANDSHAKE); + } } - /* First we walk over the authz data to see how long the handshake - * message will be. */ - for (i = 0; i < authz_length; i++) - { - unsigned short len; - unsigned char type; + //no supp data message sent + *skip = 1; + s->init_num = 0; + s->init_off = 0; + return 1; + } - type = *(authz++); - n2s(authz, len); - /* n2s increments authz by 2*/ - i += 2; +int tls1_get_client_supplemental_data(SSL *s) + { + int al = 0; + int cb_retval = 0; + int ok; + long n; + const unsigned char *p, *d; + unsigned short supp_data_entry_type = 0; + unsigned long supp_data_entry_len = 0; + unsigned long supp_data_len = 0; + size_t i = 0; - if (memchr(s->s3->tlsext_authz_client_types, - type, - s->s3->tlsext_authz_client_types_len) != NULL) - length += 1 /* authz type */ + 2 /* length */ + len; + n=s->method->ssl_get_message(s, + SSL3_ST_SR_SUPPLEMENTAL_DATA_A, + SSL3_ST_SR_SUPPLEMENTAL_DATA_B, + SSL3_MT_SUPPLEMENTAL_DATA, + /* use default limit */ + TLSEXT_MAXLEN_supplemental_data, + &ok); - authz += len; - i += len; - } + if (!ok) return((int)n); - length += 1 /* handshake type */ + - 3 /* handshake length */ + - 3 /* supplemental data length */ + - 2 /* supplemental entry type */ + - 2 /* supplemental entry length */; + p = (unsigned char *)s->init_msg; + d = p; - if (!BUF_MEM_grow_clean(s->init_buf, length)) + /* The message cannot be empty */ + if (n < 3) { - SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); - return 0; + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH); + goto f_err; } - - p = (unsigned char *)s->init_buf->data; - *(p++) = SSL3_MT_SUPPLEMENTAL_DATA; - /* Handshake length */ - l2n3(length - 4, p); - /* Length of supplemental data */ - l2n3(length - 7, p); - /* Supplemental data type */ - s2n(TLSEXT_SUPPLEMENTALDATATYPE_authz_data, p); - /* Its length */ - s2n(length - 11, p); - - authz = orig_authz; - - /* Walk over the authz again and append the selected elements. */ - for (i = 0; i < authz_length; i++) + n2l3(p, supp_data_len); + while (ps3->tlsext_authz_client_types, - type, - s->s3->tlsext_authz_client_types_len) != NULL) + n2s(p, supp_data_entry_type); + n2s(p, supp_data_entry_len); + //if there is a callback for this supp data type, send it + for (i=0; i < s->ctx->srv_supp_data_records_count; i++) { - *(p++) = type; - s2n(len, p); - memcpy(p, authz, len); - p += len; + if (s->ctx->srv_supp_data_records[i].supp_data_type == supp_data_entry_type && s->ctx->srv_supp_data_records[i].fn2) + { + cb_retval = s->ctx->srv_supp_data_records[i].fn2(s, supp_data_entry_type, p, supp_data_entry_len, &al, s->ctx->srv_supp_data_records[i].arg); + if (cb_retval == 0) + { + SSLerr(SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA, ERR_R_SSL_LIB); + goto f_err; + } + } } - - authz += len; - i += len; + p+=supp_data_entry_len; } - - s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B; - s->init_num = length; - s->init_off = 0; - - return ssl3_do_write(s, SSL3_RT_HANDSHAKE); + return 1; +f_err: + ssl3_send_alert(s,SSL3_AL_FATAL,al); + return -1; } #endif diff --git a/ssl/ssl.h b/ssl/ssl.h index a2f32d2c34..2f590fe5de 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -433,6 +433,58 @@ typedef struct { custom_srv_ext_second_cb_fn fn2; void *arg; } custom_srv_ext_record; + +/* Callbacks and structures for handling Supplemental Data: + * srv_supp_data_first_cb_fn - server sends Supplemental Data + * srv_supp_data_second_cb_fn - server receives Supplemental Data + * cli_supp_data_first_cb_fn - client receives Supplemental Data + * cli_supp_data_second_cb_fn - client sends Supplemental Data + * + * All these functions return nonzero on success. Zero will terminate + * the handshake (and return a specific TLS Fatal alert, if the function + * declaration has an "al" parameter). -1 for the "sending" functions + * will result in no supplemental data entry being added to the + * supplemental data message for the provided supplemental data type. + * + * "supp_data_type" is a Supplemental Data Type from 0-65535. + * "in" is a pointer to TLS "supplemental_data_entry" being provided to the cb. + * "out" is used by the callback to return a pointer to "supplemental data" + * which OpenSSL will later copy into the TLS handshake. The contents + * of this buffer should not be changed until the handshake is complete. + * "inlen" and "outlen" are Supplemental Data lengths from 0-65535. + * "al" is a TLS "AlertDescription" from 0-255 which WILL be sent as a + * fatal TLS alert, if the callback returns zero. + */ +typedef int (*srv_supp_data_first_cb_fn)(SSL *s, unsigned short supp_data_type, + const unsigned char **out, + unsigned short *outlen, void *arg); +typedef int (*srv_supp_data_second_cb_fn)(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg); + +typedef int (*cli_supp_data_first_cb_fn)(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg); +typedef int (*cli_supp_data_second_cb_fn)(SSL *s, unsigned short supp_data_type, + const unsigned char **out, + unsigned short *outlen, void *arg); + +typedef struct { + unsigned short supp_data_type; + srv_supp_data_first_cb_fn fn1; + srv_supp_data_second_cb_fn fn2; + void *arg; +} srv_supp_data_record; + +typedef struct { + unsigned short supp_data_type; + cli_supp_data_first_cb_fn fn1; + cli_supp_data_second_cb_fn fn2; + void *arg; +} cli_supp_data_record; + #endif #ifndef OPENSSL_NO_SSL_INTERN @@ -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 diff --git a/ssl/ssl3.h b/ssl/ssl3.h index e2a58c30cc..6e7bd0f62c 100644 --- a/ssl/ssl3.h +++ b/ssl/ssl3.h @@ -560,20 +560,6 @@ typedef struct ssl3_state_st #endif #ifndef OPENSSL_NO_TLSEXT - /* tlsext_authz_client_types contains an array of supported authz - * types, as advertised by the client. The array is sorted and - * does not contain any duplicates. */ - unsigned char *tlsext_authz_client_types; - size_t tlsext_authz_client_types_len; - /* tlsext_authz_promised_to_client is true iff we're a server and we - * echoed the client's supplemental data extension and therefore must - * send a supplemental data handshake message. */ - char tlsext_authz_promised_to_client; - /* tlsext_authz_server_promised is true iff we're a client and the - * server echoed our server_authz extension and therefore must send us - * a supplemental data handshake message. */ - char tlsext_authz_server_promised; - /* tlsext_custom_types contains an array of TLS Extension types which * were advertised by the client in its ClientHello, which were not * otherwise handled by OpenSSL, and which the server has registered @@ -628,8 +614,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 +632,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 +662,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 +706,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 +723,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 diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index b771105785..1e2ab9da97 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -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); diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 3de87ea0a6..7dcc261764 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -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"}, diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 9862f63d2b..6cbc083945 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -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) { diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 0faf2a1cbf..6f1209cbbb 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -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 @@ -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 diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c index 73e9179e4e..0a28950875 100644 --- a/ssl/ssl_rsa.c +++ b/ssl/ssl_rsa.c @@ -66,10 +66,6 @@ static int ssl_set_cert(CERT *c, X509 *x509); static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); -#ifndef OPENSSL_NO_TLSEXT -static int ssl_set_authz(CERT *c, unsigned char *authz, - size_t authz_length); -#endif int SSL_use_certificate(SSL *ssl, X509 *x) { if (x == NULL) @@ -463,6 +459,15 @@ static int ssl_set_cert(CERT *c, X509 *x) X509_free(c->pkeys[i].x509); CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509); c->pkeys[i].x509=x; +#ifndef OPENSSL_NO_TLSEXT + /* Free the old serverinfo data, if it exists. */ + if (c->pkeys[i].serverinfo != NULL) + { + OPENSSL_free(c->pkeys[i].serverinfo); + c->pkeys[i].serverinfo = NULL; + c->pkeys[i].serverinfo_length = 0; + } +#endif c->key= &(c->pkeys[i]); c->valid=0; @@ -798,50 +803,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, @@ -974,83 +935,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 +978,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; diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index 90f92b2d11..73d87fd6c1 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -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; diff --git a/ssl/ssl_stat.c b/ssl/ssl_stat.c index 144b81e55f..aae31a9849 100644 --- a/ssl/ssl_stat.c +++ b/ssl/ssl_stat.c @@ -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) diff --git a/ssl/ssltest.c b/ssl/ssltest.c index c126eb627b..3755e06905 100644 --- a/ssl/ssltest.c +++ b/ssl/ssltest.c @@ -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) @@ -651,6 +661,109 @@ static int custom_ext_3_srv_second_cb(SSL *s, unsigned short ext_type, return 1; /* Send "defg" */ } +static int supp_data_0_srv_first_cb(SSL *s, unsigned short supp_data_type, + const unsigned char **out, + unsigned short *outlen, void *arg) + { + *out = (const unsigned char*)supp_data_0_string; + *outlen = strlen(supp_data_0_string); + if (arg != s) + suppdata_error = 1; + return 1; + } + +static int supp_data_0_srv_second_cb(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + if (supp_data_type != CUSTOM_SUPP_DATA_TYPE_0) + suppdata_error = 1; + if (inlen != strlen(supp_data_0_string)) + suppdata_error = 1; + if (memcmp(in, supp_data_0_string, inlen) != 0) + suppdata_error = 1; + if (arg != s) + suppdata_error = 1; + return 1; + } + +static int supp_data_1_srv_first_cb(SSL *s, unsigned short supp_data_type, + const unsigned char **out, + unsigned short *outlen, void *arg) + { + return -1; + } + +static int supp_data_1_srv_second_cb(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + suppdata_error = 1; + return 1; + } + +static int supp_data_2_srv_second_cb(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + suppdata_error = 1; + return 1; + } + +static int supp_data_0_cli_first_cb(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + if (supp_data_type != CUSTOM_SUPP_DATA_TYPE_0) + suppdata_error = 1; + if (inlen != strlen(supp_data_0_string)) + suppdata_error = 1; + if (memcmp(in, supp_data_0_string, inlen) != 0) + suppdata_error = 1; + if (arg != s) + suppdata_error = 1; + return 1; + } + +static int supp_data_0_cli_second_cb(SSL *s, unsigned short supp_data_type, + const unsigned char **out, + unsigned short *outlen, void *arg) + { + *out = (const unsigned char*)supp_data_0_string; + *outlen = strlen(supp_data_0_string); + if (arg != s) + suppdata_error = 1; + return 1; + } + +static int supp_data_1_cli_first_cb(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + suppdata_error = 1; + return 1; + } + +static int supp_data_1_cli_second_cb(SSL *s, unsigned short supp_data_type, + const unsigned char **out, + unsigned short *outlen, void *arg) + { + return -1; + } + +static int supp_data_2_cli_first_cb(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + suppdata_error = 1; + return 1; + } static char *cipher=NULL; static int verbose=0; @@ -738,6 +851,7 @@ static void sv_usage(void) fprintf(stderr," -alpn_client - have client side offer ALPN\n"); fprintf(stderr," -alpn_server - have server side offer ALPN\n"); fprintf(stderr," -alpn_expected - 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) @@ -1241,6 +1355,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); @@ -1647,6 +1765,23 @@ bad: c_ssl=SSL_new(c_ctx); s_ssl=SSL_new(s_ctx); + if (suppdata) + { + //TEST CASES + //client and server both send and receive, verify additional arg passed back + SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_0, supp_data_0_srv_first_cb, supp_data_0_srv_second_cb, s_ssl); + SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_0, supp_data_0_cli_first_cb, supp_data_0_cli_second_cb, c_ssl); + + //-1 response from sending server/client doesn't receive, -1 response from sending client/server doesn't receive + SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_1, supp_data_1_srv_first_cb, supp_data_1_srv_second_cb, NULL); + SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_1, supp_data_1_cli_first_cb, supp_data_1_cli_second_cb, NULL); + + //null sending server/client doesn't receive, null sending client/server doesn't receive + SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_2, /*supp_data_2_srv_first_cb*/NULL, supp_data_2_srv_second_cb, NULL); + SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_2, supp_data_2_cli_first_cb, /*supp_data_2_cli_second_cb*/NULL, NULL); + + //alerts set to non-zero and zero return values not tested + } #ifndef OPENSSL_NO_KRB5 if (c_ssl && c_ssl->kssl_ctx) { @@ -2411,7 +2546,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; diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 05c66825f2..291f4ab00f 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1448,26 +1448,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) { @@ -1726,79 +1706,6 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha } #endif - /* If the client supports authz then see whether we have any to offer - * to it. */ - if (s->s3->tlsext_authz_client_types_len) - { - size_t authz_length; - /* By now we already know the new cipher, so we can look ahead - * to see whether the cert we are going to send - * has any authz data attached to it. */ - const unsigned char* authz = ssl_get_authz_data(s, &authz_length); - const unsigned char* const orig_authz = authz; - size_t i; - unsigned authz_count = 0; - - /* The authz data contains a number of the following structures: - * uint8_t authz_type - * uint16_t length - * uint8_t data[length] - * - * First we walk over it to find the number of authz elements. */ - for (i = 0; i < authz_length; i++) - { - unsigned short length; - unsigned char type; - - type = *(authz++); - if (memchr(s->s3->tlsext_authz_client_types, - type, - s->s3->tlsext_authz_client_types_len) != NULL) - authz_count++; - - n2s(authz, length); - /* n2s increments authz by 2 */ - i += 2; - authz += length; - i += length; - } - - if (authz_count) - { - /* Add TLS extension server_authz to the ServerHello message - * 2 bytes for extension type - * 2 bytes for extension length - * 1 byte for the list length - * n bytes for the list */ - const unsigned short ext_len = 1 + authz_count; - - if ((long)(limit - ret - 4 - ext_len) < 0) return NULL; - s2n(TLSEXT_TYPE_server_authz, ret); - s2n(ext_len, ret); - *(ret++) = authz_count; - s->s3->tlsext_authz_promised_to_client = 1; - } - - authz = orig_authz; - for (i = 0; i < authz_length; i++) - { - unsigned short length; - unsigned char type; - - authz_count++; - type = *(authz++); - if (memchr(s->s3->tlsext_authz_client_types, - type, - s->s3->tlsext_authz_client_types_len) != NULL) - *(ret++) = type; - n2s(authz, length); - /* n2s increments authz by 2 */ - i += 2; - authz += length; - i += length; - } - } - /* If custom types were sent in ClientHello, add ServerHello responses */ if (s->s3->tlsext_custom_types_count) { @@ -2545,66 +2452,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 @@ -2970,46 +2817,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 */ diff --git a/ssl/tls1.h b/ssl/tls1.h index b1b85bf632..92092f4e01 100644 --- a/ssl/tls1.h +++ b/ssl/tls1.h @@ -299,9 +299,12 @@ extern "C" { /* From RFC 5878 */ #define TLSEXT_SUPPLEMENTALDATATYPE_authz_data 16386 + /* This is not IANA assigned. See - * https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#authorization-data-rules */ -#define TLSEXT_AUTHZDATAFORMAT_audit_proof 182 + * https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#authorization-data-rules + * http://tools.ietf.org/id/draft-dthakore-tls-authz-01.txt + */ +#define TLSEXT_AUTHZDATAFORMAT_dtcp 225 #define TLSEXT_MAXLEN_supplemental_data 1024*16 /* Let's limit to 16k */ @@ -390,13 +393,6 @@ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg) #define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) -/* Used by clients to process audit proofs. */ -#define SSL_CTX_set_tlsext_authz_server_audit_proof_cb(ctx, cb) \ -SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB,(void (*)(void))cb) - -#define SSL_CTX_set_tlsext_authz_server_audit_proof_cb_arg(ctx, arg) \ -SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG, 0, arg); - #ifndef OPENSSL_NO_HEARTBEATS #define SSL_TLSEXT_HB_ENABLED 0x01 #define SSL_TLSEXT_HB_DONT_SEND_REQUESTS 0x02