Browse code

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>

Adriaan de Jong authored on 2011/06/29 22:30:34
Showing 7 changed files
... ...
@@ -1928,9 +1928,9 @@ key_schedule_free (struct key_schedule *ks, bool free_ssl_ctx)
1928 1928
 #ifdef USE_CRYPTO
1929 1929
   free_key_ctx_bi (&ks->static_key);
1930 1930
 #ifdef USE_SSL
1931
-  if (ks->ssl_ctx && free_ssl_ctx)
1931
+  if (tls_ctx_initialised(&ks->ssl_ctx) && free_ssl_ctx)
1932 1932
     {
1933
-      SSL_CTX_free (ks->ssl_ctx);
1933
+      tls_ctx_free (&ks->ssl_ctx);
1934 1934
       free_key_ctx_bi (&ks->tls_auth_key);
1935 1935
     }
1936 1936
 #endif /* USE_SSL */
... ...
@@ -2060,14 +2060,14 @@ do_init_crypto_tls_c1 (struct context *c)
2060 2060
 {
2061 2061
   const struct options *options = &c->options;
2062 2062
 
2063
-  if (!c->c1.ks.ssl_ctx)
2063
+  if (!tls_ctx_initialised(&c->c1.ks.ssl_ctx))
2064 2064
     {
2065 2065
       /*
2066 2066
        * Initialize the OpenSSL library's global
2067 2067
        * SSL context.
2068 2068
        */
2069
-      c->c1.ks.ssl_ctx = init_ssl (options);
2070
-      if (!c->c1.ks.ssl_ctx)
2069
+      init_ssl (options, &(c->c1.ks.ssl_ctx));
2070
+      if (!tls_ctx_initialised(&c->c1.ks.ssl_ctx))
2071 2071
 	{
2072 2072
 #if P2MP
2073 2073
 	  switch (auth_retry_get ())
... ...
@@ -2174,7 +2174,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
2174 2174
   if (packet_id_long_form)
2175 2175
     to.crypto_flags_or = CO_PACKET_ID_LONG_FORM;
2176 2176
 
2177
-  to.ssl_ctx = c->c1.ks.ssl_ctx;
2177
+  to.ssl_ctx = c->c1.ks.ssl_ctx.ctx;
2178 2178
   to.key_type = c->c1.ks.key_type;
2179 2179
   to.server = options->tls_server;
2180 2180
   to.key_method = options->key_method;
... ...
@@ -64,7 +64,7 @@ struct key_schedule
64 64
 
65 65
 #ifdef USE_SSL
66 66
   /* our global SSL context */
67
-  SSL_CTX *ssl_ctx;
67
+  struct tls_root_ctx ssl_ctx;
68 68
 
69 69
   /* optional authentication HMAC key for TLS control channel */
70 70
   struct key_ctx_bi tls_auth_key;
... ...
@@ -359,22 +359,6 @@ ssl_put_auth_challenge (const char *cr_str)
359 359
 #endif
360 360
 
361 361
 /*
362
- * OpenSSL callback to get a temporary RSA key, mostly
363
- * used for export ciphers.
364
- */
365
-static RSA *
366
-tmp_rsa_cb (SSL * s, int is_export, int keylength)
367
-{
368
-  static RSA *rsa_tmp = NULL;
369
-  if (rsa_tmp == NULL)
370
-    {
371
-      msg (D_HANDSHAKE, "Generating temp (%d bit) RSA key", keylength);
372
-      rsa_tmp = RSA_generate_key (keylength, RSA_F4, NULL, NULL);
373
-    }
374
-  return (rsa_tmp);
375
-}
376
-
377
-/*
378 362
  * Cert hash functions
379 363
  */
380 364
 static void
... ...
@@ -2031,8 +2015,8 @@ use_inline_PrivateKey_file (SSL_CTX *ctx, const char *key_string)
2031 2031
  * Initialize SSL context.
2032 2032
  * All files are in PEM format.
2033 2033
  */
2034
-SSL_CTX *
2035
-init_ssl (const struct options *options)
2034
+void
2035
+init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
2036 2036
 {
2037 2037
   SSL_CTX *ctx = NULL;
2038 2038
   DH *dh;
... ...
@@ -2040,15 +2024,14 @@ init_ssl (const struct options *options)
2040 2040
   bool using_cert_file = false;
2041 2041
   X509 *my_cert = NULL;
2042 2042
 
2043
-  ERR_clear_error ();
2043
+  ASSERT(NULL != new_ctx);
2044
+
2045
+  tls_clear_error();
2044 2046
 
2045 2047
   if (options->tls_server)
2046 2048
     {
2047
-      ctx = SSL_CTX_new (TLSv1_server_method ());
2048
-      if (ctx == NULL)
2049
-	msg (M_SSLERR, "SSL_CTX_new TLSv1_server_method");
2050
-
2051
-      SSL_CTX_set_tmp_rsa_callback (ctx, tmp_rsa_cb);
2049
+      tls_ctx_server_new(new_ctx);
2050
+      ctx = new_ctx->ctx;
2052 2051
 
2053 2052
 #if ENABLE_INLINE_FILES
2054 2053
       if (!strcmp (options->dh_file, INLINE_FILE_TAG) && options->dh_file_inline)
... ...
@@ -2076,9 +2059,8 @@ init_ssl (const struct options *options)
2076 2076
     }
2077 2077
   else				/* if client */
2078 2078
     {
2079
-      ctx = SSL_CTX_new (TLSv1_client_method ());
2080
-      if (ctx == NULL)
2081
-	msg (M_SSLERR, "SSL_CTX_new TLSv1_client_method");
2079
+      tls_ctx_client_new(new_ctx);
2080
+      ctx = new_ctx->ctx;
2082 2081
     }
2083 2082
 
2084 2083
   /* Set SSL options */
... ...
@@ -2390,17 +2372,15 @@ init_ssl (const struct options *options)
2390 2390
     }
2391 2391
 
2392 2392
  done:
2393
-  ERR_clear_error ();
2393
+  tls_clear_error ();
2394
+
2394 2395
   if (my_cert)
2395 2396
     X509_free(my_cert);
2396
-  return ctx;
2397
+
2398
+  return;
2397 2399
 
2398 2400
  err:
2399
-  if (ctx)
2400
-    {
2401
-      SSL_CTX_free (ctx);
2402
-      ctx = NULL;
2403
-    }
2401
+  tls_ctx_free (new_ctx);
2404 2402
   goto done;
2405 2403
 }
2406 2404
 
... ...
@@ -668,8 +668,11 @@ struct tls_auth_standalone
668 668
 void init_ssl_lib (void);
669 669
 void free_ssl_lib (void);
670 670
 
671
-/* Build master SSL_CTX object that serves for the whole of openvpn instantiation */
672
-SSL_CTX *init_ssl (const struct options *options);
671
+/**
672
+ * Build master SSL context object that serves for the whole of OpenVPN
673
+ * instantiation
674
+ */
675
+void init_ssl (const struct options *options, struct tls_root_ctx *ctx);
673 676
 
674 677
 struct tls_multi *tls_multi_init (struct tls_options *tls_options);
675 678
 
... ...
@@ -64,6 +64,36 @@ void tls_free_lib();
64 64
  */
65 65
 void tls_clear_error();
66 66
 
67
+/**
68
+ * Initialise a library-specific TLS context for a server.
69
+ *
70
+ * @param ctx		TLS context to initialise
71
+ */
72
+void tls_ctx_server_new(struct tls_root_ctx *ctx);
73
+
74
+/**
75
+ * Initialises a library-specific TLS context for a client.
76
+ *
77
+ * @param ctx		TLS context to initialise
78
+ */
79
+void tls_ctx_client_new(struct tls_root_ctx *ctx);
80
+
81
+/**
82
+ * Frees the library-specific TLSv1 context
83
+ *
84
+ * @param ctx		TLS context to free
85
+ */
86
+void tls_ctx_free(struct tls_root_ctx *ctx);
87
+
88
+/**
89
+ * Checks whether the given TLS context is initialised
90
+ *
91
+ * @param ctx		TLS context to check
92
+ *
93
+ * @return	true if the context is initialised, false if not.
94
+ */
95
+bool tls_ctx_initialised(struct tls_root_ctx *ctx);
96
+
67 97
 /*
68 98
  * Show the TLS ciphers that are available for us to use in the OpenSSL
69 99
  * library.
... ...
@@ -75,6 +75,61 @@ tls_clear_error()
75 75
   ERR_clear_error ();
76 76
 }
77 77
 
78
+/*
79
+ * OpenSSL callback to get a temporary RSA key, mostly
80
+ * used for export ciphers.
81
+ */
82
+static RSA *
83
+tmp_rsa_cb (SSL * s, int is_export, int keylength)
84
+{
85
+  static RSA *rsa_tmp = NULL;
86
+  if (rsa_tmp == NULL)
87
+    {
88
+      msg (D_HANDSHAKE, "Generating temp (%d bit) RSA key", keylength);
89
+      rsa_tmp = RSA_generate_key (keylength, RSA_F4, NULL, NULL);
90
+    }
91
+  return (rsa_tmp);
92
+}
93
+
94
+void
95
+tls_ctx_server_new(struct tls_root_ctx *ctx)
96
+{
97
+  ASSERT(NULL != ctx);
98
+
99
+  ctx->ctx = SSL_CTX_new (TLSv1_server_method ());
100
+
101
+  if (ctx->ctx == NULL)
102
+    msg (M_SSLERR, "SSL_CTX_new TLSv1_server_method");
103
+
104
+  SSL_CTX_set_tmp_rsa_callback (ctx->ctx, tmp_rsa_cb);
105
+}
106
+
107
+void
108
+tls_ctx_client_new(struct tls_root_ctx *ctx)
109
+{
110
+  ASSERT(NULL != ctx);
111
+
112
+  ctx->ctx = SSL_CTX_new (TLSv1_client_method ());
113
+
114
+  if (ctx->ctx == NULL)
115
+    msg (M_SSLERR, "SSL_CTX_new TLSv1_client_method");
116
+}
117
+
118
+void
119
+tls_ctx_free(struct tls_root_ctx *ctx)
120
+{
121
+  ASSERT(NULL != ctx);
122
+  if (NULL != ctx->ctx)
123
+    SSL_CTX_free (ctx->ctx);
124
+  ctx->ctx = NULL;
125
+}
126
+
127
+bool tls_ctx_initialised(struct tls_root_ctx *ctx)
128
+{
129
+  ASSERT(NULL != ctx);
130
+  return NULL != ctx->ctx;
131
+}
132
+
78 133
 void
79 134
 show_available_tls_ciphers ()
80 135
 {
... ...
@@ -33,6 +33,14 @@
33 33
 #include <openssl/ssl.h>
34 34
 
35 35
 /**
36
+ * Structure that wraps the TLS context. Contents differ depending on the
37
+ * SSL library used.
38
+ */
39
+struct tls_root_ctx {
40
+    SSL_CTX *ctx;
41
+};
42
+
43
+/**
36 44
  * Allocate space in SSL objects in which to store a struct tls_session
37 45
  * pointer back to parent.
38 46
  */