@ -1299,78 +1299,83 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s
auto our_curve = olm : : client ( ) - > identity_keys ( ) . curve25519 ;
auto our_curve = olm : : client ( ) - > identity_keys ( ) . curve25519 ;
for ( const auto & [ user , devices ] : targets ) {
{
auto deviceKeys = cache : : client ( ) - > userKeys ( user ) ;
auto currentTime = QDateTime : : currentSecsSinceEpoch ( ) ;
std : : vector < std : : pair < std : : string , mtx : : crypto : : OlmSessionPtr > > sessionsToPersist ;
// no keys for user, query them
for ( const auto & [ user , devices ] : targets ) {
if ( ! deviceKeys ) {
auto deviceKeys = cache : : client ( ) - > userKeys ( user ) ;
keysToQuery [ user ] = devices ;
continue ;
}
auto deviceTargets = devices ;
// no keys for user, query them
if ( devices . empty ( ) ) {
if ( ! deviceKeys ) {
deviceTargets . clear ( ) ;
keysToQuery [ user ] = devices ;
deviceTargets . reserve ( deviceKeys - > device_keys . size ( ) ) ;
continue ;
for ( const auto & [ device , keys ] : deviceKeys - > device_keys ) {
( void ) keys ;
deviceTargets . push_back ( device ) ;
}
}
}
for ( const auto & device : deviceTargets ) {
auto deviceTargets = devices ;
if ( ! deviceKeys - > device_keys . count ( device ) ) {
if ( devices . empty ( ) ) {
keysToQuery [ user ] = { } ;
deviceTargets . clear ( ) ;
break ;
deviceTargets . reserve ( deviceKeys - > device_keys . size ( ) ) ;
for ( const auto & [ device , keys ] : deviceKeys - > device_keys ) {
( void ) keys ;
deviceTargets . push_back ( device ) ;
}
}
}
auto d = deviceKeys - > device_keys . at ( device ) ;
for ( const auto & device : deviceTargets ) {
if ( ! deviceKeys - > device_keys . count ( device ) ) {
keysToQuery [ user ] = { } ;
break ;
}
if ( ! d . keys . count ( " curve25519: " + device ) | | ! d . keys . count ( " ed25519: " + device ) ) {
const auto & d = deviceKeys - > device_keys . at ( device ) ;
nhlog : : crypto ( ) - > warn ( " Skipping device {} since it has no keys! " , device ) ;
continue ;
}
auto device_curve = d . keys . at ( " curve25519: " + device ) ;
if ( ! d . keys . count ( " curve25519: " + device ) | | ! d . keys . count ( " ed25519: " + device ) ) {
if ( device_curve = = our_curve ) {
nhlog : : crypto ( ) - > warn ( " Skipping device {} since it has no keys! " , device ) ;
nhlog : : crypto ( ) - > warn ( " Skipping our own device, since sending "
continue ;
" ourselves olm messages makes no sense. " ) ;
}
continue ;
}
auto session = cache : : getLatestOlmSession ( device_curve ) ;
auto device_curve = d . keys . at ( " curve25519: " + device ) ;
if ( ! session | | force_new_session ) {
if ( device_curve = = our_curve ) {
auto currentTime = QDateTime : : currentSecsSinceEpoch ( ) ;
nhlog : : crypto ( ) - > warn ( " Skipping our own device, since sending "
if ( rateLimit . value ( QPair ( user , device ) ) + 60 * 60 * 10 < currentTime ) {
" ourselves olm messages makes no sense. " ) ;
claims . one_time_keys [ user ] [ device ] = mtx : : crypto : : SIGNED_CURVE25519 ;
continue ;
pks [ user ] [ device ] . ed25519 = d . keys . at ( " ed25519: " + device ) ;
}
pks [ user ] [ device ] . curve25519 = d . keys . at ( " curve25519: " + device ) ;
rateLimit . insert ( QPair ( user , device ) , currentTime ) ;
auto session = cache : : getLatestOlmSession ( device_curve ) ;
} else {
if ( ! session | | force_new_session ) {
nhlog : : crypto ( ) - > warn ( " Not creating new session with {}:{} "
if ( rateLimit . value ( QPair ( user , device ) ) + 60 * 60 * 10 < currentTime ) {
" because of rate limit " ,
claims . one_time_keys [ user ] [ device ] = mtx : : crypto : : SIGNED_CURVE25519 ;
user ,
pks [ user ] [ device ] . ed25519 = d . keys . at ( " ed25519: " + device ) ;
device ) ;
pks [ user ] [ device ] . curve25519 = d . keys . at ( " curve25519: " + device ) ;
rateLimit . insert ( QPair ( user , device ) , currentTime ) ;
} else {
nhlog : : crypto ( ) - > warn ( " Not creating new session with {}:{} "
" because of rate limit " ,
user ,
device ) ;
}
continue ;
}
}
continue ;
}
messages [ mtx : : identifiers : : parse < mtx : : identifiers : : User > ( user ) ] [ device ] =
messages [ mtx : : identifiers : : parse < mtx : : identifiers : : User > ( user ) ] [ device ] =
olm : : client ( )
olm : : client ( )
- > create_olm_encrypted_content ( session - > get ( ) ,
- > create_olm_encrypted_content ( session - > get ( ) ,
ev_json ,
ev_json ,
UserId ( user ) ,
UserId ( user ) ,
d . keys . at ( " ed25519: " + device ) ,
d . keys . at ( " ed25519: " + device ) ,
device_curve )
device_curve )
. get < mtx : : events : : msg : : OlmEncrypted > ( ) ;
. get < mtx : : events : : msg : : OlmEncrypted > ( ) ;
sessionsToPersist . emplace_back ( d . keys . at ( " curve25519: " + device ) ,
std : : move ( * session ) ) ;
}
}
if ( ! sessionsToPersist . empty ( ) ) {
try {
try {
nhlog : : crypto ( ) - > debug ( " Updated olm session: {} " ,
nhlog : : crypto ( ) - > debug ( " Updated olm sessions: {} " , sessionsToPersist . size ( ) ) ;
mtx : : crypto : : session_id ( session - > get ( ) ) ) ;
cache : : client ( ) - > saveOlmSessions ( std : : move ( sessionsToPersist ) , currentTime ) ;
cache : : saveOlmSession ( d . keys . at ( " curve25519: " + device ) ,
std : : move ( * session ) ,
QDateTime : : currentMSecsSinceEpoch ( ) ) ;
} catch ( const lmdb : : error & e ) {
} catch ( const lmdb : : error & e ) {
nhlog : : db ( ) - > critical ( " failed to save outbound olm session: {} " , e . what ( ) ) ;
nhlog : : db ( ) - > critical ( " failed to save outbound olm session: {} " , e . what ( ) ) ;
} catch ( const mtx : : crypto : : olm_exception & e ) {
} catch ( const mtx : : crypto : : olm_exception & e ) {
@ -1395,6 +1400,9 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s
mtx : : http : : RequestErr ) {
mtx : : http : : RequestErr ) {
std : : map < mtx : : identifiers : : User , std : : map < std : : string , mtx : : events : : msg : : OlmEncrypted > >
std : : map < mtx : : identifiers : : User , std : : map < std : : string , mtx : : events : : msg : : OlmEncrypted > >
messages ;
messages ;
auto currentTime = QDateTime : : currentSecsSinceEpoch ( ) ;
std : : vector < std : : pair < std : : string , mtx : : crypto : : OlmSessionPtr > > sessionsToPersist ;
for ( const auto & [ user_id , retrieved_devices ] : res . one_time_keys ) {
for ( const auto & [ user_id , retrieved_devices ] : res . one_time_keys ) {
nhlog : : net ( ) - > debug ( " claimed keys for {} " , user_id ) ;
nhlog : : net ( ) - > debug ( " claimed keys for {} " , user_id ) ;
if ( retrieved_devices . size ( ) = = 0 ) {
if ( retrieved_devices . size ( ) = = 0 ) {
@ -1440,21 +1448,24 @@ send_encrypted_to_device_messages(const std::map<std::string, std::vector<std::s
session . get ( ) , ev_json , UserId ( user_id ) , sign_key , id_key )
session . get ( ) , ev_json , UserId ( user_id ) , sign_key , id_key )
. get < mtx : : events : : msg : : OlmEncrypted > ( ) ;
. get < mtx : : events : : msg : : OlmEncrypted > ( ) ;
try {
sessionsToPersist . emplace_back ( id_key , std : : move ( session ) ) ;
nhlog : : crypto ( ) - > debug ( " Updated olm session: {} " ,
mtx : : crypto : : session_id ( session . get ( ) ) ) ;
cache : : saveOlmSession (
id_key , std : : move ( session ) , QDateTime : : currentMSecsSinceEpoch ( ) ) ;
} catch ( const lmdb : : error & e ) {
nhlog : : db ( ) - > critical ( " failed to save outbound olm session: {} " , e . what ( ) ) ;
} catch ( const mtx : : crypto : : olm_exception & e ) {
nhlog : : crypto ( ) - > critical ( " failed to pickle outbound olm session: {} " ,
e . what ( ) ) ;
}
}
}
nhlog : : net ( ) - > info ( " send_to_device: {} " , user_id ) ;
nhlog : : net ( ) - > info ( " send_to_device: {} " , user_id ) ;
}
}
if ( ! sessionsToPersist . empty ( ) ) {
try {
nhlog : : crypto ( ) - > debug ( " Updated (new) olm sessions: {} " ,
sessionsToPersist . size ( ) ) ;
cache : : client ( ) - > saveOlmSessions ( std : : move ( sessionsToPersist ) , currentTime ) ;
} catch ( const lmdb : : error & e ) {
nhlog : : db ( ) - > critical ( " failed to save outbound olm session: {} " , e . what ( ) ) ;
} catch ( const mtx : : crypto : : olm_exception & e ) {
nhlog : : crypto ( ) - > critical ( " failed to pickle outbound olm session: {} " ,
e . what ( ) ) ;
}
}
if ( ! messages . empty ( ) )
if ( ! messages . empty ( ) )
http : : client ( ) - > send_to_device < mtx : : events : : msg : : OlmEncrypted > (
http : : client ( ) - > send_to_device < mtx : : events : : msg : : OlmEncrypted > (
http : : client ( ) - > generate_txn_id ( ) , messages , [ ] ( mtx : : http : : RequestErr err ) {
http : : client ( ) - > generate_txn_id ( ) , messages , [ ] ( mtx : : http : : RequestErr err ) {