def verify_from(self, actor_whom_sender_claims_to_be: "Character", message: bytes, signature: Signature = None, decrypt=False, signature_is_on_cleartext=False) -> tuple: """ Inverse of encrypt_for. :param actor_that_sender_claims_to_be: A Character instance representing the actor whom the sender claims to be. We check the public key owned by this Character instance to verify. :param messages: The messages to be verified. :param decrypt: Whether or not to decrypt the messages. :param signature_is_on_cleartext: True if we expect the signature to be on the cleartext. Otherwise, we presume that the ciphertext is what is signed. :return: (Whether or not the signature is valid, the decrypted plaintext or NO_DECRYPTION_PERFORMED) """ if not signature and not signature_is_on_cleartext: raise ValueError("You need to either provide the Signature or decrypt and find it on the cleartext.") cleartext = NO_DECRYPTION_PERFORMED if signature_is_on_cleartext: if decrypt: cleartext = self._crypto_power.decrypt(message) signature, message = BytestringSplitter(Signature)(cleartext, return_remainder=True) else: raise ValueError( "Can't look for a signature on the cleartext if we're not decrypting.") actor = self._lookup_actor(actor_whom_sender_claims_to_be) return signature.verify(message, actor.seal), cleartext
def verify_from(self, actor_whom_sender_claims_to_be: "Character", message_kit: Union[MessageKit, bytes], signature: Signature=None, decrypt=False, signature_is_on_cleartext=False) -> tuple: """ Inverse of encrypt_for. :param actor_that_sender_claims_to_be: A Character instance representing the actor whom the sender claims to be. We check the public key owned by this Character instance to verify. :param messages: The messages to be verified. :param decrypt: Whether or not to decrypt the messages. :param signature_is_on_cleartext: True if we expect the signature to be on the cleartext. Otherwise, we presume that the ciphertext is what is signed. :return: Whether or not the signature is valid, the decrypted plaintext or NO_DECRYPTION_PERFORMED """ # TODO: In this flow we now essentially have two copies of the public key. See #174. # One from the actor (first arg) and one from the MessageKit. # Which do we use in which cases? # if not signature and not signature_is_on_cleartext: # TODO: Since a signature can now be in a MessageKit, this might not be accurate anymore. See #174. # raise ValueError("You need to either provide the Signature or \ # decrypt and find it on the cleartext.") cleartext = NO_DECRYPTION_PERFORMED if signature_is_on_cleartext: if decrypt: cleartext_with_sig = self.decrypt(message_kit) signature, cleartext = BytestringSplitter(Signature)(cleartext_with_sig, return_remainder=True) message_kit.signature = signature # TODO: Obviously this is the wrong way to do this. Let's make signature a property. else: raise ValueError( "Can't look for a signature on the cleartext if we're not \ decrypting.") message = cleartext alice_pubkey = message_kit.alice_pubkey else: # The signature is on the ciphertext. We might not even need to decrypt it. if decrypt: message = message_kit.ciphertext cleartext = self.decrypt(message_kit) else: message = bytes(message_kit) alice_pubkey = actor_whom_sender_claims_to_be.public_key(SigningPower) if signature: is_valid = signature.verify(message, alice_pubkey) else: # Meh, we didn't even get a signature. Not much we can do. is_valid = False return is_valid, cleartext