diff --git a/include/rnp/rnp.h b/include/rnp/rnp.h index 2f5c568900..8d0336d1a7 100644 --- a/include/rnp/rnp.h +++ b/include/rnp/rnp.h @@ -1724,6 +1724,21 @@ RNP_API rnp_result_t rnp_signature_get_signer(rnp_signature_handle_t sig, */ 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. * diff --git a/src/lib/rnp.cpp b/src/lib/rnp.cpp index 4f6464060a..8ec088a494 100644 --- a/src/lib/rnp.cpp +++ b/src/lib/rnp.cpp @@ -6519,6 +6519,37 @@ try { } FFI_GUARD +rnp_result_t +rnp_signature_get_revocation_reason(rnp_signature_handle_t sig, char **code, char **reason) +{ + if (!sig) { + return RNP_ERROR_NULL_POINTER; + } + std::string rcode; + std::string rreason; + if (sig->sig->sig.has_revocation_reason()) { + rcode = id_str_pair::lookup(revocation_code_map, sig->sig->sig.revocation_code(), ""); + rreason = sig->sig->sig.revocation_reason(); + } + if (code) { + rnp_result_t ret = ret_str_value("", code); + if (ret) { + return ret; + } + } + if (reason) { + rnp_result_t ret = ret_str_value("", reason); + if (ret) { + if (code) { + free(*code); + *code = NULL; + } + return ret; + } + } + return RNP_SUCCESS; +} + rnp_result_t rnp_signature_is_valid(rnp_signature_handle_t sig, uint32_t flags) try { diff --git a/src/librepgp/stream-sig.cpp b/src/librepgp/stream-sig.cpp index d0e39b7007..b150200075 100644 --- a/src/librepgp/stream-sig.cpp +++ b/src/librepgp/stream-sig.cpp @@ -1077,6 +1077,12 @@ pgp_signature_t::revocation_code() const return subpkt ? subpkt->fields.revocation_reason.code : PGP_REVOCATION_NO_REASON; } +bool +pgp_signature_t::has_revocation_reason() const +{ + return get_subpkt(PGP_SIG_SUBPKT_REVOCATION_REASON); +} + void pgp_signature_t::set_revocation_reason(pgp_revocation_type_t code, const std::string &reason) { diff --git a/src/librepgp/stream-sig.h b/src/librepgp/stream-sig.h index 98444070e7..b95d0adc11 100644 --- a/src/librepgp/stream-sig.h +++ b/src/librepgp/stream-sig.h @@ -279,6 +279,11 @@ typedef struct pgp_signature_t { */ pgp_revocation_type_t revocation_code() const; + /** + * @brief Check whether signature has revocation reason and code subpacket. + */ + bool has_revocation_reason() const; + /** @brief Set the revocation reason and code for key/subkey revocation signature. See the * RFC 4880, 5.2.3.24 for the detailed explanation. */