Git Product home page Git Product logo

Comments (17)

iinuwa avatar iinuwa commented on May 25, 2024 2

Posting another table of definitions to keep this straight in my head:

Spec Ruma Definition Example
key_id/version key name (in doc comments) used to distinguish between different signing keys used by the same entity ed25519:1
signed_curve25519:AAAAHg
Key ID KeyId [any] algorithm + key name signed_curve25519:AAAAHg
ed25519:1
signing key identifier SigningKeyId<K>
or
KeyId<SigningKeyAlgorithm, K>
signing algorithm + key name.

Generally used when talking about homeserver keys for signing events, but can also be used for signing one-time device keys
ed25519:0
ed25519:JLAFKJWSCS
device key identifier DeviceKeyId device key algorithm + device identifier.

Used for one-time keys and identity keys
signed_curve25519:AAAAHg
ed25519:JLAFKJWSCS
curve25519:JLAFKJWSCS
device identity key DeviceKeyId public keys used for identifying devices curve25519:JLAFKJWSCS
ed25519:JLAFKJWSCS
device one-time keys identifiers BTreeMap<DeviceKeyId, OneTimeKey> used for setting up encrypted sessions with another device { "curve25519:AAAAAQ": "<some key string>", "signed_curve25519:AAAAHg": { <some signed key object> } }

(If we wanted to introduce more breaking changes ( 😄 ), we could split up DeviceKeyId into DeviceOneTimeKeyId and DeviceIdentityKeyId or something. That would remove some ambiguity as currently, I don't think (but am not sure) that ed25519 is ever used for one time keys, nor is signed_curve25519 used for identity keys in the spec. However, Ruma currently allow both of those scenarios. I will focus on getting the generic SigningKeyId finished first though.)

from ruma.

iinuwa avatar iinuwa commented on May 25, 2024 1

I'd like to take a stab at it. I'll see what I can do next weekend.

from ruma.

iinuwa avatar iinuwa commented on May 25, 2024

@jplatte, in matrix-org/matrix-spec-proposals#22, you said this:

There's no dependencies on ruma-signatures in any of the other ruma crates, so no compatibility concerns.

Using the Signature type from this crate would create a dependency; would you prefer to have the type in ruma-identifiers (or ruma-common), and to have the signature functions in ruma-signatures?

from ruma.

jplatte avatar jplatte commented on May 25, 2024

I would prefer to have this in ruma-common, I think. Are these similar types all documented as part of one 'module' in the spec? If that's the case, there should probably be a corresponding Rust module in ruma-common where this type should live.

from ruma.

iinuwa avatar iinuwa commented on May 25, 2024

No, they're kind of spread out. It seems like they improved the documentation in the last version, but missed a few parts mentioning it explicitly.

Key ID Grammar

[Server] Key ID is mentioned in the parameters of the endpoints that use it in their requests (e.g. 1, 2)*:

The object's key is the algorithm and version combined ... Together, this forms the Key ID. The version must have characters matching the regular expression [a-zA-Z0-9_].

The Device Key ID is in the Client-Server spec (again in request parameters):

The names of the properties should be in the format :<device_id>. The keys themselves should be encoded as specified by the key algorithm.

Supported Key Algorithms

The supported server key algorithm, ed25519, is mentioned in an appendix.

The supported device key algorithms is mentioned in the E2EE section of the Client-Server API.

Signatures Objects

Server Key Signatures

The homeserver Signatures types is not described anywhere except the examples.

Device Key Signatures

The definition of the Signatures object is copied into each parameter description that uses it, but it seems that it's only describing device signatures:

Signatures for the device key object. A map from user ID, to a map from :<device_id> to the signature.

Other Signatures

There are a couple of other signature types that are described: Identity Server Signature and Invite Signature, which take similar formats.

Invite Signatures

The Invite Signatures type in the Federation API doesn't describe its format explicitly, but the example is similar to all the rest.

Identity Server Signatures

The Identity Server Signatures type give an explicit (though incorrect) definition of its fields:

Parameter Type Description
signatures Identity Server Signature Required. The signature from the identity server. The string key is the identity server's domain name, such as vector.im

...

Identity Server Signature

Parameter Type Description
ed25519:0 string Required. The signature.

The type for the signatures field on the Identity Server Signatures type is wrong: it should be {string: Identity Server Signature} rather than Identity Server Signature

* I got lazy, so I stopped copying links...

from ruma.

jplatte avatar jplatte commented on May 25, 2024

The homeserver Signatures types is not described anywhere except the examples.

Ouch. Is there an issue for this?

The type for the signatures field on the Identity Server Signatures type is wrong: it should be {string: Identity Server Signature} rather than Identity Server Signature

Same question: Is there an issue?

To the actual point: I guess a signature (or signing?) mod in ruma-common might be a good place for this type, but I'm not entirely sure.

from ruma.

iinuwa avatar iinuwa commented on May 25, 2024

Haven't looked if there are issues; just discovered both of those this morning. Later today, I'll check and create them if they don't exist.

I'm not sure about ruma-common, either. I'd have to think about it. I like signing as a module name though.

If we move the Signatures types to ruma-common::signing, should we also move the new (Server|Device)KeyAlgorithm and (Server|Device)KeyId types there as well? The Server* types are only used in Federation API, but the Device* ones are used in both the Federation and Client-Server APIs.

from ruma.

jplatte avatar jplatte commented on May 25, 2024

If we move the Signatures types to ruma-common::signing, should we also move the new (Server|Device)KeyAlgorithm and (Server|Device)KeyId types there as well?

If we do this, we might as well move ruma-identifers into ruma-common fully, no? Which isn't necessarily a bad thing, tbh. I can't think of a very compelling reason ruma-identifiers should be its own crate. If things continue the way it seems and ruma-events is going to be a dependency of every single API crate, we might even want to move all of that in there too.

from ruma.

iinuwa avatar iinuwa commented on May 25, 2024

I think I agree, though it may be good to get some other feedback from consumers.

from ruma.

iinuwa avatar iinuwa commented on May 25, 2024

The type for the signatures field on the Identity Server Signatures type is wrong: it should be {string: Identity Server Signature} rather than Identity Server Signature.

I was reading this wrong, but there is a mismatch between the type name and definition; created an issue for that: matrix-org/matrix-doc#2649.

The Signatures object referenced is described in prose in Section 3.2 of the Appendix. I also created an issue for defining the Signatures types more explicitly: matrix-org/matrix-doc#2650.

Now that I've read through this again, I see the pattern more clearly. All signatures are just maps from the signing entity (user ID for device signatures, server name for homeserver signatures), to the signing key identifier (algorithm and key identifier joined by a colon), to the Base64-encoded string of the signature. We could definitely have Signatures<E,K> where E is the entity type and K is the signing key identifier type.

Signing key identifiers are also basically the same, except for the accepted algorithms and the type of the right side of the key identifier. (To the latter point, if matrix-org/matrix-doc#666 goes the way of defining Device IDs and Key IDs both as opaque IDs with the same grammar, then even the validation could be the same). I don't know if it's worth it to make those generic as well though.

from ruma.

iinuwa avatar iinuwa commented on May 25, 2024

Jotting down my notes for later:

Definitions (sort of derived from the spec):

  • key identifier: used to distinguish between different signing keys used by the same entity
  • signing key identifier: signing algorithm + key identifier
  • device key identifier: device key algorithm + device identifier

It seems there is no generic term for algorithm + key identifier. I'll call it QualifiedKeyId below, to be renamed later.

Also, besides signings keys for devices, there are also identity keys and one-time keys. It seems that any of the device key algorithms can be used for identity keys in the spec, though if you're specifically using Olm v1 for encryption, then you have to use curve25519 and signed_curve25519 for identity and one-time keys, respectively.

That being said, I think this is the general idea I'm working with. (Not sure if this is all valid syntax; I'll research and fix it later.)

// K = KeyIdentifier = _key identifier_ defined above
pub struct QualifiedKeyId<A, K> {
    // fill this in here...
    // This should do the de-/serialization and validation of the key identifier
}

// Just renamed from ServerKeyAlgorithm
pub enum SigningKeyAlgorithm{
    Ed25519
}

pub type SigningKeyId<K> = QualifiedKeyId<SigningKeyAlgorithm, K>;

pub type DeviceKeyId = QualifiedKeyId<DeviceKeyAlgorithm, DeviceId>;

// Should we do this? it's just a string that matches `[a-zA-Z0-9_]`
// pub struct KeyVersion(String);

// K = Key Identifier
pub type Signature<K> = BTreeMap<SigningKeyId<K>, String>;

pub type Signatures<E, K> = BTreeMap<E, Signature<K>>;

pub type ServerSignatures = Signatures<Box<ServerName>, KeyVersion>;

pub type DeviceSignatures = Signatures<UserId, DeviceId>;

Side note: I think the other types already in the client API (ruma_client_api::r0::keys::{OneTimeKey, CrossSigningKey, etc}) can stay there, since they're only related to client stuff.

from ruma.

jplatte avatar jplatte commented on May 25, 2024

The separate KeyVersion type seems like a good idea. It should be implemented as a custom DST like DeviceId so we can create a &KeyVersion from a string slice. @iinuwa do you want to work on that and / or should I open a new help wanted issue for it?

Other than that, I'd be fine making DeviceKeyId and ServerKeyId / SigningKeyId type aliases to a generic KeyId. Would reduce some boilerplate. I like the usage of type aliases to make the map types clearer 👍

from ruma.

jplatte avatar jplatte commented on May 25, 2024

We should have this table in the docs! 🙂

from ruma.

jplatte avatar jplatte commented on May 25, 2024

Since this is going to be a breaking change for ruma-identifiers, I think it makes sense to first get it resolved before releasing any final versions of the other crates depending on it.

from ruma.

iinuwa avatar iinuwa commented on May 25, 2024

Sigh Several wishful-thinking weekends have one by, and I think it's time to unassign myself from this one. I don't have large enough chunks of time to make such large changes as this requires at this time.

from ruma.

jplatte avatar jplatte commented on May 25, 2024

This is mostly done now, but I'm not super clear on the replacement for DeviceId still. @iinuwa do you want to take care of that?

from ruma.

jplatte avatar jplatte commented on May 25, 2024

I'm not sure there's really still something to do here.

from ruma.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.