Beispiel #1
0
 def new_inbound_session(self, sender_key: IdentityKey,
                         ciphertext: str) -> Session:
     session = olm.InboundSession(self, olm.OlmPreKeyMessage(ciphertext),
                                  sender_key)
     self.remove_one_time_keys(session)
     return Session.from_pickle(session.pickle("roundtrip"),
                                passphrase="roundtrip",
                                creation_time=datetime.now())
Beispiel #2
0
 def decrypt(self, ciphertext: OlmCiphertext) -> str:
     plaintext = super().decrypt(
         olm.OlmPreKeyMessage(ciphertext.body)
         if ciphertext.type == OlmMsgType.PREKEY
         else olm.OlmMessage(ciphertext.body)
     )
     self.last_decrypted = datetime.now()
     return plaintext
Beispiel #3
0
    def olm_decrypt_event(self, content, user_id):
        """Decrypt an Olm encrypted event, and check its properties.

        Args:
            event (dict): The content property of a m.room.encrypted event.
            user_id (str): The sender of the event.

        Retuns:
            The decrypted event held by the initial event.

        Raises:
            RuntimeError: Error in the decryption process. Nothing can be done. The text
                of the exception indicates what went wrong, and should be logged or
                displayed to the user.
            KeyError: The event is missing a required field.
        """
        if content['algorithm'] != self._olm_algorithm:
            raise RuntimeError('Event was not encrypted with {}.'
                               .format(self._olm_algorithm))

        ciphertext = content['ciphertext']
        try:
            payload = ciphertext[self.curve25519]
        except KeyError:
            raise RuntimeError('This message was not encrypted for us.')

        msg_type = payload['type']
        if msg_type == 0:
            encrypted_message = olm.OlmPreKeyMessage(payload['body'])
        else:
            encrypted_message = olm.OlmMessage(payload['body'])

        sender_key = content['sender_key']
        decrypted_event = self._olm_decrypt(encrypted_message, sender_key)

        signing_key = decrypted_event['keys']['ed25519']
        if decrypted_event['sender'] != user_id:
            raise RuntimeError(
                'Found user {} instead of sender {} in Olm plaintext {}.'
                .format(decrypted_event['sender'], user_id, decrypted_event)
            )
        if decrypted_event['recipient'] != self.user_id:
            raise RuntimeError(
                'Found user {} instead of us ({}) in Olm plaintext {}.'
                .format(decrypted_event['recipient'], self.user_id, decrypted_event)
            )
        our_key = decrypted_event['recipient_keys']['ed25519']
        if our_key != self.ed25519:
            raise RuntimeError(
                'Found key {} instead of ours own ed25519 key {} in Olm plaintext {}.'
                .format(our_key, self.ed25519, decrypted_event)
            )
        try:
            device = self.device_keys[user_id][decrypted_event['sender_device']]
        except KeyError:
            pass
        else:
            if device.verified:
                if device.curve25519 != sender_key or device.ed25519 != signing_key:
                    raise RuntimeError(
                        'Device keys mismatch between payload and /keys/query data.'
                    )

        return decrypted_event
Beispiel #4
0
 def matches(self, ciphertext: str) -> bool:
     return super().matches(olm.OlmPreKeyMessage(ciphertext))
Beispiel #5
0
 def decrypt(self, ciphertext: OlmCiphertext) -> str:
     self.use_time = datetime.now()
     return super().decrypt(
         olm.OlmPreKeyMessage(ciphertext.body) if ciphertext.type ==
         OlmMsgType.PREKEY else olm.OlmMessage(ciphertext.body))