1 #include "pEp_internal.h"
2 #include "dynamic_api.h"
3 #include "cryptotech.h"
7 static int init_count = -1;
9 DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
11 PEP_STATUS status = PEP_STATUS_OK;
13 static const char *sql_log;
14 static const char *sql_trustword;
15 static const char *sql_get_identity;
16 static const char *sql_set_person;
17 static const char *sql_set_pgp_keypair;
18 static const char *sql_set_identity;
19 static const char *sql_set_trust;
20 static const char *sql_get_trust;
21 static const char *sql_least_trust;
22 static const char *sql_mark_as_compromized;
23 static const char *sql_crashdump;
24 static const char *sql_languagelist;
25 static const char *sql_i18n_token;
28 static const char *sql_blacklist_add;
29 static const char *sql_blacklist_delete;
30 static const char *sql_blacklist_is_listed;
31 static const char *sql_blacklist_retrieve;
34 static const char *sql_own_key_is_listed;
35 static const char *sql_own_key_retrieve;
38 static const char *sql_sequence_value1;
39 static const char *sql_sequence_value2;
41 // Revocation tracking
42 static const char *sql_set_revoked;
43 static const char *sql_get_revoked;
45 bool in_first = false;
47 assert(sqlite3_threadsafe());
48 if (!sqlite3_threadsafe())
49 return PEP_INIT_SQLITE3_WITHOUT_MUTEX;
51 // a little race condition - but still a race condition
52 // mitigated by calling caveat (see documentation)
60 return PEP_ILLEGAL_VALUE;
64 pEpSession *_session = calloc(1, sizeof(pEpSession));
69 _session->version = PEP_ENGINE_VERSION;
72 if (LOCAL_DB == NULL) {
73 status = PEP_INIT_CANNOT_OPEN_DB;
77 int_result = sqlite3_open_v2(
82 | SQLITE_OPEN_FULLMUTEX
83 | SQLITE_OPEN_PRIVATECACHE,
87 if (int_result != SQLITE_OK) {
88 status = PEP_INIT_CANNOT_OPEN_DB;
92 sqlite3_busy_timeout(_session->db, BUSY_WAIT_TIME);
95 if (SYSTEM_DB == NULL) {
96 status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
100 int_result = sqlite3_open_v2(
101 SYSTEM_DB, &_session->system_db,
103 | SQLITE_OPEN_FULLMUTEX
104 | SQLITE_OPEN_SHAREDCACHE,
108 if (int_result != SQLITE_OK) {
109 status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
113 sqlite3_busy_timeout(_session->system_db, 1000);
116 int_result = sqlite3_exec(
118 "create table if not exists version_info (\n"
119 " id integer primary key,\n"
120 " timestamp integer default (datetime('now')) ,\n"
124 "create table if not exists log (\n"
125 " timestamp integer default (datetime('now')) ,\n"
126 " title text not null,\n"
127 " entity text not null,\n"
128 " description text,\n"
131 "create index if not exists log_timestamp on log (\n"
134 "create table if not exists pgp_keypair (\n"
135 " fpr text primary key,\n"
136 " public_id text unique,\n"
137 " private_id text,\n"
138 " created integer,\n"
139 " expires integer,\n"
142 "create index if not exists pgp_keypair_expires on pgp_keypair (\n"
145 "create table if not exists person (\n"
146 " id text primary key,\n"
147 " username text not null,\n"
148 " main_key_id text\n"
149 " references pgp_keypair (fpr)\n"
150 " on delete set null,\n"
154 "create table if not exists identity (\n"
157 " references person (id)\n"
158 " on delete cascade,\n"
159 " main_key_id text\n"
160 " references pgp_keypair (fpr)\n"
161 " on delete set null,\n"
163 " primary key (address, user_id)\n"
165 "create table if not exists trust (\n"
166 " user_id text not null\n"
167 " references person (id)\n"
168 " on delete cascade,\n"
169 " pgp_keypair_fpr text not null\n"
170 " references pgp_keypair (fpr)\n"
171 " on delete cascade,\n"
172 " comm_type integer not null,\n"
174 " primary key (user_id, pgp_keypair_fpr)\n"
177 "create table if not exists blacklist_keys (\n"
178 " fpr text primary key\n"
181 "create table if not exists sequences(\n"
182 " name text primary key,\n"
183 " value integer default 0\n"
185 "create table if not exists revoked_keys (\n"
186 " revoked_fpr text primary key,\n"
187 " replacement_fpr text not null\n"
188 " references pgp_keypair (fpr)\n"
189 " on delete cascade,\n"
190 " revocation_date integer\n"
197 assert(int_result == SQLITE_OK);
199 int_result = sqlite3_exec(
201 "insert or replace into version_info (id, version) values (1, '1.1');",
206 assert(int_result == SQLITE_OK);
208 sql_log = "insert into log (title, entity, description, comment)"
209 "values (?1, ?2, ?3, ?4);";
211 sql_get_identity = "select fpr, username, comm_type, lang"
213 " join person on id = identity.user_id"
214 " join pgp_keypair on fpr = identity.main_key_id"
215 " join trust on id = trust.user_id"
216 " and pgp_keypair_fpr = identity.main_key_id"
217 " where address = ?1 and identity.user_id = ?2;";
219 sql_trustword = "select id, word from wordlist where lang = lower(?1) "
222 // Set person, but if already exist, only update.
223 // if main_key_id already set, don't touch.
224 sql_set_person = "insert or replace into person (id, username, lang, main_key_id)"
225 " values (?1, ?2, ?3,"
226 " (select coalesce((select main_key_id from person "
227 " where id = ?1), upper(replace(?4,' ',''))))) ;";
229 sql_set_pgp_keypair = "insert or replace into pgp_keypair (fpr) "
230 "values (upper(replace(?1,' ',''))) ;";
232 sql_set_identity = "insert or replace into identity (address, main_key_id, "
233 "user_id) values (?1, upper(replace(?2,' ','')), ?3) ;";
235 sql_set_trust = "insert or replace into trust (user_id, pgp_keypair_fpr, comm_type) "
236 "values (?1, upper(replace(?2,' ','')), ?3) ;";
238 sql_get_trust = "select comm_type from trust where user_id = ?1 "
239 "and pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
241 sql_least_trust = "select min(comm_type) from trust where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
243 sql_mark_as_compromized = "update trust not indexed set comm_type = 15"
244 " where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
246 sql_crashdump = "select timestamp, title, entity, description, comment"
247 " from log order by timestamp desc limit ?1 ;";
249 sql_languagelist = "select i18n_language.lang, name, phrase from i18n_language join i18n_token using (lang) where i18n_token.id = 1000;" ;
251 sql_i18n_token = "select phrase from i18n_token where lang = lower(?1) and id = ?2 ;";
255 sql_blacklist_add = "insert or replace into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
256 "delete from identity where main_key_id = upper(replace(?1,' ','')) ;"
257 "delete from pgp_keypair where fpr = upper(replace(?1,' ','')) ;";
259 sql_blacklist_delete = "delete from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
261 sql_blacklist_is_listed = "select count(*) from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
263 sql_blacklist_retrieve = "select * from blacklist_keys ;";
267 sql_own_key_is_listed =
268 "select count(*) from ("
269 " select main_key_id from person "
270 " where main_key_id = upper(replace(?1,' ',''))"
271 " and id = '" PEP_OWN_USERID "' "
273 " select main_key_id from identity "
274 " where main_key_id = upper(replace(?1,' ',''))"
275 " and user_id = '" PEP_OWN_USERID "' );";
277 sql_own_key_retrieve = "select main_key_id from person "
278 " where main_key_id is not null"
279 " and id = '" PEP_OWN_USERID "' "
281 " select main_key_id from identity "
282 " where main_key_id is not null"
283 " and user_id = '" PEP_OWN_USERID "' ;";
285 sql_sequence_value1 = "insert or replace into sequences (name, value) "
287 "(select coalesce((select value + 1 from sequences "
288 "where name = ?1), 1 ))) ; ";
289 sql_sequence_value2 = "select value from sequences where name = ?1 ;";
291 sql_set_revoked = "insert or replace into revoked_keys ("
292 " revoked_fpr, replacement_fpr, revocation_date) "
293 "values (upper(replace(?1,' ','')),"
294 " upper(replace(?2,' ','')),"
297 sql_get_revoked = "select revoked_fpr, revocation_date from revoked_keys"
298 " where replacement_fpr = upper(replace(?1,' ','')) ;";
301 int_result = sqlite3_prepare_v2(_session->db, sql_log, (int)strlen(sql_log),
302 &_session->log, NULL);
303 assert(int_result == SQLITE_OK);
305 int_result = sqlite3_prepare_v2(_session->system_db, sql_trustword,
306 (int)strlen(sql_trustword), &_session->trustword, NULL);
307 assert(int_result == SQLITE_OK);
309 int_result = sqlite3_prepare_v2(_session->db, sql_get_identity,
310 (int)strlen(sql_get_identity), &_session->get_identity, NULL);
311 assert(int_result == SQLITE_OK);
313 int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
314 (int)strlen(sql_set_person), &_session->set_person, NULL);
315 assert(int_result == SQLITE_OK);
317 int_result = sqlite3_prepare_v2(_session->db, sql_set_pgp_keypair,
318 (int)strlen(sql_set_pgp_keypair), &_session->set_pgp_keypair, NULL);
319 assert(int_result == SQLITE_OK);
321 int_result = sqlite3_prepare_v2(_session->db, sql_set_identity,
322 (int)strlen(sql_set_identity), &_session->set_identity, NULL);
323 assert(int_result == SQLITE_OK);
325 int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
326 (int)strlen(sql_set_trust), &_session->set_trust, NULL);
327 assert(int_result == SQLITE_OK);
329 int_result = sqlite3_prepare_v2(_session->db, sql_get_trust,
330 (int)strlen(sql_get_trust), &_session->get_trust, NULL);
331 assert(int_result == SQLITE_OK);
333 int_result = sqlite3_prepare_v2(_session->db, sql_least_trust,
334 (int)strlen(sql_least_trust), &_session->least_trust, NULL);
335 assert(int_result == SQLITE_OK);
337 int_result = sqlite3_prepare_v2(_session->db, sql_mark_as_compromized,
338 (int)strlen(sql_mark_as_compromized), &_session->mark_compromized, NULL);
339 assert(int_result == SQLITE_OK);
341 int_result = sqlite3_prepare_v2(_session->db, sql_crashdump,
342 (int)strlen(sql_crashdump), &_session->crashdump, NULL);
343 assert(int_result == SQLITE_OK);
345 int_result = sqlite3_prepare_v2(_session->system_db, sql_languagelist,
346 (int)strlen(sql_languagelist), &_session->languagelist, NULL);
347 assert(int_result == SQLITE_OK);
349 int_result = sqlite3_prepare_v2(_session->system_db, sql_i18n_token,
350 (int)strlen(sql_i18n_token), &_session->i18n_token, NULL);
351 assert(int_result == SQLITE_OK);
355 int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_add,
356 (int)strlen(sql_blacklist_add), &_session->blacklist_add, NULL);
357 assert(int_result == SQLITE_OK);
359 int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_delete,
360 (int)strlen(sql_blacklist_delete), &_session->blacklist_delete, NULL);
361 assert(int_result == SQLITE_OK);
363 int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_is_listed,
364 (int)strlen(sql_blacklist_is_listed), &_session->blacklist_is_listed, NULL);
365 assert(int_result == SQLITE_OK);
367 int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_retrieve,
368 (int)strlen(sql_blacklist_retrieve), &_session->blacklist_retrieve, NULL);
369 assert(int_result == SQLITE_OK);
373 int_result = sqlite3_prepare_v2(_session->db, sql_own_key_is_listed,
374 (int)strlen(sql_own_key_is_listed), &_session->own_key_is_listed, NULL);
375 assert(int_result == SQLITE_OK);
377 int_result = sqlite3_prepare_v2(_session->db, sql_own_key_retrieve,
378 (int)strlen(sql_own_key_retrieve), &_session->own_key_retrieve, NULL);
379 assert(int_result == SQLITE_OK);
383 int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value1,
384 (int)strlen(sql_sequence_value1), &_session->sequence_value1, NULL);
385 assert(int_result == SQLITE_OK);
387 int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value2,
388 (int)strlen(sql_sequence_value2), &_session->sequence_value2, NULL);
389 assert(int_result == SQLITE_OK);
391 // Revocation tracking
393 int_result = sqlite3_prepare_v2(_session->db, sql_set_revoked,
394 (int)strlen(sql_set_revoked), &_session->set_revoked, NULL);
395 assert(int_result == SQLITE_OK);
397 int_result = sqlite3_prepare_v2(_session->db, sql_get_revoked,
398 (int)strlen(sql_get_revoked), &_session->get_revoked, NULL);
399 assert(int_result == SQLITE_OK);
401 status = init_cryptotech(_session, in_first);
402 if (status != PEP_STATUS_OK)
405 status = init_transport_system(_session, in_first);
406 if (status != PEP_STATUS_OK)
409 status = log_event(_session, "init", "pEp " PEP_ENGINE_VERSION, NULL, NULL);
410 if (status != PEP_STATUS_OK)
415 _session->passive_mode = false;
416 _session->unencrypted_subject = false;
418 _session->use_only_own_private_keys = true;
419 #elif TARGET_OS_IPHONE
420 _session->use_only_own_private_keys = true;
422 _session->use_only_own_private_keys = false;
426 return PEP_STATUS_OK;
429 status = PEP_OUT_OF_MEMORY;
436 DYNAMIC_API void release(PEP_SESSION session)
438 bool out_last = false;
440 assert(init_count >= 0);
443 if (!((init_count >= 0) && session))
446 // a small race condition but still a race condition
447 // mitigated by calling caveat (see documentation)
456 sqlite3_finalize(session->log);
457 if (session->trustword)
458 sqlite3_finalize(session->trustword);
459 if (session->get_identity)
460 sqlite3_finalize(session->get_identity);
461 if (session->set_person)
462 sqlite3_finalize(session->set_person);
463 if (session->set_pgp_keypair)
464 sqlite3_finalize(session->set_pgp_keypair);
465 if (session->set_identity)
466 sqlite3_finalize(session->set_identity);
467 if (session->set_trust)
468 sqlite3_finalize(session->set_trust);
469 if (session->get_trust)
470 sqlite3_finalize(session->get_trust);
471 if (session->least_trust)
472 sqlite3_finalize(session->least_trust);
473 if (session->mark_compromized)
474 sqlite3_finalize(session->mark_compromized);
475 if (session->crashdump)
476 sqlite3_finalize(session->crashdump);
477 if (session->languagelist)
478 sqlite3_finalize(session->languagelist);
479 if (session->i18n_token)
480 sqlite3_finalize(session->i18n_token);
481 if (session->blacklist_add)
482 sqlite3_finalize(session->blacklist_add);
483 if (session->blacklist_delete)
484 sqlite3_finalize(session->blacklist_delete);
485 if (session->blacklist_is_listed)
486 sqlite3_finalize(session->blacklist_is_listed);
487 if (session->blacklist_retrieve)
488 sqlite3_finalize(session->blacklist_retrieve);
491 sqlite3_close_v2(session->db);
492 if (session->system_db)
493 sqlite3_close_v2(session->system_db);
496 release_transport_system(session, out_last);
497 release_cryptotech(session, out_last);
503 DYNAMIC_API void config_passive_mode(PEP_SESSION session, bool enable)
506 session->passive_mode = enable;
509 DYNAMIC_API void config_unencrypted_subject(PEP_SESSION session, bool enable)
512 session->unencrypted_subject = enable;
515 DYNAMIC_API void config_use_only_own_private_keys(PEP_SESSION session, bool enable)
518 session->use_only_own_private_keys = enable;
521 DYNAMIC_API PEP_STATUS log_event(
525 const char *description,
529 PEP_STATUS status = PEP_STATUS_OK;
536 if (!(session && title && entity))
537 return PEP_ILLEGAL_VALUE;
539 sqlite3_reset(session->log);
540 sqlite3_bind_text(session->log, 1, title, -1, SQLITE_STATIC);
541 sqlite3_bind_text(session->log, 2, entity, -1, SQLITE_STATIC);
543 sqlite3_bind_text(session->log, 3, description, -1, SQLITE_STATIC);
545 sqlite3_bind_null(session->log, 3);
547 sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
549 sqlite3_bind_null(session->log, 4);
551 result = sqlite3_step(session->log);
552 assert(result == SQLITE_DONE || result == SQLITE_BUSY);
553 if (result != SQLITE_DONE && result != SQLITE_BUSY)
554 status = PEP_UNKNOWN_ERROR;
555 } while (result == SQLITE_BUSY);
556 sqlite3_reset(session->log);
561 DYNAMIC_API PEP_STATUS trustword(
562 PEP_SESSION session, uint16_t value, const char *lang,
563 char **word, size_t *wsize
566 PEP_STATUS status = PEP_STATUS_OK;
573 if (!(session && word && wsize))
574 return PEP_ILLEGAL_VALUE;
582 assert((lang[0] >= 'A' && lang[0] <= 'Z')
583 || (lang[0] >= 'a' && lang[0] <= 'z'));
584 assert((lang[1] >= 'A' && lang[1] <= 'Z')
585 || (lang[1] >= 'a' && lang[1] <= 'z'));
586 assert(lang[2] == 0);
588 sqlite3_reset(session->trustword);
589 sqlite3_bind_text(session->trustword, 1, lang, -1, SQLITE_STATIC);
590 sqlite3_bind_int(session->trustword, 2, value);
592 result = sqlite3_step(session->trustword);
593 if (result == SQLITE_ROW) {
594 *word = strdup((const char *) sqlite3_column_text(session->trustword,
597 *wsize = sqlite3_column_bytes(session->trustword, 1);
599 status = PEP_OUT_OF_MEMORY;
601 status = PEP_TRUSTWORD_NOT_FOUND;
603 sqlite3_reset(session->trustword);
607 DYNAMIC_API PEP_STATUS trustwords(
608 PEP_SESSION session, const char *fingerprint, const char *lang,
609 char **words, size_t *wsize, int max_words
612 const char *source = fingerprint;
622 assert(max_words >= 0);
624 if (!(session && fingerprint && words && wsize && max_words >= 0))
625 return PEP_ILLEGAL_VALUE;
630 buffer = calloc(1, MAX_TRUSTWORDS_SPACE);
633 return PEP_OUT_OF_MEMORY;
636 fsize = strlen(fingerprint);
638 if (!lang || !lang[0])
641 assert((lang[0] >= 'A' && lang[0] <= 'Z')
642 || (lang[0] >= 'a' && lang[0] <= 'z'));
643 assert((lang[1] >= 'A' && lang[1] <= 'Z')
644 || (lang[1] >= 'a' && lang[1] <= 'z'));
645 assert(lang[2] == 0);
648 while (source < fingerprint + fsize) {
654 for (value=0, j=0; j < 4 && source < fingerprint + fsize; ) {
655 if (*source >= 'a' && *source <= 'f')
656 value += (*source - 'a' + 10) << (3 - j++) * 4;
657 else if (*source >= 'A' && *source <= 'F')
658 value += (*source - 'A' + 10) << (3 - j++) * 4;
659 else if (*source >= '0' && *source <= '9')
660 value += (*source - '0') << (3 - j++) * 4;
665 _status = trustword(session, value, lang, &word, &_wsize);
666 if (_status == PEP_OUT_OF_MEMORY) {
668 return PEP_OUT_OF_MEMORY;
672 return PEP_TRUSTWORD_NOT_FOUND;
675 if (dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1) {
676 strncpy(dest, word, _wsize);
682 break; // buffer full
685 if (source < fingerprint + fsize
686 && dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1)
690 if (max_words && n_words >= max_words)
695 *wsize = dest - buffer;
696 return PEP_STATUS_OK;
699 pEp_identity *new_identity(
700 const char *address, const char *fpr, const char *user_id,
704 pEp_identity *result = calloc(1, sizeof(pEp_identity));
708 result->address = strdup(address);
709 assert(result->address);
710 if (result->address == NULL) {
716 result->fpr = strdup(fpr);
718 if (result->fpr == NULL) {
719 free_identity(result);
724 result->user_id = strdup(user_id);
725 assert(result->user_id);
726 if (result->user_id == NULL) {
727 free_identity(result);
732 result->username = strdup(username);
733 assert(result->username);
734 if (result->username == NULL) {
735 free_identity(result);
743 pEp_identity *identity_dup(const pEp_identity *src)
747 pEp_identity *dup = new_identity(src->address, src->fpr, src->user_id, src->username);
752 dup->comm_type = src->comm_type;
753 dup->lang[0] = src->lang[0];
754 dup->lang[1] = src->lang[1];
761 void free_identity(pEp_identity *identity)
764 free(identity->address);
766 free(identity->user_id);
767 free(identity->username);
772 DYNAMIC_API PEP_STATUS get_identity(
776 pEp_identity **identity
779 PEP_STATUS status = PEP_STATUS_OK;
780 static pEp_identity *_identity;
789 if (!(session && address && address[0] && identity))
790 return PEP_ILLEGAL_VALUE;
794 sqlite3_reset(session->get_identity);
795 sqlite3_bind_text(session->get_identity, 1, address, -1, SQLITE_STATIC);
796 sqlite3_bind_text(session->get_identity, 2, user_id, -1, SQLITE_STATIC);
798 result = sqlite3_step(session->get_identity);
801 _identity = new_identity(
803 (const char *) sqlite3_column_text(session->get_identity, 0),
805 (const char *) sqlite3_column_text(session->get_identity, 1)
808 if (_identity == NULL)
809 return PEP_OUT_OF_MEMORY;
811 _identity->comm_type = (PEP_comm_type) sqlite3_column_int(session->get_identity, 2);
812 _lang = (const char *) sqlite3_column_text(session->get_identity, 3);
813 if (_lang && _lang[0]) {
814 assert(_lang[0] >= 'a' && _lang[0] <= 'z');
815 assert(_lang[1] >= 'a' && _lang[1] <= 'z');
816 assert(_lang[2] == 0);
817 _identity->lang[0] = _lang[0];
818 _identity->lang[1] = _lang[1];
819 _identity->lang[2] = 0;
821 *identity = _identity;
824 status = PEP_CANNOT_FIND_IDENTITY;
828 sqlite3_reset(session->get_identity);
832 DYNAMIC_API PEP_STATUS set_identity(
833 PEP_SESSION session, const pEp_identity *identity
840 assert(identity->address);
841 assert(identity->fpr);
842 assert(identity->user_id);
843 assert(identity->username);
845 if (!(session && identity && identity->address && identity->fpr &&
846 identity->user_id && identity->username))
847 return PEP_ILLEGAL_VALUE;
850 PEP_STATUS status = blacklist_is_listed(session, identity->fpr, &listed);
851 assert(status == PEP_STATUS_OK);
852 if (status != PEP_STATUS_OK)
856 return PEP_KEY_BLACKLISTED;
858 sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
860 sqlite3_reset(session->set_person);
861 sqlite3_bind_text(session->set_person, 1, identity->user_id, -1,
863 sqlite3_bind_text(session->set_person, 2, identity->username, -1,
865 if (identity->lang[0])
866 sqlite3_bind_text(session->set_person, 3, identity->lang, 1,
869 sqlite3_bind_null(session->set_person, 3);
870 sqlite3_bind_text(session->set_person, 4, identity->fpr, -1,
872 result = sqlite3_step(session->set_person);
873 sqlite3_reset(session->set_person);
874 if (result != SQLITE_DONE) {
875 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
876 return PEP_CANNOT_SET_PERSON;
879 sqlite3_reset(session->set_pgp_keypair);
880 sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
882 result = sqlite3_step(session->set_pgp_keypair);
883 sqlite3_reset(session->set_pgp_keypair);
884 if (result != SQLITE_DONE) {
885 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
886 return PEP_CANNOT_SET_PGP_KEYPAIR;
889 sqlite3_reset(session->set_identity);
890 sqlite3_bind_text(session->set_identity, 1, identity->address, -1,
892 sqlite3_bind_text(session->set_identity, 2, identity->fpr, -1,
894 sqlite3_bind_text(session->set_identity, 3, identity->user_id, -1,
896 result = sqlite3_step(session->set_identity);
897 sqlite3_reset(session->set_identity);
898 if (result != SQLITE_DONE) {
899 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
900 return PEP_CANNOT_SET_IDENTITY;
903 sqlite3_reset(session->set_trust);
904 sqlite3_bind_text(session->set_trust, 1, identity->user_id, -1,
906 sqlite3_bind_text(session->set_trust, 2, identity->fpr, -1,
908 sqlite3_bind_int(session->set_trust, 3, identity->comm_type);
909 result = sqlite3_step(session->set_trust);
910 sqlite3_reset(session->set_trust);
911 if (result != SQLITE_DONE) {
912 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
913 return PEP_CANNOT_SET_TRUST;
916 result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
917 if (result == SQLITE_OK)
918 return PEP_STATUS_OK;
920 return PEP_COMMIT_FAILED;
923 DYNAMIC_API PEP_STATUS mark_as_compromized(
931 assert(fpr && fpr[0]);
933 if (!(session && fpr && fpr[0]))
934 return PEP_ILLEGAL_VALUE;
936 sqlite3_reset(session->mark_compromized);
937 sqlite3_bind_text(session->mark_compromized, 1, fpr, -1,
939 result = sqlite3_step(session->mark_compromized);
940 sqlite3_reset(session->mark_compromized);
942 if (result != SQLITE_DONE)
943 return PEP_CANNOT_SET_TRUST;
945 return PEP_STATUS_OK;
948 void pEp_free(void *p)
953 DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
955 PEP_STATUS status = PEP_STATUS_OK;
960 assert(identity->user_id);
961 assert(identity->user_id[0]);
962 assert(identity->fpr);
963 assert(identity->fpr[0]);
965 if (!(session && identity && identity->user_id && identity->user_id[0] &&
966 identity->fpr && identity->fpr[0]))
967 return PEP_ILLEGAL_VALUE;
969 identity->comm_type = PEP_ct_unknown;
971 sqlite3_reset(session->get_trust);
972 sqlite3_bind_text(session->get_trust, 1, identity->user_id, -1, SQLITE_STATIC);
973 sqlite3_bind_text(session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
975 result = sqlite3_step(session->get_trust);
978 int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust, 0);
979 identity->comm_type = comm_type;
984 status = PEP_CANNOT_FIND_IDENTITY;
987 sqlite3_reset(session->get_trust);
991 DYNAMIC_API PEP_STATUS least_trust(
994 PEP_comm_type *comm_type
997 PEP_STATUS status = PEP_STATUS_OK;
1004 if (!(session && fpr && comm_type))
1005 return PEP_ILLEGAL_VALUE;
1007 *comm_type = PEP_ct_unknown;
1009 sqlite3_reset(session->least_trust);
1010 sqlite3_bind_text(session->least_trust, 1, fpr, -1, SQLITE_STATIC);
1012 result = sqlite3_step(session->least_trust);
1015 int _comm_type = sqlite3_column_int(session->least_trust, 0);
1016 *comm_type = (PEP_comm_type) _comm_type;
1020 status = PEP_CANNOT_FIND_IDENTITY;
1023 sqlite3_reset(session->least_trust);
1027 DYNAMIC_API PEP_STATUS decrypt_and_verify(
1028 PEP_SESSION session, const char *ctext, size_t csize,
1029 char **ptext, size_t *psize, stringlist_t **keylist
1039 if (!(session && ctext && csize && ptext && psize && keylist && keylist))
1040 return PEP_ILLEGAL_VALUE;
1042 return session->cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify(session, ctext, csize, ptext, psize, keylist);
1045 DYNAMIC_API PEP_STATUS encrypt_and_sign(
1046 PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
1047 size_t psize, char **ctext, size_t *csize
1057 if (!(session && keylist && ptext && psize && ctext && csize))
1058 return PEP_ILLEGAL_VALUE;
1060 return session->cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign(session, keylist, ptext, psize, ctext, csize);
1063 DYNAMIC_API PEP_STATUS verify_text(
1064 PEP_SESSION session, const char *text, size_t size,
1065 const char *signature, size_t sig_size, stringlist_t **keylist
1075 if (!(session && text && size && signature && sig_size && keylist))
1076 return PEP_ILLEGAL_VALUE;
1078 return session->cryptotech[PEP_crypt_OpenPGP].verify_text(session, text, size, signature, sig_size, keylist);
1081 DYNAMIC_API PEP_STATUS delete_keypair(PEP_SESSION session, const char *fpr)
1086 if (!(session && fpr))
1087 return PEP_ILLEGAL_VALUE;
1089 return session->cryptotech[PEP_crypt_OpenPGP].delete_keypair(session, fpr);
1092 DYNAMIC_API PEP_STATUS export_key(
1093 PEP_SESSION session, const char *fpr, char **key_data, size_t *size
1101 if (!(session && fpr && key_data && size))
1102 return PEP_ILLEGAL_VALUE;
1104 return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr, key_data, size);
1107 DYNAMIC_API PEP_STATUS find_keys(
1108 PEP_SESSION session, const char *pattern, stringlist_t **keylist
1115 if (!(session && pattern && keylist))
1116 return PEP_ILLEGAL_VALUE;
1118 return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern, keylist);
1121 DYNAMIC_API PEP_STATUS generate_keypair(
1122 PEP_SESSION session, pEp_identity *identity
1127 assert(identity->address);
1128 assert(identity->fpr == NULL || identity->fpr[0] == 0);
1129 assert(identity->username);
1131 if (!(session && identity && identity->address &&
1132 (identity->fpr == NULL || identity->fpr[0] == 0) && identity->username))
1133 return PEP_ILLEGAL_VALUE;
1135 return session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session, identity);
1138 DYNAMIC_API PEP_STATUS get_key_rating(
1139 PEP_SESSION session,
1141 PEP_comm_type *comm_type
1148 if (!(session && fpr && comm_type))
1149 return PEP_ILLEGAL_VALUE;
1151 return session->cryptotech[PEP_crypt_OpenPGP].get_key_rating(session, fpr, comm_type);
1154 DYNAMIC_API PEP_STATUS import_key(PEP_SESSION session, const char *key_data, size_t size)
1159 if (!(session && key_data))
1160 return PEP_ILLEGAL_VALUE;
1162 return session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data, size);
1165 DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
1170 if (!(session && pattern))
1171 return PEP_ILLEGAL_VALUE;
1173 return session->cryptotech[PEP_crypt_OpenPGP].recv_key(session, pattern);
1176 DYNAMIC_API PEP_STATUS send_key(PEP_SESSION session, const char *pattern)
1181 if (!(session && pattern))
1182 return PEP_ILLEGAL_VALUE;
1184 return session->cryptotech[PEP_crypt_OpenPGP].send_key(session, pattern);
1187 DYNAMIC_API PEP_STATUS renew_key(
1188 PEP_SESSION session,
1196 if (!(session && fpr))
1197 return PEP_ILLEGAL_VALUE;
1199 return session->cryptotech[PEP_crypt_OpenPGP].renew_key(session, fpr, ts);
1202 DYNAMIC_API PEP_STATUS revoke_key(
1203 PEP_SESSION session,
1211 if (!(session && fpr))
1212 return PEP_ILLEGAL_VALUE;
1214 return session->cryptotech[PEP_crypt_OpenPGP].revoke_key(session, fpr,
1218 DYNAMIC_API PEP_STATUS key_expired(
1219 PEP_SESSION session,
1229 if (!(session && fpr && expired))
1230 return PEP_ILLEGAL_VALUE;
1232 return session->cryptotech[PEP_crypt_OpenPGP].key_expired(session, fpr,
1236 DYNAMIC_API PEP_STATUS key_revoked(
1237 PEP_SESSION session,
1246 if (!(session && fpr && revoked))
1247 return PEP_ILLEGAL_VALUE;
1249 return session->cryptotech[PEP_crypt_OpenPGP].key_revoked(session, fpr,
1253 static void _clean_log_value(char *text)
1256 for (char *c = text; *c; c++) {
1257 if (*c < 32 && *c != '\n')
1265 static char *_concat_string(char *str1, const char *str2, char delim)
1267 str2 = str2 ? str2 : "";
1268 size_t len1 = str1 ? strlen(str1) : 0;
1269 size_t len2 = strlen(str2);
1270 size_t len = len1 + len2 + 3;
1271 char * result = realloc(str1, len + 1);
1275 strcpy(result + len1 + 1, str2);
1276 result[len - 2] = '"';
1277 result[len - 1] = delim;
1287 DYNAMIC_API PEP_STATUS get_crashdump_log(
1288 PEP_SESSION session,
1293 PEP_STATUS status = PEP_STATUS_OK;
1294 char *_logdata= NULL;
1297 assert(maxlines >= 0 && maxlines <= CRASHDUMP_MAX_LINES);
1300 if (!(session && logdata && maxlines >= 0 && maxlines <=
1301 CRASHDUMP_MAX_LINES))
1302 return PEP_ILLEGAL_VALUE;
1306 int limit = maxlines ? maxlines : CRASHDUMP_DEFAULT_LINES;
1307 const char *timestamp = NULL;
1308 const char *title = NULL;
1309 const char *entity = NULL;
1310 const char *desc = NULL;
1311 const char *comment = NULL;
1313 sqlite3_reset(session->crashdump);
1314 sqlite3_bind_int(session->crashdump, 1, limit);
1319 result = sqlite3_step(session->crashdump);
1322 timestamp = (const char *) sqlite3_column_text(session->crashdump, 0);
1323 title = (const char *) sqlite3_column_text(session->crashdump, 1);
1324 entity = (const char *) sqlite3_column_text(session->crashdump, 2);
1325 desc = (const char *) sqlite3_column_text(session->crashdump, 3);
1326 comment = (const char *) sqlite3_column_text(session->crashdump, 4);
1328 _logdata = _concat_string(_logdata, timestamp, ',');
1329 if (_logdata == NULL)
1332 _logdata = _concat_string(_logdata, title, ',');
1333 if (_logdata == NULL)
1336 _logdata = _concat_string(_logdata, entity, ',');
1337 if (_logdata == NULL)
1340 _logdata = _concat_string(_logdata, desc, ',');
1341 if (_logdata == NULL)
1344 _logdata = _concat_string(_logdata, comment, '\n');
1345 if (_logdata == NULL)
1348 _clean_log_value(_logdata);
1355 status = PEP_UNKNOWN_ERROR;
1356 result = SQLITE_DONE;
1358 } while (result != SQLITE_DONE);
1360 sqlite3_reset(session->crashdump);
1361 if (status == PEP_STATUS_OK)
1362 *logdata = _logdata;
1367 status = PEP_OUT_OF_MEMORY;
1373 DYNAMIC_API PEP_STATUS get_languagelist(
1374 PEP_SESSION session,
1378 PEP_STATUS status = PEP_STATUS_OK;
1379 char *_languages= NULL;
1384 if (!(session && languages))
1385 return PEP_ILLEGAL_VALUE;
1389 const char *lang = NULL;
1390 const char *name = NULL;
1391 const char *phrase = NULL;
1393 sqlite3_reset(session->languagelist);
1398 result = sqlite3_step(session->languagelist);
1401 lang = (const char *) sqlite3_column_text(session->languagelist, 0);
1402 name = (const char *) sqlite3_column_text(session->languagelist, 1);
1403 phrase = (const char *) sqlite3_column_text(session->languagelist, 2);
1405 _languages = _concat_string(_languages, lang, ',');
1406 if (_languages == NULL)
1409 _languages = _concat_string(_languages, name, ',');
1410 if (_languages == NULL)
1413 _languages = _concat_string(_languages, phrase, '\n');
1414 if (_languages == NULL)
1423 status = PEP_UNKNOWN_ERROR;
1424 result = SQLITE_DONE;
1426 } while (result != SQLITE_DONE);
1428 sqlite3_reset(session->languagelist);
1429 if (status == PEP_STATUS_OK)
1430 *languages = _languages;
1435 status = PEP_OUT_OF_MEMORY;
1441 DYNAMIC_API PEP_STATUS get_phrase(
1442 PEP_SESSION session,
1448 PEP_STATUS status = PEP_STATUS_OK;
1450 assert(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase);
1451 if (!(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase))
1452 return PEP_ILLEGAL_VALUE;
1456 sqlite3_reset(session->i18n_token);
1457 sqlite3_bind_text(session->i18n_token, 1, lang, -1, SQLITE_STATIC);
1458 sqlite3_bind_int(session->i18n_token, 2, phrase_id);
1460 const char *_phrase = NULL;
1463 result = sqlite3_step(session->i18n_token);
1466 _phrase = (const char *) sqlite3_column_text(session->i18n_token, 0);
1470 status = PEP_PHRASE_NOT_FOUND;
1474 status = PEP_UNKNOWN_ERROR;
1477 if (status == PEP_STATUS_OK) {
1478 *phrase = strdup(_phrase);
1479 if (*phrase == NULL)
1483 sqlite3_reset(session->i18n_token);
1487 status = PEP_OUT_OF_MEMORY;
1493 DYNAMIC_API PEP_STATUS sequence_value(
1494 PEP_SESSION session,
1499 PEP_STATUS status = PEP_STATUS_OK;
1506 if (!(session && name && value))
1507 return PEP_ILLEGAL_VALUE;
1511 sqlite3_reset(session->sequence_value1);
1512 sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
1513 result = sqlite3_step(session->sequence_value1);
1514 assert(result == SQLITE_DONE);
1515 sqlite3_reset(session->sequence_value1);
1516 if (result != SQLITE_DONE) {
1517 status = PEP_UNKNOWN_ERROR;
1520 sqlite3_reset(session->sequence_value2);
1521 sqlite3_bind_text(session->sequence_value2, 1, name, -1, SQLITE_STATIC);
1522 result = sqlite3_step(session->sequence_value2);
1525 int32_t _value = (int32_t)
1526 sqlite3_column_int64(session->sequence_value2, 0);
1531 status = PEP_UNKNOWN_ERROR;
1533 sqlite3_reset(session->sequence_value2);
1538 DYNAMIC_API PEP_STATUS set_revoked(
1539 PEP_SESSION session,
1540 const char *revoked_fpr,
1541 const char *replacement_fpr,
1542 const uint64_t revocation_date
1545 PEP_STATUS status = PEP_STATUS_OK;
1548 revoked_fpr && revoked_fpr[0] &&
1549 replacement_fpr && replacement_fpr[0]
1553 revoked_fpr && revoked_fpr[0] &&
1554 replacement_fpr && replacement_fpr[0]
1556 return PEP_ILLEGAL_VALUE;
1558 sqlite3_reset(session->set_revoked);
1559 sqlite3_bind_text(session->set_revoked, 1, revoked_fpr, -1, SQLITE_STATIC);
1560 sqlite3_bind_text(session->set_revoked, 2, replacement_fpr, -1, SQLITE_STATIC);
1561 sqlite3_bind_int64(session->set_revoked, 3, revocation_date);
1565 result = sqlite3_step(session->set_revoked);
1568 status = PEP_STATUS_OK;
1572 status = PEP_UNKNOWN_ERROR;
1575 sqlite3_reset(session->set_revoked);
1579 DYNAMIC_API PEP_STATUS get_revoked(
1580 PEP_SESSION session,
1583 uint64_t *revocation_date
1586 PEP_STATUS status = PEP_STATUS_OK;
1597 return PEP_ILLEGAL_VALUE;
1599 *revoked_fpr = NULL;
1600 *revocation_date = 0;
1602 sqlite3_reset(session->get_revoked);
1603 sqlite3_bind_text(session->get_revoked, 1, fpr, -1, SQLITE_STATIC);
1607 result = sqlite3_step(session->get_revoked);
1610 *revoked_fpr = strdup((const char *) sqlite3_column_text(session->get_revoked, 0));
1612 *revocation_date = sqlite3_column_int64(session->get_revoked, 1);
1614 status = PEP_OUT_OF_MEMORY;
1619 status = PEP_CANNOT_FIND_IDENTITY;
1622 sqlite3_reset(session->get_revoked);
1627 DYNAMIC_API PEP_STATUS reset_peptest_hack(PEP_SESSION session)
1632 return PEP_ILLEGAL_VALUE;
1634 int int_result = sqlite3_exec(
1636 "delete from identity where address like '%@peptest.ch' ;",
1641 assert(int_result == SQLITE_OK);
1643 return PEP_STATUS_OK;