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:
parent
f22b013dda
commit
ff3910eb86
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SoftEther VPN Source Code - Developer Edition Master Branch
|
||||
// Cedar Communication Module
|
||||
|
||||
// © 2020 Nokia
|
||||
|
||||
// Client.h
|
||||
// Header of Client.c
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user