1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
|
/*
* Copyright (c) 2017-2019 [Ribose Inc](https://www.ribose.com).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SUPPORT_H_
#define SUPPORT_H_
#include "config.h"
#include <string>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#else
#include "uniwin.h"
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include "rnp.h"
#include "rekey/rnp_key_store.h"
#include "../rnp/fficli.h"
#include "file-utils.h"
#include "crypto/mem.h"
#ifdef _WIN32
#define pipe(fds) _pipe(fds, 256, O_BINARY)
int setenv(const char *name, const char *value, int overwrite);
int unsetenv(const char *name);
#endif
#ifndef HAVE_MKDTEMP
char *mkdtemp(char *templ);
#endif
#ifndef HAVE_REALPATH
#define realpath(N, R) _fullpath((R), (N), _MAX_PATH)
#endif
extern rnp::SecurityContext global_ctx;
off_t file_size(const char *path);
/* Read file contents into the std::string */
std::string file_to_str(const std::string &path);
/* Read binary file contents into the vector */
std::vector<uint8_t> file_to_vec(const std::string &path);
/* Write string contents to the file */
void str_to_file(const std::string &path, const char *str);
/* Concatenate multiple strings into a full path.
* A directory separator is added between components.
* Must be called in between va_start and va_end.
* Final argument of calling function must be NULL.
*/
void vpaths_concat(char *buffer, size_t buffer_size, const char *first, va_list ap);
/* Concatenate multiple strings into a full path.
* Final argument must be NULL.
*/
char *paths_concat(char *buffer, size_t buffer_length, const char *first, ...);
/* Concatenate multiple strings into a full path and
* check that the file exists.
* Final argument must be NULL.
*/
int path_rnp_file_exists(const char *first, ...);
/* Concatenate multiple strings into a full path and
* create the directory.
* Final argument must be NULL.
*/
void path_mkdir(mode_t mode, const char *first, ...);
/* Recursively remove a directory.
* The path must be a full path and must be located in /tmp, for safety.
*/
void delete_recursively(const char *path);
void copy_recursively(const char *src, const char *dst);
/* Creates and returns a temporary directory path.
* Caller must free the string.
*/
char *make_temp_dir(void);
void clean_temp_dir(const char *path);
/* check whether bin value is equals hex string */
bool bin_eq_hex(const uint8_t *data, size_t len, const char *val);
bool hex2mpi(pgp_mpi_t *val, const char *hex);
/* check whether key id is equal to hex string */
bool cmp_keyid(const pgp_key_id_t &id, const std::string &val);
/* check whether key fp is equal to hex string */
bool cmp_keyfp(const pgp_fingerprint_t &fp, const std::string &val);
void test_ffi_init(rnp_ffi_t *ffi);
bool mpi_empty(const pgp_mpi_t &val);
bool write_pass_to_pipe(int fd, size_t count);
/* Setup readable pipe with default password inside */
bool setupPasswordfd(int *pipefd);
/* Common initialization of rnp structure : home path, keystore format and pointer to store
* password fd */
bool setup_cli_rnp_common(cli_rnp_t * rnp,
const char *ks_format,
const char *homedir,
int * pipefd);
/* Initialize key generation params with default values and specified hash algorithm */
void cli_set_default_rsa_key_desc(rnp_cfg &cfg, const char *hash);
// this is a password callback that will always fail
bool failing_password_callback(const pgp_password_ctx_t *ctx,
char * password,
size_t password_size,
void * userdata);
bool ffi_failing_password_provider(rnp_ffi_t ffi,
void * app_ctx,
rnp_key_handle_t key,
const char * pgp_context,
char * buf,
size_t buf_len);
// this is a password callback that should never be called
bool asserting_password_callback(const pgp_password_ctx_t *ctx,
char * password,
size_t password_size,
void * userdata);
bool ffi_asserting_password_provider(rnp_ffi_t ffi,
void * app_ctx,
rnp_key_handle_t key,
const char * pgp_context,
char * buf,
size_t buf_len);
// this is a password callback that just copies the string in userdata to
// the password buffer
bool string_copy_password_callback(const pgp_password_ctx_t *ctx,
char * password,
size_t password_size,
void * userdata);
bool ffi_string_password_provider(rnp_ffi_t ffi,
void * app_ctx,
rnp_key_handle_t key,
const char * pgp_context,
char * buf,
size_t buf_len);
void unused_getkeycb(rnp_ffi_t ffi,
void * app_ctx,
const char *identifier_type,
const char *identifier,
bool secret);
bool unused_getpasscb(rnp_ffi_t ffi,
void * app_ctx,
rnp_key_handle_t key,
const char * pgp_context,
char * buf,
size_t buf_len);
bool starts_with(const std::string &data, const std::string &match);
bool ends_with(const std::string &data, const std::string &match);
std::string fmt(const char *format, ...);
std::string strip_eol(const std::string &str);
std::string lowercase(const std::string &str);
bool check_json_field_str(json_object * obj,
const std::string &field,
const std::string &value);
bool check_json_field_int(json_object *obj, const std::string &field, int value);
bool check_json_field_bool(json_object *obj, const std::string &field, bool value);
bool check_json_pkt_type(json_object *pkt, int tag);
pgp_key_t *rnp_tests_get_key_by_id(rnp_key_store_t * keyring,
const std::string &keyid,
pgp_key_t * after = NULL);
pgp_key_t *rnp_tests_get_key_by_fpr(rnp_key_store_t *keyring, const std::string &keyid);
pgp_key_t *rnp_tests_get_key_by_grip(rnp_key_store_t *keyring, const std::string &grip);
pgp_key_t *rnp_tests_get_key_by_grip(rnp_key_store_t *keyring, const pgp_key_grip_t &grip);
pgp_key_t *rnp_tests_key_search(rnp_key_store_t *keyring, const std::string &uid);
/* key load/reload shortcuts */
void reload_pubring(rnp_ffi_t *ffi);
void reload_keyrings(rnp_ffi_t *ffi);
bool load_keys_gpg(rnp_ffi_t ffi, const std::string &pub, const std::string &sec = "");
bool load_keys_kbx_g10(rnp_ffi_t ffi, const std::string &pub, const std::string &sec = "");
/* key import shortcuts */
bool import_all_keys(rnp_ffi_t ffi, const std::string &path);
bool import_pub_keys(rnp_ffi_t ffi, const std::string &path);
bool import_sec_keys(rnp_ffi_t ffi, const std::string &path);
bool import_all_keys(rnp_ffi_t ffi, const uint8_t *data, size_t len, uint32_t flags = 0);
bool import_pub_keys(rnp_ffi_t ffi, const uint8_t *data, size_t len);
bool import_sec_keys(rnp_ffi_t ffi, const uint8_t *data, size_t len);
/* key export shortcut */
std::vector<uint8_t> export_key(rnp_key_handle_t key,
bool armored = false,
bool secret = false);
/* write transferable key(s) to stream */
bool write_transferable_key(pgp_transferable_key_t &key, pgp_dest_t &dst, bool armor = false);
bool write_transferable_keys(pgp_key_sequence_t &keys, pgp_dest_t *dst, bool armor = false);
/* Dump key to the stdout. Not used in real tests, but useful for artefact generation */
void dump_key_stdout(rnp_key_handle_t key, bool secret = false);
/* some shortcuts for less code */
bool check_key_valid(rnp_key_handle_t key, bool validity);
uint32_t get_key_expiry(rnp_key_handle_t key);
size_t get_key_uids(rnp_key_handle_t key);
bool check_sub_valid(rnp_key_handle_t key, size_t idx, bool validity);
bool check_uid_valid(rnp_key_handle_t key, size_t idx, bool valid);
bool check_uid_primary(rnp_key_handle_t key, size_t idx, bool primary);
void check_loaded_keys(const char * format,
bool armored,
uint8_t * buf,
size_t buf_len,
const char * id_type,
const std::vector<std::string> &expected_ids,
bool secret);
/* create bogus key handle with NULL pub/sec keys */
rnp_key_handle_t bogus_key_handle(rnp_ffi_t ffi);
bool sm2_enabled();
bool aead_eax_enabled();
bool aead_ocb_enabled();
bool aead_ocb_aes_only();
bool twofish_enabled();
bool idea_enabled();
bool brainpool_enabled();
bool blowfish_enabled();
bool cast5_enabled();
bool ripemd160_enabled();
inline size_t
rnp_round_up(size_t n, size_t align_to)
{
if (n % align_to || n == 0) {
n += align_to - (n % align_to);
}
return n;
}
/* load g10/g23 gpg key and verify that it can be
unprotected/protected
*/
bool test_load_gpg_check_key(rnp_key_store_t *pub, rnp_key_store_t *sec, const char *id);
#define MD5_FROM 1325376000
#define SHA1_DATA_FROM 1547856000
#define SHA1_KEY_FROM 1705629600
#endif /* SUPPORT_H_ */
|