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. MGF1 digest and OAEP label.
[Steve Henson] [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 *) 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 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 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", "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", "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-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", "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", "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/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", "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",

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_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key, int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
STACK_OF(X509) *chain, int build_chain); 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_sigalgs(BIO *out, SSL *s);
int ssl_print_point_formats(BIO *out, SSL *s); int ssl_print_point_formats(BIO *out, SSL *s);
int ssl_print_curves(BIO *out, SSL *s, int noshared); 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: case 20:
str_details1 = ", Finished"; str_details1 = ", Finished";
break; break;
case 23:
str_details1 = ", SupplementalData";
break;
} }
} }
} }

View File

@ -203,7 +203,6 @@ static int c_debug=0;
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
static int c_tlsextdebug=0; static int c_tlsextdebug=0;
static int c_status_req=0; static int c_status_req=0;
static int c_proof_debug=0;
#endif #endif
static int c_msg=0; static int c_msg=0;
static int c_showcerts=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); static void print_stuff(BIO *berr,SSL *con,int full);
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
static int ocsp_resp_cb(SSL *s, void *arg); 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 #endif
static BIO *bio_c_out=NULL; static BIO *bio_c_out=NULL;
static BIO *bio_c_msg=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_ign_eof=0;
static int c_brief=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 #ifndef OPENSSL_NO_PSK
/* Default PSK identity and key */ /* Default PSK identity and key */
static char *psk_identity="Client_identity"; 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," -tlsextdebug - hex dump of all TLS extensions received\n");
BIO_printf(bio_err," -status - request certificate status from server\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," -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 # ifndef OPENSSL_NO_NEXTPROTONEG
BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n"); BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
# endif # endif
BIO_printf(bio_err," -alpn arg - enable ALPN extension, considering named protocols supported (comma-separated list)\n"); BIO_printf(bio_err," -alpn arg - enable ALPN extension, considering named protocols supported (comma-separated list)\n");
#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," -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," -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"); BIO_printf(bio_err," -keymatexport label - Export keying material using label\n");
@ -822,8 +852,10 @@ static char *jpake_secret = NULL;
c_tlsextdebug=1; c_tlsextdebug=1;
else if (strcmp(*argv,"-status") == 0) else if (strcmp(*argv,"-status") == 0)
c_status_req=1; c_status_req=1;
else if (strcmp(*argv,"-proof_debug") == 0) else if (strcmp(*argv,"-auth") == 0)
c_proof_debug=1; c_auth = 1;
else if (strcmp(*argv,"-auth_require_reneg") == 0)
c_auth_require_reneg = 1;
#endif #endif
#ifdef WATT32 #ifdef WATT32
else if (strcmp(*argv,"-wdebug") == 0) else if (strcmp(*argv,"-wdebug") == 0)
@ -1397,9 +1429,12 @@ bad:
} }
#endif #endif
if (c_proof_debug) if (c_auth)
SSL_CTX_set_tlsext_authz_server_audit_proof_cb(ctx, {
audit_proof_cb); 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 #endif
con=SSL_new(ctx); con=SSL_new(ctx);
@ -1743,6 +1778,13 @@ SSL_set_tlsext_status_ids(con, ids);
"CONNECTION ESTABLISHED\n"); "CONNECTION ESTABLISHED\n");
print_ssl_summary(bio_err, con); 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); print_stuff(bio_c_out,con,full_log);
if (full_log > 0) full_log--; if (full_log > 0) full_log--;
@ -2392,26 +2434,74 @@ static int ocsp_resp_cb(SSL *s, void *arg)
return 1; 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; if (TLSEXT_TYPE_server_authz == ext_type)
size_t proof_len; server_provided_server_authz
size_t i; = (memchr(in, TLSEXT_AUTHZDATAFORMAT_dtcp, inlen) != NULL);
SSL_SESSION *sess = SSL_get_session(s);
proof = SSL_SESSION_get_tlsext_authz_server_audit_proof(sess, if (TLSEXT_TYPE_client_authz == ext_type)
&proof_len); server_provided_client_authz
if (proof != NULL) = (memchr(in, TLSEXT_AUTHZDATAFORMAT_dtcp, inlen) != NULL);
{
BIO_printf(bio_c_out, "Audit proof: "); return 1;
for (i = 0; i < proof_len; ++i)
BIO_printf(bio_c_out, "%02X", proof[i]);
BIO_printf(bio_c_out, "\n");
} }
else
static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, unsigned short *outlen,
int *al, void *arg)
{ {
BIO_printf(bio_c_out, "No audit proof found.\n"); if (c_auth)
{
/*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; 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 #endif

View File

@ -224,6 +224,20 @@ static DH *get_dh512(void);
static void s_server_init(void); static void s_server_init(void);
#endif #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 #ifndef OPENSSL_NO_DH
static unsigned char dh512_p[]={ static unsigned char dh512_p[]={
0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
@ -315,10 +329,29 @@ static int cert_chain = 0;
#endif #endif
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
static BIO *authz_in = NULL; static int suppdata_cb(SSL *s, unsigned short supp_data_type,
static const char *s_authz_file = NULL; 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 BIO *serverinfo_in = NULL;
static const char *s_serverinfo_file = NULL; static const char *s_serverinfo_file = NULL;
static int c_auth = 0;
static int c_auth_require_reneg = 0;
#endif #endif
#ifndef OPENSSL_NO_PSK #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," -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," -cert arg - certificate file to use\n");
BIO_printf(bio_err," (default is %s)\n",TEST_CERT); 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 #ifndef OPENSSL_NO_TLSEXT
BIO_printf(bio_err," -serverinfo arg - PEM serverinfo file for certificate\n"); 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 #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" \ 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"); " 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" \ 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; EVP_PKEY *s_key = NULL, *s_dkey = NULL;
int no_cache = 0, ext_cache = 0; int no_cache = 0, ext_cache = 0;
int rev = 0, naccept = -1; int rev = 0, naccept = -1;
int c_no_resumption_on_reneg = 0;
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
EVP_PKEY *s_key2 = NULL; EVP_PKEY *s_key2 = NULL;
X509 *s_cert2 = NULL; X509 *s_cert2 = NULL;
@ -1132,17 +1168,24 @@ int MAIN(int argc, char *argv[])
else if (strcmp(*argv,"-crl_download") == 0) else if (strcmp(*argv,"-crl_download") == 0)
crl_download = 1; crl_download = 1;
#ifndef OPENSSL_NO_TLSEXT #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) else if (strcmp(*argv,"-serverinfo") == 0)
{ {
if (--argc < 1) goto bad; if (--argc < 1) goto bad;
s_serverinfo_file = *(++argv); s_serverinfo_file = *(++argv);
} }
else if (strcmp(*argv,"-auth") == 0)
{
c_auth = 1;
}
#endif #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) else if (strcmp(*argv,"-certform") == 0)
{ {
if (--argc < 1) goto bad; if (--argc < 1) goto bad;
@ -1918,17 +1961,23 @@ bad:
} }
#endif #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)) if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain))
goto end; goto end;
#ifndef OPENSSL_NO_TLSEXT #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 if (s_serverinfo_file != NULL
&& !SSL_CTX_use_serverinfo_file(ctx, s_serverinfo_file)) && !SSL_CTX_use_serverinfo_file(ctx, s_serverinfo_file))
{ {
ERR_print_errors(bio_err); ERR_print_errors(bio_err);
goto end; 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 #endif
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2, NULL, build_chain)) if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2, NULL, build_chain))
@ -2097,8 +2146,6 @@ end:
X509_free(s_cert2); X509_free(s_cert2);
if (s_key2) if (s_key2)
EVP_PKEY_free(s_key2); EVP_PKEY_free(s_key2);
if (authz_in != NULL)
BIO_free(authz_in);
if (serverinfo_in != NULL) if (serverinfo_in != NULL)
BIO_free(serverinfo_in); BIO_free(serverinfo_in);
# ifndef OPENSSL_NO_NEXTPROTONEG # ifndef OPENSSL_NO_NEXTPROTONEG
@ -2631,6 +2678,13 @@ static int init_ssl_connection(SSL *con)
i=SSL_accept(con); i=SSL_accept(con);
} }
#endif #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 (i <= 0)
{ {
if (BIO_sock_should_retry(i)) if (BIO_sock_should_retry(i))
@ -3494,3 +3548,77 @@ static void free_sessions(void)
} }
first = NULL; 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 #undef tls1_send_server_supplemental_data
#define tls1_send_server_supplemental_data tls1_send_server_suppl_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 #undef tls1_get_server_supplemental_data
#define tls1_get_server_supplemental_data tls1_get_server_suppl_data #define tls1_get_server_supplemental_data tls1_get_server_suppl_data
#undef tls1_get_client_supplemental_data
#undef SSL_SESSION_get_tlsext_authz_server_audit_proof #define tls1_get_client_supplemental_data tls1_get_client_suppl_data
#define SSL_SESSION_get_tlsext_authz_server_audit_proof \
S_SES_get_tlsx_auz_srvr_aud_prf
#undef ssl3_cbc_record_digest_supported #undef ssl3_cbc_record_digest_supported
#define ssl3_cbc_record_digest_supported ssl3_cbc_record_digest_support #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<-sess_in filename>]
[B<-rand file(s)>] [B<-rand file(s)>]
[B<-serverinfo types>] [B<-serverinfo types>]
[B<-auth>]
[B<-auth_require_reneg>]
=head1 DESCRIPTION =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 The server's response (if any) will be encoded and displayed as a PEM
file. 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 =back
=head1 CONNECTED COMMANDS =head1 CONNECTED COMMANDS

View File

@ -55,7 +55,9 @@ B<openssl> B<s_server>
[B<-id_prefix arg>] [B<-id_prefix arg>]
[B<-rand file(s)>] [B<-rand file(s)>]
[B<-serverinfo file>] [B<-serverinfo file>]
[B<-auth>]
[B<-auth_require_reneg>]
[B<-no_resumption_on_reneg>]
=head1 DESCRIPTION =head1 DESCRIPTION
The B<s_server> command implements a generic SSL/TLS server which listens 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 an empty TLS ClientHello extension matching the type, the corresponding
ServerHello extension will be returned. 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 =back
=head1 CONNECTED COMMANDS =head1 CONNECTED COMMANDS

View File

@ -299,6 +299,7 @@ static int ssl23_client_hello(SSL *s)
unsigned long l; unsigned long l;
int ssl2_compat; int ssl2_compat;
int version = 0, version_major, version_minor; int version = 0, version_major, version_minor;
int al = 0;
#ifndef OPENSSL_NO_COMP #ifndef OPENSSL_NO_COMP
int j; int j;
SSL_COMP *comp; 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) if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL)
ssl2_compat = 0; ssl2_compat = 0;
#endif #endif
if (s->ctx->tlsext_authz_server_audit_proof_cb != NULL)
ssl2_compat = 0;
if (s->ctx->custom_cli_ext_records_count != 0) if (s->ctx->custom_cli_ext_records_count != 0)
ssl2_compat = 0; ssl2_compat = 0;
if (s->ctx->cli_supp_data_records_count != 0)
ssl2_compat = 0;
} }
#endif #endif
@ -553,8 +554,9 @@ static int ssl23_client_hello(SSL *s)
SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
return -1; 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); SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
return -1; return -1;
} }

View File

@ -307,13 +307,6 @@ int ssl3_connect(SSL *s)
} }
else 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->state=SSL3_ST_CR_CERT_A;
} }
s->init_num=0; s->init_num=0;
@ -332,6 +325,12 @@ int ssl3_connect(SSL *s)
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
ret=ssl3_check_finished(s); ret=ssl3_check_finished(s);
if (ret <= 0) goto end; if (ret <= 0) goto end;
if (ret == 3)
{
s->state=SSL3_ST_CR_SUPPLEMENTAL_DATA_A;
s->init_num=0;
break;
}
if (ret == 2) if (ret == 2)
{ {
s->hit = 1; s->hit = 1;
@ -410,10 +409,14 @@ int ssl3_connect(SSL *s)
} }
} }
#endif #endif
#ifndef OPENSSL_NO_TLSEXT
s->state=SSL3_ST_CW_SUPPLEMENTAL_DATA_A;
#else
if (s->s3->tmp.cert_req) if (s->s3->tmp.cert_req)
s->state=SSL3_ST_CW_CERT_A; s->state=SSL3_ST_CW_CERT_A;
else else
s->state=SSL3_ST_CW_KEY_EXCH_A; s->state=SSL3_ST_CW_KEY_EXCH_A;
#endif
s->init_num=0; s->init_num=0;
break; break;
@ -520,6 +523,19 @@ int ssl3_connect(SSL *s)
break; break;
#endif #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_A:
case SSL3_ST_CW_FINISHED_B: case SSL3_ST_CW_FINISHED_B:
ret=ssl3_send_finished(s, ret=ssl3_send_finished(s,
@ -673,6 +689,7 @@ int ssl3_client_hello(SSL *s)
unsigned char *p,*d; unsigned char *p,*d;
int i; int i;
unsigned long l; unsigned long l;
int al = 0;
#ifndef OPENSSL_NO_COMP #ifndef OPENSSL_NO_COMP
int j; int j;
SSL_COMP *comp; SSL_COMP *comp;
@ -875,8 +892,9 @@ int ssl3_client_hello(SSL *s)
SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
goto err; 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); SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
goto err; goto err;
} }
@ -1353,21 +1371,6 @@ int ssl3_get_server_certificate(SSL *s)
s->session->verify_result = s->verify_result; s->session->verify_result = s->verify_result;
x=NULL; 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; ret=1;
if (0) if (0)
{ {
@ -3568,11 +3571,11 @@ int ssl3_check_finished(SSL *s)
{ {
int ok; int ok;
long n; long n;
/* If we have no ticket it cannot be a resumed session. */
if (!s->session->tlsext_tick) /* Read the message to see if it is supplemental data,
return 1; * regardless if there is a session ticket this function is
/* this function is called when we really expect a Certificate * called when we really expect a Certificate message, so
* message, so permit appropriate message length */ * permit appropriate message length */
n=s->method->ssl_get_message(s, n=s->method->ssl_get_message(s,
SSL3_ST_CR_CERT_A, SSL3_ST_CR_CERT_A,
SSL3_ST_CR_CERT_B, SSL3_ST_CR_CERT_B,
@ -3581,6 +3584,12 @@ int ssl3_check_finished(SSL *s)
&ok); &ok);
if (!ok) return((int)n); if (!ok) return((int)n);
s->s3->tmp.reuse_message = 1; 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) if ((s->s3->tmp.message_type == SSL3_MT_FINISHED)
|| (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET)) || (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET))
return 2; return 2;
@ -3608,15 +3617,107 @@ int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
} }
#ifndef OPENSSL_NO_TLSEXT #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 tls1_get_server_supplemental_data(SSL *s)
{ {
int al; int al = 0;
int ok; int ok;
unsigned long supp_data_len, authz_data_len;
long n; long n;
unsigned short supp_data_type, authz_data_type, proof_len; const unsigned char *p, *d;
const unsigned char *p; unsigned short supp_data_entry_type = 0;
unsigned char *new_proof; 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, n=s->method->ssl_get_message(s,
SSL3_ST_CR_SUPPLEMENTAL_DATA_A, SSL3_ST_CR_SUPPLEMENTAL_DATA_A,
@ -3629,7 +3730,7 @@ int tls1_get_server_supplemental_data(SSL *s)
if (!ok) return((int)n); if (!ok) return((int)n);
p = (unsigned char *)s->init_msg; p = (unsigned char *)s->init_msg;
d = p;
/* The message cannot be empty */ /* The message cannot be empty */
if (n < 3) 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); SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
goto f_err; goto f_err;
} }
/* Length of supplemental data */
n2l3(p, supp_data_len); n2l3(p, supp_data_len);
n -= 3; while (p < d+supp_data_len)
/* 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)
{ {
al = SSL_AD_DECODE_ERROR; n2s(p, supp_data_entry_type);
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH); 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; goto f_err;
} }
/* Supplemental data type: must be authz_data */
n2s(p,supp_data_type);
n -= 2;
if (supp_data_type != TLSEXT_SUPPLEMENTALDATATYPE_authz_data)
{
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_UNKNOWN_SUPPLEMENTAL_DATA_TYPE);
goto f_err;
} }
/* Authz data length */
n2s(p, authz_data_len);
n -= 2;
if (authz_data_len != (unsigned long) n || n < 1)
{
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
goto f_err;
} }
/* Authz data type: must be audit_proof */ p += supp_data_entry_len;
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; return 1;
f_err: f_err:
ssl3_send_alert(s,SSL3_AL_FATAL,al); ssl3_send_alert(s,SSL3_AL_FATAL,al);

View File

@ -3029,10 +3029,8 @@ void ssl3_free(SSL *s)
SSL_SRP_CTX_free(s); SSL_SRP_CTX_free(s);
#endif #endif
#ifndef OPENSSL_NO_TLSEXT #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); OPENSSL_free(s->s3->serverinfo_client_tlsext_custom_types);
if (s->s3->tlsext_custom_types != NULL)
OPENSSL_free(s->s3->tlsext_custom_types);
#endif #endif
OPENSSL_cleanse(s->s3,sizeof *s->s3); OPENSSL_cleanse(s->s3,sizeof *s->s3);
OPENSSL_free(s->s3); OPENSSL_free(s->s3);
@ -3078,17 +3076,12 @@ void ssl3_clear(SSL *s)
} }
#endif #endif
#ifndef OPENSSL_NO_TLSEXT #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); OPENSSL_free(s->s3->serverinfo_client_tlsext_custom_types);
s->s3->tlsext_authz_client_types = NULL; s->s3->serverinfo_client_tlsext_custom_types = NULL;
} }
if (s->s3->tlsext_custom_types != NULL) s->s3->serverinfo_client_tlsext_custom_types_count = 0;
{
OPENSSL_free(s->s3->tlsext_custom_types);
s->s3->tlsext_custom_types = NULL;
}
s->s3->tlsext_custom_types_count = 0;
#ifndef OPENSSL_NO_EC #ifndef OPENSSL_NO_EC
s->s3->is_probably_safari = 0; s->s3->is_probably_safari = 0;
#endif /* !OPENSSL_NO_EC */ #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: case SSL_CTRL_SET_CHAIN_CERT_STORE:
return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg); 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 */ #endif /* !OPENSSL_NO_TLSEXT */
/* A Thawte special :-) */ /* 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; ctx->srp_ctx.SRP_give_srp_client_pwd_callback=(char *(*)(SSL *,void *))fp;
break; break;
#endif #endif
case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB:
ctx->tlsext_authz_server_audit_proof_cb =
(int (*)(SSL *, void *))fp;
break;
#endif #endif
default: default:
return(0); return(0);

View File

@ -413,14 +413,8 @@ int ssl3_accept(SSL *s)
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
case SSL3_ST_SW_SUPPLEMENTAL_DATA_A: case SSL3_ST_SW_SUPPLEMENTAL_DATA_A:
case SSL3_ST_SW_SUPPLEMENTAL_DATA_B: case SSL3_ST_SW_SUPPLEMENTAL_DATA_B:
/* We promised to send an audit proof in the hello. */ ret = tls1_send_server_supplemental_data(s, &skip);
if (s->s3->tlsext_authz_promised_to_client)
{
ret = tls1_send_server_supplemental_data(s);
if (ret <= 0) goto end; if (ret <= 0) goto end;
}
else
skip = 1;
s->state = SSL3_ST_SW_CERT_A; s->state = SSL3_ST_SW_CERT_A;
s->init_num = 0; s->init_num = 0;
@ -595,7 +589,16 @@ int ssl3_accept(SSL *s)
s->state=s->s3->tmp.next_state; s->state=s->s3->tmp.next_state;
break; 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_A:
case SSL3_ST_SR_CERT_B: case SSL3_ST_SR_CERT_B:
/* Check for second client hello (MS SGC) */ /* Check for second client hello (MS SGC) */
@ -604,6 +607,10 @@ int ssl3_accept(SSL *s)
goto end; goto end;
if (ret == 2) if (ret == 2)
s->state = SSL3_ST_SR_CLNT_HELLO_C; 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 { else {
if (s->s3->tmp.cert_request) if (s->s3->tmp.cert_request)
{ {
@ -894,6 +901,10 @@ int ssl3_check_client_hello(SSL *s)
&ok); &ok);
if (!ok) return((int)n); if (!ok) return((int)n);
s->s3->tmp.reuse_message = 1; 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) if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
{ {
/* We only allow the client to restart the handshake once per /* 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 *buf;
unsigned char *p,*d; unsigned char *p,*d;
int i,sl; int i,sl;
int al = 0;
unsigned long l; unsigned long l;
if (s->state == SSL3_ST_SW_SRVR_HELLO_A) 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); SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT);
return -1; 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); SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
return -1; return -1;
} }
@ -3639,98 +3652,156 @@ int ssl3_get_next_proto(SSL *s)
} }
# endif # endif
int tls1_send_server_supplemental_data(SSL *s) int tls1_send_server_supplemental_data(SSL *s, int *skip)
{ {
int al = 0;
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 length = 0;
const unsigned char *authz, *orig_authz; size_t i = 0;
unsigned char *p;
size_t authz_length, i;
if (s->state != SSL3_ST_SW_SUPPLEMENTAL_DATA_A) for (i = 0; i < s->ctx->srv_supp_data_records_count; i++)
return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
orig_authz = authz = ssl_get_authz_data(s, &authz_length);
if (authz == NULL)
{ {
/* This should never occur. */ const unsigned char *out = NULL;
return 0; unsigned short outlen = 0;
} int cb_retval = 0;
record = &s->ctx->srv_supp_data_records[i];
/* First we walk over the authz data to see how long the handshake /* NULL callback or -1 omits supp data entry */
* message will be. */ if (!record->fn1)
for (i = 0; i < authz_length; i++) 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)
{ {
unsigned short len; SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
unsigned char type; goto f_err;
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;
} }
if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length)
length += 1 /* handshake type */ + {
3 /* handshake length */ + SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
3 /* supplemental data length */ + return 0;
2 /* supplemental entry type */ + }
2 /* supplemental entry length */; /* write supp data entry...
* if first entry, write handshake message type
if (!BUF_MEM_grow_clean(s->init_buf, length)) * 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); SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
return 0; return 0;
} }
p = (unsigned char *)s->init_buf->data; p = (unsigned char *)s->init_buf->data;
*(p++) = SSL3_MT_SUPPLEMENTAL_DATA; *(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
/* Handshake length */ /* hold on to length field to update later */
l2n3(length - 4, p); size_loc = p;
/* Length of supplemental data */ /* skip over handshake length field (3
l2n3(length - 7, p); * bytes) and supp_data length field
/* Supplemental data type */ * (3 bytes) */
s2n(TLSEXT_SUPPLEMENTALDATATYPE_authz_data, p); p += 3 + 3;
/* Its length */ length += 1 +3 +3;
s2n(length - 11, p);
authz = orig_authz;
/* Walk over the authz again and append the selected elements. */
for (i = 0; i < authz_length; i++)
{
unsigned short len;
unsigned char type;
type = *(authz++);
n2s(authz, len);
/* n2s increments authz by 2 */
i += 2;
if (memchr(s->s3->tlsext_authz_client_types,
type,
s->s3->tlsext_authz_client_types_len) != NULL)
{
*(p++) = type;
s2n(len, p);
memcpy(p, authz, len);
p += len;
} }
/* 2 byte supp data type + 2 byte length + outlen */
authz += len; if (!BUF_MEM_grow(s->init_buf, outlen + 4))
i += len; {
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->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B;
s->init_num = length; s->init_num = length;
s->init_off = 0; s->init_off = 0;
return ssl3_do_write(s, SSL3_RT_HANDSHAKE); 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_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 #endif

128
ssl/ssl.h
View File

@ -406,7 +406,7 @@ 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, typedef int (*custom_cli_ext_first_cb_fn)(SSL *s, unsigned short ext_type,
const unsigned char **out, 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, typedef int (*custom_cli_ext_second_cb_fn)(SSL *s, unsigned short ext_type,
const unsigned char *in, const unsigned char *in,
unsigned short inlen, int *al, unsigned short inlen, int *al,
@ -418,7 +418,7 @@ typedef int (*custom_srv_ext_first_cb_fn)(SSL *s, unsigned short ext_type,
void *arg); void *arg);
typedef int (*custom_srv_ext_second_cb_fn)(SSL *s, unsigned short ext_type, typedef int (*custom_srv_ext_second_cb_fn)(SSL *s, unsigned short ext_type,
const unsigned char **out, const unsigned char **out,
unsigned short *outlen, void *arg); unsigned short *outlen, int *al, void *arg);
typedef struct { typedef struct {
unsigned short ext_type; unsigned short ext_type;
@ -433,6 +433,58 @@ typedef struct {
custom_srv_ext_second_cb_fn fn2; custom_srv_ext_second_cb_fn fn2;
void *arg; void *arg;
} custom_srv_ext_record; } 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 #endif
#ifndef OPENSSL_NO_SSL_INTERN #ifndef OPENSSL_NO_SSL_INTERN
@ -596,13 +648,6 @@ struct ssl_session_st
#endif #endif
#ifndef OPENSSL_NO_SRP #ifndef OPENSSL_NO_SRP
char *srp_username; char *srp_username;
#endif
#ifndef OPENSSL_NO_TLSEXT
/* Used by client: the proof for this session.
* We store it outside the sess_cert structure, since the proof
* is received before the certificate. */
unsigned char *audit_proof;
size_t audit_proof_length;
#endif #endif
}; };
@ -1149,8 +1194,6 @@ struct ssl_ctx_st
size_t tlsext_ellipticcurvelist_length; size_t tlsext_ellipticcurvelist_length;
unsigned char *tlsext_ellipticcurvelist; unsigned char *tlsext_ellipticcurvelist;
# endif /* OPENSSL_NO_EC */ # endif /* OPENSSL_NO_EC */
int (*tlsext_authz_server_audit_proof_cb)(SSL *s, void *arg);
void *tlsext_authz_server_audit_proof_cb_arg;
#endif #endif
/* Arrays containing the callbacks for custom TLS Extensions. */ /* Arrays containing the callbacks for custom TLS Extensions. */
@ -1158,6 +1201,12 @@ struct ssl_ctx_st
size_t custom_cli_ext_records_count; size_t custom_cli_ext_records_count;
custom_srv_ext_record *custom_srv_ext_records; custom_srv_ext_record *custom_srv_ext_records;
size_t custom_srv_ext_records_count; 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 #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, int SSL_CTX_set_custom_srv_ext(SSL_CTX *ctx, unsigned short ext_type,
custom_srv_ext_first_cb_fn fn1, custom_srv_ext_first_cb_fn fn1,
custom_srv_ext_second_cb_fn fn2, void *arg); 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 #endif
#define SSL_NOTHING 1 #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_GET_TLS_EXT_HEARTBEAT_PENDING 86
#define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS 87 #define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS 87
#endif #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 */ #endif /* OPENSSL_NO_TLSEXT */
#define DTLS_CTRL_GET_TIMEOUT 73 #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); int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
#ifndef OPENSSL_NO_TLSEXT #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. */ /* Set serverinfo data for the current active cert. */
int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
size_t serverinfo_length); size_t serverinfo_length);
@ -2163,10 +2223,6 @@ int SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
#ifndef OPENSSL_NO_BIO #ifndef OPENSSL_NO_BIO
int SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses); int SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses);
#endif #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); void SSL_SESSION_free(SSL_SESSION *ses);
int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp); int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
int SSL_set_session(SSL *to, SSL_SESSION *session); 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. */ /* Error codes for the SSL functions. */
/* Function codes. */ /* Function codes. */
#define SSL_F_AUTHZ_FIND_DATA 330 #define SSL_F_CHECK_SUITEB_CIPHER_LIST 335
#define SSL_F_AUTHZ_VALIDATE 323
#define SSL_F_CHECK_SUITEB_CIPHER_LIST 331
#define SSL_F_CLIENT_CERTIFICATE 100 #define SSL_F_CLIENT_CERTIFICATE 100
#define SSL_F_CLIENT_FINISHED 167 #define SSL_F_CLIENT_FINISHED 167
#define SSL_F_CLIENT_HELLO 101 #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_HELLO 109
#define SSL_F_GET_SERVER_VERIFY 110 #define SSL_F_GET_SERVER_VERIFY 110
#define SSL_F_I2D_SSL_SESSION 111 #define SSL_F_I2D_SSL_SESSION 111
#define SSL_F_READ_AUTHZ 329
#define SSL_F_READ_N 112 #define SSL_F_READ_N 112
#define SSL_F_REQUEST_CERTIFICATE 113 #define SSL_F_REQUEST_CERTIFICATE 113
#define SSL_F_SERVER_FINISH 239 #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_SESSION_ID_CONTEXT 219
#define SSL_F_SSL_CTX_SET_SSL_VERSION 170 #define SSL_F_SSL_CTX_SET_SSL_VERSION 170
#define SSL_F_SSL_CTX_SET_TRUST 229 #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 171
#define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172 #define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172
#define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE 220 #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_PRINT_FP 190
#define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312 #define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312
#define SSL_F_SSL_SESS_CERT_NEW 225 #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_CERT 191
#define SSL_F_SSL_SET_CIPHER_LIST 271 #define SSL_F_SSL_SET_CIPHER_LIST 271
#define SSL_F_SSL_SET_FD 192 #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_CONST_FUNCTION 243
#define SSL_F_SSL_UNDEFINED_FUNCTION 197 #define SSL_F_SSL_UNDEFINED_FUNCTION 197
#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244 #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 198
#define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 #define SSL_F_SSL_USE_CERTIFICATE_ASN1 199
#define SSL_F_SSL_USE_CERTIFICATE_FILE 200 #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_ENC 210
#define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314 #define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314
#define SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA 326 #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_HEARTBEAT 315
#define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT 275 #define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT 275
#define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT 276 #define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT 276
#define SSL_F_TLS1_PRF 284 #define SSL_F_TLS1_PRF 284
#define SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA 327 #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_TLS1_SETUP_KEY_BLOCK 211
#define SSL_F_WRITE_PENDING 212 #define SSL_F_WRITE_PENDING 212
/* Reason codes. */ /* Reason codes. */
#define SSL_R_APP_DATA_IN_HANDSHAKE 100 #define SSL_R_APP_DATA_IN_HANDSHAKE 100
#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 #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_ALERT_RECORD 101
#define SSL_R_BAD_AUTHENTICATION_TYPE 102 #define SSL_R_BAD_AUTHENTICATION_TYPE 102
#define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 #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_PADDING 283
#define SSL_R_ILLEGAL_SUITEB_DIGEST 380 #define SSL_R_ILLEGAL_SUITEB_DIGEST 380
#define SSL_R_INCONSISTENT_COMPRESSION 340 #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_CHALLENGE_LENGTH 158
#define SSL_R_INVALID_COMMAND 280 #define SSL_R_INVALID_COMMAND 280
#define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 #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_UNEXPECTED_RECORD 245
#define SSL_R_UNINITIALIZED 276 #define SSL_R_UNINITIALIZED 276
#define SSL_R_UNKNOWN_ALERT_TYPE 246 #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_CERTIFICATE_TYPE 247
#define SSL_R_UNKNOWN_CIPHER_RETURNED 248 #define SSL_R_UNKNOWN_CIPHER_RETURNED 248
#define SSL_R_UNKNOWN_CIPHER_TYPE 249 #define SSL_R_UNKNOWN_CIPHER_TYPE 249

View File

@ -560,28 +560,12 @@ typedef struct ssl3_state_st
#endif #endif
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
/* tlsext_authz_client_types contains an array of supported authz /* serverinfo_client_tlsext_custom_types contains an array of TLS Extension types which
* types, as advertised by the client. The array is sorted and * were advertised by the client in its ClientHello and leveraged by ServerInfo TLS extension callbacks.
* 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.
* The array does not contain any duplicates, and is in the same order * The array does not contain any duplicates, and is in the same order
* as the types were received in the client hello. */ * as the types were received in the client hello. */
unsigned short *tlsext_custom_types; unsigned short *serverinfo_client_tlsext_custom_types;
size_t tlsext_custom_types_count; /* how many tlsext_custom_types */ size_t serverinfo_client_tlsext_custom_types_count; /* how many serverinfo_client_tlsext_custom_types */
#ifndef OPENSSL_NO_EC #ifndef OPENSSL_NO_EC
/* This is set to true if we believe that this is a version of Safari /* 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_CERT_REQ_B (0x151|SSL_ST_CONNECT)
#define SSL3_ST_CR_SRVR_DONE_A (0x160|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_SRVR_DONE_B (0x161|SSL_ST_CONNECT)
#define SSL3_ST_CR_SUPPLEMENTAL_DATA_A (0x210|SSL_ST_CONNECT) #ifndef OPENSSL_NO_TLSEXT
#define SSL3_ST_CR_SUPPLEMENTAL_DATA_B (0x211|SSL_ST_CONNECT) #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 */ /* write to server */
#define SSL3_ST_CW_CERT_A (0x170|SSL_ST_CONNECT) #define SSL3_ST_CW_CERT_A (0x170|SSL_ST_CONNECT)
#define SSL3_ST_CW_CERT_B (0x171|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 #ifndef OPENSSL_NO_NEXTPROTONEG
#define SSL3_ST_CW_NEXT_PROTO_A (0x200|SSL_ST_CONNECT) #define SSL3_ST_CW_NEXT_PROTO_A (0x200|SSL_ST_CONNECT)
#define SSL3_ST_CW_NEXT_PROTO_B (0x201|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 #endif
#define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT) #define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT)
#define SSL3_ST_CW_FINISHED_B (0x1B1|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_B (0x111|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CLNT_HELLO_C (0x112|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) #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 */ /* write to client */
#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT) #define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|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_SESSION_TICKET_B (0x1F1|SSL_ST_ACCEPT)
#define SSL3_ST_SW_CERT_STATUS_A (0x200|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_CERT_STATUS_B (0x201|SSL_ST_ACCEPT)
#define SSL3_ST_SW_SUPPLEMENTAL_DATA_A (0x220|SSL_ST_ACCEPT) #ifndef OPENSSL_NO_TLSEXT
#define SSL3_ST_SW_SUPPLEMENTAL_DATA_B (0x221|SSL_ST_ACCEPT) #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_HELLO_REQUEST 0
#define SSL3_MT_CLIENT_HELLO 1 #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_CLIENT_KEY_EXCHANGE 16
#define SSL3_MT_FINISHED 20 #define SSL3_MT_FINISHED 20
#define SSL3_MT_CERTIFICATE_STATUS 22 #define SSL3_MT_CERTIFICATE_STATUS 22
#ifndef OPENSSL_NO_TLSEXT
#define SSL3_MT_SUPPLEMENTAL_DATA 23 #define SSL3_MT_SUPPLEMENTAL_DATA 23
#endif
#ifndef OPENSSL_NO_NEXTPROTONEG #ifndef OPENSSL_NO_NEXTPROTONEG
#define SSL3_MT_NEXT_PROTO 67 #define SSL3_MT_NEXT_PROTO 67
#endif #endif

View File

@ -330,23 +330,6 @@ CERT *ssl_cert_dup(CERT *cert)
} }
rpk->valid_flags = 0; rpk->valid_flags = 0;
#ifndef OPENSSL_NO_TLSEXT #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) if (cert->pkeys[i].serverinfo != NULL)
{ {
/* Just copy everything. */ /* Just copy everything. */
@ -479,11 +462,6 @@ void ssl_cert_clear_certs(CERT *c)
cpk->chain = NULL; cpk->chain = NULL;
} }
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
if (cpk->authz)
{
OPENSSL_free(cpk->authz);
cpk->authz = NULL;
}
if (cpk->serverinfo) if (cpk->serverinfo)
{ {
OPENSSL_free(cpk->serverinfo); OPENSSL_free(cpk->serverinfo);

View File

@ -70,8 +70,6 @@
static ERR_STRING_DATA SSL_str_functs[]= 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_CHECK_SUITEB_CIPHER_LIST), "CHECK_SUITEB_CIPHER_LIST"},
{ERR_FUNC(SSL_F_CLIENT_CERTIFICATE), "CLIENT_CERTIFICATE"}, {ERR_FUNC(SSL_F_CLIENT_CERTIFICATE), "CLIENT_CERTIFICATE"},
{ERR_FUNC(SSL_F_CLIENT_FINISHED), "CLIENT_FINISHED"}, {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_HELLO), "GET_SERVER_HELLO"},
{ERR_FUNC(SSL_F_GET_SERVER_VERIFY), "GET_SERVER_VERIFY"}, {ERR_FUNC(SSL_F_GET_SERVER_VERIFY), "GET_SERVER_VERIFY"},
{ERR_FUNC(SSL_F_I2D_SSL_SESSION), "i2d_SSL_SESSION"}, {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_READ_N), "READ_N"},
{ERR_FUNC(SSL_F_REQUEST_CERTIFICATE), "REQUEST_CERTIFICATE"}, {ERR_FUNC(SSL_F_REQUEST_CERTIFICATE), "REQUEST_CERTIFICATE"},
{ERR_FUNC(SSL_F_SERVER_FINISH), "SERVER_FINISH"}, {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_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_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_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), "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_ASN1), "SSL_CTX_use_certificate_ASN1"},
{ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE), "SSL_CTX_use_certificate_chain_file"}, {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_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_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_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_CERT), "SSL_SET_CERT"},
{ERR_FUNC(SSL_F_SSL_SET_CIPHER_LIST), "SSL_set_cipher_list"}, {ERR_FUNC(SSL_F_SSL_SET_CIPHER_LIST), "SSL_set_cipher_list"},
{ERR_FUNC(SSL_F_SSL_SET_FD), "SSL_set_fd"}, {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_CONST_FUNCTION), "ssl_undefined_const_function"},
{ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION), "ssl_undefined_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_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), "SSL_use_certificate"},
{ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_ASN1), "SSL_use_certificate_ASN1"}, {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_ASN1), "SSL_use_certificate_ASN1"},
{ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_FILE), "SSL_use_certificate_file"}, {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_ENC), "tls1_enc"},
{ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL), "tls1_export_keying_material"}, {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_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_HEARTBEAT), "tls1_heartbeat"},
{ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT), "TLS1_PREPARE_CLIENTHELLO_TLSEXT"}, {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_PREPARE_SERVERHELLO_TLSEXT), "TLS1_PREPARE_SERVERHELLO_TLSEXT"},
{ERR_FUNC(SSL_F_TLS1_PRF), "tls1_prf"}, {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_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_TLS1_SETUP_KEY_BLOCK), "tls1_setup_key_block"},
{ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"}, {ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"},
{0,NULL} {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_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_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_ALERT_RECORD) ,"bad alert record"},
{ERR_REASON(SSL_R_BAD_AUTHENTICATION_TYPE),"bad authentication type"}, {ERR_REASON(SSL_R_BAD_AUTHENTICATION_TYPE),"bad authentication type"},
{ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC),"bad change cipher spec"}, {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_PADDING) ,"illegal padding"},
{ERR_REASON(SSL_R_ILLEGAL_SUITEB_DIGEST) ,"illegal Suite B digest"}, {ERR_REASON(SSL_R_ILLEGAL_SUITEB_DIGEST) ,"illegal Suite B digest"},
{ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION),"inconsistent compression"}, {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_CHALLENGE_LENGTH),"invalid challenge length"},
{ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"}, {ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"},
{ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"}, {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_UNEXPECTED_RECORD) ,"unexpected record"},
{ERR_REASON(SSL_R_UNINITIALIZED) ,"uninitialized"}, {ERR_REASON(SSL_R_UNINITIALIZED) ,"uninitialized"},
{ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE) ,"unknown alert type"}, {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_CERTIFICATE_TYPE),"unknown certificate type"},
{ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED),"unknown cipher returned"}, {ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED),"unknown cipher returned"},
{ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE) ,"unknown cipher type"}, {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 else
*len = ssl->s3->alpn_selected_len; *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 */ #endif /* !OPENSSL_NO_TLSEXT */
int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, 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_cli_ext_records_count = 0;
ret->custom_srv_ext_records = NULL; ret->custom_srv_ext_records = NULL;
ret->custom_srv_ext_records_count = 0; 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 #ifndef OPENSSL_NO_BUF_FREELISTS
ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT; ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT;
ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
@ -2206,6 +2270,8 @@ void SSL_CTX_free(SSL_CTX *a)
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
OPENSSL_free(a->custom_cli_ext_records); OPENSSL_free(a->custom_cli_ext_records);
OPENSSL_free(a->custom_srv_ext_records); OPENSSL_free(a->custom_srv_ext_records);
OPENSSL_free(a->cli_supp_data_records);
OPENSSL_free(a->srv_supp_data_records);
#endif #endif
#ifndef OPENSSL_NO_ENGINE #ifndef OPENSSL_NO_ENGINE
if (a->client_cert_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 #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, int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo,
size_t *serverinfo_length) size_t *serverinfo_length)
{ {

View File

@ -505,14 +505,6 @@ typedef struct cert_pkey_st
/* Chain for this certificate */ /* Chain for this certificate */
STACK_OF(X509) *chain; STACK_OF(X509) *chain;
#ifndef OPENSSL_NO_TLSEXT #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 /* serverinfo data for this certificate. The data is in TLS Extension
* wire format, specifically it's a series of records like: * wire format, specifically it's a series of records like:
* uint16_t extension_type; // (RFC 5246, 7.4.1.4, Extension) * 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); int ssl_undefined_const_function(const SSL *s);
CERT_PKEY *ssl_get_server_send_pkey(const SSL *s); CERT_PKEY *ssl_get_server_send_pkey(const SSL *s);
#ifndef OPENSSL_NO_TLSEXT #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, int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo,
size_t *serverinfo_length); size_t *serverinfo_length);
#endif #endif
@ -1272,8 +1263,8 @@ int tls1_shared_list(SSL *s,
const unsigned char *l1, size_t l1len, const unsigned char *l1, size_t l1len,
const unsigned char *l2, size_t l2len, const unsigned char *l2, size_t l2len,
int nmatch); int nmatch);
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);
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 ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n); 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_check_clienthello_tlsext_late(SSL *s);
int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n); 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); int ssl_prepare_serverhello_tlsext(SSL *s);
/* server only */ /* 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 */ /* client only */
int tls1_send_client_supplemental_data(SSL *s, int *skip);
int tls1_get_server_supplemental_data(SSL *s); int tls1_get_server_supplemental_data(SSL *s);
#ifndef OPENSSL_NO_HEARTBEATS #ifndef OPENSSL_NO_HEARTBEATS

View File

@ -66,10 +66,6 @@
static int ssl_set_cert(CERT *c, X509 *x509); static int ssl_set_cert(CERT *c, X509 *x509);
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); 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) int SSL_use_certificate(SSL *ssl, X509 *x)
{ {
if (x == NULL) if (x == NULL)
@ -798,50 +794,6 @@ end:
#endif #endif
#ifndef OPENSSL_NO_TLSEXT #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, static int serverinfo_find_extension(const unsigned char *serverinfo,
size_t serverinfo_length, size_t serverinfo_length,
unsigned short extension_type, 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, unsigned short inlen, int *al,
void *arg) void *arg)
{ {
size_t i = 0;
if (inlen != 0) if (inlen != 0)
{ {
*al = SSL_AD_DECODE_ERROR; *al = SSL_AD_DECODE_ERROR;
return 0; 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; return 1;
} }
static int serverinfo_srv_second_cb(SSL *s, unsigned short ext_type, static int serverinfo_srv_second_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, unsigned short *outlen, const unsigned char **out, unsigned short *outlen,
void *arg) int *al, void *arg)
{ {
const unsigned char *serverinfo = NULL; const unsigned char *serverinfo = NULL;
size_t serverinfo_length = 0; 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? */ /* Is there serverinfo data for the chosen server cert? */
if ((ssl_get_server_cert_serverinfo(s, &serverinfo, if ((ssl_get_server_cert_serverinfo(s, &serverinfo,
@ -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, int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
size_t serverinfo_length) size_t serverinfo_length)
{ {
@ -1094,106 +1010,7 @@ int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
return 1; 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 #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) int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
{ {
unsigned char *serverinfo = NULL; unsigned char *serverinfo = NULL;

View File

@ -746,8 +746,6 @@ void SSL_SESSION_free(SSL_SESSION *ss)
ss->tlsext_ellipticcurvelist_length = 0; ss->tlsext_ellipticcurvelist_length = 0;
if (ss->tlsext_ellipticcurvelist != NULL) OPENSSL_free(ss->tlsext_ellipticcurvelist); if (ss->tlsext_ellipticcurvelist != NULL) OPENSSL_free(ss->tlsext_ellipticcurvelist);
#endif /* OPENSSL_NO_EC */ #endif /* OPENSSL_NO_EC */
if (ss->audit_proof != NULL) OPENSSL_free(ss->audit_proof);
ss->audit_proof_length = 0;
#endif #endif
#ifndef OPENSSL_NO_PSK #ifndef OPENSSL_NO_PSK
if (ss->psk_identity_hint != NULL) 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; 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 SSL_CTX_set_timeout(SSL_CTX *s, long t)
{ {
long l; 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_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_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_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 #endif
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) #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 */ /* This set based on extension callbacks */
int custom_ext_error = 0; 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, static int serverinfo_cli_cb(SSL* s, unsigned short ext_type,
const unsigned char* in, unsigned short inlen, const unsigned char* in, unsigned short inlen,
int* al, void* arg) 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, static int custom_ext_0_cli_first_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, const unsigned char **out,
unsigned short *outlen, void *arg) unsigned short *outlen, int *al, void *arg)
{ {
if (ext_type != CUSTOM_EXT_TYPE_0) if (ext_type != CUSTOM_EXT_TYPE_0)
custom_ext_error = 1; 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, unsigned short inlen, int *al,
void *arg) void *arg)
{ {
custom_ext_error = 1; /* Shouldn't be called */ return 1;
return 0;
} }
static int custom_ext_1_cli_first_cb(SSL *s, unsigned short ext_type, static int custom_ext_1_cli_first_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, const unsigned char **out,
unsigned short *outlen, void *arg) unsigned short *outlen, int *al, void *arg)
{ {
if (ext_type != CUSTOM_EXT_TYPE_1) if (ext_type != CUSTOM_EXT_TYPE_1)
custom_ext_error = 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, unsigned short inlen, int *al,
void *arg) void *arg)
{ {
custom_ext_error = 1; /* Shouldn't be called */ return 1;
return 0;
} }
static int custom_ext_2_cli_first_cb(SSL *s, unsigned short ext_type, static int custom_ext_2_cli_first_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, const unsigned char **out,
unsigned short *outlen, void *arg) unsigned short *outlen, int *al, void *arg)
{ {
if (ext_type != CUSTOM_EXT_TYPE_2) if (ext_type != CUSTOM_EXT_TYPE_2)
custom_ext_error = 1; 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, static int custom_ext_3_cli_first_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, const unsigned char **out,
unsigned short *outlen, void *arg) unsigned short *outlen, int *al, void *arg)
{ {
if (ext_type != CUSTOM_EXT_TYPE_3) if (ext_type != CUSTOM_EXT_TYPE_3)
custom_ext_error = 1; custom_ext_error = 1;
@ -563,22 +571,21 @@ static int custom_ext_3_cli_second_cb(SSL *s, unsigned short ext_type,
return 1; 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, static int custom_ext_0_srv_first_cb(SSL *s, unsigned short ext_type,
const unsigned char *in, const unsigned char *in,
unsigned short inlen, int *al, unsigned short inlen, int *al,
void *arg) void *arg)
{ {
custom_ext_error = 1; return 1;
return 0; /* Shouldn't be called */
} }
/* '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, static int custom_ext_0_srv_second_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, const unsigned char **out,
unsigned short *outlen, void *arg) unsigned short *outlen, int *al, void *arg)
{ {
custom_ext_error = 1; return -1; /* Don't send an extension */
return 0; /* Shouldn't be called */
} }
static int custom_ext_1_srv_first_cb(SSL *s, unsigned short ext_type, static int custom_ext_1_srv_first_cb(SSL *s, unsigned short ext_type,
@ -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, static int custom_ext_1_srv_second_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, const unsigned char **out,
unsigned short *outlen, void *arg) unsigned short *outlen, int *al, void *arg)
{ {
return -1; /* Don't send an extension */ 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, static int custom_ext_2_srv_second_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, const unsigned char **out,
unsigned short *outlen, void *arg) unsigned short *outlen, int *al, void *arg)
{ {
*out = NULL; *out = NULL;
*outlen = 0; *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, static int custom_ext_3_srv_second_cb(SSL *s, unsigned short ext_type,
const unsigned char **out, const unsigned char **out,
unsigned short *outlen, void *arg) unsigned short *outlen, int *al, void *arg)
{ {
*out = (const unsigned char*)custom_ext_srv_string; *out = (const unsigned char*)custom_ext_srv_string;
*outlen = strlen(custom_ext_srv_string); *outlen = strlen(custom_ext_srv_string);
return 1; /* Send "defg" */ 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 char *cipher=NULL;
static int verbose=0; static int verbose=0;
@ -726,11 +836,6 @@ static void sv_usage(void)
" (default is sect163r2).\n"); " (default is sect163r2).\n");
#endif #endif
fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n"); 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_file file - have server use this file\n");
fprintf(stderr," -serverinfo_sct - have client offer and expect SCT\n"); fprintf(stderr," -serverinfo_sct - have client offer and expect SCT\n");
fprintf(stderr," -serverinfo_tack - have client offer and expect TACK\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_client <string> - have client side offer ALPN\n");
fprintf(stderr," -alpn_server <string> - have server 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," -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) 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 #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[]) int main(int argc, char *argv[])
{ {
char *CApath=NULL,*CAfile=NULL; char *CApath=NULL,*CAfile=NULL;
@ -968,11 +1024,6 @@ int main(int argc, char *argv[])
#ifdef OPENSSL_FIPS #ifdef OPENSSL_FIPS
int fips_mode=0; int fips_mode=0;
#endif #endif
#ifndef OPENSSL_NO_TLSEXT
char *s_authz_file = NULL;
int c_support_proof = 0;
int c_require_proof = 0;
#endif
verbose = 0; verbose = 0;
debug = 0; debug = 0;
@ -1191,24 +1242,6 @@ int main(int argc, char *argv[])
{ {
test_cipherlist = 1; 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) else if (strcmp(*argv,"-serverinfo_sct") == 0)
{ {
serverinfo_sct = 1; serverinfo_sct = 1;
@ -1241,6 +1274,10 @@ int main(int argc, char *argv[])
if (--argc < 1) goto bad; if (--argc < 1) goto bad;
alpn_expected = *(++argv); alpn_expected = *(++argv);
} }
else if (strcmp(*argv,"-suppdata") == 0)
{
suppdata = 1;
}
else else
{ {
fprintf(stderr,"unknown option %s\n",*argv); fprintf(stderr,"unknown option %s\n",*argv);
@ -1274,15 +1311,6 @@ bad:
"to avoid protocol mismatch.\n"); "to avoid protocol mismatch.\n");
EXIT(1); 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 #ifdef OPENSSL_FIPS
if(fips_mode) if(fips_mode)
@ -1554,34 +1582,6 @@ bad:
SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb); SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb);
} }
#endif #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) if (serverinfo_sct)
SSL_CTX_set_custom_cli_ext(c_ctx, SCT_EXT_TYPE, NULL, SSL_CTX_set_custom_cli_ext(c_ctx, SCT_EXT_TYPE, NULL,
@ -1647,6 +1647,40 @@ bad:
c_ssl=SSL_new(c_ctx); c_ssl=SSL_new(c_ctx);
s_ssl=SSL_new(s_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 #ifndef OPENSSL_NO_KRB5
if (c_ssl && c_ssl->kssl_ctx) if (c_ssl && c_ssl->kssl_ctx)
{ {
@ -1717,10 +1751,6 @@ end:
#endif #endif
#ifndef OPENSSL_NO_ENGINE #ifndef OPENSSL_NO_ENGINE
ENGINE_cleanup(); ENGINE_cleanup();
#endif
#ifndef OPENSSL_NO_TLSEXT
if (c_expected.expected_proof != NULL)
OPENSSL_free(c_expected.expected_proof);
#endif #endif
CRYPTO_cleanup_all_ex_data(); CRYPTO_cleanup_all_ex_data();
ERR_free_strings(); ERR_free_strings();
@ -2411,7 +2441,11 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count)
if (verbose) if (verbose)
print_details(c_ssl, "DONE: "); print_details(c_ssl, "DONE: ");
if (suppdata_error < 0)
{
ret = 1;
goto err;
}
if (verify_serverinfo() < 0) if (verify_serverinfo() < 0)
{ {
ret = 1; ret = 1;

View File

@ -1089,20 +1089,7 @@ void ssl_set_client_disabled(SSL *s)
c->valid = 1; c->valid = 1;
} }
/* byte_compare is a compare function for qsort(3) that compares bytes. */ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al)
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)
{ {
int extdatalen=0; int extdatalen=0;
unsigned char *ret = p; unsigned char *ret = p;
@ -1448,26 +1435,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
ret += el; 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 */ /* Add custom TLS Extensions to ClientHello */
if (s->ctx->custom_cli_ext_records_count) 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; int cb_retval = 0;
cb_retval = record->fn1(s, record->ext_type, cb_retval = record->fn1(s, record->ext_type,
&out, &outlen, &out, &outlen, al,
record->arg); record->arg);
if (cb_retval == 0) if (cb_retval == 0)
return NULL; /* error */ return NULL; /* error */
@ -1539,10 +1506,12 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
return ret; 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; int extdatalen=0;
unsigned char *ret = p; unsigned char *ret = p;
size_t i;
custom_srv_ext_record *record;
#ifndef OPENSSL_NO_NEXTPROTONEG #ifndef OPENSSL_NO_NEXTPROTONEG
int next_proto_neg_seen; int next_proto_neg_seen;
#endif #endif
@ -1726,118 +1695,30 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
} }
#endif #endif
/* If the client supports authz then see whether we have any to offer for (i = 0; i < s->ctx->custom_srv_ext_records_count; i++)
* 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)
{
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; const unsigned char *out = NULL;
unsigned short outlen = 0; unsigned short outlen = 0;
int cb_retval = 0; int cb_retval = 0;
record = &s->ctx->custom_srv_ext_records[i];
/* NULL callback or -1 omits extension */ /* NULL callback or -1 omits extension */
if (!record->fn2) if (!record->fn2)
break; continue;
cb_retval = record->fn2(s, record->ext_type, cb_retval = record->fn2(s, record->ext_type,
&out, &outlen, &out, &outlen, al,
record->arg); record->arg);
if (cb_retval == 0) if (cb_retval == 0)
return NULL; /* error */ return NULL; /* error */
if (cb_retval == -1) if (cb_retval == -1)
break; /* skip this extension */ continue; /* skip this extension */
if (limit < ret + 4 + outlen) if (limit < ret + 4 + outlen)
return NULL; return NULL;
s2n(record->ext_type, ret); s2n(record->ext_type, ret);
s2n(outlen, ret); s2n(outlen, ret);
memcpy(ret, out, outlen); memcpy(ret, out, outlen);
ret += outlen; ret += outlen;
break;
}
}
}
} }
if (s->s3->alpn_selected) if (s->s3->alpn_selected)
@ -2031,11 +1912,11 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
#endif #endif
/* Clear observed custom extensions */ /* Clear observed custom extensions */
s->s3->tlsext_custom_types_count = 0; s->s3->serverinfo_client_tlsext_custom_types_count = 0;
if (s->s3->tlsext_custom_types != NULL) if (s->s3->serverinfo_client_tlsext_custom_types != NULL)
{ {
OPENSSL_free(s->s3->tlsext_custom_types); OPENSSL_free(s->s3->serverinfo_client_tlsext_custom_types);
s->s3->tlsext_custom_types = NULL; s->s3->serverinfo_client_tlsext_custom_types = NULL;
} }
if (s->s3->alpn_selected) if (s->s3->alpn_selected)
@ -2545,66 +2426,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
al)) al))
return 0; 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 /* If this ClientHello extension was unhandled and this is
* a nonresumed connection, check whether the extension is a * a nonresumed connection, check whether the extension is a
* custom TLS Extension (has a custom_srv_ext_record), and if * 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]; record = &s->ctx->custom_srv_ext_records[i];
if (type == record->ext_type) 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)) if (record->fn1 && !record->fn1(s, type, data, size, al, record->arg))
return 0; 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)) al))
return 0; 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 /* If this extension type was not otherwise handled, but
* matches a custom_cli_ext_record, then send it to the c * matches a custom_cli_ext_record, then send it to the c
* callback */ * callback */

View File

@ -299,9 +299,12 @@ extern "C" {
/* From RFC 5878 */ /* From RFC 5878 */
#define TLSEXT_SUPPLEMENTALDATATYPE_authz_data 16386 #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 */ /* DTCP Authorization Type
#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-04.txt
*/
#define TLSEXT_AUTHZDATAFORMAT_dtcp 66
#define TLSEXT_MAXLEN_supplemental_data 1024*16 /* Let's limit to 16k */ #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) \ #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) 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 #ifndef OPENSSL_NO_HEARTBEATS
#define SSL_TLSEXT_HB_ENABLED 0x01 #define SSL_TLSEXT_HB_ENABLED 0x01
#define SSL_TLSEXT_HB_DONT_SEND_REQUESTS 0x02 #define SSL_TLSEXT_HB_DONT_SEND_REQUESTS 0x02