From 59018ff99c97261f9bbaee33f919938871e05118 Mon Sep 17 00:00:00 2001 From: Dwayne Litzenberger Date: Sun, 17 Feb 2013 11:21:28 -0800 Subject: Hash: Remove "oid" attributes; add "name" attribute In PyCrypto v2.5, the "oid" attribute was added to hash objects. In retrospect, this was not a good idea, since the OID is not really a property of the hash algorithm, it's a protocol-specific identifer for the hash functions. PKCS#1 v1.5 uses it, but other protocols (e.g. OpenPGP, DNSSEC, SSH, etc.) use different identifiers, and it doesn't make sense to add these to Crypto.Hash.* every time a new algorithm is added. This also has the benefit of being compatible with the Python standard library's "hashlib" objects, which also have a name attribute. --- lib/Crypto/Hash/MD2.py | 10 ------ lib/Crypto/Hash/MD4.py | 10 ------ lib/Crypto/Hash/MD5.py | 11 +----- lib/Crypto/Hash/RIPEMD160.py | 10 ------ lib/Crypto/Hash/SHA1.py | 11 +----- lib/Crypto/Hash/SHA224.py | 10 ------ lib/Crypto/Hash/SHA256.py | 10 ------ lib/Crypto/Hash/SHA384.py | 10 ------ lib/Crypto/Hash/SHA512.py | 10 ------ lib/Crypto/Hash/hashalgo.py | 4 +++ lib/Crypto/SelfTest/Hash/common.py | 16 +++------ lib/Crypto/Signature/PKCS1_v1_5.py | 72 +++++++++++++++++++++++++++++++++++++- src/MD2.c | 1 + src/MD4.c | 1 + src/RIPEMD160.c | 1 + src/SHA224.c | 1 + src/SHA256.c | 1 + src/SHA384.c | 1 + src/SHA512.c | 1 + src/hash_template.c | 4 +++ 20 files changed, 92 insertions(+), 103 deletions(-) diff --git a/lib/Crypto/Hash/MD2.py b/lib/Crypto/Hash/MD2.py index dac959e..a2e8b31 100644 --- a/lib/Crypto/Hash/MD2.py +++ b/lib/Crypto/Hash/MD2.py @@ -51,16 +51,6 @@ class MD2Hash(HashAlgo): :undocumented: block_size """ - #: ASN.1 Object identifier (OID):: - #: - #: id-md2 OBJECT IDENTIFIER ::= { - #: iso(1) member-body(2) us(840) rsadsi(113549) - #: digestAlgorithm(2) 2 - #: } - #: - #: This value uniquely identifies the MD2 algorithm. - oid = b('\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02') - digest_size = 16 block_size = 16 diff --git a/lib/Crypto/Hash/MD4.py b/lib/Crypto/Hash/MD4.py index e28a201..4f0b6bb 100644 --- a/lib/Crypto/Hash/MD4.py +++ b/lib/Crypto/Hash/MD4.py @@ -51,16 +51,6 @@ class MD4Hash(HashAlgo): :undocumented: block_size """ - #: ASN.1 Object identifier (OID):: - #: - #: id-md2 OBJECT IDENTIFIER ::= { - #: iso(1) member-body(2) us(840) rsadsi(113549) - #: digestAlgorithm(2) 4 - #: } - #: - #: This value uniquely identifies the MD4 algorithm. - oid = b('\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x04') - digest_size = 16 block_size = 64 diff --git a/lib/Crypto/Hash/MD5.py b/lib/Crypto/Hash/MD5.py index 18e9e7b..2e6a01b 100644 --- a/lib/Crypto/Hash/MD5.py +++ b/lib/Crypto/Hash/MD5.py @@ -57,20 +57,11 @@ class MD5Hash(HashAlgo): :undocumented: block_size """ - #: ASN.1 Object identifier (OID):: - #: - #: id-md5 OBJECT IDENTIFIER ::= { - #: iso(1) member-body(2) us(840) rsadsi(113549) - #: digestAlgorithm(2) 5 - #: } - #: - #: This value uniquely identifies the MD5 algorithm. - oid = b('\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05') - digest_size = 16 block_size = 64 def __init__(self, data=None): + self.name = "MD5" HashAlgo.__init__(self, hashFactory, data) def new(self, data=None): diff --git a/lib/Crypto/Hash/RIPEMD160.py b/lib/Crypto/Hash/RIPEMD160.py index 3abed5d..2bfb26d 100644 --- a/lib/Crypto/Hash/RIPEMD160.py +++ b/lib/Crypto/Hash/RIPEMD160.py @@ -54,16 +54,6 @@ class RIPEMD160Hash(HashAlgo): :undocumented: block_size """ - #: ASN.1 Object identifier (OID):: - #: - #: id-ripemd160 OBJECT IDENTIFIER ::= { - #: iso(1) identified-organization(3) teletrust(36) - #: algorithm(3) hashAlgorithm(2) ripemd160(1) - #: } - #: - #: This value uniquely identifies the RIPMD-160 algorithm. - oid = b("\x06\x05\x2b\x24\x03\x02\x01") - digest_size = 20 block_size = 64 diff --git a/lib/Crypto/Hash/SHA1.py b/lib/Crypto/Hash/SHA1.py index 334ae18..afddf1a 100644 --- a/lib/Crypto/Hash/SHA1.py +++ b/lib/Crypto/Hash/SHA1.py @@ -57,20 +57,11 @@ class SHA1Hash(HashAlgo): :undocumented: block_size """ - #: ASN.1 Object identifier (OID):: - #: - #: id-sha1 OBJECT IDENTIFIER ::= { - #: iso(1) identified-organization(3) oiw(14) secsig(3) - #: algorithms(2) 26 - #: } - #: - #: This value uniquely identifies the SHA-1 algorithm. - oid = b('\x06\x05\x2b\x0e\x03\x02\x1a') - digest_size = 20 block_size = 64 def __init__(self, data=None): + self.name = "SHA1" HashAlgo.__init__(self, hashFactory, data) def new(self, data=None): diff --git a/lib/Crypto/Hash/SHA224.py b/lib/Crypto/Hash/SHA224.py index 959b56d..379bbb2 100644 --- a/lib/Crypto/Hash/SHA224.py +++ b/lib/Crypto/Hash/SHA224.py @@ -55,16 +55,6 @@ class SHA224Hash(HashAlgo): :undocumented: block_size """ - #: ASN.1 Object identifier (OID):: - #: - #: id-sha224 OBJECT IDENTIFIER ::= { - #: joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) - #: nistalgorithm(4) hashalgs(2) 4 - #: } - #: - #: This value uniquely identifies the SHA-224 algorithm. - oid = b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04') - digest_size = 28 block_size = 64 diff --git a/lib/Crypto/Hash/SHA256.py b/lib/Crypto/Hash/SHA256.py index b0a99b3..46b7861 100644 --- a/lib/Crypto/Hash/SHA256.py +++ b/lib/Crypto/Hash/SHA256.py @@ -55,16 +55,6 @@ class SHA256Hash(HashAlgo): :undocumented: block_size """ - #: ASN.1 Object identifier (OID):: - #: - #: id-sha256 OBJECT IDENTIFIER ::= { - #: joint-iso-itu-t(2) country(16) us(840) organization(1) - #: gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 - #: } - #: - #: This value uniquely identifies the SHA-256 algorithm. - oid = b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01') - digest_size = 32 block_size = 64 diff --git a/lib/Crypto/Hash/SHA384.py b/lib/Crypto/Hash/SHA384.py index 3490b02..da6aca1 100644 --- a/lib/Crypto/Hash/SHA384.py +++ b/lib/Crypto/Hash/SHA384.py @@ -55,16 +55,6 @@ class SHA384Hash(HashAlgo): :undocumented: block_size """ - #: ASN.1 Object identifier (OID):: - #: - #: id-sha384 OBJECT IDENTIFIER ::= { - #: joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) - #: nistalgorithm(4) hashalgs(2) 2 - #: } - #: - #: This value uniquely identifies the SHA-384 algorithm. - oid = b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02') - digest_size = 48 block_size = 128 diff --git a/lib/Crypto/Hash/SHA512.py b/lib/Crypto/Hash/SHA512.py index d57548d..d8a4c3a 100644 --- a/lib/Crypto/Hash/SHA512.py +++ b/lib/Crypto/Hash/SHA512.py @@ -55,16 +55,6 @@ class SHA512Hash(HashAlgo): :undocumented: block_size """ - #: ASN.1 Object identifier (OID):: - #: - #: id-sha512 OBJECT IDENTIFIER ::= { - #: joint-iso-itu-t(2) - #: country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 - #: } - #: - #: This value uniquely identifies the SHA-512 algorithm. - oid = b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03') - digest_size = 64 block_size = 128 diff --git a/lib/Crypto/Hash/hashalgo.py b/lib/Crypto/Hash/hashalgo.py index b38b3a6..a778bf4 100644 --- a/lib/Crypto/Hash/hashalgo.py +++ b/lib/Crypto/Hash/hashalgo.py @@ -47,6 +47,10 @@ class HashAlgo: self._hash = hashFactory.new() else: self._hash = hashFactory() + try: + self.name = self._hash.name + except AttributeError: + pass if data: self.update(data) diff --git a/lib/Crypto/SelfTest/Hash/common.py b/lib/Crypto/SelfTest/Hash/common.py index f77fb0f..fa9fd22 100644 --- a/lib/Crypto/SelfTest/Hash/common.py +++ b/lib/Crypto/SelfTest/Hash/common.py @@ -107,16 +107,9 @@ class HashTestOID(unittest.TestCase): self.oid = oid def runTest(self): + from Crypto.Signature import PKCS1_v1_5 h = self.hashmod.new() - if self.oid==None: - try: - raised = 0 - a = h.oid - except AttributeError: - raised = 1 - self.assertEqual(raised,1) - else: - self.assertEqual(h.oid, self.oid) + self.assertEqual(PKCS1_v1_5._HASH_OIDS[h.name], self.oid) class MACSelfTest(unittest.TestCase): @@ -178,11 +171,10 @@ def make_hash_tests(module, module_name, test_data, digest_size, oid=None): description = row[2].encode('latin-1') name = "%s #%d: %s" % (module_name, i+1, description) tests.append(HashSelfTest(module, name, expected, input)) - if oid is not None: - oid = b(oid) name = "%s #%d: digest_size" % (module_name, i+1) tests.append(HashDigestSizeSelfTest(module, name, digest_size)) - tests.append(HashTestOID(module, oid)) + if oid is not None: + tests.append(HashTestOID(module, b(oid))) return tests def make_mac_tests(module, module_name, test_data, hashmods): diff --git a/lib/Crypto/Signature/PKCS1_v1_5.py b/lib/Crypto/Signature/PKCS1_v1_5.py index 73ac251..22bb340 100644 --- a/lib/Crypto/Signature/PKCS1_v1_5.py +++ b/lib/Crypto/Signature/PKCS1_v1_5.py @@ -208,7 +208,7 @@ def EMSA_PKCS1_V1_5_ENCODE(hash, emLen): # { OID id-sha512 PARAMETERS NULL } # } # - digestAlgo = DerSequence([hash.oid, DerNull().encode()]) + digestAlgo = DerSequence([_HASH_OIDS[hash.name], DerNull().encode()]) digest = DerOctetString(hash.digest()) digestInfo = DerSequence([ digestAlgo.encode(), @@ -234,3 +234,73 @@ def new(key): """ return PKCS115_SigScheme(key) +# AlgorithmIdentifier OIDs for use with PKCS#1 v1.5. +# +# These map names to the associated OIDs. We should try to be compatible +# with the standard library's hashlib modules, where possible. +# +# XXX - These will probably be moved somewhere else soon. +_HASH_OIDS = { + #: id-md2 OBJECT IDENTIFIER ::= { + #: iso(1) member-body(2) us(840) rsadsi(113549) + #: digestAlgorithm(2) 2 + #: } + "MD2": b('\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02'), + "md2": b('\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02'), + + #: id-md4 OBJECT IDENTIFIER ::= { + #: iso(1) member-body(2) us(840) rsadsi(113549) + #: digestAlgorithm(2) 4 + #: } + "MD4": b('\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x04'), + "md4": b('\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x04'), + + #: id-md5 OBJECT IDENTIFIER ::= { + #: iso(1) member-body(2) us(840) rsadsi(113549) + #: digestAlgorithm(2) 5 + #: } + "MD5": b('\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05'), + "md5": b('\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05'), + + #: id-ripemd160 OBJECT IDENTIFIER ::= { + #: iso(1) identified-organization(3) teletrust(36) + #: algorithm(3) hashAlgorithm(2) ripemd160(1) + #: } + "RIPEMD160": b("\x06\x05\x2b\x24\x03\x02\x01"), + "ripemd160": b("\x06\x05\x2b\x24\x03\x02\x01"), + + #: id-sha1 OBJECT IDENTIFIER ::= { + #: iso(1) identified-organization(3) oiw(14) secsig(3) + #: algorithms(2) 26 + #: } + "SHA1": b('\x06\x05\x2b\x0e\x03\x02\x1a'), + "sha1": b('\x06\x05\x2b\x0e\x03\x02\x1a'), + + #: id-sha224 OBJECT IDENTIFIER ::= { + #: joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) + #: nistalgorithm(4) hashalgs(2) 4 + #: } + "SHA224": b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04'), + "sha224": b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04'), + + #: id-sha256 OBJECT IDENTIFIER ::= { + #: joint-iso-itu-t(2) country(16) us(840) organization(1) + #: gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 + #: } + "SHA256": b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01'), + "sha256": b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01'), + + #: id-sha384 OBJECT IDENTIFIER ::= { + #: joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) + #: nistalgorithm(4) hashalgs(2) 2 + #: } + "SHA384": b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02'), + "sha384": b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02'), + + #: id-sha512 OBJECT IDENTIFIER ::= { + #: joint-iso-itu-t(2) + #: country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 + #: } + "SHA512": b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03'), + "sha512": b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03'), +} diff --git a/src/MD2.c b/src/MD2.c index 3543e21..dadb999 100644 --- a/src/MD2.c +++ b/src/MD2.c @@ -32,6 +32,7 @@ #include "pycrypto_compat.h" #define MODULE_NAME _MD2 +#define ALGORITHM_NAME "MD2" #define DIGEST_SIZE 16 #define BLOCK_SIZE 64 diff --git a/src/MD4.c b/src/MD4.c index b08b095..d5c20f4 100644 --- a/src/MD4.c +++ b/src/MD4.c @@ -32,6 +32,7 @@ #include "pycrypto_compat.h" #define MODULE_NAME _MD4 +#define ALGORITHM_NAME "MD4" #define DIGEST_SIZE 16 #define BLOCK_SIZE 64 diff --git a/src/RIPEMD160.c b/src/RIPEMD160.c index 8ff3fc5..37d4c73 100644 --- a/src/RIPEMD160.c +++ b/src/RIPEMD160.c @@ -402,6 +402,7 @@ static int ripemd160_digest(const ripemd160_state *self, unsigned char *out) /* Template definitions */ #define MODULE_NAME _RIPEMD160 +#define ALGORITHM_NAME "RIPEMD160" #define DIGEST_SIZE RIPEMD160_DIGEST_SIZE #define hash_state ripemd160_state #define hash_init ripemd160_init diff --git a/src/SHA224.c b/src/SHA224.c index ca70fbd..99e2f7c 100644 --- a/src/SHA224.c +++ b/src/SHA224.c @@ -28,6 +28,7 @@ */ #define MODULE_NAME _SHA224 +#define ALGORITHM_NAME "SHA224" #define DIGEST_SIZE (224/8) #define BLOCK_SIZE (512/8) #define WORD_SIZE 4 diff --git a/src/SHA256.c b/src/SHA256.c index 61a2d74..8cc3265 100644 --- a/src/SHA256.c +++ b/src/SHA256.c @@ -27,6 +27,7 @@ * */ #define MODULE_NAME _SHA256 +#define ALGORITHM_NAME "SHA256" #define DIGEST_SIZE (256/8) #define BLOCK_SIZE (512/8) #define WORD_SIZE 4 diff --git a/src/SHA384.c b/src/SHA384.c index 05dfe25..24b200c 100644 --- a/src/SHA384.c +++ b/src/SHA384.c @@ -28,6 +28,7 @@ */ #define MODULE_NAME _SHA384 +#define ALGORITHM_NAME "SHA384" #define DIGEST_SIZE (384/8) #define BLOCK_SIZE (1024/8) #define WORD_SIZE 8 diff --git a/src/SHA512.c b/src/SHA512.c index 3370e8e..3b227ab 100644 --- a/src/SHA512.c +++ b/src/SHA512.c @@ -28,6 +28,7 @@ */ #define MODULE_NAME _SHA512 +#define ALGORITHM_NAME "SHA512" #define DIGEST_SIZE (512/8) #define BLOCK_SIZE (1024/8) #define WORD_SIZE 8 diff --git a/src/hash_template.c b/src/hash_template.c index 10b1b1c..afffbfb 100644 --- a/src/hash_template.c +++ b/src/hash_template.c @@ -209,9 +209,13 @@ ALG_getattr(PyObject *self, char *name) if (PyUnicode_CompareWithASCIIString(attr, "digest_size")==0) return PyLong_FromLong(DIGEST_SIZE); + if (PyUnicode_CompareWithASCIIString(attr, "name")==0) + return PyUnicode_FromString(ALGORITHM_NAME); #else if (strcmp(name, "digest_size")==0) return PyInt_FromLong(DIGEST_SIZE); + if (strcmp(name, "name")==0) + return PyString_FromString(ALGORITHM_NAME); #endif #ifdef IS_PY3K -- cgit v1.2.1