diff options
-rwxr-xr-x | src/python/botan2.py | 807 | ||||
-rw-r--r-- | src/scripts/test_python.py | 6 |
2 files changed, 410 insertions, 403 deletions
diff --git a/src/python/botan2.py b/src/python/botan2.py index 243b5a466..6cba59209 100755 --- a/src/python/botan2.py +++ b/src/python/botan2.py @@ -4,7 +4,7 @@ Python wrapper of the botan crypto library https://botan.randombit.net -(C) 2015,2017,2018 Jack Lloyd +(C) 2015,2017,2018,2019 Jack Lloyd (C) 2015 Uri Blumenthal (extensions and patches) Botan is released under the Simplified BSD License (see license.txt) @@ -40,7 +40,7 @@ class BotanException(Exception): if rc == 0: super(BotanException, self).__init__(message) else: - descr = botan.botan_error_description(rc).decode('ascii') + descr = _DLL.botan_error_description(rc).decode('ascii') super(BotanException, self).__init__("%s: %d (%s)" % (message, rc, descr)) def error_code(self): @@ -50,10 +50,10 @@ class BotanException(Exception): # Module initialization # -def load_botan_dll(expected_version): +def _load_botan_dll(expected_version): possible_dll_names = ['libbotan-2.dylib', 'libbotan-2.so'] + \ - ['libbotan-2.so.%d' % (v) for v in reversed(range(8, 16))] + ['libbotan-2.so.%d' % (v) for v in reversed(range(8, 16))] for dll_name in possible_dll_names: try: @@ -65,247 +65,246 @@ def load_botan_dll(expected_version): except OSError: pass - return None - -botan = load_botan_dll(BOTAN_FFI_VERSION) # pylint: disable=invalid-name - -if botan is None: raise BotanException("Could not find a usable Botan shared object library") -# -# ctypes function prototypes -# -def errcheck_for(fn_name): - def errcheck(rc, _func, _args): - # No idea what to do if return value isn't an int, just return it - if not isinstance(rc, int): - return rc - - if rc >= 0: - return rc - if rc == -10: # insufficient buffer space, pass up to caller - return rc - raise BotanException('%s failed' % (fn_name), rc) - return errcheck - -def _botan_ffi_api(fn, args): - fn.argtypes = args - fn.errcheck = errcheck_for(fn.__name__) - -botan.botan_version_string.argtypes = [] -botan.botan_version_string.restype = c_char_p - -botan.botan_error_description.argtypes = [c_int] -botan.botan_error_description.restype = c_char_p - -# RNG -_botan_ffi_api(botan.botan_rng_init, [c_void_p, c_char_p]) -_botan_ffi_api(botan.botan_rng_destroy, [c_void_p]) -_botan_ffi_api(botan.botan_rng_reseed, [c_void_p, c_size_t]) -_botan_ffi_api(botan.botan_rng_reseed_from_rng, [c_void_p, c_void_p, c_size_t]) -_botan_ffi_api(botan.botan_rng_add_entropy, [c_void_p, c_char_p, c_size_t]) -_botan_ffi_api(botan.botan_rng_get, [c_void_p, POINTER(c_char), c_size_t]) - -# Hash function -_botan_ffi_api(botan.botan_hash_init, [c_void_p, c_char_p, c_uint32]) -_botan_ffi_api(botan.botan_hash_destroy, [c_void_p]) -_botan_ffi_api(botan.botan_hash_name, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_hash_clear, [c_void_p]) -_botan_ffi_api(botan.botan_hash_output_length, [c_void_p, POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_hash_update, [c_void_p, POINTER(c_char), c_size_t]) -_botan_ffi_api(botan.botan_hash_final, [c_void_p, POINTER(c_char)]) - -# MAC -_botan_ffi_api(botan.botan_mac_init, [c_void_p, c_char_p, c_uint32]) -_botan_ffi_api(botan.botan_mac_destroy, [c_void_p]) -_botan_ffi_api(botan.botan_mac_name, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_mac_clear, [c_void_p]) -_botan_ffi_api(botan.botan_mac_output_length, [c_void_p, POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_mac_set_key, [c_void_p, POINTER(c_char), c_size_t]) -_botan_ffi_api(botan.botan_mac_update, [c_void_p, POINTER(c_char), c_size_t]) -_botan_ffi_api(botan.botan_mac_final, [c_void_p, POINTER(c_char)]) - -# Cipher -_botan_ffi_api(botan.botan_cipher_init, [c_void_p, c_char_p, c_uint32]) -_botan_ffi_api(botan.botan_cipher_destroy, [c_void_p]) -_botan_ffi_api(botan.botan_cipher_reset, [c_void_p]) -_botan_ffi_api(botan.botan_cipher_name, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_cipher_get_default_nonce_length, [c_void_p, POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_cipher_get_update_granularity, [c_void_p, POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_cipher_get_tag_length, [c_void_p, POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_cipher_valid_nonce_length, [c_void_p, c_size_t]) -_botan_ffi_api(botan.botan_cipher_clear, [c_void_p]) -_botan_ffi_api(botan.botan_cipher_set_key, [c_void_p, POINTER(c_char), c_size_t]) -_botan_ffi_api(botan.botan_cipher_set_associated_data, [c_void_p, POINTER(c_char), c_size_t]) -_botan_ffi_api(botan.botan_cipher_start, [c_void_p, POINTER(c_char), c_size_t]) - -_botan_ffi_api(botan.botan_cipher_update, - [c_void_p, c_uint32, - POINTER(c_char), c_size_t, POINTER(c_size_t), - POINTER(c_char), c_size_t, POINTER(c_size_t)]) - -# Bcrypt -_botan_ffi_api(botan.botan_bcrypt_generate, [POINTER(c_char), POINTER(c_size_t), - c_char_p, c_void_p, c_size_t, c_uint32]) - -_botan_ffi_api(botan.botan_bcrypt_is_valid, [c_char_p, c_char_p]) - -# PBKDF -_botan_ffi_api(botan.botan_pbkdf, [c_char_p, POINTER(c_char), c_size_t, c_char_p, c_void_p, c_size_t, c_size_t]) - -_botan_ffi_api(botan.botan_pbkdf_timed, - [c_char_p, POINTER(c_char), c_size_t, c_char_p, - c_void_p, c_size_t, c_size_t, POINTER(c_size_t)]) - -# Scrypt -_botan_ffi_api(botan.botan_scrypt, - [POINTER(c_char), c_size_t, c_char_p, POINTER(c_char), c_size_t, - c_size_t, c_size_t, c_size_t]) - -# KDF -_botan_ffi_api(botan.botan_kdf, - [c_char_p, POINTER(c_char), c_size_t, POINTER(c_char), c_size_t, - POINTER(c_char), c_size_t, POINTER(c_char), c_size_t]) - -# Public key -_botan_ffi_api(botan.botan_pubkey_destroy, [c_void_p]) -_botan_ffi_api(botan.botan_pubkey_load, [c_void_p, POINTER(c_char), c_size_t]) -_botan_ffi_api(botan.botan_pubkey_estimated_strength, [c_void_p, POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_pubkey_algo_name, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_pubkey_export, [c_void_p, POINTER(c_char), POINTER(c_size_t), c_uint32]) - -_botan_ffi_api(botan.botan_pubkey_fingerprint, - [c_void_p, c_char_p, POINTER(c_char), POINTER(c_size_t)]) - -_botan_ffi_api(botan.botan_privkey_create, [c_void_p, c_char_p, c_char_p, c_void_p]) -_botan_ffi_api(botan.botan_privkey_load, [c_void_p, c_void_p, POINTER(c_char), c_size_t, POINTER(c_char)]) -_botan_ffi_api(botan.botan_privkey_algo_name, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_privkey_export_pubkey, [c_void_p, c_void_p]) -_botan_ffi_api(botan.botan_privkey_destroy, [c_void_p]) -_botan_ffi_api(botan.botan_privkey_export, [c_void_p, POINTER(c_char), c_void_p, c_uint32]) - -# PK Encryption -_botan_ffi_api(botan.botan_pk_op_encrypt_create, [c_void_p, c_void_p, c_char_p, c_uint32]) -_botan_ffi_api(botan.botan_pk_op_encrypt_output_length, [c_void_p, c_size_t, POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_pk_op_encrypt_destroy, [c_void_p]) -_botan_ffi_api(botan.botan_pk_op_encrypt, - [c_void_p, c_void_p, POINTER(c_char), POINTER(c_size_t), - POINTER(c_char), c_size_t]) - -# PK Decryption -_botan_ffi_api(botan.botan_pk_op_decrypt_create, [c_void_p, c_void_p, c_char_p, c_uint32]) -_botan_ffi_api(botan.botan_pk_op_decrypt_output_length, [c_void_p, c_size_t, POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_pk_op_decrypt_destroy, [c_void_p]) - -_botan_ffi_api(botan.botan_pk_op_decrypt, - [c_void_p, - POINTER(c_char), POINTER(c_size_t), - POINTER(c_char), c_size_t]) - -# PK Signatures -_botan_ffi_api(botan.botan_pk_op_sign_create, [c_void_p, c_void_p, c_char_p, c_uint32]) -_botan_ffi_api(botan.botan_pk_op_sign_destroy, [c_void_p]) -_botan_ffi_api(botan.botan_pk_op_sign_update, [c_void_p, POINTER(c_char), c_size_t]) -_botan_ffi_api(botan.botan_pk_op_sign_finish, [c_void_p, c_void_p, POINTER(c_char), POINTER(c_size_t)]) - -# PK Verification -_botan_ffi_api(botan.botan_pk_op_verify_create, [c_void_p, c_void_p, c_char_p, c_uint32]) -_botan_ffi_api(botan.botan_pk_op_verify_destroy, [c_void_p]) -_botan_ffi_api(botan.botan_pk_op_verify_update, [c_void_p, POINTER(c_char), c_size_t]) -_botan_ffi_api(botan.botan_pk_op_verify_finish, [c_void_p, POINTER(c_char), c_size_t]) - -# MCEIES -_botan_ffi_api(botan.botan_mceies_encrypt, - [c_void_p, c_void_p, c_char_p, POINTER(c_char), c_size_t, - POINTER(c_char), c_size_t, POINTER(c_char), POINTER(c_size_t)]) - -_botan_ffi_api(botan.botan_mceies_decrypt, - [c_void_p, c_char_p, POINTER(c_char), c_size_t, - POINTER(c_char), c_size_t, POINTER(c_char), POINTER(c_size_t)]) - -# Key Agreement -_botan_ffi_api(botan.botan_pk_op_key_agreement_export_public, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_pk_op_key_agreement_create, [c_void_p, c_void_p, c_char_p, c_uint32]) -_botan_ffi_api(botan.botan_pk_op_key_agreement_destroy, [c_void_p]) - -_botan_ffi_api(botan.botan_pk_op_key_agreement, - [c_void_p, POINTER(c_char), POINTER(c_size_t), - POINTER(c_char), c_size_t, POINTER(c_char), c_size_t]) - -# X509 certs -_botan_ffi_api(botan.botan_x509_cert_load_file, [POINTER(c_void_p), c_char_p]) -_botan_ffi_api(botan.botan_x509_cert_load, [POINTER(c_void_p), POINTER(c_char), c_size_t]) -_botan_ffi_api(botan.botan_x509_cert_destroy, [c_void_p]) -_botan_ffi_api(botan.botan_x509_cert_get_time_starts, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_x509_cert_get_time_expires, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_x509_cert_to_string, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) - -_botan_ffi_api(botan.botan_x509_cert_get_fingerprint, - [c_void_p, c_char_p, POINTER(c_char), POINTER(c_size_t)]) - -_botan_ffi_api(botan.botan_x509_cert_get_serial_number, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_x509_cert_get_authority_key_id, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_x509_cert_get_subject_key_id, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_x509_cert_get_public_key_bits, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_x509_cert_get_public_key, [c_void_p, c_void_p]) -_botan_ffi_api(botan.botan_x509_cert_get_subject_dn, [c_void_p, c_char_p, c_size_t, POINTER(c_char), POINTER(c_size_t)]) - -# MPI -_botan_ffi_api(botan.botan_mp_init, [c_void_p]) -_botan_ffi_api(botan.botan_mp_destroy, [c_void_p]) -_botan_ffi_api(botan.botan_mp_to_hex, [c_void_p, POINTER(c_char)]) -_botan_ffi_api(botan.botan_mp_to_str, [c_void_p, c_uint8, POINTER(c_char), POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_mp_clear, [c_void_p]) -_botan_ffi_api(botan.botan_mp_set_from_int, [c_void_p, c_int]) -_botan_ffi_api(botan.botan_mp_set_from_mp, [c_void_p, c_void_p]) -_botan_ffi_api(botan.botan_mp_set_from_str, [c_void_p, POINTER(c_char)]) -_botan_ffi_api(botan.botan_mp_set_from_radix_str, [c_void_p, POINTER(c_char), c_size_t]) -_botan_ffi_api(botan.botan_mp_num_bits, [c_void_p, POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_mp_num_bytes, [c_void_p, POINTER(c_size_t)]) -_botan_ffi_api(botan.botan_mp_to_bin, [c_void_p, POINTER(c_uint8)]) -_botan_ffi_api(botan.botan_mp_from_bin, [c_void_p, POINTER(c_uint8), c_size_t]) -_botan_ffi_api(botan.botan_mp_to_uint32, [c_void_p, POINTER(c_uint32)]) -_botan_ffi_api(botan.botan_mp_is_positive, [c_void_p]) -_botan_ffi_api(botan.botan_mp_is_negative, [c_void_p]) -_botan_ffi_api(botan.botan_mp_flip_sign, [c_void_p]) -_botan_ffi_api(botan.botan_mp_is_zero, [c_void_p]) -_botan_ffi_api(botan.botan_mp_is_odd, [c_void_p]) -_botan_ffi_api(botan.botan_mp_is_even, [c_void_p]) -_botan_ffi_api(botan.botan_mp_add, [c_void_p, c_void_p, c_void_p]) -_botan_ffi_api(botan.botan_mp_sub, [c_void_p, c_void_p, c_void_p]) -_botan_ffi_api(botan.botan_mp_mul, [c_void_p, c_void_p, c_void_p]) -_botan_ffi_api(botan.botan_mp_div, [c_void_p, c_void_p, c_void_p, c_void_p]) -_botan_ffi_api(botan.botan_mp_mod_mul, [c_void_p, c_void_p, c_void_p, c_void_p]) -_botan_ffi_api(botan.botan_mp_equal, [c_void_p, c_void_p]) -_botan_ffi_api(botan.botan_mp_cmp, [POINTER(c_int), c_void_p, c_void_p]) -_botan_ffi_api(botan.botan_mp_swap, [c_void_p, c_void_p]) -_botan_ffi_api(botan.botan_mp_powmod, [c_void_p, c_void_p, c_void_p, c_void_p]) -_botan_ffi_api(botan.botan_mp_lshift, [c_void_p, c_void_p, c_size_t]) -_botan_ffi_api(botan.botan_mp_rshift, [c_void_p, c_void_p, c_size_t]) -_botan_ffi_api(botan.botan_mp_mod_inverse, [c_void_p, c_void_p, c_void_p]) -_botan_ffi_api(botan.botan_mp_rand_bits, [c_void_p, c_void_p, c_size_t]) -_botan_ffi_api(botan.botan_mp_rand_range, [c_void_p, c_void_p, c_void_p, c_void_p]) -_botan_ffi_api(botan.botan_mp_gcd, [c_void_p, c_void_p, c_void_p]) -_botan_ffi_api(botan.botan_mp_is_prime, [c_void_p, c_void_p, c_size_t]) -_botan_ffi_api(botan.botan_mp_get_bit, [c_void_p, c_size_t]) -_botan_ffi_api(botan.botan_mp_set_bit, [c_void_p, c_size_t]) -_botan_ffi_api(botan.botan_mp_clear_bit, [c_void_p, c_size_t]) +def _errcheck(rc, fn, _args): + # No idea what to do if return value isn't an int, just return it + if not isinstance(rc, int): + return rc + + if rc >= 0: + return rc + if rc == -10: # insufficient buffer space, pass up to caller + return rc + raise BotanException('%s failed' % (fn.__name__), rc) + +def _set_prototypes(dll): + # pylint: disable=too-many-statements + def ffi_api(fn, args): + fn.argtypes = args + fn.errcheck = _errcheck + + dll.botan_version_string.argtypes = [] + dll.botan_version_string.restype = c_char_p + + dll.botan_error_description.argtypes = [c_int] + dll.botan_error_description.restype = c_char_p + + # RNG + ffi_api(dll.botan_rng_init, [c_void_p, c_char_p]) + ffi_api(dll.botan_rng_destroy, [c_void_p]) + ffi_api(dll.botan_rng_reseed, [c_void_p, c_size_t]) + ffi_api(dll.botan_rng_reseed_from_rng, [c_void_p, c_void_p, c_size_t]) + ffi_api(dll.botan_rng_add_entropy, [c_void_p, c_char_p, c_size_t]) + ffi_api(dll.botan_rng_get, [c_void_p, POINTER(c_char), c_size_t]) + + # Hash function + ffi_api(dll.botan_hash_init, [c_void_p, c_char_p, c_uint32]) + ffi_api(dll.botan_hash_destroy, [c_void_p]) + ffi_api(dll.botan_hash_name, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) + ffi_api(dll.botan_hash_clear, [c_void_p]) + ffi_api(dll.botan_hash_output_length, [c_void_p, POINTER(c_size_t)]) + ffi_api(dll.botan_hash_update, [c_void_p, POINTER(c_char), c_size_t]) + ffi_api(dll.botan_hash_final, [c_void_p, POINTER(c_char)]) + + # MAC + ffi_api(dll.botan_mac_init, [c_void_p, c_char_p, c_uint32]) + ffi_api(dll.botan_mac_destroy, [c_void_p]) + ffi_api(dll.botan_mac_name, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) + ffi_api(dll.botan_mac_clear, [c_void_p]) + ffi_api(dll.botan_mac_output_length, [c_void_p, POINTER(c_size_t)]) + ffi_api(dll.botan_mac_set_key, [c_void_p, POINTER(c_char), c_size_t]) + ffi_api(dll.botan_mac_update, [c_void_p, POINTER(c_char), c_size_t]) + ffi_api(dll.botan_mac_final, [c_void_p, POINTER(c_char)]) + + # Cipher + ffi_api(dll.botan_cipher_init, [c_void_p, c_char_p, c_uint32]) + ffi_api(dll.botan_cipher_destroy, [c_void_p]) + ffi_api(dll.botan_cipher_reset, [c_void_p]) + ffi_api(dll.botan_cipher_name, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) + ffi_api(dll.botan_cipher_get_default_nonce_length, [c_void_p, POINTER(c_size_t)]) + ffi_api(dll.botan_cipher_get_update_granularity, [c_void_p, POINTER(c_size_t)]) + ffi_api(dll.botan_cipher_get_tag_length, [c_void_p, POINTER(c_size_t)]) + ffi_api(dll.botan_cipher_valid_nonce_length, [c_void_p, c_size_t]) + ffi_api(dll.botan_cipher_clear, [c_void_p]) + ffi_api(dll.botan_cipher_set_key, [c_void_p, POINTER(c_char), c_size_t]) + ffi_api(dll.botan_cipher_set_associated_data, [c_void_p, POINTER(c_char), c_size_t]) + ffi_api(dll.botan_cipher_start, [c_void_p, POINTER(c_char), c_size_t]) + + ffi_api(dll.botan_cipher_update, + [c_void_p, c_uint32, + POINTER(c_char), c_size_t, POINTER(c_size_t), + POINTER(c_char), c_size_t, POINTER(c_size_t)]) + + # Bcrypt + ffi_api(dll.botan_bcrypt_generate, [POINTER(c_char), POINTER(c_size_t), + c_char_p, c_void_p, c_size_t, c_uint32]) + + ffi_api(dll.botan_bcrypt_is_valid, [c_char_p, c_char_p]) + + # PBKDF + ffi_api(dll.botan_pbkdf, [c_char_p, POINTER(c_char), c_size_t, c_char_p, c_void_p, c_size_t, c_size_t]) + + ffi_api(dll.botan_pbkdf_timed, + [c_char_p, POINTER(c_char), c_size_t, c_char_p, + c_void_p, c_size_t, c_size_t, POINTER(c_size_t)]) + + # Scrypt + ffi_api(dll.botan_scrypt, + [POINTER(c_char), c_size_t, c_char_p, POINTER(c_char), c_size_t, + c_size_t, c_size_t, c_size_t]) + + # KDF + ffi_api(dll.botan_kdf, + [c_char_p, POINTER(c_char), c_size_t, POINTER(c_char), c_size_t, + POINTER(c_char), c_size_t, POINTER(c_char), c_size_t]) + + # Public key + ffi_api(dll.botan_pubkey_destroy, [c_void_p]) + ffi_api(dll.botan_pubkey_load, [c_void_p, POINTER(c_char), c_size_t]) + ffi_api(dll.botan_pubkey_estimated_strength, [c_void_p, POINTER(c_size_t)]) + ffi_api(dll.botan_pubkey_algo_name, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) + ffi_api(dll.botan_pubkey_export, [c_void_p, POINTER(c_char), POINTER(c_size_t), c_uint32]) + + ffi_api(dll.botan_pubkey_fingerprint, + [c_void_p, c_char_p, POINTER(c_char), POINTER(c_size_t)]) + + ffi_api(dll.botan_privkey_create, [c_void_p, c_char_p, c_char_p, c_void_p]) + ffi_api(dll.botan_privkey_load, [c_void_p, c_void_p, POINTER(c_char), c_size_t, POINTER(c_char)]) + ffi_api(dll.botan_privkey_algo_name, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) + ffi_api(dll.botan_privkey_export_pubkey, [c_void_p, c_void_p]) + ffi_api(dll.botan_privkey_destroy, [c_void_p]) + ffi_api(dll.botan_privkey_export, [c_void_p, POINTER(c_char), c_void_p, c_uint32]) + + # PK Encryption + ffi_api(dll.botan_pk_op_encrypt_create, [c_void_p, c_void_p, c_char_p, c_uint32]) + ffi_api(dll.botan_pk_op_encrypt_output_length, [c_void_p, c_size_t, POINTER(c_size_t)]) + ffi_api(dll.botan_pk_op_encrypt_destroy, [c_void_p]) + ffi_api(dll.botan_pk_op_encrypt, + [c_void_p, c_void_p, POINTER(c_char), POINTER(c_size_t), + POINTER(c_char), c_size_t]) + + # PK Decryption + ffi_api(dll.botan_pk_op_decrypt_create, [c_void_p, c_void_p, c_char_p, c_uint32]) + ffi_api(dll.botan_pk_op_decrypt_output_length, [c_void_p, c_size_t, POINTER(c_size_t)]) + ffi_api(dll.botan_pk_op_decrypt_destroy, [c_void_p]) + + ffi_api(dll.botan_pk_op_decrypt, + [c_void_p, + POINTER(c_char), POINTER(c_size_t), + POINTER(c_char), c_size_t]) + + # PK Signatures + ffi_api(dll.botan_pk_op_sign_create, [c_void_p, c_void_p, c_char_p, c_uint32]) + ffi_api(dll.botan_pk_op_sign_destroy, [c_void_p]) + ffi_api(dll.botan_pk_op_sign_update, [c_void_p, POINTER(c_char), c_size_t]) + ffi_api(dll.botan_pk_op_sign_finish, [c_void_p, c_void_p, POINTER(c_char), POINTER(c_size_t)]) + + # PK Verification + ffi_api(dll.botan_pk_op_verify_create, [c_void_p, c_void_p, c_char_p, c_uint32]) + ffi_api(dll.botan_pk_op_verify_destroy, [c_void_p]) + ffi_api(dll.botan_pk_op_verify_update, [c_void_p, POINTER(c_char), c_size_t]) + ffi_api(dll.botan_pk_op_verify_finish, [c_void_p, POINTER(c_char), c_size_t]) + + # MCEIES + ffi_api(dll.botan_mceies_encrypt, + [c_void_p, c_void_p, c_char_p, POINTER(c_char), c_size_t, + POINTER(c_char), c_size_t, POINTER(c_char), POINTER(c_size_t)]) + + ffi_api(dll.botan_mceies_decrypt, + [c_void_p, c_char_p, POINTER(c_char), c_size_t, + POINTER(c_char), c_size_t, POINTER(c_char), POINTER(c_size_t)]) + + # Key Agreement + ffi_api(dll.botan_pk_op_key_agreement_export_public, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) + ffi_api(dll.botan_pk_op_key_agreement_create, [c_void_p, c_void_p, c_char_p, c_uint32]) + ffi_api(dll.botan_pk_op_key_agreement_destroy, [c_void_p]) + + ffi_api(dll.botan_pk_op_key_agreement, + [c_void_p, POINTER(c_char), POINTER(c_size_t), + POINTER(c_char), c_size_t, POINTER(c_char), c_size_t]) + + # X509 certs + ffi_api(dll.botan_x509_cert_load_file, [POINTER(c_void_p), c_char_p]) + ffi_api(dll.botan_x509_cert_load, [POINTER(c_void_p), POINTER(c_char), c_size_t]) + ffi_api(dll.botan_x509_cert_destroy, [c_void_p]) + ffi_api(dll.botan_x509_cert_get_time_starts, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) + ffi_api(dll.botan_x509_cert_get_time_expires, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) + ffi_api(dll.botan_x509_cert_to_string, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) + + ffi_api(dll.botan_x509_cert_get_fingerprint, + [c_void_p, c_char_p, POINTER(c_char), POINTER(c_size_t)]) + + ffi_api(dll.botan_x509_cert_get_serial_number, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) + ffi_api(dll.botan_x509_cert_get_authority_key_id, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) + ffi_api(dll.botan_x509_cert_get_subject_key_id, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) + ffi_api(dll.botan_x509_cert_get_public_key_bits, [c_void_p, POINTER(c_char), POINTER(c_size_t)]) + ffi_api(dll.botan_x509_cert_get_public_key, [c_void_p, c_void_p]) + ffi_api(dll.botan_x509_cert_get_subject_dn, [c_void_p, c_char_p, c_size_t, POINTER(c_char), POINTER(c_size_t)]) + + # MPI + ffi_api(dll.botan_mp_init, [c_void_p]) + ffi_api(dll.botan_mp_destroy, [c_void_p]) + ffi_api(dll.botan_mp_to_hex, [c_void_p, POINTER(c_char)]) + ffi_api(dll.botan_mp_to_str, [c_void_p, c_uint8, POINTER(c_char), POINTER(c_size_t)]) + ffi_api(dll.botan_mp_clear, [c_void_p]) + ffi_api(dll.botan_mp_set_from_int, [c_void_p, c_int]) + ffi_api(dll.botan_mp_set_from_mp, [c_void_p, c_void_p]) + ffi_api(dll.botan_mp_set_from_str, [c_void_p, POINTER(c_char)]) + ffi_api(dll.botan_mp_set_from_radix_str, [c_void_p, POINTER(c_char), c_size_t]) + ffi_api(dll.botan_mp_num_bits, [c_void_p, POINTER(c_size_t)]) + ffi_api(dll.botan_mp_num_bytes, [c_void_p, POINTER(c_size_t)]) + ffi_api(dll.botan_mp_to_bin, [c_void_p, POINTER(c_uint8)]) + ffi_api(dll.botan_mp_from_bin, [c_void_p, POINTER(c_uint8), c_size_t]) + ffi_api(dll.botan_mp_to_uint32, [c_void_p, POINTER(c_uint32)]) + ffi_api(dll.botan_mp_is_positive, [c_void_p]) + ffi_api(dll.botan_mp_is_negative, [c_void_p]) + ffi_api(dll.botan_mp_flip_sign, [c_void_p]) + ffi_api(dll.botan_mp_is_zero, [c_void_p]) + ffi_api(dll.botan_mp_is_odd, [c_void_p]) + ffi_api(dll.botan_mp_is_even, [c_void_p]) + ffi_api(dll.botan_mp_add, [c_void_p, c_void_p, c_void_p]) + ffi_api(dll.botan_mp_sub, [c_void_p, c_void_p, c_void_p]) + ffi_api(dll.botan_mp_mul, [c_void_p, c_void_p, c_void_p]) + ffi_api(dll.botan_mp_div, [c_void_p, c_void_p, c_void_p, c_void_p]) + ffi_api(dll.botan_mp_mod_mul, [c_void_p, c_void_p, c_void_p, c_void_p]) + ffi_api(dll.botan_mp_equal, [c_void_p, c_void_p]) + ffi_api(dll.botan_mp_cmp, [POINTER(c_int), c_void_p, c_void_p]) + ffi_api(dll.botan_mp_swap, [c_void_p, c_void_p]) + ffi_api(dll.botan_mp_powmod, [c_void_p, c_void_p, c_void_p, c_void_p]) + ffi_api(dll.botan_mp_lshift, [c_void_p, c_void_p, c_size_t]) + ffi_api(dll.botan_mp_rshift, [c_void_p, c_void_p, c_size_t]) + ffi_api(dll.botan_mp_mod_inverse, [c_void_p, c_void_p, c_void_p]) + ffi_api(dll.botan_mp_rand_bits, [c_void_p, c_void_p, c_size_t]) + ffi_api(dll.botan_mp_rand_range, [c_void_p, c_void_p, c_void_p, c_void_p]) + ffi_api(dll.botan_mp_gcd, [c_void_p, c_void_p, c_void_p]) + ffi_api(dll.botan_mp_is_prime, [c_void_p, c_void_p, c_size_t]) + ffi_api(dll.botan_mp_get_bit, [c_void_p, c_size_t]) + ffi_api(dll.botan_mp_set_bit, [c_void_p, c_size_t]) + ffi_api(dll.botan_mp_clear_bit, [c_void_p, c_size_t]) + + # + # FPE + # + ffi_api(dll.botan_fpe_fe1_init, [c_void_p, c_void_p, POINTER(c_char), c_size_t, c_size_t, c_uint32]) + ffi_api(dll.botan_fpe_destroy, [c_void_p]) + ffi_api(dll.botan_fpe_encrypt, [c_void_p, c_void_p, POINTER(c_char), c_size_t]) + ffi_api(dll.botan_fpe_decrypt, [c_void_p, c_void_p, POINTER(c_char), c_size_t]) + + # + # HOTP + # + ffi_api(dll.botan_hotp_init, [c_void_p, POINTER(c_char), c_size_t, c_char_p, c_size_t]) + ffi_api(dll.botan_hotp_destroy, [c_void_p]) + ffi_api(dll.botan_hotp_generate, [c_void_p, POINTER(c_uint32), c_uint64]) + ffi_api(dll.botan_hotp_check, [c_void_p, POINTER(c_uint64), c_uint32, c_uint64, c_size_t]) + + return dll # -# FPE +# Load the DLL and set prototypes on it # -_botan_ffi_api(botan.botan_fpe_fe1_init, [c_void_p, c_void_p, POINTER(c_char), c_size_t, c_size_t, c_uint32]) -_botan_ffi_api(botan.botan_fpe_destroy, [c_void_p]) -_botan_ffi_api(botan.botan_fpe_encrypt, [c_void_p, c_void_p, POINTER(c_char), c_size_t]) -_botan_ffi_api(botan.botan_fpe_decrypt, [c_void_p, c_void_p, POINTER(c_char), c_size_t]) - -# -# HOTP -# -_botan_ffi_api(botan.botan_hotp_init, [c_void_p, POINTER(c_char), c_size_t, c_char_p, c_size_t]) -_botan_ffi_api(botan.botan_hotp_destroy, [c_void_p]) -_botan_ffi_api(botan.botan_hotp_generate, [c_void_p, POINTER(c_uint32), c_uint64]) -_botan_ffi_api(botan.botan_hotp_check, [c_void_p, POINTER(c_uint64), c_uint32, c_uint64, c_size_t]) +_DLL = _set_prototypes(_load_botan_dll(BOTAN_FFI_VERSION)) # # Internal utilities @@ -368,16 +367,16 @@ def _hex_encode(buf): # Versions # def version_major(): - return botan.botan_version_major() + return _DLL.botan_version_major() def version_minor(): - return botan.botan_version_minor() + return _DLL.botan_version_minor() def version_patch(): - return botan.botan_version_patch() + return _DLL.botan_version_patch() def version_string(): - return botan.botan_version_string().decode('ascii') + return _DLL.botan_version_string().decode('ascii') # # RNG @@ -386,27 +385,27 @@ class RandomNumberGenerator(object): # Can also use type "system" def __init__(self, rng_type='system'): self.__obj = c_void_p(0) - botan.botan_rng_init(byref(self.__obj), _ctype_str(rng_type)) + _DLL.botan_rng_init(byref(self.__obj), _ctype_str(rng_type)) def __del__(self): - botan.botan_rng_destroy(self.__obj) + _DLL.botan_rng_destroy(self.__obj) def handle_(self): return self.__obj def reseed(self, bits=256): - botan.botan_rng_reseed(self.__obj, bits) + _DLL.botan_rng_reseed(self.__obj, bits) def reseed_from_rng(self, source_rng, bits=256): - botan.botan_rng_reseed_from_rng(self.__obj, source_rng.handle_(), bits) + _DLL.botan_rng_reseed_from_rng(self.__obj, source_rng.handle_(), bits) def add_entropy(self, seed): - botan.botan_rng_add_entropy(self.__obj, _ctype_bits(seed), len(seed)) + _DLL.botan_rng_add_entropy(self.__obj, _ctype_bits(seed), len(seed)) def get(self, length): out = create_string_buffer(length) l = c_size_t(length) - botan.botan_rng_get(self.__obj, out, l) + _DLL.botan_rng_get(self.__obj, out, l) return _ctype_bufout(out) # @@ -416,30 +415,30 @@ class HashFunction(object): def __init__(self, algo): flags = c_uint32(0) # always zero in this API version self.__obj = c_void_p(0) - botan.botan_hash_init(byref(self.__obj), _ctype_str(algo), flags) + _DLL.botan_hash_init(byref(self.__obj), _ctype_str(algo), flags) output_length = c_size_t(0) - botan.botan_hash_output_length(self.__obj, byref(output_length)) + _DLL.botan_hash_output_length(self.__obj, byref(output_length)) self.__output_length = output_length.value def __del__(self): - botan.botan_hash_destroy(self.__obj) + _DLL.botan_hash_destroy(self.__obj) def algo_name(self): - return _call_fn_returning_str(32, lambda b, bl: botan.botan_hash_name(self.__obj, b, bl)) + return _call_fn_returning_str(32, lambda b, bl: _DLL.botan_hash_name(self.__obj, b, bl)) def clear(self): - botan.botan_hash_clear(self.__obj) + _DLL.botan_hash_clear(self.__obj) def output_length(self): return self.__output_length def update(self, x): - botan.botan_hash_update(self.__obj, _ctype_bits(x), len(x)) + _DLL.botan_hash_update(self.__obj, _ctype_bits(x), len(x)) def final(self): out = create_string_buffer(self.output_length()) - botan.botan_hash_final(self.__obj, out) + _DLL.botan_hash_final(self.__obj, out) return _ctype_bufout(out) # @@ -449,29 +448,29 @@ class MsgAuthCode(object): def __init__(self, algo): flags = c_uint32(0) # always zero in this API version self.__obj = c_void_p(0) - botan.botan_mac_init(byref(self.__obj), _ctype_str(algo), flags) + _DLL.botan_mac_init(byref(self.__obj), _ctype_str(algo), flags) min_keylen = c_size_t(0) max_keylen = c_size_t(0) mod_keylen = c_size_t(0) - botan.botan_mac_get_keyspec(self.__obj, byref(min_keylen), byref(max_keylen), byref(mod_keylen)) + _DLL.botan_mac_get_keyspec(self.__obj, byref(min_keylen), byref(max_keylen), byref(mod_keylen)) self.__min_keylen = min_keylen.value self.__max_keylen = max_keylen.value self.__mod_keylen = mod_keylen.value output_length = c_size_t(0) - botan.botan_mac_output_length(self.__obj, byref(output_length)) + _DLL.botan_mac_output_length(self.__obj, byref(output_length)) self.__output_length = output_length.value def __del__(self): - botan.botan_mac_destroy(self.__obj) + _DLL.botan_mac_destroy(self.__obj) def clear(self): - botan.botan_mac_clear(self.__obj) + _DLL.botan_mac_clear(self.__obj) def algo_name(self): - return _call_fn_returning_str(32, lambda b, bl: botan.botan_mac_name(self.__obj, b, bl)) + return _call_fn_returning_str(32, lambda b, bl: _DLL.botan_mac_name(self.__obj, b, bl)) def output_length(self): return self.__output_length @@ -483,80 +482,80 @@ class MsgAuthCode(object): return self.__max_keylen def set_key(self, key): - botan.botan_mac_set_key(self.__obj, key, len(key)) + _DLL.botan_mac_set_key(self.__obj, key, len(key)) def update(self, x): - botan.botan_mac_update(self.__obj, x, len(x)) + _DLL.botan_mac_update(self.__obj, x, len(x)) def final(self): out = create_string_buffer(self.output_length()) - botan.botan_mac_final(self.__obj, out) + _DLL.botan_mac_final(self.__obj, out) return _ctype_bufout(out) class SymmetricCipher(object): def __init__(self, algo, encrypt=True): flags = 0 if encrypt else 1 self.__obj = c_void_p(0) - botan.botan_cipher_init(byref(self.__obj), _ctype_str(algo), flags) + _DLL.botan_cipher_init(byref(self.__obj), _ctype_str(algo), flags) def __del__(self): - botan.botan_cipher_destroy(self.__obj) + _DLL.botan_cipher_destroy(self.__obj) def algo_name(self): - return _call_fn_returning_str(32, lambda b, bl: botan.botan_cipher_name(self.__obj, b, bl)) + return _call_fn_returning_str(32, lambda b, bl: _DLL.botan_cipher_name(self.__obj, b, bl)) def default_nonce_length(self): l = c_size_t(0) - botan.botan_cipher_get_default_nonce_length(self.__obj, byref(l)) + _DLL.botan_cipher_get_default_nonce_length(self.__obj, byref(l)) return l.value def update_granularity(self): l = c_size_t(0) - botan.botan_cipher_get_update_granularity(self.__obj, byref(l)) + _DLL.botan_cipher_get_update_granularity(self.__obj, byref(l)) return l.value def key_length(self): kmin = c_size_t(0) kmax = c_size_t(0) - botan.botan_cipher_query_keylen(self.__obj, byref(kmin), byref(kmax)) + _DLL.botan_cipher_query_keylen(self.__obj, byref(kmin), byref(kmax)) return kmin.value, kmax.value def minimum_keylength(self): l = c_size_t(0) - botan.botan_cipher_get_keyspec(self.__obj, byref(l), None, None) + _DLL.botan_cipher_get_keyspec(self.__obj, byref(l), None, None) return l.value def maximum_keylength(self): l = c_size_t(0) - botan.botan_cipher_get_keyspec(self.__obj, None, byref(l), None) + _DLL.botan_cipher_get_keyspec(self.__obj, None, byref(l), None) return l.value def tag_length(self): l = c_size_t(0) - botan.botan_cipher_get_tag_length(self.__obj, byref(l)) + _DLL.botan_cipher_get_tag_length(self.__obj, byref(l)) return l.value def is_authenticated(self): return self.tag_length() > 0 def valid_nonce_length(self, nonce_len): - rc = botan.botan_cipher_valid_nonce_length(self.__obj, nonce_len) + rc = _DLL.botan_cipher_valid_nonce_length(self.__obj, nonce_len) return rc == 1 def reset(self): - botan.botan_cipher_reset(self.__obj) + _DLL.botan_cipher_reset(self.__obj) def clear(self): - botan.botan_cipher_clear(self.__obj) + _DLL.botan_cipher_clear(self.__obj) def set_key(self, key): - botan.botan_cipher_set_key(self.__obj, key, len(key)) + _DLL.botan_cipher_set_key(self.__obj, key, len(key)) def set_assoc_data(self, ad): - botan.botan_cipher_set_associated_data(self.__obj, ad, len(ad)) + _DLL.botan_cipher_set_associated_data(self.__obj, ad, len(ad)) def start(self, nonce): - botan.botan_cipher_start(self.__obj, nonce, len(nonce)) + _DLL.botan_cipher_start(self.__obj, nonce, len(nonce)) def _update(self, txt, final): @@ -568,9 +567,9 @@ class SymmetricCipher(object): out_written = c_size_t(0) flags = c_uint32(1 if final else 0) - botan.botan_cipher_update(self.__obj, flags, - out, out_sz, byref(out_written), - _ctype_bits(inp), inp_sz, byref(inp_consumed)) + _DLL.botan_cipher_update(self.__obj, flags, + out, out_sz, byref(out_written), + _ctype_bits(inp), inp_sz, byref(inp_consumed)) # buffering not supported yet assert inp_consumed.value == inp_sz.value @@ -589,15 +588,15 @@ def bcrypt(passwd, rng_obj, work_factor=10): out_len = c_size_t(64) out = create_string_buffer(out_len.value) flags = c_uint32(0) - botan.botan_bcrypt_generate(out, byref(out_len), _ctype_str(passwd), - rng_obj.handle_(), c_size_t(work_factor), flags) + _DLL.botan_bcrypt_generate(out, byref(out_len), _ctype_str(passwd), + rng_obj.handle_(), c_size_t(work_factor), flags) b = out.raw[0:int(out_len.value)-1] if b[-1] == '\x00': b = b[:-1] return _ctype_to_str(b) def check_bcrypt(passwd, passwd_hash): - rc = botan.botan_bcrypt_is_valid(_ctype_str(passwd), _ctype_str(passwd_hash)) + rc = _DLL.botan_bcrypt_is_valid(_ctype_str(passwd), _ctype_str(passwd_hash)) return rc == 0 # @@ -606,18 +605,20 @@ def check_bcrypt(passwd, passwd_hash): def pbkdf(algo, password, out_len, iterations=10000, salt=None): if salt is None: salt = RandomNumberGenerator().get(12) + out_buf = create_string_buffer(out_len) - botan.botan_pbkdf(_ctype_str(algo), out_buf, out_len, - _ctype_str(password), salt, len(salt), iterations) + _DLL.botan_pbkdf(_ctype_str(algo), out_buf, out_len, + _ctype_str(password), salt, len(salt), iterations) return (salt, iterations, out_buf.raw) def pbkdf_timed(algo, password, out_len, ms_to_run=300, salt=None): if salt is None: salt = RandomNumberGenerator().get(12) + out_buf = create_string_buffer(out_len) iterations = c_size_t(0) - botan.botan_pbkdf_timed(_ctype_str(algo), out_buf, out_len, _ctype_str(password), - salt, len(salt), ms_to_run, byref(iterations)) + _DLL.botan_pbkdf_timed(_ctype_str(algo), out_buf, out_len, _ctype_str(password), + salt, len(salt), ms_to_run, byref(iterations)) return (salt, iterations.value, out_buf.raw) # @@ -625,8 +626,8 @@ def pbkdf_timed(algo, password, out_len, ms_to_run=300, salt=None): # def scrypt(out_len, password, salt, n=1024, r=8, p=8): out_buf = create_string_buffer(out_len) - botan.botan_scrypt(out_buf, out_len, _ctype_str(password), - _ctype_bits(salt), len(salt), n, r, p) + _DLL.botan_scrypt(out_buf, out_len, _ctype_str(password), + _ctype_bits(salt), len(salt), n, r, p) return out_buf.raw @@ -636,10 +637,10 @@ def scrypt(out_len, password, salt, n=1024, r=8, p=8): def kdf(algo, secret, out_len, salt, label): out_buf = create_string_buffer(out_len) out_sz = c_size_t(out_len) - botan.botan_kdf(_ctype_str(algo), out_buf, out_sz, - secret, len(secret), - salt, len(salt), - label, len(label)) + _DLL.botan_kdf(_ctype_str(algo), out_buf, out_sz, + secret, len(secret), + salt, len(salt), + label, len(label)) return out_buf.raw[0:int(out_sz.value)] # @@ -653,28 +654,28 @@ class PublicKey(object): # pylint: disable=invalid-name @classmethod def load(cls, val): obj = c_void_p(0) - botan.botan_pubkey_load(byref(obj), _ctype_bits(val), len(val)) + _DLL.botan_pubkey_load(byref(obj), _ctype_bits(val), len(val)) return PublicKey(obj) def __del__(self): - botan.botan_pubkey_destroy(self.__obj) + _DLL.botan_pubkey_destroy(self.__obj) def handle_(self): return self.__obj def estimated_strength(self): r = c_size_t(0) - botan.botan_pubkey_estimated_strength(self.__obj, byref(r)) + _DLL.botan_pubkey_estimated_strength(self.__obj, byref(r)) return r.value def algo_name(self): - return _call_fn_returning_str(32, lambda b, bl: botan.botan_pubkey_algo_name(self.__obj, b, bl)) + return _call_fn_returning_str(32, lambda b, bl: _DLL.botan_pubkey_algo_name(self.__obj, b, bl)) def export(self, pem=False): if pem: - return _call_fn_returning_str(4096, lambda b, bl: botan.botan_pubkey_export(self.__obj, b, bl, 1)) + return _call_fn_returning_str(4096, lambda b, bl: _DLL.botan_pubkey_export(self.__obj, b, bl, 1)) else: - return _call_fn_returning_vec(4096, lambda b, bl: botan.botan_pubkey_export(self.__obj, b, bl, 0)) + return _call_fn_returning_vec(4096, lambda b, bl: _DLL.botan_pubkey_export(self.__obj, b, bl, 0)) def encoding(self, pem=False): return self.export(pem) @@ -691,7 +692,7 @@ class PublicKey(object): # pylint: disable=invalid-name buf = create_string_buffer(n) buf_len = c_size_t(n) - botan.botan_pubkey_fingerprint(self.__obj, _ctype_str(hash_algorithm), buf, byref(buf_len)) + _DLL.botan_pubkey_fingerprint(self.__obj, _ctype_str(hash_algorithm), buf, byref(buf_len)) return _hex_encode(buf[0:int(buf_len.value)]) # @@ -706,7 +707,7 @@ class PrivateKey(object): def load(cls, val, passphrase=""): obj = c_void_p(0) rng_obj = c_void_p(0) # unused in recent versions - botan.botan_privkey_load(byref(obj), rng_obj, _ctype_bits(val), len(val), _ctype_str(passphrase)) + _DLL.botan_privkey_load(byref(obj), rng_obj, _ctype_bits(val), len(val), _ctype_str(passphrase)) return PrivateKey(obj) @classmethod @@ -729,22 +730,21 @@ class PrivateKey(object): params = "%d,%d" % (params[0], params[1]) obj = c_void_p(0) - - botan.botan_privkey_create(byref(obj), _ctype_str(algo), _ctype_str(params), rng_obj.handle_()) + _DLL.botan_privkey_create(byref(obj), _ctype_str(algo), _ctype_str(params), rng_obj.handle_()) return PrivateKey(obj) def __del__(self): - botan.botan_privkey_destroy(self.__obj) + _DLL.botan_privkey_destroy(self.__obj) def handle_(self): return self.__obj def algo_name(self): - return _call_fn_returning_str(32, lambda b, bl: botan.botan_privkey_algo_name(self.__obj, b, bl)) + return _call_fn_returning_str(32, lambda b, bl: _DLL.botan_privkey_algo_name(self.__obj, b, bl)) def get_public_key(self): pub = c_void_p(0) - botan.botan_privkey_export_pubkey(byref(pub), self.__obj) + _DLL.botan_privkey_export_pubkey(byref(pub), self.__obj) return PublicKey(pub) def to_der(self): @@ -755,24 +755,24 @@ class PrivateKey(object): def export(self, pem=False): if pem: - return _call_fn_returning_str(4096, lambda b, bl: botan.botan_privkey_export(self.__obj, b, bl, 1)) + return _call_fn_returning_str(4096, lambda b, bl: _DLL.botan_privkey_export(self.__obj, b, bl, 1)) else: - return _call_fn_returning_vec(4096, lambda b, bl: botan.botan_privkey_export(self.__obj, b, bl, 0)) + return _call_fn_returning_vec(4096, lambda b, bl: _DLL.botan_privkey_export(self.__obj, b, bl, 0)) class PKEncrypt(object): def __init__(self, key, padding): self.__obj = c_void_p(0) flags = c_uint32(0) # always zero in this ABI - botan.botan_pk_op_encrypt_create(byref(self.__obj), key.handle_(), _ctype_str(padding), flags) + _DLL.botan_pk_op_encrypt_create(byref(self.__obj), key.handle_(), _ctype_str(padding), flags) def __del__(self): - botan.botan_pk_op_encrypt_destroy(self.__obj) + _DLL.botan_pk_op_encrypt_destroy(self.__obj) def encrypt(self, msg, rng_obj): outbuf_sz = c_size_t(0) - botan.botan_pk_op_encrypt_output_length(self.__obj, len(msg), byref(outbuf_sz)) + _DLL.botan_pk_op_encrypt_output_length(self.__obj, len(msg), byref(outbuf_sz)) outbuf = create_string_buffer(outbuf_sz.value) - botan.botan_pk_op_encrypt(self.__obj, rng_obj.handle_(), outbuf, byref(outbuf_sz), msg, len(msg)) + _DLL.botan_pk_op_encrypt(self.__obj, rng_obj.handle_(), outbuf, byref(outbuf_sz), msg, len(msg)) return outbuf.raw[0:int(outbuf_sz.value)] @@ -780,51 +780,51 @@ class PKDecrypt(object): def __init__(self, key, padding): self.__obj = c_void_p(0) flags = c_uint32(0) # always zero in this ABI - botan.botan_pk_op_decrypt_create(byref(self.__obj), key.handle_(), _ctype_str(padding), flags) + _DLL.botan_pk_op_decrypt_create(byref(self.__obj), key.handle_(), _ctype_str(padding), flags) def __del__(self): - botan.botan_pk_op_decrypt_destroy(self.__obj) + _DLL.botan_pk_op_decrypt_destroy(self.__obj) def decrypt(self, msg): outbuf_sz = c_size_t(0) - botan.botan_pk_op_decrypt_output_length(self.__obj, len(msg), byref(outbuf_sz)) + _DLL.botan_pk_op_decrypt_output_length(self.__obj, len(msg), byref(outbuf_sz)) outbuf = create_string_buffer(outbuf_sz.value) - botan.botan_pk_op_decrypt(self.__obj, outbuf, byref(outbuf_sz), _ctype_bits(msg), len(msg)) + _DLL.botan_pk_op_decrypt(self.__obj, outbuf, byref(outbuf_sz), _ctype_bits(msg), len(msg)) return outbuf.raw[0:int(outbuf_sz.value)] class PKSign(object): # pylint: disable=invalid-name def __init__(self, key, padding): self.__obj = c_void_p(0) flags = c_uint32(0) # always zero in this ABI - botan.botan_pk_op_sign_create(byref(self.__obj), key.handle_(), _ctype_str(padding), flags) + _DLL.botan_pk_op_sign_create(byref(self.__obj), key.handle_(), _ctype_str(padding), flags) def __del__(self): - botan.botan_pk_op_sign_destroy(self.__obj) + _DLL.botan_pk_op_sign_destroy(self.__obj) def update(self, msg): - botan.botan_pk_op_sign_update(self.__obj, _ctype_str(msg), len(msg)) + _DLL.botan_pk_op_sign_update(self.__obj, _ctype_str(msg), len(msg)) def finish(self, rng_obj): outbuf_sz = c_size_t(0) - botan.botan_pk_op_sign_output_length(self.__obj, byref(outbuf_sz)) + _DLL.botan_pk_op_sign_output_length(self.__obj, byref(outbuf_sz)) outbuf = create_string_buffer(outbuf_sz.value) - botan.botan_pk_op_sign_finish(self.__obj, rng_obj.handle_(), outbuf, byref(outbuf_sz)) + _DLL.botan_pk_op_sign_finish(self.__obj, rng_obj.handle_(), outbuf, byref(outbuf_sz)) return outbuf.raw[0:int(outbuf_sz.value)] class PKVerify(object): def __init__(self, key, padding): self.__obj = c_void_p(0) flags = c_uint32(0) # always zero in this ABI - botan.botan_pk_op_verify_create(byref(self.__obj), key.handle_(), _ctype_str(padding), flags) + _DLL.botan_pk_op_verify_create(byref(self.__obj), key.handle_(), _ctype_str(padding), flags) def __del__(self): - botan.botan_pk_op_verify_destroy(self.__obj) + _DLL.botan_pk_op_verify_destroy(self.__obj) def update(self, msg): - botan.botan_pk_op_verify_update(self.__obj, _ctype_bits(msg), len(msg)) + _DLL.botan_pk_op_verify_update(self.__obj, _ctype_bits(msg), len(msg)) def check_signature(self, signature): - rc = botan.botan_pk_op_verify_finish(self.__obj, _ctype_bits(signature), len(signature)) + rc = _DLL.botan_pk_op_verify_finish(self.__obj, _ctype_bits(signature), len(signature)) if rc == 0: return True return False @@ -833,22 +833,22 @@ class PKKeyAgreement(object): def __init__(self, key, kdf_name): self.__obj = c_void_p(0) flags = c_uint32(0) # always zero in this ABI - botan.botan_pk_op_key_agreement_create(byref(self.__obj), key.handle_(), kdf_name, flags) + _DLL.botan_pk_op_key_agreement_create(byref(self.__obj), key.handle_(), kdf_name, flags) self.m_public_value = _call_fn_returning_vec( - 0, lambda b, bl: botan.botan_pk_op_key_agreement_export_public(key.handle_(), b, bl)) + 0, lambda b, bl: _DLL.botan_pk_op_key_agreement_export_public(key.handle_(), b, bl)) def __del__(self): - botan.botan_pk_op_key_agreement_destroy(self.__obj) + _DLL.botan_pk_op_key_agreement_destroy(self.__obj) def public_value(self): return self.m_public_value def agree(self, other, key_len, salt): return _call_fn_returning_vec(key_len, lambda b, bl: - botan.botan_pk_op_key_agreement(self.__obj, b, bl, - other, len(other), - salt, len(salt))) + _DLL.botan_pk_op_key_agreement(self.__obj, b, bl, + other, len(other), + salt, len(salt))) # # MCEIES encryption @@ -856,14 +856,14 @@ class PKKeyAgreement(object): # def mceies_encrypt(mce, rng_obj, aead, pt, ad): return _call_fn_returning_vec(len(pt) + 1024, lambda b, bl: - botan.botan_mceies_encrypt(mce.handle_(), - rng_obj.handle_(), - _ctype_str(aead), - _ctype_bits(pt), - len(pt), - _ctype_bits(ad), - len(ad), - b, bl)) + _DLL.botan_mceies_encrypt(mce.handle_(), + rng_obj.handle_(), + _ctype_str(aead), + _ctype_bits(pt), + len(pt), + _ctype_bits(ad), + len(ad), + b, bl)) def mceies_decrypt(mce, aead, ct, ad): @@ -871,13 +871,13 @@ def mceies_decrypt(mce, aead, ct, ad): #ll = c_size_t(ll) return _call_fn_returning_vec(len(ct), lambda b, bl: - botan.botan_mceies_decrypt(mce.handle_(), - _ctype_str(aead), - _ctype_bits(ct), - len(ct), - _ctype_bits(ad), - len(ad), - b, bl)) + _DLL.botan_mceies_decrypt(mce.handle_(), + _ctype_str(aead), + _ctype_bits(ct), + len(ct), + _ctype_bits(ad), + len(ad), + b, bl)) # @@ -891,17 +891,17 @@ class X509Cert(object): # pylint: disable=invalid-name raise BotanException("Both filename and buf given") elif filename is not None: self.__obj = c_void_p(0) - botan.botan_x509_cert_load_file(byref(self.__obj), _ctype_str(filename)) + _DLL.botan_x509_cert_load_file(byref(self.__obj), _ctype_str(filename)) elif buf is not None: self.__obj = c_void_p(0) - botan.botan_x509_cert_load(byref(self.__obj), _ctype_bits(buf), len(buf)) + _DLL.botan_x509_cert_load(byref(self.__obj), _ctype_bits(buf), len(buf)) def __del__(self): - botan.botan_x509_cert_destroy(self.__obj) + _DLL.botan_x509_cert_destroy(self.__obj) def time_starts(self): starts = _call_fn_returning_str( - 16, lambda b, bl: botan.botan_x509_cert_get_time_starts(self.__obj, b, bl)) + 16, lambda b, bl: _DLL.botan_x509_cert_get_time_starts(self.__obj, b, bl)) if len(starts) == 13: # UTC time struct_time = strptime(starts, "%y%m%d%H%M%SZ") @@ -915,7 +915,7 @@ class X509Cert(object): # pylint: disable=invalid-name def time_expires(self): expires = _call_fn_returning_str( - 16, lambda b, bl: botan.botan_x509_cert_get_time_expires(self.__obj, b, bl)) + 16, lambda b, bl: _DLL.botan_x509_cert_get_time_expires(self.__obj, b, bl)) if len(expires) == 13: # UTC time struct_time = strptime(expires, "%y%m%d%H%M%SZ") @@ -929,37 +929,37 @@ class X509Cert(object): # pylint: disable=invalid-name def to_string(self): return _call_fn_returning_str( - 4096, lambda b, bl: botan.botan_x509_cert_to_string(self.__obj, b, bl)) + 4096, lambda b, bl: _DLL.botan_x509_cert_to_string(self.__obj, b, bl)) def fingerprint(self, hash_algo='SHA-256'): n = HashFunction(hash_algo).output_length() * 3 return _call_fn_returning_str( - n, lambda b, bl: botan.botan_x509_cert_get_fingerprint(self.__obj, _ctype_str(hash_algo), b, bl)) + n, lambda b, bl: _DLL.botan_x509_cert_get_fingerprint(self.__obj, _ctype_str(hash_algo), b, bl)) def serial_number(self): return _call_fn_returning_vec( - 32, lambda b, bl: botan.botan_x509_cert_get_serial_number(self.__obj, b, bl)) + 32, lambda b, bl: _DLL.botan_x509_cert_get_serial_number(self.__obj, b, bl)) def authority_key_id(self): return _call_fn_returning_vec( - 32, lambda b, bl: botan.botan_x509_cert_get_authority_key_id(self.__obj, b, bl)) + 32, lambda b, bl: _DLL.botan_x509_cert_get_authority_key_id(self.__obj, b, bl)) def subject_key_id(self): return _call_fn_returning_vec( - 32, lambda b, bl: botan.botan_x509_cert_get_subject_key_id(self.__obj, b, bl)) + 32, lambda b, bl: _DLL.botan_x509_cert_get_subject_key_id(self.__obj, b, bl)) def subject_public_key_bits(self): return _call_fn_returning_vec( - 512, lambda b, bl: botan.botan_x509_cert_get_public_key_bits(self.__obj, b, bl)) + 512, lambda b, bl: _DLL.botan_x509_cert_get_public_key_bits(self.__obj, b, bl)) def subject_public_key(self): pub = c_void_p(0) - botan.botan_x509_cert_get_public_key(self.__obj, byref(pub)) + _DLL.botan_x509_cert_get_public_key(self.__obj, byref(pub)) return PublicKey(pub) def subject_dn(self, key, index): return _call_fn_returning_str( - 0, lambda b, bl: botan.botan_x509_cert_get_subject_dn(self.__obj, _ctype_str(key), index, b, bl)) + 0, lambda b, bl: _DLL.botan_x509_cert_get_subject_dn(self.__obj, _ctype_str(key), index, b, bl)) class MPI(object): @@ -967,27 +967,27 @@ class MPI(object): def __init__(self, initial_value=None): self.__obj = c_void_p(0) - botan.botan_mp_init(byref(self.__obj)) + _DLL.botan_mp_init(byref(self.__obj)) if initial_value is None: pass # left as zero elif isinstance(initial_value, MPI): - botan.botan_mp_set_from_mp(self.__obj, initial_value.handle_()) + _DLL.botan_mp_set_from_mp(self.__obj, initial_value.handle_()) elif isinstance(initial_value, str): - botan.botan_mp_set_from_str(self.__obj, _ctype_str(initial_value)) + _DLL.botan_mp_set_from_str(self.__obj, _ctype_str(initial_value)) else: # For int or long (or whatever else), try converting to string: - botan.botan_mp_set_from_str(self.__obj, _ctype_str(str(initial_value))) + _DLL.botan_mp_set_from_str(self.__obj, _ctype_str(str(initial_value))) def __del__(self): - botan.botan_mp_destroy(self.__obj) + _DLL.botan_mp_destroy(self.__obj) def handle_(self): return self.__obj def __int__(self): out = create_string_buffer(2*self.byte_count() + 1) - botan.botan_mp_to_hex(self.__obj, out) + _DLL.botan_mp_to_hex(self.__obj, out) val = int(out.value, 16) if self.is_negative(): return -val @@ -995,31 +995,31 @@ class MPI(object): return val def __repr__(self): - # Should have a better size estimate than this ... + # FIXME should have a better size estimate than this ... out_len = c_size_t(self.bit_count() // 2) out = create_string_buffer(out_len.value) - botan.botan_mp_to_str(self.__obj, c_uint8(10), out, byref(out_len)) + _DLL.botan_mp_to_str(self.__obj, c_uint8(10), out, byref(out_len)) out = out.raw[0:int(out_len.value)] if out[-1] == '\x00': out = out[:-1] - s = _ctype_to_str(out) + s = _ctype_to_str(out) if s[0] == '0': return s[1:] else: return s def is_negative(self): - rc = botan.botan_mp_is_negative(self.__obj) + rc = _DLL.botan_mp_is_negative(self.__obj) return rc == 1 def flip_sign(self): - botan.botan_mp_flip_sign(self.__obj) + _DLL.botan_mp_flip_sign(self.__obj) def cmp(self, other): r = c_int(0) - botan.botan_mp_cmp(byref(r), self.__obj, other.handle_()) + _DLL.botan_mp_cmp(byref(r), self.__obj, other.handle_()) return r.value def __eq__(self, other): @@ -1042,139 +1042,140 @@ class MPI(object): def __add__(self, other): r = MPI() - botan.botan_mp_add(r.handle_(), self.__obj, other.handle_()) + _DLL.botan_mp_add(r.handle_(), self.__obj, other.handle_()) return r def __iadd__(self, other): - botan.botan_mp_add(self.__obj, self.__obj, other.handle_()) + _DLL.botan_mp_add(self.__obj, self.__obj, other.handle_()) return self def __sub__(self, other): r = MPI() - botan.botan_mp_sub(r.handle_(), self.__obj, other.handle_()) + _DLL.botan_mp_sub(r.handle_(), self.__obj, other.handle_()) return r def __isub__(self, other): - botan.botan_mp_sub(self.__obj, self.__obj, other.handle_()) + _DLL.botan_mp_sub(self.__obj, self.__obj, other.handle_()) return self def __mul__(self, other): r = MPI() - botan.botan_mp_mul(r.handle_(), self.__obj, other.handle_()) + _DLL.botan_mp_mul(r.handle_(), self.__obj, other.handle_()) return r def __imul__(self, other): - botan.botan_mp_mul(self.__obj, self.__obj, other.handle_()) + _DLL.botan_mp_mul(self.__obj, self.__obj, other.handle_()) return self def __divmod__(self, other): d = MPI() q = MPI() - botan.botan_mp_div(d.handle_(), q.handle_(), self.__obj, other.handle_()) + _DLL.botan_mp_div(d.handle_(), q.handle_(), self.__obj, other.handle_()) return (d, q) def __mod__(self, other): d = MPI() q = MPI() - botan.botan_mp_div(d.handle_(), q.handle_(), self.__obj, other.handle_()) + _DLL.botan_mp_div(d.handle_(), q.handle_(), self.__obj, other.handle_()) return q def __lshift__(self, shift): shift = c_size_t(shift) r = MPI() - botan.botan_mp_lshift(r.handle_(), self.__obj, shift) + _DLL.botan_mp_lshift(r.handle_(), self.__obj, shift) return r def __ilshift__(self, shift): shift = c_size_t(shift) - botan.botan_mp_lshift(self.__obj, self.__obj, shift) + _DLL.botan_mp_lshift(self.__obj, self.__obj, shift) return self def __rshift__(self, shift): shift = c_size_t(shift) r = MPI() - botan.botan_mp_rshift(r.handle_(), self.__obj, shift) + _DLL.botan_mp_rshift(r.handle_(), self.__obj, shift) return r def __irshift__(self, shift): shift = c_size_t(shift) - botan.botan_mp_rshift(self.__obj, self.__obj, shift) + _DLL.botan_mp_rshift(self.__obj, self.__obj, shift) return self def pow_mod(self, exponent, modulus): r = MPI() - botan.botan_mp_powmod(r.handle_(), self.__obj, exponent.handle_(), modulus.handle_()) + _DLL.botan_mp_powmod(r.handle_(), self.__obj, exponent.handle_(), modulus.handle_()) return r def is_prime(self, rng_obj, prob=128): - return botan.botan_mp_is_prime(self.__obj, rng_obj.handle_(), c_size_t(prob)) == 1 + return _DLL.botan_mp_is_prime(self.__obj, rng_obj.handle_(), c_size_t(prob)) == 1 def inverse_mod(self, modulus): r = MPI() - botan.botan_mp_mod_inverse(r.handle_(), self.__obj, modulus.handle_()) + _DLL.botan_mp_mod_inverse(r.handle_(), self.__obj, modulus.handle_()) return r def bit_count(self): b = c_size_t(0) - botan.botan_mp_num_bits(self.__obj, byref(b)) + _DLL.botan_mp_num_bits(self.__obj, byref(b)) return b.value def byte_count(self): b = c_size_t(0) - botan.botan_mp_num_bytes(self.__obj, byref(b)) + _DLL.botan_mp_num_bytes(self.__obj, byref(b)) return b.value def get_bit(self, bit): - return botan.botan_mp_get_bit(self.__obj, c_size_t(bit)) == 1 + return _DLL.botan_mp_get_bit(self.__obj, c_size_t(bit)) == 1 def clear_bit(self, bit): - botan.botan_mp_clear_bit(self.__obj, c_size_t(bit)) + _DLL.botan_mp_clear_bit(self.__obj, c_size_t(bit)) def set_bit(self, bit): - botan.botan_mp_set_bit(self.__obj, c_size_t(bit)) + _DLL.botan_mp_set_bit(self.__obj, c_size_t(bit)) class FormatPreservingEncryptionFE1(object): def __init__(self, modulus, key, rounds=5, compat_mode=False): flags = c_uint32(1 if compat_mode else 0) self.__obj = c_void_p(0) - botan.botan_fpe_fe1_init(byref(self.__obj), modulus.handle_(), key, len(key), c_size_t(rounds), flags) + _DLL.botan_fpe_fe1_init(byref(self.__obj), modulus.handle_(), key, len(key), c_size_t(rounds), flags) def __del__(self): - botan.botan_fpe_destroy(self.__obj) + _DLL.botan_fpe_destroy(self.__obj) def encrypt(self, msg, tweak): r = MPI(msg) - botan.botan_fpe_encrypt(self.__obj, r.handle_(), _ctype_bits(tweak), len(tweak)) + _DLL.botan_fpe_encrypt(self.__obj, r.handle_(), _ctype_bits(tweak), len(tweak)) return r def decrypt(self, msg, tweak): r = MPI(msg) - botan.botan_fpe_decrypt(self.__obj, r.handle_(), _ctype_bits(tweak), len(tweak)) + _DLL.botan_fpe_decrypt(self.__obj, r.handle_(), _ctype_bits(tweak), len(tweak)) return r class HOTP(object): def __init__(self, key, digest="SHA-1", digits=6): self.__obj = c_void_p(0) - botan.botan_hotp_init(byref(self.__obj), key, len(key), _ctype_str(digest), digits) + _DLL.botan_hotp_init(byref(self.__obj), key, len(key), _ctype_str(digest), digits) def __del__(self): - botan.botan_hotp_destroy(self.__obj) + _DLL.botan_hotp_destroy(self.__obj) def generate(self, counter): code = c_uint32(0) - botan.botan_hotp_generate(self.__obj, byref(code), counter) + _DLL.botan_hotp_generate(self.__obj, byref(code), counter) return code.value def check(self, code, counter, resync_range=0): next_ctr = c_uint64(0) - rc = botan.botan_hotp_check(self.__obj, byref(next_ctr), code, counter, resync_range) + rc = _DLL.botan_hotp_check(self.__obj, byref(next_ctr), code, counter, resync_range) if rc == 0: return (True, next_ctr.value) else: return (False, counter) # Typedefs for compat with older versions +# Will be removed in a future major release cipher = SymmetricCipher # pylint: disable=invalid-name rng = RandomNumberGenerator # pylint: disable=invalid-name hash_function = HashFunction # pylint: disable=invalid-name diff --git a/src/scripts/test_python.py b/src/scripts/test_python.py index dd434531e..b6e8ca9d6 100644 --- a/src/scripts/test_python.py +++ b/src/scripts/test_python.py @@ -102,6 +102,12 @@ class BotanPythonTests(unittest.TestCase): user_rng.add_entropy('seed material...') def test_hash(self): + + try: + h = botan2.HashFunction('NoSuchHash') + except botan2.BotanException as e: + self.assertEqual(str(e), "botan_hash_init failed: -40 (Not implemented)") + h = botan2.HashFunction('SHA-256') self.assertEqual(h.algo_name(), 'SHA-256') assert h.output_length() == 32 |