[openssl] master update

Matt Caswell matt at openssl.org
Fri Jun 5 10:15:25 UTC 2020


The branch master has been updated
       via  7b2d995ed79f0653defd682e5097ed937f4cabbc (commit)
       via  7fa2b2673edd684ceb94ff19346f08121da9774f (commit)
       via  11391da217b5d07dd30dd4c1890b5320fa56be18 (commit)
       via  6a9bd9298bd706e3a4a40ecfa1d89f65f8592c65 (commit)
      from  0d52ede71685e4176999cc5e52000dcb540747fc (commit)


- Log -----------------------------------------------------------------
commit 7b2d995ed79f0653defd682e5097ed937f4cabbc
Author: Matt Caswell <matt at openssl.org>
Date:   Tue Jun 2 08:57:26 2020 +0100

    Don't downgrade keys in libssl
    
    We were downgrading to legacy keys at various points in libssl in
    order to get or set an encoded point. Now that the encoded point
    functions work with provided keys this is no longer necessary.
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11898)

commit 7fa2b2673edd684ceb94ff19346f08121da9774f
Author: Matt Caswell <matt at openssl.org>
Date:   Thu May 21 11:36:21 2020 +0100

    When asked if an ECX key has parameters we should answer "true"
    
    An ECX key doesn't have any parameters associated with it. Therefore it
    always has all the parameters it needs, and the "has" function should
    return 1 if asked about parameters. Without this
    EVP_PKEY_missing_parameters() fails for ECX keys.
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11898)

commit 11391da217b5d07dd30dd4c1890b5320fa56be18
Author: Matt Caswell <matt at openssl.org>
Date:   Thu May 21 11:33:53 2020 +0100

    Always create a key when importing
    
    Even if there is no data to import we should still create an empty key.
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11898)

commit 6a9bd9298bd706e3a4a40ecfa1d89f65f8592c65
Author: Matt Caswell <matt at openssl.org>
Date:   Wed May 20 16:20:27 2020 +0100

    Make EVP_PKEY_[get1|set1]_tls_encodedpoint work with provided keys
    
    EVP_PKEY_[get1|set1]_tls_encodedpoint() only worked if an ameth was present
    which isn't the case for provided keys. Support has been added to dh,
    ec and ecx keys.
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/11898)

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

Summary of changes:
 crypto/dh/dh_ameth.c                          |   2 +-
 crypto/dh/dh_key.c                            |  40 ++++++----
 crypto/dh/dh_local.h                          |   3 -
 crypto/evp/keymgmt_lib.c                      |  14 ++--
 crypto/evp/p_lib.c                            |  39 ++++++++++
 doc/man7/EVP_PKEY-DH.pod                      |   5 ++
 doc/man7/EVP_PKEY-EC.pod                      |   5 ++
 doc/man7/EVP_PKEY-X25519.pod                  |   5 ++
 include/crypto/dh.h                           |   3 +
 include/openssl/core_names.h                  |   1 +
 providers/implementations/keymgmt/dh_kmgmt.c  |  38 +++++++++
 providers/implementations/keymgmt/ec_kmgmt.c  |  31 ++++++++
 providers/implementations/keymgmt/ecx_kmgmt.c | 107 ++++++++++++++++++++++++--
 ssl/statem/extensions_clnt.c                  |  31 --------
 ssl/statem/extensions_srvr.c                  |  30 --------
 ssl/statem/statem_clnt.c                      |  30 --------
 ssl/statem/statem_srvr.c                      |  29 -------
 ssl/t1_lib.c                                  |  11 ---
 test/evp_pkey_provided_test.c                 |   3 +-
 19 files changed, 261 insertions(+), 166 deletions(-)

diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c
index d93d519444..d5e5f72517 100644
--- a/crypto/dh/dh_ameth.c
+++ b/crypto/dh/dh_ameth.c
@@ -438,7 +438,7 @@ static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
     case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
         return dh_buf2key(EVP_PKEY_get0_DH(pkey), arg2, arg1);
     case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
-        return dh_key2buf(EVP_PKEY_get0_DH(pkey), arg2);
+        return dh_key2buf(EVP_PKEY_get0_DH(pkey), arg2, 0, 1);
     default:
         return -2;
     }
diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c
index 1893b487ca..5d2acca25c 100644
--- a/crypto/dh/dh_key.c
+++ b/crypto/dh/dh_key.c
@@ -351,10 +351,10 @@ err:
     return 0;
 }
 
-size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out)
+size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out, size_t size, int alloc)
 {
     const BIGNUM *pubkey;
-    unsigned char *pbuf;
+    unsigned char *pbuf = NULL;
     const BIGNUM *p;
     int p_size;
 
@@ -366,19 +366,29 @@ size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out)
         DHerr(DH_F_DH_KEY2BUF, DH_R_INVALID_PUBKEY);
         return 0;
     }
-    if ((pbuf = OPENSSL_malloc(p_size)) == NULL) {
-        DHerr(DH_F_DH_KEY2BUF, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-    /*
-     * As per Section 4.2.8.1 of RFC 8446 left pad public
-     * key with zeros to the size of p
-     */
-    if (BN_bn2binpad(pubkey, pbuf, p_size) < 0) {
-        OPENSSL_free(pbuf);
-        DHerr(DH_F_DH_KEY2BUF, DH_R_BN_ERROR);
-        return 0;
+    if (pbuf_out != NULL && (alloc || *pbuf_out != NULL)) {
+        if (!alloc) {
+            if (size >= (size_t)p_size)
+                pbuf = *pbuf_out;
+        } else {
+            pbuf = OPENSSL_malloc(p_size);
+        }
+
+        if (pbuf == NULL) {
+            DHerr(DH_F_DH_KEY2BUF, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        /*
+         * As per Section 4.2.8.1 of RFC 8446 left pad public
+         * key with zeros to the size of p
+         */
+        if (BN_bn2binpad(pubkey, pbuf, p_size) < 0) {
+            if (alloc)
+                OPENSSL_free(pbuf);
+            DHerr(DH_F_DH_KEY2BUF, DH_R_BN_ERROR);
+            return 0;
+        }
+        *pbuf_out = pbuf;
     }
-    *pbuf_out = pbuf;
     return p_size;
 }
diff --git a/crypto/dh/dh_local.h b/crypto/dh/dh_local.h
index a54d25f487..51c3f974e1 100644
--- a/crypto/dh/dh_local.h
+++ b/crypto/dh/dh_local.h
@@ -58,6 +58,3 @@ struct dh_method {
     int (*generate_params) (DH *dh, int prime_len, int generator,
                             BN_GENCB *cb);
 };
-
-int dh_buf2key(DH *key, const unsigned char *buf, size_t len);
-size_t dh_key2buf(const DH *dh, unsigned char **pbuf);
diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c
index a712233043..68ed74b23a 100644
--- a/crypto/evp/keymgmt_lib.c
+++ b/crypto/evp/keymgmt_lib.c
@@ -39,6 +39,13 @@ static int try_import(const OSSL_PARAM params[], void *arg)
 {
     struct import_data_st *data = arg;
 
+    /* Just in time creation of keydata */
+    if (data->keydata == NULL
+        && (data->keydata = evp_keymgmt_newdata(data->keymgmt)) == NULL) {
+        ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
     /*
      * It's fine if there was no data to transfer, we just end up with an
      * empty destination key.
@@ -46,13 +53,6 @@ static int try_import(const OSSL_PARAM params[], void *arg)
     if (params[0].key == NULL)
         return 1;
 
-    /* Just in time creation of keydata, if needed */
-    if (data->keydata == NULL
-        && (data->keydata = evp_keymgmt_newdata(data->keymgmt)) == NULL) {
-        ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-
     return evp_keymgmt_import(data->keymgmt, data->keydata, data->selection,
                               params);
 }
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 4670912588..1d57a22aee 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -1215,6 +1215,18 @@ int EVP_PKEY_supports_digest_nid(EVP_PKEY *pkey, int nid)
 int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey,
                                const unsigned char *pt, size_t ptlen)
 {
+    if (pkey->ameth == NULL) {
+        OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
+
+        if (pkey->keymgmt == NULL || pkey->keydata == NULL)
+            return 0;
+
+        params[0] =
+            OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT,
+                                              (unsigned char *)pt, ptlen);
+        return evp_keymgmt_set_params(pkey->keymgmt, pkey->keydata, params);
+    }
+
     if (ptlen > INT_MAX)
         return 0;
     if (evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SET1_TLS_ENCPT, ptlen,
@@ -1226,6 +1238,33 @@ int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey,
 size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt)
 {
     int rv;
+
+    if (pkey->ameth == NULL) {
+        OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
+
+        if (pkey->keymgmt == NULL || pkey->keydata == NULL)
+            return 0;
+
+        params[0] =
+            OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT,
+                                              NULL, 0);
+        if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
+            return 0;
+
+        *ppt = OPENSSL_malloc(params[0].return_size);
+        if (*ppt == NULL)
+            return 0;
+
+        params[0] =
+            OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT,
+                                              *ppt, params[0].return_size);
+        if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
+            return 0;
+
+        return params[0].return_size;
+    }
+
+
     rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppt);
     if (rv <= 0)
         return 0;
diff --git a/doc/man7/EVP_PKEY-DH.pod b/doc/man7/EVP_PKEY-DH.pod
index 33b19a74f9..d2a49b7bfa 100644
--- a/doc/man7/EVP_PKEY-DH.pod
+++ b/doc/man7/EVP_PKEY-DH.pod
@@ -54,6 +54,11 @@ validation is required. The default value is 2.
 These are not named safe prime groups so setting this value for the OpenSSL FIPS
 provider will instead choose a named safe prime group based on the size of I<p>.
 
+=item "tls-encoded-pt" (B<OSSL_PKEY_PARAM_TLS_ENCODED_PT>) <octet string>
+
+Used for getting and setting the encoding of the DH public key used in a key
+exchange message for the TLS protocol.
+
 =back
 
 =head2 DH domain parameter / key generation parameters
diff --git a/doc/man7/EVP_PKEY-EC.pod b/doc/man7/EVP_PKEY-EC.pod
index 1995cf7676..85e633ceed 100644
--- a/doc/man7/EVP_PKEY-EC.pod
+++ b/doc/man7/EVP_PKEY-EC.pod
@@ -39,6 +39,11 @@ The public key value in EC point format.
 
 The private key value.
 
+=item "tls-encoded-pt" (B<OSSL_PKEY_PARAM_TLS_ENCODED_PT>) <octet string>
+
+Used for getting and setting the encoding of the EC public key used in key
+exchange message for the TLS protocol.
+
 =back
 
 =head1 EXAMPLES
diff --git a/doc/man7/EVP_PKEY-X25519.pod b/doc/man7/EVP_PKEY-X25519.pod
index fa8c86844a..ebeda8d814 100644
--- a/doc/man7/EVP_PKEY-X25519.pod
+++ b/doc/man7/EVP_PKEY-X25519.pod
@@ -34,6 +34,11 @@ The public key value.
 
 The private key value.
 
+=item "tls-encoded-pt" (B<OSSL_PKEY_PARAM_TLS_ENCODED_PT>) <octet string>
+
+Used for getting and setting the encoding of the public key used in a key exchange
+message for the TLS protocol.
+
 =back
 
 =head2 ED25519 and ED448 parameters
diff --git a/include/crypto/dh.h b/include/crypto/dh.h
index 1ae2c2f0a3..f67b4e01cd 100644
--- a/include/crypto/dh.h
+++ b/include/crypto/dh.h
@@ -32,3 +32,6 @@ int dh_check_priv_key(const DH *dh, const BIGNUM *priv_key, int *ret);
 int dh_check_pairwise(DH *dh);
 
 const DH_METHOD *dh_get_method(const DH *dh);
+
+int dh_buf2key(DH *key, const unsigned char *buf, size_t len);
+size_t dh_key2buf(const DH *dh, unsigned char **pbuf, size_t size, int alloc);
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index 8bafc1ba5e..f04168e819 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -194,6 +194,7 @@ extern "C" {
 #define OSSL_PKEY_PARAM_MASKGENFUNC         "mgf"
 #define OSSL_PKEY_PARAM_MGF1_DIGEST         "mgf1-digest"
 #define OSSL_PKEY_PARAM_MGF1_PROPERTIES     "mgf1-properties"
+#define OSSL_PKEY_PARAM_TLS_ENCODED_PT      "tls-encoded-pt"
 
 /* Diffie-Hellman/DSA public/private key */
 #define OSSL_PKEY_PARAM_PUB_KEY             "pub"
diff --git a/providers/implementations/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c
index 1e344bdc20..0dd1796dc0 100644
--- a/providers/implementations/keymgmt/dh_kmgmt.c
+++ b/providers/implementations/keymgmt/dh_kmgmt.c
@@ -36,6 +36,8 @@ static OSSL_OP_keymgmt_gen_fn dh_gen;
 static OSSL_OP_keymgmt_gen_cleanup_fn dh_gen_cleanup;
 static OSSL_OP_keymgmt_get_params_fn dh_get_params;
 static OSSL_OP_keymgmt_gettable_params_fn dh_gettable_params;
+static OSSL_OP_keymgmt_set_params_fn dh_set_params;
+static OSSL_OP_keymgmt_settable_params_fn dh_settable_params;
 static OSSL_OP_keymgmt_has_fn dh_has;
 static OSSL_OP_keymgmt_match_fn dh_match;
 static OSSL_OP_keymgmt_validate_fn dh_validate;
@@ -298,6 +300,15 @@ static ossl_inline int dh_get_params(void *key, OSSL_PARAM params[])
     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
         && !OSSL_PARAM_set_int(p, DH_size(dh)))
         return 0;
+    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT)) != NULL) {
+        if (p->data_type != OSSL_PARAM_OCTET_STRING)
+            return 0;
+        p->return_size = dh_key2buf(dh, (unsigned char **)&p->data,
+                                    p->data_size, 0);
+        if (p->return_size == 0)
+            return 0;
+    }
+
     return ffc_params_todata(dh_get0_params(dh), NULL, params)
            && dh_key_todata(dh, NULL, params);
 }
@@ -306,6 +317,7 @@ static const OSSL_PARAM dh_params[] = {
     OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
+    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
     DH_IMEXPORTABLE_PARAMETERS,
     DH_IMEXPORTABLE_PUBLIC_KEY,
     DH_IMEXPORTABLE_PRIVATE_KEY,
@@ -317,6 +329,30 @@ static const OSSL_PARAM *dh_gettable_params(void)
     return dh_params;
 }
 
+static const OSSL_PARAM dh_known_settable_params[] = {
+    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
+    OSSL_PARAM_END
+};
+
+static const OSSL_PARAM *dh_settable_params(void)
+{
+    return dh_known_settable_params;
+}
+
+static int dh_set_params(void *key, const OSSL_PARAM params[])
+{
+    DH *dh = key;
+    const OSSL_PARAM *p;
+
+    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT);
+    if (p != NULL
+            && (p->data_type != OSSL_PARAM_OCTET_STRING
+                || !dh_buf2key(dh, p->data, p->data_size)))
+        return 0;
+
+    return 1;
+}
+
 static int dh_validate_public(DH *dh)
 {
     const BIGNUM *pub_key = NULL;
@@ -621,6 +657,8 @@ const OSSL_DISPATCH dh_keymgmt_functions[] = {
     { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))dh_freedata },
     { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))dh_get_params },
     { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))dh_gettable_params },
+    { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))dh_set_params },
+    { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))dh_settable_params },
     { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))dh_has },
     { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))dh_match },
     { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))dh_validate },
diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c
index 8e7b9f3014..7e3220739f 100644
--- a/providers/implementations/keymgmt/ec_kmgmt.c
+++ b/providers/implementations/keymgmt/ec_kmgmt.c
@@ -504,6 +504,20 @@ int ec_get_params(void *key, OSSL_PARAM params[])
         if (!OSSL_PARAM_set_int(p, ecdh_cofactor_mode))
             return 0;
     }
+    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT)) != NULL) {
+        BN_CTX *ctx = BN_CTX_new_ex(ec_key_get_libctx(key));
+
+        if (ctx == NULL)
+            return 0;
+        p->return_size = EC_POINT_point2oct(EC_KEY_get0_group(key),
+                                            EC_KEY_get0_public_key(key),
+                                            POINT_CONVERSION_UNCOMPRESSED,
+                                            p->data, p->return_size, ctx);
+        BN_CTX_free(ctx);
+        if (p->return_size == 0)
+            return 0;
+    }
+
     ret = domparams_to_params(eck, NULL, params)
           && key_to_params(eck, NULL, params, 1, &pub_key)
           && otherparams_to_params(eck, NULL, params);
@@ -515,6 +529,7 @@ static const OSSL_PARAM ec_known_gettable_params[] = {
     OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
+    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
     EC_IMEXPORTABLE_DOM_PARAMETERS,
     EC_IMEXPORTABLE_PUBLIC_KEY,
     EC_IMEXPORTABLE_PRIVATE_KEY,
@@ -530,6 +545,7 @@ const OSSL_PARAM *ec_gettable_params(void)
 
 static const OSSL_PARAM ec_known_settable_params[] = {
     OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL),
+    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
     OSSL_PARAM_END
 };
 
@@ -543,6 +559,21 @@ static
 int ec_set_params(void *key, const OSSL_PARAM params[])
 {
     EC_KEY *eck = key;
+    const OSSL_PARAM *p;
+
+    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT);
+    if (p != NULL) {
+        BN_CTX *ctx = BN_CTX_new_ex(ec_key_get_libctx(key));
+        int ret = 1;
+
+        if (ctx == NULL
+                || p->data_type != OSSL_PARAM_OCTET_STRING
+                || !EC_KEY_oct2key(key, p->data, p->data_size, ctx))
+            ret = 0;
+        BN_CTX_free(ctx);
+        if (!ret)
+            return 0;
+    }
 
     return ec_key_otherparams_fromdata(eck, params);
 }
diff --git a/providers/implementations/keymgmt/ecx_kmgmt.c b/providers/implementations/keymgmt/ecx_kmgmt.c
index e2b613e5e0..e5c7e8bf3a 100644
--- a/providers/implementations/keymgmt/ecx_kmgmt.c
+++ b/providers/implementations/keymgmt/ecx_kmgmt.c
@@ -46,6 +46,14 @@ static OSSL_OP_keymgmt_gettable_params_fn x25519_gettable_params;
 static OSSL_OP_keymgmt_gettable_params_fn x448_gettable_params;
 static OSSL_OP_keymgmt_gettable_params_fn ed25519_gettable_params;
 static OSSL_OP_keymgmt_gettable_params_fn ed448_gettable_params;
+static OSSL_OP_keymgmt_set_params_fn x25519_set_params;
+static OSSL_OP_keymgmt_set_params_fn x448_set_params;
+static OSSL_OP_keymgmt_set_params_fn ed25519_set_params;
+static OSSL_OP_keymgmt_set_params_fn ed448_set_params;
+static OSSL_OP_keymgmt_settable_params_fn x25519_settable_params;
+static OSSL_OP_keymgmt_settable_params_fn x448_settable_params;
+static OSSL_OP_keymgmt_settable_params_fn ed25519_settable_params;
+static OSSL_OP_keymgmt_settable_params_fn ed448_settable_params;
 static OSSL_OP_keymgmt_has_fn ecx_has;
 static OSSL_OP_keymgmt_match_fn ecx_match;
 static OSSL_OP_keymgmt_import_fn ecx_import;
@@ -93,8 +101,11 @@ static int ecx_has(void *keydata, int selection)
     int ok = 0;
 
     if (key != NULL) {
-        if ((selection & ECX_POSSIBLE_SELECTIONS) != 0)
-            ok = 1;
+        /*
+         * ECX keys always have all the parameters they need (i.e. none).
+         * Therefore we always return with 1, if asked about parameters.
+         */
+        ok = 1;
 
         if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
             ok = ok && key->haspubkey;
@@ -233,6 +244,13 @@ static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits,
     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
         && !OSSL_PARAM_set_int(p, size))
         return 0;
+    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT)) != NULL
+            && (ecx->type == ECX_KEY_TYPE_X25519
+                || ecx->type == ECX_KEY_TYPE_X448)) {
+        if (!OSSL_PARAM_set_octet_string(p, ecx->pubkey, ecx->keylen))
+            return 0;
+    }
+
     return key_to_params(ecx, NULL, params);
 }
 
@@ -273,16 +291,17 @@ static int ed448_get_params(void *key, OSSL_PARAM params[])
         && ed_get_params(key, params);
 }
 
-static const OSSL_PARAM ecx_params[] = {
+static const OSSL_PARAM ecx_gettable_params[] = {
     OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
     OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0),
+    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
     ECX_KEY_TYPES(),
     OSSL_PARAM_END
 };
 
-static const OSSL_PARAM ed_params[] = {
+static const OSSL_PARAM ed_gettable_params[] = {
     OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
     OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
@@ -292,22 +311,92 @@ static const OSSL_PARAM ed_params[] = {
 
 static const OSSL_PARAM *x25519_gettable_params(void)
 {
-    return ecx_params;
+    return ecx_gettable_params;
 }
 
 static const OSSL_PARAM *x448_gettable_params(void)
 {
-    return ecx_params;
+    return ecx_gettable_params;
 }
 
 static const OSSL_PARAM *ed25519_gettable_params(void)
 {
-    return ed_params;
+    return ed_gettable_params;
 }
 
 static const OSSL_PARAM *ed448_gettable_params(void)
 {
-    return ed_params;
+    return ed_gettable_params;
+}
+
+static int ecx_set_params(void *key, const OSSL_PARAM params[])
+{
+    ECX_KEY *ecxkey = key;
+    const OSSL_PARAM *p;
+
+    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT);
+    if (p != NULL) {
+        void *buf = ecxkey->pubkey;
+
+        if (p->data_size != ecxkey->keylen
+                || !OSSL_PARAM_get_octet_string(p, &buf, sizeof(ecxkey->pubkey),
+                                                NULL))
+            return 0;
+        OPENSSL_clear_free(ecxkey->privkey, ecxkey->keylen);
+        ecxkey->privkey = NULL;
+        ecxkey->haspubkey = 1;
+    }
+
+    return 1;
+}
+
+static int x25519_set_params(void *key, const OSSL_PARAM params[])
+{
+    return ecx_set_params(key, params);
+}
+
+static int x448_set_params(void *key, const OSSL_PARAM params[])
+{
+    return ecx_set_params(key, params);
+}
+
+static int ed25519_set_params(void *key, const OSSL_PARAM params[])
+{
+    return 1;
+}
+
+static int ed448_set_params(void *key, const OSSL_PARAM params[])
+{
+    return 1;
+}
+
+static const OSSL_PARAM ecx_settable_params[] = {
+    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
+    OSSL_PARAM_END
+};
+
+static const OSSL_PARAM ed_settable_params[] = {
+    OSSL_PARAM_END
+};
+
+static const OSSL_PARAM *x25519_settable_params(void)
+{
+    return ecx_settable_params;
+}
+
+static const OSSL_PARAM *x448_settable_params(void)
+{
+    return ecx_settable_params;
+}
+
+static const OSSL_PARAM *ed25519_settable_params(void)
+{
+    return ed_settable_params;
+}
+
+static const OSSL_PARAM *ed448_settable_params(void)
+{
+    return ed_settable_params;
 }
 
 static void *ecx_gen_init(void *provctx, int selection, ECX_KEY_TYPE type)
@@ -450,6 +539,8 @@ static void ecx_gen_cleanup(void *genctx)
         { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ecx_key_free }, \
         { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \
         { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))alg##_gettable_params }, \
+        { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))alg##_set_params }, \
+        { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))alg##_settable_params }, \
         { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \
         { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match }, \
         { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index 764c52322d..ab2d98de60 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -648,21 +648,6 @@ static int add_key_share(SSL *s, WPACKET *pkt, unsigned int curve_id)
             /* SSLfatal() already called */
             return 0;
         }
-
-        /*
-         * TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint()
-         * knows how to get a key from an encoded point with the help of
-         * a OSSL_SERIALIZER deserializer.  We know that EVP_PKEY_get0()
-         * downgrades an EVP_PKEY to contain a legacy key.
-         *
-         * THIS IS TEMPORARY
-         */
-        EVP_PKEY_get0(key_share_key);
-        if (EVP_PKEY_id(key_share_key) == EVP_PKEY_NONE) {
-            SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_ADD_KEY_SHARE,
-                     ERR_R_EC_LIB);
-            goto err;
-        }
     }
 
     /* Encode the public key. */
@@ -1926,22 +1911,6 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
         return 0;
     }
 
-    /*
-     * TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint()
-     * knows how to get a key from an encoded point with the help of
-     * a OSSL_SERIALIZER deserializer.  We know that EVP_PKEY_get0()
-     * downgrades an EVP_PKEY to contain a legacy key.
-     *
-     * THIS IS TEMPORARY
-     */
-    EVP_PKEY_get0(skey);
-    if (EVP_PKEY_id(skey) == EVP_PKEY_NONE) {
-        EVP_PKEY_free(skey);
-        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE,
-                 ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
     if (!EVP_PKEY_set1_tls_encodedpoint(skey, PACKET_data(&encoded_pt),
                                         PACKET_remaining(&encoded_pt))) {
         SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_KEY_SHARE,
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
index aa71cec7e9..3a0fee6ebc 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -715,21 +715,6 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
             return 0;
         }
 
-        /*
-         * TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint()
-         * knows how to get a key from an encoded point with the help of
-         * a OSSL_SERIALIZER deserializer.  We know that EVP_PKEY_get0()
-         * downgrades an EVP_PKEY to contain a legacy key.
-         *
-         * THIS IS TEMPORARY
-         */
-        EVP_PKEY_get0(s->s3.peer_tmp);
-        if (EVP_PKEY_id(s->s3.peer_tmp) == EVP_PKEY_NONE) {
-            SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_KEY_SHARE,
-                     ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-
         s->s3.group_id = group_id;
 
         if (!EVP_PKEY_set1_tls_encodedpoint(s->s3.peer_tmp,
@@ -1757,21 +1742,6 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt,
         return EXT_RETURN_FAIL;
     }
 
-    /*
-     * TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint()
-     * knows how to get a key from an encoded point with the help of
-     * a OSSL_SERIALIZER deserializer.  We know that EVP_PKEY_get0()
-     * downgrades an EVP_PKEY to contain a legacy key.
-     *
-     * THIS IS TEMPORARY
-     */
-    EVP_PKEY_get0(skey);
-    if (EVP_PKEY_id(skey) == EVP_PKEY_NONE) {
-        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE,
-                 ERR_R_INTERNAL_ERROR);
-        return EXT_RETURN_FAIL;
-    }
-
     /* Generate encoding of server key */
     encoded_pt_len = EVP_PKEY_get1_tls_encodedpoint(skey, &encodedPoint);
     if (encoded_pt_len == 0) {
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index 67d8ae8ce6..7189940a62 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -2231,21 +2231,6 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey)
         return 0;
     }
 
-    /*
-     * TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint()
-     * knows how to get a key from an encoded point with the help of
-     * a OSSL_SERIALIZER deserializer.  We know that EVP_PKEY_get0()
-     * downgrades an EVP_PKEY to contain a legacy key.
-     *
-     * THIS IS TEMPORARY
-     */
-    EVP_PKEY_get0(s->s3.peer_tmp);
-    if (EVP_PKEY_id(s->s3.peer_tmp) == EVP_PKEY_NONE) {
-        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SKE_ECDHE,
-                 ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
     if (!EVP_PKEY_set1_tls_encodedpoint(s->s3.peer_tmp,
                                         PACKET_data(&encoded_pt),
                                         PACKET_remaining(&encoded_pt))) {
@@ -3148,21 +3133,6 @@ static int tls_construct_cke_ecdhe(SSL *s, WPACKET *pkt)
         goto err;
     }
 
-    /*
-     * TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint()
-     * knows how to get a key from an encoded point with the help of
-     * a OSSL_SERIALIZER deserializer.  We know that EVP_PKEY_get0()
-     * downgrades an EVP_PKEY to contain a legacy key.
-     *
-     * THIS IS TEMPORARY
-     */
-    EVP_PKEY_get0(ckey);
-    if (EVP_PKEY_id(skey) == EVP_PKEY_NONE) {
-        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_ECDHE,
-                 ERR_R_INTERNAL_ERROR);
-        goto err;
-    }
-
     if (ssl_derive(s, ckey, skey, 0) == 0) {
         /* SSLfatal() already called */
         goto err;
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index e5340b4e7f..036bfadbe5 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -2636,20 +2636,6 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
             goto err;
         }
 
-        /*
-         * TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint()
-         * knows how to get a key from an encoded point with the help of
-         * a OSSL_SERIALIZER deserializer.  We know that EVP_PKEY_get0()
-         * downgrades an EVP_PKEY to contain a legacy key.
-         *
-         * THIS IS TEMPORARY
-         */
-        EVP_PKEY_get0(s->s3.tmp.pkey);
-        if (EVP_PKEY_id(s->s3.tmp.pkey) == EVP_PKEY_NONE) {
-            SSLfatal(s, SSL_AD_INTERNAL_ERROR, 0, ERR_R_EC_LIB);
-            goto err;
-        }
-
         /* Encode the public key. */
         encodedlen = EVP_PKEY_get1_tls_encodedpoint(s->s3.tmp.pkey,
                                                     &encodedPoint);
@@ -3234,21 +3220,6 @@ static int tls_process_cke_ecdhe(SSL *s, PACKET *pkt)
             goto err;
         }
 
-        /*
-         * TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint()
-         * knows how to get a key from an encoded point with the help of
-         * a OSSL_SERIALIZER deserializer.  We know that EVP_PKEY_get0()
-         * downgrades an EVP_PKEY to contain a legacy key.
-         *
-         * THIS IS TEMPORARY
-         */
-        EVP_PKEY_get0(ckey);
-        if (EVP_PKEY_id(ckey) == EVP_PKEY_NONE) {
-            SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE,
-                     ERR_R_INTERNAL_ERROR);
-            goto err;
-        }
-
         if (EVP_PKEY_set1_tls_encodedpoint(ckey, data, i) == 0) {
             SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE,
                      ERR_R_EC_LIB);
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index a59d992e47..68bd5f2611 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -1217,17 +1217,6 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey)
     const SIGALG_LOOKUP *lu;
     int secbits = 0;
 
-    /*
-     * TODO(3.0) Remove this when we adapted this function for provider
-     * side keys.  We know that EVP_PKEY_get0() downgrades an EVP_PKEY
-     * to contain a legacy key.
-     *
-     * THIS IS TEMPORARY
-     */
-    EVP_PKEY_get0(pkey);
-    if (EVP_PKEY_id(pkey) == EVP_PKEY_NONE)
-        return 0;
-
     pkeyid = EVP_PKEY_id(pkey);
     /* Should never happen */
     if (pkeyid == -1)
diff --git a/test/evp_pkey_provided_test.c b/test/evp_pkey_provided_test.c
index 4c68f6bc6c..ffb56cb3ee 100644
--- a/test/evp_pkey_provided_test.c
+++ b/test/evp_pkey_provided_test.c
@@ -855,7 +855,8 @@ static int test_fromdata_ecx(int tst)
         goto err;
 
     if (!TEST_ptr(copy_pk = EVP_PKEY_new())
-        || !TEST_false(EVP_PKEY_copy_parameters(copy_pk, pk)))
+           /* This should succeed because there are no parameters to copy */
+        || !TEST_true(EVP_PKEY_copy_parameters(copy_pk, pk)))
         goto err;
 
     if (!TEST_true(EVP_PKEY_get_octet_string_param(


More information about the openssl-commits mailing list