merge "default" branch into "keysync" branch and resolve 2 minor merge conflicts. Please check whether the resolve was okay.
1 #include "pEp_internal.h"
2 #include "dynamic_api.h"
3 #include "cryptotech.h"
8 static int init_count = -1;
10 static int user_version(void *_version, int count, char **text, char **name)
14 assert(text && text[0]);
15 if (!(_version && count == 1 && text && text[0]))
18 int *version = (int *) _version;
19 *version = atoi(text[0]);
23 DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
25 PEP_STATUS status = PEP_STATUS_OK;
27 static const char *sql_log;
28 static const char *sql_trustword;
29 static const char *sql_get_identity;
30 static const char *sql_set_person;
31 static const char *sql_set_pgp_keypair;
32 static const char *sql_set_identity;
33 static const char *sql_set_identity_flags;
34 static const char *sql_set_trust;
35 static const char *sql_get_trust;
36 static const char *sql_least_trust;
37 static const char *sql_mark_as_compromized;
38 static const char *sql_crashdump;
39 static const char *sql_languagelist;
40 static const char *sql_i18n_token;
43 static const char *sql_blacklist_add;
44 static const char *sql_blacklist_delete;
45 static const char *sql_blacklist_is_listed;
46 static const char *sql_blacklist_retrieve;
49 static const char *sql_own_key_is_listed;
50 static const char *sql_own_identities_retrieve;
53 static const char *sql_sequence_value1;
54 static const char *sql_sequence_value2;
56 // Revocation tracking
57 static const char *sql_set_revoked;
58 static const char *sql_get_revoked;
60 bool in_first = false;
62 assert(sqlite3_threadsafe());
63 if (!sqlite3_threadsafe())
64 return PEP_INIT_SQLITE3_WITHOUT_MUTEX;
66 // a little race condition - but still a race condition
67 // mitigated by calling caveat (see documentation)
75 return PEP_ILLEGAL_VALUE;
79 pEpSession *_session = calloc(1, sizeof(pEpSession));
84 _session->version = PEP_ENGINE_VERSION;
87 if (LOCAL_DB == NULL) {
88 status = PEP_INIT_CANNOT_OPEN_DB;
92 int_result = sqlite3_open_v2(
97 | SQLITE_OPEN_FULLMUTEX
98 | SQLITE_OPEN_PRIVATECACHE,
102 if (int_result != SQLITE_OK) {
103 status = PEP_INIT_CANNOT_OPEN_DB;
107 sqlite3_busy_timeout(_session->db, BUSY_WAIT_TIME);
110 if (SYSTEM_DB == NULL) {
111 status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
115 int_result = sqlite3_open_v2(
116 SYSTEM_DB, &_session->system_db,
118 | SQLITE_OPEN_FULLMUTEX
119 | SQLITE_OPEN_SHAREDCACHE,
123 if (int_result != SQLITE_OK) {
124 status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
128 sqlite3_busy_timeout(_session->system_db, 1000);
130 // increment this when patching DDL
131 #define _DDL_USER_VERSION "2"
134 int_result = sqlite3_exec(
136 "create table if not exists version_info (\n"
137 " id integer primary key,\n"
138 " timestamp integer default (datetime('now')) ,\n"
146 if (int_result == SQLITE_OK) {
147 int_result = sqlite3_exec(
149 "pragma user_version = "_DDL_USER_VERSION";\n"
150 "insert or replace into version_info (id, version)"
151 "values (1, '" PEP_ENGINE_VERSION "');",
156 assert(int_result == SQLITE_OK);
159 int_result = sqlite3_exec(
161 "PRAGMA application_id = 0x23423423;\n"
162 "create table if not exists log (\n"
163 " timestamp integer default (datetime('now')) ,\n"
164 " title text not null,\n"
165 " entity text not null,\n"
166 " description text,\n"
169 "create index if not exists log_timestamp on log (\n"
172 "create table if not exists pgp_keypair (\n"
173 " fpr text primary key,\n"
174 " public_id text unique,\n"
175 " private_id text,\n"
176 " created integer,\n"
177 " expires integer,\n"
179 " flags integer default (0)\n"
181 "create index if not exists pgp_keypair_expires on pgp_keypair (\n"
184 "create table if not exists person (\n"
185 " id text primary key,\n"
186 " username text not null,\n"
187 " main_key_id text\n"
188 " references pgp_keypair (fpr)\n"
189 " on delete set null,\n"
192 " device_group text\n"
194 "create table if not exists identity (\n"
197 " references person (id)\n"
198 " on delete cascade,\n"
199 " main_key_id text\n"
200 " references pgp_keypair (fpr)\n"
201 " on delete set null,\n"
203 " flags integer default (0),"
204 " primary key (address, user_id)\n"
206 "create table if not exists trust (\n"
207 " user_id text not null\n"
208 " references person (id)\n"
209 " on delete cascade,\n"
210 " pgp_keypair_fpr text not null\n"
211 " references pgp_keypair (fpr)\n"
212 " on delete cascade,\n"
213 " comm_type integer not null,\n"
215 " primary key (user_id, pgp_keypair_fpr)\n"
218 "create table if not exists blacklist_keys (\n"
219 " fpr text primary key\n"
222 "create table if not exists sequences(\n"
223 " name text primary key,\n"
224 " value integer default 0\n"
226 "create table if not exists revoked_keys (\n"
227 " revoked_fpr text primary key,\n"
228 " replacement_fpr text not null\n"
229 " references pgp_keypair (fpr)\n"
230 " on delete cascade,\n"
231 " revocation_date integer\n"
238 assert(int_result == SQLITE_OK);
241 int_result = sqlite3_exec(
243 "pragma user_version;",
248 assert(int_result == SQLITE_OK);
251 int_result = sqlite3_exec(
253 "alter table identity\n"
254 " add column flags integer default (0);\n",
259 assert(int_result == SQLITE_OK);
263 int_result = sqlite3_exec(
265 "alter table pgp_keypair\n"
266 " add column flags integer default (0);\n"
267 "alter table person\n"
268 " add column device_group text;\n",
273 assert(int_result == SQLITE_OK);
276 if (version < atoi(_DDL_USER_VERSION)) {
277 int_result = sqlite3_exec(
279 "pragma user_version = "_DDL_USER_VERSION";\n"
280 "insert or replace into version_info (id, version)"
281 "values (1, '" PEP_ENGINE_VERSION "');",
286 assert(int_result == SQLITE_OK);
289 sql_log = "insert into log (title, entity, description, comment)"
290 "values (?1, ?2, ?3, ?4);";
292 sql_get_identity = "select fpr, username, comm_type, lang,"
293 " identity.flags | pgp_keypair.flags"
295 " join person on id = identity.user_id"
296 " join pgp_keypair on fpr = identity.main_key_id"
297 " join trust on id = trust.user_id"
298 " and pgp_keypair_fpr = identity.main_key_id"
299 " where address = ?1 and identity.user_id = ?2;";
301 sql_trustword = "select id, word from wordlist where lang = lower(?1) "
304 // Set person, but if already exist, only update.
305 // if main_key_id already set, don't touch.
306 sql_set_person = "insert or replace into person (id, username, lang, main_key_id)"
307 " values (?1, ?2, ?3,"
308 " (select coalesce((select main_key_id from person "
309 " where id = ?1), upper(replace(?4,' ',''))))) ;";
311 sql_set_pgp_keypair = "insert or replace into pgp_keypair (fpr) "
312 "values (upper(replace(?1,' ',''))) ;";
314 sql_set_identity = "insert or replace into identity (address, main_key_id, "
315 "user_id, flags) values (?1, upper(replace(?2,' ','')),"
318 sql_set_identity_flags = "update identity set flags = ?1 & 255 "
319 "where address = ?2 and user_id = ?3 ;";
321 sql_set_trust = "insert or replace into trust (user_id, pgp_keypair_fpr, comm_type) "
322 "values (?1, upper(replace(?2,' ','')), ?3) ;";
324 sql_get_trust = "select comm_type from trust where user_id = ?1 "
325 "and pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
327 sql_least_trust = "select min(comm_type) from trust where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
329 sql_mark_as_compromized = "update trust not indexed set comm_type = 15"
330 " where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
332 sql_crashdump = "select timestamp, title, entity, description, comment"
333 " from log order by timestamp desc limit ?1 ;";
335 sql_languagelist = "select i18n_language.lang, name, phrase from i18n_language join i18n_token using (lang) where i18n_token.id = 1000;" ;
337 sql_i18n_token = "select phrase from i18n_token where lang = lower(?1) and id = ?2 ;";
341 sql_blacklist_add = "insert or replace into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
342 "delete from identity where main_key_id = upper(replace(?1,' ','')) ;"
343 "delete from pgp_keypair where fpr = upper(replace(?1,' ','')) ;";
345 sql_blacklist_delete = "delete from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
347 sql_blacklist_is_listed = "select count(*) from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
349 sql_blacklist_retrieve = "select * from blacklist_keys ;";
353 sql_own_key_is_listed =
354 "select count(*) from ("
355 " select main_key_id from person "
356 " where main_key_id = upper(replace(?1,' ',''))"
357 " and id = '" PEP_OWN_USERID "' "
359 " select main_key_id from identity "
360 " where main_key_id = upper(replace(?1,' ',''))"
361 " and user_id = '" PEP_OWN_USERID "' );";
363 sql_own_identities_retrieve = "select address, fpr, username, '" PEP_OWN_USERID "',"
364 " comm_type, lang, identity.flags | pgp_keypair.flags"
366 " join person on id = identity.user_id"
367 " join pgp_keypair on fpr = identity.main_key_id"
368 " join trust on id = trust.user_id"
369 " and pgp_keypair_fpr = identity.main_key_id"
370 " where identity.user_id = '" PEP_OWN_USERID "';";
372 sql_sequence_value1 = "insert or replace into sequences (name, value) "
374 "(select coalesce((select value + 1 from sequences "
375 "where name = ?1), 1 ))) ; ";
376 sql_sequence_value2 = "select value from sequences where name = ?1 ;";
378 sql_set_revoked = "insert or replace into revoked_keys ("
379 " revoked_fpr, replacement_fpr, revocation_date) "
380 "values (upper(replace(?1,' ','')),"
381 " upper(replace(?2,' ','')),"
384 sql_get_revoked = "select revoked_fpr, revocation_date from revoked_keys"
385 " where replacement_fpr = upper(replace(?1,' ','')) ;";
388 int_result = sqlite3_prepare_v2(_session->db, sql_log,
389 (int)strlen(sql_log), &_session->log, NULL);
390 assert(int_result == SQLITE_OK);
392 int_result = sqlite3_prepare_v2(_session->system_db, sql_trustword,
393 (int)strlen(sql_trustword), &_session->trustword, NULL);
394 assert(int_result == SQLITE_OK);
396 int_result = sqlite3_prepare_v2(_session->db, sql_get_identity,
397 (int)strlen(sql_get_identity), &_session->get_identity, NULL);
398 assert(int_result == SQLITE_OK);
400 int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
401 (int)strlen(sql_set_person), &_session->set_person, NULL);
402 assert(int_result == SQLITE_OK);
404 int_result = sqlite3_prepare_v2(_session->db, sql_set_pgp_keypair,
405 (int)strlen(sql_set_pgp_keypair), &_session->set_pgp_keypair,
407 assert(int_result == SQLITE_OK);
409 int_result = sqlite3_prepare_v2(_session->db, sql_set_identity,
410 (int)strlen(sql_set_identity), &_session->set_identity, NULL);
411 assert(int_result == SQLITE_OK);
413 int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_flags,
414 (int)strlen(sql_set_identity_flags), &_session->set_identity_flags,
416 assert(int_result == SQLITE_OK);
418 int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
419 (int)strlen(sql_set_trust), &_session->set_trust, NULL);
420 assert(int_result == SQLITE_OK);
422 int_result = sqlite3_prepare_v2(_session->db, sql_get_trust,
423 (int)strlen(sql_get_trust), &_session->get_trust, NULL);
424 assert(int_result == SQLITE_OK);
426 int_result = sqlite3_prepare_v2(_session->db, sql_least_trust,
427 (int)strlen(sql_least_trust), &_session->least_trust, NULL);
428 assert(int_result == SQLITE_OK);
430 int_result = sqlite3_prepare_v2(_session->db, sql_mark_as_compromized,
431 (int)strlen(sql_mark_as_compromized), &_session->mark_compromized,
433 assert(int_result == SQLITE_OK);
435 int_result = sqlite3_prepare_v2(_session->db, sql_crashdump,
436 (int)strlen(sql_crashdump), &_session->crashdump, NULL);
437 assert(int_result == SQLITE_OK);
439 int_result = sqlite3_prepare_v2(_session->system_db, sql_languagelist,
440 (int)strlen(sql_languagelist), &_session->languagelist, NULL);
441 assert(int_result == SQLITE_OK);
443 int_result = sqlite3_prepare_v2(_session->system_db, sql_i18n_token,
444 (int)strlen(sql_i18n_token), &_session->i18n_token, NULL);
445 assert(int_result == SQLITE_OK);
449 int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_add,
450 (int)strlen(sql_blacklist_add), &_session->blacklist_add, NULL);
451 assert(int_result == SQLITE_OK);
453 int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_delete,
454 (int)strlen(sql_blacklist_delete), &_session->blacklist_delete,
456 assert(int_result == SQLITE_OK);
458 int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_is_listed,
459 (int)strlen(sql_blacklist_is_listed),
460 &_session->blacklist_is_listed, NULL);
461 assert(int_result == SQLITE_OK);
463 int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_retrieve,
464 (int)strlen(sql_blacklist_retrieve), &_session->blacklist_retrieve,
466 assert(int_result == SQLITE_OK);
470 int_result = sqlite3_prepare_v2(_session->db, sql_own_key_is_listed,
471 (int)strlen(sql_own_key_is_listed), &_session->own_key_is_listed,
473 assert(int_result == SQLITE_OK);
475 int_result = sqlite3_prepare_v2(_session->db, sql_own_identities_retrieve,
476 (int)strlen(sql_own_identities_retrieve),
477 &_session->own_identities_retrieve, NULL);
478 assert(int_result == SQLITE_OK);
482 int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value1,
483 (int)strlen(sql_sequence_value1), &_session->sequence_value1,
485 assert(int_result == SQLITE_OK);
487 int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value2,
488 (int)strlen(sql_sequence_value2), &_session->sequence_value2,
490 assert(int_result == SQLITE_OK);
492 // Revocation tracking
494 int_result = sqlite3_prepare_v2(_session->db, sql_set_revoked,
495 (int)strlen(sql_set_revoked), &_session->set_revoked, NULL);
496 assert(int_result == SQLITE_OK);
498 int_result = sqlite3_prepare_v2(_session->db, sql_get_revoked,
499 (int)strlen(sql_get_revoked), &_session->get_revoked, NULL);
500 assert(int_result == SQLITE_OK);
502 status = init_cryptotech(_session, in_first);
503 if (status != PEP_STATUS_OK)
506 status = init_transport_system(_session, in_first);
507 if (status != PEP_STATUS_OK)
510 status = log_event(_session, "init", "pEp " PEP_ENGINE_VERSION, NULL, NULL);
511 if (status != PEP_STATUS_OK)
516 _session->passive_mode = false;
517 _session->unencrypted_subject = false;
519 _session->use_only_own_private_keys = true;
520 #elif TARGET_OS_IPHONE
521 _session->use_only_own_private_keys = true;
523 _session->use_only_own_private_keys = false;
527 return PEP_STATUS_OK;
530 status = PEP_OUT_OF_MEMORY;
537 DYNAMIC_API void release(PEP_SESSION session)
539 bool out_last = false;
541 assert(init_count >= 0);
544 if (!((init_count >= 0) && session))
547 // a small race condition but still a race condition
548 // mitigated by calling caveat (see documentation)
555 if (session->sync_state != DeviceState_state_NONE)
556 unregister_sync_callbacks(session);
560 sqlite3_finalize(session->log);
561 if (session->trustword)
562 sqlite3_finalize(session->trustword);
563 if (session->get_identity)
564 sqlite3_finalize(session->get_identity);
565 if (session->set_person)
566 sqlite3_finalize(session->set_person);
567 if (session->set_pgp_keypair)
568 sqlite3_finalize(session->set_pgp_keypair);
569 if (session->set_identity)
570 sqlite3_finalize(session->set_identity);
571 if (session->set_identity_flags)
572 sqlite3_finalize(session->set_identity_flags);
573 if (session->set_trust)
574 sqlite3_finalize(session->set_trust);
575 if (session->get_trust)
576 sqlite3_finalize(session->get_trust);
577 if (session->least_trust)
578 sqlite3_finalize(session->least_trust);
579 if (session->mark_compromized)
580 sqlite3_finalize(session->mark_compromized);
581 if (session->crashdump)
582 sqlite3_finalize(session->crashdump);
583 if (session->languagelist)
584 sqlite3_finalize(session->languagelist);
585 if (session->i18n_token)
586 sqlite3_finalize(session->i18n_token);
587 if (session->blacklist_add)
588 sqlite3_finalize(session->blacklist_add);
589 if (session->blacklist_delete)
590 sqlite3_finalize(session->blacklist_delete);
591 if (session->blacklist_is_listed)
592 sqlite3_finalize(session->blacklist_is_listed);
593 if (session->blacklist_retrieve)
594 sqlite3_finalize(session->blacklist_retrieve);
595 if (session->own_key_is_listed)
596 sqlite3_finalize(session->own_key_is_listed);
597 if (session->own_identities_retrieve)
598 sqlite3_finalize(session->own_identities_retrieve);
599 if (session->sequence_value1)
600 sqlite3_finalize(session->sequence_value1);
601 if (session->sequence_value2)
602 sqlite3_finalize(session->sequence_value2);
603 if (session->set_revoked)
604 sqlite3_finalize(session->set_revoked);
605 if (session->get_revoked)
606 sqlite3_finalize(session->get_revoked);
609 sqlite3_close_v2(session->db);
610 if (session->system_db)
611 sqlite3_close_v2(session->system_db);
614 release_transport_system(session, out_last);
615 release_cryptotech(session, out_last);
621 DYNAMIC_API void config_passive_mode(PEP_SESSION session, bool enable)
624 session->passive_mode = enable;
627 DYNAMIC_API void config_unencrypted_subject(PEP_SESSION session, bool enable)
630 session->unencrypted_subject = enable;
633 DYNAMIC_API void config_use_only_own_private_keys(PEP_SESSION session,
637 session->use_only_own_private_keys = enable;
640 DYNAMIC_API PEP_STATUS log_event(
644 const char *description,
648 PEP_STATUS status = PEP_STATUS_OK;
655 if (!(session && title && entity))
656 return PEP_ILLEGAL_VALUE;
658 sqlite3_reset(session->log);
659 sqlite3_bind_text(session->log, 1, title, -1, SQLITE_STATIC);
660 sqlite3_bind_text(session->log, 2, entity, -1, SQLITE_STATIC);
662 sqlite3_bind_text(session->log, 3, description, -1, SQLITE_STATIC);
664 sqlite3_bind_null(session->log, 3);
666 sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
668 sqlite3_bind_null(session->log, 4);
670 result = sqlite3_step(session->log);
671 assert(result == SQLITE_DONE || result == SQLITE_BUSY);
672 if (result != SQLITE_DONE && result != SQLITE_BUSY)
673 status = PEP_UNKNOWN_ERROR;
674 } while (result == SQLITE_BUSY);
675 sqlite3_reset(session->log);
680 DYNAMIC_API PEP_STATUS trustword(
681 PEP_SESSION session, uint16_t value, const char *lang,
682 char **word, size_t *wsize
685 PEP_STATUS status = PEP_STATUS_OK;
691 if (!(session && word && wsize))
692 return PEP_ILLEGAL_VALUE;
700 assert((lang[0] >= 'A' && lang[0] <= 'Z')
701 || (lang[0] >= 'a' && lang[0] <= 'z'));
702 assert((lang[1] >= 'A' && lang[1] <= 'Z')
703 || (lang[1] >= 'a' && lang[1] <= 'z'));
704 assert(lang[2] == 0);
706 sqlite3_reset(session->trustword);
707 sqlite3_bind_text(session->trustword, 1, lang, -1, SQLITE_STATIC);
708 sqlite3_bind_int(session->trustword, 2, value);
710 const int result = sqlite3_step(session->trustword);
711 if (result == SQLITE_ROW) {
712 *word = strdup((const char *) sqlite3_column_text(session->trustword,
715 *wsize = sqlite3_column_bytes(session->trustword, 1);
717 status = PEP_OUT_OF_MEMORY;
719 status = PEP_TRUSTWORD_NOT_FOUND;
721 sqlite3_reset(session->trustword);
725 DYNAMIC_API PEP_STATUS trustwords(
726 PEP_SESSION session, const char *fingerprint, const char *lang,
727 char **words, size_t *wsize, int max_words
730 const char *source = fingerprint;
739 assert(max_words >= 0);
741 if (!(session && fingerprint && words && wsize && max_words >= 0))
742 return PEP_ILLEGAL_VALUE;
747 buffer = calloc(1, MAX_TRUSTWORDS_SPACE);
750 return PEP_OUT_OF_MEMORY;
753 fsize = strlen(fingerprint);
755 if (!lang || !lang[0])
758 assert((lang[0] >= 'A' && lang[0] <= 'Z')
759 || (lang[0] >= 'a' && lang[0] <= 'z'));
760 assert((lang[1] >= 'A' && lang[1] <= 'Z')
761 || (lang[1] >= 'a' && lang[1] <= 'z'));
762 assert(lang[2] == 0);
765 while (source < fingerprint + fsize) {
772 for (value=0, j=0; j < 4 && source < fingerprint + fsize; ) {
773 if (*source >= 'a' && *source <= 'f')
774 value += (*source - 'a' + 10) << (3 - j++) * 4;
775 else if (*source >= 'A' && *source <= 'F')
776 value += (*source - 'A' + 10) << (3 - j++) * 4;
777 else if (*source >= '0' && *source <= '9')
778 value += (*source - '0') << (3 - j++) * 4;
783 _status = trustword(session, value, lang, &word, &_wsize);
784 if (_status == PEP_OUT_OF_MEMORY) {
786 return PEP_OUT_OF_MEMORY;
790 return PEP_TRUSTWORD_NOT_FOUND;
793 if (dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1) {
794 strncpy(dest, word, _wsize);
800 break; // buffer full
803 if (source < fingerprint + fsize
804 && dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1)
808 if (max_words && n_words >= max_words)
813 *wsize = dest - buffer;
814 return PEP_STATUS_OK;
817 pEp_identity *new_identity(
818 const char *address, const char *fpr, const char *user_id,
822 pEp_identity *result = calloc(1, sizeof(pEp_identity));
826 result->address = strdup(address);
827 assert(result->address);
828 if (result->address == NULL) {
834 result->fpr = strdup(fpr);
836 if (result->fpr == NULL) {
837 free_identity(result);
842 result->user_id = strdup(user_id);
843 assert(result->user_id);
844 if (result->user_id == NULL) {
845 free_identity(result);
850 result->username = strdup(username);
851 assert(result->username);
852 if (result->username == NULL) {
853 free_identity(result);
861 pEp_identity *identity_dup(const pEp_identity *src)
865 pEp_identity *dup = new_identity(src->address, src->fpr, src->user_id,
871 dup->comm_type = src->comm_type;
872 dup->lang[0] = src->lang[0];
873 dup->lang[1] = src->lang[1];
876 dup->flags = src->flags;
881 void free_identity(pEp_identity *identity)
884 free(identity->address);
886 free(identity->user_id);
887 free(identity->username);
892 DYNAMIC_API PEP_STATUS get_identity(
896 pEp_identity **identity
899 PEP_STATUS status = PEP_STATUS_OK;
900 static pEp_identity *_identity;
907 if (!(session && address && address[0] && identity))
908 return PEP_ILLEGAL_VALUE;
912 sqlite3_reset(session->get_identity);
913 sqlite3_bind_text(session->get_identity, 1, address, -1, SQLITE_STATIC);
914 sqlite3_bind_text(session->get_identity, 2, user_id, -1, SQLITE_STATIC);
916 const int result = sqlite3_step(session->get_identity);
919 _identity = new_identity(
921 (const char *) sqlite3_column_text(session->get_identity, 0),
923 (const char *) sqlite3_column_text(session->get_identity, 1)
926 if (_identity == NULL)
927 return PEP_OUT_OF_MEMORY;
929 _identity->comm_type = (PEP_comm_type)
930 sqlite3_column_int(session->get_identity, 2);
931 const char* const _lang = (const char *)
932 sqlite3_column_text(session->get_identity, 3);
933 if (_lang && _lang[0]) {
934 assert(_lang[0] >= 'a' && _lang[0] <= 'z');
935 assert(_lang[1] >= 'a' && _lang[1] <= 'z');
936 assert(_lang[2] == 0);
937 _identity->lang[0] = _lang[0];
938 _identity->lang[1] = _lang[1];
939 _identity->lang[2] = 0;
941 _identity->flags = (unsigned int)
942 sqlite3_column_int(session->get_identity, 4);
943 *identity = _identity;
946 status = PEP_CANNOT_FIND_IDENTITY;
950 sqlite3_reset(session->get_identity);
954 DYNAMIC_API PEP_STATUS set_identity(
955 PEP_SESSION session, const pEp_identity *identity
962 assert(identity->address);
963 assert(identity->fpr);
964 assert(identity->user_id);
965 assert(identity->username);
967 if (!(session && identity && identity->address && identity->fpr &&
968 identity->user_id && identity->username))
969 return PEP_ILLEGAL_VALUE;
972 PEP_STATUS status = blacklist_is_listed(session, identity->fpr, &listed);
973 assert(status == PEP_STATUS_OK);
974 if (status != PEP_STATUS_OK)
978 return PEP_KEY_BLACKLISTED;
980 sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
982 sqlite3_reset(session->set_person);
983 sqlite3_bind_text(session->set_person, 1, identity->user_id, -1,
985 sqlite3_bind_text(session->set_person, 2, identity->username, -1,
987 if (identity->lang[0])
988 sqlite3_bind_text(session->set_person, 3, identity->lang, 1,
991 sqlite3_bind_null(session->set_person, 3);
992 sqlite3_bind_text(session->set_person, 4, identity->fpr, -1,
994 result = sqlite3_step(session->set_person);
995 sqlite3_reset(session->set_person);
996 if (result != SQLITE_DONE) {
997 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
998 return PEP_CANNOT_SET_PERSON;
1001 sqlite3_reset(session->set_pgp_keypair);
1002 sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
1004 result = sqlite3_step(session->set_pgp_keypair);
1005 sqlite3_reset(session->set_pgp_keypair);
1006 if (result != SQLITE_DONE) {
1007 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
1008 return PEP_CANNOT_SET_PGP_KEYPAIR;
1011 sqlite3_reset(session->set_identity);
1012 sqlite3_bind_text(session->set_identity, 1, identity->address, -1,
1014 sqlite3_bind_text(session->set_identity, 2, identity->fpr, -1,
1016 sqlite3_bind_text(session->set_identity, 3, identity->user_id, -1,
1018 sqlite3_bind_int(session->set_identity, 4, identity->flags);
1019 result = sqlite3_step(session->set_identity);
1020 sqlite3_reset(session->set_identity);
1021 if (result != SQLITE_DONE) {
1022 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
1023 return PEP_CANNOT_SET_IDENTITY;
1026 sqlite3_reset(session->set_trust);
1027 sqlite3_bind_text(session->set_trust, 1, identity->user_id, -1,
1029 sqlite3_bind_text(session->set_trust, 2, identity->fpr, -1,
1031 sqlite3_bind_int(session->set_trust, 3, identity->comm_type);
1032 result = sqlite3_step(session->set_trust);
1033 sqlite3_reset(session->set_trust);
1034 if (result != SQLITE_DONE) {
1035 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
1036 return PEP_CANNOT_SET_TRUST;
1039 result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
1040 if (result == SQLITE_OK)
1041 return PEP_STATUS_OK;
1043 return PEP_COMMIT_FAILED;
1046 DYNAMIC_API PEP_STATUS set_identity_flags(
1047 PEP_SESSION session,
1048 pEp_identity *identity,
1056 assert(identity->address);
1057 assert(identity->user_id);
1059 if (!(session && identity && identity->address && identity->user_id))
1060 return PEP_ILLEGAL_VALUE;
1062 sqlite3_reset(session->set_identity_flags);
1063 sqlite3_bind_int(session->set_identity_flags, 1, flags);
1064 sqlite3_bind_text(session->set_identity_flags, 2, identity->address, -1,
1066 sqlite3_bind_text(session->set_identity_flags, 3, identity->user_id, -1,
1068 result = sqlite3_step(session->set_identity_flags);
1069 sqlite3_reset(session->set_identity_flags);
1070 if (result != SQLITE_DONE)
1071 return PEP_CANNOT_SET_IDENTITY;
1073 identity->flags = flags;
1074 return PEP_STATUS_OK;
1077 DYNAMIC_API PEP_STATUS mark_as_compromized(
1078 PEP_SESSION session,
1085 assert(fpr && fpr[0]);
1087 if (!(session && fpr && fpr[0]))
1088 return PEP_ILLEGAL_VALUE;
1090 sqlite3_reset(session->mark_compromized);
1091 sqlite3_bind_text(session->mark_compromized, 1, fpr, -1,
1093 result = sqlite3_step(session->mark_compromized);
1094 sqlite3_reset(session->mark_compromized);
1096 if (result != SQLITE_DONE)
1097 return PEP_CANNOT_SET_TRUST;
1099 return PEP_STATUS_OK;
1102 void pEp_free(void *p)
1107 DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
1109 PEP_STATUS status = PEP_STATUS_OK;
1114 assert(identity->user_id);
1115 assert(identity->user_id[0]);
1116 assert(identity->fpr);
1117 assert(identity->fpr[0]);
1119 if (!(session && identity && identity->user_id && identity->user_id[0] &&
1120 identity->fpr && identity->fpr[0]))
1121 return PEP_ILLEGAL_VALUE;
1123 identity->comm_type = PEP_ct_unknown;
1125 sqlite3_reset(session->get_trust);
1126 sqlite3_bind_text(session->get_trust, 1, identity->user_id, -1,
1128 sqlite3_bind_text(session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
1130 result = sqlite3_step(session->get_trust);
1133 int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust,
1135 identity->comm_type = comm_type;
1140 status = PEP_CANNOT_FIND_IDENTITY;
1143 sqlite3_reset(session->get_trust);
1147 DYNAMIC_API PEP_STATUS least_trust(
1148 PEP_SESSION session,
1150 PEP_comm_type *comm_type
1153 PEP_STATUS status = PEP_STATUS_OK;
1160 if (!(session && fpr && comm_type))
1161 return PEP_ILLEGAL_VALUE;
1163 *comm_type = PEP_ct_unknown;
1165 sqlite3_reset(session->least_trust);
1166 sqlite3_bind_text(session->least_trust, 1, fpr, -1, SQLITE_STATIC);
1168 result = sqlite3_step(session->least_trust);
1171 int _comm_type = sqlite3_column_int(session->least_trust, 0);
1172 *comm_type = (PEP_comm_type) _comm_type;
1176 status = PEP_CANNOT_FIND_IDENTITY;
1179 sqlite3_reset(session->least_trust);
1183 DYNAMIC_API PEP_STATUS decrypt_and_verify(
1184 PEP_SESSION session, const char *ctext, size_t csize,
1185 char **ptext, size_t *psize, stringlist_t **keylist
1195 if (!(session && ctext && csize && ptext && psize && keylist))
1196 return PEP_ILLEGAL_VALUE;
1198 return session->cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify(
1199 session, ctext, csize, ptext, psize, keylist);
1202 DYNAMIC_API PEP_STATUS encrypt_and_sign(
1203 PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
1204 size_t psize, char **ctext, size_t *csize
1214 if (!(session && keylist && ptext && psize && ctext && csize))
1215 return PEP_ILLEGAL_VALUE;
1217 return session->cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign(session,
1218 keylist, ptext, psize, ctext, csize);
1221 DYNAMIC_API PEP_STATUS verify_text(
1222 PEP_SESSION session, const char *text, size_t size,
1223 const char *signature, size_t sig_size, stringlist_t **keylist
1233 if (!(session && text && size && signature && sig_size && keylist))
1234 return PEP_ILLEGAL_VALUE;
1236 return session->cryptotech[PEP_crypt_OpenPGP].verify_text(session, text,
1237 size, signature, sig_size, keylist);
1240 DYNAMIC_API PEP_STATUS delete_keypair(PEP_SESSION session, const char *fpr)
1245 if (!(session && fpr))
1246 return PEP_ILLEGAL_VALUE;
1248 return session->cryptotech[PEP_crypt_OpenPGP].delete_keypair(session, fpr);
1251 DYNAMIC_API PEP_STATUS export_key(
1252 PEP_SESSION session, const char *fpr, char **key_data, size_t *size
1260 if (!(session && fpr && key_data && size))
1261 return PEP_ILLEGAL_VALUE;
1263 return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
1267 DYNAMIC_API PEP_STATUS find_keys(
1268 PEP_SESSION session, const char *pattern, stringlist_t **keylist
1275 if (!(session && pattern && keylist))
1276 return PEP_ILLEGAL_VALUE;
1278 return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern,
1283 DYNAMIC_API PEP_STATUS generate_keypair(
1284 PEP_SESSION session, pEp_identity *identity
1289 assert(identity->address);
1290 assert(identity->fpr == NULL || identity->fpr[0] == 0);
1291 assert(identity->username);
1293 if (!(session && identity && identity->address &&
1294 (identity->fpr == NULL || identity->fpr[0] == 0) &&
1295 identity->username))
1296 return PEP_ILLEGAL_VALUE;
1299 session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session,
1301 if (status != PEP_STATUS_OK)
1304 // if a state machine for keysync is in place, inject notify
1305 if (session->sync_state != DeviceState_state_NONE)
1306 status = fsm_DeviceState_inject(session, KeyGen, NULL, NULL);
1311 DYNAMIC_API PEP_STATUS get_key_rating(
1312 PEP_SESSION session,
1314 PEP_comm_type *comm_type
1321 if (!(session && fpr && comm_type))
1322 return PEP_ILLEGAL_VALUE;
1324 return session->cryptotech[PEP_crypt_OpenPGP].get_key_rating(session, fpr,
1328 DYNAMIC_API PEP_STATUS import_key(
1329 PEP_SESSION session,
1330 const char *key_data,
1332 identity_list **private_keys
1338 if (!(session && key_data))
1339 return PEP_ILLEGAL_VALUE;
1341 return session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data,
1342 size, private_keys);
1345 DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
1350 if (!(session && pattern))
1351 return PEP_ILLEGAL_VALUE;
1353 return session->cryptotech[PEP_crypt_OpenPGP].recv_key(session, pattern);
1356 DYNAMIC_API PEP_STATUS send_key(PEP_SESSION session, const char *pattern)
1361 if (!(session && pattern))
1362 return PEP_ILLEGAL_VALUE;
1364 return session->cryptotech[PEP_crypt_OpenPGP].send_key(session, pattern);
1367 DYNAMIC_API PEP_STATUS renew_key(
1368 PEP_SESSION session,
1376 if (!(session && fpr))
1377 return PEP_ILLEGAL_VALUE;
1379 return session->cryptotech[PEP_crypt_OpenPGP].renew_key(session, fpr, ts);
1382 DYNAMIC_API PEP_STATUS revoke_key(
1383 PEP_SESSION session,
1391 if (!(session && fpr))
1392 return PEP_ILLEGAL_VALUE;
1394 return session->cryptotech[PEP_crypt_OpenPGP].revoke_key(session, fpr,
1398 DYNAMIC_API PEP_STATUS key_expired(
1399 PEP_SESSION session,
1409 if (!(session && fpr && expired))
1410 return PEP_ILLEGAL_VALUE;
1412 return session->cryptotech[PEP_crypt_OpenPGP].key_expired(session, fpr,
1416 DYNAMIC_API PEP_STATUS key_revoked(
1417 PEP_SESSION session,
1426 if (!(session && fpr && revoked))
1427 return PEP_ILLEGAL_VALUE;
1429 return session->cryptotech[PEP_crypt_OpenPGP].key_revoked(session, fpr,
1433 static void _clean_log_value(char *text)
1436 for (char *c = text; *c; c++) {
1437 if (*c < 32 && *c != '\n')
1445 static char *_concat_string(char *str1, const char *str2, char delim)
1447 str2 = str2 ? str2 : "";
1448 size_t len1 = str1 ? strlen(str1) : 0;
1449 size_t len2 = strlen(str2);
1450 size_t len = len1 + len2 + 3;
1451 char * result = realloc(str1, len + 1);
1455 strcpy(result + len1 + 1, str2);
1456 result[len - 2] = '"';
1457 result[len - 1] = delim;
1467 DYNAMIC_API PEP_STATUS get_crashdump_log(
1468 PEP_SESSION session,
1473 PEP_STATUS status = PEP_STATUS_OK;
1474 char *_logdata= NULL;
1477 assert(maxlines >= 0 && maxlines <= CRASHDUMP_MAX_LINES);
1480 if (!(session && logdata && maxlines >= 0 && maxlines <=
1481 CRASHDUMP_MAX_LINES))
1482 return PEP_ILLEGAL_VALUE;
1486 int limit = maxlines ? maxlines : CRASHDUMP_DEFAULT_LINES;
1487 const char *timestamp = NULL;
1488 const char *title = NULL;
1489 const char *entity = NULL;
1490 const char *desc = NULL;
1491 const char *comment = NULL;
1493 sqlite3_reset(session->crashdump);
1494 sqlite3_bind_int(session->crashdump, 1, limit);
1499 result = sqlite3_step(session->crashdump);
1502 timestamp = (const char *) sqlite3_column_text(session->crashdump,
1504 title = (const char *) sqlite3_column_text(session->crashdump,
1506 entity = (const char *) sqlite3_column_text(session->crashdump,
1508 desc = (const char *) sqlite3_column_text(session->crashdump,
1510 comment = (const char *) sqlite3_column_text(session->crashdump,
1513 _logdata = _concat_string(_logdata, timestamp, ',');
1514 if (_logdata == NULL)
1517 _logdata = _concat_string(_logdata, title, ',');
1518 if (_logdata == NULL)
1521 _logdata = _concat_string(_logdata, entity, ',');
1522 if (_logdata == NULL)
1525 _logdata = _concat_string(_logdata, desc, ',');
1526 if (_logdata == NULL)
1529 _logdata = _concat_string(_logdata, comment, '\n');
1530 if (_logdata == NULL)
1533 _clean_log_value(_logdata);
1540 status = PEP_UNKNOWN_ERROR;
1541 result = SQLITE_DONE;
1543 } while (result != SQLITE_DONE);
1545 sqlite3_reset(session->crashdump);
1546 if (status == PEP_STATUS_OK)
1547 *logdata = _logdata;
1552 status = PEP_OUT_OF_MEMORY;
1558 DYNAMIC_API PEP_STATUS get_languagelist(
1559 PEP_SESSION session,
1563 PEP_STATUS status = PEP_STATUS_OK;
1564 char *_languages= NULL;
1569 if (!(session && languages))
1570 return PEP_ILLEGAL_VALUE;
1574 const char *lang = NULL;
1575 const char *name = NULL;
1576 const char *phrase = NULL;
1578 sqlite3_reset(session->languagelist);
1583 result = sqlite3_step(session->languagelist);
1586 lang = (const char *) sqlite3_column_text(session->languagelist,
1588 name = (const char *) sqlite3_column_text(session->languagelist,
1590 phrase = (const char *) sqlite3_column_text(session->languagelist,
1593 _languages = _concat_string(_languages, lang, ',');
1594 if (_languages == NULL)
1597 _languages = _concat_string(_languages, name, ',');
1598 if (_languages == NULL)
1601 _languages = _concat_string(_languages, phrase, '\n');
1602 if (_languages == NULL)
1611 status = PEP_UNKNOWN_ERROR;
1612 result = SQLITE_DONE;
1614 } while (result != SQLITE_DONE);
1616 sqlite3_reset(session->languagelist);
1617 if (status == PEP_STATUS_OK)
1618 *languages = _languages;
1623 status = PEP_OUT_OF_MEMORY;
1629 DYNAMIC_API PEP_STATUS get_phrase(
1630 PEP_SESSION session,
1636 PEP_STATUS status = PEP_STATUS_OK;
1638 assert(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase);
1639 if (!(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase))
1640 return PEP_ILLEGAL_VALUE;
1644 sqlite3_reset(session->i18n_token);
1645 sqlite3_bind_text(session->i18n_token, 1, lang, -1, SQLITE_STATIC);
1646 sqlite3_bind_int(session->i18n_token, 2, phrase_id);
1648 const char *_phrase = NULL;
1651 result = sqlite3_step(session->i18n_token);
1654 _phrase = (const char *) sqlite3_column_text(session->i18n_token, 0);
1658 status = PEP_PHRASE_NOT_FOUND;
1662 status = PEP_UNKNOWN_ERROR;
1665 if (status == PEP_STATUS_OK) {
1666 *phrase = strdup(_phrase);
1667 if (*phrase == NULL)
1671 sqlite3_reset(session->i18n_token);
1675 status = PEP_OUT_OF_MEMORY;
1681 DYNAMIC_API PEP_STATUS sequence_value(
1682 PEP_SESSION session,
1687 PEP_STATUS status = PEP_STATUS_OK;
1694 if (!(session && name && value))
1695 return PEP_ILLEGAL_VALUE;
1699 sqlite3_reset(session->sequence_value1);
1700 sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
1701 result = sqlite3_step(session->sequence_value1);
1702 assert(result == SQLITE_DONE);
1703 sqlite3_reset(session->sequence_value1);
1704 if (result != SQLITE_DONE) {
1705 status = PEP_UNKNOWN_ERROR;
1708 sqlite3_reset(session->sequence_value2);
1709 sqlite3_bind_text(session->sequence_value2, 1, name, -1,
1711 result = sqlite3_step(session->sequence_value2);
1714 int32_t _value = (int32_t)
1715 sqlite3_column_int64(session->sequence_value2, 0);
1720 status = PEP_UNKNOWN_ERROR;
1722 sqlite3_reset(session->sequence_value2);
1727 DYNAMIC_API PEP_STATUS set_revoked(
1728 PEP_SESSION session,
1729 const char *revoked_fpr,
1730 const char *replacement_fpr,
1731 const uint64_t revocation_date
1734 PEP_STATUS status = PEP_STATUS_OK;
1737 revoked_fpr && revoked_fpr[0] &&
1738 replacement_fpr && replacement_fpr[0]
1742 revoked_fpr && revoked_fpr[0] &&
1743 replacement_fpr && replacement_fpr[0]
1745 return PEP_ILLEGAL_VALUE;
1747 sqlite3_reset(session->set_revoked);
1748 sqlite3_bind_text(session->set_revoked, 1, revoked_fpr, -1, SQLITE_STATIC);
1749 sqlite3_bind_text(session->set_revoked, 2, replacement_fpr, -1,
1751 sqlite3_bind_int64(session->set_revoked, 3, revocation_date);
1755 result = sqlite3_step(session->set_revoked);
1758 status = PEP_STATUS_OK;
1762 status = PEP_UNKNOWN_ERROR;
1765 sqlite3_reset(session->set_revoked);
1769 DYNAMIC_API PEP_STATUS get_revoked(
1770 PEP_SESSION session,
1773 uint64_t *revocation_date
1776 PEP_STATUS status = PEP_STATUS_OK;
1787 return PEP_ILLEGAL_VALUE;
1789 *revoked_fpr = NULL;
1790 *revocation_date = 0;
1792 sqlite3_reset(session->get_revoked);
1793 sqlite3_bind_text(session->get_revoked, 1, fpr, -1, SQLITE_STATIC);
1797 result = sqlite3_step(session->get_revoked);
1800 *revoked_fpr = strdup((const char *)
1801 sqlite3_column_text(session->get_revoked, 0));
1803 *revocation_date = sqlite3_column_int64(session->get_revoked,
1806 status = PEP_OUT_OF_MEMORY;
1811 status = PEP_CANNOT_FIND_IDENTITY;
1814 sqlite3_reset(session->get_revoked);
1819 PEP_STATUS key_created(
1820 PEP_SESSION session,
1825 assert(session && fpr && created);
1826 if (!(session && fpr && created))
1827 return PEP_ILLEGAL_VALUE;
1829 return session->cryptotech[PEP_crypt_OpenPGP].key_created(session, fpr,
1833 DYNAMIC_API const char* get_engine_version() {
1834 return PEP_ENGINE_VERSION;
1838 DYNAMIC_API PEP_STATUS reset_peptest_hack(PEP_SESSION session)
1843 return PEP_ILLEGAL_VALUE;
1845 int int_result = sqlite3_exec(
1847 "delete from identity where address like '%@peptest.ch' ;",
1852 assert(int_result == SQLITE_OK);
1854 return PEP_STATUS_OK;