1 #include "pEp_internal.h"
2 #include "dynamic_api.h"
3 #include "cryptotech.h"
7 static int init_count = -1;
9 static int user_version(void *_version, int count, char **text, char **name)
13 assert(text && text[0]);
14 if (!(_version && count == 1 && text && text[0]))
17 int *version = (int *) _version;
18 *version = atoi(text[0]);
22 DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
24 PEP_STATUS status = PEP_STATUS_OK;
26 static const char *sql_log;
27 static const char *sql_trustword;
28 static const char *sql_get_identity;
29 static const char *sql_set_person;
30 static const char *sql_set_pgp_keypair;
31 static const char *sql_set_identity;
32 static const char *sql_set_trust;
33 static const char *sql_get_trust;
34 static const char *sql_least_trust;
35 static const char *sql_mark_as_compromized;
36 static const char *sql_crashdump;
37 static const char *sql_languagelist;
38 static const char *sql_i18n_token;
41 static const char *sql_blacklist_add;
42 static const char *sql_blacklist_delete;
43 static const char *sql_blacklist_is_listed;
44 static const char *sql_blacklist_retrieve;
47 static const char *sql_own_key_is_listed;
48 static const char *sql_own_key_retrieve;
51 static const char *sql_sequence_value1;
52 static const char *sql_sequence_value2;
54 // Revocation tracking
55 static const char *sql_set_revoked;
56 static const char *sql_get_revoked;
58 bool in_first = false;
60 assert(sqlite3_threadsafe());
61 if (!sqlite3_threadsafe())
62 return PEP_INIT_SQLITE3_WITHOUT_MUTEX;
64 // a little race condition - but still a race condition
65 // mitigated by calling caveat (see documentation)
73 return PEP_ILLEGAL_VALUE;
77 pEpSession *_session = calloc(1, sizeof(pEpSession));
82 _session->version = PEP_ENGINE_VERSION;
85 if (LOCAL_DB == NULL) {
86 status = PEP_INIT_CANNOT_OPEN_DB;
90 int_result = sqlite3_open_v2(
95 | SQLITE_OPEN_FULLMUTEX
96 | SQLITE_OPEN_PRIVATECACHE,
100 if (int_result != SQLITE_OK) {
101 status = PEP_INIT_CANNOT_OPEN_DB;
105 sqlite3_busy_timeout(_session->db, BUSY_WAIT_TIME);
108 if (SYSTEM_DB == NULL) {
109 status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
113 int_result = sqlite3_open_v2(
114 SYSTEM_DB, &_session->system_db,
116 | SQLITE_OPEN_FULLMUTEX
117 | SQLITE_OPEN_SHAREDCACHE,
121 if (int_result != SQLITE_OK) {
122 status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
126 sqlite3_busy_timeout(_session->system_db, 1000);
128 // increment this when patching DDL
129 #define _DDL_USER_VERSION "1"
132 int_result = sqlite3_exec(
134 "create table version_info (\n"
135 " id integer primary key,\n"
136 " timestamp integer default (datetime('now')) ,\n"
144 if (int_result == SQLITE_OK) {
145 int_result = sqlite3_exec(
147 "pragma user_version = "_DDL_USER_VERSION";\n"
148 "insert or replace into version_info (id, version)"
149 "values (1, '" PEP_ENGINE_VERSION "');",
154 assert(int_result == SQLITE_OK);
157 int_result = sqlite3_exec(
159 "create table if not exists log (\n"
160 " timestamp integer default (datetime('now')) ,\n"
161 " title text not null,\n"
162 " entity text not null,\n"
163 " description text,\n"
166 "create index if not exists log_timestamp on log (\n"
169 "create table if not exists pgp_keypair (\n"
170 " fpr text primary key,\n"
171 " public_id text unique,\n"
172 " private_id text,\n"
173 " created integer,\n"
174 " expires integer,\n"
177 "create index if not exists pgp_keypair_expires on pgp_keypair (\n"
180 "create table if not exists person (\n"
181 " id text primary key,\n"
182 " username text not null,\n"
183 " main_key_id text\n"
184 " references pgp_keypair (fpr)\n"
185 " on delete set null,\n"
189 "create table if not exists identity (\n"
192 " references person (id)\n"
193 " on delete cascade,\n"
194 " main_key_id text\n"
195 " references pgp_keypair (fpr)\n"
196 " on delete set null,\n"
198 " flags integer default (0),"
199 " primary key (address, user_id)\n"
201 "create table if not exists trust (\n"
202 " user_id text not null\n"
203 " references person (id)\n"
204 " on delete cascade,\n"
205 " pgp_keypair_fpr text not null\n"
206 " references pgp_keypair (fpr)\n"
207 " on delete cascade,\n"
208 " comm_type integer not null,\n"
210 " primary key (user_id, pgp_keypair_fpr)\n"
213 "create table if not exists blacklist_keys (\n"
214 " fpr text primary key\n"
217 "create table if not exists sequences(\n"
218 " name text primary key,\n"
219 " value integer default 0\n"
221 "create table if not exists revoked_keys (\n"
222 " revoked_fpr text primary key,\n"
223 " replacement_fpr text not null\n"
224 " references pgp_keypair (fpr)\n"
225 " on delete cascade,\n"
226 " revocation_date integer\n"
233 assert(int_result == SQLITE_OK);
236 int_result = sqlite3_exec(
238 "pragma user_version;",
243 assert(int_result == SQLITE_OK);
246 int_result = sqlite3_exec(
248 "alter table identity\n"
249 " add column flags integer default (0);",
254 assert(int_result == SQLITE_OK);
257 if (version < atoi(_DDL_USER_VERSION)) {
258 int_result = sqlite3_exec(
260 "pragma user_version = "_DDL_USER_VERSION";\n"
261 "insert or replace into version_info (id, version)"
262 "values (1, '" PEP_ENGINE_VERSION "');",
267 assert(int_result == SQLITE_OK);
270 sql_log = "insert into log (title, entity, description, comment)"
271 "values (?1, ?2, ?3, ?4);";
273 sql_get_identity = "select fpr, username, comm_type, lang, flags"
275 " join person on id = identity.user_id"
276 " join pgp_keypair on fpr = identity.main_key_id"
277 " join trust on id = trust.user_id"
278 " and pgp_keypair_fpr = identity.main_key_id"
279 " where address = ?1 and identity.user_id = ?2;";
281 sql_trustword = "select id, word from wordlist where lang = lower(?1) "
284 // Set person, but if already exist, only update.
285 // if main_key_id already set, don't touch.
286 sql_set_person = "insert or replace into person (id, username, lang, main_key_id)"
287 " values (?1, ?2, ?3,"
288 " (select coalesce((select main_key_id from person "
289 " where id = ?1), upper(replace(?4,' ',''))))) ;";
291 sql_set_pgp_keypair = "insert or replace into pgp_keypair (fpr) "
292 "values (upper(replace(?1,' ',''))) ;";
294 sql_set_identity = "insert or replace into identity (address, main_key_id, "
295 "user_id, flags) values (?1, upper(replace(?2,' ','')),"
298 sql_set_trust = "insert or replace into trust (user_id, pgp_keypair_fpr, comm_type) "
299 "values (?1, upper(replace(?2,' ','')), ?3) ;";
301 sql_get_trust = "select comm_type from trust where user_id = ?1 "
302 "and pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
304 sql_least_trust = "select min(comm_type) from trust where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
306 sql_mark_as_compromized = "update trust not indexed set comm_type = 15"
307 " where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
309 sql_crashdump = "select timestamp, title, entity, description, comment"
310 " from log order by timestamp desc limit ?1 ;";
312 sql_languagelist = "select i18n_language.lang, name, phrase from i18n_language join i18n_token using (lang) where i18n_token.id = 1000;" ;
314 sql_i18n_token = "select phrase from i18n_token where lang = lower(?1) and id = ?2 ;";
318 sql_blacklist_add = "insert or replace into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
319 "delete from identity where main_key_id = upper(replace(?1,' ','')) ;"
320 "delete from pgp_keypair where fpr = upper(replace(?1,' ','')) ;";
322 sql_blacklist_delete = "delete from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
324 sql_blacklist_is_listed = "select count(*) from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
326 sql_blacklist_retrieve = "select * from blacklist_keys ;";
330 sql_own_key_is_listed =
331 "select count(*) from ("
332 " select main_key_id from person "
333 " where main_key_id = upper(replace(?1,' ',''))"
334 " and id = '" PEP_OWN_USERID "' "
336 " select main_key_id from identity "
337 " where main_key_id = upper(replace(?1,' ',''))"
338 " and user_id = '" PEP_OWN_USERID "' );";
340 sql_own_key_retrieve = "select main_key_id from person "
341 " where main_key_id is not null"
342 " and id = '" PEP_OWN_USERID "' "
344 " select main_key_id from identity "
345 " where main_key_id is not null"
346 " and user_id = '" PEP_OWN_USERID "' ;";
348 sql_sequence_value1 = "insert or replace into sequences (name, value) "
350 "(select coalesce((select value + 1 from sequences "
351 "where name = ?1), 1 ))) ; ";
352 sql_sequence_value2 = "select value from sequences where name = ?1 ;";
354 sql_set_revoked = "insert or replace into revoked_keys ("
355 " revoked_fpr, replacement_fpr, revocation_date) "
356 "values (upper(replace(?1,' ','')),"
357 " upper(replace(?2,' ','')),"
360 sql_get_revoked = "select revoked_fpr, revocation_date from revoked_keys"
361 " where replacement_fpr = upper(replace(?1,' ','')) ;";
364 int_result = sqlite3_prepare_v2(_session->db, sql_log, (int)strlen(sql_log),
365 &_session->log, NULL);
366 assert(int_result == SQLITE_OK);
368 int_result = sqlite3_prepare_v2(_session->system_db, sql_trustword,
369 (int)strlen(sql_trustword), &_session->trustword, NULL);
370 assert(int_result == SQLITE_OK);
372 int_result = sqlite3_prepare_v2(_session->db, sql_get_identity,
373 (int)strlen(sql_get_identity), &_session->get_identity, NULL);
374 assert(int_result == SQLITE_OK);
376 int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
377 (int)strlen(sql_set_person), &_session->set_person, NULL);
378 assert(int_result == SQLITE_OK);
380 int_result = sqlite3_prepare_v2(_session->db, sql_set_pgp_keypair,
381 (int)strlen(sql_set_pgp_keypair), &_session->set_pgp_keypair, NULL);
382 assert(int_result == SQLITE_OK);
384 int_result = sqlite3_prepare_v2(_session->db, sql_set_identity,
385 (int)strlen(sql_set_identity), &_session->set_identity, NULL);
386 assert(int_result == SQLITE_OK);
388 int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
389 (int)strlen(sql_set_trust), &_session->set_trust, NULL);
390 assert(int_result == SQLITE_OK);
392 int_result = sqlite3_prepare_v2(_session->db, sql_get_trust,
393 (int)strlen(sql_get_trust), &_session->get_trust, NULL);
394 assert(int_result == SQLITE_OK);
396 int_result = sqlite3_prepare_v2(_session->db, sql_least_trust,
397 (int)strlen(sql_least_trust), &_session->least_trust, NULL);
398 assert(int_result == SQLITE_OK);
400 int_result = sqlite3_prepare_v2(_session->db, sql_mark_as_compromized,
401 (int)strlen(sql_mark_as_compromized), &_session->mark_compromized, NULL);
402 assert(int_result == SQLITE_OK);
404 int_result = sqlite3_prepare_v2(_session->db, sql_crashdump,
405 (int)strlen(sql_crashdump), &_session->crashdump, NULL);
406 assert(int_result == SQLITE_OK);
408 int_result = sqlite3_prepare_v2(_session->system_db, sql_languagelist,
409 (int)strlen(sql_languagelist), &_session->languagelist, NULL);
410 assert(int_result == SQLITE_OK);
412 int_result = sqlite3_prepare_v2(_session->system_db, sql_i18n_token,
413 (int)strlen(sql_i18n_token), &_session->i18n_token, NULL);
414 assert(int_result == SQLITE_OK);
418 int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_add,
419 (int)strlen(sql_blacklist_add), &_session->blacklist_add, NULL);
420 assert(int_result == SQLITE_OK);
422 int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_delete,
423 (int)strlen(sql_blacklist_delete), &_session->blacklist_delete, NULL);
424 assert(int_result == SQLITE_OK);
426 int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_is_listed,
427 (int)strlen(sql_blacklist_is_listed), &_session->blacklist_is_listed, NULL);
428 assert(int_result == SQLITE_OK);
430 int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_retrieve,
431 (int)strlen(sql_blacklist_retrieve), &_session->blacklist_retrieve, NULL);
432 assert(int_result == SQLITE_OK);
436 int_result = sqlite3_prepare_v2(_session->db, sql_own_key_is_listed,
437 (int)strlen(sql_own_key_is_listed), &_session->own_key_is_listed, NULL);
438 assert(int_result == SQLITE_OK);
440 int_result = sqlite3_prepare_v2(_session->db, sql_own_key_retrieve,
441 (int)strlen(sql_own_key_retrieve), &_session->own_key_retrieve, NULL);
442 assert(int_result == SQLITE_OK);
446 int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value1,
447 (int)strlen(sql_sequence_value1), &_session->sequence_value1, NULL);
448 assert(int_result == SQLITE_OK);
450 int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value2,
451 (int)strlen(sql_sequence_value2), &_session->sequence_value2, NULL);
452 assert(int_result == SQLITE_OK);
454 // Revocation tracking
456 int_result = sqlite3_prepare_v2(_session->db, sql_set_revoked,
457 (int)strlen(sql_set_revoked), &_session->set_revoked, NULL);
458 assert(int_result == SQLITE_OK);
460 int_result = sqlite3_prepare_v2(_session->db, sql_get_revoked,
461 (int)strlen(sql_get_revoked), &_session->get_revoked, NULL);
462 assert(int_result == SQLITE_OK);
464 status = init_cryptotech(_session, in_first);
465 if (status != PEP_STATUS_OK)
468 status = init_transport_system(_session, in_first);
469 if (status != PEP_STATUS_OK)
472 status = log_event(_session, "init", "pEp " PEP_ENGINE_VERSION, NULL, NULL);
473 if (status != PEP_STATUS_OK)
478 _session->passive_mode = false;
479 _session->unencrypted_subject = false;
481 _session->use_only_own_private_keys = true;
482 #elif TARGET_OS_IPHONE
483 _session->use_only_own_private_keys = true;
485 _session->use_only_own_private_keys = false;
489 return PEP_STATUS_OK;
492 status = PEP_OUT_OF_MEMORY;
499 DYNAMIC_API void release(PEP_SESSION session)
501 bool out_last = false;
503 assert(init_count >= 0);
506 if (!((init_count >= 0) && session))
509 // a small race condition but still a race condition
510 // mitigated by calling caveat (see documentation)
519 sqlite3_finalize(session->log);
520 if (session->trustword)
521 sqlite3_finalize(session->trustword);
522 if (session->get_identity)
523 sqlite3_finalize(session->get_identity);
524 if (session->set_person)
525 sqlite3_finalize(session->set_person);
526 if (session->set_pgp_keypair)
527 sqlite3_finalize(session->set_pgp_keypair);
528 if (session->set_identity)
529 sqlite3_finalize(session->set_identity);
530 if (session->set_trust)
531 sqlite3_finalize(session->set_trust);
532 if (session->get_trust)
533 sqlite3_finalize(session->get_trust);
534 if (session->least_trust)
535 sqlite3_finalize(session->least_trust);
536 if (session->mark_compromized)
537 sqlite3_finalize(session->mark_compromized);
538 if (session->crashdump)
539 sqlite3_finalize(session->crashdump);
540 if (session->languagelist)
541 sqlite3_finalize(session->languagelist);
542 if (session->i18n_token)
543 sqlite3_finalize(session->i18n_token);
544 if (session->blacklist_add)
545 sqlite3_finalize(session->blacklist_add);
546 if (session->blacklist_delete)
547 sqlite3_finalize(session->blacklist_delete);
548 if (session->blacklist_is_listed)
549 sqlite3_finalize(session->blacklist_is_listed);
550 if (session->blacklist_retrieve)
551 sqlite3_finalize(session->blacklist_retrieve);
554 sqlite3_close_v2(session->db);
555 if (session->system_db)
556 sqlite3_close_v2(session->system_db);
559 release_transport_system(session, out_last);
560 release_cryptotech(session, out_last);
566 DYNAMIC_API void config_passive_mode(PEP_SESSION session, bool enable)
569 session->passive_mode = enable;
572 DYNAMIC_API void config_unencrypted_subject(PEP_SESSION session, bool enable)
575 session->unencrypted_subject = enable;
578 DYNAMIC_API void config_use_only_own_private_keys(PEP_SESSION session, bool enable)
581 session->use_only_own_private_keys = enable;
584 DYNAMIC_API PEP_STATUS log_event(
588 const char *description,
592 PEP_STATUS status = PEP_STATUS_OK;
599 if (!(session && title && entity))
600 return PEP_ILLEGAL_VALUE;
602 sqlite3_reset(session->log);
603 sqlite3_bind_text(session->log, 1, title, -1, SQLITE_STATIC);
604 sqlite3_bind_text(session->log, 2, entity, -1, SQLITE_STATIC);
606 sqlite3_bind_text(session->log, 3, description, -1, SQLITE_STATIC);
608 sqlite3_bind_null(session->log, 3);
610 sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
612 sqlite3_bind_null(session->log, 4);
614 result = sqlite3_step(session->log);
615 assert(result == SQLITE_DONE || result == SQLITE_BUSY);
616 if (result != SQLITE_DONE && result != SQLITE_BUSY)
617 status = PEP_UNKNOWN_ERROR;
618 } while (result == SQLITE_BUSY);
619 sqlite3_reset(session->log);
624 DYNAMIC_API PEP_STATUS trustword(
625 PEP_SESSION session, uint16_t value, const char *lang,
626 char **word, size_t *wsize
629 PEP_STATUS status = PEP_STATUS_OK;
635 if (!(session && word && wsize))
636 return PEP_ILLEGAL_VALUE;
644 assert((lang[0] >= 'A' && lang[0] <= 'Z')
645 || (lang[0] >= 'a' && lang[0] <= 'z'));
646 assert((lang[1] >= 'A' && lang[1] <= 'Z')
647 || (lang[1] >= 'a' && lang[1] <= 'z'));
648 assert(lang[2] == 0);
650 sqlite3_reset(session->trustword);
651 sqlite3_bind_text(session->trustword, 1, lang, -1, SQLITE_STATIC);
652 sqlite3_bind_int(session->trustword, 2, value);
654 const int result = sqlite3_step(session->trustword);
655 if (result == SQLITE_ROW) {
656 *word = strdup((const char *) sqlite3_column_text(session->trustword,
659 *wsize = sqlite3_column_bytes(session->trustword, 1);
661 status = PEP_OUT_OF_MEMORY;
663 status = PEP_TRUSTWORD_NOT_FOUND;
665 sqlite3_reset(session->trustword);
669 DYNAMIC_API PEP_STATUS trustwords(
670 PEP_SESSION session, const char *fingerprint, const char *lang,
671 char **words, size_t *wsize, int max_words
674 const char *source = fingerprint;
684 assert(max_words >= 0);
686 if (!(session && fingerprint && words && wsize && max_words >= 0))
687 return PEP_ILLEGAL_VALUE;
692 buffer = calloc(1, MAX_TRUSTWORDS_SPACE);
695 return PEP_OUT_OF_MEMORY;
698 fsize = strlen(fingerprint);
700 if (!lang || !lang[0])
703 assert((lang[0] >= 'A' && lang[0] <= 'Z')
704 || (lang[0] >= 'a' && lang[0] <= 'z'));
705 assert((lang[1] >= 'A' && lang[1] <= 'Z')
706 || (lang[1] >= 'a' && lang[1] <= 'z'));
707 assert(lang[2] == 0);
710 while (source < fingerprint + fsize) {
716 for (value=0, j=0; j < 4 && source < fingerprint + fsize; ) {
717 if (*source >= 'a' && *source <= 'f')
718 value += (*source - 'a' + 10) << (3 - j++) * 4;
719 else if (*source >= 'A' && *source <= 'F')
720 value += (*source - 'A' + 10) << (3 - j++) * 4;
721 else if (*source >= '0' && *source <= '9')
722 value += (*source - '0') << (3 - j++) * 4;
727 _status = trustword(session, value, lang, &word, &_wsize);
728 if (_status == PEP_OUT_OF_MEMORY) {
730 return PEP_OUT_OF_MEMORY;
734 return PEP_TRUSTWORD_NOT_FOUND;
737 if (dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1) {
738 strncpy(dest, word, _wsize);
744 break; // buffer full
747 if (source < fingerprint + fsize
748 && dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1)
752 if (max_words && n_words >= max_words)
757 *wsize = dest - buffer;
758 return PEP_STATUS_OK;
761 pEp_identity *new_identity(
762 const char *address, const char *fpr, const char *user_id,
766 pEp_identity *result = calloc(1, sizeof(pEp_identity));
770 result->address = strdup(address);
771 assert(result->address);
772 if (result->address == NULL) {
778 result->fpr = strdup(fpr);
780 if (result->fpr == NULL) {
781 free_identity(result);
786 result->user_id = strdup(user_id);
787 assert(result->user_id);
788 if (result->user_id == NULL) {
789 free_identity(result);
794 result->username = strdup(username);
795 assert(result->username);
796 if (result->username == NULL) {
797 free_identity(result);
805 pEp_identity *identity_dup(const pEp_identity *src)
809 pEp_identity *dup = new_identity(src->address, src->fpr, src->user_id, src->username);
814 dup->comm_type = src->comm_type;
815 dup->lang[0] = src->lang[0];
816 dup->lang[1] = src->lang[1];
819 dup->flags = src->flags;
824 void free_identity(pEp_identity *identity)
827 free(identity->address);
829 free(identity->user_id);
830 free(identity->username);
835 DYNAMIC_API PEP_STATUS get_identity(
839 pEp_identity **identity
842 PEP_STATUS status = PEP_STATUS_OK;
843 static pEp_identity *_identity;
850 if (!(session && address && address[0] && identity))
851 return PEP_ILLEGAL_VALUE;
855 sqlite3_reset(session->get_identity);
856 sqlite3_bind_text(session->get_identity, 1, address, -1, SQLITE_STATIC);
857 sqlite3_bind_text(session->get_identity, 2, user_id, -1, SQLITE_STATIC);
859 const int result = sqlite3_step(session->get_identity);
862 _identity = new_identity(
864 (const char *) sqlite3_column_text(session->get_identity, 0),
866 (const char *) sqlite3_column_text(session->get_identity, 1)
869 if (_identity == NULL)
870 return PEP_OUT_OF_MEMORY;
872 _identity->comm_type = (PEP_comm_type) sqlite3_column_int(session->get_identity, 2);
873 const char* const _lang = (const char *) sqlite3_column_text(session->get_identity, 3);
874 if (_lang && _lang[0]) {
875 assert(_lang[0] >= 'a' && _lang[0] <= 'z');
876 assert(_lang[1] >= 'a' && _lang[1] <= 'z');
877 assert(_lang[2] == 0);
878 _identity->lang[0] = _lang[0];
879 _identity->lang[1] = _lang[1];
880 _identity->lang[2] = 0;
882 _identity->flags = (unsigned int) sqlite3_column_int(session->get_identity, 4);
883 *identity = _identity;
886 status = PEP_CANNOT_FIND_IDENTITY;
890 sqlite3_reset(session->get_identity);
894 DYNAMIC_API PEP_STATUS set_identity(
895 PEP_SESSION session, const pEp_identity *identity
902 assert(identity->address);
903 assert(identity->fpr);
904 assert(identity->user_id);
905 assert(identity->username);
907 if (!(session && identity && identity->address && identity->fpr &&
908 identity->user_id && identity->username))
909 return PEP_ILLEGAL_VALUE;
912 PEP_STATUS status = blacklist_is_listed(session, identity->fpr, &listed);
913 assert(status == PEP_STATUS_OK);
914 if (status != PEP_STATUS_OK)
918 return PEP_KEY_BLACKLISTED;
920 sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
922 sqlite3_reset(session->set_person);
923 sqlite3_bind_text(session->set_person, 1, identity->user_id, -1,
925 sqlite3_bind_text(session->set_person, 2, identity->username, -1,
927 if (identity->lang[0])
928 sqlite3_bind_text(session->set_person, 3, identity->lang, 1,
931 sqlite3_bind_null(session->set_person, 3);
932 sqlite3_bind_text(session->set_person, 4, identity->fpr, -1,
934 result = sqlite3_step(session->set_person);
935 sqlite3_reset(session->set_person);
936 if (result != SQLITE_DONE) {
937 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
938 return PEP_CANNOT_SET_PERSON;
941 sqlite3_reset(session->set_pgp_keypair);
942 sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
944 result = sqlite3_step(session->set_pgp_keypair);
945 sqlite3_reset(session->set_pgp_keypair);
946 if (result != SQLITE_DONE) {
947 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
948 return PEP_CANNOT_SET_PGP_KEYPAIR;
951 sqlite3_reset(session->set_identity);
952 sqlite3_bind_text(session->set_identity, 1, identity->address, -1,
954 sqlite3_bind_text(session->set_identity, 2, identity->fpr, -1,
956 sqlite3_bind_text(session->set_identity, 3, identity->user_id, -1,
958 sqlite3_bind_int(session->set_trust, 4, identity->flags);
959 result = sqlite3_step(session->set_identity);
960 sqlite3_reset(session->set_identity);
961 if (result != SQLITE_DONE) {
962 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
963 return PEP_CANNOT_SET_IDENTITY;
966 sqlite3_reset(session->set_trust);
967 sqlite3_bind_text(session->set_trust, 1, identity->user_id, -1,
969 sqlite3_bind_text(session->set_trust, 2, identity->fpr, -1,
971 sqlite3_bind_int(session->set_trust, 3, identity->comm_type);
972 result = sqlite3_step(session->set_trust);
973 sqlite3_reset(session->set_trust);
974 if (result != SQLITE_DONE) {
975 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
976 return PEP_CANNOT_SET_TRUST;
979 result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
980 if (result == SQLITE_OK)
981 return PEP_STATUS_OK;
983 return PEP_COMMIT_FAILED;
986 DYNAMIC_API PEP_STATUS mark_as_compromized(
994 assert(fpr && fpr[0]);
996 if (!(session && fpr && fpr[0]))
997 return PEP_ILLEGAL_VALUE;
999 sqlite3_reset(session->mark_compromized);
1000 sqlite3_bind_text(session->mark_compromized, 1, fpr, -1,
1002 result = sqlite3_step(session->mark_compromized);
1003 sqlite3_reset(session->mark_compromized);
1005 if (result != SQLITE_DONE)
1006 return PEP_CANNOT_SET_TRUST;
1008 return PEP_STATUS_OK;
1011 void pEp_free(void *p)
1016 DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
1018 PEP_STATUS status = PEP_STATUS_OK;
1023 assert(identity->user_id);
1024 assert(identity->user_id[0]);
1025 assert(identity->fpr);
1026 assert(identity->fpr[0]);
1028 if (!(session && identity && identity->user_id && identity->user_id[0] &&
1029 identity->fpr && identity->fpr[0]))
1030 return PEP_ILLEGAL_VALUE;
1032 identity->comm_type = PEP_ct_unknown;
1034 sqlite3_reset(session->get_trust);
1035 sqlite3_bind_text(session->get_trust, 1, identity->user_id, -1, SQLITE_STATIC);
1036 sqlite3_bind_text(session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
1038 result = sqlite3_step(session->get_trust);
1041 int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust, 0);
1042 identity->comm_type = comm_type;
1047 status = PEP_CANNOT_FIND_IDENTITY;
1050 sqlite3_reset(session->get_trust);
1054 DYNAMIC_API PEP_STATUS least_trust(
1055 PEP_SESSION session,
1057 PEP_comm_type *comm_type
1060 PEP_STATUS status = PEP_STATUS_OK;
1067 if (!(session && fpr && comm_type))
1068 return PEP_ILLEGAL_VALUE;
1070 *comm_type = PEP_ct_unknown;
1072 sqlite3_reset(session->least_trust);
1073 sqlite3_bind_text(session->least_trust, 1, fpr, -1, SQLITE_STATIC);
1075 result = sqlite3_step(session->least_trust);
1078 int _comm_type = sqlite3_column_int(session->least_trust, 0);
1079 *comm_type = (PEP_comm_type) _comm_type;
1083 status = PEP_CANNOT_FIND_IDENTITY;
1086 sqlite3_reset(session->least_trust);
1090 DYNAMIC_API PEP_STATUS decrypt_and_verify(
1091 PEP_SESSION session, const char *ctext, size_t csize,
1092 char **ptext, size_t *psize, stringlist_t **keylist
1102 if (!(session && ctext && csize && ptext && psize && keylist && keylist))
1103 return PEP_ILLEGAL_VALUE;
1105 return session->cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify(session, ctext, csize, ptext, psize, keylist);
1108 DYNAMIC_API PEP_STATUS encrypt_and_sign(
1109 PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
1110 size_t psize, char **ctext, size_t *csize
1120 if (!(session && keylist && ptext && psize && ctext && csize))
1121 return PEP_ILLEGAL_VALUE;
1123 return session->cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign(session, keylist, ptext, psize, ctext, csize);
1126 DYNAMIC_API PEP_STATUS verify_text(
1127 PEP_SESSION session, const char *text, size_t size,
1128 const char *signature, size_t sig_size, stringlist_t **keylist
1138 if (!(session && text && size && signature && sig_size && keylist))
1139 return PEP_ILLEGAL_VALUE;
1141 return session->cryptotech[PEP_crypt_OpenPGP].verify_text(session, text, size, signature, sig_size, keylist);
1144 DYNAMIC_API PEP_STATUS delete_keypair(PEP_SESSION session, const char *fpr)
1149 if (!(session && fpr))
1150 return PEP_ILLEGAL_VALUE;
1152 return session->cryptotech[PEP_crypt_OpenPGP].delete_keypair(session, fpr);
1155 DYNAMIC_API PEP_STATUS export_key(
1156 PEP_SESSION session, const char *fpr, char **key_data, size_t *size
1164 if (!(session && fpr && key_data && size))
1165 return PEP_ILLEGAL_VALUE;
1167 return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr, key_data, size);
1170 DYNAMIC_API PEP_STATUS find_keys(
1171 PEP_SESSION session, const char *pattern, stringlist_t **keylist
1178 if (!(session && pattern && keylist))
1179 return PEP_ILLEGAL_VALUE;
1181 return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern, keylist);
1184 DYNAMIC_API PEP_STATUS generate_keypair(
1185 PEP_SESSION session, pEp_identity *identity
1190 assert(identity->address);
1191 assert(identity->fpr == NULL || identity->fpr[0] == 0);
1192 assert(identity->username);
1194 if (!(session && identity && identity->address &&
1195 (identity->fpr == NULL || identity->fpr[0] == 0) && identity->username))
1196 return PEP_ILLEGAL_VALUE;
1198 return session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session, identity);
1201 DYNAMIC_API PEP_STATUS get_key_rating(
1202 PEP_SESSION session,
1204 PEP_comm_type *comm_type
1211 if (!(session && fpr && comm_type))
1212 return PEP_ILLEGAL_VALUE;
1214 return session->cryptotech[PEP_crypt_OpenPGP].get_key_rating(session, fpr, comm_type);
1217 DYNAMIC_API PEP_STATUS import_key(
1218 PEP_SESSION session,
1219 const char *key_data,
1221 identity_list **private_keys
1227 if (!(session && key_data))
1228 return PEP_ILLEGAL_VALUE;
1230 return session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data, size, private_keys);
1233 DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
1238 if (!(session && pattern))
1239 return PEP_ILLEGAL_VALUE;
1241 return session->cryptotech[PEP_crypt_OpenPGP].recv_key(session, pattern);
1244 DYNAMIC_API PEP_STATUS send_key(PEP_SESSION session, const char *pattern)
1249 if (!(session && pattern))
1250 return PEP_ILLEGAL_VALUE;
1252 return session->cryptotech[PEP_crypt_OpenPGP].send_key(session, pattern);
1255 DYNAMIC_API PEP_STATUS renew_key(
1256 PEP_SESSION session,
1264 if (!(session && fpr))
1265 return PEP_ILLEGAL_VALUE;
1267 return session->cryptotech[PEP_crypt_OpenPGP].renew_key(session, fpr, ts);
1270 DYNAMIC_API PEP_STATUS revoke_key(
1271 PEP_SESSION session,
1279 if (!(session && fpr))
1280 return PEP_ILLEGAL_VALUE;
1282 return session->cryptotech[PEP_crypt_OpenPGP].revoke_key(session, fpr,
1286 DYNAMIC_API PEP_STATUS key_expired(
1287 PEP_SESSION session,
1297 if (!(session && fpr && expired))
1298 return PEP_ILLEGAL_VALUE;
1300 return session->cryptotech[PEP_crypt_OpenPGP].key_expired(session, fpr,
1304 DYNAMIC_API PEP_STATUS key_revoked(
1305 PEP_SESSION session,
1314 if (!(session && fpr && revoked))
1315 return PEP_ILLEGAL_VALUE;
1317 return session->cryptotech[PEP_crypt_OpenPGP].key_revoked(session, fpr,
1321 static void _clean_log_value(char *text)
1324 for (char *c = text; *c; c++) {
1325 if (*c < 32 && *c != '\n')
1333 static char *_concat_string(char *str1, const char *str2, char delim)
1335 str2 = str2 ? str2 : "";
1336 size_t len1 = str1 ? strlen(str1) : 0;
1337 size_t len2 = strlen(str2);
1338 size_t len = len1 + len2 + 3;
1339 char * result = realloc(str1, len + 1);
1343 strcpy(result + len1 + 1, str2);
1344 result[len - 2] = '"';
1345 result[len - 1] = delim;
1355 DYNAMIC_API PEP_STATUS get_crashdump_log(
1356 PEP_SESSION session,
1361 PEP_STATUS status = PEP_STATUS_OK;
1362 char *_logdata= NULL;
1365 assert(maxlines >= 0 && maxlines <= CRASHDUMP_MAX_LINES);
1368 if (!(session && logdata && maxlines >= 0 && maxlines <=
1369 CRASHDUMP_MAX_LINES))
1370 return PEP_ILLEGAL_VALUE;
1374 int limit = maxlines ? maxlines : CRASHDUMP_DEFAULT_LINES;
1375 const char *timestamp = NULL;
1376 const char *title = NULL;
1377 const char *entity = NULL;
1378 const char *desc = NULL;
1379 const char *comment = NULL;
1381 sqlite3_reset(session->crashdump);
1382 sqlite3_bind_int(session->crashdump, 1, limit);
1387 result = sqlite3_step(session->crashdump);
1390 timestamp = (const char *) sqlite3_column_text(session->crashdump, 0);
1391 title = (const char *) sqlite3_column_text(session->crashdump, 1);
1392 entity = (const char *) sqlite3_column_text(session->crashdump, 2);
1393 desc = (const char *) sqlite3_column_text(session->crashdump, 3);
1394 comment = (const char *) sqlite3_column_text(session->crashdump, 4);
1396 _logdata = _concat_string(_logdata, timestamp, ',');
1397 if (_logdata == NULL)
1400 _logdata = _concat_string(_logdata, title, ',');
1401 if (_logdata == NULL)
1404 _logdata = _concat_string(_logdata, entity, ',');
1405 if (_logdata == NULL)
1408 _logdata = _concat_string(_logdata, desc, ',');
1409 if (_logdata == NULL)
1412 _logdata = _concat_string(_logdata, comment, '\n');
1413 if (_logdata == NULL)
1416 _clean_log_value(_logdata);
1423 status = PEP_UNKNOWN_ERROR;
1424 result = SQLITE_DONE;
1426 } while (result != SQLITE_DONE);
1428 sqlite3_reset(session->crashdump);
1429 if (status == PEP_STATUS_OK)
1430 *logdata = _logdata;
1435 status = PEP_OUT_OF_MEMORY;
1441 DYNAMIC_API PEP_STATUS get_languagelist(
1442 PEP_SESSION session,
1446 PEP_STATUS status = PEP_STATUS_OK;
1447 char *_languages= NULL;
1452 if (!(session && languages))
1453 return PEP_ILLEGAL_VALUE;
1457 const char *lang = NULL;
1458 const char *name = NULL;
1459 const char *phrase = NULL;
1461 sqlite3_reset(session->languagelist);
1466 result = sqlite3_step(session->languagelist);
1469 lang = (const char *) sqlite3_column_text(session->languagelist, 0);
1470 name = (const char *) sqlite3_column_text(session->languagelist, 1);
1471 phrase = (const char *) sqlite3_column_text(session->languagelist, 2);
1473 _languages = _concat_string(_languages, lang, ',');
1474 if (_languages == NULL)
1477 _languages = _concat_string(_languages, name, ',');
1478 if (_languages == NULL)
1481 _languages = _concat_string(_languages, phrase, '\n');
1482 if (_languages == NULL)
1491 status = PEP_UNKNOWN_ERROR;
1492 result = SQLITE_DONE;
1494 } while (result != SQLITE_DONE);
1496 sqlite3_reset(session->languagelist);
1497 if (status == PEP_STATUS_OK)
1498 *languages = _languages;
1503 status = PEP_OUT_OF_MEMORY;
1509 DYNAMIC_API PEP_STATUS get_phrase(
1510 PEP_SESSION session,
1516 PEP_STATUS status = PEP_STATUS_OK;
1518 assert(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase);
1519 if (!(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase))
1520 return PEP_ILLEGAL_VALUE;
1524 sqlite3_reset(session->i18n_token);
1525 sqlite3_bind_text(session->i18n_token, 1, lang, -1, SQLITE_STATIC);
1526 sqlite3_bind_int(session->i18n_token, 2, phrase_id);
1528 const char *_phrase = NULL;
1531 result = sqlite3_step(session->i18n_token);
1534 _phrase = (const char *) sqlite3_column_text(session->i18n_token, 0);
1538 status = PEP_PHRASE_NOT_FOUND;
1542 status = PEP_UNKNOWN_ERROR;
1545 if (status == PEP_STATUS_OK) {
1546 *phrase = strdup(_phrase);
1547 if (*phrase == NULL)
1551 sqlite3_reset(session->i18n_token);
1555 status = PEP_OUT_OF_MEMORY;
1561 DYNAMIC_API PEP_STATUS sequence_value(
1562 PEP_SESSION session,
1567 PEP_STATUS status = PEP_STATUS_OK;
1574 if (!(session && name && value))
1575 return PEP_ILLEGAL_VALUE;
1579 sqlite3_reset(session->sequence_value1);
1580 sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
1581 result = sqlite3_step(session->sequence_value1);
1582 assert(result == SQLITE_DONE);
1583 sqlite3_reset(session->sequence_value1);
1584 if (result != SQLITE_DONE) {
1585 status = PEP_UNKNOWN_ERROR;
1588 sqlite3_reset(session->sequence_value2);
1589 sqlite3_bind_text(session->sequence_value2, 1, name, -1, SQLITE_STATIC);
1590 result = sqlite3_step(session->sequence_value2);
1593 int32_t _value = (int32_t)
1594 sqlite3_column_int64(session->sequence_value2, 0);
1599 status = PEP_UNKNOWN_ERROR;
1601 sqlite3_reset(session->sequence_value2);
1606 DYNAMIC_API PEP_STATUS set_revoked(
1607 PEP_SESSION session,
1608 const char *revoked_fpr,
1609 const char *replacement_fpr,
1610 const uint64_t revocation_date
1613 PEP_STATUS status = PEP_STATUS_OK;
1616 revoked_fpr && revoked_fpr[0] &&
1617 replacement_fpr && replacement_fpr[0]
1621 revoked_fpr && revoked_fpr[0] &&
1622 replacement_fpr && replacement_fpr[0]
1624 return PEP_ILLEGAL_VALUE;
1626 sqlite3_reset(session->set_revoked);
1627 sqlite3_bind_text(session->set_revoked, 1, revoked_fpr, -1, SQLITE_STATIC);
1628 sqlite3_bind_text(session->set_revoked, 2, replacement_fpr, -1, SQLITE_STATIC);
1629 sqlite3_bind_int64(session->set_revoked, 3, revocation_date);
1633 result = sqlite3_step(session->set_revoked);
1636 status = PEP_STATUS_OK;
1640 status = PEP_UNKNOWN_ERROR;
1643 sqlite3_reset(session->set_revoked);
1647 DYNAMIC_API PEP_STATUS get_revoked(
1648 PEP_SESSION session,
1651 uint64_t *revocation_date
1654 PEP_STATUS status = PEP_STATUS_OK;
1665 return PEP_ILLEGAL_VALUE;
1667 *revoked_fpr = NULL;
1668 *revocation_date = 0;
1670 sqlite3_reset(session->get_revoked);
1671 sqlite3_bind_text(session->get_revoked, 1, fpr, -1, SQLITE_STATIC);
1675 result = sqlite3_step(session->get_revoked);
1678 *revoked_fpr = strdup((const char *) sqlite3_column_text(session->get_revoked, 0));
1680 *revocation_date = sqlite3_column_int64(session->get_revoked, 1);
1682 status = PEP_OUT_OF_MEMORY;
1687 status = PEP_CANNOT_FIND_IDENTITY;
1690 sqlite3_reset(session->get_revoked);
1695 DYNAMIC_API PEP_STATUS reset_peptest_hack(PEP_SESSION session)
1700 return PEP_ILLEGAL_VALUE;
1702 int int_result = sqlite3_exec(
1704 "delete from identity where address like '%@peptest.ch' ;",
1709 assert(int_result == SQLITE_OK);
1711 return PEP_STATUS_OK;