@@ -101,6 +101,7 @@ def __init__(self, sock):
101101 self ._pha_supported = False
102102 self .client_cert_compression_algo = None
103103 self .server_cert_compression_algo = None
104+ self .sslkeylogfile = os .environ .get ('SSLKEYLOGFILE' )
104105
105106 def keyingMaterialExporter (self , label , length = 20 ):
106107 """Return keying material as described in RFC 5705
@@ -414,7 +415,6 @@ def _handshakeClientAsync(self, srpParams=(), certParams=(), anonParams=(),
414415 session = None , settings = None , checker = None ,
415416 nextProtos = None , serverName = None , reqTack = True ,
416417 alpn = None ):
417-
418418 handshaker = self ._handshakeClientAsyncHelper (srpParams = srpParams ,
419419 certParams = certParams ,
420420 anonParams = anonParams ,
@@ -427,6 +427,10 @@ def _handshakeClientAsync(self, srpParams=(), certParams=(), anonParams=(),
427427 for result in self ._handshakeWrapperAsync (handshaker , checker ):
428428 yield result
429429
430+ # Log client random and master secret for version < TLS1.3
431+ if self .sslkeylogfile and self .version < (3 , 4 ):
432+ self ._log_session_keys (('CLIENT_RANDOM' , self ._clientRandom , self .session .masterSecret ))
433+
430434
431435 def _handshakeClientAsyncHelper (self , srpParams , certParams , anonParams ,
432436 session , settings , serverName , nextProtos ,
@@ -1323,6 +1327,15 @@ def _clientTLS13Handshake(self, settings, session, clientHello,
13231327 self ._handshake_hash ,
13241328 prfName )
13251329
1330+ # TLS1.3 log Client and Server traffic secrets for SSLKEYLOGFILE
1331+ if self .sslkeylogfile :
1332+ self ._log_session_keys ([
1333+ ('CLIENT_HANDSHAKE_TRAFFIC_SECRET' ,
1334+ clientHello .random , cl_handshake_traffic_secret ),
1335+ ('SERVER_HANDSHAKE_TRAFFIC_SECRET' ,
1336+ clientHello .random , sr_handshake_traffic_secret )
1337+ ])
1338+
13261339 # prepare for reading encrypted messages
13271340 self ._recordLayer .calcTLS1_3PendingState (
13281341 serverHello .cipher_suite ,
@@ -1613,6 +1626,16 @@ def _clientTLS13Handshake(self, settings, session, clientHello,
16131626 bytearray (b'exp master' ),
16141627 self ._handshake_hash , prfName )
16151628
1629+
1630+ # Now that we have all the TLS1.3 secrets during the handshake,
1631+ # log them if necessary
1632+ if self .sslkeylogfile :
1633+ self ._log_session_keys ([
1634+ ('EXPORTER_SECRET' , clientHello .random , exporter_master_secret ),
1635+ ('CLIENT_TRAFFIC_SECRET_0' , clientHello .random , cl_app_traffic ),
1636+ ('SERVER_TRAFFIC_SECRET_0' , clientHello .random , sr_app_traffic )
1637+ ])
1638+
16161639 self ._recordLayer .calcTLS1_3PendingState (
16171640 serverHello .cipher_suite ,
16181641 cl_app_traffic ,
@@ -1708,7 +1731,9 @@ def _clientTLS13Handshake(self, settings, session, clientHello,
17081731 exporterMasterSecret = exporter_master_secret ,
17091732 resumptionMasterSecret = resumption_master_secret ,
17101733 # NOTE it must be a reference, not a copy!
1711- tickets = self .tickets )
1734+ tickets = self .tickets ,
1735+ cl_hs_traffic_secret = cl_handshake_traffic_secret ,
1736+ sr_hs_traffic_secret = sr_handshake_traffic_secret )
17121737
17131738 yield "finished" if not resuming else "resumed_and_finished"
17141739
@@ -2250,6 +2275,12 @@ def handshakeServerAsync(self, verifierDB=None,
22502275 for result in self ._handshakeWrapperAsync (handshaker , checker ):
22512276 yield result
22522277
2278+ # Log client random and master secret for version < TLS1.3
2279+ if self .sslkeylogfile and self .version < (3 , 4 ):
2280+ self ._log_session_keys (('CLIENT_RANDOM' ,
2281+ self ._clientRandom ,
2282+ self .session .masterSecret ))
2283+
22532284
22542285 def _handshakeServerAsyncHelper (self , verifierDB ,
22552286 cert_chain , privateKey , reqCert ,
@@ -2956,6 +2987,16 @@ def _serverTLS13Handshake(self, settings, clientHello, cipherSuite,
29562987 bytearray (b'c hs traffic' ),
29572988 self ._handshake_hash ,
29582989 prf_name )
2990+
2991+ # TLS1.3 log Client and Server traffic secrets for SSLKEYLOGFILE
2992+ if self .sslkeylogfile :
2993+ self ._log_session_keys ([
2994+ ('CLIENT_HANDSHAKE_TRAFFIC_SECRET' ,
2995+ clientHello .random , cl_handshake_traffic_secret ),
2996+ ('SERVER_HANDSHAKE_TRAFFIC_SECRET' ,
2997+ clientHello .random , sr_handshake_traffic_secret )
2998+ ])
2999+
29593000 self .version = version
29603001 self ._recordLayer .calcTLS1_3PendingState (
29613002 cipherSuite ,
@@ -3222,6 +3263,20 @@ def _serverTLS13Handshake(self, settings, clientHello, cipherSuite,
32223263 self ._handshake_hash ,
32233264 prf_name )
32243265
3266+
3267+ # Now that we have all the TLS1.3 secrets during the handshake,
3268+ # log them if necessary
3269+ if self .sslkeylogfile :
3270+ self ._log_session_keys ([
3271+ ('EXPORTER_SECRET' ,
3272+ clientHello .random , exporter_master_secret ),
3273+ ('CLIENT_TRAFFIC_SECRET_0' ,
3274+ clientHello .random , cl_app_traffic ),
3275+ ('SERVER_TRAFFIC_SECRET_0' ,
3276+ clientHello .random , sr_app_traffic )
3277+ ])
3278+
3279+
32253280 # verify Finished of client
32263281 cl_finished_key = HKDF_expand_label (cl_handshake_traffic_secret ,
32273282 b"finished" , b'' ,
@@ -3285,7 +3340,9 @@ def _serverTLS13Handshake(self, settings, clientHello, cipherSuite,
32853340 exporterMasterSecret = exporter_master_secret ,
32863341 resumptionMasterSecret = resumption_master_secret ,
32873342 # NOTE it must be a reference, not a copy
3288- tickets = self .tickets )
3343+ tickets = self .tickets ,
3344+ cl_hs_traffic_secret = cl_handshake_traffic_secret ,
3345+ sr_hs_traffic_secret = sr_handshake_traffic_secret )
32893346
32903347 # switch to application_traffic_secret for client packets
32913348 self ._changeReadState ()
@@ -4738,6 +4795,11 @@ def _serverFinished(self, premasterSecret, clientRandom, serverRandom,
47384795 clientRandom , serverRandom ,
47394796 cipherImplementations )
47404797
4798+ #Log client random and master secret if SSLKEYLOGFILE is set
4799+ if self .sslkeylogfile and self .version < (3 , 3 ):
4800+ print ('Logging session keys in serverFinished' )
4801+ self ._log_session_keys (("CLIENT_RANDOM" , clientRandom , masterSecret ))
4802+
47414803 #Exchange ChangeCipherSpec and Finished messages
47424804 for result in self ._getFinished (masterSecret ,
47434805 cipherSuite ,
@@ -4934,6 +4996,19 @@ def _calculate_master_secret(self, premaster_secret, cipher_suite,
49344996 output_length = 48 )
49354997 return secret
49364998
4999+ def _log_session_keys (self , keys ):
5000+ if isinstance (keys , tuple ):
5001+ keys = [keys ]
5002+
5003+ with open (self .sslkeylogfile , 'a' ) as ssl_key_log_file :
5004+ ssl_key_log_file .writelines (
5005+ "{0} {1} {2}\n " .format (
5006+ label ,
5007+ binascii .hexlify (client_random ).decode ().upper (),
5008+ binascii .hexlify (secret ).decode ().upper ())
5009+ for label , client_random , secret in keys
5010+ )
5011+
49375012 @staticmethod
49385013 def _pickServerKeyExchangeSig (settings , clientHello , certList = None ,
49395014 private_key = None ,
0 commit comments