File: test_digest.py

package info (click to toggle)
python-nss 1.0.1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,520 kB
  • sloc: ansic: 30,852; python: 3,346; makefile: 7
file content (121 lines) | stat: -rwxr-xr-x 5,059 bytes parent folder | download | duplicates (3)
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
116
117
118
119
120
121
from __future__ import print_function
from __future__ import absolute_import
import subprocess
import sys
import unittest

import nss.nss as nss

#-------------------------------------------------------------------------------

verbose = False
in_filename = sys.argv[0]
chunk_size = 128


#-------------------------------------------------------------------------------

class TestDigest(unittest.TestCase):
    def setUp(self):
        nss.nss_init_nodb()

    def tearDown(self):
        nss.nss_shutdown()

    def do_test(self, name, ref_cmd, nss_digest_func, hash_oid):
        hash_oid_name = nss.oid_str(hash_oid)

        if verbose:
            print('running test %s: nss_digest_func=%s hash_oid=%s in_filename=%s' % \
                (name, nss_digest_func.__name__, hash_oid_name, in_filename))

        # read binary data in from the file
        with open(in_filename, "rb") as f:
            ref_data = f.read()

        # Run the system hash function to get a reference result.
        # Since we're testing the python-nss binding we assume
        # the system command is entirely independent and correct.
        #
        # Because our digest routines return binary data (e.g. a buffer
        # of octets) and the system hash command returns a hex string
        # which we need to compare against, and because we sometimes
        # want to print the result of our digest functions always
        # convert our results to a hex string via nss.data_to_hex()
        #
        # We want to read the reference result from the subprocess as text
        # not binary, thus universal_newlines must be True.
        proc = subprocess.Popen([ref_cmd, in_filename], stdout=subprocess.PIPE,
                                universal_newlines=True)
        stdout, stderr = proc.communicate()
        reference_digest = stdout.split()[0]
        if verbose:
            print('reference_digest\n%s' % (reference_digest))

        # Run the test with convenience digest function (e.g. nss.sha256_digest, etc.).
        test_digest =  nss.data_to_hex(nss_digest_func(ref_data), separator=None)
        if verbose:
            print('nss %s\n%s' % (nss_digest_func.__name__, test_digest))

        self.assertEqual(test_digest, reference_digest,
                         msg='nss %s test failed reference=%s test=%s' % \
                             (nss_digest_func.__name__, reference_digest, test_digest))

        # Run the test using the generic hash_buf function specifying the hash algorithm.
        test_digest =  nss.data_to_hex(nss.hash_buf(hash_oid, ref_data), separator=None)
        if verbose:
            print('nss.hash_buf %s\n%s' % (hash_oid_name, test_digest))

        self.assertEqual(test_digest, reference_digest,
                         msg='nss.hash_buf %s test failed reference=%s test=%s' % \
                             (hash_oid_name, reference_digest, test_digest))

        # Run the test using the lowest level hashing functions by specifying the hash algorithm.
        # The entire input data is supplied all at once in a single call.
        context = nss.create_digest_context(hash_oid)
        context.digest_begin()
        context.digest_op(ref_data)
        test_digest = nss.data_to_hex(context.digest_final(), separator=None)
        if verbose:
            print('nss.digest_context %s\n%s' % (hash_oid_name, test_digest))

        self.assertEqual(test_digest, reference_digest,
                         msg='nss.digest_context %s test failed reference=%s test=%s' % \
                             (hash_oid_name, reference_digest, test_digest))

        # Run the test using the lowest level hashing functions by specifying the hash algorithm
        # and feeding 'chunks' of data one at a time to be consumed.
        with open(in_filename, 'rb') as in_file:
            context = nss.create_digest_context(hash_oid)
            context.digest_begin()
            while True:
                in_data = in_file.read(chunk_size)
                if len(in_data) == 0:
                    break
                context.digest_op(in_data)

        test_digest = nss.data_to_hex(context.digest_final(), separator=None)
        if verbose:
            print('chunked nss.digest_context %s\n%s' % (hash_oid_name, test_digest))

        self.assertEqual(test_digest, reference_digest,
                         msg='chunked nss.digest_context %s test failed reference=%s test=%s' % \
                             (hash_oid_name, reference_digest, test_digest))

    def test_md5(self):
        self.do_test('md5', 'md5sum', nss.md5_digest, nss.SEC_OID_MD5)

    def test_sha1(self):
        self.do_test('sha1', 'sha1sum', nss.sha1_digest, nss.SEC_OID_SHA1)

    def test_sha256(self):
        self.do_test('sha256', 'sha256sum', nss.sha256_digest, nss.SEC_OID_SHA256)

    def test_sha512(self):
        self.do_test('sha512', 'sha512sum', nss.sha512_digest, nss.SEC_OID_SHA512)


#-------------------------------------------------------------------------------

if __name__ == '__main__':
    unittest.main()