]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Refactored root SSL context initialisation
authorAdriaan de Jong <dejong@fox-it.com>
Wed, 29 Jun 2011 13:30:34 +0000 (15:30 +0200)
committerDavid Sommerseth <davids@redhat.com>
Wed, 19 Oct 2011 20:31:46 +0000 (22:31 +0200)
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>
init.c
openvpn.h
ssl.c
ssl.h
ssl_backend.h
ssl_openssl.c
ssl_openssl.h

diff --git a/init.c b/init.c
index e194c95ffa669722bd00924fcd0e2f848c6fd325..eb17b01c9f001b2848b78c62fbd220df56cf5ecb 100644 (file)
--- 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;
index bd6e873a1659296aae88e12c29a5a0f47d1fa49f..a07b03fe6df3f22be9efc895807d43218e135cf0 100644 (file)
--- 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 e94342f97dd9cfd6e4627cff30948781053a8cce..200ce15dedea6898b1830ba1c8141646ebadebed 100644 (file)
--- a/ssl.c
+++ b/ssl.c
@@ -358,22 +358,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
  */
@@ -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 c23a94600a5e794040132b6702026151cbfcd055..1743346b5a2960e613c8815b85f4ace15fab298f 100644 (file)
--- 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);
 
index 103eea44caec46c3cc2e929935662a9ac2751ee2..dfa7163869cbce8938820015a3a084474d49500f 100644 (file)
@@ -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.
index c80dfb13ea0c557341688b125818c8d8cc7ad202..c03fb54597532d24e551ffaacc754a70a1c3dc7c 100644 (file)
@@ -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 ()
 {
index fb817ae584449e4c78fea43d2bfecd9f0916e491..a87861be2eac5509ccc4a160bf7117bce75f2749 100644 (file)
 
 #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.