@@ -595,6 +595,89 @@ def calcFinished(version, masterSecret, cipherSuite, handshakeHashes,
595595
596596 return verifyData
597597
598+ def calc_key (version , secret , cipher_suite , label , handshake_hashes = None ,
599+ client_random = None , server_random = None , output_length = None ):
600+ """
601+ Method for calculating different keys depending on input.
602+ It can be used to calculate finished value, master secret,
603+ extended master secret or key expansion.
604+
605+ :param version: TLS protocol version
606+ :type version: tuple(int, int)
607+ :param bytearray secret: master secret or premasterSecret which will be
608+ used in the PRF.
609+ :param int cipher_suite: Negotiated cipher suite of the connection.
610+ :param bytes label: label for the key you want to calculate
611+ (ex. 'master secret', 'extended master secret', etc).
612+ :param handshake_hashes: running hash of the handshake messages
613+ needed for calculating extended master secret or finished value.
614+ :type handshake_hashes: ~tlslite.handshakehashes.HandshakeHashes
615+ :param bytearray client_random: client random needed for calculating
616+ master secret or key expansion.
617+ :param bytearray server_random: server random needed for calculating
618+ master secret or key expansion.
619+ :param int output_length: Number of bytes to output.
620+ """
621+
622+
623+ # SSL3 calculations.
624+ if version == (3 , 0 ):
625+ # Calculating Finished value, either for message sent
626+ # by server or by client
627+ if label == b"client finished" :
628+ senderStr = b"\x43 \x4C \x4E \x54 "
629+ return handshake_hashes .digestSSL (secret , senderStr )
630+ elif label == b"server finished" :
631+ senderStr = b"\x53 \x52 \x56 \x52 "
632+ return handshake_hashes .digestSSL (secret , senderStr )
633+ else :
634+ assert label in [b"key expansion" , b"master secret" ]
635+ func = PRF_SSL
636+
637+ # TLS1.0 or TLS1.1 calculations.
638+ elif version in ((3 , 1 ), (3 , 2 )):
639+ func = PRF
640+ # Seed needed for calculating extended master secret
641+ if label == b"extended master secret" :
642+ seed = handshake_hashes .digest ('md5' ) + \
643+ handshake_hashes .digest ('sha1' )
644+ # Seed needed for calculating Finished value
645+ elif label in [b"server finished" , b"client finished" ]:
646+ seed = handshake_hashes .digest ()
647+ else :
648+ assert label in [b"key expansion" , b"master secret" ]
649+
650+ # TLS1.2 calculations.
651+ else :
652+ assert version == (3 , 3 )
653+ if cipher_suite in CipherSuite .sha384PrfSuites :
654+ func = PRF_1_2_SHA384
655+ # Seed needed for calculating Finished value or extended master
656+ # secret
657+ if label in [b"extended master secret" , b"server finished" ,
658+ b"client finished" ]:
659+ seed = handshake_hashes .digest ('sha384' )
660+ else :
661+ assert label in [b"key expansion" , b"master secret" ]
662+ else :
663+ # Same as above, just using sha256
664+ func = PRF_1_2
665+ if label in [b"extended master secret" , b"server finished" ,
666+ b"client finished" ]:
667+ seed = handshake_hashes .digest ('sha256' )
668+ else :
669+ assert label in [b"key expansion" , b"master secret" ]
670+
671+ # Seed needed for calculating key expansion or master secret
672+ if label == b"key expansion" :
673+ seed = server_random + client_random
674+ if label == b"master secret" :
675+ seed = client_random + server_random
676+
677+ if func == PRF_SSL :
678+ return func (secret , seed , output_length )
679+ return func (secret , label , seed , output_length )
680+
598681def makeX (salt , username , password ):
599682 if len (username )>= 256 :
600683 raise ValueError ("username too long" )
0 commit comments