Skip to content

Commit

Permalink
Prompt for signature using '>PK_SIGN' if the client supports it
Browse files Browse the repository at this point in the history
- 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 <[email protected]>
Acked-by: Arne Schwabe <[email protected]>
Message-Id: <[email protected]>
URL: https://www.mail-archive.com/[email protected]/msg16364.html
Signed-off-by: Gert Doering <[email protected]>
  • Loading branch information
selvanair authored and cron2 committed Jan 29, 2018
1 parent 686fe9c commit e7995f3
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 21 deletions.
13 changes: 9 additions & 4 deletions doc/management-notes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -773,22 +773,24 @@ To accept connecting to the host and port directly, use this command:

proxy NONE

COMMAND -- rsa-sig (OpenVPN 2.3 or higher)
------------------------------------------
COMMAND -- pk-sig (OpenVPN 2.5 or higher, management version > 1)
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
operation, the data to be signed will be sent to the management interface
via a notification as follows:

>RSA_SIGN:[BASE64_DATA]
>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 (decoded) BASE64_DATA using the private key and return the SSL signature as
follows:

rsa-sig
pk-sig (or rsa-sig)
[BASE64_SIG_LINE]
.
.
Expand All @@ -801,6 +803,9 @@ 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.

New and updated clients are expected to use the version command to announce
a version > 1 and handle '>PK_SIGN' prompt and respond with 'pk-sig'.

COMMAND -- certificate (OpenVPN 2.4 or higher)
----------------------------------------------
Provides support for external storage of the certificate. Requires the
Expand Down
32 changes: 22 additions & 10 deletions src/openvpn/manage.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ man_help(void)
#endif
#endif
#ifdef MANAGMENT_EXTERNAL_KEY
msg(M_CLIENT, "rsa-sig : Enter an RSA signature in response to >RSA_SIGN challenge");
msg(M_CLIENT, "rsa-sig : Enter a 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 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");
Expand Down Expand Up @@ -935,7 +937,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;
Expand Down Expand Up @@ -1103,18 +1105,18 @@ man_client_pf(struct management *man, const char *cid_str)
#ifdef MANAGMENT_EXTERNAL_KEY

static void
man_rsa_sig(struct management *man)
man_pk_sig(struct management *man, const char *cmd_name)
{
struct man_connection *mc = &man->connection;
if (mc->ext_key_state == EKS_SOLICIT)
{
mc->ext_key_state = EKS_INPUT;
mc->in_extra_cmd = IEC_RSA_SIGN;
mc->in_extra_cmd = IEC_PK_SIGN;
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);
}
}

Expand Down Expand Up @@ -1527,7 +1529,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_pk_sig(man, "rsa-sig");
}
else if (streq(p[0], "pk-sig"))
{
man_pk_sig(man, "pk-sig");
}
else if (streq(p[0], "certificate"))
{
Expand Down Expand Up @@ -3663,14 +3669,20 @@ management_query_multiline_flatten(struct management *man,

char *
/* returns allocated base64 signature */
management_query_rsa_sig(struct management *man,
management_query_pk_sig(struct management *man,
const char *b64_data)
{
return management_query_multiline_flatten(man, b64_data, "RSA_SIGN", "rsa-sign",
&man->connection.ext_key_state, &man->connection.ext_key_input);
const char *prompt = "PK_SIGN";
const char *desc = "pk-sign";
if (man->connection.client_version <= 1)
{
prompt = "RSA_SIGN";
desc = "rsa-sign";
}
return management_query_multiline_flatten(man, b64_data, prompt, desc,
&man->connection.ext_key_state, &man->connection.ext_key_input);
}


char *
management_query_cert(struct management *man, const char *cert_name)
{
Expand Down
8 changes: 3 additions & 5 deletions src/openvpn/manage.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#include "socket.h"
#include "mroute.h"

#define MANAGEMENT_VERSION 1
#define MANAGEMENT_VERSION 2
#define MANAGEMENT_N_PASSWORD_RETRIES 3
#define MANAGEMENT_LOG_HISTORY_INITIAL_SIZE 100
#define MANAGEMENT_ECHO_BUFFER_SIZE 100
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -311,9 +312,6 @@ struct man_connection {
int up_query_mode;
struct user_pass up_query;

#ifdef MANAGMENT_EXTERNAL_KEY
struct buffer_list *rsa_sig;
#endif
#ifdef TARGET_ANDROID
int fdtosend;
int lastfdreceived;
Expand Down Expand Up @@ -440,7 +438,7 @@ void management_learn_addr(struct management *management,

#ifdef MANAGMENT_EXTERNAL_KEY

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);

Expand Down
2 changes: 1 addition & 1 deletion src/openvpn/ssl_mbedtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ external_pkcs1_sign( void *ctx_voidptr,
/* call MI for signature */
if (management)
{
out_b64 = management_query_rsa_sig(management, in_b64);
out_b64 = management_query_pk_sig(management, in_b64);
}
if (!out_b64)
{
Expand Down
2 changes: 1 addition & 1 deletion src/openvpn/ssl_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i
/* call MI for signature */
if (management)
{
out_b64 = management_query_rsa_sig(management, in_b64);
out_b64 = management_query_pk_sig(management, in_b64);
}
if (!out_b64)
{
Expand Down

0 comments on commit e7995f3

Please sign in to comment.