serialization.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. from __future__ import absolute_import
  2. from base64 import b64encode, b64decode
  3. import anyjson
  4. import base64
  5. from kombu.serialization import registry
  6. from ..exceptions import SecurityError
  7. from .certificate import Certificate, FSCertStore
  8. from .key import PrivateKey
  9. class SecureSerializer(object):
  10. def __init__(self, key=None, cert=None, cert_store=None,
  11. serialize=anyjson.serialize,
  12. deserialize=anyjson.deserialize):
  13. self._key = key
  14. self._cert = cert
  15. self._cert_store = cert_store
  16. self._serialize = serialize
  17. self._deserialize = deserialize
  18. def serialize(self, data):
  19. """serialize data structure into string"""
  20. assert self._key is not None
  21. assert self._cert is not None
  22. try:
  23. data = self._serialize(data)
  24. signature = b64encode(self._key.sign(data))
  25. signer = self._cert.get_id()
  26. return self._serialize(dict(data=data,
  27. signer=signer,
  28. signature=signature))
  29. except Exception, exc:
  30. raise SecurityError("Unable to serialize: %r" % (exc, ))
  31. def deserialize(self, data):
  32. """deserialize data structure from string"""
  33. assert self._cert_store is not None
  34. try:
  35. data = self._deserialize(data)
  36. signature = b64decode(data["signature"])
  37. signer = data["signer"]
  38. data = data["data"]
  39. self._cert_store[signer].verify(data, signature)
  40. return self._deserialize(data)
  41. except Exception, exc:
  42. raise SecurityError("Unable to deserialize: %r" % (exc, ))
  43. def register_auth(key=None, cert=None, store=None):
  44. """register security serializer"""
  45. s = SecureSerializer(key and PrivateKey(key),
  46. cert and Certificate(cert),
  47. store and FSCertStore(store),
  48. anyjson.serialize, anyjson.deserialize)
  49. registry.register("auth", s.serialize, s.deserialize,
  50. content_type="application/data",
  51. content_encoding="utf-8")