Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 79 additions & 45 deletions tests/50federation/01keys.pl
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
# server's own key
$client->do_request_json(
method => "GET",
# TODO: strictly, a valid key ID is required here, but it's hard to
# know upfront what key IDs exist
uri => "https://$first_home_server/_matrix/key/v2/server/*",
uri => "https://$first_home_server/_matrix/key/v2/server",
)->then( sub {
my ( $body ) = @_;
log_if_fail "Key response", $body;
Expand Down Expand Up @@ -77,57 +75,93 @@
});
};

test "Federation key API can act as a notary server",
requires => [ $main::HOMESERVER_INFO[0], $main::INBOUND_SERVER, $main::OUTBOUND_CLIENT ],

check => sub {
my ( $info, $inbound_server, $client ) = @_;
my $first_home_server = $info->server_name;

my $key_id = $inbound_server->key_id;
my $local_server_name = $inbound_server->server_name;

$client->do_request_json(
method => "GET",
hostname => $first_home_server,
full_uri => "/_matrix/key/v2/query/$local_server_name/$key_id",
)->then( sub {
my ( $body ) = @_;
log_if_fail "Response", $body;
sub key_query_via_get {
my ( $http_client, $notary_server, $origin_server, $key_id ) = @_;

return $http_client->do_request_json(
method => "GET",
hostname => $notary_server->server_name,
full_uri => "/_matrix/key/v2/query/$origin_server/$key_id",
);
}

sub key_query_via_post {
my ( $http_client, $notary_server, $origin_server, $key_id, %params ) = @_;

my $min_valid_until_ts = $params{min_valid_until_ts} // 0;

return $http_client->do_request_json(
method => "POST",
hostname => $notary_server->server_name,
full_uri => "/_matrix/key/v2/query",
content => {
server_keys => {
$origin_server => {
$key_id => {
minimum_valid_until_ts => $min_valid_until_ts,
},
},
},
},
);
}

my %FETCHERS=(
GET => \&key_query_via_get,
POST => \&key_query_via_post,
);

foreach my $method (keys %FETCHERS) {
test "Federation key API can act as a notary server via a $method request",
requires => [ $main::HOMESERVER_INFO[0], $main::INBOUND_SERVER, $main::OUTBOUND_CLIENT ],

check => sub {
my ( $info, $inbound_server, $client ) = @_;
my $first_home_server = $info->server_name;

my $key_id = $inbound_server->key_id;
my $local_server_name = $inbound_server->server_name;

$FETCHERS{$method}(
$client, $info, $local_server_name, $key_id
)->then( sub {
my ( $body ) = @_;
log_if_fail "Response", $body;

assert_json_keys( $body, qw( server_keys ));
assert_json_list( $body->{server_keys} );
assert_json_keys( $body, qw( server_keys ));
assert_json_list( $body->{server_keys} );

my $key = first {
$_->{server_name} eq $local_server_name and exists $_->{verify_keys}{$key_id}
} @{ $body->{server_keys} };
my $key = first {
$_->{server_name} eq $local_server_name and exists $_->{verify_keys}{$key_id}
} @{ $body->{server_keys} };

$key or
die "Expected to find a response about $key_id from $local_server_name";
$key or
die "Expected to find a response about $key_id from $local_server_name";

my $first_hs_sig = $key->{signatures}{$first_home_server} or
die "Expected the key to be signed by the first homeserver";
my $first_hs_sig = $key->{signatures}{$first_home_server} or
die "Expected the key to be signed by the first homeserver";

keys %$first_hs_sig == 1 or
die "Expected the first homeserver to apply one signature";
keys %$first_hs_sig == 1 or
die "Expected the first homeserver to apply one signature";

my ( $key_id, $signature_base64 ) = %$first_hs_sig;
my ( $key_id, $signature_base64 ) = %$first_hs_sig;

assert_base64_unpadded( $signature_base64 );
my $signature = decode_base64 $signature_base64;
assert_base64_unpadded( $signature_base64 );
my $signature = decode_base64 $signature_base64;

my $signed_bytes = encode_json_for_signing( $key );
my $signed_bytes = encode_json_for_signing( $key );

$client->get_key(
server_name => $first_home_server,
key_id => $key_id,
)->then( sub {
my ( $server_key ) = @_;
$client->get_key(
server_name => $first_home_server,
key_id => $key_id,
)->then( sub {
my ( $server_key ) = @_;

$crypto_sign->verify( $signature, $signed_bytes, $server_key ) or
die "Signature verification failed";
$crypto_sign->verify( $signature, $signed_bytes, $server_key ) or
die "Signature verification failed";

Future->done(1);
Future->done(1);
});
});
});
};
};
}