serialization.py 2.4 KB

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