src/pEpEngine.c
author Krista Bennett <krista@pep-project.org>
Wed, 17 May 2017 15:07:34 +0200
branchENGINE-209
changeset 1793 74cf3813c28e
parent 1791 0253b2e1b8ff
child 1797 32581fade44d
permissions -rw-r--r--
ENGINE-209: intermittent commit - need to put get_identities_by_fpr into some other files so I can finish up the clearing of the revoked key from affected identities
     1 // This file is under GNU General Public License 3.0
     2 // see LICENSE.txt
     3 
     4 #include "pEp_internal.h"
     5 #include "dynamic_api.h"
     6 #include "cryptotech.h"
     7 #include "transport.h"
     8 #include "blacklist.h"
     9 #include "sync_fsm.h"
    10 
    11 static int init_count = -1;
    12 
    13 // sql manipulation statements
    14 static const char *sql_log = 
    15     "insert into log (title, entity, description, comment)"
    16      "values (?1, ?2, ?3, ?4);";
    17 
    18 static const char *sql_trustword = 
    19     "select id, word from wordlist where lang = lower(?1) "
    20     "and id = ?2 ;";
    21 
    22 static const char *sql_get_identity =  
    23     "select fpr, username, comm_type, lang,"
    24     "   identity.flags | pgp_keypair.flags"
    25     "   from identity"
    26     "   join person on id = identity.user_id"
    27     "   join pgp_keypair on fpr = identity.main_key_id"
    28     "   join trust on id = trust.user_id"
    29     "       and pgp_keypair_fpr = identity.main_key_id"
    30     "   where address = ?1 and identity.user_id = ?2;";
    31 
    32 static const char *sql_get_identities_by_fpr =  
    33     "select fpr, username, comm_type, lang,"
    34     "   identity.flags | pgp_keypair.flags"
    35     "   from identity"
    36     "   join person on id = identity.user_id"
    37     "   join pgp_keypair on fpr = identity.main_key_id"
    38     "   join trust on id = trust.user_id"
    39     "       and pgp_keypair_fpr = identity.main_key_id"
    40     "   where identity.main_key_id = ?1;";
    41 
    42 // Set person, but if already exist, only update.
    43 // if main_key_id already set, don't touch.
    44 static const char *sql_set_person = 
    45     "insert or replace into person (id, username, lang, main_key_id, device_group)"
    46     "  values (?1, ?2, ?3,"
    47     "    (select coalesce((select main_key_id from person "
    48     "      where id = ?1), upper(replace(?4,' ','')))),"
    49     "    (select device_group from person where id = ?1)) ;";
    50 
    51 static const char *sql_set_device_group = 
    52     "update person set device_group = ?1 "
    53     "where id = '" PEP_OWN_USERID "';";
    54 
    55 static const char *sql_get_device_group = 
    56     "select device_group from person "
    57     "where id = '" PEP_OWN_USERID "';";
    58 
    59 static const char *sql_set_pgp_keypair = 
    60     "insert or replace into pgp_keypair (fpr) "
    61     "values (upper(replace(?1,' ',''))) ;";
    62 
    63 static const char *sql_set_identity = 
    64     "insert or replace into identity ("
    65     " address, main_key_id, "
    66     " user_id, flags"
    67     ") values ("
    68     " ?1,"
    69     " upper(replace(?2,' ','')),"
    70     " ?3,"
    71     // " (select"
    72     // "   coalesce("
    73     // "    (select flags from identity"
    74     // "     where address = ?1 and"
    75     // "           user_id = ?3),"
    76     // "    0)"
    77     // " ) | (?4 & 255)"
    78     /* set_identity ignores previous flags, and doesn't filter machine flags */
    79     " ?4"
    80     ");";
    81         
    82 static const char *sql_set_identity_flags = 
    83     "update identity set flags = "
    84     "    ((?1 & 255) | (select flags from identity"
    85     "                   where address = ?2 and user_id = ?3)) "
    86     "where address = ?2 and user_id = ?3 ;";
    87 
    88 static const char *sql_unset_identity_flags = 
    89     "update identity set flags = "
    90     "    ( ~(?1 & 255) & (select flags from identity"
    91     "                   where address = ?2 and user_id = ?3)) "
    92     "where address = ?2 and user_id = ?3 ;";
    93 
    94 static const char *sql_set_trust =
    95     "insert or replace into trust (user_id, pgp_keypair_fpr, comm_type) "
    96     "values (?1, upper(replace(?2,' ','')), ?3) ;";
    97 
    98 static const char *sql_get_trust = 
    99     "select comm_type from trust where user_id = ?1 "
   100     "and pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
   101 
   102 static const char *sql_get_key_userids = 
   103     "select user_id from trust where "
   104     "pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
   105 
   106 static const char *sql_least_trust = 
   107     "select min(comm_type) from trust where"
   108     " pgp_keypair_fpr = upper(replace(?1,' ',''))"
   109     " and comm_type != 0;"; // ignores PEP_ct_unknown
   110     // returns PEP_ct_unknown only when no known trust is recorded
   111 
   112 static const char *sql_mark_as_compromized = 
   113     "update trust not indexed set comm_type = 15"
   114     " where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
   115 
   116 static const char *sql_crashdump = 
   117     "select timestamp, title, entity, description, comment"
   118     " from log order by timestamp desc limit ?1 ;";
   119 
   120 static const char *sql_languagelist = 
   121     "select i18n_language.lang, name, phrase" 
   122     " from i18n_language join i18n_token using (lang) where i18n_token.id = 1000;" ;
   123 
   124 static const char *sql_i18n_token = 
   125     "select phrase from i18n_token where lang = lower(?1) and id = ?2 ;";
   126 
   127 
   128 // blacklist
   129 static const char *sql_blacklist_add = 
   130     "insert or replace into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
   131     "delete from identity where main_key_id = upper(replace(?1,' ','')) ;"
   132     "delete from pgp_keypair where fpr = upper(replace(?1,' ','')) ;";
   133 
   134 static const char *sql_blacklist_delete =
   135     "delete from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
   136 
   137 static const char *sql_blacklist_is_listed = 
   138     "select count(*) from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
   139 
   140 static const char *sql_blacklist_retrieve = 
   141     "select * from blacklist_keys ;";
   142                 
   143 
   144 // Own keys
   145 static const char *sql_own_key_is_listed = 
   146     "select count(*) from ("
   147     " select main_key_id from person "
   148     "   where main_key_id = upper(replace(?1,' ',''))"
   149     "    and id = '" PEP_OWN_USERID "' "
   150     " union "
   151     "  select main_key_id from identity "
   152     "   where main_key_id = upper(replace(?1,' ',''))"
   153     "    and user_id = '" PEP_OWN_USERID "' "
   154     " union "
   155     "  select fpr from own_keys "
   156     "   where fpr = upper(replace(?1,' ',''))"
   157     " );";
   158 
   159 static const char *sql_own_identities_retrieve =  
   160     "select address, fpr, username, "
   161     "   lang, identity.flags | pgp_keypair.flags"
   162     "   from identity"
   163     "   join person on id = identity.user_id"
   164     "   join pgp_keypair on fpr = identity.main_key_id"
   165     "   join trust on id = trust.user_id"
   166     "       and pgp_keypair_fpr = identity.main_key_id"
   167     "   where identity.user_id = '" PEP_OWN_USERID "'"
   168     "       and (identity.flags & ?1) = 0;";
   169         
   170 static const char *sql_own_keys_retrieve =  
   171     "select fpr from own_keys"
   172     "   natural join identity"
   173     "   where (identity.flags & ?1) = 0;";
   174 
   175 static const char *sql_set_own_key = 
   176     "insert or replace into own_keys (address, user_id, fpr)"
   177     " values (?1, '" PEP_OWN_USERID "', upper(replace(?2,' ','')));";
   178 
   179 
   180 // Sequence
   181 static const char *sql_sequence_value1 = 
   182     "insert or replace into sequences (name, value, own) "
   183     "values (?1, "
   184     "       (select coalesce((select value + 1 from sequences "
   185     "           where name = ?1), 1 )), "
   186     "       (select coalesce((select own or ?2 from sequences "
   187     "           where name = ?1), ?2))) ; ";
   188 
   189 static const char *sql_sequence_value2 = 
   190     "select value, own from sequences where name = ?1 ;";
   191 
   192 static const char *sql_sequence_value3 = 
   193     "insert or replace into sequences (name, value, own) "
   194     "values (?1, "
   195     "        ?2, "
   196     "       (select coalesce((select own or ?3 from sequences "
   197     "           where name = ?1), ?3))) ; ";
   198         
   199 // Revocation tracking
   200 static const char *sql_set_revoked =
   201     "insert or replace into revoked_keys ("
   202     "    revoked_fpr, replacement_fpr, revocation_date) "
   203     "values (upper(replace(?1,' ','')),"
   204     "        upper(replace(?2,' ','')),"
   205     "        ?3) ;";
   206         
   207 static const char *sql_get_revoked = 
   208     "select revoked_fpr, revocation_date from revoked_keys"
   209     "    where replacement_fpr = upper(replace(?1,' ','')) ;";
   210 
   211 static int user_version(void *_version, int count, char **text, char **name)
   212 {
   213     assert(_version);
   214     assert(count == 1);
   215     assert(text && text[0]);
   216     if (!(_version && count == 1 && text && text[0]))
   217         return -1;
   218 
   219     int *version = (int *) _version;
   220     *version = atoi(text[0]);
   221     return 0;
   222 }
   223 
   224 DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
   225 {
   226     PEP_STATUS status = PEP_STATUS_OK;
   227     int int_result;
   228     
   229     bool in_first = false;
   230     bool very_first = false;
   231 
   232     assert(sqlite3_threadsafe());
   233     if (!sqlite3_threadsafe())
   234         return PEP_INIT_SQLITE3_WITHOUT_MUTEX;
   235 
   236     // a little race condition - but still a race condition
   237     // mitigated by calling caveat (see documentation)
   238 
   239     ++init_count;
   240     if (init_count == 0)
   241         in_first = true;
   242 
   243     assert(session);
   244     if (session == NULL)
   245         return PEP_ILLEGAL_VALUE;
   246 
   247     *session = NULL;
   248 
   249     pEpSession *_session = calloc(1, sizeof(pEpSession));
   250     assert(_session);
   251     if (_session == NULL)
   252         goto enomem;
   253 
   254     _session->version = PEP_ENGINE_VERSION;
   255 
   256 #ifdef DEBUG_ERRORSTACK
   257     _session->errorstack = new_stringlist(NULL);
   258 #endif
   259 
   260     assert(LOCAL_DB);
   261     if (LOCAL_DB == NULL) {
   262         status = PEP_INIT_CANNOT_OPEN_DB;
   263         goto pep_error;
   264     }
   265 
   266     int_result = sqlite3_open_v2(
   267             LOCAL_DB,
   268             &_session->db,
   269             SQLITE_OPEN_READWRITE
   270                 | SQLITE_OPEN_CREATE
   271                 | SQLITE_OPEN_FULLMUTEX
   272                 | SQLITE_OPEN_PRIVATECACHE,
   273             NULL 
   274         );
   275 
   276     if (int_result != SQLITE_OK) {
   277         status = PEP_INIT_CANNOT_OPEN_DB;
   278         goto pep_error;
   279     }
   280 
   281     sqlite3_busy_timeout(_session->db, BUSY_WAIT_TIME);
   282 
   283     assert(SYSTEM_DB);
   284     if (SYSTEM_DB == NULL) {
   285         status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
   286         goto pep_error;
   287     }
   288 
   289     int_result = sqlite3_open_v2(
   290             SYSTEM_DB, &_session->system_db,
   291             SQLITE_OPEN_READONLY
   292                 | SQLITE_OPEN_FULLMUTEX
   293                 | SQLITE_OPEN_SHAREDCACHE,
   294             NULL
   295         );
   296 
   297     if (int_result != SQLITE_OK) {
   298         status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
   299         goto pep_error;
   300     }
   301 
   302     sqlite3_busy_timeout(_session->system_db, 1000);
   303 
   304 // increment this when patching DDL
   305 #define _DDL_USER_VERSION "5"
   306 
   307     if (in_first) {
   308 
   309         int_result = sqlite3_exec(
   310             _session->db,
   311                 "create table if not exists version_info (\n"
   312                 "   id integer primary key,\n"
   313                 "   timestamp integer default (datetime('now')),\n"
   314                 "   version text,\n"
   315                 "   comment text\n"
   316                 ");\n",
   317                 NULL,
   318                 NULL,
   319                 NULL
   320         );
   321         int_result = sqlite3_exec(
   322             _session->db,
   323                 "PRAGMA application_id = 0x23423423;\n"
   324                 "create table if not exists log (\n"
   325                 "   timestamp integer default (datetime('now')),\n"
   326                 "   title text not null,\n"
   327                 "   entity text not null,\n"
   328                 "   description text,\n"
   329                 "   comment text\n"
   330                 ");\n"
   331                 "create index if not exists log_timestamp on log (\n"
   332                 "   timestamp\n"
   333                 ");\n"
   334                 "create table if not exists pgp_keypair (\n"
   335                 "   fpr text primary key,\n"
   336                 "   created integer,\n"
   337                 "   expires integer,\n"
   338                 "   comment text,\n"
   339                 "   flags integer default 0\n"
   340                 ");\n"
   341                 "create index if not exists pgp_keypair_expires on pgp_keypair (\n"
   342                 "   expires\n"
   343                 ");\n"
   344                 "create table if not exists person (\n"
   345                 "   id text primary key,\n"
   346                 "   username text not null,\n"
   347                 "   main_key_id text\n"
   348                 "       references pgp_keypair (fpr)\n"
   349                 "       on delete set null,\n"
   350                 "   lang text,\n"
   351                 "   comment text,\n"
   352                 "   device_group text\n"
   353                 ");\n"
   354                 "create table if not exists identity (\n"
   355                 "   address text,\n"
   356                 "   user_id text\n"
   357                 "       references person (id)\n"
   358                 "       on delete cascade,\n"
   359                 "   main_key_id text\n"
   360                 "       references pgp_keypair (fpr)\n"
   361                 "       on delete set null,\n"
   362                 "   comment text,\n"
   363                 "   flags integer default 0,"
   364                 "   primary key (address, user_id)\n"
   365                 ");\n"
   366                 "create table if not exists trust (\n"
   367                 "   user_id text not null\n"
   368                 "       references person (id)\n"
   369                 "       on delete cascade,\n"
   370                 "   pgp_keypair_fpr text not null\n"
   371                 "       references pgp_keypair (fpr)\n"
   372                 "       on delete cascade,\n"
   373                 "   comm_type integer not null,\n"
   374                 "   comment text,\n"
   375                 "   primary key (user_id, pgp_keypair_fpr)\n"
   376                 ");\n"
   377                 // blacklist
   378                 "create table if not exists blacklist_keys (\n"
   379                 "   fpr text primary key\n"
   380                 ");\n"
   381                 // sequences
   382                 "create table if not exists sequences(\n"
   383                 "   name text primary key,\n"
   384                 "   value integer default 0,\n"
   385                 "   own integer default 0\n"
   386                 ");\n"
   387                 "create table if not exists revoked_keys (\n"
   388                 "   revoked_fpr text primary key,\n"
   389                 "   replacement_fpr text not null\n"
   390                 "       references pgp_keypair (fpr)\n"
   391                 "       on delete cascade,\n"
   392                 "   revocation_date integer\n"
   393                 ");\n"
   394                 "create table if not exists own_keys (\n"
   395                 "   address text,\n"
   396                 "   user_id text,\n"
   397                 "   fpr text not null\n"
   398                 "       references pgp_keypair (fpr)\n"
   399                 "       on delete cascade,\n"
   400                 "   foreign key (address, user_id)\n"
   401                 "       references identity\n"
   402                 "       on delete cascade,\n"
   403                 "   check (user_id = '" PEP_OWN_USERID "')\n"
   404                 "   primary key (address, fpr)\n"
   405                 ");\n" 
   406                 ,
   407             NULL,
   408             NULL,
   409             NULL
   410         );
   411         assert(int_result == SQLITE_OK);
   412 
   413         int version;
   414         int_result = sqlite3_exec(
   415             _session->db,
   416             "pragma user_version;",
   417             user_version,
   418             &version,
   419             NULL
   420         );
   421         assert(int_result == SQLITE_OK);
   422 
   423         if(version != 0) { 
   424             // Version has been already set
   425 
   426             // Early mistake : version 0 shouldn't have existed.
   427             // Numbering should have started at 1 to detect newly created DB.
   428             // Version 0 DBs are not anymore compatible.
   429 
   430             // // Was version 0 compat code.
   431             // if (version < 1) {
   432             //     int_result = sqlite3_exec(
   433             //         _session->db,
   434             //         "alter table identity\n"
   435             //         "   add column flags integer default 0;\n",
   436             //         NULL,
   437             //         NULL,
   438             //         NULL
   439             //     );
   440             //     assert(int_result == SQLITE_OK);
   441             // }
   442 
   443             if (version < 2) {
   444                 int_result = sqlite3_exec(
   445                     _session->db,
   446                     "alter table pgp_keypair\n"
   447                     "   add column flags integer default 0;\n"
   448                     "alter table person\n"
   449                     "   add column device_group text;\n",
   450                     NULL,
   451                     NULL,
   452                     NULL
   453                 );
   454                 assert(int_result == SQLITE_OK);
   455             }
   456 
   457             if (version < 3) {
   458                 int_result = sqlite3_exec(
   459                     _session->db,
   460                     "alter table sequences\n"
   461                     "   add column own integer default 0;\n",
   462                     NULL,
   463                     NULL,
   464                     NULL
   465                 );
   466                 assert(int_result == SQLITE_OK);
   467             }
   468 
   469             if (version < 5) {
   470                 int_result = sqlite3_exec(
   471                     _session->db,
   472                     "delete from pgp_keypair where fpr = '';",
   473                     NULL,
   474                     NULL,
   475                     NULL
   476                 );
   477                 assert(int_result == SQLITE_OK);
   478                 int_result = sqlite3_exec(
   479                     _session->db,
   480                     "delete from trust where pgp_keypair_fpr = '';",
   481                     NULL,
   482                     NULL,
   483                     NULL
   484                 );
   485                 assert(int_result == SQLITE_OK);
   486             }
   487         }
   488         else { 
   489             // Version from DB was 0, it means this is initial setup.
   490             // DB has just been created, and all tables are empty.
   491             very_first = true;
   492         }
   493 
   494         if (version < atoi(_DDL_USER_VERSION)) {
   495             int_result = sqlite3_exec(
   496                 _session->db,
   497                 "pragma user_version = "_DDL_USER_VERSION";\n"
   498                 "insert or replace into version_info (id, version)"
   499                     "values (1, '" PEP_ENGINE_VERSION "');",
   500                 NULL,
   501                 NULL,
   502                 NULL
   503             );
   504             assert(int_result == SQLITE_OK);
   505         }
   506     }
   507 
   508     int_result = sqlite3_prepare_v2(_session->db, sql_log,
   509             (int)strlen(sql_log), &_session->log, NULL);
   510     assert(int_result == SQLITE_OK);
   511 
   512     int_result = sqlite3_prepare_v2(_session->system_db, sql_trustword,
   513             (int)strlen(sql_trustword), &_session->trustword, NULL);
   514     assert(int_result == SQLITE_OK);
   515 
   516     int_result = sqlite3_prepare_v2(_session->db, sql_get_identity,
   517             (int)strlen(sql_get_identity), &_session->get_identity, NULL);
   518     assert(int_result == SQLITE_OK);
   519 
   520     int_result = sqlite3_prepare_v2(_session->db, sql_get_identities_by_fpr,
   521             (int)strlen(sql_get_identities_by_fpr), 
   522             &_session->get_identities_by_fpr, NULL);
   523     assert(int_result == SQLITE_OK);
   524 
   525     int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
   526             (int)strlen(sql_set_person), &_session->set_person, NULL);
   527     assert(int_result == SQLITE_OK);
   528 
   529     int_result = sqlite3_prepare_v2(_session->db, sql_set_device_group,
   530             (int)strlen(sql_set_device_group), &_session->set_device_group, NULL);
   531     assert(int_result == SQLITE_OK);
   532 
   533     int_result = sqlite3_prepare_v2(_session->db, sql_get_device_group,
   534             (int)strlen(sql_get_device_group), &_session->get_device_group, NULL);
   535     assert(int_result == SQLITE_OK);
   536 
   537     int_result = sqlite3_prepare_v2(_session->db, sql_set_pgp_keypair,
   538             (int)strlen(sql_set_pgp_keypair), &_session->set_pgp_keypair,
   539             NULL);
   540     assert(int_result == SQLITE_OK);
   541 
   542     int_result = sqlite3_prepare_v2(_session->db, sql_set_identity,
   543             (int)strlen(sql_set_identity), &_session->set_identity, NULL);
   544     assert(int_result == SQLITE_OK);
   545 
   546     int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_flags,
   547             (int)strlen(sql_set_identity_flags), &_session->set_identity_flags,
   548             NULL);
   549     assert(int_result == SQLITE_OK);
   550 
   551     int_result = sqlite3_prepare_v2(_session->db, sql_unset_identity_flags,
   552             (int)strlen(sql_unset_identity_flags), &_session->unset_identity_flags,
   553             NULL);
   554     assert(int_result == SQLITE_OK);
   555 
   556     int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
   557             (int)strlen(sql_set_trust), &_session->set_trust, NULL);
   558     assert(int_result == SQLITE_OK);
   559 
   560     int_result = sqlite3_prepare_v2(_session->db, sql_get_trust,
   561             (int)strlen(sql_get_trust), &_session->get_trust, NULL);
   562     assert(int_result == SQLITE_OK);
   563 
   564     int_result = sqlite3_prepare_v2(_session->db, sql_get_key_userids,
   565             (int)strlen(sql_get_key_userids), &_session->get_key_userids, NULL);
   566     assert(int_result == SQLITE_OK);
   567 
   568     int_result = sqlite3_prepare_v2(_session->db, sql_least_trust,
   569             (int)strlen(sql_least_trust), &_session->least_trust, NULL);
   570     assert(int_result == SQLITE_OK);
   571 
   572     int_result = sqlite3_prepare_v2(_session->db, sql_mark_as_compromized,
   573             (int)strlen(sql_mark_as_compromized), &_session->mark_compromized,
   574             NULL);
   575     assert(int_result == SQLITE_OK);
   576 
   577     int_result = sqlite3_prepare_v2(_session->db, sql_crashdump,
   578             (int)strlen(sql_crashdump), &_session->crashdump, NULL);
   579     assert(int_result == SQLITE_OK);
   580 
   581     int_result = sqlite3_prepare_v2(_session->system_db, sql_languagelist,
   582             (int)strlen(sql_languagelist), &_session->languagelist, NULL);
   583     assert(int_result == SQLITE_OK);
   584 
   585     int_result = sqlite3_prepare_v2(_session->system_db, sql_i18n_token,
   586             (int)strlen(sql_i18n_token), &_session->i18n_token, NULL);
   587     assert(int_result == SQLITE_OK);
   588 
   589     // blacklist
   590 
   591     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_add,
   592             (int)strlen(sql_blacklist_add), &_session->blacklist_add, NULL);
   593     assert(int_result == SQLITE_OK);
   594 
   595     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_delete,
   596             (int)strlen(sql_blacklist_delete), &_session->blacklist_delete,
   597             NULL);
   598     assert(int_result == SQLITE_OK);
   599 
   600     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_is_listed,
   601             (int)strlen(sql_blacklist_is_listed),
   602             &_session->blacklist_is_listed, NULL);
   603     assert(int_result == SQLITE_OK);
   604 
   605     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_retrieve,
   606             (int)strlen(sql_blacklist_retrieve), &_session->blacklist_retrieve,
   607             NULL);
   608     assert(int_result == SQLITE_OK);
   609     
   610     // Own keys
   611     
   612     int_result = sqlite3_prepare_v2(_session->db, sql_own_key_is_listed,
   613             (int)strlen(sql_own_key_is_listed), &_session->own_key_is_listed,
   614             NULL);
   615     assert(int_result == SQLITE_OK);
   616     
   617     int_result = sqlite3_prepare_v2(_session->db, sql_own_identities_retrieve,
   618             (int)strlen(sql_own_identities_retrieve),
   619             &_session->own_identities_retrieve, NULL);
   620     assert(int_result == SQLITE_OK);
   621  
   622     int_result = sqlite3_prepare_v2(_session->db, sql_own_keys_retrieve,
   623             (int)strlen(sql_own_keys_retrieve),
   624             &_session->own_keys_retrieve, NULL);
   625     assert(int_result == SQLITE_OK);
   626  
   627     int_result = sqlite3_prepare_v2(_session->db, sql_set_own_key,
   628             (int)strlen(sql_set_own_key),
   629             &_session->set_own_key, NULL);
   630     assert(int_result == SQLITE_OK);
   631  
   632     // Sequence
   633 
   634     int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value1,
   635             (int)strlen(sql_sequence_value1), &_session->sequence_value1,
   636             NULL);
   637     assert(int_result == SQLITE_OK);
   638 
   639     int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value2,
   640             (int)strlen(sql_sequence_value2), &_session->sequence_value2,
   641             NULL);
   642     assert(int_result == SQLITE_OK);
   643 
   644     int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value3,
   645             (int)strlen(sql_sequence_value3), &_session->sequence_value3,
   646             NULL);
   647     assert(int_result == SQLITE_OK);
   648 
   649     // Revocation tracking
   650     
   651     int_result = sqlite3_prepare_v2(_session->db, sql_set_revoked,
   652             (int)strlen(sql_set_revoked), &_session->set_revoked, NULL);
   653     assert(int_result == SQLITE_OK);
   654     
   655     int_result = sqlite3_prepare_v2(_session->db, sql_get_revoked,
   656             (int)strlen(sql_get_revoked), &_session->get_revoked, NULL);
   657     assert(int_result == SQLITE_OK);
   658     
   659     status = init_cryptotech(_session, in_first);
   660     if (status != PEP_STATUS_OK)
   661         goto pep_error;
   662 
   663     status = init_transport_system(_session, in_first);
   664     if (status != PEP_STATUS_OK)
   665         goto pep_error;
   666 
   667     status = log_event(_session, "init", "pEp " PEP_ENGINE_VERSION, NULL, NULL);
   668     if (status != PEP_STATUS_OK)
   669         goto pep_error;
   670 
   671     // runtime config
   672 
   673 #ifdef ANDROID
   674 #elif TARGET_OS_IPHONE
   675 #else /* Desktop */
   676     if (very_first)
   677     {
   678         // On first run, all private keys already present in PGP keyring 
   679         // are taken as own in order to seamlessly integrate with
   680         // pre-existing GPG setup.
   681 
   682         ////////////////////////////// WARNING: ///////////////////////////
   683         // Considering all PGP priv keys as own is dangerous in case of 
   684         // re-initialization of pEp DB, while keeping PGP keyring as-is!
   685         //
   686         // Indeed, if pEpEngine did import spoofed private keys in previous
   687         // install, then those keys become automatically trusted in case 
   688         // pEp_management.db is deleted.
   689         //
   690         // A solution to distinguish bare GPG keyring from pEp keyring is
   691         // needed here. Then keys managed by pEpEngine wouldn't be
   692         // confused with GPG keys managed by the user through GPA.
   693         ///////////////////////////////////////////////////////////////////
   694         
   695         stringlist_t *keylist = NULL;
   696 
   697         status = find_private_keys(_session, NULL, &keylist);
   698         assert(status != PEP_OUT_OF_MEMORY);
   699         if (status == PEP_OUT_OF_MEMORY)
   700             return PEP_OUT_OF_MEMORY;
   701         
   702         if (keylist != NULL && keylist->value != NULL)
   703         {
   704             stringlist_t *_keylist;
   705             for (_keylist = keylist; _keylist && _keylist->value; _keylist = _keylist->next) {
   706                 status = set_own_key(_session, 
   707                                      "" /* address is unused in own_keys */,
   708                                      _keylist->value);
   709             }
   710         }
   711     }
   712 #endif
   713 
   714     // sync_session set to own session by default
   715     // sync_session is then never null on a valid session
   716     _session->sync_session = _session;
   717 
   718     *session = _session;
   719     return PEP_STATUS_OK;
   720 
   721 enomem:
   722     status = PEP_OUT_OF_MEMORY;
   723 
   724 pep_error:
   725     release(_session);
   726     return status;
   727 }
   728 
   729 DYNAMIC_API void release(PEP_SESSION session)
   730 {
   731     bool out_last = false;
   732 
   733     assert(init_count >= 0);
   734     assert(session);
   735 
   736     if (!((init_count >= 0) && session))
   737         return;
   738 
   739     // a small race condition but still a race condition
   740     // mitigated by calling caveat (see documentation)
   741 
   742     if (init_count == 0)
   743         out_last = true;
   744     --init_count;
   745 
   746     if (session) {
   747         if (session->sync_state != DeviceState_state_NONE)
   748             unregister_sync_callbacks(session);
   749 
   750         if (session->db) {
   751             if (session->log)
   752                 sqlite3_finalize(session->log);
   753             if (session->trustword)
   754                 sqlite3_finalize(session->trustword);
   755             if (session->get_identity)
   756                 sqlite3_finalize(session->get_identity);
   757             if (session->get_identities_by_fpr)
   758                 sqlite3_finalize(session->get_identities_by_fpr);        
   759             if (session->set_person)
   760                 sqlite3_finalize(session->set_person);
   761             if (session->set_device_group)
   762                 sqlite3_finalize(session->set_device_group);
   763             if (session->get_device_group)
   764                 sqlite3_finalize(session->get_device_group);
   765             if (session->set_pgp_keypair)
   766                 sqlite3_finalize(session->set_pgp_keypair);
   767             if (session->set_identity)
   768                 sqlite3_finalize(session->set_identity);
   769             if (session->set_identity_flags)
   770                 sqlite3_finalize(session->set_identity_flags);
   771             if (session->unset_identity_flags)
   772                 sqlite3_finalize(session->unset_identity_flags);
   773             if (session->set_trust)
   774                 sqlite3_finalize(session->set_trust);
   775             if (session->get_trust)
   776                 sqlite3_finalize(session->get_trust);
   777             if (session->get_key_userids)
   778                 sqlite3_finalize(session->get_key_userids);    
   779             if (session->least_trust)
   780                 sqlite3_finalize(session->least_trust);
   781             if (session->mark_compromized)
   782                 sqlite3_finalize(session->mark_compromized);
   783             if (session->crashdump)
   784                 sqlite3_finalize(session->crashdump);
   785             if (session->languagelist)
   786                 sqlite3_finalize(session->languagelist);
   787             if (session->i18n_token)
   788                 sqlite3_finalize(session->i18n_token);
   789             if (session->blacklist_add)
   790                 sqlite3_finalize(session->blacklist_add);
   791             if (session->blacklist_delete)
   792                 sqlite3_finalize(session->blacklist_delete);
   793             if (session->blacklist_is_listed)
   794                 sqlite3_finalize(session->blacklist_is_listed);
   795             if (session->blacklist_retrieve)
   796                 sqlite3_finalize(session->blacklist_retrieve);
   797             if (session->own_key_is_listed)
   798                 sqlite3_finalize(session->own_key_is_listed);
   799             if (session->own_identities_retrieve)
   800                 sqlite3_finalize(session->own_identities_retrieve);
   801             if (session->own_keys_retrieve)
   802                 sqlite3_finalize(session->own_keys_retrieve);
   803             if (session->set_own_key)
   804                 sqlite3_finalize(session->set_own_key);
   805             if (session->sequence_value1)
   806                 sqlite3_finalize(session->sequence_value1);
   807             if (session->sequence_value2)
   808                 sqlite3_finalize(session->sequence_value2);
   809             if (session->sequence_value3)
   810                 sqlite3_finalize(session->sequence_value3);
   811             if (session->set_revoked)
   812                 sqlite3_finalize(session->set_revoked);
   813             if (session->get_revoked)
   814                 sqlite3_finalize(session->get_revoked);
   815 
   816             if (session->db)
   817                 sqlite3_close_v2(session->db);
   818             if (session->system_db)
   819                 sqlite3_close_v2(session->system_db);
   820         }
   821 
   822         release_transport_system(session, out_last);
   823         release_cryptotech(session, out_last);
   824 
   825 #ifdef DEBUG_ERRORSTACK
   826         free_stringlist(session->errorstack);
   827 #endif
   828         free(session);
   829     }
   830 }
   831 
   832 DYNAMIC_API void config_passive_mode(PEP_SESSION session, bool enable)
   833 {
   834     assert(session);
   835     session->passive_mode = enable;
   836 }
   837 
   838 DYNAMIC_API void config_unencrypted_subject(PEP_SESSION session, bool enable)
   839 {
   840     assert(session);
   841     session->unencrypted_subject = enable;
   842 }
   843 
   844 DYNAMIC_API void config_keep_sync_msg(PEP_SESSION session, bool enable)
   845 {
   846     assert(session);
   847     session->keep_sync_msg = enable;
   848 }
   849 
   850 DYNAMIC_API PEP_STATUS log_event(
   851         PEP_SESSION session,
   852         const char *title,
   853         const char *entity,
   854         const char *description,
   855         const char *comment
   856     )
   857 {
   858     PEP_STATUS status = PEP_STATUS_OK;
   859     int result;
   860 
   861     assert(session);
   862     assert(title);
   863     assert(entity);
   864 
   865     if (!(session && title && entity))
   866         return PEP_ILLEGAL_VALUE;
   867 
   868     sqlite3_reset(session->log);
   869     sqlite3_bind_text(session->log, 1, title, -1, SQLITE_STATIC);
   870     sqlite3_bind_text(session->log, 2, entity, -1, SQLITE_STATIC);
   871     if (description)
   872         sqlite3_bind_text(session->log, 3, description, -1, SQLITE_STATIC);
   873     else
   874         sqlite3_bind_null(session->log, 3);
   875     if (comment)
   876         sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
   877     else
   878         sqlite3_bind_null(session->log, 4);
   879     do {
   880         result = sqlite3_step(session->log);
   881         assert(result == SQLITE_DONE || result == SQLITE_BUSY);
   882         if (result != SQLITE_DONE && result != SQLITE_BUSY)
   883             status = PEP_UNKNOWN_ERROR;
   884     } while (result == SQLITE_BUSY);
   885     sqlite3_reset(session->log);
   886 
   887     return ERROR(status);
   888 }
   889 
   890 DYNAMIC_API PEP_STATUS trustword(
   891             PEP_SESSION session, uint16_t value, const char *lang,
   892             char **word, size_t *wsize
   893         )
   894 {
   895     PEP_STATUS status = PEP_STATUS_OK;
   896 
   897     assert(session);
   898     assert(word);
   899     assert(wsize);
   900 
   901     if (!(session && word && wsize))
   902         return PEP_ILLEGAL_VALUE;
   903 
   904     *word = NULL;
   905     *wsize = 0;
   906 
   907     if (lang == NULL)
   908         lang = "en";
   909 
   910     assert((lang[0] >= 'A' && lang[0] <= 'Z')
   911             || (lang[0] >= 'a' && lang[0] <= 'z'));
   912     assert((lang[1] >= 'A' && lang[1] <= 'Z')
   913             || (lang[1] >= 'a' && lang[1] <= 'z'));
   914     assert(lang[2] == 0);
   915 
   916     sqlite3_reset(session->trustword);
   917     sqlite3_bind_text(session->trustword, 1, lang, -1, SQLITE_STATIC);
   918     sqlite3_bind_int(session->trustword, 2, value);
   919 
   920     const int result = sqlite3_step(session->trustword);
   921     if (result == SQLITE_ROW) {
   922         *word = strdup((const char *) sqlite3_column_text(session->trustword,
   923                     1));
   924         if (*word)
   925             *wsize = sqlite3_column_bytes(session->trustword, 1);
   926         else
   927             status = PEP_OUT_OF_MEMORY;
   928     } else
   929         status = PEP_TRUSTWORD_NOT_FOUND;
   930 
   931     sqlite3_reset(session->trustword);
   932     return status;
   933 }
   934 
   935 DYNAMIC_API PEP_STATUS trustwords(
   936         PEP_SESSION session, const char *fingerprint, const char *lang,
   937         char **words, size_t *wsize, int max_words
   938     )
   939 {
   940     const char *source = fingerprint;
   941 
   942     assert(session);
   943     assert(fingerprint);
   944     assert(words);
   945     assert(wsize);
   946     assert(max_words >= 0);
   947 
   948     if (!(session && fingerprint && words && wsize && max_words >= 0))
   949         return PEP_ILLEGAL_VALUE;
   950 
   951     *words = NULL;
   952     *wsize = 0;
   953 
   954     char *buffer = calloc(1, MAX_TRUSTWORDS_SPACE);
   955     assert(buffer);
   956     if (buffer == NULL)
   957         return PEP_OUT_OF_MEMORY;
   958     char *dest = buffer;
   959 
   960     const size_t fsize = strlen(fingerprint);
   961 
   962     if (!lang || !lang[0])
   963         lang = "en";
   964 
   965     assert((lang[0] >= 'A' && lang[0] <= 'Z')
   966             || (lang[0] >= 'a' && lang[0] <= 'z'));
   967     assert((lang[1] >= 'A' && lang[1] <= 'Z')
   968             || (lang[1] >= 'a' && lang[1] <= 'z'));
   969     assert(lang[2] == 0);
   970 
   971     int n_words = 0;
   972     while (source < fingerprint + fsize) {
   973         PEP_STATUS _status;
   974         uint16_t value;
   975         char *word = NULL;
   976         size_t _wsize = 0;
   977         int j;
   978 
   979         for (value=0, j=0; j < 4 && source < fingerprint + fsize; ) {
   980             if (*source >= 'a' && *source <= 'f')
   981                 value += (*source - 'a' + 10) << (3 - j++) * 4;
   982             else if (*source >= 'A' && *source <= 'F')
   983                 value += (*source - 'A' + 10) << (3 - j++) * 4;
   984             else if (*source >= '0' && *source <= '9')
   985                 value += (*source - '0') << (3 - j++) * 4;
   986             
   987             source++;
   988         }
   989 
   990         _status = trustword(session, value, lang, &word, &_wsize);
   991         if (_status == PEP_OUT_OF_MEMORY) {
   992             free(buffer);
   993             return PEP_OUT_OF_MEMORY;
   994         }
   995         if (word == NULL) {
   996             free(buffer);
   997             return PEP_TRUSTWORD_NOT_FOUND;
   998         }
   999 
  1000         if (dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1) {
  1001             strncpy(dest, word, _wsize);
  1002             free(word);
  1003             dest += _wsize;
  1004         }
  1005         else {
  1006             free(word);
  1007             break; // buffer full
  1008         }
  1009 
  1010         if (source < fingerprint + fsize
  1011                 && dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1)
  1012             *dest++ = ' ';
  1013 
  1014         ++n_words;
  1015         if (max_words && n_words >= max_words)
  1016             break;
  1017     }
  1018 
  1019     *words = buffer;
  1020     *wsize = dest - buffer;
  1021     return PEP_STATUS_OK;
  1022 }
  1023 
  1024 pEp_identity *new_identity(
  1025         const char *address, const char *fpr, const char *user_id,
  1026         const char *username
  1027     )
  1028 {
  1029     pEp_identity *result = calloc(1, sizeof(pEp_identity));
  1030     assert(result);
  1031     if (result) {
  1032         if (address) {
  1033             result->address = strdup(address);
  1034             assert(result->address);
  1035             if (result->address == NULL) {
  1036                 free(result);
  1037                 return NULL;
  1038             }
  1039         }
  1040         if (fpr) {
  1041             result->fpr = strdup(fpr);
  1042             assert(result->fpr);
  1043             if (result->fpr == NULL) {
  1044                 free_identity(result);
  1045                 return NULL;
  1046             }
  1047         }
  1048         if (user_id) {
  1049             result->user_id = strdup(user_id);
  1050             assert(result->user_id);
  1051             if (result->user_id == NULL) {
  1052                 free_identity(result);
  1053                 return NULL;
  1054             }
  1055         }
  1056         if (username) {
  1057             result->username = strdup(username);
  1058             assert(result->username);
  1059             if (result->username == NULL) {
  1060                 free_identity(result);
  1061                 return NULL;
  1062             }
  1063         }
  1064     }
  1065     return result;
  1066 }
  1067 
  1068 pEp_identity *identity_dup(const pEp_identity *src)
  1069 {
  1070     assert(src);
  1071 
  1072     pEp_identity *dup = new_identity(src->address, src->fpr, src->user_id,
  1073             src->username);
  1074     assert(dup);
  1075     if (dup == NULL)
  1076         return NULL;
  1077     
  1078     dup->comm_type = src->comm_type;
  1079     dup->lang[0] = src->lang[0];
  1080     dup->lang[1] = src->lang[1];
  1081     dup->lang[2] = 0;
  1082     dup->me = src->me;
  1083     dup->flags = src->flags;
  1084 
  1085     return dup;
  1086 }
  1087 
  1088 void free_identity(pEp_identity *identity)
  1089 {
  1090     if (identity) {
  1091         free(identity->address);
  1092         free(identity->fpr);
  1093         free(identity->user_id);
  1094         free(identity->username);
  1095         free(identity);
  1096     }
  1097 }
  1098 
  1099 DYNAMIC_API PEP_STATUS get_identity(
  1100         PEP_SESSION session,
  1101         const char *address,
  1102         const char *user_id,
  1103         pEp_identity **identity
  1104     )
  1105 {
  1106     PEP_STATUS status = PEP_STATUS_OK;
  1107     static pEp_identity *_identity;
  1108 
  1109     assert(session);
  1110     assert(address);
  1111     assert(address[0]);
  1112     assert(identity);
  1113 
  1114     if (!(session && address && address[0] && identity))
  1115         return PEP_ILLEGAL_VALUE;
  1116 
  1117     *identity = NULL;
  1118 
  1119     sqlite3_reset(session->get_identity);
  1120     sqlite3_bind_text(session->get_identity, 1, address, -1, SQLITE_STATIC);
  1121     sqlite3_bind_text(session->get_identity, 2, user_id, -1, SQLITE_STATIC);
  1122 
  1123     const int result = sqlite3_step(session->get_identity);
  1124     switch (result) {
  1125     case SQLITE_ROW:
  1126         _identity = new_identity(
  1127                 address,
  1128                 (const char *) sqlite3_column_text(session->get_identity, 0),
  1129                 user_id,
  1130                 (const char *) sqlite3_column_text(session->get_identity, 1)
  1131                 );
  1132         assert(_identity);
  1133         if (_identity == NULL)
  1134             return PEP_OUT_OF_MEMORY;
  1135 
  1136         _identity->comm_type = (PEP_comm_type)
  1137             sqlite3_column_int(session->get_identity, 2);
  1138         const char* const _lang = (const char *)
  1139             sqlite3_column_text(session->get_identity, 3);
  1140         if (_lang && _lang[0]) {
  1141             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  1142             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  1143             assert(_lang[2] == 0);
  1144             _identity->lang[0] = _lang[0];
  1145             _identity->lang[1] = _lang[1];
  1146             _identity->lang[2] = 0;
  1147         }
  1148         _identity->flags = (unsigned int)
  1149             sqlite3_column_int(session->get_identity, 4);
  1150         *identity = _identity;
  1151         break;
  1152     default:
  1153         status = PEP_CANNOT_FIND_IDENTITY;
  1154         *identity = NULL;
  1155     }
  1156 
  1157     sqlite3_reset(session->get_identity);
  1158     return status;
  1159 }
  1160 
  1161 DYNAMIC_API PEP_STATUS set_identity(
  1162         PEP_SESSION session, const pEp_identity *identity
  1163     )
  1164 {
  1165     int result;
  1166 
  1167     assert(session);
  1168     assert(identity);
  1169     assert(identity->address);
  1170     assert(identity->user_id);
  1171     assert(identity->username);
  1172 
  1173     if (!(session && identity && identity->address &&
  1174                 identity->user_id && identity->username))
  1175         return PEP_ILLEGAL_VALUE;
  1176 
  1177     PEP_STATUS status = PEP_STATUS_OK;
  1178     
  1179     bool listed;
  1180 
  1181     bool has_fpr = (identity->fpr && identity->fpr[0] != '\0');
  1182     
  1183     if (has_fpr) {    
  1184         // blacklist check
  1185         status = blacklist_is_listed(session, identity->fpr, &listed);
  1186         assert(status == PEP_STATUS_OK);
  1187         if (status != PEP_STATUS_OK)
  1188             return status;
  1189 
  1190         if (listed)
  1191             return PEP_KEY_BLACKLISTED;
  1192     }
  1193 
  1194     sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
  1195 
  1196     if (identity->lang[0]) {
  1197         assert(identity->lang[0] >= 'a' && identity->lang[0] <= 'z');
  1198         assert(identity->lang[1] >= 'a' && identity->lang[1] <= 'z');
  1199         assert(identity->lang[2] == 0);
  1200     }
  1201 
  1202     sqlite3_reset(session->set_person);
  1203     sqlite3_bind_text(session->set_person, 1, identity->user_id, -1,
  1204             SQLITE_STATIC);
  1205     sqlite3_bind_text(session->set_person, 2, identity->username, -1,
  1206             SQLITE_STATIC);
  1207     if (identity->lang[0])
  1208         sqlite3_bind_text(session->set_person, 3, identity->lang, 2,
  1209                 SQLITE_STATIC);
  1210     else
  1211         sqlite3_bind_null(session->set_person, 3);
  1212     sqlite3_bind_text(session->set_person, 4, identity->fpr, -1,
  1213                       SQLITE_STATIC);
  1214     result = sqlite3_step(session->set_person);
  1215     sqlite3_reset(session->set_person);
  1216     if (result != SQLITE_DONE) {
  1217         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  1218         return PEP_CANNOT_SET_PERSON;
  1219     }
  1220 
  1221     if (has_fpr) {
  1222         sqlite3_reset(session->set_pgp_keypair);
  1223         sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
  1224                 SQLITE_STATIC);
  1225         result = sqlite3_step(session->set_pgp_keypair);
  1226         sqlite3_reset(session->set_pgp_keypair);
  1227         if (result != SQLITE_DONE) {
  1228             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  1229             return PEP_CANNOT_SET_PGP_KEYPAIR;
  1230         }
  1231     }
  1232 
  1233     sqlite3_reset(session->set_identity);
  1234     sqlite3_bind_text(session->set_identity, 1, identity->address, -1,
  1235             SQLITE_STATIC);
  1236     sqlite3_bind_text(session->set_identity, 2, identity->fpr, -1,
  1237             SQLITE_STATIC);
  1238     sqlite3_bind_text(session->set_identity, 3, identity->user_id, -1,
  1239             SQLITE_STATIC);
  1240     sqlite3_bind_int(session->set_identity, 4, identity->flags);
  1241     result = sqlite3_step(session->set_identity);
  1242     sqlite3_reset(session->set_identity);
  1243     if (result != SQLITE_DONE) {
  1244         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  1245         return PEP_CANNOT_SET_IDENTITY;
  1246     }
  1247 
  1248     if (has_fpr) {
  1249         if(strcmp(identity->user_id, PEP_OWN_USERID) == 0) {
  1250             sqlite3_reset(session->set_own_key);
  1251             sqlite3_bind_text(session->set_own_key, 1, identity->address, -1,
  1252                 SQLITE_STATIC);
  1253             sqlite3_bind_text(session->set_own_key, 2, identity->fpr, -1,
  1254                 SQLITE_STATIC);
  1255             result = sqlite3_step(session->set_own_key);
  1256             sqlite3_reset(session->set_own_key);
  1257             if (result != SQLITE_DONE) {
  1258                 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  1259                 return PEP_CANNOT_SET_PGP_KEYPAIR;
  1260             }
  1261         }
  1262 
  1263         status = set_trust(session, identity->user_id, identity->fpr,
  1264                            identity->comm_type)
  1265         sqlite3_reset(session->set_trust);
  1266         sqlite3_bind_text(session->set_trust, 1, identity->user_id, -1,
  1267                 SQLITE_STATIC);
  1268         sqlite3_bind_text(session->set_trust, 2, identity->fpr, -1,
  1269                 SQLITE_STATIC);
  1270         sqlite3_bind_int(session->set_trust, 3, identity->comm_type);
  1271         result = sqlite3_step(session->set_trust);
  1272         sqlite3_reset(session->set_trust);
  1273         if (result != SQLITE_DONE) {
  1274             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  1275             return PEP_CANNOT_SET_TRUST;
  1276         }
  1277     }
  1278     
  1279     result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  1280     if (result == SQLITE_OK)
  1281         return PEP_STATUS_OK;
  1282     else
  1283         return PEP_COMMIT_FAILED;
  1284 }
  1285 
  1286 PEP_STATUS get_identities_by_fpr(PEP_SESSION session, 
  1287                                  char* fpr, 
  1288                                  identity_list** id_list) 
  1289 {
  1290     PEP_STATUS status = PEP_STATUS_OK;
  1291     
  1292     return status;
  1293 }
  1294 
  1295 
  1296 static PEP_STATUS set_trust(PEP_SESSION session, 
  1297                             const char* user_id,
  1298                             const char* fpr, 
  1299                             PEP_comm_type comm_type)
  1300 {
  1301     if (!user_id || !fpr)
  1302         return PEP_ILLEGAL_VALUE;
  1303         
  1304     sqlite3_reset(session->set_trust);
  1305     sqlite3_bind_text(session->set_trust, 1, user_id, -1,
  1306             SQLITE_STATIC);
  1307     sqlite3_bind_text(session->set_trust, 2, fpr, -1,
  1308             SQLITE_STATIC);
  1309     sqlite3_bind_int(session->set_trust, 3, comm_type);
  1310     result = sqlite3_step(session->set_trust);
  1311     sqlite3_reset(session->set_trust);
  1312     if (result != SQLITE_DONE) {
  1313         return PEP_CANNOT_SET_TRUST;
  1314     }
  1315     
  1316     return PEP_STATUS_OK;
  1317 }
  1318 
  1319 DYNAMIC_API PEP_STATUS set_device_group(
  1320         PEP_SESSION session,
  1321         const char *group_name
  1322     )
  1323 {
  1324     int result;
  1325 
  1326     assert(session);
  1327 
  1328     if (!(session && group_name))
  1329         return PEP_ILLEGAL_VALUE;
  1330 
  1331     sqlite3_reset(session->set_device_group);
  1332     if(group_name){
  1333         sqlite3_bind_text(session->set_device_group, 1, group_name, -1,
  1334                 SQLITE_STATIC);
  1335     } else {
  1336         sqlite3_bind_null(session->set_device_group, 1);
  1337     }
  1338 
  1339     result = sqlite3_step(session->set_device_group);
  1340     sqlite3_reset(session->set_device_group);
  1341     if (result != SQLITE_DONE)
  1342         return PEP_CANNOT_SET_PERSON;
  1343 
  1344     return PEP_STATUS_OK;
  1345 }
  1346 
  1347 DYNAMIC_API PEP_STATUS get_device_group(PEP_SESSION session, char **group_name)
  1348 {
  1349     PEP_STATUS status = PEP_STATUS_OK;
  1350     int result;
  1351 
  1352     assert(session);
  1353     assert(group_name);
  1354 
  1355     if (!(session && group_name))
  1356         return PEP_ILLEGAL_VALUE;
  1357 
  1358     sqlite3_reset(session->get_device_group);
  1359 
  1360     result = sqlite3_step(session->get_device_group);
  1361     switch (result) {
  1362     case SQLITE_ROW: {
  1363         const char *_group_name = (const char *)sqlite3_column_text(session->get_device_group, 0);
  1364         if(_group_name){
  1365             *group_name = strdup(_group_name);
  1366                 if(*group_name == NULL)
  1367                     status = PEP_OUT_OF_MEMORY;
  1368         }
  1369         break;
  1370     }
  1371  
  1372     default:
  1373         status = PEP_RECORD_NOT_FOUND;
  1374     }
  1375 
  1376     sqlite3_reset(session->get_device_group);
  1377     return status;
  1378 }
  1379 
  1380 DYNAMIC_API PEP_STATUS set_identity_flags(
  1381         PEP_SESSION session,
  1382         pEp_identity *identity,
  1383         unsigned int flags
  1384     )
  1385 {
  1386     int result;
  1387 
  1388     assert(session);
  1389     assert(identity);
  1390     assert(identity->address);
  1391     assert(identity->user_id);
  1392 
  1393     if (!(session && identity && identity->address && identity->user_id))
  1394         return PEP_ILLEGAL_VALUE;
  1395 
  1396     sqlite3_reset(session->set_identity_flags);
  1397     sqlite3_bind_int(session->set_identity_flags, 1, flags);
  1398     sqlite3_bind_text(session->set_identity_flags, 2, identity->address, -1,
  1399             SQLITE_STATIC);
  1400     sqlite3_bind_text(session->set_identity_flags, 3, identity->user_id, -1,
  1401             SQLITE_STATIC);
  1402     result = sqlite3_step(session->set_identity_flags);
  1403     sqlite3_reset(session->set_identity_flags);
  1404     if (result != SQLITE_DONE)
  1405         return PEP_CANNOT_SET_IDENTITY;
  1406 
  1407     identity->flags |= flags;
  1408     return PEP_STATUS_OK;
  1409 }
  1410 
  1411 DYNAMIC_API PEP_STATUS unset_identity_flags(
  1412         PEP_SESSION session,
  1413         pEp_identity *identity,
  1414         unsigned int flags
  1415     )
  1416 {
  1417     int result;
  1418 
  1419     assert(session);
  1420     assert(identity);
  1421     assert(identity->address);
  1422     assert(identity->user_id);
  1423 
  1424     if (!(session && identity && identity->address && identity->user_id))
  1425         return PEP_ILLEGAL_VALUE;
  1426 
  1427     sqlite3_reset(session->unset_identity_flags);
  1428     sqlite3_bind_int(session->unset_identity_flags, 1, flags);
  1429     sqlite3_bind_text(session->unset_identity_flags, 2, identity->address, -1,
  1430             SQLITE_STATIC);
  1431     sqlite3_bind_text(session->unset_identity_flags, 3, identity->user_id, -1,
  1432             SQLITE_STATIC);
  1433     result = sqlite3_step(session->unset_identity_flags);
  1434     sqlite3_reset(session->unset_identity_flags);
  1435     if (result != SQLITE_DONE)
  1436         return PEP_CANNOT_SET_IDENTITY;
  1437 
  1438     identity->flags &= ~flags;
  1439     return PEP_STATUS_OK;
  1440 }
  1441 
  1442 DYNAMIC_API PEP_STATUS mark_as_compromized(
  1443         PEP_SESSION session,
  1444         const char *fpr
  1445     )
  1446 {
  1447     int result;
  1448 
  1449     assert(session);
  1450     assert(fpr && fpr[0]);
  1451 
  1452     if (!(session && fpr && fpr[0]))
  1453         return PEP_ILLEGAL_VALUE;
  1454 
  1455     sqlite3_reset(session->mark_compromized);
  1456     sqlite3_bind_text(session->mark_compromized, 1, fpr, -1,
  1457             SQLITE_STATIC);
  1458     result = sqlite3_step(session->mark_compromized);
  1459     sqlite3_reset(session->mark_compromized);
  1460 
  1461     if (result != SQLITE_DONE)
  1462         return PEP_CANNOT_SET_TRUST;
  1463 
  1464     return PEP_STATUS_OK;
  1465 }
  1466 
  1467 void pEp_free(void *p)
  1468 {
  1469     free(p);
  1470 }
  1471 
  1472 DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
  1473 {
  1474     PEP_STATUS status = PEP_STATUS_OK;
  1475     int result;
  1476 
  1477     assert(session);
  1478     assert(identity);
  1479     assert(identity->user_id);
  1480     assert(identity->user_id[0]);
  1481     assert(identity->fpr);
  1482     assert(identity->fpr[0]);
  1483 
  1484     if (!(session && identity && identity->user_id && identity->user_id[0] &&
  1485                 identity->fpr && identity->fpr[0]))
  1486         return PEP_ILLEGAL_VALUE;
  1487 
  1488     identity->comm_type = PEP_ct_unknown;
  1489 
  1490     sqlite3_reset(session->get_trust);
  1491     sqlite3_bind_text(session->get_trust, 1, identity->user_id, -1,
  1492             SQLITE_STATIC);
  1493     sqlite3_bind_text(session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
  1494 
  1495     result = sqlite3_step(session->get_trust);
  1496     switch (result) {
  1497     case SQLITE_ROW: {
  1498         int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust,
  1499                 0);
  1500         identity->comm_type = comm_type;
  1501         break;
  1502     }
  1503  
  1504     default:
  1505         status = PEP_CANNOT_FIND_IDENTITY;
  1506     }
  1507 
  1508     sqlite3_reset(session->get_trust);
  1509     return status;
  1510 }
  1511 
  1512 DYNAMIC_API PEP_STATUS least_trust(
  1513         PEP_SESSION session,
  1514         const char *fpr,
  1515         PEP_comm_type *comm_type
  1516     )
  1517 {
  1518     PEP_STATUS status = PEP_STATUS_OK;
  1519     int result;
  1520 
  1521     assert(session);
  1522     assert(fpr);
  1523     assert(comm_type);
  1524 
  1525     if (!(session && fpr && comm_type))
  1526         return PEP_ILLEGAL_VALUE;
  1527 
  1528     *comm_type = PEP_ct_unknown;
  1529 
  1530     sqlite3_reset(session->least_trust);
  1531     sqlite3_bind_text(session->least_trust, 1, fpr, -1, SQLITE_STATIC);
  1532 
  1533     result = sqlite3_step(session->least_trust);
  1534     switch (result) {
  1535         case SQLITE_ROW: {
  1536             int _comm_type = sqlite3_column_int(session->least_trust, 0);
  1537             *comm_type = (PEP_comm_type) _comm_type;
  1538             break;
  1539         }
  1540         default:
  1541             // never reached because of sql min()
  1542             status = PEP_CANNOT_FIND_IDENTITY;
  1543     }
  1544 
  1545     sqlite3_reset(session->least_trust);
  1546     return status;
  1547 }
  1548 
  1549 DYNAMIC_API PEP_STATUS decrypt_and_verify(
  1550     PEP_SESSION session, const char *ctext, size_t csize,
  1551     const char *dsigtext, size_t dsigsize,
  1552     char **ptext, size_t *psize, stringlist_t **keylist
  1553     )
  1554 {
  1555     assert(session);
  1556     assert(ctext);
  1557     assert(csize);
  1558     assert(ptext);
  1559     assert(psize);
  1560     assert(keylist);
  1561 
  1562     if (!(session && ctext && csize && ptext && psize && keylist))
  1563         return PEP_ILLEGAL_VALUE;
  1564 
  1565     return session->cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify(
  1566             session, ctext, csize, dsigtext, dsigsize, ptext, psize, keylist);
  1567 }
  1568 
  1569 DYNAMIC_API PEP_STATUS encrypt_and_sign(
  1570     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  1571     size_t psize, char **ctext, size_t *csize
  1572     )
  1573 {
  1574     assert(session);
  1575     assert(keylist);
  1576     assert(ptext);
  1577     assert(psize);
  1578     assert(ctext);
  1579     assert(csize);
  1580 
  1581     if (!(session && keylist && ptext && psize && ctext && csize))
  1582         return PEP_ILLEGAL_VALUE;
  1583 
  1584     return session->cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign(session,
  1585             keylist, ptext, psize, ctext, csize);
  1586 }
  1587 
  1588 PEP_STATUS encrypt_only(
  1589     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  1590     size_t psize, char **ctext, size_t *csize
  1591     )
  1592 {
  1593     assert(session);
  1594     assert(keylist);
  1595     assert(ptext);
  1596     assert(psize);
  1597     assert(ctext);
  1598     assert(csize);
  1599 
  1600     if (!(session && keylist && ptext && psize && ctext && csize))
  1601         return PEP_ILLEGAL_VALUE;
  1602 
  1603     return session->cryptotech[PEP_crypt_OpenPGP].encrypt_only(session,
  1604             keylist, ptext, psize, ctext, csize);
  1605 }
  1606 
  1607 
  1608 DYNAMIC_API PEP_STATUS verify_text(
  1609     PEP_SESSION session, const char *text, size_t size,
  1610     const char *signature, size_t sig_size, stringlist_t **keylist
  1611     )
  1612 {
  1613     assert(session);
  1614     assert(text);
  1615     assert(size);
  1616     assert(signature);
  1617     assert(sig_size);
  1618     assert(keylist);
  1619 
  1620     if (!(session && text && size && signature && sig_size && keylist))
  1621         return PEP_ILLEGAL_VALUE;
  1622 
  1623     return session->cryptotech[PEP_crypt_OpenPGP].verify_text(session, text,
  1624             size, signature, sig_size, keylist);
  1625 }
  1626 
  1627 DYNAMIC_API PEP_STATUS delete_keypair(PEP_SESSION session, const char *fpr)
  1628 {
  1629     assert(session);
  1630     assert(fpr);
  1631 
  1632     if (!(session && fpr))
  1633         return PEP_ILLEGAL_VALUE;
  1634 
  1635     return session->cryptotech[PEP_crypt_OpenPGP].delete_keypair(session, fpr);
  1636 }
  1637 
  1638 DYNAMIC_API PEP_STATUS export_key(
  1639         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  1640     )
  1641 {
  1642     assert(session);
  1643     assert(fpr);
  1644     assert(key_data);
  1645     assert(size);
  1646 
  1647     if (!(session && fpr && key_data && size))
  1648         return PEP_ILLEGAL_VALUE;
  1649 
  1650     return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  1651             key_data, size, false);
  1652 }
  1653 
  1654 DYNAMIC_API PEP_STATUS export_secrect_key(
  1655         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  1656     )
  1657 {
  1658     assert(session);
  1659     assert(fpr);
  1660     assert(key_data);
  1661     assert(size);
  1662 
  1663     if (!(session && fpr && key_data && size))
  1664         return PEP_ILLEGAL_VALUE;
  1665 
  1666     // don't accept key IDs but full fingerprints only
  1667     if (strlen(fpr) < 16)
  1668         return PEP_ILLEGAL_VALUE;
  1669 
  1670     return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  1671             key_data, size, true);
  1672 }
  1673 
  1674 DYNAMIC_API PEP_STATUS find_keys(
  1675         PEP_SESSION session, const char *pattern, stringlist_t **keylist
  1676     )
  1677 {
  1678     assert(session);
  1679     assert(pattern);
  1680     assert(keylist);
  1681 
  1682     if (!(session && pattern && keylist))
  1683         return PEP_ILLEGAL_VALUE;
  1684 
  1685     return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern,
  1686             keylist);
  1687 }
  1688 
  1689 
  1690 DYNAMIC_API PEP_STATUS generate_keypair(
  1691         PEP_SESSION session, pEp_identity *identity
  1692     )
  1693 {
  1694     assert(session);
  1695     assert(identity);
  1696     assert(identity->address);
  1697     assert(identity->fpr == NULL || identity->fpr[0] == 0);
  1698     assert(identity->username);
  1699 
  1700     if (!(session && identity && identity->address &&
  1701             (identity->fpr == NULL || identity->fpr[0] == 0) &&
  1702             identity->username))
  1703         return PEP_ILLEGAL_VALUE;
  1704 
  1705     PEP_STATUS status =
  1706         session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session,
  1707                 identity);
  1708     if (status != PEP_STATUS_OK)
  1709         return status;
  1710 
  1711     return status;
  1712 }
  1713 
  1714 DYNAMIC_API PEP_STATUS get_key_rating(
  1715         PEP_SESSION session,
  1716         const char *fpr,
  1717         PEP_comm_type *comm_type
  1718     )
  1719 {
  1720     assert(session);
  1721     assert(fpr);
  1722     assert(comm_type);
  1723 
  1724     if (!(session && fpr && comm_type))
  1725         return PEP_ILLEGAL_VALUE;
  1726 
  1727     return session->cryptotech[PEP_crypt_OpenPGP].get_key_rating(session, fpr,
  1728             comm_type);
  1729 }
  1730 
  1731 DYNAMIC_API PEP_STATUS import_key(
  1732         PEP_SESSION session,
  1733         const char *key_data,
  1734         size_t size,
  1735         identity_list **private_keys
  1736     )
  1737 {
  1738     assert(session);
  1739     assert(key_data);
  1740 
  1741     if (!(session && key_data))
  1742         return PEP_ILLEGAL_VALUE;
  1743 
  1744     return session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data,
  1745             size, private_keys);
  1746 }
  1747 
  1748 DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
  1749 {
  1750     assert(session);
  1751     assert(pattern);
  1752 
  1753     if (!(session && pattern))
  1754         return PEP_ILLEGAL_VALUE;
  1755 
  1756     return session->cryptotech[PEP_crypt_OpenPGP].recv_key(session, pattern);
  1757 }
  1758 
  1759 DYNAMIC_API PEP_STATUS send_key(PEP_SESSION session, const char *pattern)
  1760 {
  1761     assert(session);
  1762     assert(pattern);
  1763 
  1764     if (!(session && pattern))
  1765         return PEP_ILLEGAL_VALUE;
  1766 
  1767     return session->cryptotech[PEP_crypt_OpenPGP].send_key(session, pattern);
  1768 }
  1769 
  1770 DYNAMIC_API PEP_STATUS renew_key(
  1771         PEP_SESSION session,
  1772         const char *fpr,
  1773         const timestamp *ts
  1774     )
  1775 {
  1776     assert(session);
  1777     assert(fpr);
  1778 
  1779     if (!(session && fpr))
  1780         return PEP_ILLEGAL_VALUE;
  1781 
  1782     return session->cryptotech[PEP_crypt_OpenPGP].renew_key(session, fpr, ts);
  1783 }
  1784 
  1785 DYNAMIC_API PEP_STATUS revoke_key(
  1786         PEP_SESSION session,
  1787         const char *fpr,
  1788         const char *reason
  1789     )
  1790 {
  1791     assert(session);
  1792     assert(fpr);
  1793 
  1794     if (!(session && fpr))
  1795         return PEP_ILLEGAL_VALUE;
  1796 
  1797     return session->cryptotech[PEP_crypt_OpenPGP].revoke_key(session, fpr,
  1798             reason);
  1799 }
  1800 
  1801 DYNAMIC_API PEP_STATUS key_expired(
  1802         PEP_SESSION session,
  1803         const char *fpr,
  1804         const time_t when,
  1805         bool *expired
  1806     )
  1807 {
  1808     assert(session);
  1809     assert(fpr);
  1810     assert(expired);
  1811 
  1812     if (!(session && fpr && expired))
  1813         return PEP_ILLEGAL_VALUE;
  1814 
  1815     return session->cryptotech[PEP_crypt_OpenPGP].key_expired(session, fpr,
  1816             when, expired);
  1817 }
  1818 
  1819 DYNAMIC_API PEP_STATUS key_revoked(
  1820        PEP_SESSION session,
  1821        const char *fpr,
  1822        bool *revoked
  1823    )
  1824 {
  1825     assert(session);
  1826     assert(fpr);
  1827     assert(revoked);
  1828     
  1829     if (!(session && fpr && revoked))
  1830         return PEP_ILLEGAL_VALUE;
  1831     
  1832     return session->cryptotech[PEP_crypt_OpenPGP].key_revoked(session, fpr,
  1833             revoked);
  1834 }
  1835 
  1836 static void _clean_log_value(char *text)
  1837 {
  1838     if (text) {
  1839         for (char *c = text; *c; c++) {
  1840             if (*c < 32 && *c != '\n')
  1841                 *c = 32;
  1842             else if (*c == '"')
  1843                 *c = '\'';
  1844         }
  1845     }
  1846 }
  1847 
  1848 static char *_concat_string(char *str1, const char *str2, char delim)
  1849 {
  1850     str2 = str2 ? str2 : "";
  1851     size_t len1 = str1 ? strlen(str1) : 0;
  1852     size_t len2 = strlen(str2);
  1853     size_t len = len1 + len2 + 3;
  1854     char * result = realloc(str1, len + 1);
  1855 
  1856     if (result) {
  1857         result[len1] = '"';
  1858         strcpy(result + len1 + 1, str2);
  1859         result[len - 2] = '"';
  1860         result[len - 1] = delim;
  1861         result[len] = 0;
  1862     }
  1863     else {
  1864         free(str1);
  1865     }
  1866 
  1867     return result;
  1868 }
  1869 
  1870 DYNAMIC_API PEP_STATUS get_crashdump_log(
  1871         PEP_SESSION session,
  1872         int maxlines,
  1873         char **logdata
  1874     )
  1875 {
  1876     PEP_STATUS status = PEP_STATUS_OK;
  1877     char *_logdata= NULL;
  1878 
  1879     assert(session);
  1880     assert(maxlines >= 0 && maxlines <= CRASHDUMP_MAX_LINES);
  1881     assert(logdata);
  1882 
  1883     if (!(session && logdata && maxlines >= 0 && maxlines <=
  1884             CRASHDUMP_MAX_LINES))
  1885         return PEP_ILLEGAL_VALUE;
  1886 
  1887     *logdata = NULL;
  1888 
  1889     int limit = maxlines ? maxlines : CRASHDUMP_DEFAULT_LINES;
  1890     const char *timestamp = NULL;
  1891     const char *title = NULL;
  1892     const char *entity = NULL;
  1893     const char *desc = NULL;
  1894     const char *comment = NULL;
  1895 
  1896     sqlite3_reset(session->crashdump);
  1897     sqlite3_bind_int(session->crashdump, 1, limit);
  1898 
  1899     int result;
  1900 
  1901     do {
  1902         result = sqlite3_step(session->crashdump);
  1903         switch (result) {
  1904         case SQLITE_ROW:
  1905             timestamp = (const char *) sqlite3_column_text(session->crashdump,
  1906                     0);
  1907             title   = (const char *) sqlite3_column_text(session->crashdump,
  1908                     1);
  1909             entity  = (const char *) sqlite3_column_text(session->crashdump,
  1910                     2);
  1911             desc    = (const char *) sqlite3_column_text(session->crashdump,
  1912                     3);
  1913             comment = (const char *) sqlite3_column_text(session->crashdump,
  1914                     4);
  1915 
  1916             _logdata = _concat_string(_logdata, timestamp, ',');
  1917             if (_logdata == NULL)
  1918                 goto enomem;
  1919 
  1920             _logdata = _concat_string(_logdata, title, ',');
  1921             if (_logdata == NULL)
  1922                 goto enomem;
  1923 
  1924             _logdata = _concat_string(_logdata, entity, ',');
  1925             if (_logdata == NULL)
  1926                 goto enomem;
  1927 
  1928             _logdata = _concat_string(_logdata, desc, ',');
  1929             if (_logdata == NULL)
  1930                 goto enomem;
  1931 
  1932             _logdata = _concat_string(_logdata, comment, '\n');
  1933             if (_logdata == NULL)
  1934                 goto enomem;
  1935 
  1936             _clean_log_value(_logdata);
  1937             break;
  1938 
  1939         case SQLITE_DONE:
  1940             break;
  1941 
  1942         default:
  1943             status = PEP_UNKNOWN_ERROR;
  1944             result = SQLITE_DONE;
  1945         }
  1946     } while (result != SQLITE_DONE);
  1947 
  1948     sqlite3_reset(session->crashdump);
  1949     if (status == PEP_STATUS_OK)
  1950         *logdata = _logdata;
  1951 
  1952     goto the_end;
  1953 
  1954 enomem:
  1955     status = PEP_OUT_OF_MEMORY;
  1956 
  1957 the_end:
  1958     return ERROR(status);
  1959 }
  1960 
  1961 DYNAMIC_API PEP_STATUS get_languagelist(
  1962         PEP_SESSION session,
  1963         char **languages
  1964     )
  1965 {
  1966     PEP_STATUS status = PEP_STATUS_OK;
  1967     char *_languages= NULL;
  1968 
  1969     assert(session);
  1970     assert(languages);
  1971 
  1972     if (!(session && languages))
  1973         return PEP_ILLEGAL_VALUE;
  1974 
  1975     *languages = NULL;
  1976 
  1977     const char *lang = NULL;
  1978     const char *name = NULL;
  1979     const char *phrase = NULL;
  1980 
  1981     sqlite3_reset(session->languagelist);
  1982 
  1983     int result;
  1984 
  1985     do {
  1986         result = sqlite3_step(session->languagelist);
  1987         switch (result) {
  1988         case SQLITE_ROW:
  1989             lang = (const char *) sqlite3_column_text(session->languagelist,
  1990                     0);
  1991             name = (const char *) sqlite3_column_text(session->languagelist,
  1992                     1);
  1993             phrase = (const char *) sqlite3_column_text(session->languagelist,
  1994                     2);
  1995 
  1996             _languages = _concat_string(_languages, lang, ',');
  1997             if (_languages == NULL)
  1998                 goto enomem;
  1999 
  2000             _languages = _concat_string(_languages, name, ',');
  2001             if (_languages == NULL)
  2002                 goto enomem;
  2003 
  2004             _languages = _concat_string(_languages, phrase, '\n');
  2005             if (_languages == NULL)
  2006                 goto enomem;
  2007 
  2008             break;
  2009 
  2010         case SQLITE_DONE:
  2011             break;
  2012 
  2013         default:
  2014             status = PEP_UNKNOWN_ERROR;
  2015             result = SQLITE_DONE;
  2016         }
  2017     } while (result != SQLITE_DONE);
  2018 
  2019     sqlite3_reset(session->languagelist);
  2020     if (status == PEP_STATUS_OK)
  2021         *languages = _languages;
  2022 
  2023     goto the_end;
  2024 
  2025 enomem:
  2026     status = PEP_OUT_OF_MEMORY;
  2027 
  2028 the_end:
  2029     return status;
  2030 }
  2031 
  2032 static PEP_STATUS get_key_userids(
  2033         PEP_SESSION session,
  2034         const char* fpr,
  2035         stringlist_t** keylist
  2036     )
  2037 {
  2038     PEP_STATUS status = PEP_STATUS_OK;
  2039     assert(fpr);
  2040     assert(keylist);
  2041     
  2042     if (!keylist || !fpr)
  2043         return PEP_ILLEGAL_VALUE;
  2044         
  2045     *keylist = NULL;
  2046 
  2047     stringlist_t* userid_list = NULL;
  2048     
  2049     sqlite3_reset(session->get_key_userids);
  2050 
  2051     int result;
  2052 
  2053     char* userid;
  2054     
  2055     do {
  2056         userid = NULL;
  2057         
  2058         result = sqlite3_step(session->get_key_userids);
  2059         switch (result) {
  2060         case SQLITE_ROW:
  2061             userid = (const char *) sqlite3_column_text(session->get_key_userids,
  2062                     0);
  2063     
  2064             if (!userid)
  2065                 return PEP_UNKNOWN_ERROR;
  2066 
  2067             if (!userid_list) {
  2068                 userid_list = new_stringlist(userid);
  2069                 if (!userid_list)
  2070                     goto enomem;
  2071             }
  2072             else {
  2073                 stringlist_add(userid_list, userid);
  2074             }
  2075             
  2076             break;
  2077 
  2078         case SQLITE_DONE:
  2079             break;
  2080 
  2081         default:
  2082             status = PEP_UNKNOWN_ERROR;
  2083             result = SQLITE_DONE;
  2084         }
  2085     } while (result != SQLITE_DONE);
  2086 
  2087     sqlite3_reset(session->get_key_userids);
  2088     if (status == PEP_STATUS_OK)
  2089         *keylist = userid_list;
  2090 
  2091     goto the_end;
  2092 
  2093 enomem:
  2094     status = PEP_OUT_OF_MEMORY;
  2095 
  2096 the_end:
  2097     return status;
  2098 }
  2099 
  2100 DYNAMIC_API PEP_STATUS get_phrase(
  2101         PEP_SESSION session,
  2102         const char *lang,
  2103         int phrase_id,
  2104         char **phrase
  2105     )
  2106 {
  2107     PEP_STATUS status = PEP_STATUS_OK;
  2108 
  2109     assert(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase);
  2110     if (!(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase))
  2111         return PEP_ILLEGAL_VALUE;
  2112 
  2113     *phrase = NULL;
  2114 
  2115     sqlite3_reset(session->i18n_token);
  2116     sqlite3_bind_text(session->i18n_token, 1, lang, -1, SQLITE_STATIC);
  2117     sqlite3_bind_int(session->i18n_token, 2, phrase_id);
  2118 
  2119     const char *_phrase = NULL;
  2120     int result;
  2121 
  2122     result = sqlite3_step(session->i18n_token);
  2123     switch (result) {
  2124     case SQLITE_ROW:
  2125         _phrase = (const char *) sqlite3_column_text(session->i18n_token, 0);
  2126         break;
  2127 
  2128     case SQLITE_DONE:
  2129         status = PEP_PHRASE_NOT_FOUND;
  2130         break;
  2131 
  2132     default:
  2133         status = PEP_UNKNOWN_ERROR;
  2134     }
  2135 
  2136     if (status == PEP_STATUS_OK) {
  2137         *phrase = strdup(_phrase);
  2138         if (*phrase == NULL)
  2139             goto enomem;
  2140     }
  2141 
  2142     sqlite3_reset(session->i18n_token);
  2143     goto the_end;
  2144 
  2145 enomem:
  2146     status = PEP_OUT_OF_MEMORY;
  2147 
  2148 the_end:
  2149     return status;
  2150 }
  2151 
  2152 static PEP_STATUS _get_sequence_value(PEP_SESSION session, const char *name,
  2153         int32_t *value)
  2154 {
  2155     assert(session && name && value);
  2156     if (!(session && name && value))
  2157         return PEP_ILLEGAL_VALUE;
  2158 
  2159     PEP_STATUS status = PEP_STATUS_OK;
  2160 
  2161     sqlite3_reset(session->sequence_value2);
  2162     sqlite3_bind_text(session->sequence_value2, 1, name, -1,
  2163             SQLITE_STATIC);
  2164     int result = sqlite3_step(session->sequence_value2);
  2165     switch (result) {
  2166         case SQLITE_ROW: {
  2167             int32_t _value = (int32_t)
  2168                     sqlite3_column_int(session->sequence_value2, 0);
  2169             int _own = (int)
  2170                     sqlite3_column_int(session->sequence_value2, 1);
  2171             *value = _value;
  2172             if (_own)
  2173                 status = PEP_OWN_SEQUENCE;
  2174             break;
  2175         }
  2176         case SQLITE_DONE:
  2177             status = PEP_RECORD_NOT_FOUND;
  2178             break;
  2179         default:
  2180             status = PEP_UNKNOWN_ERROR;
  2181     }
  2182     sqlite3_reset(session->sequence_value2);
  2183 
  2184     return status;
  2185 }
  2186 
  2187 static PEP_STATUS _increment_sequence_value(PEP_SESSION session,
  2188         const char *name, int own)
  2189 {
  2190     assert(session && name);
  2191     if (!(session && name))
  2192         return PEP_ILLEGAL_VALUE;
  2193 
  2194     sqlite3_reset(session->sequence_value1);
  2195     sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
  2196     sqlite3_bind_int(session->sequence_value1, 2, own);
  2197     int result = sqlite3_step(session->sequence_value1);
  2198     assert(result == SQLITE_DONE);
  2199     sqlite3_reset(session->sequence_value1);
  2200     if (result == SQLITE_DONE)
  2201         return PEP_STATUS_OK;
  2202     else
  2203         return PEP_CANNOT_INCREASE_SEQUENCE;
  2204 }
  2205 
  2206 static PEP_STATUS _set_sequence_value(PEP_SESSION session,
  2207         const char *name, int32_t value, int own)
  2208 {
  2209     assert(session && name && value > 0);
  2210     if (!(session && name && value > 0))
  2211         return PEP_ILLEGAL_VALUE;
  2212 
  2213     sqlite3_reset(session->sequence_value3);
  2214     sqlite3_bind_text(session->sequence_value3, 1, name, -1, SQLITE_STATIC);
  2215     sqlite3_bind_int(session->sequence_value3, 2, value);
  2216     sqlite3_bind_int(session->sequence_value3, 3, own);
  2217     int result = sqlite3_step(session->sequence_value3);
  2218     assert(result == SQLITE_DONE);
  2219     sqlite3_reset(session->sequence_value3);
  2220     if (result == SQLITE_DONE)
  2221         return PEP_STATUS_OK;
  2222     else
  2223         return PEP_CANNOT_SET_SEQUENCE_VALUE;
  2224 }
  2225 
  2226 DYNAMIC_API PEP_STATUS sequence_value(
  2227         PEP_SESSION session,
  2228         char *name,
  2229         int32_t *value
  2230     )
  2231 {
  2232     PEP_STATUS status = PEP_STATUS_OK;
  2233     int result;
  2234 
  2235     assert(session);
  2236     assert(name && value && *value >= 0);
  2237 
  2238     if (!(session && name && value && *value >= 0))
  2239         return PEP_ILLEGAL_VALUE;
  2240 
  2241     int own = 0;
  2242     if (!name[0]) {
  2243         pEpUUID uuid;
  2244         uuid_generate_random(uuid);
  2245         uuid_unparse_upper(uuid, name);
  2246         own = 1;
  2247     }
  2248     else {
  2249         if (name == session->sync_session->sync_uuid || 
  2250             strcmp(name, session->sync_session->sync_uuid) == 0)
  2251             own = 1;
  2252     }
  2253 
  2254     if (*value) {
  2255         sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
  2256         int32_t old_value = 0;
  2257         status = _get_sequence_value(session, name, &old_value);
  2258         if (status != PEP_STATUS_OK && status != PEP_RECORD_NOT_FOUND)
  2259         {
  2260             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2261             return status;
  2262         }
  2263 
  2264         if (old_value >= *value) {
  2265             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2266             return PEP_SEQUENCE_VIOLATED;
  2267         }
  2268         else {
  2269             status = _set_sequence_value(session, name, *value, own);
  2270             if (status == PEP_STATUS_OK) {
  2271                 result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  2272                 if (result == SQLITE_OK)
  2273                     return PEP_STATUS_OK;
  2274                 else
  2275                     return PEP_COMMIT_FAILED;
  2276             } else {
  2277                 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2278                 return status;
  2279             }
  2280         }
  2281     }
  2282 
  2283     assert(*value == 0);
  2284     sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
  2285     status = _increment_sequence_value(session, name, own);
  2286     if (status == PEP_STATUS_OK) {
  2287         status = _get_sequence_value(session, name, value);
  2288     }
  2289     if (status == PEP_STATUS_OK || status == PEP_OWN_SEQUENCE) {
  2290         result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  2291         if (result == SQLITE_OK){
  2292             assert(*value < INT32_MAX);
  2293             if (*value == INT32_MAX){
  2294                 return PEP_CANNOT_INCREASE_SEQUENCE;
  2295             }
  2296             return status;
  2297         } else {
  2298             return PEP_COMMIT_FAILED;
  2299         }
  2300     } else {
  2301         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2302         return status;
  2303     }
  2304     return status;
  2305 }
  2306 
  2307 DYNAMIC_API PEP_STATUS set_revoked(
  2308        PEP_SESSION session,
  2309        const char *revoked_fpr,
  2310        const char *replacement_fpr,
  2311        const uint64_t revocation_date
  2312     )
  2313 {
  2314     PEP_STATUS status = PEP_STATUS_OK;
  2315     
  2316     assert(session &&
  2317            revoked_fpr && revoked_fpr[0] &&
  2318            replacement_fpr && replacement_fpr[0]
  2319           );
  2320     
  2321     if (!(session &&
  2322           revoked_fpr && revoked_fpr[0] &&
  2323           replacement_fpr && replacement_fpr[0]
  2324          ))
  2325         return PEP_ILLEGAL_VALUE;
  2326     
  2327     sqlite3_reset(session->set_revoked);
  2328     sqlite3_bind_text(session->set_revoked, 1, revoked_fpr, -1, SQLITE_STATIC);
  2329     sqlite3_bind_text(session->set_revoked, 2, replacement_fpr, -1,
  2330             SQLITE_STATIC);
  2331     sqlite3_bind_int64(session->set_revoked, 3, revocation_date);
  2332 
  2333     int result;
  2334     
  2335     result = sqlite3_step(session->set_revoked);
  2336     switch (result) {
  2337         case SQLITE_DONE:
  2338             status = PEP_STATUS_OK;
  2339             break;
  2340             
  2341         default:
  2342             status = PEP_UNKNOWN_ERROR;
  2343     }
  2344     
  2345     sqlite3_reset(session->set_revoked);
  2346     return status;
  2347 }
  2348 
  2349 DYNAMIC_API PEP_STATUS get_revoked(
  2350         PEP_SESSION session,
  2351         const char *fpr,
  2352         char **revoked_fpr,
  2353         uint64_t *revocation_date
  2354     )
  2355 {
  2356     PEP_STATUS status = PEP_STATUS_OK;
  2357 
  2358     assert(session &&
  2359            revoked_fpr &&
  2360            fpr && fpr[0]
  2361           );
  2362     
  2363     if (!(session &&
  2364            revoked_fpr &&
  2365            fpr && fpr[0]
  2366           ))
  2367         return PEP_ILLEGAL_VALUE;
  2368 
  2369     *revoked_fpr = NULL;
  2370     *revocation_date = 0;
  2371 
  2372     sqlite3_reset(session->get_revoked);
  2373     sqlite3_bind_text(session->get_revoked, 1, fpr, -1, SQLITE_STATIC);
  2374 
  2375     int result;
  2376     
  2377     result = sqlite3_step(session->get_revoked);
  2378     switch (result) {
  2379         case SQLITE_ROW: {
  2380             *revoked_fpr = strdup((const char *)
  2381                     sqlite3_column_text(session->get_revoked, 0));
  2382             if(*revoked_fpr)
  2383                 *revocation_date = sqlite3_column_int64(session->get_revoked,
  2384                         1);
  2385             else
  2386                 status = PEP_OUT_OF_MEMORY;
  2387 
  2388             break;
  2389         }
  2390         default:
  2391             status = PEP_CANNOT_FIND_IDENTITY;
  2392     }
  2393 
  2394     sqlite3_reset(session->get_revoked);
  2395 
  2396     return status;
  2397 }
  2398 
  2399 PEP_STATUS key_created(
  2400         PEP_SESSION session,
  2401         const char *fpr,
  2402         time_t *created
  2403     )
  2404 {
  2405     assert(session && fpr && created);
  2406     if (!(session && fpr && created))
  2407         return PEP_ILLEGAL_VALUE;
  2408 
  2409     return session->cryptotech[PEP_crypt_OpenPGP].key_created(session, fpr,
  2410             created);
  2411 }
  2412 
  2413 PEP_STATUS find_private_keys(PEP_SESSION session, const char* pattern,
  2414                              stringlist_t **keylist) {
  2415     assert(session && keylist);
  2416     if (!(session && keylist))
  2417         return PEP_ILLEGAL_VALUE;
  2418     
  2419     return session->cryptotech[PEP_crypt_OpenPGP].find_private_keys(session, pattern,
  2420                                                                     keylist);
  2421 }
  2422 
  2423 DYNAMIC_API const char* get_engine_version() {
  2424     return PEP_ENGINE_VERSION;
  2425 }
  2426 
  2427 
  2428 DYNAMIC_API PEP_STATUS reset_peptest_hack(PEP_SESSION session)
  2429 {
  2430     assert(session);
  2431 
  2432     if (!session)
  2433         return PEP_ILLEGAL_VALUE;
  2434 
  2435     int int_result = sqlite3_exec(
  2436         session->db,
  2437         "delete from identity where address like '%@peptest.ch' ;",
  2438         NULL,
  2439         NULL,
  2440         NULL
  2441     );
  2442     assert(int_result == SQLITE_OK);
  2443 
  2444     if (int_result != SQLITE_OK)
  2445         return PEP_UNKNOWN_ERROR;
  2446 
  2447     return PEP_STATUS_OK;
  2448 }
  2449 
  2450 #ifdef DEBUG_ERRORSTACK
  2451 PEP_STATUS session_add_error(PEP_SESSION session, const char* file, unsigned line, PEP_STATUS status)
  2452 {
  2453     char logline[48];
  2454     if(status>0)
  2455     {
  2456         snprintf(logline,47, "%.24s:%u status=%u (0x%x)", file, line, status, status);
  2457     }else{
  2458         snprintf(logline,47, "%.24s:%u status=%i.", file, line, status);
  2459     }
  2460     stringlist_add(session->errorstack, logline); // logline is copied! :-)
  2461     return status;
  2462 }
  2463 
  2464 DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  2465 {
  2466     return session->errorstack;
  2467 }
  2468 
  2469 DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  2470 {
  2471     free_stringlist(session->errorstack);
  2472     session->errorstack = new_stringlist(NULL);
  2473 }
  2474 
  2475 #else
  2476 
  2477 static stringlist_t* dummy_errorstack = NULL;
  2478 
  2479 DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  2480 {
  2481     if(dummy_errorstack == NULL)
  2482     {
  2483         dummy_errorstack = new_stringlist("( Please recompile pEpEngine with -DDEBUG_ERRORSTACK )");
  2484     }
  2485 
  2486     return dummy_errorstack;
  2487 }
  2488 
  2489 DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  2490 {
  2491     // nothing to do here
  2492 }
  2493 
  2494 #endif