Replace use of Sequoia's backend with a custom key store.
- Sequoia's key store doesn't meet pep's needs (in particular, the
ability to search on a key's user id) and trying to shoehorn pep's
needs onto Sequoia's key store abstractions is just introducing
overhead with no appreciable gain in functionality.
- This patch changes the Sequoia backend to use a local sqlite
database to store the public keys.
1 // This file is under GNU General Public License 3.0
4 #define _POSIX_C_SOURCE 200809L
17 #include <sys/types.h>
21 #include "platform_unix.h"
24 #ifndef LOCAL_DB_FILENAME
25 #define LOCAL_DB_FILENAME ".pEp_management.db"
27 #define SYSTEM_DB_FILENAME "system.db"
38 /* FIXME : timegm will miss when linking for x86_64 on android, when supported */
40 time_t timegm(struct tm* const t) {
41 static const time_t kTimeMax = ~(1L << (sizeof(time_t) * CHAR_BIT - 1));
42 static const time_t kTimeMin = (1L << (sizeof(time_t) * CHAR_BIT - 1));
43 time64_t result = timegm64(t);
44 if (result < kTimeMin || result > kTimeMax)
50 char *stpncpy(char *dst, const char *src, size_t n)
58 if ((*d++ = *s++) == 0) {
60 /* NUL pad the remaining n-1 bytes */
70 char *stpcpy(char *dst, const char *src)
72 for (;; ++dst, ++src) {
83 static bool seeded = false;
84 static unsigned short xsubi[3];
87 const long long t = (long long)time(NULL);
88 xsubi[0] = (unsigned short)t;
89 xsubi[1] = (unsigned short)(t>>16);
90 xsubi[2] = (unsigned short)(t>>32);
94 return nrand48(xsubi);
97 const char *android_system_db(void)
99 static char buffer[MAX_PATH];
100 static bool done = false;
104 if(tw_env = getenv("TRUSTWORDS")){
105 char *p = stpncpy(buffer, tw_env, MAX_PATH);
106 ssize_t len = MAX_PATH - (p - buffer) - 2;
108 if (len < strlen(SYSTEM_DB_FILENAME)) {
114 strncpy(p, SYSTEM_DB_FILENAME, len);
125 void uuid_generate_random(pEpUUID out)
129 size_t size = sizeof(uuid_string_t);
132 if ((rc_create = uuid_create(&uuid)) != UUID_RC_OK ||
133 uuid_make(uuid, UUID_MAKE_V1) != UUID_RC_OK ||
134 uuid_export(uuid, UUID_FMT_BIN, &_out, &size) != UUID_RC_OK)
136 memset(out, 0, sizeof(pEpUUID));
139 if (rc_create == UUID_RC_OK)
146 void uuid_unparse_upper(pEpUUID uu, uuid_string_t out)
150 size_t size = sizeof(uuid_string_t);
153 if ((rc_create = uuid_create(&uuid)) != UUID_RC_OK ||
154 uuid_import(uuid, UUID_FMT_BIN, uu, sizeof(pEpUUID)) != UUID_RC_OK ||
155 uuid_export(uuid, UUID_FMT_STR, &_out, &size) != UUID_RC_OK)
157 memset(out, 0, sizeof(uuid_string_t));
161 out[sizeof(uuid_string_t) - 1] = 0;
164 if (rc_create == UUID_RC_OK)
172 #if !defined(BSD) && !defined(__APPLE__)
174 size_t strlcpy(char* dst, const char* src, size_t size) {
175 size_t retval = strlen(src);
176 size_t size_to_copy = (retval < size ? retval : size - 1);
178 // strlcpy doc says src and dst not allowed to overlap, as
179 // it's undefined. So this is acceptable:
180 memcpy((void*)dst, (void*)src, size_to_copy); // no defined error return, but strcpy doesn't either
181 dst[size_to_copy] = '\0';
185 size_t strlcat(char* dst, const char* src, size_t size) {
186 size_t start_len = strnlen(dst, size);
187 if (start_len == size)
188 return size; // no copy, no null termination in size bytes, according to spec
190 size_t add_len = strlen(src);
191 size_t retval = start_len + add_len;
192 size_t size_to_copy = (retval < size ? add_len : (size - start_len) - 1);
194 // strlcat doc says src and dst not allowed to overlap, as
195 // it's undefined. So this is acceptable:
196 memcpy((void*)(dst + start_len), (void*)src, size_to_copy); // no defined error return, but strcpy doesn't either
197 dst[start_len + size_to_copy] = '\0';
202 // FIXME: This may cause problems - this is a quick compatibility fix for netpgp code
203 int regnexec(const regex_t* preg, const char* string,
204 size_t len, size_t nmatch, regmatch_t pmatch[], int eflags) {
205 return regexec(preg, string, nmatch, pmatch, eflags);
212 const char *unix_local_db(void)
214 const char *unix_local_db(int reset)
217 static char buffer[MAX_PATH];
218 static bool done = false;
223 if ((!done) || reset)
227 if((home_env = getenv("HOME"))){
228 char *p = stpncpy(buffer, home_env, MAX_PATH);
229 ssize_t len = MAX_PATH - (p - buffer) - 2;
231 if (len < strlen(LOCAL_DB_FILENAME)) {
237 strncpy(p, LOCAL_DB_FILENAME, len);
247 static const char *gpg_conf_path = ".gnupg";
248 static const char *gpg_conf_name = "gpg.conf";
249 static const char *gpg_agent_conf_name = "gpg-agent.conf";
250 static const char *gpg_conf_empty = "# Created by pEpEngine\n";
253 static bool ensure_gpg_home(const char **conf, const char **home){
255 static bool ensure_gpg_home(const char **conf, const char **home, int reset){
257 static char path[MAX_PATH];
258 static char dirname[MAX_PATH];
259 static bool done = false;
264 if (reset || !done) {
268 char *gpg_home_env = getenv("GNUPGHOME");
269 char *home_env = getenv("HOME");
273 p = stpncpy(path, gpg_home_env, MAX_PATH);
274 len = MAX_PATH - (p - path) - 2;
276 if (len < strlen(gpg_conf_name))
284 p = stpncpy(path, home_env, MAX_PATH);
285 len = MAX_PATH - (p - path) - 3;
287 if (len < strlen(gpg_conf_path) + strlen(gpg_conf_name))
294 strncpy(p, gpg_conf_path, len);
295 p += strlen(gpg_conf_path);
296 len -= strlen(gpg_conf_path) - 1;
304 strncpy(dirname, path, MAX_PATH);
306 strncpy(p, gpg_conf_name, len);
308 if(access(path, F_OK)){
310 if(access(dirname, F_OK )) {
311 mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR);
314 fd = open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
318 len = strlen(gpg_conf_empty);
319 res = write(fd, gpg_conf_empty, len);
332 if(home) *home=dirname;
338 static bool ensure_gpg_agent_conf(const char **agent_conf){
340 static bool ensure_gpg_agent_conf(const char **agent_conf, int reset){
342 static char agent_path[MAX_PATH];
343 static bool done = false;
349 if (!ensure_gpg_home(NULL, &dirname)) /* Then dirname won't be set. */
352 if (reset || !done) {
355 if (!ensure_gpg_home(NULL, &dirname, reset)) /* Then dirname won't be set. */
359 char *p = stpncpy(agent_path, dirname, MAX_PATH);
361 ssize_t len = MAX_PATH - (p - agent_path) - 2;
363 if (len < strlen(gpg_agent_conf_name))
371 strncpy(p, gpg_agent_conf_name, len);
373 if(access(agent_path, F_OK)){
375 if(access(dirname, F_OK )) {
376 mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR);
379 fd = open(agent_path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
383 len = strlen(gpg_conf_empty);
384 res = write(fd, gpg_conf_empty, len);
394 if(agent_conf) *agent_conf=agent_path;
400 const char *gpg_conf(void)
403 if(ensure_gpg_home(&conf, NULL))
408 const char *gpg_conf(int reset)
411 if(ensure_gpg_home(&conf, NULL, reset))
418 const char *gpg_home(void)
421 if(ensure_gpg_home(NULL, &home))
426 const char *gpg_home(int reset)
429 if(ensure_gpg_home(NULL, &home, reset))
436 const char *gpg_agent_conf(void)
438 const char *agent_conf;
439 if(ensure_gpg_agent_conf(&agent_conf))
444 const char *gpg_agent_conf(int reset)
446 const char *agent_conf;
447 if(ensure_gpg_agent_conf(&agent_conf, reset))