[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[dak/master] Mark signatures using SHA-1 or RIPE-MD/160 as "weak"



---
 daklib/gpg.py                    |  9 +++++++++
 tests/fixtures/gpg/ripemd160.asc | 12 ++++++++++++
 tests/fixtures/gpg/sha1.asc      | 12 ++++++++++++
 tests/test_gpg.py                | 17 +++++++++++++++++
 4 files changed, 50 insertions(+)
 create mode 100644 tests/fixtures/gpg/ripemd160.asc
 create mode 100644 tests/fixtures/gpg/sha1.asc

diff --git a/daklib/gpg.py b/daklib/gpg.py
index d3b3721..6a16f2c 100644
--- a/daklib/gpg.py
+++ b/daklib/gpg.py
@@ -64,6 +64,7 @@ class SignedFile(object):
     The following attributes are available:
       contents            - string with the content (after removing PGP armor)
       valid               - Boolean indicating a valid signature was found
+      weak_signature      - signature uses a weak algorithm (e.g. SHA-1)
       fingerprint         - fingerprint of the key used for signing
       primary_fingerprint - fingerprint of the primary key associated to the key used for signing
     """
@@ -80,6 +81,7 @@ class SignedFile(object):
         self.valid = False
         self.expired = False
         self.invalid = False
+        self.weak_signature = False
         self.fingerprints = []
         self.primary_fingerprints = []
         self.signature_ids = []
@@ -199,8 +201,15 @@ class SignedFile(object):
             # GnuPG accepted MD5 as a hash algorithm until gnupg 1.4.20,
             # which Debian 8 does not yet include.  We want to make sure
             # to not accept uploads covered by a MD5-based signature.
+            # RFC 4880, table 9.4:
+            #   1 - MD5
+            #   2 - SHA-1
+            #   3 - RIPE-MD/160
             if fields[9] == "1":
                 raise GpgException("Digest algorithm MD5 is not trusted.")
+            if fields[9] in ("2", "3"):
+                self.weak_signature = True
+
             self.valid = True
             self.fingerprints.append(fields[2])
             self.primary_fingerprints.append(fields[11])
diff --git a/tests/fixtures/gpg/ripemd160.asc b/tests/fixtures/gpg/ripemd160.asc
new file mode 100644
index 0000000..fe348f0
--- /dev/null
+++ b/tests/fixtures/gpg/ripemd160.asc
@@ -0,0 +1,12 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: RIPEMD160
+
+Message generated with gpg --homedir gnupghome --digest-algo=ripemd160 --clearsign
+-----BEGIN PGP SIGNATURE-----
+
+iLMEAQEDAB0WIQQKu4kHnLWPj5T28xDLnVxYKGBuhAUCWK3gXgAKCRDLnVxYKGBu
+hKXLA/94BEorjxLEnynLq2tS51g6vvYr6j3lKQ72K7naZWwVCeUoiE/w0aAmtASd
++xWCnsJZB9hUv7qsaG2SAt9oDu7lxre8NoQlNemRYGIDx7Pc1sRcQqYDmNntHSAA
+cl8rtda8/qNSTmLjfIdGFQQ4iSTOveDfsZ0RlWqvAwv3bCGkjw==
+=C8iz
+-----END PGP SIGNATURE-----
diff --git a/tests/fixtures/gpg/sha1.asc b/tests/fixtures/gpg/sha1.asc
new file mode 100644
index 0000000..948b971
--- /dev/null
+++ b/tests/fixtures/gpg/sha1.asc
@@ -0,0 +1,12 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+Message generated with gpg --homedir gnupghome --digest-algo=sha1 --clearsign
+-----BEGIN PGP SIGNATURE-----
+
+iLMEAQECAB0WIQQKu4kHnLWPj5T28xDLnVxYKGBuhAUCWK3frwAKCRDLnVxYKGBu
+hN2sBACy+H4lgESaCrKmb1xq5PaP5P8RWnjJdZ/ZzQgn+6xdvm3uydvPiXuS1aiU
+jRbYujOizTjJteZ218Me32YQtAoibBpz1OnUwf4TT/sVkdkmxk/dp5CLxPzXBsge
+wpjCw97E6CegH0pABBJ9pdzId4stNrut5ZqLTFESjDcWTpyvEA==
+=CMAI
+-----END PGP SIGNATURE-----
diff --git a/tests/test_gpg.py b/tests/test_gpg.py
index e7ec86a..1aab399 100755
--- a/tests/test_gpg.py
+++ b/tests/test_gpg.py
@@ -35,10 +35,27 @@ class GpgTest(DakTestCase):
     def test_valid(self):
         result = verify('gpg/valid.asc')
         self.assertTrue(result.valid)
+        self.assertFalse(result.weak_signature)
         self.assertEqual(result.primary_fingerprint, fpr_valid)
         self.assertEqual(result.contents, "Valid: yes\n")
         self.assertEqual(result.signature_timestamp, datetime.datetime(2014, 9, 2, 21, 24, 10))
 
+    def test_weak_sha1(self):
+        result = verify('gpg/sha1.asc')
+        self.assertTrue(result.valid)
+        self.assertTrue(result.weak_signature)
+        self.assertEqual(result.primary_fingerprint, fpr_valid)
+        self.assertEqual(result.contents, "Message generated with gpg --homedir gnupghome --digest-algo=sha1 --clearsign\n")
+        self.assertEqual(result.signature_timestamp, datetime.datetime(2017, 2, 22, 18, 59, 59))
+
+    def test_weak_ripemd160(self):
+        result = verify('gpg/ripemd160.asc')
+        self.assertTrue(result.valid)
+        self.assertTrue(result.weak_signature)
+        self.assertEqual(result.primary_fingerprint, fpr_valid)
+        self.assertEqual(result.contents, "Message generated with gpg --homedir gnupghome --digest-algo=ripemd160 --clearsign\n")
+        self.assertEqual(result.signature_timestamp, datetime.datetime(2017, 2, 22, 19, 2, 54))
+
     def test_expired(self):
         result = verify('gpg/expired.asc', False)
         self.assertFalse(result.valid)
-- 
2.1.4



Reply to: