aboutsummaryrefslogtreecommitdiffstats
path: root/python/itsdangerous/signer.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/itsdangerous/signer.py')
-rw-r--r--python/itsdangerous/signer.py179
1 files changed, 0 insertions, 179 deletions
diff --git a/python/itsdangerous/signer.py b/python/itsdangerous/signer.py
deleted file mode 100644
index 6bddc03..0000000
--- a/python/itsdangerous/signer.py
+++ /dev/null
@@ -1,179 +0,0 @@
-import hashlib
-import hmac
-
-from ._compat import constant_time_compare
-from .encoding import _base64_alphabet
-from .encoding import base64_decode
-from .encoding import base64_encode
-from .encoding import want_bytes
-from .exc import BadSignature
-
-
-class SigningAlgorithm(object):
- """Subclasses must implement :meth:`get_signature` to provide
- signature generation functionality.
- """
-
- def get_signature(self, key, value):
- """Returns the signature for the given key and value."""
- raise NotImplementedError()
-
- def verify_signature(self, key, value, sig):
- """Verifies the given signature matches the expected
- signature.
- """
- return constant_time_compare(sig, self.get_signature(key, value))
-
-
-class NoneAlgorithm(SigningAlgorithm):
- """Provides an algorithm that does not perform any signing and
- returns an empty signature.
- """
-
- def get_signature(self, key, value):
- return b""
-
-
-class HMACAlgorithm(SigningAlgorithm):
- """Provides signature generation using HMACs."""
-
- #: The digest method to use with the MAC algorithm. This defaults to
- #: SHA1, but can be changed to any other function in the hashlib
- #: module.
- default_digest_method = staticmethod(hashlib.sha1)
-
- def __init__(self, digest_method=None):
- if digest_method is None:
- digest_method = self.default_digest_method
- self.digest_method = digest_method
-
- def get_signature(self, key, value):
- mac = hmac.new(key, msg=value, digestmod=self.digest_method)
- return mac.digest()
-
-
-class Signer(object):
- """This class can sign and unsign bytes, validating the signature
- provided.
-
- Salt can be used to namespace the hash, so that a signed string is
- only valid for a given namespace. Leaving this at the default value
- or re-using a salt value across different parts of your application
- where the same signed value in one part can mean something different
- in another part is a security risk.
-
- See :ref:`the-salt` for an example of what the salt is doing and how
- you can utilize it.
-
- .. versionadded:: 0.14
- ``key_derivation`` and ``digest_method`` were added as arguments
- to the class constructor.
-
- .. versionadded:: 0.18
- ``algorithm`` was added as an argument to the class constructor.
- """
-
- #: The digest method to use for the signer. This defaults to
- #: SHA1 but can be changed to any other function in the hashlib
- #: module.
- #:
- #: .. versionadded:: 0.14
- default_digest_method = staticmethod(hashlib.sha1)
-
- #: Controls how the key is derived. The default is Django-style
- #: concatenation. Possible values are ``concat``, ``django-concat``
- #: and ``hmac``. This is used for deriving a key from the secret key
- #: with an added salt.
- #:
- #: .. versionadded:: 0.14
- default_key_derivation = "django-concat"
-
- def __init__(
- self,
- secret_key,
- salt=None,
- sep=".",
- key_derivation=None,
- digest_method=None,
- algorithm=None,
- ):
- self.secret_key = want_bytes(secret_key)
- self.sep = want_bytes(sep)
- if self.sep in _base64_alphabet:
- raise ValueError(
- "The given separator cannot be used because it may be"
- " contained in the signature itself. Alphanumeric"
- " characters and `-_=` must not be used."
- )
- self.salt = "itsdangerous.Signer" if salt is None else salt
- if key_derivation is None:
- key_derivation = self.default_key_derivation
- self.key_derivation = key_derivation
- if digest_method is None:
- digest_method = self.default_digest_method
- self.digest_method = digest_method
- if algorithm is None:
- algorithm = HMACAlgorithm(self.digest_method)
- self.algorithm = algorithm
-
- def derive_key(self):
- """This method is called to derive the key. The default key
- derivation choices can be overridden here. Key derivation is not
- intended to be used as a security method to make a complex key
- out of a short password. Instead you should use large random
- secret keys.
- """
- salt = want_bytes(self.salt)
- if self.key_derivation == "concat":
- return self.digest_method(salt + self.secret_key).digest()
- elif self.key_derivation == "django-concat":
- return self.digest_method(salt + b"signer" + self.secret_key).digest()
- elif self.key_derivation == "hmac":
- mac = hmac.new(self.secret_key, digestmod=self.digest_method)
- mac.update(salt)
- return mac.digest()
- elif self.key_derivation == "none":
- return self.secret_key
- else:
- raise TypeError("Unknown key derivation method")
-
- def get_signature(self, value):
- """Returns the signature for the given value."""
- value = want_bytes(value)
- key = self.derive_key()
- sig = self.algorithm.get_signature(key, value)
- return base64_encode(sig)
-
- def sign(self, value):
- """Signs the given string."""
- return want_bytes(value) + want_bytes(self.sep) + self.get_signature(value)
-
- def verify_signature(self, value, sig):
- """Verifies the signature for the given value."""
- key = self.derive_key()
- try:
- sig = base64_decode(sig)
- except Exception:
- return False
- return self.algorithm.verify_signature(key, value, sig)
-
- def unsign(self, signed_value):
- """Unsigns the given string."""
- signed_value = want_bytes(signed_value)
- sep = want_bytes(self.sep)
- if sep not in signed_value:
- raise BadSignature("No %r found in value" % self.sep)
- value, sig = signed_value.rsplit(sep, 1)
- if self.verify_signature(value, sig):
- return value
- raise BadSignature("Signature %r does not match" % sig, payload=value)
-
- def validate(self, signed_value):
- """Only validates the given signed value. Returns ``True`` if
- the signature exists and is valid.
- """
- try:
- self.unsign(signed_value)
- return True
- except BadSignature:
- return False