sign method

Future<void> sign(
  1. List<SignableKey> keys
)

Implementation

Future<void> sign(List<SignableKey> keys) async {
  final signedKeys = <MatrixSignableKey>[];
  Uint8List? selfSigningKey;
  Uint8List? userSigningKey;
  final userKeys = client.userDeviceKeys[client.userID];
  if (userKeys == null) {
    throw Exception('[sign] keys are not in cache but sign was called');
  }

  void addSignature(
    SignableKey key,
    SignableKey signedWith,
    String signature,
  ) {
    final signedKey = key.cloneForSigning();
    ((signedKey.signatures ??=
            <String, Map<String, String>>{})[signedWith.userId] ??=
        <String, String>{})['ed25519:${signedWith.identifier}'] = signature;
    signedKeys.add(signedKey);
  }

  for (final key in keys) {
    if (key.userId == client.userID) {
      // we are singing a key of ourself
      if (key is CrossSigningKey) {
        if (key.usage.contains('master')) {
          // okay, we'll sign our own master key
          final signature =
              encryption.olmManager.signString(key.signingContent);
          addSignature(key, userKeys.deviceKeys[client.deviceID]!, signature);
        }
        // we don't care about signing other cross-signing keys
      } else {
        // okay, we'll sign a device key with our self signing key
        selfSigningKey ??= base64decodeUnpadded(
          await encryption.ssss
                  .getCached(EventTypes.CrossSigningSelfSigning) ??
              '',
        );
        if (selfSigningKey.isNotEmpty) {
          final signature = _sign(key.signingContent, selfSigningKey);
          addSignature(key, userKeys.selfSigningKey!, signature);
        }
      }
    } else if (key is CrossSigningKey && key.usage.contains('master')) {
      // we are signing someone elses master key
      userSigningKey ??= base64decodeUnpadded(
        await encryption.ssss.getCached(EventTypes.CrossSigningUserSigning) ??
            '',
      );
      if (userSigningKey.isNotEmpty) {
        final signature = _sign(key.signingContent, userSigningKey);
        addSignature(key, userKeys.userSigningKey!, signature);
      }
    }
  }
  if (signedKeys.isNotEmpty) {
    // post our new keys!
    final payload = <String, Map<String, Map<String, Object?>>>{};
    for (final key in signedKeys) {
      final signatures = key.signatures;
      final identifier = key.identifier;
      if (identifier == null || signatures == null || signatures.isEmpty) {
        continue;
      }
      if (!payload.containsKey(key.userId)) {
        payload[key.userId] = <String, Map<String, Object?>>{};
      }
      if (payload[key.userId]?[key.identifier]?['signatures'] != null) {
        // we need to merge signature objects
        payload[key.userId]![key.identifier]!
            .tryGetMap<String, Map<String, String>>('signatures')!
            .addAll(signatures);
      } else {
        // we can just add signatures
        payload[key.userId]![identifier] = key.toJson();
      }
    }

    await client.uploadCrossSigningSignatures(payload);
  }
}