- C2 internal state
- C2 API
- new_client(id, key) [local]
- remove_client(id) [local]
- new_topic_client(id, topic) [remote]
- remove_topic_client(id, topic) [remote]
- reset_client(id) [remote]
- new_topic(topic) [local]
- remove_topic(topic) [local]
- new_client_key(id) [local & remote, SK mode]
- reset_client_pubkeys(id) [remote, PK mode]
- send_client_pubkey(iddst, idsrc) [remote, PK mode]
- remove_client_pubkey(iddst, idsrc) [remote, PK mode]
- new_c2_key() [local & remote, PK mode]
- C2 human interface
C2 (command-and-control) is the host that manages clients’ keys remotely, by sending commands to clients over MQTT.
E4's C2 holds client keys and topic keys, and manages clients by sending them commands.
C2 internal state
C2's state is composed of:
clientkeys, a map from client identities (as 16-byte strings) to their keys (symmetric keys or public keys, depending on the mode).
topickeys, a map from topics (as strings) to 32-byte topics keys.
This state is typically stored as a database.
Unlike clients whose actions are triggered by events (commands received, messages going in and out), C2's actions can be triggered by an operator, via a web UI or command-line interface, or by another service via C2's HTTP or gRPC APIs, for example by E4's automation engine.
Operations performed by C2 are of three types
Operations modifying the local state (local
Operations modifying clients’ states (remote
topickeystable), by sending a command as an MQTT messages (with QoS 2).
Operations modifying both the local state and clients’ states
This is just the minimal set of functionalities that the C2 API can implement, via HTTP and/or gRPC interfaces.
Other helper endpoints can be added, as needed by other components (command-line client, automation engine, etc.).
The API might also be extended by having endpoints supporting batch commands (for example, to reset multiple clients with a single request).
new_client(id, key) [local]
(id, key) to
clientkeys; overwrite the existing key if
id already exists. Depending on the mode,
key is either a symmetric key or a public key.
id from C2's
clientkeys map; fails if
id does not exist.
new_topic_client(id, topic) [remote]
Sends the key of
topic to the
id using a
SetTopicKey command; fails if no key is known for
topic or for
remove_topic_client(id, topic) [remote]
Removes the given topic from the client's
topickeys table using a
topickeys table of the given client, using a
A random key is generated for
topic, erasing any previous entry in
topickeys. The key is then distributed to all clients that have the key for this topic.
If the given topic is in
topickeys, then the topic and its key are removed from it; fails if
topic does not exist.
new_client_key(id) [local & remote, SK mode]
id exists, random key is generated for
id and sent to it using a
SetIdKey command. The
(id, key) pair is then added to C2's
A risk when updating the client key is the client being “in the dark” if it did not receive the key update.
Here there is no need for the client to retain the old key.
However, C2 may need to retain the previous key, but this only shifts the DoS problem to the next generation of key update, unless C2 can get a confirmation that the client registered the new key.
Depending on the use case and associated risk, we can implement a failure recovery mechanism, whereby clients can recover from desynchronized keys.
reset_client_pubkeys(id) [remote, PK mode]
clientkeys table of the given client, using a
send_client_pubkey(iddst, idsrc) [remote, PK mode]
Sends the public key of
iddst, to add it to its
Note that when a client is added to a topic, other devices from this topic don't automatically receive the client's public key. This would be necessary when emulating group messaging (many-to-many communications), but not in many-to-one network. In the former case, public key sharing can be automated through simple scripts. This behavior may be modified according to the users’ needs.
remove_client_pubkey(iddst, idsrc) [remote, PK mode]
Remove the public key of
iddst, to add it to its
new_c2_key() [local & remote, PK mode]
A random key pair is generated for C2 and its public key is sent to all clients using a
SetC2Key command. The new key pair is then used by C2 and replaces the previous one.
C2 human interface
C2 human interfaces can be command-line clients or a web-based GUI, using the API to translate user actions into C2 operations.
To facilitate manual operation, the following user-friendly mechanisms can be implemented:
idcan be generated from a string alias, as a hash of the alias
The key or key pair can be derived from a passphrase, using a password-based key derivation function