aboutsummaryrefslogtreecommitdiffstats
path: root/src/scripts/cli_tests.py
blob: b86d37b1b308a6c692a0f057a9d1cce70629b15d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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()