Skip to content

Commit 9573b81

Browse files
author
Ivan Nikolchev
committed
add new calc_key function
1 parent c32629e commit 9573b81

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

tlslite/mathtls.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
598681
def makeX(salt, username, password):
599682
if len(username)>=256:
600683
raise ValueError("username too long")

0 commit comments

Comments
 (0)