Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for designated revokers #2160

Merged
merged 12 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions include/rekey/rnp_key_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,20 @@ class KeyStore {
*/
pgp_key_t *add_key(pgp_key_t &key);

/**
* @brief Add signature of the specific key to the keystore, revalidating and refresing
* key's data. Currently supports only direct-key or subkey binding signature.
*
* @param keyfp key's fingerprint.
* @param sig signature packet.
* @param front set to true if signature should be added to the beggining of the signature
* list.
* @return pgp_subsig_t*
*/
pgp_subsig_t *add_key_sig(const pgp_fingerprint_t &keyfp,
const pgp_signature_t & sig,
bool front);

/**
* @brief Add transferable key to the keystore.
*
Expand Down
134 changes: 134 additions & 0 deletions include/rnp/rnp.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ typedef uint32_t rnp_result_t;
#define RNP_VERIFY_REQUIRE_ALL_SIGS (1U << 1)
#define RNP_VERIFY_ALLOW_HIDDEN_RECIPIENT (1U << 2)

/**
* Revocation key flags.
*/
#define RNP_REVOKER_SENSITIVE (1U << 0)

/**
* Return a constant string describing the result code
*/
Expand Down Expand Up @@ -1519,6 +1524,108 @@ RNP_API rnp_result_t rnp_key_get_signature_at(rnp_key_handle_t key,
size_t idx,
rnp_signature_handle_t *sig);

/**
* @brief Create new direct-key signature over the target, issued by signer. It may be
* customized via the rnp_signature_set_* calls, and finalized via the
* rnp_signature_sign() call.
*
* @param signer signing key, must be secret, and must exist in the keyring up to the
* rnp_signature_sign() call. Cannot be NULL.
* @param target target key for which signature should be made. May be NULL, then signature
* over the signer (self-signature) will be made.
*
* @param sig on success signature handle will be stored here. It is initialized with current
* creation time, default hash algorithm and version. Cannot be NULL.
* @return RNP_SUCCESS or error code if failued.
*/
RNP_API rnp_result_t rnp_key_direct_signature_create(rnp_key_handle_t signer,
rnp_key_handle_t target,
rnp_signature_handle_t *sig);

/**
* @brief Create new key or subkey revocation signature. It may be
* customized via the rnp_signature_set_* calls, and finalized via the
* rnp_signature_sign() call.
*
* @param signer revoker's key, must be secret, and must exist in the keyring up to the
* rnp_signature_sign() call. Cannot be NULL.
* @param target target key for which signature should be made. May be NULL, then signer will
* revoke itself.
*
* @param sig on success signature handle will be stored here. It is initialized with current
* creation time, default hash algorithm and version. Cannot be NULL.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_key_revocation_signature_create(rnp_key_handle_t signer,
rnp_key_handle_t target,
rnp_signature_handle_t *sig);

/**
* @brief Set hash algorithm, used during signing.
*
* @param sig editable key signature handle, i.e. created with rnp_key_*_signature_create().
* @param hash hash algorithm name, i.e. "SHA256" or others.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_key_signature_set_hash(rnp_signature_handle_t sig, const char *hash);

/**
* @brief Set revocation reason and code for the revocation signature.
* See `rnp_key_revoke()` for the details.
* @param sig editable key signature handle, i.e. created with rnp_key_*_signature_create().
* @param code revocation reason code. Could be NULL, then default one will be set.
* @param reason human-readable reason for revocation. Could be NULL or empty string.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_key_signature_set_revocation_reason(rnp_signature_handle_t sig,
const char * code,
const char * reason);

/**
* @brief Add designated revoker subpacket to the signature. See RFC 4880, section 5.2.3.15.
* Only single revoker could be set - subsequent calls would overwrite the previous one.
*
* @param sig editable key signature handle, i.e. created with rnp_key_*_signature_create().
* @param revoker revoker's key.
* @param flags additional flags. The following flag is currently supported:
* RNP_REVOKER_SENSITIVE: information about the revocation key should be
* considered as sensitive. See RFC for the details.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_key_signature_set_revoker(rnp_signature_handle_t sig,
rnp_key_handle_t revoker,
uint32_t flags);

/**
* @brief Finalize populating and sign signature, created with one of the
* rnp_key_*_signature_create functions, and add it to the corresponding key.
*
* @param sig signature handle.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_key_signature_sign(rnp_signature_handle_t sig);

/**
* @brief Get number of the designated revokers for the key. Designated revoker is a key, which
* is allowed to revoke this key.
*
* @param key key handle, cannot be NULL.
* @param count number of designated revokers will be stored here.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_key_get_revoker_count(rnp_key_handle_t key, size_t *count);

/**
* @brief Get the fingerprint of designated revoker's key, based on it's index.
*
* @param key key handle, cannot be NULL.
* @param idx zero-based index.
* @param revoker on success hex-encoded revoker's key fingerprint will be stored here. Must be
* later freed via rnp_buffer_destroy().
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_key_get_revoker_at(rnp_key_handle_t key, size_t idx, char **revoker);

/**
* @brief Get key's revocation signature handle, if any.
*
Expand Down Expand Up @@ -1644,6 +1751,33 @@ RNP_API rnp_result_t rnp_signature_get_key_fprint(rnp_signature_handle_t sig, ch
RNP_API rnp_result_t rnp_signature_get_signer(rnp_signature_handle_t sig,
rnp_key_handle_t * key);

/**
* @brief Get fingerprint of the designated revocation key, if it is available. See
* section 5.2.3.15 of the RFC 4880 for the details.
*
* @param sig signature handle, cannot be NULL.
* @param revoker on success hex-encoded revocation key fingerprint will be stored here, if
* available. Otherwise empty string will be stored. Must be freed via
* rnp_buffer_destroy().
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_signature_get_revoker(rnp_signature_handle_t sig, char **revoker);

/**
* @brief Get revocation reason data, if it is available in the signature.
*
* @param sig signature handle, cannot be NULL.
* @param code string with revocation code will be stored here, if not NULL. See description of
* function rnp_key_revoke() for possible values. If information is not available,
* empty string will be stored here.
* @param reason revocation reason will be stored here, if available. Otherwise empty string
* will be stored here. May be NULL if this information is not needed.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_signature_get_revocation_reason(rnp_signature_handle_t sig,
char ** code,
char ** reason);

/**
* @brief Get signature validity, revalidating it if didn't before.
*
Expand Down
14 changes: 12 additions & 2 deletions src/lib/ffi-priv-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,20 @@ struct rnp_uid_handle_st {
};

struct rnp_signature_handle_st {
rnp_ffi_t ffi;
rnp_ffi_t ffi;
/**
* @brief Key to which this signature belongs, if available.
*/
const pgp_key_t *key;
pgp_subsig_t * sig;
bool own_sig;
/**
* @brief sig pointer is owned by structure and should be deallocated.
*/
bool own_sig;
/**
* @brief This is a new signature, which is being populated.
*/
bool new_sig;
};

struct rnp_recipient_handle_st {
Expand Down
Loading