Exemplo n.º 1
0
 def test_token_validation(self):
     manager = tokenlib.TokenManager(timeout=0.2)
     token = manager.make_token({"hello": "world"})
     token_bytes = decode_token_bytes(token)
     # Proper token == valid.
     data = manager.parse_token(token)
     self.assertEquals(data["hello"], "world")
     # Badly-encoded bytes == not valid.
     bad_token = "@" + token[1:]
     with self.assertRaises(errors.MalformedTokenError):
         manager.parse_token(bad_token)
     # Bad signature == not valid.
     bad_token = encode_token_bytes(b"X" * 50)
     with self.assertRaises(errors.InvalidSignatureError):
         manager.parse_token(bad_token)
     bad_token_bytes = token_bytes[:-1]
     bad_token_bytes += b"X" if token_bytes[-1] == b"Z" else b"Z"
     bad_token = encode_token_bytes(bad_token_bytes)
     with self.assertRaises(errors.InvalidSignatureError):
         manager.parse_token(bad_token)
     # Modified payload == not valid.
     bad_token = encode_token_bytes(b"admin" + token_bytes[6:])
     with self.assertRaises(errors.InvalidSignatureError):
         manager.parse_token(bad_token)
     # Expired token == not valid.
     time.sleep(0.2)
     with self.assertRaises(errors.ExpiredTokenError):
         manager.parse_token(token)
Exemplo n.º 2
0
 def test_token_validation(self):
     manager = tokenlib.TokenManager(timeout=0.2)
     token = manager.make_token({"hello": "world"})
     token_bytes = decode_token_bytes(token)
     # Proper token == valid.
     data = manager.parse_token(token)
     self.assertEquals(data["hello"], "world")
     # Badly-encoded bytes == not valid.
     bad_token = "@" + token[1:]
     with self.assertRaises(errors.MalformedTokenError):
         manager.parse_token(bad_token)
     # Bad signature == not valid.
     bad_token = encode_token_bytes(b"X" * 50)
     with self.assertRaises(errors.InvalidSignatureError):
         manager.parse_token(bad_token)
     bad_token_bytes = token_bytes[:-1]
     bad_token_bytes += b"X" if token_bytes[-1] == b"Z" else b"Z"
     bad_token = encode_token_bytes(bad_token_bytes)
     with self.assertRaises(errors.InvalidSignatureError):
         manager.parse_token(bad_token)
     # Modified payload == not valid.
     bad_token = encode_token_bytes(b"admin" + token_bytes[6:])
     with self.assertRaises(errors.InvalidSignatureError):
         manager.parse_token(bad_token)
     # Expired token == not valid.
     time.sleep(0.2)
     with self.assertRaises(errors.ExpiredTokenError):
         manager.parse_token(token)
Exemplo n.º 3
0
 def test_get_derived_secret_errors_out_for_malformed_tokens(self):
     manager = tokenlib.TokenManager()
     digest_size = manager.hashmod_digest_size
     bad_token = encode_token_bytes(b"{}" + (b"X" * digest_size))
     with self.assertRaises(errors.MalformedTokenError):
         manager.get_derived_secret(bad_token)
     bad_token = encode_token_bytes(b"42" + (b"X" * digest_size))
     with self.assertRaises(errors.MalformedTokenError):
         manager.get_derived_secret(bad_token)
     bad_token = encode_token_bytes(b"NOTJSON" + (b"X" * digest_size))
     with self.assertRaises(errors.MalformedTokenError):
         manager.get_derived_secret(bad_token)
Exemplo n.º 4
0
 def test_get_derived_secret_errors_out_for_malformed_tokens(self):
     manager = tokenlib.TokenManager()
     digest_size = manager.hashmod_digest_size
     bad_token = encode_token_bytes(b"{}" + (b"X" * digest_size))
     with self.assertRaises(errors.MalformedTokenError):
         manager.get_derived_secret(bad_token)
     bad_token = encode_token_bytes(b"42" + (b"X" * digest_size))
     with self.assertRaises(errors.MalformedTokenError):
         manager.get_derived_secret(bad_token)
     bad_token = encode_token_bytes(b"NOTJSON" + (b"X" * digest_size))
     with self.assertRaises(errors.MalformedTokenError):
         manager.get_derived_secret(bad_token)
Exemplo n.º 5
0
    def get_derived_secret(self, token):
        """Get the derived secret key associated with the given token.

        A per-token secret key is calculated by deriving it from the master
        secret with HKDF.
        """
        try:
            payload = decode_token_bytes(token)[:-self.hashmod_digest_size]
            salt = json.loads(payload.decode("utf8"))["salt"].encode("ascii")
        except (TypeError, KeyError, ValueError) as e:
            raise errors.MalformedTokenError(str(e))
        info = HKDF_INFO_DERIVE + token.encode("ascii")
        secret = HKDF(self.secret, salt=salt, info=info,
                      size=self.hashmod_digest_size, hashmod=self.hashmod)
        return encode_token_bytes(secret)
Exemplo n.º 6
0
    def make_token(self, data):
        """Generate a new token embedding the given dict of data.

        The token is a JSON dump of the given data along with an expiry
        time and salt.  It has a HMAC signature appended and is b64-encoded
        for transmission.
        """
        data = data.copy()
        if "salt" not in data:
            data["salt"] = hexlify(os.urandom(3)).decode("ascii")
        if "expires" not in data:
            data["expires"] = time.time() + self.timeout
        payload = json.dumps(data).encode("utf8")
        sig = self._get_signature(payload)
        assert len(sig) == self.hashmod_digest_size
        return encode_token_bytes(payload + sig)
Exemplo n.º 7
0
    def make_token(self, data):
        """Generate a new token embedding the given dict of data.

        The token is a JSON dump of the given data along with an expiry
        time and salt.  It has a HMAC signature appended and is b64-encoded
        for transmission.
        """
        data = data.copy()
        if "salt" not in data:
            data["salt"] = hexlify(os.urandom(3)).decode("ascii")
        if "expires" not in data:
            data["expires"] = time.time() + self.timeout
        payload = json.dumps(data).encode("utf8")
        sig = self._get_signature(payload)
        assert len(sig) == self.hashmod_digest_size
        return encode_token_bytes(payload + sig)
Exemplo n.º 8
0
    def get_derived_secret(self, token):
        """Get the derived secret key associated with the given token.

        A per-token secret key is calculated by deriving it from the master
        secret with HKDF.
        """
        try:
            payload = decode_token_bytes(token)[:-self.hashmod_digest_size]
            salt = json.loads(payload.decode("utf8"))["salt"].encode("ascii")
        except (TypeError, KeyError, ValueError) as e:
            raise errors.MalformedTokenError(str(e))
        info = HKDF_INFO_DERIVE + token.encode("ascii")
        secret = HKDF(self.secret,
                      salt=salt,
                      info=info,
                      size=self.hashmod_digest_size,
                      hashmod=self.hashmod)
        return encode_token_bytes(secret)