ENGINE-67 #comment cut-and-paste error - tried to free one the the statements twice. #close Fixed typo, valgrind shows no more double-free error.
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_identity_flags;
33 static const char *sql_set_trust;
34 static const char *sql_get_trust;
35 static const char *sql_least_trust;
36 static const char *sql_mark_as_compromized;
37 static const char *sql_crashdump;
38 static const char *sql_languagelist;
39 static const char *sql_i18n_token;
42 static const char *sql_blacklist_add;
43 static const char *sql_blacklist_delete;
44 static const char *sql_blacklist_is_listed;
45 static const char *sql_blacklist_retrieve;
48 static const char *sql_own_key_is_listed;
49 static const char *sql_own_key_retrieve;
52 static const char *sql_sequence_value1;
53 static const char *sql_sequence_value2;
55 // Revocation tracking
56 static const char *sql_set_revoked;
57 static const char *sql_get_revoked;
59 bool in_first = false;
61 assert(sqlite3_threadsafe());
62 if (!sqlite3_threadsafe())
63 return PEP_INIT_SQLITE3_WITHOUT_MUTEX;
65 // a little race condition - but still a race condition
66 // mitigated by calling caveat (see documentation)
74 return PEP_ILLEGAL_VALUE;
78 pEpSession *_session = calloc(1, sizeof(pEpSession));
83 _session->version = PEP_ENGINE_VERSION;
86 if (LOCAL_DB == NULL) {
87 status = PEP_INIT_CANNOT_OPEN_DB;
91 int_result = sqlite3_open_v2(
96 | SQLITE_OPEN_FULLMUTEX
97 | SQLITE_OPEN_PRIVATECACHE,
101 if (int_result != SQLITE_OK) {
102 status = PEP_INIT_CANNOT_OPEN_DB;
106 sqlite3_busy_timeout(_session->db, BUSY_WAIT_TIME);
109 if (SYSTEM_DB == NULL) {
110 status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
114 int_result = sqlite3_open_v2(
115 SYSTEM_DB, &_session->system_db,
117 | SQLITE_OPEN_FULLMUTEX
118 | SQLITE_OPEN_SHAREDCACHE,
122 if (int_result != SQLITE_OK) {
123 status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
127 sqlite3_busy_timeout(_session->system_db, 1000);
129 // increment this when patching DDL
130 #define _DDL_USER_VERSION "1"
133 int_result = sqlite3_exec(
135 "create table version_info (\n"
136 " id integer primary key,\n"
137 " timestamp integer default (datetime('now')) ,\n"
145 if (int_result == SQLITE_OK) {
146 int_result = sqlite3_exec(
148 "pragma user_version = "_DDL_USER_VERSION";\n"
149 "insert or replace into version_info (id, version)"
150 "values (1, '" PEP_ENGINE_VERSION "');",
155 assert(int_result == SQLITE_OK);
158 int_result = sqlite3_exec(
160 "create table if not exists log (\n"
161 " timestamp integer default (datetime('now')) ,\n"
162 " title text not null,\n"
163 " entity text not null,\n"
164 " description text,\n"
167 "create index if not exists log_timestamp on log (\n"
170 "create table if not exists pgp_keypair (\n"
171 " fpr text primary key,\n"
172 " public_id text unique,\n"
173 " private_id text,\n"
174 " created integer,\n"
175 " expires integer,\n"
178 "create index if not exists pgp_keypair_expires on pgp_keypair (\n"
181 "create table if not exists person (\n"
182 " id text primary key,\n"
183 " username text not null,\n"
184 " main_key_id text\n"
185 " references pgp_keypair (fpr)\n"
186 " on delete set null,\n"
190 "create table if not exists identity (\n"
193 " references person (id)\n"
194 " on delete cascade,\n"
195 " main_key_id text\n"
196 " references pgp_keypair (fpr)\n"
197 " on delete set null,\n"
199 " flags integer default (0),"
200 " primary key (address, user_id)\n"
202 "create table if not exists trust (\n"
203 " user_id text not null\n"
204 " references person (id)\n"
205 " on delete cascade,\n"
206 " pgp_keypair_fpr text not null\n"
207 " references pgp_keypair (fpr)\n"
208 " on delete cascade,\n"
209 " comm_type integer not null,\n"
211 " primary key (user_id, pgp_keypair_fpr)\n"
214 "create table if not exists blacklist_keys (\n"
215 " fpr text primary key\n"
218 "create table if not exists sequences(\n"
219 " name text primary key,\n"
220 " value integer default 0\n"
222 "create table if not exists revoked_keys (\n"
223 " revoked_fpr text primary key,\n"
224 " replacement_fpr text not null\n"
225 " references pgp_keypair (fpr)\n"
226 " on delete cascade,\n"
227 " revocation_date integer\n"
234 assert(int_result == SQLITE_OK);
237 int_result = sqlite3_exec(
239 "pragma user_version;",
244 assert(int_result == SQLITE_OK);
247 int_result = sqlite3_exec(
249 "alter table identity\n"
250 " add column flags integer default (0);",
255 assert(int_result == SQLITE_OK);
258 if (version < atoi(_DDL_USER_VERSION)) {
259 int_result = sqlite3_exec(
261 "pragma user_version = "_DDL_USER_VERSION";\n"
262 "insert or replace into version_info (id, version)"
263 "values (1, '" PEP_ENGINE_VERSION "');",
268 assert(int_result == SQLITE_OK);
271 sql_log = "insert into log (title, entity, description, comment)"
272 "values (?1, ?2, ?3, ?4);";
274 sql_get_identity = "select fpr, username, comm_type, lang, flags"
276 " join person on id = identity.user_id"
277 " join pgp_keypair on fpr = identity.main_key_id"
278 " join trust on id = trust.user_id"
279 " and pgp_keypair_fpr = identity.main_key_id"
280 " where address = ?1 and identity.user_id = ?2;";
282 sql_trustword = "select id, word from wordlist where lang = lower(?1) "
285 // Set person, but if already exist, only update.
286 // if main_key_id already set, don't touch.
287 sql_set_person = "insert or replace into person (id, username, lang, main_key_id)"
288 " values (?1, ?2, ?3,"
289 " (select coalesce((select main_key_id from person "
290 " where id = ?1), upper(replace(?4,' ',''))))) ;";
292 sql_set_pgp_keypair = "insert or replace into pgp_keypair (fpr) "
293 "values (upper(replace(?1,' ',''))) ;";
295 sql_set_identity = "insert or replace into identity (address, main_key_id, "
296 "user_id, flags) values (?1, upper(replace(?2,' ','')),"
299 sql_set_identity_flags = "update identity set flags = ?1 "
300 "where address = ?2 and user_id = ?3 ;";
302 sql_set_trust = "insert or replace into trust (user_id, pgp_keypair_fpr, comm_type) "
303 "values (?1, upper(replace(?2,' ','')), ?3) ;";
305 sql_get_trust = "select comm_type from trust where user_id = ?1 "
306 "and pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
308 sql_least_trust = "select min(comm_type) from trust where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
310 sql_mark_as_compromized = "update trust not indexed set comm_type = 15"
311 " where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
313 sql_crashdump = "select timestamp, title, entity, description, comment"
314 " from log order by timestamp desc limit ?1 ;";
316 sql_languagelist = "select i18n_language.lang, name, phrase from i18n_language join i18n_token using (lang) where i18n_token.id = 1000;" ;
318 sql_i18n_token = "select phrase from i18n_token where lang = lower(?1) and id = ?2 ;";
322 sql_blacklist_add = "insert or replace into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
323 "delete from identity where main_key_id = upper(replace(?1,' ','')) ;"
324 "delete from pgp_keypair where fpr = upper(replace(?1,' ','')) ;";
326 sql_blacklist_delete = "delete from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
328 sql_blacklist_is_listed = "select count(*) from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
330 sql_blacklist_retrieve = "select * from blacklist_keys ;";
334 sql_own_key_is_listed =
335 "select count(*) from ("
336 " select main_key_id from person "
337 " where main_key_id = upper(replace(?1,' ',''))"
338 " and id = '" PEP_OWN_USERID "' "
340 " select main_key_id from identity "
341 " where main_key_id = upper(replace(?1,' ',''))"
342 " and user_id = '" PEP_OWN_USERID "' );";
344 sql_own_key_retrieve = "select main_key_id from person "
345 " where main_key_id is not null"
346 " and id = '" PEP_OWN_USERID "' "
348 " select main_key_id from identity "
349 " where main_key_id is not null"
350 " and user_id = '" PEP_OWN_USERID "' ;";
352 sql_sequence_value1 = "insert or replace into sequences (name, value) "
354 "(select coalesce((select value + 1 from sequences "
355 "where name = ?1), 1 ))) ; ";
356 sql_sequence_value2 = "select value from sequences where name = ?1 ;";
358 sql_set_revoked = "insert or replace into revoked_keys ("
359 " revoked_fpr, replacement_fpr, revocation_date) "
360 "values (upper(replace(?1,' ','')),"
361 " upper(replace(?2,' ','')),"
364 sql_get_revoked = "select revoked_fpr, revocation_date from revoked_keys"
365 " where replacement_fpr = upper(replace(?1,' ','')) ;";
368 int_result = sqlite3_prepare_v2(_session->db, sql_log, (int)strlen(sql_log),
369 &_session->log, NULL);
370 assert(int_result == SQLITE_OK);
372 int_result = sqlite3_prepare_v2(_session->system_db, sql_trustword,
373 (int)strlen(sql_trustword), &_session->trustword, NULL);
374 assert(int_result == SQLITE_OK);
376 int_result = sqlite3_prepare_v2(_session->db, sql_get_identity,
377 (int)strlen(sql_get_identity), &_session->get_identity, NULL);
378 assert(int_result == SQLITE_OK);
380 int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
381 (int)strlen(sql_set_person), &_session->set_person, NULL);
382 assert(int_result == SQLITE_OK);
384 int_result = sqlite3_prepare_v2(_session->db, sql_set_pgp_keypair,
385 (int)strlen(sql_set_pgp_keypair), &_session->set_pgp_keypair, NULL);
386 assert(int_result == SQLITE_OK);
388 int_result = sqlite3_prepare_v2(_session->db, sql_set_identity,
389 (int)strlen(sql_set_identity), &_session->set_identity, NULL);
390 assert(int_result == SQLITE_OK);
392 int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_flags,
393 (int)strlen(sql_set_identity_flags), &_session->set_identity_flags, NULL);
394 assert(int_result == SQLITE_OK);
396 int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
397 (int)strlen(sql_set_trust), &_session->set_trust, NULL);
398 assert(int_result == SQLITE_OK);
400 int_result = sqlite3_prepare_v2(_session->db, sql_get_trust,
401 (int)strlen(sql_get_trust), &_session->get_trust, NULL);
402 assert(int_result == SQLITE_OK);
404 int_result = sqlite3_prepare_v2(_session->db, sql_least_trust,
405 (int)strlen(sql_least_trust), &_session->least_trust, NULL);
406 assert(int_result == SQLITE_OK);
408 int_result = sqlite3_prepare_v2(_session->db, sql_mark_as_compromized,
409 (int)strlen(sql_mark_as_compromized), &_session->mark_compromized, NULL);
410 assert(int_result == SQLITE_OK);
412 int_result = sqlite3_prepare_v2(_session->db, sql_crashdump,
413 (int)strlen(sql_crashdump), &_session->crashdump, NULL);
414 assert(int_result == SQLITE_OK);
416 int_result = sqlite3_prepare_v2(_session->system_db, sql_languagelist,
417 (int)strlen(sql_languagelist), &_session->languagelist, NULL);
418 assert(int_result == SQLITE_OK);
420 int_result = sqlite3_prepare_v2(_session->system_db, sql_i18n_token,
421 (int)strlen(sql_i18n_token), &_session->i18n_token, NULL);
422 assert(int_result == SQLITE_OK);
426 int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_add,
427 (int)strlen(sql_blacklist_add), &_session->blacklist_add, NULL);
428 assert(int_result == SQLITE_OK);
430 int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_delete,
431 (int)strlen(sql_blacklist_delete), &_session->blacklist_delete, NULL);
432 assert(int_result == SQLITE_OK);
434 int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_is_listed,
435 (int)strlen(sql_blacklist_is_listed), &_session->blacklist_is_listed, NULL);
436 assert(int_result == SQLITE_OK);
438 int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_retrieve,
439 (int)strlen(sql_blacklist_retrieve), &_session->blacklist_retrieve, NULL);
440 assert(int_result == SQLITE_OK);
444 int_result = sqlite3_prepare_v2(_session->db, sql_own_key_is_listed,
445 (int)strlen(sql_own_key_is_listed), &_session->own_key_is_listed, NULL);
446 assert(int_result == SQLITE_OK);
448 int_result = sqlite3_prepare_v2(_session->db, sql_own_key_retrieve,
449 (int)strlen(sql_own_key_retrieve), &_session->own_key_retrieve, NULL);
450 assert(int_result == SQLITE_OK);
454 int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value1,
455 (int)strlen(sql_sequence_value1), &_session->sequence_value1, NULL);
456 assert(int_result == SQLITE_OK);
458 int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value2,
459 (int)strlen(sql_sequence_value2), &_session->sequence_value2, NULL);
460 assert(int_result == SQLITE_OK);
462 // Revocation tracking
464 int_result = sqlite3_prepare_v2(_session->db, sql_set_revoked,
465 (int)strlen(sql_set_revoked), &_session->set_revoked, NULL);
466 assert(int_result == SQLITE_OK);
468 int_result = sqlite3_prepare_v2(_session->db, sql_get_revoked,
469 (int)strlen(sql_get_revoked), &_session->get_revoked, NULL);
470 assert(int_result == SQLITE_OK);
472 status = init_cryptotech(_session, in_first);
473 if (status != PEP_STATUS_OK)
476 status = init_transport_system(_session, in_first);
477 if (status != PEP_STATUS_OK)
480 status = log_event(_session, "init", "pEp " PEP_ENGINE_VERSION, NULL, NULL);
481 if (status != PEP_STATUS_OK)
486 _session->passive_mode = false;
487 _session->unencrypted_subject = false;
489 _session->use_only_own_private_keys = true;
490 #elif TARGET_OS_IPHONE
491 _session->use_only_own_private_keys = true;
493 _session->use_only_own_private_keys = false;
497 return PEP_STATUS_OK;
500 status = PEP_OUT_OF_MEMORY;
507 DYNAMIC_API void release(PEP_SESSION session)
509 bool out_last = false;
511 assert(init_count >= 0);
514 if (!((init_count >= 0) && session))
517 // a small race condition but still a race condition
518 // mitigated by calling caveat (see documentation)
527 sqlite3_finalize(session->log);
528 if (session->trustword)
529 sqlite3_finalize(session->trustword);
530 if (session->get_identity)
531 sqlite3_finalize(session->get_identity);
532 if (session->set_person)
533 sqlite3_finalize(session->set_person);
534 if (session->set_pgp_keypair)
535 sqlite3_finalize(session->set_pgp_keypair);
536 if (session->set_identity)
537 sqlite3_finalize(session->set_identity);
538 if (session->set_identity_flags)
539 sqlite3_finalize(session->set_identity_flags);
540 if (session->set_trust)
541 sqlite3_finalize(session->set_trust);
542 if (session->get_trust)
543 sqlite3_finalize(session->get_trust);
544 if (session->least_trust)
545 sqlite3_finalize(session->least_trust);
546 if (session->mark_compromized)
547 sqlite3_finalize(session->mark_compromized);
548 if (session->crashdump)
549 sqlite3_finalize(session->crashdump);
550 if (session->languagelist)
551 sqlite3_finalize(session->languagelist);
552 if (session->i18n_token)
553 sqlite3_finalize(session->i18n_token);
554 if (session->blacklist_add)
555 sqlite3_finalize(session->blacklist_add);
556 if (session->blacklist_delete)
557 sqlite3_finalize(session->blacklist_delete);
558 if (session->blacklist_is_listed)
559 sqlite3_finalize(session->blacklist_is_listed);
560 if (session->blacklist_retrieve)
561 sqlite3_finalize(session->blacklist_retrieve);
562 if (session->own_key_is_listed)
563 sqlite3_finalize(session->own_key_is_listed);
564 if (session->own_key_retrieve)
565 sqlite3_finalize(session->own_key_retrieve);
566 if (session->sequence_value1)
567 sqlite3_finalize(session->sequence_value1);
568 if (session->sequence_value2)
569 sqlite3_finalize(session->sequence_value2);
570 if (session->set_revoked)
571 sqlite3_finalize(session->set_revoked);
572 if (session->get_revoked)
573 sqlite3_finalize(session->get_revoked);
576 sqlite3_close_v2(session->db);
577 if (session->system_db)
578 sqlite3_close_v2(session->system_db);
581 release_transport_system(session, out_last);
582 release_cryptotech(session, out_last);
588 DYNAMIC_API void config_passive_mode(PEP_SESSION session, bool enable)
591 session->passive_mode = enable;
594 DYNAMIC_API void config_unencrypted_subject(PEP_SESSION session, bool enable)
597 session->unencrypted_subject = enable;
600 DYNAMIC_API void config_use_only_own_private_keys(PEP_SESSION session, bool enable)
603 session->use_only_own_private_keys = enable;
606 DYNAMIC_API PEP_STATUS log_event(
610 const char *description,
614 PEP_STATUS status = PEP_STATUS_OK;
621 if (!(session && title && entity))
622 return PEP_ILLEGAL_VALUE;
624 sqlite3_reset(session->log);
625 sqlite3_bind_text(session->log, 1, title, -1, SQLITE_STATIC);
626 sqlite3_bind_text(session->log, 2, entity, -1, SQLITE_STATIC);
628 sqlite3_bind_text(session->log, 3, description, -1, SQLITE_STATIC);
630 sqlite3_bind_null(session->log, 3);
632 sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
634 sqlite3_bind_null(session->log, 4);
636 result = sqlite3_step(session->log);
637 assert(result == SQLITE_DONE || result == SQLITE_BUSY);
638 if (result != SQLITE_DONE && result != SQLITE_BUSY)
639 status = PEP_UNKNOWN_ERROR;
640 } while (result == SQLITE_BUSY);
641 sqlite3_reset(session->log);
646 DYNAMIC_API PEP_STATUS trustword(
647 PEP_SESSION session, uint16_t value, const char *lang,
648 char **word, size_t *wsize
651 PEP_STATUS status = PEP_STATUS_OK;
657 if (!(session && word && wsize))
658 return PEP_ILLEGAL_VALUE;
666 assert((lang[0] >= 'A' && lang[0] <= 'Z')
667 || (lang[0] >= 'a' && lang[0] <= 'z'));
668 assert((lang[1] >= 'A' && lang[1] <= 'Z')
669 || (lang[1] >= 'a' && lang[1] <= 'z'));
670 assert(lang[2] == 0);
672 sqlite3_reset(session->trustword);
673 sqlite3_bind_text(session->trustword, 1, lang, -1, SQLITE_STATIC);
674 sqlite3_bind_int(session->trustword, 2, value);
676 const int result = sqlite3_step(session->trustword);
677 if (result == SQLITE_ROW) {
678 *word = strdup((const char *) sqlite3_column_text(session->trustword,
681 *wsize = sqlite3_column_bytes(session->trustword, 1);
683 status = PEP_OUT_OF_MEMORY;
685 status = PEP_TRUSTWORD_NOT_FOUND;
687 sqlite3_reset(session->trustword);
691 DYNAMIC_API PEP_STATUS trustwords(
692 PEP_SESSION session, const char *fingerprint, const char *lang,
693 char **words, size_t *wsize, int max_words
696 const char *source = fingerprint;
706 assert(max_words >= 0);
708 if (!(session && fingerprint && words && wsize && max_words >= 0))
709 return PEP_ILLEGAL_VALUE;
714 buffer = calloc(1, MAX_TRUSTWORDS_SPACE);
717 return PEP_OUT_OF_MEMORY;
720 fsize = strlen(fingerprint);
722 if (!lang || !lang[0])
725 assert((lang[0] >= 'A' && lang[0] <= 'Z')
726 || (lang[0] >= 'a' && lang[0] <= 'z'));
727 assert((lang[1] >= 'A' && lang[1] <= 'Z')
728 || (lang[1] >= 'a' && lang[1] <= 'z'));
729 assert(lang[2] == 0);
732 while (source < fingerprint + fsize) {
738 for (value=0, j=0; j < 4 && source < fingerprint + fsize; ) {
739 if (*source >= 'a' && *source <= 'f')
740 value += (*source - 'a' + 10) << (3 - j++) * 4;
741 else if (*source >= 'A' && *source <= 'F')
742 value += (*source - 'A' + 10) << (3 - j++) * 4;
743 else if (*source >= '0' && *source <= '9')
744 value += (*source - '0') << (3 - j++) * 4;
749 _status = trustword(session, value, lang, &word, &_wsize);
750 if (_status == PEP_OUT_OF_MEMORY) {
752 return PEP_OUT_OF_MEMORY;
756 return PEP_TRUSTWORD_NOT_FOUND;
759 if (dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1) {
760 strncpy(dest, word, _wsize);
766 break; // buffer full
769 if (source < fingerprint + fsize
770 && dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1)
774 if (max_words && n_words >= max_words)
779 *wsize = dest - buffer;
780 return PEP_STATUS_OK;
783 pEp_identity *new_identity(
784 const char *address, const char *fpr, const char *user_id,
788 pEp_identity *result = calloc(1, sizeof(pEp_identity));
792 result->address = strdup(address);
793 assert(result->address);
794 if (result->address == NULL) {
800 result->fpr = strdup(fpr);
802 if (result->fpr == NULL) {
803 free_identity(result);
808 result->user_id = strdup(user_id);
809 assert(result->user_id);
810 if (result->user_id == NULL) {
811 free_identity(result);
816 result->username = strdup(username);
817 assert(result->username);
818 if (result->username == NULL) {
819 free_identity(result);
827 pEp_identity *identity_dup(const pEp_identity *src)
831 pEp_identity *dup = new_identity(src->address, src->fpr, src->user_id, src->username);
836 dup->comm_type = src->comm_type;
837 dup->lang[0] = src->lang[0];
838 dup->lang[1] = src->lang[1];
841 dup->flags = src->flags;
846 void free_identity(pEp_identity *identity)
849 free(identity->address);
851 free(identity->user_id);
852 free(identity->username);
857 DYNAMIC_API PEP_STATUS get_identity(
861 pEp_identity **identity
864 PEP_STATUS status = PEP_STATUS_OK;
865 static pEp_identity *_identity;
872 if (!(session && address && address[0] && identity))
873 return PEP_ILLEGAL_VALUE;
877 sqlite3_reset(session->get_identity);
878 sqlite3_bind_text(session->get_identity, 1, address, -1, SQLITE_STATIC);
879 sqlite3_bind_text(session->get_identity, 2, user_id, -1, SQLITE_STATIC);
881 const int result = sqlite3_step(session->get_identity);
884 _identity = new_identity(
886 (const char *) sqlite3_column_text(session->get_identity, 0),
888 (const char *) sqlite3_column_text(session->get_identity, 1)
891 if (_identity == NULL)
892 return PEP_OUT_OF_MEMORY;
894 _identity->comm_type = (PEP_comm_type) sqlite3_column_int(session->get_identity, 2);
895 const char* const _lang = (const char *) sqlite3_column_text(session->get_identity, 3);
896 if (_lang && _lang[0]) {
897 assert(_lang[0] >= 'a' && _lang[0] <= 'z');
898 assert(_lang[1] >= 'a' && _lang[1] <= 'z');
899 assert(_lang[2] == 0);
900 _identity->lang[0] = _lang[0];
901 _identity->lang[1] = _lang[1];
902 _identity->lang[2] = 0;
904 _identity->flags = (unsigned int) sqlite3_column_int(session->get_identity, 4);
905 *identity = _identity;
908 status = PEP_CANNOT_FIND_IDENTITY;
912 sqlite3_reset(session->get_identity);
916 DYNAMIC_API PEP_STATUS set_identity(
917 PEP_SESSION session, const pEp_identity *identity
924 assert(identity->address);
925 assert(identity->fpr);
926 assert(identity->user_id);
927 assert(identity->username);
929 if (!(session && identity && identity->address && identity->fpr &&
930 identity->user_id && identity->username))
931 return PEP_ILLEGAL_VALUE;
934 PEP_STATUS status = blacklist_is_listed(session, identity->fpr, &listed);
935 assert(status == PEP_STATUS_OK);
936 if (status != PEP_STATUS_OK)
940 return PEP_KEY_BLACKLISTED;
942 sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
944 sqlite3_reset(session->set_person);
945 sqlite3_bind_text(session->set_person, 1, identity->user_id, -1,
947 sqlite3_bind_text(session->set_person, 2, identity->username, -1,
949 if (identity->lang[0])
950 sqlite3_bind_text(session->set_person, 3, identity->lang, 1,
953 sqlite3_bind_null(session->set_person, 3);
954 sqlite3_bind_text(session->set_person, 4, identity->fpr, -1,
956 result = sqlite3_step(session->set_person);
957 sqlite3_reset(session->set_person);
958 if (result != SQLITE_DONE) {
959 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
960 return PEP_CANNOT_SET_PERSON;
963 sqlite3_reset(session->set_pgp_keypair);
964 sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
966 result = sqlite3_step(session->set_pgp_keypair);
967 sqlite3_reset(session->set_pgp_keypair);
968 if (result != SQLITE_DONE) {
969 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
970 return PEP_CANNOT_SET_PGP_KEYPAIR;
973 sqlite3_reset(session->set_identity);
974 sqlite3_bind_text(session->set_identity, 1, identity->address, -1,
976 sqlite3_bind_text(session->set_identity, 2, identity->fpr, -1,
978 sqlite3_bind_text(session->set_identity, 3, identity->user_id, -1,
980 sqlite3_bind_int(session->set_identity, 4, identity->flags);
981 result = sqlite3_step(session->set_identity);
982 sqlite3_reset(session->set_identity);
983 if (result != SQLITE_DONE) {
984 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
985 return PEP_CANNOT_SET_IDENTITY;
988 sqlite3_reset(session->set_trust);
989 sqlite3_bind_text(session->set_trust, 1, identity->user_id, -1,
991 sqlite3_bind_text(session->set_trust, 2, identity->fpr, -1,
993 sqlite3_bind_int(session->set_trust, 3, identity->comm_type);
994 result = sqlite3_step(session->set_trust);
995 sqlite3_reset(session->set_trust);
996 if (result != SQLITE_DONE) {
997 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
998 return PEP_CANNOT_SET_TRUST;
1001 result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
1002 if (result == SQLITE_OK)
1003 return PEP_STATUS_OK;
1005 return PEP_COMMIT_FAILED;
1008 DYNAMIC_API PEP_STATUS set_identity_flags(
1009 PEP_SESSION session,
1010 pEp_identity *identity,
1018 assert(identity->address);
1019 assert(identity->user_id);
1021 if (!(session && identity && identity->address && identity->user_id))
1022 return PEP_ILLEGAL_VALUE;
1024 sqlite3_reset(session->set_identity_flags);
1025 sqlite3_bind_int(session->set_identity_flags, 1, flags);
1026 sqlite3_bind_text(session->set_identity_flags, 2, identity->address, -1,
1028 sqlite3_bind_text(session->set_identity_flags, 3, identity->user_id, -1,
1030 result = sqlite3_step(session->set_identity_flags);
1031 sqlite3_reset(session->set_identity_flags);
1032 if (result != SQLITE_DONE)
1033 return PEP_CANNOT_SET_IDENTITY;
1035 identity->flags = flags;
1036 return PEP_STATUS_OK;
1039 DYNAMIC_API PEP_STATUS mark_as_compromized(
1040 PEP_SESSION session,
1047 assert(fpr && fpr[0]);
1049 if (!(session && fpr && fpr[0]))
1050 return PEP_ILLEGAL_VALUE;
1052 sqlite3_reset(session->mark_compromized);
1053 sqlite3_bind_text(session->mark_compromized, 1, fpr, -1,
1055 result = sqlite3_step(session->mark_compromized);
1056 sqlite3_reset(session->mark_compromized);
1058 if (result != SQLITE_DONE)
1059 return PEP_CANNOT_SET_TRUST;
1061 return PEP_STATUS_OK;
1064 void pEp_free(void *p)
1069 DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
1071 PEP_STATUS status = PEP_STATUS_OK;
1076 assert(identity->user_id);
1077 assert(identity->user_id[0]);
1078 assert(identity->fpr);
1079 assert(identity->fpr[0]);
1081 if (!(session && identity && identity->user_id && identity->user_id[0] &&
1082 identity->fpr && identity->fpr[0]))
1083 return PEP_ILLEGAL_VALUE;
1085 identity->comm_type = PEP_ct_unknown;
1087 sqlite3_reset(session->get_trust);
1088 sqlite3_bind_text(session->get_trust, 1, identity->user_id, -1, SQLITE_STATIC);
1089 sqlite3_bind_text(session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
1091 result = sqlite3_step(session->get_trust);
1094 int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust, 0);
1095 identity->comm_type = comm_type;
1100 status = PEP_CANNOT_FIND_IDENTITY;
1103 sqlite3_reset(session->get_trust);
1107 DYNAMIC_API PEP_STATUS least_trust(
1108 PEP_SESSION session,
1110 PEP_comm_type *comm_type
1113 PEP_STATUS status = PEP_STATUS_OK;
1120 if (!(session && fpr && comm_type))
1121 return PEP_ILLEGAL_VALUE;
1123 *comm_type = PEP_ct_unknown;
1125 sqlite3_reset(session->least_trust);
1126 sqlite3_bind_text(session->least_trust, 1, fpr, -1, SQLITE_STATIC);
1128 result = sqlite3_step(session->least_trust);
1131 int _comm_type = sqlite3_column_int(session->least_trust, 0);
1132 *comm_type = (PEP_comm_type) _comm_type;
1136 status = PEP_CANNOT_FIND_IDENTITY;
1139 sqlite3_reset(session->least_trust);
1143 DYNAMIC_API PEP_STATUS decrypt_and_verify(
1144 PEP_SESSION session, const char *ctext, size_t csize,
1145 char **ptext, size_t *psize, stringlist_t **keylist
1155 if (!(session && ctext && csize && ptext && psize && keylist && keylist))
1156 return PEP_ILLEGAL_VALUE;
1158 return session->cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify(session, ctext, csize, ptext, psize, keylist);
1161 DYNAMIC_API PEP_STATUS encrypt_and_sign(
1162 PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
1163 size_t psize, char **ctext, size_t *csize
1173 if (!(session && keylist && ptext && psize && ctext && csize))
1174 return PEP_ILLEGAL_VALUE;
1176 return session->cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign(session, keylist, ptext, psize, ctext, csize);
1179 DYNAMIC_API PEP_STATUS verify_text(
1180 PEP_SESSION session, const char *text, size_t size,
1181 const char *signature, size_t sig_size, stringlist_t **keylist
1191 if (!(session && text && size && signature && sig_size && keylist))
1192 return PEP_ILLEGAL_VALUE;
1194 return session->cryptotech[PEP_crypt_OpenPGP].verify_text(session, text, size, signature, sig_size, keylist);
1197 DYNAMIC_API PEP_STATUS delete_keypair(PEP_SESSION session, const char *fpr)
1202 if (!(session && fpr))
1203 return PEP_ILLEGAL_VALUE;
1205 return session->cryptotech[PEP_crypt_OpenPGP].delete_keypair(session, fpr);
1208 DYNAMIC_API PEP_STATUS export_key(
1209 PEP_SESSION session, const char *fpr, char **key_data, size_t *size
1217 if (!(session && fpr && key_data && size))
1218 return PEP_ILLEGAL_VALUE;
1220 return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr, key_data, size);
1223 DYNAMIC_API PEP_STATUS find_keys(
1224 PEP_SESSION session, const char *pattern, stringlist_t **keylist
1231 if (!(session && pattern && keylist))
1232 return PEP_ILLEGAL_VALUE;
1234 return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern, keylist);
1237 DYNAMIC_API PEP_STATUS generate_keypair(
1238 PEP_SESSION session, pEp_identity *identity
1243 assert(identity->address);
1244 assert(identity->fpr == NULL || identity->fpr[0] == 0);
1245 assert(identity->username);
1247 if (!(session && identity && identity->address &&
1248 (identity->fpr == NULL || identity->fpr[0] == 0) && identity->username))
1249 return PEP_ILLEGAL_VALUE;
1251 return session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session, identity);
1254 DYNAMIC_API PEP_STATUS get_key_rating(
1255 PEP_SESSION session,
1257 PEP_comm_type *comm_type
1264 if (!(session && fpr && comm_type))
1265 return PEP_ILLEGAL_VALUE;
1267 return session->cryptotech[PEP_crypt_OpenPGP].get_key_rating(session, fpr, comm_type);
1270 DYNAMIC_API PEP_STATUS import_key(
1271 PEP_SESSION session,
1272 const char *key_data,
1274 identity_list **private_keys
1280 if (!(session && key_data))
1281 return PEP_ILLEGAL_VALUE;
1283 return session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data, size, private_keys);
1286 DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
1291 if (!(session && pattern))
1292 return PEP_ILLEGAL_VALUE;
1294 return session->cryptotech[PEP_crypt_OpenPGP].recv_key(session, pattern);
1297 DYNAMIC_API PEP_STATUS send_key(PEP_SESSION session, const char *pattern)
1302 if (!(session && pattern))
1303 return PEP_ILLEGAL_VALUE;
1305 return session->cryptotech[PEP_crypt_OpenPGP].send_key(session, pattern);
1308 DYNAMIC_API PEP_STATUS renew_key(
1309 PEP_SESSION session,
1317 if (!(session && fpr))
1318 return PEP_ILLEGAL_VALUE;
1320 return session->cryptotech[PEP_crypt_OpenPGP].renew_key(session, fpr, ts);
1323 DYNAMIC_API PEP_STATUS revoke_key(
1324 PEP_SESSION session,
1332 if (!(session && fpr))
1333 return PEP_ILLEGAL_VALUE;
1335 return session->cryptotech[PEP_crypt_OpenPGP].revoke_key(session, fpr,
1339 DYNAMIC_API PEP_STATUS key_expired(
1340 PEP_SESSION session,
1350 if (!(session && fpr && expired))
1351 return PEP_ILLEGAL_VALUE;
1353 return session->cryptotech[PEP_crypt_OpenPGP].key_expired(session, fpr,
1357 DYNAMIC_API PEP_STATUS key_revoked(
1358 PEP_SESSION session,
1367 if (!(session && fpr && revoked))
1368 return PEP_ILLEGAL_VALUE;
1370 return session->cryptotech[PEP_crypt_OpenPGP].key_revoked(session, fpr,
1374 static void _clean_log_value(char *text)
1377 for (char *c = text; *c; c++) {
1378 if (*c < 32 && *c != '\n')
1386 static char *_concat_string(char *str1, const char *str2, char delim)
1388 str2 = str2 ? str2 : "";
1389 size_t len1 = str1 ? strlen(str1) : 0;
1390 size_t len2 = strlen(str2);
1391 size_t len = len1 + len2 + 3;
1392 char * result = realloc(str1, len + 1);
1396 strcpy(result + len1 + 1, str2);
1397 result[len - 2] = '"';
1398 result[len - 1] = delim;
1408 DYNAMIC_API PEP_STATUS get_crashdump_log(
1409 PEP_SESSION session,
1414 PEP_STATUS status = PEP_STATUS_OK;
1415 char *_logdata= NULL;
1418 assert(maxlines >= 0 && maxlines <= CRASHDUMP_MAX_LINES);
1421 if (!(session && logdata && maxlines >= 0 && maxlines <=
1422 CRASHDUMP_MAX_LINES))
1423 return PEP_ILLEGAL_VALUE;
1427 int limit = maxlines ? maxlines : CRASHDUMP_DEFAULT_LINES;
1428 const char *timestamp = NULL;
1429 const char *title = NULL;
1430 const char *entity = NULL;
1431 const char *desc = NULL;
1432 const char *comment = NULL;
1434 sqlite3_reset(session->crashdump);
1435 sqlite3_bind_int(session->crashdump, 1, limit);
1440 result = sqlite3_step(session->crashdump);
1443 timestamp = (const char *) sqlite3_column_text(session->crashdump, 0);
1444 title = (const char *) sqlite3_column_text(session->crashdump, 1);
1445 entity = (const char *) sqlite3_column_text(session->crashdump, 2);
1446 desc = (const char *) sqlite3_column_text(session->crashdump, 3);
1447 comment = (const char *) sqlite3_column_text(session->crashdump, 4);
1449 _logdata = _concat_string(_logdata, timestamp, ',');
1450 if (_logdata == NULL)
1453 _logdata = _concat_string(_logdata, title, ',');
1454 if (_logdata == NULL)
1457 _logdata = _concat_string(_logdata, entity, ',');
1458 if (_logdata == NULL)
1461 _logdata = _concat_string(_logdata, desc, ',');
1462 if (_logdata == NULL)
1465 _logdata = _concat_string(_logdata, comment, '\n');
1466 if (_logdata == NULL)
1469 _clean_log_value(_logdata);
1476 status = PEP_UNKNOWN_ERROR;
1477 result = SQLITE_DONE;
1479 } while (result != SQLITE_DONE);
1481 sqlite3_reset(session->crashdump);
1482 if (status == PEP_STATUS_OK)
1483 *logdata = _logdata;
1488 status = PEP_OUT_OF_MEMORY;
1494 DYNAMIC_API PEP_STATUS get_languagelist(
1495 PEP_SESSION session,
1499 PEP_STATUS status = PEP_STATUS_OK;
1500 char *_languages= NULL;
1505 if (!(session && languages))
1506 return PEP_ILLEGAL_VALUE;
1510 const char *lang = NULL;
1511 const char *name = NULL;
1512 const char *phrase = NULL;
1514 sqlite3_reset(session->languagelist);
1519 result = sqlite3_step(session->languagelist);
1522 lang = (const char *) sqlite3_column_text(session->languagelist, 0);
1523 name = (const char *) sqlite3_column_text(session->languagelist, 1);
1524 phrase = (const char *) sqlite3_column_text(session->languagelist, 2);
1526 _languages = _concat_string(_languages, lang, ',');
1527 if (_languages == NULL)
1530 _languages = _concat_string(_languages, name, ',');
1531 if (_languages == NULL)
1534 _languages = _concat_string(_languages, phrase, '\n');
1535 if (_languages == NULL)
1544 status = PEP_UNKNOWN_ERROR;
1545 result = SQLITE_DONE;
1547 } while (result != SQLITE_DONE);
1549 sqlite3_reset(session->languagelist);
1550 if (status == PEP_STATUS_OK)
1551 *languages = _languages;
1556 status = PEP_OUT_OF_MEMORY;
1562 DYNAMIC_API PEP_STATUS get_phrase(
1563 PEP_SESSION session,
1569 PEP_STATUS status = PEP_STATUS_OK;
1571 assert(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase);
1572 if (!(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase))
1573 return PEP_ILLEGAL_VALUE;
1577 sqlite3_reset(session->i18n_token);
1578 sqlite3_bind_text(session->i18n_token, 1, lang, -1, SQLITE_STATIC);
1579 sqlite3_bind_int(session->i18n_token, 2, phrase_id);
1581 const char *_phrase = NULL;
1584 result = sqlite3_step(session->i18n_token);
1587 _phrase = (const char *) sqlite3_column_text(session->i18n_token, 0);
1591 status = PEP_PHRASE_NOT_FOUND;
1595 status = PEP_UNKNOWN_ERROR;
1598 if (status == PEP_STATUS_OK) {
1599 *phrase = strdup(_phrase);
1600 if (*phrase == NULL)
1604 sqlite3_reset(session->i18n_token);
1608 status = PEP_OUT_OF_MEMORY;
1614 DYNAMIC_API PEP_STATUS sequence_value(
1615 PEP_SESSION session,
1620 PEP_STATUS status = PEP_STATUS_OK;
1627 if (!(session && name && value))
1628 return PEP_ILLEGAL_VALUE;
1632 sqlite3_reset(session->sequence_value1);
1633 sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
1634 result = sqlite3_step(session->sequence_value1);
1635 assert(result == SQLITE_DONE);
1636 sqlite3_reset(session->sequence_value1);
1637 if (result != SQLITE_DONE) {
1638 status = PEP_UNKNOWN_ERROR;
1641 sqlite3_reset(session->sequence_value2);
1642 sqlite3_bind_text(session->sequence_value2, 1, name, -1, SQLITE_STATIC);
1643 result = sqlite3_step(session->sequence_value2);
1646 int32_t _value = (int32_t)
1647 sqlite3_column_int64(session->sequence_value2, 0);
1652 status = PEP_UNKNOWN_ERROR;
1654 sqlite3_reset(session->sequence_value2);
1659 DYNAMIC_API PEP_STATUS set_revoked(
1660 PEP_SESSION session,
1661 const char *revoked_fpr,
1662 const char *replacement_fpr,
1663 const uint64_t revocation_date
1666 PEP_STATUS status = PEP_STATUS_OK;
1669 revoked_fpr && revoked_fpr[0] &&
1670 replacement_fpr && replacement_fpr[0]
1674 revoked_fpr && revoked_fpr[0] &&
1675 replacement_fpr && replacement_fpr[0]
1677 return PEP_ILLEGAL_VALUE;
1679 sqlite3_reset(session->set_revoked);
1680 sqlite3_bind_text(session->set_revoked, 1, revoked_fpr, -1, SQLITE_STATIC);
1681 sqlite3_bind_text(session->set_revoked, 2, replacement_fpr, -1, SQLITE_STATIC);
1682 sqlite3_bind_int64(session->set_revoked, 3, revocation_date);
1686 result = sqlite3_step(session->set_revoked);
1689 status = PEP_STATUS_OK;
1693 status = PEP_UNKNOWN_ERROR;
1696 sqlite3_reset(session->set_revoked);
1700 DYNAMIC_API PEP_STATUS get_revoked(
1701 PEP_SESSION session,
1704 uint64_t *revocation_date
1707 PEP_STATUS status = PEP_STATUS_OK;
1718 return PEP_ILLEGAL_VALUE;
1720 *revoked_fpr = NULL;
1721 *revocation_date = 0;
1723 sqlite3_reset(session->get_revoked);
1724 sqlite3_bind_text(session->get_revoked, 1, fpr, -1, SQLITE_STATIC);
1728 result = sqlite3_step(session->get_revoked);
1731 *revoked_fpr = strdup((const char *) sqlite3_column_text(session->get_revoked, 0));
1733 *revocation_date = sqlite3_column_int64(session->get_revoked, 1);
1735 status = PEP_OUT_OF_MEMORY;
1740 status = PEP_CANNOT_FIND_IDENTITY;
1743 sqlite3_reset(session->get_revoked);
1748 DYNAMIC_API PEP_STATUS reset_peptest_hack(PEP_SESSION session)
1753 return PEP_ILLEGAL_VALUE;
1755 int int_result = sqlite3_exec(
1757 "delete from identity where address like '%@peptest.ch' ;",
1762 assert(int_result == SQLITE_OK);
1764 return PEP_STATUS_OK;