def validate_payload(request, payload): """Verify that the given payload matches the signature.""" # Get authentication details key_id = request.querydict.get("id", "") # aka fingerprint signature = request.querydict.get("sig2", "") if not signature: return None # Validate the payload public_key = get_public_key(key_id) if public_key is None: return None if not public_key.verify_data(signature, payload): return None return public_key.get_id()
def authenticate(request): """ Check if the request comes from someone that has a private key that we have have authorized. This is done by validating (using the public key) that the token is signed correctly. We also make sure that keys can only be used once. """ # Get authentication details key_id = request.querydict.get("id", "") # aka fingerprint token = request.querydict.get("token", "") signature = request.querydict.get("sig1", "") if not token or not signature: return None # Check the timestamp (first part of the token) client_time = int(token.split("-")[0]) server_time = int(time.time()) if not (server_time - 5 <= client_time <= server_time): return None # too late (or early) # Validate the signature public_key = get_public_key(key_id) if public_key is None: return None if not public_key.verify_data(signature, token.encode()): return None # Ok, but what if someone somehow read the key during its transfer # and tries to re-use it? for _, invalid_token in invalid_tokens: if token == invalid_token: return None # Clear invalid tokens that have expired and mark this one as invalid old = server_time - 10 while invalid_tokens and invalid_tokens[0][0] < old: invalid_tokens.popleft() invalid_tokens.append((server_time, token)) # todo: return string based on "comment" in public key. return public_key.get_id() # fingerprint