@@ -662,13 +662,15 @@ static void UpdateMissedDataSessions(void)
662662
663663#if defined(WOLFSSL_SNIFFER_KEYLOGFILE )
664664static int addSecretNode (unsigned char * clientRandom ,
665+ int type ,
665666 unsigned char * masterSecret ,
666667 char * error );
667668static void hexToBin (const char * hex , unsigned char * bin , int binLength );
668669static int parseKeyLogFile (const char * fileName , char * error );
669- static unsigned char * findMasterSecret (unsigned char * clientRandom );
670+ static unsigned char * findSecret (unsigned char * clientRandom , int type );
670671static void freeSecretList (void );
671672static int snifferSecretCb (unsigned char * client_random ,
673+ int type ,
672674 unsigned char * output_secret );
673675static void setSnifferSecretCb (SnifferSession * session );
674676static int addKeyLogSnifferServerHelper (const char * address ,
@@ -7207,15 +7209,18 @@ int ssl_PollSniffer(WOLF_EVENT** events, int maxEvents, WOLF_EVENT_FLAG flags,
72077209
72087210#if defined(WOLFSSL_SNIFFER_KEYLOGFILE )
72097211
7210- #define CLIENT_RANDOM_LABEL_LENGTH 13
7211- #define CLIENT_RANDOM_LENGTH 32
7212- #define MASTER_SECRET_LENGTH 48
7213- #define CLIENT_RANDOM_BITS ((CLIENT_RANDOM_LENGTH) * 8)
7214-
7212+ /* Maximum length of the NSS Keylog prefix string */
7213+ #define MAX_PREFIX_LENGTH (31)
7214+ /* Maximum length (in bytes) required to store the binary representation of
7215+ * the "client random" value parsed from keylog file */
7216+ #define CLIENT_RANDOM_LENGTH (32)
7217+ /* Maximum length (in bytes) required to store the binary representation of the
7218+ * "secret" value parsed from keylog file */
7219+ #define SECRET_LENGTH (48)
72157220
72167221typedef struct SecretNode {
72177222 unsigned char clientRandom [CLIENT_RANDOM_LENGTH ];
7218- unsigned char masterSecret [ MASTER_SECRET_LENGTH ];
7223+ unsigned char secrets [ SNIFFER_SECRET_NUM_SECRET_TYPES ][ SECRET_LENGTH ];
72197224 struct SecretNode * next ;
72207225} SecretNode ;
72217226
@@ -7233,7 +7238,6 @@ secretHashTable[WOLFSSL_SNIFFER_KEYLOGFILE_HASH_TABLE_SIZE] = {NULL};
72337238static WOLFSSL_GLOBAL wolfSSL_Mutex secretListMutex ;
72347239#endif
72357240
7236-
72377241static unsigned int secretHashFunction (unsigned char * clientRandom );
72387242
72397243#ifdef HAVE_C___ATOMIC
@@ -7253,72 +7257,78 @@ static unsigned int secretHashFunction(unsigned char* clientRandom)
72537257{
72547258 int i = 0 ;
72557259 unsigned int hash = 0 ;
7260+ const int CLIENT_RANDOM_NUM_BITS = CLIENT_RANDOM_LENGTH * 8 ;
72567261
72577262 for (i = 0 ; i < CLIENT_RANDOM_LENGTH ; i ++ ) {
7258- hash = (hash * CLIENT_RANDOM_BITS + clientRandom [i ])
7263+ hash = (hash * CLIENT_RANDOM_NUM_BITS + clientRandom [i ])
72597264 % WOLFSSL_SNIFFER_KEYLOGFILE_HASH_TABLE_SIZE ;
72607265 }
72617266
72627267 return hash ;
72637268}
72647269
72657270
7271+ /*
7272+ * Adds a new secret to the secret table, creating a new node based on the
7273+ * client random if necessary. If the client random is already present in the
7274+ * list, the requested secret will be updated.
7275+ */
72667276static int addSecretNode (unsigned char * clientRandom ,
7267- unsigned char * masterSecret ,
7277+ int type ,
7278+ unsigned char * secret ,
72687279 char * error )
72697280{
7270- unsigned int index = 0 ;
7271- SecretNode * newSecretNode = NULL ;
7281+ int index = 0 ;
7282+ int ret = 0 ;
7283+ SecretNode * node = NULL ;
72727284
7273- newSecretNode = (SecretNode * )XMALLOC (sizeof (SecretNode ),
7274- NULL ,
7275- DYNAMIC_TYPE_SNIFFER_KEYLOG_NODE );
7276- if (newSecretNode == NULL ) {
7277- SetError (MEMORY_STR , error , NULL , 0 );
7285+ if (type >= SNIFFER_SECRET_NUM_SECRET_TYPES ) {
72787286 return WOLFSSL_SNIFFER_ERROR ;
72797287 }
72807288
7281- XMEMCPY (newSecretNode -> clientRandom , clientRandom , CLIENT_RANDOM_LENGTH );
7282- XMEMCPY (newSecretNode -> masterSecret , masterSecret , MASTER_SECRET_LENGTH );
7283-
72847289 LOCK_SECRET_LIST ();
72857290
72867291 index = secretHashFunction (clientRandom );
7287- newSecretNode -> next = NULL ;
7292+ node = secretHashTable [ index ] ;
72887293
7289- if (secretHashTable [index ] == NULL ) {
7290- secretHashTable [index ] = newSecretNode ;
7291- }
7292- else {
7293- SecretNode * current = secretHashTable [index ];
7294- while (current != NULL ) {
7295- if (memcmp (current -> clientRandom ,
7296- clientRandom ,
7297- CLIENT_RANDOM_LENGTH ) == 0 ) {
7298- /* No need for a new node, since it already exists */
7299- fprintf (stderr , "Found duplicate client random value in "
7300- "keylog file. Rejecting.\n" );
7301- XFREE (newSecretNode , NULL , DYNAMIC_TYPE_SNIFFER_KEYLOG_NODE );
7302- break ;
7303- }
7304- if (current -> next == NULL ) {
7305- current -> next = newSecretNode ;
7306- break ;
7307- }
7308- current = current -> next ;
7294+ while (node ) {
7295+ /* Node already exists, so just add the requested secret */
7296+ if (XMEMCMP (node -> clientRandom , clientRandom , CLIENT_RANDOM_LENGTH )
7297+ == 0 )
7298+ {
7299+ XMEMCPY (node -> secrets [type ], secret , SECRET_LENGTH );
7300+ ret = 0 ;
7301+ goto unlockReturn ;
73097302 }
7303+ node = node -> next ;
73107304 }
73117305
7306+ node = (SecretNode * )XMALLOC (sizeof (SecretNode ),
7307+ NULL ,
7308+ DYNAMIC_TYPE_SNIFFER_KEYLOG_NODE );
7309+ if (node == NULL ) {
7310+ SetError (MEMORY_STR , error , NULL , 0 );
7311+ ret = WOLFSSL_SNIFFER_ERROR ;
7312+ goto unlockReturn ;
7313+ }
7314+
7315+ XMEMCPY (node -> clientRandom , clientRandom , CLIENT_RANDOM_LENGTH );
7316+ XMEMCPY (node -> secrets [type ], secret , SECRET_LENGTH );
7317+ node -> next = secretHashTable [index ];
7318+ secretHashTable [index ] = node ;
7319+
7320+ unlockReturn :
7321+
73127322 UNLOCK_SECRET_LIST ();
73137323
7314- return 0 ;
7324+ return ret ;
73157325}
73167326
73177327
73187328/*
73197329 * Looks up a master secret for a given client random from the keylog file
73207330 */
7321- static unsigned char * findMasterSecret (unsigned char * clientRandom )
7331+ static unsigned char * findSecret (unsigned char * clientRandom , int type )
73227332{
73237333 unsigned char * secret = NULL ;
73247334 SecretNode * node = NULL ;
@@ -7332,7 +7342,7 @@ static unsigned char* findMasterSecret(unsigned char* clientRandom)
73327342 while (node != NULL ) {
73337343 if (XMEMCMP (node -> clientRandom ,
73347344 clientRandom , CLIENT_RANDOM_LENGTH ) == 0 ) {
7335- secret = node -> masterSecret ;
7345+ secret = node -> secrets [ type ] ;
73367346 break ;
73377347 }
73387348 node = node -> next ;
@@ -7348,23 +7358,25 @@ static void hexToBin(const char* hex, unsigned char* bin, int binLength)
73487358{
73497359 int i = 0 ;
73507360 for (i = 0 ; i < binLength ; i ++ ) {
7351- sscanf (hex + 2 * i , "%02hhx" , & bin [i ]);
7361+ sscanf (hex + 2 * i , "%02hhx" , & bin [i ]);
73527362 }
73537363}
73547364
7355-
7365+ /*
7366+ * Helper function to parse secrets from the keylog file into the secret table
7367+ */
73567368static int parseKeyLogFile (const char * fileName , char * error )
73577369{
7358- const char CLIENT_RANDOM_LABEL_STR [] = "CLIENT_RANDOM" ;
73597370 unsigned char clientRandom [CLIENT_RANDOM_LENGTH ];
7360- unsigned char masterSecret [ MASTER_SECRET_LENGTH ];
7371+ unsigned char secret [ SECRET_LENGTH ];
73617372 FILE * file = NULL ;
73627373 int ret = 0 ;
7374+ int type = 0 ;
73637375 /* +1 for null terminator */
7364- char clientRandomLabel [ CLIENT_RANDOM_LABEL_LENGTH + 1 ] = {0 };
7376+ char prefix [ MAX_PREFIX_LENGTH + 1 ] = {0 };
73657377 /* 2 chars for Hexadecimal representation, plus null terminator */
73667378 char clientRandomHex [2 * CLIENT_RANDOM_LENGTH + 1 ] = {0 };
7367- char masterSecretHex [2 * MASTER_SECRET_LENGTH + 1 ] = {0 };
7379+ char secretHex [2 * SECRET_LENGTH + 1 ] = {0 };
73687380
73697381
73707382 file = fopen (fileName , "r" );
@@ -7374,16 +7386,43 @@ static int parseKeyLogFile(const char* fileName, char* error)
73747386 return WOLFSSL_SNIFFER_ERROR ;
73757387 }
73767388
7377- while (fscanf (file , "%13s %64s %96s" ,
7378- clientRandomLabel , clientRandomHex , masterSecretHex ) == 3 ) {
7379- if (XSTRCMP (clientRandomLabel , CLIENT_RANDOM_LABEL_STR ) == 0 ) {
7380- hexToBin (clientRandomHex , clientRandom , CLIENT_RANDOM_LENGTH );
7381- hexToBin (masterSecretHex , masterSecret , MASTER_SECRET_LENGTH );
7382- ret = addSecretNode (clientRandom , masterSecret , error );
7383- if (ret != 0 ) {
7384- fclose (file );
7385- return ret ;
7386- }
7389+ /* Format specifiers for each column should be:
7390+ * MAX_PREFIX_LENGTH, 2*CLIENT_RANDOM_LENGTH, and 2*SECRET_LENGTH */
7391+ while (fscanf (file , "%31s %64s %96s" , prefix , clientRandomHex , secretHex )
7392+ == 3 ) {
7393+
7394+ if (XSTRCMP (prefix , "CLIENT_RANDOM" ) == 0 ) {
7395+ type = SNIFFER_SECRET_TLS12_MASTER_SECRET ;
7396+ }
7397+ #if defined(WOLFSSL_TLS13 )
7398+ else if (XSTRCMP (prefix , "CLIENT_EARLY_TRAFFIC_SECRET ") == 0 ) {
7399+ type = SNIFFER_SECRET_CLIENT_EARLY_TRAFFIC_SECRET ;
7400+ }
7401+ else if (XSTRCMP (prefix , "CLIENT_HANDSHAKE_TRAFFIC_SECRET ") == 0 ) {
7402+ type = SNIFFER_SECRET_CLIENT_HANDSHAKE_TRAFFIC_SECRET ;
7403+ }
7404+ else if (XSTRCMP (prefix , "SERVER_HANDSHAKE_TRAFFIC_SECRET ") == 0 ) {
7405+ type = SNIFFER_SECRET_SERVER_HANDSHAKE_TRAFFIC_SECRET ;
7406+ }
7407+ else if (XSTRCMP (prefix , "CLIENT_TRAFFIC_SECRET_0 ") == 0 ) {
7408+ type = SNIFFER_SECRET_CLIENT_TRAFFIC_SECRET ;
7409+ }
7410+ else if (XSTRCMP (prefix , "SERVER_TRAFFIC_SECRET_0 ") == 0 ) {
7411+ type = SNIFFER_SECRET_SERVER_TRAFFIC_SECRET ;
7412+ }
7413+ #endif /* WOLFSSL_TLS13 */
7414+ else {
7415+ fprintf (stderr , "unrecognized prefix: %s\n" , prefix );
7416+ continue ;
7417+ }
7418+
7419+ hexToBin (clientRandomHex , clientRandom , CLIENT_RANDOM_LENGTH );
7420+ hexToBin (secretHex , secret , SECRET_LENGTH );
7421+ ret = addSecretNode (clientRandom , type , secret , error );
7422+
7423+ if (ret != 0 ) {
7424+ fclose (file );
7425+ return ret ;
73877426 }
73887427 }
73897428 fclose (file );
@@ -7418,6 +7457,7 @@ static void freeSecretList(void)
74187457 * Looks up secret based on client random and copies it to output_secret
74197458 */
74207459static int snifferSecretCb (unsigned char * client_random ,
7460+ int type ,
74217461 unsigned char * output_secret )
74227462{
74237463 unsigned char * secret = NULL ;
@@ -7426,10 +7466,14 @@ static int snifferSecretCb(unsigned char* client_random,
74267466 return WOLFSSL_SNIFFER_FATAL_ERROR ;
74277467 }
74287468
7469+ if (type >= SNIFFER_SECRET_NUM_SECRET_TYPES ) {
7470+ return WOLFSSL_SNIFFER_FATAL_ERROR ;
7471+ }
7472+
74297473 /* get secret from secret table based on client random */
7430- secret = findMasterSecret (client_random );
7474+ secret = findSecret (client_random , type );
74317475 if (secret != NULL ) {
7432- XMEMCPY (output_secret , secret , MASTER_SECRET_LENGTH );
7476+ XMEMCPY (output_secret , secret , SECRET_LENGTH );
74337477 return 0 ;
74347478 }
74357479
0 commit comments