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:
commit
e32cbae224
4
CHANGES
4
CHANGES
@ -31,6 +31,10 @@
|
||||
MGF1 digest and OAEP label.
|
||||
[Steve Henson]
|
||||
|
||||
*) Add callbacks supporting generation and retrieval of supplemental
|
||||
data entries.
|
||||
[Scott Deboy <sdeboy@apache.org>, Trevor Perrin and Ben Laurie]
|
||||
|
||||
*) Add EVP support for key wrapping algorithms, to avoid problems with
|
||||
existing code the flag EVP_CIPHER_CTX_WRAP_ALLOW has to be set in
|
||||
the EVP_CIPHER_CTX or an error is returned. Add AES and DES3 wrap
|
||||
|
@ -593,7 +593,10 @@ my %table=(
|
||||
"darwin64-ppc-cc","cc:-arch ppc64 -O3 -DB_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc64_asm}:osx64:dlfcn:darwin-shared:-fPIC -fno-common:-arch ppc64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
|
||||
"darwin-i386-cc","cc:-arch i386 -O3 -fomit-frame-pointer -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:".eval{my $asm=$x86_asm;$asm=~s/cast\-586\.o//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
|
||||
"debug-darwin-i386-cc","cc:-arch i386 -g3 -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:${x86_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
|
||||
"debug-darwin64-x86_64-cc","cc:-arch x86_64 -ggdb -g2 -O0 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
|
||||
"darwin64-x86_64-cc","cc:-arch x86_64 -O3 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$x86_64_asm;$asm=~s/rc4\-[^:]+//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
|
||||
"debug-darwin64-x86_64-cc","cc:-arch x86_64 -ggdb -g2 -O0 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
|
||||
"darwin64-x86_64-cc","cc:-arch x86_64 -O3 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
|
||||
"debug-darwin-ppc-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DB_ENDIAN -g -Wall -O::-D_REENTRANT:MACOSX::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
|
||||
# iPhoneOS/iOS
|
||||
"iphoneos-cross","llvm-gcc:-O3 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fomit-frame-pointer -fno-common::-D_REENTRANT:iOS:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
|
||||
@ -2008,7 +2011,7 @@ BEGIN
|
||||
VALUE "ProductVersion", "$version\\0"
|
||||
// Optional:
|
||||
//VALUE "Comments", "\\0"
|
||||
VALUE "LegalCopyright", "Copyright © 1998-2005 The OpenSSL Project. Copyright © 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
|
||||
VALUE "LegalCopyright", "Copyright © 1998-2005 The OpenSSL Project. Copyright © 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
|
||||
//VALUE "LegalTrademarks", "\\0"
|
||||
//VALUE "PrivateBuild", "\\0"
|
||||
//VALUE "SpecialBuild", "\\0"
|
||||
|
@ -156,10 +156,6 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
|
||||
int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
|
||||
int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
|
||||
STACK_OF(X509) *chain, int build_chain);
|
||||
# ifndef OPENSSL_NO_TLSEXT
|
||||
int set_cert_key_and_authz(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
|
||||
unsigned char *authz, size_t authz_length);
|
||||
# endif
|
||||
int ssl_print_sigalgs(BIO *out, SSL *s);
|
||||
int ssl_print_point_formats(BIO *out, SSL *s);
|
||||
int ssl_print_curves(BIO *out, SSL *s, int noshared);
|
||||
|
@ -879,6 +879,9 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *
|
||||
case 20:
|
||||
str_details1 = ", Finished";
|
||||
break;
|
||||
case 23:
|
||||
str_details1 = ", SupplementalData";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
142
apps/s_client.c
142
apps/s_client.c
@ -203,7 +203,6 @@ static int c_debug=0;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
static int c_tlsextdebug=0;
|
||||
static int c_status_req=0;
|
||||
static int c_proof_debug=0;
|
||||
#endif
|
||||
static int c_msg=0;
|
||||
static int c_showcerts=0;
|
||||
@ -215,7 +214,8 @@ static void sc_usage(void);
|
||||
static void print_stuff(BIO *berr,SSL *con,int full);
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
static int ocsp_resp_cb(SSL *s, void *arg);
|
||||
static int audit_proof_cb(SSL *s, void *arg);
|
||||
static int c_auth = 0;
|
||||
static int c_auth_require_reneg = 0;
|
||||
#endif
|
||||
static BIO *bio_c_out=NULL;
|
||||
static BIO *bio_c_msg=NULL;
|
||||
@ -223,6 +223,37 @@ static int c_quiet=0;
|
||||
static int c_ign_eof=0;
|
||||
static int c_brief=0;
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
|
||||
static unsigned char *generated_supp_data = NULL;
|
||||
|
||||
static const unsigned char *most_recent_supplemental_data = NULL;
|
||||
static size_t most_recent_supplemental_data_length = 0;
|
||||
|
||||
static int server_provided_server_authz = 0;
|
||||
static int server_provided_client_authz = 0;
|
||||
|
||||
static const unsigned char auth_ext_data[]={TLSEXT_AUTHZDATAFORMAT_dtcp};
|
||||
|
||||
static int suppdata_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg);
|
||||
|
||||
static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, int *al, void *arg);
|
||||
|
||||
static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out, unsigned short *outlen,
|
||||
int *al, void *arg);
|
||||
|
||||
static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg);
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
/* Default PSK identity and key */
|
||||
static char *psk_identity="Client_identity";
|
||||
@ -365,15 +396,14 @@ static void sc_usage(void)
|
||||
BIO_printf(bio_err," -tlsextdebug - hex dump of all TLS extensions received\n");
|
||||
BIO_printf(bio_err," -status - request certificate status from server\n");
|
||||
BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n");
|
||||
BIO_printf(bio_err," -proof_debug - request an audit proof and print its hex dump\n");
|
||||
BIO_printf(bio_err," -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n");
|
||||
BIO_printf(bio_err," -auth - send and receive RFC 5878 TLS auth extensions and supplemental data\n");
|
||||
BIO_printf(bio_err," -auth_require_reneg - Do not send TLS auth extensions until renegotiation\n");
|
||||
#endif
|
||||
# ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
|
||||
# endif
|
||||
BIO_printf(bio_err," -alpn arg - enable ALPN extension, considering named protocols supported (comma-separated list)\n");
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
BIO_printf(bio_err," -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n");
|
||||
#endif
|
||||
#endif
|
||||
BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
|
||||
BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
|
||||
BIO_printf(bio_err," -keymatexport label - Export keying material using label\n");
|
||||
@ -822,8 +852,10 @@ static char *jpake_secret = NULL;
|
||||
c_tlsextdebug=1;
|
||||
else if (strcmp(*argv,"-status") == 0)
|
||||
c_status_req=1;
|
||||
else if (strcmp(*argv,"-proof_debug") == 0)
|
||||
c_proof_debug=1;
|
||||
else if (strcmp(*argv,"-auth") == 0)
|
||||
c_auth = 1;
|
||||
else if (strcmp(*argv,"-auth_require_reneg") == 0)
|
||||
c_auth_require_reneg = 1;
|
||||
#endif
|
||||
#ifdef WATT32
|
||||
else if (strcmp(*argv,"-wdebug") == 0)
|
||||
@ -1397,9 +1429,12 @@ bad:
|
||||
}
|
||||
|
||||
#endif
|
||||
if (c_proof_debug)
|
||||
SSL_CTX_set_tlsext_authz_server_audit_proof_cb(ctx,
|
||||
audit_proof_cb);
|
||||
if (c_auth)
|
||||
{
|
||||
SSL_CTX_set_custom_cli_ext(ctx, TLSEXT_TYPE_client_authz, authz_tlsext_generate_cb, authz_tlsext_cb, bio_err);
|
||||
SSL_CTX_set_custom_cli_ext(ctx, TLSEXT_TYPE_server_authz, authz_tlsext_generate_cb, authz_tlsext_cb, bio_err);
|
||||
SSL_CTX_set_cli_supp_data(ctx, TLSEXT_SUPPLEMENTALDATATYPE_authz_data, suppdata_cb, auth_suppdata_generate_cb, bio_err);
|
||||
}
|
||||
#endif
|
||||
|
||||
con=SSL_new(ctx);
|
||||
@ -1743,6 +1778,13 @@ SSL_set_tlsext_status_ids(con, ids);
|
||||
"CONNECTION ESTABLISHED\n");
|
||||
print_ssl_summary(bio_err, con);
|
||||
}
|
||||
/*handshake is complete - free the generated supp data allocated in the callback */
|
||||
if (generated_supp_data)
|
||||
{
|
||||
OPENSSL_free(generated_supp_data);
|
||||
generated_supp_data = NULL;
|
||||
}
|
||||
|
||||
print_stuff(bio_c_out,con,full_log);
|
||||
if (full_log > 0) full_log--;
|
||||
|
||||
@ -2392,26 +2434,74 @@ static int ocsp_resp_cb(SSL *s, void *arg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int audit_proof_cb(SSL *s, void *arg)
|
||||
static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
const unsigned char *proof;
|
||||
size_t proof_len;
|
||||
size_t i;
|
||||
SSL_SESSION *sess = SSL_get_session(s);
|
||||
if (TLSEXT_TYPE_server_authz == ext_type)
|
||||
server_provided_server_authz
|
||||
= (memchr(in, TLSEXT_AUTHZDATAFORMAT_dtcp, inlen) != NULL);
|
||||
|
||||
proof = SSL_SESSION_get_tlsext_authz_server_audit_proof(sess,
|
||||
&proof_len);
|
||||
if (proof != NULL)
|
||||
if (TLSEXT_TYPE_client_authz == ext_type)
|
||||
server_provided_client_authz
|
||||
= (memchr(in, TLSEXT_AUTHZDATAFORMAT_dtcp, inlen) != NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out, unsigned short *outlen,
|
||||
int *al, void *arg)
|
||||
{
|
||||
if (c_auth)
|
||||
{
|
||||
BIO_printf(bio_c_out, "Audit proof: ");
|
||||
for (i = 0; i < proof_len; ++i)
|
||||
BIO_printf(bio_c_out, "%02X", proof[i]);
|
||||
BIO_printf(bio_c_out, "\n");
|
||||
/*if auth_require_reneg flag is set, only send extensions if
|
||||
renegotiation has occurred */
|
||||
if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s)))
|
||||
{
|
||||
*out = auth_ext_data;
|
||||
*outlen = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* no auth extension to send */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int suppdata_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
if (supp_data_type == TLSEXT_SUPPLEMENTALDATATYPE_authz_data)
|
||||
{
|
||||
BIO_printf(bio_c_out, "No audit proof found.\n");
|
||||
most_recent_supplemental_data = in;
|
||||
most_recent_supplemental_data_length = inlen;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, int *al, void *arg)
|
||||
{
|
||||
if (c_auth && server_provided_client_authz && server_provided_server_authz)
|
||||
{
|
||||
/*if auth_require_reneg flag is set, only send supplemental data if
|
||||
renegotiation has occurred */
|
||||
if (!c_auth_require_reneg
|
||||
|| (c_auth_require_reneg && SSL_num_renegotiations(s)))
|
||||
{
|
||||
generated_supp_data = OPENSSL_malloc(10);
|
||||
memcpy(generated_supp_data, "5432154321", 10);
|
||||
*out = generated_supp_data;
|
||||
*outlen = 10;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* no supplemental data to send */
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
152
apps/s_server.c
152
apps/s_server.c
@ -224,6 +224,20 @@ static DH *get_dh512(void);
|
||||
static void s_server_init(void);
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
|
||||
static const unsigned char auth_ext_data[]={TLSEXT_AUTHZDATAFORMAT_dtcp};
|
||||
|
||||
static unsigned char *generated_supp_data = NULL;
|
||||
|
||||
static const unsigned char *most_recent_supplemental_data = NULL;
|
||||
static size_t most_recent_supplemental_data_length = 0;
|
||||
|
||||
static int client_provided_server_authz = 0;
|
||||
static int client_provided_client_authz = 0;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_DH
|
||||
static unsigned char dh512_p[]={
|
||||
0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
|
||||
@ -315,10 +329,29 @@ static int cert_chain = 0;
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
static BIO *authz_in = NULL;
|
||||
static const char *s_authz_file = NULL;
|
||||
static int suppdata_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg);
|
||||
|
||||
static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, int *al, void *arg);
|
||||
|
||||
static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out, unsigned short *outlen,
|
||||
int *al, void *arg);
|
||||
|
||||
static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg);
|
||||
|
||||
static BIO *serverinfo_in = NULL;
|
||||
static const char *s_serverinfo_file = NULL;
|
||||
|
||||
static int c_auth = 0;
|
||||
static int c_auth_require_reneg = 0;
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
@ -482,10 +515,12 @@ static void sv_usage(void)
|
||||
BIO_printf(bio_err," -Verify arg - turn on peer certificate verification, must have a cert.\n");
|
||||
BIO_printf(bio_err," -cert arg - certificate file to use\n");
|
||||
BIO_printf(bio_err," (default is %s)\n",TEST_CERT);
|
||||
BIO_printf(bio_err," -authz arg - binary authz file for certificate\n");
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
BIO_printf(bio_err," -serverinfo arg - PEM serverinfo file for certificate\n");
|
||||
BIO_printf(bio_err," -auth - send and receive RFC 5878 TLS auth extensions and supplemental data\n");
|
||||
BIO_printf(bio_err," -auth_require_reneg - Do not send TLS auth extensions until renegotiation\n");
|
||||
#endif
|
||||
BIO_printf(bio_err," -no_resumption_on_reneg - set SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION flag\n");
|
||||
BIO_printf(bio_err," -crl_check - check the peer certificate has not been revoked by its CA.\n" \
|
||||
" The CRL(s) are appended to the certificate file\n");
|
||||
BIO_printf(bio_err," -crl_check_all - check the peer certificate has not been revoked by its CA\n" \
|
||||
@ -1018,6 +1053,7 @@ int MAIN(int argc, char *argv[])
|
||||
EVP_PKEY *s_key = NULL, *s_dkey = NULL;
|
||||
int no_cache = 0, ext_cache = 0;
|
||||
int rev = 0, naccept = -1;
|
||||
int c_no_resumption_on_reneg = 0;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
EVP_PKEY *s_key2 = NULL;
|
||||
X509 *s_cert2 = NULL;
|
||||
@ -1132,17 +1168,24 @@ int MAIN(int argc, char *argv[])
|
||||
else if (strcmp(*argv,"-crl_download") == 0)
|
||||
crl_download = 1;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
else if (strcmp(*argv,"-authz") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
s_authz_file = *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-serverinfo") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
s_serverinfo_file = *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-auth") == 0)
|
||||
{
|
||||
c_auth = 1;
|
||||
}
|
||||
#endif
|
||||
else if (strcmp(*argv, "-no_resumption_on_reneg") == 0)
|
||||
{
|
||||
c_no_resumption_on_reneg = 1;
|
||||
}
|
||||
else if (strcmp(*argv,"-auth_require_reneg") == 0)
|
||||
{
|
||||
c_auth_require_reneg = 1;
|
||||
}
|
||||
else if (strcmp(*argv,"-certform") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
@ -1918,17 +1961,23 @@ bad:
|
||||
}
|
||||
#endif
|
||||
|
||||
if (c_no_resumption_on_reneg)
|
||||
SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
||||
if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain))
|
||||
goto end;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s_authz_file != NULL && !SSL_CTX_use_authz_file(ctx, s_authz_file))
|
||||
goto end;
|
||||
if (s_serverinfo_file != NULL
|
||||
&& !SSL_CTX_use_serverinfo_file(ctx, s_serverinfo_file))
|
||||
{
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (c_auth)
|
||||
{
|
||||
SSL_CTX_set_custom_srv_ext(ctx, TLSEXT_TYPE_client_authz, authz_tlsext_cb, authz_tlsext_generate_cb, bio_err);
|
||||
SSL_CTX_set_custom_srv_ext(ctx, TLSEXT_TYPE_server_authz, authz_tlsext_cb, authz_tlsext_generate_cb, bio_err);
|
||||
SSL_CTX_set_srv_supp_data(ctx, TLSEXT_SUPPLEMENTALDATATYPE_authz_data, auth_suppdata_generate_cb, suppdata_cb, bio_err);
|
||||
}
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2, NULL, build_chain))
|
||||
@ -2097,8 +2146,6 @@ end:
|
||||
X509_free(s_cert2);
|
||||
if (s_key2)
|
||||
EVP_PKEY_free(s_key2);
|
||||
if (authz_in != NULL)
|
||||
BIO_free(authz_in);
|
||||
if (serverinfo_in != NULL)
|
||||
BIO_free(serverinfo_in);
|
||||
# ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
@ -2631,6 +2678,13 @@ static int init_ssl_connection(SSL *con)
|
||||
i=SSL_accept(con);
|
||||
}
|
||||
#endif
|
||||
/*handshake is complete - free the generated supp data allocated in the callback */
|
||||
if (generated_supp_data)
|
||||
{
|
||||
OPENSSL_free(generated_supp_data);
|
||||
generated_supp_data = NULL;
|
||||
}
|
||||
|
||||
if (i <= 0)
|
||||
{
|
||||
if (BIO_sock_should_retry(i))
|
||||
@ -3494,3 +3548,77 @@ static void free_sessions(void)
|
||||
}
|
||||
first = NULL;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
if (TLSEXT_TYPE_server_authz == ext_type)
|
||||
client_provided_server_authz
|
||||
= memchr(in, TLSEXT_AUTHZDATAFORMAT_dtcp, inlen) != NULL;
|
||||
|
||||
if (TLSEXT_TYPE_client_authz == ext_type)
|
||||
client_provided_client_authz
|
||||
= memchr(in, TLSEXT_AUTHZDATAFORMAT_dtcp, inlen) != NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out, unsigned short *outlen,
|
||||
int *al, void *arg)
|
||||
{
|
||||
if (c_auth && client_provided_client_authz && client_provided_server_authz)
|
||||
{
|
||||
/*if auth_require_reneg flag is set, only send extensions if
|
||||
renegotiation has occurred */
|
||||
if (!c_auth_require_reneg
|
||||
|| (c_auth_require_reneg && SSL_num_renegotiations(s)))
|
||||
{
|
||||
*out = auth_ext_data;
|
||||
*outlen = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* no auth extension to send */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int suppdata_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
if (supp_data_type == TLSEXT_SUPPLEMENTALDATATYPE_authz_data)
|
||||
{
|
||||
most_recent_supplemental_data = in;
|
||||
most_recent_supplemental_data_length = inlen;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, int *al, void *arg)
|
||||
{
|
||||
if (c_auth && client_provided_client_authz && client_provided_server_authz)
|
||||
{
|
||||
/*if auth_require_reneg flag is set, only send supplemental data if
|
||||
renegotiation has occurred */
|
||||
if (!c_auth_require_reneg
|
||||
|| (c_auth_require_reneg && SSL_num_renegotiations(s)))
|
||||
{
|
||||
generated_supp_data = OPENSSL_malloc(10);
|
||||
memcpy(generated_supp_data, "1234512345", 10);
|
||||
*out = generated_supp_data;
|
||||
*outlen = 10;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* no supplemental data to send */
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -207,12 +207,12 @@
|
||||
|
||||
#undef tls1_send_server_supplemental_data
|
||||
#define tls1_send_server_supplemental_data tls1_send_server_suppl_data
|
||||
#undef tls1_send_client_supplemental_data
|
||||
#define tls1_send_client_supplemental_data tls1_send_client_suppl_data
|
||||
#undef tls1_get_server_supplemental_data
|
||||
#define tls1_get_server_supplemental_data tls1_get_server_suppl_data
|
||||
|
||||
#undef SSL_SESSION_get_tlsext_authz_server_audit_proof
|
||||
#define SSL_SESSION_get_tlsext_authz_server_audit_proof \
|
||||
S_SES_get_tlsx_auz_srvr_aud_prf
|
||||
#undef tls1_get_client_supplemental_data
|
||||
#define tls1_get_client_supplemental_data tls1_get_client_suppl_data
|
||||
|
||||
#undef ssl3_cbc_record_digest_supported
|
||||
#define ssl3_cbc_record_digest_supported ssl3_cbc_record_digest_support
|
||||
|
@ -44,6 +44,8 @@ B<openssl> B<s_client>
|
||||
[B<-sess_in filename>]
|
||||
[B<-rand file(s)>]
|
||||
[B<-serverinfo types>]
|
||||
[B<-auth>]
|
||||
[B<-auth_require_reneg>]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
@ -245,6 +247,15 @@ a list of comma-separated TLS Extension Types (numbers between 0 and
|
||||
The server's response (if any) will be encoded and displayed as a PEM
|
||||
file.
|
||||
|
||||
=item B<-auth>
|
||||
|
||||
send RFC 5878 client and server authorization extensions in the Client Hello as well as
|
||||
supplemental data if the server also sent the authorization extensions in the Server Hello.
|
||||
|
||||
=item B<-auth_require_reneg>
|
||||
|
||||
only send RFC 5878 client and server authorization extensions during renegotiation.
|
||||
|
||||
=back
|
||||
|
||||
=head1 CONNECTED COMMANDS
|
||||
|
@ -55,7 +55,9 @@ B<openssl> B<s_server>
|
||||
[B<-id_prefix arg>]
|
||||
[B<-rand file(s)>]
|
||||
[B<-serverinfo file>]
|
||||
|
||||
[B<-auth>]
|
||||
[B<-auth_require_reneg>]
|
||||
[B<-no_resumption_on_reneg>]
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The B<s_server> command implements a generic SSL/TLS server which listens
|
||||
@ -285,6 +287,20 @@ followed by "length" bytes of extension data). If the client sends
|
||||
an empty TLS ClientHello extension matching the type, the corresponding
|
||||
ServerHello extension will be returned.
|
||||
|
||||
=item B<-auth>
|
||||
|
||||
send RFC 5878 client and server authorization extensions in the Client Hello as well as
|
||||
supplemental data if the server also sent the authorization extensions in the Server Hello.
|
||||
|
||||
=item B<-auth_require_reneg>
|
||||
|
||||
only send RFC 5878 client and server authorization extensions during renegotiation.
|
||||
|
||||
=item B<-no_resumption_on_reneg>
|
||||
|
||||
set SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION flag. Required in order to receive supplemental data
|
||||
during renegotiation if auth and auth_require_reneg are set.
|
||||
|
||||
=back
|
||||
|
||||
=head1 CONNECTED COMMANDS
|
||||
|
@ -299,6 +299,7 @@ static int ssl23_client_hello(SSL *s)
|
||||
unsigned long l;
|
||||
int ssl2_compat;
|
||||
int version = 0, version_major, version_minor;
|
||||
int al = 0;
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
int j;
|
||||
SSL_COMP *comp;
|
||||
@ -362,10 +363,10 @@ static int ssl23_client_hello(SSL *s)
|
||||
if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL)
|
||||
ssl2_compat = 0;
|
||||
#endif
|
||||
if (s->ctx->tlsext_authz_server_audit_proof_cb != NULL)
|
||||
ssl2_compat = 0;
|
||||
if (s->ctx->custom_cli_ext_records_count != 0)
|
||||
ssl2_compat = 0;
|
||||
if (s->ctx->cli_supp_data_records_count != 0)
|
||||
ssl2_compat = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -553,8 +554,9 @@ static int ssl23_client_hello(SSL *s)
|
||||
SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
|
||||
return -1;
|
||||
}
|
||||
if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
|
||||
if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, &al)) == NULL)
|
||||
{
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,al);
|
||||
SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
|
266
ssl/s3_clnt.c
266
ssl/s3_clnt.c
@ -307,13 +307,6 @@ int ssl3_connect(SSL *s)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
/* The server hello indicated that
|
||||
* an audit proof would follow. */
|
||||
if (s->s3->tlsext_authz_server_promised)
|
||||
s->state=SSL3_ST_CR_SUPPLEMENTAL_DATA_A;
|
||||
else
|
||||
#endif
|
||||
s->state=SSL3_ST_CR_CERT_A;
|
||||
}
|
||||
s->init_num=0;
|
||||
@ -332,6 +325,12 @@ int ssl3_connect(SSL *s)
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
ret=ssl3_check_finished(s);
|
||||
if (ret <= 0) goto end;
|
||||
if (ret == 3)
|
||||
{
|
||||
s->state=SSL3_ST_CR_SUPPLEMENTAL_DATA_A;
|
||||
s->init_num=0;
|
||||
break;
|
||||
}
|
||||
if (ret == 2)
|
||||
{
|
||||
s->hit = 1;
|
||||
@ -410,10 +409,14 @@ int ssl3_connect(SSL *s)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
s->state=SSL3_ST_CW_SUPPLEMENTAL_DATA_A;
|
||||
#else
|
||||
if (s->s3->tmp.cert_req)
|
||||
s->state=SSL3_ST_CW_CERT_A;
|
||||
else
|
||||
s->state=SSL3_ST_CW_KEY_EXCH_A;
|
||||
#endif
|
||||
s->init_num=0;
|
||||
|
||||
break;
|
||||
@ -520,6 +523,19 @@ int ssl3_connect(SSL *s)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
case SSL3_ST_CW_SUPPLEMENTAL_DATA_A:
|
||||
case SSL3_ST_CW_SUPPLEMENTAL_DATA_B:
|
||||
ret = tls1_send_client_supplemental_data(s, &skip);
|
||||
if (ret <= 0) goto end;
|
||||
if (s->s3->tmp.cert_req)
|
||||
s->state=SSL3_ST_CW_CERT_A;
|
||||
else
|
||||
s->state=SSL3_ST_CW_KEY_EXCH_A;
|
||||
s->init_num=0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SSL3_ST_CW_FINISHED_A:
|
||||
case SSL3_ST_CW_FINISHED_B:
|
||||
ret=ssl3_send_finished(s,
|
||||
@ -673,6 +689,7 @@ int ssl3_client_hello(SSL *s)
|
||||
unsigned char *p,*d;
|
||||
int i;
|
||||
unsigned long l;
|
||||
int al = 0;
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
int j;
|
||||
SSL_COMP *comp;
|
||||
@ -875,8 +892,9 @@ int ssl3_client_hello(SSL *s)
|
||||
SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
|
||||
goto err;
|
||||
}
|
||||
if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
|
||||
if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, &al)) == NULL)
|
||||
{
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,al);
|
||||
SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
@ -1353,21 +1371,6 @@ int ssl3_get_server_certificate(SSL *s)
|
||||
s->session->verify_result = s->verify_result;
|
||||
|
||||
x=NULL;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
/* Check the audit proof. */
|
||||
if (s->ctx->tlsext_authz_server_audit_proof_cb)
|
||||
{
|
||||
ret = s->ctx->tlsext_authz_server_audit_proof_cb(s,
|
||||
s->ctx->tlsext_authz_server_audit_proof_cb_arg);
|
||||
if (ret <= 0)
|
||||
{
|
||||
al = SSL_AD_BAD_CERTIFICATE;
|
||||
SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_INVALID_AUDIT_PROOF);
|
||||
goto f_err;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
ret=1;
|
||||
if (0)
|
||||
{
|
||||
@ -3568,11 +3571,11 @@ int ssl3_check_finished(SSL *s)
|
||||
{
|
||||
int ok;
|
||||
long n;
|
||||
/* If we have no ticket it cannot be a resumed session. */
|
||||
if (!s->session->tlsext_tick)
|
||||
return 1;
|
||||
/* this function is called when we really expect a Certificate
|
||||
* message, so permit appropriate message length */
|
||||
|
||||
/* Read the message to see if it is supplemental data,
|
||||
* regardless if there is a session ticket this function is
|
||||
* called when we really expect a Certificate message, so
|
||||
* permit appropriate message length */
|
||||
n=s->method->ssl_get_message(s,
|
||||
SSL3_ST_CR_CERT_A,
|
||||
SSL3_ST_CR_CERT_B,
|
||||
@ -3581,6 +3584,12 @@ int ssl3_check_finished(SSL *s)
|
||||
&ok);
|
||||
if (!ok) return((int)n);
|
||||
s->s3->tmp.reuse_message = 1;
|
||||
|
||||
if (s->s3->tmp.message_type == SSL3_MT_SUPPLEMENTAL_DATA)
|
||||
return 3;
|
||||
/* If we have no ticket it cannot be a resumed session. */
|
||||
if (!s->session->tlsext_tick)
|
||||
return 1;
|
||||
if ((s->s3->tmp.message_type == SSL3_MT_FINISHED)
|
||||
|| (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET))
|
||||
return 2;
|
||||
@ -3608,28 +3617,120 @@ int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
int tls1_send_client_supplemental_data(SSL *s, int *skip)
|
||||
{
|
||||
int al = 0;
|
||||
if (s->ctx->cli_supp_data_records_count)
|
||||
{
|
||||
unsigned char *p = NULL;
|
||||
unsigned char *size_loc = NULL;
|
||||
cli_supp_data_record *record = NULL;
|
||||
size_t length = 0;
|
||||
size_t i = 0;
|
||||
|
||||
for (i = 0; i < s->ctx->cli_supp_data_records_count; i++)
|
||||
{
|
||||
const unsigned char *out = NULL;
|
||||
unsigned short outlen = 0;
|
||||
int cb_retval = 0;
|
||||
record = &s->ctx->cli_supp_data_records[i];
|
||||
|
||||
/* NULL callback or -1 omits supp data entry*/
|
||||
if (!record->fn2)
|
||||
continue;
|
||||
cb_retval = record->fn2(s, record->supp_data_type,
|
||||
&out, &outlen, &al,
|
||||
record->arg);
|
||||
if (cb_retval == -1)
|
||||
continue; /* skip this supp data entry */
|
||||
if (cb_retval == 0)
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
goto f_err;
|
||||
}
|
||||
if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length)
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
/* if first entry, write handshake message type */
|
||||
if (length == 0)
|
||||
{
|
||||
if (!BUF_MEM_grow_clean(s->init_buf, 4))
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
p = (unsigned char *)s->init_buf->data;
|
||||
*(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
|
||||
/* update message length when all
|
||||
* callbacks complete */
|
||||
size_loc = p;
|
||||
/* skip over handshake length field (3
|
||||
* bytes) and supp_data length field
|
||||
* (3 bytes) */
|
||||
p += 3 + 3;
|
||||
length += 1 +3 +3;
|
||||
}
|
||||
if (!BUF_MEM_grow(s->init_buf, outlen + 4))
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
s2n(record->supp_data_type, p);
|
||||
s2n(outlen, p);
|
||||
memcpy(p, out, outlen);
|
||||
length += (outlen + 4);
|
||||
p += outlen;
|
||||
}
|
||||
if (length > 0)
|
||||
{
|
||||
/* write handshake length */
|
||||
l2n3(length - 4, size_loc);
|
||||
/* supp_data length */
|
||||
l2n3(length - 7, size_loc);
|
||||
s->state = SSL3_ST_CW_SUPPLEMENTAL_DATA_B;
|
||||
s->init_num = length;
|
||||
s->init_off = 0;
|
||||
return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
|
||||
}
|
||||
}
|
||||
|
||||
/* no supp data message sent */
|
||||
*skip = 1;
|
||||
s->init_num = 0;
|
||||
s->init_off = 0;
|
||||
return 1;
|
||||
|
||||
f_err:
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,al);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tls1_get_server_supplemental_data(SSL *s)
|
||||
{
|
||||
int al;
|
||||
int al = 0;
|
||||
int ok;
|
||||
unsigned long supp_data_len, authz_data_len;
|
||||
long n;
|
||||
unsigned short supp_data_type, authz_data_type, proof_len;
|
||||
const unsigned char *p;
|
||||
unsigned char *new_proof;
|
||||
const unsigned char *p, *d;
|
||||
unsigned short supp_data_entry_type = 0;
|
||||
unsigned long supp_data_entry_len = 0;
|
||||
unsigned long supp_data_len = 0;
|
||||
size_t i;
|
||||
int cb_retval = 0;
|
||||
|
||||
n=s->method->ssl_get_message(s,
|
||||
SSL3_ST_CR_SUPPLEMENTAL_DATA_A,
|
||||
SSL3_ST_CR_SUPPLEMENTAL_DATA_B,
|
||||
SSL3_MT_SUPPLEMENTAL_DATA,
|
||||
/* use default limit */
|
||||
TLSEXT_MAXLEN_supplemental_data,
|
||||
&ok);
|
||||
SSL3_ST_CR_SUPPLEMENTAL_DATA_A,
|
||||
SSL3_ST_CR_SUPPLEMENTAL_DATA_B,
|
||||
SSL3_MT_SUPPLEMENTAL_DATA,
|
||||
/* use default limit */
|
||||
TLSEXT_MAXLEN_supplemental_data,
|
||||
&ok);
|
||||
|
||||
if (!ok) return((int)n);
|
||||
|
||||
p = (unsigned char *)s->init_msg;
|
||||
|
||||
d = p;
|
||||
/* The message cannot be empty */
|
||||
if (n < 3)
|
||||
{
|
||||
@ -3637,72 +3738,29 @@ int tls1_get_server_supplemental_data(SSL *s)
|
||||
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
|
||||
goto f_err;
|
||||
}
|
||||
/* Length of supplemental data */
|
||||
n2l3(p,supp_data_len);
|
||||
n -= 3;
|
||||
/* We must have at least one supplemental data entry
|
||||
* with type (1 byte) and length (2 bytes). */
|
||||
if (supp_data_len != (unsigned long) n || n < 4)
|
||||
n2l3(p, supp_data_len);
|
||||
while (p < d+supp_data_len)
|
||||
{
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
|
||||
goto f_err;
|
||||
n2s(p, supp_data_entry_type);
|
||||
n2s(p, supp_data_entry_len);
|
||||
/* if there is a callback for this supp data type, send it */
|
||||
for (i=0; i < s->ctx->cli_supp_data_records_count; i++)
|
||||
{
|
||||
if (s->ctx->cli_supp_data_records[i].supp_data_type == supp_data_entry_type &&
|
||||
s->ctx->cli_supp_data_records[i].fn1)
|
||||
{
|
||||
cb_retval = s->ctx->cli_supp_data_records[i].fn1(s, supp_data_entry_type, p,
|
||||
supp_data_entry_len, &al,
|
||||
s->ctx->cli_supp_data_records[i].arg);
|
||||
if (cb_retval == 0)
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA, ERR_R_SSL_LIB);
|
||||
goto f_err;
|
||||
}
|
||||
}
|
||||
}
|
||||
p += supp_data_entry_len;
|
||||
}
|
||||
/* Supplemental data type: must be authz_data */
|
||||
n2s(p,supp_data_type);
|
||||
n -= 2;
|
||||
if (supp_data_type != TLSEXT_SUPPLEMENTALDATATYPE_authz_data)
|
||||
{
|
||||
al = SSL_AD_UNEXPECTED_MESSAGE;
|
||||
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_UNKNOWN_SUPPLEMENTAL_DATA_TYPE);
|
||||
goto f_err;
|
||||
}
|
||||
/* Authz data length */
|
||||
n2s(p, authz_data_len);
|
||||
n -= 2;
|
||||
if (authz_data_len != (unsigned long) n || n < 1)
|
||||
{
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
|
||||
goto f_err;
|
||||
}
|
||||
/* Authz data type: must be audit_proof */
|
||||
authz_data_type = *(p++);
|
||||
n -= 1;
|
||||
if (authz_data_type != TLSEXT_AUTHZDATAFORMAT_audit_proof)
|
||||
{
|
||||
al=SSL_AD_UNEXPECTED_MESSAGE;
|
||||
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_UNKNOWN_AUTHZ_DATA_TYPE);
|
||||
goto f_err;
|
||||
}
|
||||
/* We have a proof: read its length */
|
||||
if (n < 2)
|
||||
{
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
|
||||
goto f_err;
|
||||
}
|
||||
n2s(p, proof_len);
|
||||
n -= 2;
|
||||
if (proof_len != (unsigned long) n)
|
||||
{
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
|
||||
goto f_err;
|
||||
}
|
||||
/* Store the proof */
|
||||
new_proof = OPENSSL_realloc(s->session->audit_proof,
|
||||
proof_len);
|
||||
if (new_proof == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
s->session->audit_proof_length = proof_len;
|
||||
s->session->audit_proof = new_proof;
|
||||
memcpy(s->session->audit_proof, p, proof_len);
|
||||
|
||||
/* Got the proof, but can't verify it yet. */
|
||||
return 1;
|
||||
f_err:
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,al);
|
||||
|
29
ssl/s3_lib.c
29
ssl/s3_lib.c
@ -3029,10 +3029,8 @@ void ssl3_free(SSL *s)
|
||||
SSL_SRP_CTX_free(s);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s->s3->tlsext_authz_client_types != NULL)
|
||||
OPENSSL_free(s->s3->tlsext_authz_client_types);
|
||||
if (s->s3->tlsext_custom_types != NULL)
|
||||
OPENSSL_free(s->s3->tlsext_custom_types);
|
||||
if (s->s3->serverinfo_client_tlsext_custom_types != NULL)
|
||||
OPENSSL_free(s->s3->serverinfo_client_tlsext_custom_types);
|
||||
#endif
|
||||
OPENSSL_cleanse(s->s3,sizeof *s->s3);
|
||||
OPENSSL_free(s->s3);
|
||||
@ -3078,17 +3076,12 @@ void ssl3_clear(SSL *s)
|
||||
}
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s->s3->tlsext_authz_client_types != NULL)
|
||||
if (s->s3->serverinfo_client_tlsext_custom_types != NULL)
|
||||
{
|
||||
OPENSSL_free(s->s3->tlsext_authz_client_types);
|
||||
s->s3->tlsext_authz_client_types = NULL;
|
||||
OPENSSL_free(s->s3->serverinfo_client_tlsext_custom_types);
|
||||
s->s3->serverinfo_client_tlsext_custom_types = NULL;
|
||||
}
|
||||
if (s->s3->tlsext_custom_types != NULL)
|
||||
{
|
||||
OPENSSL_free(s->s3->tlsext_custom_types);
|
||||
s->s3->tlsext_custom_types = NULL;
|
||||
}
|
||||
s->s3->tlsext_custom_types_count = 0;
|
||||
s->s3->serverinfo_client_tlsext_custom_types_count = 0;
|
||||
#ifndef OPENSSL_NO_EC
|
||||
s->s3->is_probably_safari = 0;
|
||||
#endif /* !OPENSSL_NO_EC */
|
||||
@ -3897,10 +3890,6 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
|
||||
case SSL_CTRL_SET_CHAIN_CERT_STORE:
|
||||
return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg);
|
||||
|
||||
case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG:
|
||||
ctx->tlsext_authz_server_audit_proof_cb_arg = parg;
|
||||
break;
|
||||
|
||||
#endif /* !OPENSSL_NO_TLSEXT */
|
||||
|
||||
/* A Thawte special :-) */
|
||||
@ -4023,12 +4012,6 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
|
||||
ctx->srp_ctx.SRP_give_srp_client_pwd_callback=(char *(*)(SSL *,void *))fp;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB:
|
||||
ctx->tlsext_authz_server_audit_proof_cb =
|
||||
(int (*)(SSL *, void *))fp;
|
||||
break;
|
||||
|
||||
#endif
|
||||
default:
|
||||
return(0);
|
||||
|
259
ssl/s3_srvr.c
259
ssl/s3_srvr.c
@ -413,14 +413,8 @@ int ssl3_accept(SSL *s)
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
case SSL3_ST_SW_SUPPLEMENTAL_DATA_A:
|
||||
case SSL3_ST_SW_SUPPLEMENTAL_DATA_B:
|
||||
/* We promised to send an audit proof in the hello. */
|
||||
if (s->s3->tlsext_authz_promised_to_client)
|
||||
{
|
||||
ret = tls1_send_server_supplemental_data(s);
|
||||
if (ret <= 0) goto end;
|
||||
}
|
||||
else
|
||||
skip = 1;
|
||||
ret = tls1_send_server_supplemental_data(s, &skip);
|
||||
if (ret <= 0) goto end;
|
||||
|
||||
s->state = SSL3_ST_SW_CERT_A;
|
||||
s->init_num = 0;
|
||||
@ -595,7 +589,16 @@ int ssl3_accept(SSL *s)
|
||||
|
||||
s->state=s->s3->tmp.next_state;
|
||||
break;
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
case SSL3_ST_SR_SUPPLEMENTAL_DATA_A:
|
||||
case SSL3_ST_SR_SUPPLEMENTAL_DATA_B:
|
||||
ret=tls1_get_client_supplemental_data(s);
|
||||
if (ret <= 0) goto end;
|
||||
s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
|
||||
s->state=SSL3_ST_SW_FLUSH;
|
||||
s->init_num=0;
|
||||
break;
|
||||
#endif
|
||||
case SSL3_ST_SR_CERT_A:
|
||||
case SSL3_ST_SR_CERT_B:
|
||||
/* Check for second client hello (MS SGC) */
|
||||
@ -604,6 +607,10 @@ int ssl3_accept(SSL *s)
|
||||
goto end;
|
||||
if (ret == 2)
|
||||
s->state = SSL3_ST_SR_CLNT_HELLO_C;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
else if (ret == 3)
|
||||
s->state = SSL3_ST_SR_SUPPLEMENTAL_DATA_A;
|
||||
#endif
|
||||
else {
|
||||
if (s->s3->tmp.cert_request)
|
||||
{
|
||||
@ -894,6 +901,10 @@ int ssl3_check_client_hello(SSL *s)
|
||||
&ok);
|
||||
if (!ok) return((int)n);
|
||||
s->s3->tmp.reuse_message = 1;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s->s3->tmp.message_type == SSL3_MT_SUPPLEMENTAL_DATA)
|
||||
return 3;
|
||||
#endif
|
||||
if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
|
||||
{
|
||||
/* We only allow the client to restart the handshake once per
|
||||
@ -1488,6 +1499,7 @@ int ssl3_send_server_hello(SSL *s)
|
||||
unsigned char *buf;
|
||||
unsigned char *p,*d;
|
||||
int i,sl;
|
||||
int al = 0;
|
||||
unsigned long l;
|
||||
|
||||
if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
|
||||
@ -1556,8 +1568,9 @@ int ssl3_send_server_hello(SSL *s)
|
||||
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT);
|
||||
return -1;
|
||||
}
|
||||
if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
|
||||
if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, &al)) == NULL)
|
||||
{
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, al);
|
||||
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
@ -3639,98 +3652,156 @@ int ssl3_get_next_proto(SSL *s)
|
||||
}
|
||||
# endif
|
||||
|
||||
int tls1_send_server_supplemental_data(SSL *s)
|
||||
int tls1_send_server_supplemental_data(SSL *s, int *skip)
|
||||
{
|
||||
size_t length = 0;
|
||||
const unsigned char *authz, *orig_authz;
|
||||
unsigned char *p;
|
||||
size_t authz_length, i;
|
||||
|
||||
if (s->state != SSL3_ST_SW_SUPPLEMENTAL_DATA_A)
|
||||
return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
|
||||
|
||||
orig_authz = authz = ssl_get_authz_data(s, &authz_length);
|
||||
if (authz == NULL)
|
||||
int al = 0;
|
||||
if (s->ctx->srv_supp_data_records_count)
|
||||
{
|
||||
/* This should never occur. */
|
||||
return 0;
|
||||
}
|
||||
unsigned char *p = NULL;
|
||||
unsigned char *size_loc = NULL;
|
||||
srv_supp_data_record *record = NULL;
|
||||
size_t length = 0;
|
||||
size_t i = 0;
|
||||
|
||||
/* First we walk over the authz data to see how long the handshake
|
||||
* message will be. */
|
||||
for (i = 0; i < authz_length; i++)
|
||||
{
|
||||
unsigned short len;
|
||||
unsigned char type;
|
||||
|
||||
type = *(authz++);
|
||||
n2s(authz, len);
|
||||
/* n2s increments authz by 2*/
|
||||
i += 2;
|
||||
|
||||
if (memchr(s->s3->tlsext_authz_client_types,
|
||||
type,
|
||||
s->s3->tlsext_authz_client_types_len) != NULL)
|
||||
length += 1 /* authz type */ + 2 /* length */ + len;
|
||||
|
||||
authz += len;
|
||||
i += len;
|
||||
}
|
||||
|
||||
length += 1 /* handshake type */ +
|
||||
3 /* handshake length */ +
|
||||
3 /* supplemental data length */ +
|
||||
2 /* supplemental entry type */ +
|
||||
2 /* supplemental entry length */;
|
||||
|
||||
if (!BUF_MEM_grow_clean(s->init_buf, length))
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = (unsigned char *)s->init_buf->data;
|
||||
*(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
|
||||
/* Handshake length */
|
||||
l2n3(length - 4, p);
|
||||
/* Length of supplemental data */
|
||||
l2n3(length - 7, p);
|
||||
/* Supplemental data type */
|
||||
s2n(TLSEXT_SUPPLEMENTALDATATYPE_authz_data, p);
|
||||
/* Its length */
|
||||
s2n(length - 11, p);
|
||||
|
||||
authz = orig_authz;
|
||||
|
||||
/* Walk over the authz again and append the selected elements. */
|
||||
for (i = 0; i < authz_length; i++)
|
||||
{
|
||||
unsigned short len;
|
||||
unsigned char type;
|
||||
|
||||
type = *(authz++);
|
||||
n2s(authz, len);
|
||||
/* n2s increments authz by 2 */
|
||||
i += 2;
|
||||
|
||||
if (memchr(s->s3->tlsext_authz_client_types,
|
||||
type,
|
||||
s->s3->tlsext_authz_client_types_len) != NULL)
|
||||
for (i = 0; i < s->ctx->srv_supp_data_records_count; i++)
|
||||
{
|
||||
*(p++) = type;
|
||||
s2n(len, p);
|
||||
memcpy(p, authz, len);
|
||||
p += len;
|
||||
}
|
||||
const unsigned char *out = NULL;
|
||||
unsigned short outlen = 0;
|
||||
int cb_retval = 0;
|
||||
record = &s->ctx->srv_supp_data_records[i];
|
||||
|
||||
authz += len;
|
||||
i += len;
|
||||
/* NULL callback or -1 omits supp data entry */
|
||||
if (!record->fn1)
|
||||
continue;
|
||||
cb_retval = record->fn1(s, record->supp_data_type,
|
||||
&out, &outlen, &al, record->arg);
|
||||
if (cb_retval == -1)
|
||||
continue; /* skip this supp data entry */
|
||||
if (cb_retval == 0)
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
goto f_err;
|
||||
}
|
||||
if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length)
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
/* write supp data entry...
|
||||
* if first entry, write handshake message type
|
||||
* jump back to write length at end */
|
||||
if (length == 0)
|
||||
{
|
||||
/* 1 byte message type + 3 bytes for
|
||||
* message length */
|
||||
if (!BUF_MEM_grow_clean(s->init_buf, 4))
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
p = (unsigned char *)s->init_buf->data;
|
||||
*(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
|
||||
/* hold on to length field to update later */
|
||||
size_loc = p;
|
||||
/* skip over handshake length field (3
|
||||
* bytes) and supp_data length field
|
||||
* (3 bytes) */
|
||||
p += 3 + 3;
|
||||
length += 1 +3 +3;
|
||||
}
|
||||
/* 2 byte supp data type + 2 byte length + outlen */
|
||||
if (!BUF_MEM_grow(s->init_buf, outlen + 4))
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
s2n(record->supp_data_type, p);
|
||||
s2n(outlen, p);
|
||||
memcpy(p, out, outlen);
|
||||
/* update length to supp data type (2 bytes) +
|
||||
* supp data length (2 bytes) + supp data */
|
||||
length += (outlen + 4);
|
||||
p += outlen;
|
||||
}
|
||||
if (length > 0)
|
||||
{
|
||||
/* write handshake length */
|
||||
l2n3(length - 4, size_loc);
|
||||
/* supp_data length */
|
||||
l2n3(length - 7, size_loc);
|
||||
s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B;
|
||||
s->init_num = length;
|
||||
s->init_off = 0;
|
||||
|
||||
return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
|
||||
}
|
||||
}
|
||||
|
||||
s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B;
|
||||
s->init_num = length;
|
||||
/* no supp data message sent */
|
||||
*skip = 1;
|
||||
s->init_num = 0;
|
||||
s->init_off = 0;
|
||||
return 1;
|
||||
f_err:
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,al);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
|
||||
int tls1_get_client_supplemental_data(SSL *s)
|
||||
{
|
||||
int al = 0;
|
||||
int cb_retval = 0;
|
||||
int ok;
|
||||
long n;
|
||||
const unsigned char *p, *d;
|
||||
unsigned short supp_data_entry_type = 0;
|
||||
unsigned long supp_data_entry_len = 0;
|
||||
unsigned long supp_data_len = 0;
|
||||
size_t i = 0;
|
||||
|
||||
n=s->method->ssl_get_message(s,
|
||||
SSL3_ST_SR_SUPPLEMENTAL_DATA_A,
|
||||
SSL3_ST_SR_SUPPLEMENTAL_DATA_B,
|
||||
SSL3_MT_SUPPLEMENTAL_DATA,
|
||||
/* use default limit */
|
||||
TLSEXT_MAXLEN_supplemental_data,
|
||||
&ok);
|
||||
|
||||
if (!ok) return((int)n);
|
||||
|
||||
p = (unsigned char *)s->init_msg;
|
||||
d = p;
|
||||
|
||||
/* The message cannot be empty */
|
||||
if (n < 3)
|
||||
{
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
|
||||
goto f_err;
|
||||
}
|
||||
n2l3(p, supp_data_len);
|
||||
while (p<d+supp_data_len)
|
||||
{
|
||||
n2s(p, supp_data_entry_type);
|
||||
n2s(p, supp_data_entry_len);
|
||||
/* if there is a callback for this supp data type, send it */
|
||||
for (i=0; i < s->ctx->srv_supp_data_records_count; i++)
|
||||
{
|
||||
if (s->ctx->srv_supp_data_records[i].supp_data_type == supp_data_entry_type && s->ctx->srv_supp_data_records[i].fn2)
|
||||
{
|
||||
cb_retval = s->ctx->srv_supp_data_records[i].fn2(s, supp_data_entry_type, p, supp_data_entry_len, &al, s->ctx->srv_supp_data_records[i].arg);
|
||||
if (cb_retval == 0)
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA, ERR_R_SSL_LIB);
|
||||
goto f_err;
|
||||
}
|
||||
}
|
||||
}
|
||||
p+=supp_data_entry_len;
|
||||
}
|
||||
return 1;
|
||||
f_err:
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,al);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
130
ssl/ssl.h
130
ssl/ssl.h
@ -406,11 +406,11 @@ typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, S
|
||||
*/
|
||||
typedef int (*custom_cli_ext_first_cb_fn)(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg);
|
||||
unsigned short *outlen, int *al, void *arg);
|
||||
typedef int (*custom_cli_ext_second_cb_fn)(SSL *s, unsigned short ext_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg);
|
||||
void *arg);
|
||||
|
||||
typedef int (*custom_srv_ext_first_cb_fn)(SSL *s, unsigned short ext_type,
|
||||
const unsigned char *in,
|
||||
@ -418,7 +418,7 @@ typedef int (*custom_srv_ext_first_cb_fn)(SSL *s, unsigned short ext_type,
|
||||
void *arg);
|
||||
typedef int (*custom_srv_ext_second_cb_fn)(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg);
|
||||
unsigned short *outlen, int *al, void *arg);
|
||||
|
||||
typedef struct {
|
||||
unsigned short ext_type;
|
||||
@ -433,6 +433,58 @@ typedef struct {
|
||||
custom_srv_ext_second_cb_fn fn2;
|
||||
void *arg;
|
||||
} custom_srv_ext_record;
|
||||
|
||||
/* Callbacks and structures for handling Supplemental Data:
|
||||
* srv_supp_data_first_cb_fn - server sends Supplemental Data
|
||||
* srv_supp_data_second_cb_fn - server receives Supplemental Data
|
||||
* cli_supp_data_first_cb_fn - client receives Supplemental Data
|
||||
* cli_supp_data_second_cb_fn - client sends Supplemental Data
|
||||
*
|
||||
* All these functions return nonzero on success. Zero will terminate
|
||||
* the handshake (and return a specific TLS Fatal alert, if the function
|
||||
* declaration has an "al" parameter). -1 for the "sending" functions
|
||||
* will result in no supplemental data entry being added to the
|
||||
* supplemental data message for the provided supplemental data type.
|
||||
*
|
||||
* "supp_data_type" is a Supplemental Data Type from 0-65535.
|
||||
* "in" is a pointer to TLS "supplemental_data_entry" being provided to the cb.
|
||||
* "out" is used by the callback to return a pointer to "supplemental data"
|
||||
* which OpenSSL will later copy into the TLS handshake. The contents
|
||||
* of this buffer should not be changed until the handshake is complete.
|
||||
* "inlen" and "outlen" are Supplemental Data lengths from 0-65535.
|
||||
* "al" is a TLS "AlertDescription" from 0-255 which WILL be sent as a
|
||||
* fatal TLS alert, if the callback returns zero.
|
||||
*/
|
||||
typedef int (*srv_supp_data_first_cb_fn)(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, int *al, void *arg);
|
||||
typedef int (*srv_supp_data_second_cb_fn)(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg);
|
||||
|
||||
typedef int (*cli_supp_data_first_cb_fn)(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg);
|
||||
typedef int (*cli_supp_data_second_cb_fn)(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, int *al, void *arg);
|
||||
|
||||
typedef struct {
|
||||
unsigned short supp_data_type;
|
||||
srv_supp_data_first_cb_fn fn1;
|
||||
srv_supp_data_second_cb_fn fn2;
|
||||
void *arg;
|
||||
} srv_supp_data_record;
|
||||
|
||||
typedef struct {
|
||||
unsigned short supp_data_type;
|
||||
cli_supp_data_first_cb_fn fn1;
|
||||
cli_supp_data_second_cb_fn fn2;
|
||||
void *arg;
|
||||
} cli_supp_data_record;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_SSL_INTERN
|
||||
@ -596,13 +648,6 @@ struct ssl_session_st
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
char *srp_username;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
/* Used by client: the proof for this session.
|
||||
* We store it outside the sess_cert structure, since the proof
|
||||
* is received before the certificate. */
|
||||
unsigned char *audit_proof;
|
||||
size_t audit_proof_length;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -1149,8 +1194,6 @@ struct ssl_ctx_st
|
||||
size_t tlsext_ellipticcurvelist_length;
|
||||
unsigned char *tlsext_ellipticcurvelist;
|
||||
# endif /* OPENSSL_NO_EC */
|
||||
int (*tlsext_authz_server_audit_proof_cb)(SSL *s, void *arg);
|
||||
void *tlsext_authz_server_audit_proof_cb_arg;
|
||||
#endif
|
||||
|
||||
/* Arrays containing the callbacks for custom TLS Extensions. */
|
||||
@ -1158,6 +1201,12 @@ struct ssl_ctx_st
|
||||
size_t custom_cli_ext_records_count;
|
||||
custom_srv_ext_record *custom_srv_ext_records;
|
||||
size_t custom_srv_ext_records_count;
|
||||
|
||||
/* Arrays containing the callbacks for Supplemental Data. */
|
||||
cli_supp_data_record *cli_supp_data_records;
|
||||
size_t cli_supp_data_records_count;
|
||||
srv_supp_data_record *srv_supp_data_records;
|
||||
size_t srv_supp_data_records_count;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1304,6 +1353,31 @@ int SSL_CTX_set_custom_cli_ext(SSL_CTX *ctx, unsigned short ext_type,
|
||||
int SSL_CTX_set_custom_srv_ext(SSL_CTX *ctx, unsigned short ext_type,
|
||||
custom_srv_ext_first_cb_fn fn1,
|
||||
custom_srv_ext_second_cb_fn fn2, void *arg);
|
||||
|
||||
/* Register callbacks to handle Supplemental Data as client or server.
|
||||
*
|
||||
* For SSL_CTX_set_srv_supp_data, a NULL srv_supp_data_first_cb_fn results in no supplemental data
|
||||
* being sent by the server for that TLS extension.
|
||||
* A NULL srv_supp_data_second_cb_fn results in no supplemental data
|
||||
* being received by the server for that TLS extension.
|
||||
*
|
||||
* For SSL_CTX_set_cli_supp_data, a NULL cli_supp_data_first_cb_fn results in no supplemental data
|
||||
* being received by the client for that TLS extension.
|
||||
* A NULL cli_supp_data_second_cb_fn results in no supplemental data
|
||||
* being sent by the client for that TLS extension.
|
||||
*
|
||||
* Returns nonzero on success. You cannot register twice for the same supp_data_type.
|
||||
*/
|
||||
int SSL_CTX_set_srv_supp_data(SSL_CTX *ctx,
|
||||
unsigned short supp_data_type,
|
||||
srv_supp_data_first_cb_fn fn1,
|
||||
srv_supp_data_second_cb_fn fn2, void *arg);
|
||||
|
||||
int SSL_CTX_set_cli_supp_data(SSL_CTX *ctx,
|
||||
unsigned short supp_data_type,
|
||||
cli_supp_data_first_cb_fn fn1,
|
||||
cli_supp_data_second_cb_fn fn2, void *arg);
|
||||
|
||||
#endif
|
||||
|
||||
#define SSL_NOTHING 1
|
||||
@ -1825,9 +1899,6 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
#define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING 86
|
||||
#define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS 87
|
||||
#endif
|
||||
/* Callback for verifying audit proofs (client only) */
|
||||
#define SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB 95
|
||||
#define SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG 96
|
||||
#endif /* OPENSSL_NO_TLSEXT */
|
||||
|
||||
#define DTLS_CTRL_GET_TIMEOUT 73
|
||||
@ -2099,17 +2170,6 @@ int SSL_use_certificate(SSL *ssl, X509 *x);
|
||||
int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
/* Set authz data for the current active cert. */
|
||||
int SSL_CTX_use_authz(SSL_CTX *ctx, unsigned char *authz, size_t authz_length);
|
||||
int SSL_use_authz(SSL *ssl, unsigned char *authz, size_t authz_length);
|
||||
/* Get the authz of type 'type' associated with the current active cert. */
|
||||
const unsigned char *SSL_CTX_get_authz_data(SSL_CTX *ctx, unsigned char type,
|
||||
size_t *data_length);
|
||||
#ifndef OPENSSL_NO_STDIO
|
||||
int SSL_CTX_use_authz_file(SSL_CTX *ctx, const char *file);
|
||||
int SSL_use_authz_file(SSL *ssl, const char *file);
|
||||
#endif
|
||||
|
||||
/* Set serverinfo data for the current active cert. */
|
||||
int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
|
||||
size_t serverinfo_length);
|
||||
@ -2163,10 +2223,6 @@ int SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
|
||||
#ifndef OPENSSL_NO_BIO
|
||||
int SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
unsigned char *SSL_SESSION_get_tlsext_authz_server_audit_proof(SSL_SESSION *s,
|
||||
size_t *proof_length);
|
||||
#endif
|
||||
void SSL_SESSION_free(SSL_SESSION *ses);
|
||||
int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
|
||||
int SSL_set_session(SSL *to, SSL_SESSION *session);
|
||||
@ -2507,9 +2563,7 @@ void ERR_load_SSL_strings(void);
|
||||
/* Error codes for the SSL functions. */
|
||||
|
||||
/* Function codes. */
|
||||
#define SSL_F_AUTHZ_FIND_DATA 330
|
||||
#define SSL_F_AUTHZ_VALIDATE 323
|
||||
#define SSL_F_CHECK_SUITEB_CIPHER_LIST 331
|
||||
#define SSL_F_CHECK_SUITEB_CIPHER_LIST 335
|
||||
#define SSL_F_CLIENT_CERTIFICATE 100
|
||||
#define SSL_F_CLIENT_FINISHED 167
|
||||
#define SSL_F_CLIENT_HELLO 101
|
||||
@ -2552,7 +2606,6 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_GET_SERVER_HELLO 109
|
||||
#define SSL_F_GET_SERVER_VERIFY 110
|
||||
#define SSL_F_I2D_SSL_SESSION 111
|
||||
#define SSL_F_READ_AUTHZ 329
|
||||
#define SSL_F_READ_N 112
|
||||
#define SSL_F_REQUEST_CERTIFICATE 113
|
||||
#define SSL_F_SERVER_FINISH 239
|
||||
@ -2658,7 +2711,6 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219
|
||||
#define SSL_F_SSL_CTX_SET_SSL_VERSION 170
|
||||
#define SSL_F_SSL_CTX_SET_TRUST 229
|
||||
#define SSL_F_SSL_CTX_USE_AUTHZ 324
|
||||
#define SSL_F_SSL_CTX_USE_CERTIFICATE 171
|
||||
#define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172
|
||||
#define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE 220
|
||||
@ -2700,7 +2752,6 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_SSL_SESSION_PRINT_FP 190
|
||||
#define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312
|
||||
#define SSL_F_SSL_SESS_CERT_NEW 225
|
||||
#define SSL_F_SSL_SET_AUTHZ 325
|
||||
#define SSL_F_SSL_SET_CERT 191
|
||||
#define SSL_F_SSL_SET_CIPHER_LIST 271
|
||||
#define SSL_F_SSL_SET_FD 192
|
||||
@ -2717,7 +2768,6 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_SSL_UNDEFINED_CONST_FUNCTION 243
|
||||
#define SSL_F_SSL_UNDEFINED_FUNCTION 197
|
||||
#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244
|
||||
#define SSL_F_SSL_USE_AUTHZ 328
|
||||
#define SSL_F_SSL_USE_CERTIFICATE 198
|
||||
#define SSL_F_SSL_USE_CERTIFICATE_ASN1 199
|
||||
#define SSL_F_SSL_USE_CERTIFICATE_FILE 200
|
||||
@ -2737,18 +2787,19 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_TLS1_ENC 210
|
||||
#define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314
|
||||
#define SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA 326
|
||||
#define SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA 336
|
||||
#define SSL_F_TLS1_HEARTBEAT 315
|
||||
#define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT 275
|
||||
#define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT 276
|
||||
#define SSL_F_TLS1_PRF 284
|
||||
#define SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA 327
|
||||
#define SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA 333
|
||||
#define SSL_F_TLS1_SETUP_KEY_BLOCK 211
|
||||
#define SSL_F_WRITE_PENDING 212
|
||||
|
||||
/* Reason codes. */
|
||||
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
|
||||
#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272
|
||||
#define SSL_R_AUTHZ_DATA_TOO_LARGE 375
|
||||
#define SSL_R_BAD_ALERT_RECORD 101
|
||||
#define SSL_R_BAD_AUTHENTICATION_TYPE 102
|
||||
#define SSL_R_BAD_CHANGE_CIPHER_SPEC 103
|
||||
@ -2841,8 +2892,6 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_ILLEGAL_PADDING 283
|
||||
#define SSL_R_ILLEGAL_SUITEB_DIGEST 380
|
||||
#define SSL_R_INCONSISTENT_COMPRESSION 340
|
||||
#define SSL_R_INVALID_AUDIT_PROOF 371
|
||||
#define SSL_R_INVALID_AUTHZ_DATA 374
|
||||
#define SSL_R_INVALID_CHALLENGE_LENGTH 158
|
||||
#define SSL_R_INVALID_COMMAND 280
|
||||
#define SSL_R_INVALID_COMPRESSION_ALGORITHM 341
|
||||
@ -3032,7 +3081,6 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_UNEXPECTED_RECORD 245
|
||||
#define SSL_R_UNINITIALIZED 276
|
||||
#define SSL_R_UNKNOWN_ALERT_TYPE 246
|
||||
#define SSL_R_UNKNOWN_AUTHZ_DATA_TYPE 372
|
||||
#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247
|
||||
#define SSL_R_UNKNOWN_CIPHER_RETURNED 248
|
||||
#define SSL_R_UNKNOWN_CIPHER_TYPE 249
|
||||
|
46
ssl/ssl3.h
46
ssl/ssl3.h
@ -560,28 +560,12 @@ typedef struct ssl3_state_st
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
/* tlsext_authz_client_types contains an array of supported authz
|
||||
* types, as advertised by the client. The array is sorted and
|
||||
* does not contain any duplicates. */
|
||||
unsigned char *tlsext_authz_client_types;
|
||||
size_t tlsext_authz_client_types_len;
|
||||
/* tlsext_authz_promised_to_client is true iff we're a server and we
|
||||
* echoed the client's supplemental data extension and therefore must
|
||||
* send a supplemental data handshake message. */
|
||||
char tlsext_authz_promised_to_client;
|
||||
/* tlsext_authz_server_promised is true iff we're a client and the
|
||||
* server echoed our server_authz extension and therefore must send us
|
||||
* a supplemental data handshake message. */
|
||||
char tlsext_authz_server_promised;
|
||||
|
||||
/* tlsext_custom_types contains an array of TLS Extension types which
|
||||
* were advertised by the client in its ClientHello, which were not
|
||||
* otherwise handled by OpenSSL, and which the server has registered
|
||||
* a custom_srv_ext_record to handle.
|
||||
/* serverinfo_client_tlsext_custom_types contains an array of TLS Extension types which
|
||||
* were advertised by the client in its ClientHello and leveraged by ServerInfo TLS extension callbacks.
|
||||
* The array does not contain any duplicates, and is in the same order
|
||||
* as the types were received in the client hello. */
|
||||
unsigned short *tlsext_custom_types;
|
||||
size_t tlsext_custom_types_count; /* how many tlsext_custom_types */
|
||||
unsigned short *serverinfo_client_tlsext_custom_types;
|
||||
size_t serverinfo_client_tlsext_custom_types_count; /* how many serverinfo_client_tlsext_custom_types */
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
/* This is set to true if we believe that this is a version of Safari
|
||||
@ -628,8 +612,10 @@ typedef struct ssl3_state_st
|
||||
#define SSL3_ST_CR_CERT_REQ_B (0x151|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CR_SRVR_DONE_A (0x160|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CR_SRVR_DONE_B (0x161|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CR_SUPPLEMENTAL_DATA_A (0x210|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CR_SUPPLEMENTAL_DATA_B (0x211|SSL_ST_CONNECT)
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
#define SSL3_ST_CR_SUPPLEMENTAL_DATA_A (0x212|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CR_SUPPLEMENTAL_DATA_B (0x213|SSL_ST_CONNECT)
|
||||
#endif
|
||||
/* write to server */
|
||||
#define SSL3_ST_CW_CERT_A (0x170|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CW_CERT_B (0x171|SSL_ST_CONNECT)
|
||||
@ -644,6 +630,10 @@ typedef struct ssl3_state_st
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
#define SSL3_ST_CW_NEXT_PROTO_A (0x200|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CW_NEXT_PROTO_B (0x201|SSL_ST_CONNECT)
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
#define SSL3_ST_CW_SUPPLEMENTAL_DATA_A (0x222|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CW_SUPPLEMENTAL_DATA_B (0x223|SSL_ST_CONNECT)
|
||||
#endif
|
||||
#endif
|
||||
#define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CW_FINISHED_B (0x1B1|SSL_ST_CONNECT)
|
||||
@ -670,6 +660,10 @@ typedef struct ssl3_state_st
|
||||
#define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SR_CLNT_HELLO_D (0x115|SSL_ST_ACCEPT)
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
#define SSL3_ST_SR_SUPPLEMENTAL_DATA_A (0x212|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SR_SUPPLEMENTAL_DATA_B (0x213|SSL_ST_ACCEPT)
|
||||
#endif
|
||||
/* write to client */
|
||||
#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
|
||||
#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)
|
||||
@ -710,8 +704,10 @@ typedef struct ssl3_state_st
|
||||
#define SSL3_ST_SW_SESSION_TICKET_B (0x1F1|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SW_CERT_STATUS_A (0x200|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SW_CERT_STATUS_B (0x201|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SW_SUPPLEMENTAL_DATA_A (0x220|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SW_SUPPLEMENTAL_DATA_B (0x221|SSL_ST_ACCEPT)
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
#define SSL3_ST_SW_SUPPLEMENTAL_DATA_A (0x222|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SW_SUPPLEMENTAL_DATA_B (0x223|SSL_ST_ACCEPT)
|
||||
#endif
|
||||
|
||||
#define SSL3_MT_HELLO_REQUEST 0
|
||||
#define SSL3_MT_CLIENT_HELLO 1
|
||||
@ -725,7 +721,9 @@ typedef struct ssl3_state_st
|
||||
#define SSL3_MT_CLIENT_KEY_EXCHANGE 16
|
||||
#define SSL3_MT_FINISHED 20
|
||||
#define SSL3_MT_CERTIFICATE_STATUS 22
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
#define SSL3_MT_SUPPLEMENTAL_DATA 23
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
#define SSL3_MT_NEXT_PROTO 67
|
||||
#endif
|
||||
|
@ -330,23 +330,6 @@ CERT *ssl_cert_dup(CERT *cert)
|
||||
}
|
||||
rpk->valid_flags = 0;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (cert->pkeys[i].authz != NULL)
|
||||
{
|
||||
/* Just copy everything. */
|
||||
ret->pkeys[i].authz_length =
|
||||
cert->pkeys[i].authz_length;
|
||||
ret->pkeys[i].authz =
|
||||
OPENSSL_malloc(ret->pkeys[i].authz_length);
|
||||
if (ret->pkeys[i].authz == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(ret->pkeys[i].authz,
|
||||
cert->pkeys[i].authz,
|
||||
cert->pkeys[i].authz_length);
|
||||
}
|
||||
|
||||
if (cert->pkeys[i].serverinfo != NULL)
|
||||
{
|
||||
/* Just copy everything. */
|
||||
@ -479,11 +462,6 @@ void ssl_cert_clear_certs(CERT *c)
|
||||
cpk->chain = NULL;
|
||||
}
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (cpk->authz)
|
||||
{
|
||||
OPENSSL_free(cpk->authz);
|
||||
cpk->authz = NULL;
|
||||
}
|
||||
if (cpk->serverinfo)
|
||||
{
|
||||
OPENSSL_free(cpk->serverinfo);
|
||||
|
@ -70,8 +70,6 @@
|
||||
|
||||
static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{
|
||||
{ERR_FUNC(SSL_F_AUTHZ_FIND_DATA), "AUTHZ_FIND_DATA"},
|
||||
{ERR_FUNC(SSL_F_AUTHZ_VALIDATE), "AUTHZ_VALIDATE"},
|
||||
{ERR_FUNC(SSL_F_CHECK_SUITEB_CIPHER_LIST), "CHECK_SUITEB_CIPHER_LIST"},
|
||||
{ERR_FUNC(SSL_F_CLIENT_CERTIFICATE), "CLIENT_CERTIFICATE"},
|
||||
{ERR_FUNC(SSL_F_CLIENT_FINISHED), "CLIENT_FINISHED"},
|
||||
@ -115,7 +113,6 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{ERR_FUNC(SSL_F_GET_SERVER_HELLO), "GET_SERVER_HELLO"},
|
||||
{ERR_FUNC(SSL_F_GET_SERVER_VERIFY), "GET_SERVER_VERIFY"},
|
||||
{ERR_FUNC(SSL_F_I2D_SSL_SESSION), "i2d_SSL_SESSION"},
|
||||
{ERR_FUNC(SSL_F_READ_AUTHZ), "READ_AUTHZ"},
|
||||
{ERR_FUNC(SSL_F_READ_N), "READ_N"},
|
||||
{ERR_FUNC(SSL_F_REQUEST_CERTIFICATE), "REQUEST_CERTIFICATE"},
|
||||
{ERR_FUNC(SSL_F_SERVER_FINISH), "SERVER_FINISH"},
|
||||
@ -221,7 +218,6 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{ERR_FUNC(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT), "SSL_CTX_set_session_id_context"},
|
||||
{ERR_FUNC(SSL_F_SSL_CTX_SET_SSL_VERSION), "SSL_CTX_set_ssl_version"},
|
||||
{ERR_FUNC(SSL_F_SSL_CTX_SET_TRUST), "SSL_CTX_set_trust"},
|
||||
{ERR_FUNC(SSL_F_SSL_CTX_USE_AUTHZ), "SSL_CTX_use_authz"},
|
||||
{ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE), "SSL_CTX_use_certificate"},
|
||||
{ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1), "SSL_CTX_use_certificate_ASN1"},
|
||||
{ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE), "SSL_CTX_use_certificate_chain_file"},
|
||||
@ -263,7 +259,6 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"},
|
||||
{ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT), "SSL_SESSION_set1_id_context"},
|
||||
{ERR_FUNC(SSL_F_SSL_SESS_CERT_NEW), "ssl_sess_cert_new"},
|
||||
{ERR_FUNC(SSL_F_SSL_SET_AUTHZ), "SSL_SET_AUTHZ"},
|
||||
{ERR_FUNC(SSL_F_SSL_SET_CERT), "SSL_SET_CERT"},
|
||||
{ERR_FUNC(SSL_F_SSL_SET_CIPHER_LIST), "SSL_set_cipher_list"},
|
||||
{ERR_FUNC(SSL_F_SSL_SET_FD), "SSL_set_fd"},
|
||||
@ -280,7 +275,6 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION), "ssl_undefined_const_function"},
|
||||
{ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION), "ssl_undefined_function"},
|
||||
{ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION), "ssl_undefined_void_function"},
|
||||
{ERR_FUNC(SSL_F_SSL_USE_AUTHZ), "SSL_use_authz"},
|
||||
{ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE), "SSL_use_certificate"},
|
||||
{ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_ASN1), "SSL_use_certificate_ASN1"},
|
||||
{ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_FILE), "SSL_use_certificate_file"},
|
||||
@ -300,11 +294,13 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
||||
{ERR_FUNC(SSL_F_TLS1_ENC), "tls1_enc"},
|
||||
{ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL), "tls1_export_keying_material"},
|
||||
{ERR_FUNC(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA), "tls1_get_server_supplemental_data"},
|
||||
{ERR_FUNC(SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA), "tls1_get_client_supplemental_data"},
|
||||
{ERR_FUNC(SSL_F_TLS1_HEARTBEAT), "tls1_heartbeat"},
|
||||
{ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT), "TLS1_PREPARE_CLIENTHELLO_TLSEXT"},
|
||||
{ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT), "TLS1_PREPARE_SERVERHELLO_TLSEXT"},
|
||||
{ERR_FUNC(SSL_F_TLS1_PRF), "tls1_prf"},
|
||||
{ERR_FUNC(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA), "tls1_send_server_supplemental_data"},
|
||||
{ERR_FUNC(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA), "tls1_send_client_supplemental_data"},
|
||||
{ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "tls1_setup_key_block"},
|
||||
{ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"},
|
||||
{0,NULL}
|
||||
@ -314,7 +310,6 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{
|
||||
{ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE) ,"app data in handshake"},
|
||||
{ERR_REASON(SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT),"attempt to reuse session in different context"},
|
||||
{ERR_REASON(SSL_R_AUTHZ_DATA_TOO_LARGE) ,"authz data too large"},
|
||||
{ERR_REASON(SSL_R_BAD_ALERT_RECORD) ,"bad alert record"},
|
||||
{ERR_REASON(SSL_R_BAD_AUTHENTICATION_TYPE),"bad authentication type"},
|
||||
{ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC),"bad change cipher spec"},
|
||||
@ -407,8 +402,6 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_ILLEGAL_PADDING) ,"illegal padding"},
|
||||
{ERR_REASON(SSL_R_ILLEGAL_SUITEB_DIGEST) ,"illegal Suite B digest"},
|
||||
{ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION),"inconsistent compression"},
|
||||
{ERR_REASON(SSL_R_INVALID_AUDIT_PROOF) ,"invalid audit proof"},
|
||||
{ERR_REASON(SSL_R_INVALID_AUTHZ_DATA) ,"invalid authz data"},
|
||||
{ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"},
|
||||
{ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"},
|
||||
{ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"},
|
||||
@ -598,7 +591,6 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_UNEXPECTED_RECORD) ,"unexpected record"},
|
||||
{ERR_REASON(SSL_R_UNINITIALIZED) ,"uninitialized"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE) ,"unknown alert type"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN_AUTHZ_DATA_TYPE),"unknown authz data type"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE),"unknown certificate type"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED),"unknown cipher returned"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE) ,"unknown cipher type"},
|
||||
|
@ -1862,6 +1862,66 @@ void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
|
||||
else
|
||||
*len = ssl->s3->alpn_selected_len;
|
||||
}
|
||||
|
||||
int SSL_CTX_set_cli_supp_data(SSL_CTX *ctx,
|
||||
unsigned short supp_data_type,
|
||||
cli_supp_data_first_cb_fn fn1,
|
||||
cli_supp_data_second_cb_fn fn2, void* arg)
|
||||
{
|
||||
size_t i;
|
||||
cli_supp_data_record* record;
|
||||
|
||||
/* Check for duplicates */
|
||||
for (i=0; i < ctx->cli_supp_data_records_count; i++)
|
||||
if (supp_data_type == ctx->cli_supp_data_records[i].supp_data_type)
|
||||
return 0;
|
||||
|
||||
ctx->cli_supp_data_records = OPENSSL_realloc(ctx->cli_supp_data_records,
|
||||
(ctx->cli_supp_data_records_count+1) * sizeof(cli_supp_data_record));
|
||||
if (!ctx->cli_supp_data_records)
|
||||
{
|
||||
ctx->cli_supp_data_records_count = 0;
|
||||
return 0;
|
||||
}
|
||||
ctx->cli_supp_data_records_count++;
|
||||
record = &ctx->cli_supp_data_records[ctx->cli_supp_data_records_count - 1];
|
||||
record->supp_data_type = supp_data_type;
|
||||
record->fn1 = fn1;
|
||||
record->fn2 = fn2;
|
||||
record->arg = arg;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_CTX_set_srv_supp_data(SSL_CTX *ctx,
|
||||
unsigned short supp_data_type,
|
||||
srv_supp_data_first_cb_fn fn1,
|
||||
srv_supp_data_second_cb_fn fn2, void* arg)
|
||||
{
|
||||
size_t i;
|
||||
srv_supp_data_record* record;
|
||||
|
||||
/* Check for duplicates */
|
||||
for (i=0; i < ctx->srv_supp_data_records_count; i++)
|
||||
if (supp_data_type == ctx->srv_supp_data_records[i].supp_data_type)
|
||||
return 0;
|
||||
|
||||
ctx->srv_supp_data_records = OPENSSL_realloc(ctx->srv_supp_data_records,
|
||||
(ctx->srv_supp_data_records_count+1) * sizeof(srv_supp_data_record));
|
||||
if (!ctx->srv_supp_data_records)
|
||||
{
|
||||
ctx->srv_supp_data_records_count = 0;
|
||||
return 0;
|
||||
}
|
||||
ctx->srv_supp_data_records_count++;
|
||||
record = &ctx->srv_supp_data_records[ctx->srv_supp_data_records_count - 1];
|
||||
record->supp_data_type = supp_data_type;
|
||||
record->fn1 = fn1;
|
||||
record->fn2 = fn2;
|
||||
record->arg = arg;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* !OPENSSL_NO_TLSEXT */
|
||||
|
||||
int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
|
||||
@ -2065,6 +2125,10 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
|
||||
ret->custom_cli_ext_records_count = 0;
|
||||
ret->custom_srv_ext_records = NULL;
|
||||
ret->custom_srv_ext_records_count = 0;
|
||||
ret->cli_supp_data_records = NULL;
|
||||
ret->cli_supp_data_records_count = 0;
|
||||
ret->srv_supp_data_records = NULL;
|
||||
ret->srv_supp_data_records_count = 0;
|
||||
#ifndef OPENSSL_NO_BUF_FREELISTS
|
||||
ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT;
|
||||
ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
|
||||
@ -2206,6 +2270,8 @@ void SSL_CTX_free(SSL_CTX *a)
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
OPENSSL_free(a->custom_cli_ext_records);
|
||||
OPENSSL_free(a->custom_srv_ext_records);
|
||||
OPENSSL_free(a->cli_supp_data_records);
|
||||
OPENSSL_free(a->srv_supp_data_records);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (a->client_cert_engine)
|
||||
@ -2643,25 +2709,6 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd)
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
unsigned char *ssl_get_authz_data(SSL *s, size_t *authz_length)
|
||||
{
|
||||
CERT *c;
|
||||
int i;
|
||||
|
||||
c = s->cert;
|
||||
i = ssl_get_server_cert_index(s);
|
||||
|
||||
if (i == -1)
|
||||
return NULL;
|
||||
|
||||
*authz_length = 0;
|
||||
if (c->pkeys[i].authz == NULL)
|
||||
return(NULL);
|
||||
*authz_length = c->pkeys[i].authz_length;
|
||||
|
||||
return c->pkeys[i].authz;
|
||||
}
|
||||
|
||||
int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo,
|
||||
size_t *serverinfo_length)
|
||||
{
|
||||
|
@ -505,14 +505,6 @@ typedef struct cert_pkey_st
|
||||
/* Chain for this certificate */
|
||||
STACK_OF(X509) *chain;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
/* authz/authz_length contain authz data for this certificate. The data
|
||||
* is in wire format, specifically it's a series of records like:
|
||||
* uint8_t authz_type; // (RFC 5878, AuthzDataFormat)
|
||||
* uint16_t length;
|
||||
* uint8_t data[length]; */
|
||||
unsigned char *authz;
|
||||
size_t authz_length;
|
||||
|
||||
/* serverinfo data for this certificate. The data is in TLS Extension
|
||||
* wire format, specifically it's a series of records like:
|
||||
* uint16_t extension_type; // (RFC 5246, 7.4.1.4, Extension)
|
||||
@ -1014,7 +1006,6 @@ int ssl_undefined_void_function(void);
|
||||
int ssl_undefined_const_function(const SSL *s);
|
||||
CERT_PKEY *ssl_get_server_send_pkey(const SSL *s);
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
unsigned char *ssl_get_authz_data(SSL *s, size_t *authz_length);
|
||||
int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo,
|
||||
size_t *serverinfo_length);
|
||||
#endif
|
||||
@ -1272,8 +1263,8 @@ int tls1_shared_list(SSL *s,
|
||||
const unsigned char *l1, size_t l1len,
|
||||
const unsigned char *l2, size_t l2len,
|
||||
int nmatch);
|
||||
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit);
|
||||
unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit);
|
||||
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al);
|
||||
unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al);
|
||||
int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n);
|
||||
int ssl_check_clienthello_tlsext_late(SSL *s);
|
||||
int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n);
|
||||
@ -1281,8 +1272,10 @@ int ssl_prepare_clienthello_tlsext(SSL *s);
|
||||
int ssl_prepare_serverhello_tlsext(SSL *s);
|
||||
|
||||
/* server only */
|
||||
int tls1_send_server_supplemental_data(SSL *s);
|
||||
int tls1_send_server_supplemental_data(SSL *s, int *skip);
|
||||
int tls1_get_client_supplemental_data(SSL *s);
|
||||
/* client only */
|
||||
int tls1_send_client_supplemental_data(SSL *s, int *skip);
|
||||
int tls1_get_server_supplemental_data(SSL *s);
|
||||
|
||||
#ifndef OPENSSL_NO_HEARTBEATS
|
||||
|
271
ssl/ssl_rsa.c
271
ssl/ssl_rsa.c
@ -66,10 +66,6 @@
|
||||
|
||||
static int ssl_set_cert(CERT *c, X509 *x509);
|
||||
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
static int ssl_set_authz(CERT *c, unsigned char *authz,
|
||||
size_t authz_length);
|
||||
#endif
|
||||
int SSL_use_certificate(SSL *ssl, X509 *x)
|
||||
{
|
||||
if (x == NULL)
|
||||
@ -798,50 +794,6 @@ end:
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
/* authz_validate returns true iff authz is well formed, i.e. that it meets the
|
||||
* wire format as documented in the CERT_PKEY structure and that there are no
|
||||
* duplicate entries. */
|
||||
static char authz_validate(const unsigned char *authz, size_t length)
|
||||
{
|
||||
unsigned char types_seen_bitmap[32];
|
||||
|
||||
if (!authz)
|
||||
return 1;
|
||||
|
||||
memset(types_seen_bitmap, 0, sizeof(types_seen_bitmap));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned char type, byte, bit;
|
||||
unsigned short len;
|
||||
|
||||
if (!length)
|
||||
return 1;
|
||||
|
||||
type = *(authz++);
|
||||
length--;
|
||||
|
||||
byte = type / 8;
|
||||
bit = type & 7;
|
||||
if (types_seen_bitmap[byte] & (1 << bit))
|
||||
return 0;
|
||||
types_seen_bitmap[byte] |= (1 << bit);
|
||||
|
||||
if (length < 2)
|
||||
return 0;
|
||||
len = ((unsigned short) authz[0]) << 8 |
|
||||
((unsigned short) authz[1]);
|
||||
authz += 2;
|
||||
length -= 2;
|
||||
|
||||
if (length < len)
|
||||
return 0;
|
||||
|
||||
authz += len;
|
||||
length -= len;
|
||||
}
|
||||
}
|
||||
|
||||
static int serverinfo_find_extension(const unsigned char *serverinfo,
|
||||
size_t serverinfo_length,
|
||||
unsigned short extension_type,
|
||||
@ -896,20 +848,61 @@ static int serverinfo_srv_first_cb(SSL *s, unsigned short ext_type,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
if (inlen != 0)
|
||||
{
|
||||
*al = SSL_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if already in list, error out */
|
||||
for (i = 0; i < s->s3->serverinfo_client_tlsext_custom_types_count; i++)
|
||||
{
|
||||
if (s->s3->serverinfo_client_tlsext_custom_types[i] == ext_type)
|
||||
{
|
||||
*al = SSL_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
s->s3->serverinfo_client_tlsext_custom_types_count++;
|
||||
s->s3->serverinfo_client_tlsext_custom_types = OPENSSL_realloc(
|
||||
s->s3->serverinfo_client_tlsext_custom_types,
|
||||
s->s3->serverinfo_client_tlsext_custom_types_count * 2);
|
||||
if (s->s3->serverinfo_client_tlsext_custom_types == NULL)
|
||||
{
|
||||
s->s3->serverinfo_client_tlsext_custom_types_count = 0;
|
||||
*al = TLS1_AD_INTERNAL_ERROR;
|
||||
return 0;
|
||||
}
|
||||
s->s3->serverinfo_client_tlsext_custom_types[
|
||||
s->s3->serverinfo_client_tlsext_custom_types_count - 1] = ext_type;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int serverinfo_srv_second_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out, unsigned short *outlen,
|
||||
void *arg)
|
||||
const unsigned char **out, unsigned short *outlen,
|
||||
int *al, void *arg)
|
||||
{
|
||||
const unsigned char *serverinfo = NULL;
|
||||
size_t serverinfo_length = 0;
|
||||
size_t i = 0;
|
||||
unsigned int match = 0;
|
||||
/* Did the client send a TLS extension for this type? */
|
||||
for (i = 0; i < s->s3->serverinfo_client_tlsext_custom_types_count; i++)
|
||||
{
|
||||
if (s->s3->serverinfo_client_tlsext_custom_types[i] == ext_type)
|
||||
{
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match)
|
||||
{
|
||||
/* extension not sent by client...don't send extension */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Is there serverinfo data for the chosen server cert? */
|
||||
if ((ssl_get_server_cert_serverinfo(s, &serverinfo,
|
||||
@ -917,7 +910,7 @@ static int serverinfo_srv_second_cb(SSL *s, unsigned short ext_type,
|
||||
{
|
||||
/* Find the relevant extension from the serverinfo */
|
||||
int retval = serverinfo_find_extension(serverinfo, serverinfo_length,
|
||||
ext_type, out, outlen);
|
||||
ext_type, out, outlen);
|
||||
if (retval == 0)
|
||||
return 0; /* Error */
|
||||
if (retval == -1)
|
||||
@ -974,83 +967,6 @@ static int serverinfo_process_buffer(const unsigned char *serverinfo,
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned char *authz_find_data(const unsigned char *authz,
|
||||
size_t authz_length,
|
||||
unsigned char data_type,
|
||||
size_t *data_length)
|
||||
{
|
||||
if (authz == NULL) return NULL;
|
||||
if (!authz_validate(authz, authz_length))
|
||||
{
|
||||
SSLerr(SSL_F_AUTHZ_FIND_DATA,SSL_R_INVALID_AUTHZ_DATA);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned char type;
|
||||
unsigned short len;
|
||||
if (!authz_length)
|
||||
return NULL;
|
||||
|
||||
type = *(authz++);
|
||||
authz_length--;
|
||||
|
||||
/* We've validated the authz data, so we don't have to
|
||||
* check again that we have enough bytes left. */
|
||||
len = ((unsigned short) authz[0]) << 8 |
|
||||
((unsigned short) authz[1]);
|
||||
authz += 2;
|
||||
authz_length -= 2;
|
||||
if (type == data_type)
|
||||
{
|
||||
*data_length = len;
|
||||
return authz;
|
||||
}
|
||||
authz += len;
|
||||
authz_length -= len;
|
||||
}
|
||||
/* No match */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ssl_set_authz(CERT *c, unsigned char *authz, size_t authz_length)
|
||||
{
|
||||
CERT_PKEY *current_key = c->key;
|
||||
if (current_key == NULL)
|
||||
return 0;
|
||||
if (!authz_validate(authz, authz_length))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_SET_AUTHZ,SSL_R_INVALID_AUTHZ_DATA);
|
||||
return(0);
|
||||
}
|
||||
current_key->authz = OPENSSL_realloc(current_key->authz, authz_length);
|
||||
if (current_key->authz == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_SET_AUTHZ,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
current_key->authz_length = authz_length;
|
||||
memcpy(current_key->authz, authz, authz_length);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_CTX_use_authz(SSL_CTX *ctx, unsigned char *authz,
|
||||
size_t authz_length)
|
||||
{
|
||||
if (authz == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_CTX_USE_AUTHZ,ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (!ssl_cert_inst(&ctx->cert))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_CTX_USE_AUTHZ,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
return ssl_set_authz(ctx->cert, authz, authz_length);
|
||||
}
|
||||
|
||||
int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
|
||||
size_t serverinfo_length)
|
||||
{
|
||||
@ -1094,106 +1010,7 @@ int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_use_authz(SSL *ssl, unsigned char *authz, size_t authz_length)
|
||||
{
|
||||
if (authz == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_USE_AUTHZ,ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (!ssl_cert_inst(&ssl->cert))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_USE_AUTHZ,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
return ssl_set_authz(ssl->cert, authz, authz_length);
|
||||
}
|
||||
|
||||
const unsigned char *SSL_CTX_get_authz_data(SSL_CTX *ctx, unsigned char type,
|
||||
size_t *data_length)
|
||||
{
|
||||
CERT_PKEY *current_key;
|
||||
|
||||
if (ctx->cert == NULL)
|
||||
return NULL;
|
||||
current_key = ctx->cert->key;
|
||||
if (current_key->authz == NULL)
|
||||
return NULL;
|
||||
return authz_find_data(current_key->authz,
|
||||
current_key->authz_length, type, data_length);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_STDIO
|
||||
/* read_authz returns a newly allocated buffer with authz data */
|
||||
static unsigned char *read_authz(const char *file, size_t *authz_length)
|
||||
{
|
||||
BIO *authz_in = NULL;
|
||||
unsigned char *authz = NULL;
|
||||
/* Allow authzs up to 64KB. */
|
||||
static const size_t authz_limit = 65536;
|
||||
size_t read_length;
|
||||
unsigned char *ret = NULL;
|
||||
|
||||
authz_in = BIO_new(BIO_s_file_internal());
|
||||
if (authz_in == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_READ_AUTHZ,ERR_R_BUF_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (BIO_read_filename(authz_in,file) <= 0)
|
||||
{
|
||||
SSLerr(SSL_F_READ_AUTHZ,ERR_R_SYS_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
authz = OPENSSL_malloc(authz_limit);
|
||||
read_length = BIO_read(authz_in, authz, authz_limit);
|
||||
if (read_length == authz_limit || read_length <= 0)
|
||||
{
|
||||
SSLerr(SSL_F_READ_AUTHZ,SSL_R_AUTHZ_DATA_TOO_LARGE);
|
||||
OPENSSL_free(authz);
|
||||
goto end;
|
||||
}
|
||||
*authz_length = read_length;
|
||||
ret = authz;
|
||||
end:
|
||||
if (authz_in != NULL) BIO_free(authz_in);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SSL_CTX_use_authz_file(SSL_CTX *ctx, const char *file)
|
||||
{
|
||||
unsigned char *authz = NULL;
|
||||
size_t authz_length = 0;
|
||||
int ret;
|
||||
|
||||
authz = read_authz(file, &authz_length);
|
||||
if (authz == NULL)
|
||||
return 0;
|
||||
|
||||
ret = SSL_CTX_use_authz(ctx, authz, authz_length);
|
||||
/* SSL_CTX_use_authz makes a local copy of the authz. */
|
||||
OPENSSL_free(authz);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SSL_use_authz_file(SSL *ssl, const char *file)
|
||||
{
|
||||
unsigned char *authz = NULL;
|
||||
size_t authz_length = 0;
|
||||
int ret;
|
||||
|
||||
authz = read_authz(file, &authz_length);
|
||||
if (authz == NULL)
|
||||
return 0;
|
||||
|
||||
ret = SSL_use_authz(ssl, authz, authz_length);
|
||||
/* SSL_use_authz makes a local copy of the authz. */
|
||||
OPENSSL_free(authz);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
|
||||
{
|
||||
unsigned char *serverinfo = NULL;
|
||||
|
@ -746,8 +746,6 @@ void SSL_SESSION_free(SSL_SESSION *ss)
|
||||
ss->tlsext_ellipticcurvelist_length = 0;
|
||||
if (ss->tlsext_ellipticcurvelist != NULL) OPENSSL_free(ss->tlsext_ellipticcurvelist);
|
||||
#endif /* OPENSSL_NO_EC */
|
||||
if (ss->audit_proof != NULL) OPENSSL_free(ss->audit_proof);
|
||||
ss->audit_proof_length = 0;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
if (ss->psk_identity_hint != NULL)
|
||||
@ -869,15 +867,6 @@ int SSL_SESSION_set1_id_context(SSL_SESSION *s,const unsigned char *sid_ctx,
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
unsigned char *SSL_SESSION_get_tlsext_authz_server_audit_proof(SSL_SESSION *s, size_t *proof_length)
|
||||
{
|
||||
if (s->audit_proof != NULL)
|
||||
*proof_length = s->audit_proof_length;
|
||||
return s->audit_proof;
|
||||
}
|
||||
#endif
|
||||
|
||||
long SSL_CTX_set_timeout(SSL_CTX *s, long t)
|
||||
{
|
||||
long l;
|
||||
|
@ -210,6 +210,14 @@ case SSL3_ST_SR_KEY_EXCH_A: str="SSLv3 read client key exchange A"; break;
|
||||
case SSL3_ST_SR_KEY_EXCH_B: str="SSLv3 read client key exchange B"; break;
|
||||
case SSL3_ST_SR_CERT_VRFY_A: str="SSLv3 read certificate verify A"; break;
|
||||
case SSL3_ST_SR_CERT_VRFY_B: str="SSLv3 read certificate verify B"; break;
|
||||
case SSL3_ST_CW_SUPPLEMENTAL_DATA_A: str="SSLv3 client write supplemental data A"; break;
|
||||
case SSL3_ST_CW_SUPPLEMENTAL_DATA_B: str="SSLv3 client write supplemental data B"; break;
|
||||
case SSL3_ST_SW_SUPPLEMENTAL_DATA_A: str="SSLv3 server write supplemental data A"; break;
|
||||
case SSL3_ST_SW_SUPPLEMENTAL_DATA_B: str="SSLv3 client write supplemental data B"; break;
|
||||
case SSL3_ST_CR_SUPPLEMENTAL_DATA_A: str="SSLv3 client read supplemental data A"; break;
|
||||
case SSL3_ST_CR_SUPPLEMENTAL_DATA_B: str="SSLv3 client read supplemental data B"; break;
|
||||
case SSL3_ST_SR_SUPPLEMENTAL_DATA_A: str="SSLv3 server read supplemental data A"; break;
|
||||
case SSL3_ST_SR_SUPPLEMENTAL_DATA_B: str="SSLv3 client read supplemental data B"; break;
|
||||
#endif
|
||||
|
||||
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
|
||||
|
314
ssl/ssltest.c
314
ssl/ssltest.c
@ -446,6 +446,16 @@ int custom_ext = 0;
|
||||
/* This set based on extension callbacks */
|
||||
int custom_ext_error = 0;
|
||||
|
||||
/* Not IETF assigned supplemental data types */
|
||||
#define CUSTOM_SUPP_DATA_TYPE_0 100
|
||||
#define CUSTOM_SUPP_DATA_TYPE_1 101
|
||||
#define CUSTOM_SUPP_DATA_TYPE_2 102
|
||||
|
||||
const char supp_data_0_string[] = "00000";
|
||||
|
||||
int suppdata = 0;
|
||||
int suppdata_error = 0;
|
||||
|
||||
static int serverinfo_cli_cb(SSL* s, unsigned short ext_type,
|
||||
const unsigned char* in, unsigned short inlen,
|
||||
int* al, void* arg)
|
||||
@ -479,7 +489,7 @@ static int verify_serverinfo()
|
||||
|
||||
static int custom_ext_0_cli_first_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg)
|
||||
unsigned short *outlen, int *al, void *arg)
|
||||
{
|
||||
if (ext_type != CUSTOM_EXT_TYPE_0)
|
||||
custom_ext_error = 1;
|
||||
@ -491,13 +501,12 @@ static int custom_ext_0_cli_second_cb(SSL *s, unsigned short ext_type,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
custom_ext_error = 1; /* Shouldn't be called */
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int custom_ext_1_cli_first_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg)
|
||||
unsigned short *outlen, int *al, void *arg)
|
||||
{
|
||||
if (ext_type != CUSTOM_EXT_TYPE_1)
|
||||
custom_ext_error = 1;
|
||||
@ -511,13 +520,12 @@ static int custom_ext_1_cli_second_cb(SSL *s, unsigned short ext_type,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
custom_ext_error = 1; /* Shouldn't be called */
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int custom_ext_2_cli_first_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg)
|
||||
unsigned short *outlen, int *al, void *arg)
|
||||
{
|
||||
if (ext_type != CUSTOM_EXT_TYPE_2)
|
||||
custom_ext_error = 1;
|
||||
@ -540,7 +548,7 @@ static int custom_ext_2_cli_second_cb(SSL *s, unsigned short ext_type,
|
||||
|
||||
static int custom_ext_3_cli_first_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg)
|
||||
unsigned short *outlen, int *al, void *arg)
|
||||
{
|
||||
if (ext_type != CUSTOM_EXT_TYPE_3)
|
||||
custom_ext_error = 1;
|
||||
@ -563,28 +571,27 @@ static int custom_ext_3_cli_second_cb(SSL *s, unsigned short ext_type,
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* custom_ext_0_cli_first_cb returns -1 - the server won't receive a callback for this extension */
|
||||
static int custom_ext_0_srv_first_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
custom_ext_error = 1;
|
||||
return 0; /* Shouldn't be called */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 'generate' callbacks are always called, even if the 'receive' callback isn't called */
|
||||
static int custom_ext_0_srv_second_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg)
|
||||
unsigned short *outlen, int *al, void *arg)
|
||||
{
|
||||
custom_ext_error = 1;
|
||||
return 0; /* Shouldn't be called */
|
||||
return -1; /* Don't send an extension */
|
||||
}
|
||||
|
||||
static int custom_ext_1_srv_first_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
if (ext_type != CUSTOM_EXT_TYPE_1)
|
||||
custom_ext_error = 1;
|
||||
@ -598,7 +605,7 @@ static int custom_ext_1_srv_first_cb(SSL *s, unsigned short ext_type,
|
||||
|
||||
static int custom_ext_1_srv_second_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg)
|
||||
unsigned short *outlen, int *al, void *arg)
|
||||
{
|
||||
return -1; /* Don't send an extension */
|
||||
}
|
||||
@ -620,7 +627,7 @@ static int custom_ext_2_srv_first_cb(SSL *s, unsigned short ext_type,
|
||||
|
||||
static int custom_ext_2_srv_second_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg)
|
||||
unsigned short *outlen, int *al, void *arg)
|
||||
{
|
||||
*out = NULL;
|
||||
*outlen = 0;
|
||||
@ -644,13 +651,116 @@ static int custom_ext_3_srv_first_cb(SSL *s, unsigned short ext_type,
|
||||
|
||||
static int custom_ext_3_srv_second_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg)
|
||||
unsigned short *outlen, int *al, void *arg)
|
||||
{
|
||||
*out = (const unsigned char*)custom_ext_srv_string;
|
||||
*outlen = strlen(custom_ext_srv_string);
|
||||
return 1; /* Send "defg" */
|
||||
}
|
||||
|
||||
static int supp_data_0_srv_first_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, int *al, void *arg)
|
||||
{
|
||||
*out = (const unsigned char*)supp_data_0_string;
|
||||
*outlen = strlen(supp_data_0_string);
|
||||
if (arg != s)
|
||||
suppdata_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int supp_data_0_srv_second_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
if (supp_data_type != CUSTOM_SUPP_DATA_TYPE_0)
|
||||
suppdata_error = 1;
|
||||
if (inlen != strlen(supp_data_0_string))
|
||||
suppdata_error = 1;
|
||||
if (memcmp(in, supp_data_0_string, inlen) != 0)
|
||||
suppdata_error = 1;
|
||||
if (arg != s)
|
||||
suppdata_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int supp_data_1_srv_first_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, int *al, void *arg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int supp_data_1_srv_second_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
suppdata_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int supp_data_2_srv_second_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
suppdata_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int supp_data_0_cli_first_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
if (supp_data_type != CUSTOM_SUPP_DATA_TYPE_0)
|
||||
suppdata_error = 1;
|
||||
if (inlen != strlen(supp_data_0_string))
|
||||
suppdata_error = 1;
|
||||
if (memcmp(in, supp_data_0_string, inlen) != 0)
|
||||
suppdata_error = 1;
|
||||
if (arg != s)
|
||||
suppdata_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int supp_data_0_cli_second_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, int *al, void *arg)
|
||||
{
|
||||
*out = (const unsigned char*)supp_data_0_string;
|
||||
*outlen = strlen(supp_data_0_string);
|
||||
if (arg != s)
|
||||
suppdata_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int supp_data_1_cli_first_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
suppdata_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int supp_data_1_cli_second_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, int *al, void *arg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int supp_data_2_cli_first_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
suppdata_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *cipher=NULL;
|
||||
static int verbose=0;
|
||||
@ -726,11 +836,6 @@ static void sv_usage(void)
|
||||
" (default is sect163r2).\n");
|
||||
#endif
|
||||
fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
fprintf(stderr," -server_authz arg - binary authz file for certificate\n");
|
||||
fprintf(stderr," -c_support_proof - indicate client support for server_authz audit proofs\n");
|
||||
fprintf(stderr," -c_require_proof - fail if no audit proof is sent\n");
|
||||
#endif
|
||||
fprintf(stderr," -serverinfo_file file - have server use this file\n");
|
||||
fprintf(stderr," -serverinfo_sct - have client offer and expect SCT\n");
|
||||
fprintf(stderr," -serverinfo_tack - have client offer and expect TACK\n");
|
||||
@ -738,6 +843,7 @@ static void sv_usage(void)
|
||||
fprintf(stderr," -alpn_client <string> - have client side offer ALPN\n");
|
||||
fprintf(stderr," -alpn_server <string> - have server side offer ALPN\n");
|
||||
fprintf(stderr," -alpn_expected <string> - the ALPN protocol that should be negotiated\n");
|
||||
fprintf(stderr, "-suppdata - exercise supplemental data callbacks\n");
|
||||
}
|
||||
|
||||
static void print_details(SSL *c_ssl, const char *prefix)
|
||||
@ -867,56 +973,6 @@ int opaque_prf_input_cb(SSL *ssl, void *peerinput, size_t len, void *arg_)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
struct audit_proof_cb_arg_st
|
||||
{
|
||||
unsigned char *expected_proof;
|
||||
size_t expected_proof_length;
|
||||
int require;
|
||||
};
|
||||
|
||||
struct audit_proof_cb_arg_st c_expected = { NULL, 0, 0 };
|
||||
|
||||
static int audit_proof_cb(SSL *s, void *arg)
|
||||
{
|
||||
const unsigned char *proof;
|
||||
size_t proof_len;
|
||||
SSL_SESSION *sess = SSL_get_session(s);
|
||||
struct audit_proof_cb_arg_st *cb_arg = (struct audit_proof_cb_arg_st*)arg;
|
||||
|
||||
proof = SSL_SESSION_get_tlsext_authz_server_audit_proof(sess,
|
||||
&proof_len);
|
||||
if (proof != NULL)
|
||||
{
|
||||
if (proof_len == cb_arg->expected_proof_length &&
|
||||
cb_arg->expected_proof != NULL &&
|
||||
memcmp(proof, cb_arg->expected_proof, proof_len) == 0)
|
||||
{
|
||||
BIO_printf(bio_stdout, "Audit proof OK (%lu bytes).\n",
|
||||
(long)proof_len);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
BIO_printf(bio_stdout, "Audit proof mismatch.\n");
|
||||
/* Cause handshake failure. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
else /* proof == NULL */
|
||||
{
|
||||
BIO_printf(bio_stdout, "No audit proof found.\n");
|
||||
if (cb_arg->require)
|
||||
{
|
||||
/* Cause handshake failure. */
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *CApath=NULL,*CAfile=NULL;
|
||||
@ -968,11 +1024,6 @@ int main(int argc, char *argv[])
|
||||
#ifdef OPENSSL_FIPS
|
||||
int fips_mode=0;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
char *s_authz_file = NULL;
|
||||
int c_support_proof = 0;
|
||||
int c_require_proof = 0;
|
||||
#endif
|
||||
|
||||
verbose = 0;
|
||||
debug = 0;
|
||||
@ -1191,24 +1242,6 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
test_cipherlist = 1;
|
||||
}
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
else if(strcmp(*argv,"-server_authz") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
s_authz_file = *(++argv);
|
||||
tls1 = 1;
|
||||
}
|
||||
else if (strcmp(*argv,"-c_support_proof") == 0)
|
||||
{
|
||||
c_support_proof = 1;
|
||||
tls1 = 1;
|
||||
}
|
||||
else if (strcmp(*argv,"-c_require_proof") == 0)
|
||||
{
|
||||
c_require_proof = 1;
|
||||
tls1 = 1;
|
||||
}
|
||||
#endif
|
||||
else if (strcmp(*argv,"-serverinfo_sct") == 0)
|
||||
{
|
||||
serverinfo_sct = 1;
|
||||
@ -1241,6 +1274,10 @@ int main(int argc, char *argv[])
|
||||
if (--argc < 1) goto bad;
|
||||
alpn_expected = *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-suppdata") == 0)
|
||||
{
|
||||
suppdata = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"unknown option %s\n",*argv);
|
||||
@ -1274,15 +1311,6 @@ bad:
|
||||
"to avoid protocol mismatch.\n");
|
||||
EXIT(1);
|
||||
}
|
||||
if (c_require_proof && s_authz_file == NULL && !force)
|
||||
{
|
||||
fprintf(stderr, "This case cannot work. -c_require_proof "
|
||||
"requires an audit proof, but none was supplied. "
|
||||
"Use -f to perform the test anyway (and\n-d to see "
|
||||
"what happens), or use -server_authz to supply an "
|
||||
"audit proof.\n");
|
||||
EXIT(1);
|
||||
}
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
if(fips_mode)
|
||||
@ -1554,34 +1582,6 @@ bad:
|
||||
SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb);
|
||||
}
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s_authz_file != NULL)
|
||||
{
|
||||
if(!SSL_CTX_use_authz_file(s_ctx, s_authz_file))
|
||||
{
|
||||
BIO_printf(bio_err, "Unable to set authz data\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (c_support_proof || c_require_proof)
|
||||
{
|
||||
size_t proof_length;
|
||||
const unsigned char *proof = SSL_CTX_get_authz_data(s_ctx,
|
||||
TLSEXT_AUTHZDATAFORMAT_audit_proof, &proof_length);
|
||||
if (proof != NULL)
|
||||
{
|
||||
/* Store a local copy. */
|
||||
c_expected.expected_proof = OPENSSL_malloc(proof_length);
|
||||
c_expected.expected_proof_length = proof_length;
|
||||
memcpy(c_expected.expected_proof, proof, proof_length);
|
||||
}
|
||||
c_expected.require = c_require_proof;
|
||||
SSL_CTX_set_tlsext_authz_server_audit_proof_cb(c_ctx,
|
||||
audit_proof_cb);
|
||||
SSL_CTX_set_tlsext_authz_server_audit_proof_cb_arg(c_ctx,
|
||||
&c_expected);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (serverinfo_sct)
|
||||
SSL_CTX_set_custom_cli_ext(c_ctx, SCT_EXT_TYPE, NULL,
|
||||
@ -1647,6 +1647,40 @@ bad:
|
||||
c_ssl=SSL_new(c_ctx);
|
||||
s_ssl=SSL_new(s_ctx);
|
||||
|
||||
if (suppdata)
|
||||
{
|
||||
/* TEST CASES */
|
||||
/* client and server both send and receive, verify
|
||||
* additional arg passed back */
|
||||
SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_0,
|
||||
supp_data_0_srv_first_cb,
|
||||
supp_data_0_srv_second_cb, s_ssl);
|
||||
SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_0,
|
||||
supp_data_0_cli_first_cb,
|
||||
supp_data_0_cli_second_cb, c_ssl);
|
||||
|
||||
/* -1 response from sending server/client doesn't
|
||||
* receive, -1 response from sending client/server
|
||||
* doesn't receive */
|
||||
SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_1,
|
||||
supp_data_1_srv_first_cb,
|
||||
supp_data_1_srv_second_cb, NULL);
|
||||
SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_1,
|
||||
supp_data_1_cli_first_cb,
|
||||
supp_data_1_cli_second_cb, NULL);
|
||||
|
||||
/* null sending server/client doesn't receive, null
|
||||
sending client/server doesn't receive */
|
||||
SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_2,
|
||||
/*supp_data_2_srv_first_cb*/NULL,
|
||||
supp_data_2_srv_second_cb, NULL);
|
||||
SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_2,
|
||||
supp_data_2_cli_first_cb,
|
||||
/*supp_data_2_cli_second_cb*/NULL,
|
||||
NULL);
|
||||
|
||||
/* alerts set to non-zero and zero return values not tested */
|
||||
}
|
||||
#ifndef OPENSSL_NO_KRB5
|
||||
if (c_ssl && c_ssl->kssl_ctx)
|
||||
{
|
||||
@ -1717,10 +1751,6 @@ end:
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_cleanup();
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (c_expected.expected_proof != NULL)
|
||||
OPENSSL_free(c_expected.expected_proof);
|
||||
#endif
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
ERR_free_strings();
|
||||
@ -2411,7 +2441,11 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count)
|
||||
|
||||
if (verbose)
|
||||
print_details(c_ssl, "DONE: ");
|
||||
|
||||
if (suppdata_error < 0)
|
||||
{
|
||||
ret = 1;
|
||||
goto err;
|
||||
}
|
||||
if (verify_serverinfo() < 0)
|
||||
{
|
||||
ret = 1;
|
||||
|
308
ssl/t1_lib.c
308
ssl/t1_lib.c
@ -1089,20 +1089,7 @@ void ssl_set_client_disabled(SSL *s)
|
||||
c->valid = 1;
|
||||
}
|
||||
|
||||
/* byte_compare is a compare function for qsort(3) that compares bytes. */
|
||||
static int byte_compare(const void *in_a, const void *in_b)
|
||||
{
|
||||
unsigned char a = *((const unsigned char*) in_a);
|
||||
unsigned char b = *((const unsigned char*) in_b);
|
||||
|
||||
if (a > b)
|
||||
return 1;
|
||||
else if (a < b)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
|
||||
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al)
|
||||
{
|
||||
int extdatalen=0;
|
||||
unsigned char *ret = p;
|
||||
@ -1448,26 +1435,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
||||
ret += el;
|
||||
}
|
||||
|
||||
/* Add TLS extension Server_Authz_DataFormats to the ClientHello */
|
||||
/* 2 bytes for extension type */
|
||||
/* 2 bytes for extension length */
|
||||
/* 1 byte for the list length */
|
||||
/* 1 byte for the list (we only support audit proofs) */
|
||||
if (s->ctx->tlsext_authz_server_audit_proof_cb != NULL)
|
||||
{
|
||||
const unsigned short ext_len = 2;
|
||||
const unsigned char list_len = 1;
|
||||
|
||||
if (limit < ret + 6)
|
||||
return NULL;
|
||||
|
||||
s2n(TLSEXT_TYPE_server_authz, ret);
|
||||
/* Extension length: 2 bytes */
|
||||
s2n(ext_len, ret);
|
||||
*(ret++) = list_len;
|
||||
*(ret++) = TLSEXT_AUTHZDATAFORMAT_audit_proof;
|
||||
}
|
||||
|
||||
/* Add custom TLS Extensions to ClientHello */
|
||||
if (s->ctx->custom_cli_ext_records_count)
|
||||
{
|
||||
@ -1486,7 +1453,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
||||
{
|
||||
int cb_retval = 0;
|
||||
cb_retval = record->fn1(s, record->ext_type,
|
||||
&out, &outlen,
|
||||
&out, &outlen, al,
|
||||
record->arg);
|
||||
if (cb_retval == 0)
|
||||
return NULL; /* error */
|
||||
@ -1539,10 +1506,12 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
|
||||
unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al)
|
||||
{
|
||||
int extdatalen=0;
|
||||
unsigned char *ret = p;
|
||||
size_t i;
|
||||
custom_srv_ext_record *record;
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
int next_proto_neg_seen;
|
||||
#endif
|
||||
@ -1726,118 +1695,30 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If the client supports authz then see whether we have any to offer
|
||||
* to it. */
|
||||
if (s->s3->tlsext_authz_client_types_len)
|
||||
for (i = 0; i < s->ctx->custom_srv_ext_records_count; i++)
|
||||
{
|
||||
size_t authz_length;
|
||||
/* By now we already know the new cipher, so we can look ahead
|
||||
* to see whether the cert we are going to send
|
||||
* has any authz data attached to it. */
|
||||
const unsigned char* authz = ssl_get_authz_data(s, &authz_length);
|
||||
const unsigned char* const orig_authz = authz;
|
||||
size_t i;
|
||||
unsigned authz_count = 0;
|
||||
const unsigned char *out = NULL;
|
||||
unsigned short outlen = 0;
|
||||
int cb_retval = 0;
|
||||
|
||||
/* The authz data contains a number of the following structures:
|
||||
* uint8_t authz_type
|
||||
* uint16_t length
|
||||
* uint8_t data[length]
|
||||
*
|
||||
* First we walk over it to find the number of authz elements. */
|
||||
for (i = 0; i < authz_length; i++)
|
||||
{
|
||||
unsigned short length;
|
||||
unsigned char type;
|
||||
record = &s->ctx->custom_srv_ext_records[i];
|
||||
|
||||
type = *(authz++);
|
||||
if (memchr(s->s3->tlsext_authz_client_types,
|
||||
type,
|
||||
s->s3->tlsext_authz_client_types_len) != NULL)
|
||||
authz_count++;
|
||||
|
||||
n2s(authz, length);
|
||||
/* n2s increments authz by 2 */
|
||||
i += 2;
|
||||
authz += length;
|
||||
i += length;
|
||||
}
|
||||
|
||||
if (authz_count)
|
||||
{
|
||||
/* Add TLS extension server_authz to the ServerHello message
|
||||
* 2 bytes for extension type
|
||||
* 2 bytes for extension length
|
||||
* 1 byte for the list length
|
||||
* n bytes for the list */
|
||||
const unsigned short ext_len = 1 + authz_count;
|
||||
|
||||
if ((long)(limit - ret - 4 - ext_len) < 0) return NULL;
|
||||
s2n(TLSEXT_TYPE_server_authz, ret);
|
||||
s2n(ext_len, ret);
|
||||
*(ret++) = authz_count;
|
||||
s->s3->tlsext_authz_promised_to_client = 1;
|
||||
}
|
||||
|
||||
authz = orig_authz;
|
||||
for (i = 0; i < authz_length; i++)
|
||||
{
|
||||
unsigned short length;
|
||||
unsigned char type;
|
||||
|
||||
authz_count++;
|
||||
type = *(authz++);
|
||||
if (memchr(s->s3->tlsext_authz_client_types,
|
||||
type,
|
||||
s->s3->tlsext_authz_client_types_len) != NULL)
|
||||
*(ret++) = type;
|
||||
n2s(authz, length);
|
||||
/* n2s increments authz by 2 */
|
||||
i += 2;
|
||||
authz += length;
|
||||
i += length;
|
||||
}
|
||||
}
|
||||
|
||||
/* If custom types were sent in ClientHello, add ServerHello responses */
|
||||
if (s->s3->tlsext_custom_types_count)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < s->s3->tlsext_custom_types_count; i++)
|
||||
{
|
||||
size_t j;
|
||||
custom_srv_ext_record *record;
|
||||
|
||||
for (j = 0; j < s->ctx->custom_srv_ext_records_count; j++)
|
||||
{
|
||||
record = &s->ctx->custom_srv_ext_records[j];
|
||||
if (s->s3->tlsext_custom_types[i] == record->ext_type)
|
||||
{
|
||||
const unsigned char *out = NULL;
|
||||
unsigned short outlen = 0;
|
||||
int cb_retval = 0;
|
||||
|
||||
/* NULL callback or -1 omits extension */
|
||||
if (!record->fn2)
|
||||
break;
|
||||
cb_retval = record->fn2(s, record->ext_type,
|
||||
&out, &outlen,
|
||||
record->arg);
|
||||
if (cb_retval == 0)
|
||||
return NULL; /* error */
|
||||
if (cb_retval == -1)
|
||||
break; /* skip this extension */
|
||||
if (limit < ret + 4 + outlen)
|
||||
return NULL;
|
||||
s2n(record->ext_type, ret);
|
||||
s2n(outlen, ret);
|
||||
memcpy(ret, out, outlen);
|
||||
ret += outlen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* NULL callback or -1 omits extension */
|
||||
if (!record->fn2)
|
||||
continue;
|
||||
cb_retval = record->fn2(s, record->ext_type,
|
||||
&out, &outlen, al,
|
||||
record->arg);
|
||||
if (cb_retval == 0)
|
||||
return NULL; /* error */
|
||||
if (cb_retval == -1)
|
||||
continue; /* skip this extension */
|
||||
if (limit < ret + 4 + outlen)
|
||||
return NULL;
|
||||
s2n(record->ext_type, ret);
|
||||
s2n(outlen, ret);
|
||||
memcpy(ret, out, outlen);
|
||||
ret += outlen;
|
||||
}
|
||||
|
||||
if (s->s3->alpn_selected)
|
||||
@ -2031,12 +1912,12 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
|
||||
#endif
|
||||
|
||||
/* Clear observed custom extensions */
|
||||
s->s3->tlsext_custom_types_count = 0;
|
||||
if (s->s3->tlsext_custom_types != NULL)
|
||||
s->s3->serverinfo_client_tlsext_custom_types_count = 0;
|
||||
if (s->s3->serverinfo_client_tlsext_custom_types != NULL)
|
||||
{
|
||||
OPENSSL_free(s->s3->tlsext_custom_types);
|
||||
s->s3->tlsext_custom_types = NULL;
|
||||
}
|
||||
OPENSSL_free(s->s3->serverinfo_client_tlsext_custom_types);
|
||||
s->s3->serverinfo_client_tlsext_custom_types = NULL;
|
||||
}
|
||||
|
||||
if (s->s3->alpn_selected)
|
||||
{
|
||||
@ -2545,66 +2426,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
|
||||
al))
|
||||
return 0;
|
||||
}
|
||||
|
||||
else if (type == TLSEXT_TYPE_server_authz)
|
||||
{
|
||||
unsigned char *sdata = data;
|
||||
unsigned char server_authz_dataformatlist_length;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
*al = TLS1_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
server_authz_dataformatlist_length = *(sdata++);
|
||||
|
||||
if (server_authz_dataformatlist_length != size - 1)
|
||||
{
|
||||
*al = TLS1_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Successful session resumption uses the same authz
|
||||
* information as the original session so we ignore this
|
||||
* in the case of a session resumption. */
|
||||
if (!s->hit)
|
||||
{
|
||||
if (s->s3->tlsext_authz_client_types != NULL)
|
||||
OPENSSL_free(s->s3->tlsext_authz_client_types);
|
||||
s->s3->tlsext_authz_client_types =
|
||||
OPENSSL_malloc(server_authz_dataformatlist_length);
|
||||
if (!s->s3->tlsext_authz_client_types)
|
||||
{
|
||||
*al = TLS1_AD_INTERNAL_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s->s3->tlsext_authz_client_types_len =
|
||||
server_authz_dataformatlist_length;
|
||||
memcpy(s->s3->tlsext_authz_client_types,
|
||||
sdata,
|
||||
server_authz_dataformatlist_length);
|
||||
|
||||
/* Sort the types in order to check for duplicates. */
|
||||
qsort(s->s3->tlsext_authz_client_types,
|
||||
server_authz_dataformatlist_length,
|
||||
1 /* element size */,
|
||||
byte_compare);
|
||||
|
||||
for (i = 0; i < server_authz_dataformatlist_length; i++)
|
||||
{
|
||||
if (i > 0 &&
|
||||
s->s3->tlsext_authz_client_types[i] ==
|
||||
s->s3->tlsext_authz_client_types[i-1])
|
||||
{
|
||||
*al = TLS1_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If this ClientHello extension was unhandled and this is
|
||||
* a nonresumed connection, check whether the extension is a
|
||||
* custom TLS Extension (has a custom_srv_ext_record), and if
|
||||
@ -2620,35 +2441,8 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
|
||||
record = &s->ctx->custom_srv_ext_records[i];
|
||||
if (type == record->ext_type)
|
||||
{
|
||||
size_t j;
|
||||
|
||||
/* Error on duplicate TLS Extensions */
|
||||
for (j = 0; j < s->s3->tlsext_custom_types_count; j++)
|
||||
{
|
||||
if (type == s->s3->tlsext_custom_types[j])
|
||||
{
|
||||
*al = TLS1_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* NULL callback still notes the extension */
|
||||
if (record->fn1 && !record->fn1(s, type, data, size, al, record->arg))
|
||||
return 0;
|
||||
|
||||
/* Add the (non-duplicated) entry */
|
||||
s->s3->tlsext_custom_types_count++;
|
||||
s->s3->tlsext_custom_types = OPENSSL_realloc(
|
||||
s->s3->tlsext_custom_types,
|
||||
s->s3->tlsext_custom_types_count * 2);
|
||||
if (s->s3->tlsext_custom_types == NULL)
|
||||
{
|
||||
s->s3->tlsext_custom_types = 0;
|
||||
*al = TLS1_AD_INTERNAL_ERROR;
|
||||
return 0;
|
||||
}
|
||||
s->s3->tlsext_custom_types[
|
||||
s->s3->tlsext_custom_types_count - 1] = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2970,46 +2764,6 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char
|
||||
al))
|
||||
return 0;
|
||||
}
|
||||
|
||||
else if (type == TLSEXT_TYPE_server_authz)
|
||||
{
|
||||
/* We only support audit proofs. It's an error to send
|
||||
* an authz hello extension if the client
|
||||
* didn't request a proof. */
|
||||
unsigned char *sdata = data;
|
||||
unsigned char server_authz_dataformatlist_length;
|
||||
|
||||
if (!s->ctx->tlsext_authz_server_audit_proof_cb)
|
||||
{
|
||||
*al = TLS1_AD_UNSUPPORTED_EXTENSION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!size)
|
||||
{
|
||||
*al = TLS1_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
server_authz_dataformatlist_length = *(sdata++);
|
||||
if (server_authz_dataformatlist_length != size - 1)
|
||||
{
|
||||
*al = TLS1_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We only support audit proofs, so a legal ServerHello
|
||||
* authz list contains exactly one entry. */
|
||||
if (server_authz_dataformatlist_length != 1 ||
|
||||
sdata[0] != TLSEXT_AUTHZDATAFORMAT_audit_proof)
|
||||
{
|
||||
*al = TLS1_AD_UNSUPPORTED_EXTENSION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s->s3->tlsext_authz_server_promised = 1;
|
||||
}
|
||||
|
||||
/* If this extension type was not otherwise handled, but
|
||||
* matches a custom_cli_ext_record, then send it to the c
|
||||
* callback */
|
||||
|
16
ssl/tls1.h
16
ssl/tls1.h
@ -299,9 +299,12 @@ extern "C" {
|
||||
|
||||
/* From RFC 5878 */
|
||||
#define TLSEXT_SUPPLEMENTALDATATYPE_authz_data 16386
|
||||
/* This is not IANA assigned. See
|
||||
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#authorization-data-rules */
|
||||
#define TLSEXT_AUTHZDATAFORMAT_audit_proof 182
|
||||
|
||||
/* DTCP Authorization Type
|
||||
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#authorization-data-rules
|
||||
* http://tools.ietf.org/id/draft-dthakore-tls-authz-04.txt
|
||||
*/
|
||||
#define TLSEXT_AUTHZDATAFORMAT_dtcp 66
|
||||
|
||||
#define TLSEXT_MAXLEN_supplemental_data 1024*16 /* Let's limit to 16k */
|
||||
|
||||
@ -390,13 +393,6 @@ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg)
|
||||
#define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
|
||||
SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
|
||||
|
||||
/* Used by clients to process audit proofs. */
|
||||
#define SSL_CTX_set_tlsext_authz_server_audit_proof_cb(ctx, cb) \
|
||||
SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB,(void (*)(void))cb)
|
||||
|
||||
#define SSL_CTX_set_tlsext_authz_server_audit_proof_cb_arg(ctx, arg) \
|
||||
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG, 0, arg);
|
||||
|
||||
#ifndef OPENSSL_NO_HEARTBEATS
|
||||
#define SSL_TLSEXT_HB_ENABLED 0x01
|
||||
#define SSL_TLSEXT_HB_DONT_SEND_REQUESTS 0x02
|
||||
|
Loading…
x
Reference in New Issue
Block a user