Add callbacks supporting generation and retrieval of supplemental data entries, facil...
authorScott Deboy <sdeboy@secondstryke.com>
Tue, 18 Jun 2013 21:34:38 +0000 (14:34 -0700)
committerBen Laurie <ben@links.org>
Fri, 6 Sep 2013 12:59:13 +0000 (13:59 +0100)
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.

25 files changed:
CHANGES
Configure
apps/s_apps.h
apps/s_cb.c
apps/s_client.c
apps/s_server.c
crypto/symhacks.h
doc/apps/s_client.pod
doc/apps/s_server.pod
ssl/s23_clnt.c
ssl/s3_clnt.c
ssl/s3_lib.c
ssl/s3_srvr.c
ssl/ssl.h
ssl/ssl3.h
ssl/ssl_cert.c
ssl/ssl_err.c
ssl/ssl_lib.c
ssl/ssl_locl.h
ssl/ssl_rsa.c
ssl/ssl_sess.c
ssl/ssl_stat.c
ssl/ssltest.c
ssl/t1_lib.c
ssl/tls1.h

diff --git a/CHANGES b/CHANGES
index 166fe56..e2154a1 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,10 @@
 
  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
index d742dfc..cc5caeb 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -593,6 +593,7 @@ 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_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
index ce5a763..f46d1eb 100644 (file)
@@ -156,10 +156,6 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
 int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
 int set_cert_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);
index 69a50a4..927f9d9 100644 (file)
@@ -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;
index 2f13503..e38f16e 100644 (file)
@@ -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";
@@ -362,14 +391,13 @@ 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");
 # 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");
@@ -823,8 +851,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)
@@ -1399,9 +1429,12 @@ bad:
                }
 
 #endif
-       if (c_proof_debug)
-               SSL_CTX_set_tlsext_authz_server_audit_proof_cb(ctx,
-                                                              audit_proof_cb);
+       if (c_auth)
+               {
+               SSL_CTX_set_custom_cli_ext(ctx, TLSEXT_TYPE_client_authz, authz_tlsext_generate_cb, authz_tlsext_cb, bio_err);
+               SSL_CTX_set_custom_cli_ext(ctx, TLSEXT_TYPE_server_authz, authz_tlsext_generate_cb, authz_tlsext_cb, bio_err);
+               SSL_CTX_set_cli_supp_data(ctx, TLSEXT_SUPPLEMENTALDATATYPE_authz_data, suppdata_cb, auth_suppdata_generate_cb, bio_err);
+               }
 #endif
 
        con=SSL_new(ctx);
@@ -2395,26 +2428,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)
                {
-               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
index ae5b161..d3b2d4a 100644 (file)
@@ -225,6 +225,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,
@@ -316,10 +328,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
@@ -480,10 +511,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" \
@@ -1023,6 +1056,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;
@@ -1137,17 +1171,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;
@@ -1920,14 +1961,22 @@ 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))
@@ -2105,8 +2154,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);
        if (next_proto.data)
@@ -3514,3 +3561,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
+
index 0fec54b..036b9c8 100644 (file)
 
 #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
index a37c4e2..85e5b9c 100644 (file)
@@ -45,6 +45,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
 
@@ -272,6 +274,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
index cd167d1..ddfc27d 100644 (file)
@@ -57,7 +57,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
@@ -315,6 +317,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
index 15da654..15878c6 100644 (file)
@@ -340,10 +340,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
 
index 21e09b9..13006b7 100644 (file)
@@ -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,
@@ -1357,21 +1373,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)
                {
@@ -3563,11 +3564,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,
@@ -3576,6 +3575,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;
@@ -3603,15 +3610,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,
@@ -3624,7 +3715,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)
                {
@@ -3632,72 +3723,26 @@ int tls1_get_server_supplemental_data(SSL *s)
                SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
                goto f_err;
                }
-       /* Length of supplemental data */
-       n2l3(p,supp_data_len);
-       n -= 3;
-       /* We must have at least one supplemental data entry
-        * with type (1 byte) and length (2 bytes). */
-       if (supp_data_len != (unsigned long) n || n < 4)
+       n2l3(p, supp_data_len);
+       while (p<d+supp_data_len)
                {
-               al = SSL_AD_DECODE_ERROR;
-               SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
-               goto f_err;
-               }
-       /* 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);
index 68b1ada..321db08 100644 (file)
@@ -3029,8 +3029,6 @@ void ssl3_free(SSL *s)
        SSL_SRP_CTX_free(s);
 #endif
 #ifndef OPENSSL_NO_TLSEXT
-       if (s->s3->tlsext_authz_client_types != NULL)
-               OPENSSL_free(s->s3->tlsext_authz_client_types);
        if (s->s3->tlsext_custom_types != NULL)
                OPENSSL_free(s->s3->tlsext_custom_types);
 #endif
@@ -3078,11 +3076,6 @@ void ssl3_clear(SSL *s)
                }
 #endif
 #ifndef OPENSSL_NO_TLSEXT
-       if (s->s3->tlsext_authz_client_types != NULL)
-               {
-               OPENSSL_free(s->s3->tlsext_authz_client_types);
-               s->s3->tlsext_authz_client_types = NULL;
-               }
        if (s->s3->tlsext_custom_types != NULL)
                {
                OPENSSL_free(s->s3->tlsext_custom_types);
@@ -3892,10 +3885,6 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
        case SSL_CTRL_SET_CHAIN_CERT_STORE:
                return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg);
 
-       case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG:
-               ctx->tlsext_authz_server_audit_proof_cb_arg = parg;
-               break;
-
 #endif /* !OPENSSL_NO_TLSEXT */
 
        /* A Thawte special :-) */
@@ -4005,12 +3994,6 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
                ctx->srp_ctx.SRP_give_srp_client_pwd_callback=(char *(*)(SSL *,void *))fp;
                break;
 #endif
-
-       case SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB:
-               ctx->tlsext_authz_server_audit_proof_cb =
-                       (int (*)(SSL *, void *))fp;
-               break;
-
 #endif
        case SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB:
                {
index 28d5bed..ad3a4d8 100644 (file)
@@ -413,14 +413,8 @@ int ssl3_accept(SSL *s)
 #ifndef OPENSSL_NO_TLSEXT
                case SSL3_ST_SW_SUPPLEMENTAL_DATA_A:
                case SSL3_ST_SW_SUPPLEMENTAL_DATA_B:
-                       /* We promised to send an audit proof in the hello. */
-                       if (s->s3->tlsext_authz_promised_to_client)
-                               {
-                               ret = tls1_send_server_supplemental_data(s);
-                               if (ret <= 0) goto end;
-                               }
-                       else
-                               skip = 1;
+                       ret = tls1_send_server_supplemental_data(s, &skip);
+                       if (ret <= 0) goto end;
 
                        s->state = SSL3_ST_SW_CERT_A;
                        s->init_num = 0;
@@ -595,7 +589,16 @@ int ssl3_accept(SSL *s)
 
                        s->state=s->s3->tmp.next_state;
                        break;
-
+#ifndef OPENSSL_NO_TLSEXT
+               case SSL3_ST_SR_SUPPLEMENTAL_DATA_A:
+               case SSL3_ST_SR_SUPPLEMENTAL_DATA_B:
+                       ret=tls1_get_client_supplemental_data(s);
+                       if (ret <= 0) goto end;
+                       s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
+                       s->state=SSL3_ST_SW_FLUSH;
+                       s->init_num=0;
+                       break;
+#endif
                case SSL3_ST_SR_CERT_A:
                case SSL3_ST_SR_CERT_B:
                        /* Check for second client hello (MS SGC) */
@@ -604,6 +607,10 @@ int ssl3_accept(SSL *s)
                                goto end;
                        if (ret == 2)
                                s->state = SSL3_ST_SR_CLNT_HELLO_C;
+#ifndef OPENSSL_NO_TLSEXT
+                       else if (ret == 3)
+                               s->state = SSL3_ST_SR_SUPPLEMENTAL_DATA_A;
+#endif
                        else {
                                if (s->s3->tmp.cert_request)
                                        {
@@ -894,6 +901,12 @@ int ssl3_check_client_hello(SSL *s)
                &ok);
        if (!ok) return((int)n);
        s->s3->tmp.reuse_message = 1;
+#ifndef OPENSSL_NO_TLSEXT
+       if (s->s3->tmp.message_type == SSL3_MT_SUPPLEMENTAL_DATA)
+               {
+               return 3;
+               }
+#endif
        if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
                {
                /* We only allow the client to restart the handshake once per
@@ -3686,98 +3699,149 @@ int ssl3_get_next_proto(SSL *s)
        }
 # endif
 
-int tls1_send_server_supplemental_data(SSL *s)
+int tls1_send_server_supplemental_data(SSL *s, int *skip)
        {
-       size_t length = 0;
-       const unsigned char *authz, *orig_authz;
-       unsigned char *p;
-       size_t authz_length, i;
-
-       if (s->state != SSL3_ST_SW_SUPPLEMENTAL_DATA_A)
-               return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+       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
index 2f70067..f4caef7 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -433,6 +433,58 @@ typedef struct {
        custom_srv_ext_second_cb_fn fn2; 
        void *arg;
 } custom_srv_ext_record;
+
+/* Callbacks and structures for handling Supplemental Data:
+ *   srv_supp_data_first_cb_fn  - server sends Supplemental Data
+ *   srv_supp_data_second_cb_fn - server receives Supplemental Data
+ *   cli_supp_data_first_cb_fn  - client receives Supplemental Data
+ *   cli_supp_data_second_cb_fn - client sends Supplemental Data
+ *
+ *   All these functions return nonzero on success.  Zero will terminate
+ *   the handshake (and return a specific TLS Fatal alert, if the function
+ *   declaration has an "al" parameter).  -1 for the "sending" functions
+ *   will result in no supplemental data entry being added to the
+ *   supplemental data message for the provided supplemental data type.
+ *
+ *   "supp_data_type" is a Supplemental Data Type from 0-65535.
+ *   "in" is a pointer to TLS "supplemental_data_entry" being provided to the cb.
+ *   "out" is used by the callback to return a pointer to "supplemental data"
+ *     which OpenSSL will later copy into the TLS handshake.  The contents
+ *     of this buffer should not be changed until the handshake is complete.
+ *   "inlen" and "outlen" are Supplemental Data lengths from 0-65535.
+ *   "al" is a TLS "AlertDescription" from 0-255 which WILL be sent as a
+ *     fatal TLS alert, if the callback returns zero.
+ */
+typedef int (*srv_supp_data_first_cb_fn)(SSL *s, unsigned short supp_data_type,
+            const unsigned char **out,
+            unsigned short *outlen, void *arg);
+typedef int (*srv_supp_data_second_cb_fn)(SSL *s, unsigned short supp_data_type,
+            const unsigned char *in,
+            unsigned short inlen, int *al,
+            void *arg);
+
+typedef int (*cli_supp_data_first_cb_fn)(SSL *s, unsigned short supp_data_type,
+            const unsigned char *in,
+            unsigned short inlen, int *al,
+            void *arg);
+typedef int (*cli_supp_data_second_cb_fn)(SSL *s, unsigned short supp_data_type,
+            const unsigned char **out,
+            unsigned short *outlen, void *arg);
+
+typedef struct {
+       unsigned short supp_data_type;
+       srv_supp_data_first_cb_fn fn1;
+       srv_supp_data_second_cb_fn fn2;
+       void *arg;
+} srv_supp_data_record;
+
+typedef struct {
+       unsigned short supp_data_type;
+       cli_supp_data_first_cb_fn fn1;
+       cli_supp_data_second_cb_fn fn2;
+       void *arg;
+} cli_supp_data_record;
+
 #endif
 
 #ifndef OPENSSL_NO_SSL_INTERN
@@ -596,13 +648,6 @@ struct ssl_session_st
 #endif
 #ifndef OPENSSL_NO_SRP
        char *srp_username;
-#endif
-#ifndef OPENSSL_NO_TLSEXT
-       /* Used by client: the proof for this session.
-        * We store it outside the sess_cert structure, since the proof
-        * is received before the certificate. */
-       unsigned char *audit_proof;
-       size_t audit_proof_length;
 #endif
        };
 
@@ -1138,14 +1183,17 @@ struct ssl_ctx_st
        size_t tlsext_ellipticcurvelist_length;
        unsigned char *tlsext_ellipticcurvelist;
 # endif /* OPENSSL_NO_EC */
-       int (*tlsext_authz_server_audit_proof_cb)(SSL *s, void *arg);
-       void *tlsext_authz_server_audit_proof_cb_arg;
-
        /* 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
@@ -1291,6 +1339,31 @@ int SSL_CTX_set_custom_cli_ext(SSL_CTX *ctx, unsigned short ext_type,
 int SSL_CTX_set_custom_srv_ext(SSL_CTX *ctx, unsigned short ext_type,
                               custom_srv_ext_first_cb_fn fn1, 
                               custom_srv_ext_second_cb_fn fn2, void *arg);
+
+/* Register callbacks to handle Supplemental Data as client or server.
+ *
+ * For SSL_CTX_set_srv_supp_data, a NULL srv_supp_data_first_cb_fn results in no supplemental data
+ * being sent by the server for that TLS extension.
+ * A NULL srv_supp_data_second_cb_fn results in no supplemental data
+ * being received by the server for that TLS extension.
+ *
+ * For SSL_CTX_set_cli_supp_data, a NULL cli_supp_data_first_cb_fn results in no supplemental data
+ * being received by the client for that TLS extension.
+ * A NULL cli_supp_data_second_cb_fn results in no supplemental data
+ * being sent by the client for that TLS extension.
+ *
+ * Returns nonzero on success.  You cannot register twice for the same supp_data_type.
+ */
+int SSL_CTX_set_srv_supp_data(SSL_CTX *ctx,
+                             unsigned short supp_data_type,
+                             srv_supp_data_first_cb_fn fn1,
+                             srv_supp_data_second_cb_fn fn2, void *arg);
+
+int SSL_CTX_set_cli_supp_data(SSL_CTX *ctx,
+                             unsigned short supp_data_type,
+                             cli_supp_data_first_cb_fn fn1,
+                             cli_supp_data_second_cb_fn fn2, void *arg);
+
 #endif
 
 #define SSL_NOTHING    1
@@ -1812,9 +1885,6 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
 #define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING         86
 #define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS     87
 #endif
-/* Callback for verifying audit proofs (client only) */
-#define SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB 95
-#define SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG 96
 #endif /* OPENSSL_NO_TLSEXT */
 
 #define DTLS_CTRL_GET_TIMEOUT          73
@@ -2052,17 +2122,6 @@ int      SSL_use_certificate(SSL *ssl, X509 *x);
 int    SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
 
 #ifndef OPENSSL_NO_TLSEXT
-/* Set authz data for the current active cert. */
-int    SSL_CTX_use_authz(SSL_CTX *ctx, unsigned char *authz, size_t authz_length);
-int    SSL_use_authz(SSL *ssl, unsigned char *authz, size_t authz_length);
-/* Get the authz of type 'type' associated with the current active cert. */
-const unsigned char *SSL_CTX_get_authz_data(SSL_CTX *ctx, unsigned char type,
-                                           size_t *data_length);
-#ifndef OPENSSL_NO_STDIO
-int    SSL_CTX_use_authz_file(SSL_CTX *ctx, const char *file);
-int    SSL_use_authz_file(SSL *ssl, const char *file);
-#endif
-
 /* Set serverinfo data for the current active cert. */
 int    SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
                               size_t serverinfo_length);
@@ -2116,10 +2175,6 @@ int      SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
 #ifndef OPENSSL_NO_BIO
 int    SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses);
 #endif
-#ifndef OPENSSL_NO_TLSEXT
-unsigned char *SSL_SESSION_get_tlsext_authz_server_audit_proof(SSL_SESSION *s,
-       size_t *proof_length);
-#endif
 void   SSL_SESSION_free(SSL_SESSION *ses);
 int    i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
 int    SSL_set_session(SSL *to, SSL_SESSION *session);
@@ -2454,8 +2509,6 @@ void ERR_load_SSL_strings(void);
 /* Error codes for the SSL functions. */
 
 /* Function codes. */
-#define SSL_F_AUTHZ_FIND_DATA                           330
-#define SSL_F_AUTHZ_VALIDATE                            323
 #define SSL_F_CHECK_SUITEB_CIPHER_LIST                  335
 #define SSL_F_CLIENT_CERTIFICATE                        100
 #define SSL_F_CLIENT_FINISHED                           167
@@ -2499,7 +2552,6 @@ void ERR_load_SSL_strings(void);
 #define SSL_F_GET_SERVER_HELLO                          109
 #define SSL_F_GET_SERVER_VERIFY                                 110
 #define SSL_F_I2D_SSL_SESSION                           111
-#define SSL_F_READ_AUTHZ                                329
 #define SSL_F_READ_N                                    112
 #define SSL_F_REQUEST_CERTIFICATE                       113
 #define SSL_F_SERVER_FINISH                             239
@@ -2605,7 +2657,6 @@ void ERR_load_SSL_strings(void);
 #define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT            219
 #define SSL_F_SSL_CTX_SET_SSL_VERSION                   170
 #define SSL_F_SSL_CTX_SET_TRUST                                 229
-#define SSL_F_SSL_CTX_USE_AUTHZ                                 324
 #define SSL_F_SSL_CTX_USE_CERTIFICATE                   171
 #define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1              172
 #define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE        220
@@ -2646,7 +2697,6 @@ void ERR_load_SSL_strings(void);
 #define SSL_F_SSL_SESSION_PRINT_FP                      190
 #define SSL_F_SSL_SESSION_SET1_ID_CONTEXT               312
 #define SSL_F_SSL_SESS_CERT_NEW                                 225
-#define SSL_F_SSL_SET_AUTHZ                             325
 #define SSL_F_SSL_SET_CERT                              191
 #define SSL_F_SSL_SET_CIPHER_LIST                       271
 #define SSL_F_SSL_SET_FD                                192
@@ -2663,7 +2713,6 @@ void ERR_load_SSL_strings(void);
 #define SSL_F_SSL_UNDEFINED_CONST_FUNCTION              243
 #define SSL_F_SSL_UNDEFINED_FUNCTION                    197
 #define SSL_F_SSL_UNDEFINED_VOID_FUNCTION               244
-#define SSL_F_SSL_USE_AUTHZ                             328
 #define SSL_F_SSL_USE_CERTIFICATE                       198
 #define SSL_F_SSL_USE_CERTIFICATE_ASN1                  199
 #define SSL_F_SSL_USE_CERTIFICATE_FILE                  200
@@ -2683,18 +2732,19 @@ void ERR_load_SSL_strings(void);
 #define SSL_F_TLS1_ENC                                  210
 #define SSL_F_TLS1_EXPORT_KEYING_MATERIAL               314
 #define SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA                 326
+#define SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA                 336
 #define SSL_F_TLS1_HEARTBEAT                            315
 #define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT           275
 #define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT           276
 #define SSL_F_TLS1_PRF                                  284
 #define SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA        327
+#define SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA        333
 #define SSL_F_TLS1_SETUP_KEY_BLOCK                      211
 #define SSL_F_WRITE_PENDING                             212
 
 /* Reason codes. */
 #define SSL_R_APP_DATA_IN_HANDSHAKE                     100
 #define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272
-#define SSL_R_AUTHZ_DATA_TOO_LARGE                      375
 #define SSL_R_BAD_ALERT_RECORD                          101
 #define SSL_R_BAD_AUTHENTICATION_TYPE                   102
 #define SSL_R_BAD_CHANGE_CIPHER_SPEC                    103
@@ -2786,8 +2836,6 @@ void ERR_load_SSL_strings(void);
 #define SSL_R_ILLEGAL_PADDING                           283
 #define SSL_R_ILLEGAL_SUITEB_DIGEST                     380
 #define SSL_R_INCONSISTENT_COMPRESSION                  340
-#define SSL_R_INVALID_AUDIT_PROOF                       371
-#define SSL_R_INVALID_AUTHZ_DATA                        374
 #define SSL_R_INVALID_CHALLENGE_LENGTH                  158
 #define SSL_R_INVALID_COMMAND                           280
 #define SSL_R_INVALID_COMPRESSION_ALGORITHM             341
@@ -2975,7 +3023,6 @@ void ERR_load_SSL_strings(void);
 #define SSL_R_UNEXPECTED_RECORD                                 245
 #define SSL_R_UNINITIALIZED                             276
 #define SSL_R_UNKNOWN_ALERT_TYPE                        246
-#define SSL_R_UNKNOWN_AUTHZ_DATA_TYPE                   372
 #define SSL_R_UNKNOWN_CERTIFICATE_TYPE                  247
 #define SSL_R_UNKNOWN_CIPHER_RETURNED                   248
 #define SSL_R_UNKNOWN_CIPHER_TYPE                       249
index 2c2f6ae..0ae97b4 100644 (file)
@@ -564,20 +564,6 @@ typedef struct ssl3_state_st
 #endif
 
 #ifndef OPENSSL_NO_TLSEXT
-       /* tlsext_authz_client_types contains an array of supported authz
-        * types, as advertised by the client. The array is sorted and
-        * does not contain any duplicates. */
-       unsigned char *tlsext_authz_client_types;
-       size_t tlsext_authz_client_types_len;
-       /* tlsext_authz_promised_to_client is true iff we're a server and we
-        * echoed the client's supplemental data extension and therefore must
-        * send a supplemental data handshake message. */
-       char tlsext_authz_promised_to_client;
-       /* tlsext_authz_server_promised is true iff we're a client and the
-        * server echoed our server_authz extension and therefore must send us
-        * a supplemental data handshake message. */
-       char tlsext_authz_server_promised;
-
        /* tlsext_custom_types contains an array of TLS Extension types which 
         * were advertised by the client in its ClientHello, which were not 
         * otherwise handled by OpenSSL, and which the server has registered
@@ -633,8 +619,10 @@ typedef struct ssl3_state_st
 #define SSL3_ST_CR_CERT_REQ_B          (0x151|SSL_ST_CONNECT)
 #define SSL3_ST_CR_SRVR_DONE_A         (0x160|SSL_ST_CONNECT)
 #define SSL3_ST_CR_SRVR_DONE_B         (0x161|SSL_ST_CONNECT)
-#define SSL3_ST_CR_SUPPLEMENTAL_DATA_A (0x210|SSL_ST_CONNECT)
-#define SSL3_ST_CR_SUPPLEMENTAL_DATA_B  (0x211|SSL_ST_CONNECT)
+#ifndef OPENSSL_NO_TLSEXT
+#define SSL3_ST_CR_SUPPLEMENTAL_DATA_A (0x212|SSL_ST_CONNECT)
+#define SSL3_ST_CR_SUPPLEMENTAL_DATA_B  (0x213|SSL_ST_CONNECT)
+#endif
 /* write to server */
 #define SSL3_ST_CW_CERT_A              (0x170|SSL_ST_CONNECT)
 #define SSL3_ST_CW_CERT_B              (0x171|SSL_ST_CONNECT)
@@ -649,6 +637,10 @@ typedef struct ssl3_state_st
 #ifndef OPENSSL_NO_NEXTPROTONEG
 #define SSL3_ST_CW_NEXT_PROTO_A                (0x200|SSL_ST_CONNECT)
 #define SSL3_ST_CW_NEXT_PROTO_B                (0x201|SSL_ST_CONNECT)
+#ifndef OPENSSL_NO_TLSEXT
+#define SSL3_ST_CW_SUPPLEMENTAL_DATA_A         (0x222|SSL_ST_CONNECT)
+#define SSL3_ST_CW_SUPPLEMENTAL_DATA_B         (0x223|SSL_ST_CONNECT)
+#endif
 #endif
 #define SSL3_ST_CW_FINISHED_A          (0x1B0|SSL_ST_CONNECT)
 #define SSL3_ST_CW_FINISHED_B          (0x1B1|SSL_ST_CONNECT)
@@ -674,6 +666,10 @@ typedef struct ssl3_state_st
 #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)
@@ -714,8 +710,10 @@ typedef struct ssl3_state_st
 #define SSL3_ST_SW_SESSION_TICKET_B    (0x1F1|SSL_ST_ACCEPT)
 #define SSL3_ST_SW_CERT_STATUS_A       (0x200|SSL_ST_ACCEPT)
 #define SSL3_ST_SW_CERT_STATUS_B       (0x201|SSL_ST_ACCEPT)
-#define SSL3_ST_SW_SUPPLEMENTAL_DATA_A (0x220|SSL_ST_ACCEPT)
-#define SSL3_ST_SW_SUPPLEMENTAL_DATA_B (0x221|SSL_ST_ACCEPT)
+#ifndef OPENSSL_NO_TLSEXT
+#define SSL3_ST_SW_SUPPLEMENTAL_DATA_A (0x222|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_SUPPLEMENTAL_DATA_B (0x223|SSL_ST_ACCEPT)
+#endif
 
 #define SSL3_MT_HELLO_REQUEST                  0
 #define SSL3_MT_CLIENT_HELLO                   1
@@ -729,7 +727,9 @@ typedef struct ssl3_state_st
 #define SSL3_MT_CLIENT_KEY_EXCHANGE            16
 #define SSL3_MT_FINISHED                       20
 #define SSL3_MT_CERTIFICATE_STATUS             22
+#ifndef OPENSSL_NO_TLSEXT
 #define SSL3_MT_SUPPLEMENTAL_DATA              23
+#endif
 #ifndef OPENSSL_NO_NEXTPROTONEG
 #define SSL3_MT_NEXT_PROTO                     67
 #endif
index 81b5811..d442e54 100644 (file)
@@ -330,23 +330,6 @@ CERT *ssl_cert_dup(CERT *cert)
                        }
                rpk->valid_flags = 0;
 #ifndef OPENSSL_NO_TLSEXT
-     if (cert->pkeys[i].authz != NULL)
-                       {
-                       /* Just copy everything. */
-                       ret->pkeys[i].authz_length =
-                               cert->pkeys[i].authz_length;
-                       ret->pkeys[i].authz =
-                               OPENSSL_malloc(ret->pkeys[i].authz_length);
-                       if (ret->pkeys[i].authz == NULL)
-                               {
-                               SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
-                               return NULL;
-                               }
-                       memcpy(ret->pkeys[i].authz,
-                              cert->pkeys[i].authz,
-                              cert->pkeys[i].authz_length);
-                       }
-
                if (cert->pkeys[i].serverinfo != NULL)
                        {
                        /* Just copy everything. */
@@ -479,11 +462,6 @@ void ssl_cert_clear_certs(CERT *c)
                        cpk->chain = NULL;
                        }
 #ifndef OPENSSL_NO_TLSEXT
-               if (cpk->authz)
-                       {
-                       OPENSSL_free(cpk->authz);
-                       cpk->authz = NULL;
-                       }
                if (cpk->serverinfo)
                        {
                        OPENSSL_free(cpk->serverinfo);
index e89968c..607c364 100644 (file)
@@ -70,8 +70,6 @@
 
 static ERR_STRING_DATA SSL_str_functs[]=
        {
-{ERR_FUNC(SSL_F_AUTHZ_FIND_DATA),      "AUTHZ_FIND_DATA"},
-{ERR_FUNC(SSL_F_AUTHZ_VALIDATE),       "AUTHZ_VALIDATE"},
 {ERR_FUNC(SSL_F_CHECK_SUITEB_CIPHER_LIST),     "CHECK_SUITEB_CIPHER_LIST"},
 {ERR_FUNC(SSL_F_CLIENT_CERTIFICATE),   "CLIENT_CERTIFICATE"},
 {ERR_FUNC(SSL_F_CLIENT_FINISHED),      "CLIENT_FINISHED"},
@@ -115,7 +113,6 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {ERR_FUNC(SSL_F_GET_SERVER_HELLO),     "GET_SERVER_HELLO"},
 {ERR_FUNC(SSL_F_GET_SERVER_VERIFY),    "GET_SERVER_VERIFY"},
 {ERR_FUNC(SSL_F_I2D_SSL_SESSION),      "i2d_SSL_SESSION"},
-{ERR_FUNC(SSL_F_READ_AUTHZ),   "READ_AUTHZ"},
 {ERR_FUNC(SSL_F_READ_N),       "READ_N"},
 {ERR_FUNC(SSL_F_REQUEST_CERTIFICATE),  "REQUEST_CERTIFICATE"},
 {ERR_FUNC(SSL_F_SERVER_FINISH),        "SERVER_FINISH"},
@@ -221,7 +218,6 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {ERR_FUNC(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT),       "SSL_CTX_set_session_id_context"},
 {ERR_FUNC(SSL_F_SSL_CTX_SET_SSL_VERSION),      "SSL_CTX_set_ssl_version"},
 {ERR_FUNC(SSL_F_SSL_CTX_SET_TRUST),    "SSL_CTX_set_trust"},
-{ERR_FUNC(SSL_F_SSL_CTX_USE_AUTHZ),    "SSL_CTX_use_authz"},
 {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE),      "SSL_CTX_use_certificate"},
 {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1), "SSL_CTX_use_certificate_ASN1"},
 {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE),   "SSL_CTX_use_certificate_chain_file"},
@@ -262,7 +258,6 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"},
 {ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT),  "SSL_SESSION_set1_id_context"},
 {ERR_FUNC(SSL_F_SSL_SESS_CERT_NEW),    "ssl_sess_cert_new"},
-{ERR_FUNC(SSL_F_SSL_SET_AUTHZ),        "SSL_SET_AUTHZ"},
 {ERR_FUNC(SSL_F_SSL_SET_CERT), "SSL_SET_CERT"},
 {ERR_FUNC(SSL_F_SSL_SET_CIPHER_LIST),  "SSL_set_cipher_list"},
 {ERR_FUNC(SSL_F_SSL_SET_FD),   "SSL_set_fd"},
@@ -279,7 +274,6 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION), "ssl_undefined_const_function"},
 {ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION),       "ssl_undefined_function"},
 {ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION),  "ssl_undefined_void_function"},
-{ERR_FUNC(SSL_F_SSL_USE_AUTHZ),        "SSL_use_authz"},
 {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE),  "SSL_use_certificate"},
 {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_ASN1),     "SSL_use_certificate_ASN1"},
 {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_FILE),     "SSL_use_certificate_file"},
@@ -299,11 +293,13 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {ERR_FUNC(SSL_F_TLS1_ENC),     "tls1_enc"},
 {ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL),  "tls1_export_keying_material"},
 {ERR_FUNC(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA),    "tls1_get_server_supplemental_data"},
+{ERR_FUNC(SSL_F_TLS1_GET_CLIENT_SUPPLEMENTAL_DATA),    "tls1_get_client_supplemental_data"},
 {ERR_FUNC(SSL_F_TLS1_HEARTBEAT),       "tls1_heartbeat"},
 {ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT),      "TLS1_PREPARE_CLIENTHELLO_TLSEXT"},
 {ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT),      "TLS1_PREPARE_SERVERHELLO_TLSEXT"},
 {ERR_FUNC(SSL_F_TLS1_PRF),     "tls1_prf"},
 {ERR_FUNC(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA),   "tls1_send_server_supplemental_data"},
+{ERR_FUNC(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA),   "tls1_send_client_supplemental_data"},
 {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "tls1_setup_key_block"},
 {ERR_FUNC(SSL_F_WRITE_PENDING),        "WRITE_PENDING"},
 {0,NULL}
@@ -313,7 +309,6 @@ static ERR_STRING_DATA SSL_str_reasons[]=
        {
 {ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE) ,"app data in handshake"},
 {ERR_REASON(SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT),"attempt to reuse session in different context"},
-{ERR_REASON(SSL_R_AUTHZ_DATA_TOO_LARGE)  ,"authz data too large"},
 {ERR_REASON(SSL_R_BAD_ALERT_RECORD)      ,"bad alert record"},
 {ERR_REASON(SSL_R_BAD_AUTHENTICATION_TYPE),"bad authentication type"},
 {ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC),"bad change cipher spec"},
@@ -405,8 +400,6 @@ static ERR_STRING_DATA SSL_str_reasons[]=
 {ERR_REASON(SSL_R_ILLEGAL_PADDING)       ,"illegal padding"},
 {ERR_REASON(SSL_R_ILLEGAL_SUITEB_DIGEST) ,"illegal Suite B digest"},
 {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION),"inconsistent compression"},
-{ERR_REASON(SSL_R_INVALID_AUDIT_PROOF)   ,"invalid audit proof"},
-{ERR_REASON(SSL_R_INVALID_AUTHZ_DATA)    ,"invalid authz data"},
 {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"},
 {ERR_REASON(SSL_R_INVALID_COMMAND)       ,"invalid command"},
 {ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"},
@@ -594,7 +587,6 @@ static ERR_STRING_DATA SSL_str_reasons[]=
 {ERR_REASON(SSL_R_UNEXPECTED_RECORD)     ,"unexpected record"},
 {ERR_REASON(SSL_R_UNINITIALIZED)         ,"uninitialized"},
 {ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE)    ,"unknown alert type"},
-{ERR_REASON(SSL_R_UNKNOWN_AUTHZ_DATA_TYPE),"unknown authz data type"},
 {ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE),"unknown certificate type"},
 {ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED),"unknown cipher returned"},
 {ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE)   ,"unknown cipher type"},
index 9f00400..0b2d5ff 100644 (file)
@@ -1840,6 +1840,66 @@ void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
        else
                *len = ssl->s3->alpn_selected_len;
        }
+
+int SSL_CTX_set_cli_supp_data(SSL_CTX *ctx,
+                             unsigned short supp_data_type,
+                             cli_supp_data_first_cb_fn fn1,
+                             cli_supp_data_second_cb_fn fn2, void* arg)
+       {
+       size_t i;
+       cli_supp_data_record* record;
+
+       /* Check for duplicates */
+       for (i=0; i < ctx->cli_supp_data_records_count; i++)
+               if (supp_data_type == ctx->cli_supp_data_records[i].supp_data_type)
+                       return 0;
+
+       ctx->cli_supp_data_records = OPENSSL_realloc(ctx->cli_supp_data_records,
+       (ctx->cli_supp_data_records_count+1) * sizeof(cli_supp_data_record));
+       if (!ctx->cli_supp_data_records)
+               {
+               ctx->cli_supp_data_records_count = 0;
+               return 0;
+               }
+       ctx->cli_supp_data_records_count++;
+       record = &ctx->cli_supp_data_records[ctx->cli_supp_data_records_count - 1];
+       record->supp_data_type = supp_data_type;
+       record->fn1 = fn1;
+       record->fn2 = fn2;
+       record->arg = arg;
+       return 1;
+       }
+
+int SSL_CTX_set_srv_supp_data(SSL_CTX *ctx,
+                             unsigned short supp_data_type,
+                             srv_supp_data_first_cb_fn fn1,
+                             srv_supp_data_second_cb_fn fn2, void* arg)
+       {
+       size_t i;
+       srv_supp_data_record* record;
+
+       /* Check for duplicates */
+       for (i=0; i < ctx->srv_supp_data_records_count; i++)
+               if (supp_data_type == ctx->srv_supp_data_records[i].supp_data_type)
+                       return 0;
+
+       ctx->srv_supp_data_records = OPENSSL_realloc(ctx->srv_supp_data_records,
+       (ctx->srv_supp_data_records_count+1) * sizeof(srv_supp_data_record));
+       if (!ctx->srv_supp_data_records)
+               {
+               ctx->srv_supp_data_records_count = 0;
+               return 0;
+               }
+       ctx->srv_supp_data_records_count++;
+       record = &ctx->srv_supp_data_records[ctx->srv_supp_data_records_count - 1];
+       record->supp_data_type = supp_data_type;
+       record->fn1 = fn1;
+       record->fn2 = fn2;
+       record->arg = arg;
+
+       return 1;
+       }
+
 #endif /* !OPENSSL_NO_TLSEXT */
 
 int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
@@ -2043,6 +2103,10 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
        ret->custom_cli_ext_records_count = 0;
        ret->custom_srv_ext_records = NULL;
        ret->custom_srv_ext_records_count = 0;
+       ret->cli_supp_data_records = NULL;
+       ret->cli_supp_data_records_count = 0;
+       ret->srv_supp_data_records = NULL;
+       ret->srv_supp_data_records_count = 0;
 #ifndef OPENSSL_NO_BUF_FREELISTS
        ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT;
        ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
@@ -2184,6 +2248,8 @@ void SSL_CTX_free(SSL_CTX *a)
 #ifndef OPENSSL_NO_TLSEXT
        OPENSSL_free(a->custom_cli_ext_records);
        OPENSSL_free(a->custom_srv_ext_records);
+       OPENSSL_free(a->cli_supp_data_records);
+       OPENSSL_free(a->srv_supp_data_records);
 #endif
 #ifndef OPENSSL_NO_ENGINE
        if (a->client_cert_engine)
@@ -2621,25 +2687,6 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd)
        }
 
 #ifndef OPENSSL_NO_TLSEXT
-unsigned char *ssl_get_authz_data(SSL *s, size_t *authz_length)
-       {
-       CERT *c;
-       int i;
-
-       c = s->cert;
-       i = ssl_get_server_cert_index(s);
-
-       if (i == -1)
-               return NULL;
-
-       *authz_length = 0;
-       if (c->pkeys[i].authz == NULL)
-               return(NULL);
-       *authz_length = c->pkeys[i].authz_length;
-
-       return c->pkeys[i].authz;
-       }
-
 int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo,
                                   size_t *serverinfo_length)
        {
index 56f9b4b..5c074ac 100644 (file)
@@ -503,14 +503,6 @@ typedef struct cert_pkey_st
        /* Chain for this certificate */
        STACK_OF(X509) *chain;
 #ifndef OPENSSL_NO_TLSEXT
-       /* authz/authz_length contain authz data for this certificate. The data
-        * is in wire format, specifically it's a series of records like:
-        *   uint8_t authz_type;  // (RFC 5878, AuthzDataFormat)
-        *   uint16_t length;
-        *   uint8_t data[length]; */
-       unsigned char *authz;
-       size_t authz_length;
-
        /* serverinfo data for this certificate.  The data is in TLS Extension
         * wire format, specifically it's a series of records like:
         *   uint16_t extension_type; // (RFC 5246, 7.4.1.4, Extension)
@@ -1009,7 +1001,6 @@ int ssl_undefined_void_function(void);
 int ssl_undefined_const_function(const SSL *s);
 CERT_PKEY *ssl_get_server_send_pkey(const SSL *s);
 #ifndef OPENSSL_NO_TLSEXT
-unsigned char *ssl_get_authz_data(SSL *s, size_t *authz_length);
 int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo,
                                   size_t *serverinfo_length);
 #endif
@@ -1275,8 +1266,10 @@ int ssl_prepare_clienthello_tlsext(SSL *s);
 int ssl_prepare_serverhello_tlsext(SSL *s);
 
 /* server only */
-int tls1_send_server_supplemental_data(SSL *s);
+int tls1_send_server_supplemental_data(SSL *s, int *skip);
+int tls1_get_client_supplemental_data(SSL *s);
 /* client only */
+int tls1_send_client_supplemental_data(SSL *s, int *skip);
 int tls1_get_server_supplemental_data(SSL *s);
 
 #ifndef OPENSSL_NO_HEARTBEATS
index 2837624..4187877 100644 (file)
 
 static int ssl_set_cert(CERT *c, X509 *x509);
 static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
-#ifndef OPENSSL_NO_TLSEXT
-static int ssl_set_authz(CERT *c, unsigned char *authz,
-                        size_t authz_length);
-#endif
 int SSL_use_certificate(SSL *ssl, X509 *x)
        {
        if (x == NULL)
@@ -463,6 +459,15 @@ static int ssl_set_cert(CERT *c, X509 *x)
                X509_free(c->pkeys[i].x509);
        CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
        c->pkeys[i].x509=x;
+#ifndef OPENSSL_NO_TLSEXT
+       /* Free the old serverinfo data, if it exists. */
+       if (c->pkeys[i].serverinfo != NULL)
+               {
+               OPENSSL_free(c->pkeys[i].serverinfo);
+               c->pkeys[i].serverinfo = NULL;
+               c->pkeys[i].serverinfo_length = 0;
+               }
+#endif
        c->key= &(c->pkeys[i]);
 
        c->valid=0;
@@ -802,50 +807,6 @@ end:
 #endif
 
 #ifndef OPENSSL_NO_TLSEXT
-/* authz_validate returns true iff authz is well formed, i.e. that it meets the
- * wire format as documented in the CERT_PKEY structure and that there are no
- * duplicate entries. */
-static char authz_validate(const unsigned char *authz, size_t length)
-       {
-       unsigned char types_seen_bitmap[32];
-
-       if (!authz)
-               return 1;
-
-       memset(types_seen_bitmap, 0, sizeof(types_seen_bitmap));
-
-       for (;;)
-               {
-               unsigned char type, byte, bit;
-               unsigned short len;
-
-               if (!length)
-                       return 1;
-
-               type = *(authz++);
-               length--;
-
-               byte = type / 8;
-               bit = type & 7;
-               if (types_seen_bitmap[byte] & (1 << bit))
-                       return 0;
-               types_seen_bitmap[byte] |= (1 << bit);
-
-               if (length < 2)
-                       return 0;
-               len = ((unsigned short) authz[0]) << 8 |
-                     ((unsigned short) authz[1]);
-               authz += 2;
-               length -= 2;
-
-               if (length < len)
-                       return 0;
-
-               authz += len;
-               length -= len;
-               }
-       }
-
 static int serverinfo_find_extension(const unsigned char *serverinfo,
                                     size_t serverinfo_length,
                                     unsigned short extension_type,
@@ -978,83 +939,6 @@ static int serverinfo_process_buffer(const unsigned char *serverinfo,
                }
        }
 
-static const unsigned char *authz_find_data(const unsigned char *authz,
-                                           size_t authz_length,
-                                           unsigned char data_type,
-                                           size_t *data_length)
-       {
-       if (authz == NULL) return NULL;
-       if (!authz_validate(authz, authz_length))
-               {
-               SSLerr(SSL_F_AUTHZ_FIND_DATA,SSL_R_INVALID_AUTHZ_DATA);
-               return NULL;
-               }
-
-       for (;;)
-               {
-               unsigned char type;
-               unsigned short len;
-               if (!authz_length)
-                       return NULL;
-
-               type = *(authz++);
-               authz_length--;
-
-               /* We've validated the authz data, so we don't have to
-                * check again that we have enough bytes left. */
-               len = ((unsigned short) authz[0]) << 8 |
-                     ((unsigned short) authz[1]);
-               authz += 2;
-               authz_length -= 2;
-               if (type == data_type)
-                       {
-                       *data_length = len;
-                       return authz;
-                       }
-               authz += len;
-               authz_length -= len;
-               }
-       /* No match */
-       return NULL;
-       }
-
-static int ssl_set_authz(CERT *c, unsigned char *authz, size_t authz_length)
-       {
-       CERT_PKEY *current_key = c->key;
-       if (current_key == NULL)
-               return 0;
-       if (!authz_validate(authz, authz_length))
-               {
-               SSLerr(SSL_F_SSL_SET_AUTHZ,SSL_R_INVALID_AUTHZ_DATA);
-               return(0);
-               }
-       current_key->authz = OPENSSL_realloc(current_key->authz, authz_length);
-       if (current_key->authz == NULL)
-               {
-               SSLerr(SSL_F_SSL_SET_AUTHZ,ERR_R_MALLOC_FAILURE);
-               return 0;
-               }
-       current_key->authz_length = authz_length;
-       memcpy(current_key->authz, authz, authz_length);
-       return 1;
-       }
-
-int SSL_CTX_use_authz(SSL_CTX *ctx, unsigned char *authz,
-                     size_t authz_length)
-       {
-       if (authz == NULL)
-               {
-               SSLerr(SSL_F_SSL_CTX_USE_AUTHZ,ERR_R_PASSED_NULL_PARAMETER);
-               return 0;
-               }
-       if (!ssl_cert_inst(&ctx->cert))
-               {
-               SSLerr(SSL_F_SSL_CTX_USE_AUTHZ,ERR_R_MALLOC_FAILURE);
-               return 0;
-               }
-       return ssl_set_authz(ctx->cert, authz, authz_length);
-       }
-
 int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
                           size_t serverinfo_length)
        {
@@ -1098,106 +982,7 @@ int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
        return 1;
        }
 
-int SSL_use_authz(SSL *ssl, unsigned char *authz, size_t authz_length)
-       {
-       if (authz == NULL)
-               {
-               SSLerr(SSL_F_SSL_USE_AUTHZ,ERR_R_PASSED_NULL_PARAMETER);
-               return 0;
-               }
-       if (!ssl_cert_inst(&ssl->cert))
-               {
-               SSLerr(SSL_F_SSL_USE_AUTHZ,ERR_R_MALLOC_FAILURE);
-               return 0;
-               }
-       return ssl_set_authz(ssl->cert, authz, authz_length);
-       }
-
-const unsigned char *SSL_CTX_get_authz_data(SSL_CTX *ctx, unsigned char type,
-                                           size_t *data_length)
-       {
-       CERT_PKEY *current_key;
-
-       if (ctx->cert == NULL)
-               return NULL;
-       current_key = ctx->cert->key;
-       if (current_key->authz == NULL)
-               return NULL;
-       return authz_find_data(current_key->authz,
-               current_key->authz_length, type, data_length);
-       }
-
 #ifndef OPENSSL_NO_STDIO
-/* read_authz returns a newly allocated buffer with authz data */
-static unsigned char *read_authz(const char *file, size_t *authz_length)
-       {
-       BIO *authz_in = NULL;
-       unsigned char *authz = NULL;
-       /* Allow authzs up to 64KB. */
-       static const size_t authz_limit = 65536;
-       size_t read_length;
-       unsigned char *ret = NULL;
-
-       authz_in = BIO_new(BIO_s_file_internal());
-       if (authz_in == NULL)
-               {
-               SSLerr(SSL_F_READ_AUTHZ,ERR_R_BUF_LIB);
-               goto end;
-               }
-
-       if (BIO_read_filename(authz_in,file) <= 0)
-               {
-               SSLerr(SSL_F_READ_AUTHZ,ERR_R_SYS_LIB);
-               goto end;
-               }
-
-       authz = OPENSSL_malloc(authz_limit);
-       read_length = BIO_read(authz_in, authz, authz_limit);
-       if (read_length == authz_limit || read_length <= 0)
-               {
-               SSLerr(SSL_F_READ_AUTHZ,SSL_R_AUTHZ_DATA_TOO_LARGE);
-               OPENSSL_free(authz);
-               goto end;
-               }
-       *authz_length = read_length;
-       ret = authz;
-end:
-       if (authz_in != NULL) BIO_free(authz_in);
-       return ret;
-       }
-
-int SSL_CTX_use_authz_file(SSL_CTX *ctx, const char *file)
-       {
-       unsigned char *authz = NULL;
-       size_t authz_length = 0;
-       int ret;
-
-       authz = read_authz(file, &authz_length);
-       if (authz == NULL)
-               return 0;
-
-       ret = SSL_CTX_use_authz(ctx, authz, authz_length);
-       /* SSL_CTX_use_authz makes a local copy of the authz. */
-       OPENSSL_free(authz);
-       return ret;
-       }
-
-int SSL_use_authz_file(SSL *ssl, const char *file)
-       {
-       unsigned char *authz = NULL;
-       size_t authz_length = 0;
-       int ret;
-
-       authz = read_authz(file, &authz_length);
-       if (authz == NULL)
-               return 0;
-
-       ret = SSL_use_authz(ssl, authz, authz_length);
-       /* SSL_use_authz makes a local copy of the authz. */
-       OPENSSL_free(authz);
-       return ret;
-       }
-
 int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
        {
        unsigned char *serverinfo = NULL;
index 90f92b2..73d87fd 100644 (file)
@@ -746,8 +746,6 @@ void SSL_SESSION_free(SSL_SESSION *ss)
        ss->tlsext_ellipticcurvelist_length = 0;
        if (ss->tlsext_ellipticcurvelist != NULL) OPENSSL_free(ss->tlsext_ellipticcurvelist);
 #endif /* OPENSSL_NO_EC */
-       if (ss->audit_proof != NULL) OPENSSL_free(ss->audit_proof);
-       ss->audit_proof_length = 0;
 #endif
 #ifndef OPENSSL_NO_PSK
        if (ss->psk_identity_hint != NULL)
@@ -869,15 +867,6 @@ int SSL_SESSION_set1_id_context(SSL_SESSION *s,const unsigned char *sid_ctx,
        return 1;
        }
 
-#ifndef OPENSSL_NO_TLSEXT
-unsigned char *SSL_SESSION_get_tlsext_authz_server_audit_proof(SSL_SESSION *s, size_t *proof_length)
-       {
-       if (s->audit_proof != NULL)
-               *proof_length = s->audit_proof_length;
-       return s->audit_proof;
-       }
-#endif
-
 long SSL_CTX_set_timeout(SSL_CTX *s, long t)
        {
        long l;
index 144b81e..aae31a9 100644 (file)
@@ -210,6 +210,14 @@ case SSL3_ST_SR_KEY_EXCH_A:        str="SSLv3 read client key exchange A"; break;
 case SSL3_ST_SR_KEY_EXCH_B:    str="SSLv3 read client key exchange B"; break;
 case SSL3_ST_SR_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)
index cb76439..20b169d 100644 (file)
@@ -521,6 +521,16 @@ int custom_ext = 0;
 /* This set based on extension callbacks */
 int custom_ext_error = 0;
 
+/*Not IETF assigned supplemental data types*/
+#define CUSTOM_SUPP_DATA_TYPE_0 100
+#define CUSTOM_SUPP_DATA_TYPE_1 101
+#define CUSTOM_SUPP_DATA_TYPE_2 102
+
+const char supp_data_0_string[] = "00000";
+
+int suppdata = 0;
+int suppdata_error = 0;
+
 static int serverinfo_cli_cb(SSL* s, unsigned short ext_type,
                             const unsigned char* in, unsigned short inlen, 
                             int* al, void* arg)
@@ -726,6 +736,109 @@ static int custom_ext_3_srv_second_cb(SSL *s, unsigned short ext_type,
        return 1; /* Send "defg" */
        }
 
+static int supp_data_0_srv_first_cb(SSL *s, unsigned short supp_data_type,
+                                   const unsigned char **out,
+                                   unsigned short *outlen, void *arg)
+       {
+       *out = (const unsigned char*)supp_data_0_string;
+       *outlen = strlen(supp_data_0_string);
+       if (arg != s)
+               suppdata_error = 1;
+       return 1;
+       }
+
+static int supp_data_0_srv_second_cb(SSL *s, unsigned short supp_data_type,
+                                    const unsigned char *in,
+                                    unsigned short inlen, int *al,
+                                    void *arg)
+       {
+       if (supp_data_type != CUSTOM_SUPP_DATA_TYPE_0)
+               suppdata_error = 1;
+       if (inlen != strlen(supp_data_0_string))
+               suppdata_error = 1;
+       if (memcmp(in, supp_data_0_string, inlen) != 0)
+               suppdata_error = 1;
+       if (arg != s)
+               suppdata_error = 1;
+       return 1;
+       }
+
+static int supp_data_1_srv_first_cb(SSL *s, unsigned short supp_data_type,
+                                   const unsigned char **out,
+                                   unsigned short *outlen, void *arg)
+       {
+       return -1;
+       }
+
+static int supp_data_1_srv_second_cb(SSL *s, unsigned short supp_data_type,
+                                    const unsigned char *in,
+                                    unsigned short inlen, int *al,
+                                    void *arg)
+       {
+       suppdata_error = 1;
+       return 1;
+       }
+
+static int supp_data_2_srv_second_cb(SSL *s, unsigned short supp_data_type,
+                                    const unsigned char *in,
+                                    unsigned short inlen, int *al,
+                                    void *arg)
+       {
+       suppdata_error = 1;
+       return 1;
+       }
+
+static int supp_data_0_cli_first_cb(SSL *s, unsigned short supp_data_type,
+                                   const unsigned char *in,
+                                   unsigned short inlen, int *al,
+                                   void *arg)
+       {
+       if (supp_data_type != CUSTOM_SUPP_DATA_TYPE_0)
+               suppdata_error = 1;
+       if (inlen != strlen(supp_data_0_string))
+               suppdata_error = 1;
+       if (memcmp(in, supp_data_0_string, inlen) != 0)
+               suppdata_error = 1;
+       if (arg != s)
+               suppdata_error = 1;
+       return 1;
+       }
+
+static int supp_data_0_cli_second_cb(SSL *s, unsigned short supp_data_type,
+                                    const unsigned char **out,
+                                    unsigned short *outlen, void *arg)
+       {
+       *out = (const unsigned char*)supp_data_0_string;
+       *outlen = strlen(supp_data_0_string);
+       if (arg != s)
+               suppdata_error = 1;
+       return 1;
+       }
+
+static int supp_data_1_cli_first_cb(SSL *s, unsigned short supp_data_type,
+                                   const unsigned char *in,
+                                   unsigned short inlen, int *al,
+                                   void *arg)
+       {
+       suppdata_error = 1;
+       return 1;
+       }
+
+static int supp_data_1_cli_second_cb(SSL *s, unsigned short supp_data_type,
+                                    const unsigned char **out,
+                                    unsigned short *outlen, void *arg)
+       {
+       return -1;
+       }
+
+static int supp_data_2_cli_first_cb(SSL *s, unsigned short supp_data_type,
+                                   const unsigned char *in,
+                                   unsigned short inlen, int *al,
+                                   void *arg)
+       {
+       suppdata_error = 1;
+       return 1;
+       }
 
 static char *cipher=NULL;
 static int verbose=0;
@@ -813,6 +926,7 @@ static void sv_usage(void)
        fprintf(stderr," -alpn_client <string> - have client side offer ALPN\n");
        fprintf(stderr," -alpn_server <string> - have server side offer ALPN\n");
        fprintf(stderr," -alpn_expected <string> - the ALPN protocol that should be negotiated\n");
+       fprintf(stderr, "-suppdata - exercise supplemental data callbacks\n");
        }
 
 static void print_details(SSL *c_ssl, const char *prefix)
@@ -1257,6 +1371,10 @@ int main(int argc, char *argv[])
                        if (--argc < 1) goto bad;
                        alpn_expected = *(++argv);
                        }
+               else if (strcmp(*argv,"-suppdata") == 0)
+                       {
+                       suppdata = 1;
+                       }
                else
                        {
                        fprintf(stderr,"unknown option %s\n",*argv);
@@ -1646,6 +1764,23 @@ bad:
        c_ssl=SSL_new(c_ctx);
        s_ssl=SSL_new(s_ctx);
 
+       if (suppdata)
+               {
+               //TEST CASES
+               //client and server both send and receive, verify additional arg passed back
+               SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_0, supp_data_0_srv_first_cb, supp_data_0_srv_second_cb, s_ssl);
+               SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_0, supp_data_0_cli_first_cb, supp_data_0_cli_second_cb, c_ssl);
+
+               //-1 response from sending server/client doesn't receive, -1 response from sending client/server doesn't receive
+               SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_1, supp_data_1_srv_first_cb, supp_data_1_srv_second_cb, NULL);
+               SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_1, supp_data_1_cli_first_cb, supp_data_1_cli_second_cb, NULL);
+
+               //null sending server/client doesn't receive, null sending client/server doesn't receive
+               SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_2, /*supp_data_2_srv_first_cb*/NULL, supp_data_2_srv_second_cb, NULL);
+               SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_2, supp_data_2_cli_first_cb, /*supp_data_2_cli_second_cb*/NULL, NULL);
+
+               //alerts set to non-zero and zero return values not tested
+               }
 #ifndef OPENSSL_NO_KRB5
        if (c_ssl  &&  c_ssl->kssl_ctx)
                 {
@@ -2419,6 +2554,11 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count)
                goto err;
                }
 #endif
+       if (suppdata_error < 0)
+               {
+               ret = 1;
+               goto err;
+               }
        if (verify_serverinfo() < 0)
                {
                ret = 1;
index 66119d4..d95732a 100644 (file)
@@ -1445,26 +1445,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
                 ret += el;
                 }
 
-       /* Add TLS extension Server_Authz_DataFormats to the ClientHello */
-       /* 2 bytes for extension type */
-       /* 2 bytes for extension length */
-       /* 1 byte for the list length */
-       /* 1 byte for the list (we only support audit proofs) */
-       if (s->ctx->tlsext_authz_server_audit_proof_cb != NULL)
-               {
-                const unsigned short ext_len = 2;
-                const unsigned char list_len = 1;
-
-               if (limit < ret + 6)
-                       return NULL;
-
-               s2n(TLSEXT_TYPE_server_authz, ret);
-                /* Extension length: 2 bytes */
-               s2n(ext_len, ret);
-               *(ret++) = list_len;
-               *(ret++) = TLSEXT_AUTHZDATAFORMAT_audit_proof;
-               }
-
        /* Add custom TLS Extensions to ClientHello */
        if (s->ctx->custom_cli_ext_records_count)
                {
@@ -1693,79 +1673,6 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
                }
 #endif
 
-       /* If the client supports authz then see whether we have any to offer
-        * to it. */
-       if (s->s3->tlsext_authz_client_types_len)
-               {
-               size_t authz_length;
-               /* By now we already know the new cipher, so we can look ahead
-                * to see whether the cert we are going to send
-                * has any authz data attached to it. */
-               const unsigned char* authz = ssl_get_authz_data(s, &authz_length);
-               const unsigned char* const orig_authz = authz;
-               size_t i;
-               unsigned authz_count = 0;
-
-               /* The authz data contains a number of the following structures:
-                *      uint8_t authz_type
-                *      uint16_t length
-                *      uint8_t data[length]
-                *
-                * First we walk over it to find the number of authz elements. */
-               for (i = 0; i < authz_length; i++)
-                       {
-                       unsigned short length;
-                       unsigned char type;
-
-                       type = *(authz++);
-                       if (memchr(s->s3->tlsext_authz_client_types,
-                                  type,
-                                  s->s3->tlsext_authz_client_types_len) != NULL)
-                               authz_count++;
-
-                       n2s(authz, length);
-                       /* n2s increments authz by 2 */
-                       i += 2;
-                       authz += length;
-                       i += length;
-                       }
-
-               if (authz_count)
-                       {
-                       /* Add TLS extension server_authz to the ServerHello message
-                        * 2 bytes for extension type
-                        * 2 bytes for extension length
-                        * 1 byte for the list length
-                        * n bytes for the list */
-                       const unsigned short ext_len = 1 + authz_count;
-
-                       if ((long)(limit - ret - 4 - ext_len) < 0) return NULL;
-                       s2n(TLSEXT_TYPE_server_authz, ret);
-                       s2n(ext_len, ret);
-                       *(ret++) = authz_count;
-                       s->s3->tlsext_authz_promised_to_client = 1;
-                       }
-
-               authz = orig_authz;
-               for (i = 0; i < authz_length; i++)
-                       {
-                       unsigned short length;
-                       unsigned char type;
-
-                       authz_count++;
-                       type = *(authz++);
-                       if (memchr(s->s3->tlsext_authz_client_types,
-                                  type,
-                                  s->s3->tlsext_authz_client_types_len) != NULL)
-                               *(ret++) = type;
-                       n2s(authz, length);
-                       /* n2s increments authz by 2 */
-                       i += 2;
-                       authz += length;
-                       i += length;
-                       }
-               }
-
        /* If custom types were sent in ClientHello, add ServerHello responses */
        if (s->s3->tlsext_custom_types_count)
                {
@@ -2511,66 +2418,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
                                                              al))
                                return 0;
                         }
-
-               else if (type == TLSEXT_TYPE_server_authz)
-                       {
-                       unsigned char *sdata = data;
-                       unsigned char server_authz_dataformatlist_length;
-
-                       if (size == 0)
-                               {
-                               *al = TLS1_AD_DECODE_ERROR;
-                               return 0;
-                               }
-
-                       server_authz_dataformatlist_length = *(sdata++);
-
-                       if (server_authz_dataformatlist_length != size - 1)
-                               {
-                               *al = TLS1_AD_DECODE_ERROR;
-                               return 0;
-                               }
-
-                       /* Successful session resumption uses the same authz
-                        * information as the original session so we ignore this
-                        * in the case of a session resumption. */
-                       if (!s->hit)
-                               {
-                               if (s->s3->tlsext_authz_client_types != NULL)
-                                       OPENSSL_free(s->s3->tlsext_authz_client_types);
-                               s->s3->tlsext_authz_client_types =
-                                       OPENSSL_malloc(server_authz_dataformatlist_length);
-                               if (!s->s3->tlsext_authz_client_types)
-                                       {
-                                       *al = TLS1_AD_INTERNAL_ERROR;
-                                       return 0;
-                                       }
-
-                               s->s3->tlsext_authz_client_types_len =
-                                       server_authz_dataformatlist_length;
-                               memcpy(s->s3->tlsext_authz_client_types,
-                                      sdata,
-                                      server_authz_dataformatlist_length);
-
-                               /* Sort the types in order to check for duplicates. */
-                               qsort(s->s3->tlsext_authz_client_types,
-                                     server_authz_dataformatlist_length,
-                                     1 /* element size */,
-                                     byte_compare);
-
-                               for (i = 0; i < server_authz_dataformatlist_length; i++)
-                                       {
-                                       if (i > 0 &&
-                                           s->s3->tlsext_authz_client_types[i] ==
-                                             s->s3->tlsext_authz_client_types[i-1])
-                                               {
-                                               *al = TLS1_AD_DECODE_ERROR;
-                                               return 0;
-                                               }
-                                       }
-                               }
-                       }
-
                /* If this ClientHello extension was unhandled and this is 
                 * a nonresumed connection, check whether the extension is a 
                 * custom TLS Extension (has a custom_srv_ext_record), and if
@@ -2936,46 +2783,6 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char
                                                              al))
                                 return 0;
                         }
-
-               else if (type == TLSEXT_TYPE_server_authz)
-                       {
-                       /* We only support audit proofs. It's an error to send
-                        * an authz hello extension if the client
-                        * didn't request a proof. */
-                       unsigned char *sdata = data;
-                       unsigned char server_authz_dataformatlist_length;
-
-                       if (!s->ctx->tlsext_authz_server_audit_proof_cb)
-                               {
-                               *al = TLS1_AD_UNSUPPORTED_EXTENSION;
-                               return 0;
-                               }
-
-                       if (!size)
-                               {
-                               *al = TLS1_AD_DECODE_ERROR;
-                               return 0;
-                               }
-
-                       server_authz_dataformatlist_length = *(sdata++);
-                       if (server_authz_dataformatlist_length != size - 1)
-                               {
-                               *al = TLS1_AD_DECODE_ERROR;
-                               return 0;
-                               }
-
-                       /* We only support audit proofs, so a legal ServerHello
-                        * authz list contains exactly one entry. */
-                       if (server_authz_dataformatlist_length != 1 ||
-                               sdata[0] != TLSEXT_AUTHZDATAFORMAT_audit_proof)
-                               {
-                               *al = TLS1_AD_UNSUPPORTED_EXTENSION;
-                               return 0;
-                               }
-
-                       s->s3->tlsext_authz_server_promised = 1;
-                       }
-
                /* If this extension type was not otherwise handled, but 
                 * matches a custom_cli_ext_record, then send it to the c
                 * callback */
index b1b85bf..92092f4 100644 (file)
@@ -299,9 +299,12 @@ extern "C" {
 
 /* From RFC 5878 */
 #define TLSEXT_SUPPLEMENTALDATATYPE_authz_data 16386
+
 /* This is not IANA assigned. See
- * https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#authorization-data-rules */
-#define TLSEXT_AUTHZDATAFORMAT_audit_proof 182
+ * https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#authorization-data-rules
+ * http://tools.ietf.org/id/draft-dthakore-tls-authz-01.txt
+ */
+#define TLSEXT_AUTHZDATAFORMAT_dtcp 225
 
 #define TLSEXT_MAXLEN_supplemental_data 1024*16 /* Let's limit to 16k */
 
@@ -390,13 +393,6 @@ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg)
 #define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
 SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
 
-/* Used by clients to process audit proofs. */
-#define SSL_CTX_set_tlsext_authz_server_audit_proof_cb(ctx, cb) \
-SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB,(void (*)(void))cb)
-
-#define SSL_CTX_set_tlsext_authz_server_audit_proof_cb_arg(ctx, arg) \
-SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TLSEXT_AUTHZ_SERVER_AUDIT_PROOF_CB_ARG, 0, arg);
-
 #ifndef OPENSSL_NO_HEARTBEATS
 #define SSL_TLSEXT_HB_ENABLED                          0x01
 #define SSL_TLSEXT_HB_DONT_SEND_REQUESTS       0x02