mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-02 12:14:38 +02:00
Merge pull request #3296 from dgarske/sniffer_fixes
Fixes for Sniffer (Max Fragment, ECC Static and SNI)
This commit is contained in:
167
src/sniffer.c
167
src/sniffer.c
@@ -452,6 +452,11 @@ typedef struct SnifferSession {
|
|||||||
word32 srvReassemblyMemory; /* server packet memory used */
|
word32 srvReassemblyMemory; /* server packet memory used */
|
||||||
struct SnifferSession* next; /* for hash table list */
|
struct SnifferSession* next; /* for hash table list */
|
||||||
byte* ticketID; /* mac ID of session ticket */
|
byte* ticketID; /* mac ID of session ticket */
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
byte* tlsFragBuf;
|
||||||
|
word32 tlsFragOffset;
|
||||||
|
word32 tlsFragSize;
|
||||||
|
#endif
|
||||||
#ifdef HAVE_SNI
|
#ifdef HAVE_SNI
|
||||||
const char* sni; /* server name indication */
|
const char* sni; /* server name indication */
|
||||||
#endif
|
#endif
|
||||||
@@ -648,6 +653,12 @@ static void FreeSnifferSession(SnifferSession* session)
|
|||||||
#ifdef WOLFSSL_TLS13
|
#ifdef WOLFSSL_TLS13
|
||||||
if (session->cliKeyShare)
|
if (session->cliKeyShare)
|
||||||
XFREE(session->cliKeyShare, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(session->cliKeyShare, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
if (session->tlsFragBuf) {
|
||||||
|
XFREE(session->tlsFragBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
session->tlsFragBuf = NULL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
XFREE(session, NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
|
XFREE(session, NULL, DYNAMIC_TYPE_SNIFFER_SESSION);
|
||||||
@@ -666,14 +677,7 @@ void ssl_FreeSniffer(void)
|
|||||||
wc_LockMutex(&ServerListMutex);
|
wc_LockMutex(&ServerListMutex);
|
||||||
wc_LockMutex(&SessionMutex);
|
wc_LockMutex(&SessionMutex);
|
||||||
|
|
||||||
srv = ServerList;
|
/* Free sessions (wolfSSL objects) first */
|
||||||
while (srv) {
|
|
||||||
removeServer = srv;
|
|
||||||
srv = srv->next;
|
|
||||||
FreeSnifferServer(removeServer);
|
|
||||||
}
|
|
||||||
ServerList = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < HASH_SIZE; i++) {
|
for (i = 0; i < HASH_SIZE; i++) {
|
||||||
session = SessionTable[i];
|
session = SessionTable[i];
|
||||||
while (session) {
|
while (session) {
|
||||||
@@ -684,6 +688,15 @@ void ssl_FreeSniffer(void)
|
|||||||
}
|
}
|
||||||
SessionCount = 0;
|
SessionCount = 0;
|
||||||
|
|
||||||
|
/* Then server (wolfSSL_CTX) */
|
||||||
|
srv = ServerList;
|
||||||
|
while (srv) {
|
||||||
|
removeServer = srv;
|
||||||
|
srv = srv->next;
|
||||||
|
FreeSnifferServer(removeServer);
|
||||||
|
}
|
||||||
|
ServerList = NULL;
|
||||||
|
|
||||||
wc_UnLockMutex(&SessionMutex);
|
wc_UnLockMutex(&SessionMutex);
|
||||||
wc_UnLockMutex(&ServerListMutex);
|
wc_UnLockMutex(&ServerListMutex);
|
||||||
|
|
||||||
@@ -1895,7 +1908,7 @@ static int CheckIp6Hdr(Ip6Hdr* iphdr, IpInfo* info, int length, char* error)
|
|||||||
/* returns 0 on success, -1 on error */
|
/* returns 0 on success, -1 on error */
|
||||||
static int CheckIpHdr(IpHdr* iphdr, IpInfo* info, int length, char* error)
|
static int CheckIpHdr(IpHdr* iphdr, IpInfo* info, int length, char* error)
|
||||||
{
|
{
|
||||||
int version = IP_V(iphdr);
|
int version = IP_V(iphdr);
|
||||||
|
|
||||||
if (version == IPV6)
|
if (version == IPV6)
|
||||||
return CheckIp6Hdr((Ip6Hdr*)iphdr, info, length, error);
|
return CheckIp6Hdr((Ip6Hdr*)iphdr, info, length, error);
|
||||||
@@ -2055,6 +2068,11 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
{
|
{
|
||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
int useEccCurveId = ECC_CURVE_DEF;
|
||||||
|
if (ksInfo && ksInfo->curve_id != 0)
|
||||||
|
useEccCurveId = ksInfo->curve_id;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
/* Static RSA */
|
/* Static RSA */
|
||||||
@@ -2074,6 +2092,11 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
SetError(RSA_DECODE_STR, error, session, 0);
|
SetError(RSA_DECODE_STR, error, session, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
else {
|
||||||
|
useEccCurveId = -1; /* don't try loading ECC */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
@@ -2124,7 +2147,7 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
#endif /* !NO_RSA */
|
#endif /* !NO_RSA */
|
||||||
|
|
||||||
#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)
|
#if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)
|
||||||
/* Static Ephemeral DH Key */
|
/* Static DH Key */
|
||||||
if (ksInfo && ksInfo->dh_key_bits != 0) {
|
if (ksInfo && ksInfo->dh_key_bits != 0) {
|
||||||
DhKey dhKey;
|
DhKey dhKey;
|
||||||
const DhParams* params;
|
const DhParams* params;
|
||||||
@@ -2212,8 +2235,8 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
#endif /* !NO_DH && WOLFSSL_DH_EXTRA */
|
#endif /* !NO_DH && WOLFSSL_DH_EXTRA */
|
||||||
|
|
||||||
#ifdef HAVE_ECC
|
#ifdef HAVE_ECC
|
||||||
/* Static Ephemeral ECC Key */
|
/* Static ECC Key */
|
||||||
if (ksInfo && ksInfo->curve_id != 0) {
|
if (useEccCurveId >= ECC_CURVE_DEF) {
|
||||||
ecc_key key;
|
ecc_key key;
|
||||||
ecc_key pubKey;
|
ecc_key pubKey;
|
||||||
int length, keyInit = 0, pubKeyInit = 0;
|
int length, keyInit = 0, pubKeyInit = 0;
|
||||||
@@ -2224,6 +2247,15 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
keyInit = 1;
|
keyInit = 1;
|
||||||
ret = wc_ecc_init(&pubKey);
|
ret = wc_ecc_init(&pubKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
|
||||||
|
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
|
||||||
|
!defined(HAVE_SELFTEST)
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_ecc_set_rng(&key, session->sslServer->rng);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
pubKeyInit = 1;
|
pubKeyInit = 1;
|
||||||
ret = wc_EccPrivateKeyDecode(keyBuf->buffer, &idx, &key, keyBuf->length);
|
ret = wc_EccPrivateKeyDecode(keyBuf->buffer, &idx, &key, keyBuf->length);
|
||||||
@@ -2247,7 +2279,7 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = wc_ecc_import_x963_ex(input, length, &pubKey, ksInfo->curve_id);
|
ret = wc_ecc_import_x963_ex(input, length, &pubKey, useEccCurveId);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE);
|
SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE);
|
||||||
}
|
}
|
||||||
@@ -2743,12 +2775,34 @@ static int ProcessServerHello(int msgSz, const byte* input, int* sslBytes,
|
|||||||
session->sslClient->session.ticketNonce.len = 1;
|
session->sslClient->session.ticketNonce.len = 1;
|
||||||
session->sslClient->session.ticketNonce.data[0] = 0;
|
session->sslClient->session.ticketNonce.data[0] = 0;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
case EXT_MAX_FRAGMENT_LENGTH:
|
||||||
|
{
|
||||||
|
word16 max_fragment = MAX_RECORD_SIZE;
|
||||||
|
switch (input[0]) {
|
||||||
|
case WOLFSSL_MFL_2_8 : max_fragment = 256; break;
|
||||||
|
case WOLFSSL_MFL_2_9 : max_fragment = 512; break;
|
||||||
|
case WOLFSSL_MFL_2_10: max_fragment = 1024; break;
|
||||||
|
case WOLFSSL_MFL_2_11: max_fragment = 2048; break;
|
||||||
|
case WOLFSSL_MFL_2_12: max_fragment = 4096; break;
|
||||||
|
case WOLFSSL_MFL_2_13: max_fragment = 8192; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
session->sslServer->max_fragment = max_fragment;
|
||||||
|
session->sslClient->max_fragment = max_fragment;
|
||||||
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
case EXT_SUPPORTED_VERSIONS:
|
case EXT_SUPPORTED_VERSIONS:
|
||||||
session->sslServer->version.major = input[0];
|
session->sslServer->version.major = input[0];
|
||||||
session->sslServer->version.minor = input[1];
|
session->sslServer->version.minor = input[1];
|
||||||
session->sslClient->version.major = input[0];
|
session->sslClient->version.major = input[0];
|
||||||
session->sslClient->version.minor = input[1];
|
session->sslClient->version.minor = input[1];
|
||||||
|
if (IsAtLeastTLSv1_3(session->sslServer->version)) {
|
||||||
|
/* The server side handshake encryption is on for future packets */
|
||||||
|
session->flags.serverCipherOn = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EXT_MASTER_SECRET:
|
case EXT_MASTER_SECRET:
|
||||||
#ifdef HAVE_EXTENDED_MASTER
|
#ifdef HAVE_EXTENDED_MASTER
|
||||||
@@ -2971,6 +3025,10 @@ static int ProcessClientHello(const byte* input, int* sslBytes,
|
|||||||
}
|
}
|
||||||
wc_UnLockMutex(&session->context->namedKeysMutex);
|
wc_UnLockMutex(&session->context->namedKeysMutex);
|
||||||
}
|
}
|
||||||
|
if (ret > 0) {
|
||||||
|
/* make sure WOLFSSL_SUCCESS is converted to zero error code */
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -3098,9 +3156,6 @@ static int ProcessClientHello(const byte* input, int* sslBytes,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
XMEMCPY(session->cliKeyShare, &input[2], ksLen);
|
XMEMCPY(session->cliKeyShare, &input[2], ksLen);
|
||||||
|
|
||||||
/* The server side handshake encryption is on for future packets */
|
|
||||||
session->flags.serverCipherOn = 1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_SESSION_TICKET
|
#ifdef HAVE_SESSION_TICKET
|
||||||
@@ -3252,7 +3307,6 @@ static int KeyWatchCall(SnifferSession* session, const byte* data, int dataSz,
|
|||||||
static int ProcessCertificate(const byte* input, int* sslBytes,
|
static int ProcessCertificate(const byte* input, int* sslBytes,
|
||||||
SnifferSession* session, char* error)
|
SnifferSession* session, char* error)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
const byte* certChain;
|
const byte* certChain;
|
||||||
word32 certChainSz;
|
word32 certChainSz;
|
||||||
word32 certSz;
|
word32 certSz;
|
||||||
@@ -3407,13 +3461,32 @@ static int ProcessFinished(const byte* input, int size, int* sslBytes,
|
|||||||
|
|
||||||
/* Process HandShake input */
|
/* Process HandShake input */
|
||||||
static int DoHandShake(const byte* input, int* sslBytes,
|
static int DoHandShake(const byte* input, int* sslBytes,
|
||||||
SnifferSession* session, char* error)
|
SnifferSession* session, char* error, word16 rhSize)
|
||||||
{
|
{
|
||||||
byte type;
|
byte type;
|
||||||
int size;
|
int size;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int startBytes;
|
|
||||||
WOLFSSL* ssl;
|
WOLFSSL* ssl;
|
||||||
|
int startBytes;
|
||||||
|
|
||||||
|
(void)rhSize;
|
||||||
|
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
if (session->tlsFragBuf) {
|
||||||
|
XMEMCPY(session->tlsFragBuf + session->tlsFragOffset, input, rhSize);
|
||||||
|
session->tlsFragOffset += rhSize;
|
||||||
|
*sslBytes -= rhSize;
|
||||||
|
|
||||||
|
if (session->tlsFragOffset < session->tlsFragSize) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reassembled complete fragment */
|
||||||
|
input = session->tlsFragBuf;
|
||||||
|
*sslBytes = session->tlsFragSize;
|
||||||
|
rhSize = session->tlsFragSize;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (*sslBytes < HANDSHAKE_HEADER_SZ) {
|
if (*sslBytes < HANDSHAKE_HEADER_SZ) {
|
||||||
SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
|
SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
|
||||||
@@ -3449,6 +3522,30 @@ static int DoHandShake(const byte* input, int* sslBytes,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
if (rhSize < size) {
|
||||||
|
/* partial fragment, let's reassemble */
|
||||||
|
if (session->tlsFragBuf == NULL) {
|
||||||
|
session->tlsFragOffset = 0;
|
||||||
|
session->tlsFragSize = size + HANDSHAKE_HEADER_SZ;
|
||||||
|
session->tlsFragBuf = (byte*)XMALLOC(session->tlsFragSize, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (session->tlsFragBuf == NULL) {
|
||||||
|
SetError(MEMORY_STR, error, NULL, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* include the handshake header */
|
||||||
|
input -= HANDSHAKE_HEADER_SZ;
|
||||||
|
*sslBytes += HANDSHAKE_HEADER_SZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMEMCPY(session->tlsFragBuf + session->tlsFragOffset, input, rhSize);
|
||||||
|
session->tlsFragOffset += rhSize;
|
||||||
|
*sslBytes -= rhSize;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSL_TLS13
|
#ifdef WOLFSSL_TLS13
|
||||||
if (type != client_hello) {
|
if (type != client_hello) {
|
||||||
/* For resumption the hash is before / after client_hello PSK binder */
|
/* For resumption the hash is before / after client_hello PSK binder */
|
||||||
@@ -3465,7 +3562,8 @@ static int DoHandShake(const byte* input, int* sslBytes,
|
|||||||
if (HashUpdate(session->hash, input, size) != 0) {
|
if (HashUpdate(session->hash, input, size) != 0) {
|
||||||
SetError(EXTENDED_MASTER_HASH_STR, error,
|
SetError(EXTENDED_MASTER_HASH_STR, error,
|
||||||
session, FATAL_ERROR_STATE);
|
session, FATAL_ERROR_STATE);
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -3560,9 +3658,18 @@ static int DoHandShake(const byte* input, int* sslBytes,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SetError(GOT_UNKNOWN_HANDSHAKE_STR, error, session, 0);
|
SetError(GOT_UNKNOWN_HANDSHAKE_STR, error, session, 0);
|
||||||
return -1;
|
ret = -1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
if (session->tlsFragBuf) {
|
||||||
|
XFREE(session->tlsFragBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
session->tlsFragBuf = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
*sslBytes = startBytes - size; /* actual bytes of full process */
|
*sslBytes = startBytes - size; /* actual bytes of full process */
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -3982,6 +4089,9 @@ int TcpChecksum(IpInfo* ipInfo, TcpInfo* tcpInfo, int dataLen,
|
|||||||
static int CheckHeaders(IpInfo* ipInfo, TcpInfo* tcpInfo, const byte* packet,
|
static int CheckHeaders(IpInfo* ipInfo, TcpInfo* tcpInfo, const byte* packet,
|
||||||
int length, const byte** sslFrame, int* sslBytes, char* error)
|
int length, const byte** sslFrame, int* sslBytes, char* error)
|
||||||
{
|
{
|
||||||
|
IpHdr* iphdr = (IpHdr*)packet;
|
||||||
|
int version;
|
||||||
|
|
||||||
TraceHeader();
|
TraceHeader();
|
||||||
TracePacket();
|
TracePacket();
|
||||||
|
|
||||||
@@ -3990,6 +4100,17 @@ static int CheckHeaders(IpInfo* ipInfo, TcpInfo* tcpInfo, const byte* packet,
|
|||||||
SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
|
SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version = IP_V(iphdr);
|
||||||
|
if (version != IPV6 && version != IPV4) {
|
||||||
|
/* Is this VLAN IEEE 802.1Q Frame? TPID = 0x8100 */
|
||||||
|
if (packet[2] == 0x81 && packet[3] == 0x00) {
|
||||||
|
/* trim VLAN header and try again */
|
||||||
|
packet += 8;
|
||||||
|
length -= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (CheckIpHdr((IpHdr*)packet, ipInfo, length, error) != 0)
|
if (CheckIpHdr((IpHdr*)packet, ipInfo, length, error) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -4822,8 +4943,8 @@ doPart:
|
|||||||
int used;
|
int used;
|
||||||
|
|
||||||
Trace(GOT_HANDSHAKE_STR);
|
Trace(GOT_HANDSHAKE_STR);
|
||||||
ret = DoHandShake(sslFrame, &sslBytes, session, error);
|
ret = DoHandShake(sslFrame, &sslBytes, session, error, rhSize);
|
||||||
if (ret != 0) {
|
if (ret != 0 || sslBytes > startIdx) {
|
||||||
if (session->flags.fatalError == 0)
|
if (session->flags.fatalError == 0)
|
||||||
SetError(BAD_HANDSHAKE_STR, error, session,
|
SetError(BAD_HANDSHAKE_STR, error, session,
|
||||||
FATAL_ERROR_STATE);
|
FATAL_ERROR_STATE);
|
||||||
|
@@ -43,9 +43,9 @@ All options may be enabled with the following configure command line:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
./configure --enable-sniffer \
|
./configure --enable-sniffer \
|
||||||
CPPFLAGS=”-DWOLFSSL_SNIFFER_STATS -DWOLFSSL_SNIFFER_WATCH \
|
CPPFLAGS="-DWOLFSSL_SNIFFER_STATS -DWOLFSSL_SNIFFER_WATCH \
|
||||||
-DWOLFSSL_SNIFFER_STORE_DATA_CB -DWOLFSSL_SNIFFER_CHAIN_INPUT \
|
-DWOLFSSL_SNIFFER_STORE_DATA_CB -DWOLFSSL_SNIFFER_CHAIN_INPUT \
|
||||||
-DSTARTTLS_ALLOWED”
|
-DSTARTTLS_ALLOWED"
|
||||||
```
|
```
|
||||||
|
|
||||||
To add some other cipher support to the sniffer, you can add options like:
|
To add some other cipher support to the sniffer, you can add options like:
|
||||||
|
@@ -267,8 +267,11 @@ static int myWatchCb(void* vSniffer,
|
|||||||
certName = DEFAULT_SERVER_KEY_ECC;
|
certName = DEFAULT_SERVER_KEY_ECC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (certName == NULL)
|
if (certName == NULL) {
|
||||||
return -1;
|
/* don't return error if key is not loaded */
|
||||||
|
printf("Warning: No matching key found for cert hash\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return ssl_SetWatchKey_file(vSniffer, certName, FILETYPE_PEM, NULL, error);
|
return ssl_SetWatchKey_file(vSniffer, certName, FILETYPE_PEM, NULL, error);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user