mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-23 01:49:53 +03:00
Support user-specified server trust chain
This commit is contained in:
parent
1f40de2dda
commit
2761c1ca42
@ -9465,7 +9465,7 @@ UINT StSetServerCert(ADMIN *a, RPC_KEY_PAIR *t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCedarCert(c, t->Cert, t->Key);
|
SetCedarCertAndChain(c, t->Cert, t->Key, t->Chain);
|
||||||
|
|
||||||
ALog(a, NULL, "LA_SET_SERVER_CERT");
|
ALog(a, NULL, "LA_SET_SERVER_CERT");
|
||||||
|
|
||||||
@ -14565,6 +14565,7 @@ void InRpcKeyPair(RPC_KEY_PAIR *t, PACK *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
t->Cert = PackGetX(p, "Cert");
|
t->Cert = PackGetX(p, "Cert");
|
||||||
|
t->Chain = PackGetXList(p, "Chain");
|
||||||
t->Key = PackGetK(p, "Key");
|
t->Key = PackGetK(p, "Key");
|
||||||
t->Flag1 = PackGetInt(p, "Flag1");
|
t->Flag1 = PackGetInt(p, "Flag1");
|
||||||
}
|
}
|
||||||
@ -14577,12 +14578,14 @@ void OutRpcKeyPair(PACK *p, RPC_KEY_PAIR *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PackAddX(p, "Cert", t->Cert);
|
PackAddX(p, "Cert", t->Cert);
|
||||||
|
PackAddXList(p, "Chain", t->Chain);
|
||||||
PackAddK(p, "Key", t->Key);
|
PackAddK(p, "Key", t->Key);
|
||||||
PackAddInt(p, "Flag1", t->Flag1);
|
PackAddInt(p, "Flag1", t->Flag1);
|
||||||
}
|
}
|
||||||
void FreeRpcKeyPair(RPC_KEY_PAIR *t)
|
void FreeRpcKeyPair(RPC_KEY_PAIR *t)
|
||||||
{
|
{
|
||||||
FreeX(t->Cert);
|
FreeX(t->Cert);
|
||||||
|
FreeXList(t->Chain);
|
||||||
FreeK(t->Key);
|
FreeK(t->Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,6 +230,7 @@ struct RPC_FARM_CONNECTION_STATUS
|
|||||||
struct RPC_KEY_PAIR
|
struct RPC_KEY_PAIR
|
||||||
{
|
{
|
||||||
X *Cert; // Certificate
|
X *Cert; // Certificate
|
||||||
|
LIST *Chain; // Trust chain
|
||||||
K *Key; // Secret key
|
K *Key; // Secret key
|
||||||
UINT Flag1; // Flag1
|
UINT Flag1; // Flag1
|
||||||
};
|
};
|
||||||
|
@ -8463,6 +8463,11 @@ bool CmLoadKExW(HWND hWnd, K **k, wchar_t *filename, UINT size)
|
|||||||
|
|
||||||
// Read a set of certificate and private key
|
// Read a set of certificate and private key
|
||||||
bool CmLoadXAndK(HWND hWnd, X **x, K **k)
|
bool CmLoadXAndK(HWND hWnd, X **x, K **k)
|
||||||
|
{
|
||||||
|
return CmLoadXListAndK(hWnd, x, k, NULL);
|
||||||
|
}
|
||||||
|
// Read a set of certificate and private key and trust chain
|
||||||
|
bool CmLoadXListAndK(HWND hWnd, X **x, K **k, LIST **cc)
|
||||||
{
|
{
|
||||||
wchar_t *s;
|
wchar_t *s;
|
||||||
bool is_p12;
|
bool is_p12;
|
||||||
@ -8510,7 +8515,7 @@ START_FIRST:
|
|||||||
}
|
}
|
||||||
if (IsEncryptedP12(p12) == false)
|
if (IsEncryptedP12(p12) == false)
|
||||||
{
|
{
|
||||||
if (ParseP12(p12, x, k, NULL) == false)
|
if (ParseP12Ex(p12, x, k, cc, NULL) == false)
|
||||||
{
|
{
|
||||||
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
|
||||||
FreeP12(p12);
|
FreeP12(p12);
|
||||||
@ -8529,7 +8534,7 @@ START_FIRST:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ParseP12(p12, x, k, password) == false)
|
if (ParseP12Ex(p12, x, k, cc, password) == false)
|
||||||
{
|
{
|
||||||
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_P12_W"), tmp);
|
||||||
FreeP12(p12);
|
FreeP12(p12);
|
||||||
@ -8542,6 +8547,10 @@ START_FIRST:
|
|||||||
{
|
{
|
||||||
FreeX(*x);
|
FreeX(*x);
|
||||||
FreeK(*k);
|
FreeK(*k);
|
||||||
|
if (cc != NULL)
|
||||||
|
{
|
||||||
|
FreeXList(*cc);
|
||||||
|
}
|
||||||
FreeP12(p12);
|
FreeP12(p12);
|
||||||
FreeBuf(b);
|
FreeBuf(b);
|
||||||
if (MsgBox(hWnd, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("DLG_BAD_SIGNATURE")) == IDRETRY)
|
if (MsgBox(hWnd, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("DLG_BAD_SIGNATURE")) == IDRETRY)
|
||||||
@ -8550,6 +8559,11 @@ START_FIRST:
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (cc != NULL && LIST_NUM(*cc) == 0)
|
||||||
|
{
|
||||||
|
ReleaseList(*cc);
|
||||||
|
*cc = NULL;
|
||||||
|
}
|
||||||
FreeP12(p12);
|
FreeP12(p12);
|
||||||
FreeBuf(b);
|
FreeBuf(b);
|
||||||
return true;
|
return true;
|
||||||
@ -8558,19 +8572,40 @@ START_FIRST:
|
|||||||
{
|
{
|
||||||
// Processing of X509
|
// Processing of X509
|
||||||
BUF *b = ReadDumpW(tmp);
|
BUF *b = ReadDumpW(tmp);
|
||||||
X *x509;
|
X *x509 = NULL;
|
||||||
K *key;
|
K *key;
|
||||||
|
LIST *chain = NULL;
|
||||||
if (b == NULL)
|
if (b == NULL)
|
||||||
{
|
{
|
||||||
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
x509 = BufToX(b, IsBase64(b));
|
// DER-encoded X509 files can't hold multiple certificates
|
||||||
|
if (cc == NULL || IsBase64(b) == false)
|
||||||
|
{
|
||||||
|
x509 = BufToX(b, IsBase64(b));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chain = BufToXList(b, true);
|
||||||
|
if (LIST_NUM(chain) > 0)
|
||||||
|
{
|
||||||
|
x509 = LIST_DATA(chain, 0);
|
||||||
|
Delete(chain, x509);
|
||||||
|
|
||||||
|
if (LIST_NUM(chain) == 0)
|
||||||
|
{
|
||||||
|
ReleaseList(chain);
|
||||||
|
chain = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
FreeBuf(b);
|
FreeBuf(b);
|
||||||
if (x509 == NULL)
|
if (x509 == NULL)
|
||||||
{
|
{
|
||||||
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_X509_W"), tmp);
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_X509_W"), tmp);
|
||||||
|
FreeXList(chain);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8579,6 +8614,7 @@ START_FIRST:
|
|||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
{
|
{
|
||||||
FreeX(x509);
|
FreeX(x509);
|
||||||
|
FreeXList(chain);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
UniStrCpy(tmp, sizeof(tmp), s);
|
UniStrCpy(tmp, sizeof(tmp), s);
|
||||||
@ -8589,6 +8625,7 @@ START_FIRST:
|
|||||||
{
|
{
|
||||||
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_OPEN_FILE_ERROR_W"), tmp);
|
||||||
FreeX(x509);
|
FreeX(x509);
|
||||||
|
FreeXList(chain);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8603,6 +8640,7 @@ START_FIRST:
|
|||||||
{
|
{
|
||||||
FreeBuf(b);
|
FreeBuf(b);
|
||||||
FreeX(x509);
|
FreeX(x509);
|
||||||
|
FreeXList(chain);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
key = BufToK(b, true, IsBase64(b), pass);
|
key = BufToK(b, true, IsBase64(b), pass);
|
||||||
@ -8612,6 +8650,7 @@ START_FIRST:
|
|||||||
{
|
{
|
||||||
FreeBuf(b);
|
FreeBuf(b);
|
||||||
FreeX(x509);
|
FreeX(x509);
|
||||||
|
FreeXList(chain);
|
||||||
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_KEY_W"), tmp);
|
MsgBoxEx(hWnd, MB_ICONSTOP, _UU("DLG_BAD_KEY_W"), tmp);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -8621,6 +8660,7 @@ START_FIRST:
|
|||||||
FreeBuf(b);
|
FreeBuf(b);
|
||||||
FreeX(x509);
|
FreeX(x509);
|
||||||
FreeK(key);
|
FreeK(key);
|
||||||
|
FreeXList(chain);
|
||||||
if (MsgBox(hWnd, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("DLG_BAD_SIGNATURE")) == IDRETRY)
|
if (MsgBox(hWnd, MB_ICONEXCLAMATION | MB_RETRYCANCEL, _UU("DLG_BAD_SIGNATURE")) == IDRETRY)
|
||||||
{
|
{
|
||||||
goto START_FIRST;
|
goto START_FIRST;
|
||||||
@ -8631,6 +8671,10 @@ START_FIRST:
|
|||||||
FreeBuf(b);
|
FreeBuf(b);
|
||||||
*x = x509;
|
*x = x509;
|
||||||
*k = key;
|
*k = key;
|
||||||
|
if (cc != NULL)
|
||||||
|
{
|
||||||
|
*cc = chain;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -409,6 +409,7 @@ void CmEditAccountDlgInit(HWND hWnd, CM_ACCOUNT *a);
|
|||||||
void CmEditAccountDlgOnOk(HWND hWnd, CM_ACCOUNT *a);
|
void CmEditAccountDlgOnOk(HWND hWnd, CM_ACCOUNT *a);
|
||||||
void CmEditAccountDlgStartEnumHub(HWND hWnd, CM_ACCOUNT *a);
|
void CmEditAccountDlgStartEnumHub(HWND hWnd, CM_ACCOUNT *a);
|
||||||
bool CmLoadXAndK(HWND hWnd, X **x, K **k);
|
bool CmLoadXAndK(HWND hWnd, X **x, K **k);
|
||||||
|
bool CmLoadXListAndK(HWND hWnd, X **x, K **k, LIST **cc);
|
||||||
bool CmLoadKEx(HWND hWnd, K **k, char *filename, UINT size);
|
bool CmLoadKEx(HWND hWnd, K **k, char *filename, UINT size);
|
||||||
bool CmLoadKExW(HWND hWnd, K **k, wchar_t *filename, UINT size);
|
bool CmLoadKExW(HWND hWnd, K **k, wchar_t *filename, UINT size);
|
||||||
bool CmLoadXFromFileOrSecureCard(HWND hWnd, X **x);
|
bool CmLoadXFromFileOrSecureCard(HWND hWnd, X **x);
|
||||||
|
@ -1157,6 +1157,10 @@ void CleanupCedar(CEDAR *c)
|
|||||||
{
|
{
|
||||||
FreeK(c->ServerK);
|
FreeK(c->ServerK);
|
||||||
}
|
}
|
||||||
|
if (c->ServerChain)
|
||||||
|
{
|
||||||
|
FreeXList(c->ServerChain);
|
||||||
|
}
|
||||||
|
|
||||||
if (c->CipherList)
|
if (c->CipherList)
|
||||||
{
|
{
|
||||||
@ -1386,6 +1390,10 @@ void FreeNetSvcList(CEDAR *cedar)
|
|||||||
|
|
||||||
// Change certificate of Cedar
|
// Change certificate of Cedar
|
||||||
void SetCedarCert(CEDAR *c, X *server_x, K *server_k)
|
void SetCedarCert(CEDAR *c, X *server_x, K *server_k)
|
||||||
|
{
|
||||||
|
SetCedarCertAndChain(c, server_x, server_k, NULL);
|
||||||
|
}
|
||||||
|
void SetCedarCertAndChain(CEDAR *c, X *server_x, K *server_k, LIST *server_chain)
|
||||||
{
|
{
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (server_x == NULL || server_k == NULL)
|
if (server_x == NULL || server_k == NULL)
|
||||||
@ -1405,8 +1413,14 @@ void SetCedarCert(CEDAR *c, X *server_x, K *server_k)
|
|||||||
FreeK(c->ServerK);
|
FreeK(c->ServerK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c->ServerChain != NULL)
|
||||||
|
{
|
||||||
|
FreeXList(c->ServerChain);
|
||||||
|
}
|
||||||
|
|
||||||
c->ServerX = CloneX(server_x);
|
c->ServerX = CloneX(server_x);
|
||||||
c->ServerK = CloneK(server_k);
|
c->ServerK = CloneK(server_k);
|
||||||
|
c->ServerChain = CloneXList(server_chain);
|
||||||
}
|
}
|
||||||
Unlock(c->lock);
|
Unlock(c->lock);
|
||||||
}
|
}
|
||||||
|
@ -930,6 +930,7 @@ struct CEDAR
|
|||||||
COUNTER *ConnectionIncrement; // Connection increment counter
|
COUNTER *ConnectionIncrement; // Connection increment counter
|
||||||
X *ServerX; // Server certificate
|
X *ServerX; // Server certificate
|
||||||
K *ServerK; // Private key of the server certificate
|
K *ServerK; // Private key of the server certificate
|
||||||
|
LIST *ServerChain; // Server trust chain
|
||||||
char UsernameHubSeparator; // Character which separates the username from the hub name
|
char UsernameHubSeparator; // Character which separates the username from the hub name
|
||||||
char *CipherList; // List of encryption algorithms
|
char *CipherList; // List of encryption algorithms
|
||||||
UINT Version; // Version information
|
UINT Version; // Version information
|
||||||
@ -1000,6 +1001,7 @@ CEDAR *NewCedar(X *server_x, K *server_k);
|
|||||||
void CedarForceLink();
|
void CedarForceLink();
|
||||||
void SetCedarVpnBridge(CEDAR *c);
|
void SetCedarVpnBridge(CEDAR *c);
|
||||||
void SetCedarCert(CEDAR *c, X *server_x, K *server_k);
|
void SetCedarCert(CEDAR *c, X *server_x, K *server_k);
|
||||||
|
void SetCedarCertAndChain(CEDAR *c, X *server_x, K *server_k, LIST *server_chain);
|
||||||
void ReleaseCedar(CEDAR *c);
|
void ReleaseCedar(CEDAR *c);
|
||||||
void CleanupCedar(CEDAR *c);
|
void CleanupCedar(CEDAR *c);
|
||||||
void StopCedar(CEDAR *c);
|
void StopCedar(CEDAR *c);
|
||||||
|
@ -8638,18 +8638,51 @@ UINT PsServerKeyGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
|
|||||||
// Read the certificate and the private key
|
// Read the certificate and the private key
|
||||||
bool CmdLoadCertAndKey(CONSOLE *c, X **xx, K **kk, wchar_t *cert_filename, wchar_t *key_filename)
|
bool CmdLoadCertAndKey(CONSOLE *c, X **xx, K **kk, wchar_t *cert_filename, wchar_t *key_filename)
|
||||||
{
|
{
|
||||||
X *x;
|
return CmdLoadCertChainAndKey(c, xx, kk, NULL, cert_filename, key_filename);
|
||||||
|
}
|
||||||
|
bool CmdLoadCertChainAndKey(CONSOLE *c, X **xx, K **kk, LIST **cc, wchar_t *cert_filename, wchar_t *key_filename)
|
||||||
|
{
|
||||||
|
X *x = NULL;
|
||||||
K *k;
|
K *k;
|
||||||
|
LIST *chain = NULL;
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (c == NULL || cert_filename == NULL || key_filename == NULL || xx == NULL || kk == NULL)
|
if (c == NULL || cert_filename == NULL || key_filename == NULL || xx == NULL || kk == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
x = FileToXW(cert_filename);
|
BUF *b = ReadDumpW(cert_filename);
|
||||||
|
if (b == NULL)
|
||||||
|
{
|
||||||
|
c->Write(c, _UU("CMD_LOADCERT_FAILED"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DER-encoded X509 files can't hold multiple certificates
|
||||||
|
if (cc == NULL || IsBase64(b) == false)
|
||||||
|
{
|
||||||
|
x = BufToX(b, IsBase64(b));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chain = BufToXList(b, true);
|
||||||
|
if (LIST_NUM(chain) > 0)
|
||||||
|
{
|
||||||
|
x = LIST_DATA(chain, 0);
|
||||||
|
Delete(chain, x);
|
||||||
|
|
||||||
|
if (LIST_NUM(chain) == 0)
|
||||||
|
{
|
||||||
|
ReleaseList(chain);
|
||||||
|
chain = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FreeBuf(b);
|
||||||
if (x == NULL)
|
if (x == NULL)
|
||||||
{
|
{
|
||||||
c->Write(c, _UU("CMD_LOADCERT_FAILED"));
|
c->Write(c, _UU("CMD_LOADCERT_FAILED"));
|
||||||
|
FreeXList(chain);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8658,6 +8691,7 @@ bool CmdLoadCertAndKey(CONSOLE *c, X **xx, K **kk, wchar_t *cert_filename, wchar
|
|||||||
{
|
{
|
||||||
c->Write(c, _UU("CMD_LOADKEY_FAILED"));
|
c->Write(c, _UU("CMD_LOADKEY_FAILED"));
|
||||||
FreeX(x);
|
FreeX(x);
|
||||||
|
FreeXList(chain);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8666,12 +8700,17 @@ bool CmdLoadCertAndKey(CONSOLE *c, X **xx, K **kk, wchar_t *cert_filename, wchar
|
|||||||
c->Write(c, _UU("CMD_KEYPAIR_FAILED"));
|
c->Write(c, _UU("CMD_KEYPAIR_FAILED"));
|
||||||
FreeX(x);
|
FreeX(x);
|
||||||
FreeK(k);
|
FreeK(k);
|
||||||
|
FreeXList(chain);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*xx = x;
|
*xx = x;
|
||||||
*kk = k;
|
*kk = k;
|
||||||
|
if (cc != NULL)
|
||||||
|
{
|
||||||
|
*cc = chain;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -8754,7 +8793,7 @@ UINT PsServerCertSet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
|
|||||||
|
|
||||||
Zero(&t, sizeof(t));
|
Zero(&t, sizeof(t));
|
||||||
|
|
||||||
if (CmdLoadCertAndKey(c, &t.Cert, &t.Key,
|
if (CmdLoadCertChainAndKey(c, &t.Cert, &t.Key, &t.Chain,
|
||||||
GetParamUniStr(o, "LOADCERT"),
|
GetParamUniStr(o, "LOADCERT"),
|
||||||
GetParamUniStr(o, "LOADKEY")))
|
GetParamUniStr(o, "LOADKEY")))
|
||||||
{
|
{
|
||||||
|
@ -236,6 +236,7 @@ bool CmdEvalPortList(CONSOLE *c, wchar_t *str, void *param);
|
|||||||
wchar_t *PsClusterSettingMemberPromptPorts(CONSOLE *c, void *param);
|
wchar_t *PsClusterSettingMemberPromptPorts(CONSOLE *c, void *param);
|
||||||
K *CmdLoadKey(CONSOLE *c, wchar_t *filename);
|
K *CmdLoadKey(CONSOLE *c, wchar_t *filename);
|
||||||
bool CmdLoadCertAndKey(CONSOLE *c, X **xx, K **kk, wchar_t *cert_filename, wchar_t *key_filename);
|
bool CmdLoadCertAndKey(CONSOLE *c, X **xx, K **kk, wchar_t *cert_filename, wchar_t *key_filename);
|
||||||
|
bool CmdLoadCertChainAndKey(CONSOLE *c, X **xx, K **kk, LIST **cc, wchar_t *cert_filename, wchar_t *key_filename);
|
||||||
bool CmdEvalTcpOrUdp(CONSOLE *c, wchar_t *str, void *param);
|
bool CmdEvalTcpOrUdp(CONSOLE *c, wchar_t *str, void *param);
|
||||||
wchar_t *GetConnectionTypeStr(UINT type);
|
wchar_t *GetConnectionTypeStr(UINT type);
|
||||||
bool CmdEvalHostAndSubnetMask4(CONSOLE *c, wchar_t *str, void *param);
|
bool CmdEvalHostAndSubnetMask4(CONSOLE *c, wchar_t *str, void *param);
|
||||||
|
@ -2990,6 +2990,7 @@ void ConnectionAccept(CONNECTION *c)
|
|||||||
SOCK *s;
|
SOCK *s;
|
||||||
X *x;
|
X *x;
|
||||||
K *k;
|
K *k;
|
||||||
|
LIST *chain;
|
||||||
char tmp[128];
|
char tmp[128];
|
||||||
UINT initial_timeout = CONNECTING_TIMEOUT;
|
UINT initial_timeout = CONNECTING_TIMEOUT;
|
||||||
UCHAR ctoken_hash[SHA1_SIZE];
|
UCHAR ctoken_hash[SHA1_SIZE];
|
||||||
@ -3040,24 +3041,27 @@ void ConnectionAccept(CONNECTION *c)
|
|||||||
|
|
||||||
x = CloneX(c->Cedar->ServerX);
|
x = CloneX(c->Cedar->ServerX);
|
||||||
k = CloneK(c->Cedar->ServerK);
|
k = CloneK(c->Cedar->ServerK);
|
||||||
|
chain = CloneXList(c->Cedar->ServerChain);
|
||||||
}
|
}
|
||||||
Unlock(c->Cedar->lock);
|
Unlock(c->Cedar->lock);
|
||||||
|
|
||||||
// Start the SSL communication
|
// Start the SSL communication
|
||||||
Copy(&s->SslAcceptSettings, &c->Cedar->SslAcceptSettings, sizeof(SSL_ACCEPT_SETTINGS));
|
Copy(&s->SslAcceptSettings, &c->Cedar->SslAcceptSettings, sizeof(SSL_ACCEPT_SETTINGS));
|
||||||
if (StartSSL(s, x, k) == false)
|
if (StartSSLEx2(s, x, k, chain, 0, NULL) == false)
|
||||||
{
|
{
|
||||||
// Failed
|
// Failed
|
||||||
AddNoSsl(c->Cedar, &s->RemoteIP);
|
AddNoSsl(c->Cedar, &s->RemoteIP);
|
||||||
Debug("ConnectionAccept(): StartSSL() failed\n");
|
Debug("ConnectionAccept(): StartSSL() failed\n");
|
||||||
FreeX(x);
|
FreeX(x);
|
||||||
FreeK(k);
|
FreeK(k);
|
||||||
|
FreeXList(chain);
|
||||||
|
|
||||||
goto FINAL;
|
goto FINAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeX(x);
|
FreeX(x);
|
||||||
FreeK(k);
|
FreeK(k);
|
||||||
|
FreeXList(chain);
|
||||||
|
|
||||||
SLog(c->Cedar, "LS_SSL_START", c->Name, s->CipherName);
|
SLog(c->Cedar, "LS_SSL_START", c->Name, s->CipherName);
|
||||||
|
|
||||||
|
@ -3602,7 +3602,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
|
|||||||
if (p->Eap_TlsCtx.SslPipe == NULL)
|
if (p->Eap_TlsCtx.SslPipe == NULL)
|
||||||
{
|
{
|
||||||
p->Eap_TlsCtx.Dh = DhNewFromBits(DH_PARAM_BITS_DEFAULT);
|
p->Eap_TlsCtx.Dh = DhNewFromBits(DH_PARAM_BITS_DEFAULT);
|
||||||
p->Eap_TlsCtx.SslPipe = NewSslPipeEx(true, p->Cedar->ServerX, p->Cedar->ServerK, p->Eap_TlsCtx.Dh, true, &(p->Eap_TlsCtx.ClientCert));
|
p->Eap_TlsCtx.SslPipe = NewSslPipeEx2(true, p->Cedar->ServerX, p->Cedar->ServerK, p->Cedar->ServerChain, p->Eap_TlsCtx.Dh, true, &(p->Eap_TlsCtx.ClientCert));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the current frame is fragmented, or it is a possible last of a fragmented series, bufferize it
|
// If the current frame is fragmented, or it is a possible last of a fragmented series, bufferize it
|
||||||
|
@ -16809,6 +16809,7 @@ void SmSslDlgOnOk(HWND hWnd, SM_SSL *s)
|
|||||||
|
|
||||||
t.Cert = CloneX(s->Cert);
|
t.Cert = CloneX(s->Cert);
|
||||||
t.Key = CloneK(s->Key);
|
t.Key = CloneK(s->Key);
|
||||||
|
t.Chain = CloneXList(s->Chain);
|
||||||
|
|
||||||
if (CALL(hWnd, ScSetServerCert(s->p->Rpc, &t)) == false)
|
if (CALL(hWnd, ScSetServerCert(s->p->Rpc, &t)) == false)
|
||||||
{
|
{
|
||||||
@ -16923,6 +16924,7 @@ void SmSslDlgInit(HWND hWnd, SM_SSL *s)
|
|||||||
// Copy the certificate and key
|
// Copy the certificate and key
|
||||||
s->Cert = CloneX(t.Cert);
|
s->Cert = CloneX(t.Cert);
|
||||||
s->Key = CloneK(t.Key);
|
s->Key = CloneK(t.Key);
|
||||||
|
s->Chain = CloneXList(t.Chain);
|
||||||
|
|
||||||
if (t.Key != NULL)
|
if (t.Key != NULL)
|
||||||
{
|
{
|
||||||
@ -17174,6 +17176,7 @@ UINT SmSslDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param
|
|||||||
SM_SSL *s = (SM_SSL *)param;
|
SM_SSL *s = (SM_SSL *)param;
|
||||||
X *x;
|
X *x;
|
||||||
K *k;
|
K *k;
|
||||||
|
LIST *chain;
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (hWnd == NULL)
|
if (hWnd == NULL)
|
||||||
{
|
{
|
||||||
@ -17222,16 +17225,18 @@ UINT SmSslDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param
|
|||||||
|
|
||||||
case B_IMPORT:
|
case B_IMPORT:
|
||||||
// Import
|
// Import
|
||||||
if (CmLoadXAndK(hWnd, &x, &k))
|
if (CmLoadXListAndK(hWnd, &x, &k, &chain))
|
||||||
{
|
{
|
||||||
wchar_t tmp[MAX_SIZE];
|
wchar_t tmp[MAX_SIZE];
|
||||||
|
|
||||||
LABEL_APPLY_NEW_CERT:
|
LABEL_APPLY_NEW_CERT:
|
||||||
FreeX(s->Cert);
|
FreeX(s->Cert);
|
||||||
FreeK(s->Key);
|
FreeK(s->Key);
|
||||||
|
FreeXList(s->Chain);
|
||||||
s->Cert = x;
|
s->Cert = x;
|
||||||
s->Key = k;
|
s->Key = k;
|
||||||
s->SetCertAndKey = true;
|
s->SetCertAndKey = true;
|
||||||
|
s->Chain = chain;
|
||||||
// Show the Certificate Information
|
// Show the Certificate Information
|
||||||
SmGetCertInfoStr(tmp, sizeof(tmp), s->Cert);
|
SmGetCertInfoStr(tmp, sizeof(tmp), s->Cert);
|
||||||
SetText(hWnd, S_CERT_INFO, tmp);
|
SetText(hWnd, S_CERT_INFO, tmp);
|
||||||
@ -17310,6 +17315,7 @@ void SmSslDlg(HWND hWnd, SM_SERVER *p)
|
|||||||
// Cleanup
|
// Cleanup
|
||||||
FreeX(s.Cert);
|
FreeX(s.Cert);
|
||||||
FreeK(s.Key);
|
FreeK(s.Key);
|
||||||
|
FreeXList(s.Chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listener creation dialog procedure
|
// Listener creation dialog procedure
|
||||||
|
@ -112,6 +112,7 @@ typedef struct SM_SSL
|
|||||||
SM_SERVER *p; // P
|
SM_SERVER *p; // P
|
||||||
X *Cert; // Certificate
|
X *Cert; // Certificate
|
||||||
K *Key; // Secret key
|
K *Key; // Secret key
|
||||||
|
LIST *Chain; // Trust chain
|
||||||
bool SetCertAndKey; // Set the key
|
bool SetCertAndKey; // Set the key
|
||||||
} SM_SSL;
|
} SM_SSL;
|
||||||
|
|
||||||
|
@ -5608,6 +5608,7 @@ void SiLoadServerCfg(SERVER *s, FOLDER *f)
|
|||||||
char tmp[MAX_SIZE];
|
char tmp[MAX_SIZE];
|
||||||
X *x = NULL;
|
X *x = NULL;
|
||||||
K *k = NULL;
|
K *k = NULL;
|
||||||
|
LIST *chain = NewList(NULL);
|
||||||
FOLDER *params_folder;
|
FOLDER *params_folder;
|
||||||
UINT i;
|
UINT i;
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
@ -5847,10 +5848,14 @@ void SiLoadServerCfg(SERVER *s, FOLDER *f)
|
|||||||
FreeBuf(b);
|
FreeBuf(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Server trust chain
|
||||||
|
SiLoadCertList(chain, CfgGetFolder(f, "ServerChain"));
|
||||||
|
|
||||||
if (x == NULL || k == NULL || CheckXandK(x, k) == false)
|
if (x == NULL || k == NULL || CheckXandK(x, k) == false)
|
||||||
{
|
{
|
||||||
FreeX(x);
|
FreeX(x);
|
||||||
FreeK(k);
|
FreeK(k);
|
||||||
|
FreeXList(chain);
|
||||||
SiGenerateDefaultCert(&x, &k);
|
SiGenerateDefaultCert(&x, &k);
|
||||||
|
|
||||||
SetCedarCert(c, x, k);
|
SetCedarCert(c, x, k);
|
||||||
@ -5860,10 +5865,18 @@ void SiLoadServerCfg(SERVER *s, FOLDER *f)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetCedarCert(c, x, k);
|
if (LIST_NUM(chain) == 0)
|
||||||
|
{
|
||||||
|
SetCedarCert(c, x, k);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetCedarCertAndChain(c, x, k, chain);
|
||||||
|
}
|
||||||
|
|
||||||
FreeX(x);
|
FreeX(x);
|
||||||
FreeK(k);
|
FreeK(k);
|
||||||
|
FreeXList(chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Character which separates the username from the hub name
|
// Character which separates the username from the hub name
|
||||||
@ -6246,6 +6259,9 @@ void SiWriteServerCfg(FOLDER *f, SERVER *s)
|
|||||||
CfgAddBuf(f, "ServerKey", b);
|
CfgAddBuf(f, "ServerKey", b);
|
||||||
FreeBuf(b);
|
FreeBuf(b);
|
||||||
|
|
||||||
|
// Server trust chain
|
||||||
|
SiWriteCertList(CfgCreateFolder(f, "ServerChain"), c->ServerChain);
|
||||||
|
|
||||||
{
|
{
|
||||||
// Character which separates the username from the hub name
|
// Character which separates the username from the hub name
|
||||||
char str[2];
|
char str[2];
|
||||||
|
@ -1079,6 +1079,41 @@ X *CloneX(X *x)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clone of certificate chain
|
||||||
|
LIST *CloneXList(LIST *chain)
|
||||||
|
{
|
||||||
|
BUF *b;
|
||||||
|
X *x;
|
||||||
|
LIST *ret;
|
||||||
|
// Validate arguments
|
||||||
|
if (chain == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = NewList(NULL);
|
||||||
|
LockList(chain);
|
||||||
|
{
|
||||||
|
UINT i;
|
||||||
|
for (i = 0;i < LIST_NUM(chain);i++)
|
||||||
|
{
|
||||||
|
x = LIST_DATA(chain, i);
|
||||||
|
b = XToBuf(x, false);
|
||||||
|
if (b == NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = BufToX(b, false);
|
||||||
|
Add(ret, x);
|
||||||
|
FreeBuf(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnlockList(chain);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// Generate a P12
|
// Generate a P12
|
||||||
P12 *NewP12(X *x, K *k, char *password)
|
P12 *NewP12(X *x, K *k, char *password)
|
||||||
{
|
{
|
||||||
@ -1133,9 +1168,15 @@ bool IsEncryptedP12(P12 *p12)
|
|||||||
|
|
||||||
// Extract the X and the K from the P12
|
// Extract the X and the K from the P12
|
||||||
bool ParseP12(P12 *p12, X **x, K **k, char *password)
|
bool ParseP12(P12 *p12, X **x, K **k, char *password)
|
||||||
|
{
|
||||||
|
return ParseP12Ex(p12, x, k, NULL, password);
|
||||||
|
}
|
||||||
|
// Extract the X, the K and the chain from the P12
|
||||||
|
bool ParseP12Ex(P12 *p12, X **x, K **k, LIST **cc, char *password)
|
||||||
{
|
{
|
||||||
EVP_PKEY *pkey;
|
EVP_PKEY *pkey;
|
||||||
X509 *x509;
|
X509 *x509;
|
||||||
|
STACK_OF(X509) *sk = NULL;
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (p12 == NULL || x == NULL || k == NULL)
|
if (p12 == NULL || x == NULL || k == NULL)
|
||||||
{
|
{
|
||||||
@ -1165,9 +1206,9 @@ bool ParseP12(P12 *p12, X **x, K **k, char *password)
|
|||||||
// Extraction
|
// Extraction
|
||||||
Lock(openssl_lock);
|
Lock(openssl_lock);
|
||||||
{
|
{
|
||||||
if (PKCS12_parse(p12->pkcs12, password, &pkey, &x509, NULL) == false)
|
if (PKCS12_parse(p12->pkcs12, password, &pkey, &x509, &sk) == false)
|
||||||
{
|
{
|
||||||
if (PKCS12_parse(p12->pkcs12, NULL, &pkey, &x509, NULL) == false)
|
if (PKCS12_parse(p12->pkcs12, NULL, &pkey, &x509, &sk) == false)
|
||||||
{
|
{
|
||||||
Unlock(openssl_lock);
|
Unlock(openssl_lock);
|
||||||
return false;
|
return false;
|
||||||
@ -1182,6 +1223,7 @@ bool ParseP12(P12 *p12, X **x, K **k, char *password)
|
|||||||
if (*x == NULL)
|
if (*x == NULL)
|
||||||
{
|
{
|
||||||
FreePKey(pkey);
|
FreePKey(pkey);
|
||||||
|
sk_X509_free(sk);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1189,6 +1231,37 @@ bool ParseP12(P12 *p12, X **x, K **k, char *password)
|
|||||||
(*k)->private_key = true;
|
(*k)->private_key = true;
|
||||||
(*k)->pkey = pkey;
|
(*k)->pkey = pkey;
|
||||||
|
|
||||||
|
if (sk == NULL || cc == NULL)
|
||||||
|
{
|
||||||
|
if (cc != NULL)
|
||||||
|
{
|
||||||
|
*cc = NULL;
|
||||||
|
}
|
||||||
|
if (sk != NULL)
|
||||||
|
{
|
||||||
|
sk_X509_free(sk);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIST *chain = NewList(NULL);
|
||||||
|
X *x1;
|
||||||
|
while (sk_X509_num(sk)) {
|
||||||
|
x509 = sk_X509_shift(sk);
|
||||||
|
x1 = X509ToX(x509);
|
||||||
|
if (x1 != NULL)
|
||||||
|
{
|
||||||
|
Add(chain, x1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
X509_free(x509);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sk_X509_free(sk);
|
||||||
|
|
||||||
|
*cc = chain;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3365,6 +3438,29 @@ void FreeX(X *x)
|
|||||||
Free(x);
|
Free(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Release of an X chain
|
||||||
|
void FreeXList(LIST *chain)
|
||||||
|
{
|
||||||
|
// Validate arguments
|
||||||
|
if (chain == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LockList(chain);
|
||||||
|
{
|
||||||
|
UINT i;
|
||||||
|
for (i = 0; i < LIST_NUM(chain); i++)
|
||||||
|
{
|
||||||
|
X *x = LIST_DATA(chain, i);
|
||||||
|
FreeX(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnlockList(chain);
|
||||||
|
|
||||||
|
ReleaseList(chain);
|
||||||
|
}
|
||||||
|
|
||||||
// Release of the X509
|
// Release of the X509
|
||||||
void FreeX509(X509 *x509)
|
void FreeX509(X509 *x509)
|
||||||
{
|
{
|
||||||
@ -3406,6 +3502,31 @@ X *BufToX(BUF *b, bool text)
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert the BUF to X chain
|
||||||
|
LIST *BufToXList(BUF *b, bool text)
|
||||||
|
{
|
||||||
|
LIST *chain;
|
||||||
|
BIO *bio;
|
||||||
|
// Validate arguments
|
||||||
|
if (b == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bio = BufToBio(b);
|
||||||
|
if (bio == NULL)
|
||||||
|
{
|
||||||
|
FreeBuf(b);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
chain = BioToXList(bio, text);
|
||||||
|
|
||||||
|
FreeBio(bio);
|
||||||
|
|
||||||
|
return chain;
|
||||||
|
}
|
||||||
|
|
||||||
// Get a digest of the X
|
// Get a digest of the X
|
||||||
void GetXDigest(X *x, UCHAR *buf, bool sha1)
|
void GetXDigest(X *x, UCHAR *buf, bool sha1)
|
||||||
{
|
{
|
||||||
@ -3469,6 +3590,49 @@ X *BioToX(BIO *bio, bool text)
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert BIO to X chain
|
||||||
|
LIST *BioToXList(BIO *bio, bool text)
|
||||||
|
{
|
||||||
|
X *x;
|
||||||
|
STACK_OF(X509_INFO) *sk = NULL;
|
||||||
|
X509_INFO *xi;
|
||||||
|
LIST *chain;
|
||||||
|
|
||||||
|
// Validate arguments
|
||||||
|
if (bio == NULL || text == false)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Lock(openssl_lock);
|
||||||
|
{
|
||||||
|
sk = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
|
||||||
|
if (sk == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
chain = NewList(NULL);
|
||||||
|
|
||||||
|
while (sk_X509_INFO_num(sk))
|
||||||
|
{
|
||||||
|
xi = sk_X509_INFO_shift(sk);
|
||||||
|
x = X509ToX(xi->x509);
|
||||||
|
if (x != NULL)
|
||||||
|
{
|
||||||
|
Add(chain, x);
|
||||||
|
xi->x509 = NULL;
|
||||||
|
}
|
||||||
|
X509_INFO_free(xi);
|
||||||
|
}
|
||||||
|
|
||||||
|
sk_X509_INFO_free(sk);
|
||||||
|
}
|
||||||
|
Unlock(openssl_lock);
|
||||||
|
|
||||||
|
return chain;
|
||||||
|
}
|
||||||
|
|
||||||
// Convert the X509 to X
|
// Convert the X509 to X
|
||||||
X *X509ToX(X509 *x509)
|
X *X509ToX(X509 *x509)
|
||||||
{
|
{
|
||||||
|
@ -293,9 +293,12 @@ BUF *BioToBuf(BIO *bio);
|
|||||||
BIO *NewBio();
|
BIO *NewBio();
|
||||||
void FreeBio(BIO *bio);
|
void FreeBio(BIO *bio);
|
||||||
X *BioToX(BIO *bio, bool text);
|
X *BioToX(BIO *bio, bool text);
|
||||||
|
LIST *BioToXList(BIO *bio, bool text);
|
||||||
X *BufToX(BUF *b, bool text);
|
X *BufToX(BUF *b, bool text);
|
||||||
|
LIST *BufToXList(BUF *b, bool text);
|
||||||
void FreeX509(X509 *x509);
|
void FreeX509(X509 *x509);
|
||||||
void FreeX(X *x);
|
void FreeX(X *x);
|
||||||
|
void FreeXList(LIST *chain);
|
||||||
BIO *XToBio(X *x, bool text);
|
BIO *XToBio(X *x, bool text);
|
||||||
BUF *XToBuf(X *x, bool text);
|
BUF *XToBuf(X *x, bool text);
|
||||||
K *BioToK(BIO *bio, bool private_key, bool text, char *password);
|
K *BioToK(BIO *bio, bool private_key, bool text, char *password);
|
||||||
@ -357,9 +360,11 @@ void FreePKCS12(PKCS12 *pkcs12);
|
|||||||
void FreeP12(P12 *p12);
|
void FreeP12(P12 *p12);
|
||||||
bool P12ToFileW(P12 *p12, wchar_t *filename);
|
bool P12ToFileW(P12 *p12, wchar_t *filename);
|
||||||
bool ParseP12(P12 *p12, X **x, K **k, char *password);
|
bool ParseP12(P12 *p12, X **x, K **k, char *password);
|
||||||
|
bool ParseP12Ex(P12 *p12, X **x, K **k, LIST **cc, char *password);
|
||||||
bool IsEncryptedP12(P12 *p12);
|
bool IsEncryptedP12(P12 *p12);
|
||||||
P12 *NewP12(X *x, K *k, char *password);
|
P12 *NewP12(X *x, K *k, char *password);
|
||||||
X *CloneX(X *x);
|
X *CloneX(X *x);
|
||||||
|
LIST *CloneXList(LIST *chain);
|
||||||
K *CloneK(K *k);
|
K *CloneK(K *k);
|
||||||
void FreeCryptLibrary();
|
void FreeCryptLibrary();
|
||||||
void GetPrintNameFromX(wchar_t *str, UINT size, X *x);
|
void GetPrintNameFromX(wchar_t *str, UINT size, X *x);
|
||||||
|
@ -5702,6 +5702,10 @@ SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh)
|
|||||||
|
|
||||||
// Create a new SSL pipe with extended options
|
// Create a new SSL pipe with extended options
|
||||||
SSL_PIPE *NewSslPipeEx(bool server_mode, X *x, K *k, DH_CTX *dh, bool verify_peer, struct SslClientCertInfo *clientcert)
|
SSL_PIPE *NewSslPipeEx(bool server_mode, X *x, K *k, DH_CTX *dh, bool verify_peer, struct SslClientCertInfo *clientcert)
|
||||||
|
{
|
||||||
|
return NewSslPipeEx2(server_mode, x, k, NULL, dh, verify_peer, clientcert);
|
||||||
|
}
|
||||||
|
SSL_PIPE *NewSslPipeEx2(bool server_mode, X *x, K *k, LIST *chain, DH_CTX *dh, bool verify_peer, struct SslClientCertInfo *clientcert)
|
||||||
{
|
{
|
||||||
SSL_PIPE *s;
|
SSL_PIPE *s;
|
||||||
SSL *ssl;
|
SSL *ssl;
|
||||||
@ -5715,7 +5719,24 @@ SSL_PIPE *NewSslPipeEx(bool server_mode, X *x, K *k, DH_CTX *dh, bool verify_pee
|
|||||||
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_3); // For some reason pppd under linux doesn't like it
|
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_3); // For some reason pppd under linux doesn't like it
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
AddChainSslCertOnDirectory(ssl_ctx);
|
if (chain == NULL)
|
||||||
|
{
|
||||||
|
AddChainSslCertOnDirectory(ssl_ctx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UINT i;
|
||||||
|
X *x;
|
||||||
|
LockList(chain);
|
||||||
|
{
|
||||||
|
for (i = 0;i < LIST_NUM(chain);i++)
|
||||||
|
{
|
||||||
|
x = LIST_DATA(chain, i);
|
||||||
|
AddChainSslCert(ssl_ctx, x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnlockList(chain);
|
||||||
|
}
|
||||||
|
|
||||||
if (dh != NULL)
|
if (dh != NULL)
|
||||||
{
|
{
|
||||||
@ -11641,6 +11662,10 @@ bool StartSSL(SOCK *sock, X *x, K *priv)
|
|||||||
return StartSSLEx(sock, x, priv, 0, NULL);
|
return StartSSLEx(sock, x, priv, 0, NULL);
|
||||||
}
|
}
|
||||||
bool StartSSLEx(SOCK *sock, X *x, K *priv, UINT ssl_timeout, char *sni_hostname)
|
bool StartSSLEx(SOCK *sock, X *x, K *priv, UINT ssl_timeout, char *sni_hostname)
|
||||||
|
{
|
||||||
|
return StartSSLEx2(sock, x, priv, NULL, ssl_timeout, sni_hostname);
|
||||||
|
}
|
||||||
|
bool StartSSLEx2(SOCK *sock, X *x, K *priv, LIST *chain, UINT ssl_timeout, char *sni_hostname)
|
||||||
{
|
{
|
||||||
X509 *x509;
|
X509 *x509;
|
||||||
EVP_PKEY *key;
|
EVP_PKEY *key;
|
||||||
@ -11736,7 +11761,24 @@ bool StartSSLEx(SOCK *sock, X *x, K *priv, UINT ssl_timeout, char *sni_hostname)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
Unlock(openssl_lock);
|
Unlock(openssl_lock);
|
||||||
AddChainSslCertOnDirectory(ssl_ctx);
|
if (chain == NULL)
|
||||||
|
{
|
||||||
|
AddChainSslCertOnDirectory(ssl_ctx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UINT i;
|
||||||
|
X *x;
|
||||||
|
LockList(chain);
|
||||||
|
{
|
||||||
|
for (i = 0;i < LIST_NUM(chain);i++)
|
||||||
|
{
|
||||||
|
x = LIST_DATA(chain, i);
|
||||||
|
AddChainSslCert(ssl_ctx, x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnlockList(chain);
|
||||||
|
}
|
||||||
Lock(openssl_lock);
|
Lock(openssl_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1081,6 +1081,7 @@ UINT SecureSend(SOCK *sock, void *data, UINT size);
|
|||||||
UINT SecureRecv(SOCK *sock, void *data, UINT size);
|
UINT SecureRecv(SOCK *sock, void *data, UINT size);
|
||||||
bool StartSSL(SOCK *sock, X *x, K *priv);
|
bool StartSSL(SOCK *sock, X *x, K *priv);
|
||||||
bool StartSSLEx(SOCK *sock, X *x, K *priv, UINT ssl_timeout, char *sni_hostname);
|
bool StartSSLEx(SOCK *sock, X *x, K *priv, UINT ssl_timeout, char *sni_hostname);
|
||||||
|
bool StartSSLEx2(SOCK *sock, X *x, K *priv, LIST *chain, UINT ssl_timeout, char *sni_hostname);
|
||||||
bool AddChainSslCert(struct ssl_ctx_st *ctx, X *x);
|
bool AddChainSslCert(struct ssl_ctx_st *ctx, X *x);
|
||||||
void AddChainSslCertOnDirectory(struct ssl_ctx_st *ctx);
|
void AddChainSslCertOnDirectory(struct ssl_ctx_st *ctx);
|
||||||
bool SendAll(SOCK *sock, void *data, UINT size, bool secure);
|
bool SendAll(SOCK *sock, void *data, UINT size, bool secure);
|
||||||
@ -1355,6 +1356,7 @@ struct SslClientCertInfo {
|
|||||||
|
|
||||||
SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh);
|
SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh);
|
||||||
SSL_PIPE *NewSslPipeEx(bool server_mode, X *x, K *k, DH_CTX *dh, bool verify_peer, struct SslClientCertInfo *clientcert);
|
SSL_PIPE *NewSslPipeEx(bool server_mode, X *x, K *k, DH_CTX *dh, bool verify_peer, struct SslClientCertInfo *clientcert);
|
||||||
|
SSL_PIPE *NewSslPipeEx2(bool server_mode, X *x, K *k, LIST *chain, DH_CTX *dh, bool verify_peer, struct SslClientCertInfo *clientcert);
|
||||||
void FreeSslPipe(SSL_PIPE *s);
|
void FreeSslPipe(SSL_PIPE *s);
|
||||||
bool SyncSslPipe(SSL_PIPE *s);
|
bool SyncSslPipe(SSL_PIPE *s);
|
||||||
|
|
||||||
|
@ -870,6 +870,50 @@ X *PackGetX(PACK *p, char *name)
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the X chain from the PACK
|
||||||
|
LIST *PackGetXList(PACK *p, char *name)
|
||||||
|
{
|
||||||
|
X *x;
|
||||||
|
BUF *b;
|
||||||
|
LIST *chain;
|
||||||
|
UINT i;
|
||||||
|
// Validate arguments
|
||||||
|
if (p == NULL || name == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ELEMENT *e = GetElement(p, name, VALUE_DATA);
|
||||||
|
if (e == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
chain = NewList(NULL);
|
||||||
|
for (i = 0;i < e->num_value;i++)
|
||||||
|
{
|
||||||
|
b = PackGetBufEx(p, name, i);
|
||||||
|
if (b == NULL)
|
||||||
|
{
|
||||||
|
FreeXList(chain);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = BufToX(b, false);
|
||||||
|
|
||||||
|
if (x == NULL)
|
||||||
|
{
|
||||||
|
x = BufToX(b, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeBuf(b);
|
||||||
|
|
||||||
|
Add(chain, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
return chain;
|
||||||
|
}
|
||||||
|
|
||||||
// Add the K to the PACK
|
// Add the K to the PACK
|
||||||
ELEMENT *PackAddK(PACK *p, char *name, K *k)
|
ELEMENT *PackAddK(PACK *p, char *name, K *k)
|
||||||
{
|
{
|
||||||
@ -916,6 +960,36 @@ ELEMENT *PackAddX(PACK *p, char *name, X *x)
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add an X chain into the PACK
|
||||||
|
ELEMENT *PackAddXList(PACK *p, char *name, LIST *chain)
|
||||||
|
{
|
||||||
|
BUF *b;
|
||||||
|
X *x;
|
||||||
|
ELEMENT *e = NULL;
|
||||||
|
// Validate arguments
|
||||||
|
if (p == NULL || name == NULL || chain == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT i;
|
||||||
|
for (i = 0;i < LIST_NUM(chain);i++)
|
||||||
|
{
|
||||||
|
x = LIST_DATA(chain, i);
|
||||||
|
b = XToBuf(x, false);
|
||||||
|
|
||||||
|
if (b == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = PackAddBufEx(p, name, b, i, LIST_NUM(chain));
|
||||||
|
FreeBuf(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
// Get a buffer from the PACK
|
// Get a buffer from the PACK
|
||||||
BUF *PackGetBuf(PACK *p, char *name)
|
BUF *PackGetBuf(PACK *p, char *name)
|
||||||
{
|
{
|
||||||
|
@ -127,8 +127,10 @@ VALUE *NewInt64Value(UINT64 i);
|
|||||||
TOKEN_LIST *GetPackElementNames(PACK *p);
|
TOKEN_LIST *GetPackElementNames(PACK *p);
|
||||||
|
|
||||||
X *PackGetX(PACK *p, char *name);
|
X *PackGetX(PACK *p, char *name);
|
||||||
|
LIST *PackGetXList(PACK *p, char *name);
|
||||||
K *PackGetK(PACK *p, char *name);
|
K *PackGetK(PACK *p, char *name);
|
||||||
ELEMENT *PackAddX(PACK *p, char *name, X *x);
|
ELEMENT *PackAddX(PACK *p, char *name, X *x);
|
||||||
|
ELEMENT *PackAddXList(PACK *p, char *name, LIST *chain);
|
||||||
ELEMENT *PackAddK(PACK *p, char *name, K *k);
|
ELEMENT *PackAddK(PACK *p, char *name, K *k);
|
||||||
ELEMENT *PackAddStr(PACK *p, char *name, char *str);
|
ELEMENT *PackAddStr(PACK *p, char *name, char *str);
|
||||||
ELEMENT *PackAddStrEx(PACK *p, char *name, char *str, UINT index, UINT total);
|
ELEMENT *PackAddStrEx(PACK *p, char *name, char *str, UINT index, UINT total);
|
||||||
|
Loading…
Reference in New Issue
Block a user