[openssl-commits] [openssl] master update

Dr. Stephen Henson steve at openssl.org
Mon Apr 3 22:48:44 UTC 2017


The branch master has been updated
       via  8edb4ee1a237b43d9520eaa658a4ad2671e8dd0c (commit)
       via  5a185729a3b029845c4596657b4495b3a8ead6f0 (commit)
       via  25a9fabbefa26422b6c9ee6635115b7ae3b97f21 (commit)
       via  f15b50c4cb6a5d36a3789863035d8b795378280c (commit)
       via  86135bedd52124aa8410847169f7a25c055b3bec (commit)
       via  5969a2dd2cce3ee4f35cc256256d9c8119080e98 (commit)
       via  9784ec04745a8c8ecbf5610c0a2f5540e1e0f2cd (commit)
       via  d2add501f070290a8de8c356d1c3c1a155cf1225 (commit)
       via  3578020bb16df7a9acf5b332ca409e88548ccbe7 (commit)
       via  be885d50758f887520e6fa0a5edeaec7c5e70b65 (commit)
       via  fa7c263747cb73f03b321399a1452cc40516d9a4 (commit)
      from  18d20b5eb66fda0ada2e65c2b19aeae75827bdf8 (commit)


- Log -----------------------------------------------------------------
commit 8edb4ee1a237b43d9520eaa658a4ad2671e8dd0c
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Sat Apr 1 00:40:15 2017 +0100

    update ordinals
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3015)

commit 5a185729a3b029845c4596657b4495b3a8ead6f0
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Fri Mar 31 17:15:22 2017 +0100

    Document new ssl(3) functions and options.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3015)

commit 25a9fabbefa26422b6c9ee6635115b7ae3b97f21
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Fri Mar 31 23:06:15 2017 +0100

    Add certificate_authorities tests client to server.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3015)

commit f15b50c4cb6a5d36a3789863035d8b795378280c
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Fri Mar 31 22:35:28 2017 +0100

    Add ExpectedServerCANames
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3015)

commit 86135bedd52124aa8410847169f7a25c055b3bec
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Fri Mar 31 22:30:58 2017 +0100

    Constify SSL_dup_CA_list()
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3015)

commit 5969a2dd2cce3ee4f35cc256256d9c8119080e98
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Fri Mar 31 17:04:28 2017 +0100

    Print CA names in s_server, add -requestCAfile to s_client
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3015)

commit 9784ec04745a8c8ecbf5610c0a2f5540e1e0f2cd
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Mar 20 18:33:54 2017 +0000

    Don't use client specific functions to retrieve CA list
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3015)

commit d2add501f070290a8de8c356d1c3c1a155cf1225
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Mar 20 18:32:43 2017 +0000

    Add requestCAfile option
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3015)

commit 3578020bb16df7a9acf5b332ca409e88548ccbe7
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Mar 20 18:31:44 2017 +0000

    Add extensions to debug list
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3015)

commit be885d50758f887520e6fa0a5edeaec7c5e70b65
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Sat Mar 18 13:44:13 2017 +0000

    SSL_CONF support for certificate_authorities
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3015)

commit fa7c263747cb73f03b321399a1452cc40516d9a4
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Mar 13 15:00:36 2017 +0000

    New certificate_authorities functions
    
    Add functions to add/retrieve the certificate_authorities. The older
    client_CA functions mainly just call the new versions now.
    
    Rename fields sice new extension can be generated by client and server.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3015)

-----------------------------------------------------------------------

Summary of changes:
 apps/s_apps.h                         |   1 +
 apps/s_cb.c                           |  23 ++++++++
 apps/s_client.c                       |  36 ++++++------
 apps/s_server.c                       |   2 +
 doc/man1/s_client.pod                 |   7 +++
 doc/man3/SSL_CONF_cmd.pod             |   8 +++
 doc/man3/SSL_CTX_set0_CA_list.pod     |  94 ++++++++++++++++++++++++++++++
 include/openssl/ssl.h                 |  10 +++-
 ssl/s3_lib.c                          |   4 +-
 ssl/ssl_cert.c                        |  81 +++++++++++++++++---------
 ssl/ssl_conf.c                        |  22 +++++--
 ssl/ssl_lib.c                         |  12 ++--
 ssl/ssl_locl.h                        |  15 +++--
 ssl/statem/extensions.c               |   6 +-
 ssl/statem/statem_lib.c               |   6 +-
 ssl/t1_lib.c                          |   2 +-
 test/README.ssltest.md                |   4 ++
 test/handshake_helper.c               |  11 +++-
 test/handshake_helper.h               |   2 +
 test/ssl-tests/20-cert-select.conf    |   2 +
 test/ssl-tests/20-cert-select.conf.in |   8 ++-
 test/ssl_test.c                       | 105 ++++++++++++++++++----------------
 test/ssl_test_ctx.c                   |   7 +++
 test/ssl_test_ctx.h                   |   2 +
 util/libssl.num                       |   7 +++
 25 files changed, 358 insertions(+), 119 deletions(-)
 create mode 100644 doc/man3/SSL_CTX_set0_CA_list.pod

diff --git a/apps/s_apps.h b/apps/s_apps.h
index bf27de2..aa0565d 100644
--- a/apps/s_apps.h
+++ b/apps/s_apps.h
@@ -77,4 +77,5 @@ int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath,
                     int crl_download);
 void ssl_ctx_security_debug(SSL_CTX *ctx, int verbose);
 int set_keylog_file(SSL_CTX *ctx, const char *keylog_file);
+void print_ca_names(BIO *bio, SSL *s);
 #endif
diff --git a/apps/s_cb.c b/apps/s_cb.c
index f395a2a..1b68164 100644
--- a/apps/s_cb.c
+++ b/apps/s_cb.c
@@ -665,6 +665,11 @@ static STRINT_PAIR tlsext_types[] = {
 #ifdef TLSEXT_TYPE_extended_master_secret
     {"extended master secret", TLSEXT_TYPE_extended_master_secret},
 #endif
+    {"key share", TLSEXT_TYPE_key_share},
+    {"supported versions", TLSEXT_TYPE_supported_versions},
+    {"psk", TLSEXT_TYPE_psk},
+    {"psk kex modes", TLSEXT_TYPE_psk_kex_modes},
+    {"certificate authorities", TLSEXT_TYPE_certificate_authorities},
     {NULL}
 };
 
@@ -1421,3 +1426,21 @@ int set_keylog_file(SSL_CTX *ctx, const char *keylog_file)
     SSL_CTX_set_keylog_callback(ctx, keylog_callback);
     return 0;
 }
+
+void print_ca_names(BIO *bio, SSL *s)
+{
+    const char *cs = SSL_is_server(s) ? "server" : "client";
+    const STACK_OF(X509_NAME) *sk = SSL_get0_peer_CA_list(s);
+    int i;
+
+    if (sk == NULL || sk_X509_NAME_num(sk) == 0) {
+        BIO_printf(bio, "---\nNo %s certificate CA names sent\n", cs);
+        return;
+    }
+
+    BIO_printf(bio, "---\nAcceptable %s certificate CA names\n",cs);
+    for (i = 0; i < sk_X509_NAME_num(sk); i++) {
+        X509_NAME_print_ex(bio, sk_X509_NAME_value(sk, i), 0, XN_FLAG_ONELINE);
+        BIO_write(bio, "\n", 1);
+    }
+}
diff --git a/apps/s_client.c b/apps/s_client.c
index cab7e25..9267393 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -547,7 +547,7 @@ typedef enum OPTION_choice {
     OPT_SERVERINFO, OPT_STARTTLS, OPT_SERVERNAME,
     OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_SMTPHOST,
     OPT_ASYNC, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF,
-    OPT_KEYLOG_FILE, OPT_EARLY_DATA,
+    OPT_KEYLOG_FILE, OPT_EARLY_DATA, OPT_REQCAFILE,
     OPT_V_ENUM,
     OPT_X_ENUM,
     OPT_S_ENUM,
@@ -587,6 +587,8 @@ const OPTIONS s_client_options[] = {
      "Do not load the default certificates file"},
     {"no-CApath", OPT_NOCAPATH, '-',
      "Do not load certificates from the default certificates directory"},
+    {"requestCAfile", OPT_REQCAFILE, '<',
+      "PEM format file of CA names to send to the server"},
     {"dane_tlsa_domain", OPT_DANE_TLSA_DOMAIN, 's', "DANE TLSA base domain"},
     {"dane_tlsa_rrdata", OPT_DANE_TLSA_RRDATA, 's',
      "DANE TLSA rrdata presentation form"},
@@ -831,6 +833,7 @@ int s_client_main(int argc, char **argv)
     char *port = OPENSSL_strdup(PORT);
     char *inrand = NULL;
     char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL;
+    char *ReqCAfile = NULL;
     char *sess_in = NULL, *crl_file = NULL, *p;
     char *xmpphost = NULL;
     const char *ehlo = "mail.example.com";
@@ -1276,6 +1279,9 @@ int s_client_main(int argc, char **argv)
         case OPT_BUILD_CHAIN:
             build_chain = 1;
             break;
+        case OPT_REQCAFILE:
+            ReqCAfile = opt_arg();
+            break;
         case OPT_CAFILE:
             CAfile = opt_arg();
             break;
@@ -1577,6 +1583,17 @@ int s_client_main(int argc, char **argv)
         ERR_print_errors(bio_err);
         goto end;
     }
+    if (ReqCAfile != NULL) {
+        STACK_OF(X509_NAME) *nm = sk_X509_NAME_new_null();
+
+        if (nm == NULL || !SSL_add_file_cert_subjects_to_stack(nm, ReqCAfile)) {
+            sk_X509_NAME_pop_free(nm, X509_NAME_free);
+            BIO_printf(bio_err, "Error loading CA names\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        SSL_CTX_set0_CA_list(ctx, nm);
+    }
 #ifndef OPENSSL_NO_ENGINE
     if (ssl_client_engine) {
         if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine)) {
@@ -2804,9 +2821,7 @@ static void print_stuff(BIO *bio, SSL *s, int full)
     X509 *peer = NULL;
     char buf[BUFSIZ];
     STACK_OF(X509) *sk;
-    STACK_OF(X509_NAME) *sk2;
     const SSL_CIPHER *c;
-    X509_NAME *xn;
     int i;
 #ifndef OPENSSL_NO_COMP
     const COMP_METHOD *comp, *expansion;
@@ -2848,21 +2863,10 @@ static void print_stuff(BIO *bio, SSL *s, int full)
             BIO_printf(bio, "subject=%s\n", buf);
             X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf);
             BIO_printf(bio, "issuer=%s\n", buf);
-        } else
-            BIO_printf(bio, "no peer certificate available\n");
-
-        sk2 = SSL_get_client_CA_list(s);
-        if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) {
-            BIO_printf(bio, "---\nAcceptable client certificate CA names\n");
-            for (i = 0; i < sk_X509_NAME_num(sk2); i++) {
-                xn = sk_X509_NAME_value(sk2, i);
-                X509_NAME_oneline(xn, buf, sizeof(buf));
-                BIO_write(bio, buf, strlen(buf));
-                BIO_write(bio, "\n", 1);
-            }
         } else {
-            BIO_printf(bio, "---\nNo client certificate CA names sent\n");
+            BIO_printf(bio, "no peer certificate available\n");
         }
+        print_ca_names(bio, s);
 
         ssl_print_sigalgs(bio, s);
         ssl_print_tmp_key(bio, s);
diff --git a/apps/s_server.c b/apps/s_server.c
index 5858278..4bd2620 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -2704,6 +2704,7 @@ static void print_connection_info(SSL *con)
     ssl_print_point_formats(bio_s_out, con);
     ssl_print_groups(bio_s_out, con, 0);
 #endif
+    print_ca_names(bio_s_out, con);
     BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)");
 
 #if !defined(OPENSSL_NO_NEXTPROTONEG)
@@ -2990,6 +2991,7 @@ static int www_body(int s, int stype, unsigned char *context)
 #ifndef OPENSSL_NO_EC
             ssl_print_groups(io, con, 0);
 #endif
+            print_ca_names(io, con);
             BIO_printf(io, (SSL_session_reused(con)
                             ? "---\nReused, " : "---\nNew, "));
             c = SSL_get_current_cipher(con);
diff --git a/doc/man1/s_client.pod b/doc/man1/s_client.pod
index e9794c4..272d997 100644
--- a/doc/man1/s_client.pod
+++ b/doc/man1/s_client.pod
@@ -25,6 +25,7 @@ B<openssl> B<s_client>
 [B<-CAfile filename>]
 [B<-no-CAfile>]
 [B<-no-CApath>]
+[B<-requestCAfile filename>]
 [B<-dane_tlsa_domain domain>]
 [B<-dane_tlsa_rrdata rrdata>]
 [B<-dane_ee_no_namechecks>]
@@ -218,6 +219,12 @@ Do not load the trusted CA certificates from the default file location
 
 Do not load the trusted CA certificates from the default directory location
 
+=item B<-requestCAfile file>
+
+A file containing a list of certificates whose subject names will be sent
+to the server in the B<certificate_authorities> extension. Only supported
+for TLS 1.3
+
 =item B<-dane_tlsa_domain domain>
 
 Enable RFC6698/RFC7671 DANE TLSA authentication and specify the
diff --git a/doc/man3/SSL_CONF_cmd.pod b/doc/man3/SSL_CONF_cmd.pod
index 6045a4f..f5c6576 100644
--- a/doc/man3/SSL_CONF_cmd.pod
+++ b/doc/man3/SSL_CONF_cmd.pod
@@ -217,6 +217,14 @@ These options indicate a file or directory used for building certificate
 chains or verifying certificate chains. These options are only supported
 if certificate operations are permitted.
 
+=item B<RequestCAFile>
+
+This option indicates a file containing a set of certificates in PEM form.
+The subject names of the certificates are sent to the peer in the
+B<certificate_authorities> extension for TLS 1.3 (in ClientHello or
+CertificateRequest) or in a certificate request for previous versions or
+TLS.
+
 =item B<ServerInfoFile>
 
 Attempts to use the file B<value> in the "serverinfo" extension using the
diff --git a/doc/man3/SSL_CTX_set0_CA_list.pod b/doc/man3/SSL_CTX_set0_CA_list.pod
new file mode 100644
index 0000000..5e94f5c
--- /dev/null
+++ b/doc/man3/SSL_CTX_set0_CA_list.pod
@@ -0,0 +1,94 @@
+=pod
+
+=head1 NAME
+
+SSL_set0_CA_list, SSL_CTX_set0_CA_list, SSL_get0_CA_list,
+SSL_CTX_get0_CA_list, SSL_add1_CA_list, SSL_CTX_add1_CA_list,
+SSL_get0_peer_CA_list - get or set CA list
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ void SSL_CTX_set0_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list);
+ void SSL_set0_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list);
+ const STACK_OF(X509_NAME) *SSL_CTX_get0_CA_list(const SSL_CTX *ctx);
+ const STACK_OF(X509_NAME) *SSL_get0_CA_list(const SSL *s);
+ int SSL_CTX_add1_CA_list(SSL_CTX *ctx, const X509 *x);
+ int SSL_add1_CA_list(SSL *ssl, const X509 *x);
+
+ const STACK_OF(X509_NAME) *SSL_get0_peer_CA_list(const SSL *s);
+
+=head1 DESCRIPTION
+
+SSL_CTX_set0_CA_list() sets the list of CAs to be sent to the peer to
+B<name_list>. Ownership of B<name_list> is transferred to B<ctx> and
+it should not be freed by the caller.
+
+SSL_set0_CA_list() sets the list of CAs to be sent to the peer to B<name_list>
+overriding any list set in the parent B<SSL_CTX> of B<s>. Ownership of
+B<name_list> is transferred to B<s> and it should not be freed by the caller.
+
+SSL_CTX_get0_CA_list() retrieves any previously set list of CAs set for
+B<ctx>.
+
+SSL_CTX_get0_CA_list() retrieves any previously set list of CAs set for
+B<s> or if none are set the list from the parent B<SSL_CTX> is retrieved.
+
+SSL_CTX_add1_CA_list() appends the CA subject name extracted from B<x> to the
+list of CAs sent to peer for B<ctx>.
+
+SSL_add1_CA_list() appends the CA subject name extracted from B<x> to the
+list of CAs sent to the peer for B<s>, overriding the setting in the parent
+B<SSL_CTX>.
+
+SSL_get0_peer_CA_list() retrieves the list of CA names (if any) the peer
+has sent.
+
+=head1 NOTES
+
+These functions are generalised versions of the client authentication
+CA list functions such as L<SSL_CTX_set_client_CA_list(3)>.
+
+For TLS versions before 1.3 the list of CA names is only sent from the server
+to client when requesting a client certificate. So any list of CA names set
+is never sent from client to server and the list of CA names retrieved by
+SSL_get0_peer_CA_list() is always B<NULL>.
+
+For TLS 1.3 the list of CA names is sent using the B<certificate_authorities>
+extension and will be sent by a client (in the ClientHello message) or by
+a server (when requesting a certificate).
+
+=head1 RETURN VALUES
+
+SSL_CTX_set0_CA_list() and SSL_set0_CA_list() do not return a value.
+
+SSL_CTX_get0_CA_list() and SSL_get0_CA_list() return a stack of CA names
+or B<NULL> is no CA names are set.
+
+SSL_CTX_add1_CA_list() and SSL_add1_CA_list() return 1 for success and 0
+for failure.
+
+SSL_get0_peer_CA_list() returns a stack of CA names sent by the peer or
+B<NULL> or an empty stack if no list was sent.
+
+=back
+
+=head1 SEE ALSO
+
+L<ssl(7)>,
+L<SSL_CTX_set_client_CA_list(3)>,
+L<SSL_get_client_CA_list(3)>,
+L<SSL_load_client_CA_file(3)>,
+L<SSL_CTX_load_verify_locations(3)>
+
+=head1 COPYRIGHT
+
+Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the OpenSSL license (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index b1a8c69..5ebd997 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -1718,6 +1718,14 @@ __owur const char *SSL_alert_type_string(int value);
 __owur const char *SSL_alert_desc_string_long(int value);
 __owur const char *SSL_alert_desc_string(int value);
 
+void SSL_set0_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list);
+void SSL_CTX_set0_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list);
+__owur const STACK_OF(X509_NAME) *SSL_get0_CA_list(const SSL *s);
+__owur const STACK_OF(X509_NAME) *SSL_CTX_get0_CA_list(const SSL_CTX *ctx);
+__owur int SSL_add1_CA_list(SSL *ssl, const X509 *x);
+__owur int SSL_CTX_add1_CA_list(SSL_CTX *ctx, const X509 *x);
+__owur const STACK_OF(X509_NAME) *SSL_get0_peer_CA_list(const SSL *s);
+
 void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list);
 void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list);
 __owur STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s);
@@ -1735,7 +1743,7 @@ __owur long SSL_get_default_timeout(const SSL *s);
 #endif
 
 __owur char *SSL_CIPHER_description(const SSL_CIPHER *, char *buf, int size);
-__owur STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);
+__owur STACK_OF(X509_NAME) *SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk);
 
 __owur SSL *SSL_dup(SSL *ssl);
 
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index d8cce5e..54c49ab 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -2935,7 +2935,7 @@ void ssl3_free(SSL *s)
 #endif
 
     OPENSSL_free(s->s3->tmp.ctype);
-    sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
+    sk_X509_NAME_pop_free(s->s3->tmp.peer_ca_names, X509_NAME_free);
     OPENSSL_free(s->s3->tmp.ciphers_raw);
     OPENSSL_clear_free(s->s3->tmp.pms, s->s3->tmp.pmslen);
     OPENSSL_free(s->s3->tmp.peer_sigalgs);
@@ -2954,7 +2954,7 @@ void ssl3_clear(SSL *s)
 {
     ssl3_cleanup_key_block(s);
     OPENSSL_free(s->s3->tmp.ctype);
-    sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
+    sk_X509_NAME_pop_free(s->s3->tmp.peer_ca_names, X509_NAME_free);
     OPENSSL_free(s->s3->tmp.ciphers_raw);
     OPENSSL_clear_free(s->s3->tmp.pms, s->s3->tmp.pmslen);
     OPENSSL_free(s->s3->tmp.peer_sigalgs);
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 50b2e64..a4e7977 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -459,14 +459,14 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk)
     return i;
 }
 
-static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,
-                               STACK_OF(X509_NAME) *name_list)
+static void set0_CA_list(STACK_OF(X509_NAME) **ca_list,
+                        STACK_OF(X509_NAME) *name_list)
 {
     sk_X509_NAME_pop_free(*ca_list, X509_NAME_free);
     *ca_list = name_list;
 }
 
-STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk)
+STACK_OF(X509_NAME) *SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk)
 {
     int i;
     STACK_OF(X509_NAME) *ret;
@@ -488,63 +488,90 @@ STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk)
     return (ret);
 }
 
-void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list)
+void SSL_set0_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list)
 {
-    set_client_CA_list(&(s->client_CA), name_list);
+    set0_CA_list(&s->ca_names, name_list);
+}
+
+void SSL_CTX_set0_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list)
+{
+    set0_CA_list(&ctx->ca_names, name_list);
+}
+
+const STACK_OF(X509_NAME) *SSL_CTX_get0_CA_list(const SSL_CTX *ctx)
+{
+    return ctx->ca_names;
+}
+
+const STACK_OF(X509_NAME) *SSL_get0_CA_list(const SSL *s)
+{
+    return s->ca_names != NULL ? s->ca_names : s->ctx->ca_names;
 }
 
 void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list)
 {
-    set_client_CA_list(&(ctx->client_CA), name_list);
+    SSL_CTX_set0_CA_list(ctx, name_list);
 }
 
 STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
 {
-    return (ctx->client_CA);
+    return ctx->ca_names;
+}
+
+void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list)
+{
+    SSL_set0_CA_list(s, name_list);
+}
+
+const STACK_OF(X509_NAME) *SSL_get0_peer_CA_list(const SSL *s)
+{
+    return s->s3 != NULL ? s->s3->tmp.peer_ca_names : NULL;
 }
 
 STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s)
 {
-    if (!s->server) {           /* we are in the client */
-        if (s->s3 != NULL)
-            return s->s3->tmp.ca_names;
-        else
-            return NULL;
-    } else {
-        if (s->client_CA != NULL)
-            return s->client_CA;
-        else
-            return s->ctx->client_CA;
-    }
+    if (!s->server)
+        return s->s3 != NULL ?  s->s3->tmp.peer_ca_names : NULL;
+    return s->ca_names != NULL ?  s->ca_names : s->ctx->ca_names;
 }
 
-static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x)
+static int add_ca_name(STACK_OF(X509_NAME) **sk, const X509 *x)
 {
     X509_NAME *name;
 
     if (x == NULL)
-        return (0);
-    if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL))
-        return (0);
+        return 0;
+    if (*sk == NULL && ((*sk = sk_X509_NAME_new_null()) == NULL))
+        return 0;
 
     if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL)
-        return (0);
+        return 0;
 
     if (!sk_X509_NAME_push(*sk, name)) {
         X509_NAME_free(name);
-        return (0);
+        return 0;
     }
-    return (1);
+    return 1;
+}
+
+int SSL_add1_CA_list(SSL *ssl, const X509 *x)
+{
+    return add_ca_name(&ssl->ca_names, x);
+}
+
+int SSL_CTX_add1_CA_list(SSL_CTX *ctx, const X509 *x)
+{
+    return add_ca_name(&ctx->ca_names, x);
 }
 
 int SSL_add_client_CA(SSL *ssl, X509 *x)
 {
-    return (add_client_CA(&(ssl->client_CA), x));
+    return add_ca_name(&ssl->ca_names, x);
 }
 
 int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
 {
-    return (add_client_CA(&(ctx->client_CA), x));
+    return add_ca_name(&ctx->ca_names, x);
 }
 
 static int xname_sk_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c
index 954e421..4b46192 100644
--- a/ssl/ssl_conf.c
+++ b/ssl/ssl_conf.c
@@ -465,7 +465,7 @@ static int cmd_VerifyCAFile(SSL_CONF_CTX *cctx, const char *value)
     return do_store(cctx, value, NULL, 1);
 }
 
-static int cmd_ClientCAFile(SSL_CONF_CTX *cctx, const char *value)
+static int cmd_RequestCAFile(SSL_CONF_CTX *cctx, const char *value)
 {
     if (cctx->canames == NULL)
         cctx->canames = sk_X509_NAME_new_null();
@@ -474,7 +474,12 @@ static int cmd_ClientCAFile(SSL_CONF_CTX *cctx, const char *value)
     return SSL_add_file_cert_subjects_to_stack(cctx->canames, value);
 }
 
-static int cmd_ClientCAPath(SSL_CONF_CTX *cctx, const char *value)
+static int cmd_ClientCAFile(SSL_CONF_CTX *cctx, const char *value)
+{
+    return cmd_RequestCAFile(cctx, value);
+}
+
+static int cmd_RequestCAPath(SSL_CONF_CTX *cctx, const char *value)
 {
     if (cctx->canames == NULL)
         cctx->canames = sk_X509_NAME_new_null();
@@ -483,6 +488,11 @@ static int cmd_ClientCAPath(SSL_CONF_CTX *cctx, const char *value)
     return SSL_add_dir_cert_subjects_to_stack(cctx->canames, value);
 }
 
+static int cmd_ClientCAPath(SSL_CONF_CTX *cctx, const char *value)
+{
+    return cmd_RequestCAPath(cctx, value);
+}
+
 #ifndef OPENSSL_NO_DH
 static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value)
 {
@@ -575,9 +585,13 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
                  SSL_CONF_TYPE_DIR),
     SSL_CONF_CMD(VerifyCAFile, "verifyCAfile", SSL_CONF_FLAG_CERTIFICATE,
                  SSL_CONF_TYPE_FILE),
+    SSL_CONF_CMD(RequestCAFile, "requestCAFile", SSL_CONF_FLAG_CERTIFICATE,
+                 SSL_CONF_TYPE_FILE),
     SSL_CONF_CMD(ClientCAFile, NULL,
                  SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
                  SSL_CONF_TYPE_FILE),
+    SSL_CONF_CMD(RequestCAPath, NULL, SSL_CONF_FLAG_CERTIFICATE,
+                 SSL_CONF_TYPE_DIR),
     SSL_CONF_CMD(ClientCAPath, NULL,
                  SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
                  SSL_CONF_TYPE_DIR),
@@ -802,9 +816,9 @@ int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx)
     }
     if (cctx->canames) {
         if (cctx->ssl)
-            SSL_set_client_CA_list(cctx->ssl, cctx->canames);
+            SSL_set0_CA_list(cctx->ssl, cctx->canames);
         else if (cctx->ctx)
-            SSL_CTX_set_client_CA_list(cctx->ctx, cctx->canames);
+            SSL_CTX_set0_CA_list(cctx->ctx, cctx->canames);
         else
             sk_X509_NAME_pop_free(cctx->canames, X509_NAME_free);
         cctx->canames = NULL;
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 24fc994..4f4eba1 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1018,7 +1018,7 @@ void SSL_free(SSL *s)
     OPENSSL_free(s->ext.tls13_cookie);
     OPENSSL_free(s->clienthello);
 
-    sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
+    sk_X509_NAME_pop_free(s->ca_names, X509_NAME_free);
 
     sk_X509_pop_free(s->verified_chain, X509_free);
 
@@ -2692,7 +2692,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
         goto err2;
     }
 
-    if ((ret->client_CA = sk_X509_NAME_new_null()) == NULL)
+    if ((ret->ca_names = sk_X509_NAME_new_null()) == NULL)
         goto err;
 
     if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data))
@@ -2814,7 +2814,7 @@ void SSL_CTX_free(SSL_CTX *a)
     sk_SSL_CIPHER_free(a->cipher_list);
     sk_SSL_CIPHER_free(a->cipher_list_by_id);
     ssl_cert_free(a->cert);
-    sk_X509_NAME_pop_free(a->client_CA, X509_NAME_free);
+    sk_X509_NAME_pop_free(a->ca_names, X509_NAME_free);
     sk_X509_pop_free(a->extra_certs, X509_free);
     a->comp_methods = NULL;
 #ifndef OPENSSL_NO_SRTP
@@ -3410,10 +3410,10 @@ SSL *SSL_dup(SSL *s)
             goto err;
 
     /* Dup the client_CA list */
-    if (s->client_CA != NULL) {
-        if ((sk = sk_X509_NAME_dup(s->client_CA)) == NULL)
+    if (s->ca_names != NULL) {
+        if ((sk = sk_X509_NAME_dup(s->ca_names)) == NULL)
             goto err;
-        ret->client_CA = sk;
+        ret->ca_names = sk;
         for (i = 0; i < sk_X509_NAME_num(sk); i++) {
             xn = sk_X509_NAME_value(sk, i);
             if (sk_X509_NAME_set(sk, i, X509_NAME_dup(xn)) == NULL) {
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 4378b71..f532931 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -542,7 +542,7 @@ struct ssl_session_st {
     /* This is the cert and type for the other end. */
     X509 *peer;
     int peer_type;
-    /* Certificate chain peer sent */
+    /* Certificate chain peer sent. */
     STACK_OF(X509) *peer_chain;
     /*
      * when app_verify_callback accepts a session where the peer's
@@ -790,8 +790,12 @@ struct ssl_ctx_st {
     /* used if SSL's info_callback is NULL */
     void (*info_callback) (const SSL *ssl, int type, int val);
 
-    /* what we put in client cert requests */
-    STACK_OF(X509_NAME) *client_CA;
+    /*
+     * What we put in certificate_authorities extension for TLS 1.3
+     * (ClientHello and CertificateRequest) or just client cert requests for
+     * earlier versions.
+     */
+    STACK_OF(X509_NAME) *ca_names;
 
     /*
      * Default values to use in SSL structures follow (these are copied by
@@ -1115,7 +1119,7 @@ struct ssl_st {
     /* extra application data */
     CRYPTO_EX_DATA ex_data;
     /* for server side, keep the list of CA_dn we can use */
-    STACK_OF(X509_NAME) *client_CA;
+    STACK_OF(X509_NAME) *ca_names;
     CRYPTO_REF_COUNT references;
     /* protocol behaviour */
     uint32_t options;
@@ -1371,7 +1375,8 @@ typedef struct ssl3_state_st {
         /* Certificate types in certificate request message. */
         uint8_t *ctype;
         size_t ctype_len;
-        STACK_OF(X509_NAME) *ca_names;
+        /* Certificate authorities list peer sent */
+        STACK_OF(X509_NAME) *peer_ca_names;
         size_t key_block_length;
         unsigned char *key_block;
         const EVP_CIPHER *new_sym_enc;
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index 043b830..96c5394 100644
--- a/ssl/statem/extensions.c
+++ b/ssl/statem/extensions.c
@@ -983,8 +983,8 @@ static int final_ems(SSL *s, unsigned int context, int sent, int *al)
 
 static int init_certificate_authorities(SSL *s, unsigned int context)
 {
-    sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
-    s->s3->tmp.ca_names = NULL;
+    sk_X509_NAME_pop_free(s->s3->tmp.peer_ca_names, X509_NAME_free);
+    s->s3->tmp.peer_ca_names = NULL;
     return 1;
 }
 
@@ -992,7 +992,7 @@ static int tls_construct_certificate_authorities(SSL *s, WPACKET *pkt,
                                                  unsigned int context, X509 *x,
                                                  size_t chainidx, int *al)
 {
-    STACK_OF(X509_NAME) *ca_sk = SSL_get_client_CA_list(s);
+    const STACK_OF(X509_NAME) *ca_sk = SSL_get0_CA_list(s);
 
     if (ca_sk == NULL || sk_X509_NAME_num(ca_sk) == 0)
         return 1;
diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c
index 860b814..f292b82 100644
--- a/ssl/statem/statem_lib.c
+++ b/ssl/statem/statem_lib.c
@@ -2023,8 +2023,8 @@ int parse_ca_names(SSL *s, PACKET *pkt, int *al)
         xn = NULL;
     }
 
-    sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
-    s->s3->tmp.ca_names = ca_sk;
+    sk_X509_NAME_pop_free(s->s3->tmp.peer_ca_names, X509_NAME_free);
+    s->s3->tmp.peer_ca_names = ca_sk;
 
     return 1;
 
@@ -2038,7 +2038,7 @@ int parse_ca_names(SSL *s, PACKET *pkt, int *al)
 
 int construct_ca_names(SSL *s, WPACKET *pkt)
 {
-    STACK_OF(X509_NAME) *ca_sk = SSL_get_client_CA_list(s);
+    const STACK_OF(X509_NAME) *ca_sk = SSL_get0_CA_list(s);
 
     /* Start sub-packet for client CA list */
     if (!WPACKET_start_sub_packet_u16(pkt))
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 1c98b53..698c25b 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -2041,7 +2041,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
             rv |= CERT_PKEY_CERT_TYPE;
         }
 
-        ca_dn = s->s3->tmp.ca_names;
+        ca_dn = s->s3->tmp.peer_ca_names;
 
         if (!sk_X509_NAME_num(ca_dn))
             rv |= CERT_PKEY_ISSUER_NAME;
diff --git a/test/README.ssltest.md b/test/README.ssltest.md
index 0d6f466..288dffa 100644
--- a/test/README.ssltest.md
+++ b/test/README.ssltest.md
@@ -102,6 +102,10 @@ handshake.
   send. If this is "empty" the list is expected to be empty otherwise it
   is a file of certificates whose subject names form the list.
 
+* ExpectedServerCANames - list of CA names the client must send, TLS 1.3 only.
+  If this is "empty" the list is expected to be empty otherwise it is a file
+  of certificates whose subject names form the list.
+
 ## Configuring the client and server
 
 The client and server configurations can be any valid `SSL_CTX`
diff --git a/test/handshake_helper.c b/test/handshake_helper.c
index 4bccac1..47af3fe 100644
--- a/test/handshake_helper.c
+++ b/test/handshake_helper.c
@@ -34,6 +34,7 @@ void HANDSHAKE_RESULT_free(HANDSHAKE_RESULT *result)
     OPENSSL_free(result->server_npn_negotiated);
     OPENSSL_free(result->client_alpn_negotiated);
     OPENSSL_free(result->server_alpn_negotiated);
+    sk_X509_NAME_pop_free(result->server_ca_names, X509_NAME_free);
     sk_X509_NAME_pop_free(result->client_ca_names, X509_NAME_free);
     OPENSSL_free(result);
 }
@@ -1123,7 +1124,7 @@ static HANDSHAKE_RESULT *do_handshake_internal(
     /* API dictates unsigned int rather than size_t. */
     unsigned int proto_len = 0;
     EVP_PKEY *tmp_key;
-    STACK_OF(X509_NAME) *names;
+    const STACK_OF(X509_NAME) *names;
 
     memset(&server_ctx_data, 0, sizeof(server_ctx_data));
     memset(&server2_ctx_data, 0, sizeof(server2_ctx_data));
@@ -1297,12 +1298,18 @@ static HANDSHAKE_RESULT *do_handshake_internal(
     SSL_get_peer_signature_type_nid(client.ssl, &ret->server_sign_type);
     SSL_get_peer_signature_type_nid(server.ssl, &ret->client_sign_type);
 
-    names = SSL_get_client_CA_list(client.ssl);
+    names = SSL_get0_peer_CA_list(client.ssl);
     if (names == NULL)
         ret->client_ca_names = NULL;
     else
         ret->client_ca_names = SSL_dup_CA_list(names);
 
+    names = SSL_get0_peer_CA_list(server.ssl);
+    if (names == NULL)
+        ret->server_ca_names = NULL;
+    else
+        ret->server_ca_names = SSL_dup_CA_list(names);
+
     ret->server_cert_type = peer_pkey_type(client.ssl);
     ret->client_cert_type = peer_pkey_type(server.ssl);
 
diff --git a/test/handshake_helper.h b/test/handshake_helper.h
index a7df584..2736057 100644
--- a/test/handshake_helper.h
+++ b/test/handshake_helper.h
@@ -52,6 +52,8 @@ typedef struct handshake_result {
     int server_sign_hash;
     /* server signature type */
     int server_sign_type;
+    /* server CA names */
+    STACK_OF(X509_NAME) *server_ca_names;
     /* client certificate key type */
     int client_cert_type;
     /* client signing hash */
diff --git a/test/ssl-tests/20-cert-select.conf b/test/ssl-tests/20-cert-select.conf
index e787efc..20154bb 100644
--- a/test/ssl-tests/20-cert-select.conf
+++ b/test/ssl-tests/20-cert-select.conf
@@ -34,11 +34,13 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
 [0-ECDSA CipherString Selection-client]
 CipherString = aECDSA
+RequestCAFile = ${ENV::TEST_CERTS_DIR}/root-cert.pem
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
 [test-0]
 ExpectedResult = Success
+ExpectedServerCANames = empty
 ExpectedServerCertType = P-256
 ExpectedServerSignType = EC
 
diff --git a/test/ssl-tests/20-cert-select.conf.in b/test/ssl-tests/20-cert-select.conf.in
index 1d92e68..aadae27 100644
--- a/test/ssl-tests/20-cert-select.conf.in
+++ b/test/ssl-tests/20-cert-select.conf.in
@@ -21,10 +21,13 @@ our @tests = (
         server => $server,
         client => {
             "CipherString" => "aECDSA",
+            "RequestCAFile" => test_pem("root-cert.pem"),
         },
         test   => {
             "ExpectedServerCertType" =>, "P-256",
             "ExpectedServerSignType" =>, "EC",
+            # Note: certificate_authorities not sent for TLS < 1.3
+            "ExpectedServerCANames" =>, "empty",
             "ExpectedResult" => "Success"
         },
     },
@@ -214,6 +217,7 @@ my @tests_tls_1_3 = (
             "ExpectedServerCertType" => "P-256",
             "ExpectedServerSignHash" => "SHA256",
             "ExpectedServerSignType" => "EC",
+            "ExpectedServerCANames" => "empty",
             "ExpectedResult" => "Success"
         },
     },
@@ -247,11 +251,13 @@ my @tests_tls_1_3 = (
         server => $server_tls_1_3,
         client => {
             "SignatureAlgorithms" => "ECDSA+SHA256:RSA-PSS+SHA256",
+            "RequestCAFile" => test_pem("root-cert.pem"),
         },
         test   => {
             "ExpectedServerCertType" => "P-256",
             "ExpectedServerSignHash" => "SHA256",
             "ExpectedServerSignType" => "EC",
+            "ExpectedServerCANames" => test_pem("root-cert.pem"),
             "ExpectedResult" => "Success"
         },
     },
@@ -325,7 +331,7 @@ my @tests_tls_1_3 = (
         server => {
             "ClientSignatureAlgorithms" => "PSS+SHA256",
             "VerifyCAFile" => test_pem("root-cert.pem"),
-            "ClientCAFile" => test_pem("root-cert.pem"),
+            "RequestCAFile" => test_pem("root-cert.pem"),
             "VerifyMode" => "Require"
         },
         client => $client_tls_1_3,
diff --git a/test/ssl_test.c b/test/ssl_test.c
index 0cdec46..9406f94 100644
--- a/test/ssl_test.c
+++ b/test/ssl_test.c
@@ -195,54 +195,6 @@ static int check_nid(const char *name, int expected_nid, int nid)
     return 0;
 }
 
-static int check_tmp_key(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
-{
-    return check_nid("Tmp key", test_ctx->expected_tmp_key_type,
-                     result->tmp_key_type);
-}
-
-static int check_server_cert_type(HANDSHAKE_RESULT *result,
-                                  SSL_TEST_CTX *test_ctx)
-{
-    return check_nid("Server certificate", test_ctx->expected_server_cert_type,
-                     result->server_cert_type);
-}
-
-static int check_server_sign_hash(HANDSHAKE_RESULT *result,
-                                  SSL_TEST_CTX *test_ctx)
-{
-    return check_nid("Server signing hash", test_ctx->expected_server_sign_hash,
-                     result->server_sign_hash);
-}
-
-static int check_server_sign_type(HANDSHAKE_RESULT *result,
-                                  SSL_TEST_CTX *test_ctx)
-{
-    return check_nid("Server signing", test_ctx->expected_server_sign_type,
-                     result->server_sign_type);
-}
-
-static int check_client_cert_type(HANDSHAKE_RESULT *result,
-                                  SSL_TEST_CTX *test_ctx)
-{
-    return check_nid("Client certificate", test_ctx->expected_client_cert_type,
-                     result->client_cert_type);
-}
-
-static int check_client_sign_hash(HANDSHAKE_RESULT *result,
-                                  SSL_TEST_CTX *test_ctx)
-{
-    return check_nid("Client signing hash", test_ctx->expected_client_sign_hash,
-                     result->client_sign_hash);
-}
-
-static int check_client_sign_type(HANDSHAKE_RESULT *result,
-                                  SSL_TEST_CTX *test_ctx)
-{
-    return check_nid("Client signing", test_ctx->expected_client_sign_type,
-                     result->client_sign_type);
-}
-
 static void print_ca_names(STACK_OF(X509_NAME) *names)
 {
     BIO *err;
@@ -291,6 +243,62 @@ static int check_ca_names(const char *name,
     return 0;
 }
 
+static int check_tmp_key(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
+{
+    return check_nid("Tmp key", test_ctx->expected_tmp_key_type,
+                     result->tmp_key_type);
+}
+
+static int check_server_cert_type(HANDSHAKE_RESULT *result,
+                                  SSL_TEST_CTX *test_ctx)
+{
+    return check_nid("Server certificate", test_ctx->expected_server_cert_type,
+                     result->server_cert_type);
+}
+
+static int check_server_sign_hash(HANDSHAKE_RESULT *result,
+                                  SSL_TEST_CTX *test_ctx)
+{
+    return check_nid("Server signing hash", test_ctx->expected_server_sign_hash,
+                     result->server_sign_hash);
+}
+
+static int check_server_sign_type(HANDSHAKE_RESULT *result,
+                                  SSL_TEST_CTX *test_ctx)
+{
+    return check_nid("Server signing", test_ctx->expected_server_sign_type,
+                     result->server_sign_type);
+}
+
+static int check_server_ca_names(HANDSHAKE_RESULT *result,
+                                 SSL_TEST_CTX *test_ctx)
+{
+    return check_ca_names("Server CA names",
+                          test_ctx->expected_server_ca_names,
+                          result->server_ca_names);
+}
+
+static int check_client_cert_type(HANDSHAKE_RESULT *result,
+                                  SSL_TEST_CTX *test_ctx)
+{
+    return check_nid("Client certificate", test_ctx->expected_client_cert_type,
+                     result->client_cert_type);
+}
+
+static int check_client_sign_hash(HANDSHAKE_RESULT *result,
+                                  SSL_TEST_CTX *test_ctx)
+{
+    return check_nid("Client signing hash", test_ctx->expected_client_sign_hash,
+                     result->client_sign_hash);
+}
+
+static int check_client_sign_type(HANDSHAKE_RESULT *result,
+                                  SSL_TEST_CTX *test_ctx)
+{
+    return check_nid("Client signing", test_ctx->expected_client_sign_type,
+                     result->client_sign_type);
+}
+
 static int check_client_ca_names(HANDSHAKE_RESULT *result,
                                  SSL_TEST_CTX *test_ctx)
 {
@@ -324,6 +332,7 @@ static int check_test(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
         ret &= check_server_cert_type(result, test_ctx);
         ret &= check_server_sign_hash(result, test_ctx);
         ret &= check_server_sign_type(result, test_ctx);
+        ret &= check_server_ca_names(result, test_ctx);
         ret &= check_client_cert_type(result, test_ctx);
         ret &= check_client_sign_hash(result, test_ctx);
         ret &= check_client_sign_type(result, test_ctx);
diff --git a/test/ssl_test_ctx.c b/test/ssl_test_ctx.c
index 7189777..6a3b9d1 100644
--- a/test/ssl_test_ctx.c
+++ b/test/ssl_test_ctx.c
@@ -546,6 +546,11 @@ __owur static int parse_expected_ca_names(STACK_OF(X509_NAME) **pnames,
         *pnames = SSL_load_client_CA_file(value);
     return *pnames != NULL;
 }
+__owur static int parse_expected_server_ca_names(SSL_TEST_CTX *test_ctx,
+                                                 const char *value)
+{
+    return parse_expected_ca_names(&test_ctx->expected_server_ca_names, value);
+}
 __owur static int parse_expected_client_ca_names(SSL_TEST_CTX *test_ctx,
                                                  const char *value)
 {
@@ -580,6 +585,7 @@ static const ssl_test_ctx_option ssl_test_ctx_options[] = {
     { "ExpectedServerCertType", &parse_expected_server_cert_type },
     { "ExpectedServerSignHash", &parse_expected_server_sign_hash },
     { "ExpectedServerSignType", &parse_expected_server_sign_type },
+    { "ExpectedServerCANames", &parse_expected_server_ca_names },
     { "ExpectedClientCertType", &parse_expected_client_cert_type },
     { "ExpectedClientSignHash", &parse_expected_client_sign_hash },
     { "ExpectedClientSignType", &parse_expected_client_sign_type },
@@ -661,6 +667,7 @@ void SSL_TEST_CTX_free(SSL_TEST_CTX *ctx)
     ssl_test_ctx_free_extra_data(ctx);
     OPENSSL_free(ctx->expected_npn_protocol);
     OPENSSL_free(ctx->expected_alpn_protocol);
+    sk_X509_NAME_pop_free(ctx->expected_server_ca_names, X509_NAME_free);
     sk_X509_NAME_pop_free(ctx->expected_client_ca_names, X509_NAME_free);
     OPENSSL_free(ctx);
 }
diff --git a/test/ssl_test_ctx.h b/test/ssl_test_ctx.h
index 0b37b15..54cefb6 100644
--- a/test/ssl_test_ctx.h
+++ b/test/ssl_test_ctx.h
@@ -188,6 +188,8 @@ typedef struct {
     int expected_server_sign_hash;
     /* Expected server signature type */
     int expected_server_sign_type;
+    /* Expected server CA names */
+    STACK_OF(X509_NAME) *expected_server_ca_names;
     /* Expected client certificate key type */
     int expected_client_cert_type;
     /* Expected client signing hash */
diff --git a/util/libssl.num b/util/libssl.num
index 3c024e4..4994910 100644
--- a/util/libssl.num
+++ b/util/libssl.num
@@ -432,3 +432,10 @@ SSL_write_early_data                    432	1_1_1	EXIST::FUNCTION:
 SSL_read_early_data                     433	1_1_1	EXIST::FUNCTION:
 SSL_get_early_data_status               434	1_1_1	EXIST::FUNCTION:
 SSL_SESSION_get_max_early_data          435	1_1_1	EXIST::FUNCTION:
+SSL_add1_CA_list                        436	1_1_1	EXIST::FUNCTION:
+SSL_set0_CA_list                        437	1_1_1	EXIST::FUNCTION:
+SSL_CTX_set0_CA_list                    438	1_1_1	EXIST::FUNCTION:
+SSL_get0_CA_list                        439	1_1_1	EXIST::FUNCTION:
+SSL_get0_peer_CA_list                   440	1_1_1	EXIST::FUNCTION:
+SSL_CTX_add1_CA_list                    441	1_1_1	EXIST::FUNCTION:
+SSL_CTX_get0_CA_list                    442	1_1_1	EXIST::FUNCTION:


More information about the openssl-commits mailing list