summaryrefslogtreecommitdiffstats
path: root/src/openvpn/ssl_openssl.c
diff options
context:
space:
mode:
authorJoachim Schipper <joachim.schipper@fox-it.com>2013-09-19 12:47:27 +0200
committerGert Doering <gert@greenie.muc.de>2013-11-23 12:39:41 +0100
commitc3b2d487bc5089c8c0cf65df8e6cc2232d84b05b (patch)
treeb196b4df5bdd202be7830eef1e2f146ffaab1f83 /src/openvpn/ssl_openssl.c
parent076fd3e46bbbe6261317d58cc2442f8eccc927ce (diff)
downloadopenvpn-c3b2d487bc5089c8c0cf65df8e6cc2232d84b05b.tar.gz
openvpn-c3b2d487bc5089c8c0cf65df8e6cc2232d84b05b.tar.xz
openvpn-c3b2d487bc5089c8c0cf65df8e6cc2232d84b05b.zip
Refactor tls_ctx_use_external_private_key()
OpenSSL's tls_ctx_load_cert_file() had a parameter in which a copy of the context's certificate chain was stored on return, used by tls_ctx_use_external_private_key() only and free()d immediately thereafter. PolarSSL also supported this output parameter, but returned a pointer to the context's certificate chain (rather than to a copy of the certificate, as OpenSSL does) - which meant that we would have to #ifdef the free(). PolarSSL cannot make a copy of a certificate chain, and OpenSSL cannot store a pointer to (instead of a copy of) the cert. So remove the output parameter from tls_ctx_load_cert_file() and incorporate the needed functionality directly into tls_ctx_use_external_private_key() (which is straightforward for both OpenSSL and PolarSSL, as long as you don't try to support both at once.) Signed-off-by: Joachim Schipper <joachim.schipper@fox-it.com> Acked-by: Arne Schwabe <arne@rfc2549.org> Message-Id: <1379587649-25506-2-git-send-email-steffan.karger@fox-it.com> URL: http://article.gmane.org/gmane.network.openvpn.devel/7888 Signed-off-by: Gert Doering <gert@greenie.muc.de>
Diffstat (limited to 'src/openvpn/ssl_openssl.c')
-rw-r--r--src/openvpn/ssl_openssl.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index e392691..d6e194a 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -473,9 +473,10 @@ tls_ctx_add_extra_certs (struct tls_root_ctx *ctx, BIO *bio)
}
}
-void
-tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file,
- const char *cert_file_inline, X509 **x509
+/* Like tls_ctx_load_cert, but returns a copy of the certificate in **X509 */
+static void
+tls_ctx_load_cert_file_and_copy (struct tls_root_ctx *ctx,
+ const char *cert_file, const char *cert_file_inline, X509 **x509
)
{
BIO *in = NULL;
@@ -530,6 +531,13 @@ end:
}
void
+tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file,
+ const char *cert_file_inline)
+{
+ tls_ctx_load_cert_file_ext(ctx, cert_file, cert_file_inline, NULL);
+}
+
+void
tls_ctx_free_cert_file (X509 *x509)
{
X509_free(x509);
@@ -665,15 +673,19 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i
}
int
-tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, X509 *cert)
+tls_ctx_use_external_private_key (struct tls_root_ctx *ctx,
+ const char *cert_file, const char *cert_file_inline)
{
RSA *rsa = NULL;
RSA *pub_rsa;
RSA_METHOD *rsa_meth;
+ X509 *cert = NULL;
ASSERT (NULL != ctx);
ASSERT (NULL != cert);
+ tls_ctx_load_cert_file_ext(ctx, cert_file, cert_file_inline, &cert);
+
/* allocate custom RSA method object */
ALLOC_OBJ_CLEAR (rsa_meth, RSA_METHOD);
rsa_meth->name = "OpenVPN external private key RSA Method";
@@ -708,10 +720,13 @@ tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, X509 *cert)
if (!SSL_CTX_use_RSAPrivateKey(ctx->ctx, rsa))
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);
else