Skip to contentSkip to conversation

Improve management-external-key/cert error handling

PATCH In review Steffan Karger 2 participants 8 messages Mar 4, 2018 – Oct 6, 2018

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Improve management-external-key/cert error handling

Check the return values of management_query_cert() and tls_ctx_use_external_private_key(), and error out with a more descriptive error message. To do so, we make the openssl-backed implementation of tls_ctx_use_external_private_key() not throw fatal error anymore.

(And fix line wrapping while touching this code.)

---
 src/openvpn/ssl.c         | 29 +++++++++++++++++++++--------
 src/openvpn/ssl_openssl.c |  2 +-
 2 files changed, 22 insertions(+), 9 deletions(-)
src/openvpn/ssl.c +21 -8
index 79b985e..25a7085 100644
@@ -660,18 +660,31 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)
     else if ((options->management_flags & MF_EXTERNAL_KEY)
              && (options->cert_file || options->management_flags & MF_EXTERNAL_CERT))
     {
-        if (options->cert_file)
+        if (options->cert_file
+            && 0 != tls_ctx_use_external_private_key(new_ctx,
+                                                     options->cert_file,
+                                                     options->cert_file_inline))
         {
-            tls_ctx_use_external_private_key(new_ctx, options->cert_file,
-                                             options->cert_file_inline);
+            msg(M_WARN, "Failed to initialize management-external-key");
+            goto err;
         }
         else
         {
-            char *external_certificate = management_query_cert(management,
-                                                               options->management_certificate);
-            tls_ctx_use_external_private_key(new_ctx, external_certificate,
-                                             true);
-            free(external_certificate);
+            char *external_cert = management_query_cert(
+                            management, options->management_certificate);
+
+            if (!external_cert)
+            {
+                msg(M_FATAL, "Failed to initialize management-external-cert");
+            }
+
+            if (0 != tls_ctx_use_external_private_key(new_ctx, external_cert,
+                                                      true))
+            {
+                msg(M_FATAL, "Failed to initialize management-external-key");
+            }
+
+            free(external_cert);
         }
     }
 #endif
src/openvpn/ssl_openssl.c +1 -1
index 66d98c5..87f6768 100644
@@ -1327,7 +1327,7 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
     return 0;
 
 err:
-    crypto_msg(M_FATAL, "Cannot enable SSL external private key capability");
+    crypto_msg(M_WARN, "Cannot enable SSL external private key capability");
     return 1;
 }
 
Signature · 1 line
2.7.4
#1 lore raw

Hi,

Quoted 20 lines · Steffan Karger

Check the return values of management_query_cert() and tls_ctx_use_external_private_key(), and error out with a more descriptive error message. To do so, we make the openssl-backed implementation of tls_ctx_use_external_private_key() not throw fatal error anymore.

(And fix line wrapping while touching this code.)

---
 src/openvpn/ssl.c         | 29 +++++++++++++++++++++--------
 src/openvpn/ssl_openssl.c |  2 +-
 2 files changed, 22 insertions(+), 9 deletions(-)
src/openvpn/ssl.c +0 -0
index 79b985e..25a7085 100644
@@ -660,18 +660,31 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)
     else if ((options->management_flags & MF_EXTERNAL_KEY)
              && (options->cert_file || options->management_flags & MF_EXTERNAL_CERT))

src/openvpn/ssl.c init_ssl(const struct options *options, struct tls_root_ctx *new_ctx) · line 668

Quoted 10 lines
src/openvpn/ssl.c +5 -3
     {
-        if (options->cert_file)
+        if (options->cert_file
+            && 0 != tls_ctx_use_external_private_key(new_ctx,
+                                                     options->cert_file,
+                                                     options->cert_file_inline))
         {
-            tls_ctx_use_external_private_key(new_ctx, options->cert_file,
-                                             options->cert_file_inline);
+            msg(M_WARN, "Failed to initialize management-external-key");

Don't we need a M_FATAL here -- similar to the M_FATAL for the same failure below?

src/openvpn/ssl.c init_ssl(const struct options *options, struct tls_root_ctx *new_ctx) · line 669

Quoted 1 line
src/openvpn/ssl.c +1 -0
+            goto err;

Then this could be removed as well.

Quoted 31 lines
src/openvpn/ssl.c +15 -5
         }
         else
         {
-            char *external_certificate = management_query_cert(management,
-                                                               options->management_certificate);
-            tls_ctx_use_external_private_key(new_ctx, external_certificate,
-                                             true);
-            free(external_certificate);
+            char *external_cert = management_query_cert(
+                            management, options->management_certificate);
+
+            if (!external_cert)
+            {
+                msg(M_FATAL, "Failed to initialize management-external-cert");
+            }
+
+            if (0 != tls_ctx_use_external_private_key(new_ctx, external_cert,
+                                                      true))
+            {
+                msg(M_FATAL, "Failed to initialize management-external-key");
+            }
+
+            free(external_cert);
         }
     }
 #endif
src/openvpn/ssl_openssl.c +0 -0
index 66d98c5..87f6768 100644

src/openvpn/ssl_openssl.c tls_ctx_use_external_private_key(struct tls_root_ctx *ctx, · line 1332

Quoted 7 lines
src/openvpn/ssl_openssl.c +1 -1
@@ -1327,7 +1327,7 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
     return 0;
 
 err:
-    crypto_msg(M_FATAL, "Cannot enable SSL external private key capability");
+    crypto_msg(M_WARN, "Cannot enable SSL external private key capability");
     return 1;
 }

Selva

#2 lore raw

PATCH 1/1 Improve management-external-key/cert error handling

Check the return values of management_query_cert() and tls_ctx_use_external_private_key(), and error out with a more descriptive error message. To do so, we make the openssl-backed implementation of tls_ctx_use_external_private_key() not throw fatal error anymore.

(And fix line wrapping while touching this code.)

---
v2: error out with M_FATAL as suggested by Selva.

 src/openvpn/ssl.c         | 28 ++++++++++++++++++++--------
 src/openvpn/ssl_openssl.c |  2 +-
 2 files changed, 21 insertions(+), 9 deletions(-)
src/openvpn/ssl.c +20 -8
index 1756f8a2..1882db52 100644
@@ -660,18 +660,30 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)
     else if ((options->management_flags & MF_EXTERNAL_KEY)
              && (options->cert_file || options->management_flags & MF_EXTERNAL_CERT))
     {
-        if (options->cert_file)
+        if (options->cert_file
+            && 0 != tls_ctx_use_external_private_key(new_ctx,
+                                                     options->cert_file,
+                                                     options->cert_file_inline))
         {
-            tls_ctx_use_external_private_key(new_ctx, options->cert_file,
-                                             options->cert_file_inline);
+            msg(M_FATAL, "Failed to initialize management-external-key");
         }
         else
         {
-            char *external_certificate = management_query_cert(management,
-                                                               options->management_certificate);
-            tls_ctx_use_external_private_key(new_ctx, external_certificate,
-                                             true);
-            free(external_certificate);
+            char *external_cert = management_query_cert(
+                            management, options->management_certificate);
+
+            if (!external_cert)
+            {
+                msg(M_FATAL, "Failed to initialize management-external-cert");
+            }
+
+            if (0 != tls_ctx_use_external_private_key(new_ctx, external_cert,
+                                                      true))
+            {
+                msg(M_FATAL, "Failed to initialize management-external-key");
+            }
+
+            free(external_cert);
         }
     }
 #endif
src/openvpn/ssl_openssl.c +1 -1
index 66d98c54..87f67680 100644
@@ -1327,7 +1327,7 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
     return 0;
 
 err:
-    crypto_msg(M_FATAL, "Cannot enable SSL external private key capability");
+    crypto_msg(M_WARN, "Cannot enable SSL external private key capability");
     return 1;
 }
 
Signature · 1 line
2.15.1
#3 lore raw

Hi,

I wanted to give this a quick test, but it doesn't apply.

It seems you have patch 116 (Antonio's "inline-tag changed to bool" patch) in your local repo.

By the way, the M_FATAL after management_query_cert() looks like a regression. One problem with these FATAL exits is that it makes it hard for the GUI to gracefully handle when user presses cancel on some dialogs. Anyway that's beyond this patch... So just saying..

Quoted 63 lines · Steffan Karger

Check the return values of management_query_cert() and tls_ctx_use_external_private_key(), and error out with a more descriptive error message. To do so, we make the openssl-backed implementation of tls_ctx_use_external_private_key() not throw fatal error anymore.

(And fix line wrapping while touching this code.)

---
v2: error out with M_FATAL as suggested by Selva.

 src/openvpn/ssl.c         | 28 ++++++++++++++++++++--------
 src/openvpn/ssl_openssl.c |  2 +-
 2 files changed, 21 insertions(+), 9 deletions(-)
src/openvpn/ssl.c +20 -8
index 1756f8a2..1882db52 100644
@@ -660,18 +660,30 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)
     else if ((options->management_flags & MF_EXTERNAL_KEY)
              && (options->cert_file || options->management_flags & MF_EXTERNAL_CERT))
     {
-        if (options->cert_file)
+        if (options->cert_file
+            && 0 != tls_ctx_use_external_private_key(new_ctx,
+                                                     options->cert_file,
+                                                     options->cert_file_inline))
         {
-            tls_ctx_use_external_private_key(new_ctx, options->cert_file,
-                                             options->cert_file_inline);
+            msg(M_FATAL, "Failed to initialize management-external-key");
         }
         else
         {
-            char *external_certificate = management_query_cert(management,
-                                                               options->management_certificate);
-            tls_ctx_use_external_private_key(new_ctx, external_certificate,
-                                             true);
-            free(external_certificate);
+            char *external_cert = management_query_cert(
+                            management, options->management_certificate);
+
+            if (!external_cert)
+            {
+                msg(M_FATAL, "Failed to initialize management-external-cert");
+            }
+
+            if (0 != tls_ctx_use_external_private_key(new_ctx, external_cert,
+                                                      true))
+            {
+                msg(M_FATAL, "Failed to initialize management-external-key");
+            }
+
+            free(external_cert);
         }
     }
 #endif
src/openvpn/ssl_openssl.c +0 -0
index 66d98c54..87f67680 100644

src/openvpn/ssl_openssl.c tls_ctx_use_external_private_key(struct tls_root_ctx *ctx, · line 1333

Quoted 8 lines
src/openvpn/ssl_openssl.c +1 -1
@@ -1327,7 +1327,7 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
     return 0;
 
 err:
-    crypto_msg(M_FATAL, "Cannot enable SSL external private key capability");
+    crypto_msg(M_WARN, "Cannot enable SSL external private key capability");
     return 1;
 }
 

Selva

#4 lore raw

PATCH v3 1/1 Improve management-external-key/cert error handling

Check the return values of management_query_cert() and tls_ctx_use_external_private_key(), and error out with a more descriptive error message. To do so, we make the openssl-backed implementation of tls_ctx_use_external_private_key() not throw fatal error anymore.

(And fix line wrapping while touching this code.)

---
v2: error out with M_FATAL as suggested by Selva.
v3: rebase on master (without extra patches)

 src/openvpn/ssl.c         | 28 ++++++++++++++++++++--------
 src/openvpn/ssl_openssl.c |  2 +-
 2 files changed, 21 insertions(+), 9 deletions(-)
src/openvpn/ssl.c +20 -8
index 669f941b..b06820ba 100644
@@ -660,18 +660,30 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)
     else if ((options->management_flags & MF_EXTERNAL_KEY)
              && (options->cert_file || options->management_flags & MF_EXTERNAL_CERT))
     {
-        if (options->cert_file)
+        if (options->cert_file
+            && 0 != tls_ctx_use_external_private_key(new_ctx,
+                                                     options->cert_file,
+                                                     options->cert_file_inline))
         {
-            tls_ctx_use_external_private_key(new_ctx, options->cert_file,
-                                             options->cert_file_inline);
+            msg(M_FATAL, "Failed to initialize management-external-key");
         }
         else
         {
-            char *external_certificate = management_query_cert(management,
-                                                               options->management_certificate);
-            tls_ctx_use_external_private_key(new_ctx, INLINE_FILE_TAG,
-                                             external_certificate);
-            free(external_certificate);
+            char *external_cert = management_query_cert(
+                            management, options->management_certificate);
+
+            if (!external_cert)
+            {
+                msg(M_FATAL, "Failed to initialize management-external-cert");
+            }
+
+            if (0 != tls_ctx_use_external_private_key(new_ctx, INLINE_FILE_TAG,
+                                                      external_cert))
+            {
+                msg(M_FATAL, "Failed to initialize management-external-key");
+            }
+
+            free(external_cert);
         }
     }
 #endif
src/openvpn/ssl_openssl.c +1 -1
index 8ef68ebd..4d434fa2 100644
@@ -1330,7 +1330,7 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
     return 0;
 
 err:
-    crypto_msg(M_FATAL, "Cannot enable SSL external private key capability");
+    crypto_msg(M_WARN, "Cannot enable SSL external private key capability");
     return 1;
 }
 
Signature · 1 line
2.14.1
#5 lore raw

Hi,

This one applies cleanly on top of master.

Quoted 26 lines · Steffan Karger

Check the return values of management_query_cert() and tls_ctx_use_external_private_key(), and error out with a more descriptive error message. To do so, we make the openssl-backed implementation of tls_ctx_use_external_private_key() not throw fatal error anymore.

(And fix line wrapping while touching this code.)

---
v2: error out with M_FATAL as suggested by Selva.
v3: rebase on master (without extra patches)

 src/openvpn/ssl.c         | 28 ++++++++++++++++++++--------
 src/openvpn/ssl_openssl.c |  2 +-
 2 files changed, 21 insertions(+), 9 deletions(-)
src/openvpn/ssl.c +0 -1
index 669f941b..b06820ba 100644
@@ -660,18 +660,30 @@ init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)
     else if ((options->management_flags & MF_EXTERNAL_KEY)
              && (options->cert_file || options->management_flags & MF_EXTERNAL_CERT))
     {
-        if (options->cert_file)

src/openvpn/ssl.c init_ssl(const struct options *options, struct tls_root_ctx *new_ctx) · line 670

Quoted 10 lines
src/openvpn/ssl.c +5 -2
+        if (options->cert_file
+            && 0 != tls_ctx_use_external_private_key(new_ctx,
+                                                     options->cert_file,
+                                                     options->cert_file_inline))
         {
-            tls_ctx_use_external_private_key(new_ctx, options->cert_file,
-                                             options->cert_file_inline);
+            msg(M_FATAL, "Failed to initialize management-external-key");
         }
         else

But I can't believe I missed this in the last round. This else clause will now get executed not only if options->cert_file is false, but also if its true and the call to tls_ctx_use_external_private_key() succeeds! That would be wrong and is not what we want.

Quoted 31 lines
src/openvpn/ssl.c +15 -5
         {
-            char *external_certificate = management_query_cert(management,
-                                                               options->management_certificate);
-            tls_ctx_use_external_private_key(new_ctx, INLINE_FILE_TAG,
-                                             external_certificate);
-            free(external_certificate);
+            char *external_cert = management_query_cert(
+                            management, options->management_certificate);
+
 
+            if (!external_cert)
+            {
+                msg(M_FATAL, "Failed to initialize management-external-cert");
+            }
+
+            if (0 != tls_ctx_use_external_private_key(new_ctx, INLINE_FILE_TAG,
+                                                      external_cert))
+            {
+                msg(M_FATAL, "Failed to initialize management-external-key");
+            }
+
+            free(external_cert);
         }
     }

#endif

src/openvpn/ssl_openssl.c +0 -0
index 8ef68ebd..4d434fa2 100644

src/openvpn/ssl_openssl.c tls_ctx_use_external_private_key(struct tls_root_ctx *ctx, · line 1335

Quoted 7 lines
src/openvpn/ssl_openssl.c +1 -1
@@ -1330,7 +1330,7 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
     return 0;
 
 err:
-    crypto_msg(M_FATAL, "Cannot enable SSL external private key capability");
+    crypto_msg(M_WARN, "Cannot enable SSL external private key capability");
     return 1;
 }

Selva

#6 lore raw

Hi,

Quoted 4 lines · Selva Nair

But I can't believe I missed this in the last round. This else clause will now get executed not only if options->cert_file is false, but also if its true and the call to tls_ctx_use_external_private_key() succeeds! That would be wrong and is not what we want.

Thanks for catching this before it went into master!

For archiving purposes: this patch is no longer needed because it has been superseded by the refactoring in "Do not load certificate from tls_ctx_use_external_private_key()" (Message-Id:
<[email protected]...>).

I'll register it like so in patchwork too.

-Steffan

#7 lore raw
In reply to Selva Nair

Hi,

Quoted 4 lines · Selva Nair

I wanted to give this a quick test, but it doesn't apply.

It seems you have patch 116 (Antonio's "inline-tag changed to bool" patch) in your local repo.

Oops, you're right - this was based on top of my local working branch, which indeed includes Antonio's inline-tag cleanup patch. Just sent a version based on current public master.

Quoted 4 lines

By the way, the M_FATAL after management_query_cert() looks like a regression. One problem with these FATAL exits is that it makes it hard for the GUI to gracefully handle when user presses cancel on some dialogs. Anyway that's beyond this patch... So just saying..

Not really a regression, right? Previously, management_query_cert() would return NULL, which would cause tls_ctx_use_external_private_key() to ASSERT out, because tls_ctx_load_cert_file_and_copy() would not be able to return a valid "cert" pointer.

But you're definitely right that the error handling over the management interface could benefit greatly from some rework. (Beyond this patch, indeed.)

-Steffan