// (5) Where sender_device_keys is present in the decrypted content:
if (e.raw().get().contains("sender_device_keys")) {
auto deviceKeys = e.raw().get().at("sender_device_keys").template get<Api::QueryKeysJob::DeviceInformation>();
// The following statement checks:
// (1) sender_device_keys.user_id must also match the sender of the event.
// (2) [CORRECTED: sender_device_keys.keys.curve25519:<device_id>] must also match the sender_key property in the cleartext m.room.encrypted event body.
// (3) ed25519 keys not checked (the check is performed in client/actions/encryption.cpp )
// (4) The sender_device_keys structure must have a valid signature from the key with ID ed25519:<device_id> (i.e., the sending device's Ed25519 key).
auto verifiedInfo = verifyDeviceInfo(e.sender(), deviceKeys.deviceId, deviceKeys);
if (verifiedInfo.has_value()) {
auto existingDeviceOpt = get(e.sender(), deviceKeys.deviceId);
if (existingDeviceOpt.has_value()) {
return {InTracker, existingDeviceOpt.value()};
} else {
return {InEvent, verifiedInfo.value()};
}
} else {
kzo.client.dbg() << "sender_device_keys present but invalid, rejecting" << std::endl;
return {NotFound, {}};
}
} else {
auto existingDeviceOpt = findByCurve25519Key(e.sender(), senderCurve25519Key);