ruma::signatures

Function hash_and_sign_event

Source
pub fn hash_and_sign_event<K>(
    entity_id: &str,
    key_pair: &K,
    object: &mut BTreeMap<String, CanonicalJsonValue>,
    version: &RoomVersionId,
) -> Result<(), Error>
where K: KeyPair,
Available on crate feature signatures only.
Expand description

Hashes and signs an event and adds the hash and signature to objects under the keys hashes and signatures, respectively.

If hashes and/or signatures are already present, the new data will be appended to the existing data.

§Parameters

  • entity_id: The identifier of the entity creating the signature. Generally this means a homeserver, e.g. “example.com”.
  • key_pair: A cryptographic key pair used to sign the event.
  • object: A JSON object to be hashed and signed according to the Matrix specification.

§Errors

Returns an error if:

  • object contains a field called content that is not a JSON object.
  • object contains a field called hashes that is not a JSON object.
  • object contains a field called signatures that is not a JSON object.
  • object is missing the type field or the field is not a JSON string.

§Examples

const PKCS8: &str = "\
    MFECAQEwBQYDK2VwBCIEINjozvdfbsGEt6DD+7Uf4PiJ/YvTNXV2mIPc/\
    tA0T+6tgSEA3TPraTczVkDPTRaX4K+AfUuyx7Mzq1UafTXypnl0t2k\
";

let document: Base64 = Base64::parse(PKCS8).unwrap();

// Create an Ed25519 key pair.
let key_pair = Ed25519KeyPair::from_der(
    document.as_bytes(),
    "1".into(), // The "version" of the key.
)
.unwrap();

// Deserialize an event from JSON.
let mut object = serde_json::from_str(
    r#"{
        "room_id": "!x:domain",
        "sender": "@a:domain",
        "origin": "domain",
        "origin_server_ts": 1000000,
        "signatures": {},
        "hashes": {},
        "type": "X",
        "content": {},
        "prev_events": [],
        "auth_events": [],
        "depth": 3,
        "unsigned": {
            "age_ts": 1000000
        }
    }"#,
)
.unwrap();

// Hash and sign the JSON with the key pair.
assert!(hash_and_sign_event("domain", &key_pair, &mut object, &RoomVersionId::V1).is_ok());

This will modify the JSON from the structure shown to a structure like this:

{
    "auth_events": [],
    "content": {},
    "depth": 3,
    "hashes": {
        "sha256": "5jM4wQpv6lnBo7CLIghJuHdW+s2CMBJPUOGOC89ncos"
    },
    "origin": "domain",
    "origin_server_ts": 1000000,
    "prev_events": [],
    "room_id": "!x:domain",
    "sender": "@a:domain",
    "signatures": {
        "domain": {
            "ed25519:1": "KxwGjPSDEtvnFgU00fwFz+l6d2pJM6XBIaMEn81SXPTRl16AqLAYqfIReFGZlHi5KLjAWbOoMszkwsQma+lYAg"
        }
    },
    "type": "X",
    "unsigned": {
        "age_ts": 1000000
    }
}

Notice the addition of hashes and signatures.