diff --git a/src/sniffer.c b/src/sniffer.c index 758e7be74d..eed3216808 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -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; } } diff --git a/sslSniffer/README.md b/sslSniffer/README.md index 27a6f52781..dbf68955ed 100644 --- a/sslSniffer/README.md +++ b/sslSniffer/README.md @@ -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: diff --git a/sslSniffer/sslSnifferTest/snifftest.c b/sslSniffer/sslSnifferTest/snifftest.c index 0cfb388597..de586f9595 100644 --- a/sslSniffer/sslSnifferTest/snifftest.c +++ b/sslSniffer/sslSnifferTest/snifftest.c @@ -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 (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++); + 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"); + } + } + printf("Selected %s\n", d->name); pcap = pcap_create(d->name, 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 (pcap == NULL) fprintf(stderr, "pcap_create failed %s\n", err); + + 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)); + + } + else { + saveFile = 1; + pcap = pcap_open_offline(pcapFile , err); + if (pcap == NULL) { + fprintf(stderr, "pcap_open_offline failed %s\n", err); + err_sys(err); + } + } - printf("Enter the port to scan [default: 11111]: "); + 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); - } - } - } - } - 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); - } - } - - if (!pcapFile) { - fprintf(stderr, "Error: -pcap option is required.\n"); + ret = load_key(sniName, server, port, keyFilesBuf, NULL, err); + if (ret != 0) { 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); - } - + /* 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); + } - } + 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 } diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 1b437c1000..41ea648a54 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -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 */