1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-12-26 01:59:53 +03:00

Openssl engine certificate authentication

TODO cert get, call finish engine, call init engine in another step, handle authentication, internatiolazion (help is needed)
This commit is contained in:
mcallist 2020-07-06 20:25:18 +02:00
parent f22b013dda
commit ff3910eb86
12 changed files with 192 additions and 17 deletions

View File

@ -1,6 +1,6 @@
// SoftEther VPN Source Code - Developer Edition Master Branch
// Cedar Communication Module
// © 2020 Nokia
// Cedar.h
// Header of Cedar.c
@ -376,6 +376,7 @@
#define CLIENT_AUTHTYPE_PLAIN_PASSWORD 2 // Plain password authentication
#define CLIENT_AUTHTYPE_CERT 3 // Certificate authentication
#define CLIENT_AUTHTYPE_SECURE 4 // Secure device authentication
#define CLIENT_AUTHTYPE_OPENSSLENGINE 5 // Openssl engine authentication

View File

@ -1,6 +1,6 @@
// SoftEther VPN Source Code - Developer Edition Master Branch
// Cedar Communication Module
// © 2020 Nokia
// Client.c
// Client Manager
@ -4402,6 +4402,17 @@ void InRpcClientAuth(CLIENT_AUTH *c, PACK *p)
PackGetStr(p, "SecurePublicCertName", c->SecurePublicCertName, sizeof(c->SecurePublicCertName));
PackGetStr(p, "SecurePrivateKeyName", c->SecurePrivateKeyName, sizeof(c->SecurePrivateKeyName));
break;
case CLIENT_AUTHTYPE_OPENSSLENGINE:
b = PackGetBuf(p, "ClientX");
if (b != NULL)
{
c->ClientX = BufToX(b, false);
FreeBuf(b);
}
PackGetStr(p, "OpensslEnginePrivateKeyName", c->OpensslEnginePrivateKeyName, sizeof(c->OpensslEnginePrivateKeyName));
PackGetStr(p, "OpensslEngineName", c->OpensslEngineName, sizeof(c->OpensslEngineName));
break;
}
}
void OutRpcClientAuth(PACK *p, CLIENT_AUTH *c)
@ -4448,6 +4459,17 @@ void OutRpcClientAuth(PACK *p, CLIENT_AUTH *c)
PackAddStr(p, "SecurePublicCertName", c->SecurePublicCertName);
PackAddStr(p, "SecurePrivateKeyName", c->SecurePrivateKeyName);
break;
case CLIENT_AUTHTYPE_OPENSSLENGINE:
b = XToBuf(c->ClientX, false);
if (b != NULL)
{
PackAddBuf(p, "ClientX", b);
FreeBuf(b);
}
PackAddStr(p, "OpensslEnginePrivateKeyName", c->OpensslEnginePrivateKeyName);
PackAddStr(p, "OpensslEngineName", c->OpensslEngineName);
break;
}
}
@ -6402,6 +6424,11 @@ bool CtConnect(CLIENT *c, RPC_CLIENT_CONNECT *connect)
// Register a procedure for secure device authentication
r->ClientAuth->SecureSignProc = CiSecureSignProc;
}
else if (r->ClientAuth->AuthType == CLIENT_AUTHTYPE_OPENSSLENGINE)
{
/* r->ClientAuth->ClientK = OpensslEngineToK("asdf"); */
r->ClientAuth->SecureSignProc = NULL;
}
else
{
r->ClientAuth->SecureSignProc = NULL;
@ -9266,6 +9293,20 @@ CLIENT_AUTH *CiLoadClientAuth(FOLDER *f)
CfgGetStr(f, "SecurePublicCertName", a->SecurePublicCertName, sizeof(a->SecurePublicCertName));
CfgGetStr(f, "SecurePrivateKeyName", a->SecurePrivateKeyName, sizeof(a->SecurePrivateKeyName));
break;
case CLIENT_AUTHTYPE_OPENSSLENGINE:
b = CfgGetBuf(f, "ClientCert");
if (b != NULL)
{
a->ClientX = BufToX(b, false);
}
FreeBuf(b);
if (CfgGetStr(f, "OpensslEnginePrivateKeyName", a->OpensslEnginePrivateKeyName, sizeof(a->OpensslEnginePrivateKeyName)))
{
a->ClientK = OpensslEngineToK(a->OpensslEnginePrivateKeyName, a->OpensslEngineName);
}
CfgGetStr(f, "OpensslEngineName", a->OpensslEngineName, sizeof(a->OpensslEngineName));
break;
}
return a;
@ -9810,6 +9851,16 @@ void CiWriteClientAuth(FOLDER *f, CLIENT_AUTH *a)
CfgAddStr(f, "SecurePublicCertName", a->SecurePublicCertName);
CfgAddStr(f, "SecurePrivateKeyName", a->SecurePrivateKeyName);
break;
case CLIENT_AUTHTYPE_OPENSSLENGINE:
if (a->ClientX != NULL) {
b = XToBuf(a->ClientX, false);
CfgAddByte(f, "ClientCert", b->Buf, b->Size);
FreeBuf(b);
}
CfgAddStr(f, "OpensslEnginePrivateKeyName", a->OpensslEnginePrivateKeyName);
CfgAddStr(f, "OpensslEngineName", a->OpensslEngineName);
break;
}
}

View File

@ -1,6 +1,6 @@
// SoftEther VPN Source Code - Developer Edition Master Branch
// Cedar Communication Module
// © 2020 Nokia
// Client.h
// Header of Client.c

View File

@ -1,6 +1,6 @@
// SoftEther VPN Source Code - Developer Edition Master Branch
// Cedar Communication Module
// © 2020 Nokia
// Command.c
// vpncmd Command Line Management Utility
@ -2948,6 +2948,7 @@ void PcMain(PC *pc)
{"AccountStatusShow", PcAccountStatusShow},
{"AccountStatusHide", PcAccountStatusHide},
{"AccountSecureCertSet", PcAccountSecureCertSet},
{"AccountOpensslEngineCertSet", PcAccountOpensslEngineCertSet},
{"AccountRetrySet", PcAccountRetrySet},
{"AccountStartupSet", PcAccountStartupSet},
{"AccountStartupRemove", PcAccountStartupRemove},
@ -6420,6 +6421,76 @@ UINT PcAccountSecureCertSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *para
return ret;
}
UINT PcAccountOpensslEngineCertSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{
LIST *o;
PC *pc = (PC *)param;
UINT ret = ERR_NO_ERROR;
RPC_CLIENT_GET_ACCOUNT t;
// Parameter list that can be specified
PARAM args[] =
{
{"[name]", CmdPrompt, _UU("CMD_AccountCreate_Prompt_Name"), CmdEvalNotEmpty, NULL},
{"LOADCERT", CmdPrompt, _UU("CMD_LOADCERTPATH"), CmdEvalIsFile, NULL},
{"KEYNAME", CmdPrompt, _UU("CMD_AccountSecureCertSet_PROMPT_KEYNAME"), CmdEvalNotEmpty, NULL},
{"ENGINENAME", CmdPrompt, _UU("Openssl engine name."), CmdEvalNotEmpty, NULL},
};
// Get the parameter list
o = ParseCommandList(c, cmd_name, str, args, sizeof(args) / sizeof(args[0]));
if (o == NULL)
{
return ERR_INVALID_PARAMETER;
}
// RPC call
Zero(&t, sizeof(t));
UniStrCpy(t.AccountName, sizeof(t.AccountName), GetParamUniStr(o, "[name]"));
ret = CcGetAccount(pc->RemoteClient, &t);
if (ret == ERR_NO_ERROR)
{
RPC_CLIENT_CREATE_ACCOUNT z;
t.ClientAuth->AuthType = CLIENT_AUTHTYPE_OPENSSLENGINE;
X *x;
x = FileToXW(GetParamUniStr(o, "LOADCERT"));
if (x == NULL)
{
c->Write(c, _UU("CMD_LOADCERT_FAILED"));
}
StrCpy(t.ClientAuth->OpensslEnginePrivateKeyName, sizeof(t.ClientAuth->OpensslEnginePrivateKeyName),
GetParamStr(o, "KEYNAME"));
StrCpy(t.ClientAuth->OpensslEngineName, sizeof(t.ClientAuth->OpensslEngineName),
GetParamStr(o, "ENGINENAME"));
t.ClientAuth->ClientX = CloneX(x);
Zero(&z, sizeof(z));
z.CheckServerCert = t.CheckServerCert;
z.RetryOnServerCert = t.RetryOnServerCert;
z.ClientAuth = t.ClientAuth;
z.ClientOption = t.ClientOption;
z.ServerCert = t.ServerCert;
z.StartupAccount = t.StartupAccount;
ret = CcSetAccount(pc->RemoteClient, &z);
}
if (ret != ERR_NO_ERROR)
{
// Error has occurred
CmdPrintError(c, ret);
}
CiFreeClientGetAccount(&t);
// Release of the parameter list
FreeParamValueList(o);
return ret;
}
// Set the retry interval and number of retries when disconnect or connection failure of connection settings
UINT PcAccountRetrySet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
{

View File

@ -1,6 +1,6 @@
// SoftEther VPN Source Code - Developer Edition Master Branch
// Cedar Communication Module
// © 2020 Nokia
// Command.h
// Header of Command.c
@ -368,6 +368,7 @@ UINT PcAccountNicSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountStatusShow(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountStatusHide(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountSecureCertSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountOpensslEngineCertSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountRetrySet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountStartupSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);
UINT PcAccountStartupRemove(CONSOLE *c, char *cmd_name, wchar_t *str, void *param);

View File

@ -1,6 +1,6 @@
// SoftEther VPN Source Code - Developer Edition Master Branch
// Cedar Communication Module
// © 2020 Nokia
// Connection.c
// Connection Manager
@ -539,6 +539,14 @@ CLIENT_AUTH *CopyClientAuth(CLIENT_AUTH *a)
StrCpy(ret->SecurePublicCertName, sizeof(ret->SecurePublicCertName), a->SecurePublicCertName);
StrCpy(ret->SecurePrivateKeyName, sizeof(ret->SecurePrivateKeyName), a->SecurePrivateKeyName);
break;
case CLIENT_AUTHTYPE_OPENSSLENGINE:
// Secure device authentication
ret->ClientX = CloneX(a->ClientX);
StrCpy(ret->OpensslEnginePrivateKeyName, sizeof(ret->OpensslEnginePrivateKeyName), a->OpensslEnginePrivateKeyName);
StrCpy(ret->OpensslEngineName, sizeof(ret->OpensslEngineName), a->OpensslEngineName);
ret->ClientK = OpensslEngineToK(ret->OpensslEnginePrivateKeyName, ret->OpensslEngineName);
break;
}
return ret;

View File

@ -1,6 +1,6 @@
// SoftEther VPN Source Code - Developer Edition Master Branch
// Cedar Communication Module
// © 2020 Nokia
// Connection.h
// Header of Connection.c
@ -99,6 +99,8 @@ struct CLIENT_AUTH
K *ClientK; // Client private key
char SecurePublicCertName[MAX_SECURE_DEVICE_FILE_LEN + 1]; // Secure device certificate name
char SecurePrivateKeyName[MAX_SECURE_DEVICE_FILE_LEN + 1]; // Secure device secret key name
char OpensslEnginePrivateKeyName[MAX_SECURE_DEVICE_FILE_LEN + 1]; // Secure device secret key name
char OpensslEngineName[MAX_SECURE_DEVICE_FILE_LEN + 1]; // Secure device secret key name
CHECK_CERT_PROC *CheckCertProc; // Server certificate confirmation procedure
SECURE_SIGN_PROC *SecureSignProc; // Security signing procedure
};

View File

@ -1,6 +1,6 @@
// SoftEther VPN Source Code - Developer Edition Master Branch
// Cedar Communication Module
// © 2020 Nokia
// Link.c
// Inter-HUB Link
@ -622,7 +622,7 @@ LINK *NewLink(CEDAR *cedar, HUB *hub, CLIENT_OPTION *option, CLIENT_AUTH *auth,
// Limitation of authentication method
if (auth->AuthType != CLIENT_AUTHTYPE_ANONYMOUS && auth->AuthType != CLIENT_AUTHTYPE_PASSWORD &&
auth->AuthType != CLIENT_AUTHTYPE_PLAIN_PASSWORD && auth->AuthType != CLIENT_AUTHTYPE_CERT)
auth->AuthType != CLIENT_AUTHTYPE_PLAIN_PASSWORD && auth->AuthType != CLIENT_AUTHTYPE_CERT && auth->AuthType != CLIENT_AUTHTYPE_OPENSSLENGINE)
{
// Authentication method other than anonymous authentication, password authentication, plain password, certificate authentication cannot be used
return NULL;

View File

@ -1,6 +1,6 @@
// SoftEther VPN Source Code - Developer Edition Master Branch
// Cedar Communication Module
// © 2020 Nokia
// Protocol.c
// SoftEther protocol related routines
@ -5511,6 +5511,20 @@ bool ClientUploadAuth(CONNECTION *c)
}
break;
case CLIENT_AUTHTYPE_OPENSSLENGINE:
// Certificate authentication
if (a->ClientX != NULL && a->ClientX->is_compatible_bit &&
a->ClientX->bits != 0 && (a->ClientX->bits / 8) <= sizeof(sign))
{
if (RsaSignEx(sign, c->Random, SHA1_SIZE, a->ClientK, a->ClientX->bits))
{
p = PackLoginWithCert(o->HubName, a->Username, a->ClientX, sign, a->ClientX->bits / 8);
c->ClientX = CloneX(a->ClientX);
}
}
break;
case CLIENT_AUTHTYPE_SECURE:
// Authentication by secure device
if (ClientSecureSign(c, sign, c->Random, &x))

View File

@ -1,6 +1,6 @@
// SoftEther VPN Source Code - Developer Edition Master Branch
// Cedar Communication Module
// © 2020 Nokia
// Session.c
// Session Manager
@ -1918,10 +1918,17 @@ SESSION *NewClientSessionEx(CEDAR *cedar, CLIENT_OPTION *option, CLIENT_AUTH *au
{
s->ClientAuth->ClientX = CloneX(s->ClientAuth->ClientX);
}
if (s->ClientAuth->ClientK != NULL)
{
s->ClientAuth->ClientK = CloneK(s->ClientAuth->ClientK);
}
if (s->ClientAuth->ClientK != NULL)
{
if (s->ClientAuth->AuthType != CLIENT_AUTHTYPE_OPENSSLENGINE)
{
s->ClientAuth->ClientK = CloneK(s->ClientAuth->ClientK);
}
else
{
s->ClientAuth->ClientK = OpensslEngineToK(s->ClientAuth->OpensslEnginePrivateKeyName, s->ClientAuth->OpensslEngineName);
}
}
if (StrCmpi(s->ClientOption->DeviceName, LINK_DEVICE_NAME) == 0)
{

View File

@ -1,6 +1,6 @@
// SoftEther VPN Source Code - Developer Edition Master Branch
// Mayaqua Kernel
// © 2020 Nokia
// Encrypt.c
// Encryption and digital certification routine
@ -46,6 +46,7 @@
#include <intrin.h> // For __cpuid()
#else // _MSC_VER
#ifndef SKIP_CPU_FEATURES
#include "cpu_features_macros.h"
#endif
@ -3111,6 +3112,24 @@ bool IsEncryptedK(BUF *b, bool private_key)
return true;
}
K *OpensslEngineToK(char *key_file_name, char *engine_name)
{
#ifdef UNIX_LINUX
K *k;
ENGINE_load_dynamic();
ENGINE *engine = ENGINE_by_id("tpm2tss");
ENGINE_init(engine);
EVP_PKEY *pkey;
pkey = ENGINE_load_private_key(engine, key_file_name, NULL, NULL);
k = ZeroMalloc(sizeof(K));
k->pkey = pkey;
k->private_key = true;
return k;
#else
return NULL;
#endif // UNIX_LINUX
}
// Convert the BUF to a K
K *BufToK(BUF *b, bool private_key, bool text, char *password)
{

View File

@ -1,6 +1,6 @@
// SoftEther VPN Source Code - Developer Edition Master Branch
// Mayaqua Kernel
// © 2020 Nokia
// Encrypt.h
// Header of Encrypt.c
@ -300,6 +300,7 @@ K *BioToK(BIO *bio, bool private_key, bool text, char *password);
int PKeyPasswordCallbackFunction(char *buf, int bufsize, int verify, void *param);
void FreePKey(EVP_PKEY *pkey);
void FreeK(K *k);
K *OpensslEngineToK(char *key_file_name, char *engine_name);
K *BufToK(BUF *b, bool private_key, bool text, char *password);
bool IsEncryptedK(BUF *b, bool private_key);
bool IsBase64(BUF *b);