summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdriaan de Jong <dejong@fox-it.com>2011-06-29 15:30:34 +0200
committerDavid Sommerseth <davids@redhat.com>2011-10-19 22:31:46 +0200
commit6245178696842fb22f2c53d87184236fd471a334 (patch)
treea40bdda0e4296e6dfb428f7566bab23da3e8d302
parentb64ffdcf09edd7110c1f851942d0e8d4e05d883c (diff)
downloadopenvpn-6245178696842fb22f2c53d87184236fd471a334.tar.gz
openvpn-6245178696842fb22f2c53d87184236fd471a334.tar.xz
openvpn-6245178696842fb22f2c53d87184236fd471a334.zip
Refactored root SSL context initialisation
Signed-off-by: Adriaan de Jong <dejong@fox-it.com> Acked-by: Gert Doering <gert@greenie.muc.de> Acked-by: James Yonan <james@openvpn.net> Signed-off-by: David Sommerseth <davids@redhat.com>
-rw-r--r--init.c12
-rw-r--r--openvpn.h2
-rw-r--r--ssl.c48
-rw-r--r--ssl.h7
-rw-r--r--ssl_backend.h30
-rw-r--r--ssl_openssl.c55
-rw-r--r--ssl_openssl.h8
7 files changed, 119 insertions, 43 deletions
diff --git a/init.c b/init.c
index e194c95..eb17b01 100644
--- a/init.c
+++ b/init.c
@@ -1928,9 +1928,9 @@ key_schedule_free (struct key_schedule *ks, bool free_ssl_ctx)
#ifdef USE_CRYPTO
free_key_ctx_bi (&ks->static_key);
#ifdef USE_SSL
- if (ks->ssl_ctx && free_ssl_ctx)
+ if (tls_ctx_initialised(&ks->ssl_ctx) && free_ssl_ctx)
{
- SSL_CTX_free (ks->ssl_ctx);
+ tls_ctx_free (&ks->ssl_ctx);
free_key_ctx_bi (&ks->tls_auth_key);
}
#endif /* USE_SSL */
@@ -2060,14 +2060,14 @@ do_init_crypto_tls_c1 (struct context *c)
{
const struct options *options = &c->options;
- if (!c->c1.ks.ssl_ctx)
+ if (!tls_ctx_initialised(&c->c1.ks.ssl_ctx))
{
/*
* Initialize the OpenSSL library's global
* SSL context.
*/
- c->c1.ks.ssl_ctx = init_ssl (options);
- if (!c->c1.ks.ssl_ctx)
+ init_ssl (options, &(c->c1.ks.ssl_ctx));
+ if (!tls_ctx_initialised(&c->c1.ks.ssl_ctx))
{
#if P2MP
switch (auth_retry_get ())
@@ -2174,7 +2174,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
if (packet_id_long_form)
to.crypto_flags_or = CO_PACKET_ID_LONG_FORM;
- to.ssl_ctx = c->c1.ks.ssl_ctx;
+ to.ssl_ctx = c->c1.ks.ssl_ctx.ctx;
to.key_type = c->c1.ks.key_type;
to.server = options->tls_server;
to.key_method = options->key_method;
diff --git a/openvpn.h b/openvpn.h
index bd6e873..a07b03f 100644
--- a/openvpn.h
+++ b/openvpn.h
@@ -64,7 +64,7 @@ struct key_schedule
#ifdef USE_SSL
/* our global SSL context */
- SSL_CTX *ssl_ctx;
+ struct tls_root_ctx ssl_ctx;
/* optional authentication HMAC key for TLS control channel */
struct key_ctx_bi tls_auth_key;
diff --git a/ssl.c b/ssl.c
index e94342f..200ce15 100644
--- a/ssl.c
+++ b/ssl.c
@@ -359,22 +359,6 @@ ssl_put_auth_challenge (const char *cr_str)
#endif
/*
- * OpenSSL callback to get a temporary RSA key, mostly
- * used for export ciphers.
- */
-static RSA *
-tmp_rsa_cb (SSL * s, int is_export, int keylength)
-{
- static RSA *rsa_tmp = NULL;
- if (rsa_tmp == NULL)
- {
- msg (D_HANDSHAKE, "Generating temp (%d bit) RSA key", keylength);
- rsa_tmp = RSA_generate_key (keylength, RSA_F4, NULL, NULL);
- }
- return (rsa_tmp);
-}
-
-/*
* Cert hash functions
*/
static void
@@ -2031,8 +2015,8 @@ use_inline_PrivateKey_file (SSL_CTX *ctx, const char *key_string)
* Initialize SSL context.
* All files are in PEM format.
*/
-SSL_CTX *
-init_ssl (const struct options *options)
+void
+init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
{
SSL_CTX *ctx = NULL;
DH *dh;
@@ -2040,15 +2024,14 @@ init_ssl (const struct options *options)
bool using_cert_file = false;
X509 *my_cert = NULL;
- ERR_clear_error ();
+ ASSERT(NULL != new_ctx);
+
+ tls_clear_error();
if (options->tls_server)
{
- ctx = SSL_CTX_new (TLSv1_server_method ());
- if (ctx == NULL)
- msg (M_SSLERR, "SSL_CTX_new TLSv1_server_method");
-
- SSL_CTX_set_tmp_rsa_callback (ctx, tmp_rsa_cb);
+ tls_ctx_server_new(new_ctx);
+ ctx = new_ctx->ctx;
#if ENABLE_INLINE_FILES
if (!strcmp (options->dh_file, INLINE_FILE_TAG) && options->dh_file_inline)
@@ -2076,9 +2059,8 @@ init_ssl (const struct options *options)
}
else /* if client */
{
- ctx = SSL_CTX_new (TLSv1_client_method ());
- if (ctx == NULL)
- msg (M_SSLERR, "SSL_CTX_new TLSv1_client_method");
+ tls_ctx_client_new(new_ctx);
+ ctx = new_ctx->ctx;
}
/* Set SSL options */
@@ -2390,17 +2372,15 @@ init_ssl (const struct options *options)
}
done:
- ERR_clear_error ();
+ tls_clear_error ();
+
if (my_cert)
X509_free(my_cert);
- return ctx;
+
+ return;
err:
- if (ctx)
- {
- SSL_CTX_free (ctx);
- ctx = NULL;
- }
+ tls_ctx_free (new_ctx);
goto done;
}
diff --git a/ssl.h b/ssl.h
index c23a946..1743346 100644
--- a/ssl.h
+++ b/ssl.h
@@ -668,8 +668,11 @@ struct tls_auth_standalone
void init_ssl_lib (void);
void free_ssl_lib (void);
-/* Build master SSL_CTX object that serves for the whole of openvpn instantiation */
-SSL_CTX *init_ssl (const struct options *options);
+/**
+ * Build master SSL context object that serves for the whole of OpenVPN
+ * instantiation
+ */
+void init_ssl (const struct options *options, struct tls_root_ctx *ctx);
struct tls_multi *tls_multi_init (struct tls_options *tls_options);
diff --git a/ssl_backend.h b/ssl_backend.h
index 103eea4..dfa7163 100644
--- a/ssl_backend.h
+++ b/ssl_backend.h
@@ -64,6 +64,36 @@ void tls_free_lib();
*/
void tls_clear_error();
+/**
+ * Initialise a library-specific TLS context for a server.
+ *
+ * @param ctx TLS context to initialise
+ */
+void tls_ctx_server_new(struct tls_root_ctx *ctx);
+
+/**
+ * Initialises a library-specific TLS context for a client.
+ *
+ * @param ctx TLS context to initialise
+ */
+void tls_ctx_client_new(struct tls_root_ctx *ctx);
+
+/**
+ * Frees the library-specific TLSv1 context
+ *
+ * @param ctx TLS context to free
+ */
+void tls_ctx_free(struct tls_root_ctx *ctx);
+
+/**
+ * Checks whether the given TLS context is initialised
+ *
+ * @param ctx TLS context to check
+ *
+ * @return true if the context is initialised, false if not.
+ */
+bool tls_ctx_initialised(struct tls_root_ctx *ctx);
+
/*
* Show the TLS ciphers that are available for us to use in the OpenSSL
* library.
diff --git a/ssl_openssl.c b/ssl_openssl.c
index c80dfb1..c03fb54 100644
--- a/ssl_openssl.c
+++ b/ssl_openssl.c
@@ -75,6 +75,61 @@ tls_clear_error()
ERR_clear_error ();
}
+/*
+ * OpenSSL callback to get a temporary RSA key, mostly
+ * used for export ciphers.
+ */
+static RSA *
+tmp_rsa_cb (SSL * s, int is_export, int keylength)
+{
+ static RSA *rsa_tmp = NULL;
+ if (rsa_tmp == NULL)
+ {
+ msg (D_HANDSHAKE, "Generating temp (%d bit) RSA key", keylength);
+ rsa_tmp = RSA_generate_key (keylength, RSA_F4, NULL, NULL);
+ }
+ return (rsa_tmp);
+}
+
+void
+tls_ctx_server_new(struct tls_root_ctx *ctx)
+{
+ ASSERT(NULL != ctx);
+
+ ctx->ctx = SSL_CTX_new (TLSv1_server_method ());
+
+ if (ctx->ctx == NULL)
+ msg (M_SSLERR, "SSL_CTX_new TLSv1_server_method");
+
+ SSL_CTX_set_tmp_rsa_callback (ctx->ctx, tmp_rsa_cb);
+}
+
+void
+tls_ctx_client_new(struct tls_root_ctx *ctx)
+{
+ ASSERT(NULL != ctx);
+
+ ctx->ctx = SSL_CTX_new (TLSv1_client_method ());
+
+ if (ctx->ctx == NULL)
+ msg (M_SSLERR, "SSL_CTX_new TLSv1_client_method");
+}
+
+void
+tls_ctx_free(struct tls_root_ctx *ctx)
+{
+ ASSERT(NULL != ctx);
+ if (NULL != ctx->ctx)
+ SSL_CTX_free (ctx->ctx);
+ ctx->ctx = NULL;
+}
+
+bool tls_ctx_initialised(struct tls_root_ctx *ctx)
+{
+ ASSERT(NULL != ctx);
+ return NULL != ctx->ctx;
+}
+
void
show_available_tls_ciphers ()
{
diff --git a/ssl_openssl.h b/ssl_openssl.h
index fb817ae..a87861b 100644
--- a/ssl_openssl.h
+++ b/ssl_openssl.h
@@ -33,6 +33,14 @@
#include <openssl/ssl.h>
/**
+ * Structure that wraps the TLS context. Contents differ depending on the
+ * SSL library used.
+ */
+struct tls_root_ctx {
+ SSL_CTX *ctx;
+};
+
+/**
* Allocate space in SSL objects in which to store a struct tls_session
* pointer back to parent.
*/