Skip to contentSkip to conversation

Support external EC cert/key using --management-external-xxx

PATCH In review [email protected]... 6 participants 35 messages Jan 14, 2018 – Feb 21, 2018 3 messages not in the archive

lore
Share & tools
lore
#0 lore raw

cover Support external EC cert/key using --management-external-xxx

From: Selva Nair <[email protected]...>

Hi,

For now this is only for openssl 1.1.0+. With some ifdefs and compat functions could be back ported to 1.0.2.

For 1.0.1 hacks like duplicating internal ECDSA_METHOD struct or linking to internal headers appears to be required. Not interesting unless there is a strong demand.

For mbedtls I've no idea how to hook into the ecdsa signing methods.

Tested on linux/openssl-1.1.0g by manually passing the signature to management, with signature generated on command line by
'echo $rsa_sig_cut_n_paste | base64 -d | openssl pkeyutl -inkey keyfile | base64'

Doing something similar for cryptoapicert is in the works (actually that was the objective, but this was obviously easier to test, lather, rinse)

Selva

Selva Nair (3):
Refactor ssl_openssl.c in prep for external EC key support Allow external EC key through --management-external-key Document management request >ECDSA_SIGN and response ecdsa-sig

 doc/management-notes.txt  |  30 ++++++
 src/openvpn/manage.c      |  30 ++++++
 src/openvpn/manage.h      |   3 +
 src/openvpn/ssl_openssl.c | 234 +++++++++++++++++++++++++++++++++++++++++-----
 4 files changed, 273 insertions(+), 24 deletions(-)
Signature · 1 line
2.1.4
#1 lore raw

PATCH 1/3 Refactor ssl_openssl.c in prep for external EC key support

From: Selva Nair <[email protected]...>

- Move setting of key method callbacks into a function

No change in functionality.

---
 src/openvpn/ssl_openssl.c | 65 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 41 insertions(+), 24 deletions(-)
src/openvpn/ssl_openssl.c +41 -24
index d6d9acf..c29dbcf 100644
@@ -1063,20 +1063,17 @@ done:
     return ret;
 }
 
-int
-tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
-                                 const char *cert_file, const char *cert_file_inline)
+static int
+tls_ctx_use_external_rsa_key(struct tls_root_ctx *ctx, EVP_PKEY *pkey)
 {
     RSA *rsa = NULL;
     RSA *pub_rsa;
     RSA_METHOD *rsa_meth;
-    X509 *cert = NULL;
 
     ASSERT(NULL != ctx);
 
-    tls_ctx_load_cert_file_and_copy(ctx, cert_file, cert_file_inline, &cert);
-
-    ASSERT(NULL != cert);
+    pub_rsa = EVP_PKEY_get0_RSA(pkey);
+    ASSERT(NULL != pub_rsa);
 
     /* allocate custom RSA method object */
     rsa_meth = RSA_meth_new("OpenVPN external private key RSA Method",
@@ -1098,18 +1095,6 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
         goto err;
     }
 
-    /* get the public key */
-    EVP_PKEY *pkey = X509_get0_pubkey(cert);
-    ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */
-    pub_rsa = EVP_PKEY_get0_RSA(pkey);
-
-    /* Certificate might not be RSA but DSA or EC */
-    if (!pub_rsa)
-    {
-        crypto_msg(M_WARN, "management-external-key requires a RSA certificate");
-        goto err;
-    }
-
     /* initialize RSA object */
     const BIGNUM *n = NULL;
     const BIGNUM *e = NULL;
@@ -1118,8 +1103,10 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
     RSA_set_flags(rsa, RSA_flags(rsa) | RSA_FLAG_EXT_PKEY);
     if (!RSA_set_method(rsa, rsa_meth))
     {
+        RSA_meth_free(rsa_meth);
         goto err;
     }
+    /* from this point rsa_meth will get freed with rsa */
 
     /* bind our custom RSA object to ssl_ctx */
     if (!SSL_CTX_use_RSAPrivateKey(ctx->ctx, rsa))
@@ -1127,15 +1114,10 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
         goto err;
     }
 
-    X509_free(cert);
     RSA_free(rsa); /* doesn't necessarily free, just decrements refcount */
     return 1;
 
 err:
-    if (cert)
-    {
-        X509_free(cert);
-    }
     if (rsa)
     {
         RSA_free(rsa);
@@ -1147,6 +1129,41 @@ err:
             RSA_meth_free(rsa_meth);
         }
     }
+    return 0;
+}
+
+int
+tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
+                                 const char *cert_file, const char *cert_file_inline)
+{
+    X509 *cert = NULL;
+
+    ASSERT(NULL != ctx);
+
+    tls_ctx_load_cert_file_and_copy(ctx, cert_file, cert_file_inline, &cert);
+
+    ASSERT(NULL != cert);
+
+    /* get the public key */
+    EVP_PKEY *pkey = X509_get0_pubkey(cert);
+    ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */
+    X509_free(cert);
+
+    if (EVP_PKEY_get0_RSA(pkey))
+    {
+        if (!tls_ctx_use_external_rsa_key(ctx, pkey))
+        {
+            goto err;
+        }
+    }
+    else
+    {
+        crypto_msg(M_WARN, "management-external-key requires a RSA certificate");
+        goto err;
+    }
+    return 1;
+
+err:
     crypto_msg(M_FATAL, "Cannot enable SSL external private key capability");
     return 0;
 }
Signature · 1 line
2.1.4
Acked-by on v1 1/3
#2 lore raw

Re: [Openvpn-devel] [PATCH 1/3] Refactor ssl_openssl.c in prep for external EC key support

Am 14.01.18 um 20:44 schrieb [email protected]...:

Quoted 7 lines

From: Selva Nair <[email protected]...>

- Move setting of key method callbacks into a function

No change in functionality.

This patch is fairly simple and does exactly what it says.

Acked-by Arne Schwabe
#3 lore raw

[Openvpn-devel] [PATCH applied] Re: Refactor ssl_openssl.c in prep for external EC key support

In reply to [email protected]...

Your patch has been applied to the master branch.

For the time being, I've decided to follow the rule "refactoring and new features go to master", and since this "refactoring in preparation for a new feature" (EC external key), it falls under this rule.

If there's good arguments we should have it in 2.4, I won't stand in the way, though.

commit d59a1c2f488cc3f4725df1e053592d53c30cf0eb

Author: Selva Nair
Date:   Sun Jan 14 14:44:31 2018 -0500
     Refactor ssl_openssl.c in prep for external EC key support

     Signed-off-by: Selva Nair <[email protected]...>
     Acked-by: Arne Schwabe <[email protected]...>
     Message-Id: <[email protected]...>
     URL: https://www.mail-archive.com/[email protected]/msg16227.html
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#4 lore raw

PATCH 2/3 Allow external EC key through --management-external-key

In reply to [email protected]...

From: Selva Nair <[email protected]...>

- This automatically supports EC certificates through --management-external-cert
- EC signature request from management has the same format as for rsa with >RSA_SIGN replaced by >ECDSA_SIGN Response should be of the form 'ecdsa-sig' followed by DER encoded signature as base64 followed by 'END'

---
 src/openvpn/manage.c      |  30 ++++++++
 src/openvpn/manage.h      |   3 +
 src/openvpn/ssl_openssl.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 202 insertions(+)
src/openvpn/manage.c +30 -0
index 55b106c..0152dee 100644
@@ -113,6 +113,8 @@ man_help(void)
 #ifdef MANAGMENT_EXTERNAL_KEY
     msg(M_CLIENT, "rsa-sig                : Enter an RSA signature in response to >RSA_SIGN challenge");
     msg(M_CLIENT, "                         Enter signature base64 on subsequent lines followed by END");
+    msg(M_CLIENT, "ecdsa-sig              : Enter an ECDSA signature in response to >ECDSA_SIGN challenge");
+    msg(M_CLIENT, "                         Enter signature base64 on subsequent lines followed by END");
     msg(M_CLIENT, "certificate            : Enter a client certificate in response to >NEED-CERT challenge");
     msg(M_CLIENT, "                         Enter certificate base64 on subsequent lines followed by END");
 #endif
@@ -936,6 +938,7 @@ in_extra_dispatch(struct management *man)
 #endif /* ifdef MANAGEMENT_PF */
 #ifdef MANAGMENT_EXTERNAL_KEY
         case IEC_RSA_SIGN:
+        case IEC_ECDSA_SIGN:
             man->connection.ext_key_state = EKS_READY;
             buffer_list_free(man->connection.ext_key_input);
             man->connection.ext_key_input = man->connection.in_extra;
@@ -1119,6 +1122,22 @@ man_rsa_sig(struct management *man)
 }
 
 static void
+man_ecdsa_sig(struct management *man)
+{
+    struct man_connection *mc = &man->connection;
+    if (mc->ext_key_state == EKS_SOLICIT)
+    {
+        mc->ext_key_state = EKS_INPUT;
+        mc->in_extra_cmd = IEC_ECDSA_SIGN;
+        in_extra_reset(mc, IER_NEW);
+    }
+    else
+    {
+        msg(M_CLIENT, "ERROR: The ecdsa-sig command is not currently available");
+    }
+}
+
+static void
 man_certificate(struct management *man)
 {
     struct man_connection *mc = &man->connection;
@@ -1516,6 +1535,10 @@ man_dispatch_command(struct management *man, struct status_output *so, const cha
     {
         man_rsa_sig(man);
     }
+    else if (streq(p[0], "ecdsa-sig"))
+    {
+        man_ecdsa_sig(man);
+    }
     else if (streq(p[0], "certificate"))
     {
         man_certificate(man);
@@ -3655,6 +3678,13 @@ management_query_rsa_sig(struct management *man,
                                               &man->connection.ext_key_state, &man->connection.ext_key_input);
 }
 
+char *
+management_query_ecdsa_sig(struct management *man,
+                           const char *b64_data)
+{
+    return management_query_multiline_flatten(man, b64_data, "ECDSA_SIGN", "ecdsa-sign",
+                                              &man->connection.ext_key_state, &man->connection.ext_key_input);
+}
 
 char *
 management_query_cert(struct management *man, const char *cert_name)
src/openvpn/manage.h +3 -0
index 676be64..0b1ae5b 100644
@@ -281,6 +281,7 @@ struct man_connection {
 #define IEC_CLIENT_PF   2
 #define IEC_RSA_SIGN    3
 #define IEC_CERTIFICATE 4
+#define IEC_ECDSA_SIGN  5
     int in_extra_cmd;
     struct buffer_list *in_extra;
 #ifdef MANAGEMENT_DEF_AUTH
@@ -441,6 +442,8 @@ void management_learn_addr(struct management *management,
 
 char *management_query_rsa_sig(struct management *man, const char *b64_data);
 
+char *management_query_ecdsa_sig(struct management *man, const char *b64_data);
+
 char *management_query_cert(struct management *man, const char *cert_name);
 
 #endif
src/openvpn/ssl_openssl.c +169 -0

186 lines not on this page · raw message

Signature · 1 line
2.1.4
Tested-by on v1 2/3
#5 lore raw

Re: [Openvpn-devel] [PATCH 2/3] Allow external EC key through --management-external-key

Am 14.01.18 um 20:44 schrieb [email protected]...:

Quoted 9 lines

From: Selva Nair <[email protected]...>

- This automatically supports EC certificates through --management-external-cert
- EC signature request from management has the same format as for rsa with >RSA_SIGN replaced by >ECDSA_SIGN Response should be of the form 'ecdsa-sig' followed by DER encoded signature as base64 followed by 'END'

Thanks for the code. I implemented and tested this on my Android client. It works very well. However I found some minor issues (see below).

But first a high level issue. I think if you enable manange-external-key with an "old" ui that only understand rsa keys the OpenVPN client will hang after ECDSA prompt since the ui will never reply with anything.

We might need an argument to management-external-key to say "yes I am ecdsa ready".

Quoted 7 lines

static void

src/openvpn/manage.c +5 -0
+man_ecdsa_sig(struct management *man)
+{
+    struct man_connection *mc = &man->connection;
+    if (mc->ext_key_state == EKS_SOLICIT)
+    {

src/openvpn/manage.c man_rsa_sig(struct management *man) · line 1139

Quoted 10 lines
src/openvpn/manage.c +10 -0
+        mc->ext_key_state = EKS_INPUT;
+        mc->in_extra_cmd = IEC_ECDSA_SIGN;
+        in_extra_reset(mc, IER_NEW);
+    }
+    else
+    {
+        msg(M_CLIENT, "ERROR: The ecdsa-sig command is not currently available");
+    }
+}
+

This function is almost identical to man_rsa_sign. I would like to have them both combined into one and then called by man_ecdsa_sig/man_rsa_sig.

src/openvpn/manage.c management_query_rsa_sig(struct management *man, · line 3687

Quoted 9 lines
src/openvpn/manage.c +7 -0
+char *
+management_query_ecdsa_sig(struct management *man,
+                           const char *b64_data)
+{
+    return management_query_multiline_flatten(man, b64_data, "ECDSA_SIGN", "ecdsa-sign",
+                                              &man->connection.ext_key_state, &man->connection.ext_key_input);
+}

Hm, could be merged with management_query_rsa_sig but since it a one liner I have no strong preference.

Quoted 13 lines
src/openvpn/ssl_openssl.c +13 -0
+#if OPENSSL_VERSION_NUMBER >= 0x10100001L && !defined(OPENSSL_NO_EC)
+
+/* called when EC_KEY is destroyed */
+static void
+openvpn_extkey_ec_finish(EC_KEY *ec)
+{
+    /* release the method structure */
+    const EC_KEY_METHOD *ec_meth = EC_KEY_get_method(ec);
+    EC_KEY_METHOD_free((EC_KEY_METHOD *) ec_meth);
+}
+
+/* EC_KEY_METHOD callback: sign().
+ * Sign the hash using EC key and return DER encoded signature in sig,

src/openvpn/ssl_openssl.c err: · line 1157

Quoted 10 lines
src/openvpn/ssl_openssl.c +10 -0
+ * its length in siglen. Return value is 1 on success, 0 on error.
+ */
+static int
+ecdsa_sign(int type, const unsigned char *dgst, int dgstlen, unsigned char *sig,
+           unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *ec)
+{
+    char *in_b64 = NULL;
+    char *out_b64 = NULL;
+    int ret = 0;
+    int len;

len could just as well be done als inline C99 decleration. But no problem. (Also I am not so firm on our new style here)

Quoted 26 lines
src/openvpn/ssl_openssl.c +26 -0
+
+    /* convert 'from' to base64 *
+    if (openvpn_base64_encode(dgst, dgstlen, &in_b64) <= 0)
+    {
+        goto done;
+    }
+
+    /* call MI for signature */
+    if (management)
+    {
+        out_b64 = management_query_ecdsa_sig(management, in_b64);
+    }
+    if (!out_b64)
+    {
+        goto done;
+    }
+
+    /* decode base64 signature to binary */
+    len = ECDSA_size(ec);
+    *siglen = openvpn_base64_decode(out_b64, sig, len);
+    if (*siglen > 0)
+    {
+        ret = 1;
+    }
+
+done:

src/openvpn/ssl_openssl.c err: · line 1193

Quoted 10 lines
src/openvpn/ssl_openssl.c +10 -0
+    if (in_b64)
+    {
+        free(in_b64);
+    }
+    if (out_b64)
+    {
+        free(out_b64);
+    }
+    return ret;
+}

This method has a bit code duplication to rsa_priv_enc but I think it is still okay here since you have an rather ugly looking function that is hard to read.

Quoted 12 lines
src/openvpn/ssl_openssl.c +12 -0
+
+/* EC_KEY_METHOD callback: sign_setup(). We do no precomputations */
+static int
+ecdsa_sign_setup(EC_KEY *ec, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+{
+    return 1;
+}
+
+/* EC_KEY_METHOD callback: sign_sig().
+ * Sign the hash and return the result as a newly allocated ECDS_SIG
+ * struct or NULL on error.
+ */

src/openvpn/ssl_openssl.c err: · line 1215

Quoted 10 lines
src/openvpn/ssl_openssl.c +10 -0
+static ECDSA_SIG *
+ecdsa_sign_sig(const unsigned char *dgst, int dgstlen, const BIGNUM *in_kinv,
+               const BIGNUM *in_r, EC_KEY *ec)
+{
+    ECDSA_SIG *ecsig = NULL;
+    int len = ECDSA_size(ec);
+    struct gc_arena gc = gc_new();
+
+    unsigned char *buf = gc_malloc(len, false, &gc);
+    if (1 != ecdsa_sign(0, dgst, dgstlen, buf, &len, NULL, NULL, ec))

I am not sure about 1!= style here. Might be okay. I would try to avoid this.

len should be size_t. My compiler agrees:

ssl_openssl.c:1215:48: warning: passing 'int *' to parameter of type 'unsigned int *' converts between pointers to integer types with different sign [-Wpointer-sign]

    if (1 != ecdsa_sign(0, dgst, dgstlen, buf, &len, NULL, NULL, ec))
                                               ^~~~

ssl_openssl.c:1152:26: note: passing argument to parameter 'siglen' here
unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r,
EC_KEY *ec)

                         ^

1 warning generated.

Quoted 14 lines

int
tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
const char *cert_file, const char *cert_file_inline)

src/openvpn/ssl_openssl.c +7 -0
@@ -1156,11 +1310,26 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
             goto err;
         }
     }
+#if OPENSSL_VERSION_NUMBER >= 0x10100001L && !defined(OPENSSL_NO_EC)
+    else if (EVP_PKEY_get0_EC_KEY(pkey))
+    {
+        if (!tls_ctx_use_external_ec_key(ctx, pkey))
+        {
+            goto err;
+        }

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

Quoted 10 lines
src/openvpn/ssl_openssl.c +7 -0
+    }
+    else
+    {
+        crypto_msg(M_WARN, "management-external-key requires an RSA or EC certificate");
+        goto err;
+    }
+#else
     else
     {
         crypto_msg(M_WARN, "management-external-key requires a RSA certificate");

If you touch that line you can as well fix the grammar in the existing string that you fixed in the new string :)

Arne

author
#6 lore raw

Re: [Openvpn-devel] [PATCH 2/3] Allow external EC key through --management-external-key

Hi,

Wow that was fast :)

Thanks for the review. I'll provide a v2, but some quick remarks/rfc

Quoted 15 lines · Arne Schwabe

Am 14.01.18 um 20:44 schrieb [email protected]...:

Quoted 9 lines

From: Selva Nair <[email protected]...>

- This automatically supports EC certificates through --management-external-cert
- EC signature request from management has the same format as for rsa with >RSA_SIGN replaced by >ECDSA_SIGN Response should be of the form 'ecdsa-sig' followed by DER encoded signature as base64 followed by 'END'

Thanks for the code. I implemented and tested this on my Android client. It works very well. However I found some minor issues (see below).

Quoted 8 lines

But first a high level issue. I think if you enable manange-external-key with an "old" ui that only understand rsa keys the OpenVPN client will hang after ECDSA prompt since the ui will never reply with anything.

We might need an argument to management-external-key to say "yes I am ecdsa ready".

This needs some thought as config option is not really a way of indicating client capabilities, or so it seems.

I can see this could pose a problem for clients that currently support external key.
If there are only a few such known clients we can handle this transparently by looking at IV_GUI_VER?

Quoted 12 lines
Quoted 12 lines

static void

src/openvpn/manage.c +10 -0
+man_ecdsa_sig(struct management *man)
+{
+    struct man_connection *mc = &man->connection;
+    if (mc->ext_key_state == EKS_SOLICIT)
+    {
+        mc->ext_key_state = EKS_INPUT;
+        mc->in_extra_cmd = IEC_ECDSA_SIGN;
+        in_extra_reset(mc, IER_NEW);
+    }
+    else
Quoted 8 lines

src/openvpn/manage.c man_rsa_sig(struct management *man) · line 1139

Quoted 5 lines
src/openvpn/manage.c +5 -0
+    {
+        msg(M_CLIENT, "ERROR: The ecdsa-sig command is not currently available");
+    }
+}
+

This function is almost identical to man_rsa_sign. I would like to have them both combined into one and then called by man_ecdsa_sig/man_rsa_sig.

Could combine these into one function named man_external_sig with an extra parameter, say, cmd = IEC_ECDSA_SIGN or IEC_RSA_SIGN

Quoted 75 lines

src/openvpn/manage.c management_query_rsa_sig(struct management *man, · line 3687

Quoted 10 lines
src/openvpn/manage.c +7 -0
+char *
+management_query_ecdsa_sig(struct management *man,
+                           const char *b64_data)
+{
+    return management_query_multiline_flatten(man, b64_data, "ECDSA_SIGN", "ecdsa-sign",
+                                              &man->connection.ext_key_state, &man->connection.ext_key_input);
+}

Hm, could be merged with management_query_rsa_sig but since it a one liner I have no strong preference.

Quoted 13 lines
src/openvpn/ssl_openssl.c +13 -0
+#if OPENSSL_VERSION_NUMBER >= 0x10100001L && !defined(OPENSSL_NO_EC)
+
+/* called when EC_KEY is destroyed */
+static void
+openvpn_extkey_ec_finish(EC_KEY *ec)
+{
+    /* release the method structure */
+    const EC_KEY_METHOD *ec_meth = EC_KEY_get_method(ec);
+    EC_KEY_METHOD_free((EC_KEY_METHOD *) ec_meth);
+}
+
+/* EC_KEY_METHOD callback: sign().
+ * Sign the hash using EC key and return DER encoded signature in sig,

src/openvpn/ssl_openssl.c err: · line 1157

Quoted 10 lines
src/openvpn/ssl_openssl.c +10 -0
+ * its length in siglen. Return value is 1 on success, 0 on error.
+ */
+static int
+ecdsa_sign(int type, const unsigned char *dgst, int dgstlen, unsigned char *sig,
+           unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *ec)
+{
+    char *in_b64 = NULL;
+    char *out_b64 = NULL;
+    int ret = 0;
+    int len;

len could just as well be done als inline C99 decleration. But no problem. (Also I am not so firm on our new style here)

Quoted 33 lines
src/openvpn/ssl_openssl.c +33 -0
+
+    /* convert 'from' to base64 *
+    if (openvpn_base64_encode(dgst, dgstlen, &in_b64) <= 0)
+    {
+        goto done;
+    }
+
+    /* call MI for signature */
+    if (management)
+    {
+        out_b64 = management_query_ecdsa_sig(management, in_b64);
+    }
+    if (!out_b64)
+    {
+        goto done;
+    }
+
+    /* decode base64 signature to binary */
+    len = ECDSA_size(ec);
+    *siglen = openvpn_base64_decode(out_b64, sig, len);
+    if (*siglen > 0)
+    {
+        ret = 1;
+    }
+
+done:
+    if (in_b64)
+    {
+        free(in_b64);
+    }
+    if (out_b64)
+    {
+        free(out_b64);
Quoted 8 lines

src/openvpn/ssl_openssl.c err: · line 1193

Quoted 3 lines
src/openvpn/ssl_openssl.c +3 -0
+    }
+    return ret;
+}

This method has a bit code duplication to rsa_priv_enc but I think it is still okay here since you have an rather ugly looking function that is hard to read.

Will give it another try to see whether those can be combined without uglifying things further.

Quoted 18 lines
Quoted 18 lines
src/openvpn/ssl_openssl.c +17 -0
+
+/* EC_KEY_METHOD callback: sign_setup(). We do no precomputations */
+static int
+ecdsa_sign_setup(EC_KEY *ec, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+{
+    return 1;
+}
+
+/* EC_KEY_METHOD callback: sign_sig().
+ * Sign the hash and return the result as a newly allocated ECDS_SIG
+ * struct or NULL on error.
+ */
+static ECDSA_SIG *
+ecdsa_sign_sig(const unsigned char *dgst, int dgstlen, const BIGNUM *in_kinv,
+               const BIGNUM *in_r, EC_KEY *ec)
+{
+    ECDSA_SIG *ecsig = NULL;
Quoted 8 lines

src/openvpn/ssl_openssl.c err: · line 1215

Quoted 5 lines
src/openvpn/ssl_openssl.c +5 -0
+    int len = ECDSA_size(ec);
+    struct gc_arena gc = gc_new();
+
+    unsigned char *buf = gc_malloc(len, false, &gc);
+    if (1 != ecdsa_sign(0, dgst, dgstlen, buf, &len, NULL, NULL, ec))

I am not sure about 1!= style here. Might be okay. I would try to avoid this.

Not my favourite either, but for some reason I thought that style was preferred in ssl_xx files (may be so in ssl_mbedtls.c?). So much "easier" to write that as xxx != 1 :) Will do.

Quoted 6 lines

len should be size_t. My compiler agrees:

ssl_openssl.c:1215:48: warning: passing 'int *' to parameter of type 'unsigned int *' converts between pointers to integer types with different sign [-Wpointer-sign]

Quoted 8 lines
    if (1 != ecdsa_sign(0, dgst, dgstlen, buf, &len, NULL, NULL, ec))
                                               ^~~~

ssl_openssl.c:1152:26: note: passing argument to parameter 'siglen' here
unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r,
EC_KEY *ec)

                         ^

1 warning generated.

Yeah, it should be unsigned int. My bad.

Quoted 28 lines
Quoted 14 lines

int
tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
const char *cert_file, const char *cert_file_inline)

src/openvpn/ssl_openssl.c +7 -0
@@ -1156,11 +1310,26 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
             goto err;
         }
     }
+#if OPENSSL_VERSION_NUMBER >= 0x10100001L && !defined(OPENSSL_NO_EC)
+    else if (EVP_PKEY_get0_EC_KEY(pkey))
+    {
+        if (!tls_ctx_use_external_ec_key(ctx, pkey))
+        {
+            goto err;
+        }

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

Quoted 10 lines
src/openvpn/ssl_openssl.c +7 -0
+    }
+    else
+    {
+        crypto_msg(M_WARN, "management-external-key requires an RSA or EC certificate");
+        goto err;
+    }
+#else
     else
     {
         crypto_msg(M_WARN, "management-external-key requires a RSA certificate");

If you touch that line you can as well fix the grammar in the existing string that you fixed in the new string :)

Quoted 1 line

Arne

Thanks again,

Selva

author
#7 lore raw

Re: [Openvpn-devel] [PATCH 2/3] Allow external EC key through --management-external-key

Hi,

Quoted 12 lines · Arne Schwabe
Quoted 11 lines

Am 14.01.18 um 20:44 schrieb [email protected]...:

Quoted 9 lines

From: Selva Nair <[email protected]...>

- This automatically supports EC certificates through --management-external-cert
- EC signature request from management has the same format as for rsa with >RSA_SIGN replaced by >ECDSA_SIGN Response should be of the form 'ecdsa-sig' followed by DER encoded signature as base64 followed by 'END'

snipped..

Quoted 12 lines
Quoted 12 lines
Quoted 12 lines

static void

src/openvpn/manage.c +10 -0
+man_ecdsa_sig(struct management *man)
+{
+    struct man_connection *mc = &man->connection;
+    if (mc->ext_key_state == EKS_SOLICIT)
+    {
+        mc->ext_key_state = EKS_INPUT;
+        mc->in_extra_cmd = IEC_ECDSA_SIGN;
+        in_extra_reset(mc, IER_NEW);
+    }
+    else
Quoted 8 lines
Quoted 8 lines

src/openvpn/manage.c man_rsa_sig(struct management *man) · line 1139

Quoted 5 lines
src/openvpn/manage.c +5 -0
+    {
+        msg(M_CLIENT, "ERROR: The ecdsa-sig command is not currently available");
+    }
+}
+

This function is almost identical to man_rsa_sign. I would like to have them both combined into one and then called by man_ecdsa_sig/man_rsa_sig.

Refactored code that addresses this and other suggestions is here
https://github.com/selvanair/openvpn/commits/external-ec-cert
(last 3 commits left unsquashed for now).

Will send in v2 after testing and squashing but comments welcome.

Regarding amending --management-external-cert command, better to address it separately, so not handled here.

Also I'm toying with the idea of renaming ecdsa-sig/ECDSA-SIGN by pkey-sig/PKEY-SIGN so that eventually we may be able to use it for all types of keys and retire rsa-sig. Any thoughts on that?

Selva

#8 lore raw

Re: [Openvpn-devel] [PATCH 2/3] Allow external EC key through --management-external-key

Hi,

Quoted 3 lines · Selva Nair

Also I'm toying with the idea of renaming ecdsa-sig/ECDSA-SIGN by pkey-sig/PKEY-SIGN so that eventually we may be able to use it for all types of keys and retire rsa-sig. Any thoughts on that?

This was my first though when looking at these patches. Haven't looked at the code yet, but functionally I think that's the way to go. Even if it were that Ed25519 / Ed448 sigs are technically not ECDSA sigs.

I'll look into these great patches more later.

-Steffan

author
#9 lore raw

Re: [Openvpn-devel] [PATCH 2/3] Allow external EC key through --management-external-key

Hi

Quoted 11 lines · Steffan Karger

Hi,

Quoted 3 lines · Selva Nair

Also I'm toying with the idea of renaming ecdsa-sig/ECDSA-SIGN by pkey-sig/PKEY-SIGN so that eventually we may be able to use it for all types of keys and retire rsa-sig. Any thoughts on that?

This was my first though when looking at these patches. Haven't looked at the code yet, but functionally I think that's the way to go. Even if it were that Ed25519 / Ed448 sigs are technically not ECDSA sigs.

I was waiting for the chatlog before finalizing v2. Looks like there are a number of opinions
that seem to converge towards the same view.

This is what I have in my current v2 ready to go out:

(i) Current behaviour for rsa signatures stays for now: daemon sends

Quoted 1 line

RSA_SIGN client responds

with rsa-sig
(ii) Daemon sends >PK_SIG client responds with pk-sig [*] Initially this will be used only for EC, but trivial to switch RSA to this in future.
So document that new mgmt clients should be prepared to handle all supported key types via >PK_SIGN/pk-sig and >RSA_SIGN will be eventually removed.

As a nice side effect, clients are allowed to respond with pk-sig even if the challenge was

Quoted 1 line

RSA_SIGN. As a not so nice side effect, the daemon will reply with

"SUCCESS rsa-sign
succeeded" because that's what it asked for -- I suppose we can live with that.

We can deprecate and remove >RSA_SIGN at a later date by a hard switch when all known clients are capable of handling >PK_SIGN

Does this sound like an acceptable solution?

Question: while at it should we alter the syntax to

Quoted 1 line

PK_SIGN,xxx,<base64>

where xxx will be empty for now, but it reserves space for extra info that may come handy for some future signature types (like use PSS padding for RSA or use PureEdDSA or whatever).

Thanks,

Selva

#10 lore raw

Re: [Openvpn-devel] [PATCH 2/3] Allow external EC key through --management-external-key

Quoted 41 lines · Selva Nair

Hi

On Wed, Jan 17, 2018 at 3:53 AM, Steffan Karger <[email protected]... <mailto:[email protected]...>> wrote:

Hi,

On 17-01-18 05:24, Selva Nair wrote:
> Also I'm toying with the idea of renaming ecdsa-sig/ECDSA-SIGN by > pkey-sig/PKEY-SIGN so that eventually we may be able to use it for > all types of keys and retire rsa-sig. Any thoughts on that?

This was my first though when looking at these patches.  Haven't looked at the code yet, but functionally I think that's the way to go.  Even if it were that Ed25519 / Ed448 sigs are technically not ECDSA sigs.

I was waiting for the chatlog before finalizing v2. Looks like there are a number of opinions
that seem to converge towards the same view.

This is what I have in my current v2 ready to go out:

(i) Current behaviour for rsa signatures stays for now: daemon sends

Quoted 1 line

RSA_SIGN  client responds

with rsa-sig
(ii) Daemon sends >PK_SIG client responds with pk-sig [*] Initially this will be used only for EC, but trivial to switch RSA to this in future.
So document that new mgmt clients should be prepared to handle all supported key types via >PK_SIGN/pk-sig and >RSA_SIGN will be eventually removed.

As a nice side effect, clients are allowed to respond with pk-sig even if the challenge was

Quoted 1 line

RSA_SIGN. As a not so nice side effect, the daemon will reply with "SUCCESS

rsa-sign
succeeded" because that's what it asked for -- I suppose we can live with that.

We can deprecate and remove >RSA_SIGN at a later date by a hard switch when all known clients are capable of handling >PK_SIGN

Quoted 8 lines

Does this sound like an acceptable solution?

Question: while at it should we alter the syntax to

Quoted 1 line

PK_SIGN,xxx,<base64>

where xxx will be empty for now, but it reserves space for extra info that may come handy for some future signature types (like use PSS padding for RSA or use PureEdDSA or whatever).

Hi,

I've discussed this quickly with James quite recently. We are concerned about breaking existing front-end integrations by doing too much funky stuff with RSA_SIGN for EC support. That in particular touches the signal renaming to PK_SIGN.

So we have another suggestion. For external keys to be used, --management-external-key is needed. Add an optional argument to this option, which indicates a version. If this argument is not provided, everything works as it is today - without EC support. If using: --management-external-key 2 ... for version 2, do a hard-shift to PK_SIGN with RSA and EC support.

This way we ensure we don't break any existing implementations, we can allow a period of transition to the new version, and we can in the future when we are sure PK_SIGN works well and has seen deployment elsewhere start a deprecation process if the legacy version 1. But we're not put in a situation where anything changes suddenly and abruptly.

Any thoughts?

Signature · 4 lines
kind regards,

David Sommerseth
OpenVPN Inc
author
#11 lore raw

Re: [Openvpn-devel] [PATCH 2/3] Allow external EC key through --management-external-key

Quoted 65 lines · David Sommerseth
Quoted 41 lines · Selva Nair

Hi

On Wed, Jan 17, 2018 at 3:53 AM, Steffan Karger <[email protected]... <mailto:[email protected]...>> wrote:

Hi,

On 17-01-18 05:24, Selva Nair wrote:
> Also I'm toying with the idea of renaming ecdsa-sig/ECDSA-SIGN by > pkey-sig/PKEY-SIGN so that eventually we may be able to use it for > all types of keys and retire rsa-sig. Any thoughts on that?

This was my first though when looking at these patches. Haven't looked at the code yet, but functionally I think that's the way to go. Even if it were that Ed25519 / Ed448 sigs are technically not ECDSA sigs.

I was waiting for the chatlog before finalizing v2. Looks like there are a number of opinions
that seem to converge towards the same view.

This is what I have in my current v2 ready to go out:

(i) Current behaviour for rsa signatures stays for now: daemon sends

Quoted 1 line

RSA_SIGN client responds

with rsa-sig
(ii) Daemon sends >PK_SIG client responds with pk-sig [*] Initially this will be used only for EC, but trivial to switch RSA to this in future.
So document that new mgmt clients should be prepared to handle all supported key types via >PK_SIGN/pk-sig and >RSA_SIGN will be eventually removed.

As a nice side effect, clients are allowed to respond with pk-sig even if the challenge was

Quoted 1 line

RSA_SIGN. As a not so nice side effect, the daemon will reply with "SUCCESS

rsa-sign
succeeded" because that's what it asked for -- I suppose we can live with that.

We can deprecate and remove >RSA_SIGN at a later date by a hard switch when all known clients are capable of handling >PK_SIGN

Quoted 8 lines

Does this sound like an acceptable solution?

Question: while at it should we alter the syntax to

Quoted 1 line

PK_SIGN,xxx,<base64>

where xxx will be empty for now, but it reserves space for extra info that may come handy for some future signature types (like use PSS padding for RSA or use PureEdDSA or whatever).

Hi,

I've discussed this quickly with James quite recently. We are concerned about breaking existing front-end integrations by doing too much funky stuff with RSA_SIGN for EC support. That in particular touches the signal renaming to PK_SIGN.

So we have another suggestion. For external keys to be used, --management-external-key is needed. Add an optional argument to this option, which indicates a version. If this argument is not provided, everything works as it is today - without EC support. If using: --management-external-key 2 ... for version 2, do a hard-shift to PK_SIGN with RSA and EC support.

Quoted 7 lines

This way we ensure we don't break any existing implementations, we can allow a period of transition to the new version, and we can in the future when we are sure PK_SIGN works well and has seen deployment elsewhere start a deprecation process if the legacy version 1. But we're not put in a situation where anything changes suddenly and abruptly.

Any thoughts?

This is similar to what Arne proposed while reviewing version 1 of the patch. But I was not excited about encoding client capability into a config option. On further thought, this may offer a little less unpleasant UX to some users and I'm ok with it.

I guess tunnelblick supports this options so Jonathan (and Arne) may have more insight.

The current patch also allows a delayed deprecation of RSA_SIGN giving time for clients to prepare to handle PK_SIGN. But the UX differs a little:

- lay user: everything just works always if the provider/admin is good; or someone fixes things for them.

- client developers: as long as we deprecate commands/options responsibly (no hard switching), and document it, they/we will cope

So its about average/advanced users changing their RSA cert to EC with --management-external-key and a client that doesn't yet support PK_SIGN:

- Present patch: connection process appears stuck (but UI is still responsive) and logs show the daemon is waiting for signature

- This proposal: connection fails with: "External EC cert/key not supported in this config. Try using --management-external-key 2" User edits the config option and the connection process appears stuck .....

I suppose the latter is a bit better.

Selva

#12 lore raw

Re: [Openvpn-devel] [PATCH 2/3] Allow external EC key through --management-external-key

Quoted 8 lines · Selva Nair

- Present patch: connection process appears stuck (but UI is still responsive) and logs show the daemon is waiting for signature

- This proposal: connection fails with: "External EC cert/key not supported in this config. Try using --management-external-key 2" User edits the config option and the connection process appears stuck .....

I suppose the latter is a bit better.

Well, it should probably be tweaked slightly better. First of all, if run via a GUI front-end, it's the GUI which should set this argument. We could consider to add a "fail-safe" on this option, so once set - it can't be changed again. The more advanced rabbit whole fix would be that the command line provided --management-external-key option overrides whatever is in the configuration file; doing this will require more work though.

This will make the VPN connection will still fail, but it won't be stuck any more. The user may complain "but I did add that option!?" which then is a better starting point for support cases ... "Yes, it is most likely ignored as your user interface is not capable of this feature".

Another alternative is to extend an already longer error log entry, by mentioning "also ensure that your management interface front-end supports version 2."

Signature · 4 lines
kind regards,

David Sommerseth
OpenVPN Inc
author
#13 lore raw

Re: [Openvpn-devel] [PATCH 2/3] Allow external EC key through --management-external-key

Hi,

Quoted 8 lines · David Sommerseth
Quoted 7 lines · Selva Nair

- Present patch: connection process appears stuck (but UI is still responsive) and logs show the daemon is waiting for signature

- This proposal: connection fails with: "External EC cert/key not supported in this config. Try using --management-external-key 2" User edits the config option and the connection process appears stuck .....

Quoted 8 lines
Quoted 1 line

I suppose the latter is a bit better.

Well, it should probably be tweaked slightly better. First of all, if run via a GUI front-end, it's the GUI which should set this argument. We could consider to add a "fail-safe" on this option, so once set - it can't be changed again. The more advanced rabbit whole fix would be that the command line provided --management-external-key option overrides whatever is in the configuration file; doing this will require more work though.

Problem with GUI specifying the option is that it has to first check whether the config uses management-external-key (this option interferes with --key, --pkcs12 etc.). Probably not an issue with most UI's out there but Windows GUI doesn't currently parse the config at all. That said, Windows GUI doesn't support management-external-key so that's not a strong argument.

Quoted 9 lines

This will make the VPN connection will still fail, but it won't be stuck any more. The user may complain "but I did add that option!?" which then is a better starting point for support cases ... "Yes, it is most likely ignored as your user interface is not capable of this feature".

Another alternative is to extend an already longer error log entry, by mentioning "also ensure that your management interface front-end supports version 2."

What about extending the current "version" command with an argument where the client states the version of "management-speak" that it supports. Current management version is 1, we increase it to 1.1 and unless the client says "version 1.1" or more we do not send PK_SIGN. The client could do that when it gets the version message or any time later. The response to version command (current management version and openvpn daemon's version stays the same). No full-fledged cap negotiation, but good enough.

The UX would be much better that way.

Selva

author
#14 lore raw

Re: [Openvpn-devel] [PATCH 2/3] Allow external EC key through --management-external-key

Quoted 2 lines

The client could do that when it gets the version message or any time later.

Sorry for the type: read that as

The client could do that when it gets the welcome message or any time later.

Selva

author
#15 lore raw

Re: [Openvpn-devel] [PATCH 2/3] Allow external EC key through --management-external-key

In reply to Selva Nair

Hi,

Quoted 47 lines · Selva Nair

Hi,

Quoted 8 lines · David Sommerseth
Quoted 7 lines · Selva Nair

- Present patch: connection process appears stuck (but UI is still responsive) and logs show the daemon is waiting for signature

- This proposal: connection fails with: "External EC cert/key not supported in this config. Try using --management-external-key 2" User edits the config option and the connection process appears stuck .....

Quoted 8 lines
Quoted 1 line

I suppose the latter is a bit better.

Well, it should probably be tweaked slightly better. First of all, if run via a GUI front-end, it's the GUI which should set this argument. We could consider to add a "fail-safe" on this option, so once set - it can't be changed again. The more advanced rabbit whole fix would be that the command line provided --management-external-key option overrides whatever is in the configuration file; doing this will require more work though.

Problem with GUI specifying the option is that it has to first check whether the config uses management-external-key (this option interferes with --key, --pkcs12 etc.). Probably not an issue with most UI's out there but Windows GUI doesn't currently parse the config at all. That said, Windows GUI doesn't support management-external-key so that's not a strong argument.

Quoted 9 lines

This will make the VPN connection will still fail, but it won't be stuck any more. The user may complain "but I did add that option!?" which then is a better starting point for support cases ... "Yes, it is most likely ignored as your user interface is not capable of this feature".

Another alternative is to extend an already longer error log entry, by mentioning "also ensure that your management interface front-end supports version 2."

What about extending the current "version" command with an argument where the client states the version of "management-speak" that it supports. Current management version is 1, we increase it to 1.1 and unless the client says "version 1.1" or more we do not send PK_SIGN. The client could do that when it gets the version message or any time later. The response to version command (current management version and openvpn daemon's version stays the same). No full-fledged cap negotiation, but good enough.

Quoted 1 line

The UX would be much better that way.

I would appreciate some feedback.

Thanks,

Selva

A message that is not in the archive (sent off-list or not yet received): [email protected]...

#17 lore raw

PATCH 2/3 Allow external EC key through --management-external-key

Hi.

Quoted 8 lines · Selva Nair

What about extending the current "version" command with an argument where the client states the version of "management-speak" that it supports. Current management version is 1, we increase it to 1.1 and unless the client says "version 1.1" or more we do not send PK_SIGN. The client could do that when it gets the version message or any time later. The response to version command (current management version and openvpn daemon's version stays the same). No full-fledged cap negotiation, but good enough.

That sounds reasonable; easy to implement in Tunnelblick

Quoted 1 line

The UX would be much better that way.

Absolutely.

Best regards,

Jon Bullard

author
#18 lore raw

Re: [Openvpn-devel] [PATCH 2/3] Allow external EC key through --management-external-key

Hi,

Quoted 12 lines · Jonathan K. Bullard

Hi.

Quoted 8 lines · Selva Nair

What about extending the current "version" command with an argument where the client states the version of "management-speak" that it supports. Current management version is 1, we increase it to 1.1 and unless the client says "version 1.1" or more we do not send PK_SIGN. The client could do that when it gets the version message or any time later. The response to version command (current management version and openvpn daemon's version stays the same). No full-fledged cap negotiation, but good enough.

Quoted 7 lines

That sounds reasonable; easy to implement in Tunnelblick

Quoted 1 line

The UX would be much better that way.

Absolutely.

Encouraged by Jonathan's reply I have made a patch to rename RSA_SIGN to PK_SIGN if client announces a version > 1. Will send it and a modified EC key patch soon.

Selva

#19 lore raw

Re: [Openvpn-devel] [PATCH 2/3] Allow external EC key through --management-external-key

Quoted 19 lines · Selva Nair

Hi,

Quoted 15 lines · Jonathan K. Bullard

Hi.

Quoted 8 lines · Selva Nair

What about extending the current "version" command with an argument where the client states the version of "management-speak" that it supports. Current management version is 1, we increase it to 1.1 and unless the client says "version 1.1" or more we do not send PK_SIGN. The client could do that when it gets the version message or any time later. The response to version command (current management version and openvpn daemon's version stays the same). No full-fledged cap negotiation, but good enough.

That sounds reasonable; easy to implement in Tunnelblick

Quoted 8 lines
Quoted 4 lines
Quoted 1 line

The UX would be much better that way.

Absolutely.

Encouraged by Jonathan's reply I have made a patch to rename RSA_SIGN to PK_SIGN if client announces a version > 1. Will send it and a modified EC key patch soon.

Sounds good! Just one question ... any reason why to complicate the version number with decimals? Why not just version 1, 2,...X? Coding wise, this is much easier too, as we don't need to do more complicated conversion steps from strings to float.

Signature · 4 lines
kind regards,

David Sommerseth
OpenVPN Inc
author
#20 lore raw

Re: [Openvpn-devel] [PATCH 2/3] Allow external EC key through --management-external-key

Hi,

Quoted 25 lines · David Sommerseth
Quoted 24 lines · Selva Nair

Hi,

Quoted 19 lines · Jonathan K. Bullard

Hi.

Quoted 8 lines · Selva Nair

What about extending the current "version" command with an argument where the client states the version of "management-speak" that it supports. Current management version is 1, we increase it to 1.1 and unless the client says "version 1.1" or more we do not send PK_SIGN. The client could do that when it gets the version message or any time later. The response to version command (current management version and openvpn daemon's version stays the same). No full-fledged cap negotiation, but good enough.

That sounds reasonable; easy to implement in Tunnelblick

Quoted 1 line

The UX would be much better that way.

Absolutely.

Quoted 8 lines
Quoted 3 lines

Encouraged by Jonathan's reply I have made a patch to rename RSA_SIGN to PK_SIGN if client announces a version > 1. Will send it and a modified EC key patch soon.

Sounds good! Just one question ... any reason why to complicate the version number with decimals? Why not just version 1, 2,...X? Coding wise, this is much easier too, as we don't need to do more complicated conversion steps from strings to float.

Yes, patch submitted this afternoon uses just a single integer -- so the version goes up to 2. My plan was to split "1.1" into major + minor (float in the RFC patch was just for amusement) but as you say a single integer is so much easier and good enough for this.

Thanks,

Selva

#21 lore raw

PATCH v2 2/3 Allow external EC key through --management-external-key

In reply to Arne Schwabe

From: Selva Nair <[email protected]...>

- This automatically supports EC certificates through --management-external-cert
- EC signature request from management has the same format as for rsa with '>RSA_SIGN' replaced by '>PK_SIGN'. Response should be of the form 'pk-sig' followed by DER encoded signature as base64 followed by 'END'

To allow future deprecation of rsa-sig, response to '>RSA_SIGN' challenge could be presented as 'pk-sig' or 'rsa-sig'.

v2: changes
Based on feedback from Jan 17 meeting
- Name the command as PK_SIGN and pk-sig and have it ready for replacing RSA_SIGN and rsa-sig in future
Base on review by Arne Schwabe ([email protected]...)
- Split rsa_priv_enc to allow code reuse for ecdsa_sign
- Rename man_rsa_sig to man_external_sig with an extra arg to use it for multiple key-types
- Bug fix: change len to unsigned int in ecdsa_sign_sig

---

Note: Adding an option to determine whether the client can handle the new feature is left for a separate patch if deemed necessary.

 src/openvpn/manage.c      |  25 +++++-
 src/openvpn/manage.h      |   3 +
 src/openvpn/ssl_openssl.c | 215 ++++++++++++++++++++++++++++++++++++++--------
 3 files changed, 201 insertions(+), 42 deletions(-)
src/openvpn/manage.c +21 -4
index 650f9e0..fac5eec 100644
@@ -113,6 +113,8 @@ man_help(void)
 #ifdef MANAGMENT_EXTERNAL_KEY
     msg(M_CLIENT, "rsa-sig                : Enter an RSA signature in response to >RSA_SIGN challenge");
     msg(M_CLIENT, "                         Enter signature base64 on subsequent lines followed by END");
+    msg(M_CLIENT, "pk-sig                 : Enter a signature in response to >PK_SIGN challenge");
+    msg(M_CLIENT, "                         Enter signature in base64 on subsequent lines followed by END");
     msg(M_CLIENT, "certificate            : Enter a client certificate in response to >NEED-CERT challenge");
     msg(M_CLIENT, "                         Enter certificate base64 on subsequent lines followed by END");
 #endif
@@ -936,6 +938,7 @@ in_extra_dispatch(struct management *man)
 #endif /* ifdef MANAGEMENT_PF */
 #ifdef MANAGMENT_EXTERNAL_KEY
         case IEC_RSA_SIGN:
+        case IEC_PK_SIGN:
             man->connection.ext_key_state = EKS_READY;
             buffer_list_free(man->connection.ext_key_input);
             man->connection.ext_key_input = man->connection.in_extra;
@@ -1103,18 +1106,21 @@ man_client_pf(struct management *man, const char *cid_str)
 #ifdef MANAGMENT_EXTERNAL_KEY
 
 static void
-man_rsa_sig(struct management *man)
+man_external_sig(struct management *man, int cmd)
 {
+    ASSERT(cmd == IEC_RSA_SIGN || cmd == IEC_PK_SIGN);
     struct man_connection *mc = &man->connection;
+    const char *cmd_name = (cmd == IEC_RSA_SIGN) ? "rsa-sig" : "pk-sig";
     if (mc->ext_key_state == EKS_SOLICIT)
     {
         mc->ext_key_state = EKS_INPUT;
-        mc->in_extra_cmd = IEC_RSA_SIGN;
+        mc->in_extra_cmd = cmd;
         in_extra_reset(mc, IER_NEW);
     }
     else
     {
-        msg(M_CLIENT, "ERROR: The rsa-sig command is not currently available");
+        msg(M_CLIENT, "ERROR: The %s command is not currently available",
+            cmd_name);
     }
 }
 
@@ -1514,7 +1520,11 @@ man_dispatch_command(struct management *man, struct status_output *so, const cha
 #ifdef MANAGMENT_EXTERNAL_KEY
     else if (streq(p[0], "rsa-sig"))
     {
-        man_rsa_sig(man);
+        man_external_sig(man, IEC_RSA_SIGN);
+    }
+    else if (streq(p[0], "pk-sig"))
+    {
+        man_external_sig(man, IEC_PK_SIGN);
     }
     else if (streq(p[0], "certificate"))
     {
@@ -3655,6 +3665,13 @@ management_query_rsa_sig(struct management *man,
                                               &man->connection.ext_key_state, &man->connection.ext_key_input);
 }
 
+char *
+management_query_pk_sig(struct management *man,
+                          const char *b64_data)
+{
+    return management_query_multiline_flatten(man, b64_data, "PK_SIGN", "pk-sign",
+                    &man->connection.ext_key_state, &man->connection.ext_key_input);
+}
 
 char *
 management_query_cert(struct management *man, const char *cert_name)
src/openvpn/manage.h +3 -0
index 364488f..c468f20 100644
@@ -281,6 +281,7 @@ struct man_connection {
 #define IEC_CLIENT_PF   2
 #define IEC_RSA_SIGN    3
 #define IEC_CERTIFICATE 4
+#define IEC_PK_SIGN     5
     int in_extra_cmd;
     struct buffer_list *in_extra;
 #ifdef MANAGEMENT_DEF_AUTH
@@ -441,6 +442,8 @@ void management_learn_addr(struct management *management,
 
 char *management_query_rsa_sig(struct management *man, const char *b64_data);
 
+char *management_query_pk_sig(struct management *man, const char *b64_data);
+
 char *management_query_cert(struct management *man, const char *cert_name);
 
 #endif
src/openvpn/ssl_openssl.c +177 -38

252 lines not on this page · raw message

Signature · 1 line
2.1.4
#22 lore raw

PATCH v3 2/3 Allow external EC key through --management-external-key

From: Selva Nair <[email protected]...>

- This automatically supports EC certificates through --management-external-cert
- EC signature request from management is prompted by

Quoted 1 line

PK_SIGN if the client supports it (or >RSA_SIGN)

Response should be of the form 'pk-sig' (or rsa-sig by older clients) followed by DER encoded signature as base64 terminated by 'END' on a new line.

v3: This is v2 adapted to the client_version capability Requires pacthes 1 and 2 of the series 147:
https://patchwork.openvpn.net/project/openvpn2/list/?series=147

---
 doc/management-notes.txt  |   9 +-
 src/openvpn/ssl_openssl.c | 210 +++++++++++++++++++++++++++++++++++++---------
 2 files changed, 176 insertions(+), 43 deletions(-)
doc/management-notes.txt +5 -4
index 070c2d6..96470d0 100644
@@ -779,14 +779,14 @@ COMMAND -- rsa-sig (OpenVPN 2.3 or higher, management version <= 1)
 Provides support for external storage of the private key. Requires the
 --management-external-key option. This option can be used instead of "key"
 in client mode, and allows the client to run without the need to load the
-actual private key. When the SSL protocol needs to perform an RSA sign
+actual private key. When the SSL protocol needs to perform a sign
 operation, the data to be signed will be sent to the management interface
 via a notification as follows:
 
 >PK_SIGN:[BASE64_DATA] (if client announces support for management version > 1)
 >RSA_SIGN:[BASE64_DATA] (only older clients will be prompted like this)
 
-The management interface client should then create a PKCS#1 v1.5 signature of
+The management interface client should then create an appropriate signature of
 the (decoded) BASE64_DATA using the private key and return the SSL signature as
 follows:
 
@@ -797,8 +797,9 @@ pk-sig   (or rsa-sig)
 .
 END
 
-Base64 encoded output of RSA_private_encrypt() (OpenSSL) or mbedtls_pk_sign()
-(mbed TLS) will provide a correct signature.
+Base64 encoded output of RSA_private_encrypt for RSA or ECDSA_sign() for EC
+using OpenSSL or mbedtls_pk_sign() using mbed TLS will provide a correct
+signature.
 
 This capability is intended to allow the use of arbitrary cryptographic
 service providers with OpenVPN via the management interface.
src/openvpn/ssl_openssl.c +171 -39

253 lines not on this page · raw message

Signature · 1 line
2.1.4
Acked-by on v3 2/3
#23 lore raw

Re: [Openvpn-devel] [PATCH v3 2/3] Allow external EC key through --management-external-key

Am 25.01.18 um 20:45 schrieb [email protected]...:

Quoted 11 lines

From: Selva Nair <[email protected]...>

- This automatically supports EC certificates through --management-external-cert
- EC signature request from management is prompted by

Quoted 1 line

PK_SIGN if the client supports it (or >RSA_SIGN)

Response should be of the form 'pk-sig' (or rsa-sig by older clients) followed by DER encoded signature as base64 terminated by 'END' on a new line.

Ack from my side. Note that this patch will ask for a ec signatre with > RSA-SIGN when the user has put a EC certificate in the config and the ui does not send "version 2". I am not sure that we need to address this tough. That kind of configuration will break anyway. It just now does at a different point. And putting an EC certificate is not something that should happen on accident.

Arne

author
#24 lore raw

Re: [Openvpn-devel] [PATCH v3 2/3] Allow external EC key through --management-external-key

Hi,

Thanks for the review and ACK.

Quoted 13 lines · Arne Schwabe

Am 25.01.18 um 20:45 schrieb [email protected]...:

Quoted 11 lines

From: Selva Nair <[email protected]...>

- This automatically supports EC certificates through --management-external-cert
- EC signature request from management is prompted by

Quoted 1 line

PK_SIGN if the client supports it (or >RSA_SIGN)

Response should be of the form 'pk-sig' (or rsa-sig by older clients) followed by DER encoded signature as base64 terminated by 'END' on a new line.

Quoted 8 lines

Ack from my side. Note that this patch will ask for a ec signatre with > RSA-SIGN when the user has put a EC certificate in the config and the ui does not send "version 2". I am not sure that we need to address this tough. That kind of configuration will break anyway. It just now does at a different point. And putting an EC certificate is not something that should happen on accident.

I do not think we need to be concerned about this. An old UI would just say either it doesn't support signing using the key or that it got incorrect signature request from the daemon. So instead of erroring out in openvpn we will error out in the UI.

But that's the theory, I do not know how extant UI's out there would respond to RSA_SIGN request with data != 36 bytes or when key is not RSA. The !=36 byte thing already happened when we merged the TLS1.2 patch. What will the android client do in this case?

Jonathan, would tunnelblick cope if it gets an RSA_SIGN when the key is EC or with unexpected data size?

Selva

#25 lore raw

[Openvpn-devel] [PATCH applied] Re: Allow external EC key through --management-external-key

In reply to [email protected]...

Your patch has been applied to the master branch.

(I have not done any real review on it, except "compile test" and "stare a bit at the code for really obvious issues" - trusting Arne since his GUI seems to be the only thing really using it today, so if he's happy, I am as well)

commit 7eca140c70ff76177371dc94c19aeb8644c2c3b5

Author: Selva Nair
Date:   Thu Jan 25 14:45:13 2018 -0500
     Allow external EC key through --management-external-key

     Signed-off-by: Selva Nair <[email protected]...>
     Acked-by: Arne Schwabe <[email protected]...>
     Message-Id: <[email protected]...>
     URL: https://www.mail-archive.com/[email protected]/msg16365.html
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#26 lore raw

Re: [Openvpn-devel] [PATCH applied] Re: Allow external EC key through --management-external-key

Hi,

Quoted 7 lines · Gert Doering

Your patch has been applied to the master branch.

(I have not done any real review on it, except "compile test" and "stare a bit at the code for really obvious issues" - trusting Arne since his GUI seems to be the only thing really using it today, so if he's happy, I am as well)

Quoted 5 lines

commit 7eca140c70ff76177371dc94c19aeb8644c2c3b5

Author: Selva Nair
Date:   Thu Jan 25 14:45:13 2018 -0500

Allow external EC key through --management-external-key

*sigh*

Today's the day of buildbot exploisions.

*This* one breaks LibreSSL compilation (namely, the OpenBSD buildbot), because

ssl_openssl.c: In function 'tls_ctx_use_external_ec_key':
ssl_openssl.c:1229: error: 'EC_KEY_METHOD' undeclared (first use in this function) ssl_openssl.c:1229: error: 'ec_method' undeclared (first use in this function) ssl_openssl.c:1233: warning: implicit declaration of function 'EC_KEY_METHOD_new' ssl_openssl.c:1233: warning: implicit declaration of function 'EC_KEY_OpenSSL' ssl_openssl.c:1240: warning: implicit declaration of function 'EC_KEY_METHOD_set_init' ssl_openssl.c:1241: warning: implicit declaration of function 'EC_KEY_METHOD_set_sign' ssl_openssl.c:1249: warning: implicit declaration of function 'EC_KEY_set_method'

So we need another "&& !defined(LIBRESSL)" here, I think.

(And this, dear OpenBSD folks, is why application developers are just a tiny little bit unhappy with the way LibreSSL claims OpenSSL "recent API" compatibility by means of OPENSSL_VERSION but then... doesn't)

gert

Signature · 3 lines
now what should I write here...

Gert Doering - Munich, Germany                             [email protected]...
author
#27 lore raw

Re: [Openvpn-devel] [PATCH applied] Re: Allow external EC key through --management-external-key

Hi,

Quoted 32 lines · Gert Doering

Hi,

Quoted 7 lines · Gert Doering

Your patch has been applied to the master branch.

(I have not done any real review on it, except "compile test" and "stare a bit at the code for really obvious issues" - trusting Arne since his GUI seems to be the only thing really using it today, so if he's happy, I am as well)

Quoted 5 lines

commit 7eca140c70ff76177371dc94c19aeb8644c2c3b5

Author: Selva Nair
Date:   Thu Jan 25 14:45:13 2018 -0500

Allow external EC key through --management-external-key

*sigh*

Today's the day of buildbot exploisions.

*This* one breaks LibreSSL compilation (namely, the OpenBSD buildbot), because

ssl_openssl.c: In function 'tls_ctx_use_external_ec_key':
ssl_openssl.c:1229: error: 'EC_KEY_METHOD' undeclared (first use in this function) ssl_openssl.c:1229: error: 'ec_method' undeclared (first use in this function) ssl_openssl.c:1233: warning: implicit declaration of function 'EC_KEY_METHOD_new' ssl_openssl.c:1233: warning: implicit declaration of function 'EC_KEY_OpenSSL' ssl_openssl.c:1240: warning: implicit declaration of function 'EC_KEY_METHOD_set_init' ssl_openssl.c:1241: warning: implicit declaration of function 'EC_KEY_METHOD_set_sign' ssl_openssl.c:1249: warning: implicit declaration of function 'EC_KEY_set_method'

Quoted 5 lines

So we need another "&& !defined(LIBRESSL)" here, I think.

(And this, dear OpenBSD folks, is why application developers are just a tiny little bit unhappy with the way LibreSSL claims OpenSSL "recent API" compatibility by means of OPENSSL_VERSION but then... doesn't)

Adding && !defined(LIBRESSL_VERSION_NUMBER)
to the line
#if OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_EC)

should fix it, I think. I don't have a freebsd build env to test this.

Thanks,

Selva

A message that is not in the archive (sent off-list or not yet received): [email protected]...

#29 lore raw

Re: [Openvpn-devel] [PATCH applied] Re: Allow external EC key through --management-external-key

Hi,

Quoted 2 lines · Selva Nair
Quoted 2 lines
Quoted 2 lines

*This* one breaks LibreSSL compilation (namely, the OpenBSD buildbot), because

[..]

Quoted 7 lines

Tested using the freebsd-11 box in openvpn-vagrant and did pkg install libressl-2.6.4 (that replaces openssl 1.1.0).

This particular error gets fixed by adding
!defined(LIBRESSL_VERSION_NUMBER) in two places.

I can send a patch for this.

This would be appreciated (please --cc me directly as the list is still not working properly).

Quoted 5 lines

But there are other errors:

In file included from crypto_openssl.c:44:
./openssl_compat.h:699:1: error: static declaration of 'SSL_CTX_set_min_proto_version' follows

[..]

Quoted 3 lines

./openssl_compat.h:728:1: error: static declaration of 'SSL_CTX_set_max_proto_version' follows
non-static declaration

[..]

Quoted 2 lines

In openssl those are macros but not in libressl so the current openssl_compat.h defs don't work.

This is interesting. Seems my OpenBSD version is too old, as I've not seen these errors in my buildbots.

Let's fix one thing at a time, and start with the easy ones, which will make the buildbots happy for the time being :-) - and then look at "more recent LibreSSL fallouts".

gert

Signature · 3 lines
now what should I write here...

Gert Doering - Munich, Germany                             [email protected]...
author
#30 lore raw

Re: [Openvpn-devel] [PATCH applied] Re: Allow external EC key through --management-external-key

Hi,

Quoted 26 lines · Gert Doering

Hi,

Quoted 2 lines · Selva Nair
Quoted 2 lines
Quoted 2 lines

*This* one breaks LibreSSL compilation (namely, the OpenBSD buildbot), because

[..]

Quoted 7 lines

Tested using the freebsd-11 box in openvpn-vagrant and did pkg install libressl-2.6.4 (that replaces openssl 1.1.0).

This particular error gets fixed by adding
!defined(LIBRESSL_VERSION_NUMBER) in two places.

I can send a patch for this.

This would be appreciated (please --cc me directly as the list is still not working properly).

Quoted 5 lines

But there are other errors:

In file included from crypto_openssl.c:44:
./openssl_compat.h:699:1: error: static declaration of 'SSL_CTX_set_min_proto_version' follows

[..]

Quoted 3 lines

./openssl_compat.h:728:1: error: static declaration of 'SSL_CTX_set_max_proto_version' follows
non-static declaration

Quoted 6 lines

[..]

Quoted 2 lines

In openssl those are macros but not in libressl so the current openssl_compat.h defs don't work.

This is interesting. Seems my OpenBSD version is too old, as I've not seen these errors in my buildbots.

This could be also because of using the vagrant box with freebsd-11. It came up with openssl 1.0 (not libressl) installed -- is that the default? And there were no build errors as external-ec-key gets disabled with openssl 1.0. On installing openssl 1.1.0g and rebuilding, again, no errors as expected.

The only libressl package that showed up with "pkg search" was 2.6.4 and installing that removed openssl 1.1.0g (which it shouldn't but that's a different topic). Then the missing EC_KEY_METHOD and conflicting signatures for SSL_CTX_set_max_proto_version etc showed up.

Anyway, I am sending a patch for disabling external-ec-key code when libressl is in use.

Selva

#31 lore raw

PATCH 3/3 Document management request >ECDSA_SIGN and response ecdsa-sig

In reply to [email protected]...

From: Selva Nair <[email protected]...>

---
 doc/management-notes.txt | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
doc/management-notes.txt +30 -0
index a9ba18a..e2e8249 100644
@@ -795,6 +795,36 @@ Base64 encoded output of RSA_private_encrypt() (OpenSSL) or mbedtls_pk_sign()
 This capability is intended to allow the use of arbitrary cryptographic
 service providers with OpenVPN via the management interface.
 
+COMMAND -- ecdsa-sig (OpenVPN 2.5 or higher)
+------------------------------------------
+Same as rsa-sig but for EC keys: requires openssl 1.1
+
+Provides support for external storage of the EC private key. Requires the
+--management-external-key option. This option can be used instead of "key"
+in client mode, and allows the client to run without the need to load the
+actual private key. When the SSL protocol needs to perform a sign
+operation, the data to be signed will be sent to the management interface
+via a notification as follows:
+
+>ECDSA_SIGN:[BASE64_DATA]
+
+The management interface client should then create a DER encoded signature of
+the (decoded) BASE64_DATA using the private key and return the SSL signature as
+follows:
+
+ecdsa-sig
+[BASE64_SIG_LINE]
+.
+.
+.
+END
+
+Base64 encoded output of ECDSA_sign() (OpenSSL) or mbedtls_pk_sign()
+(mbed TLS) will provide a correct signature.
+
+This capability is intended to allow the use of arbitrary cryptographic
+service providers with OpenVPN via the management interface.
+
 COMMAND -- certificate (OpenVPN 2.4 or higher)
 ----------------------------------------------
 Provides support for external storage of the certificate. Requires the
Signature · 1 line
2.1.4
Acked-by on v1 3/3
#32 lore raw

Re: [Openvpn-devel] [PATCH 3/3] Document management request >ECDSA_SIGN and response ecdsa-sig

Am 14.01.18 um 20:44 schrieb [email protected]...:

Quoted 32 lines

From: Selva Nair <[email protected]...>

---
 doc/management-notes.txt | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
doc/management-notes.txt +17 -0
index a9ba18a..e2e8249 100644
@@ -795,6 +795,36 @@ Base64 encoded output of RSA_private_encrypt() (OpenSSL) or mbedtls_pk_sign()
 This capability is intended to allow the use of arbitrary cryptographic
 service providers with OpenVPN via the management interface.
 
+COMMAND -- ecdsa-sig (OpenVPN 2.5 or higher)
+------------------------------------------
+Same as rsa-sig but for EC keys: requires openssl 1.1
+
+Provides support for external storage of the EC private key. Requires the
+--management-external-key option. This option can be used instead of "key"
+in client mode, and allows the client to run without the need to load the
+actual private key. When the SSL protocol needs to perform a sign
+operation, the data to be signed will be sent to the management interface
+via a notification as follows:
+
+>ECDSA_SIGN:[BASE64_DATA]
+
+The management interface client should then create a DER encoded signature of
+the (decoded) BASE64_DATA using the private key and return the SSL signature as
+follows:
+

doc/management-notes.txt Base64 encoded output of RSA_private_encrypt() (OpenSSL) or mbedtls_pk_sign() · line 824

Quoted 10 lines
doc/management-notes.txt +10 -0
+ecdsa-sig
+[BASE64_SIG_LINE]
+.
+.
+.
+END
+
+Base64 encoded output of ECDSA_sign() (OpenSSL) or mbedtls_pk_sign()
+(mbed TLS) will provide a correct signature.
+

Signature.getInstance("NONEwithECDSA") worked for me in Java for this. Any other signature algorithm did _NOT_ work e.g. SHA384withECDSA. I think ecdsa-sign might already provided a hash to sign.

On the other hand mbedtls documentation states:

For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0. For ECDSA md_alg may never be MBEDTLS_MD_NONE.

So this interface might not work with mbedtls.

Arne

Acked-by Arne Schwabe
#33 lore raw

PATCH v2 3/3 Document management request >PK_SIGN and response pk-sig

From: Selva Nair <[email protected]...>

v2: Commands renamed to >PK_SIGN and pk-sig

---
Well, the previous version has been acked, but obviously that patch is obsolete now.

 doc/management-notes.txt | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
doc/management-notes.txt +37 -0
index a9ba18a..064e335 100644
@@ -795,6 +795,43 @@ Base64 encoded output of RSA_private_encrypt() (OpenSSL) or mbedtls_pk_sign()
 This capability is intended to allow the use of arbitrary cryptographic
 service providers with OpenVPN via the management interface.
 
+COMMAND -- pk-sig (OpenVPN 2.5 or higher)
+------------------------------------------
+Provides support for external storage of the private key. Requires the
+--management-external-key option. This option can be used instead of "key"
+in client mode, and allows the client to run without the need to load the
+actual private key. When the SSL protocol needs to perform a sign
+operation, the data to be signed will be sent to the management interface
+via a notification as follows:
+
+>PK_SIGN:[BASE64_DATA]
+
+The management interface client should then create an appropriate signature of
+the (decoded) BASE64_DATA using the private key and return the SSL signature as
+follows:
+
+pk-sig
+[BASE64_SIG_LINE]
+.
+.
+.
+END
+
+RSA signatures (for RSA keys) and and ECDSA signatures (for EC keys) are
+supported. For EC keys openssl 1.1 or higher is required.
+
+Base64 encoded output of RSA_private_encrypt for RSA or ECDSA_sign() for EC
+using OpenSSL or mbedtls_pk_sign() using mbed TLS will provide a correct
+signature.
+
+This capability is intended to allow the use of arbitrary cryptographic service
+providers with OpenVPN via the management interface.
+
+Currently RSA signature is challenged for by '>RSA_SIGN', but eventually
+'>PK_SIGN' prompt will be used for all signature types. New management clients
+should be prepared to respond to '>PK_SIGN' with 'pk-sig' followed by the
+appropriate signature.
+
 COMMAND -- certificate (OpenVPN 2.4 or higher)
 ----------------------------------------------
 Provides support for external storage of the certificate. Requires the
Signature · 1 line
2.1.4

A message that is not in the archive (sent off-list or not yet received): [email protected]...

author
#35 lore raw

Re: [Openvpn-devel] [PATCH 3/3] Document management request >ECDSA_SIGN and response ecdsa-sig

Hi,

FWIW, some remarks on the hash and the signature below.

Quoted 39 lines · Arne Schwabe

Am 14.01.18 um 20:44 schrieb [email protected]...:

Quoted 38 lines

From: Selva Nair <[email protected]...>

---
 doc/management-notes.txt | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
doc/management-notes.txt +23 -0
index a9ba18a..e2e8249 100644
@@ -795,6 +795,36 @@ Base64 encoded output of RSA_private_encrypt() (OpenSSL) or mbedtls_pk_sign()
 This capability is intended to allow the use of arbitrary cryptographic
 service providers with OpenVPN via the management interface.
 
+COMMAND -- ecdsa-sig (OpenVPN 2.5 or higher)
+------------------------------------------
+Same as rsa-sig but for EC keys: requires openssl 1.1
+
+Provides support for external storage of the EC private key. Requires the
+--management-external-key option. This option can be used instead of "key"
+in client mode, and allows the client to run without the need to load the
+actual private key. When the SSL protocol needs to perform a sign
+operation, the data to be signed will be sent to the management interface
+via a notification as follows:
+
+>ECDSA_SIGN:[BASE64_DATA]
+
+The management interface client should then create a DER encoded signature of
+the (decoded) BASE64_DATA using the private key and return the SSL signature as
+follows:
+
+ecdsa-sig
+[BASE64_SIG_LINE]
+.
+.
+.
+END
Quoted 8 lines

doc/management-notes.txt Base64 encoded output of RSA_private_encrypt() (OpenSSL) or mbedtls_pk_sign() · line 824

Quoted 4 lines
doc/management-notes.txt +4 -0
+
+Base64 encoded output of ECDSA_sign() (OpenSSL) or mbedtls_pk_sign()
+(mbed TLS) will provide a correct signature.
+

Signature.getInstance("NONEwithECDSA") worked for me in Java for this. Any other signature algorithm did _NOT_ work e.g. SHA384withECDSA. I think ecdsa-sign might already provided a hash to sign.

Yes, the hash is what is provided in this signature request. In this particular case,
the data is handshake history and may not be even saved. Its the accumulated hash that is passed in by the SSL/TLS library to the callback.

So "NONEwithECDSA" should be the right choice for Java (Sun/Oracle) -- or ECDSAforSSL in case of IBM Java.

Quoted 5 lines

On the other hand mbedtls documentation states:

For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0. For ECDSA md_alg may never be MBEDTLS_MD_NONE.

External RSA keys currently work with both openssl and mbedtls.

To elaborate, for RSA, its more complicated as the hash to be encoded with the OID of the hash algo prepended to it as specified in PKCS1 v1.5, then padded and signed. Unless the pre TLS1.2 MD5+SHA1 mixed hash is in use. In the latter case only padding is needed and that's the case where mbedtls specifies hash type as none.

For RSA, openssl callback gets the encoded hash (not padded) and signing involves padding + encryption only (hash type is not needed). But mbedtls provides the hash and hash algorithm and the signing routine has to encode it. However, the pkcs1 v1.5 encoding part is already present in ssl_mbedtls.c (implemented by Stefan, I suppose) so what the management interface gets is the same data for both openssl and mbedtls builds as far as RSA is concerned.

Quoted 2 lines

So this interface might not work with mbedtls.

It should work if only we could find a way to set a callback for this in mbedtls.
It seems they provide that facility only for RSA keys. Stefan may know. Not sure how pkcs11-helper hooks on to it -- does it support EC keys?

Regards,

Selva

#36 lore raw

Re: [Openvpn-devel] [PATCH 3/3] Document management request >ECDSA_SIGN and response ecdsa-sig

Hi,

Quickly replying without proper reading, to not postpone my response.

Quoted 73 lines · Selva Nair

FWIW, some remarks on the hash and the signature below.

Quoted 39 lines · Arne Schwabe

Am 14.01.18 um 20:44 schrieb [email protected]...:

Quoted 38 lines

From: Selva Nair <[email protected]...>

---
 doc/management-notes.txt | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
doc/management-notes.txt +23 -0
index a9ba18a..e2e8249 100644
@@ -795,6 +795,36 @@ Base64 encoded output of RSA_private_encrypt() (OpenSSL) or mbedtls_pk_sign()
 This capability is intended to allow the use of arbitrary cryptographic
 service providers with OpenVPN via the management interface.
 
+COMMAND -- ecdsa-sig (OpenVPN 2.5 or higher)
+------------------------------------------
+Same as rsa-sig but for EC keys: requires openssl 1.1
+
+Provides support for external storage of the EC private key. Requires the
+--management-external-key option. This option can be used instead of "key"
+in client mode, and allows the client to run without the need to load the
+actual private key. When the SSL protocol needs to perform a sign
+operation, the data to be signed will be sent to the management interface
+via a notification as follows:
+
+>ECDSA_SIGN:[BASE64_DATA]
+
+The management interface client should then create a DER encoded signature of
+the (decoded) BASE64_DATA using the private key and return the SSL signature as
+follows:
+
+ecdsa-sig
+[BASE64_SIG_LINE]
+.
+.
+.
+END
Quoted 8 lines

doc/management-notes.txt Base64 encoded output of RSA_private_encrypt() (OpenSSL) or mbedtls_pk_sign() · line 824

Quoted 4 lines
doc/management-notes.txt +4 -0
+
+Base64 encoded output of ECDSA_sign() (OpenSSL) or mbedtls_pk_sign()
+(mbed TLS) will provide a correct signature.
+

Signature.getInstance("NONEwithECDSA") worked for me in Java for this. Any other signature algorithm did _NOT_ work e.g. SHA384withECDSA. I think ecdsa-sign might already provided a hash to sign.

Yes, the hash is what is provided in this signature request. In this particular case,
the data is handshake history and may not be even saved. Its the accumulated hash that is passed in by the SSL/TLS library to the callback.

So "NONEwithECDSA" should be the right choice for Java (Sun/Oracle) -- or ECDSAforSSL in case of IBM Java.

Quoted 5 lines

On the other hand mbedtls documentation states:

For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0. For ECDSA md_alg may never be MBEDTLS_MD_NONE.

External RSA keys currently work with both openssl and mbedtls.

To elaborate, for RSA, its more complicated as the hash to be encoded with the OID of the hash algo prepended to it as specified in PKCS1 v1.5, then padded and signed. Unless the pre TLS1.2 MD5+SHA1 mixed hash is in use. In the latter case only padding is needed and that's the case where mbedtls specifies hash type as none.

Quoted 6 lines

For RSA, openssl callback gets the encoded hash (not padded) and signing involves padding + encryption only (hash type is not needed). But mbedtls provides the hash and hash algorithm and the signing routine has to encode it. However, the pkcs1 v1.5 encoding part is already present in ssl_mbedtls.c (implemented by Stefan, I suppose) so what the management interface gets is the same data for both openssl and mbedtls builds as far as RSA is concerned.

This was written by a colleague of mine, but I sent patches to refactor this a little while ago:

https://patchwork.openvpn.net/project/openvpn2/list/?series=57

Those are still awaiting review and might be worth to check out in this context.

Quoted 6 lines
Quoted 1 line

So this interface might not work with mbedtls.

It should work if only we could find a way to set a callback for this in mbedtls.
It seems they provide that facility only for RSA keys. Stefan may know. Not sure how pkcs11-helper hooks on to it -- does it support EC keys?

Last time I checked there was only a way to externally sign using RSA (in mbed), but I haven't checked in a while. I'm fine with leaving mbed aside in this patch set for now, as long as it doesn't break it. I'll then later look into implementing the mbed equivalent.

-Steffan

author
#37 lore raw

Re: [Openvpn-devel] [PATCH 3/3] Document management request >ECDSA_SIGN and response ecdsa-sig

In reply to [email protected]...

Hi,

Quoted 7 lines · On Sun, Jan 14, 2018 at 2:44 PM, <[email protected]...> wrote:

From: Selva Nair <[email protected]...>

---
 doc/management-notes.txt | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

Documentation changes are now handled in the management client version patches and v3 of ecdsa-signature patch. So please ignore this one.

Selva