Skip to content

Commit

Permalink
Merge pull request #763 from tlsfuzzer/dhe-for-gcm
Browse files Browse the repository at this point in the history
(EC)DHE support for malformed GCM tags test case
  • Loading branch information
tomato42 committed Jun 17, 2021
2 parents 2cf33f0 + 440d8f6 commit 046dc12
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 17 deletions.
84 changes: 67 additions & 17 deletions scripts/test-fuzzed-ciphertext.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,19 @@
fuzz_encrypted_message, AlertGenerator
from tlsfuzzer.expect import ExpectServerHello, ExpectCertificate, \
ExpectServerHelloDone, ExpectChangeCipherSpec, ExpectFinished, \
ExpectAlert, ExpectClose, ExpectApplicationData
ExpectAlert, ExpectClose, ExpectApplicationData, \
ExpectServerKeyExchange

from tlslite.constants import CipherSuite, AlertLevel, AlertDescription
from tlslite.constants import CipherSuite, AlertLevel, AlertDescription, \
GroupName, ExtensionType
from tlslite.extensions import SupportedGroupsExtension, \
SignatureAlgorithmsExtension, SignatureAlgorithmsCertExtension
from tlsfuzzer.utils.lists import natural_sort_keys
from tlsfuzzer.helpers import SIG_ALL


version = 3

version = 2

def help_msg():
print("Usage: <script-name> [-h hostname] [-p port] [[probe-name] ...]")
Expand All @@ -40,7 +47,8 @@ def help_msg():
print(" execution of preceding expected failure probe")
print(" usage: [-x probe-name] [-X exception], order is compulsory!")
print(" -n num run 'num' or all(if 0) tests instead of default(all)")
print(" (excluding \"sanity\" tests)")
print(" (\"sanity\" tests are always executed)")
print(" -d negotiate (EC)DHE instead of RSA key exchange")
print(" --help this message")


Expand All @@ -52,9 +60,10 @@ def main():
run_exclude = set()
expected_failures = {}
last_exp_tmp = None
dhe = False

argv = sys.argv[1:]
opts, args = getopt.getopt(argv, "h:p:e:x:X:n:", ["help"])
opts, args = getopt.getopt(argv, "h:p:e:x:X:n:d", ["help"])
for opt, arg in opts:
if opt == '-h':
host = arg
Expand All @@ -71,6 +80,8 @@ def main():
expected_failures[last_exp_tmp] = str(arg)
elif opt == '-n':
num_limit = int(arg)
elif opt == '-d':
dhe = True
elif opt == '--help':
help_msg()
sys.exit(0)
Expand All @@ -86,19 +97,37 @@ def main():

conversation = Connect(host, port)
node = conversation
ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
node = node.add_child(ClientHelloGenerator(ciphers))
if dhe:
ext = {}
groups = [GroupName.secp256r1,
GroupName.ffdhe2048]
ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
.create(groups)
ext[ExtensionType.signature_algorithms] = \
SignatureAlgorithmsExtension().create(SIG_ALL)
ext[ExtensionType.signature_algorithms_cert] = \
SignatureAlgorithmsCertExtension().create(SIG_ALL)
ciphers = [CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
else:
ext = None
ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
node = node.add_child(ExpectServerHello())
node = node.add_child(ExpectCertificate())
if dhe:
node = node.add_child(ExpectServerKeyExchange())
node = node.add_child(ExpectServerHelloDone())
node = node.add_child(ClientKeyExchangeGenerator())
node = node.add_child(ChangeCipherSpecGenerator())
node = node.add_child(FinishedGenerator())
node = node.add_child(ExpectChangeCipherSpec())
node = node.add_child(ExpectFinished())
node = node.add_child(
ApplicationDataGenerator(b"GET / HTTP/1.0\n\n"))
ApplicationDataGenerator(b"GET / HTTP/1.0\r\n\r\n"))
node = node.add_child(ExpectApplicationData())
node = node.add_child(AlertGenerator(AlertLevel.warning,
AlertDescription.close_notify))
Expand All @@ -107,27 +136,45 @@ def main():
conversations["sanity"] = conversation

# 8 chars: explicit nonce
# 16 chars: AES-CTR encrypt: GET / HTTP/1.0\n\n
# 18 chars: AES-CTR encrypt: GET / HTTP/1.0\r\n\r\n
# 16 chars: GCM tag 128 bit
# 1 char: experimentally determined there mysteriously is one more byte
# in the message.
fuzzes = [(-i, 1) for i in range(1,8+16+16+1)]
# 1 char: because the offsets are 1-based, not 0-based
fuzzes = [(-i, j) for i in range(1,8+18+16+1)
for j in [1 << x for x in range(8)]]
for pos, val in fuzzes:
conversation = Connect(host, port)
node = conversation
ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
node = node.add_child(ClientHelloGenerator(ciphers))
if dhe:
ext = {}
groups = [GroupName.secp256r1,
GroupName.ffdhe2048]
ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
.create(groups)
ext[ExtensionType.signature_algorithms] = \
SignatureAlgorithmsExtension().create(SIG_ALL)
ext[ExtensionType.signature_algorithms_cert] = \
SignatureAlgorithmsCertExtension().create(SIG_ALL)
ciphers = [CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
else:
ext = None
ciphers = [CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
node = node.add_child(ExpectServerHello())
node = node.add_child(ExpectCertificate())
if dhe:
node = node.add_child(ExpectServerKeyExchange())
node = node.add_child(ExpectServerHelloDone())
node = node.add_child(ClientKeyExchangeGenerator())
node = node.add_child(ChangeCipherSpecGenerator())
node = node.add_child(FinishedGenerator())
node = node.add_child(ExpectChangeCipherSpec())
node = node.add_child(ExpectFinished())
node = node.add_child(fuzz_encrypted_message(
ApplicationDataGenerator(b"GET / HTTP/1.0\n\n"), xors={pos:val}))
ApplicationDataGenerator(b"GET / HTTP/1.0\r\n\r\n"), xors={pos:val}))
node = node.add_child(ExpectAlert(AlertLevel.fatal,
AlertDescription.bad_record_mac))
node = node.add_child(ExpectClose())
Expand Down Expand Up @@ -199,6 +246,9 @@ def main():
bad += 1
failed.append(c_name)

print("Basic test to verify if AES-128-GCM tags are being checked by the")
print("server. Expects TLS 1.2 or earlier and RSA key exchange (or (EC)DHE")
print("if -d option is used\n")
print("Test end")
print(20 * '=')
print("version: {0}".format(version))
Expand Down
2 changes: 2 additions & 0 deletions tests/tlslite-ng-random-subset.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@
"arguments" : ["--named-ffdh", "RFC5054 group 3"]},
{"name" : "test-ffdhe-negotiation.py"},
{"name" : "test-fuzzed-ciphertext.py"},
{"name" : "test-fuzzed-ciphertext.py",
"arguments" : ["-d"]},
{"name" : "test-fuzzed-finished.py"},
{"name" : "test-fuzzed-MAC.py"},
{"name" : "test-fuzzed-padding.py"},
Expand Down
2 changes: 2 additions & 0 deletions tests/tlslite-ng.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@
"arguments" : ["--named-ffdh", "RFC5054 group 3"]},
{"name" : "test-ffdhe-negotiation.py"},
{"name" : "test-fuzzed-ciphertext.py"},
{"name" : "test-fuzzed-ciphertext.py",
"arguments" : ["-d"]},
{"name" : "test-fuzzed-finished.py"},
{"name" : "test-fuzzed-MAC.py"},
{"name" : "test-fuzzed-padding.py"},
Expand Down

0 comments on commit 046dc12

Please sign in to comment.