diff --git a/src/sniffer.c b/src/sniffer.c index 462946030..7e3803475 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -3467,7 +3467,8 @@ static int RemoveFatalSession(IpInfo* ipInfo, TcpInfo* tcpInfo, /* 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; @@ -3477,6 +3478,9 @@ int ssl_DecodePacket(const byte* packet, int length, byte** data, char* error) int ret; SnifferSession* session = 0; + if (NULL != sslInfo) + XMEMSET(sslInfo, 0, sizeof(SSLInfo)); + if (CheckHeaders(&ipInfo, &tcpInfo, packet, length, &sslFrame, &sslBytes, error) != 0) return -1; @@ -3500,10 +3504,42 @@ 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); + + /* Pass back Session Info after we have processed the Server Hello. */ + if ((NULL != sslInfo) && (0 != session->sslServer->options.cipherSuite)) { + 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; + + const char* pCipher = wolfSSL_get_cipher(session->sslServer); + if (pCipher) + XMEMCPY(sslInfo->serverCipherSuiteName, pCipher, + sizeof(sslInfo->serverCipherSuiteName) - 1); + } 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) diff --git a/wolfssl/sniffer.h b/wolfssl/sniffer.h index 4bd9f42d7..2595d23be 100644 --- a/wolfssl/sniffer.h +++ b/wolfssl/sniffer.h @@ -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