[openssl-commits] [openssl] master update

Dr. Stephen Henson steve at openssl.org
Mon Jan 30 13:02:48 UTC 2017


The branch master has been updated
       via  787ebcafcd82daf5809ef308f8b6d6bbec17b354 (commit)
       via  91410d40cbc2f63bf6c27c01f9f002ef7bcc3277 (commit)
       via  cdf516d988807671bfda18bad135b26c3fac8888 (commit)
       via  d8979bdda8dae95d0fc694dbc80a6b6865dd5232 (commit)
       via  a92e710b7a15eb82fbfb9e9c8e4029d56a08dfb3 (commit)
       via  54b7f2a5ca463072dde5590e4dd3112bd47bba28 (commit)
       via  a593cffe48e923f9db9c1eb5540d0851fa165ad6 (commit)
       via  377c5e98cb98f2d4588efc8a78ac37701be0add2 (commit)
       via  4d43ee28d4a2a575616b9fc54c0a04e8243bf86f (commit)
       via  8a43a42a02947fbff84378a9110a03f3eefeb48f (commit)
       via  edbfba1a342a66bfa569ea241d3ca77815b1f916 (commit)
       via  018031faa82a4f1d9ab1d0a048b56ba1f0163ae9 (commit)
       via  42ef7aead2b310a183e53a4d336a6706395b5c17 (commit)
       via  5554facbe7f1ef4945fc03ae0a447c2396a80ef7 (commit)
       via  b2eb699874976d4ecc48b2180cba5d8301d844fa (commit)
       via  98c792d18c067f45a0a04bf6e6b0ea6cae238804 (commit)
       via  968ae5b33389526636b61851b085ccc745703303 (commit)
      from  1f04f23ef42564c5e9c186ec290a7a17bcf56b0f (commit)


- Log -----------------------------------------------------------------
commit 787ebcafcd82daf5809ef308f8b6d6bbec17b354
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Sun Jan 29 15:12:58 2017 +0000

    Update macros.
    
    Use TLS_MAX_SIGALGCNT for the maximum number of entries in the
    signature algorithms array.
    
    Use TLS_MAX_SIGSTRING_LEN for the maxiumum length of each signature
    component instead of a magic number.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

commit 91410d40cbc2f63bf6c27c01f9f002ef7bcc3277
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Sun Jan 29 13:38:55 2017 +0000

    fix style issues
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

commit cdf516d988807671bfda18bad135b26c3fac8888
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Sun Jan 29 00:43:45 2017 +0000

    Fix TLS 1.2 and no sigalgs.
    
    For TLS 1.2 if we have no signature algorithms extension then lookup
    using the complete table instead of (empty) shared signature algorithms
    list so we pick up defaults.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

commit d8979bdda8dae95d0fc694dbc80a6b6865dd5232
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Sat Jan 28 19:45:33 2017 +0000

    Use PSS for simple test so TLS 1.3 handhake is successful.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

commit a92e710b7a15eb82fbfb9e9c8e4029d56a08dfb3
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Fri Jan 27 15:56:47 2017 +0000

    Add tests for client and server signature type
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

commit 54b7f2a5ca463072dde5590e4dd3112bd47bba28
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Fri Jan 27 15:06:16 2017 +0000

    Add test support for TLS signature types.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

commit a593cffe48e923f9db9c1eb5540d0851fa165ad6
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Fri Jan 27 02:19:54 2017 +0000

    Update documentation
    
    Add details of the use of PSS for signature algorithms.
    
    Document SSL_get_peer_signature_nid() and SSL_get_peer_signature_type_nid().
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

commit 377c5e98cb98f2d4588efc8a78ac37701be0add2
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Fri Jan 27 04:33:04 2017 +0000

    make update
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

commit 4d43ee28d4a2a575616b9fc54c0a04e8243bf86f
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Thu Jan 26 15:24:35 2017 +0000

    Replace TLS_SIGALGS with SIGALG_LOOKUP
    
    Since every supported signature algorithm is now an entry in the
    SIGALG_LOOKUP table we can replace shared signature algortihms with
    pointers to constant table entries.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

commit 8a43a42a02947fbff84378a9110a03f3eefeb48f
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Thu Jan 26 14:40:59 2017 +0000

    Support TLS 1.3 signature scheme names.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

commit edbfba1a342a66bfa569ea241d3ca77815b1f916
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Thu Jan 26 14:23:05 2017 +0000

    Extend TLS 1.3 signature table.
    
    Add additional entries in the TLS 1.2 signature table to include
    the name, sig and hash NID (if any) and required curve (if any).
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

commit 018031faa82a4f1d9ab1d0a048b56ba1f0163ae9
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Thu Jan 26 00:15:54 2017 +0000

    Use shared signature algorithm list to find type.
    
    Lookup the signature type in the shared list: we can use this to
    use PSS if the peer supports it for TLS 1.2.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

commit 42ef7aead2b310a183e53a4d336a6706395b5c17
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Wed Jan 25 23:28:57 2017 +0000

    Add SSL_get_peer_signature_type_nid() function.
    
    Add function to retrieve signature type: in the case of RSA
    keys the signature type can be EVP_PKEY_RSA or EVP_PKEY_RSA_PSS.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

commit 5554facbe7f1ef4945fc03ae0a447c2396a80ef7
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Wed Jan 25 16:46:02 2017 +0000

    Store peer signature type.
    
    Store peer signature type in s->s3->tmp.peer_sigtype and check it
    to see if the peer used PSS.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

commit b2eb699874976d4ecc48b2180cba5d8301d844fa
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Wed Jan 25 16:22:13 2017 +0000

    More complete PSS support.
    
    Extend support for PSS key signatures by using the EVP_PKEY_RSA_PSS type
    to distinguish them from PKCS1 signature types.
    
    Allow setting of PSS signature algorithms using the string "PSS" or
    "RSA-PSS".
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

commit 98c792d18c067f45a0a04bf6e6b0ea6cae238804
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Wed Jan 25 14:33:55 2017 +0000

    Use uint16_t for signature scheme.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

commit 968ae5b33389526636b61851b085ccc745703303
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Wed Jan 25 14:02:00 2017 +0000

    use RSA_PSS_SALTLEN_DIGEST constant
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2301)

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

Summary of changes:
 apps/s_cb.c                             |  37 +++-
 doc/man3/SSL_CTX_set1_sigalgs.pod       |   7 +-
 doc/man3/SSL_get_peer_signature_nid.pod |  45 ++++
 include/openssl/tls1.h                  |   2 +
 ssl/ssl_locl.h                          |  53 +++--
 ssl/statem/extensions_clnt.c            |   2 +-
 ssl/statem/statem_clnt.c                |  12 +-
 ssl/statem/statem_lib.c                 |  16 +-
 ssl/statem/statem_srvr.c                |   5 +-
 ssl/t1_lib.c                            | 373 +++++++++++++++++---------------
 test/README.ssltest.md                  |   5 +-
 test/handshake_helper.c                 |   3 +
 test/handshake_helper.h                 |   4 +
 test/ssl-tests/01-simple.conf           |   4 +-
 test/ssl-tests/01-simple.conf.in        |   4 +-
 test/ssl-tests/04-client_auth.conf      |   1 +
 test/ssl-tests/04-client_auth.conf.in   |   5 +-
 test/ssl-tests/20-cert-select.conf      |  37 +++-
 test/ssl-tests/20-cert-select.conf.in   |  19 +-
 test/ssl_test.c                         |  16 ++
 test/ssl_test_ctx.c                     |  22 +-
 test/ssl_test_ctx.h                     |   4 +
 util/libssl.num                         |   1 +
 23 files changed, 441 insertions(+), 236 deletions(-)
 create mode 100644 doc/man3/SSL_get_peer_signature_nid.pod

diff --git a/apps/s_cb.c b/apps/s_cb.c
index d5c308e..3f46156 100644
--- a/apps/s_cb.c
+++ b/apps/s_cb.c
@@ -213,6 +213,26 @@ static void ssl_print_client_cert_types(BIO *bio, SSL *s)
     BIO_puts(bio, "\n");
 }
 
+static const char *get_sigtype(int nid)
+{
+    switch (nid) {
+    case EVP_PKEY_RSA:
+        return "RSA";
+
+    case EVP_PKEY_RSA_PSS:
+        return "RSA-PSS";
+
+    case EVP_PKEY_DSA:
+        return "DSA";
+
+     case EVP_PKEY_EC:
+        return "ECDSA";
+
+    default:
+        return NULL;
+    }
+}
+
 static int do_print_sigalgs(BIO *out, SSL *s, int shared)
 {
     int i, nsig, client;
@@ -241,12 +261,7 @@ static int do_print_sigalgs(BIO *out, SSL *s, int shared)
             SSL_get_sigalgs(s, i, &sign_nid, &hash_nid, NULL, &rsign, &rhash);
         if (i)
             BIO_puts(out, ":");
-        if (sign_nid == EVP_PKEY_RSA)
-            sstr = "RSA";
-        else if (sign_nid == EVP_PKEY_DSA)
-            sstr = "DSA";
-        else if (sign_nid == EVP_PKEY_EC)
-            sstr = "ECDSA";
+        sstr = get_sigtype(sign_nid);
         if (sstr)
             BIO_printf(out, "%s+", sstr);
         else
@@ -262,13 +277,15 @@ static int do_print_sigalgs(BIO *out, SSL *s, int shared)
 
 int ssl_print_sigalgs(BIO *out, SSL *s)
 {
-    int mdnid;
+    int nid;
     if (!SSL_is_server(s))
         ssl_print_client_cert_types(out, s);
     do_print_sigalgs(out, s, 0);
     do_print_sigalgs(out, s, 1);
-    if (SSL_get_peer_signature_nid(s, &mdnid))
-        BIO_printf(out, "Peer signing digest: %s\n", OBJ_nid2sn(mdnid));
+    if (SSL_get_peer_signature_nid(s, &nid))
+        BIO_printf(out, "Peer signing digest: %s\n", OBJ_nid2sn(nid));
+    if (SSL_get_peer_signature_type_nid(s, &nid))
+        BIO_printf(bio_err, "Peer signature type: %s\n", get_sigtype(nid));
     return 1;
 }
 
@@ -1088,6 +1105,8 @@ void print_ssl_summary(SSL *s)
         BIO_puts(bio_err, "\n");
         if (SSL_get_peer_signature_nid(s, &nid))
             BIO_printf(bio_err, "Hash used: %s\n", OBJ_nid2sn(nid));
+        if (SSL_get_peer_signature_type_nid(s, &nid))
+            BIO_printf(bio_err, "Signature type: %s\n", get_sigtype(nid));
         print_verify_detail(s, bio_err);
     } else
         BIO_puts(bio_err, "No peer certificate\n");
diff --git a/doc/man3/SSL_CTX_set1_sigalgs.pod b/doc/man3/SSL_CTX_set1_sigalgs.pod
index f828c02..7795388 100644
--- a/doc/man3/SSL_CTX_set1_sigalgs.pod
+++ b/doc/man3/SSL_CTX_set1_sigalgs.pod
@@ -70,11 +70,14 @@ prohibits them (for example SHA1 if the security level is 4 or more).
 
 Currently the NID_md5, NID_sha1, NID_sha224, NID_sha256, NID_sha384 and
 NID_sha512 digest NIDs are supported and the public key algorithm NIDs
-EVP_PKEY_RSA, EVP_PKEY_DSA and EVP_PKEY_EC.
+EVP_PKEY_RSA, EVP_PKEY_RSA_PSS, EVP_PKEY_DSA and EVP_PKEY_EC.
 
 The short or long name values for digests can be used in a string (for
 example "MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512") and
-the public key algorithm strings "RSA", "DSA" or "ECDSA".
+the public key algorithm strings "RSA", "RSA-PSS", "DSA" or "ECDSA".
+
+The TLS 1.3 signature scheme names (such as "rsa_pss_sha256") can also
+be used.
 
 The use of MD5 as a digest is strongly discouraged due to security weaknesses.
 
diff --git a/doc/man3/SSL_get_peer_signature_nid.pod b/doc/man3/SSL_get_peer_signature_nid.pod
new file mode 100644
index 0000000..492b13f
--- /dev/null
+++ b/doc/man3/SSL_get_peer_signature_nid.pod
@@ -0,0 +1,45 @@
+=pod
+
+=head1 NAME
+
+SSL_get_peer_signature_nid, SSL_get_peer_signature_type_nid - get TLS
+message signing types
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ int SSL_get_peer_signature_nid(SSL *ssl, int *psig_nid);
+ int SSL_get_peer_signature_type_nid(const SSL *ssl, int *psigtype_nid);
+
+=head1 DESCRIPTION
+
+SSL_get_peer_signature_nid() sets B<*psig_nid> to the NID of the digest used
+by the peer to sign TLS messages. It is implemented as a macro.
+
+SSL_get_peer_signature_type_nid() sets B<*psigtype_nid> to the signature
+type used by the peer to sign TLS messages. Currently the signature type
+is the NID of the public key type used for signing except for PSS signing
+where it is B<EVP_PKEY_RSA_PSS>.
+
+=head1 RETURN VALUES
+
+These functions return 1 for success and 0 for failure. There are several
+possible reasons for failure: the ciphersuite has no signature (e.g. it
+uses RSA key exchange or is anonymous), the TLS version is below 1.2 or
+the functions were called before the peer signed a message.
+
+=head1 SEE ALSO
+
+L<ssl(7)>, L<SSL_get_peer_certificate(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/tls1.h b/include/openssl/tls1.h
index 328b266..a4258ac 100644
--- a/include/openssl/tls1.h
+++ b/include/openssl/tls1.h
@@ -252,6 +252,8 @@ __owur int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
                                const unsigned char *p, size_t plen,
                                int use_context);
 
+int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid);
+
 int SSL_get_sigalgs(SSL *s, int idx,
                     int *psign, int *phash, int *psignandhash,
                     unsigned char *rsig, unsigned char *rhash);
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index c7bfa22..13be4f3 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -1266,11 +1266,13 @@ typedef struct ssl3_state_st {
          * algorithms extension for server or as part of a certificate
          * request for client.
          */
-        unsigned int *peer_sigalgs;
+        uint16_t *peer_sigalgs;
         /* Size of above array */
         size_t peer_sigalgslen;
         /* Digest peer uses for signing */
         const EVP_MD *peer_md;
+        /* Signature type: public key type or EVP_PKEY_RSA_PSS for PSS */
+        int peer_sigtype;
         /* Array of digests used for signing */
         const EVP_MD *md[SSL_PKEY_NUM];
         /*
@@ -1507,6 +1509,25 @@ typedef struct {
     size_t meths_count;
 } custom_ext_methods;
 
+/*
+ * Structure containing table entry of values associated with the signature
+ * algorithms (signature scheme) extension
+*/
+typedef struct sigalg_lookup_st {
+    /* TLS 1.3 signature scheme name */
+    const char *name;
+    /* Raw value used in extension */
+    uint16_t sigalg;
+    /* NID of hash algorithm */
+    int hash;
+    /* NID of signature algorithm */
+    int sig;
+    /* Combined hash and signature NID, if any */
+    int sigandhash;
+    /* Required public key curve (ECDSA only) */
+    int curve;
+} SIGALG_LOOKUP;
+
 typedef struct cert_st {
     /* Current active set */
     /*
@@ -1535,7 +1556,7 @@ typedef struct cert_st {
      * the client hello as the supported signature algorithms extension. For
      * servers it represents the signature algorithms we are willing to use.
      */
-    unsigned int *conf_sigalgs;
+    uint16_t *conf_sigalgs;
     /* Size of above array */
     size_t conf_sigalgslen;
     /*
@@ -1545,14 +1566,14 @@ typedef struct cert_st {
      * represents the signature algorithms we are willing to use for client
      * authentication.
      */
-    unsigned int *client_sigalgs;
+    uint16_t *client_sigalgs;
     /* Size of above array */
     size_t client_sigalgslen;
     /*
      * Signature algorithms shared by client and server: cached because these
      * are used most often.
      */
-    TLS_SIGALGS *shared_sigalgs;
+    const SIGALG_LOOKUP **shared_sigalgs;
     size_t shared_sigalgslen;
     /*
      * Certificate setup callback: if set is called whenever a certificate
@@ -1586,18 +1607,6 @@ typedef struct cert_st {
     CRYPTO_RWLOCK *lock;
 } CERT;
 
-/* Structure containing decoded values of signature algorithms extension */
-struct tls_sigalgs_st {
-    /* NID of hash algorithm */
-    int hash_nid;
-    /* NID of signature algorithm */
-    int sign_nid;
-    /* Combined hash and signature NID */
-    int signandhash_nid;
-    /* Raw value used in extension */
-    unsigned int rsigalg;
-};
-
 # define FP_ICC  (int (*)(const void *,const void *))
 
 /*
@@ -1741,10 +1750,7 @@ typedef enum tlsext_index_en {
 /* An invalid index into the TLSv1.3 PSK identities */
 #define TLSEXT_PSK_BAD_IDENTITY                                 -1
 
-#define SIGID_IS_PSS(sigid) ((sigid) == TLSEXT_SIGALG_rsa_pss_sha256 \
-                             || (sigid) == TLSEXT_SIGALG_rsa_pss_sha384 \
-                             || (sigid) == TLSEXT_SIGALG_rsa_pss_sha512)
-
+#define SSL_USE_PSS(s) (s->s3->tmp.peer_sigtype == EVP_PKEY_RSA_PSS)
 
 /* A dummy signature value not valid for TLSv1.2 signature algs */
 #define TLSEXT_signature_rsa_pss                                0x0101
@@ -2250,12 +2256,11 @@ __owur EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md);
 void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
 __owur long ssl_get_algorithm2(SSL *s);
 __owur int tls12_copy_sigalgs(SSL *s, WPACKET *pkt,
-                              const unsigned int *psig, size_t psiglen);
+                              const uint16_t *psig, size_t psiglen);
 __owur int tls1_save_sigalgs(SSL *s, PACKET *pkt);
 __owur int tls1_process_sigalgs(SSL *s);
-__owur size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned int **psigs);
-__owur int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, unsigned int sig,
-                                   EVP_PKEY *pkey);
+__owur size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs);
+__owur int tls12_check_peer_sigalg(SSL *s, unsigned int sig, EVP_PKEY *pkey);
 void ssl_set_client_disabled(SSL *s);
 __owur int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op);
 
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index ceae77f..68b52e1 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -227,7 +227,7 @@ int tls_construct_ctos_sig_algs(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
                                 int *al)
 {
     size_t salglen;
-    const unsigned int *salg;
+    const uint16_t *salg;
 
     if (!SSL_CLIENT_USE_SIGALGS(s))
         return 1;
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index 9ce4ff6..d5d933c 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -1902,7 +1902,7 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey, int *al)
 
 MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
 {
-    int al = -1, ispss = 0;
+    int al = -1;
     long alg_k;
     EVP_PKEY *pkey = NULL;
     EVP_MD_CTX *md_ctx = NULL;
@@ -1967,7 +1967,7 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
                 SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
                 goto err;
             }
-            rv = tls12_check_peer_sigalg(&md, s, sigalg, pkey);
+            rv = tls12_check_peer_sigalg(s, sigalg, pkey);
             if (rv == -1) {
                 al = SSL_AD_INTERNAL_ERROR;
                 goto err;
@@ -1975,7 +1975,7 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
                 al = SSL_AD_DECODE_ERROR;
                 goto err;
             }
-            ispss = SIGID_IS_PSS(sigalg);
+            md = s->s3->tmp.peer_md;
 #ifdef SSL_DEBUG
             fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
 #endif
@@ -2021,10 +2021,10 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
             SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB);
             goto err;
         }
-        if (ispss) {
+        if (SSL_USE_PSS(s)) {
             if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) <= 0
-                       /* -1 here means set saltlen to the digest len */
-                    || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1) <= 0) {
+                || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx,
+                                                RSA_PSS_SALTLEN_DIGEST) <= 0) {
                 al = SSL_AD_INTERNAL_ERROR;
                 SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB);
                 goto err;
diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c
index c8b1469..a05b67f 100644
--- a/ssl/statem/statem_lib.c
+++ b/ssl/statem/statem_lib.c
@@ -231,8 +231,8 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt)
 
     if (ispss) {
         if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) <= 0
-                   /* -1 here means set saltlen to the digest len */
-                || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1) <= 0) {
+            || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx,
+                                                RSA_PSS_SALTLEN_DIGEST) <= 0) {
             SSLerr(SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ERR_R_EVP_LIB);
             goto err;
         }
@@ -286,7 +286,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
     unsigned char *gost_data = NULL;
 #endif
     int al = SSL_AD_INTERNAL_ERROR, ret = MSG_PROCESS_ERROR;
-    int type = 0, j, pktype, ispss = 0;
+    int type = 0, j, pktype;
     unsigned int len;
     X509 *peer;
     const EVP_MD *md = NULL;
@@ -333,14 +333,14 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
                 al = SSL_AD_DECODE_ERROR;
                 goto f_err;
             }
-            rv = tls12_check_peer_sigalg(&md, s, sigalg, pkey);
+            rv = tls12_check_peer_sigalg(s, sigalg, pkey);
             if (rv == -1) {
                 goto f_err;
             } else if (rv == 0) {
                 al = SSL_AD_DECODE_ERROR;
                 goto f_err;
             }
-            ispss = SIGID_IS_PSS(sigalg);
+            md = s->s3->tmp.peer_md;
 #ifdef SSL_DEBUG
             fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
 #endif
@@ -402,10 +402,10 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
     }
 #endif
 
-    if (ispss) {
+    if (SSL_USE_PSS(s)) {
         if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) <= 0
-                   /* -1 here means set saltlen to the digest len */
-                || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1) <= 0) {
+            || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx,
+                                                RSA_PSS_SALTLEN_DIGEST) <= 0) {
             SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
             goto f_err;
         }
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index 023f1ac..4228a4b 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -2274,8 +2274,7 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
             if (ispss) {
                 if (EVP_PKEY_CTX_set_rsa_padding(pctx,
                                                  RSA_PKCS1_PSS_PADDING) <= 0
-                           /* -1 here means set saltlen to the digest len */
-                        || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1) <= 0) {
+                    || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, RSA_PSS_SALTLEN_DIGEST) <= 0) {
                     SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
                            ERR_R_EVP_LIB);
                     goto f_err;
@@ -2333,7 +2332,7 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt)
     }
 
     if (SSL_USE_SIGALGS(s)) {
-        const unsigned int *psigs;
+        const uint16_t *psigs;
         size_t nl = tls12_get_psigalgs(s, 1, &psigs);
 
         if (!WPACKET_start_sub_packet_u16(pkt)
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index a7239c7..c906061 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -607,7 +607,7 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
         else
             return 0;           /* Should never happen */
         for (i = 0; i < c->shared_sigalgslen; i++)
-            if (check_md == c->shared_sigalgs[i].signandhash_nid)
+            if (check_md == c->shared_sigalgs[i]->sigandhash)
                 break;
         if (i == c->shared_sigalgslen)
             return 0;
@@ -670,7 +670,7 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
 #endif                          /* OPENSSL_NO_EC */
 
 /* Default sigalg schemes */
-static const unsigned int tls12_sigalgs[] = {
+static const uint16_t tls12_sigalgs[] = {
 #ifndef OPENSSL_NO_EC
     TLSEXT_SIGALG_ecdsa_secp256r1_sha256,
     TLSEXT_SIGALG_ecdsa_secp384r1_sha384,
@@ -699,77 +699,88 @@ static const unsigned int tls12_sigalgs[] = {
 };
 
 #ifndef OPENSSL_NO_EC
-static const unsigned int suiteb_sigalgs[] = {
+static const uint16_t suiteb_sigalgs[] = {
     TLSEXT_SIGALG_ecdsa_secp256r1_sha256,
     TLSEXT_SIGALG_ecdsa_secp384r1_sha384
 };
 #endif
 
-typedef struct sigalg_lookup_st {
-    unsigned int sigalg;
-    int hash;
-    int sig;
-} SIGALG_LOOKUP;
-
 static const SIGALG_LOOKUP sigalg_lookup_tbl[] = {
 #ifndef OPENSSL_NO_EC
-    {TLSEXT_SIGALG_ecdsa_secp256r1_sha256, NID_sha256, EVP_PKEY_EC},
-    {TLSEXT_SIGALG_ecdsa_secp384r1_sha384, NID_sha384, EVP_PKEY_EC},
-    {TLSEXT_SIGALG_ecdsa_secp521r1_sha512, NID_sha512, EVP_PKEY_EC},
-    {TLSEXT_SIGALG_ecdsa_sha1, NID_sha1, EVP_PKEY_EC},
+    {"ecdsa_secp256r1_sha256", TLSEXT_SIGALG_ecdsa_secp256r1_sha256,
+     NID_sha256, EVP_PKEY_EC, NID_ecdsa_with_SHA256, NID_X9_62_prime256v1},
+    {"ecdsa_secp384r1_sha384", TLSEXT_SIGALG_ecdsa_secp384r1_sha384,
+     NID_sha384, EVP_PKEY_EC, NID_ecdsa_with_SHA384, NID_secp384r1},
+    {"ecdsa_secp521r1_sha512", TLSEXT_SIGALG_ecdsa_secp521r1_sha512,
+     NID_sha512, EVP_PKEY_EC, NID_ecdsa_with_SHA512, NID_secp521r1},
+    {NULL, TLSEXT_SIGALG_ecdsa_sha1,
+     NID_sha1, EVP_PKEY_EC, NID_ecdsa_with_SHA1, NID_undef},
 #endif
-    /*
-     * PSS must appear before PKCS1 so that we prefer that when signing where
-     * possible
-     */
-    {TLSEXT_SIGALG_rsa_pss_sha256, NID_sha256, EVP_PKEY_RSA},
-    {TLSEXT_SIGALG_rsa_pss_sha384, NID_sha384, EVP_PKEY_RSA},
-    {TLSEXT_SIGALG_rsa_pss_sha512, NID_sha512, EVP_PKEY_RSA},
-    {TLSEXT_SIGALG_rsa_pkcs1_sha256, NID_sha256, EVP_PKEY_RSA},
-    {TLSEXT_SIGALG_rsa_pkcs1_sha384, NID_sha384, EVP_PKEY_RSA},
-    {TLSEXT_SIGALG_rsa_pkcs1_sha512, NID_sha512, EVP_PKEY_RSA},
-    {TLSEXT_SIGALG_rsa_pkcs1_sha1, NID_sha1, EVP_PKEY_RSA},
+    {"rsa_pss_sha256", TLSEXT_SIGALG_rsa_pss_sha256,
+     NID_sha256, EVP_PKEY_RSA_PSS, NID_undef, NID_undef},
+    {"rsa_pss_sha384", TLSEXT_SIGALG_rsa_pss_sha384,
+     NID_sha384, EVP_PKEY_RSA_PSS, NID_undef, NID_undef},
+    {"rsa_pss_sha512", TLSEXT_SIGALG_rsa_pss_sha512,
+     NID_sha512, EVP_PKEY_RSA_PSS, NID_undef, NID_undef},
+    {"rsa_pkcs1_sha256", TLSEXT_SIGALG_rsa_pkcs1_sha256,
+     NID_sha256, EVP_PKEY_RSA, NID_sha256WithRSAEncryption, NID_undef},
+    {"rsa_pkcs1_sha384", TLSEXT_SIGALG_rsa_pkcs1_sha384,
+     NID_sha384, EVP_PKEY_RSA, NID_sha384WithRSAEncryption, NID_undef},
+    {"rsa_pkcs1_sha512", TLSEXT_SIGALG_rsa_pkcs1_sha512,
+     NID_sha512, EVP_PKEY_RSA, NID_sha512WithRSAEncryption, NID_undef},
+    {"rsa_pkcs1_sha1", TLSEXT_SIGALG_rsa_pkcs1_sha1,
+     NID_sha1, EVP_PKEY_RSA, NID_sha1WithRSAEncryption, NID_undef},
 #ifndef OPENSSL_NO_DSA
-    {TLSEXT_SIGALG_dsa_sha256, NID_sha256, EVP_PKEY_DSA},
-    {TLSEXT_SIGALG_dsa_sha384, NID_sha384, EVP_PKEY_DSA},
-    {TLSEXT_SIGALG_dsa_sha512, NID_sha512, EVP_PKEY_DSA},
-    {TLSEXT_SIGALG_dsa_sha1, NID_sha1, EVP_PKEY_DSA},
+    {NULL, TLSEXT_SIGALG_dsa_sha256,
+     NID_sha256, EVP_PKEY_DSA, NID_dsa_with_SHA256, NID_undef},
+    {NULL, TLSEXT_SIGALG_dsa_sha384,
+     NID_sha384, EVP_PKEY_DSA, NID_undef, NID_undef},
+    {NULL, TLSEXT_SIGALG_dsa_sha512,
+     NID_sha512, EVP_PKEY_DSA, NID_undef, NID_undef},
+    {NULL, TLSEXT_SIGALG_dsa_sha1,
+     NID_sha1, EVP_PKEY_DSA, NID_dsaWithSHA1, NID_undef},
 #endif
 #ifndef OPENSSL_NO_GOST
-    {TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, NID_id_GostR3411_2012_256, NID_id_GostR3410_2012_256},
-    {TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, NID_id_GostR3411_2012_512, NID_id_GostR3410_2012_512},
-    {TLSEXT_SIGALG_gostr34102001_gostr3411, NID_id_GostR3411_94, NID_id_GostR3410_2001}
+    {NULL, TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256,
+     NID_id_GostR3411_2012_256, NID_id_GostR3410_2012_256, NID_undef,
+     NID_undef},
+    {NULL, TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512,
+     NID_id_GostR3411_2012_512, NID_id_GostR3410_2012_512, NID_undef,
+     NID_undef},
+    {NULL, TLSEXT_SIGALG_gostr34102001_gostr3411,
+     NID_id_GostR3411_94, NID_id_GostR3410_2001, NID_undef, NID_undef}
 #endif
 };
 
-static int tls_sigalg_get_hash(unsigned int sigalg)
+/* Lookup TLS signature algorithm */
+static const SIGALG_LOOKUP *tls1_lookup_sigalg(uint16_t sigalg)
 {
     size_t i;
-    const SIGALG_LOOKUP *curr;
+    const SIGALG_LOOKUP *s;
 
-    for (i = 0, curr = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl);
-         i++, curr++) {
-        if (curr->sigalg == sigalg)
-            return curr->hash;
+    for (i = 0, s = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl);
+         i++, s++) {
+        if (s->sigalg == sigalg)
+            return s;
     }
-
-    return 0;
+    return NULL;
 }
 
-static int tls_sigalg_get_sig(unsigned int sigalg)
+static int tls_sigalg_get_hash(uint16_t sigalg)
 {
-    size_t i;
-    const SIGALG_LOOKUP *curr;
+    const SIGALG_LOOKUP *r = tls1_lookup_sigalg(sigalg);
 
-    for (i = 0, curr = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl);
-         i++, curr++) {
-        if (curr->sigalg == sigalg)
-            return curr->sig;
-    }
+    return r != NULL ? r->hash : 0;
+}
 
-    return 0;
+static int tls_sigalg_get_sig(uint16_t sigalg)
+{
+    const SIGALG_LOOKUP *r = tls1_lookup_sigalg(sigalg);
+
+    return r != NULL ? r->sig : 0;
 }
-size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned int **psigs)
+
+size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs)
 {
     /*
      * If Suite B mode use Suite B sigalgs only, ignore any other
@@ -809,20 +820,26 @@ size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned int **psigs)
 
 /*
  * Check signature algorithm is consistent with sent supported signature
- * algorithms and if so return relevant digest.
+ * algorithms and if so set relevant digest and signature scheme in
+ * s.
  */
-int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, unsigned int sig,
-                            EVP_PKEY *pkey)
+int tls12_check_peer_sigalg(SSL *s, unsigned int sig, EVP_PKEY *pkey)
 {
-    const unsigned int *sent_sigs;
+    const uint16_t *sent_sigs;
+    const EVP_MD *md = NULL;
     char sigalgstr[2];
     size_t sent_sigslen, i;
     int pkeyid = EVP_PKEY_id(pkey);
+    int peer_sigtype;
+
     /* Should never happen */
     if (pkeyid == -1)
         return -1;
     /* Check key type is consistent with signature */
-    if (pkeyid != tls_sigalg_get_sig(sig)) {
+    peer_sigtype = tls_sigalg_get_sig(sig);
+    /* RSA keys can be used for RSA-PSS */
+    if (pkeyid != peer_sigtype
+        && (peer_sigtype != EVP_PKEY_RSA_PSS || pkeyid != EVP_PKEY_RSA)) {
         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
         return 0;
     }
@@ -872,8 +889,8 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, unsigned int sig,
         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
         return 0;
     }
-    *pmd = tls12_get_hash(tls_sigalg_get_hash(sig));
-    if (*pmd == NULL) {
+    md = tls12_get_hash(tls_sigalg_get_hash(sig));
+    if (md == NULL) {
         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_UNKNOWN_DIGEST);
         return 0;
     }
@@ -884,7 +901,7 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, unsigned int sig,
     sigalgstr[0] = (sig >> 8) & 0xff;
     sigalgstr[1] = sig & 0xff;
     if (!ssl_security(s, SSL_SECOP_SIGALG_CHECK,
-                      EVP_MD_size(*pmd) * 4, EVP_MD_type(*pmd),
+                      EVP_MD_size(md) * 4, EVP_MD_type(md),
                       (void *)sigalgstr)) {
         SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
         return 0;
@@ -892,7 +909,16 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, unsigned int sig,
     /*
      * Store the digest used so applications can retrieve it if they wish.
      */
-    s->s3->tmp.peer_md = *pmd;
+    s->s3->tmp.peer_md = md;
+    s->s3->tmp.peer_sigtype = peer_sigtype;
+    return 1;
+}
+
+int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid)
+{
+    if (s->s3->tmp.peer_sigtype == NID_undef)
+        return 0;
+    *pnid = s->s3->tmp.peer_sigtype;
     return 1;
 }
 
@@ -1250,7 +1276,7 @@ TICKET_RETURN tls_decrypt_ticket(SSL *s, const unsigned char *etick,
 int tls12_get_sigandhash(SSL *s, WPACKET *pkt, const EVP_PKEY *pk,
                          const EVP_MD *md, int *ispss)
 {
-    int md_id, sig_id, tmpispss = 0;
+    int md_id, sig_id;
     size_t i;
     const SIGALG_LOOKUP *curr;
 
@@ -1260,34 +1286,42 @@ int tls12_get_sigandhash(SSL *s, WPACKET *pkt, const EVP_PKEY *pk,
     sig_id = EVP_PKEY_id(pk);
     if (md_id == NID_undef)
         return 0;
+    /* For TLS 1.3 only allow RSA-PSS */
+    if (SSL_IS_TLS13(s) && sig_id == EVP_PKEY_RSA)
+        sig_id = EVP_PKEY_RSA_PSS;
 
-    for (i = 0, curr = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl);
-         i++, curr++) {
-        if (curr->hash == md_id && curr->sig == sig_id) {
-            if (sig_id == EVP_PKEY_RSA) {
-                tmpispss = SIGID_IS_PSS(curr->sigalg);
-                if (!SSL_IS_TLS13(s) && tmpispss) {
-                    size_t j;
-
-                    /*
-                     * Check peer actually sent a PSS sig id - it could have
-                     * been a PKCS1 sig id instead.
-                     */
-                    for (j = 0; j < s->cert->shared_sigalgslen; j++)
-                        if (s->cert->shared_sigalgs[j].rsigalg == curr->sigalg)
-                            break;
-
-                    if (j == s->cert->shared_sigalgslen)
-                        continue;
-                }
+    if (s->s3->tmp.peer_sigalgs == NULL) {
+        /* Should never happen: we abort if no sigalgs extension and TLS 1.3 */
+        if (SSL_IS_TLS13(s))
+            return 0;
+        /* For TLS 1.2 and no sigalgs lookup using complete table */
+        for (i = 0, curr = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl);
+             i++, curr++) {
+            if (curr->hash == md_id && curr->sig == sig_id) {
+                if (!WPACKET_put_bytes_u16(pkt, curr->sigalg))
+                    return 0;
+                *ispss = curr->sig == EVP_PKEY_RSA_PSS;
+                return 1;
             }
+        }
+        return 0;
+    }
+
+    for (i = 0; i < s->cert->shared_sigalgslen; i++) {
+        curr = s->cert->shared_sigalgs[i];
+
+        /*
+         * Look for matching key and hash. If key type is RSA also match PSS
+         * signature type.
+         */
+        if (curr->hash == md_id && (curr->sig == sig_id
+            || (sig_id == EVP_PKEY_RSA && curr->sig == EVP_PKEY_RSA_PSS))){
             if (!WPACKET_put_bytes_u16(pkt, curr->sigalg))
                 return 0;
-            *ispss = tmpispss;
+            *ispss = curr->sig == EVP_PKEY_RSA_PSS;
             return 1;
         }
     }
-
     return 0;
 }
 
@@ -1340,6 +1374,12 @@ static int tls12_get_pkey_idx(int sig_nid)
 #ifndef OPENSSL_NO_RSA
     case EVP_PKEY_RSA:
         return SSL_PKEY_RSA_SIGN;
+    /*
+     * For now return RSA key for PSS. When we support PSS only keys
+     * this will need to be updated.
+     */
+    case EVP_PKEY_RSA_PSS:
+        return SSL_PKEY_RSA_SIGN;
 #endif
 #ifndef OPENSSL_NO_DSA
     case EVP_PKEY_DSA:
@@ -1363,30 +1403,6 @@ static int tls12_get_pkey_idx(int sig_nid)
     return -1;
 }
 
-/* Convert TLS 1.2 signature algorithm extension values into NIDs */
-static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid,
-                               int *psignhash_nid, unsigned int data)
-{
-    int sign_nid = NID_undef, hash_nid = NID_undef;
-    if (!phash_nid && !psign_nid && !psignhash_nid)
-        return;
-    if (phash_nid || psignhash_nid) {
-        hash_nid = tls_sigalg_get_hash(data);
-        if (phash_nid)
-            *phash_nid = hash_nid;
-    }
-    if (psign_nid || psignhash_nid) {
-        sign_nid = tls_sigalg_get_sig(data);
-        if (psign_nid)
-            *psign_nid = sign_nid;
-    }
-    if (psignhash_nid) {
-        if (sign_nid == NID_undef || hash_nid == NID_undef
-            || OBJ_find_sigid_by_algs(psignhash_nid, hash_nid, sign_nid) <= 0)
-            *psignhash_nid = NID_undef;
-    }
-}
-
 /* Check to see if a signature algorithm is allowed */
 static int tls12_sigalg_allowed(SSL *s, int op, unsigned int ptmp)
 {
@@ -1414,7 +1430,7 @@ static int tls12_sigalg_allowed(SSL *s, int op, unsigned int ptmp)
 
 void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op)
 {
-    const unsigned int *sigalgs;
+    const uint16_t *sigalgs;
     size_t i, sigalgslen;
     int have_rsa = 0, have_dsa = 0, have_ecdsa = 0;
     /*
@@ -1426,6 +1442,8 @@ void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op)
     for (i = 0; i < sigalgslen; i ++, sigalgs++) {
         switch (tls_sigalg_get_sig(*sigalgs)) {
 #ifndef OPENSSL_NO_RSA
+        /* Any RSA-PSS signature algorithms also mean we allow RSA */
+        case EVP_PKEY_RSA_PSS:
         case EVP_PKEY_RSA:
             if (!have_rsa && tls12_sigalg_allowed(s, op, *sigalgs))
                 have_rsa = 1;
@@ -1454,7 +1472,7 @@ void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op)
 }
 
 int tls12_copy_sigalgs(SSL *s, WPACKET *pkt,
-                       const unsigned int *psig, size_t psiglen)
+                       const uint16_t *psig, size_t psiglen)
 {
     size_t i;
 
@@ -1468,11 +1486,11 @@ int tls12_copy_sigalgs(SSL *s, WPACKET *pkt,
 }
 
 /* Given preference and allowed sigalgs set shared sigalgs */
-static size_t tls12_shared_sigalgs(SSL *s, TLS_SIGALGS *shsig,
-                                   const unsigned int *pref, size_t preflen,
-                                   const unsigned int *allow, size_t allowlen)
+static size_t tls12_shared_sigalgs(SSL *s, const SIGALG_LOOKUP **shsig,
+                                   const uint16_t *pref, size_t preflen,
+                                   const uint16_t *allow, size_t allowlen)
 {
-    const unsigned int *ptmp, *atmp;
+    const uint16_t *ptmp, *atmp;
     size_t i, j, nmatch = 0;
     for (i = 0, ptmp = pref; i < preflen; i++, ptmp++) {
         /* Skip disabled hashes or signature algorithms */
@@ -1482,10 +1500,7 @@ static size_t tls12_shared_sigalgs(SSL *s, TLS_SIGALGS *shsig,
             if (*ptmp == *atmp) {
                 nmatch++;
                 if (shsig) {
-                    shsig->rsigalg = *ptmp;
-                    tls1_lookup_sigalg(&shsig->hash_nid,
-                                       &shsig->sign_nid,
-                                       &shsig->signandhash_nid, *ptmp);
+                    *shsig = tls1_lookup_sigalg(*ptmp);
                     shsig++;
                 }
                 break;
@@ -1498,10 +1513,10 @@ static size_t tls12_shared_sigalgs(SSL *s, TLS_SIGALGS *shsig,
 /* Set shared signature algorithms for SSL structures */
 static int tls1_set_shared_sigalgs(SSL *s)
 {
-    const unsigned int *pref, *allow, *conf;
+    const uint16_t *pref, *allow, *conf;
     size_t preflen, allowlen, conflen;
     size_t nmatch;
-    TLS_SIGALGS *salgs = NULL;
+    const SIGALG_LOOKUP **salgs = NULL;
     CERT *c = s->cert;
     unsigned int is_suiteb = tls1_suiteb(s);
 
@@ -1530,7 +1545,7 @@ static int tls1_set_shared_sigalgs(SSL *s)
     }
     nmatch = tls12_shared_sigalgs(s, NULL, pref, preflen, allow, allowlen);
     if (nmatch) {
-        salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS));
+        salgs = OPENSSL_malloc(nmatch * sizeof(*salgs));
         if (salgs == NULL)
             return 0;
         nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen);
@@ -1547,6 +1562,7 @@ static int tls1_set_shared_sigalgs(SSL *s)
 int tls1_save_sigalgs(SSL *s, PACKET *pkt)
 {
     CERT *c = s->cert;
+    unsigned int stmp;
     size_t size, i;
 
     /* Extension ignored for inappropriate versions */
@@ -1570,9 +1586,8 @@ int tls1_save_sigalgs(SSL *s, PACKET *pkt)
     if (s->s3->tmp.peer_sigalgs == NULL)
         return 0;
     s->s3->tmp.peer_sigalgslen = size;
-    for (i = 0; i < size && PACKET_get_net_2(pkt, &s->s3->tmp.peer_sigalgs[i]);
-         i++)
-        continue;
+    for (i = 0; i < size && PACKET_get_net_2(pkt, &stmp); i++)
+        s->s3->tmp.peer_sigalgs[i] = stmp;
 
     if (i != size)
         return 0;
@@ -1588,22 +1603,19 @@ int tls1_process_sigalgs(SSL *s)
     const EVP_MD **pmd = s->s3->tmp.md;
     uint32_t *pvalid = s->s3->tmp.valid_flags;
     CERT *c = s->cert;
-    TLS_SIGALGS *sigptr;
+
     if (!tls1_set_shared_sigalgs(s))
         return 0;
 
-    for (i = 0, sigptr = c->shared_sigalgs;
-         i < c->shared_sigalgslen; i++, sigptr++) {
+    for (i = 0; i < c->shared_sigalgslen; i++) {
+        const SIGALG_LOOKUP *sigptr = c->shared_sigalgs[i];
+
         /* Ignore PKCS1 based sig algs in TLSv1.3 */
-        if (SSL_IS_TLS13(s)
-                && (sigptr->rsigalg == TLSEXT_SIGALG_rsa_pkcs1_sha1
-                    || sigptr->rsigalg == TLSEXT_SIGALG_rsa_pkcs1_sha256
-                    || sigptr->rsigalg == TLSEXT_SIGALG_rsa_pkcs1_sha384
-                    || sigptr->rsigalg == TLSEXT_SIGALG_rsa_pkcs1_sha512))
+        if (SSL_IS_TLS13(s) && sigptr->sig == EVP_PKEY_RSA)
             continue;
-        idx = tls12_get_pkey_idx(sigptr->sign_nid);
+        idx = tls12_get_pkey_idx(sigptr->sig);
         if (idx > 0 && pmd[idx] == NULL) {
-            md = tls12_get_hash(sigptr->hash_nid);
+            md = tls12_get_hash(sigptr->hash);
             pmd[idx] = md;
             pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN;
             if (idx == SSL_PKEY_RSA_SIGN) {
@@ -1655,19 +1667,27 @@ int SSL_get_sigalgs(SSL *s, int idx,
                     int *psign, int *phash, int *psignhash,
                     unsigned char *rsig, unsigned char *rhash)
 {
-    unsigned int *psig = s->s3->tmp.peer_sigalgs;
+    uint16_t *psig = s->s3->tmp.peer_sigalgs;
     size_t numsigalgs = s->s3->tmp.peer_sigalgslen;
     if (psig == NULL || numsigalgs > INT_MAX)
         return 0;
     if (idx >= 0) {
+        const SIGALG_LOOKUP *lu;
+
         if (idx >= (int)numsigalgs)
             return 0;
         psig += idx;
-        if (rhash)
+        if (rhash != NULL)
             *rhash = (unsigned char)((*psig >> 8) & 0xff);
-        if (rsig)
+        if (rsig != NULL)
             *rsig = (unsigned char)(*psig & 0xff);
-        tls1_lookup_sigalg(phash, psign, psignhash, *psig);
+        lu = tls1_lookup_sigalg(*psig);
+        if (psign != NULL)
+            *psign = lu != NULL ? lu->sig : NID_undef;
+        if (phash != NULL)
+            *phash = lu != NULL ? lu->hash : NID_undef;
+        if (psignhash != NULL)
+            *psignhash = lu != NULL ? lu->sigandhash : NID_undef;
     }
     return (int)numsigalgs;
 }
@@ -1676,35 +1696,39 @@ int SSL_get_shared_sigalgs(SSL *s, int idx,
                            int *psign, int *phash, int *psignhash,
                            unsigned char *rsig, unsigned char *rhash)
 {
-    TLS_SIGALGS *shsigalgs = s->cert->shared_sigalgs;
-    if (!shsigalgs || idx >= (int)s->cert->shared_sigalgslen
-            || s->cert->shared_sigalgslen > INT_MAX)
+    const SIGALG_LOOKUP *shsigalgs;
+    if (s->cert->shared_sigalgs == NULL
+        || idx >= (int)s->cert->shared_sigalgslen
+        || s->cert->shared_sigalgslen > INT_MAX)
         return 0;
-    shsigalgs += idx;
-    if (phash)
-        *phash = shsigalgs->hash_nid;
-    if (psign)
-        *psign = shsigalgs->sign_nid;
-    if (psignhash)
-        *psignhash = shsigalgs->signandhash_nid;
-    if (rsig)
-        *rsig = (unsigned char)(shsigalgs->rsigalg & 0xff);
-    if (rhash)
-        *rhash = (unsigned char)((shsigalgs->rsigalg >> 8) & 0xff);
+    shsigalgs = s->cert->shared_sigalgs[idx];
+    if (phash != NULL)
+        *phash = shsigalgs->hash;
+    if (psign != NULL)
+        *psign = shsigalgs->sig;
+    if (psignhash != NULL)
+        *psignhash = shsigalgs->sigandhash;
+    if (rsig != NULL)
+        *rsig = (unsigned char)(shsigalgs->sigalg & 0xff);
+    if (rhash != NULL)
+        *rhash = (unsigned char)((shsigalgs->sigalg >> 8) & 0xff);
     return (int)s->cert->shared_sigalgslen;
 }
 
-#define MAX_SIGALGLEN   (TLSEXT_hash_num * TLSEXT_signature_num * 2)
+/* Maximum possible number of unique entries in sigalgs array */
+#define TLS_MAX_SIGALGCNT (OSSL_NELEM(sigalg_lookup_tbl) * 2)
 
 typedef struct {
     size_t sigalgcnt;
-    int sigalgs[MAX_SIGALGLEN];
+    int sigalgs[TLS_MAX_SIGALGCNT];
 } sig_cb_st;
 
 static void get_sigorhash(int *psig, int *phash, const char *str)
 {
     if (strcmp(str, "RSA") == 0) {
         *psig = EVP_PKEY_RSA;
+    } else if (strcmp(str, "RSA-PSS") == 0 || strcmp(str, "PSS") == 0) {
+        *psig = EVP_PKEY_RSA_PSS;
     } else if (strcmp(str, "DSA") == 0) {
         *psig = EVP_PKEY_DSA;
     } else if (strcmp(str, "ECDSA") == 0) {
@@ -1715,31 +1739,44 @@ static void get_sigorhash(int *psig, int *phash, const char *str)
             *phash = OBJ_ln2nid(str);
     }
 }
+/* Maximum length of a signature algorithm string component */
+#define TLS_MAX_SIGSTRING_LEN   40
 
 static int sig_cb(const char *elem, int len, void *arg)
 {
     sig_cb_st *sarg = arg;
     size_t i;
-    char etmp[20], *p;
+    char etmp[TLS_MAX_SIGSTRING_LEN], *p;
     int sig_alg = NID_undef, hash_alg = NID_undef;
     if (elem == NULL)
         return 0;
-    if (sarg->sigalgcnt == MAX_SIGALGLEN)
+    if (sarg->sigalgcnt == TLS_MAX_SIGALGCNT)
         return 0;
     if (len > (int)(sizeof(etmp) - 1))
         return 0;
     memcpy(etmp, elem, len);
     etmp[len] = 0;
     p = strchr(etmp, '+');
-    if (!p)
-        return 0;
-    *p = 0;
-    p++;
-    if (!*p)
-        return 0;
-
-    get_sigorhash(&sig_alg, &hash_alg, etmp);
-    get_sigorhash(&sig_alg, &hash_alg, p);
+    /* See if we have a match for TLS 1.3 names */
+    if (p == NULL) {
+        const SIGALG_LOOKUP *s;
+
+        for (i = 0, s = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl);
+             i++, s++) {
+            if (s->name != NULL && strcmp(etmp, s->name) == 0) {
+                sig_alg = s->sig;
+                hash_alg = s->hash;
+                break;
+            }
+        }
+    } else {
+        *p = 0;
+        p++;
+        if (*p == 0)
+            return 0;
+        get_sigorhash(&sig_alg, &hash_alg, etmp);
+        get_sigorhash(&sig_alg, &hash_alg, p);
+    }
 
     if (sig_alg == NID_undef || hash_alg == NID_undef)
         return 0;
@@ -1768,10 +1805,9 @@ int tls1_set_sigalgs_list(CERT *c, const char *str, int client)
     return tls1_set_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client);
 }
 
-/* TODO(TLS1.3): Needs updating to allow setting of TLS1.3 sig algs */
 int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client)
 {
-    unsigned int *sigalgs, *sptr;
+    uint16_t *sigalgs, *sptr;
     size_t i;
 
     if (salglen & 1)
@@ -1779,10 +1815,6 @@ int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client)
     sigalgs = OPENSSL_malloc((salglen / 2) * sizeof(*sigalgs));
     if (sigalgs == NULL)
         return 0;
-    /*
-     * TODO(TLS1.3): Somehow we need to be able to set RSA-PSS as well as
-     * RSA-PKCS1. For now we only allow setting of RSA-PKCS1
-     */
     for (i = 0, sptr = sigalgs; i < salglen; i += 2) {
         size_t j;
         const SIGALG_LOOKUP *curr;
@@ -1791,9 +1823,6 @@ int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client)
 
         for (j = 0, curr = sigalg_lookup_tbl; j < OSSL_NELEM(sigalg_lookup_tbl);
              j++, curr++) {
-            /* Skip setting PSS so we get PKCS1 by default */
-            if (SIGID_IS_PSS(curr->sigalg))
-                continue;
             if (curr->hash == md_id && curr->sig == sig_id) {
                 *sptr++ = curr->sigalg;
                 break;
@@ -1831,7 +1860,7 @@ static int tls1_check_sig_alg(CERT *c, X509 *x, int default_nid)
     if (default_nid)
         return sig_nid == default_nid ? 1 : 0;
     for (i = 0; i < c->shared_sigalgslen; i++)
-        if (sig_nid == c->shared_sigalgs[i].signandhash_nid)
+        if (sig_nid == c->shared_sigalgs[i]->sigandhash)
             return 1;
     return 0;
 }
@@ -1971,7 +2000,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
          */
         if (default_nid > 0 && c->conf_sigalgs) {
             size_t j;
-            const unsigned int *p = c->conf_sigalgs;
+            const uint16_t *p = c->conf_sigalgs;
             for (j = 0; j < c->conf_sigalgslen; j++, p++) {
                 if (tls_sigalg_get_hash(*p) == NID_sha1
                         && tls_sigalg_get_sig(*p) == rsign)
diff --git a/test/README.ssltest.md b/test/README.ssltest.md
index 5e2b2d7..3d0fe91 100644
--- a/test/README.ssltest.md
+++ b/test/README.ssltest.md
@@ -92,9 +92,12 @@ handshake.
 * ExpectedServerCertType, ExpectedClientCertType - the expected algorithm or
   curve of server or client certificate
 
-* ExpectedServerSignatureHash, ExpectedClientSignatureHash - the expected
+* ExpectedServerSignHash, ExpectedClientSignHash - the expected
   signing hash used by server or client certificate
 
+* ExpectedServerSignType, ExpectedClientSignType - the expected
+  signature type used by server or client when signing messages
+
 ## 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 fd79565..a789899 100644
--- a/test/handshake_helper.c
+++ b/test/handshake_helper.c
@@ -1073,6 +1073,9 @@ static HANDSHAKE_RESULT *do_handshake_internal(
     SSL_get_peer_signature_nid(client.ssl, &ret->server_sign_hash);
     SSL_get_peer_signature_nid(server.ssl, &ret->client_sign_hash);
 
+    SSL_get_peer_signature_type_nid(client.ssl, &ret->server_sign_type);
+    SSL_get_peer_signature_type_nid(server.ssl, &ret->client_sign_type);
+
     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 604eed9..bdbeabb 100644
--- a/test/handshake_helper.h
+++ b/test/handshake_helper.h
@@ -49,10 +49,14 @@ typedef struct handshake_result {
     int server_cert_type;
     /* server signing hash */
     int server_sign_hash;
+    /* server signature type */
+    int server_sign_type;
     /* client certificate key type */
     int client_cert_type;
     /* client signing hash */
     int client_sign_hash;
+    /* client signature type */
+    int client_sign_type;
 } HANDSHAKE_RESULT;
 
 HANDSHAKE_RESULT *HANDSHAKE_RESULT_new(void);
diff --git a/test/ssl-tests/01-simple.conf b/test/ssl-tests/01-simple.conf
index 5f4dd84..7fc23f0 100644
--- a/test/ssl-tests/01-simple.conf
+++ b/test/ssl-tests/01-simple.conf
@@ -40,12 +40,12 @@ client = 1-Server signature algorithms bug-client
 [1-Server signature algorithms bug-server]
 Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
 CipherString = DEFAULT
-ClientSignatureAlgorithms = ECDSA+SHA256
+ClientSignatureAlgorithms = PSS+SHA512:RSA+SHA512
 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
 
 [1-Server signature algorithms bug-client]
 CipherString = DEFAULT
-SignatureAlgorithms = RSA+SHA256
+SignatureAlgorithms = PSS+SHA256:RSA+SHA256
 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
 VerifyMode = Peer
 
diff --git a/test/ssl-tests/01-simple.conf.in b/test/ssl-tests/01-simple.conf.in
index 086d66d..54dc451 100644
--- a/test/ssl-tests/01-simple.conf.in
+++ b/test/ssl-tests/01-simple.conf.in
@@ -22,8 +22,8 @@ our @tests = (
     {
         name => "Server signature algorithms bug",
         # Should have no effect as we aren't doing client auth
-        server => { "ClientSignatureAlgorithms" => "ECDSA+SHA256" },
-        client => { "SignatureAlgorithms" => "RSA+SHA256" },
+        server => { "ClientSignatureAlgorithms" => "PSS+SHA512:RSA+SHA512" },
+        client => { "SignatureAlgorithms" => "PSS+SHA256:RSA+SHA256" },
         test   => { "ExpectedResult" => "Success" },
     },
 
diff --git a/test/ssl-tests/04-client_auth.conf b/test/ssl-tests/04-client_auth.conf
index a917098..9602488 100644
--- a/test/ssl-tests/04-client_auth.conf
+++ b/test/ssl-tests/04-client_auth.conf
@@ -562,6 +562,7 @@ VerifyMode = Peer
 [test-18]
 ExpectedClientCertType = RSA
 ExpectedClientSignHash = SHA256
+ExpectedClientSignType = RSA
 ExpectedResult = Success
 
 
diff --git a/test/ssl-tests/04-client_auth.conf.in b/test/ssl-tests/04-client_auth.conf.in
index d45e399..be601a9 100644
--- a/test/ssl-tests/04-client_auth.conf.in
+++ b/test/ssl-tests/04-client_auth.conf.in
@@ -34,10 +34,12 @@ sub generate_tests() {
                 $caalert = "UnknownCA";
             }
             my $clihash;
+            my $clisigtype;
             my $clisigalgs;
-            # TODO add TLSv1.3 versions
+            # TODO(TLS1.3) add TLSv1.3 versions
             if ($protocol_name eq "TLSv1.2") {
                 $clihash = "SHA256";
+                $clisigtype = "RSA";
                 $clisigalgs = "SHA256+RSA";
             }
             # Sanity-check simple handshake.
@@ -106,6 +108,7 @@ sub generate_tests() {
                 },
                 test   => { "ExpectedResult" => "Success",
                             "ExpectedClientCertType" => "RSA",
+                            "ExpectedClientSignType" => $clisigtype,
                             "ExpectedClientSignHash" => $clihash,
                 },
             };
diff --git a/test/ssl-tests/20-cert-select.conf b/test/ssl-tests/20-cert-select.conf
index c663b7e..9f30abb 100644
--- a/test/ssl-tests/20-cert-select.conf
+++ b/test/ssl-tests/20-cert-select.conf
@@ -1,6 +1,6 @@
 # Generated with generate_ssl_tests.pl
 
-num_tests = 6
+num_tests = 7
 
 test-0 = 0-ECDSA CipherString Selection
 test-1 = 1-RSA CipherString Selection
@@ -8,6 +8,7 @@ test-2 = 2-ECDSA CipherString Selection, no ECDSA certificate
 test-3 = 3-ECDSA Signature Algorithm Selection
 test-4 = 4-ECDSA Signature Algorithm Selection, no ECDSA certificate
 test-5 = 5-RSA Signature Algorithm Selection
+test-6 = 6-RSA-PSS Signature Algorithm Selection
 # ===========================================================
 
 [0-ECDSA CipherString Selection]
@@ -33,6 +34,7 @@ VerifyMode = Peer
 [test-0]
 ExpectedResult = Success
 ExpectedServerCertType = P-256
+ExpectedServerSignType = EC
 
 
 # ===========================================================
@@ -60,6 +62,7 @@ VerifyMode = Peer
 [test-1]
 ExpectedResult = Success
 ExpectedServerCertType = RSA
+ExpectedServerSignType = RSA-PSS
 
 
 # ===========================================================
@@ -112,6 +115,7 @@ VerifyMode = Peer
 ExpectedResult = Success
 ExpectedServerCertType = P-256
 ExpectedServerSignHash = SHA256
+ExpectedServerSignType = EC
 
 
 # ===========================================================
@@ -165,5 +169,36 @@ VerifyMode = Peer
 ExpectedResult = Success
 ExpectedServerCertType = RSA
 ExpectedServerSignHash = SHA256
+ExpectedServerSignType = RSA
+
+
+# ===========================================================
+
+[6-RSA-PSS Signature Algorithm Selection]
+ssl_conf = 6-RSA-PSS Signature Algorithm Selection-ssl
+
+[6-RSA-PSS Signature Algorithm Selection-ssl]
+server = 6-RSA-PSS Signature Algorithm Selection-server
+client = 6-RSA-PSS Signature Algorithm Selection-client
+
+[6-RSA-PSS Signature Algorithm Selection-server]
+Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem
+CipherString = DEFAULT
+ECDSA.Certificate = ${ENV::TEST_CERTS_DIR}/server-ecdsa-cert.pem
+ECDSA.PrivateKey = ${ENV::TEST_CERTS_DIR}/server-ecdsa-key.pem
+MaxProtocol = TLSv1.2
+PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem
+
+[6-RSA-PSS Signature Algorithm Selection-client]
+CipherString = DEFAULT
+SignatureAlgorithms = RSA-PSS+SHA256
+VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem
+VerifyMode = Peer
+
+[test-6]
+ExpectedResult = Success
+ExpectedServerCertType = RSA
+ExpectedServerSignHash = SHA256
+ExpectedServerSignType = RSA-PSS
 
 
diff --git a/test/ssl-tests/20-cert-select.conf.in b/test/ssl-tests/20-cert-select.conf.in
index e8bac76..6bc1d90 100644
--- a/test/ssl-tests/20-cert-select.conf.in
+++ b/test/ssl-tests/20-cert-select.conf.in
@@ -15,7 +15,7 @@ my $dir_sep = $^O ne "VMS" ? "/" : "";
 my $server = {
     "ECDSA.Certificate" => "\${ENV::TEST_CERTS_DIR}${dir_sep}server-ecdsa-cert.pem",
     "ECDSA.PrivateKey" => "\${ENV::TEST_CERTS_DIR}${dir_sep}server-ecdsa-key.pem",
-    # TODO: add test cases for TLSv1.3
+    # TODO(TLS1.3): add test cases for TLSv1.3
     "MaxProtocol" => "TLSv1.2"
 };
 
@@ -28,6 +28,7 @@ our @tests = (
         },
         test   => {
             "ExpectedServerCertType" =>, "P-256",
+            "ExpectedServerSignType" =>, "EC",
             "ExpectedResult" => "Success"
         },
     },
@@ -39,6 +40,7 @@ our @tests = (
         },
         test   => {
             "ExpectedServerCertType" =>, "RSA",
+            "ExpectedServerSignType" =>, "RSA-PSS",
             "ExpectedResult" => "Success"
         },
     },
@@ -61,6 +63,7 @@ our @tests = (
         test   => {
             "ExpectedServerCertType" => "P-256",
             "ExpectedServerSignHash" => "SHA256",
+            "ExpectedServerSignType" => "EC",
             "ExpectedResult" => "Success"
         },
     },
@@ -83,6 +86,20 @@ our @tests = (
         test   => {
             "ExpectedServerCertType" => "RSA",
             "ExpectedServerSignHash" => "SHA256",
+            "ExpectedServerSignType" => "RSA",
+            "ExpectedResult" => "Success"
+        },
+    },
+    {
+        name => "RSA-PSS Signature Algorithm Selection",
+        server => $server,
+        client => {
+            "SignatureAlgorithms" => "RSA-PSS+SHA256",
+        },
+        test   => {
+            "ExpectedServerCertType" => "RSA",
+            "ExpectedServerSignHash" => "SHA256",
+            "ExpectedServerSignType" => "RSA-PSS",
             "ExpectedResult" => "Success"
         },
     }
diff --git a/test/ssl_test.c b/test/ssl_test.c
index 58ddca4..752de63 100644
--- a/test/ssl_test.c
+++ b/test/ssl_test.c
@@ -217,6 +217,13 @@ static int check_server_sign_hash(HANDSHAKE_RESULT *result,
                      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)
 {
@@ -231,6 +238,13 @@ static int check_client_sign_hash(HANDSHAKE_RESULT *result,
                      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);
+}
+
 /*
  * This could be further simplified by constructing an expected
  * HANDSHAKE_RESULT, and implementing comparison methods for
@@ -254,8 +268,10 @@ static int check_test(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
         ret &= check_tmp_key(result, 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_client_cert_type(result, test_ctx);
         ret &= check_client_sign_hash(result, test_ctx);
+        ret &= check_client_sign_type(result, test_ctx);
     }
     return ret;
 }
diff --git a/test/ssl_test_ctx.c b/test/ssl_test_ctx.c
index 3a937b3..e88e577 100644
--- a/test/ssl_test_ctx.c
+++ b/test/ssl_test_ctx.c
@@ -432,9 +432,9 @@ IMPLEMENT_SSL_TEST_INT_OPTION(SSL_TEST_CTX, test, app_data_size)
 
 IMPLEMENT_SSL_TEST_INT_OPTION(SSL_TEST_CTX, test, max_fragment_size)
 
-/***********************/
-/* Expected key types  */
-/***********************/
+/*************************************/
+/* Expected key and signature types  */
+/*************************************/
 
 __owur static int parse_expected_key_type(int *ptype, const char *value)
 {
@@ -473,6 +473,13 @@ __owur static int parse_expected_server_cert_type(SSL_TEST_CTX *test_ctx,
                                    value);
 }
 
+__owur static int parse_expected_server_sign_type(SSL_TEST_CTX *test_ctx,
+                                                 const char *value)
+{
+    return parse_expected_key_type(&test_ctx->expected_server_sign_type,
+                                   value);
+}
+
 __owur static int parse_expected_client_cert_type(SSL_TEST_CTX *test_ctx,
                                                   const char *value)
 {
@@ -480,6 +487,13 @@ __owur static int parse_expected_client_cert_type(SSL_TEST_CTX *test_ctx,
                                    value);
 }
 
+__owur static int parse_expected_client_sign_type(SSL_TEST_CTX *test_ctx,
+                                                 const char *value)
+{
+    return parse_expected_key_type(&test_ctx->expected_client_sign_type,
+                                   value);
+}
+
 /*************************/
 /* Expected signing hash */
 /*************************/
@@ -540,8 +554,10 @@ static const ssl_test_ctx_option ssl_test_ctx_options[] = {
     { "ExpectedTmpKeyType", &parse_expected_tmp_key_type },
     { "ExpectedServerCertType", &parse_expected_server_cert_type },
     { "ExpectedServerSignHash", &parse_expected_server_sign_hash },
+    { "ExpectedServerSignType", &parse_expected_server_sign_type },
     { "ExpectedClientCertType", &parse_expected_client_cert_type },
     { "ExpectedClientSignHash", &parse_expected_client_sign_hash },
+    { "ExpectedClientSignType", &parse_expected_client_sign_type },
 };
 
 /* Nested client options. */
diff --git a/test/ssl_test_ctx.h b/test/ssl_test_ctx.h
index b34efe3..13652b0 100644
--- a/test/ssl_test_ctx.h
+++ b/test/ssl_test_ctx.h
@@ -165,10 +165,14 @@ typedef struct {
     int expected_server_cert_type;
     /* Expected server signing hash */
     int expected_server_sign_hash;
+    /* Expected server signature type */
+    int expected_server_sign_type;
     /* Expected client certificate key type */
     int expected_client_cert_type;
     /* Expected client signing hash */
     int expected_client_sign_hash;
+    /* Expected client signature type */
+    int expected_client_sign_type;
 } SSL_TEST_CTX;
 
 const char *ssl_test_result_name(ssl_test_result_t result);
diff --git a/util/libssl.num b/util/libssl.num
index 94def68..199c17a 100644
--- a/util/libssl.num
+++ b/util/libssl.num
@@ -412,3 +412,4 @@ SSL_COMP_get_id                         412	1_1_0d	EXIST::FUNCTION:
 SSL_COMP_get0_name                      413	1_1_0d	EXIST::FUNCTION:
 SSL_CTX_set_keylog_callback             414	1_1_1	EXIST::FUNCTION:
 SSL_CTX_get_keylog_callback             415	1_1_1	EXIST::FUNCTION:
+SSL_get_peer_signature_type_nid         416	1_1_1	EXIST::FUNCTION:


More information about the openssl-commits mailing list