mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-23 01:49:53 +03:00
* Implementing user search by certificate common name.
* Reworking EAP-TLS flow * Implementing iterative TLS downgrade supporting PPPD TLS 1.3+Tickets, Windows TLS 1.3 w/o Tickets, VPN Client Pro TLS 1.2.
This commit is contained in:
parent
8362637353
commit
149096e13c
@ -897,6 +897,32 @@ USER *AcGetUser(HUB *h, char *name)
|
|||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
USER* AcGetUserByCert(HUB *h, char *common_name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < LIST_NUM(h->HubDb->UserList); i++)
|
||||||
|
{
|
||||||
|
USER* u = LIST_DATA(h->HubDb->UserList, i);
|
||||||
|
if (u->AuthType == AUTHTYPE_USERCERT)
|
||||||
|
{
|
||||||
|
X* cert = ((AUTHUSERCERT*)u->AuthData)->UserX;
|
||||||
|
if (cert != NULL)
|
||||||
|
{
|
||||||
|
char cname[MAX_SIZE];
|
||||||
|
UniToStr(cname, sizeof(cname), cert->subject_name->CommonName);
|
||||||
|
if (StrCmp(common_name, cname) == 0)
|
||||||
|
{
|
||||||
|
AddRef(u->ref);
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Delete the user
|
// Delete the user
|
||||||
bool AcDeleteUser(HUB *h, char *name)
|
bool AcDeleteUser(HUB *h, char *name)
|
||||||
{
|
{
|
||||||
|
@ -177,6 +177,7 @@ void FreeAuthData(UINT authtype, void *authdata);
|
|||||||
bool AcAddUser(HUB *h, USER *u);
|
bool AcAddUser(HUB *h, USER *u);
|
||||||
bool AcAddGroup(HUB *h, USERGROUP *g);
|
bool AcAddGroup(HUB *h, USERGROUP *g);
|
||||||
USER *AcGetUser(HUB *h, char *name);
|
USER *AcGetUser(HUB *h, char *name);
|
||||||
|
USER* AcGetUserByCert(HUB* h, char *common_name);
|
||||||
USERGROUP *AcGetGroup(HUB *h, char *name);
|
USERGROUP *AcGetGroup(HUB *h, char *name);
|
||||||
bool AcIsUser(HUB *h, char *name);
|
bool AcIsUser(HUB *h, char *name);
|
||||||
bool AcIsGroup(HUB *h, char *name);
|
bool AcIsGroup(HUB *h, char *name);
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#include "Hub.h"
|
#include "Hub.h"
|
||||||
#include "IPC.h"
|
#include "IPC.h"
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
#include "Proto_IPsec.h"
|
|
||||||
#include "Radius.h"
|
#include "Radius.h"
|
||||||
#include "Server.h"
|
#include "Server.h"
|
||||||
|
|
||||||
@ -599,6 +598,9 @@ THREAD *NewPPPSession(CEDAR *cedar, IP *client_ip, UINT client_port, IP *server_
|
|||||||
p->AuthProtocol = PPP_UNSPECIFIED;
|
p->AuthProtocol = PPP_UNSPECIFIED;
|
||||||
p->MsChapV2_ErrorCode = 691;
|
p->MsChapV2_ErrorCode = 691;
|
||||||
p->EapClient = NULL;
|
p->EapClient = NULL;
|
||||||
|
Zero(&p->Eap_Identity, sizeof(p->Eap_Identity));
|
||||||
|
p->Eap_TlsCtx.DisableTls13 = false;
|
||||||
|
p->Eap_TlsCtx.DisableTls13SessionTickets = false;
|
||||||
|
|
||||||
p->DataTimeout = PPP_DATA_TIMEOUT;
|
p->DataTimeout = PPP_DATA_TIMEOUT;
|
||||||
p->PacketRecvTimeout = PPP_PACKET_RECV_TIMEOUT;
|
p->PacketRecvTimeout = PPP_PACKET_RECV_TIMEOUT;
|
||||||
@ -1263,12 +1265,12 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
|
|||||||
UINT64 offer = 0;
|
UINT64 offer = 0;
|
||||||
PPP_LCP *c;
|
PPP_LCP *c;
|
||||||
UCHAR ms_chap_v2_code[3];
|
UCHAR ms_chap_v2_code[3];
|
||||||
ETHERIP_ID d;
|
|
||||||
char username[MAX_SIZE];
|
char username[MAX_SIZE];
|
||||||
char hubname[MAX_SIZE];
|
char hubname[MAX_SIZE];
|
||||||
HUB *hub;
|
HUB *hub;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
UINT authtype;
|
UINT authtype;
|
||||||
|
UCHAR eapidentitypkt[MAX_SIZE] = { 0 };
|
||||||
|
|
||||||
WRITE_USHORT(ms_chap_v2_code, PPP_LCP_AUTH_CHAP);
|
WRITE_USHORT(ms_chap_v2_code, PPP_LCP_AUTH_CHAP);
|
||||||
ms_chap_v2_code[2] = PPP_CHAP_ALG_MS_CHAP_V2;
|
ms_chap_v2_code[2] = PPP_CHAP_ALG_MS_CHAP_V2;
|
||||||
@ -1277,24 +1279,31 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
|
|||||||
{
|
{
|
||||||
case PPP_EAP_TYPE_IDENTITY:
|
case PPP_EAP_TYPE_IDENTITY:
|
||||||
// Parse username
|
// Parse username
|
||||||
Copy(p->Eap_Identity, eap_packet->Data, MIN(MAX_SIZE, eap_datasize));
|
Copy(eapidentitypkt, eap_packet->Data, MIN(MAX_SIZE, eap_datasize));
|
||||||
Zero(&d, sizeof(d));
|
Zero(&p->Eap_Identity, sizeof(p->Eap_Identity));
|
||||||
PPPParseUsername(p->Cedar, p->Eap_Identity, &d);
|
PPPParseUsername(p->Cedar, eapidentitypkt, &p->Eap_Identity);
|
||||||
StrCpy(username, sizeof(username), d.UserName);
|
Debug("EAP: username=%s, hubname=%s\n", p->Eap_Identity.UserName, p->Eap_Identity.HubName);
|
||||||
StrCpy(hubname, sizeof(hubname), d.HubName);
|
|
||||||
Debug("EAP: username=%s, hubname=%s\n", username, hubname);
|
|
||||||
|
|
||||||
// Locate user
|
// Locate user
|
||||||
LockHubList(p->Cedar);
|
LockHubList(p->Cedar);
|
||||||
{
|
{
|
||||||
hub = GetHub(p->Cedar, hubname);
|
hub = GetHub(p->Cedar, p->Eap_Identity.HubName);
|
||||||
}
|
}
|
||||||
UnlockHubList(p->Cedar);
|
UnlockHubList(p->Cedar);
|
||||||
if (hub != NULL)
|
if (hub != NULL)
|
||||||
{
|
{
|
||||||
AcLock(hub);
|
AcLock(hub);
|
||||||
{
|
{
|
||||||
USER *user = AcGetUser(hub, username);
|
USER *user = AcGetUser(hub, p->Eap_Identity.UserName);
|
||||||
|
if (user == NULL)
|
||||||
|
{
|
||||||
|
user = AcGetUserByCert(hub, p->Eap_Identity.UserName);
|
||||||
|
if (user != NULL)
|
||||||
|
{
|
||||||
|
// We overwrite the identity by the one we found
|
||||||
|
StrCpy(p->Eap_Identity.UserName, sizeof(p->Eap_Identity.UserName), user->Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (user == NULL)
|
if (user == NULL)
|
||||||
{
|
{
|
||||||
user = AcGetUser(hub, "*");
|
user = AcGetUser(hub, "*");
|
||||||
@ -3422,7 +3431,7 @@ bool PPPGetIPAddressValueFromLCP(PPP_LCP *c, UINT type, IP *ip)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EAP packet utilities
|
// EAP packet utilities
|
||||||
bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSize)
|
bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapSize)
|
||||||
{
|
{
|
||||||
UCHAR *dataBuffer;
|
UCHAR *dataBuffer;
|
||||||
UINT dataSize;
|
UINT dataSize;
|
||||||
@ -3432,8 +3441,8 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
|
|||||||
PPP_EAP *eap;
|
PPP_EAP *eap;
|
||||||
UCHAR flags = PPP_EAP_TLS_FLAG_NONE;
|
UCHAR flags = PPP_EAP_TLS_FLAG_NONE;
|
||||||
UINT sizeLeft = 0;
|
UINT sizeLeft = 0;
|
||||||
Debug("Got EAP-TLS size=%i\n", eapTlsSize);
|
Debug("Got EAP-TLS size=%i\n", eapSize);
|
||||||
if (eapTlsSize == 1)
|
if (eapSize == 1 && p->Eap_TlsCtx.ClientCert.X == NULL)
|
||||||
{
|
{
|
||||||
// This is an EAP-TLS message ACK
|
// This is an EAP-TLS message ACK
|
||||||
if (p->Eap_TlsCtx.CachedBufferSend != NULL)
|
if (p->Eap_TlsCtx.CachedBufferSend != NULL)
|
||||||
@ -3471,15 +3480,225 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
|
|||||||
p->Eap_TlsCtx.CachedBufferSendPntr = NULL;
|
p->Eap_TlsCtx.CachedBufferSendPntr = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (p->Eap_TlsCtx.ClientCert.X == NULL)
|
||||||
|
{
|
||||||
|
// Some clients needs a little help it seems - namely VPN Client Pro on Android
|
||||||
|
flags |= PPP_EAP_TLS_FLAG_SSLSTARTED;
|
||||||
|
p->Eap_PacketId = p->NextId++;
|
||||||
|
lcp = BuildEAPTlsRequest(p->Eap_PacketId, 0, flags);
|
||||||
|
PPPSetStatus(p, PPP_STATUS_AUTHENTICATING);
|
||||||
|
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
|
||||||
|
{
|
||||||
|
PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
|
WHERE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Debug("Sent EAP-TLS size=%i\n", lcp->DataSize);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
dataBuffer = eap_packet->Tls.TlsDataWithoutLength;
|
||||||
|
dataSize = eapSize - 1;
|
||||||
|
if (eap_packet->Tls.Flags & PPP_EAP_TLS_FLAG_TLS_LENGTH)
|
||||||
|
{
|
||||||
|
dataBuffer = eap_packet->Tls.TlsDataWithLength.Data;
|
||||||
|
dataSize -= 4;
|
||||||
|
tlsLength = Endian32(eap_packet->Tls.TlsDataWithLength.TlsLength);
|
||||||
|
}
|
||||||
|
/*Debug("=======RECV EAP-TLS PACKET DUMP=======\n");
|
||||||
|
for (i = 0; i < dataSize; i++)
|
||||||
|
{
|
||||||
|
if (i > 0) printf(" ");
|
||||||
|
Debug("%02X", dataBuffer[i]);
|
||||||
|
}
|
||||||
|
Debug("\n=======RECV EAP-TLS PACKET DUMP END=======\n");*/
|
||||||
|
if (eap_packet->Tls.Flags & PPP_EAP_TLS_FLAG_FRAGMENTED)
|
||||||
|
{
|
||||||
|
isFragmented = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->PPPStatus == PPP_STATUS_AUTHENTICATING)
|
||||||
|
{
|
||||||
|
// First we initialize the SslPipe if it is not already inited
|
||||||
|
if (p->Eap_TlsCtx.SslPipe == NULL)
|
||||||
|
{
|
||||||
|
p->Eap_TlsCtx.Dh = DhNewFromBits(DH_PARAM_BITS_DEFAULT);
|
||||||
|
p->Eap_TlsCtx.SslPipe = NewSslPipeEx3(true, p->Cedar->ServerX, p->Cedar->ServerK, p->Cedar->ServerChain, p->Eap_TlsCtx.Dh, true, &(p->Eap_TlsCtx.ClientCert), p->Eap_TlsCtx.DisableTls13SessionTickets, p->Eap_TlsCtx.DisableTls13);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the current frame is fragmented, or it is a possible last of a fragmented series, bufferize it
|
||||||
|
if (isFragmented || p->Eap_TlsCtx.CachedBufferRecv != NULL)
|
||||||
|
{
|
||||||
|
if (p->Eap_TlsCtx.CachedBufferRecv == NULL && tlsLength > 0)
|
||||||
|
{
|
||||||
|
p->Eap_TlsCtx.CachedBufferRecv = ZeroMalloc(MAX(dataSize, tlsLength));
|
||||||
|
p->Eap_TlsCtx.CachedBufferRecvPntr = p->Eap_TlsCtx.CachedBufferRecv;
|
||||||
|
}
|
||||||
|
else if (p->Eap_TlsCtx.CachedBufferRecv == NULL)
|
||||||
|
{
|
||||||
|
p->Eap_TlsCtx.CachedBufferRecv = ZeroMalloc(MAX(dataSize, PPP_MRU_MAX * 10)); // 10 MRUs should be enough
|
||||||
|
p->Eap_TlsCtx.CachedBufferRecvPntr = p->Eap_TlsCtx.CachedBufferRecv;
|
||||||
|
}
|
||||||
|
sizeLeft = GetMemSize(p->Eap_TlsCtx.CachedBufferRecv);
|
||||||
|
sizeLeft -= (UINT)(p->Eap_TlsCtx.CachedBufferRecvPntr - p->Eap_TlsCtx.CachedBufferRecv);
|
||||||
|
|
||||||
|
Copy(p->Eap_TlsCtx.CachedBufferRecvPntr, dataBuffer, MIN(sizeLeft, dataSize));
|
||||||
|
|
||||||
|
p->Eap_TlsCtx.CachedBufferRecvPntr += MIN(sizeLeft, dataSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we got a cached buffer, we should feed the FIFOs via it
|
||||||
|
if (p->Eap_TlsCtx.CachedBufferRecv != NULL)
|
||||||
|
{
|
||||||
|
dataBuffer = p->Eap_TlsCtx.CachedBufferRecv;
|
||||||
|
dataSize = GetMemSize(p->Eap_TlsCtx.CachedBufferRecv);
|
||||||
|
if (dataSize == MAX_BUFFERING_PACKET_SIZE)
|
||||||
|
{
|
||||||
|
dataSize = (UINT)(p->Eap_TlsCtx.CachedBufferRecvPntr - p->Eap_TlsCtx.CachedBufferRecv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just acknoweldge that we buffered the fragmented data
|
||||||
|
if (isFragmented)
|
||||||
|
{
|
||||||
|
p->Eap_PacketId = p->NextId++;
|
||||||
|
PPP_LCP *lcp = BuildEAPTlsRequest(p->Eap_PacketId, 0, PPP_EAP_TLS_FLAG_NONE);
|
||||||
|
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
|
||||||
|
{
|
||||||
|
PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
|
WHERE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Debug("Sent EAP-TLS size=%i\n", lcp->DataSize);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// It probably should be the final ACK on closed SSL pipe
|
bool syncOk;
|
||||||
SyncSslPipe(p->Eap_TlsCtx.SslPipe);
|
/*Debug("=======RECV EAP-TLS FIFO DUMP=======\n");
|
||||||
|
for (i = 0; i < dataSize; i++)
|
||||||
|
{
|
||||||
|
if (i > 0) printf(" ");
|
||||||
|
Debug("%02X", dataBuffer[i]);
|
||||||
|
}
|
||||||
|
Debug("\n=======RECV EAP-TLS PACKET FIFO END=======\n");*/
|
||||||
|
WriteFifo(p->Eap_TlsCtx.SslPipe->RawIn->SendFifo, dataBuffer, dataSize);
|
||||||
|
syncOk = SyncSslPipe(p->Eap_TlsCtx.SslPipe);
|
||||||
|
|
||||||
|
// Delete the cached buffer after we fed it into the pipe
|
||||||
|
if (p->Eap_TlsCtx.CachedBufferRecv != NULL)
|
||||||
|
{
|
||||||
|
Free(p->Eap_TlsCtx.CachedBufferRecv);
|
||||||
|
p->Eap_TlsCtx.CachedBufferRecv = NULL;
|
||||||
|
p->Eap_TlsCtx.CachedBufferRecvPntr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Very special case - we attempt to restart without TLS 1.3
|
||||||
|
if (!syncOk && (p->Eap_TlsCtx.DisableTls13 == false || p->Eap_TlsCtx.DisableTls13SessionTickets == false))
|
||||||
|
{
|
||||||
|
FreeSslPipe(p->Eap_TlsCtx.SslPipe);
|
||||||
|
DhFree(p->Eap_TlsCtx.Dh);
|
||||||
|
p->Eap_TlsCtx.SslPipe = NULL;
|
||||||
|
p->Eap_TlsCtx.Dh = NULL;
|
||||||
|
if (p->Eap_TlsCtx.DisableTls13SessionTickets == true)
|
||||||
|
{
|
||||||
|
p->Eap_TlsCtx.DisableTls13 = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->Eap_TlsCtx.DisableTls13SessionTickets = true;
|
||||||
|
}
|
||||||
|
flags |= PPP_EAP_TLS_FLAG_SSLSTARTED;
|
||||||
|
p->Eap_PacketId = p->NextId++;
|
||||||
|
lcp = BuildEAPTlsRequest(p->Eap_PacketId, 0, flags);
|
||||||
|
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
|
||||||
|
{
|
||||||
|
PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
|
WHERE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Debug("EAP-TLS: Restarting the handshake! DisableTls13SessionTickets = %d, DisableTls13 = %d\n", p->Eap_TlsCtx.DisableTls13SessionTickets, p->Eap_TlsCtx.DisableTls13);
|
||||||
|
Debug("Sent EAP-TLS size=%i\n", lcp->DataSize);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We continue the TLS handshake
|
||||||
|
if (p->Eap_TlsCtx.SslPipe->IsDisconnected == false)
|
||||||
|
{
|
||||||
|
dataSize = FifoSize(p->Eap_TlsCtx.SslPipe->RawOut->RecvFifo);
|
||||||
|
// Do we need to send a fragmented packet?
|
||||||
|
if (dataSize > p->Mru1 - 8 - 1 - 1)
|
||||||
|
{
|
||||||
|
if (p->Eap_TlsCtx.CachedBufferSend == NULL)
|
||||||
|
{
|
||||||
|
p->Eap_TlsCtx.CachedBufferSend = ZeroMalloc(dataSize);
|
||||||
|
p->Eap_TlsCtx.CachedBufferSendPntr = p->Eap_TlsCtx.CachedBufferSend;
|
||||||
|
}
|
||||||
|
ReadFifo(p->Eap_TlsCtx.SslPipe->RawOut->RecvFifo, p->Eap_TlsCtx.CachedBufferSend, dataSize);
|
||||||
|
|
||||||
|
// Now send data from the cached buffer with set fragmentation flag and also total TLS Size
|
||||||
|
tlsLength = dataSize;
|
||||||
|
dataSize = p->Mru1 - 8 - 1 - 1 - 4; // Calculating the maximum payload size (adjusting for including TlsLength)
|
||||||
|
flags = PPP_EAP_TLS_FLAG_TLS_LENGTH; // L flag
|
||||||
|
flags |= PPP_EAP_TLS_FLAG_FRAGMENTED; // M flag
|
||||||
|
p->Eap_PacketId = p->NextId++;
|
||||||
|
lcp = BuildEAPTlsRequest(p->Eap_PacketId, dataSize, flags);
|
||||||
|
eap = lcp->Data;
|
||||||
|
eap->Tls.TlsDataWithLength.TlsLength = Endian32(tlsLength);
|
||||||
|
Copy(eap->Tls.TlsDataWithLength.Data, p->Eap_TlsCtx.CachedBufferSend, dataSize);
|
||||||
|
p->Eap_TlsCtx.CachedBufferSendPntr += dataSize;
|
||||||
|
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
|
||||||
|
{
|
||||||
|
PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
|
WHERE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Debug("Sent EAP-TLS size=%i type=%i flag=%i\n", lcp->DataSize, eap->Type, eap->Tls.Flags);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (dataSize > 0 || p->Eap_TlsCtx.ClientCert.X == NULL)
|
||||||
|
{
|
||||||
|
p->Eap_PacketId = p->NextId++;
|
||||||
|
lcp = BuildEAPTlsRequest(p->Eap_PacketId, dataSize, 0);
|
||||||
|
eap = lcp->Data;
|
||||||
|
ReadFifo(p->Eap_TlsCtx.SslPipe->RawOut->RecvFifo, &(eap->Tls.TlsDataWithoutLength), dataSize);
|
||||||
|
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
|
||||||
|
{
|
||||||
|
PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
|
WHERE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Debug("Sent EAP-TLS size=%i type=%i flag=%i\n", lcp->DataSize, eap->Type, eap->Tls.Flags);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we received the client certificate and the handshake is finished
|
||||||
|
// If yes, we ignore everything else
|
||||||
if (p->Eap_TlsCtx.ClientCert.X != NULL)
|
if (p->Eap_TlsCtx.ClientCert.X != NULL)
|
||||||
{
|
{
|
||||||
IPC* ipc;
|
IPC* ipc;
|
||||||
ETHERIP_ID d;
|
|
||||||
UINT error_code;
|
UINT error_code;
|
||||||
|
/*PPP_PACKET* pack;
|
||||||
|
|
||||||
|
// Send an ACK that we received the last packet
|
||||||
|
if (!p->Eap_TlsCtx.SslPipe->IsDisconnected)
|
||||||
|
{
|
||||||
|
p->Eap_PacketId = p->NextId++;
|
||||||
|
lcp = BuildEAPTlsRequest(p->Eap_PacketId, 0, 0);
|
||||||
|
eap = lcp->Data;
|
||||||
|
pack = ZeroMalloc(sizeof(PPP_PACKET));
|
||||||
|
pack->IsControl = true;
|
||||||
|
pack->Protocol = PPP_PROTOCOL_EAP;
|
||||||
|
pack->Lcp = lcp;
|
||||||
|
Debug("Sent EAP-TLS size=%i type=%i flag=%i\n", lcp->DataSize, eap->Type, eap->Tls.Flags);
|
||||||
|
if (PPPSendPacketAndFree(p, pack) == false)
|
||||||
|
{
|
||||||
|
PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
|
WHERE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
/*if (!p->Eap_TlsCtx.SslPipe->IsDisconnected)
|
/*if (!p->Eap_TlsCtx.SslPipe->IsDisconnected)
|
||||||
{
|
{
|
||||||
@ -3498,9 +3717,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
|
|||||||
return true;
|
return true;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
PPPParseUsername(p->Cedar, p->Eap_Identity, &d);
|
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, p->Eap_Identity.HubName, p->Eap_Identity.UserName, "", NULL,
|
||||||
|
|
||||||
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, d.HubName, d.UserName, "", NULL,
|
|
||||||
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
|
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
|
||||||
p->ClientHostname, p->CryptName, false, p->AdjustMss, NULL, p->Eap_TlsCtx.ClientCert.X,
|
p->ClientHostname, p->CryptName, false, p->AdjustMss, NULL, p->Eap_TlsCtx.ClientCert.X,
|
||||||
IPC_LAYER_3);
|
IPC_LAYER_3);
|
||||||
@ -3560,165 +3777,29 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
// If we end up here, we got problems, send an EAP failure
|
||||||
|
if (p->Eap_TlsCtx.SslPipe->IsDisconnected)
|
||||||
{
|
{
|
||||||
// Some clients needs a little help it seems - namely VPN Client Pro on Android
|
PPP_PACKET* pack;
|
||||||
flags |= PPP_EAP_TLS_FLAG_SSLSTARTED;
|
UINT identificator = p->Eap_PacketId;
|
||||||
p->Eap_PacketId = p->NextId++;
|
|
||||||
lcp = BuildEAPTlsRequest(p->Eap_PacketId, 0, flags);
|
PPPSetStatus(p, PPP_STATUS_AUTH_FAIL);
|
||||||
PPPSetStatus(p, PPP_STATUS_AUTHENTICATING);
|
|
||||||
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
|
pack = ZeroMalloc(sizeof(PPP_PACKET));
|
||||||
|
pack->IsControl = true;
|
||||||
|
pack->Protocol = PPP_PROTOCOL_EAP;
|
||||||
|
lcp = NewPPPLCP(PPP_EAP_CODE_FAILURE, identificator);
|
||||||
|
pack->Lcp = lcp;
|
||||||
|
Debug("Sent EAP-TLS size=%i FAILURE\n", lcp->DataSize);
|
||||||
|
if (PPPSendPacketAndFree(p, pack) == false)
|
||||||
{
|
{
|
||||||
PPPSetStatus(p, PPP_STATUS_FAIL);
|
PPPSetStatus(p, PPP_STATUS_FAIL);
|
||||||
WHERE;
|
WHERE;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Debug("Sent EAP-TLS size=%i\n", lcp->DataSize);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
dataBuffer = eap_packet->Tls.TlsDataWithoutLength;
|
|
||||||
dataSize = eapTlsSize - 1;
|
|
||||||
if (eap_packet->Tls.Flags & PPP_EAP_TLS_FLAG_TLS_LENGTH)
|
|
||||||
{
|
|
||||||
dataBuffer = eap_packet->Tls.TlsDataWithLength.Data;
|
|
||||||
dataSize -= 4;
|
|
||||||
tlsLength = Endian32(eap_packet->Tls.TlsDataWithLength.TlsLength);
|
|
||||||
}
|
|
||||||
/*Debug("=======RECV EAP-TLS PACKET DUMP=======\n");
|
|
||||||
for (i = 0; i < dataSize; i++)
|
|
||||||
{
|
|
||||||
if (i > 0) printf(" ");
|
|
||||||
Debug("%02X", dataBuffer[i]);
|
|
||||||
}
|
|
||||||
Debug("\n=======RECV EAP-TLS PACKET DUMP END=======\n");*/
|
|
||||||
if (eap_packet->Tls.Flags & PPP_EAP_TLS_FLAG_FRAGMENTED)
|
|
||||||
{
|
|
||||||
isFragmented = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p->PPPStatus == PPP_STATUS_AUTHENTICATING)
|
|
||||||
{
|
|
||||||
// First we initialize the SslPipe if it is not already inited
|
|
||||||
if (p->Eap_TlsCtx.SslPipe == NULL)
|
|
||||||
{
|
|
||||||
p->Eap_TlsCtx.Dh = DhNewFromBits(DH_PARAM_BITS_DEFAULT);
|
|
||||||
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 (isFragmented || p->Eap_TlsCtx.CachedBufferRecv != NULL)
|
|
||||||
{
|
|
||||||
if (p->Eap_TlsCtx.CachedBufferRecv == NULL && tlsLength > 0)
|
|
||||||
{
|
|
||||||
p->Eap_TlsCtx.CachedBufferRecv = ZeroMalloc(MAX(dataSize, tlsLength));
|
|
||||||
p->Eap_TlsCtx.CachedBufferRecvPntr = p->Eap_TlsCtx.CachedBufferRecv;
|
|
||||||
}
|
|
||||||
else if (p->Eap_TlsCtx.CachedBufferRecv == NULL)
|
|
||||||
{
|
|
||||||
p->Eap_TlsCtx.CachedBufferRecv = ZeroMalloc(MAX(dataSize, PPP_MRU_MAX * 10)); // 10 MRUs should be enough
|
|
||||||
p->Eap_TlsCtx.CachedBufferRecvPntr = p->Eap_TlsCtx.CachedBufferRecv;
|
|
||||||
}
|
|
||||||
sizeLeft = GetMemSize(p->Eap_TlsCtx.CachedBufferRecv);
|
|
||||||
sizeLeft -= (UINT)(p->Eap_TlsCtx.CachedBufferRecvPntr - p->Eap_TlsCtx.CachedBufferRecv);
|
|
||||||
|
|
||||||
Copy(p->Eap_TlsCtx.CachedBufferRecvPntr, dataBuffer, MIN(sizeLeft, dataSize));
|
|
||||||
|
|
||||||
p->Eap_TlsCtx.CachedBufferRecvPntr += MIN(sizeLeft, dataSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we got a cached buffer, we should feed the FIFOs via it
|
|
||||||
if (p->Eap_TlsCtx.CachedBufferRecv != NULL)
|
|
||||||
{
|
|
||||||
dataBuffer = p->Eap_TlsCtx.CachedBufferRecv;
|
|
||||||
dataSize = GetMemSize(p->Eap_TlsCtx.CachedBufferRecv);
|
|
||||||
if (dataSize == MAX_BUFFERING_PACKET_SIZE)
|
|
||||||
{
|
|
||||||
dataSize = (UINT)(p->Eap_TlsCtx.CachedBufferRecvPntr - p->Eap_TlsCtx.CachedBufferRecv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just acknoweldge that we buffered the fragmented data
|
|
||||||
if (isFragmented)
|
|
||||||
{
|
|
||||||
p->Eap_PacketId = p->NextId++;
|
|
||||||
PPP_LCP *lcp = BuildEAPTlsRequest(p->Eap_PacketId, 0, PPP_EAP_TLS_FLAG_NONE);
|
|
||||||
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
|
|
||||||
{
|
|
||||||
PPPSetStatus(p, PPP_STATUS_FAIL);
|
|
||||||
WHERE;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Debug("Sent EAP-TLS size=%i\n", lcp->DataSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*Debug("=======RECV EAP-TLS FIFO DUMP=======\n");
|
|
||||||
for (i = 0; i < dataSize; i++)
|
|
||||||
{
|
|
||||||
if (i > 0) printf(" ");
|
|
||||||
Debug("%02X", dataBuffer[i]);
|
|
||||||
}
|
|
||||||
Debug("\n=======RECV EAP-TLS PACKET FIFO END=======\n");*/
|
|
||||||
WriteFifo(p->Eap_TlsCtx.SslPipe->RawIn->SendFifo, dataBuffer, dataSize);
|
|
||||||
SyncSslPipe(p->Eap_TlsCtx.SslPipe);
|
|
||||||
// Delete the cached buffer after we fed it into the pipe
|
|
||||||
if (p->Eap_TlsCtx.CachedBufferRecv != NULL)
|
|
||||||
{
|
|
||||||
Free(p->Eap_TlsCtx.CachedBufferRecv);
|
|
||||||
p->Eap_TlsCtx.CachedBufferRecv = NULL;
|
|
||||||
p->Eap_TlsCtx.CachedBufferRecvPntr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p->Eap_TlsCtx.SslPipe->IsDisconnected == false)
|
|
||||||
{
|
|
||||||
dataSize = FifoSize(p->Eap_TlsCtx.SslPipe->RawOut->RecvFifo);
|
|
||||||
// Do we need to send a fragmented packet?
|
|
||||||
if (dataSize > p->Mru1 - 8 - 1 - 1)
|
|
||||||
{
|
|
||||||
if (p->Eap_TlsCtx.CachedBufferSend == NULL)
|
|
||||||
{
|
|
||||||
p->Eap_TlsCtx.CachedBufferSend = ZeroMalloc(dataSize);
|
|
||||||
p->Eap_TlsCtx.CachedBufferSendPntr = p->Eap_TlsCtx.CachedBufferSend;
|
|
||||||
}
|
|
||||||
ReadFifo(p->Eap_TlsCtx.SslPipe->RawOut->RecvFifo, p->Eap_TlsCtx.CachedBufferSend, dataSize);
|
|
||||||
|
|
||||||
// Now send data from the cached buffer with set fragmentation flag and also total TLS Size
|
|
||||||
tlsLength = dataSize;
|
|
||||||
dataSize = p->Mru1 - 8 - 1 - 1 - 4; // Calculating the maximum payload size (adjusting for including TlsLength)
|
|
||||||
flags = PPP_EAP_TLS_FLAG_TLS_LENGTH; // L flag
|
|
||||||
flags |= PPP_EAP_TLS_FLAG_FRAGMENTED; // M flag
|
|
||||||
p->Eap_PacketId = p->NextId++;
|
|
||||||
lcp = BuildEAPTlsRequest(p->Eap_PacketId, dataSize, flags);
|
|
||||||
eap = lcp->Data;
|
|
||||||
eap->Tls.TlsDataWithLength.TlsLength = Endian32(tlsLength);
|
|
||||||
Copy(eap->Tls.TlsDataWithLength.Data, p->Eap_TlsCtx.CachedBufferSend, dataSize);
|
|
||||||
p->Eap_TlsCtx.CachedBufferSendPntr += dataSize;
|
|
||||||
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
|
|
||||||
{
|
|
||||||
PPPSetStatus(p, PPP_STATUS_FAIL);
|
|
||||||
WHERE;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Debug("Sent EAP-TLS size=%i type=%i flag=%i\n", lcp->DataSize, eap->Type, eap->Tls.Flags);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p->Eap_PacketId = p->NextId++;
|
|
||||||
lcp = BuildEAPTlsRequest(p->Eap_PacketId, dataSize, 0);
|
|
||||||
eap = lcp->Data;
|
|
||||||
ReadFifo(p->Eap_TlsCtx.SslPipe->RawOut->RecvFifo, &(eap->Tls.TlsDataWithoutLength), dataSize);
|
|
||||||
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp) == false)
|
|
||||||
{
|
|
||||||
PPPSetStatus(p, PPP_STATUS_FAIL);
|
|
||||||
WHERE;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Debug("Sent EAP-TLS size=%i type=%i flag=%i\n", lcp->DataSize, eap->Type, eap->Tls.Flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#define PROTO_PPP_H
|
#define PROTO_PPP_H
|
||||||
|
|
||||||
#include "CedarType.h"
|
#include "CedarType.h"
|
||||||
|
#include "Proto_IPsec.h"
|
||||||
|
|
||||||
#include "Mayaqua/TcpIp.h"
|
#include "Mayaqua/TcpIp.h"
|
||||||
|
|
||||||
@ -229,6 +230,8 @@ struct PPP_EAP_TLS_CONTEXT
|
|||||||
UCHAR *CachedBufferRecvPntr;
|
UCHAR *CachedBufferRecvPntr;
|
||||||
UCHAR *CachedBufferSend;
|
UCHAR *CachedBufferSend;
|
||||||
UCHAR *CachedBufferSendPntr;
|
UCHAR *CachedBufferSendPntr;
|
||||||
|
bool DisableTls13;
|
||||||
|
bool DisableTls13SessionTickets;
|
||||||
};
|
};
|
||||||
|
|
||||||
// PPP request resend
|
// PPP request resend
|
||||||
@ -302,7 +305,7 @@ struct PPP_SESSION
|
|||||||
// EAP contexts
|
// EAP contexts
|
||||||
UINT Eap_Protocol; // Current EAP Protocol used
|
UINT Eap_Protocol; // Current EAP Protocol used
|
||||||
UINT Eap_PacketId; // EAP Packet ID;
|
UINT Eap_PacketId; // EAP Packet ID;
|
||||||
UCHAR Eap_Identity[MAX_SIZE]; // Received from client identity
|
ETHERIP_ID Eap_Identity; // Received from client identity
|
||||||
PPP_EAP_TLS_CONTEXT Eap_TlsCtx; // Context information for EAP TLS. May be possibly reused for EAP TTLS?
|
PPP_EAP_TLS_CONTEXT Eap_TlsCtx; // Context information for EAP TLS. May be possibly reused for EAP TTLS?
|
||||||
|
|
||||||
LIST *SentReqPacketList; // Sent requests list
|
LIST *SentReqPacketList; // Sent requests list
|
||||||
@ -387,7 +390,7 @@ bool PPPSetIPOptionToLCP(PPP_IPOPTION *o, PPP_LCP *c, bool only_modify);
|
|||||||
bool PPPGetIPAddressValueFromLCP(PPP_LCP *c, UINT type, IP *ip);
|
bool PPPGetIPAddressValueFromLCP(PPP_LCP *c, UINT type, IP *ip);
|
||||||
bool PPPSetIPAddressValueToLCP(PPP_LCP *c, UINT type, IP *ip, bool only_modify);
|
bool PPPSetIPAddressValueToLCP(PPP_LCP *c, UINT type, IP *ip, bool only_modify);
|
||||||
// EAP packet utilities
|
// EAP packet utilities
|
||||||
bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSize);
|
bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapSize);
|
||||||
PPP_LCP *BuildEAPPacketEx(UCHAR code, UCHAR id, UCHAR type, UINT datasize);
|
PPP_LCP *BuildEAPPacketEx(UCHAR code, UCHAR id, UCHAR type, UINT datasize);
|
||||||
PPP_LCP *BuildEAPTlsPacketEx(UCHAR code, UCHAR id, UCHAR type, UINT datasize, UCHAR flags);
|
PPP_LCP *BuildEAPTlsPacketEx(UCHAR code, UCHAR id, UCHAR type, UINT datasize, UCHAR flags);
|
||||||
PPP_LCP *BuildEAPTlsRequest(UCHAR id, UINT datasize, UCHAR flags);
|
PPP_LCP *BuildEAPTlsRequest(UCHAR id, UINT datasize, UCHAR flags);
|
||||||
|
@ -5713,7 +5713,13 @@ SSL_PIPE *NewSslPipeEx(bool server_mode, X *x, K *k, DH_CTX *dh, bool verify_pee
|
|||||||
{
|
{
|
||||||
return NewSslPipeEx2(server_mode, x, k, NULL, dh, verify_peer, 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* NewSslPipeEx2(bool server_mode, X* x, K* k, LIST* chain, DH_CTX* dh, bool verify_peer, struct SslClientCertInfo* clientcert)
|
||||||
|
{
|
||||||
|
return NewSslPipeEx3(server_mode, x, k, chain, dh, verify_peer, clientcert, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
SSL_PIPE *NewSslPipeEx3(bool server_mode, X *x, K *k, LIST *chain, DH_CTX *dh, bool verify_peer, struct SslClientCertInfo *clientcert, bool disableTls13Tickets, bool disableTls13)
|
||||||
{
|
{
|
||||||
SSL_PIPE *s;
|
SSL_PIPE *s;
|
||||||
SSL *ssl;
|
SSL *ssl;
|
||||||
@ -5723,10 +5729,6 @@ SSL_PIPE *NewSslPipeEx2(bool server_mode, X *x, K *k, LIST *chain, DH_CTX *dh, b
|
|||||||
{
|
{
|
||||||
if (server_mode)
|
if (server_mode)
|
||||||
{
|
{
|
||||||
#ifdef SSL_OP_NO_TLSv1_3
|
|
||||||
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_3); // For some reason pppd under linux doesn't like it
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (chain == NULL)
|
if (chain == NULL)
|
||||||
{
|
{
|
||||||
AddChainSslCertOnDirectory(ssl_ctx);
|
AddChainSslCertOnDirectory(ssl_ctx);
|
||||||
@ -5784,6 +5786,18 @@ SSL_PIPE *NewSslPipeEx2(bool server_mode, X *x, K *k, LIST *chain, DH_CTX *dh, b
|
|||||||
SSL_CTX_set_options(ssl_ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
|
SSL_CTX_set_options(ssl_ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SSL_OP_NO_TLSv1_3
|
||||||
|
if (disableTls13)
|
||||||
|
{
|
||||||
|
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_3);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disableTls13Tickets)
|
||||||
|
{
|
||||||
|
SSL_CTX_set_num_tickets(ssl_ctx, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ssl = SSL_new(ssl_ctx);
|
ssl = SSL_new(ssl_ctx);
|
||||||
|
|
||||||
SSL_set_ex_data(ssl, GetSslClientCertIndex(), clientcert);
|
SSL_set_ex_data(ssl, GetSslClientCertIndex(), clientcert);
|
||||||
@ -15832,6 +15846,14 @@ DH *TmpDhCallback(SSL *ssl, int is_export, int keylength)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log SSL keys
|
||||||
|
void keylog_cb_func(const SSL* ssl, const char* line)
|
||||||
|
{
|
||||||
|
Debug("SSL_KEYLOG_BEGIN\n");
|
||||||
|
Debug(line);
|
||||||
|
Debug("\nSSL_KEYLOG_END\n");
|
||||||
|
}
|
||||||
|
|
||||||
// Create the SSL_CTX
|
// Create the SSL_CTX
|
||||||
struct ssl_ctx_st *NewSSLCtx(bool server_mode)
|
struct ssl_ctx_st *NewSSLCtx(bool server_mode)
|
||||||
{
|
{
|
||||||
@ -15868,6 +15890,8 @@ struct ssl_ctx_st *NewSSLCtx(bool server_mode)
|
|||||||
SSL_CTX_set_ecdh_auto(ctx, 1);
|
SSL_CTX_set_ecdh_auto(ctx, 1);
|
||||||
#endif // SSL_CTX_set_ecdh_auto
|
#endif // SSL_CTX_set_ecdh_auto
|
||||||
|
|
||||||
|
SSL_CTX_set_keylog_callback(ctx, &keylog_cb_func);
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1407,6 +1407,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);
|
SSL_PIPE *NewSslPipeEx2(bool server_mode, X *x, K *k, LIST *chain, DH_CTX *dh, bool verify_peer, struct SslClientCertInfo *clientcert);
|
||||||
|
SSL_PIPE* NewSslPipeEx3(bool server_mode, X* x, K* k, LIST* chain, DH_CTX* dh, bool verify_peer, struct SslClientCertInfo* clientcert, bool disableTls13Tickets, bool disableTls13);
|
||||||
void FreeSslPipe(SSL_PIPE *s);
|
void FreeSslPipe(SSL_PIPE *s);
|
||||||
bool SyncSslPipe(SSL_PIPE *s);
|
bool SyncSslPipe(SSL_PIPE *s);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user