From ec7f2d7d48e89ad5763a42a6b8cef9078a5fbd1c Mon Sep 17 00:00:00 2001
From: Steffan Karger <steffan@karger.me>
Date: Mon, 6 Apr 2015 10:06:20 +0200
Subject: [PATCH] Reload OpenSSL engines after forking
As reported in trac ticket #480, the cryptodev OpenSSL engine opens
/dev/crypto on load, but runs into trouble when the pid changes due to a
call to daemon(). We cannot simply call daemon() before initializing,
because that will change the interpretation of relative paths in the config
file. To work around that, not only fixup the PKCS#11 state after calling
daemon(), but also reload the OpenSSL engines.
v2 - always call ENGINE_cleanup() on fork, even when we did not initialize
engines ourselves.
Signed-off-by: Steffan Karger <steffan@karger.me>
---
src/openvpn/crypto.c | 17 +++++++++++++++++
src/openvpn/crypto.h | 7 +++++++
src/openvpn/crypto_backend.h | 8 +++++++-
src/openvpn/crypto_openssl.c | 21 +++++++++++++--------
src/openvpn/crypto_polarssl.c | 5 +++++
src/openvpn/init.c | 4 +---
6 files changed, 50 insertions(+), 12 deletions(-)
diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
index 588d9f0..e9856d9 100644
a
|
b
|
|
36 | 36 | #include "crypto.h" |
37 | 37 | #include "error.h" |
38 | 38 | #include "misc.h" |
| 39 | #include "pkcs11.h" |
39 | 40 | |
40 | 41 | #include "memdbg.h" |
41 | 42 | |
… |
… |
crypto_adjust_frame_parameters(struct frame *frame, |
426 | 427 | __func__, crypto_overhead); |
427 | 428 | } |
428 | 429 | |
| 430 | void |
| 431 | crypto_fork_fixup(const char *crypto_engine) |
| 432 | { |
| 433 | #if defined(ENABLE_PKCS11) |
| 434 | pkcs11_forkFixup (); |
| 435 | #endif |
| 436 | |
| 437 | if (crypto_engine) |
| 438 | { |
| 439 | /* Reload crypto engines, because a cryptodev engine opens file |
| 440 | * descriptors, which might no longer be usable after forking. */ |
| 441 | crypto_uninit_lib_engine(); |
| 442 | crypto_init_lib_engine(crypto_engine); |
| 443 | } |
| 444 | } |
| 445 | |
429 | 446 | /* |
430 | 447 | * Build a struct key_type. |
431 | 448 | */ |
diff --git a/src/openvpn/crypto.h b/src/openvpn/crypto.h
index 504896d..c2d7486 100644
a
|
b
|
void crypto_adjust_frame_parameters(struct frame *frame, |
354 | 354 | bool packet_id, |
355 | 355 | bool packet_id_long_form); |
356 | 356 | |
| 357 | /** |
| 358 | * Try to fixup crypto stuff that breaks after forking. |
| 359 | * |
| 360 | * @param crypto_engine Name of the crypto engine to reload. |
| 361 | */ |
| 362 | void crypto_fork_fixup(const char *crypto_engine); |
| 363 | |
357 | 364 | |
358 | 365 | /* Minimum length of the nonce used by the PRNG */ |
359 | 366 | #define NONCE_SECRET_LEN_MIN 16 |
diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h
index 4e45df0..db6421a 100644
a
|
b
|
void crypto_uninit_lib (void); |
49 | 49 | |
50 | 50 | void crypto_clear_error (void); |
51 | 51 | |
52 | | /* |
| 52 | /** |
53 | 53 | * Initialise the given named crypto engine. |
54 | 54 | */ |
55 | 55 | void crypto_init_lib_engine (const char *engine_name); |
56 | 56 | |
| 57 | /** |
| 58 | * Uninitialise previously loaded crypto engines. |
| 59 | */ |
| 60 | void crypto_uninit_lib_engine (void); |
| 61 | |
| 62 | |
57 | 63 | #ifdef DMALLOC |
58 | 64 | /* |
59 | 65 | * OpenSSL memory debugging. If dmalloc debugging is enabled, tell |
diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
index 2d81a6d..2602c57 100644
a
|
b
|
crypto_init_lib_engine (const char *engine_name) |
138 | 138 | #endif |
139 | 139 | } |
140 | 140 | |
| 141 | void |
| 142 | crypto_uninit_lib_engine (void) { |
| 143 | #if HAVE_OPENSSL_ENGINE |
| 144 | ENGINE_cleanup (); |
| 145 | if (engine_initialized) |
| 146 | { |
| 147 | engine_persist = NULL; |
| 148 | engine_initialized = false; |
| 149 | } |
| 150 | #endif |
| 151 | } |
| 152 | |
141 | 153 | /* |
142 | 154 | * |
143 | 155 | * Functions related to the core crypto library |
… |
… |
crypto_uninit_lib (void) |
168 | 180 | fclose (fp); |
169 | 181 | #endif |
170 | 182 | |
171 | | #if HAVE_OPENSSL_ENGINE |
172 | | if (engine_initialized) |
173 | | { |
174 | | ENGINE_cleanup (); |
175 | | engine_persist = NULL; |
176 | | engine_initialized = false; |
177 | | } |
178 | | #endif |
| 183 | crypto_uninit_lib_engine(); |
179 | 184 | } |
180 | 185 | |
181 | 186 | void |
diff --git a/src/openvpn/crypto_polarssl.c b/src/openvpn/crypto_polarssl.c
index c038f8e..900a98a 100644
a
|
b
|
crypto_init_lib_engine (const char *engine_name) |
66 | 66 | "available"); |
67 | 67 | } |
68 | 68 | |
| 69 | void |
| 70 | crypto_uninit_lib_engine (void) |
| 71 | { |
| 72 | } |
| 73 | |
69 | 74 | /* |
70 | 75 | * |
71 | 76 | * Functions related to the core crypto library |
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index 73c6aff..fddb744 100644
a
|
b
|
possibly_become_daemon (const struct options *options) |
929 | 929 | if (options->log) |
930 | 930 | set_std_files_to_null (true); |
931 | 931 | |
932 | | #if defined(ENABLE_PKCS11) |
933 | | pkcs11_forkFixup (); |
934 | | #endif |
| 932 | crypto_fork_fixup (options->engine); |
935 | 933 | |
936 | 934 | ret = true; |
937 | 935 | } |