Line data Source code
1 : /*
2 : * Famedly Matrix SDK
3 : * Copyright (C) 2019, 2020, 2021 Famedly GmbH
4 : *
5 : * This program is free software: you can redistribute it and/or modify
6 : * it under the terms of the GNU Affero General Public License as
7 : * published by the Free Software Foundation, either version 3 of the
8 : * License, or (at your option) any later version.
9 : *
10 : * This program is distributed in the hope that it will be useful,
11 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : * GNU Affero General Public License for more details.
14 : *
15 : * You should have received a copy of the GNU Affero General Public License
16 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 : */
18 :
19 : import 'package:olm/olm.dart' as olm;
20 :
21 : import 'package:matrix/encryption/utils/stored_inbound_group_session.dart';
22 : import 'package:matrix/matrix.dart';
23 :
24 : class SessionKey {
25 : /// The raw json content of the key
26 : Map<String, dynamic> content = <String, dynamic>{};
27 :
28 : /// Map of stringified-index to event id, so that we can detect replay attacks
29 : Map<String, String> indexes;
30 :
31 : /// Map of userId to map of deviceId to index, that we know that device receivied, e.g. sending it ourself.
32 : /// Used for automatically answering key requests
33 : Map<String, Map<String, int>> allowedAtIndex;
34 :
35 : /// Underlying olm [InboundGroupSession] object
36 : olm.InboundGroupSession? inboundGroupSession;
37 :
38 : /// Key for libolm pickle / unpickle
39 : final String key;
40 :
41 : /// Forwarding keychain
42 6 : List<String> get forwardingCurve25519KeyChain =>
43 12 : (content['forwarding_curve25519_key_chain'] != null
44 6 : ? List<String>.from(content['forwarding_curve25519_key_chain'])
45 : : null) ??
46 4 : <String>[];
47 :
48 : /// Claimed keys of the original sender
49 : late Map<String, String> senderClaimedKeys;
50 :
51 : /// Sender curve25519 key
52 : String senderKey;
53 :
54 : /// Is this session valid?
55 12 : bool get isValid => inboundGroupSession != null;
56 :
57 : /// roomId for this session
58 : String roomId;
59 :
60 : /// Id of this session
61 : String sessionId;
62 :
63 23 : SessionKey(
64 : {required this.content,
65 : required this.inboundGroupSession,
66 : required this.key,
67 : Map<String, String>? indexes,
68 : Map<String, Map<String, int>>? allowedAtIndex,
69 : required this.roomId,
70 : required this.sessionId,
71 : required this.senderKey,
72 : required this.senderClaimedKeys})
73 0 : : indexes = indexes ?? <String, String>{},
74 0 : allowedAtIndex = allowedAtIndex ?? <String, Map<String, int>>{};
75 :
76 6 : SessionKey.fromDb(StoredInboundGroupSession dbEntry, this.key)
77 12 : : content = Event.getMapFromPayload(dbEntry.content),
78 12 : indexes = Event.getMapFromPayload(dbEntry.indexes)
79 8 : .catchMap((k, v) => MapEntry<String, String>(k, v)),
80 12 : allowedAtIndex = Event.getMapFromPayload(dbEntry.allowedAtIndex)
81 9 : .catchMap((k, v) => MapEntry(k, Map<String, int>.from(v))),
82 6 : roomId = dbEntry.roomId,
83 6 : sessionId = dbEntry.sessionId,
84 6 : senderKey = dbEntry.senderKey,
85 6 : inboundGroupSession = olm.InboundGroupSession() {
86 : final parsedSenderClaimedKeys =
87 12 : Event.getMapFromPayload(dbEntry.senderClaimedKeys)
88 12 : .catchMap((k, v) => MapEntry<String, String>(k, v));
89 : // we need to try...catch as the map used to be <String, int> and that will throw an error.
90 12 : senderClaimedKeys = (parsedSenderClaimedKeys.isNotEmpty)
91 : ? parsedSenderClaimedKeys
92 3 : : (content
93 3 : .tryGetMap<String, dynamic>('sender_claimed_keys')
94 0 : ?.catchMap((k, v) => MapEntry<String, String>(k, v)) ??
95 9 : (content['sender_claimed_ed25519_key'] is String
96 0 : ? <String, String>{
97 0 : 'ed25519': content['sender_claimed_ed25519_key']
98 : }
99 3 : : <String, String>{}));
100 :
101 : try {
102 24 : inboundGroupSession!.unpickle(key, dbEntry.pickle);
103 : } catch (e, s) {
104 0 : dispose();
105 0 : Logs().e('[LibOlm] Unable to unpickle inboundGroupSession', e, s);
106 : }
107 : }
108 :
109 20 : void dispose() {
110 40 : inboundGroupSession?.free();
111 20 : inboundGroupSession = null;
112 : }
113 : }
|