Skip to content

Commit

Permalink
(WIP) FFI: Add bunch of functions to retrieve information from the si…
Browse files Browse the repository at this point in the history
…gnatures.
  • Loading branch information
ni4 committed Sep 5, 2024
1 parent 529fe07 commit 58fb05e
Show file tree
Hide file tree
Showing 2 changed files with 330 additions and 0 deletions.
168 changes: 168 additions & 0 deletions include/rnp/rnp.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,21 @@ typedef uint32_t rnp_result_t;
#define RNP_KEY_FEATURE_AEAD (1U << 1)
#define RNP_KEY_FEATURE_V5 (1U << 2)

/**
* Key usage flags.
*/

#define RNP_KEY_USAGE_CERTIFY (1U << 0)
#define RNP_KEY_USAGE_SIGN (1U << 1)
#define RNP_KEY_USAGE_ENCRYPT_COMMS (1U << 2)
#define RNP_KEY_USAGE_ENCRYPT_STORAGE (1U << 3)

/**
* Key server preferences flags.
*/

#define RNP_KEY_SERVER_NO_MODIFY (1U << 7)

/**
* Return a constant string describing the result code
*/
Expand Down Expand Up @@ -1753,9 +1768,162 @@ RNP_API rnp_result_t rnp_signature_get_creation(rnp_signature_handle_t sig, uint
RNP_API rnp_result_t rnp_signature_get_expiration(rnp_signature_handle_t sig,
uint32_t * expires);

/**
* @brief Get the key features if any as per RFC 4880 and later. Do not confuse with key flags.
*
* @param sig signature handle, cannot be NULL.
* @param features on success result will be stored here as or'ed together flag bits.
* If corresponding value is not available then 0 will be stored.
* Currently known feature bit flags are (consult RFC for more details):
* RNP_KEY_FEATURE_MDC - support for MDC packets (see RFC 4880)
* RNP_KEY_FEATURE_AEAD - support for OCB encrypted packet and v5 SKESK (please
* see LibrePGP standard)
* RNP_KEY_FEATURE_V5 - version 5 public-key format and corresponding
* fingerprint
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_signature_get_features(rnp_signature_handle_t sig,
uint32_t * features);

/**
* @brief Get number of the preferred symmetric algorithms, listed in the signature. Applies to
* the self-signature (self-certification or direct-key signature).
*
* @param sig signature handle, cannot be NULL.
* @param count on success nunmber of available algorithms will be stored here. It may be 0 if
* no such information is available within the signature.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_signature_get_preferred_alg_count(rnp_signature_handle_t sig,
size_t * count);

/**
* @brief Get preferred symmetric algorithm from the preferences, specified in the signature.
*
* @param sig signature handle, cannot be NULL.
* @param idx index in the list. Number of availabke items could be obtained via the
* rnp_signature_get_preferred_alg_count() call.
* @param alg on success algorithm name will be stored here. Caller must deallocate it using
* the rnp_buffer_destroy() function.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_signature_get_preferred_alg(rnp_signature_handle_t sig,
size_t idx,
char ** alg);

/**
* @brief Get number of the preferred hash algorithms, listed in the signature. Applies to the
* self-signature (self-certification or direct-key signature).
*
* @param sig signature handle, cannot be NULL.
* @param count on success nunmber of available algorithms will be stored here. It may be 0 if
* no such information is available within the signature.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_signature_get_preferred_hash_count(rnp_signature_handle_t sig,
size_t * count);

/**
* @brief Get preferred hash algorithm from the preferences, specified in the signature.
*
* @param sig signature handle, cannot be NULL.
* @param idx index in the list. Number of availabke items could be obtained via the
* rnp_signature_get_preferred_hash_count() call.
* @param alg on success algorithm name will be stored here. Caller must deallocate it using
* the rnp_buffer_destroy() function.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_signature_get_preferred_hash(rnp_signature_handle_t sig,
size_t idx,
char ** alg);

/**
* @brief Get number of the preferred compression algorithms, listed in the signature. Applies
* to the self-signature (self-certification or direct-key signature).
*
* @param sig signature handle, cannot be NULL.
* @param count on success nunmber of available algorithms will be stored here. It may be 0 if
* no such information is available within the signature.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_signature_get_preferred_zalg_count(rnp_signature_handle_t sig,
size_t * count);

/**
* @brief Get preferred compression algorithm from the preferences, specified in the signature.
*
* @param sig signature handle, cannot be NULL.
* @param idx index in the list. Number of availabke items could be obtained via the
* rnp_signature_get_preferred_zalg_count() call.
* @param alg on success algorithm name will be stored here. Caller must deallocate it using
* the rnp_buffer_destroy() function.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_signature_get_preferred_zalg(rnp_signature_handle_t sig,
size_t idx,
char ** alg);

/**
* @brief Get key usage flags from the signature, if any. Those are mapped directly to the
* values described in the OpenPGP specification.
*
* @param sig signature handle, cannot be NULL.
* @param flags on success result will be stored here as or'ed together flag bits.
* If corresponding value is not available then 0 will be stored.
* These flags would correspond to string values which are passed to the
* rnp_op_generate_add_usage(). See the RNP_KEY_USAGE_* constants for possible
* values.
*
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_signature_get_key_flags(rnp_signature_handle_t sig, uint32_t *flags);

/**
* @brief Get the key expiration time from the signature.
*
* @param sig signature handle, cannot be NULL.
* @param expiry on success result will be stored here. It is number of seconds since key
* creation (not the signature creation) when this key is considered to be valid.
* Zero value means that key is valid forever.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_signature_get_key_expiration(rnp_signature_handle_t sig,
uint32_t * expiry);

/**
* @brief Check whether signature indicates that corresponding user id should be considered as
* primary.
*
* @param sig signature handle, cannot be NULL.
* @param primary on success result will be stored here. True for primary and false otherwise.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_signature_get_primary_uid(rnp_signature_handle_t sig, bool *primary);

/**
* @brief Get the key server associated with this key, if any.
*
* @param sig signature handle, cannot be NULL.
* @param keyserver on success key server string, stored in the signature, will be stored here.
* If it isn't present in the signature, an empty value will be stored. In
* both cases, the buffer must be deallocated via the rnp_buffer_destroy()
* call.
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_signature_get_key_server(rnp_signature_handle_t sig,
char ** keyserver);

/**
* @brief Get the key server preferences flags, if any.
*
* @param sig signature handle, cannot be NULL.
* @param flags on success flags will be stored here. Currently only one flag is supported:
* RNP_KEY_SERVER_NO_MODIFY
* @return RNP_SUCCESS or error code if failed.
*/
RNP_API rnp_result_t rnp_signature_get_key_server_prefs(rnp_signature_handle_t sig,
uint32_t * flags);

/** Get signer's key id from the signature.
* Note: if key id is not available from the signature then NULL value will
* be stored to result.
Expand Down
162 changes: 162 additions & 0 deletions src/lib/rnp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6474,6 +6474,168 @@ try {
}
FFI_GUARD

rnp_result_t
rnp_signature_get_preferred_alg_count(rnp_signature_handle_t sig, size_t *count)
try {
if (!sig || !count) {
return RNP_ERROR_NULL_POINTER;
}
if (!sig->sig) {
return RNP_ERROR_BAD_PARAMETERS;
}
*count = sig->sig->sig.preferred_symm_algs().size();
return RNP_SUCCESS;
}
FFI_GUARD

rnp_result_t
rnp_signature_get_preferred_alg(rnp_signature_handle_t sig, size_t idx, char **alg)
try {
if (!sig || !alg) {
return RNP_ERROR_NULL_POINTER;
}
if (!sig->sig) {
return RNP_ERROR_BAD_PARAMETERS;
}
auto algs = sig->sig->sig.preferred_symm_algs();
if (idx >= algs.size()) {
return RNP_ERROR_BAD_PARAMETERS;
}
return get_map_value(symm_alg_map, algs[idx], alg);
}
FFI_GUARD

rnp_result_t
rnp_signature_get_preferred_hash_count(rnp_signature_handle_t sig, size_t *count)
try {
if (!sig || !count) {
return RNP_ERROR_NULL_POINTER;
}
if (!sig->sig) {
return RNP_ERROR_BAD_PARAMETERS;
}
*count = sig->sig->sig.preferred_hash_algs().size();
return RNP_SUCCESS;
}
FFI_GUARD

rnp_result_t
rnp_signature_get_preferred_hash(rnp_signature_handle_t sig, size_t idx, char **alg)
try {
if (!sig || !alg) {
return RNP_ERROR_NULL_POINTER;
}
if (!sig->sig) {
return RNP_ERROR_BAD_PARAMETERS;
}
auto algs = sig->sig->sig.preferred_hash_algs();
if (idx >= algs.size()) {
return RNP_ERROR_BAD_PARAMETERS;
}
return get_map_value(hash_alg_map, algs[idx], alg);
}
FFI_GUARD

rnp_result_t
rnp_signature_get_preferred_zalg_count(rnp_signature_handle_t sig, size_t *count)
try {
if (!sig || !count) {
return RNP_ERROR_NULL_POINTER;
}
if (!sig->sig) {
return RNP_ERROR_BAD_PARAMETERS;
}
*count = sig->sig->sig.preferred_z_algs().size();
return RNP_SUCCESS;
}
FFI_GUARD

rnp_result_t
rnp_signature_get_preferred_zalg(rnp_signature_handle_t sig, size_t idx, char **alg)
try {
if (!sig || !alg) {
return RNP_ERROR_NULL_POINTER;
}
if (!sig->sig) {
return RNP_ERROR_BAD_PARAMETERS;
}
auto algs = sig->sig->sig.preferred_z_algs();
if (idx >= algs.size()) {
return RNP_ERROR_BAD_PARAMETERS;
}
return get_map_value(compress_alg_map, algs[idx], alg);
}
FFI_GUARD

rnp_result_t
rnp_signature_get_key_flags(rnp_signature_handle_t sig, uint32_t *flags)
try {
if (!sig || !flags) {
return RNP_ERROR_NULL_POINTER;
}
if (!sig->sig) {
return RNP_ERROR_BAD_PARAMETERS;
}
*flags = sig->sig->sig.key_flags();
return RNP_SUCCESS;
}
FFI_GUARD

rnp_result_t
rnp_signature_get_key_expiration(rnp_signature_handle_t sig, uint32_t *expiry)
try {
if (!sig || !expiry) {
return RNP_ERROR_NULL_POINTER;
}
if (!sig->sig) {
return RNP_ERROR_BAD_PARAMETERS;
}
*expiry = sig->sig->sig.key_expiration();
return RNP_SUCCESS;
}
FFI_GUARD

rnp_result_t
rnp_signature_get_primary_uid(rnp_signature_handle_t sig, bool *primary)
try {
if (!sig || !primary) {
return RNP_ERROR_NULL_POINTER;
}
if (!sig->sig) {
return RNP_ERROR_BAD_PARAMETERS;
}
*primary = sig->sig->sig.primary_uid();
return RNP_SUCCESS;
}
FFI_GUARD

rnp_result_t
rnp_signature_get_key_server(rnp_signature_handle_t sig, char **keyserver)
try {
if (!sig || !keyserver) {
return RNP_ERROR_NULL_POINTER;
}
if (!sig->sig) {
return RNP_ERROR_BAD_PARAMETERS;
}
return ret_str_value(sig->sig->sig.key_server().c_str(), keyserver);
}
FFI_GUARD

rnp_result_t
rnp_signature_get_key_server_prefs(rnp_signature_handle_t sig, uint32_t *flags)
try {
if (!sig || !flags) {
return RNP_ERROR_NULL_POINTER;
}
if (!sig->sig) {
return RNP_ERROR_BAD_PARAMETERS;
}
*flags = sig->sig->sig.key_server_prefs();
return RNP_SUCCESS;
}
FFI_GUARD

rnp_result_t
rnp_signature_get_keyid(rnp_signature_handle_t handle, char **result)
try {
Expand Down

0 comments on commit 58fb05e

Please sign in to comment.