Merge pull request #7973 from bandi13/fixSniffer

Fix sniffer
This commit is contained in:
David Garske
2024-10-29 15:21:41 -07:00
committed by GitHub
4 changed files with 312 additions and 297 deletions

View File

@ -4292,8 +4292,8 @@ static int KeyWatchCall(SnifferSession* session, const byte* data, int dataSz,
char* error)
{
int ret;
Sha256 sha;
byte digest[SHA256_DIGEST_SIZE];
wc_Sha256 sha;
byte digest[WC_SHA256_DIGEST_SIZE];
if (WatchCb == NULL) {
SetError(WATCH_CB_MISSING_STR, error, session, FATAL_ERROR_STATE);
@ -6023,8 +6023,7 @@ static int CheckSequence(IpInfo* ipInfo, TcpInfo* tcpInfo,
/* returns 0 on success (continue), -1 on error, 1 on success (end) */
static int CheckPreRecord(IpInfo* ipInfo, TcpInfo* tcpInfo,
const byte** sslFrame, SnifferSession** pSession,
int* sslBytes, const byte** end,
void* vChain, word32 chainSz, char* error)
int* sslBytes, const byte** end, char* error)
{
word32 length;
SnifferSession* session = *pSession;
@ -6094,53 +6093,12 @@ static int CheckPreRecord(IpInfo* ipInfo, TcpInfo* tcpInfo,
return WOLFSSL_FATAL_ERROR;
}
}
if (vChain == NULL) {
XMEMCPY(&ssl->buffers.inputBuffer.buffer[length],
*sslFrame, *sslBytes);
*sslBytes += length;
ssl->buffers.inputBuffer.length = *sslBytes;
*sslFrame = ssl->buffers.inputBuffer.buffer;
*end = *sslFrame + *sslBytes;
}
else {
#ifdef WOLFSSL_SNIFFER_CHAIN_INPUT
struct iovec* chain = (struct iovec*)vChain;
word32 i, offset, headerSz, qty, remainder;
Trace(CHAIN_INPUT_STR);
headerSz = (word32)((const byte*)*sslFrame - (const byte*)chain[0].iov_base);
remainder = *sslBytes;
if ( (*sslBytes + length) > ssl->buffers.inputBuffer.bufferSize) {
if (GrowInputBuffer(ssl, *sslBytes, length) < 0) {
SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
return WOLFSSL_FATAL_ERROR;
}
}
qty = min(*sslBytes, (word32)chain[0].iov_len - headerSz);
XMEMCPY(&ssl->buffers.inputBuffer.buffer[length],
(byte*)chain[0].iov_base + headerSz, qty);
offset = length;
for (i = 1; i < chainSz; i++) {
offset += qty;
remainder -= qty;
if (chain[i].iov_len > remainder)
qty = remainder;
else
qty = (word32)chain[i].iov_len;
XMEMCPY(ssl->buffers.inputBuffer.buffer + offset,
chain[i].iov_base, qty);
}
*sslBytes += length;
ssl->buffers.inputBuffer.length = *sslBytes;
*sslFrame = ssl->buffers.inputBuffer.buffer;
*end = *sslFrame + *sslBytes;
#endif
(void)chainSz;
}
XMEMCPY(&ssl->buffers.inputBuffer.buffer[length],
*sslFrame, *sslBytes);
*sslBytes += length;
ssl->buffers.inputBuffer.length = *sslBytes;
*sslFrame = ssl->buffers.inputBuffer.buffer;
*end = *sslFrame + *sslBytes;
}
if (session->flags.clientHello == 0 && **sslFrame != handshake) {
@ -6616,27 +6574,33 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, int isChain,
{
TcpInfo tcpInfo;
IpInfo ipInfo;
byte* tmpPacket = NULL; /* Assemble the chain */
const byte* sslFrame;
const byte* end;
int sslBytes; /* ssl bytes unconsumed */
int ret;
SnifferSession* session = NULL;
void* vChain = NULL;
word32 chainSz = 0;
if (isChain) {
#ifdef WOLFSSL_SNIFFER_CHAIN_INPUT
struct iovec* chain;
word32 i;
vChain = (void*)packet;
chainSz = (word32)length;
word32 chainSz = (word32)length;
chain = (struct iovec*)vChain;
chain = (struct iovec*)packet;
length = 0;
for (i = 0; i < chainSz; i++)
for (i = 0; i < chainSz; i++) length += chain[i].iov_len;
tmpPacket = (byte*)XMALLOC(length, NULL, DYNAMIC_TYPE_SNIFFER_CHAIN_BUFFER);
if (tmpPacket == NULL) return MEMORY_E;
length = 0;
for (i = 0; i < chainSz; i++) {
XMEMCPY(tmpPacket+length,chain[i].iov_base,chain[i].iov_len);
length += chain[i].iov_len;
packet = (const byte*)chain[0].iov_base;
}
packet = (const byte*)tmpPacket;
#else
SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
return WOLFSSL_SNIFFER_ERROR;
@ -6645,18 +6609,27 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, int isChain,
if (CheckHeaders(&ipInfo, &tcpInfo, packet, length, &sslFrame, &sslBytes,
error, 1, 1) != 0) {
return WOLFSSL_SNIFFER_ERROR;
ret = WOLFSSL_SNIFFER_ERROR;
goto exit_decode;
}
end = sslFrame + sslBytes;
ret = CheckSession(&ipInfo, &tcpInfo, sslBytes, &session, error);
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error))
return WOLFSSL_SNIFFER_FATAL_ERROR;
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) {
ret = WOLFSSL_SNIFFER_FATAL_ERROR;
goto exit_decode;
}
#ifdef WOLFSSL_ASYNC_CRYPT
else if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) return WC_PENDING_E;
else if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
ret = WC_PENDING_E;
goto exit_decode;
}
#endif
else if (ret == -1) return WOLFSSL_SNIFFER_ERROR;
else if (ret == -1) {
ret = WOLFSSL_SNIFFER_ERROR;
goto exit_decode;
}
else if (ret == 1) {
#ifdef WOLFSSL_SNIFFER_STATS
if (sslBytes > 0) {
@ -6669,7 +6642,8 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, int isChain,
INC_STAT(SnifferStats.sslDecryptedPackets);
}
#endif
return 0; /* done for now */
ret = 0;
goto exit_decode; /* done for now */
}
#ifdef WOLFSSL_ASYNC_CRYPT
@ -6677,30 +6651,41 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, int isChain,
#endif
ret = CheckSequence(&ipInfo, &tcpInfo, session, &sslBytes, &sslFrame,error);
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error))
return WOLFSSL_SNIFFER_FATAL_ERROR;
else if (ret == -1) return WOLFSSL_SNIFFER_ERROR;
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) {
ret = WOLFSSL_SNIFFER_FATAL_ERROR;
goto exit_decode;
}
else if (ret == -1) {
ret = WOLFSSL_SNIFFER_ERROR;
goto exit_decode;
}
else if (ret == 1) {
#ifdef WOLFSSL_SNIFFER_STATS
INC_STAT(SnifferStats.sslDecryptedPackets);
#endif
return 0; /* done for now */
ret = 0;
goto exit_decode; /* done for now */
}
else if (ret != 0) {
/* return specific error case */
return ret;
goto exit_decode; /* return specific error case */
}
ret = CheckPreRecord(&ipInfo, &tcpInfo, &sslFrame, &session, &sslBytes,
&end, vChain, chainSz, error);
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error))
return WOLFSSL_SNIFFER_FATAL_ERROR;
else if (ret == -1) return WOLFSSL_SNIFFER_ERROR;
&end, error);
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) {
ret = WOLFSSL_SNIFFER_FATAL_ERROR;
goto exit_decode;
}
else if (ret == -1) {
ret = WOLFSSL_SNIFFER_ERROR;
goto exit_decode;
}
else if (ret == 1) {
#ifdef WOLFSSL_SNIFFER_STATS
INC_STAT(SnifferStats.sslDecryptedPackets);
#endif
return 0; /* done for now */
ret = 0;
goto exit_decode; /* done for now */
}
#ifdef WOLFSSL_ASYNC_CRYPT
@ -6708,7 +6693,8 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, int isChain,
if (asyncOkay &&
session->sslServer->error == WC_NO_ERR_TRACE(WC_PENDING_E) &&
!session->flags.wasPolled) {
return WC_PENDING_E;
ret = WC_PENDING_E;
goto exit_decode;
}
#endif
@ -6745,7 +6731,7 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, int isChain,
wolfSSL_AsyncPoll(session->sslServer, WOLF_POLL_FLAG_CHECK_HW);
}
else {
return ret; /* return to caller */
goto exit_decode; /* return to caller */
}
}
else {
@ -6756,12 +6742,18 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, int isChain,
(void)asyncOkay;
#endif
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error))
return WOLFSSL_SNIFFER_FATAL_ERROR;
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) {
ret = WOLFSSL_SNIFFER_FATAL_ERROR;
goto exit_decode;
}
if (CheckFinCapture(&ipInfo, &tcpInfo, session) == 0) {
CopySessionInfo(session, sslInfo);
}
exit_decode:
if (isChain) {
XFREE(tmpPacket, NULL, DYNAMIC_TYPE_SNIFFER_CHAIN_BUFFER);
}
return ret;
}
@ -6868,11 +6860,15 @@ int ssl_Trace(const char* traceFile, char* error)
if (traceFile) {
/* Don't try to reopen the file */
if (TraceFile == NULL) {
TraceFile = XFOPEN(traceFile, "a");
if (!TraceFile) {
SetError(BAD_TRACE_FILE_STR, error, NULL, 0);
return WOLFSSL_FATAL_ERROR;
}
if (XSTRCMP(traceFile, "-") == 0) {
TraceFile = stdout;
} else {
TraceFile = XFOPEN(traceFile, "a");
if (!TraceFile) {
SetError(BAD_TRACE_FILE_STR, error, NULL, 0);
return WOLFSSL_FATAL_ERROR;
}
}
TraceOn = 1;
}
}

View File

@ -197,7 +197,7 @@ Frees all resources consumed by the wolfSSL sniffer and should be called when us
int ssl_Trace(const char* traceFile, char* error);
```
Enables Tracing when a file is passed in. Disables Tracing if previously on and a NULL value is passed in for the file.
Enables Tracing when a file is passed in. When `traceFile` is "-", then the trace will be printed to STDOUT. Disables Tracing if previously on and a NULL value is passed in for the file.
Returns Values:

View File

@ -145,7 +145,7 @@ enum {
#endif
#define DEFAULT_SERVER_IP "127.0.0.1"
#define DEFAULT_SERVER_PORT (443)
#define DEFAULT_SERVER_PORT (11111)
#ifdef WOLFSSL_SNIFFER_WATCH
static const byte rsaHash[] = {
@ -166,6 +166,7 @@ static const byte eccHash[] = {
static pcap_t* pcap = NULL;
static pcap_if_t* alldevs = NULL;
static struct bpf_program pcap_fp;
static const char *traceFile = "./tracefile.txt";
static void FreeAll(void)
{
@ -377,7 +378,6 @@ static int load_key(const char* name, const char* server, int port,
if (loadCount == 0) {
printf("Failed loading private key %s: ret %d\n", keyFile, ret);
printf("Please run directly from wolfSSL root dir\n");
ret = -1;
}
else {
@ -843,7 +843,7 @@ static void* snifferWorker(void* arg)
char err[PCAP_ERRBUF_SIZE];
ssl_InitSniffer_ex2(worker->id);
ssl_Trace("./tracefile.txt", err);
ssl_Trace(traceFile, err);
ssl_EnableRecovery(1, -1, err);
#ifdef WOLFSSL_SNIFFER_WATCH
ssl_SetWatchKeyCallback(myWatchCb, err);
@ -951,39 +951,90 @@ int main(int argc, char** argv)
int i = 0, defDev = 0;
int packetNumber = 0;
int frame = ETHER_IF_FRAME_LEN;
char cmdLineArg[128];
char *pcapFile = NULL;
char *deviceName = NULL;
char err[PCAP_ERRBUF_SIZE];
char filter[32];
char filter[128];
const char *keyFilesSrc = NULL;
#ifdef WOLFSSL_SNIFFER_KEYLOGFILE
const char *sslKeyLogFile = NULL;
#endif /* WOLFSSL_SNIFFER_KEYLOGFILE */
char keyFilesBuf[MAX_FILENAME_SZ];
char keyFilesUser[MAX_FILENAME_SZ];
const char *server = DEFAULT_SERVER_IP;
int port = DEFAULT_SERVER_PORT;
const char *server = NULL;
int port = -1;
const char *sniName = NULL;
const char *passwd = NULL;
pcap_if_t *d;
pcap_addr_t *a;
#ifdef THREADED_SNIFFTEST
int workerThreadCount;
#ifdef HAVE_SESSION_TICKET
/* Multiple threads on resume not yet supported */
workerThreadCount = 1;
#else
workerThreadCount = 5;
#endif
#ifdef DEBUG_WOLFSSL
wolfSSL_Debugging_ON();
#endif
show_appinfo();
signal(SIGINT, sig_handler);
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-pcap") == 0 && i + 1 < argc) {
pcapFile = argv[++i];
}
else if (strcmp(argv[i], "-deviceName") == 0 && i + 1 < argc) {
deviceName = argv[++i];
}
else if (strcmp(argv[i], "-key") == 0 && i + 1 < argc) {
keyFilesSrc = argv[++i];
}
else if (strcmp(argv[i], "-server") == 0 && i + 1 < argc) {
server = argv[++i];
}
else if (strcmp(argv[i], "-port") == 0 && i + 1 < argc) {
port = XATOI(argv[++i]);
}
else if (strcmp(argv[i], "-password") == 0 && i + 1 < argc) {
passwd = argv[++i];
}
else if (strcmp(argv[i], "-tracefile") == 0 && i + 1 < argc) {
traceFile = argv[++i];
}
#if defined(WOLFSSL_SNIFFER_KEYLOGFILE)
else if (strcmp(argv[i], "-keylogfile") == 0 && i + 1 < argc) {
sslKeyLogFile = argv[++i];
}
#endif /* WOLFSSL_SNIFFER_KEYLOGFILE */
#if defined(THREADED_SNIFFTEST)
else if (strcmp(argv[i], "-threads") == 0 && i + 1 < argc) {
workerThreadCount = XATOI(argv[++i]);
}
#endif /* THREADED_SNIFFTEST */
else {
fprintf(stderr, "Error parsing: %s\n", argv[i]);
fprintf(stderr, "Usage: %s -pcap pcap_arg -key key_arg"
" [-deviceName deviceName_arg]"
" [-password password_arg] [-server server_arg]"
" [-port port_arg]"
" [-tracefile tracefile_arg]"
#if defined(WOLFSSL_SNIFFER_KEYLOGFILE)
" [-keylogfile keylogfile_arg]"
#endif /* WOLFSSL_SNIFFER_KEYLOGFILE */
#if defined(THREADED_SNIFFTEST)
" [-threads threads_arg]"
#endif /* THREADED_SNIFFTEST */
"\n", argv[0]);
exit(EXIT_FAILURE);
}
}
#ifndef THREADED_SNIFFTEST
#ifndef _WIN32
ssl_InitSniffer(); /* dll load on Windows */
#endif
ssl_Trace("./tracefile.txt", err);
ssl_Trace(traceFile, err);
ssl_EnableRecovery(1, -1, err);
#ifdef WOLFSSL_SNIFFER_WATCH
ssl_SetWatchKeyCallback(myWatchCb, err);
@ -991,101 +1042,175 @@ int main(int argc, char** argv)
#ifdef WOLFSSL_SNIFFER_STORE_DATA_CB
ssl_SetStoreDataCallback(myStoreDataCb);
#endif
#else
#ifdef HAVE_SESSION_TICKET
/* Multiple threads on resume not yet supported */
workerThreadCount = 1;
#else
workerThreadCount = 5;
#endif
#endif
SNPRINTF(filter, sizeof(filter), "(ip6 or ip) and tcp");
if (argc == 1) {
char cmdLineArg[128];
if (pcapFile == NULL) {
/* normal case, user chooses device and port */
if (pcap_findalldevs(&alldevs, err) == -1)
err_sys("Error in pcap_findalldevs");
for (d = alldevs; d; d=d->next) {
printf("%d. %s", ++i, d->name);
if (strcmp(d->name, "lo0") == 0) {
defDev = i;
if (deviceName == NULL) {
for (d = alldevs, i = 0; d; d=d->next) {
printf("%d. %s", ++i, d->name);
if (strcmp(d->name, "lo0") == 0) {
defDev = i;
}
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
if (i == 0)
err_sys("No interfaces found! Make sure pcap or WinPcap is"
" installed correctly and you have sufficient permissions");
printf("Enter the interface number (1-%d) [default: %d]: ", i, defDev);
XMEMSET(cmdLineArg, 0, sizeof(cmdLineArg));
if (XFGETS(cmdLineArg, sizeof(cmdLineArg), stdin))
inum = XATOI(cmdLineArg);
if (inum == 0)
inum = defDev;
else if (inum < 1 || inum > i)
err_sys("Interface number out of range");
/* Jump to the selected adapter */
for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);
} else {
int deviceNameSz = (int)XSTRLEN(deviceName);
for (d = alldevs; d; d = d->next) {
if (XSTRNCMP(d->name,deviceName,deviceNameSz) == 0) {
fprintf(stderr, "%s == %s\n", d->name, deviceName);
break;
}
}
if (d == NULL) {
err_sys("Can't find the device you're looking for");
}
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
if (i == 0)
err_sys("No interfaces found! Make sure pcap or WinPcap is"
" installed correctly and you have sufficient permissions");
printf("Enter the interface number (1-%d) [default: %d]: ", i, defDev);
XMEMSET(cmdLineArg, 0, sizeof(cmdLineArg));
if (XFGETS(cmdLineArg, sizeof(cmdLineArg), stdin))
inum = XATOI(cmdLineArg);
if (inum == 0)
inum = defDev;
else if (inum < 1 || inum > i)
err_sys("Interface number out of range");
/* Jump to the selected adapter */
for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);
printf("Selected %s\n", d->name);
pcap = pcap_create(d->name, err);
if (pcap == NULL) fprintf(stderr, "pcap_create failed %s\n", err);
if (pcap == NULL) printf("pcap_create failed %s\n", err);
/* print out addresses for selected interface */
for (a = d->addresses; a; a = a->next) {
if (a->addr->sa_family == AF_INET) {
server =
iptos(&((struct sockaddr_in *)a->addr)->sin_addr);
printf("server = %s\n", server);
}
else if (a->addr->sa_family == AF_INET6) {
server =
ip6tos(&((struct sockaddr_in6 *)a->addr)->sin6_addr);
printf("server = %s\n", server);
if (server == NULL) {
/* print out addresses for selected interface */
for (a = d->addresses; a; a = a->next) {
if (a->addr->sa_family == AF_INET) {
server =
iptos(&((struct sockaddr_in *)a->addr)->sin_addr);
printf("server = %s\n", server);
}
else if (a->addr->sa_family == AF_INET6) {
server =
ip6tos(&((struct sockaddr_in6 *)a->addr)->sin6_addr);
printf("server = %s\n", server);
}
}
}
if (server == NULL)
err_sys("Unable to get device IPv4 or IPv6 address");
ret = pcap_set_snaplen(pcap, 65536);
if (ret != 0) printf("pcap_set_snaplen failed %s\n", pcap_geterr(pcap));
if (ret != 0)
fprintf(stderr, "pcap_set_snaplen failed %s\n", pcap_geterr(pcap));
ret = pcap_set_timeout(pcap, 1000);
if (ret != 0) printf("pcap_set_timeout failed %s\n", pcap_geterr(pcap));
if (ret != 0)
fprintf(stderr, "pcap_set_timeout failed %s\n", pcap_geterr(pcap));
ret = pcap_set_buffer_size(pcap, 1000000);
if (ret != 0)
printf("pcap_set_buffer_size failed %s\n", pcap_geterr(pcap));
fprintf(stderr, "pcap_set_buffer_size failed %s\n",
pcap_geterr(pcap));
ret = pcap_set_promisc(pcap, 1);
if (ret != 0) printf("pcap_set_promisc failed %s\n", pcap_geterr(pcap));
if (ret != 0)
fprintf(stderr,"pcap_set_promisc failed %s\n", pcap_geterr(pcap));
ret = pcap_activate(pcap);
if (ret != 0) printf("pcap_activate failed %s\n", pcap_geterr(pcap));
if (ret != 0)
fprintf(stderr, "pcap_activate failed %s\n", pcap_geterr(pcap));
printf("Enter the port to scan [default: 11111]: ");
}
else {
saveFile = 1;
pcap = pcap_open_offline(pcapFile , err);
if (pcap == NULL) {
fprintf(stderr, "pcap_open_offline failed %s\n", err);
err_sys(err);
}
}
if (server == NULL) {
server = DEFAULT_SERVER_IP;
}
if (port < 0) {
printf("Enter the port to scan [default: %d, '0' for all]: ",
DEFAULT_SERVER_PORT);
XMEMSET(cmdLineArg, 0, sizeof(cmdLineArg));
if (XFGETS(cmdLineArg, sizeof(cmdLineArg), stdin)) {
port = XATOI(cmdLineArg);
}
if (port <= 0)
port = 11111;
if ((port < 0) || (cmdLineArg[0] == '\n'))
port = DEFAULT_SERVER_PORT;
SNPRINTF(filter, sizeof(filter), "tcp and port %d", port);
}
if (port > 0) {
SNPRINTF(cmdLineArg, sizeof(filter), " and port %d", port);
XSTRLCAT(filter, cmdLineArg, sizeof(filter));
}
ret = pcap_compile(pcap, &pcap_fp, filter, 0, 0);
if (ret != 0) printf("pcap_compile failed %s\n", pcap_geterr(pcap));
#if defined(WOLFSSL_SNIFFER_KEYLOGFILE)
/* If we offer keylog support, then user must provide EITHER a pubkey
* OR a keylog file but NOT both */
if (keyFilesSrc && sslKeyLogFile) {
fprintf(stderr,
"Error: either -key OR -keylogfile option but NOT both.\n");
exit(EXIT_FAILURE);
}
ret = pcap_setfilter(pcap, &pcap_fp);
if (ret != 0) printf("pcap_setfilter failed %s\n", pcap_geterr(pcap));
if (sslKeyLogFile != NULL) {
ret = ssl_LoadSecretsFromKeyLogFile(sslKeyLogFile, err);
if (ret != 0) {
fprintf(stderr,
"ERROR=%d, unable to load secrets from keylog file\n",ret);
err_sys(err);
}
ret = ssl_CreateKeyLogSnifferServer(server, port, err);
if (ret != 0) {
fprintf(stderr,
"ERROR=%d, unable to create keylog sniffer server\n",ret);
err_sys(err);
}
}
else
#endif /* WOLFSSL_SNIFFER_KEYLOGFILE */
if (keyFilesSrc) {
ret = load_key(NULL, server, port, keyFilesSrc, passwd, err);
if (ret != 0) {
fprintf(stderr, "Failed to load key\n");
err_sys(err);
}
}
else {
/* optionally enter the private key to use */
#if defined(WOLFSSL_STATIC_EPHEMERAL) && defined(DEFAULT_SERVER_EPH_KEY)
#if defined(WOLFSSL_STATIC_EPHEMERAL) && defined(DEFAULT_SERVER_EPH_KEY)
keyFilesSrc = DEFAULT_SERVER_EPH_KEY;
#else
#else
keyFilesSrc = DEFAULT_SERVER_KEY;
#endif
#endif
printf("Enter the server key [default: %s]: ", keyFilesSrc);
XMEMSET(keyFilesBuf, 0, sizeof(keyFilesBuf));
XMEMSET(keyFilesUser, 0, sizeof(keyFilesUser));
@ -1109,137 +1234,24 @@ int main(int argc, char** argv)
}
#endif /* !WOLFSSL_SNIFFER_WATCH && HAVE_SNI */
/* get IPv4 or IPv6 addresses for selected interface */
for (a = d->addresses; a; a = a->next) {
server = NULL;
if (a->addr->sa_family == AF_INET) {
server =
iptos(&((struct sockaddr_in *)a->addr)->sin_addr);
}
else if (a->addr->sa_family == AF_INET6) {
server =
ip6tos(&((struct sockaddr_in6 *)a->addr)->sin6_addr);
}
if (server) {
XSTRNCPY(keyFilesBuf, keyFilesSrc, sizeof(keyFilesBuf));
ret = load_key(sniName, server, port, keyFilesBuf, NULL, err);
if (ret != 0) {
exit(EXIT_FAILURE);
}
}
ret = load_key(sniName, server, port, keyFilesBuf, NULL, err);
if (ret != 0) {
exit(EXIT_FAILURE);
}
}
else {
char *pcapFile = NULL;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-pcap") == 0 && i + 1 < argc) {
pcapFile = argv[++i];
}
else if (strcmp(argv[i], "-key") == 0 && i + 1 < argc) {
keyFilesSrc = argv[++i];
}
else if (strcmp(argv[i], "-server") == 0 && i + 1 < argc) {
server = argv[++i];
}
else if (strcmp(argv[i], "-port") == 0 && i + 1 < argc) {
port = XATOI(argv[++i]);
}
else if (strcmp(argv[i], "-password") == 0 && i + 1 < argc) {
passwd = argv[++i];
}
#if defined(WOLFSSL_SNIFFER_KEYLOGFILE)
else if (strcmp(argv[i], "-keylogfile") == 0 && i + 1 < argc) {
sslKeyLogFile = argv[++i];
}
#endif /* WOLFSSL_SNIFFER_KEYLOGFILE */
#if defined(THREADED_SNIFFTEST)
else if (strcmp(argv[i], "-threads") == 0 && i + 1 < argc) {
workerThreadCount = XATOI(argv[++i]);
}
#endif /* THREADED_SNIFFTEST */
else {
fprintf(stderr, "Invalid option or missing argument: %s\n", argv[i]);
fprintf(stderr, "Usage: %s -pcap pcap_arg -key key_arg"
" [-password password_arg] [-server server_arg] [-port port_arg]"
#if defined(WOLFSSL_SNIFFER_KEYLOGFILE)
" [-keylogfile keylogfile_arg]"
#endif /* WOLFSSL_SNIFFER_KEYLOGFILE */
#if defined(THREADED_SNIFFTEST)
" [-threads threads_arg]"
#endif /* THREADED_SNIFFTEST */
"\n", argv[0]);
exit(EXIT_FAILURE);
}
}
/* Only let through TCP/IP packets */
printf("Using packet filter: %s\n", filter);
ret = pcap_compile(pcap, &pcap_fp, filter, 0, 0);
if (ret != 0) {
fprintf(stderr, "pcap_compile failed %s\n", pcap_geterr(pcap));
exit(EXIT_FAILURE);
}
if (!pcapFile) {
fprintf(stderr, "Error: -pcap option is required.\n");
exit(EXIT_FAILURE);
}
#if defined(WOLFSSL_SNIFFER_KEYLOGFILE)
/* If we offer keylog support, then user must provide EITHER a pubkey
* OR a keylog file but NOT both */
if ((!keyFilesSrc && !sslKeyLogFile) || (keyFilesSrc && sslKeyLogFile)) {
fprintf(stderr, "Error: either -key OR -keylogfile option required but NOT both.\n");
exit(EXIT_FAILURE);
}
#else
if (!keyFilesSrc) {
fprintf(stderr, "Error: -key option is required.\n");
exit(EXIT_FAILURE);
}
#endif
saveFile = 1;
pcap = pcap_open_offline(pcapFile , err);
if (pcap == NULL) {
fprintf(stderr, "pcap_open_offline failed %s\n", err);
err_sys(err);
}
else {
#if defined(WOLFSSL_SNIFFER_KEYLOGFILE)
if (sslKeyLogFile != NULL) {
ret = ssl_LoadSecretsFromKeyLogFile(sslKeyLogFile, err);
if (ret != 0) {
fprintf(stderr, "ERROR=%d, unable to load secrets from keylog file\n",ret);
err_sys(err);
}
ret = ssl_CreateKeyLogSnifferServer(server, port, err);
if (ret != 0) {
fprintf(stderr, "ERROR=%d, unable to create keylog sniffer server\n",ret);
err_sys(err);
}
}
else
#endif /* WOLFSSL_SNIFFER_KEYLOGFILE */
{
ret = load_key(NULL, server, port, keyFilesSrc, passwd, err);
if (ret != 0) {
fprintf(stderr, "Failed to load key\n");
err_sys(err);
}
}
/* Only let through TCP/IP packets */
ret = pcap_compile(pcap, &pcap_fp, "(ip6 or ip) and tcp", 0, 0);
if (ret != 0) {
fprintf(stderr, "pcap_compile failed %s\n", pcap_geterr(pcap));
exit(EXIT_FAILURE);
}
ret = pcap_setfilter(pcap, &pcap_fp);
if (ret != 0) {
fprintf(stderr, "pcap_setfilter failed %s\n", pcap_geterr(pcap));
exit(EXIT_FAILURE);
}
}
ret = pcap_setfilter(pcap, &pcap_fp);
if (ret != 0) {
fprintf(stderr, "pcap_setfilter failed %s\n", pcap_geterr(pcap));
exit(EXIT_FAILURE);
}
if (ret != 0)
@ -1263,7 +1275,7 @@ int main(int argc, char** argv)
#endif
while (1) {
struct pcap_pkthdr header;
struct pcap_pkthdr *header;
const unsigned char* packet = NULL;
byte* data = NULL; /* pointer to decrypted data */
#ifdef THREADED_SNIFFTEST
@ -1290,22 +1302,28 @@ int main(int argc, char** argv)
if (data == NULL) {
/* grab next pcap packet */
packetNumber++;
packet = pcap_next(pcap, &header);
if(pcap_next_ex(pcap, &header, &packet) < 0) {
break;
}
}
if (packet) {
if (header.caplen > 40) { /* min ip(20) + min tcp(20) */
if (header->caplen > 40) { /* min ip(20) + min tcp(20) */
packet += frame;
header.caplen -= frame;
header->caplen -= frame;
}
else {
/* packet doesn't contain minimum ip/tcp header */
continue;
}
if (pcap_datalink(pcap) == DLT_LINUX_SLL) {
packet += 2;
header->caplen -= 2;
}
#ifdef THREADED_SNIFFTEST
XMEMSET(&info, 0, sizeof(SnifferStreamInfo));
ret = ssl_DecodePacket_GetStream(&info, packet, header.caplen, err);
ret = ssl_DecodePacket_GetStream(&info, packet, header->caplen, err);
/* calculate SnifferStreamInfo checksum */
infoSum = 0;
@ -1328,7 +1346,7 @@ int main(int argc, char** argv)
/* add the packet to the worker's linked list */
if (SnifferWorkerPacketAdd(&workers[threadNum], ret, (byte*)packet,
header.caplen, packetNumber)) {
header->caplen, packetNumber)) {
printf("Unable to add packet %d to worker", packetNumber);
break;
}
@ -1337,7 +1355,7 @@ int main(int argc, char** argv)
#else
/* Decode Packet, ret value will indicate whether a
* bad packet was encountered */
hadBadPacket = DecodePacket((byte*)packet, header.caplen,
hadBadPacket = DecodePacket((byte*)packet, header->caplen,
packetNumber,err);
#endif
}

View File

@ -1114,15 +1114,16 @@ typedef struct w64wrapper {
DYNAMIC_TYPE_LMS = 101,
DYNAMIC_TYPE_BIO = 102,
DYNAMIC_TYPE_X509_ACERT = 103,
DYNAMIC_TYPE_SNIFFER_SERVER = 1000,
DYNAMIC_TYPE_SNIFFER_SESSION = 1001,
DYNAMIC_TYPE_SNIFFER_PB = 1002,
DYNAMIC_TYPE_SNIFFER_PB_BUFFER = 1003,
DYNAMIC_TYPE_SNIFFER_TICKET_ID = 1004,
DYNAMIC_TYPE_SNIFFER_NAMED_KEY = 1005,
DYNAMIC_TYPE_SNIFFER_KEY = 1006,
DYNAMIC_TYPE_SNIFFER_KEYLOG_NODE = 1007,
DYNAMIC_TYPE_AES_EAX = 1008
DYNAMIC_TYPE_SNIFFER_SERVER = 1000,
DYNAMIC_TYPE_SNIFFER_SESSION = 1001,
DYNAMIC_TYPE_SNIFFER_PB = 1002,
DYNAMIC_TYPE_SNIFFER_PB_BUFFER = 1003,
DYNAMIC_TYPE_SNIFFER_TICKET_ID = 1004,
DYNAMIC_TYPE_SNIFFER_NAMED_KEY = 1005,
DYNAMIC_TYPE_SNIFFER_KEY = 1006,
DYNAMIC_TYPE_SNIFFER_KEYLOG_NODE = 1007,
DYNAMIC_TYPE_SNIFFER_CHAIN_BUFFER = 1008,
DYNAMIC_TYPE_AES_EAX = 1009,
};
/* max error buffer string size */