uploadCrossSigningKeys method

Future<void> uploadCrossSigningKeys({
  1. AuthenticationData? auth,
  2. MatrixCrossSigningKey? masterKey,
  3. MatrixCrossSigningKey? selfSigningKey,
  4. MatrixCrossSigningKey? userSigningKey,
})

Publishes cross-signing keys for the user.

This API endpoint uses the User-Interactive Authentication API.

User-Interactive Authentication MUST be performed, except in these cases:

  • there is no existing cross-signing master key uploaded to the homeserver, OR
  • there is an existing cross-signing master key and it exactly matches the cross-signing master key provided in the request body. If there are any additional keys provided in the request (self-signing key, user-signing key) they MUST also match the existing keys stored on the server. In other words, the request contains no new keys.

This allows clients to freely upload one set of keys, but not modify/overwrite keys if they already exist. Allowing clients to upload the same set of keys more than once makes this endpoint idempotent in the case where the response is lost over the network, which would otherwise cause a UIA challenge upon retry.

auth Additional authentication information for the user-interactive authentication API.

masterKey Optional. The user's master key.

selfSigningKey Optional. The user's self-signing key. Must be signed by the accompanying master key, or by the user's most recently uploaded master key if no master key is included in the request.

userSigningKey Optional. The user's user-signing key. Must be signed by the accompanying master key, or by the user's most recently uploaded master key if no master key is included in the request.

Implementation

Future<void> uploadCrossSigningKeys({
  AuthenticationData? auth,
  MatrixCrossSigningKey? masterKey,
  MatrixCrossSigningKey? selfSigningKey,
  MatrixCrossSigningKey? userSigningKey,
}) async {
  final requestUri =
      Uri(path: '_matrix/client/v3/keys/device_signing/upload');
  final request = Request('POST', baseUri!.resolveUri(requestUri));
  request.headers['authorization'] = 'Bearer ${bearerToken!}';
  request.headers['content-type'] = 'application/json';
  request.bodyBytes = utf8.encode(
    jsonEncode({
      if (auth != null) 'auth': auth.toJson(),
      if (masterKey != null) 'master_key': masterKey.toJson(),
      if (selfSigningKey != null) 'self_signing_key': selfSigningKey.toJson(),
      if (userSigningKey != null) 'user_signing_key': userSigningKey.toJson(),
    }),
  );
  final response = await httpClient.send(request);
  final responseBody = await response.stream.toBytes();
  if (response.statusCode != 200) unexpectedResponse(response, responseBody);
  final responseString = utf8.decode(responseBody);
  final json = jsonDecode(responseString);
  return ignore(json);
}