Skip to content

Commit e9021c4

Browse files
ni4antonsviridenko
authored andcommitted
Refactor some of the CLI functions to use C++ FFI wrappers.
1 parent 8d7b219 commit e9021c4

File tree

2 files changed

+77
-122
lines changed

2 files changed

+77
-122
lines changed

src/rnp/fficli.cpp

Lines changed: 71 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -814,189 +814,144 @@ cli_rnp_t::set_defkey()
814814
}
815815

816816
bool
817-
cli_rnp_t::is_cv25519_subkey(rnp_key_handle_t handle)
817+
cli_rnp_t::is_cv25519_subkey(rnpffi::Key &key)
818818
{
819-
bool primary = false;
820-
if (rnp_key_is_primary(handle, &primary)) {
821-
ERR_MSG("Error: failed to check for subkey.");
822-
return false;
823-
}
824-
if (primary) {
825-
return false;
826-
}
827-
char *alg = NULL;
828-
if (rnp_key_get_alg(handle, &alg)) {
829-
ERR_MSG("Error: failed to check key's alg.");
830-
return false;
831-
}
832-
bool ecdh = !strcmp(alg, RNP_ALGNAME_ECDH);
833-
rnp_buffer_destroy(alg);
834-
if (!ecdh) {
835-
return false;
836-
}
837-
char *curve = NULL;
838-
if (rnp_key_get_curve(handle, &curve)) {
839-
ERR_MSG("Error: failed to check key's curve.");
819+
try {
820+
if (key.is_primary()) {
821+
return false;
822+
}
823+
if (strcmp(key.alg().c_str(), RNP_ALGNAME_ECDH)) {
824+
return false;
825+
}
826+
return !strcmp(key.curve().c_str(), "Curve25519");
827+
} catch (const rnpffi::ffi_exception &e) {
828+
ERR_MSG("FFI call error: %s.", e.func());
840829
return false;
841830
}
842-
bool cv25519 = !strcmp(curve, "Curve25519");
843-
rnp_buffer_destroy(curve);
844-
return cv25519;
845831
}
846832

847833
bool
848-
cli_rnp_t::get_protection(rnp_key_handle_t handle,
849-
std::string & hash,
850-
std::string & cipher,
851-
size_t & iterations)
834+
cli_rnp_t::get_protection(rnpffi::Key &key,
835+
std::string &hash,
836+
std::string &cipher,
837+
size_t & iterations)
852838
{
853-
bool prot = false;
854-
if (rnp_key_is_protected(handle, &prot)) {
855-
ERR_MSG("Error: failed to check key's protection.");
856-
return false;
857-
}
858-
if (!prot) {
859-
hash = "";
860-
cipher = "";
861-
iterations = 0;
862-
return true;
863-
}
864-
865-
char *val = NULL;
866839
try {
867-
if (rnp_key_get_protection_hash(handle, &val)) {
868-
ERR_MSG("Error: failed to retrieve key's protection hash.");
869-
return false;
870-
}
871-
hash = val;
872-
rnp_buffer_destroy(val);
873-
if (rnp_key_get_protection_cipher(handle, &val)) {
874-
ERR_MSG("Error: failed to retrieve key's protection cipher.");
875-
return false;
876-
}
877-
cipher = val;
878-
rnp_buffer_destroy(val);
879-
if (rnp_key_get_protection_iterations(handle, &iterations)) {
880-
ERR_MSG("Error: failed to retrieve key's protection iterations.");
881-
return false;
840+
if (!key.is_protected()) {
841+
hash = "";
842+
cipher = "";
843+
iterations = 0;
844+
return true;
882845
}
846+
hash = key.protection_hash();
847+
cipher = key.protection_cipher();
848+
iterations = key.protection_iterations();
883849
return true;
884-
} catch (const std::exception &e) {
885-
ERR_MSG("Error: failed to retrieve key's properties: %s", e.what());
886-
rnp_buffer_destroy(val);
850+
} catch (const rnpffi::ffi_exception &e) {
851+
ERR_MSG("FFI call error: %s", e.func());
887852
return false;
888853
}
889854
}
890855

891856
bool
892-
cli_rnp_t::check_cv25519_bits(rnp_key_handle_t key, char *prot_password, bool &tweaked)
857+
cli_rnp_t::check_cv25519_bits(rnpffi::Key &key, rnpffi::String &prot_password, bool &tweaked)
893858
{
894859
/* unlock key first to check whether bits are tweaked */
895-
if (prot_password && rnp_key_unlock(key, prot_password)) {
860+
if (prot_password.c_str() && !key.unlock(prot_password.str())) {
896861
ERR_MSG("Error: failed to unlock key. Did you specify valid password?");
897862
return false;
898863
}
899-
rnp_result_t ret = rnp_key_25519_bits_tweaked(key, &tweaked);
900-
if (ret) {
864+
bool res = false;
865+
try {
866+
tweaked = key.is_25519_bits_tweaked();
867+
res = true;
868+
} catch (...) {
901869
ERR_MSG("Error: failed to check whether key's bits are tweaked.");
902870
}
903-
if (prot_password) {
904-
rnp_key_lock(key);
871+
if (prot_password.c_str()) {
872+
key.lock();
905873
}
906-
return !ret;
874+
return res;
907875
}
908876

909877
bool
910-
cli_rnp_t::fix_cv25519_subkey(const std::string &key, bool checkonly)
878+
cli_rnp_t::fix_cv25519_subkey(const std::string &str, bool checkonly)
911879
{
912-
std::vector<rnp_key_handle_t> keys;
913-
if (!keys_matching(keys, key, CLI_SEARCH_SECRET | CLI_SEARCH_SUBKEYS)) {
914-
ERR_MSG("Secret keys matching '%s' not found.", key.c_str());
880+
size_t keys = 0;
881+
auto key = key_matching(str, CLI_SEARCH_SECRET | CLI_SEARCH_SUBKEYS, &keys);
882+
if (!keys) {
883+
ERR_MSG("Secret keys matching '%s' not found.", str.c_str());
915884
return false;
916885
}
917-
bool res = false;
918-
std::string prot_hash;
919-
std::string prot_cipher;
920-
size_t prot_iterations;
921-
char * prot_password = NULL;
922-
bool tweaked = false;
923-
924-
if (keys.size() > 1) {
886+
if (keys > 1) {
925887
ERR_MSG(
926888
"Ambiguous input: too many keys found for '%s'. Did you use keyid or fingerprint?",
927-
key.c_str());
928-
goto done;
889+
str.c_str());
890+
return false;
929891
}
930-
cli_rnp_print_key_info(userio_out, ffi, keys[0], true, false);
931-
if (!is_cv25519_subkey(keys[0])) {
892+
cli_rnp_print_key_info(userio_out, ffi, key->handle(), true, false);
893+
if (!is_cv25519_subkey(*key)) {
932894
ERR_MSG("Error: specified key is not Curve25519 ECDH subkey.");
933-
goto done;
895+
return false;
934896
}
935897

936-
if (!get_protection(keys[0], prot_hash, prot_cipher, prot_iterations)) {
937-
goto done;
898+
std::string prot_hash;
899+
std::string prot_cipher;
900+
size_t prot_iterations;
901+
if (!get_protection(*key, prot_hash, prot_cipher, prot_iterations)) {
902+
return false;
938903
}
939904

940-
if (!prot_hash.empty() &&
941-
(rnp_request_password(ffi, keys[0], "unprotect", &prot_password) || !prot_password)) {
905+
rnpffi::String prot_password(true);
906+
rnpffi::FFI ffiobj(ffi, false);
907+
if (!prot_hash.empty() && (!ffiobj.request_password(*key, "unprotect", prot_password) ||
908+
!prot_password.c_str())) {
942909
ERR_MSG("Error: failed to obtain protection password.");
943-
goto done;
910+
return false;
944911
}
945912

946-
if (!check_cv25519_bits(keys[0], prot_password, tweaked)) {
947-
goto done;
913+
bool tweaked = false;
914+
if (!check_cv25519_bits(*key, prot_password, tweaked)) {
915+
return false;
948916
}
949917

950918
if (checkonly) {
951919
fprintf(userio_out,
952920
tweaked ? "Cv25519 key bits are set correctly and do not require fixing.\n" :
953921
"Warning: Cv25519 key bits need fixing.\n");
954-
res = tweaked;
955-
goto done;
922+
return tweaked;
956923
}
957924

958925
if (tweaked) {
959926
ERR_MSG("Warning: key's bits are fixed already, no action is required.");
960-
res = true;
961-
goto done;
927+
return true;
962928
}
963929

964930
/* now unprotect so we can tweak bits */
965931
if (!prot_hash.empty()) {
966-
if (rnp_key_unprotect(keys[0], prot_password)) {
932+
if (!key->unprotect(prot_password.str())) {
967933
ERR_MSG("Error: failed to unprotect key. Did you specify valid password?");
968-
goto done;
934+
return false;
969935
}
970-
if (rnp_key_unlock(keys[0], NULL)) {
936+
if (!key->unlock()) {
971937
ERR_MSG("Error: failed to unlock key.");
972-
goto done;
938+
return false;
973939
}
974940
}
975941

976942
/* tweak key bits and protect back */
977-
if (rnp_key_25519_bits_tweak(keys[0])) {
943+
if (!key->do_25519_bits_tweak()) {
978944
ERR_MSG("Error: failed to tweak key's bits.");
979-
goto done;
945+
return false;
980946
}
981947

982-
if (!prot_hash.empty() && rnp_key_protect(keys[0],
983-
prot_password,
984-
prot_cipher.c_str(),
985-
NULL,
986-
prot_hash.c_str(),
987-
prot_iterations)) {
948+
if (!prot_hash.empty() &&
949+
!key->protect(prot_password.str(), prot_cipher, prot_hash, prot_iterations)) {
988950
ERR_MSG("Error: failed to protect key back.");
989-
goto done;
951+
return false;
990952
}
991953

992-
res = cli_rnp_save_keyrings(this);
993-
done:
994-
clear_key_handles(keys);
995-
if (prot_password) {
996-
rnp_buffer_clear(prot_password, strlen(prot_password) + 1);
997-
rnp_buffer_destroy(prot_password);
998-
}
999-
return res;
954+
return cli_rnp_save_keyrings(this);
1000955
}
1001956

1002957
bool

src/rnp/fficli.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ class cli_rnp_t {
4747
char **subst_argv{};
4848
#endif
4949
bool load_keyring(bool secret);
50-
bool is_cv25519_subkey(rnp_key_handle_t handle);
51-
bool get_protection(rnp_key_handle_t handle,
52-
std::string & hash,
53-
std::string & cipher,
54-
size_t & iterations);
55-
bool check_cv25519_bits(rnp_key_handle_t key, char *prot_password, bool &tweaked);
50+
bool is_cv25519_subkey(rnpffi::Key &key);
51+
bool get_protection(rnpffi::Key &key,
52+
std::string &hash,
53+
std::string &cipher,
54+
size_t & iterations);
55+
bool check_cv25519_bits(rnpffi::Key &key, rnpffi::String &prot_password, bool &tweaked);
5656

5757
public:
5858
rnp_ffi_t ffi{};

0 commit comments

Comments
 (0)