]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Refactor ssl_openssl.c in prep for external EC key support
authorSelva Nair <selva.nair@gmail.com>
Sun, 14 Jan 2018 19:44:31 +0000 (14:44 -0500)
committerGert Doering <gert@greenie.muc.de>
Thu, 25 Jan 2018 13:42:01 +0000 (14:42 +0100)
- Move setting of key method callbacks into a function

No change in functionality.

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>
src/openvpn/ssl_openssl.c

index cc1f8f15db6c1a63fddbfc2ede3ad8d41d5c2afb..01be656bad097f2162424abbeb2ffafe2672a1cd 100644 (file)
@@ -1097,20 +1097,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",
@@ -1132,18 +1129,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;
@@ -1152,8 +1137,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))
@@ -1161,15 +1148,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);
@@ -1181,6 +1163,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;
 }