Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

federation_client: handle inline signing_keys in hs.yaml #9647

Merged
merged 1 commit into from
Mar 18, 2021
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions changelog.d/9647.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
In the `federation_client` commandline client, handle inline `signing_key`s in `homeserver.yaml`.
71 changes: 17 additions & 54 deletions scripts-dev/federation_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
from typing import Any, Optional
from urllib import parse as urlparse

import nacl.signing
import requests
import signedjson.key
import signedjson.types
import srvlookup
import yaml
Expand All @@ -44,18 +44,6 @@ def encode_base64(input_bytes):
return output_string


def decode_base64(input_string):
"""Decode a base64 string to bytes inferring padding from the length of the
string."""

input_bytes = input_string.encode("ascii")
input_len = len(input_bytes)
padding = b"=" * (3 - ((input_len + 3) % 4))
output_len = 3 * ((input_len + 2) // 4) + (input_len + 2) % 4 - 2
output_bytes = base64.b64decode(input_bytes + padding)
return output_bytes[:output_len]


def encode_canonical_json(value):
return json.dumps(
value,
Expand Down Expand Up @@ -88,42 +76,6 @@ def sign_json(
return json_object


NACL_ED25519 = "ed25519"


def decode_signing_key_base64(algorithm, version, key_base64):
"""Decode a base64 encoded signing key
Args:
algorithm (str): The algorithm the key is for (currently "ed25519").
version (str): Identifies this key out of the keys for this entity.
key_base64 (str): Base64 encoded bytes of the key.
Returns:
A SigningKey object.
"""
if algorithm == NACL_ED25519:
key_bytes = decode_base64(key_base64)
key = nacl.signing.SigningKey(key_bytes)
key.version = version
key.alg = NACL_ED25519
return key
else:
raise ValueError("Unsupported algorithm %s" % (algorithm,))


def read_signing_keys(stream):
"""Reads a list of keys from a stream
Args:
stream : A stream to iterate for keys.
Returns:
list of SigningKey objects.
"""
keys = []
for line in stream:
algorithm, version, key_base64 = line.split()
keys.append(decode_signing_key_base64(algorithm, version, key_base64))
return keys


def request(
method: Optional[str],
origin_name: str,
Expand Down Expand Up @@ -228,11 +180,16 @@ def main():

args = parser.parse_args()

if not args.server_name or not args.signing_key_path:
args.signing_key = None
if args.signing_key_path:
with open(args.signing_key_path) as f:
args.signing_key = f.readline()

if not args.server_name or not args.signing_key:
read_args_from_config(args)

with open(args.signing_key_path) as f:
key = read_signing_keys(f)[0]
algorithm, version, key_base64 = args.signing_key.split()
key = signedjson.key.decode_signing_key_base64(algorithm, version, key_base64)

result = request(
args.method,
Expand All @@ -255,10 +212,16 @@ def main():
def read_args_from_config(args):
with open(args.config, "r") as fh:
config = yaml.safe_load(fh)

if not args.server_name:
args.server_name = config["server_name"]
if not args.signing_key_path:
args.signing_key_path = config["signing_key_path"]

if not args.signing_key:
if "signing_key" in config:
args.signing_key = config["signing_key"]
else:
with open(config["signing_key_path"]) as f:
args.signing_key = f.readline()


class MatrixConnectionAdapter(HTTPAdapter):
Expand Down