Add callbacks supporting generation and retrieval of supplemental data entries, facilitating RFC 5878 (TLS auth extensions)
Removed prior audit proof logic - audit proof support was implemented using the generic TLS extension API Tests exercising the new supplemental data registration and callback api can be found in ssltest.c. Implemented changes to s_server and s_client to exercise supplemental data callbacks via the -auth argument, as well as additional flags to exercise supplemental data being sent only during renegotiation. (cherry picked from commit 36086186a9b90cdad0d2cd0a598a10f03f8f4bcc) Conflicts: Configure apps/s_client.c apps/s_server.c ssl/ssl.h ssl/ssl3.h ssl/ssltest.c
This commit is contained in:
parent
f407eec799
commit
038bec784e
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 <EFBFBD> 1998-2005 The OpenSSL Project. Copyright <20> 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);
|
||||
|
@ -876,6 +876,9 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *
|
||||
case 16:
|
||||
str_details1 = ", ClientKeyExchange";
|
||||
break;
|
||||
case 23:
|
||||
str_details1 = ", SupplementalData";
|
||||
break;
|
||||
case 20:
|
||||
str_details1 = ", Finished";
|
||||
break;
|
||||
|
137
apps/s_client.c
137
apps/s_client.c
@ -203,7 +203,6 @@ static int c_debug=0;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
static int c_tlsextdebug=0;
|
||||
static int c_status_req=0;
|
||||
static int c_proof_debug=0;
|
||||
#endif
|
||||
static int c_msg=0;
|
||||
static int c_showcerts=0;
|
||||
@ -215,7 +214,8 @@ static void sc_usage(void);
|
||||
static void print_stuff(BIO *berr,SSL *con,int full);
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
static int ocsp_resp_cb(SSL *s, void *arg);
|
||||
static int audit_proof_cb(SSL *s, void *arg);
|
||||
static int c_auth = 0;
|
||||
static int c_auth_require_reneg = 0;
|
||||
#endif
|
||||
static BIO *bio_c_out=NULL;
|
||||
static BIO *bio_c_msg=NULL;
|
||||
@ -223,6 +223,35 @@ static int c_quiet=0;
|
||||
static int c_ign_eof=0;
|
||||
static int c_brief=0;
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
|
||||
static const unsigned char *most_recent_supplemental_data;
|
||||
static size_t most_recent_supplemental_data_length;
|
||||
|
||||
static int server_provided_server_authz = 0;
|
||||
static int server_provided_client_authz = 0;
|
||||
|
||||
static const unsigned char auth_ext_data[]={TLSEXT_AUTHZDATAFORMAT_dtcp};
|
||||
|
||||
static int suppdata_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg);
|
||||
|
||||
static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg);
|
||||
|
||||
static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out, unsigned short *outlen,
|
||||
void *arg);
|
||||
|
||||
static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg);
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
/* Default PSK identity and key */
|
||||
static char *psk_identity="Client_identity";
|
||||
@ -365,15 +394,14 @@ static void sc_usage(void)
|
||||
BIO_printf(bio_err," -tlsextdebug - hex dump of all TLS extensions received\n");
|
||||
BIO_printf(bio_err," -status - request certificate status from server\n");
|
||||
BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n");
|
||||
BIO_printf(bio_err," -proof_debug - request an audit proof and print its hex dump\n");
|
||||
BIO_printf(bio_err," -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n");
|
||||
BIO_printf(bio_err," -auth - send and receive RFC 5878 TLS auth extensions and supplemental data\n");
|
||||
BIO_printf(bio_err," -auth_require_reneg - Do not send TLS auth extensions until renegotiation\n");
|
||||
#endif
|
||||
# ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
|
||||
# endif
|
||||
BIO_printf(bio_err," -alpn arg - enable ALPN extension, considering named protocols supported (comma-separated list)\n");
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
BIO_printf(bio_err," -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n");
|
||||
#endif
|
||||
#endif
|
||||
BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
|
||||
BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
|
||||
BIO_printf(bio_err," -keymatexport label - Export keying material using label\n");
|
||||
@ -822,8 +850,10 @@ static char *jpake_secret = NULL;
|
||||
c_tlsextdebug=1;
|
||||
else if (strcmp(*argv,"-status") == 0)
|
||||
c_status_req=1;
|
||||
else if (strcmp(*argv,"-proof_debug") == 0)
|
||||
c_proof_debug=1;
|
||||
else if (strcmp(*argv,"-auth") == 0)
|
||||
c_auth = 1;
|
||||
else if (strcmp(*argv,"-auth_require_reneg") == 0)
|
||||
c_auth_require_reneg = 1;
|
||||
#endif
|
||||
#ifdef WATT32
|
||||
else if (strcmp(*argv,"-wdebug") == 0)
|
||||
@ -1397,9 +1427,12 @@ bad:
|
||||
}
|
||||
|
||||
#endif
|
||||
if (c_proof_debug)
|
||||
SSL_CTX_set_tlsext_authz_server_audit_proof_cb(ctx,
|
||||
audit_proof_cb);
|
||||
if (c_auth)
|
||||
{
|
||||
SSL_CTX_set_custom_cli_ext(ctx, TLSEXT_TYPE_client_authz, authz_tlsext_generate_cb, authz_tlsext_cb, bio_err);
|
||||
SSL_CTX_set_custom_cli_ext(ctx, TLSEXT_TYPE_server_authz, authz_tlsext_generate_cb, authz_tlsext_cb, bio_err);
|
||||
SSL_CTX_set_cli_supp_data(ctx, TLSEXT_SUPPLEMENTALDATATYPE_authz_data, suppdata_cb, auth_suppdata_generate_cb, bio_err);
|
||||
}
|
||||
#endif
|
||||
|
||||
con=SSL_new(ctx);
|
||||
@ -2392,26 +2425,76 @@ static int ocsp_resp_cb(SSL *s, void *arg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int audit_proof_cb(SSL *s, void *arg)
|
||||
static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
const unsigned char *proof;
|
||||
size_t proof_len;
|
||||
size_t i;
|
||||
SSL_SESSION *sess = SSL_get_session(s);
|
||||
|
||||
proof = SSL_SESSION_get_tlsext_authz_server_audit_proof(sess,
|
||||
&proof_len);
|
||||
if (proof != NULL)
|
||||
if (TLSEXT_TYPE_server_authz == ext_type)
|
||||
{
|
||||
BIO_printf(bio_c_out, "Audit proof: ");
|
||||
for (i = 0; i < proof_len; ++i)
|
||||
BIO_printf(bio_c_out, "%02X", proof[i]);
|
||||
BIO_printf(bio_c_out, "\n");
|
||||
server_provided_server_authz = (memchr(in,
|
||||
TLSEXT_AUTHZDATAFORMAT_dtcp,
|
||||
inlen) != NULL);
|
||||
}
|
||||
else
|
||||
|
||||
if (TLSEXT_TYPE_client_authz == ext_type)
|
||||
{
|
||||
BIO_printf(bio_c_out, "No audit proof found.\n");
|
||||
server_provided_client_authz = (memchr(in,
|
||||
TLSEXT_AUTHZDATAFORMAT_dtcp,
|
||||
inlen) != NULL);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out, unsigned short *outlen,
|
||||
void *arg)
|
||||
{
|
||||
if (c_auth)
|
||||
{
|
||||
if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s)))
|
||||
{
|
||||
*out = auth_ext_data;
|
||||
*outlen = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
//no auth extension to send
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int suppdata_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
if (supp_data_type == TLSEXT_SUPPLEMENTALDATATYPE_authz_data)
|
||||
{
|
||||
most_recent_supplemental_data = in;
|
||||
most_recent_supplemental_data_length = inlen;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg)
|
||||
{
|
||||
unsigned char *result;
|
||||
if (c_auth && server_provided_client_authz && server_provided_server_authz)
|
||||
{
|
||||
if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s)))
|
||||
{
|
||||
result = OPENSSL_malloc(10);
|
||||
memcpy(result, "5432154321", 10);
|
||||
*out = result;
|
||||
*outlen = 10;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
//no supplemental data to send
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
146
apps/s_server.c
146
apps/s_server.c
@ -224,6 +224,18 @@ static DH *get_dh512(void);
|
||||
static void s_server_init(void);
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
|
||||
static const unsigned char auth_ext_data[]={TLSEXT_AUTHZDATAFORMAT_dtcp};
|
||||
|
||||
static const unsigned char *most_recent_supplemental_data;
|
||||
static size_t most_recent_supplemental_data_length;
|
||||
|
||||
static int client_provided_server_authz = 0;
|
||||
static int client_provided_client_authz = 0;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_DH
|
||||
static unsigned char dh512_p[]={
|
||||
0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
|
||||
@ -315,10 +327,29 @@ static int cert_chain = 0;
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
static BIO *authz_in = NULL;
|
||||
static const char *s_authz_file = NULL;
|
||||
static int suppdata_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg);
|
||||
|
||||
static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg);
|
||||
|
||||
static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out, unsigned short *outlen,
|
||||
void *arg);
|
||||
|
||||
static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg);
|
||||
|
||||
static BIO *serverinfo_in = NULL;
|
||||
static const char *s_serverinfo_file = NULL;
|
||||
|
||||
static int c_auth = 0;
|
||||
static int c_auth_require_reneg = 0;
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
@ -482,10 +513,12 @@ static void sv_usage(void)
|
||||
BIO_printf(bio_err," -Verify arg - turn on peer certificate verification, must have a cert.\n");
|
||||
BIO_printf(bio_err," -cert arg - certificate file to use\n");
|
||||
BIO_printf(bio_err," (default is %s)\n",TEST_CERT);
|
||||
BIO_printf(bio_err," -authz arg - binary authz file for certificate\n");
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
BIO_printf(bio_err," -serverinfo arg - PEM serverinfo file for certificate\n");
|
||||
BIO_printf(bio_err," -auth - send and receive RFC 5878 TLS auth extensions and supplemental data\n");
|
||||
BIO_printf(bio_err," -auth_require_reneg - Do not send TLS auth extensions until renegotiation\n");
|
||||
#endif
|
||||
BIO_printf(bio_err," -no_resumption_on_reneg - set SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION flag\n");
|
||||
BIO_printf(bio_err," -crl_check - check the peer certificate has not been revoked by its CA.\n" \
|
||||
" The CRL(s) are appended to the certificate file\n");
|
||||
BIO_printf(bio_err," -crl_check_all - check the peer certificate has not been revoked by its CA\n" \
|
||||
@ -1018,6 +1051,7 @@ int MAIN(int argc, char *argv[])
|
||||
EVP_PKEY *s_key = NULL, *s_dkey = NULL;
|
||||
int no_cache = 0, ext_cache = 0;
|
||||
int rev = 0, naccept = -1;
|
||||
int c_no_resumption_on_reneg = 0;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
EVP_PKEY *s_key2 = NULL;
|
||||
X509 *s_cert2 = NULL;
|
||||
@ -1132,17 +1166,24 @@ int MAIN(int argc, char *argv[])
|
||||
else if (strcmp(*argv,"-crl_download") == 0)
|
||||
crl_download = 1;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
else if (strcmp(*argv,"-authz") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
s_authz_file = *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-serverinfo") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
s_serverinfo_file = *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-auth") == 0)
|
||||
{
|
||||
c_auth = 1;
|
||||
}
|
||||
#endif
|
||||
else if (strcmp(*argv, "-no_resumption_on_reneg") == 0)
|
||||
{
|
||||
c_no_resumption_on_reneg = 1;
|
||||
}
|
||||
else if (strcmp(*argv,"-auth_require_reneg") == 0)
|
||||
{
|
||||
c_auth_require_reneg = 1;
|
||||
}
|
||||
else if (strcmp(*argv,"-certform") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
@ -1918,17 +1959,25 @@ bad:
|
||||
}
|
||||
#endif
|
||||
|
||||
if (c_no_resumption_on_reneg)
|
||||
{
|
||||
SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
||||
}
|
||||
if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain))
|
||||
goto end;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s_authz_file != NULL && !SSL_CTX_use_authz_file(ctx, s_authz_file))
|
||||
goto end;
|
||||
if (s_serverinfo_file != NULL
|
||||
&& !SSL_CTX_use_serverinfo_file(ctx, s_serverinfo_file))
|
||||
{
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (c_auth)
|
||||
{
|
||||
SSL_CTX_set_custom_srv_ext(ctx, TLSEXT_TYPE_client_authz, authz_tlsext_cb, authz_tlsext_generate_cb, bio_err);
|
||||
SSL_CTX_set_custom_srv_ext(ctx, TLSEXT_TYPE_server_authz, authz_tlsext_cb, authz_tlsext_generate_cb, bio_err);
|
||||
SSL_CTX_set_srv_supp_data(ctx, TLSEXT_SUPPLEMENTALDATATYPE_authz_data, auth_suppdata_generate_cb, suppdata_cb, bio_err);
|
||||
}
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2, NULL, build_chain))
|
||||
@ -2097,8 +2146,6 @@ end:
|
||||
X509_free(s_cert2);
|
||||
if (s_key2)
|
||||
EVP_PKEY_free(s_key2);
|
||||
if (authz_in != NULL)
|
||||
BIO_free(authz_in);
|
||||
if (serverinfo_in != NULL)
|
||||
BIO_free(serverinfo_in);
|
||||
# ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
@ -3494,3 +3541,78 @@ static void free_sessions(void)
|
||||
}
|
||||
first = NULL;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
if (TLSEXT_TYPE_server_authz == ext_type)
|
||||
{
|
||||
client_provided_server_authz = (memchr(in,
|
||||
TLSEXT_AUTHZDATAFORMAT_dtcp,
|
||||
inlen) != NULL);
|
||||
}
|
||||
|
||||
if (TLSEXT_TYPE_client_authz == ext_type)
|
||||
{
|
||||
client_provided_client_authz = (memchr(in,
|
||||
TLSEXT_AUTHZDATAFORMAT_dtcp,
|
||||
inlen) != NULL);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
|
||||
const unsigned char **out, unsigned short *outlen,
|
||||
void *arg)
|
||||
{
|
||||
if (c_auth && client_provided_client_authz && client_provided_server_authz)
|
||||
{
|
||||
if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s)))
|
||||
{
|
||||
*out = auth_ext_data;
|
||||
*outlen = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
//no auth extension to send
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int suppdata_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
if (supp_data_type == TLSEXT_SUPPLEMENTALDATATYPE_authz_data)
|
||||
{
|
||||
most_recent_supplemental_data = in;
|
||||
most_recent_supplemental_data_length = inlen;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg)
|
||||
{
|
||||
unsigned char *result;
|
||||
if (c_auth && client_provided_client_authz && client_provided_server_authz)
|
||||
{
|
||||
if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s)))
|
||||
{
|
||||
result = OPENSSL_malloc(10);
|
||||
memcpy(result, "1234512345", 10);
|
||||
*out = result;
|
||||
*outlen = 10;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
//no supplemental data to send
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -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
|
||||
|
@ -362,10 +362,10 @@ static int ssl23_client_hello(SSL *s)
|
||||
if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL)
|
||||
ssl2_compat = 0;
|
||||
#endif
|
||||
if (s->ctx->tlsext_authz_server_audit_proof_cb != NULL)
|
||||
ssl2_compat = 0;
|
||||
if (s->ctx->custom_cli_ext_records_count != 0)
|
||||
ssl2_compat = 0;
|
||||
if (s->ctx->cli_supp_data_records_count != 0)
|
||||
ssl2_compat = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
239
ssl/s3_clnt.c
239
ssl/s3_clnt.c
@ -307,13 +307,6 @@ int ssl3_connect(SSL *s)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
/* The server hello indicated that
|
||||
* an audit proof would follow. */
|
||||
if (s->s3->tlsext_authz_server_promised)
|
||||
s->state=SSL3_ST_CR_SUPPLEMENTAL_DATA_A;
|
||||
else
|
||||
#endif
|
||||
s->state=SSL3_ST_CR_CERT_A;
|
||||
}
|
||||
s->init_num=0;
|
||||
@ -332,6 +325,12 @@ int ssl3_connect(SSL *s)
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
ret=ssl3_check_finished(s);
|
||||
if (ret <= 0) goto end;
|
||||
if (ret == 3)
|
||||
{
|
||||
s->state=SSL3_ST_CR_SUPPLEMENTAL_DATA_A;
|
||||
s->init_num=0;
|
||||
break;
|
||||
}
|
||||
if (ret == 2)
|
||||
{
|
||||
s->hit = 1;
|
||||
@ -410,10 +409,14 @@ int ssl3_connect(SSL *s)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
s->state=SSL3_ST_CW_SUPPLEMENTAL_DATA_A;
|
||||
#else
|
||||
if (s->s3->tmp.cert_req)
|
||||
s->state=SSL3_ST_CW_CERT_A;
|
||||
else
|
||||
s->state=SSL3_ST_CW_KEY_EXCH_A;
|
||||
#endif
|
||||
s->init_num=0;
|
||||
|
||||
break;
|
||||
@ -520,6 +523,19 @@ int ssl3_connect(SSL *s)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
case SSL3_ST_CW_SUPPLEMENTAL_DATA_A:
|
||||
case SSL3_ST_CW_SUPPLEMENTAL_DATA_B:
|
||||
ret = tls1_send_client_supplemental_data(s, &skip);
|
||||
if (ret <= 0) goto end;
|
||||
if (s->s3->tmp.cert_req)
|
||||
s->state=SSL3_ST_CW_CERT_A;
|
||||
else
|
||||
s->state=SSL3_ST_CW_KEY_EXCH_A;
|
||||
s->init_num=0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SSL3_ST_CW_FINISHED_A:
|
||||
case SSL3_ST_CW_FINISHED_B:
|
||||
ret=ssl3_send_finished(s,
|
||||
@ -1353,21 +1369,6 @@ int ssl3_get_server_certificate(SSL *s)
|
||||
s->session->verify_result = s->verify_result;
|
||||
|
||||
x=NULL;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
/* Check the audit proof. */
|
||||
if (s->ctx->tlsext_authz_server_audit_proof_cb)
|
||||
{
|
||||
ret = s->ctx->tlsext_authz_server_audit_proof_cb(s,
|
||||
s->ctx->tlsext_authz_server_audit_proof_cb_arg);
|
||||
if (ret <= 0)
|
||||
{
|
||||
al = SSL_AD_BAD_CERTIFICATE;
|
||||
SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_INVALID_AUDIT_PROOF);
|
||||
goto f_err;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
ret=1;
|
||||
if (0)
|
||||
{
|
||||
@ -3568,11 +3569,9 @@ int ssl3_check_finished(SSL *s)
|
||||
{
|
||||
int ok;
|
||||
long n;
|
||||
/* If we have no ticket it cannot be a resumed session. */
|
||||
if (!s->session->tlsext_tick)
|
||||
return 1;
|
||||
/* this function is called when we really expect a Certificate
|
||||
* message, so permit appropriate message length */
|
||||
/* Read the message to see if it is supplemental data, regardless if there is a session ticket
|
||||
this function is called when we really expect a Certificate
|
||||
message, so permit appropriate message length */
|
||||
n=s->method->ssl_get_message(s,
|
||||
SSL3_ST_CR_CERT_A,
|
||||
SSL3_ST_CR_CERT_B,
|
||||
@ -3581,6 +3580,14 @@ int ssl3_check_finished(SSL *s)
|
||||
&ok);
|
||||
if (!ok) return((int)n);
|
||||
s->s3->tmp.reuse_message = 1;
|
||||
|
||||
if (s->s3->tmp.message_type == SSL3_MT_SUPPLEMENTAL_DATA)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
/* If we have no ticket it cannot be a resumed session. */
|
||||
if (!s->session->tlsext_tick)
|
||||
return 1;
|
||||
if ((s->s3->tmp.message_type == SSL3_MT_FINISHED)
|
||||
|| (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET))
|
||||
return 2;
|
||||
@ -3608,15 +3615,99 @@ int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
int tls1_send_client_supplemental_data(SSL *s, int *skip)
|
||||
{
|
||||
if (s->ctx->cli_supp_data_records_count)
|
||||
{
|
||||
unsigned char *p = NULL;
|
||||
unsigned char *size_loc = NULL;
|
||||
cli_supp_data_record *record = NULL;
|
||||
size_t length = 0;
|
||||
size_t i = 0;
|
||||
|
||||
for (i = 0; i < s->ctx->cli_supp_data_records_count; i++)
|
||||
{
|
||||
const unsigned char *out = NULL;
|
||||
unsigned short outlen = 0;
|
||||
int cb_retval = 0;
|
||||
record = &s->ctx->cli_supp_data_records[i];
|
||||
|
||||
/* NULL callback or -1 omits supp data entry*/
|
||||
if (!record->fn2)
|
||||
continue;
|
||||
cb_retval = record->fn2(s, record->supp_data_type,
|
||||
&out, &outlen,
|
||||
record->arg);
|
||||
if (cb_retval == -1)
|
||||
continue; /* skip this supp data entry */
|
||||
if (cb_retval == 0)
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length)
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
//if first entry, write handshake message type
|
||||
if (length == 0)
|
||||
{
|
||||
if (!BUF_MEM_grow_clean(s->init_buf, 4))
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
p = (unsigned char *)s->init_buf->data;
|
||||
*(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
|
||||
//update message length when all callbacks complete
|
||||
size_loc = p;
|
||||
//skip over handshake length field (3 bytes) and supp_data length field (3 bytes)
|
||||
p += 3 + 3;
|
||||
length += 1 +3 +3;
|
||||
}
|
||||
if (!BUF_MEM_grow(s->init_buf, outlen + 4))
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
s2n(record->supp_data_type, p);
|
||||
s2n(outlen, p);
|
||||
memcpy(p, out, outlen);
|
||||
length += (outlen + 4);
|
||||
p += outlen;
|
||||
}
|
||||
if (length > 0)
|
||||
{
|
||||
//write handshake length
|
||||
l2n3(length - 4, size_loc);
|
||||
//supp_data length
|
||||
l2n3(length - 7, size_loc);
|
||||
s->state = SSL3_ST_CW_SUPPLEMENTAL_DATA_B;
|
||||
s->init_num = length;
|
||||
s->init_off = 0;
|
||||
return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
|
||||
}
|
||||
}
|
||||
|
||||
//no supp data message sent
|
||||
*skip = 1;
|
||||
s->init_num = 0;
|
||||
s->init_off = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls1_get_server_supplemental_data(SSL *s)
|
||||
{
|
||||
int al;
|
||||
int al = 0;
|
||||
int ok;
|
||||
unsigned long supp_data_len, authz_data_len;
|
||||
long n;
|
||||
unsigned short supp_data_type, authz_data_type, proof_len;
|
||||
const unsigned char *p;
|
||||
unsigned char *new_proof;
|
||||
const unsigned char *p, *d;
|
||||
unsigned short supp_data_entry_type = 0;
|
||||
unsigned long supp_data_entry_len = 0;
|
||||
unsigned long supp_data_len = 0;
|
||||
size_t i;
|
||||
int cb_retval = 0;
|
||||
|
||||
n=s->method->ssl_get_message(s,
|
||||
SSL3_ST_CR_SUPPLEMENTAL_DATA_A,
|
||||
@ -3629,7 +3720,7 @@ int tls1_get_server_supplemental_data(SSL *s)
|
||||
if (!ok) return((int)n);
|
||||
|
||||
p = (unsigned char *)s->init_msg;
|
||||
|
||||
d = p;
|
||||
/* The message cannot be empty */
|
||||
if (n < 3)
|
||||
{
|
||||
@ -3637,72 +3728,26 @@ int tls1_get_server_supplemental_data(SSL *s)
|
||||
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
|
||||
goto f_err;
|
||||
}
|
||||
/* Length of supplemental data */
|
||||
n2l3(p,supp_data_len);
|
||||
n -= 3;
|
||||
/* We must have at least one supplemental data entry
|
||||
* with type (1 byte) and length (2 bytes). */
|
||||
if (supp_data_len != (unsigned long) n || n < 4)
|
||||
n2l3(p, supp_data_len);
|
||||
while (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);
|
||||
|
17
ssl/s3_lib.c
17
ssl/s3_lib.c
@ -3029,8 +3029,6 @@ void ssl3_free(SSL *s)
|
||||
SSL_SRP_CTX_free(s);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s->s3->tlsext_authz_client_types != NULL)
|
||||
OPENSSL_free(s->s3->tlsext_authz_client_types);
|
||||
if (s->s3->tlsext_custom_types != NULL)
|
||||
OPENSSL_free(s->s3->tlsext_custom_types);
|
||||
#endif
|
||||
@ -3078,11 +3076,6 @@ void ssl3_clear(SSL *s)
|
||||
}
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s->s3->tlsext_authz_client_types != NULL)
|
||||
{
|
||||
OPENSSL_free(s->s3->tlsext_authz_client_types);
|
||||
s->s3->tlsext_authz_client_types = NULL;
|
||||
}
|
||||
if (s->s3->tlsext_custom_types != NULL)
|
||||
{
|
||||
OPENSSL_free(s->s3->tlsext_custom_types);
|
||||
@ -3897,10 +3890,6 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
|
||||
case SSL_CTRL_SET_CHAIN_CERT_STORE:
|
||||
return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg);
|
||||
|
||||
case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG:
|
||||
ctx->tlsext_authz_server_audit_proof_cb_arg = parg;
|
||||
break;
|
||||
|
||||
#endif /* !OPENSSL_NO_TLSEXT */
|
||||
|
||||
/* A Thawte special :-) */
|
||||
@ -4023,12 +4012,6 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
|
||||
ctx->srp_ctx.SRP_give_srp_client_pwd_callback=(char *(*)(SSL *,void *))fp;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB:
|
||||
ctx->tlsext_authz_server_audit_proof_cb =
|
||||
(int (*)(SSL *, void *))fp;
|
||||
break;
|
||||
|
||||
#endif
|
||||
default:
|
||||
return(0);
|
||||
|
250
ssl/s3_srvr.c
250
ssl/s3_srvr.c
@ -413,14 +413,8 @@ int ssl3_accept(SSL *s)
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
case SSL3_ST_SW_SUPPLEMENTAL_DATA_A:
|
||||
case SSL3_ST_SW_SUPPLEMENTAL_DATA_B:
|
||||
/* We promised to send an audit proof in the hello. */
|
||||
if (s->s3->tlsext_authz_promised_to_client)
|
||||
{
|
||||
ret = tls1_send_server_supplemental_data(s);
|
||||
if (ret <= 0) goto end;
|
||||
}
|
||||
else
|
||||
skip = 1;
|
||||
ret = tls1_send_server_supplemental_data(s, &skip);
|
||||
if (ret <= 0) goto end;
|
||||
|
||||
s->state = SSL3_ST_SW_CERT_A;
|
||||
s->init_num = 0;
|
||||
@ -595,7 +589,16 @@ int ssl3_accept(SSL *s)
|
||||
|
||||
s->state=s->s3->tmp.next_state;
|
||||
break;
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
case SSL3_ST_SR_SUPPLEMENTAL_DATA_A:
|
||||
case SSL3_ST_SR_SUPPLEMENTAL_DATA_B:
|
||||
ret=tls1_get_client_supplemental_data(s);
|
||||
if (ret <= 0) goto end;
|
||||
s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
|
||||
s->state=SSL3_ST_SW_FLUSH;
|
||||
s->init_num=0;
|
||||
break;
|
||||
#endif
|
||||
case SSL3_ST_SR_CERT_A:
|
||||
case SSL3_ST_SR_CERT_B:
|
||||
/* Check for second client hello (MS SGC) */
|
||||
@ -604,6 +607,10 @@ int ssl3_accept(SSL *s)
|
||||
goto end;
|
||||
if (ret == 2)
|
||||
s->state = SSL3_ST_SR_CLNT_HELLO_C;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
else if (ret == 3)
|
||||
s->state = SSL3_ST_SR_SUPPLEMENTAL_DATA_A;
|
||||
#endif
|
||||
else {
|
||||
if (s->s3->tmp.cert_request)
|
||||
{
|
||||
@ -894,6 +901,12 @@ int ssl3_check_client_hello(SSL *s)
|
||||
&ok);
|
||||
if (!ok) return((int)n);
|
||||
s->s3->tmp.reuse_message = 1;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s->s3->tmp.message_type == SSL3_MT_SUPPLEMENTAL_DATA)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
#endif
|
||||
if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
|
||||
{
|
||||
/* We only allow the client to restart the handshake once per
|
||||
@ -3639,98 +3652,149 @@ int ssl3_get_next_proto(SSL *s)
|
||||
}
|
||||
# endif
|
||||
|
||||
int tls1_send_server_supplemental_data(SSL *s)
|
||||
int tls1_send_server_supplemental_data(SSL *s, int *skip)
|
||||
{
|
||||
size_t length = 0;
|
||||
const unsigned char *authz, *orig_authz;
|
||||
unsigned char *p;
|
||||
size_t authz_length, i;
|
||||
|
||||
if (s->state != SSL3_ST_SW_SUPPLEMENTAL_DATA_A)
|
||||
return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
|
||||
|
||||
orig_authz = authz = ssl_get_authz_data(s, &authz_length);
|
||||
if (authz == NULL)
|
||||
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,
|
||||
record->arg);
|
||||
if (cb_retval == -1)
|
||||
continue; /* skip this supp data entry */
|
||||
if (cb_retval == 0)
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length)
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
//write supp data entry...
|
||||
//if first entry, write handshake message type
|
||||
//jump back to write length at end
|
||||
if (length == 0)
|
||||
{
|
||||
//1 byte message type + 3 bytes for message length
|
||||
if (!BUF_MEM_grow_clean(s->init_buf, 4))
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
p = (unsigned char *)s->init_buf->data;
|
||||
*(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
|
||||
//hold on to length field to update later
|
||||
size_loc = p;
|
||||
//skip over handshake length field (3 bytes) and supp_data length field (3 bytes)
|
||||
p += 3 + 3;
|
||||
length += 1 +3 +3;
|
||||
}
|
||||
//2 byte supp data type + 2 byte length + outlen
|
||||
if (!BUF_MEM_grow(s->init_buf, outlen + 4))
|
||||
{
|
||||
SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
s2n(record->supp_data_type, p);
|
||||
s2n(outlen, p);
|
||||
memcpy(p, out, outlen);
|
||||
//update length to supp data type (2 bytes) + supp data length (2 bytes) + supp data
|
||||
length += (outlen + 4);
|
||||
p += outlen;
|
||||
}
|
||||
if (length > 0)
|
||||
{
|
||||
//write handshake length
|
||||
l2n3(length - 4, size_loc);
|
||||
//supp_data length
|
||||
l2n3(length - 7, size_loc);
|
||||
s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B;
|
||||
s->init_num = length;
|
||||
s->init_off = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
|
124
ssl/ssl.h
124
ssl/ssl.h
@ -433,6 +433,58 @@ typedef struct {
|
||||
custom_srv_ext_second_cb_fn fn2;
|
||||
void *arg;
|
||||
} custom_srv_ext_record;
|
||||
|
||||
/* Callbacks and structures for handling Supplemental Data:
|
||||
* srv_supp_data_first_cb_fn - server sends Supplemental Data
|
||||
* srv_supp_data_second_cb_fn - server receives Supplemental Data
|
||||
* cli_supp_data_first_cb_fn - client receives Supplemental Data
|
||||
* cli_supp_data_second_cb_fn - client sends Supplemental Data
|
||||
*
|
||||
* All these functions return nonzero on success. Zero will terminate
|
||||
* the handshake (and return a specific TLS Fatal alert, if the function
|
||||
* declaration has an "al" parameter). -1 for the "sending" functions
|
||||
* will result in no supplemental data entry being added to the
|
||||
* supplemental data message for the provided supplemental data type.
|
||||
*
|
||||
* "supp_data_type" is a Supplemental Data Type from 0-65535.
|
||||
* "in" is a pointer to TLS "supplemental_data_entry" being provided to the cb.
|
||||
* "out" is used by the callback to return a pointer to "supplemental data"
|
||||
* which OpenSSL will later copy into the TLS handshake. The contents
|
||||
* of this buffer should not be changed until the handshake is complete.
|
||||
* "inlen" and "outlen" are Supplemental Data lengths from 0-65535.
|
||||
* "al" is a TLS "AlertDescription" from 0-255 which WILL be sent as a
|
||||
* fatal TLS alert, if the callback returns zero.
|
||||
*/
|
||||
typedef int (*srv_supp_data_first_cb_fn)(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg);
|
||||
typedef int (*srv_supp_data_second_cb_fn)(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg);
|
||||
|
||||
typedef int (*cli_supp_data_first_cb_fn)(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg);
|
||||
typedef int (*cli_supp_data_second_cb_fn)(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg);
|
||||
|
||||
typedef struct {
|
||||
unsigned short supp_data_type;
|
||||
srv_supp_data_first_cb_fn fn1;
|
||||
srv_supp_data_second_cb_fn fn2;
|
||||
void *arg;
|
||||
} srv_supp_data_record;
|
||||
|
||||
typedef struct {
|
||||
unsigned short supp_data_type;
|
||||
cli_supp_data_first_cb_fn fn1;
|
||||
cli_supp_data_second_cb_fn fn2;
|
||||
void *arg;
|
||||
} cli_supp_data_record;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_SSL_INTERN
|
||||
@ -596,13 +648,6 @@ struct ssl_session_st
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
char *srp_username;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
/* Used by client: the proof for this session.
|
||||
* We store it outside the sess_cert structure, since the proof
|
||||
* is received before the certificate. */
|
||||
unsigned char *audit_proof;
|
||||
size_t audit_proof_length;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -1149,8 +1194,6 @@ struct ssl_ctx_st
|
||||
size_t tlsext_ellipticcurvelist_length;
|
||||
unsigned char *tlsext_ellipticcurvelist;
|
||||
# endif /* OPENSSL_NO_EC */
|
||||
int (*tlsext_authz_server_audit_proof_cb)(SSL *s, void *arg);
|
||||
void *tlsext_authz_server_audit_proof_cb_arg;
|
||||
#endif
|
||||
|
||||
/* Arrays containing the callbacks for custom TLS Extensions. */
|
||||
@ -1158,6 +1201,12 @@ struct ssl_ctx_st
|
||||
size_t custom_cli_ext_records_count;
|
||||
custom_srv_ext_record *custom_srv_ext_records;
|
||||
size_t custom_srv_ext_records_count;
|
||||
|
||||
/* Arrays containing the callbacks for Supplemental Data. */
|
||||
cli_supp_data_record *cli_supp_data_records;
|
||||
size_t cli_supp_data_records_count;
|
||||
srv_supp_data_record *srv_supp_data_records;
|
||||
size_t srv_supp_data_records_count;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1304,6 +1353,31 @@ int SSL_CTX_set_custom_cli_ext(SSL_CTX *ctx, unsigned short ext_type,
|
||||
int SSL_CTX_set_custom_srv_ext(SSL_CTX *ctx, unsigned short ext_type,
|
||||
custom_srv_ext_first_cb_fn fn1,
|
||||
custom_srv_ext_second_cb_fn fn2, void *arg);
|
||||
|
||||
/* Register callbacks to handle Supplemental Data as client or server.
|
||||
*
|
||||
* For SSL_CTX_set_srv_supp_data, a NULL srv_supp_data_first_cb_fn results in no supplemental data
|
||||
* being sent by the server for that TLS extension.
|
||||
* A NULL srv_supp_data_second_cb_fn results in no supplemental data
|
||||
* being received by the server for that TLS extension.
|
||||
*
|
||||
* For SSL_CTX_set_cli_supp_data, a NULL cli_supp_data_first_cb_fn results in no supplemental data
|
||||
* being received by the client for that TLS extension.
|
||||
* A NULL cli_supp_data_second_cb_fn results in no supplemental data
|
||||
* being sent by the client for that TLS extension.
|
||||
*
|
||||
* Returns nonzero on success. You cannot register twice for the same supp_data_type.
|
||||
*/
|
||||
int SSL_CTX_set_srv_supp_data(SSL_CTX *ctx,
|
||||
unsigned short supp_data_type,
|
||||
srv_supp_data_first_cb_fn fn1,
|
||||
srv_supp_data_second_cb_fn fn2, void *arg);
|
||||
|
||||
int SSL_CTX_set_cli_supp_data(SSL_CTX *ctx,
|
||||
unsigned short supp_data_type,
|
||||
cli_supp_data_first_cb_fn fn1,
|
||||
cli_supp_data_second_cb_fn fn2, void *arg);
|
||||
|
||||
#endif
|
||||
|
||||
#define SSL_NOTHING 1
|
||||
@ -1825,9 +1899,6 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
#define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING 86
|
||||
#define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS 87
|
||||
#endif
|
||||
/* Callback for verifying audit proofs (client only) */
|
||||
#define SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB 95
|
||||
#define SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG 96
|
||||
#endif /* OPENSSL_NO_TLSEXT */
|
||||
|
||||
#define DTLS_CTRL_GET_TIMEOUT 73
|
||||
@ -2099,17 +2170,6 @@ int SSL_use_certificate(SSL *ssl, X509 *x);
|
||||
int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
/* Set authz data for the current active cert. */
|
||||
int SSL_CTX_use_authz(SSL_CTX *ctx, unsigned char *authz, size_t authz_length);
|
||||
int SSL_use_authz(SSL *ssl, unsigned char *authz, size_t authz_length);
|
||||
/* Get the authz of type 'type' associated with the current active cert. */
|
||||
const unsigned char *SSL_CTX_get_authz_data(SSL_CTX *ctx, unsigned char type,
|
||||
size_t *data_length);
|
||||
#ifndef OPENSSL_NO_STDIO
|
||||
int SSL_CTX_use_authz_file(SSL_CTX *ctx, const char *file);
|
||||
int SSL_use_authz_file(SSL *ssl, const char *file);
|
||||
#endif
|
||||
|
||||
/* Set serverinfo data for the current active cert. */
|
||||
int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
|
||||
size_t serverinfo_length);
|
||||
@ -2163,10 +2223,6 @@ int SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
|
||||
#ifndef OPENSSL_NO_BIO
|
||||
int SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
unsigned char *SSL_SESSION_get_tlsext_authz_server_audit_proof(SSL_SESSION *s,
|
||||
size_t *proof_length);
|
||||
#endif
|
||||
void SSL_SESSION_free(SSL_SESSION *ses);
|
||||
int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
|
||||
int SSL_set_session(SSL *to, SSL_SESSION *session);
|
||||
@ -2507,9 +2563,7 @@ void ERR_load_SSL_strings(void);
|
||||
/* Error codes for the SSL functions. */
|
||||
|
||||
/* Function codes. */
|
||||
#define SSL_F_AUTHZ_FIND_DATA 330
|
||||
#define SSL_F_AUTHZ_VALIDATE 323
|
||||
#define SSL_F_CHECK_SUITEB_CIPHER_LIST 331
|
||||
#define SSL_F_CHECK_SUITEB_CIPHER_LIST 335
|
||||
#define SSL_F_CLIENT_CERTIFICATE 100
|
||||
#define SSL_F_CLIENT_FINISHED 167
|
||||
#define SSL_F_CLIENT_HELLO 101
|
||||
@ -2552,7 +2606,6 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_GET_SERVER_HELLO 109
|
||||
#define SSL_F_GET_SERVER_VERIFY 110
|
||||
#define SSL_F_I2D_SSL_SESSION 111
|
||||
#define SSL_F_READ_AUTHZ 329
|
||||
#define SSL_F_READ_N 112
|
||||
#define SSL_F_REQUEST_CERTIFICATE 113
|
||||
#define SSL_F_SERVER_FINISH 239
|
||||
@ -2658,7 +2711,6 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219
|
||||
#define SSL_F_SSL_CTX_SET_SSL_VERSION 170
|
||||
#define SSL_F_SSL_CTX_SET_TRUST 229
|
||||
#define SSL_F_SSL_CTX_USE_AUTHZ 324
|
||||
#define SSL_F_SSL_CTX_USE_CERTIFICATE 171
|
||||
#define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172
|
||||
#define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE 220
|
||||
@ -2700,7 +2752,6 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_SSL_SESSION_PRINT_FP 190
|
||||
#define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312
|
||||
#define SSL_F_SSL_SESS_CERT_NEW 225
|
||||
#define SSL_F_SSL_SET_AUTHZ 325
|
||||
#define SSL_F_SSL_SET_CERT 191
|
||||
#define SSL_F_SSL_SET_CIPHER_LIST 271
|
||||
#define SSL_F_SSL_SET_FD 192
|
||||
@ -2717,7 +2768,6 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_SSL_UNDEFINED_CONST_FUNCTION 243
|
||||
#define SSL_F_SSL_UNDEFINED_FUNCTION 197
|
||||
#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244
|
||||
#define SSL_F_SSL_USE_AUTHZ 328
|
||||
#define SSL_F_SSL_USE_CERTIFICATE 198
|
||||
#define SSL_F_SSL_USE_CERTIFICATE_ASN1 199
|
||||
#define SSL_F_SSL_USE_CERTIFICATE_FILE 200
|
||||
@ -2737,18 +2787,19 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_F_TLS1_ENC 210
|
||||
#define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314
|
||||
#define SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA 326
|
||||
#define SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA 336
|
||||
#define SSL_F_TLS1_HEARTBEAT 315
|
||||
#define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT 275
|
||||
#define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT 276
|
||||
#define SSL_F_TLS1_PRF 284
|
||||
#define SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA 327
|
||||
#define SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA 333
|
||||
#define SSL_F_TLS1_SETUP_KEY_BLOCK 211
|
||||
#define SSL_F_WRITE_PENDING 212
|
||||
|
||||
/* Reason codes. */
|
||||
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
|
||||
#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272
|
||||
#define SSL_R_AUTHZ_DATA_TOO_LARGE 375
|
||||
#define SSL_R_BAD_ALERT_RECORD 101
|
||||
#define SSL_R_BAD_AUTHENTICATION_TYPE 102
|
||||
#define SSL_R_BAD_CHANGE_CIPHER_SPEC 103
|
||||
@ -2841,8 +2892,6 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_ILLEGAL_PADDING 283
|
||||
#define SSL_R_ILLEGAL_SUITEB_DIGEST 380
|
||||
#define SSL_R_INCONSISTENT_COMPRESSION 340
|
||||
#define SSL_R_INVALID_AUDIT_PROOF 371
|
||||
#define SSL_R_INVALID_AUTHZ_DATA 374
|
||||
#define SSL_R_INVALID_CHALLENGE_LENGTH 158
|
||||
#define SSL_R_INVALID_COMMAND 280
|
||||
#define SSL_R_INVALID_COMPRESSION_ALGORITHM 341
|
||||
@ -3032,7 +3081,6 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_UNEXPECTED_RECORD 245
|
||||
#define SSL_R_UNINITIALIZED 276
|
||||
#define SSL_R_UNKNOWN_ALERT_TYPE 246
|
||||
#define SSL_R_UNKNOWN_AUTHZ_DATA_TYPE 372
|
||||
#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247
|
||||
#define SSL_R_UNKNOWN_CIPHER_RETURNED 248
|
||||
#define SSL_R_UNKNOWN_CIPHER_TYPE 249
|
||||
|
36
ssl/ssl3.h
36
ssl/ssl3.h
@ -560,20 +560,6 @@ typedef struct ssl3_state_st
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
/* tlsext_authz_client_types contains an array of supported authz
|
||||
* types, as advertised by the client. The array is sorted and
|
||||
* does not contain any duplicates. */
|
||||
unsigned char *tlsext_authz_client_types;
|
||||
size_t tlsext_authz_client_types_len;
|
||||
/* tlsext_authz_promised_to_client is true iff we're a server and we
|
||||
* echoed the client's supplemental data extension and therefore must
|
||||
* send a supplemental data handshake message. */
|
||||
char tlsext_authz_promised_to_client;
|
||||
/* tlsext_authz_server_promised is true iff we're a client and the
|
||||
* server echoed our server_authz extension and therefore must send us
|
||||
* a supplemental data handshake message. */
|
||||
char tlsext_authz_server_promised;
|
||||
|
||||
/* tlsext_custom_types contains an array of TLS Extension types which
|
||||
* were advertised by the client in its ClientHello, which were not
|
||||
* otherwise handled by OpenSSL, and which the server has registered
|
||||
@ -628,8 +614,10 @@ typedef struct ssl3_state_st
|
||||
#define SSL3_ST_CR_CERT_REQ_B (0x151|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CR_SRVR_DONE_A (0x160|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CR_SRVR_DONE_B (0x161|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CR_SUPPLEMENTAL_DATA_A (0x210|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CR_SUPPLEMENTAL_DATA_B (0x211|SSL_ST_CONNECT)
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
#define SSL3_ST_CR_SUPPLEMENTAL_DATA_A (0x212|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CR_SUPPLEMENTAL_DATA_B (0x213|SSL_ST_CONNECT)
|
||||
#endif
|
||||
/* write to server */
|
||||
#define SSL3_ST_CW_CERT_A (0x170|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CW_CERT_B (0x171|SSL_ST_CONNECT)
|
||||
@ -644,6 +632,10 @@ typedef struct ssl3_state_st
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
#define SSL3_ST_CW_NEXT_PROTO_A (0x200|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CW_NEXT_PROTO_B (0x201|SSL_ST_CONNECT)
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
#define SSL3_ST_CW_SUPPLEMENTAL_DATA_A (0x222|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CW_SUPPLEMENTAL_DATA_B (0x223|SSL_ST_CONNECT)
|
||||
#endif
|
||||
#endif
|
||||
#define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT)
|
||||
#define SSL3_ST_CW_FINISHED_B (0x1B1|SSL_ST_CONNECT)
|
||||
@ -670,6 +662,10 @@ typedef struct ssl3_state_st
|
||||
#define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SR_CLNT_HELLO_D (0x115|SSL_ST_ACCEPT)
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
#define SSL3_ST_SR_SUPPLEMENTAL_DATA_A (0x212|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SR_SUPPLEMENTAL_DATA_B (0x213|SSL_ST_ACCEPT)
|
||||
#endif
|
||||
/* write to client */
|
||||
#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
|
||||
#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)
|
||||
@ -710,8 +706,10 @@ typedef struct ssl3_state_st
|
||||
#define SSL3_ST_SW_SESSION_TICKET_B (0x1F1|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SW_CERT_STATUS_A (0x200|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SW_CERT_STATUS_B (0x201|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SW_SUPPLEMENTAL_DATA_A (0x220|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SW_SUPPLEMENTAL_DATA_B (0x221|SSL_ST_ACCEPT)
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
#define SSL3_ST_SW_SUPPLEMENTAL_DATA_A (0x222|SSL_ST_ACCEPT)
|
||||
#define SSL3_ST_SW_SUPPLEMENTAL_DATA_B (0x223|SSL_ST_ACCEPT)
|
||||
#endif
|
||||
|
||||
#define SSL3_MT_HELLO_REQUEST 0
|
||||
#define SSL3_MT_CLIENT_HELLO 1
|
||||
@ -725,7 +723,9 @@ typedef struct ssl3_state_st
|
||||
#define SSL3_MT_CLIENT_KEY_EXCHANGE 16
|
||||
#define SSL3_MT_FINISHED 20
|
||||
#define SSL3_MT_CERTIFICATE_STATUS 22
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
#define SSL3_MT_SUPPLEMENTAL_DATA 23
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
#define SSL3_MT_NEXT_PROTO 67
|
||||
#endif
|
||||
|
@ -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
|
||||
@ -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
|
||||
|
233
ssl/ssl_rsa.c
233
ssl/ssl_rsa.c
@ -66,10 +66,6 @@
|
||||
|
||||
static int ssl_set_cert(CERT *c, X509 *x509);
|
||||
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
static int ssl_set_authz(CERT *c, unsigned char *authz,
|
||||
size_t authz_length);
|
||||
#endif
|
||||
int SSL_use_certificate(SSL *ssl, X509 *x)
|
||||
{
|
||||
if (x == NULL)
|
||||
@ -463,6 +459,15 @@ static int ssl_set_cert(CERT *c, X509 *x)
|
||||
X509_free(c->pkeys[i].x509);
|
||||
CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
|
||||
c->pkeys[i].x509=x;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
/* Free the old serverinfo data, if it exists. */
|
||||
if (c->pkeys[i].serverinfo != NULL)
|
||||
{
|
||||
OPENSSL_free(c->pkeys[i].serverinfo);
|
||||
c->pkeys[i].serverinfo = NULL;
|
||||
c->pkeys[i].serverinfo_length = 0;
|
||||
}
|
||||
#endif
|
||||
c->key= &(c->pkeys[i]);
|
||||
|
||||
c->valid=0;
|
||||
@ -798,50 +803,6 @@ end:
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
/* authz_validate returns true iff authz is well formed, i.e. that it meets the
|
||||
* wire format as documented in the CERT_PKEY structure and that there are no
|
||||
* duplicate entries. */
|
||||
static char authz_validate(const unsigned char *authz, size_t length)
|
||||
{
|
||||
unsigned char types_seen_bitmap[32];
|
||||
|
||||
if (!authz)
|
||||
return 1;
|
||||
|
||||
memset(types_seen_bitmap, 0, sizeof(types_seen_bitmap));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned char type, byte, bit;
|
||||
unsigned short len;
|
||||
|
||||
if (!length)
|
||||
return 1;
|
||||
|
||||
type = *(authz++);
|
||||
length--;
|
||||
|
||||
byte = type / 8;
|
||||
bit = type & 7;
|
||||
if (types_seen_bitmap[byte] & (1 << bit))
|
||||
return 0;
|
||||
types_seen_bitmap[byte] |= (1 << bit);
|
||||
|
||||
if (length < 2)
|
||||
return 0;
|
||||
len = ((unsigned short) authz[0]) << 8 |
|
||||
((unsigned short) authz[1]);
|
||||
authz += 2;
|
||||
length -= 2;
|
||||
|
||||
if (length < len)
|
||||
return 0;
|
||||
|
||||
authz += len;
|
||||
length -= len;
|
||||
}
|
||||
}
|
||||
|
||||
static int serverinfo_find_extension(const unsigned char *serverinfo,
|
||||
size_t serverinfo_length,
|
||||
unsigned short extension_type,
|
||||
@ -974,83 +935,6 @@ static int serverinfo_process_buffer(const unsigned char *serverinfo,
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned char *authz_find_data(const unsigned char *authz,
|
||||
size_t authz_length,
|
||||
unsigned char data_type,
|
||||
size_t *data_length)
|
||||
{
|
||||
if (authz == NULL) return NULL;
|
||||
if (!authz_validate(authz, authz_length))
|
||||
{
|
||||
SSLerr(SSL_F_AUTHZ_FIND_DATA,SSL_R_INVALID_AUTHZ_DATA);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned char type;
|
||||
unsigned short len;
|
||||
if (!authz_length)
|
||||
return NULL;
|
||||
|
||||
type = *(authz++);
|
||||
authz_length--;
|
||||
|
||||
/* We've validated the authz data, so we don't have to
|
||||
* check again that we have enough bytes left. */
|
||||
len = ((unsigned short) authz[0]) << 8 |
|
||||
((unsigned short) authz[1]);
|
||||
authz += 2;
|
||||
authz_length -= 2;
|
||||
if (type == data_type)
|
||||
{
|
||||
*data_length = len;
|
||||
return authz;
|
||||
}
|
||||
authz += len;
|
||||
authz_length -= len;
|
||||
}
|
||||
/* No match */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ssl_set_authz(CERT *c, unsigned char *authz, size_t authz_length)
|
||||
{
|
||||
CERT_PKEY *current_key = c->key;
|
||||
if (current_key == NULL)
|
||||
return 0;
|
||||
if (!authz_validate(authz, authz_length))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_SET_AUTHZ,SSL_R_INVALID_AUTHZ_DATA);
|
||||
return(0);
|
||||
}
|
||||
current_key->authz = OPENSSL_realloc(current_key->authz, authz_length);
|
||||
if (current_key->authz == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_SET_AUTHZ,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
current_key->authz_length = authz_length;
|
||||
memcpy(current_key->authz, authz, authz_length);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_CTX_use_authz(SSL_CTX *ctx, unsigned char *authz,
|
||||
size_t authz_length)
|
||||
{
|
||||
if (authz == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_CTX_USE_AUTHZ,ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (!ssl_cert_inst(&ctx->cert))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_CTX_USE_AUTHZ,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
return ssl_set_authz(ctx->cert, authz, authz_length);
|
||||
}
|
||||
|
||||
int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
|
||||
size_t serverinfo_length)
|
||||
{
|
||||
@ -1094,106 +978,7 @@ int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_use_authz(SSL *ssl, unsigned char *authz, size_t authz_length)
|
||||
{
|
||||
if (authz == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_USE_AUTHZ,ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (!ssl_cert_inst(&ssl->cert))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_USE_AUTHZ,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
return ssl_set_authz(ssl->cert, authz, authz_length);
|
||||
}
|
||||
|
||||
const unsigned char *SSL_CTX_get_authz_data(SSL_CTX *ctx, unsigned char type,
|
||||
size_t *data_length)
|
||||
{
|
||||
CERT_PKEY *current_key;
|
||||
|
||||
if (ctx->cert == NULL)
|
||||
return NULL;
|
||||
current_key = ctx->cert->key;
|
||||
if (current_key->authz == NULL)
|
||||
return NULL;
|
||||
return authz_find_data(current_key->authz,
|
||||
current_key->authz_length, type, data_length);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_STDIO
|
||||
/* read_authz returns a newly allocated buffer with authz data */
|
||||
static unsigned char *read_authz(const char *file, size_t *authz_length)
|
||||
{
|
||||
BIO *authz_in = NULL;
|
||||
unsigned char *authz = NULL;
|
||||
/* Allow authzs up to 64KB. */
|
||||
static const size_t authz_limit = 65536;
|
||||
size_t read_length;
|
||||
unsigned char *ret = NULL;
|
||||
|
||||
authz_in = BIO_new(BIO_s_file_internal());
|
||||
if (authz_in == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_READ_AUTHZ,ERR_R_BUF_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (BIO_read_filename(authz_in,file) <= 0)
|
||||
{
|
||||
SSLerr(SSL_F_READ_AUTHZ,ERR_R_SYS_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
authz = OPENSSL_malloc(authz_limit);
|
||||
read_length = BIO_read(authz_in, authz, authz_limit);
|
||||
if (read_length == authz_limit || read_length <= 0)
|
||||
{
|
||||
SSLerr(SSL_F_READ_AUTHZ,SSL_R_AUTHZ_DATA_TOO_LARGE);
|
||||
OPENSSL_free(authz);
|
||||
goto end;
|
||||
}
|
||||
*authz_length = read_length;
|
||||
ret = authz;
|
||||
end:
|
||||
if (authz_in != NULL) BIO_free(authz_in);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SSL_CTX_use_authz_file(SSL_CTX *ctx, const char *file)
|
||||
{
|
||||
unsigned char *authz = NULL;
|
||||
size_t authz_length = 0;
|
||||
int ret;
|
||||
|
||||
authz = read_authz(file, &authz_length);
|
||||
if (authz == NULL)
|
||||
return 0;
|
||||
|
||||
ret = SSL_CTX_use_authz(ctx, authz, authz_length);
|
||||
/* SSL_CTX_use_authz makes a local copy of the authz. */
|
||||
OPENSSL_free(authz);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SSL_use_authz_file(SSL *ssl, const char *file)
|
||||
{
|
||||
unsigned char *authz = NULL;
|
||||
size_t authz_length = 0;
|
||||
int ret;
|
||||
|
||||
authz = read_authz(file, &authz_length);
|
||||
if (authz == NULL)
|
||||
return 0;
|
||||
|
||||
ret = SSL_use_authz(ssl, authz, authz_length);
|
||||
/* SSL_use_authz makes a local copy of the authz. */
|
||||
OPENSSL_free(authz);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
|
||||
{
|
||||
unsigned char *serverinfo = NULL;
|
||||
|
@ -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)
|
||||
|
141
ssl/ssltest.c
141
ssl/ssltest.c
@ -446,6 +446,16 @@ int custom_ext = 0;
|
||||
/* This set based on extension callbacks */
|
||||
int custom_ext_error = 0;
|
||||
|
||||
/*Not IETF assigned supplemental data types*/
|
||||
#define CUSTOM_SUPP_DATA_TYPE_0 100
|
||||
#define CUSTOM_SUPP_DATA_TYPE_1 101
|
||||
#define CUSTOM_SUPP_DATA_TYPE_2 102
|
||||
|
||||
const char supp_data_0_string[] = "00000";
|
||||
|
||||
int suppdata = 0;
|
||||
int suppdata_error = 0;
|
||||
|
||||
static int serverinfo_cli_cb(SSL* s, unsigned short ext_type,
|
||||
const unsigned char* in, unsigned short inlen,
|
||||
int* al, void* arg)
|
||||
@ -651,6 +661,109 @@ static int custom_ext_3_srv_second_cb(SSL *s, unsigned short ext_type,
|
||||
return 1; /* Send "defg" */
|
||||
}
|
||||
|
||||
static int supp_data_0_srv_first_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg)
|
||||
{
|
||||
*out = (const unsigned char*)supp_data_0_string;
|
||||
*outlen = strlen(supp_data_0_string);
|
||||
if (arg != s)
|
||||
suppdata_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int supp_data_0_srv_second_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
if (supp_data_type != CUSTOM_SUPP_DATA_TYPE_0)
|
||||
suppdata_error = 1;
|
||||
if (inlen != strlen(supp_data_0_string))
|
||||
suppdata_error = 1;
|
||||
if (memcmp(in, supp_data_0_string, inlen) != 0)
|
||||
suppdata_error = 1;
|
||||
if (arg != s)
|
||||
suppdata_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int supp_data_1_srv_first_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int supp_data_1_srv_second_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
suppdata_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int supp_data_2_srv_second_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
suppdata_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int supp_data_0_cli_first_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
if (supp_data_type != CUSTOM_SUPP_DATA_TYPE_0)
|
||||
suppdata_error = 1;
|
||||
if (inlen != strlen(supp_data_0_string))
|
||||
suppdata_error = 1;
|
||||
if (memcmp(in, supp_data_0_string, inlen) != 0)
|
||||
suppdata_error = 1;
|
||||
if (arg != s)
|
||||
suppdata_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int supp_data_0_cli_second_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg)
|
||||
{
|
||||
*out = (const unsigned char*)supp_data_0_string;
|
||||
*outlen = strlen(supp_data_0_string);
|
||||
if (arg != s)
|
||||
suppdata_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int supp_data_1_cli_first_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
suppdata_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int supp_data_1_cli_second_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char **out,
|
||||
unsigned short *outlen, void *arg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int supp_data_2_cli_first_cb(SSL *s, unsigned short supp_data_type,
|
||||
const unsigned char *in,
|
||||
unsigned short inlen, int *al,
|
||||
void *arg)
|
||||
{
|
||||
suppdata_error = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *cipher=NULL;
|
||||
static int verbose=0;
|
||||
@ -738,6 +851,7 @@ static void sv_usage(void)
|
||||
fprintf(stderr," -alpn_client <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)
|
||||
@ -1241,6 +1355,10 @@ int main(int argc, char *argv[])
|
||||
if (--argc < 1) goto bad;
|
||||
alpn_expected = *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-suppdata") == 0)
|
||||
{
|
||||
suppdata = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"unknown option %s\n",*argv);
|
||||
@ -1647,6 +1765,23 @@ bad:
|
||||
c_ssl=SSL_new(c_ctx);
|
||||
s_ssl=SSL_new(s_ctx);
|
||||
|
||||
if (suppdata)
|
||||
{
|
||||
//TEST CASES
|
||||
//client and server both send and receive, verify additional arg passed back
|
||||
SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_0, supp_data_0_srv_first_cb, supp_data_0_srv_second_cb, s_ssl);
|
||||
SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_0, supp_data_0_cli_first_cb, supp_data_0_cli_second_cb, c_ssl);
|
||||
|
||||
//-1 response from sending server/client doesn't receive, -1 response from sending client/server doesn't receive
|
||||
SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_1, supp_data_1_srv_first_cb, supp_data_1_srv_second_cb, NULL);
|
||||
SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_1, supp_data_1_cli_first_cb, supp_data_1_cli_second_cb, NULL);
|
||||
|
||||
//null sending server/client doesn't receive, null sending client/server doesn't receive
|
||||
SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_2, /*supp_data_2_srv_first_cb*/NULL, supp_data_2_srv_second_cb, NULL);
|
||||
SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_2, supp_data_2_cli_first_cb, /*supp_data_2_cli_second_cb*/NULL, NULL);
|
||||
|
||||
//alerts set to non-zero and zero return values not tested
|
||||
}
|
||||
#ifndef OPENSSL_NO_KRB5
|
||||
if (c_ssl && c_ssl->kssl_ctx)
|
||||
{
|
||||
@ -2411,7 +2546,11 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count)
|
||||
|
||||
if (verbose)
|
||||
print_details(c_ssl, "DONE: ");
|
||||
|
||||
if (suppdata_error < 0)
|
||||
{
|
||||
ret = 1;
|
||||
goto err;
|
||||
}
|
||||
if (verify_serverinfo() < 0)
|
||||
{
|
||||
ret = 1;
|
||||
|
193
ssl/t1_lib.c
193
ssl/t1_lib.c
@ -1448,26 +1448,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
||||
ret += el;
|
||||
}
|
||||
|
||||
/* Add TLS extension Server_Authz_DataFormats to the ClientHello */
|
||||
/* 2 bytes for extension type */
|
||||
/* 2 bytes for extension length */
|
||||
/* 1 byte for the list length */
|
||||
/* 1 byte for the list (we only support audit proofs) */
|
||||
if (s->ctx->tlsext_authz_server_audit_proof_cb != NULL)
|
||||
{
|
||||
const unsigned short ext_len = 2;
|
||||
const unsigned char list_len = 1;
|
||||
|
||||
if (limit < ret + 6)
|
||||
return NULL;
|
||||
|
||||
s2n(TLSEXT_TYPE_server_authz, ret);
|
||||
/* Extension length: 2 bytes */
|
||||
s2n(ext_len, ret);
|
||||
*(ret++) = list_len;
|
||||
*(ret++) = TLSEXT_AUTHZDATAFORMAT_audit_proof;
|
||||
}
|
||||
|
||||
/* Add custom TLS Extensions to ClientHello */
|
||||
if (s->ctx->custom_cli_ext_records_count)
|
||||
{
|
||||
@ -1726,79 +1706,6 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If the client supports authz then see whether we have any to offer
|
||||
* to it. */
|
||||
if (s->s3->tlsext_authz_client_types_len)
|
||||
{
|
||||
size_t authz_length;
|
||||
/* By now we already know the new cipher, so we can look ahead
|
||||
* to see whether the cert we are going to send
|
||||
* has any authz data attached to it. */
|
||||
const unsigned char* authz = ssl_get_authz_data(s, &authz_length);
|
||||
const unsigned char* const orig_authz = authz;
|
||||
size_t i;
|
||||
unsigned authz_count = 0;
|
||||
|
||||
/* The authz data contains a number of the following structures:
|
||||
* uint8_t authz_type
|
||||
* uint16_t length
|
||||
* uint8_t data[length]
|
||||
*
|
||||
* First we walk over it to find the number of authz elements. */
|
||||
for (i = 0; i < authz_length; i++)
|
||||
{
|
||||
unsigned short length;
|
||||
unsigned char type;
|
||||
|
||||
type = *(authz++);
|
||||
if (memchr(s->s3->tlsext_authz_client_types,
|
||||
type,
|
||||
s->s3->tlsext_authz_client_types_len) != NULL)
|
||||
authz_count++;
|
||||
|
||||
n2s(authz, length);
|
||||
/* n2s increments authz by 2 */
|
||||
i += 2;
|
||||
authz += length;
|
||||
i += length;
|
||||
}
|
||||
|
||||
if (authz_count)
|
||||
{
|
||||
/* Add TLS extension server_authz to the ServerHello message
|
||||
* 2 bytes for extension type
|
||||
* 2 bytes for extension length
|
||||
* 1 byte for the list length
|
||||
* n bytes for the list */
|
||||
const unsigned short ext_len = 1 + authz_count;
|
||||
|
||||
if ((long)(limit - ret - 4 - ext_len) < 0) return NULL;
|
||||
s2n(TLSEXT_TYPE_server_authz, ret);
|
||||
s2n(ext_len, ret);
|
||||
*(ret++) = authz_count;
|
||||
s->s3->tlsext_authz_promised_to_client = 1;
|
||||
}
|
||||
|
||||
authz = orig_authz;
|
||||
for (i = 0; i < authz_length; i++)
|
||||
{
|
||||
unsigned short length;
|
||||
unsigned char type;
|
||||
|
||||
authz_count++;
|
||||
type = *(authz++);
|
||||
if (memchr(s->s3->tlsext_authz_client_types,
|
||||
type,
|
||||
s->s3->tlsext_authz_client_types_len) != NULL)
|
||||
*(ret++) = type;
|
||||
n2s(authz, length);
|
||||
/* n2s increments authz by 2 */
|
||||
i += 2;
|
||||
authz += length;
|
||||
i += length;
|
||||
}
|
||||
}
|
||||
|
||||
/* If custom types were sent in ClientHello, add ServerHello responses */
|
||||
if (s->s3->tlsext_custom_types_count)
|
||||
{
|
||||
@ -2545,66 +2452,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
|
||||
al))
|
||||
return 0;
|
||||
}
|
||||
|
||||
else if (type == TLSEXT_TYPE_server_authz)
|
||||
{
|
||||
unsigned char *sdata = data;
|
||||
unsigned char server_authz_dataformatlist_length;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
*al = TLS1_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
server_authz_dataformatlist_length = *(sdata++);
|
||||
|
||||
if (server_authz_dataformatlist_length != size - 1)
|
||||
{
|
||||
*al = TLS1_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Successful session resumption uses the same authz
|
||||
* information as the original session so we ignore this
|
||||
* in the case of a session resumption. */
|
||||
if (!s->hit)
|
||||
{
|
||||
if (s->s3->tlsext_authz_client_types != NULL)
|
||||
OPENSSL_free(s->s3->tlsext_authz_client_types);
|
||||
s->s3->tlsext_authz_client_types =
|
||||
OPENSSL_malloc(server_authz_dataformatlist_length);
|
||||
if (!s->s3->tlsext_authz_client_types)
|
||||
{
|
||||
*al = TLS1_AD_INTERNAL_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s->s3->tlsext_authz_client_types_len =
|
||||
server_authz_dataformatlist_length;
|
||||
memcpy(s->s3->tlsext_authz_client_types,
|
||||
sdata,
|
||||
server_authz_dataformatlist_length);
|
||||
|
||||
/* Sort the types in order to check for duplicates. */
|
||||
qsort(s->s3->tlsext_authz_client_types,
|
||||
server_authz_dataformatlist_length,
|
||||
1 /* element size */,
|
||||
byte_compare);
|
||||
|
||||
for (i = 0; i < server_authz_dataformatlist_length; i++)
|
||||
{
|
||||
if (i > 0 &&
|
||||
s->s3->tlsext_authz_client_types[i] ==
|
||||
s->s3->tlsext_authz_client_types[i-1])
|
||||
{
|
||||
*al = TLS1_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If this ClientHello extension was unhandled and this is
|
||||
* a nonresumed connection, check whether the extension is a
|
||||
* custom TLS Extension (has a custom_srv_ext_record), and if
|
||||
@ -2970,46 +2817,6 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char
|
||||
al))
|
||||
return 0;
|
||||
}
|
||||
|
||||
else if (type == TLSEXT_TYPE_server_authz)
|
||||
{
|
||||
/* We only support audit proofs. It's an error to send
|
||||
* an authz hello extension if the client
|
||||
* didn't request a proof. */
|
||||
unsigned char *sdata = data;
|
||||
unsigned char server_authz_dataformatlist_length;
|
||||
|
||||
if (!s->ctx->tlsext_authz_server_audit_proof_cb)
|
||||
{
|
||||
*al = TLS1_AD_UNSUPPORTED_EXTENSION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!size)
|
||||
{
|
||||
*al = TLS1_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
server_authz_dataformatlist_length = *(sdata++);
|
||||
if (server_authz_dataformatlist_length != size - 1)
|
||||
{
|
||||
*al = TLS1_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We only support audit proofs, so a legal ServerHello
|
||||
* authz list contains exactly one entry. */
|
||||
if (server_authz_dataformatlist_length != 1 ||
|
||||
sdata[0] != TLSEXT_AUTHZDATAFORMAT_audit_proof)
|
||||
{
|
||||
*al = TLS1_AD_UNSUPPORTED_EXTENSION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s->s3->tlsext_authz_server_promised = 1;
|
||||
}
|
||||
|
||||
/* If this extension type was not otherwise handled, but
|
||||
* matches a custom_cli_ext_record, then send it to the c
|
||||
* callback */
|
||||
|
14
ssl/tls1.h
14
ssl/tls1.h
@ -299,9 +299,12 @@ extern "C" {
|
||||
|
||||
/* From RFC 5878 */
|
||||
#define TLSEXT_SUPPLEMENTALDATATYPE_authz_data 16386
|
||||
|
||||
/* This is not IANA assigned. See
|
||||
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#authorization-data-rules */
|
||||
#define TLSEXT_AUTHZDATAFORMAT_audit_proof 182
|
||||
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#authorization-data-rules
|
||||
* http://tools.ietf.org/id/draft-dthakore-tls-authz-01.txt
|
||||
*/
|
||||
#define TLSEXT_AUTHZDATAFORMAT_dtcp 225
|
||||
|
||||
#define TLSEXT_MAXLEN_supplemental_data 1024*16 /* Let's limit to 16k */
|
||||
|
||||
@ -390,13 +393,6 @@ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg)
|
||||
#define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
|
||||
SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
|
||||
|
||||
/* Used by clients to process audit proofs. */
|
||||
#define SSL_CTX_set_tlsext_authz_server_audit_proof_cb(ctx, cb) \
|
||||
SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB,(void (*)(void))cb)
|
||||
|
||||
#define SSL_CTX_set_tlsext_authz_server_audit_proof_cb_arg(ctx, arg) \
|
||||
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG, 0, arg);
|
||||
|
||||
#ifndef OPENSSL_NO_HEARTBEATS
|
||||
#define SSL_TLSEXT_HB_ENABLED 0x01
|
||||
#define SSL_TLSEXT_HB_DONT_SEND_REQUESTS 0x02
|
||||
|
Loading…
x
Reference in New Issue
Block a user