[Openvpn-devel,1/3] Refactor ssl_openssl.c in prep for external EC key support

Message ID 1515959073-10376-2-git-send-email-selva.nair@gmail.com
State Accepted
Headers show
Series
  • Support external EC cert/key using --management-external-xxx
Related show

Commit Message

Selva Nair Jan. 14, 2018, 7:44 p.m.
From: Selva Nair <selva.nair@gmail.com>

- Move setting of key method callbacks into a function

No change in functionality.

Signed-off-by: Selva Nair <selva.nair@gmail.com>
---
 src/openvpn/ssl_openssl.c | 65 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 41 insertions(+), 24 deletions(-)

Comments

Arne Schwabe Jan. 16, 2018, 10:40 p.m. | #1
Am 14.01.18 um 20:44 schrieb selva.nair@gmail.com:
> From: Selva Nair <selva.nair@gmail.com>
> 
> - Move setting of key method callbacks into a function
> 
> No change in functionality.
> 
>

This patch is fairly simple and does exactly what it says.

Acked-By: Arne Schwabe

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
Gert Doering Jan. 25, 2018, 1:56 p.m. | #2
Your patch has been applied to the master branch.

For the time being, I've decided to follow the rule "refactoring and
new features go to master", and since this "refactoring in preparation
for a new feature" (EC external key), it falls under this rule.

If there's good arguments we should have it in 2.4, I won't stand in 
the way, though.

commit d59a1c2f488cc3f4725df1e053592d53c30cf0eb
Author: Selva Nair
Date:   Sun Jan 14 14:44:31 2018 -0500

     Refactor ssl_openssl.c in prep for external EC key support

     Signed-off-by: Selva Nair <selva.nair@gmail.com>
     Acked-by: Arne Schwabe <arne@rfc2549.org>
     Message-Id: <1515959073-10376-2-git-send-email-selva.nair@gmail.com>
     URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg16227.html
     Signed-off-by: Gert Doering <gert@greenie.muc.de>


--
kind regards,

Gert Doering


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot

Patch

diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index d6d9acf..c29dbcf 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -1063,20 +1063,17 @@  done:
     return ret;
 }
 
-int
-tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
-                                 const char *cert_file, const char *cert_file_inline)
+static int
+tls_ctx_use_external_rsa_key(struct tls_root_ctx *ctx, EVP_PKEY *pkey)
 {
     RSA *rsa = NULL;
     RSA *pub_rsa;
     RSA_METHOD *rsa_meth;
-    X509 *cert = NULL;
 
     ASSERT(NULL != ctx);
 
-    tls_ctx_load_cert_file_and_copy(ctx, cert_file, cert_file_inline, &cert);
-
-    ASSERT(NULL != cert);
+    pub_rsa = EVP_PKEY_get0_RSA(pkey);
+    ASSERT(NULL != pub_rsa);
 
     /* allocate custom RSA method object */
     rsa_meth = RSA_meth_new("OpenVPN external private key RSA Method",
@@ -1098,18 +1095,6 @@  tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
         goto err;
     }
 
-    /* get the public key */
-    EVP_PKEY *pkey = X509_get0_pubkey(cert);
-    ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */
-    pub_rsa = EVP_PKEY_get0_RSA(pkey);
-
-    /* Certificate might not be RSA but DSA or EC */
-    if (!pub_rsa)
-    {
-        crypto_msg(M_WARN, "management-external-key requires a RSA certificate");
-        goto err;
-    }
-
     /* initialize RSA object */
     const BIGNUM *n = NULL;
     const BIGNUM *e = NULL;
@@ -1118,8 +1103,10 @@  tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
     RSA_set_flags(rsa, RSA_flags(rsa) | RSA_FLAG_EXT_PKEY);
     if (!RSA_set_method(rsa, rsa_meth))
     {
+        RSA_meth_free(rsa_meth);
         goto err;
     }
+    /* from this point rsa_meth will get freed with rsa */
 
     /* bind our custom RSA object to ssl_ctx */
     if (!SSL_CTX_use_RSAPrivateKey(ctx->ctx, rsa))
@@ -1127,15 +1114,10 @@  tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
         goto err;
     }
 
-    X509_free(cert);
     RSA_free(rsa); /* doesn't necessarily free, just decrements refcount */
     return 1;
 
 err:
-    if (cert)
-    {
-        X509_free(cert);
-    }
     if (rsa)
     {
         RSA_free(rsa);
@@ -1147,6 +1129,41 @@  err:
             RSA_meth_free(rsa_meth);
         }
     }
+    return 0;
+}
+
+int
+tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
+                                 const char *cert_file, const char *cert_file_inline)
+{
+    X509 *cert = NULL;
+
+    ASSERT(NULL != ctx);
+
+    tls_ctx_load_cert_file_and_copy(ctx, cert_file, cert_file_inline, &cert);
+
+    ASSERT(NULL != cert);
+
+    /* get the public key */
+    EVP_PKEY *pkey = X509_get0_pubkey(cert);
+    ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */
+    X509_free(cert);
+
+    if (EVP_PKEY_get0_RSA(pkey))
+    {
+        if (!tls_ctx_use_external_rsa_key(ctx, pkey))
+        {
+            goto err;
+        }
+    }
+    else
+    {
+        crypto_msg(M_WARN, "management-external-key requires a RSA certificate");
+        goto err;
+    }
+    return 1;
+
+err:
     crypto_msg(M_FATAL, "Cannot enable SSL external private key capability");
     return 0;
 }