The branch master has been updated
       via  fc52ae8c4b4a00c7158549510ace0e5beef2306b (commit)
       via  5060cd5f3ed14a2dc4764cc1e042f76af6b44664 (commit)
      from  ef161e7b8f61ea588c654c9600bde80b2e07588f (commit)


- Log -----------------------------------------------------------------
commit fc52ae8c4b4a00c7158549510ace0e5beef2306b
Author: Matt Caswell <m...@openssl.org>
Date:   Mon Jan 18 16:50:07 2021 +0000

    Don't copy parameters on setting a key in libssl
    
    Whenever we set a private key in libssl, we first found the certificate
    that matched the key algorithm. Then we copied the key parameters from the
    private key into the public key for the certficate before finally checking
    that the private key matched the public key in the certificate. This makes
    no sense! Part of checking the private key is to make sure that the
    parameters match. It seems that this code has been present since SSLeay.
    Perhaps at some point it made sense to do this - but it doesn't any more.
    
    We remove that piece of code altogether. The previous code also had the
    undocumented side effect of removing the certificate if the key didn't
    match. This makes sense if you've just overwritten the parameters in the
    certificate with bad values - but doesn't seem to otherwise. I've also
    removed that error logic.
    
    Due to issue #13893, the public key associated with the certificate is
    always a legacy key. EVP_PKEY_copy_parameters will downgrade the "from"
    key to legacy if the target is legacy, so this means that in libssl all
    private keys were always downgraded to legacy when they are first set
    in the SSL/SSL_CTX. Removing the EVP_PKEY_copy_parameters code has the
    added benefit of removing that downgrade.
    
    Reviewed-by: Tomas Mraz <to...@openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13899)

commit 5060cd5f3ed14a2dc4764cc1e042f76af6b44664
Author: Matt Caswell <m...@openssl.org>
Date:   Tue Jan 19 11:36:24 2021 +0000

    Ensure legacy_asn1_ctrl_to_param can handle MDs not in the OBJ database
    
    The legacy_asn1_ctrl_to_param implementation of
    ASN1_PKEY_CTRL_DEFAULT_MD_NID calls EVP_PKEY_get_default_digest_name()
    which returns an mdname. Previously we were using OBJ_sn2nid/OBJ_ln2nid
    to lookup that name in the OBJ database. However we might get an md name
    back that only exists in the namemap, not in the OBJ database. In that
    case we need to check the various aliases for the name, to see if one of
    those matches the name we are looking for.
    
    Reviewed-by: Tomas Mraz <to...@openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/13899)

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

Summary of changes:
 crypto/evp/p_lib.c | 37 +++++++++++++++++++++++++++++++++----
 ssl/ssl_rsa.c      | 23 +++--------------------
 2 files changed, 36 insertions(+), 24 deletions(-)

diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index cc5a612748..f82e42c7e3 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -16,6 +16,7 @@
 #include <stdio.h>
 #include "internal/cryptlib.h"
 #include "internal/refcount.h"
+#include "internal/namemap.h"
 #include <openssl/bn.h>
 #include <openssl/err.h>
 #include <openssl/objects.h>
@@ -1153,6 +1154,18 @@ int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
                       pctx);
 }
 
+static void mdname2nid(const char *mdname, void *data)
+{
+    int *nid = (int *)data;
+
+    if (*nid != NID_undef)
+        return;
+
+    *nid = OBJ_sn2nid(mdname);
+    if (*nid == NID_undef)
+        *nid = OBJ_ln2nid(mdname);
+}
+
 static int legacy_asn1_ctrl_to_param(EVP_PKEY *pkey, int op,
                                      int arg1, void *arg2)
 {
@@ -1166,11 +1179,27 @@ static int legacy_asn1_ctrl_to_param(EVP_PKEY *pkey, 
int op,
                                                       sizeof(mdname));
 
             if (rv > 0) {
-                int nid;
+                int mdnum;
+                OSSL_LIB_CTX *libctx = 
ossl_provider_libctx(pkey->keymgmt->prov);
+                /* Make sure the MD is in the namemap if available */
+                EVP_MD *md = EVP_MD_fetch(libctx, mdname, NULL);
+                OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+                int nid = NID_undef;
 
-                nid = OBJ_sn2nid(mdname);
-                if (nid == NID_undef)
-                    nid = OBJ_ln2nid(mdname);
+                /*
+                 * The only reason to fetch the MD was to make sure it is in 
the
+                 * namemap. We can immediately free it.
+                 */
+                EVP_MD_free(md);
+                mdnum = ossl_namemap_name2num(namemap, mdname);
+                if (mdnum == 0)
+                    return 0;
+
+                /*
+                 * We have the namemap number - now we need to find the
+                 * associated nid
+                 */
+                ossl_namemap_doall_names(namemap, mdnum, mdname2nid, &nid);
                 *(int *)arg2 = nid;
             }
             return rv;
diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c
index bfdd5ff43d..1c1053d316 100644
--- a/ssl/ssl_rsa.c
+++ b/ssl/ssl_rsa.c
@@ -124,26 +124,9 @@ static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
         return 0;
     }
 
-    if (c->pkeys[i].x509 != NULL) {
-        EVP_PKEY *pktmp;
-        pktmp = X509_get0_pubkey(c->pkeys[i].x509);
-        if (pktmp == NULL) {
-            ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
-            return 0;
-        }
-        /*
-         * The return code from EVP_PKEY_copy_parameters is deliberately
-         * ignored. Some EVP_PKEY types cannot do this.
-         */
-        EVP_PKEY_copy_parameters(pktmp, pkey);
-        ERR_clear_error();
-
-        if (!X509_check_private_key(c->pkeys[i].x509, pkey)) {
-            X509_free(c->pkeys[i].x509);
-            c->pkeys[i].x509 = NULL;
-            return 0;
-        }
-    }
+    if (c->pkeys[i].x509 != NULL
+            && !X509_check_private_key(c->pkeys[i].x509, pkey))
+        return 0;
 
     EVP_PKEY_free(c->pkeys[i].privatekey);
     EVP_PKEY_up_ref(pkey);

Reply via email to