Skip to content

Commit

Permalink
C API updates, and related tweaks
Browse files Browse the repository at this point in the history
- Adds C wrappers for all the swarm authentication methods
- Adds C wrapper for querying if the keys object has admin permission
- Adds C wrapper for key_supplement to generate supplemental key messages

- Changes the swarm `subaccount` value to be base64 instead of hex
  (since it isn't really a pubkey)
- Makes the vector passed into key_supplement const&
  • Loading branch information
jagerman committed Aug 31, 2023
1 parent 224dda9 commit 9b0cdcd
Show file tree
Hide file tree
Showing 4 changed files with 380 additions and 12 deletions.
219 changes: 218 additions & 1 deletion include/session/config/groups/keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,18 @@ LIBSESSION_EXPORT int groups_keys_init(
size_t dumplen,
char* error) __attribute__((warn_unused_result));

/// API: groups/groups_keys_is_admin
///
/// Returns true if this object has the group private keys, i.e. the user is an all-powerful
/// wiz^H^H^Hadmin of the group.
///
/// Inputs:
/// - `conf` -- the groups config object
///
/// Outputs:
/// - `true` if we have admin keys, `false` otherwise.
LIBSESSION_EXPORT bool groups_keys_is_admin(const config_group_keys* conf);

/// API: groups/groups_keys_rekey
///
/// Generates a new encryption key for the group and returns an encrypted key message to be pushed
Expand Down Expand Up @@ -190,7 +202,7 @@ LIBSESSION_EXPORT bool groups_keys_needs_dump(const config_group_keys* conf)
LIBSESSION_EXPORT void groups_keys_dump(
config_group_keys* conf, unsigned char** out, size_t* outlen);

/// API: grous/groups_keys_key_supplement
/// API: groups/groups_keys_key_supplement
///
/// Generates a supplemental key message for one or more session IDs. This is used to distribute
/// existing active keys to a new member so that that member can access existing keys, configs, and
Expand Down Expand Up @@ -225,6 +237,211 @@ LIBSESSION_EXPORT bool groups_keys_key_supplement(
unsigned char** message,
size_t* message_len);

/// API: groups/groups_keys_swarm_make_subaccount
///
/// Constructs a swarm subaccount signing value that a member can use to access messages in the
/// swarm. The member will have read and write access, but not delete access. Requires group
/// admins keys.
///
/// Inputs:
/// - `conf` -- the config object
/// - `session_id` -- the session ID of the member (in hex)
/// - `sign_value` -- [out] pointer to a 100 byte (or larger) buffer where the 100 byte signing
/// value will be written. This is the value that should be sent to a member to allow
/// authentication.
///
/// Outputs:
/// - `true` -- if making the subaccount succeeds, false if it fails (e.g. because of an invalid
/// session id, or not being an admin). If a failure occurs, sign_value will not be written to.
LIBSESSION_EXPORT bool groups_keys_swarm_make_subaccount(
config_group_keys* conf, const char* session_id, unsigned char* sign_value);

/// API: groups/groups_keys_swarm_make_subaccount_flags
///
/// Same as groups_keys_swarm_make_subaccount, but lets you specify whether the write/del flags are
/// present.
///
///
/// Inputs:
/// - `conf` -- the config object
/// - `session_id` -- the member session id (hex c string)
/// - `write` -- if true then the member shall be allowed to submit messages into the group account
/// of the swarm and extend (but not shorten) the expiry of messages in the group account. If
/// false then the user can only retrieve messages. Typically this is true.
/// - `del` -- if true (default is false) then the user shall be allowed to delete messages from the
/// swarm. This permission can be used to appoint a sort of "moderator" who can delete messages
/// without having the full admin group keys. Typically this is false.
/// - `sign_value` -- pointer to a buffer with at least 100 bytes where the 100 byte signing value
/// will be written.
///
/// Outputs:
/// - `bool` - same as groups_keys_swarm_make_subaccount
LIBSESSION_EXPORT bool groups_keys_swarm_make_subaccount_flags(
config_group_keys* conf,
const char* session_id,
bool write,
bool del,
unsigned char* sign_value);

/// API: groups/groups_keys_swarm_verify_subaccount
///
/// Verifies that a received subaccount signing value (allegedly produced by
/// groups_keys_swarm_make_subaccount) is a valid subaccount signing value for the given group
/// pubkey, including a proper signature by an admin of the group. The signing value must have read
/// permission, but parameters can be given to also require write or delete permissions. A
/// subaccount signing value should always be checked for validity using this before creating a
/// group that would depend on it.
///
/// Inputs:
/// - note that this function does *not* take a config object as it is intended for use to validate
/// an invitation before constructing the keys config objects.
/// - `groupid` -- the group id/pubkey, in hex, beginning with "03".
/// - `session_ed25519_secretkey` -- the user's Session ID secret key (64 bytes).
/// - `signing_value` -- the 100-byte subaccount signing value to validate
///
/// The key will require read and write access to be acceptable. (See the _flags version if you
/// need something else).
///
/// Outputs:
/// - `true` if `signing_value` is a valid subaccount signing value for `groupid` with (at least)
/// read and write permissions, `false` if the signing value does not validate or does not meet
/// the requirements.
LIBSESSION_EXPORT bool groups_keys_swarm_verify_subaccount(
const char* group_id,
const unsigned char* session_ed25519_secretkey,
const unsigned char* signing_value);

/// API: groups/groups_keys_swarm_verify_subaccount_flags
///
/// Same as groups_keys_swarm_verify_subaccount, except that you can specify whether you want to
/// require the write and or delete flags.
///
/// Inputs:
/// - same as groups_keys_swarm_verify_subaccount
/// - `write` -- if true, require that the signing_value has write permission (i.e. that the
/// user will be allowed to post messages).
/// - `del` -- if true, required that the signing_value has delete permissions (i.e. that the
/// user will be allowed to remove storage messages from the group's swarm). Note that this
/// permission is about forcible swarm message deletion, and has no effect on an ability to
/// submit a deletion meta-message to the group (which only requires writing a message).
LIBSESSION_EXPORT bool groups_keys_swarm_verify_subaccount_flags(
const char* group_id,
const unsigned char* session_ed25519_secretkey,
const unsigned char* signing_value,
bool write,
bool del);

/// API: groups/groups_keys_swarm_subaccount_sign
///
/// This helper function generates the required signature for swarm subaccount authentication,
/// given the user's keys and swarm auth keys (as provided by an admin, produced via
/// `groups_keys_swarm_make_subaccount`).
///
/// Storage server subaccount authentication requires passing the three values in the returned
/// struct in the storage server request.
///
/// This version of the function writes base64-encoded values to the output parameters; there is
/// also a `_binary` version that writes raw values.
///
/// Inputs:
/// - `conf` -- the keys config object
/// - `msg` -- the binary data that needs to be signed (which depends on the storage server request
/// being made; for example, "retrieve9991234567890123" for a retrieve request to namespace 999
/// made at unix time 1234567890.123; see storage server RPC documentation for details).
/// - `msg_len` -- the length of the `msg` buffer
/// - `signing_value` -- the 100-byte subaccount signing value, as produced by an admin's
/// `swarm_make_subaccount` and provided to this member.
/// - `subaccount` -- [out] a C string buffer of *at least* 49 bytes where the null-terminated
/// 48-byte base64-encoded subaccount value will be written. This is the value to pass as
/// `subaccount` for storage server subaccount authentication.
/// - `subaccount_sig` -- [out] a C string buffer of *at least* 89 bytes where the null-terminated,
/// 88-ascii-character base64-encoded version of the 64-byte admin signature authorizing this
/// subaccount will be written. This is the value to be passed as `subaccount_sig` for storage
/// server subaccount authentication.
/// - `signature` -- [out] a C string buffer of *at least* 89 bytes where the null-terminated,
/// 88-character request signature will be written, base64 encoded. This is passes as the
/// `signature` value, alongside `subaccount`/`subaccoung_sig` to perform subaccount signature
/// authentication.
///
/// Outputs:
/// - true if the values were written, false if an error occured (e.g. from an invalid signing_value
/// or cryptography error).
LIBSESSION_EXPORT bool groups_keys_swarm_subaccount_sign(
config_group_keys* conf,
const unsigned char* msg,
size_t msg_len,
const unsigned char* signing_value,

char* subaccount,
char* subaccount_sig,
char* signature);

/// API: groups/groups_keys_swarm_subaccount_sign_binary
///
/// Does exactly the same as groups_keys_swarm_subaccount_sign except that the subaccount,
/// subaccount_sig, and signature values are written in binary (without null termination) of exactly
/// 36, 64, and 64 bytes, respectively.
///
/// Inputs:
/// - see groups_keys_swarm_subaccount_sign
/// - `subaccount`, `subaccount_sig`, and `signature` are binary output buffers of size 36, 64, and
/// 64, respectively.
///
/// Outputs:
/// See groups_keys_swarm_subaccount.
LIBSESSION_EXPORT bool groups_keys_swarm_subaccount_sign_binary(
config_group_keys* conf,
const unsigned char* msg,
size_t msg_len,
const unsigned char* signing_value,

unsigned char* subaccount,
unsigned char* subaccount_sig,
unsigned char* signature);

/// API: groups/groups_keys_swarm_subaccount_token
///
/// Constructs the subaccount token for a session id. The main use of this is to submit a swarm
/// token revocation; for issuing subaccount tokens you want to use
/// `groups_keys_swarm_make_subaccount` instead. This will produce the same subaccount token that
/// `groups_keys_swarm_make_subaccount` implicitly creates that can be passed to a swarm to add a
/// revocation for that subaccount.
///
/// This is recommended to be used when removing a non-admin member to prevent their access.
/// (Note, however, that there are circumstances where this can fail to prevent access, and so
/// should be combined with proper member removal and key rotation so that even if the member
/// gains access to messages, they cannot read them).
///
/// Inputs:
/// - `conf` -- the keys config object
/// - `session_id` -- the session ID of the member (in hex)
/// - `token` -- [out] a 36-byte buffer into which to write the subaccount token.
///
/// Outputs:
/// - true if the call succeeded, false if an error occured.
LIBSESSION_EXPORT bool groups_keys_swarm_subaccount_token(
config_group_keys* conf, const char* session_id, unsigned char* token);

/// API: groups/groups_keys_swarm_subaccount_token_flags
///
/// Same as `groups_keys_swarm_subaccount_token`, but takes `write` and `del` flags for creating a
/// token matching a user with non-standard permissions.
///
/// Inputs:
/// - `conf` -- the keys config object
/// - `session_id` -- the session ID of the member (in hex)
/// - `write`, `del` -- see groups_keys_swarm_make_subaccount_flags
/// - `token` -- [out] a 36-byte buffer into which to write the subaccount token.
///
/// Outputs:
/// - true if the call succeeded, false if an error occured.
LIBSESSION_EXPORT bool groups_keys_swarm_subaccount_token_flags(
config_group_keys* conf,
const char* session_id,
bool write,
bool del,
unsigned char* token);

/// API: groups/groups_keys_encrypt_message
///
/// Encrypts a message using the most recent group encryption key of this object. The message will
Expand Down
12 changes: 6 additions & 6 deletions include/session/config/groups/keys.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ class Keys final : public ConfigSig {
/// Outputs:
/// - `ustring` containing the message that should be pushed to the swarm containing encrypted
/// keys for the given user(s).
ustring key_supplement(std::vector<std::string> sids) const;
ustring key_supplement(const std::vector<std::string>& sids) const;
ustring key_supplement(std::string sid) const {
return key_supplement(std::vector{{std::move(sid)}});
}
Expand Down Expand Up @@ -373,7 +373,7 @@ class Keys final : public ConfigSig {
/// API: groups/Keys::swarm_auth
///
/// This struct containing the storage server authentication values for subaccount
/// authentication. The three strings in this struct may be either raw bytes, or hex/base64
/// authentication. The three strings in this struct may be either raw bytes, or base64
/// encoded, depending on the `binary` parameter passed to `swarm_subaccount_sign`.
///
/// `.subaccount` is the value to be passed as the "subaccount" authentication parameter. (It
Expand All @@ -397,7 +397,7 @@ class Keys final : public ConfigSig {
///
/// This helper function generates the required signature for swarm subaccount authentication,
/// given the user's keys and swarm auth keys (as provided by an admin, produced via
/// `swarm_auth_key`).
/// `swarm_make_subaccount`).
///
/// Storage server subaccount authentication requires passing the three values in the returned
/// struct in the storage server request. (See Keys::swarm_auth for details).
Expand All @@ -408,9 +408,9 @@ class Keys final : public ConfigSig {
/// 999 made at unix time 1234567890.123; see storage server RPC documentation for details).
/// - `signing_value` -- the 100-byte subaccount signing value, as produced by an admin's
/// `swarm_make_subaccount` and provided to this member.
/// - `binary` -- if set to true then the returned values will be binary. If omitted, the
/// returned struct values will be hex-encoded (subaccount token) or base64-encoded
/// (signatures) suitable for direct passing as JSON values to the storage server.
/// - `binary` -- if set to true then the returned values will be binary. If omitted (or
/// explicitly false), the returned struct values will be base64-encoded suitable for direct
/// passing as JSON values to the storage server without further encoding/modification.
///
/// Outputs:
/// - struct containing three binary values enabling swarm authentication (see description
Expand Down

0 comments on commit 9b0cdcd

Please sign in to comment.