From aefe029c0a216c34bd2d12bc33822c090f420048 Mon Sep 17 00:00:00 2001 From: Sorunome Date: Wed, 27 May 2020 18:50:09 +0200 Subject: [PATCH] add ability to sign yourself based on ssss --- lib/src/cross_signing.dart | 29 +++++++++++++++++++++++++++-- lib/src/ssss.dart | 6 +++++- lib/src/utils/device_keys_list.dart | 8 ++++---- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/lib/src/cross_signing.dart b/lib/src/cross_signing.dart index ab9f018..67803c3 100644 --- a/lib/src/cross_signing.dart +++ b/lib/src/cross_signing.dart @@ -27,6 +27,31 @@ class CrossSigning { (await client.ssss.getCached(USER_SIGNING_KEY)) != null; } + Future selfSign({String password, String recoveryKey}) async { + final handle = client.ssss.open(MASTER_KEY); + await handle.unlock(password: password, recoveryKey: recoveryKey); + await handle.maybeCacheAll(); + final masterPrivateKey = base64.decode(await handle.getStored(MASTER_KEY)); + final keyObj = olm.PkSigning(); + String masterPubkey; + try { + masterPubkey = keyObj.init_with_seed(masterPrivateKey); + } finally { + keyObj.free(); + } + if (masterPubkey == null || !client.userDeviceKeys.containsKey(client.userID) || !client.userDeviceKeys[client.userID].deviceKeys.containsKey(client.deviceID)) { + throw 'Master or user keys not found'; + } + final masterKey = client.userDeviceKeys[client.userID].masterKey; + if (masterKey == null || masterKey.ed25519Key != masterPubkey) { + throw 'Master pubkey key doesn\'t match'; + } + // master key is valid, set it to verified + masterKey.setVerified(true, false); + // and now sign bout our own key and our master key + await sign([masterKey, client.userDeviceKeys[client.userID].deviceKeys[client.deviceID]]); + } + bool signable(List keys) { for (final key in keys) { if (key is CrossSigningKey && key.usage.contains('master')) { @@ -86,7 +111,7 @@ class CrossSigning { signature); } // we don't care about signing other cross-signing keys - } else if (key.identifier != client.deviceID) { + } else { // okay, we'll sign a device key with our self signing key selfSigningKey ??= base64 .decode(await client.ssss.getCached(SELF_SIGNING_KEY) ?? ''); @@ -119,8 +144,8 @@ class CrossSigning { String _sign(String canonicalJson, Uint8List key) { final keyObj = olm.PkSigning(); - keyObj.init_with_seed(key); try { + keyObj.init_with_seed(key); return keyObj.sign(canonicalJson); } finally { keyObj.free(); diff --git a/lib/src/ssss.dart b/lib/src/ssss.dart index b350da4..70cf540 100644 --- a/lib/src/ssss.dart +++ b/lib/src/ssss.dart @@ -213,7 +213,11 @@ class SSSS { for (final type in CACHE_TYPES) { final secret = await getCached(type); if (secret == null) { - await getStored(type, keyId, key); + try { + await getStored(type, keyId, key); + } catch (_) { + // the entry wasn't stored, just ignore it + } } } } diff --git a/lib/src/utils/device_keys_list.dart b/lib/src/utils/device_keys_list.dart index d96c2db..9559218 100644 --- a/lib/src/utils/device_keys_list.dart +++ b/lib/src/utils/device_keys_list.dart @@ -168,7 +168,7 @@ abstract class SignedKey { return valid; } - bool hasValidSignatureChain({bool verfiedOnly = true, Set visited}) { + bool hasValidSignatureChain({bool verifiedOnly = true, Set visited}) { visited ??= {}; final setKey = '${userId};${identifier}'; if (visited.contains(setKey)) { @@ -228,15 +228,15 @@ abstract class SignedKey { } if ((verifiedOnly && key.directVerified) || - (key is SignedKey && - key.usage.includes('master') && + (key is CrossSigningKey && + key.usage.contains('master') && key.directVerified && key.userId == client.userID)) { return true; // we verified this key and it is valid...all checks out! } // or else we just recurse into that key and chack if it works out final haveChain = key.hasValidSignatureChain( - verfiedOnly: verfiedOnly, visited: visited); + verifiedOnly: verifiedOnly, visited: visited); if (haveChain) { return true; }