1 /*
2  * Copyright (c) 2019-2021, [Ribose Inc](https://www.ribose.com).
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *
11  * 2.  Redistributions in binary form must reproduce the above copyright notice,
12  *     this list of conditions and the following disclaimer in the documentation
13  *     and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #ifndef FFICLI_H_
28 #define FFICLI_H_
29 
30 #include <stddef.h>
31 #include <stdbool.h>
32 #include <time.h>
33 #include "rnp/rnp.h"
34 #include "rnp/rnp_err.h"
35 #include "config.h"
36 #include "rnpcfg.h"
37 #include "json.h"
38 
39 typedef struct cli_rnp_t {
40     rnp_ffi_t ffi{};
41     rnp_cfg   cfg{};
42     FILE *    resfp{};      /* where to put result messages, defaults to stdout */
43     FILE *    passfp{};     /* file pointer for password input */
44     FILE *    userio_in{};  /* file pointer for user's inputs */
45     FILE *    userio_out{}; /* file pointer for user's outputs */
46     int       pswdtries{};  /* number of password tries, -1 for unlimited */
47 } cli_rnp_t;
48 
49 typedef enum cli_search_flags_t {
50     CLI_SEARCH_SECRET = 1 << 0,     /* search secret keys only */
51     CLI_SEARCH_SUBKEYS = 1 << 1,    /* add subkeys as well */
52     CLI_SEARCH_FIRST_ONLY = 1 << 2, /* return only first key matching */
53     CLI_SEARCH_SUBKEYS_AFTER =
54       (1 << 3) | CLI_SEARCH_SUBKEYS, /* put subkeys after the primary key */
55     CLI_SEARCH_DEFAULT = 1 << 4      /* add default key if nothing found */
56 } cli_search_flags_t;
57 
58 /**
59  * @brief Set keystore parameters to the rnp_cfg_t. This includes keyring paths, types and
60  *        default key.
61  *
62  * @param cfg pointer to the allocated rnp_cfg_t structure
63  * @return true on success or false otherwise.
64  * @return false
65  */
66 bool cli_cfg_set_keystore_info(rnp_cfg &cfg);
67 
68 rnp_cfg &         cli_rnp_cfg(cli_rnp_t &rnp);
69 const std::string cli_rnp_defkey(cli_rnp_t *rnp);
70 const std::string cli_rnp_pubpath(cli_rnp_t *rnp);
71 const std::string cli_rnp_secpath(cli_rnp_t *rnp);
72 const std::string cli_rnp_pubformat(cli_rnp_t *rnp);
73 const std::string cli_rnp_secformat(cli_rnp_t *rnp);
74 
75 bool cli_rnp_init(cli_rnp_t *, const rnp_cfg &);
76 bool cli_rnp_baseinit(cli_rnp_t *);
77 void cli_rnp_end(cli_rnp_t *);
78 bool cli_rnp_load_keyrings(cli_rnp_t *rnp, bool loadsecret);
79 bool cli_rnp_save_keyrings(cli_rnp_t *rnp);
80 void cli_rnp_set_default_key(cli_rnp_t *rnp);
81 void cli_rnp_print_key_info(
82   FILE *fp, rnp_ffi_t ffi, rnp_key_handle_t key, bool psecret, bool psigs);
83 bool cli_rnp_set_generate_params(rnp_cfg &cfg);
84 bool cli_rnp_generate_key(cli_rnp_t *rnp, const char *username);
85 /**
86  * @brief Find key(s) matching set of flags and search string.
87  *
88  * @param rnp initialized cli_rnp_t object.
89  * @param keys search results will be added here, leaving already existing items.
90  * @param str search string: may be part of the userid, keyid, fingerprint or grip.
91  * @param flags combination of the following flags:
92  *              CLI_SEARCH_SECRET : require key to be secret,
93  *              CLI_SEARCH_SUBKEYS : include subkeys to the results (see
94  *                CLI_SEARCH_SUBKEYS_AFTER description).
95  *              CLI_SEARCH_FIRST_ONLY : include only first key found
96  *              CLI_SEARCH_SUBKEYS_AFTER : for each primary key add its subkeys after the main
97  *                key. This changes behaviour of subkey search, since those will be added only
98  *                if subkey is orphaned or primary key matches search.
99  * @return true if operation succeeds and at least one key is found, or false otherwise.
100  */
101 bool cli_rnp_keys_matching_string(cli_rnp_t *                    rnp,
102                                   std::vector<rnp_key_handle_t> &keys,
103                                   const std::string &            str,
104                                   int                            flags);
105 /**
106  * @brief Find key(s) matching set of flags and search string(s).
107  *
108  * @param rnp initialized cli_rnp_t object.
109  * @param keys search results will be put here, overwriting vector's contents.
110  * @param strs set of search strings, may be empty.
111  * @param flags the same flags as for cli_rnp_keys_matching_string(), except additional one:
112  *              CLI_SEARCH_DEFAULT : if no key is found then default key from cli_rnp_t will be
113  *                searched.
114  * @return true if operation succeeds and at least one key is found for each search string, or
115  *         false otherwise.
116  */
117 bool        cli_rnp_keys_matching_strings(cli_rnp_t *                     rnp,
118                                           std::vector<rnp_key_handle_t> & keys,
119                                           const std::vector<std::string> &strs,
120                                           int                             flags);
121 bool        cli_rnp_export_keys(cli_rnp_t *rnp, const char *filter);
122 bool        cli_rnp_export_revocation(cli_rnp_t *rnp, const char *key);
123 bool        cli_rnp_revoke_key(cli_rnp_t *rnp, const char *key);
124 bool        cli_rnp_remove_key(cli_rnp_t *rnp, const char *key);
125 bool        cli_rnp_add_key(cli_rnp_t *rnp);
126 bool        cli_rnp_dump_file(cli_rnp_t *rnp);
127 bool        cli_rnp_armor_file(cli_rnp_t *rnp);
128 bool        cli_rnp_dearmor_file(cli_rnp_t *rnp);
129 bool        cli_rnp_setup(cli_rnp_t *rnp);
130 bool        cli_rnp_protect_file(cli_rnp_t *rnp);
131 bool        cli_rnp_process_file(cli_rnp_t *rnp);
132 std::string cli_rnp_escape_string(const std::string &src);
133 
134 void clear_key_handles(std::vector<rnp_key_handle_t> &keys);
135 
136 const char *json_obj_get_str(json_object *obj, const char *key);
137 int64_t     json_obj_get_int64(json_object *obj, const char *key);
138 bool        rnp_casecmp(const std::string &str1, const std::string &str2);
139 
140 #ifdef _WIN32
141 bool rnp_win_substitute_cmdline_args(int *argc, char ***argv);
142 void rnp_win_clear_args(int argc, char **argv);
143 #endif
144 
145 /* TODO: we should decide what to do with functions/constants/defines below */
146 #define RNP_KEYID_SIZE 8
147 #define RNP_FP_SIZE 20
148 #define RNP_GRIP_SIZE 20
149 
150 #define ERR_MSG(...)                           \
151     do {                                       \
152         (void) fprintf((stderr), __VA_ARGS__); \
153         (void) fprintf((stderr), "\n");        \
154     } while (0)
155 
156 #define EXT_ASC (".asc")
157 #define EXT_SIG (".sig")
158 #define EXT_PGP (".pgp")
159 #define EXT_GPG (".gpg")
160 
161 #define SUBDIRECTORY_GNUPG ".gnupg"
162 #define SUBDIRECTORY_RNP ".rnp"
163 #define PUBRING_KBX "pubring.kbx"
164 #define SECRING_KBX "secring.kbx"
165 #define PUBRING_GPG "pubring.gpg"
166 #define SECRING_GPG "secring.gpg"
167 #define PUBRING_G10 "public-keys-v1.d"
168 #define SECRING_G10 "private-keys-v1.d"
169 
170 #endif
171