From c3b2d487bc5089c8c0cf65df8e6cc2232d84b05b Mon Sep 17 00:00:00 2001 From: Joachim Schipper Date: Thu, 19 Sep 2013 12:47:27 +0200 Subject: 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 Acked-by: Arne Schwabe 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 --- src/openvpn/ssl_openssl.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'src/openvpn/ssl_openssl.c') 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; @@ -529,6 +530,13 @@ end: X509_free (x); } +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) { @@ -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 -- cgit