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.
Changes between 1.0.x and 1.1.0 [xx XXX xxxx]
+ *) 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
"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_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
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);
case 16:
str_details1 = ", ClientKeyExchange";
break;
+ case 23:
+ str_details1 = ", SupplementalData";
+ break;
case 20:
str_details1 = ", Finished";
break;
#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;
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;
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";
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");
# ifndef OPENSSL_NO_NEXTPROTONEG
BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
BIO_printf(bio_err," -alpn arg - enable ALPN extension, considering named protocols supported (comma-separated list)\n");
# endif
-#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");
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)
}
#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);
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)
{
- BIO_printf(bio_c_out, "No audit proof found.\n");
+ 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
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,
#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
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" \
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;
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;
}
#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))
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))
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);
if (next_proto.data)
}
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
+
#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
/* Hack some long ENGINE names */
#undef ENGINE_get_default_BN_mod_exp_crt
[B<-sess_in filename>]
[B<-rand file(s)>]
[B<-serverinfo types>]
+[B<-auth>]
+[B<-auth_require_reneg>]
=head1 DESCRIPTION
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
[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
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
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
}
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;
#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;
}
}
#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;
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,
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)
{
{
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,
&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;
}
#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,
if (!ok) return((int)n);
p = (unsigned char *)s->init_msg;
-
+ d = p;
/* The message cannot be empty */
if (n < 3)
{
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;
- }
- /* 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;
+ n2s(p, supp_data_entry_type);
+ n2s(p, supp_data_entry_len);
+ //if there is a callback for this supp data type, send it
+ for (i=0; i < s->ctx->cli_supp_data_records_count; i++)
+ {
+ if (s->ctx->cli_supp_data_records[i].supp_data_type == supp_data_entry_type && s->ctx->cli_supp_data_records[i].fn1)
+ {
+ cb_retval = s->ctx->cli_supp_data_records[i].fn1(s, supp_data_entry_type, p, supp_data_entry_len, &al, s->ctx->cli_supp_data_records[i].arg);
+ if (cb_retval == 0)
+ {
+ SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA, ERR_R_SSL_LIB);
+ goto f_err;
+ }
+ }
+ }
+ p+=supp_data_entry_len;
}
- s->session->audit_proof_length = proof_len;
- s->session->audit_proof = new_proof;
- memcpy(s->session->audit_proof, p, proof_len);
-
- /* Got the proof, but can't verify it yet. */
return 1;
f_err:
ssl3_send_alert(s,SSL3_AL_FATAL,al);
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
}
#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);
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 :-) */
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
case SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB:
{
#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;
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) */
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)
{
&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
}
# endif
-int tls1_send_server_supplemental_data(SSL *s)
+int tls1_send_server_supplemental_data(SSL *s, int *skip)
{
- size_t length = 0;
- const unsigned char *authz, *orig_authz;
- unsigned char *p;
- size_t authz_length, i;
-
- if (s->state != SSL3_ST_SW_SUPPLEMENTAL_DATA_A)
- return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+ if (s->ctx->srv_supp_data_records_count)
+ {
+ unsigned char *p = NULL;
+ unsigned char *size_loc = NULL;
+ srv_supp_data_record *record = NULL;
+ size_t length = 0;
+ size_t i = 0;
+
+ for (i = 0; i < s->ctx->srv_supp_data_records_count; i++)
+ {
+ const unsigned char *out = NULL;
+ unsigned short outlen = 0;
+ int cb_retval = 0;
+ record = &s->ctx->srv_supp_data_records[i];
+
+ /* NULL callback or -1 omits supp data entry */
+ if (!record->fn1)
+ continue;
+ cb_retval = record->fn1(s, record->supp_data_type,
+ &out, &outlen,
+ record->arg);
+ if (cb_retval == -1)
+ continue; /* skip this supp data entry */
+ if (cb_retval == 0)
+ {
+ SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
+ return 0;
+ }
+ if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length)
+ {
+ SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
+ return 0;
+ }
+ //write supp data entry...
+ //if first entry, write handshake message type
+ //jump back to write length at end
+ if (length == 0)
+ {
+ //1 byte message type + 3 bytes for message length
+ if (!BUF_MEM_grow_clean(s->init_buf, 4))
+ {
+ SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
+ return 0;
+ }
+ p = (unsigned char *)s->init_buf->data;
+ *(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
+ //hold on to length field to update later
+ size_loc = p;
+ //skip over handshake length field (3 bytes) and supp_data length field (3 bytes)
+ p += 3 + 3;
+ length += 1 +3 +3;
+ }
+ //2 byte supp data type + 2 byte length + outlen
+ if (!BUF_MEM_grow(s->init_buf, outlen + 4))
+ {
+ SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
+ return 0;
+ }
+ s2n(record->supp_data_type, p);
+ s2n(outlen, p);
+ memcpy(p, out, outlen);
+ //update length to supp data type (2 bytes) + supp data length (2 bytes) + supp data
+ length += (outlen + 4);
+ p += outlen;
+ }
+ if (length > 0)
+ {
+ //write handshake length
+ l2n3(length - 4, size_loc);
+ //supp_data length
+ l2n3(length - 7, size_loc);
+ s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B;
+ s->init_num = length;
+ s->init_off = 0;
- orig_authz = authz = ssl_get_authz_data(s, &authz_length);
- if (authz == NULL)
- {
- /* This should never occur. */
- return 0;
+ return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+ }
}
- /* First we walk over the authz data to see how long the handshake
- * message will be. */
- for (i = 0; i < authz_length; i++)
- {
- unsigned short len;
- unsigned char type;
+ //no supp data message sent
+ *skip = 1;
+ s->init_num = 0;
+ s->init_off = 0;
+ return 1;
+ }
- type = *(authz++);
- n2s(authz, len);
- /* n2s increments authz by 2*/
- i += 2;
+int tls1_get_client_supplemental_data(SSL *s)
+ {
+ int al = 0;
+ int cb_retval = 0;
+ int ok;
+ long n;
+ const unsigned char *p, *d;
+ unsigned short supp_data_entry_type = 0;
+ unsigned long supp_data_entry_len = 0;
+ unsigned long supp_data_len = 0;
+ size_t i = 0;
- if (memchr(s->s3->tlsext_authz_client_types,
- type,
- s->s3->tlsext_authz_client_types_len) != NULL)
- length += 1 /* authz type */ + 2 /* length */ + len;
+ n=s->method->ssl_get_message(s,
+ SSL3_ST_SR_SUPPLEMENTAL_DATA_A,
+ SSL3_ST_SR_SUPPLEMENTAL_DATA_B,
+ SSL3_MT_SUPPLEMENTAL_DATA,
+ /* use default limit */
+ TLSEXT_MAXLEN_supplemental_data,
+ &ok);
- authz += len;
- i += len;
- }
+ if (!ok) return((int)n);
- length += 1 /* handshake type */ +
- 3 /* handshake length */ +
- 3 /* supplemental data length */ +
- 2 /* supplemental entry type */ +
- 2 /* supplemental entry length */;
+ p = (unsigned char *)s->init_msg;
+ d = p;
- if (!BUF_MEM_grow_clean(s->init_buf, length))
+ /* The message cannot be empty */
+ if (n < 3)
{
- SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
- return 0;
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
+ goto f_err;
}
-
- p = (unsigned char *)s->init_buf->data;
- *(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
- /* Handshake length */
- l2n3(length - 4, p);
- /* Length of supplemental data */
- l2n3(length - 7, p);
- /* Supplemental data type */
- s2n(TLSEXT_SUPPLEMENTALDATATYPE_authz_data, p);
- /* Its length */
- s2n(length - 11, p);
-
- authz = orig_authz;
-
- /* Walk over the authz again and append the selected elements. */
- for (i = 0; i < authz_length; i++)
+ n2l3(p, supp_data_len);
+ while (p<d+supp_data_len)
{
- 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)
+ n2s(p, supp_data_entry_type);
+ n2s(p, supp_data_entry_len);
+ //if there is a callback for this supp data type, send it
+ for (i=0; i < s->ctx->srv_supp_data_records_count; i++)
{
- *(p++) = type;
- s2n(len, p);
- memcpy(p, authz, len);
- p += len;
+ if (s->ctx->srv_supp_data_records[i].supp_data_type == supp_data_entry_type && s->ctx->srv_supp_data_records[i].fn2)
+ {
+ cb_retval = s->ctx->srv_supp_data_records[i].fn2(s, supp_data_entry_type, p, supp_data_entry_len, &al, s->ctx->srv_supp_data_records[i].arg);
+ if (cb_retval == 0)
+ {
+ SSLerr(SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA, ERR_R_SSL_LIB);
+ goto f_err;
+ }
+ }
}
-
- authz += len;
- i += len;
+ p+=supp_data_entry_len;
}
-
- s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B;
- s->init_num = length;
- s->init_off = 0;
-
- return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+ return 1;
+f_err:
+ ssl3_send_alert(s,SSL3_AL_FATAL,al);
+ return -1;
}
#endif
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
#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
};
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;
-
/* Arrays containing the callbacks for custom TLS Extensions. */
custom_cli_ext_record *custom_cli_ext_records;
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
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
#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
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);
#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);
/* 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 335
#define SSL_F_CLIENT_CERTIFICATE 100
#define SSL_F_CLIENT_FINISHED 167
#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
#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
#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
#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
#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
#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
#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
#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
#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)
#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)
#define SSL3_ST_SR_CLNT_HELLO_A (0x110|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT)
+#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)
#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
#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
}
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. */
cpk->chain = NULL;
}
#ifndef OPENSSL_NO_TLSEXT
- if (cpk->authz)
- {
- OPENSSL_free(cpk->authz);
- cpk->authz = NULL;
- }
if (cpk->serverinfo)
{
OPENSSL_free(cpk->serverinfo);
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"},
{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"},
{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"},
{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"},
{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"},
{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}
{
{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"},
{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"},
{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"},
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,
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));
#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)
}
#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)
{
/* 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)
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
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
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)
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;
#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,
}
}
-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)
{
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;
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)
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;
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)
/* 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)
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;
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)
if (--argc < 1) goto bad;
alpn_expected = *(++argv);
}
+ else if (strcmp(*argv,"-suppdata") == 0)
+ {
+ suppdata = 1;
+ }
else
{
fprintf(stderr,"unknown option %s\n",*argv);
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)
{
goto err;
}
#endif
+ if (suppdata_error < 0)
+ {
+ ret = 1;
+ goto err;
+ }
if (verify_serverinfo() < 0)
{
ret = 1;
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)
{
}
#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)
{
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
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 */
/* 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 */
#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