diff options
author | Jack Lloyd <[email protected]> | 2018-03-10 15:42:41 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-03-10 15:42:41 -0500 |
commit | 5a062118ef5e4c508caa67fc8c3a38a7e1db069f (patch) | |
tree | 5ec06e8b42f6f79d19146aa070acb7a1e3d6c314 | |
parent | afe4ae0f83b7207873afac760cb3c32ed40ce4c9 (diff) |
Split Python tests out of botan2.py
No reason to ship these to the end user
-rwxr-xr-x | src/python/botan2.py | 258 | ||||
-rwxr-xr-x | src/scripts/ci_build.py | 10 | ||||
-rwxr-xr-x | src/scripts/install.py | 5 | ||||
-rw-r--r-- | src/scripts/test_python.py | 265 |
4 files changed, 277 insertions, 261 deletions
diff --git a/src/python/botan2.py b/src/python/botan2.py index 700719496..07f4b0d01 100755 --- a/src/python/botan2.py +++ b/src/python/botan2.py @@ -18,7 +18,7 @@ versions of Botan >= 2.0 import sys from ctypes import CDLL, POINTER, byref, c_void_p, c_size_t, c_uint32, c_char, c_char_p, create_string_buffer -from binascii import hexlify, unhexlify, b2a_base64 +from binascii import hexlify from datetime import datetime import time @@ -93,12 +93,9 @@ def _ctype_bufout(buf): else: return buf.raw -def hex_encode(buf): +def _hex_encode(buf): return hexlify(buf).decode('ascii') -def hex_decode(buf): - return unhexlify(buf.encode('ascii')) - # # Versions # @@ -404,7 +401,7 @@ class public_key(object): # pylint: disable=invalid-name buf_len = c_size_t(n) botan.botan_pubkey_fingerprint(self.pubkey, _ctype_str(hash_algorithm), buf, byref(buf_len)) - return hex_encode(buf[0:buf_len.value]) + return _hex_encode(buf[0:buf_len.value]) class private_key(object): # pylint: disable=invalid-name def __init__(self, alg, param, rng_instance): @@ -716,252 +713,3 @@ class x509_cert(object): # pylint: disable=invalid-name c_void_p, c_char_p, c_size_t, POINTER(c_char), POINTER(c_size_t)] return _call_fn_returning_string( 0, lambda b, bl: botan.botan_x509_cert_get_subject_dn(self.x509_cert, _ctype_str(key), index, b, bl)) - - -# -# Tests and examples -# -def test(): - - def test_version(): - - print("\n%s" % version_string()) - print("v%d.%d.%d\n" % (version_major(), version_minor(), version_patch())) - print("\nPython %s\n" % sys.version.replace('\n', ' ')) - - def test_kdf(): - print("KDF2(SHA-1) %s" % - hex_encode(kdf('KDF2(SHA-1)', hex_decode('701F3480DFE95F57941F804B1B2413EF'), 7, - hex_decode('55A4E9DD5F4CA2EF82'), hex_decode('')))) - - def test_pbkdf(): - print("PBKDF2(SHA-1) %s" % - hex_encode(pbkdf('PBKDF2(SHA-1)', '', 32, 10000, hex_decode('0001020304050607'))[2])) - print("good output %s\n" % - '59B2B1143B4CB1059EC58D9722FB1C72471E0D85C6F7543BA5228526375B0127') - - (salt, iterations, psk) = pbkdf_timed('PBKDF2(SHA-256)', 'xyz', 32, 200) - - print("PBKDF2(SHA-256) x=timed, y=iterated; salt = %s (len=%d) #iterations = %d\n" % - (hex_encode(salt), len(salt), iterations)) - - print('x %s' % hex_encode(psk)) - print('y %s\n' % (hex_encode(pbkdf('PBKDF2(SHA-256)', 'xyz', 32, iterations, salt)[2]))) - - def test_bcrypt(): - print("Testing Bcrypt...") - r = rng() - phash = bcrypt('testing', r) - print("bcrypt returned %s (%d bytes)" % (hex_encode(phash), len(phash))) - print("validating the hash produced: %r" % (check_bcrypt('testing', phash))) - print("\n") - - def test_hmac(): - - hmac = message_authentication_code('HMAC(SHA-256)') - hmac.set_key(hex_decode('0102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20')) - hmac.update(hex_decode('616263')) - - hmac_vec = hex_decode('A21B1F5D4CF4F73A4DD939750F7A066A7F98CC131CB16A6692759021CFAB8181') - hmac_output = hmac.final() - - if hmac_output != hmac_vec: - print("Bad HMAC:\t%s" % hex_encode(hmac_output)) - print("vs good: \t%s" % hex_encode(hmac_vec)) - else: - print("HMAC output correct: %s\n" % hex_encode(hmac_output)) - - def test_rng(): - user_rng = rng("user") - - print("rng output:\n\t%s\n\t%s\n\t%s\n" % - (hex_encode(user_rng.get(42)), - hex_encode(user_rng.get(13)), - hex_encode(user_rng.get(9)))) - - def test_hash(): - md5 = hash_function('MD5') - assert md5.output_length() == 16 - md5.update('h') - md5.update('i') - h1 = md5.final() - print("md5 hash: %s (%s)\n" % (hex_encode(h1), '49f68a5c8493ec2c0bf489821c21fc3b')) - - md5.update(hex_decode('f468025b')) - h2 = md5.final() - print("md5 hash: %s (%s)\n" % (hex_encode(h2), '47efd2be302a937775e93dea281b6751')) - - def test_cipher(): - for mode in ['AES-128/CTR-BE', 'Serpent/GCM', 'ChaCha20Poly1305']: - enc = cipher(mode, encrypt=True) - - (kmin, kmax) = enc.key_length() - print("%s: default nonce=%d update_size=%d key_min=%d key_max=%d" % - (mode, enc.default_nonce_length(), enc.update_granularity(), kmin, kmax)) - iv = rng().get(enc.default_nonce_length()) - key = rng().get(kmax) - pt = rng().get(21) - - print(" plaintext %s (%d)" % (hex_encode(pt), len(pt))) - - enc.set_key(key) - enc.start(iv) - - update_result = enc.update('') - assert not update_result - - ct = enc.finish(pt) - print(" ciphertext %s (%d)" % (hex_encode(ct), len(ct))) - - dec = cipher(mode, encrypt=False) - dec.set_key(key) - dec.start(iv) - decrypted = dec.finish(ct) - - print(" decrypted %s (%d)\n" % (hex_encode(decrypted), len(decrypted))) - - - def test_mceliece(): - mce_priv = private_key('mce', [2960, 57], rng()) - mce_pub = mce_priv.get_public_key() - - mce_plaintext = 'mce plaintext' - mce_ad = 'mce AD' - mce_ciphertext = mceies_encrypt(mce_pub, rng(), 'ChaCha20Poly1305', mce_plaintext, mce_ad) - - print("mceies len(pt)=%d len(ct)=%d" % (len(mce_plaintext), len(mce_ciphertext))) - - mce_decrypt = mceies_decrypt(mce_priv, 'ChaCha20Poly1305', mce_ciphertext, mce_ad) - print(" mceies plaintext \'%s\' (%d)" % (mce_plaintext, len(mce_plaintext))) - - # Since mceies_decrypt() returns bytes in Python3, the following line - # needs .decode('utf-8') to convert mce_decrypt from bytes to a - # text string (Unicode). - # You don't need to add .decode() if - # (a) your expected output is bytes rather than a text string, or - # (b) you are using Python2 rather than Python3. - print(" mceies decrypted \'%s\' (%d)" % (mce_decrypt.decode('utf-8'), len(mce_decrypt))) - - print("mce_pub %s/SHA-1 fingerprint: %s\nEstimated strength %s bits (len %d)\n" % ( - mce_pub.algo_name(), mce_pub.fingerprint("SHA-1"), - mce_pub.estimated_strength(), len(mce_pub.encoding()) - )) - - def test_rsa(): - rsapriv = private_key('rsa', 1536, rng()) - rsapub = rsapriv.get_public_key() - - print("rsapub %s SHA-1 fingerprint: %s estimated strength %d (len %d)" % ( - rsapub.algo_name(), rsapub.fingerprint("SHA-1"), - rsapub.estimated_strength(), len(rsapub.encoding()) - )) - - dec = pk_op_decrypt(rsapriv, "EME1(SHA-256)") - enc = pk_op_encrypt(rsapub, "EME1(SHA-256)") - - sys_rng = rng() - symkey = sys_rng.get(32) - ctext = enc.encrypt(symkey, sys_rng) - print("ptext \'%s\' (%d)" % (hex_encode(symkey), len(symkey))) - print("ctext \'%s\' (%d)" % (hex_encode(ctext), len(ctext))) - print("decrypt \'%s\' (%d)\n" % (hex_encode(dec.decrypt(ctext)), - len(dec.decrypt(ctext)))) - - signer = pk_op_sign(rsapriv, 'EMSA4(SHA-384)') - - signer.update('messa') - signer.update('ge') - sig = signer.finish(rng()) - - print("EMSA4(SHA-384) signature: %s" % hex_encode(sig)) - - verify = pk_op_verify(rsapub, 'EMSA4(SHA-384)') - - verify.update('mess') - verify.update('age') - print("good sig accepted? %s" % verify.check_signature(sig)) - - verify.update('mess of things') - verify.update('age') - print("bad sig accepted? %s" % verify.check_signature(sig)) - - verify.update('message') - print("good sig accepted? %s\n" % verify.check_signature(sig)) - - def test_dh(): - a_rng = rng('user') - b_rng = rng('user') - - for dh_grp in ['secp256r1', 'curve25519']: - dh_kdf = 'KDF2(SHA-384)'.encode('utf-8') - a_dh_priv = private_key('ecdh', dh_grp, rng()) - b_dh_priv = private_key('ecdh', dh_grp, rng()) - - a_dh = pk_op_key_agreement(a_dh_priv, dh_kdf) - b_dh = pk_op_key_agreement(b_dh_priv, dh_kdf) - - a_dh_pub = a_dh.public_value() - b_dh_pub = b_dh.public_value() - - a_salt = a_rng.get(8) - b_salt = b_rng.get(8) - - print("ecdh %s pubs:\n %s (salt %s)\n %s (salt %s)\n" % - (dh_grp, - hex_encode(a_dh_pub), hex_encode(a_salt), - hex_encode(b_dh_pub), hex_encode(b_salt))) - - a_key = a_dh.agree(b_dh_pub, 32, a_salt + b_salt) - b_key = b_dh.agree(a_dh_pub, 32, a_salt + b_salt) - - print("ecdh %s shared:\n %s\n %s\n" % - (dh_grp, hex_encode(a_key), hex_encode(b_key))) - - def test_certs(): - cert = x509_cert(filename="src/tests/data/x509/ecc/CSCA.CSCA.csca-germany.1.crt") - print("CSCA (Germany) Certificate\nDetails:") - print("SHA-1 fingerprint: %s" % cert.fingerprint("SHA-1")) - print("Expected: 32:42:1C:C3:EC:54:D7:E9:43:EC:51:F0:19:23:BD:85:1D:F2:1B:B9") - - print("Not before: %s" % cert.time_starts()) - print("Not after: %s" % cert.time_expires()) - - print("Serial number: %s" % hex_encode(cert.serial_number())) - print("Authority Key ID: %s" % hex_encode(cert.authority_key_id())) - print("Subject Key ID: %s" % hex_encode(cert.subject_key_id())) - print("Public key bits:\n%s\n" % b2a_base64(cert.subject_public_key_bits())) - - pubkey = cert.subject_public_key() - print("Public key algo: %s" % pubkey.algo_name()) - print("Public key strength: %s" % pubkey.estimated_strength() + " bits") - - dn_fields = ("Name", "Email", "Organization", "Organizational Unit", "Country") - for field in dn_fields: - try: - print("%s: %s" % (field, cert.subject_dn(field, 0))) - except BotanException: - print("Field: %s not found in certificate" % field) - - print(cert.to_string()) - - test_version() - test_kdf() - test_pbkdf() - test_bcrypt() - test_hmac() - test_rng() - test_hash() - test_cipher() - test_mceliece() - test_rsa() - test_dh() - test_certs() - - -def main(args=None): - if args is None: - args = sys.argv - test() - -if __name__ == '__main__': - sys.exit(main()) diff --git a/src/scripts/ci_build.py b/src/scripts/ci_build.py index 5560ced51..a9a6afbdf 100755 --- a/src/scripts/ci_build.py +++ b/src/scripts/ci_build.py @@ -213,6 +213,7 @@ def run_cmd(cmd, root_dir): cmd = [os.path.expandvars(elem) for elem in cmd] sub_env = os.environ.copy() sub_env['LD_LIBRARY_PATH'] = root_dir + sub_env['PYTHONPATH'] = os.path.join(root_dir, 'src/python') redirect_stdout = None if len(cmd) > 3 and cmd[-2] == '>': @@ -376,6 +377,7 @@ def main(args=None): 'src/scripts/build_docs.py', 'src/scripts/website.py', 'src/scripts/bench.py', + 'src/scripts/test_python.py', 'src/scripts/python_unittests.py', 'src/scripts/python_unittests_unix.py'] @@ -436,14 +438,14 @@ def main(args=None): os.path.join(root_dir, 'src/scripts/cli_tests.py'), botan_exe]) - botan_py = os.path.join(root_dir, 'src/python/botan2.py') + python_tests = os.path.join(root_dir, 'src/scripts/test_python.py') if target in ['shared', 'coverage']: if use_python2: - cmds.append(['python2', botan_py]) + cmds.append(['python2', '-b', python_tests]) if use_python3: - cmds.append(['python3', botan_py]) + cmds.append(['python3', '-b', python_tests]) if target in ['shared', 'static', 'bsi', 'nist']: cmds.append(make_cmd + ['install']) @@ -480,7 +482,7 @@ def main(args=None): if have_prog('coverage'): cmds.append(['coverage', 'run', '--branch', '--rcfile', os.path.join(root_dir, 'src/configs/coverage.rc'), - botan_py]) + python_tests]) if have_prog('codecov'): # If codecov exists assume we are on Travis and report to codecov.io diff --git a/src/scripts/install.py b/src/scripts/install.py index 243d58eda..03a15ba3e 100755 --- a/src/scripts/install.py +++ b/src/scripts/install.py @@ -236,8 +236,9 @@ def main(args): makedirs(prepend_destdir(py_lib_path)) py_dir = cfg['python_dir'] - for py in os.listdir(py_dir): - copy_file(os.path.join(py_dir, py), prepend_destdir(os.path.join(py_lib_path, py))) + + copy_file(os.path.join(py_dir, 'botan2.py'), + prepend_destdir(os.path.join(py_lib_path, 'botan2.py'))) if cfg['with_documentation']: target_doc_dir = os.path.join(options.prefix, options.docdir, diff --git a/src/scripts/test_python.py b/src/scripts/test_python.py new file mode 100644 index 000000000..aad6b212b --- /dev/null +++ b/src/scripts/test_python.py @@ -0,0 +1,265 @@ +#!/usr/bin/env python + +""" +(C) 2015,2017,2018 Jack Lloyd + +Botan is released under the Simplified BSD License (see license.txt) +""" + +import botan2 +import sys +import binascii + +def hex_encode(buf): + return binascii.hexlify(buf).decode('ascii') + +def hex_decode(buf): + return binascii.unhexlify(buf.encode('ascii')) + +def test(): + + def test_version(): + + print("\n%s" % botan2.version_string()) + print("v%d.%d.%d\n" % (botan2.version_major(), botan2.version_minor(), botan2.version_patch())) + print("\nPython %s\n" % sys.version.replace('\n', ' ')) + + def test_kdf(): + print("KDF2(SHA-1) %s" % + hex_encode(botan2.kdf('KDF2(SHA-1)', + hex_decode('701F3480DFE95F57941F804B1B2413EF'), 7, + hex_decode('55A4E9DD5F4CA2EF82'), hex_decode('')))) + + def test_pbkdf(): + print("PBKDF2(SHA-1) %s" % + hex_encode(botan2.pbkdf('PBKDF2(SHA-1)', '', 32, 10000, hex_decode('0001020304050607'))[2])) + print("good output %s\n" % + '59B2B1143B4CB1059EC58D9722FB1C72471E0D85C6F7543BA5228526375B0127') + + (salt, iterations, psk) = botan2.pbkdf_timed('PBKDF2(SHA-256)', 'xyz', 32, 200) + + print("PBKDF2(SHA-256) x=timed, y=iterated; salt = %s (len=%d) #iterations = %d\n" % + (hex_encode(salt), len(salt), iterations)) + + print('x %s' % hex_encode(psk)) + print('y %s\n' % (hex_encode(botan2.pbkdf('PBKDF2(SHA-256)', 'xyz', 32, iterations, salt)[2]))) + + def test_bcrypt(): + print("Testing Bcrypt...") + r = botan2.rng() + phash = botan2.bcrypt('testing', r) + print("bcrypt returned %s (%d bytes)" % (hex_encode(phash), len(phash))) + print("validating the hash produced: %r" % (botan2.check_bcrypt('testing', phash))) + print("\n") + + def test_hmac(): + + hmac = botan2.message_authentication_code('HMAC(SHA-256)') + hmac.set_key(hex_decode('0102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20')) + hmac.update(hex_decode('616263')) + + hmac_vec = hex_decode('A21B1F5D4CF4F73A4DD939750F7A066A7F98CC131CB16A6692759021CFAB8181') + hmac_output = hmac.final() + + if hmac_output != hmac_vec: + print("Bad HMAC:\t%s" % hex_encode(hmac_output)) + print("vs good: \t%s" % hex_encode(hmac_vec)) + else: + print("HMAC output correct: %s\n" % hex_encode(hmac_output)) + + def test_rng(): + user_rng = botan2.rng("user") + + print("rng output:\n\t%s\n\t%s\n\t%s\n" % + (hex_encode(user_rng.get(42)), + hex_encode(user_rng.get(13)), + hex_encode(user_rng.get(9)))) + + def test_hash(): + md5 = botan2.hash_function('MD5') + assert md5.output_length() == 16 + md5.update('h') + md5.update('i') + h1 = md5.final() + print("md5 hash: %s (%s)\n" % (hex_encode(h1), '49f68a5c8493ec2c0bf489821c21fc3b')) + + md5.update(hex_decode('f468025b')) + h2 = md5.final() + print("md5 hash: %s (%s)\n" % (hex_encode(h2), '47efd2be302a937775e93dea281b6751')) + + def test_cipher(): + for mode in ['AES-128/CTR-BE', 'Serpent/GCM', 'ChaCha20Poly1305']: + enc = botan2.cipher(mode, encrypt=True) + + (kmin, kmax) = enc.key_length() + print("%s: default nonce=%d update_size=%d key_min=%d key_max=%d" % + (mode, enc.default_nonce_length(), enc.update_granularity(), kmin, kmax)) + + rng = botan2.rng() + iv = rng.get(enc.default_nonce_length()) + key = rng.get(kmax) + pt = rng.get(21) + + print(" plaintext %s (%d)" % (hex_encode(pt), len(pt))) + + enc.set_key(key) + enc.start(iv) + + update_result = enc.update('') + assert not update_result + + ct = enc.finish(pt) + print(" ciphertext %s (%d)" % (hex_encode(ct), len(ct))) + + dec = botan2.cipher(mode, encrypt=False) + dec.set_key(key) + dec.start(iv) + decrypted = dec.finish(ct) + + print(" decrypted %s (%d)\n" % (hex_encode(decrypted), len(decrypted))) + + + def test_mceliece(): + mce_priv = botan2.private_key('mce', [2960, 57], botan2.rng()) + mce_pub = mce_priv.get_public_key() + + mce_plaintext = 'mce plaintext' + mce_ad = 'mce AD' + mce_ciphertext = botan2.mceies_encrypt(mce_pub, botan2.rng(), 'ChaCha20Poly1305', mce_plaintext, mce_ad) + + print("mceies len(pt)=%d len(ct)=%d" % (len(mce_plaintext), len(mce_ciphertext))) + + mce_decrypt = botan2.mceies_decrypt(mce_priv, 'ChaCha20Poly1305', mce_ciphertext, mce_ad) + print(" mceies plaintext \'%s\' (%d)" % (mce_plaintext, len(mce_plaintext))) + + # Since mceies_decrypt() returns bytes in Python3, the following line + # needs .decode('utf-8') to convert mce_decrypt from bytes to a + # text string (Unicode). + # You don't need to add .decode() if + # (a) your expected output is bytes rather than a text string, or + # (b) you are using Python2 rather than Python3. + print(" mceies decrypted \'%s\' (%d)" % (mce_decrypt.decode('utf-8'), len(mce_decrypt))) + + print("mce_pub %s/SHA-1 fingerprint: %s\nEstimated strength %s bits (len %d)\n" % ( + mce_pub.algo_name(), mce_pub.fingerprint("SHA-1"), + mce_pub.estimated_strength(), len(mce_pub.encoding()) + )) + + def test_rsa(): + rsapriv = botan2.private_key('rsa', 1536, botan2.rng()) + rsapub = rsapriv.get_public_key() + + print("rsapub %s SHA-1 fingerprint: %s estimated strength %d (len %d)" % ( + rsapub.algo_name(), rsapub.fingerprint("SHA-1"), + rsapub.estimated_strength(), len(rsapub.encoding()) + )) + + dec = botan2.pk_op_decrypt(rsapriv, "EME1(SHA-256)") + enc = botan2.pk_op_encrypt(rsapub, "EME1(SHA-256)") + + sys_rng = botan2.rng() + symkey = sys_rng.get(32) + ctext = enc.encrypt(symkey, sys_rng) + print("ptext \'%s\' (%d)" % (hex_encode(symkey), len(symkey))) + print("ctext \'%s\' (%d)" % (hex_encode(ctext), len(ctext))) + print("decrypt \'%s\' (%d)\n" % (hex_encode(dec.decrypt(ctext)), + len(dec.decrypt(ctext)))) + + signer = botan2.pk_op_sign(rsapriv, 'EMSA4(SHA-384)') + + signer.update('messa') + signer.update('ge') + sig = signer.finish(botan2.rng()) + + print("EMSA4(SHA-384) signature: %s" % hex_encode(sig)) + + verify = botan2.pk_op_verify(rsapub, 'EMSA4(SHA-384)') + + verify.update('mess') + verify.update('age') + print("good sig accepted? %s" % verify.check_signature(sig)) + + verify.update('mess of things') + verify.update('age') + print("bad sig accepted? %s" % verify.check_signature(sig)) + + verify.update('message') + print("good sig accepted? %s\n" % verify.check_signature(sig)) + + def test_dh(): + a_rng = botan2.rng('user') + b_rng = botan2.rng('user') + + for dh_grp in ['secp256r1', 'curve25519']: + dh_kdf = 'KDF2(SHA-384)'.encode('utf-8') + a_dh_priv = botan2.private_key('ecdh', dh_grp, botan2.rng()) + b_dh_priv = botan2.private_key('ecdh', dh_grp, botan2.rng()) + + a_dh = botan2.pk_op_key_agreement(a_dh_priv, dh_kdf) + b_dh = botan2.pk_op_key_agreement(b_dh_priv, dh_kdf) + + a_dh_pub = a_dh.public_value() + b_dh_pub = b_dh.public_value() + + a_salt = a_rng.get(8) + b_salt = b_rng.get(8) + + print("ecdh %s pubs:\n %s (salt %s)\n %s (salt %s)\n" % + (dh_grp, + hex_encode(a_dh_pub), hex_encode(a_salt), + hex_encode(b_dh_pub), hex_encode(b_salt))) + + a_key = a_dh.agree(b_dh_pub, 32, a_salt + b_salt) + b_key = b_dh.agree(a_dh_pub, 32, a_salt + b_salt) + + print("ecdh %s shared:\n %s\n %s\n" % + (dh_grp, hex_encode(a_key), hex_encode(b_key))) + + def test_certs(): + cert = botan2.x509_cert(filename="src/tests/data/x509/ecc/CSCA.CSCA.csca-germany.1.crt") + print("CSCA (Germany) Certificate\nDetails:") + print("SHA-1 fingerprint: %s" % cert.fingerprint("SHA-1")) + print("Expected: 32:42:1C:C3:EC:54:D7:E9:43:EC:51:F0:19:23:BD:85:1D:F2:1B:B9") + + print("Not before: %s" % cert.time_starts()) + print("Not after: %s" % cert.time_expires()) + + print("Serial number: %s" % hex_encode(cert.serial_number())) + print("Authority Key ID: %s" % hex_encode(cert.authority_key_id())) + print("Subject Key ID: %s" % hex_encode(cert.subject_key_id())) + print("Public key bits:\n%s\n" % binascii.b2a_base64(cert.subject_public_key_bits())) + + pubkey = cert.subject_public_key() + print("Public key algo: %s" % pubkey.algo_name()) + print("Public key strength: %s" % pubkey.estimated_strength() + " bits") + + dn_fields = ("Name", "Email", "Organization", "Organizational Unit", "Country") + for field in dn_fields: + try: + print("%s: %s" % (field, cert.subject_dn(field, 0))) + except BotanException: + print("Field: %s not found in certificate" % field) + + print(cert.to_string()) + + test_version() + test_kdf() + test_pbkdf() + test_bcrypt() + test_hmac() + test_rng() + test_hash() + test_cipher() + test_mceliece() + test_rsa() + test_dh() + test_certs() + + +def main(args=None): + if args is None: + args = sys.argv + test() + +if __name__ == '__main__': + sys.exit(main()) |