Skip to content

Commit

Permalink
Merge pull request #868 from GeorgePantelakis/master
Browse files Browse the repository at this point in the history
Extend extract.py to also create measurements file for K inverse
  • Loading branch information
tomato42 committed Oct 5, 2023
2 parents cd236fb + 9e630de commit 3af0fdb
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 46 deletions.
121 changes: 85 additions & 36 deletions tests/test_tlsfuzzer_extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ def test_binary_convert(self):
class TestCommandLine(unittest.TestCase):

@mock.patch(
'tlsfuzzer.extract.Extract.process_measurements_and_create_csv_file'
'tlsfuzzer.extract.Extract.process_and_create_multiple_csv_files'
)
@mock.patch('tlsfuzzer.extract.Log')
@mock.patch('tlsfuzzer.extract.Extract._write_pkts')
Expand Down Expand Up @@ -268,7 +268,7 @@ def test_command_line(self, mock_parse, mock_write, mock_write_pkt,
mock_measurements.assert_not_called()

@mock.patch(
'tlsfuzzer.extract.Extract.process_measurements_and_create_csv_file'
'tlsfuzzer.extract.Extract.process_and_create_multiple_csv_files'
)
@mock.patch('tlsfuzzer.extract.Log')
@mock.patch('tlsfuzzer.extract.Extract._write_pkts')
Expand Down Expand Up @@ -305,7 +305,7 @@ def test_delay_and_CR(self, mock_parse, mock_write, mock_write_pkt,
mock_measurements.assert_not_called()

@mock.patch(
'tlsfuzzer.extract.Extract.process_measurements_and_create_csv_file'
'tlsfuzzer.extract.Extract.process_and_create_multiple_csv_files'
)
@mock.patch('tlsfuzzer.extract.Log')
@mock.patch('tlsfuzzer.extract.Extract._write_pkts')
Expand Down Expand Up @@ -341,7 +341,7 @@ def test_no_quickack(self, mock_parse, mock_write, mock_write_pkt,
mock_measurements.assert_not_called()

@mock.patch(
'tlsfuzzer.extract.Extract.process_measurements_and_create_csv_file'
'tlsfuzzer.extract.Extract.process_and_create_multiple_csv_files'
)
@mock.patch('tlsfuzzer.extract.Log')
@mock.patch('tlsfuzzer.extract.Extract._write_pkts')
Expand Down Expand Up @@ -374,7 +374,7 @@ def test_raw_times(self, mock_parse, mock_write, mock_write_pkt, mock_log,
mock_measurements.assert_not_called()

@mock.patch(
'tlsfuzzer.extract.Extract.process_measurements_and_create_csv_file'
'tlsfuzzer.extract.Extract.process_and_create_multiple_csv_files'
)
@mock.patch('tlsfuzzer.extract.Log')
@mock.patch('tlsfuzzer.extract.Extract._write_pkts')
Expand Down Expand Up @@ -481,7 +481,7 @@ def test_column_name_with_binary_file(self, mock_parse, mock_write, mock_write_p
str(e.exception))

@mock.patch(
'tlsfuzzer.extract.Extract.process_measurements_and_create_csv_file'
'tlsfuzzer.extract.Extract.process_and_create_multiple_csv_files'
)
@mock.patch('tlsfuzzer.extract.Log')
@mock.patch('tlsfuzzer.extract.Extract._write_pkts')
Expand Down Expand Up @@ -554,13 +554,11 @@ def test_incomplete_ext_times_options(self):
@mock.patch('tlsfuzzer.extract.Extract._write_pkts')
@mock.patch('tlsfuzzer.extract.Extract._write_csv')
@mock.patch(
'tlsfuzzer.extract.Extract.process_measurements_and_create_csv_file'
'tlsfuzzer.extract.Extract.process_and_create_multiple_csv_files'
)
@mock.patch('tlsfuzzer.extract.Extract.ecdsa_iter')
@mock.patch('tlsfuzzer.extract.Extract.ecdsa_max_value')
@mock.patch('tlsfuzzer.extract.Extract.parse')
def test_ecdsa_signs_options(self, mock_parse, mock_max_value, mock_iter,
mock_process, mock_write, mock_write_pkt, mock_log):
def test_ecdsa_signs_options(self, mock_parse, mock_process, mock_write,
mock_write_pkt, mock_log):
output = "/tmp"
raw_data = "/tmp/data"
data_size = 32
Expand Down Expand Up @@ -589,21 +587,17 @@ def test_ecdsa_signs_options(self, mock_parse, mock_max_value, mock_iter,
mock_write.assert_not_called()
mock_write_pkt.assert_not_called()
mock_log.assert_not_called()
mock_iter.assert_called_once()
mock_max_value.assert_called_once()
mock_process.assert_called_once()

@mock.patch('tlsfuzzer.extract.Log')
@mock.patch('tlsfuzzer.extract.Extract._write_pkts')
@mock.patch('tlsfuzzer.extract.Extract._write_csv')
@mock.patch(
'tlsfuzzer.extract.Extract.process_measurements_and_create_csv_file'
'tlsfuzzer.extract.Extract.process_and_create_multiple_csv_files'
)
@mock.patch('tlsfuzzer.extract.Extract.ecdsa_iter')
@mock.patch('tlsfuzzer.extract.Extract.ecdsa_max_value')
@mock.patch('tlsfuzzer.extract.Extract.parse')
def test_verbose_option(self, mock_parse, mock_max_value, mock_iter,
mock_process, mock_write, mock_write_pkt, mock_log):
def test_verbose_option(self, mock_parse, mock_process, mock_write,
mock_write_pkt, mock_log):
output = "/tmp"
raw_data = "/tmp/data"
data_size = 32
Expand Down Expand Up @@ -633,21 +627,17 @@ def test_verbose_option(self, mock_parse, mock_max_value, mock_iter,
mock_write.assert_not_called()
mock_write_pkt.assert_not_called()
mock_log.assert_not_called()
mock_iter.assert_called_once()
mock_max_value.assert_called_once()
mock_process.assert_called_once()

@mock.patch('tlsfuzzer.extract.Log')
@mock.patch('tlsfuzzer.extract.Extract._write_pkts')
@mock.patch('tlsfuzzer.extract.Extract._write_csv')
@mock.patch(
'tlsfuzzer.extract.Extract.process_measurements_and_create_csv_file'
'tlsfuzzer.extract.Extract.process_and_create_multiple_csv_files'
)
@mock.patch('tlsfuzzer.extract.Extract.ecdsa_iter')
@mock.patch('tlsfuzzer.extract.Extract.ecdsa_max_value')
@mock.patch('tlsfuzzer.extract.Extract.parse')
def test_frequency_option(self, mock_parse, mock_max_value, mock_iter,
mock_process, mock_write, mock_write_pkt, mock_log):
def test_frequency_option(self, mock_parse, mock_process, mock_write,
mock_write_pkt, mock_log):
output = "/tmp"
raw_data = "/tmp/data"
data_size = 32
Expand Down Expand Up @@ -679,21 +669,17 @@ def test_frequency_option(self, mock_parse, mock_max_value, mock_iter,
mock_write.assert_not_called()
mock_write_pkt.assert_not_called()
mock_log.assert_not_called()
mock_iter.assert_called_once()
mock_max_value.assert_called_once()
mock_process.assert_called_once()

@mock.patch('tlsfuzzer.extract.Log')
@mock.patch('tlsfuzzer.extract.Extract._write_pkts')
@mock.patch('tlsfuzzer.extract.Extract._write_csv')
@mock.patch(
'tlsfuzzer.extract.Extract.process_measurements_and_create_csv_file'
'tlsfuzzer.extract.Extract.process_and_create_multiple_csv_files'
)
@mock.patch('tlsfuzzer.extract.Extract.ecdsa_iter')
@mock.patch('tlsfuzzer.extract.Extract.ecdsa_max_value')
@mock.patch('tlsfuzzer.extract.Extract.parse')
def test_hash_func_option(self, mock_parse, mock_max_value, mock_iter,
mock_process, mock_write, mock_write_pkt, mock_log):
def test_hash_func_option(self, mock_parse, mock_process, mock_write,
mock_write_pkt, mock_log):
output = "/tmp"
raw_data = "/tmp/data"
data_size = 32
Expand Down Expand Up @@ -725,8 +711,6 @@ def test_hash_func_option(self, mock_parse, mock_max_value, mock_iter,
mock_write.assert_not_called()
mock_write_pkt.assert_not_called()
mock_log.assert_not_called()
mock_iter.assert_called_once()
mock_max_value.assert_called_once()
mock_process.assert_called_once()

def test_specify_to_private_keys(self):
Expand Down Expand Up @@ -1284,6 +1268,38 @@ def test_measurement_creation_with_verbose_and_frequency(
"At least one measurement should have been written."
)

@mock.patch('__main__.__builtins__.open')
def test_measurement_creation_with_invert_k_size(
self, mock_file
):
raw_times = join(dirname(abspath(__file__)),
"measurements_test_files", "times.bin")
raw_sigs = join(dirname(abspath(__file__)),
"measurements_test_files", "sigs.bin")
raw_data = join(dirname(abspath(__file__)),
"measurements_test_files", "data.bin")
priv_key = join(dirname(abspath(__file__)),
"measurements_test_files", "priv_key.pem")

mock_file.side_effect = self.file_emulator
self.times_used_write = 0

extract = Extract(
output="/tmp/minerva", raw_times=raw_times, binary=8,
sigs=raw_sigs, data=raw_data, data_size=32, priv_key=priv_key,
key_type="ecdsa"
)

extract.process_measurements_and_create_csv_file(
extract.ecdsa_iter(return_type="invert-k-size"),
extract.ecdsa_max_value()
)

self.assertGreater(
self.times_used_write, 0,
"At least one measurement should have been written."
)

@mock.patch('__main__.__builtins__.open')
def test_measurement_creation_with_hamming_weigt(
self, mock_file
Expand Down Expand Up @@ -1342,8 +1358,10 @@ def test_measurement_creation_with_invalid_iter_option(
extract.ecdsa_max_value()
)

self.assertIn("Iterator return must be k-size or hamming-weight.",
str(e.exception))
self.assertIn(
"Iterator return must be k-size, invert-k-size or hamming-weight.",
str(e.exception)
)

@mock.patch('__main__.__builtins__.open')
def test_measurement_creation_with_wrong_hash_func(
Expand Down Expand Up @@ -1434,3 +1452,34 @@ def test_measurement_creation_with_incomplete_times(

self.assertIn("There are some extra values that are not used.",
str(e.exception))

@mock.patch('__main__.__builtins__.open')
def test_multiple_measurement_creation(
self, mock_file
):
raw_times = join(dirname(abspath(__file__)),
"measurements_test_files", "times.bin")
raw_sigs = join(dirname(abspath(__file__)),
"measurements_test_files", "sigs.bin")
raw_data = join(dirname(abspath(__file__)),
"measurements_test_files", "data.bin")
priv_key = join(dirname(abspath(__file__)),
"measurements_test_files", "priv_key.pem")

mock_file.side_effect = self.file_emulator
self.times_used_write = 0

extract = Extract(
output="/tmp/minerva", raw_times=raw_times, binary=8,
sigs=raw_sigs, data=raw_data, data_size=32, priv_key=priv_key,
key_type="ecdsa"
)

extract.process_and_create_multiple_csv_files({
"measurements.csv": "k-size",
})

self.assertGreater(
self.times_used_write, 0,
"At least one measurement should have been written."
)
48 changes: 38 additions & 10 deletions tlsfuzzer/extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,20 +228,21 @@ def main():
log = Log(logfile)
log.read_log()

analysis = Extract(
extract = Extract(
log, capture, output, ip_address, port, raw_times, col_name,
binary=binary, endian=endian, no_quickack=no_quickack,
delay=delay, carriage_return=carriage_return,
data=data, data_size=data_size, sigs=sigs, priv_key=priv_key,
key_type=key_type, frequency=freq, hash_func=hash_func,
verbose=verbose
)
analysis.parse()
extract.parse()

if all([raw_times, data, data_size, sigs, priv_key]):
analysis.process_measurements_and_create_csv_file(
analysis.ecdsa_iter(), analysis.ecdsa_max_value()
)
extract.process_and_create_multiple_csv_files({
"measurements.csv": "k-size",
"measurements-invert.csv": "invert-k-size",
})


class Extract:
Expand Down Expand Up @@ -889,21 +890,30 @@ def _convert_to_hamming_weight(self, value_iter):
for value in value_iter:
yield bit_count(value)

def _calculate_invert_k(self, value_iter):
"""Iterator. It will calculate the invert K."""
n_value = self.priv_key.curve.order
for value in value_iter:
yield ecdsa.ecdsa.numbertheory.inverse_mod(value, n_value)

def ecdsa_iter(self, return_type="k-size"):
"""
Iterator. Iterator to use for signatures signed by ECDSA private key.
"""
if return_type not in ["k-size", "hamming-weight"]:
raise ValueError(
"Iterator return must be k-size or hamming-weight."
)

k_iter = self._ecdsa_calculate_k()

if return_type == "k-size":
k_wrap_iter = self._convert_to_bit_size(k_iter)
elif return_type == "invert-k-size":
k_wrap_iter = self._convert_to_bit_size(
self._calculate_invert_k(k_iter)
)
elif return_type == "hamming-weight":
k_wrap_iter = self._convert_to_hamming_weight(k_iter)
else:
raise ValueError(
"Iterator return must be k-size, invert-k-size or hamming-weight."
)

return k_wrap_iter

Expand Down Expand Up @@ -1187,6 +1197,24 @@ def process_measurements_and_create_csv_file(

self._measurements_fp.close()

def process_and_create_multiple_csv_files(self, files = {
"measurements.csv": "k-size"
}):
original_measuremments_csv = self.measurements_csv

for file in files:
if self.verbose:
print("Creating {0} file...".format(file))


self.measurements_csv = file

self.process_measurements_and_create_csv_file(
self.ecdsa_iter(return_type=files[file]), self.ecdsa_max_value()
)

self.measurements_csv = original_measuremments_csv

@staticmethod
def hostname_to_ip(hostname):
"""
Expand Down

0 comments on commit 3af0fdb

Please sign in to comment.