logo
pub fn hash_and_sign_event<K>(
    entity_id: &str,
    key_pair: &K,
    object: &mut CanonicalJsonObject,
    version: &RoomVersionId
) -> Result<(), Error> where
    K: KeyPair
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 = "\
    MFMCAQEwBQYDK2VwBCIEINjozvdfbsGEt6DD+7Uf4PiJ/YvTNXV2mIPc/\
    tA0T+6toSMDIQDdM+tpNzNWQM9NFpfgr4B9S7LHszOrVRp9NfKmeXS3aQ\
";

let document = base64::decode_config(&PKCS8, base64::STANDARD_NO_PAD).unwrap();

// Create an Ed25519 key pair.
let key_pair = Ed25519KeyPair::from_der(
    &document,
    "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.