diff options
author | Simon Warta <[email protected]> | 2015-12-12 13:21:43 +0100 |
---|---|---|
committer | Simon Warta <[email protected]> | 2017-04-18 09:37:41 +0200 |
commit | fe6375e0f23757eb65c1ad491ab625afda0ee821 (patch) | |
tree | d1511d3429838398a06d6a91273bf77d42f5dfac /src/scripts | |
parent | 3553ac7b22620604d19da4881201fb416425d23f (diff) |
Add botan encryption cli app
Diffstat (limited to 'src/scripts')
-rwxr-xr-x | src/scripts/cli_tests.py | 115 | ||||
-rw-r--r-- | src/scripts/vecparser.py | 51 |
2 files changed, 166 insertions, 0 deletions
diff --git a/src/scripts/cli_tests.py b/src/scripts/cli_tests.py new file mode 100755 index 000000000..b86d37b1b --- /dev/null +++ b/src/scripts/cli_tests.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 + +import binascii +import collections +import unittest +import argparse +import re +import subprocess +import vecparser +import sys + +cli_binary = "" +testdata = {} + +class TestSequence(unittest.TestCase): + pass + +def create_test(data): + def do_test_expected(self): + iv = data['Nonce'] + key = data['Key'] + ad = data['AD'] if 'AD' in data else "" + plaintext = data['In'].lower() + ciphertext = data['Out'].lower() + algorithm = data['Algorithm'] + direction = data['Direction'] + + if algorithm == "AES-128/GCM": + mode = "aes-128-gcm" + elif algorithm == "AES-192/GCM": + mode = "aes-192-gcm" + elif algorithm == "AES-256/GCM": + mode = "aes-256-gcm" + else: raise Exception("Unknown algorithm: '" + algorithm + "'") + + cmd = [ + cli_binary, + "encryption", + "--mode=%s" % mode, + "--iv=%s" % iv, + "--ad=%s" % ad, + "--key=%s" % key] + if direction == "decrypt": + cmd += ['--decrypt'] + # out_raw = subprocess.check_output(cmd) + + if direction == "decrypt": + invalue = ciphertext + else: + invalue = plaintext + + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) + out_raw = p.communicate(input=binascii.unhexlify(invalue))[0] + out = binascii.hexlify(out_raw).decode("UTF-8").lower() + + # Renamings + if direction == "decrypt": + expected = plaintext + else: + expected = ciphertext + actual = out + self.assertEqual(expected, actual) + return do_test_expected + +def get_testdata(document): + out = collections.OrderedDict() + for algorithm in document: + if algorithm in ['AES-128/GCM', 'AES-192/GCM', 'AES-256/GCM']: + testcase_number = 0 + for testcase in document[algorithm]: + testcase_number += 1 + for direction in ['encrypt', 'decrypt']: + testname = "%s no %d (%s)" % (algorithm.lower(), testcase_number, direction) + testname = re.sub("[^a-z0-9\-]", "_", testname) + testname = re.sub("_+", "_", testname) + testname = testname.strip("_") + out[testname] = {} + for key in testcase: + value = testcase[key] + out[testname][key] = value + out[testname]['Algorithm'] = algorithm + out[testname]['Direction'] = direction + return out + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description="") + parser.add_argument('cli_binary', + help='path to the botan cli binary') + parser.add_argument('unittest_args', nargs="*") + args = parser.parse_args() + + cli_binary = args.cli_binary + + vecfile = vecparser.VecDocument("src/tests/data/aead/gcm.vec") + #data = vecfile.get_data() + #for algo in data: + # print(algo) + # i = 0 + # for testcase in data[algo]: + # i += 1 + # print(str(i) + ":", testcase) + + testdata = get_testdata(vecfile.get_data()) + #for testname in testdata: + # print(testname) + # for key in testdata[testname]: + # print(" " + key + ": " + testdata[testname][key]) + for testname in testdata: + test_method = create_test (testdata[testname]) + test_method.__name__ = 'test_%s' % testname + setattr(TestSequence, test_method.__name__, test_method) + + # Hand over sys.argv[0] and unittest_args to the testing framework + sys.argv[1:] = args.unittest_args + unittest.main() diff --git a/src/scripts/vecparser.py b/src/scripts/vecparser.py new file mode 100644 index 000000000..2f59a0ea2 --- /dev/null +++ b/src/scripts/vecparser.py @@ -0,0 +1,51 @@ +from collections import OrderedDict +import re + +class VecDocument: + data = OrderedDict() + + def __init__(self, filepath): + last_testcase_number = 1 + current_testcase_number = 1 + current_group_name = "" + last_group_name = "" + current_testcase = {} + + PATTERN_GROUPHEADER = "^\[(.+)\]$" + PATTERN_KEYVALUE = "^\s*([a-zA-Z]+)\s*=(.*)$" + + with open(filepath, 'r') as f: + # Append one empty line to simplify parsing + lines = f.read().splitlines() + ["\n"] + + for line in lines: + line = line.strip() + if line.startswith("#"): + pass # Skip + elif line == "": + current_testcase_number += 1 + elif re.match(PATTERN_GROUPHEADER, line): + match = re.match(PATTERN_GROUPHEADER, line) + current_group_name = match.group(1) + elif re.match(PATTERN_KEYVALUE, line): + match = re.match(PATTERN_KEYVALUE, line) + key = match.group(1) + value = match.group(2).strip() + current_testcase[key] = value + + if current_testcase_number != last_testcase_number: + if not current_group_name in self.data: + self.data[current_group_name] = [] + if len(current_testcase) != 0: + self.data[current_group_name].append(current_testcase) + current_testcase = {} + last_testcase_number = current_testcase_number + + if current_group_name != last_group_name: + last_group_name = current_group_name + # Reset testcase number + last_testcase_number = 1 + current_testcase_number = 1 + + def get_data(self): + return self.data |