Crate ruma_signatures

source ·
Expand description

Crate ruma_signatures implements digital signatures according to the Matrix specification.

Digital signatures are used by Matrix homeservers to verify the authenticity of events in the Matrix system, as well as requests between homeservers for federation. Each homeserver has one or more signing key pairs which it uses to sign all events and federation requests. Matrix clients and other Matrix homeservers can ask the homeserver for its public keys and use those keys to verify the signed data.

Each signing key pair has an identifier, which consists of the name of the digital signature algorithm it uses and a “version” string, separated by a colon. The version is an arbitrary identifier used to distinguish key pairs using the same algorithm from the same homeserver.

Signing JSON

A homeserver signs JSON with a key pair:

// Create an Ed25519 key pair.
let key_pair = ruma_signatures::Ed25519KeyPair::new(
    &public_key, // &[u8]
    &private_key, // &[u8]
    "1".to_string(), // The "version" of the key.
).expect("the provided keys should be suitable for Ed25519");
let value = serde_json::from_str("{}").expect("an empty JSON object should deserialize");
ruma_signatures::sign_json(&key_pair, &value).expect("value is a a JSON object"); // `Signature`

Signing Matrix events

Signing an event uses a more involved process than signing arbitrary JSON. Event signing is not yet implemented by ruma_signatures.

Verifying signatures

A client application or another homeserver can verify a signature on arbitrary JSON:

let signature = ruma_signatures::Signature::new("ed25519:1", &signature_bytes).expect(
    "key identifier should be valid"
);
let value = serde_json::from_str("{}").expect("an empty JSON object should deserialize");
let verifier = ruma_signatures::Ed25519Verifier::new();
assert!(ruma_signatures::verify_json(&verifier, &public_key, &signature, &value).is_ok());

Verifying signatures of Matrix events is not yet implemented by ruma_signatures.

Signature sets

Signatures that a homeserver has added to an event are stored in a JSON object under the “signatures” key in the event’s JSON representation:

{
  "content": {},
  "event_type": "not.a.real.event",
  "signatures": {
    "example.com": {
      "ed25519:1": "K8280/U9SSy9IVtjBuVeLr+HpOB4BQFWbg+UZaADMtTdGYI7Geitb76LTrr5QV/7Xg4ahLwYGYZzuHGZKM5ZAQ"
    }
  }
}

The keys inside the “signatures” object are the hostnames of homeservers that have added signatures. Within each of those objects are a set of signatures, keyed by the signing key pair’s identifier.

This inner object can be created by serializing a SignatureSet:

let signature = ruma_signatures::Signature::new("ed25519:1", &signature_bytes).expect(
    "key identifier should be valid"
);
let mut signature_set = ruma_signatures::SignatureSet::new();
signature_set.insert(signature);
serde_json::to_string(&signature_set).expect("signature_set should serialize");

This code produces the object under the “example.com” key in the preceeding JSON. Similarly, a SignatureSet can be produced by deserializing JSON that follows this form.

The outer object (the map of server names to signature sets) is a Signatures value and created like this:

let signature = ruma_signatures::Signature::new("ed25519:1", &signature_bytes).expect(
    "key identifier should be valid"
);
let mut signature_set = ruma_signatures::SignatureSet::new();
signature_set.insert(signature);
let mut signatures = ruma_signatures::Signatures::new();
signatures.insert("example.com", signature_set).expect("example.com is a valid server name");
serde_json::to_string(&signatures).expect("signatures should serialize");

Just like the SignatureSet itself, the Signatures value can also be deserialized from JSON.

Structs

An Ed25519 key pair.
A verifier for Ed25519 digital signatures.
An error produced when ruma_signatures operations fail.
A digital signature.
A set of digital signatures created by a single homeserver.
A map of server names to sets of digital signatures created by that server.

Enums

The algorithm used for signing data.
The host name of an URL.

Traits

A cryptographic key pair for digitally signing data.
A digital signature verifier.

Functions

Signs an arbitrary JSON object.
Converts a JSON object into the “canonical” string form, suitable for signing.
Use a public key to verify a signature of a JSON object.