summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGES4
-rwxr-xr-xConfigure5
-rw-r--r--apps/s_apps.h4
-rw-r--r--apps/s_cb.c3
-rw-r--r--apps/s_client.c137
-rw-r--r--apps/s_server.c146
-rw-r--r--crypto/symhacks.h8
-rw-r--r--doc/apps/s_client.pod11
-rw-r--r--doc/apps/s_server.pod18
-rw-r--r--ssl/s23_clnt.c4
-rw-r--r--ssl/s3_clnt.c239
-rw-r--r--ssl/s3_lib.c17
-rw-r--r--ssl/s3_srvr.c238
-rw-r--r--ssl/ssl.h124
-rw-r--r--ssl/ssl3.h36
-rw-r--r--ssl/ssl_cert.c22
-rw-r--r--ssl/ssl_err.c12
-rw-r--r--ssl/ssl_lib.c85
-rw-r--r--ssl/ssl_locl.h13
-rw-r--r--ssl/ssl_rsa.c233
-rw-r--r--ssl/ssl_sess.c11
-rw-r--r--ssl/ssl_stat.c8
-rw-r--r--ssl/ssltest.c141
-rw-r--r--ssl/t1_lib.c193
-rw-r--r--ssl/tls1.h14
25 files changed, 919 insertions, 807 deletions
diff --git a/CHANGES b/CHANGES
index 0b49a88c91..45d7596ac1 100644
--- a/CHANGES
+++ b/CHANGES
@@ -31,6 +31,10 @@
MGF1 digest and OAEP label.
[Steve Henson]
+ *) Add callbacks supporting generation and retrieval of supplemental
+ data entries.
+ [Scott Deboy <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
diff --git a/Configure b/Configure
index 80ec25a62b..70bfe14e37 100755
--- a/Configure
+++ b/Configure
@@ -593,7 +593,10 @@ my %table=(
"darwin64-ppc-cc","cc:-arch ppc64 -O3 -DB_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc64_asm}:osx64:dlfcn:darwin-shared:-fPIC -fno-common:-arch ppc64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"darwin-i386-cc","cc:-arch i386 -O3 -fomit-frame-pointer -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:".eval{my $asm=$x86_asm;$asm=~s/cast\-586\.o//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"debug-darwin-i386-cc","cc:-arch i386 -g3 -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:${x86_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
+"debug-darwin64-x86_64-cc","cc:-arch x86_64 -ggdb -g2 -O0 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"darwin64-x86_64-cc","cc:-arch x86_64 -O3 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$x86_64_asm;$asm=~s/rc4\-[^:]+//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
+"debug-darwin64-x86_64-cc","cc:-arch x86_64 -ggdb -g2 -O0 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
+"darwin64-x86_64-cc","cc:-arch x86_64 -O3 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"debug-darwin-ppc-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DB_ENDIAN -g -Wall -O::-D_REENTRANT:MACOSX::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
# iPhoneOS/iOS
"iphoneos-cross","llvm-gcc:-O3 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fomit-frame-pointer -fno-common::-D_REENTRANT:iOS:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
@@ -2008,7 +2011,7 @@ BEGIN
VALUE "ProductVersion", "$version\\0"
// Optional:
//VALUE "Comments", "\\0"
- VALUE "LegalCopyright", "Copyright © 1998-2005 The OpenSSL Project. Copyright © 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
+ VALUE "LegalCopyright", "Copyright � 1998-2005 The OpenSSL Project. Copyright � 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
//VALUE "LegalTrademarks", "\\0"
//VALUE "PrivateBuild", "\\0"
//VALUE "SpecialBuild", "\\0"
diff --git a/apps/s_apps.h b/apps/s_apps.h
index ce5a763da8..f46d1ebe45 100644
--- a/apps/s_apps.h
+++ b/apps/s_apps.h
@@ -156,10 +156,6 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
STACK_OF(X509) *chain, int build_chain);
-# ifndef OPENSSL_NO_TLSEXT
-int set_cert_key_and_authz(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
- unsigned char *authz, size_t authz_length);
-# endif
int ssl_print_sigalgs(BIO *out, SSL *s);
int ssl_print_point_formats(BIO *out, SSL *s);
int ssl_print_curves(BIO *out, SSL *s, int noshared);
diff --git a/apps/s_cb.c b/apps/s_cb.c
index 78f1d93c6c..040ffaf186 100644
--- a/apps/s_cb.c
+++ b/apps/s_cb.c
@@ -876,6 +876,9 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *
case 16:
str_details1 = ", ClientKeyExchange";
break;
+ case 23:
+ str_details1 = ", SupplementalData";
+ break;
case 20:
str_details1 = ", Finished";
break;
diff --git a/apps/s_client.c b/apps/s_client.c
index 3d607ea90d..715e063a65 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -203,7 +203,6 @@ static int c_debug=0;
#ifndef OPENSSL_NO_TLSEXT
static int c_tlsextdebug=0;
static int c_status_req=0;
-static int c_proof_debug=0;
#endif
static int c_msg=0;
static int c_showcerts=0;
@@ -215,7 +214,8 @@ static void sc_usage(void);
static void print_stuff(BIO *berr,SSL *con,int full);
#ifndef OPENSSL_NO_TLSEXT
static int ocsp_resp_cb(SSL *s, void *arg);
-static int audit_proof_cb(SSL *s, void *arg);
+static int c_auth = 0;
+static int c_auth_require_reneg = 0;
#endif
static BIO *bio_c_out=NULL;
static BIO *bio_c_msg=NULL;
@@ -223,6 +223,35 @@ static int c_quiet=0;
static int c_ign_eof=0;
static int c_brief=0;
+#ifndef OPENSSL_NO_TLSEXT
+
+static const unsigned char *most_recent_supplemental_data;
+static size_t most_recent_supplemental_data_length;
+
+static int server_provided_server_authz = 0;
+static int server_provided_client_authz = 0;
+
+static const unsigned char auth_ext_data[]={TLSEXT_AUTHZDATAFORMAT_dtcp};
+
+static int suppdata_cb(SSL *s, unsigned short supp_data_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg);
+
+static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
+ const unsigned char **out,
+ unsigned short *outlen, void *arg);
+
+static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
+ const unsigned char **out, unsigned short *outlen,
+ void *arg);
+
+static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg);
+#endif
+
#ifndef OPENSSL_NO_PSK
/* Default PSK identity and key */
static char *psk_identity="Client_identity";
@@ -365,15 +394,14 @@ static void sc_usage(void)
BIO_printf(bio_err," -tlsextdebug - hex dump of all TLS extensions received\n");
BIO_printf(bio_err," -status - request certificate status from server\n");
BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n");
- BIO_printf(bio_err," -proof_debug - request an audit proof and print its hex dump\n");
+ BIO_printf(bio_err," -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n");
+ BIO_printf(bio_err," -auth - send and receive RFC 5878 TLS auth extensions and supplemental data\n");
+ BIO_printf(bio_err," -auth_require_reneg - Do not send TLS auth extensions until renegotiation\n");
+#endif
# ifndef OPENSSL_NO_NEXTPROTONEG
BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
# endif
BIO_printf(bio_err," -alpn arg - enable ALPN extension, considering named protocols supported (comma-separated list)\n");
-#ifndef OPENSSL_NO_TLSEXT
- BIO_printf(bio_err," -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n");
-#endif
-#endif
BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
BIO_printf(bio_err," -keymatexport label - Export keying material using label\n");
@@ -822,8 +850,10 @@ static char *jpake_secret = NULL;
c_tlsextdebug=1;
else if (strcmp(*argv,"-status") == 0)
c_status_req=1;
- else if (strcmp(*argv,"-proof_debug") == 0)
- c_proof_debug=1;
+ else if (strcmp(*argv,"-auth") == 0)
+ c_auth = 1;
+ else if (strcmp(*argv,"-auth_require_reneg") == 0)
+ c_auth_require_reneg = 1;
#endif
#ifdef WATT32
else if (strcmp(*argv,"-wdebug") == 0)
@@ -1397,9 +1427,12 @@ bad:
}
#endif
- if (c_proof_debug)
- SSL_CTX_set_tlsext_authz_server_audit_proof_cb(ctx,
- audit_proof_cb);
+ if (c_auth)
+ {
+ SSL_CTX_set_custom_cli_ext(ctx, TLSEXT_TYPE_client_authz, authz_tlsext_generate_cb, authz_tlsext_cb, bio_err);
+ SSL_CTX_set_custom_cli_ext(ctx, TLSEXT_TYPE_server_authz, authz_tlsext_generate_cb, authz_tlsext_cb, bio_err);
+ SSL_CTX_set_cli_supp_data(ctx, TLSEXT_SUPPLEMENTALDATATYPE_authz_data, suppdata_cb, auth_suppdata_generate_cb, bio_err);
+ }
#endif
con=SSL_new(ctx);
@@ -2392,26 +2425,76 @@ static int ocsp_resp_cb(SSL *s, void *arg)
return 1;
}
-static int audit_proof_cb(SSL *s, void *arg)
+static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg)
{
- const unsigned char *proof;
- size_t proof_len;
- size_t i;
- SSL_SESSION *sess = SSL_get_session(s);
-
- proof = SSL_SESSION_get_tlsext_authz_server_audit_proof(sess,
- &proof_len);
- if (proof != NULL)
+ if (TLSEXT_TYPE_server_authz == ext_type)
{
- BIO_printf(bio_c_out, "Audit proof: ");
- for (i = 0; i < proof_len; ++i)
- BIO_printf(bio_c_out, "%02X", proof[i]);
- BIO_printf(bio_c_out, "\n");
+ server_provided_server_authz = (memchr(in,
+ TLSEXT_AUTHZDATAFORMAT_dtcp,
+ inlen) != NULL);
}
- else
+
+ if (TLSEXT_TYPE_client_authz == ext_type)
+ {
+ server_provided_client_authz = (memchr(in,
+ TLSEXT_AUTHZDATAFORMAT_dtcp,
+ inlen) != NULL);
+ }
+
+ return 1;
+ }
+
+static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
+ const unsigned char **out, unsigned short *outlen,
+ void *arg)
+ {
+ if (c_auth)
+ {
+ if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s)))
+ {
+ *out = auth_ext_data;
+ *outlen = 1;
+ return 1;
+ }
+ }
+ //no auth extension to send
+ return -1;
+ }
+
+static int suppdata_cb(SSL *s, unsigned short supp_data_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg)
+ {
+ if (supp_data_type == TLSEXT_SUPPLEMENTALDATATYPE_authz_data)
{
- BIO_printf(bio_c_out, "No audit proof found.\n");
+ most_recent_supplemental_data = in;
+ most_recent_supplemental_data_length = inlen;
}
return 1;
}
+
+static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
+ const unsigned char **out,
+ unsigned short *outlen, void *arg)
+ {
+ unsigned char *result;
+ if (c_auth && server_provided_client_authz && server_provided_server_authz)
+ {
+ if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s)))
+ {
+ result = OPENSSL_malloc(10);
+ memcpy(result, "5432154321", 10);
+ *out = result;
+ *outlen = 10;
+ return 1;
+ }
+ }
+ //no supplemental data to send
+ return -1;
+ }
+
#endif
diff --git a/apps/s_server.c b/apps/s_server.c
index 6aa4161b64..42e2133308 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -224,6 +224,18 @@ static DH *get_dh512(void);
static void s_server_init(void);
#endif
+#ifndef OPENSSL_NO_TLSEXT
+
+static const unsigned char auth_ext_data[]={TLSEXT_AUTHZDATAFORMAT_dtcp};
+
+static const unsigned char *most_recent_supplemental_data;
+static size_t most_recent_supplemental_data_length;
+
+static int client_provided_server_authz = 0;
+static int client_provided_client_authz = 0;
+
+#endif
+
#ifndef OPENSSL_NO_DH
static unsigned char dh512_p[]={
0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
@@ -315,10 +327,29 @@ static int cert_chain = 0;
#endif
#ifndef OPENSSL_NO_TLSEXT
-static BIO *authz_in = NULL;
-static const char *s_authz_file = NULL;
+static int suppdata_cb(SSL *s, unsigned short supp_data_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg);
+
+static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
+ const unsigned char **out,
+ unsigned short *outlen, void *arg);
+
+static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
+ const unsigned char **out, unsigned short *outlen,
+ void *arg);
+
+static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg);
+
static BIO *serverinfo_in = NULL;
static const char *s_serverinfo_file = NULL;
+
+static int c_auth = 0;
+static int c_auth_require_reneg = 0;
#endif
#ifndef OPENSSL_NO_PSK
@@ -482,10 +513,12 @@ static void sv_usage(void)
BIO_printf(bio_err," -Verify arg - turn on peer certificate verification, must have a cert.\n");
BIO_printf(bio_err," -cert arg - certificate file to use\n");
BIO_printf(bio_err," (default is %s)\n",TEST_CERT);
- BIO_printf(bio_err," -authz arg - binary authz file for certificate\n");
#ifndef OPENSSL_NO_TLSEXT
BIO_printf(bio_err," -serverinfo arg - PEM serverinfo file for certificate\n");
+ BIO_printf(bio_err," -auth - send and receive RFC 5878 TLS auth extensions and supplemental data\n");
+ BIO_printf(bio_err," -auth_require_reneg - Do not send TLS auth extensions until renegotiation\n");
#endif
+ BIO_printf(bio_err," -no_resumption_on_reneg - set SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION flag\n");
BIO_printf(bio_err," -crl_check - check the peer certificate has not been revoked by its CA.\n" \
" The CRL(s) are appended to the certificate file\n");
BIO_printf(bio_err," -crl_check_all - check the peer certificate has not been revoked by its CA\n" \
@@ -1018,6 +1051,7 @@ int MAIN(int argc, char *argv[])
EVP_PKEY *s_key = NULL, *s_dkey = NULL;
int no_cache = 0, ext_cache = 0;
int rev = 0, naccept = -1;
+ int c_no_resumption_on_reneg = 0;
#ifndef OPENSSL_NO_TLSEXT
EVP_PKEY *s_key2 = NULL;
X509 *s_cert2 = NULL;
@@ -1132,17 +1166,24 @@ int MAIN(int argc, char *argv[])
else if (strcmp(*argv,"-crl_download") == 0)
crl_download = 1;
#ifndef OPENSSL_NO_TLSEXT
- else if (strcmp(*argv,"-authz") == 0)
- {
- if (--argc < 1) goto bad;
- s_authz_file = *(++argv);
- }
else if (strcmp(*argv,"-serverinfo") == 0)
{
if (--argc < 1) goto bad;
s_serverinfo_file = *(++argv);
}
+ else if (strcmp(*argv,"-auth") == 0)
+ {
+ c_auth = 1;
+ }
#endif
+ else if (strcmp(*argv, "-no_resumption_on_reneg") == 0)
+ {
+ c_no_resumption_on_reneg = 1;
+ }
+ else if (strcmp(*argv,"-auth_require_reneg") == 0)
+ {
+ c_auth_require_reneg = 1;
+ }
else if (strcmp(*argv,"-certform") == 0)
{
if (--argc < 1) goto bad;
@@ -1918,17 +1959,25 @@ bad:
}
#endif
+ if (c_no_resumption_on_reneg)
+ {
+ SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
+ }
if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain))
goto end;
#ifndef OPENSSL_NO_TLSEXT
- if (s_authz_file != NULL && !SSL_CTX_use_authz_file(ctx, s_authz_file))
- goto end;
if (s_serverinfo_file != NULL
&& !SSL_CTX_use_serverinfo_file(ctx, s_serverinfo_file))
{
ERR_print_errors(bio_err);
goto end;
}
+ if (c_auth)
+ {
+ SSL_CTX_set_custom_srv_ext(ctx, TLSEXT_TYPE_client_authz, authz_tlsext_cb, authz_tlsext_generate_cb, bio_err);
+ SSL_CTX_set_custom_srv_ext(ctx, TLSEXT_TYPE_server_authz, authz_tlsext_cb, authz_tlsext_generate_cb, bio_err);
+ SSL_CTX_set_srv_supp_data(ctx, TLSEXT_SUPPLEMENTALDATATYPE_authz_data, auth_suppdata_generate_cb, suppdata_cb, bio_err);
+ }
#endif
#ifndef OPENSSL_NO_TLSEXT
if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2, NULL, build_chain))
@@ -2097,8 +2146,6 @@ end:
X509_free(s_cert2);
if (s_key2)
EVP_PKEY_free(s_key2);
- if (authz_in != NULL)
- BIO_free(authz_in);
if (serverinfo_in != NULL)
BIO_free(serverinfo_in);
# ifndef OPENSSL_NO_NEXTPROTONEG
@@ -3494,3 +3541,78 @@ static void free_sessions(void)
}
first = NULL;
}
+
+#ifndef OPENSSL_NO_TLSEXT
+static int authz_tlsext_cb(SSL *s, unsigned short ext_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg)
+ {
+ if (TLSEXT_TYPE_server_authz == ext_type)
+ {
+ client_provided_server_authz = (memchr(in,
+ TLSEXT_AUTHZDATAFORMAT_dtcp,
+ inlen) != NULL);
+ }
+
+ if (TLSEXT_TYPE_client_authz == ext_type)
+ {
+ client_provided_client_authz = (memchr(in,
+ TLSEXT_AUTHZDATAFORMAT_dtcp,
+ inlen) != NULL);
+ }
+
+ return 1;
+ }
+
+static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type,
+ const unsigned char **out, unsigned short *outlen,
+ void *arg)
+ {
+ if (c_auth && client_provided_client_authz && client_provided_server_authz)
+ {
+ if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s)))
+ {
+ *out = auth_ext_data;
+ *outlen = 1;
+ return 1;
+ }
+ }
+ //no auth extension to send
+ return -1;
+ }
+
+static int suppdata_cb(SSL *s, unsigned short supp_data_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg)
+ {
+ if (supp_data_type == TLSEXT_SUPPLEMENTALDATATYPE_authz_data)
+ {
+ most_recent_supplemental_data = in;
+ most_recent_supplemental_data_length = inlen;
+ }
+ return 1;
+ }
+
+static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type,
+ const unsigned char **out,
+ unsigned short *outlen, void *arg)
+ {
+ unsigned char *result;
+ if (c_auth && client_provided_client_authz && client_provided_server_authz)
+ {
+ if (!c_auth_require_reneg || (c_auth_require_reneg && SSL_num_renegotiations(s)))
+ {
+ result = OPENSSL_malloc(10);
+ memcpy(result, "1234512345", 10);
+ *out = result;
+ *outlen = 10;
+ return 1;
+ }
+ }
+ //no supplemental data to send
+ return -1;
+ }
+#endif
+
diff --git a/crypto/symhacks.h b/crypto/symhacks.h
index 66733a302b..5774d24561 100644
--- a/crypto/symhacks.h
+++ b/crypto/symhacks.h
@@ -207,12 +207,12 @@
#undef tls1_send_server_supplemental_data
#define tls1_send_server_supplemental_data tls1_send_server_suppl_data
+#undef tls1_send_client_supplemental_data
+#define tls1_send_client_supplemental_data tls1_send_client_suppl_data
#undef tls1_get_server_supplemental_data
#define tls1_get_server_supplemental_data tls1_get_server_suppl_data
-
-#undef SSL_SESSION_get_tlsext_authz_server_audit_proof
-#define SSL_SESSION_get_tlsext_authz_server_audit_proof \
- S_SES_get_tlsx_auz_srvr_aud_prf
+#undef tls1_get_client_supplemental_data
+#define tls1_get_client_supplemental_data tls1_get_client_suppl_data
#undef ssl3_cbc_record_digest_supported
#define ssl3_cbc_record_digest_supported ssl3_cbc_record_digest_support
diff --git a/doc/apps/s_client.pod b/doc/apps/s_client.pod
index 8755930cec..ab3547d321 100644
--- a/doc/apps/s_client.pod
+++ b/doc/apps/s_client.pod
@@ -44,6 +44,8 @@ B<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
diff --git a/doc/apps/s_server.pod b/doc/apps/s_server.pod
index c1b40321c6..b0d5d28428 100644
--- a/doc/apps/s_server.pod
+++ b/doc/apps/s_server.pod
@@ -55,7 +55,9 @@ B<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
diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c
index 710d4f228e..a101bce161 100644
--- a/ssl/s23_clnt.c
+++ b/ssl/s23_clnt.c
@@ -362,10 +362,10 @@ static int ssl23_client_hello(SSL *s)
if (s->ctx->tlsext_opaque_prf_input_callback != 0 || s->tlsext_opaque_prf_input != NULL)
ssl2_compat = 0;
#endif
- if (s->ctx->tlsext_authz_server_audit_proof_cb != NULL)
- ssl2_compat = 0;
if (s->ctx->custom_cli_ext_records_count != 0)
ssl2_compat = 0;
+ if (s->ctx->cli_supp_data_records_count != 0)
+ ssl2_compat = 0;
}
#endif
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 9e3c847de9..d7178793ab 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -307,13 +307,6 @@ int ssl3_connect(SSL *s)
}
else
{
-#ifndef OPENSSL_NO_TLSEXT
- /* The server hello indicated that
- * an audit proof would follow. */
- if (s->s3->tlsext_authz_server_promised)
- s->state=SSL3_ST_CR_SUPPLEMENTAL_DATA_A;
- else
-#endif
s->state=SSL3_ST_CR_CERT_A;
}
s->init_num=0;
@@ -332,6 +325,12 @@ int ssl3_connect(SSL *s)
#ifndef OPENSSL_NO_TLSEXT
ret=ssl3_check_finished(s);
if (ret <= 0) goto end;
+ if (ret == 3)
+ {
+ s->state=SSL3_ST_CR_SUPPLEMENTAL_DATA_A;
+ s->init_num=0;
+ break;
+ }
if (ret == 2)
{
s->hit = 1;
@@ -410,10 +409,14 @@ int ssl3_connect(SSL *s)
}
}
#endif
+#ifndef OPENSSL_NO_TLSEXT
+ s->state=SSL3_ST_CW_SUPPLEMENTAL_DATA_A;
+#else
if (s->s3->tmp.cert_req)
s->state=SSL3_ST_CW_CERT_A;
else
s->state=SSL3_ST_CW_KEY_EXCH_A;
+#endif
s->init_num=0;
break;
@@ -520,6 +523,19 @@ int ssl3_connect(SSL *s)
break;
#endif
+#ifndef OPENSSL_NO_TLSEXT
+ case SSL3_ST_CW_SUPPLEMENTAL_DATA_A:
+ case SSL3_ST_CW_SUPPLEMENTAL_DATA_B:
+ ret = tls1_send_client_supplemental_data(s, &skip);
+ if (ret <= 0) goto end;
+ if (s->s3->tmp.cert_req)
+ s->state=SSL3_ST_CW_CERT_A;
+ else
+ s->state=SSL3_ST_CW_KEY_EXCH_A;
+ s->init_num=0;
+ break;
+#endif
+
case SSL3_ST_CW_FINISHED_A:
case SSL3_ST_CW_FINISHED_B:
ret=ssl3_send_finished(s,
@@ -1353,21 +1369,6 @@ int ssl3_get_server_certificate(SSL *s)
s->session->verify_result = s->verify_result;
x=NULL;
-#ifndef OPENSSL_NO_TLSEXT
- /* Check the audit proof. */
- if (s->ctx->tlsext_authz_server_audit_proof_cb)
- {
- ret = s->ctx->tlsext_authz_server_audit_proof_cb(s,
- s->ctx->tlsext_authz_server_audit_proof_cb_arg);
- if (ret <= 0)
- {
- al = SSL_AD_BAD_CERTIFICATE;
- SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_INVALID_AUDIT_PROOF);
- goto f_err;
- }
- }
-
-#endif
ret=1;
if (0)
{
@@ -3568,11 +3569,9 @@ int ssl3_check_finished(SSL *s)
{
int ok;
long n;
- /* If we have no ticket it cannot be a resumed session. */
- if (!s->session->tlsext_tick)
- return 1;
- /* this function is called when we really expect a Certificate
- * message, so permit appropriate message length */
+/* Read the message to see if it is supplemental data, regardless if there is a session ticket
+ this function is called when we really expect a Certificate
+ message, so permit appropriate message length */
n=s->method->ssl_get_message(s,
SSL3_ST_CR_CERT_A,
SSL3_ST_CR_CERT_B,
@@ -3581,6 +3580,14 @@ int ssl3_check_finished(SSL *s)
&ok);
if (!ok) return((int)n);
s->s3->tmp.reuse_message = 1;
+
+ if (s->s3->tmp.message_type == SSL3_MT_SUPPLEMENTAL_DATA)
+ {
+ return 3;
+ }
+ /* If we have no ticket it cannot be a resumed session. */
+ if (!s->session->tlsext_tick)
+ return 1;
if ((s->s3->tmp.message_type == SSL3_MT_FINISHED)
|| (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET))
return 2;
@@ -3608,15 +3615,99 @@ int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
}
#ifndef OPENSSL_NO_TLSEXT
+int tls1_send_client_supplemental_data(SSL *s, int *skip)
+ {
+ if (s->ctx->cli_supp_data_records_count)
+ {
+ unsigned char *p = NULL;
+ unsigned char *size_loc = NULL;
+ cli_supp_data_record *record = NULL;
+ size_t length = 0;
+ size_t i = 0;
+
+ for (i = 0; i < s->ctx->cli_supp_data_records_count; i++)
+ {
+ const unsigned char *out = NULL;
+ unsigned short outlen = 0;
+ int cb_retval = 0;
+ record = &s->ctx->cli_supp_data_records[i];
+
+ /* NULL callback or -1 omits supp data entry*/
+ if (!record->fn2)
+ continue;
+ cb_retval = record->fn2(s, record->supp_data_type,
+ &out, &outlen,
+ record->arg);
+ if (cb_retval == -1)
+ continue; /* skip this supp data entry */
+ if (cb_retval == 0)
+ {
+ SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
+ return 0;
+ }
+ if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length)
+ {
+ SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
+ return 0;
+ }
+ //if first entry, write handshake message type
+ if (length == 0)
+ {
+ if (!BUF_MEM_grow_clean(s->init_buf, 4))
+ {
+ SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
+ return 0;
+ }
+ p = (unsigned char *)s->init_buf->data;
+ *(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
+ //update message length when all callbacks complete
+ size_loc = p;
+ //skip over handshake length field (3 bytes) and supp_data length field (3 bytes)
+ p += 3 + 3;
+ length += 1 +3 +3;
+ }
+ if (!BUF_MEM_grow(s->init_buf, outlen + 4))
+ {
+ SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
+ return 0;
+ }
+ s2n(record->supp_data_type, p);
+ s2n(outlen, p);
+ memcpy(p, out, outlen);
+ length += (outlen + 4);
+ p += outlen;
+ }
+ if (length > 0)
+ {
+ //write handshake length
+ l2n3(length - 4, size_loc);
+ //supp_data length
+ l2n3(length - 7, size_loc);
+ s->state = SSL3_ST_CW_SUPPLEMENTAL_DATA_B;
+ s->init_num = length;
+ s->init_off = 0;
+ return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+ }
+ }
+
+ //no supp data message sent
+ *skip = 1;
+ s->init_num = 0;
+ s->init_off = 0;
+ return 1;
+ }
+
int tls1_get_server_supplemental_data(SSL *s)
{
- int al;
+ int al = 0;
int ok;
- unsigned long supp_data_len, authz_data_len;
long n;
- unsigned short supp_data_type, authz_data_type, proof_len;
- const unsigned char *p;
- unsigned char *new_proof;
+ const unsigned char *p, *d;
+ unsigned short supp_data_entry_type = 0;
+ unsigned long supp_data_entry_len = 0;
+ unsigned long supp_data_len = 0;
+ size_t i;
+ int cb_retval = 0;
n=s->method->ssl_get_message(s,
SSL3_ST_CR_SUPPLEMENTAL_DATA_A,
@@ -3629,7 +3720,7 @@ int tls1_get_server_supplemental_data(SSL *s)
if (!ok) return((int)n);
p = (unsigned char *)s->init_msg;
-
+ d = p;
/* The message cannot be empty */
if (n < 3)
{
@@ -3637,72 +3728,26 @@ int tls1_get_server_supplemental_data(SSL *s)
SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
goto f_err;
}
- /* Length of supplemental data */
- n2l3(p,supp_data_len);
- n -= 3;
- /* We must have at least one supplemental data entry