better cache invalidation of ssss cache

This commit is contained in:
Sorunome 2020-06-05 22:22:07 +02:00
parent 4c60369b8d
commit 115cd9e5b3
No known key found for this signature in database
GPG key ID: B19471D07FC9BE9C
3 changed files with 64 additions and 12 deletions

View file

@ -177,7 +177,7 @@ class SSSS {
} }
// check if it is still valid // check if it is still valid
final keys = keyIdsFromType(type); final keys = keyIdsFromType(type);
if (keys.contains(ret.keyId)) { if (keys.contains(ret.keyId) && client.accountData[type].content['encrypted'][ret.keyId]['ciphertext'] == ret.ciphertext) {
return ret.content; return ret.content;
} }
return null; return null;
@ -200,7 +200,7 @@ class SSSS {
final decrypted = decryptAes(encryptInfo, key, type); final decrypted = decryptAes(encryptInfo, key, type);
if (CACHE_TYPES.contains(type) && client.database != null) { if (CACHE_TYPES.contains(type) && client.database != null) {
// cache the thing // cache the thing
await client.database.storeSSSSCache(client.id, type, keyId, decrypted); await client.database.storeSSSSCache(client.id, type, keyId, enc['ciphertext'], decrypted);
} }
return decrypted; return decrypted;
} }
@ -224,7 +224,7 @@ class SSSS {
); );
if (CACHE_TYPES.contains(type) && client.database != null) { if (CACHE_TYPES.contains(type) && client.database != null) {
// cache the thing // cache the thing
await client.database.storeSSSSCache(client.id, type, keyId, secret); await client.database.storeSSSSCache(client.id, type, keyId, encrypted.ciphertext, secret);
} }
} }
@ -352,8 +352,9 @@ class SSSS {
if (client.database != null) { if (client.database != null) {
final keyId = keyIdFromType(request.type); final keyId = keyIdFromType(request.type);
if (keyId != null) { if (keyId != null) {
final ciphertext = client.accountData[request.type].content['encrypted'][keyId]['ciphertext'];
await client.database await client.database
.storeSSSSCache(client.id, request.type, keyId, secret); .storeSSSSCache(client.id, request.type, keyId, ciphertext, secret);
} }
} }
} }

View file

@ -4805,11 +4805,13 @@ class DbSSSSCache extends DataClass implements Insertable<DbSSSSCache> {
final int clientId; final int clientId;
final String type; final String type;
final String keyId; final String keyId;
final String ciphertext;
final String content; final String content;
DbSSSSCache( DbSSSSCache(
{@required this.clientId, {@required this.clientId,
@required this.type, @required this.type,
@required this.keyId, @required this.keyId,
@required this.ciphertext,
@required this.content}); @required this.content});
factory DbSSSSCache.fromData(Map<String, dynamic> data, GeneratedDatabase db, factory DbSSSSCache.fromData(Map<String, dynamic> data, GeneratedDatabase db,
{String prefix}) { {String prefix}) {
@ -4822,6 +4824,8 @@ class DbSSSSCache extends DataClass implements Insertable<DbSSSSCache> {
type: stringType.mapFromDatabaseResponse(data['${effectivePrefix}type']), type: stringType.mapFromDatabaseResponse(data['${effectivePrefix}type']),
keyId: keyId:
stringType.mapFromDatabaseResponse(data['${effectivePrefix}key_id']), stringType.mapFromDatabaseResponse(data['${effectivePrefix}key_id']),
ciphertext: stringType
.mapFromDatabaseResponse(data['${effectivePrefix}ciphertext']),
content: content:
stringType.mapFromDatabaseResponse(data['${effectivePrefix}content']), stringType.mapFromDatabaseResponse(data['${effectivePrefix}content']),
); );
@ -4838,6 +4842,9 @@ class DbSSSSCache extends DataClass implements Insertable<DbSSSSCache> {
if (!nullToAbsent || keyId != null) { if (!nullToAbsent || keyId != null) {
map['key_id'] = Variable<String>(keyId); map['key_id'] = Variable<String>(keyId);
} }
if (!nullToAbsent || ciphertext != null) {
map['ciphertext'] = Variable<String>(ciphertext);
}
if (!nullToAbsent || content != null) { if (!nullToAbsent || content != null) {
map['content'] = Variable<String>(content); map['content'] = Variable<String>(content);
} }
@ -4851,6 +4858,7 @@ class DbSSSSCache extends DataClass implements Insertable<DbSSSSCache> {
clientId: serializer.fromJson<int>(json['client_id']), clientId: serializer.fromJson<int>(json['client_id']),
type: serializer.fromJson<String>(json['type']), type: serializer.fromJson<String>(json['type']),
keyId: serializer.fromJson<String>(json['key_id']), keyId: serializer.fromJson<String>(json['key_id']),
ciphertext: serializer.fromJson<String>(json['ciphertext']),
content: serializer.fromJson<String>(json['content']), content: serializer.fromJson<String>(json['content']),
); );
} }
@ -4861,16 +4869,22 @@ class DbSSSSCache extends DataClass implements Insertable<DbSSSSCache> {
'client_id': serializer.toJson<int>(clientId), 'client_id': serializer.toJson<int>(clientId),
'type': serializer.toJson<String>(type), 'type': serializer.toJson<String>(type),
'key_id': serializer.toJson<String>(keyId), 'key_id': serializer.toJson<String>(keyId),
'ciphertext': serializer.toJson<String>(ciphertext),
'content': serializer.toJson<String>(content), 'content': serializer.toJson<String>(content),
}; };
} }
DbSSSSCache copyWith( DbSSSSCache copyWith(
{int clientId, String type, String keyId, String content}) => {int clientId,
String type,
String keyId,
String ciphertext,
String content}) =>
DbSSSSCache( DbSSSSCache(
clientId: clientId ?? this.clientId, clientId: clientId ?? this.clientId,
type: type ?? this.type, type: type ?? this.type,
keyId: keyId ?? this.keyId, keyId: keyId ?? this.keyId,
ciphertext: ciphertext ?? this.ciphertext,
content: content ?? this.content, content: content ?? this.content,
); );
@override @override
@ -4879,14 +4893,19 @@ class DbSSSSCache extends DataClass implements Insertable<DbSSSSCache> {
..write('clientId: $clientId, ') ..write('clientId: $clientId, ')
..write('type: $type, ') ..write('type: $type, ')
..write('keyId: $keyId, ') ..write('keyId: $keyId, ')
..write('ciphertext: $ciphertext, ')
..write('content: $content') ..write('content: $content')
..write(')')) ..write(')'))
.toString(); .toString();
} }
@override @override
int get hashCode => $mrjf($mrjc(clientId.hashCode, int get hashCode => $mrjf($mrjc(
$mrjc(type.hashCode, $mrjc(keyId.hashCode, content.hashCode)))); clientId.hashCode,
$mrjc(
type.hashCode,
$mrjc(
keyId.hashCode, $mrjc(ciphertext.hashCode, content.hashCode)))));
@override @override
bool operator ==(dynamic other) => bool operator ==(dynamic other) =>
identical(this, other) || identical(this, other) ||
@ -4894,6 +4913,7 @@ class DbSSSSCache extends DataClass implements Insertable<DbSSSSCache> {
other.clientId == this.clientId && other.clientId == this.clientId &&
other.type == this.type && other.type == this.type &&
other.keyId == this.keyId && other.keyId == this.keyId &&
other.ciphertext == this.ciphertext &&
other.content == this.content); other.content == this.content);
} }
@ -4901,32 +4921,38 @@ class SsssCacheCompanion extends UpdateCompanion<DbSSSSCache> {
final Value<int> clientId; final Value<int> clientId;
final Value<String> type; final Value<String> type;
final Value<String> keyId; final Value<String> keyId;
final Value<String> ciphertext;
final Value<String> content; final Value<String> content;
const SsssCacheCompanion({ const SsssCacheCompanion({
this.clientId = const Value.absent(), this.clientId = const Value.absent(),
this.type = const Value.absent(), this.type = const Value.absent(),
this.keyId = const Value.absent(), this.keyId = const Value.absent(),
this.ciphertext = const Value.absent(),
this.content = const Value.absent(), this.content = const Value.absent(),
}); });
SsssCacheCompanion.insert({ SsssCacheCompanion.insert({
@required int clientId, @required int clientId,
@required String type, @required String type,
@required String keyId, @required String keyId,
@required String ciphertext,
@required String content, @required String content,
}) : clientId = Value(clientId), }) : clientId = Value(clientId),
type = Value(type), type = Value(type),
keyId = Value(keyId), keyId = Value(keyId),
ciphertext = Value(ciphertext),
content = Value(content); content = Value(content);
static Insertable<DbSSSSCache> custom({ static Insertable<DbSSSSCache> custom({
Expression<int> clientId, Expression<int> clientId,
Expression<String> type, Expression<String> type,
Expression<String> keyId, Expression<String> keyId,
Expression<String> ciphertext,
Expression<String> content, Expression<String> content,
}) { }) {
return RawValuesInsertable({ return RawValuesInsertable({
if (clientId != null) 'client_id': clientId, if (clientId != null) 'client_id': clientId,
if (type != null) 'type': type, if (type != null) 'type': type,
if (keyId != null) 'key_id': keyId, if (keyId != null) 'key_id': keyId,
if (ciphertext != null) 'ciphertext': ciphertext,
if (content != null) 'content': content, if (content != null) 'content': content,
}); });
} }
@ -4935,11 +4961,13 @@ class SsssCacheCompanion extends UpdateCompanion<DbSSSSCache> {
{Value<int> clientId, {Value<int> clientId,
Value<String> type, Value<String> type,
Value<String> keyId, Value<String> keyId,
Value<String> ciphertext,
Value<String> content}) { Value<String> content}) {
return SsssCacheCompanion( return SsssCacheCompanion(
clientId: clientId ?? this.clientId, clientId: clientId ?? this.clientId,
type: type ?? this.type, type: type ?? this.type,
keyId: keyId ?? this.keyId, keyId: keyId ?? this.keyId,
ciphertext: ciphertext ?? this.ciphertext,
content: content ?? this.content, content: content ?? this.content,
); );
} }
@ -4956,6 +4984,9 @@ class SsssCacheCompanion extends UpdateCompanion<DbSSSSCache> {
if (keyId.present) { if (keyId.present) {
map['key_id'] = Variable<String>(keyId.value); map['key_id'] = Variable<String>(keyId.value);
} }
if (ciphertext.present) {
map['ciphertext'] = Variable<String>(ciphertext.value);
}
if (content.present) { if (content.present) {
map['content'] = Variable<String>(content.value); map['content'] = Variable<String>(content.value);
} }
@ -4991,6 +5022,14 @@ class SsssCache extends Table with TableInfo<SsssCache, DbSSSSCache> {
$customConstraints: 'NOT NULL'); $customConstraints: 'NOT NULL');
} }
final VerificationMeta _ciphertextMeta = const VerificationMeta('ciphertext');
GeneratedTextColumn _ciphertext;
GeneratedTextColumn get ciphertext => _ciphertext ??= _constructCiphertext();
GeneratedTextColumn _constructCiphertext() {
return GeneratedTextColumn('ciphertext', $tableName, false,
$customConstraints: 'NOT NULL');
}
final VerificationMeta _contentMeta = const VerificationMeta('content'); final VerificationMeta _contentMeta = const VerificationMeta('content');
GeneratedTextColumn _content; GeneratedTextColumn _content;
GeneratedTextColumn get content => _content ??= _constructContent(); GeneratedTextColumn get content => _content ??= _constructContent();
@ -5000,7 +5039,8 @@ class SsssCache extends Table with TableInfo<SsssCache, DbSSSSCache> {
} }
@override @override
List<GeneratedColumn> get $columns => [clientId, type, keyId, content]; List<GeneratedColumn> get $columns =>
[clientId, type, keyId, ciphertext, content];
@override @override
SsssCache get asDslTable => this; SsssCache get asDslTable => this;
@override @override
@ -5030,6 +5070,14 @@ class SsssCache extends Table with TableInfo<SsssCache, DbSSSSCache> {
} else if (isInserting) { } else if (isInserting) {
context.missing(_keyIdMeta); context.missing(_keyIdMeta);
} }
if (data.containsKey('ciphertext')) {
context.handle(
_ciphertextMeta,
ciphertext.isAcceptableOrUnknown(
data['ciphertext'], _ciphertextMeta));
} else if (isInserting) {
context.missing(_ciphertextMeta);
}
if (data.containsKey('content')) { if (data.containsKey('content')) {
context.handle(_contentMeta, context.handle(_contentMeta,
content.isAcceptableOrUnknown(data['content'], _contentMeta)); content.isAcceptableOrUnknown(data['content'], _contentMeta));
@ -5770,14 +5818,15 @@ abstract class _$Database extends GeneratedDatabase {
); );
} }
Future<int> storeSSSSCache( Future<int> storeSSSSCache(int client_id, String type, String key_id,
int client_id, String type, String key_id, String content) { String ciphertext, String content) {
return customInsert( return customInsert(
'INSERT OR REPLACE INTO ssss_cache (client_id, type, key_id, content) VALUES (:client_id, :type, :key_id, :content)', 'INSERT OR REPLACE INTO ssss_cache (client_id, type, key_id, ciphertext, content) VALUES (:client_id, :type, :key_id, :ciphertext, :content)',
variables: [ variables: [
Variable.withInt(client_id), Variable.withInt(client_id),
Variable.withString(type), Variable.withString(type),
Variable.withString(key_id), Variable.withString(key_id),
Variable.withString(ciphertext),
Variable.withString(content) Variable.withString(content)
], ],
updates: {ssssCache}, updates: {ssssCache},
@ -5789,6 +5838,7 @@ abstract class _$Database extends GeneratedDatabase {
clientId: row.readInt('client_id'), clientId: row.readInt('client_id'),
type: row.readString('type'), type: row.readString('type'),
keyId: row.readString('key_id'), keyId: row.readString('key_id'),
ciphertext: row.readString('ciphertext'),
content: row.readString('content'), content: row.readString('content'),
); );
} }

View file

@ -78,6 +78,7 @@ CREATE TABLE ssss_cache (
client_id INTEGER NOT NULL REFERENCES clients(client_id), client_id INTEGER NOT NULL REFERENCES clients(client_id),
type TEXT NOT NULL, type TEXT NOT NULL,
key_id TEXT NOT NULL, key_id TEXT NOT NULL,
ciphertext TEXT NOT NULL,
content TEXT NOT NULL, content TEXT NOT NULL,
UNIQUE(client_id, type) UNIQUE(client_id, type)
) AS DbSSSSCache; ) AS DbSSSSCache;
@ -195,7 +196,7 @@ setVerifiedUserCrossSigningKey: UPDATE user_cross_signing_keys SET verified = :v
setBlockedUserCrossSigningKey: UPDATE user_cross_signing_keys SET blocked = :blocked WHERE client_id = :client_id AND user_id = :user_id AND public_key = :public_key; setBlockedUserCrossSigningKey: UPDATE user_cross_signing_keys SET blocked = :blocked WHERE client_id = :client_id AND user_id = :user_id AND public_key = :public_key;
storeUserCrossSigningKey: INSERT OR REPLACE INTO user_cross_signing_keys (client_id, user_id, public_key, content, verified, blocked) VALUES (:client_id, :user_id, :public_key, :content, :verified, :blocked); storeUserCrossSigningKey: INSERT OR REPLACE INTO user_cross_signing_keys (client_id, user_id, public_key, content, verified, blocked) VALUES (:client_id, :user_id, :public_key, :content, :verified, :blocked);
removeUserCrossSigningKey: DELETE FROM user_cross_signing_keys WHERE client_id = :client_id AND user_id = :user_id AND public_key = :public_key; removeUserCrossSigningKey: DELETE FROM user_cross_signing_keys WHERE client_id = :client_id AND user_id = :user_id AND public_key = :public_key;
storeSSSSCache: INSERT OR REPLACE INTO ssss_cache (client_id, type, key_id, content) VALUES (:client_id, :type, :key_id, :content); storeSSSSCache: INSERT OR REPLACE INTO ssss_cache (client_id, type, key_id, ciphertext, content) VALUES (:client_id, :type, :key_id, :ciphertext, :content);
dbGetSSSSCache: SELECT * FROM ssss_cache WHERE client_id = :client_id AND type = :type; dbGetSSSSCache: SELECT * FROM ssss_cache WHERE client_id = :client_id AND type = :type;
insertClient: INSERT INTO clients (name, homeserver_url, token, user_id, device_id, device_name, prev_batch, olm_account) VALUES (:name, :homeserver_url, :token, :user_id, :device_id, :device_name, :prev_batch, :olm_account); insertClient: INSERT INTO clients (name, homeserver_url, token, user_id, device_id, device_name, prev_batch, olm_account) VALUES (:name, :homeserver_url, :token, :user_id, :device_id, :device_name, :prev_batch, :olm_account);
ensureRoomExists: INSERT OR IGNORE INTO rooms (client_id, room_id, membership) VALUES (:client_id, :room_id, :membership); ensureRoomExists: INSERT OR IGNORE INTO rooms (client_id, room_id, membership) VALUES (:client_id, :room_id, :membership);