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>
... | ... |
@@ -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; |
... | ... |
@@ -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 |
*/ |