aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/python/botan.py143
-rwxr-xr-xsrc/scripts/ci/travis/lint.sh9
2 files changed, 80 insertions, 72 deletions
diff --git a/src/python/botan.py b/src/python/botan.py
index 4da158285..399680b86 100755
--- a/src/python/botan.py
+++ b/src/python/botan.py
@@ -18,7 +18,7 @@ module should be used only with the library version it accompanied.
"""
import sys
-from ctypes import *
+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 datetime import datetime
import time
@@ -61,7 +61,7 @@ def _call_fn_returning_string(guess, fn):
return v.decode('ascii')[:-1]
def _ctype_str(s):
- assert(type(s) == type(""))
+ assert type(s) == type("")
if sys.version_info[0] < 3:
return s
else:
@@ -112,18 +112,18 @@ RNG
"""
class rng(object):
# Can also use type "system"
- def __init__(self, rng_type = 'system'):
+ def __init__(self, rng_type='system'):
botan.botan_rng_init.argtypes = [c_void_p, c_char_p]
self.rng = c_void_p(0)
rc = botan.botan_rng_init(byref(self.rng), _ctype_str(rng_type))
if rc != 0 or self.rng is None:
- raise Exception("No rng " + algo + " for you!")
+ raise Exception("No rng " + rng_type + " available")
def __del__(self):
botan.botan_rng_destroy.argtypes = [c_void_p]
botan.botan_rng_destroy(self.rng)
- def reseed(self, bits = 256):
+ def reseed(self, bits=256):
botan.botan_rng_reseed.argtypes = [c_void_p, c_size_t]
botan.botan_rng_reseed(self.rng, bits)
@@ -132,7 +132,10 @@ class rng(object):
out = create_string_buffer(length)
l = c_size_t(length)
rc = botan.botan_rng_get(self.rng, out, l)
- return _ctype_bufout(out)
+ if rc == 0:
+ return _ctype_bufout(out)
+ else:
+ return None
"""
Hash function
@@ -155,10 +158,12 @@ class hash_function(object):
return botan.botan_hash_clear(self.hash)
def output_length(self):
- botan.botan_hash_output_length.argtypes = [c_void_p,POINTER(c_size_t)]
+ botan.botan_hash_output_length.argtypes = [c_void_p, POINTER(c_size_t)]
l = c_size_t(0)
rc = botan.botan_hash_output_length(self.hash, byref(l))
- return l.value
+ if rc == 0:
+ return l.value
+ raise Exception("botan_hash_output_length failed")
def update(self, x):
botan.botan_hash_update.argtypes = [c_void_p, POINTER(c_char), c_size_t]
@@ -194,7 +199,9 @@ class message_authentication_code(object):
botan.botan_mac_output_length.argtypes = [c_void_p, POINTER(c_size_t)]
l = c_size_t(0)
rc = botan.botan_mac_output_length(self.mac, byref(l))
- return l.value
+ if rc == 0:
+ return l.value
+ raise Exception("botan_mac_output_length failed")
def set_key(self, key):
botan.botan_mac_set_key.argtypes = [c_void_p, POINTER(c_char), c_size_t]
@@ -211,8 +218,8 @@ class message_authentication_code(object):
return _ctype_bufout(out)
class cipher(object):
- def __init__(self, algo, encrypt = True):
- botan.botan_cipher_init.argtypes = [c_void_p,c_char_p, c_uint32]
+ def __init__(self, algo, encrypt=True):
+ botan.botan_cipher_init.argtypes = [c_void_p, c_char_p, c_uint32]
flags = 0 if encrypt else 1
self.cipher = c_void_p(0)
rc = botan.botan_cipher_init(byref(self.cipher), _ctype_str(algo), flags)
@@ -297,14 +304,14 @@ class cipher(object):
def update(self, txt):
return self._update(txt, False)
- def finish(self, txt = None):
+ def finish(self, txt=None):
return self._update(txt, True)
-"""
-Bcrypt
-"""
-def bcrypt(passwd, rng, work_factor = 10):
+def bcrypt(passwd, rng, work_factor=10):
+ """
+ Bcrypt password hashing
+ """
botan.botan_bcrypt_generate.argtypes = [POINTER(c_char), POINTER(c_size_t),
c_char_p, c_void_p, c_size_t, c_uint32]
out_len = c_size_t(64)
@@ -320,24 +327,24 @@ def bcrypt(passwd, rng, work_factor = 10):
def check_bcrypt(passwd, bcrypt):
rc = botan.botan_bcrypt_is_valid(_ctype_str(passwd), bcrypt)
- return (rc == 0)
+ return rc == 0
"""
PBKDF
"""
-def pbkdf(algo, password, out_len, iterations = 10000, salt = rng().get(12)):
+def pbkdf(algo, password, out_len, iterations=10000, salt=rng().get(12)):
botan.botan_pbkdf.argtypes = [c_char_p, POINTER(c_char), c_size_t, c_char_p, c_void_p, c_size_t, c_size_t]
out_buf = create_string_buffer(out_len)
botan.botan_pbkdf(_ctype_str(algo), out_buf, out_len, _ctype_str(password), salt, len(salt), iterations)
- return (salt,iterations,out_buf.raw)
+ return (salt, iterations, out_buf.raw)
-def pbkdf_timed(algo, password, out_len, ms_to_run = 300, salt = rng().get(12)):
+def pbkdf_timed(algo, password, out_len, ms_to_run=300, salt=rng().get(12)):
botan.botan_pbkdf_timed.argtypes = [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)]
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))
- return (salt,iterations.value,out_buf.raw)
+ return (salt, iterations.value, out_buf.raw)
"""
KDF
@@ -353,7 +360,7 @@ def kdf(algo, secret, out_len, salt, label):
Public and private keys
"""
class public_key(object):
- def __init__(self, obj = c_void_p(0)):
+ def __init__(self, obj=c_void_p(0)):
self.pubkey = obj
def __del__(self):
@@ -368,14 +375,14 @@ class public_key(object):
def algo_name(self):
botan.botan_pubkey_algo_name.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)]
- return _call_fn_returning_string(32, lambda b,bl: botan.botan_pubkey_algo_name(self.pubkey, b, bl))
+ return _call_fn_returning_string(32, lambda b, bl: botan.botan_pubkey_algo_name(self.pubkey, b, bl))
- def encoding(self, pem = False):
+ def encoding(self, pem=False):
botan.botan_pubkey_export.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t), c_uint32]
flag = 1 if pem else 0
- return _call_fn_returning_vec(0, lambda b,bl: botan.botan_pubkey_export(self.pubkey, b, bl, flag))
+ return _call_fn_returning_vec(0, lambda b, bl: botan.botan_pubkey_export(self.pubkey, b, bl, flag))
- def fingerprint(self, hash = 'SHA-256'):
+ def fingerprint(self, hash='SHA-256'):
botan.botan_pubkey_fingerprint.argtypes = [c_void_p, c_char_p,
POINTER(c_char), POINTER(c_size_t)]
@@ -421,7 +428,7 @@ class private_key(object):
return public_key(pub)
def export(self):
- botan.botan_privkey_export.argtypes = [c_void_p,POINTER(c_char),c_void_p]
+ botan.botan_privkey_export.argtypes = [c_void_p, POINTER(c_char), c_void_p]
n = 4096
buf = create_string_buffer(n)
@@ -502,7 +509,7 @@ class pk_op_sign(object):
botan.botan_pk_op_sign_destroy(self.op)
def update(self, msg):
- botan.botan_pk_op_sign_update.argtypes = [c_void_p, POINTER(c_char), c_size_t]
+ botan.botan_pk_op_sign_update.argtypes = [c_void_p, POINTER(c_char), c_size_t]
botan.botan_pk_op_sign_update(self.op, _ctype_str(msg), len(msg))
def finish(self, rng):
@@ -544,7 +551,7 @@ def mceies_encrypt(mce, rng, aead, pt, ad):
botan.botan_mceies_encrypt.argtypes = [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)]
- return _call_fn_returning_vec(0, lambda b,bl:
+ return _call_fn_returning_vec(0, lambda b, bl:
botan.botan_mceies_encrypt(mce.pubkey,
rng.rng,
_ctype_str(aead),
@@ -561,7 +568,7 @@ def mceies_decrypt(mce, aead, pt, ad):
#msg = cast(msg, c_char_p)
#ll = c_size_t(ll)
- return _call_fn_returning_vec(0, lambda b,bl:
+ return _call_fn_returning_vec(0, lambda b, bl:
botan.botan_mceies_decrypt(mce.privkey,
_ctype_str(aead),
_ctype_bits(pt),
@@ -593,19 +600,19 @@ class pk_op_key_agreement(object):
botan.botan_pk_op_key_agreement.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t),
POINTER(c_char), c_size_t, POINTER(c_char), c_size_t]
- return _call_fn_returning_vec(key_len,
- lambda b,bl: botan.botan_pk_op_key_agreement(self.op, b, bl,
- other, len(other),
- salt, len(salt)))
+ return _call_fn_returning_vec(key_len, lambda b, bl:
+ botan.botan_pk_op_key_agreement(self.op, b, bl,
+ other, len(other),
+ salt, len(salt)))
"""
X.509 certificates
"""
class x509_cert(object):
def __init__(self, filename=None, buf=None):
if filename is None and buf is None:
- raise ArgumentError("No filename or buf given")
+ raise Exception("No filename or buf given")
if filename is not None and buf is not None:
- raise ArgumentError("Both filename and buf given")
+ raise Exception("Both filename and buf given")
elif filename is not None:
botan.botan_x509_cert_load_file.argtypes = [POINTER(c_void_p), c_char_p]
self.x509_cert = c_void_p(0)
@@ -621,7 +628,7 @@ class x509_cert(object):
def time_starts(self):
botan.botan_x509_cert_get_time_starts.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)]
- starts = _call_fn_returning_string(16, lambda b,bl: botan.botan_x509_cert_get_time_starts(self.x509_cert, b, bl))
+ starts = _call_fn_returning_string(16, lambda b, bl: botan.botan_x509_cert_get_time_starts(self.x509_cert, b, bl))
if len(starts) == 13:
# UTC time
struct_time = time.strptime(starts, "%y%m%d%H%M%SZ")
@@ -635,7 +642,7 @@ class x509_cert(object):
def time_expires(self):
botan.botan_x509_cert_get_time_expires.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)]
- expires = _call_fn_returning_string(16, lambda b,bl: botan.botan_x509_cert_get_time_expires(self.x509_cert, b, bl))
+ expires = _call_fn_returning_string(16, lambda b, bl: botan.botan_x509_cert_get_time_expires(self.x509_cert, b, bl))
if len(expires) == 13:
# UTC time
struct_time = time.strptime(expires, "%y%m%d%H%M%SZ")
@@ -648,30 +655,30 @@ class x509_cert(object):
def to_string(self):
botan.botan_x509_cert_to_string.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)]
- return _call_fn_returning_string(0, lambda b,bl: botan.botan_x509_cert_to_string(self.x509_cert, b, bl))
+ return _call_fn_returning_string(0, lambda b, bl: botan.botan_x509_cert_to_string(self.x509_cert, b, bl))
- def fingerprint(self, hash_algo = 'SHA-256'):
+ def fingerprint(self, hash_algo='SHA-256'):
botan.botan_x509_cert_get_fingerprint.argtypes = [c_void_p, c_char_p,
POINTER(c_char), POINTER(c_size_t)]
n = hash_function(hash_algo).output_length() * 3
- return _call_fn_returning_string(n, lambda b,bl: botan.botan_x509_cert_get_fingerprint(self.x509_cert, _ctype_str(hash_algo), b, bl))
+ return _call_fn_returning_string(n, lambda b, bl: botan.botan_x509_cert_get_fingerprint(self.x509_cert, _ctype_str(hash_algo), b, bl))
def serial_number(self):
botan.botan_x509_cert_get_serial_number.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)]
- return _call_fn_returning_vec(0, lambda b,bl: botan.botan_x509_cert_get_serial_number(self.x509_cert, b, bl))
+ return _call_fn_returning_vec(0, lambda b, bl: botan.botan_x509_cert_get_serial_number(self.x509_cert, b, bl))
def authority_key_id(self):
botan.botan_x509_cert_get_authority_key_id.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)]
- return _call_fn_returning_vec(0, lambda b,bl: botan.botan_x509_cert_get_authority_key_id(self.x509_cert, b, bl))
+ return _call_fn_returning_vec(0, lambda b, bl: botan.botan_x509_cert_get_authority_key_id(self.x509_cert, b, bl))
def subject_key_id(self):
botan.botan_x509_cert_get_subject_key_id.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)]
- return _call_fn_returning_vec(0, lambda b,bl: botan.botan_x509_cert_get_subject_key_id(self.x509_cert, b, bl))
+ return _call_fn_returning_vec(0, lambda b, bl: botan.botan_x509_cert_get_subject_key_id(self.x509_cert, b, bl))
def subject_public_key_bits(self):
botan.botan_x509_cert_get_public_key_bits.argtypes = [c_void_p, POINTER(c_char), POINTER(c_size_t)]
- return _call_fn_returning_vec(0, lambda b,bl: botan.botan_x509_cert_get_public_key_bits(self.x509_cert, b, bl))
+ return _call_fn_returning_vec(0, lambda b, bl: botan.botan_x509_cert_get_public_key_bits(self.x509_cert, b, bl))
def subject_public_key(self):
botan.botan_x509_cert_get_public_key.argtypes = [c_void_p, c_void_p]
@@ -682,7 +689,7 @@ class x509_cert(object):
def subject_dn(self, key, index):
botan.botan_x509_cert_get_subject_dn.argtypes = [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))
+ 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))
"""
@@ -707,7 +714,7 @@ def test():
print("good output %s\n" %
'59B2B1143B4CB1059EC58D9722FB1C72471E0D85C6F7543BA5228526375B0127')
- (salt,iterations,psk) = pbkdf_timed('PBKDF2(SHA-256)', 'xyz', 32, 200)
+ (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))
@@ -762,7 +769,7 @@ def test():
for mode in ['AES-128/CTR-BE', 'Serpent/GCM', 'ChaCha20Poly1305']:
enc = cipher(mode, encrypt=True)
- (kmin,kmax) = enc.key_length()
+ (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())
@@ -786,7 +793,7 @@ def test():
def test_mceliece():
- mce_priv = private_key('mce', [2960,57], rng())
+ mce_priv = private_key('mce', [2960, 57], rng())
mce_pub = mce_priv.get_public_key()
mce_plaintext = 'mce plaintext'
@@ -806,21 +813,19 @@ def test():
# (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())
- )
- )
+ 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())
- )
- )
+ 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)")
@@ -861,26 +866,24 @@ def test():
for dh_grp in ['secp256r1', 'curve25519']:
dh_kdf = 'KDF2(SHA-384)'.encode('utf-8')
a_dh_priv = private_key('ecdh', dh_grp, rng())
- a_dh_pub = a_dh_priv.get_public_key()
-
b_dh_priv = private_key('ecdh', dh_grp, rng())
- b_dh_pub = b_dh_priv.get_public_key()
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.public_value()),
- hex_encode(a_salt),
- hex_encode(b_dh.public_value()),
- hex_encode(b_salt)))
+ 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.public_value(), 32, a_salt + b_salt)
- b_key = b_dh.agree(a_dh.public_value(), 32, a_salt + 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)))
@@ -901,7 +904,7 @@ def test():
pubkey = cert.subject_public_key()
print("Public key algo: %s" % pubkey.algo_name())
- print("Public key strength: %s" % pubkey.estimated_strength() + " bits" )
+ print("Public key strength: %s" % pubkey.estimated_strength() + " bits")
dn_fields = ("Name", "Email", "Organization", "Organizational Unit", "Country")
for field in dn_fields:
@@ -926,7 +929,7 @@ def test():
test_certs()
-def main(args = None):
+def main(args=None):
if args is None:
args = sys.argv
test()
diff --git a/src/scripts/ci/travis/lint.sh b/src/scripts/ci/travis/lint.sh
index fe72ff589..36657e92a 100755
--- a/src/scripts/ci/travis/lint.sh
+++ b/src/scripts/ci/travis/lint.sh
@@ -2,7 +2,12 @@
set -ev
which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available
-echo "travis_fold:start:pylint"
+echo "travis_fold:start:pylint_configure"
python3 -m pylint configure.py
python2 -m pylint configure.py
-echo "travis_fold:end:pylint"
+echo "travis_fold:end:pylint_configure"
+
+echo "travis_fold:start:pylint_botanpy"
+python3 -m pylint src/python/botan.py
+python2 -m pylint src/python/botan.py
+echo "travis_fold:end:pylint_botanpy"