Browse code

Prompt for signature using '>PK_SIGN' if the client supports it

- Increase the management version from 1 to 2
- If the client announces support for management version > 1
prompt for signature using >PK_SIGN to which the client
responds using 'pk-sig'
Older (current) clients will be continued to be prompted
by '>RSA_SIGN' and can respond using 'rsa-sig'
- Remove an unused rsa_sig buffer-list variable

This facilitates a transparent transition to PK_SIG and future deprecation
of RSA_SIGN

Signed-off-by: Selva Nair <selva.nair@gmail.com>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <1516909261-31623-2-git-send-email-selva.nair@gmail.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg16364.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Selva Nair authored on 2018/01/26 04:41:01
Showing 5 changed files
... ...
@@ -773,8 +773,9 @@ To accept connecting to the host and port directly, use this command:
773 773
 
774 774
   proxy NONE
775 775
 
776
-COMMAND -- rsa-sig (OpenVPN 2.3 or higher)
776
+COMMAND -- pk-sig (OpenVPN 2.5 or higher, management version > 1)
777
+COMMAND -- rsa-sig (OpenVPN 2.3 or higher, management version <= 1)
778
+-----------------------------------------------------------------
777 779
 Provides support for external storage of the private key. Requires the
778 780
 --management-external-key option. This option can be used instead of "key"
779 781
 in client mode, and allows the client to run without the need to load the
... ...
@@ -782,13 +783,14 @@ actual private key. When the SSL protocol needs to perform an RSA sign
782 782
 operation, the data to be signed will be sent to the management interface
783 783
 via a notification as follows:
784 784
 
785
->RSA_SIGN:[BASE64_DATA]
785
+>PK_SIGN:[BASE64_DATA] (if client announces support for management version > 1)
786
+>RSA_SIGN:[BASE64_DATA] (only older clients will be prompted like this)
786 787
 
787 788
 The management interface client should then create a PKCS#1 v1.5 signature of
788 789
 the (decoded) BASE64_DATA using the private key and return the SSL signature as
789 790
 follows:
790 791
 
791
-rsa-sig
792
+pk-sig   (or rsa-sig)
792 793
 [BASE64_SIG_LINE]
793 794
 .
794 795
 .
... ...
@@ -801,6 +803,9 @@ Base64 encoded output of RSA_private_encrypt() (OpenSSL) or mbedtls_pk_sign()
801 801
 This capability is intended to allow the use of arbitrary cryptographic
802 802
 service providers with OpenVPN via the management interface.
803 803
 
804
+New and updated clients are expected to use the version command to announce
805
+a version > 1 and handle '>PK_SIGN' prompt and respond with 'pk-sig'.
806
+
804 807
 COMMAND -- certificate (OpenVPN 2.4 or higher)
805 808
 ----------------------------------------------
806 809
 Provides support for external storage of the certificate. Requires the
... ...
@@ -111,7 +111,9 @@ man_help(void)
111 111
 #endif
112 112
 #endif
113 113
 #ifdef MANAGMENT_EXTERNAL_KEY
114
-    msg(M_CLIENT, "rsa-sig                : Enter an RSA signature in response to >RSA_SIGN challenge");
114
+    msg(M_CLIENT, "rsa-sig                : Enter a signature in response to >RSA_SIGN challenge");
115
+    msg(M_CLIENT, "                         Enter signature base64 on subsequent lines followed by END");
116
+    msg(M_CLIENT, "pk-sig                 : Enter a signature in response to >PK_SIGN challenge");
115 117
     msg(M_CLIENT, "                         Enter signature base64 on subsequent lines followed by END");
116 118
     msg(M_CLIENT, "certificate            : Enter a client certificate in response to >NEED-CERT challenge");
117 119
     msg(M_CLIENT, "                         Enter certificate base64 on subsequent lines followed by END");
... ...
@@ -935,7 +937,7 @@ in_extra_dispatch(struct management *man)
935 935
 
936 936
 #endif /* ifdef MANAGEMENT_PF */
937 937
 #ifdef MANAGMENT_EXTERNAL_KEY
938
-        case IEC_RSA_SIGN:
938
+        case IEC_PK_SIGN:
939 939
             man->connection.ext_key_state = EKS_READY;
940 940
             buffer_list_free(man->connection.ext_key_input);
941 941
             man->connection.ext_key_input = man->connection.in_extra;
... ...
@@ -1103,18 +1105,18 @@ man_client_pf(struct management *man, const char *cid_str)
1103 1103
 #ifdef MANAGMENT_EXTERNAL_KEY
1104 1104
 
1105 1105
 static void
1106
-man_rsa_sig(struct management *man)
1106
+man_pk_sig(struct management *man, const char *cmd_name)
1107 1107
 {
1108 1108
     struct man_connection *mc = &man->connection;
1109 1109
     if (mc->ext_key_state == EKS_SOLICIT)
1110 1110
     {
1111 1111
         mc->ext_key_state = EKS_INPUT;
1112
-        mc->in_extra_cmd = IEC_RSA_SIGN;
1112
+        mc->in_extra_cmd = IEC_PK_SIGN;
1113 1113
         in_extra_reset(mc, IER_NEW);
1114 1114
     }
1115 1115
     else
1116 1116
     {
1117
-        msg(M_CLIENT, "ERROR: The rsa-sig command is not currently available");
1117
+        msg(M_CLIENT, "ERROR: The %s command is not currently available", cmd_name);
1118 1118
     }
1119 1119
 }
1120 1120
 
... ...
@@ -1527,7 +1529,11 @@ man_dispatch_command(struct management *man, struct status_output *so, const cha
1527 1527
 #ifdef MANAGMENT_EXTERNAL_KEY
1528 1528
     else if (streq(p[0], "rsa-sig"))
1529 1529
     {
1530
-        man_rsa_sig(man);
1530
+        man_pk_sig(man, "rsa-sig");
1531
+    }
1532
+    else if (streq(p[0], "pk-sig"))
1533
+    {
1534
+        man_pk_sig(man, "pk-sig");
1531 1535
     }
1532 1536
     else if (streq(p[0], "certificate"))
1533 1537
     {
... ...
@@ -3663,14 +3669,20 @@ management_query_multiline_flatten(struct management *man,
3663 3663
 
3664 3664
 char *
3665 3665
 /* returns allocated base64 signature */
3666
-management_query_rsa_sig(struct management *man,
3666
+management_query_pk_sig(struct management *man,
3667 3667
                          const char *b64_data)
3668 3668
 {
3669
-    return management_query_multiline_flatten(man, b64_data, "RSA_SIGN", "rsa-sign",
3670
-                                              &man->connection.ext_key_state, &man->connection.ext_key_input);
3669
+    const char *prompt = "PK_SIGN";
3670
+    const char *desc = "pk-sign";
3671
+    if (man->connection.client_version <= 1)
3672
+    {
3673
+        prompt = "RSA_SIGN";
3674
+        desc = "rsa-sign";
3675
+    }
3676
+    return management_query_multiline_flatten(man, b64_data, prompt, desc,
3677
+            &man->connection.ext_key_state, &man->connection.ext_key_input);
3671 3678
 }
3672 3679
 
3673
-
3674 3680
 char *
3675 3681
 management_query_cert(struct management *man, const char *cert_name)
3676 3682
 {
... ...
@@ -31,7 +31,7 @@
31 31
 #include "socket.h"
32 32
 #include "mroute.h"
33 33
 
34
-#define MANAGEMENT_VERSION                      1
34
+#define MANAGEMENT_VERSION                      2
35 35
 #define MANAGEMENT_N_PASSWORD_RETRIES           3
36 36
 #define MANAGEMENT_LOG_HISTORY_INITIAL_SIZE   100
37 37
 #define MANAGEMENT_ECHO_BUFFER_SIZE           100
... ...
@@ -281,6 +281,7 @@ struct man_connection {
281 281
 #define IEC_CLIENT_PF   2
282 282
 #define IEC_RSA_SIGN    3
283 283
 #define IEC_CERTIFICATE 4
284
+#define IEC_PK_SIGN     5
284 285
     int in_extra_cmd;
285 286
     struct buffer_list *in_extra;
286 287
 #ifdef MANAGEMENT_DEF_AUTH
... ...
@@ -311,9 +312,6 @@ struct man_connection {
311 311
     int up_query_mode;
312 312
     struct user_pass up_query;
313 313
 
314
-#ifdef MANAGMENT_EXTERNAL_KEY
315
-    struct buffer_list *rsa_sig;
316
-#endif
317 314
 #ifdef TARGET_ANDROID
318 315
     int fdtosend;
319 316
     int lastfdreceived;
... ...
@@ -440,7 +438,7 @@ void management_learn_addr(struct management *management,
440 440
 
441 441
 #ifdef MANAGMENT_EXTERNAL_KEY
442 442
 
443
-char *management_query_rsa_sig(struct management *man, const char *b64_data);
443
+char *management_query_pk_sig(struct management *man, const char *b64_data);
444 444
 
445 445
 char *management_query_cert(struct management *man, const char *cert_name);
446 446
 
... ...
@@ -583,7 +583,7 @@ external_pkcs1_sign( void *ctx_voidptr,
583 583
     /* call MI for signature */
584 584
     if (management)
585 585
     {
586
-        out_b64 = management_query_rsa_sig(management, in_b64);
586
+        out_b64 = management_query_pk_sig(management, in_b64);
587 587
     }
588 588
     if (!out_b64)
589 589
     {
... ...
@@ -1068,7 +1068,7 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i
1068 1068
     /* call MI for signature */
1069 1069
     if (management)
1070 1070
     {
1071
-        out_b64 = management_query_rsa_sig(management, in_b64);
1071
+        out_b64 = management_query_pk_sig(management, in_b64);
1072 1072
     }
1073 1073
     if (!out_b64)
1074 1074
     {