From 629c26c21857f205b08211d7b1333eb5580c525d Mon Sep 17 00:00:00 2001 From: Legrandin Date: Tue, 4 Mar 2014 22:04:34 +0100 Subject: Remove a few custom exception types. The following custom exceptions are replaced with ValueError: * Crypto.Util.PaddingError * Crypto.PublicKey.KeyFormatError The custom Crypto.Util.asn1.NoDerElementError is now private to the module. Some white spaces have been removed. --- lib/Crypto/PublicKey/DSA.py | 10 +-- lib/Crypto/PublicKey/__init__.py | 3 - lib/Crypto/SelfTest/PublicKey/test_import_DSA.py | 46 ++++++------ lib/Crypto/Util/Padding.py | 23 +++--- lib/Crypto/Util/asn1.py | 92 ++++++++++++------------ 5 files changed, 84 insertions(+), 90 deletions(-) diff --git a/lib/Crypto/PublicKey/DSA.py b/lib/Crypto/PublicKey/DSA.py index 1818def..69f7f04 100644 --- a/lib/Crypto/PublicKey/DSA.py +++ b/lib/Crypto/PublicKey/DSA.py @@ -99,7 +99,7 @@ from Crypto.Util.py3compat import * from Crypto import Random from Crypto.IO import PKCS8, PEM from Crypto.Util.number import bytes_to_long, long_to_bytes -from Crypto.PublicKey import _DSA, _slowmath, pubkey, KeyFormatError +from Crypto.PublicKey import _DSA, _slowmath, pubkey from Crypto.Util.asn1 import DerObject, DerSequence,\ DerInteger, DerObjectId, DerBitString, newDerSequence, newDerBitString @@ -496,7 +496,7 @@ class DSAImplementation(object): :Raise ValueError: When **bits** is too little, too big, or not a multiple of 64. """ - + # Check against FIPS 186-2, which says that the size of the prime p # must be a multiple of 64 bits between 512 and 1024 for i in (0, 1, 2, 3, 4, 5, 6, 7, 8): @@ -596,7 +596,7 @@ class DSAImplementation(object): except (ValueError, EOFError): pass - raise KeyFormatError("DSA key format is not supported") + raise ValueError("DSA key format is not supported") def importKey(self, extern_key, passphrase=None): """Import a DSA key (public or private). @@ -626,7 +626,7 @@ class DSAImplementation(object): from which the decryption key is derived. :Return: A DSA key object (`_DSAobj`). - :Raise KeyFormatError: + :Raise ValueError: When the given key cannot be parsed (possibly because the pass phrase is wrong). @@ -663,7 +663,7 @@ class DSAImplementation(object): # This is probably a DER encoded key return self._importKeyDER(extern_key, passphrase) - raise KeyFormatError("DSA key format is not supported") + raise ValueError("DSA key format is not supported") #: `Object ID`_ for a DSA key. #: diff --git a/lib/Crypto/PublicKey/__init__.py b/lib/Crypto/PublicKey/__init__.py index df60c25..503809f 100644 --- a/lib/Crypto/PublicKey/__init__.py +++ b/lib/Crypto/PublicKey/__init__.py @@ -36,9 +36,6 @@ Crypto.PublicKey.RSA (Signing, encryption, and blinding) :undocumented: _DSA, _RSA, _fastmath, _slowmath, pubkey """ -class KeyFormatError(ValueError): - pass - __all__ = ['RSA', 'DSA', 'ElGamal'] __revision__ = "$Id$" diff --git a/lib/Crypto/SelfTest/PublicKey/test_import_DSA.py b/lib/Crypto/SelfTest/PublicKey/test_import_DSA.py index 1cb6837..82e1ad8 100644 --- a/lib/Crypto/SelfTest/PublicKey/test_import_DSA.py +++ b/lib/Crypto/SelfTest/PublicKey/test_import_DSA.py @@ -22,7 +22,7 @@ import unittest -from Crypto.PublicKey import DSA, KeyFormatError +from Crypto.PublicKey import DSA from Crypto.SelfTest.st_common import * from Crypto.Util.py3compat import * @@ -73,7 +73,7 @@ class ImportKeyTests(unittest.TestCase): self.assertEqual(self.g, key_obj.key.g) def testExportKey1(self): - tup = (self.y, self.g, self.p, self.q) + tup = (self.y, self.g, self.p, self.q) key = self.dsa.construct(tup) encoded = key.exportKey('DER') self.assertEqual(self.der_public, encoded) @@ -103,7 +103,7 @@ tPG+TJKpGYb7pVk= self.assertEqual(self.g, key_obj.key.g) def testExportKey2(self): - tup = (self.y, self.g, self.p, self.q) + tup = (self.y, self.g, self.p, self.q) key = self.dsa.construct(tup) encoded = key.exportKey('PEM') self.assertEqual(self.pem_public, encoded) @@ -124,7 +124,7 @@ tPG+TJKpGYb7pVk= 'a40ed9c2630c2fa4cdbf838539deb9a29f919085f2046369f627ca84b2cb1e2c'+\ '7940564b670f963ab1164d4e2ca2bf6ffd39f12f548928bf4d2d1b5e6980b4f1'+\ 'be4c92a91986fba55902145ebd9a3f0b82069d98420986b314215025756065' - + def testImportKey3(self): key_obj = self.dsa.importKey(self.der_private) self.failUnless(key_obj.has_private()) @@ -135,11 +135,11 @@ tPG+TJKpGYb7pVk= self.assertEqual(self.x, key_obj.key.x) def testExportKey3(self): - tup = (self.y, self.g, self.p, self.q, self.x) + tup = (self.y, self.g, self.p, self.q, self.x) key = self.dsa.construct(tup) encoded = key.exportKey('DER', pkcs8=False) self.assertEqual(self.der_private, encoded) - + # 4. pem_private="""\ -----BEGIN DSA PRIVATE KEY----- @@ -166,11 +166,11 @@ ggadmEIJhrMUIVAldWBl self.assertEqual(self.x, key_obj.key.x) def testExportKey4(self): - tup = (self.y, self.g, self.p, self.q, self.x) + tup = (self.y, self.g, self.p, self.q, self.x) key = self.dsa.construct(tup) encoded = key.exportKey('PEM', pkcs8=False) self.assertEqual(self.pem_private, encoded) - + # 5. PKCS8 (unencrypted) der_pkcs8=\ '3082014a0201003082012b06072a8648ce3804013082011e02818100e756ee17'+\ @@ -183,8 +183,8 @@ ggadmEIJhrMUIVAldWBl 'f444f34b82e3554d0b90a778faaf1306f025dae6a3e36c7f93dd5bac4052b923'+\ '70040aca70b8d5820599711900efbc961812c355dd9beffe0981da85c5548074'+\ 'b41c56ae43fd300d89262e4efd89943f99a651b03888041602145ebd9a3f0b82'+\ - '069d98420986b314215025756065' - + '069d98420986b314215025756065' + def testImportKey5(self): key_obj = self.dsa.importKey(self.der_pkcs8) self.failUnless(key_obj.has_private()) @@ -195,13 +195,13 @@ ggadmEIJhrMUIVAldWBl self.assertEqual(self.x, key_obj.key.x) def testExportKey5(self): - tup = (self.y, self.g, self.p, self.q, self.x) + tup = (self.y, self.g, self.p, self.q, self.x) key = self.dsa.construct(tup) encoded = key.exportKey('DER') self.assertEqual(self.der_pkcs8, encoded) encoded = key.exportKey('DER', pkcs8=True) self.assertEqual(self.der_pkcs8, encoded) - + # 6. pem_pkcs8="""\ -----BEGIN PRIVATE KEY----- @@ -213,7 +213,7 @@ fq6uNxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG 8CXa5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0 tBxWrkP9MA2JJi5O/YmUP5mmUbA4iAQWAhRevZo/C4IGnZhCCYazFCFQJXVgZQ== -----END PRIVATE KEY-----""" - + def testImportKey6(self): for pem in (self.pem_pkcs8, tostr(self.pem_pkcs8)): key_obj = self.dsa.importKey(pem) @@ -225,16 +225,16 @@ tBxWrkP9MA2JJi5O/YmUP5mmUbA4iAQWAhRevZo/C4IGnZhCCYazFCFQJXVgZQ== self.assertEqual(self.x, key_obj.key.x) def testExportKey6(self): - tup = (self.y, self.g, self.p, self.q, self.x) + tup = (self.y, self.g, self.p, self.q, self.x) key = self.dsa.construct(tup) encoded = key.exportKey('PEM') self.assertEqual(self.pem_pkcs8, encoded) encoded = key.exportKey('PEM', pkcs8=True) self.assertEqual(self.pem_pkcs8, encoded) - + # 7. OpenSSH/RFC4253 ssh_pub="""ssh-dss AAAAB3NzaC1kc3MAAACBAOdW7hcX9LZ5THwhRyShl2N0LEVXK0s/j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4uBtHmjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47BgV6/2qm66YguDLWDDAAAAFQCtMvSM064MRaGYph+kteIDIHY7IwAAAIB539w9YU/mNfzrfq6uNxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG8CXa5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0tBxWrkP9MA2JJi5O/YmUP5mmUbA4iAAAAIEAgzUqaaEy80hD0qDrmVv/Ti8IOnPwBJ0skeovDOQ9FEq9pIGZ5LADxXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTneuaKfkZCF8gRjafYnyoSyyx4seUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmAtPG+TJKpGYb7pVk=""" - + def testImportKey7(self): for ssh in (self.ssh_pub, tostr(self.ssh_pub)): key_obj = self.dsa.importKey(ssh) @@ -245,11 +245,11 @@ tBxWrkP9MA2JJi5O/YmUP5mmUbA4iAQWAhRevZo/C4IGnZhCCYazFCFQJXVgZQ== self.assertEqual(self.g, key_obj.key.g) def testExportKey7(self): - tup = (self.y, self.g, self.p, self.q) + tup = (self.y, self.g, self.p, self.q) key = self.dsa.construct(tup) encoded = key.exportKey('OpenSSH') self.assertEqual(self.ssh_pub, encoded) - + # 8. Encrypted OpenSSL/OpenSSH pem_private_encrypted="""\ -----BEGIN DSA PRIVATE KEY----- @@ -279,7 +279,7 @@ xVJtxaV37m3aXxtCsPnbBg== self.assertEqual(self.x, key_obj.key.x) def testExportKey8(self): - tup = (self.y, self.g, self.p, self.q, self.x) + tup = (self.y, self.g, self.p, self.q, self.x) key = self.dsa.construct(tup) encoded = key.exportKey('PEM', pkcs8=False, passphrase="PWDTEST") key = self.dsa.importKey(encoded, "PWDTEST") @@ -288,7 +288,7 @@ xVJtxaV37m3aXxtCsPnbBg== self.assertEqual(self.q, key.key.q) self.assertEqual(self.g, key.key.g) self.assertEqual(self.x, key.key.x) - + # 9. Encrypted PKCS8 # pbeWithMD5AndDES-CBC pem_pkcs8_encrypted="""\ @@ -343,7 +343,7 @@ eZ4k+NQDbEL8GiHmFxzDWQAuPPZKJWEEEV2p/To+WOh+kSDHQw== self.assertEqual(self.x, key_obj.key.x) def testExportKey10(self): - tup = (self.y, self.g, self.p, self.q, self.x) + tup = (self.y, self.g, self.p, self.q, self.x) key = self.dsa.construct(tup) randfunc = BytesIO(unhexlify(b("27A1C66C42AFEECE") + b("D725BF1B6B8239F4"))).read key._randfunc = randfunc @@ -353,10 +353,10 @@ eZ4k+NQDbEL8GiHmFxzDWQAuPPZKJWEEEV2p/To+WOh+kSDHQw== # ---- def testImportError1(self): - self.assertRaises(KeyFormatError, self.dsa.importKey, self.der_pkcs8_encrypted, "wrongpwd") + self.assertRaises(ValueError, self.dsa.importKey, self.der_pkcs8_encrypted, "wrongpwd") def testExportError2(self): - tup = (self.y, self.g, self.p, self.q, self.x) + tup = (self.y, self.g, self.p, self.q, self.x) key = self.dsa.construct(tup) self.assertRaises(ValueError, key.exportKey, 'DER', pkcs8=False, passphrase="PWDTEST") diff --git a/lib/Crypto/Util/Padding.py b/lib/Crypto/Util/Padding.py index b8498a3..e05b79a 100644 --- a/lib/Crypto/Util/Padding.py +++ b/lib/Crypto/Util/Padding.py @@ -27,17 +27,14 @@ This module provides minimal support for adding and removing standard padding from data. """ -__all__ = [ 'PaddingError', 'pad', 'unpad' ] +__all__ = [ 'ValueError', 'pad', 'unpad' ] from Crypto.Util.py3compat import * -class PaddingError(ValueError): - """Exception raised when padding is incorrect and cannot be removed.""" - pass def pad(data_to_pad, block_size, style='pkcs7'): """Apply standard padding. - + :Parameters: data_to_pad : byte string The data that needs to be padded. @@ -63,7 +60,7 @@ def pad(data_to_pad, block_size, style='pkcs7'): def unpad(padded_data, block_size, style='pkcs7'): """Remove standard padding. - + :Parameters: padded_data : byte string A piece of data with padding that needs to be stripped. @@ -74,29 +71,29 @@ def unpad(padded_data, block_size, style='pkcs7'): Padding algorithm. It can be *'pkcs7'* (default), *'iso7816'* or *'x923'*. :Return: Data without padding. - :Raises PaddingError: + :Raises ValueError: if the padding is incorrect. """ pdata_len = len(padded_data) if pdata_len % block_size: - raise PaddingError("Input data is not padded") + raise ValueError("Input data is not padded") if style in ('pkcs7', 'x923'): padding_len = bord(padded_data[-1]) if padding_len<1 or padding_len>min(block_size, pdata_len): - raise PaddingError("Padding is incorrect.") + raise ValueError("Padding is incorrect.") if style == 'pkcs7': if padded_data[-padding_len:]!=bchr(padding_len)*padding_len: - raise PaddingError("PKCS#7 padding is incorrect.") + raise ValueError("PKCS#7 padding is incorrect.") else: if padded_data[-padding_len:-1]!=bchr(0)*(padding_len-1): - raise PaddingError("ANSI X.923 padding is incorrect.") + raise ValueError("ANSI X.923 padding is incorrect.") elif style == 'iso7816': padding_len = pdata_len - padded_data.rfind(bchr(128)) if padding_len<1 or padding_len>min(block_size, pdata_len): - raise PaddingError("Padding is incorrect.") + raise ValueError("Padding is incorrect.") if padding_len>1 and padded_data[1-padding_len:]!=bchr(0)*(padding_len-1): - raise PaddingError("ISO 7816-4 padding is incorrect.") + raise ValueError("ISO 7816-4 padding is incorrect.") else: raise ValueError("Unknown padding style") return padded_data[:-padding_len] diff --git a/lib/Crypto/Util/asn1.py b/lib/Crypto/Util/asn1.py index 0e471a3..4c0ca37 100644 --- a/lib/Crypto/Util/asn1.py +++ b/lib/Crypto/Util/asn1.py @@ -76,7 +76,7 @@ class BytesIO_EOF(BytesIO): def read_byte(self): return self.read(1)[0] -class NoDerElementError(EOFError): +class _NoDerElementError(EOFError): pass class DerObject(object): @@ -106,7 +106,7 @@ class DerObject(object): True when the ASN.1 type is *constructed*. False when it is *primitive*. """ - + if asn1Id==None: self._idOctet = None return @@ -118,7 +118,7 @@ class DerObject(object): # * bit 5 is set if the type is 'construted' # and unset if 'primitive' # * bits 7-6 depend on the encoding class - # + # # Class | Bit 7, Bit 6 # universal | 0 0 # application | 0 1 @@ -146,7 +146,7 @@ class DerObject(object): def _lengthOctets(self): """Build length octets according to the current object's payload. - + Return a byte string that encodes the payload length (in bytes) in a format suitable for DER length octets (L). """ @@ -182,7 +182,7 @@ class DerObject(object): :Parameters: derEle : byte string A complete DER element. - + :Raise ValueError: In case of parsing errors. :Raise EOFError: @@ -197,14 +197,14 @@ class DerObject(object): raise ValueError("Unexpected extra data after the DER structure") except EOFError: pass - + def _decodeFromStream(self, s): """Decode a complete DER element from a file.""" - + try: idOctet = bord(s.read_byte()) except EOFError: - raise NoDerElementError + raise _NoDerElementError if self._idOctet != None: if idOctet != self._idOctet: raise ValueError("Unexpected DER tag") @@ -215,7 +215,7 @@ class DerObject(object): class DerInteger(DerObject): """Class to model a DER INTEGER. - + An example of encoding is: >>> from Crypto.Util.asn1 import DerInteger @@ -275,7 +275,7 @@ class DerInteger(DerObject): :Parameters: derEle : byte string A complete INTEGER DER element. - + :Raise ValueError: In case of parsing errors. :Raise EOFError: @@ -285,10 +285,10 @@ class DerInteger(DerObject): def _decodeFromStream(self, s): """Decode a complete DER INTEGER from a file.""" - + # Fill up self.payload DerObject._decodeFromStream(self, s) - + # Derive self.value from self.payload self.value = 0L bits = 1 @@ -311,7 +311,7 @@ class DerSequence(DerObject): This object behaves like a dynamic Python sequence. Sub-elements that are INTEGERs behave like Python integers. - + Any other sub-element is a binary string encoded as a complete DER sub-element (TLV). @@ -345,12 +345,12 @@ class DerSequence(DerObject): 3 4 [4L, 9L, b'\x07\x01\x02'] - + """ def __init__(self, startSeq=None, implicit=None): """Initialize the DER object as a SEQUENCE. - + :Parameters: startSeq : Python sequence A sequence whose element are either integers or @@ -393,7 +393,7 @@ class DerSequence(DerObject): def hasInts(self, onlyNonNegative=True): """Return the number of items in this sequence that are integers. - + :Parameters: onlyNonNegative : boolean If True, negative integers are not counted in. @@ -411,14 +411,14 @@ class DerSequence(DerObject): :Parameters: onlyNonNegative : boolean - If True, the presence of negative integers + If True, the presence of negative integers causes the method to return False.""" return self._seq and self.hasInts(onlyNonNegative)==len(self._seq) - + def encode(self): """Return this DER SEQUENCE, fully encoded as a binary string. - + :Raises ValueError: If some elements in the sequence are neither integers nor byte strings. @@ -441,7 +441,7 @@ class DerSequence(DerObject): :Parameters: derEle : byte string A complete SEQUENCE DER element. - + :Raise ValueError: In case of parsing errors. :Raise EOFError: @@ -454,9 +454,9 @@ class DerSequence(DerObject): def _decodeFromStream(self, s): """Decode a complete DER SEQUENCE from a file.""" - + self._seq = [] - + # Fill up self.payload DerObject._decodeFromStream(self, s) @@ -467,7 +467,7 @@ class DerSequence(DerObject): p.setRecord(True) der = DerObject() der._decodeFromStream(p) - + # Parse INTEGERs differently if der._idOctet != 0x02: self._seq.append(p._recording) @@ -475,8 +475,8 @@ class DerSequence(DerObject): derInt = DerInteger() derInt.decode(p._recording) self._seq.append(derInt.value) - - except NoDerElementError: + + except _NoDerElementError: break # end @@ -494,7 +494,7 @@ def newDerSequence(*der_objs): class DerOctetString(DerObject): """Class to model a DER OCTET STRING. - + An example of encoding is: >>> from Crypto.Util.asn1 import DerOctetString @@ -521,7 +521,7 @@ class DerOctetString(DerObject): def __init__(self, value=b(''), implicit=None): """Initialize the DER object as an OCTET STRING. - + :Parameters: value : byte string The initial payload of the object. @@ -530,7 +530,7 @@ class DerOctetString(DerObject): implicit : integer The IMPLICIT tag to use for the encoded object. It overrides the universal tag for OCTET STRING (4). - """ + """ DerObject.__init__(self, 0x04, value, implicit, False) def newDerOctetString(binstring): @@ -553,7 +553,7 @@ class DerNull(DerObject): class DerObjectId(DerObject): """Class to model a DER OBJECT ID. - + An example of encoding is: >>> from Crypto.Util.asn1 import DerObjectId @@ -580,14 +580,14 @@ class DerObjectId(DerObject): def __init__(self, value='', implicit=None): """Initialize the DER object as an OBJECT ID. - + :Parameters: value : string The initial Object Identifier (e.g. "1.2.0.0.6.2"). implicit : integer The IMPLICIT tag to use for the encoded object. It overrides the universal tag for OBJECT ID (6). - """ + """ DerObject.__init__(self, 0x06, b(''), implicit, False) self.value = value #: The Object ID, a dot separated list of integers @@ -623,7 +623,7 @@ class DerObjectId(DerObject): """ DerObject.decode(self, derEle) - + def _decodeFromStream(self, s): """Decode a complete DER OBJECT ID from a file.""" @@ -654,7 +654,7 @@ def newDerObjectId(dottedstring): class DerBitString(DerObject): """Class to model a DER BIT STRING. - + An example of encoding is: >>> from Crypto.Util.asn1 import DerBitString @@ -681,7 +681,7 @@ class DerBitString(DerObject): def __init__(self, value=b(''), implicit=None): """Initialize the DER object as a BIT STRING. - + :Parameters: value : byte string The initial, packed bit string. @@ -689,7 +689,7 @@ class DerBitString(DerObject): implicit : integer The IMPLICIT tag to use for the encoded object. It overrides the universal tag for OCTET STRING (3). - """ + """ DerObject.__init__(self, 0x03, b(''), implicit, False) self.value = value #: The bitstring value (packed) @@ -700,7 +700,7 @@ class DerBitString(DerObject): # Add padding count byte self.payload = b('\x00') + self.value return DerObject.encode(self) - + def decode(self, derEle): """Decode a complete DER BIT STRING, and re-initializes this object with it. @@ -716,7 +716,7 @@ class DerBitString(DerObject): """ DerObject.decode(self, derEle) - + def _decodeFromStream(self, s): """Decode a complete DER BIT STRING DER from a file.""" @@ -725,7 +725,7 @@ class DerBitString(DerObject): if self.payload and bord(self.payload[0])!=0: raise ValueError("Not a valid BIT STRING") - + # Fill-up self.value self.value = b('') # Remove padding count byte @@ -744,7 +744,7 @@ def newDerBitString(binstring): class DerSetOf(DerObject): """Class to model a DER SET OF. - + An example of encoding is: >>> from Crypto.Util.asn1 import DerBitString @@ -771,14 +771,14 @@ class DerSetOf(DerObject): def __init__(self, startSet=None, implicit=None): """Initialize the DER object as a SET OF. - + :Parameters: startSet : container The initial set of integers or DER encoded objects. implicit : integer The IMPLICIT tag to use for the encoded object. It overrides the universal tag for SET OF (17). - """ + """ DerObject.__init__(self, 0x11, b(''), implicit, True) self._seq = [] self._elemOctet = None @@ -830,14 +830,14 @@ class DerSetOf(DerObject): :Raise EOFError: If the DER element is too short. """ - + DerObject.decode(self, derEle) def _decodeFromStream(self, s): """Decode a complete DER SET OF from a file.""" self._seq = [] - + # Fill up self.payload DerObject._decodeFromStream(self, s) @@ -849,7 +849,7 @@ class DerSetOf(DerObject): p.setRecord(True) der = DerObject() der._decodeFromStream(p) - + # Verify that all members are of the same type if setIdOctet < 0: setIdOctet = der._idOctet @@ -864,8 +864,8 @@ class DerSetOf(DerObject): derInt = DerInteger() derInt.decode(p._recording) self._seq.append(derInt.value) - - except NoDerElementError: + + except _NoDerElementError: break # end -- cgit v1.2.1