Merge pull request #1929 from ejohnstown/sniffer

Sniffer Updates
This commit is contained in:
toddouska
2018-11-26 13:24:31 -08:00
committed by GitHub
5 changed files with 113 additions and 5 deletions

View File

@ -245,7 +245,8 @@ static const char* const msgTable[] =
/* 81 */
"Bad Decrypt Size",
"Extended Master Secret Hash Error"
"Extended Master Secret Hash Error",
"Handshake Message Split Across TLS Records"
};
@ -1016,6 +1017,23 @@ static void TraceRemovedSession(void)
}
/* Show SSLInfo if provided and is valid. */
static void TraceSessionInfo(SSLInfo* sslInfo)
{
if (TraceOn) {
if (sslInfo != NULL && sslInfo->isValid) {
fprintf(TraceFile,
"\tver:(%u %u) suiteId:(%02x %02x) suiteName:(%s)\n",
sslInfo->protocolVersionMajor,
sslInfo->protocolVersionMinor,
sslInfo->serverCipherSuite0,
sslInfo->serverCipherSuite,
sslInfo->serverCipherSuiteName);
}
}
}
/* Set user error string */
static void SetError(int idx, char* error, SnifferSession* session, int fatal)
{
@ -2060,8 +2078,9 @@ static int DoHandShake(const byte* input, int* sslBytes,
startBytes = *sslBytes;
if (*sslBytes < size) {
SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
return -1;
Trace(SPLIT_HANDSHAKE_MSG_STR);
*sslBytes = 0;
return ret;
}
/* A session's arrays are released when the handshake is completed. */
@ -3463,9 +3482,42 @@ static int RemoveFatalSession(IpInfo* ipInfo, TcpInfo* tcpInfo,
}
/* Copies the session's infomation to the provided sslInfo. Skip copy if
* SSLInfo is not provided. */
static void CopySessionInfo(SnifferSession* session, SSLInfo* sslInfo)
{
if (NULL != sslInfo) {
XMEMSET(sslInfo, 0, sizeof(SSLInfo));
/* Pass back Session Info after we have processed the Server Hello. */
if (0 != session->sslServer->options.cipherSuite) {
const char* pCipher;
sslInfo->isValid = 1;
sslInfo->protocolVersionMajor = session->sslServer->version.major;
sslInfo->protocolVersionMinor = session->sslServer->version.minor;
sslInfo->serverCipherSuite0 =
session->sslServer->options.cipherSuite0;
sslInfo->serverCipherSuite =
session->sslServer->options.cipherSuite;
pCipher = wolfSSL_get_cipher(session->sslServer);
if (NULL != pCipher) {
XSTRNCPY((char*)sslInfo->serverCipherSuiteName, pCipher,
sizeof(sslInfo->serverCipherSuiteName));
sslInfo->serverCipherSuiteName
[sizeof(sslInfo->serverCipherSuiteName) - 1] = '\0';
}
TraceSessionInfo(sslInfo);
}
}
}
/* Passes in an IP/TCP packet for decoding (ethernet/localhost frame) removed */
/* returns Number of bytes on success, 0 for no data yet, and -1 on error */
int ssl_DecodePacket(const byte* packet, int length, byte** data, char* error)
static int ssl_DecodePacketInternal(const byte* packet, int length,
byte** data, SSLInfo* sslInfo, char* error)
{
TcpInfo tcpInfo;
IpInfo ipInfo;
@ -3498,10 +3550,31 @@ int ssl_DecodePacket(const byte* packet, int length, byte** data, char* error)
ret = ProcessMessage(sslFrame, session, sslBytes, data, end, error);
if (RemoveFatalSession(&ipInfo, &tcpInfo, session, error)) return -1;
CheckFinCapture(&ipInfo, &tcpInfo, session);
CopySessionInfo(session, sslInfo);
return ret;
}
/* Passes in an IP/TCP packet for decoding (ethernet/localhost frame) removed */
/* returns Number of bytes on success, 0 for no data yet, and -1 on error */
/* Also returns Session Info if available */
int ssl_DecodePacketWithSessionInfo(const unsigned char* packet, int length,
unsigned char** data, SSLInfo* sslInfo, char* error)
{
return ssl_DecodePacketInternal(packet, length, data, sslInfo, error);
}
/* Passes in an IP/TCP packet for decoding (ethernet/localhost frame) removed */
/* returns Number of bytes on success, 0 for no data yet, and -1 on error */
int ssl_DecodePacket(const byte* packet, int length, byte** data, char* error)
{
return ssl_DecodePacketInternal(packet, length, data, NULL, error);
}
/* Deallocator for the decoded data buffer. */
/* returns 0 on success, -1 on error */
int ssl_FreeDecodeBuffer(byte** data, char* error)

View File

@ -295,6 +295,7 @@ int main(int argc, char** argv)
static int packetNumber = 0;
struct pcap_pkthdr header;
const unsigned char* packet = pcap_next(pcap, &header);
SSLInfo sslInfo;
packetNumber++;
if (packet) {
@ -307,7 +308,8 @@ int main(int argc, char** argv)
else
continue;
ret = ssl_DecodePacket(packet, header.caplen, &data, err);
ret = ssl_DecodePacketWithSessionInfo(packet, header.caplen, &data,
&sslInfo, err);
if (ret < 0) {
printf("ssl_Decode ret = %d, %s\n", ret, err);
hadBadPacket = 1;

View File

@ -93,6 +93,37 @@ enum {
};
/*
* New Sniffer API that provides read-only access to the TLS and cipher
* information associated with the SSL session.
*/
#if defined(__GNUC__)
#define WOLFSSL_PACK __attribute__ ((packed))
#else
#define WOLFSSL_PACK
#endif
typedef struct SSLInfo
{
unsigned char isValid;
/* indicates if the info in this struct is valid: 0 = no, 1 = yes */
unsigned char protocolVersionMajor; /* SSL Version: major */
unsigned char protocolVersionMinor; /* SSL Version: minor */
unsigned char serverCipherSuite0; /* first byte, normally 0 */
unsigned char serverCipherSuite; /* second byte, actual suite */
unsigned char serverCipherSuiteName[256];
/* cipher name, e.g., "TLS_RSA_..." */
} WOLFSSL_PACK SSLInfo;
WOLFSSL_API
SSL_SNIFFER_API int ssl_DecodePacketWithSessionInfo(
const unsigned char* packet, int length,
unsigned char** data, SSLInfo* sslInfo, char* error);
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@ -118,6 +118,7 @@
#define BAD_DECRYPT_SIZE 81
#define EXTENDED_MASTER_HASH_STR 82
#define SPLIT_HANDSHAKE_MSG_STR 83
/* !!!! also add to msgTable in sniffer.c and .rc file !!!! */

View File

@ -99,5 +99,6 @@ STRINGTABLE
81, "Bad Decrypt Size"
82, "Extended Master Secret Hash Error"
83, "Handshake Message Split Across TLS Records"
}