|  | @@ -3,7 +3,7 @@ from __future__ import absolute_import
 | 
	
		
			
				|  |  |  import anyjson
 | 
	
		
			
				|  |  |  import base64
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -from kombu.serialization import registry
 | 
	
		
			
				|  |  | +from kombu.serialization import registry, encode, decode
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  from ..exceptions import SecurityError
 | 
	
		
			
				|  |  |  from ..utils.encoding import bytes_to_str, str_to_bytes
 | 
	
	
		
			
				|  | @@ -23,27 +23,35 @@ def b64decode(s):
 | 
	
		
			
				|  |  |  class SecureSerializer(object):
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      def __init__(self, key=None, cert=None, cert_store=None,
 | 
	
		
			
				|  |  | -            serialize=anyjson.serialize,
 | 
	
		
			
				|  |  | -            deserialize=anyjson.deserialize,
 | 
	
		
			
				|  |  | -            digest='sha1'):
 | 
	
		
			
				|  |  | +            digest="sha1", serializer="json"):
 | 
	
		
			
				|  |  |          self._key = key
 | 
	
		
			
				|  |  |          self._cert = cert
 | 
	
		
			
				|  |  |          self._cert_store = cert_store
 | 
	
		
			
				|  |  | -        self._serialize = serialize
 | 
	
		
			
				|  |  | -        self._deserialize = deserialize
 | 
	
		
			
				|  |  |          self._digest = digest
 | 
	
		
			
				|  |  | +        self._serialize = anyjson.serialize
 | 
	
		
			
				|  |  | +        self._deserialize = anyjson.deserialize
 | 
	
		
			
				|  |  | +        self._serializer = serializer
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      def serialize(self, data):
 | 
	
		
			
				|  |  |          """serialize data structure into string"""
 | 
	
		
			
				|  |  |          assert self._key is not None
 | 
	
		
			
				|  |  |          assert self._cert is not None
 | 
	
		
			
				|  |  |          try:
 | 
	
		
			
				|  |  | -            data = self._serialize(data)
 | 
	
		
			
				|  |  | -            signature = b64encode(self._key.sign(data, self._digest))
 | 
	
		
			
				|  |  | +            content_type, content_encoding, body = encode(
 | 
	
		
			
				|  |  | +                    data, serializer=self._serializer)
 | 
	
		
			
				|  |  | +            # What we sign is the serialized body, not the body itself.
 | 
	
		
			
				|  |  | +            # this way the receiver doesn't have to decode the contents
 | 
	
		
			
				|  |  | +            # to verify the signature (and thus avoiding potential flaws
 | 
	
		
			
				|  |  | +            # in the decoding step).
 | 
	
		
			
				|  |  | +            signature = b64encode(self._key.sign(body, self._digest))
 | 
	
		
			
				|  |  |              signer = self._cert.get_id()
 | 
	
		
			
				|  |  | -            return self._serialize(dict(data=data,
 | 
	
		
			
				|  |  | -                                        signer=signer,
 | 
	
		
			
				|  |  | -                                        signature=signature))
 | 
	
		
			
				|  |  | +            return self._serialize({
 | 
	
		
			
				|  |  | +                    "body": body,
 | 
	
		
			
				|  |  | +                    "signer": self._cert.get_id(),
 | 
	
		
			
				|  |  | +                    "signature": signature,
 | 
	
		
			
				|  |  | +                    "content_type": content_type,
 | 
	
		
			
				|  |  | +                    "content_encoding": content_encoding,
 | 
	
		
			
				|  |  | +            })
 | 
	
		
			
				|  |  |          except Exception, exc:
 | 
	
		
			
				|  |  |              raise SecurityError("Unable to serialize: %r" % (exc, ))
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -54,19 +62,22 @@ class SecureSerializer(object):
 | 
	
		
			
				|  |  |              data = self._deserialize(data)
 | 
	
		
			
				|  |  |              signature = b64decode(data["signature"])
 | 
	
		
			
				|  |  |              signer = data["signer"]
 | 
	
		
			
				|  |  | -            data = data["data"]
 | 
	
		
			
				|  |  | -            self._cert_store[signer].verify(data, signature, self._digest)
 | 
	
		
			
				|  |  | -            return self._deserialize(data)
 | 
	
		
			
				|  |  | +            body = data["body"]
 | 
	
		
			
				|  |  | +            self._cert_store[signer].verify(body,
 | 
	
		
			
				|  |  | +                                            signature, self._digest)
 | 
	
		
			
				|  |  | +            return decode(body, data["content_type"],
 | 
	
		
			
				|  |  | +                                data["content_encoding"], force=True)
 | 
	
		
			
				|  |  |          except Exception, exc:
 | 
	
		
			
				|  |  |              raise SecurityError("Unable to deserialize: %r" % (exc, ))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -def register_auth(key=None, cert=None, store=None):
 | 
	
		
			
				|  |  | +def register_auth(key=None, cert=None, store=None, digest="sha1",
 | 
	
		
			
				|  |  | +        serializer="pickle"):
 | 
	
		
			
				|  |  |      """register security serializer"""
 | 
	
		
			
				|  |  |      s = SecureSerializer(key and PrivateKey(key),
 | 
	
		
			
				|  |  |                           cert and Certificate(cert),
 | 
	
		
			
				|  |  |                           store and FSCertStore(store),
 | 
	
		
			
				|  |  | -                         anyjson.serialize, anyjson.deserialize)
 | 
	
		
			
				|  |  | +                         digest=digest, serializer=serializer)
 | 
	
		
			
				|  |  |      registry.register("auth", s.serialize, s.deserialize,
 | 
	
		
			
				|  |  |                        content_type="application/data",
 | 
	
		
			
				|  |  |                        content_encoding="utf-8")
 |