diff --git a/LibMatrix/Responses/Federation/ServerKeysResponse.cs b/LibMatrix/Responses/Federation/ServerKeysResponse.cs
new file mode 100644
index 0000000..cb62e34
--- /dev/null
+++ b/LibMatrix/Responses/Federation/ServerKeysResponse.cs
@@ -0,0 +1,55 @@
+using System.Diagnostics;
+using System.Text.Json.Serialization;
+using LibMatrix.Abstractions;
+
+namespace LibMatrix.Responses.Federation;
+
+public class ServerKeysResponse {
+ [JsonPropertyName("server_name")]
+ public string ServerName { get; set; }
+
+ [JsonPropertyName("valid_until_ts")]
+ public ulong ValidUntilTs { get; set; }
+
+ [JsonIgnore]
+ public DateTime ValidUntil {
+ get => DateTimeOffset.FromUnixTimeMilliseconds((long)ValidUntilTs).DateTime;
+ set => ValidUntilTs = (ulong)new DateTimeOffset(value).ToUnixTimeMilliseconds();
+ }
+
+ [JsonPropertyName("verify_keys")]
+ public Dictionary<string, CurrentVerifyKey> VerifyKeys { get; set; } = new();
+
+ [JsonIgnore]
+ public Dictionary<VersionedKeyId, CurrentVerifyKey> VerifyKeysById {
+ get => VerifyKeys.ToDictionary(key => (VersionedKeyId)key.Key, key => key.Value);
+ set => VerifyKeys = value.ToDictionary(key => (string)key.Key, key => key.Value);
+ }
+
+ [JsonPropertyName("old_verify_keys")]
+ public Dictionary<string, ExpiredVerifyKey> OldVerifyKeys { get; set; } = new();
+
+ [JsonIgnore]
+ public Dictionary<VersionedKeyId, ExpiredVerifyKey> OldVerifyKeysById {
+ get => OldVerifyKeys.ToDictionary(key => (VersionedKeyId)key.Key, key => key.Value);
+ set => OldVerifyKeys = value.ToDictionary(key => (string)key.Key, key => key.Value);
+ }
+
+ [DebuggerDisplay("{Key}")]
+ public class CurrentVerifyKey {
+ [JsonPropertyName("key")]
+ public string Key { get; set; }
+ }
+
+ [DebuggerDisplay("{Key} (expired {Expired})")]
+ public class ExpiredVerifyKey : CurrentVerifyKey {
+ [JsonPropertyName("expired_ts")]
+ public ulong ExpiredTs { get; set; }
+
+ [JsonIgnore]
+ public DateTime Expired {
+ get => DateTimeOffset.FromUnixTimeMilliseconds((long)ExpiredTs).DateTime;
+ set => ExpiredTs = (ulong)new DateTimeOffset(value).ToUnixTimeMilliseconds();
+ }
+ }
+}
diff --git a/LibMatrix/Responses/Federation/ServerVersionResponse.cs b/LibMatrix/Responses/Federation/ServerVersionResponse.cs
new file mode 100644
index 0000000..b09bdd0
--- /dev/null
+++ b/LibMatrix/Responses/Federation/ServerVersionResponse.cs
@@ -0,0 +1,16 @@
+using System.Text.Json.Serialization;
+
+namespace LibMatrix.Responses.Federation;
+
+public class ServerVersionResponse {
+ [JsonPropertyName("server")]
+ public required ServerInfo Server { get; set; }
+
+ public class ServerInfo {
+ [JsonPropertyName("name")]
+ public string Name { get; set; }
+
+ [JsonPropertyName("version")]
+ public string Version { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/LibMatrix.Federation/Utilities/JsonSigning.cs b/LibMatrix/Responses/Federation/SignedObject.cs
index c727cde..3f6ffd6 100644
--- a/LibMatrix.Federation/Utilities/JsonSigning.cs
+++ b/LibMatrix/Responses/Federation/SignedObject.cs
@@ -1,17 +1,11 @@
-using System.Globalization;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using ArcaneLibs.Extensions;
-using LibMatrix.Extensions;
-using LibMatrix.FederationTest.Utilities;
+using LibMatrix.Abstractions;
using LibMatrix.Homeservers;
-using Org.BouncyCastle.Crypto.Parameters;
-using Org.BouncyCastle.Math.EC.Rfc8032;
-namespace LibMatrix.Federation.Utilities;
-
-public static class JsonSigning { }
+namespace LibMatrix.Responses.Federation;
[JsonConverter(typeof(SignedObjectConverterFactory))]
public class SignedObject<T> {
@@ -19,8 +13,8 @@ public class SignedObject<T> {
public Dictionary<string, Dictionary<string, string>> Signatures { get; set; } = new();
[JsonIgnore]
- public Dictionary<string, Dictionary<ServerKeysResponse.VersionedKeyId, string>> VerifyKeysById {
- get => Signatures.ToDictionary(server => server.Key, server => server.Value.ToDictionary(key => (ServerKeysResponse.VersionedKeyId)key.Key, key => key.Value));
+ public Dictionary<string, Dictionary<VersionedKeyId, string>> SignaturesById {
+ get => Signatures.ToDictionary(server => server.Key, server => server.Value.ToDictionary(key => (VersionedKeyId)key.Key, key => key.Value));
set => Signatures = value.ToDictionary(server => server.Key, server => server.Value.ToDictionary(key => (string)key.Key, key => key.Value));
}
@@ -34,7 +28,6 @@ public class SignedObject<T> {
}
}
-// Content needs to be merged at toplevel
public class SignedObjectConverter<T> : JsonConverter<SignedObject<T>> {
public override SignedObject<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
var jsonObject = JsonSerializer.Deserialize<JsonObject>(ref reader, options);
@@ -72,37 +65,4 @@ internal class SignedObjectConverterFactory : JsonConverterFactory {
var converter = (JsonConverter)Activator.CreateInstance(typeof(SignedObjectConverter<>).MakeGenericType(wrappedType))!;
return converter;
}
-}
-
-public static class ObjectExtensions {
- public static SignedObject<T> Sign<T>(this SignedObject<T> content, string serverName, string keyName, Ed25519PrivateKeyParameters key) {
- var signResult = Sign(content.Content, serverName, keyName, key);
- var signedObject = new SignedObject<T> {
- Signatures = content.Signatures,
- Content = signResult.Content
- };
-
- if (!signedObject.Signatures.ContainsKey(serverName))
- signedObject.Signatures[serverName] = new Dictionary<string, string>();
-
- signedObject.Signatures[serverName][keyName] = signResult.Signatures[serverName][keyName];
- return signedObject;
- }
-
- public static SignedObject<T> Sign<T>(this T content, string serverName, string keyName, Ed25519PrivateKeyParameters key) {
- SignedObject<T> signedObject = new() {
- Signatures = [],
- Content = JsonSerializer.Deserialize<JsonObject>(JsonSerializer.Serialize(content)) ?? new JsonObject(),
- };
-
- var contentBytes = CanonicalJsonSerializer.SerializeToUtf8Bytes(signedObject.Content);
- var signature = new byte[Ed25519.SignatureSize];
- key.Sign(Ed25519.Algorithm.Ed25519, null, contentBytes, 0, contentBytes.Length, signature, 0);
-
- if (!signedObject.Signatures.ContainsKey(serverName))
- signedObject.Signatures[serverName] = new Dictionary<string, string>();
-
- signedObject.Signatures[serverName][keyName] = UnpaddedBase64.Encode(signature);
- return signedObject;
- }
}
\ No newline at end of file
|