From 2c7b684fa074f1af92d29692b55ace433f21eec2 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Sun, 19 Jun 2011 01:40:22 -0400 Subject: [PATCH] simplify exceptions into four classes instead of eight; make error messages more verbose --- lib/blowfish.py | 54 ++++++++++++++++++++---------------------------------- 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/lib/blowfish.py b/lib/blowfish.py index 8a5e5f2..25a1908 100644 --- a/lib/blowfish.py +++ b/lib/blowfish.py @@ -33,16 +33,6 @@ The entire Blowfish() class (excluding verify_key()) is by Michael Gilfix Blowfish.verify_key(), exception classes, encrypt() and decrypt() wrappers, and interactive mode are by Ben Kurtovic . - -Map of exceptions: - * BlowfishError - * BlockSizeError - * KeyLengthError - * KeyTooShortError - * KeyTooLongError - * DecryptionError - * IncorrectKeyError - * BadCyphertextError """ class BlowfishError(Exception): @@ -53,22 +43,12 @@ class BlockSizeError(BlowfishError): """Attempted to handle a block not 8 bytes in length.""" class KeyLengthError(BlowfishError): - """Base class for invalid key length exceptions.""" - -class KeyTooShortError(KeyLengthError): - """The given key is too short: it is less than 8 bytes (64 bits).""" - -class KeyTooLongError(KeyLengthError): - """The given key is too long: it is more than 56 bytes (448 bits.""" + """Attempted to use a key that is either less than 8 bytes or more than 56 + bytes in length.""" class DecryptionError(BlowfishError): - """Base class for exceptions that occur during decryption only.""" - -class IncorrectKeyError(DecryptionError): - """Attempted to decrypt something with the wrong key.""" - -class BadCyphertextError(DecryptionError): - """The given cyphertext is malformed and cannot be decrypted.""" + """Attempted to decrypt malformed cyphertext (e.g., not evenly divisible + into 8-byte blocks) or attempted to decrypt using a bad key.""" class Blowfish(object): """Blowfish encryption Scheme @@ -462,7 +442,8 @@ class Blowfish(object): def encrypt(self, data): if not len(data) == 8: - raise BlockSizeError("{0} != 8".format(len(data))) + raise BlockSizeError("blocks must be 8 bytes long, but tried to " + + "encrypt one {0} bytes long".format(len(data))) # Use big endianess since that's what everyone else uses xl = ord (data[3]) | (ord (data[2]) << 8) | (ord (data[1]) << 16) | (ord (data[0]) << 24) @@ -477,7 +458,8 @@ class Blowfish(object): def decrypt(self, data): if not len(data) == 8: - raise BlockSizeError("{0} != 8".format(len(data))) + raise BlockSizeError("blocks must be 8 bytes long, but tried to " + + "decrypt one {0} bytes long".format(len(data))) # Use big endianess since that's what everyone else uses cl = ord (data[3]) | (ord (data[2]) << 8) | (ord (data[1]) << 16) | (ord (data[0]) << 24) @@ -503,11 +485,13 @@ class Blowfish(object): """Make sure our key is not too short or too long; if there's a problem, raise KeyTooShortError() or KeyTooLongError().""" if not key: - raise KeyTooShortError("no key given") + raise KeyLengthError("no key given") if len(key) < 8: - raise KeyTooShortError("{0} < 8".format(len(key))) + raise KeyLengthError(("key is {0} bytes long, but it must be at " + + "least 8").format(len(key))) if len(key) > 56: - raise KeyTooLongError("{0} > 56".format(len(key))) + raise KeyLengthError(("key is {0} bytes long, but it must be " + + "less than 56").format(len(key))) def encrypt(key, plaintext): """Encrypt any length of plaintext using a given key that must be between @@ -534,18 +518,20 @@ def decrypt(key, cyphertext): try: cyphertext = cyphertext.decode("hex") - except TypeError as e: - raise BadCyphertextError(e) + except TypeError as error: + e = error.message + raise DecryptionError("cyphertext could not be decoded: " + e.lower()) if len(cyphertext) % 8 > 0: - raise BadCyphertextError("cyphertext cannot be broken into " + - "8-byte blocks evenly") + raise DecryptionError("cyphertext cannot be broken into " + + "8-byte blocks evenly") blocks = [cyphertext[f:f+8] for f in range(0, len(cyphertext), 8)] msg = ''.join(map(cypher.decrypt, blocks)) if not msg.startswith("TRUE"): # sanity check to ensure valid decryption - raise IncorrectKeyError() + raise DecryptionError("the given key is incorrect, or part of the " + + "cyphertext is malformed") size, msg = msg[4:].split("|", 1) while len(msg) > int(size):