Sfoglia il codice sorgente

tests for security package

mher 14 anni fa
parent
commit
a0a0eb25d1

+ 21 - 14
celery/security/serialization.py

@@ -2,8 +2,9 @@ import pickle
 
 from kombu.serialization import registry
 
-from certificate import Certificate, FSCertStore
-from key import PrivateKey
+from celery.security.certificate import Certificate, FSCertStore
+from celery.security.key import PrivateKey
+from celery.security.exceptions import SecurityError
 
 class SecureSerializer(object):
 
@@ -16,22 +17,28 @@ class SecureSerializer(object):
         """serialize data structure into string"""
         assert self._key is not None
         assert self._cert is not None
-        data = pickle.dumps(data)
-        signature = self._key.sign(data)
-        signer = self._cert.get_id()
-        return pickle.dumps(dict(data=data,
-                                 signer=signer,
-                                 signature=signature))
+        try:
+            data = pickle.dumps(data)
+            signature = self._key.sign(data)
+            signer = self._cert.get_id()
+            return pickle.dumps(dict(data=data,
+                                     signer=signer,
+                                     signature=signature))
+        except Exception, e:
+            raise SecurityError("Unable to serialize", e)
 
     def deserialize(self, data):
         """deserialize data structure from string"""
         assert self._cert_store is not None
-        data = pickle.loads(data)
-        signature = data['signature']
-        signer = data['signer']
-        data = data['data']
-        self._cert_store[signer].verify(data, signature)
-        return pickle.loads(data)
+        try:
+            data = pickle.loads(data)
+            signature = data['signature']
+            signer = data['signer']
+            data = data['data']
+            self._cert_store[signer].verify(data, signature)
+            return pickle.loads(data)
+        except Exception, e:
+            raise SecurityError("Unable to deserialize", e)
 
 def register_auth(key=None, cert=None, store=None):
     """register security serializer"""

+ 70 - 0
celery/tests/test_security/__init__.py

@@ -0,0 +1,70 @@
+# Keys and certificates for tests (KEY1 is a private key of CERT1, etc.)
+# Generated with:
+#
+# openssl genrsa -des3 -passout pass:test -out key1.key 1024
+# openssl req -new -key key1.key -out key1.csr -passin pass:test
+# cp key1.key key1.key.org
+# openssl rsa -in key1.key.org -out key1.key -passin pass:test
+# openssl x509 -req -days 365 -in cert1.csr -signkey key1.key -out cert1.crt
+# rm key1.key.org cert1.csr
+
+KEY1 = """-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQDCsmLC+eqL4z6bhtv0nzbcnNXuQrZUoh827jGfDI3kxNZ2LbEy
+kJOn7GIl2tPpcY2Dm1sOM8G1XLm/8Izprp4ifpF4Gi0mqz0GquY5dcMNASG9zkRO
+J1z8dQUyp3PIUHdQdrKbYQVifkA4dh6Kg27k8/IcdY1lHsaIju4bX7MADwIDAQAB
+AoGBAKWpCRWjdiluwu+skO0Up6aRIAop42AhzfN8OuZ81SMJRP2rJTHECI8COATD
+rDneb63Ce3ibG0BI1Jf3gr624D806xVqK/SVHZNbfWx0daE3Q43DDk1UdhRF5+0X
+HPqqU/IdeW1YGyWJi+IhMTXyGqhZ1BTN+4vHL7NlRpDt6JOpAkEA+xvfRO4Ca7Lw
+NEgvW7n+/L9b+xygQBtOA5s260pO+8jMrXvOdCjISaKHD8HZGFN9oUmLsDXXBhjh
+j0WCMdsHbQJBAMZ9OIw6M/Uxv5ANPCD58p6PZTb0knXVPMYBFQ7Y/h2HZzqbEyiI
+DLGZpAa9/IhVkoCULd/TNytz5rl27KEni+sCQArFQEdZmhr6etkTO4zIpoo6vvw/
+VxRI14jKEIn5Dvg3vae3RryuvyCBax+e5evoMNxJJkexl354dLxLc/ElfuUCQQCq
+U14pBvD7ITuPM6w7aAEIi2iBZhIgR2GlT9xwJ0i4si6lHdms2EJ8TKlyl6mSnEvh
+RkavYSJgiU6eLC0WhUcNAkEA7vuNcz/uuckmq870qfSzUQJIYLzwVOadEdEEAVy0
+L0usztlKmAH8U/ceQMMJLMI9W4m680JrMf3iS7f+SkgUTA==
+-----END RSA PRIVATE KEY-----"""
+
+KEY2 = """-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDH22L8b9AmST9ABDmQTQ2DWMdDmK5YXZt4AIY81IcsTQ/ccM0C
+fwXEP9tdkYwtcxMCWdASwY5pfMy9vFp0hyrRQMSNfuoxAgONuNWPyQoIvY3ZXRe6
+rS+hb/LN4+vdjX+oxmYiQ2HmSB9rh2bepE6Cw+RLJr5sXXq+xZJ+BLt5tQIDAQAB
+AoGBAMGBO0Arip/nP6Rd8tYypKjN5nEefX/1cjgoWdC//fj4zCil1vlZv12abm0U
+JWNEDd2y0/G1Eow0V5BFtFcrIFowU44LZEiSf7sKXlNHRHlbZmDgNXFZOt7nVbHn
+6SN+oCYjaPjji8idYeb3VQXPtqMoMn73MuyxD3k3tWmVLonpAkEA6hsu62qhUk5k
+Nt88UZOauU1YizxsWvT0bHioaceE4TEsbO3NZs7dmdJIcRFcU787lANaaIq7Rw26
+qcumME9XhwJBANqMOzsYQ6BX54UzS6x99Jjlq9MEbTCbAEZr/yjopb9f617SwfuE
+AEKnIq3HL6/Tnhv3V8Zy3wYHgDoGNeTVe+MCQQDi/nyeNAQ8RFqTgh2Ak/jAmCi0
+yV/fSgj+bHgQKS/FEuMas/IoL4lbrzQivkyhv5lLSX0ORQaWPM+z+A0qZqRdAkBh
+XE+Wx/x4ljCh+nQf6AzrgIXHgBVUrfi1Zq9Jfjs4wnaMy793WRr0lpiwaigoYFHz
+i4Ei+1G30eeh8dpYk3KZAkB0ucTOsQynDlL5rLGYZ+IcfSfH3w2l5EszY47kKQG9
+Fxeq/HOp9JYw4gRu6Ycvqu57KHwpHhR0FCXRBxuYcJ5V
+-----END RSA PRIVATE KEY-----"""
+
+CERT1 = """-----BEGIN CERTIFICATE-----
+MIICATCCAWoCCQCR6B3XQcBOvjANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB
+VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
+cyBQdHkgTHRkMB4XDTExMDcxOTA5MDgyMloXDTEyMDcxODA5MDgyMlowRTELMAkG
+A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
+IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwrJi
+wvnqi+M+m4bb9J823JzV7kK2VKIfNu4xnwyN5MTWdi2xMpCTp+xiJdrT6XGNg5tb
+DjPBtVy5v/CM6a6eIn6ReBotJqs9BqrmOXXDDQEhvc5ETidc/HUFMqdzyFB3UHay
+m2EFYn5AOHYeioNu5PPyHHWNZR7GiI7uG1+zAA8CAwEAATANBgkqhkiG9w0BAQUF
+AAOBgQA4+OiJ+pyq9lbEMFYC9K2+e77noHJkwUOs4wO6p1R14ZqSmoIszQ7KEBiH
+2HHPMUY6kt4GL1aX4Vr1pUlXXdH5WaEk0fvDYZemILDMqIQJ9ettx8KihZjFGC4k
+Y4Sy5xmqdE9Kjjd854gTRRnzpMnJp6+74Ki2X8GHxn3YBM+9Ng==
+-----END CERTIFICATE-----"""
+
+CERT2 = """-----BEGIN CERTIFICATE-----
+MIICATCCAWoCCQCV/9A2ZBM37TANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB
+VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
+cyBQdHkgTHRkMB4XDTExMDcxOTA5MDkwMloXDTEyMDcxODA5MDkwMlowRTELMAkG
+A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
+IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAx9ti
+/G/QJkk/QAQ5kE0Ng1jHQ5iuWF2beACGPNSHLE0P3HDNAn8FxD/bXZGMLXMTAlnQ
+EsGOaXzMvbxadIcq0UDEjX7qMQIDjbjVj8kKCL2N2V0Xuq0voW/yzePr3Y1/qMZm
+IkNh5kgfa4dm3qROgsPkSya+bF16vsWSfgS7ebUCAwEAATANBgkqhkiG9w0BAQUF
+AAOBgQBzaZ5vBkzksPhnWb2oobuy6Ne/LMEtdQ//qeVY4sKl2tOJUCSdWRen9fqP
+e+zYdEdkFCd8rp568Eiwkq/553uy4rlE927/AEqs/+KGYmAtibk/9vmi+/+iZXyS
+WWZybzzDZFncq1/N1C3Y/hrCBNDFO4TsnTLAhWtZ4c0vDAiacw==
+-----END CERTIFICATE-----"""
+

+ 38 - 0
celery/tests/test_security/test_certificate.py

@@ -0,0 +1,38 @@
+from celery.tests.utils import unittest
+
+from celery.security.certificate import Certificate, CertStore
+from celery.security.exceptions import SecurityError
+from celery.tests.test_security import CERT1, CERT2, KEY1, KEY2
+
+class TestCertificate(unittest.TestCase):
+
+    def test_valid_certificate(self):
+        Certificate(CERT1)
+        Certificate(CERT2)
+
+    def test_invalid_certificate(self):
+        self.assertRaises(TypeError, Certificate, None)
+        self.assertRaises(SecurityError, Certificate, "")
+        self.assertRaises(SecurityError, Certificate, "foo")
+        self.assertRaises(SecurityError, Certificate, CERT1[:20]+CERT1[21:])
+        self.assertRaises(SecurityError, Certificate, KEY1)
+
+class TestCertStore(unittest.TestCase):
+
+    def test_itercerts(self):
+        cert1 = Certificate(CERT1)
+        cert2 = Certificate(CERT2)
+        certstore = CertStore()
+        for c in certstore.itercerts():
+            self.assertTrue(False)
+        certstore.add_cert(cert1)
+        certstore.add_cert(cert2)
+        for c in certstore.itercerts():
+            self.assertIn(c, (cert1, cert2))
+
+    def test_duplicate(self):
+        cert1 = Certificate(CERT1)
+        certstore = CertStore()
+        certstore.add_cert(cert1)
+        self.assertRaises(SecurityError, certstore.add_cert, cert1)
+

+ 19 - 0
celery/tests/test_security/test_key.py

@@ -0,0 +1,19 @@
+from celery.tests.utils import unittest
+
+from celery.security.key import PrivateKey
+from celery.security.exceptions import SecurityError
+from celery.tests.test_security import CERT1, CERT2, KEY1, KEY2
+
+class TestKey(unittest.TestCase):
+
+    def test_valid_private_key(self):
+        PrivateKey(KEY1)
+        PrivateKey(KEY2)
+
+    def test_invalid_private_key(self):
+        self.assertRaises(TypeError, PrivateKey, None)
+        self.assertRaises(SecurityError, PrivateKey, "")
+        self.assertRaises(SecurityError, PrivateKey, "foo")
+        self.assertRaises(SecurityError, PrivateKey, KEY1[:20] + KEY1[21:])
+        self.assertRaises(SecurityError, PrivateKey, CERT1)
+

+ 47 - 0
celery/tests/test_security/test_serialization.py

@@ -0,0 +1,47 @@
+from celery.tests.utils import unittest
+
+from celery.security.serialization import SecureSerializer
+from celery.security.certificate import Certificate, CertStore
+from celery.security.key import PrivateKey
+from celery.security.exceptions import SecurityError
+from celery.tests.test_security import CERT1, CERT2, KEY1, KEY2
+
+class TestSecureSerializer(unittest.TestCase):
+
+    def _get_s(self, key, cert, certs):
+        store = CertStore()
+        for c in certs:
+            store.add_cert(Certificate(c))
+        return SecureSerializer(PrivateKey(key), Certificate(cert), store)
+
+    def test_serialize(self):
+        s = self._get_s(KEY1, CERT1, [CERT1])
+        self.assertEqual(s.deserialize(s.serialize("foo")), "foo")
+
+    def test_deserialize(self):
+        s = self._get_s(KEY1, CERT1, [CERT1])
+        self.assertRaises(SecurityError, s.deserialize, "bad data")
+
+    def test_unmatched_key_cert(self):
+        s = self._get_s(KEY1, CERT2, [CERT1, CERT2])
+        self.assertRaises(SecurityError,
+                          s.deserialize, s.serialize("foo"))
+
+    def test_unknown_source(self):
+        s1 = self._get_s(KEY1, CERT1, [CERT2])
+        s2 = self._get_s(KEY1, CERT1, [])
+        self.assertRaises(SecurityError,
+                          s1.deserialize, s1.serialize("foo"))
+        self.assertRaises(SecurityError,
+                          s2.deserialize, s2.serialize("foo"))
+
+    def test_self_send(self):
+        s1 = self._get_s(KEY1, CERT1, [CERT1])
+        s2 = self._get_s(KEY1, CERT1, [CERT1])
+        self.assertEqual(s2.deserialize(s1.serialize("foo")), "foo")
+
+    def test_separate_ends(self):
+        s1 = self._get_s(KEY1, CERT1, [CERT2])
+        s2 = self._get_s(KEY2, CERT2, [CERT1])
+        self.assertEqual(s2.deserialize(s1.serialize("foo")), "foo")
+