src/pEpEngine.c
author Hernâni Marques <hernani@pep.foundation>
Wed, 27 Jun 2018 00:52:09 +0200
changeset 2771 b0c0d39f643d
parent 2688 a34d253c9292
child 2739 1353fe080162
child 2744 df7e5d64011f
child 2760 5c3a4af5453f
permissions -rw-r--r--
typos (by reading for IETF)
     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 
    10 #include <time.h>
    11 #include <stdlib.h>
    12 
    13 #define _PEP_SQLITE_DEBUG 0
    14 #if _PEP_SQLITE_DEBUG
    15 #include <sqlite3.h>
    16 #endif
    17 
    18 static volatile int init_count = -1;
    19 
    20 // sql overloaded functions - modified from sqlite3.c
    21 static void _sql_lower(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
    22     char *z1;
    23     const char *z2;
    24     int i, n;
    25     z2 = (char*)sqlite3_value_text(argv[0]);
    26     n = sqlite3_value_bytes(argv[0]);
    27     /* Verify that the call to _bytes() does not invalidate the _text() pointer */
    28     assert( z2==(char*)sqlite3_value_text(argv[0]) );
    29     if( z2 ){
    30         z1 = (char*)sqlite3_malloc(n+1);
    31         if( z1 ){
    32             for(i=0; i<n; i++){
    33                 char c = z2[i];
    34                 char c_mod = c | 0x20;
    35                 if (c_mod < 0x61 || c_mod > 0x7a)
    36                     c_mod = c;
    37                 z1[i] = c_mod;
    38             }
    39             z1[n] = '\0';
    40             sqlite3_result_text(ctx, z1, n, sqlite3_free);
    41         }
    42     }
    43 }
    44 
    45 #if _PEP_SQLITE_DEBUG
    46 int sql_trace_callback (unsigned trace_constant, 
    47                         void* context_ptr,
    48                         void* P,
    49                         void* X) {
    50     switch (trace_constant) {
    51         case SQLITE_TRACE_STMT:
    52             fprintf(stderr, "SQL_DEBUG: STMT - ");
    53             const char* X_str = (const char*) X;
    54             if (!EMPTYSTR(X_str) && X_str[0] == '-' && X_str[1] == '-')
    55                 fprintf(stderr, "%s\n", X_str);
    56             else
    57                 fprintf(stderr, "%s\n", sqlite3_expanded_sql((sqlite3_stmt*)P));
    58             break;
    59         case SQLITE_TRACE_ROW:
    60             fprintf(stderr, "SQL_DEBUG: ROW - ");
    61             fprintf(stderr, "%s\n", sqlite3_expanded_sql((sqlite3_stmt*)P));
    62             break;            
    63         case SQLITE_TRACE_CLOSE:
    64             fprintf(stderr, "SQL_DEBUG: CLOSE - ");
    65             break;
    66         default:
    67             break;
    68     }
    69     return 0;
    70 }
    71 #endif
    72 
    73 // sql manipulation statements
    74 static const char *sql_log = 
    75     "insert into log (title, entity, description, comment)"
    76      "values (?1, ?2, ?3, ?4);";
    77 
    78 static const char *sql_trustword = 
    79     "select id, word from wordlist where lang = lower(?1) "
    80     "and id = ?2 ;";
    81 
    82 static const char *sql_get_identity =  
    83     "select fpr, username, comm_type, lang,"
    84     "   identity.flags | pgp_keypair.flags,"
    85     "   is_own"
    86     "   from identity"
    87     "   join person on id = identity.user_id"
    88     "   join pgp_keypair on fpr = identity.main_key_id"
    89     "   join trust on id = trust.user_id"
    90     "       and pgp_keypair_fpr = identity.main_key_id"    
    91     "   where (case when (address = ?1) then (1)"
    92     "               when (lower(address) = lower(?1)) then (1)"
    93     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
    94     "               else 0"
    95     "          end) = 1"
    96     "   and identity.user_id = ?2" 
    97     "   order by is_own desc, "
    98     "   timestamp desc; ";
    99 
   100 static const char *sql_get_identity_without_trust_check =  
   101     "select identity.main_key_id, username, lang,"
   102     "   identity.flags, is_own"
   103     "   from identity"
   104     "   join person on id = identity.user_id"
   105     "   where (case when (address = ?1) then (1)"
   106     "               when (lower(address) = lower(?1)) then (1)"
   107     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   108     "               else 0"
   109     "          end) = 1"
   110     "   and identity.user_id = ?2 "
   111     "   order by is_own desc, "
   112     "   timestamp desc; ";
   113 
   114 static const char *sql_get_identities_by_address =  
   115     "select user_id, identity.main_key_id, username, lang,"
   116     "   identity.flags, is_own"
   117     "   from identity"
   118     "   join person on id = identity.user_id"
   119     "   where (case when (address = ?1) then (1)"
   120     "               when (lower(address) = lower(?1)) then (1)"
   121     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   122     "               else 0"
   123     "          end) = 1 "
   124     "   order by is_own desc, "
   125     "   timestamp desc; ";
   126 
   127 static const char *sql_replace_identities_fpr =  
   128     "update identity"
   129     "   set main_key_id = ?1 "
   130     "   where main_key_id = ?2 ;";
   131     
   132 static const char *sql_remove_fpr_as_default =
   133     "update person set main_key_id = NULL where main_key_id = ?1 ;"
   134     "update identity set main_key_id = NULL where main_key_id = ?1 ;";
   135 
   136 // Set person, but if already exist, only update.
   137 // if main_key_id already set, don't touch.
   138 static const char *sql_set_person = 
   139      "insert into person (id, username, lang, main_key_id, device_group)"
   140      "  values (?1, ?2, ?3, ?4, "
   141      "          (select device_group from person where id = ?1)) ;";
   142 
   143 static const char *sql_update_person = 
   144     "update person "
   145     "   set username = ?2, "
   146     "       lang = ?3, "
   147     "       main_key_id =  "
   148     "           (select coalesce( "
   149     "               (select main_key_id from person where id = ?1), " 
   150     "                upper(replace(?4,' ','')))),"         
   151     "       device_group = "
   152     "           (select device_group from person where id = ?1)"
   153     "   where id = ?1 ;";
   154     
   155 static const char *sql_set_as_pep_user =
   156     "update person set is_pep_user = 1 "
   157     "   where id = ?1 ; ";
   158 
   159 static const char *sql_is_pep_user =
   160     "select is_pep_user from person "
   161     "   where id = ?1 ; ";
   162 
   163 static const char* sql_exists_person = 
   164     "select count(*) from person "
   165     "   where id = ?1 ;";
   166 
   167 static const char *sql_set_device_group = 
   168     "update person set device_group = ?1 "
   169     "   where id = ?2;";
   170 
   171 // This will cascade to identity and trust
   172 static const char* sql_replace_userid =
   173     "update person set id = ?1 " 
   174     "   where id = ?2;";
   175 
   176 static const char *sql_replace_main_user_fpr =  
   177     "update person "
   178     "   set main_key_id = ?1 "
   179     "   where id = ?2 ;";
   180 
   181 static const char *sql_get_main_user_fpr =  
   182     "select main_key_id from person"
   183     "   where id = ?1 ;";
   184 
   185 static const char *sql_refresh_userid_default_key =
   186     "update person "
   187     "   set main_key_id = "
   188     "       (select identity.main_key_id from identity "
   189     "           join trust on trust.user_id = identity.user_id "
   190     "               and trust.pgp_keypair_fpr = identity.main_key_id "
   191     "           join person on identity.user_id = identity.user_id "
   192     "       where identity.user_id = ?1 "
   193     "       order by trust.comm_type desc "
   194     "       limit 1) "
   195     "where id = ?1 ; ";
   196 
   197 static const char *sql_get_device_group = 
   198     "select device_group from person "
   199     "where id = ?1;";
   200 
   201 static const char *sql_set_pgp_keypair = 
   202     "insert or ignore into pgp_keypair (fpr) "
   203     "values (upper(replace(?1,' ',''))) ;";
   204 
   205 static const char* sql_exists_identity_entry = 
   206     "select count(*) from identity "
   207     "   where (case when (address = ?1) then (1)"
   208     "               when (lower(address) = lower(?1)) then (1)"
   209     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   210     "               else 0"
   211     "          end) = 1"
   212     "    and user_id = ?2;";
   213  
   214 static const char *sql_set_identity_entry = 
   215     "insert into identity ("
   216     "       address, main_key_id, "
   217     "       user_id, flags, is_own"
   218     "   ) values ("
   219     "       ?1,"
   220     "       upper(replace(?2,' ','')),"
   221     "       ?3,"
   222     "       ?4,"
   223     "       ?5"
   224     "   );";
   225     
   226 static const char* sql_update_identity_entry =    
   227     "update identity "
   228     "   set main_key_id = upper(replace(?2,' ','')), "
   229     "       flags = ?4, " 
   230     "       is_own = ?5 "
   231     "   where (case when (address = ?1) then (1)"
   232     "               when (lower(address) = lower(?1)) then (1)"
   233     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1) "
   234     "               else 0 "
   235     "          end) = 1 "
   236     "          and user_id = ?3 ;";
   237 
   238     // " (select"
   239     // "   coalesce("
   240     // "    (select flags from identity"
   241     // "     where address = ?1 and"
   242     // "           user_id = ?3),"
   243     // "    0)"
   244     // " ) | (?4 & 255)"
   245     /* set_identity ignores previous flags, and doesn't filter machine flags */
   246         
   247 static const char *sql_set_identity_flags = 
   248     "update identity set flags = "
   249     "    ((?1 & 255) | (select flags from identity"
   250     "                    where (case when (address = ?2) then (1)"
   251     "                                when (lower(address) = lower(?2)) then (1)"
   252     "                                when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   253     "                                else 0 "    
   254     "                           end) = 1 "
   255     "                           and user_id = ?3)) "
   256     "   where (case when (address = ?2) then (1)"
   257     "               when (lower(address) = lower(?2)) then (1)"
   258     "               when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   259     "               else 0"
   260     "          end) = 1"
   261     "          and user_id = ?3 ;";
   262 
   263 static const char *sql_unset_identity_flags = 
   264     "update identity set flags = "
   265     "    ( ~(?1 & 255) & (select flags from identity"
   266     "                    where (case when (address = ?2) then (1)"
   267     "                                when (lower(address) = lower(?2)) then (1)"
   268     "                                when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   269     "                                else 0 "    
   270     "                           end) = 1 "
   271     "                           and user_id = ?3)) "
   272     "   where (case when (address = ?2) then (1)"
   273     "               when (lower(address) = lower(?2)) then (1)"
   274     "               when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   275     "               else 0"
   276     "          end) = 1"
   277     "          and user_id = ?3 ;";
   278 
   279 static const char *sql_set_trust =
   280     "insert into trust (user_id, pgp_keypair_fpr, comm_type) "
   281     "values (?1, upper(replace(?2,' ','')), ?3) ;";
   282 
   283 static const char *sql_update_trust =
   284     "update trust set comm_type = ?3 " 
   285     "   where user_id = ?1 and pgp_keypair_fpr = upper(replace(?2,' ',''));";
   286 
   287 static const char *sql_update_trust_to_pep =
   288     "update trust set comm_type = comm_type + 71 "
   289     "   where (user_id = ?1 "
   290     "          and (case when (comm_type = 56) then (1) "
   291     "                    when (comm_type = 184) then (1) "
   292     "                    else 0"
   293     "               end) = 1); ";
   294 
   295 static const char* sql_exists_trust_entry = 
   296     "select count(*) from trust "
   297     "   where user_id = ?1 and pgp_keypair_fpr = upper(replace(?2,' ',''));";
   298     
   299 static const char *sql_update_trust_for_fpr =
   300     "update trust "
   301     "set comm_type = ?1 "
   302     "where pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
   303 
   304 static const char *sql_get_trust = 
   305     "select comm_type from trust where user_id = ?1 "
   306     "and pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
   307 
   308 static const char *sql_least_trust = 
   309     "select min(comm_type) from trust where"
   310     " pgp_keypair_fpr = upper(replace(?1,' ',''))"
   311     " and comm_type != 0;"; // ignores PEP_ct_unknown
   312     // returns PEP_ct_unknown only when no known trust is recorded
   313 
   314 static const char *sql_mark_as_compromised = 
   315     "update trust not indexed set comm_type = 15"
   316     " where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
   317     
   318 static const char *sql_crashdump = 
   319     "select timestamp, title, entity, description, comment"
   320     " from log order by timestamp desc limit ?1 ;";
   321 
   322 static const char *sql_languagelist = 
   323     "select i18n_language.lang, name, phrase" 
   324     " from i18n_language join i18n_token using (lang) where i18n_token.id = 1000;" ;
   325 
   326 static const char *sql_i18n_token = 
   327     "select phrase from i18n_token where lang = lower(?1) and id = ?2 ;";
   328 
   329 // blacklist
   330 static const char *sql_blacklist_add = 
   331     "insert or ignore into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
   332     "delete from identity where main_key_id = upper(replace(?1,' ','')) ;"
   333     "delete from pgp_keypair where fpr = upper(replace(?1,' ','')) ;";
   334 
   335 static const char *sql_blacklist_delete =
   336     "delete from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
   337 
   338 static const char *sql_blacklist_is_listed = 
   339     "select count(*) from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
   340 
   341 static const char *sql_blacklist_retrieve = 
   342     "select * from blacklist_keys ;";
   343                 
   344 
   345 // Own keys
   346 // We only care if it's 0 or non-zero
   347 static const char *sql_own_key_is_listed = 
   348     "select count(*) from ("
   349     "   select pgp_keypair_fpr from trust"
   350     "      join identity on trust.user_id = identity.user_id"
   351     "      where pgp_keypair_fpr = upper(replace(?1,' ',''))"
   352     "           and identity.is_own = 1"
   353     ");";
   354 
   355 static const char *sql_own_identities_retrieve =  
   356     "select address, fpr, username, identity.user_id, "
   357     "   lang, identity.flags | pgp_keypair.flags"
   358     "   from identity"
   359     "   join person on id = identity.user_id"
   360     "   join pgp_keypair on fpr = identity.main_key_id"
   361     "   join trust on id = trust.user_id"
   362     "       and pgp_keypair_fpr = identity.main_key_id"
   363     "   where identity.is_own = 1"
   364     "       and (identity.flags & ?1) = 0;";
   365 
   366 static const char *sql_own_keys_retrieve = 
   367     "select pgp_keypair_fpr from trust"
   368     "   join identity on trust.user_id = identity.user_id"
   369     "   where identity.is_own = 1";
   370 
   371 static const char* sql_get_user_default_key =
   372     "select main_key_id from person" 
   373     "   where id = ?1;";
   374 
   375 static const char* sql_get_default_own_userid =
   376     "select id from person"
   377     "   join identity on id = identity.user_id"
   378     "   where identity.is_own = 1";
   379 
   380 // Sequence
   381 static const char *sql_sequence_value1 = 
   382     "insert or replace into sequences (name, value, own) "
   383     "values (?1, "
   384     "       (select coalesce((select value + 1 from sequences "
   385     "           where name = ?1), 1 )), "
   386     "       (select coalesce((select own or ?2 from sequences "
   387     "           where name = ?1), ?2))) ; ";
   388 
   389 static const char *sql_sequence_value2 = 
   390     "select value, own from sequences where name = ?1 ;";
   391 
   392 static const char *sql_sequence_value3 = 
   393     "insert or replace into sequences (name, value, own) "
   394     "values (?1, "
   395     "        ?2, "
   396     "       (select coalesce((select own or ?3 from sequences "
   397     "           where name = ?1), ?3))) ; ";
   398         
   399 // Revocation tracking
   400 static const char *sql_set_revoked =
   401     "insert or replace into revoked_keys ("
   402     "    revoked_fpr, replacement_fpr, revocation_date) "
   403     "values (upper(replace(?1,' ','')),"
   404     "        upper(replace(?2,' ','')),"
   405     "        ?3) ;";
   406         
   407 static const char *sql_get_revoked = 
   408     "select revoked_fpr, revocation_date from revoked_keys"
   409     "    where replacement_fpr = upper(replace(?1,' ','')) ;";
   410 
   411 static const char *sql_get_userid_alias_default =
   412     "select default_id from alternate_user_id "
   413     "   where alternate_id = ?1 ; ";
   414 
   415 // Revocation tracking
   416 static const char *sql_add_mistrusted_key =
   417     "insert or replace into mistrusted_keys (fpr) "
   418     "   values (upper(replace(?1,' ',''))) ;";
   419         
   420 static const char *sql_delete_mistrusted_key = 
   421     "delete from mistrusted_keys where fpr = upper(replace(?1,' ','')) ;";
   422 
   423 static const char *sql_is_mistrusted_key = 
   424     "select count(*) from mistrusted_keys where fpr = upper(replace(?1,' ','')) ;";
   425 
   426 static const char *sql_add_userid_alias =
   427     "insert or replace into alternate_user_id (alternate_id, default_id) "
   428     "values (?2, ?1) ;";
   429     
   430 static int user_version(void *_version, int count, char **text, char **name)
   431 {
   432     assert(_version);
   433     assert(count == 1);
   434     assert(text && text[0]);
   435     if (!(_version && count == 1 && text && text[0]))
   436         return -1;
   437 
   438     int *version = (int *) _version;
   439     *version = atoi(text[0]);
   440     return 0;
   441 }
   442 
   443 static int table_contains_column(PEP_SESSION session, const char* table_name,
   444                                                       const char* col_name) {
   445 
   446 
   447     if (!session || !table_name || !col_name)
   448         return -1;
   449         
   450     // Table names can't be SQL parameters, so we do it this way.
   451     
   452     // these two must be the same number.
   453     char sql_buf[500];
   454     const size_t max_q_len = 500;
   455     
   456     size_t t_size, c_size, q_size;
   457     
   458     const char* q1 = "SELECT "; // 7
   459     const char* q2 = " from "; // 6
   460     const char* q3 = ";";       // 1
   461     
   462     q_size = 14;
   463     t_size = strlen(table_name);
   464     c_size = strlen(col_name);
   465     
   466     size_t query_len = q_size + c_size + t_size + 1;
   467     
   468     if (query_len > max_q_len)
   469         return -1;
   470 
   471     strlcpy(sql_buf, q1, max_q_len);
   472     strlcat(sql_buf, col_name, max_q_len);
   473     strlcat(sql_buf, q2, max_q_len);
   474     strlcat(sql_buf, table_name, max_q_len);
   475     strlcat(sql_buf, q3, max_q_len);
   476 
   477     sqlite3_stmt *stmt; 
   478 
   479     sqlite3_prepare_v2(session->db, sql_buf, -1, &stmt, NULL);
   480 
   481     int retval = 0;
   482 
   483     int rc = sqlite3_step(stmt);  
   484     if (rc == SQLITE_DONE || rc == SQLITE_OK || rc == SQLITE_ROW) {
   485         retval = 1;
   486     }
   487 
   488     sqlite3_finalize(stmt);      
   489         
   490     return retval;
   491 }
   492 
   493 void errorLogCallback(void *pArg, int iErrCode, const char *zMsg){
   494   fprintf(stderr, "(%d) %s\n", iErrCode, zMsg);
   495 }
   496 
   497 #ifdef USE_GPG
   498 PEP_STATUS pgp_import_ultimately_trusted_keypairs(PEP_SESSION session);
   499 #endif // USE_GPG
   500 
   501 DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
   502 {
   503     PEP_STATUS status = PEP_STATUS_OK;
   504     int int_result;
   505     
   506     bool in_first = false;
   507     bool very_first = false;
   508 
   509     assert(sqlite3_threadsafe());
   510     if (!sqlite3_threadsafe())
   511         return PEP_INIT_SQLITE3_WITHOUT_MUTEX;
   512 
   513     // a little race condition - but still a race condition
   514     // mitigated by calling caveat (see documentation)
   515 
   516     // this increment is made atomic IN THE ADAPTERS by
   517     // guarding the call to init with the appropriate mutex.
   518     int _count = ++init_count;
   519     if (_count == 0)
   520         in_first = true;
   521     
   522     // Race condition mitigated by calling caveat starts here :
   523     // If another call to init() preempts right now, then preemptive call
   524     // will have in_first false, will not create SQL tables, and following
   525     // calls relying on those tables will fail.
   526     //
   527     // Therefore, as above, adapters MUST guard init() with a mutex.
   528     // 
   529     // Therefore, first session
   530     // is to be created and last session to be deleted alone, and not
   531     // concurently to other sessions creation or deletion.
   532     // We expect adapters to enforce this either by implicitely creating a
   533     // client session, or by using synchronization primitive to protect
   534     // creation/deletion of first/last session from the app.
   535 
   536     assert(session);
   537     if (session == NULL)
   538         return PEP_ILLEGAL_VALUE;
   539 
   540     *session = NULL;
   541 
   542     pEpSession *_session = calloc(1, sizeof(pEpSession));
   543     assert(_session);
   544     if (_session == NULL)
   545         goto enomem;
   546 
   547     _session->version = PEP_ENGINE_VERSION;
   548 
   549 #ifdef DEBUG_ERRORSTACK
   550     _session->errorstack = new_stringlist("init()");
   551 #endif
   552 
   553     assert(LOCAL_DB);
   554     if (LOCAL_DB == NULL) {
   555         status = PEP_INIT_CANNOT_OPEN_DB;
   556         goto pep_error;
   557     }
   558     
   559 #if _PEP_SQLITE_DEBUG    
   560     sqlite3_config(SQLITE_CONFIG_LOG, errorLogCallback, NULL);
   561 #endif
   562 
   563     int_result = sqlite3_open_v2(
   564             LOCAL_DB,
   565             &_session->db,
   566             SQLITE_OPEN_READWRITE
   567                 | SQLITE_OPEN_CREATE
   568                 | SQLITE_OPEN_FULLMUTEX
   569                 | SQLITE_OPEN_PRIVATECACHE,
   570             NULL 
   571         );
   572 
   573     if (int_result != SQLITE_OK) {
   574         status = PEP_INIT_CANNOT_OPEN_DB;
   575         goto pep_error;
   576     }
   577 
   578     int_result = sqlite3_exec(
   579             _session->db,
   580             "PRAGMA locking_mode=NORMAL;\n"
   581             "PRAGMA journal_mode=WAL;\n",
   582             NULL,
   583             NULL,
   584             NULL
   585         );
   586 
   587 
   588     sqlite3_busy_timeout(_session->db, BUSY_WAIT_TIME);
   589 
   590 #if _PEP_SQLITE_DEBUG
   591     sqlite3_trace_v2(_session->db, 
   592         SQLITE_TRACE_STMT | SQLITE_TRACE_ROW | SQLITE_TRACE_CLOSE,
   593         sql_trace_callback,
   594         NULL);
   595 #endif
   596 
   597     assert(SYSTEM_DB);
   598     if (SYSTEM_DB == NULL) {
   599         status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
   600         goto pep_error;
   601     }
   602 
   603     int_result = sqlite3_open_v2(
   604             SYSTEM_DB, &_session->system_db,
   605             SQLITE_OPEN_READONLY
   606                 | SQLITE_OPEN_FULLMUTEX
   607                 | SQLITE_OPEN_SHAREDCACHE,
   608             NULL
   609         );
   610 
   611     if (int_result != SQLITE_OK) {
   612         status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
   613         goto pep_error;
   614     }
   615 
   616     sqlite3_busy_timeout(_session->system_db, 1000);
   617 
   618 // increment this when patching DDL
   619 #define _DDL_USER_VERSION "8"
   620 
   621     if (in_first) {
   622 
   623         int_result = sqlite3_exec(
   624             _session->db,
   625                 "create table if not exists version_info (\n"
   626                 "   id integer primary key,\n"
   627                 "   timestamp integer default (datetime('now')),\n"
   628                 "   version text,\n"
   629                 "   comment text\n"
   630                 ");\n",
   631                 NULL,
   632                 NULL,
   633                 NULL
   634         );
   635         int_result = sqlite3_exec(
   636             _session->db,
   637                 "PRAGMA application_id = 0x23423423;\n"
   638                 "create table if not exists log (\n"
   639                 "   timestamp integer default (datetime('now')),\n"
   640                 "   title text not null,\n"
   641                 "   description text,\n"
   642                 "   entity text not null,\n"
   643                 "   comment text\n"
   644                 ");\n"
   645                 "create index if not exists log_timestamp on log (\n"
   646                 "   timestamp\n"
   647                 ");\n"
   648                 "create table if not exists pgp_keypair (\n"
   649                 "   fpr text primary key,\n"
   650                 "   created integer,\n"
   651                 "   expires integer,\n"
   652                 "   comment text,\n"
   653                 "   flags integer default 0\n"
   654                 ");\n"
   655                 "create index if not exists pgp_keypair_expires on pgp_keypair (\n"
   656                 "   expires\n"
   657                 ");\n"
   658                 "create table if not exists person (\n"
   659                 "   id text primary key,\n"
   660                 "   username text not null,\n"
   661                 "   main_key_id text\n"
   662                 "       references pgp_keypair (fpr)\n"
   663                 "       on delete set null,\n"
   664                 "   lang text,\n"
   665                 "   comment text,\n"
   666                 "   device_group text,\n"
   667                 "   is_pep_user integer default 0\n"
   668                 ");\n"
   669                 "create table if not exists identity (\n"
   670                 "   address text,\n"
   671                 "   user_id text\n"
   672                 "       references person (id)\n"
   673                 "       on delete cascade on update cascade,\n"
   674                 "   main_key_id text\n"
   675                 "       references pgp_keypair (fpr)\n"
   676                 "       on delete set null,\n"
   677                 "   comment text,\n"
   678                 "   flags integer default 0,\n"
   679                 "   is_own integer default 0,\n"
   680                 "   timestamp integer default (datetime('now')),\n"
   681                 "   primary key (address, user_id)\n"
   682                 ");\n"
   683                 "create table if not exists trust (\n"
   684                 "   user_id text not null\n"
   685                 "       references person (id)\n"
   686                 "       on delete cascade on update cascade,\n"
   687                 "   pgp_keypair_fpr text not null\n"
   688                 "       references pgp_keypair (fpr)\n"
   689                 "       on delete cascade,\n"
   690                 "   comm_type integer not null,\n"
   691                 "   comment text,\n"
   692                 "   primary key (user_id, pgp_keypair_fpr)\n"
   693                 ");\n"
   694                 // blacklist
   695                 "create table if not exists blacklist_keys (\n"
   696                 "   fpr text primary key\n"
   697                 ");\n"
   698                 // sequences
   699                 "create table if not exists sequences(\n"
   700                 "   name text primary key,\n"
   701                 "   value integer default 0,\n"
   702                 "   own integer default 0\n"
   703                 ");\n"
   704                 "create table if not exists revoked_keys (\n"
   705                 "   revoked_fpr text primary key,\n"
   706                 "   replacement_fpr text not null\n"
   707                 "       references pgp_keypair (fpr)\n"
   708                 "       on delete cascade,\n"
   709                 "   revocation_date integer\n"
   710                 ");\n"
   711                 // user id aliases
   712                 "create table if not exists alternate_user_id (\n"
   713                 "    default_id text references person (id)\n"
   714                 "       on delete cascade on update cascade,\n"
   715                 "    alternate_id text primary key\n"
   716                 ");\n"
   717                 // mistrusted keys
   718                 "create table if not exists mistrusted_keys (\n"
   719                 "    fpr text primary key\n"
   720                 ");\n"
   721                 ,
   722             NULL,
   723             NULL,
   724             NULL
   725         );
   726         assert(int_result == SQLITE_OK);
   727 
   728         int version;
   729         int_result = sqlite3_exec(
   730             _session->db,
   731             "pragma user_version;",
   732             user_version,
   733             &version,
   734             NULL
   735         );
   736 
   737         assert(int_result == SQLITE_OK);
   738         
   739         void (*xFunc_lower)(sqlite3_context*,int,sqlite3_value**) = &_sql_lower;
   740         
   741         int_result = sqlite3_create_function_v2(
   742             _session->db,
   743             "lower",
   744             1,
   745             SQLITE_UTF8 | SQLITE_DETERMINISTIC,
   746             NULL,
   747             xFunc_lower,
   748             NULL,
   749             NULL,
   750             NULL);
   751         assert(int_result == SQLITE_OK);
   752 
   753         int_result = sqlite3_exec(
   754             _session->db,
   755             "pragma foreign_keys=ON;\n",
   756             NULL,
   757             NULL,
   758             NULL
   759         );
   760 
   761         assert(int_result == SQLITE_OK);
   762 
   763         
   764         // Sometimes the user_version wasn't set correctly. Check to see if this
   765         // is really necessary...
   766         if (version == 1) {
   767             bool version_changed = true;
   768             if (table_contains_column(_session, "identity", "timestamp") > 0) {
   769                 version = 8;
   770             }            
   771             if (table_contains_column(_session, "person", "is_pep_user") > 0) {
   772                 version = 7;
   773             }            
   774             else if (table_contains_column(_session, "identity", "is_own") > 0) {
   775                 version = 6;
   776             }
   777             else if (table_contains_column(_session, "sequences", "own") > 0) {
   778                 version = 3;
   779             }
   780             else if (table_contains_column(_session, "pgp_keypair", "flags") > 0) {
   781                 version = 2;
   782             }
   783             else {
   784                 version_changed = false;
   785             }
   786             
   787             if (version_changed) {
   788                 // set it in the DB, finally. Yeesh.
   789                 char verbuf[21]; // enough digits for a max-sized 64 bit int, cmon. 
   790                 sprintf(verbuf,"%d",version);
   791                 
   792                 size_t query_size = strlen(verbuf) + 25;
   793                 char* query = calloc(query_size, 1);
   794                 
   795                 strlcpy(query, "pragma user_version = ", query_size);
   796                 strlcat(query, verbuf, query_size);
   797                 strlcat(query, ";", query_size);
   798                 
   799                 int_result = sqlite3_exec(
   800                     _session->db,
   801                     query,
   802                     user_version,
   803                     &version,
   804                     NULL
   805                 );
   806                 free(query);
   807             }
   808         }
   809 
   810 
   811         if(version != 0) { 
   812             // Version has been already set
   813 
   814             // Early mistake : version 0 shouldn't have existed.
   815             // Numbering should have started at 1 to detect newly created DB.
   816             // Version 0 DBs are not anymore compatible.
   817 
   818             // // Was version 0 compat code.
   819             // if (version < 1) {
   820             //     int_result = sqlite3_exec(
   821             //         _session->db,
   822             //         "alter table identity\n"
   823             //         "   add column flags integer default 0;\n",
   824             //         NULL,
   825             //         NULL,
   826             //         NULL
   827             //     );
   828             //     assert(int_result == SQLITE_OK);
   829             // }
   830             
   831             if (version < 2) {
   832                 int_result = sqlite3_exec(
   833                     _session->db,
   834                     "alter table pgp_keypair\n"
   835                     "   add column flags integer default 0;\n"
   836                     "alter table person\n"
   837                     "   add column device_group text;\n",
   838                     NULL,
   839                     NULL,
   840                     NULL
   841                 );
   842                 assert(int_result == SQLITE_OK);
   843             }
   844 
   845             if (version < 3) {
   846                 int_result = sqlite3_exec(
   847                     _session->db,
   848                     "alter table sequences\n"
   849                     "   add column own integer default 0;\n",
   850                     NULL,
   851                     NULL,
   852                     NULL
   853                 );
   854                 assert(int_result == SQLITE_OK);
   855             }
   856 
   857             if (version < 5) {
   858                 int_result = sqlite3_exec(
   859                     _session->db,
   860                     "delete from pgp_keypair where fpr = '';",
   861                     NULL,
   862                     NULL,
   863                     NULL
   864                 );
   865                 assert(int_result == SQLITE_OK);
   866                 int_result = sqlite3_exec(
   867                     _session->db,
   868                     "delete from trust where pgp_keypair_fpr = '';",
   869                     NULL,
   870                     NULL,
   871                     NULL
   872                 );
   873                 assert(int_result == SQLITE_OK);
   874             }
   875             
   876             if (version < 6) {
   877                 int_result = sqlite3_exec(
   878                     _session->db,
   879                     "alter table identity\n"
   880                     "   add column is_own integer default 0;\n",
   881                     NULL,
   882                     NULL,
   883                     NULL
   884                 );
   885                 assert(int_result == SQLITE_OK);                
   886                 int_result = sqlite3_exec(
   887                     _session->db,
   888                     "update identity\n"
   889                     "   set is_own = 1\n"
   890                     "   where (user_id = '" PEP_OWN_USERID "');\n",
   891                     NULL,
   892                     NULL,
   893                     NULL
   894                 );
   895                 assert(int_result == SQLITE_OK);    
   896 
   897                 // Turns out that just adding "on update cascade" in
   898                 // sqlite is a PITA. We need to be able to cascade
   899                 // person->id replacements (for temp ids like "TOFU_")
   900                 // so here we go...
   901                 int_result = sqlite3_exec(
   902                     _session->db,
   903                     "PRAGMA foreign_keys=off;\n"
   904                     "BEGIN TRANSACTION;\n"
   905                     "ALTER TABLE identity RENAME TO _identity_old;\n"
   906                     "create table identity (\n"
   907                     "   address text,\n"
   908                     "   user_id text\n"
   909                     "       references person (id)\n"
   910                     "       on delete cascade on update cascade,\n"
   911                     "   main_key_id text\n"
   912                     "       references pgp_keypair (fpr)\n"
   913                     "       on delete set null,\n"
   914                     "   comment text,\n"
   915                     "   flags integer default 0,\n"
   916                     "   is_own integer default 0,\n"
   917                     "   primary key (address, user_id)\n"
   918                     ");\n"
   919                     "INSERT INTO identity SELECT * FROM _identity_old;\n"
   920                     "DROP TABLE _identity_old;\n"
   921                     "ALTER TABLE trust RENAME TO _trust_old;\n"
   922                     "create table trust (\n"
   923                     "   user_id text not null\n"
   924                     "       references person (id)\n"
   925                     "       on delete cascade on update cascade,\n"
   926                     "   pgp_keypair_fpr text not null\n"
   927                     "       references pgp_keypair (fpr)\n"
   928                     "       on delete cascade,\n"
   929                     "   comm_type integer not null,\n"
   930                     "   comment text,\n"
   931                     "   primary key (user_id, pgp_keypair_fpr)\n"
   932                     ");\n"
   933                     "INSERT INTO trust SELECT * FROM _trust_old;\n"
   934                     "DROP TABLE _trust_old;\n"
   935                     "COMMIT;\n"
   936                     "\n"
   937                     "PRAGMA foreign_keys=on;\n"
   938                     "create table if not exists alternate_user_id (\n"
   939                     "    default_id text references person (id)\n"
   940                     "       on delete cascade on update cascade,\n"
   941                     "    alternate_id text primary key\n"
   942                     ");\n"
   943                     ,
   944                     NULL,
   945                     NULL,
   946                     NULL
   947                 );
   948                 assert(int_result == SQLITE_OK);    
   949             }
   950             if (version < 7) {
   951                 int_result = sqlite3_exec(
   952                     _session->db,
   953                     "alter table person\n"
   954                     "   add column is_pep_user integer default 0;\n",
   955                     NULL,
   956                     NULL,
   957                     NULL
   958                 );
   959                 assert(int_result == SQLITE_OK);
   960                 int_result = sqlite3_exec(
   961                     _session->db,
   962                     "update person\n"
   963                     "   set is_pep_user = 1\n"
   964                     "   where id = "
   965                     "       (select distinct id from person "
   966                     "               join trust on id = user_id "
   967                     "               where (case when (comm_type = 127) then (id) "
   968                     "                           when (comm_type = 255) then (id) "
   969                     "                           else 0"
   970                     "                      end) = id );\n",
   971                     NULL,
   972                     NULL,
   973                     NULL
   974                 );
   975                 assert(int_result == SQLITE_OK);
   976                 
   977                 int_result = sqlite3_exec(
   978                     _session->db,
   979                     "create table if not exists mistrusted_keys (\n"
   980                     "    fpr text primary key\n"
   981                     ");\n",            
   982                     NULL,
   983                     NULL,
   984                     NULL
   985                 );
   986                 assert(int_result == SQLITE_OK);    
   987             }
   988             if (version < 8) {
   989                 int_result = sqlite3_exec(
   990                     _session->db,
   991                     "PRAGMA foreign_keys=off;\n"
   992                     "BEGIN TRANSACTION;\n"
   993                     "ALTER TABLE identity RENAME TO _identity_old;\n"
   994                     "create table identity (\n"
   995                     "   address text,\n"
   996                     "   user_id text\n"
   997                     "       references person (id)\n"
   998                     "       on delete cascade on update cascade,\n"
   999                     "   main_key_id text\n"
  1000                     "       references pgp_keypair (fpr)\n"
  1001                     "       on delete set null,\n"
  1002                     "   comment text,\n"
  1003                     "   flags integer default 0,\n"
  1004                     "   is_own integer default 0,\n"
  1005                     "   timestamp integer default (datetime('now')),\n"
  1006                     "   primary key (address, user_id)\n"
  1007                     ");\n"
  1008                     "INSERT INTO identity (address, user_id, main_key_id, "
  1009                     "                      comment, flags, is_own) "
  1010                     "   SELECT _identity_old.address, _identity_old.user_id, "
  1011                     "          _identity_old.main_key_id, _identity_old.comment, "
  1012                     "          _identity_old.flags, _identity_old.is_own "
  1013                     "   FROM _identity_old "
  1014                     "   WHERE 1;\n"
  1015                     "DROP TABLE _identity_old;\n"
  1016                     "COMMIT;\n"
  1017                     "\n"
  1018                     "PRAGMA foreign_keys=on;\n"
  1019                     ,
  1020                     NULL,
  1021                     NULL,
  1022                     NULL
  1023                 );
  1024                 assert(int_result == SQLITE_OK);    
  1025             }
  1026         }        
  1027         else { 
  1028             // Version from DB was 0, it means this is initial setup.
  1029             // DB has just been created, and all tables are empty.
  1030             very_first = true;
  1031         }
  1032 
  1033         if (version < atoi(_DDL_USER_VERSION)) {
  1034             int_result = sqlite3_exec(
  1035                 _session->db,
  1036                 "pragma user_version = "_DDL_USER_VERSION";\n"
  1037                 "insert or replace into version_info (id, version)"
  1038                     "values (1, '" PEP_ENGINE_VERSION "');",
  1039                 NULL,
  1040                 NULL,
  1041                 NULL
  1042             );
  1043             assert(int_result == SQLITE_OK);
  1044         }
  1045         
  1046         // We need to init a few globals for message id that we'd rather not
  1047         // calculate more than once.
  1048         _init_globals();
  1049     }
  1050 
  1051     int_result = sqlite3_prepare_v2(_session->db, sql_log,
  1052             (int)strlen(sql_log), &_session->log, NULL);
  1053     assert(int_result == SQLITE_OK);
  1054 
  1055     int_result = sqlite3_prepare_v2(_session->system_db, sql_trustword,
  1056             (int)strlen(sql_trustword), &_session->trustword, NULL);
  1057     assert(int_result == SQLITE_OK);
  1058 
  1059     int_result = sqlite3_prepare_v2(_session->db, sql_get_identity,
  1060             (int)strlen(sql_get_identity), &_session->get_identity, NULL);
  1061     assert(int_result == SQLITE_OK);
  1062 
  1063     int_result = sqlite3_prepare_v2(_session->db, sql_get_identity_without_trust_check,
  1064             (int)strlen(sql_get_identity_without_trust_check), 
  1065             &_session->get_identity_without_trust_check, NULL);
  1066     assert(int_result == SQLITE_OK);
  1067 
  1068     int_result = sqlite3_prepare_v2(_session->db, sql_get_identities_by_address,
  1069             (int)strlen(sql_get_identities_by_address), 
  1070             &_session->get_identities_by_address, NULL);
  1071     assert(int_result == SQLITE_OK);
  1072 
  1073     int_result = sqlite3_prepare_v2(_session->db, sql_get_user_default_key,
  1074             (int)strlen(sql_get_user_default_key), &_session->get_user_default_key, NULL);
  1075     assert(int_result == SQLITE_OK);
  1076 
  1077     int_result = sqlite3_prepare_v2(_session->db, sql_get_default_own_userid,
  1078             (int)strlen(sql_get_default_own_userid), &_session->get_default_own_userid, NULL);
  1079     assert(int_result == SQLITE_OK);
  1080     
  1081     int_result = sqlite3_prepare_v2(_session->db, sql_get_userid_alias_default,
  1082             (int)strlen(sql_get_userid_alias_default), &_session->get_userid_alias_default, NULL);
  1083     assert(int_result == SQLITE_OK);
  1084 
  1085     int_result = sqlite3_prepare_v2(_session->db, sql_add_userid_alias,
  1086             (int)strlen(sql_add_userid_alias), &_session->add_userid_alias, NULL);
  1087     assert(int_result == SQLITE_OK);
  1088 
  1089     int_result = sqlite3_prepare_v2(_session->db, sql_replace_userid,
  1090             (int)strlen(sql_replace_userid), &_session->replace_userid, NULL);
  1091     assert(int_result == SQLITE_OK);
  1092 
  1093     int_result = sqlite3_prepare_v2(_session->db, sql_replace_main_user_fpr,
  1094             (int)strlen(sql_replace_main_user_fpr), &_session->replace_main_user_fpr, NULL);
  1095     assert(int_result == SQLITE_OK);
  1096 
  1097     int_result = sqlite3_prepare_v2(_session->db, sql_get_main_user_fpr,
  1098             (int)strlen(sql_get_main_user_fpr), &_session->get_main_user_fpr, NULL);
  1099     assert(int_result == SQLITE_OK);
  1100 
  1101     int_result = sqlite3_prepare_v2(_session->db, sql_refresh_userid_default_key,
  1102             (int)strlen(sql_refresh_userid_default_key), &_session->refresh_userid_default_key, NULL);
  1103     assert(int_result == SQLITE_OK);
  1104 
  1105     int_result = sqlite3_prepare_v2(_session->db, sql_replace_identities_fpr,
  1106             (int)strlen(sql_replace_identities_fpr), 
  1107             &_session->replace_identities_fpr, NULL);
  1108     assert(int_result == SQLITE_OK);
  1109     
  1110     int_result = sqlite3_prepare_v2(_session->db, sql_remove_fpr_as_default,
  1111             (int)strlen(sql_remove_fpr_as_default), 
  1112             &_session->remove_fpr_as_default, NULL);
  1113     assert(int_result == SQLITE_OK);
  1114 
  1115     int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
  1116             (int)strlen(sql_set_person), &_session->set_person, NULL);
  1117     assert(int_result == SQLITE_OK);
  1118 
  1119     int_result = sqlite3_prepare_v2(_session->db, sql_update_person,
  1120             (int)strlen(sql_update_person), &_session->update_person, NULL);
  1121     assert(int_result == SQLITE_OK);
  1122 
  1123     int_result = sqlite3_prepare_v2(_session->db, sql_exists_person,
  1124             (int)strlen(sql_exists_person), &_session->exists_person, NULL);
  1125     assert(int_result == SQLITE_OK);
  1126 
  1127     int_result = sqlite3_prepare_v2(_session->db, sql_set_as_pep_user,
  1128             (int)strlen(sql_set_as_pep_user), &_session->set_as_pep_user, NULL);
  1129     assert(int_result == SQLITE_OK);
  1130     
  1131     int_result = sqlite3_prepare_v2(_session->db, sql_is_pep_user,
  1132             (int)strlen(sql_is_pep_user), &_session->is_pep_user, NULL);
  1133     assert(int_result == SQLITE_OK);
  1134 
  1135     int_result = sqlite3_prepare_v2(_session->db, sql_set_device_group,
  1136             (int)strlen(sql_set_device_group), &_session->set_device_group, NULL);
  1137     assert(int_result == SQLITE_OK);
  1138 
  1139     int_result = sqlite3_prepare_v2(_session->db, sql_get_device_group,
  1140             (int)strlen(sql_get_device_group), &_session->get_device_group, NULL);
  1141     assert(int_result == SQLITE_OK);
  1142 
  1143     int_result = sqlite3_prepare_v2(_session->db, sql_set_pgp_keypair,
  1144             (int)strlen(sql_set_pgp_keypair), &_session->set_pgp_keypair,
  1145             NULL);
  1146     assert(int_result == SQLITE_OK);
  1147 
  1148     int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_entry,
  1149             (int)strlen(sql_set_identity_entry), &_session->set_identity_entry, NULL);
  1150     assert(int_result == SQLITE_OK);
  1151 
  1152     int_result = sqlite3_prepare_v2(_session->db, sql_update_identity_entry,
  1153             (int)strlen(sql_update_identity_entry), &_session->update_identity_entry, NULL);
  1154     assert(int_result == SQLITE_OK);
  1155 
  1156     int_result = sqlite3_prepare_v2(_session->db, sql_exists_identity_entry,
  1157             (int)strlen(sql_exists_identity_entry), &_session->exists_identity_entry, NULL);
  1158     assert(int_result == SQLITE_OK);
  1159 
  1160     int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_flags,
  1161             (int)strlen(sql_set_identity_flags), &_session->set_identity_flags,
  1162             NULL);
  1163     assert(int_result == SQLITE_OK);
  1164 
  1165     int_result = sqlite3_prepare_v2(_session->db, sql_unset_identity_flags,
  1166             (int)strlen(sql_unset_identity_flags), &_session->unset_identity_flags,
  1167             NULL);
  1168     assert(int_result == SQLITE_OK);
  1169 
  1170     int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
  1171             (int)strlen(sql_set_trust), &_session->set_trust, NULL);
  1172     assert(int_result == SQLITE_OK);
  1173 
  1174     int_result = sqlite3_prepare_v2(_session->db, sql_update_trust,
  1175             (int)strlen(sql_update_trust), &_session->update_trust, NULL);
  1176     assert(int_result == SQLITE_OK);
  1177 
  1178     int_result = sqlite3_prepare_v2(_session->db, sql_update_trust_to_pep,
  1179             (int)strlen(sql_update_trust_to_pep), &_session->update_trust_to_pep, NULL);
  1180     assert(int_result == SQLITE_OK);
  1181 
  1182     int_result = sqlite3_prepare_v2(_session->db, sql_exists_trust_entry,
  1183                  (int)strlen(sql_exists_trust_entry), &_session->exists_trust_entry, NULL);
  1184     assert(int_result == SQLITE_OK);
  1185 
  1186     int_result = sqlite3_prepare_v2(_session->db, sql_update_trust_for_fpr,
  1187             (int)strlen(sql_update_trust_for_fpr), &_session->update_trust_for_fpr, NULL);
  1188     assert(int_result == SQLITE_OK);
  1189 
  1190     int_result = sqlite3_prepare_v2(_session->db, sql_get_trust,
  1191             (int)strlen(sql_get_trust), &_session->get_trust, NULL);
  1192     assert(int_result == SQLITE_OK);
  1193 
  1194     int_result = sqlite3_prepare_v2(_session->db, sql_least_trust,
  1195             (int)strlen(sql_least_trust), &_session->least_trust, NULL);
  1196     assert(int_result == SQLITE_OK);
  1197 
  1198     int_result = sqlite3_prepare_v2(_session->db, sql_mark_as_compromised,
  1199             (int)strlen(sql_mark_as_compromised), &_session->mark_compromised,
  1200             NULL);
  1201     assert(int_result == SQLITE_OK);
  1202 
  1203     int_result = sqlite3_prepare_v2(_session->db, sql_crashdump,
  1204             (int)strlen(sql_crashdump), &_session->crashdump, NULL);
  1205     assert(int_result == SQLITE_OK);
  1206 
  1207     int_result = sqlite3_prepare_v2(_session->system_db, sql_languagelist,
  1208             (int)strlen(sql_languagelist), &_session->languagelist, NULL);
  1209     assert(int_result == SQLITE_OK);
  1210 
  1211     int_result = sqlite3_prepare_v2(_session->system_db, sql_i18n_token,
  1212             (int)strlen(sql_i18n_token), &_session->i18n_token, NULL);
  1213     assert(int_result == SQLITE_OK);
  1214     
  1215     // blacklist
  1216 
  1217     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_add,
  1218             (int)strlen(sql_blacklist_add), &_session->blacklist_add, NULL);
  1219     assert(int_result == SQLITE_OK);
  1220 
  1221     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_delete,
  1222             (int)strlen(sql_blacklist_delete), &_session->blacklist_delete,
  1223             NULL);
  1224     assert(int_result == SQLITE_OK);
  1225 
  1226     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_is_listed,
  1227             (int)strlen(sql_blacklist_is_listed),
  1228             &_session->blacklist_is_listed, NULL);
  1229     assert(int_result == SQLITE_OK);
  1230 
  1231     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_retrieve,
  1232             (int)strlen(sql_blacklist_retrieve), &_session->blacklist_retrieve,
  1233             NULL);
  1234     assert(int_result == SQLITE_OK);
  1235     
  1236     // Own keys
  1237     
  1238     int_result = sqlite3_prepare_v2(_session->db, sql_own_key_is_listed,
  1239             (int)strlen(sql_own_key_is_listed), &_session->own_key_is_listed,
  1240             NULL);
  1241     assert(int_result == SQLITE_OK);
  1242     
  1243     int_result = sqlite3_prepare_v2(_session->db, sql_own_identities_retrieve,
  1244             (int)strlen(sql_own_identities_retrieve),
  1245             &_session->own_identities_retrieve, NULL);
  1246     assert(int_result == SQLITE_OK);
  1247  
  1248     int_result = sqlite3_prepare_v2(_session->db, sql_own_keys_retrieve,
  1249             (int)strlen(sql_own_keys_retrieve),
  1250             &_session->own_keys_retrieve, NULL);
  1251     assert(int_result == SQLITE_OK);
  1252  
  1253     // int_result = sqlite3_prepare_v2(_session->db, sql_set_own_key,
  1254     //         (int)strlen(sql_set_own_key),
  1255     //         &_session->set_own_key, NULL);
  1256     // assert(int_result == SQLITE_OK);
  1257  
  1258     // Sequence
  1259 
  1260     int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value1,
  1261             (int)strlen(sql_sequence_value1), &_session->sequence_value1,
  1262             NULL);
  1263     assert(int_result == SQLITE_OK);
  1264 
  1265     int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value2,
  1266             (int)strlen(sql_sequence_value2), &_session->sequence_value2,
  1267             NULL);
  1268     assert(int_result == SQLITE_OK);
  1269 
  1270     int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value3,
  1271             (int)strlen(sql_sequence_value3), &_session->sequence_value3,
  1272             NULL);
  1273     assert(int_result == SQLITE_OK);
  1274 
  1275     // Revocation tracking
  1276     
  1277     int_result = sqlite3_prepare_v2(_session->db, sql_set_revoked,
  1278             (int)strlen(sql_set_revoked), &_session->set_revoked, NULL);
  1279     assert(int_result == SQLITE_OK);
  1280     
  1281     int_result = sqlite3_prepare_v2(_session->db, sql_get_revoked,
  1282             (int)strlen(sql_get_revoked), &_session->get_revoked, NULL);
  1283     assert(int_result == SQLITE_OK);
  1284     
  1285     int_result = sqlite3_prepare_v2(_session->db, sql_add_mistrusted_key,
  1286             (int)strlen(sql_add_mistrusted_key), &_session->add_mistrusted_key, NULL);
  1287     assert(int_result == SQLITE_OK);
  1288 
  1289     int_result = sqlite3_prepare_v2(_session->db, sql_delete_mistrusted_key,
  1290             (int)strlen(sql_delete_mistrusted_key), &_session->delete_mistrusted_key, NULL);
  1291     assert(int_result == SQLITE_OK);
  1292 
  1293     int_result = sqlite3_prepare_v2(_session->db, sql_is_mistrusted_key,
  1294             (int)strlen(sql_is_mistrusted_key), &_session->is_mistrusted_key, NULL);
  1295     assert(int_result == SQLITE_OK);
  1296     
  1297     status = init_cryptotech(_session, in_first);
  1298     if (status != PEP_STATUS_OK)
  1299         goto pep_error;
  1300 
  1301     status = init_transport_system(_session, in_first);
  1302     if (status != PEP_STATUS_OK)
  1303         goto pep_error;
  1304 
  1305     status = log_event(_session, "init", "pEp " PEP_ENGINE_VERSION, NULL, NULL);
  1306     if (status != PEP_STATUS_OK)
  1307         goto pep_error;
  1308 
  1309     // runtime config
  1310 
  1311     if (very_first)
  1312     {
  1313 #ifdef USE_GPG
  1314         // On first run, all private keys already present in PGP keyring 
  1315         // are taken as own in order to seamlessly integrate with
  1316         // pre-existing GPG setup.
  1317 
  1318         // Note: earlier fears about danger because of DB reinitialisation should
  1319         // be a non-issue here, as we ONLY take the ultimately trusted keys now.
  1320         // Thus, unless the user has assigned ultimate trust through PGP, there is
  1321         // no chance of automatically imported pEp keys from a previous run making
  1322         // their way into PEP trusted status without explicit action (Bare imported
  1323         // private keys have an 'unknown' trust designation in PGP).
  1324 
  1325         // We don't really worry about the status here.
  1326         status = pgp_import_ultimately_trusted_keypairs(_session);        
  1327 #endif // USE_GPG
  1328     }
  1329 
  1330     // sync_session set to own session by default
  1331     // sync_session is then never null on a valid session
  1332     _session->sync_session = _session;
  1333 
  1334     *session = _session;
  1335     
  1336     // Note: Following statement is NOT for any cryptographic/secure functionality; it is
  1337     //       ONLY used for some randomness in generated outer message ID, which are
  1338     //       required by the RFC to be globally unique!
  1339     srand((unsigned int) time(NULL));
  1340     
  1341     return PEP_STATUS_OK;
  1342 
  1343 enomem:
  1344     status = PEP_OUT_OF_MEMORY;
  1345 
  1346 pep_error:
  1347     release(_session);
  1348     return status;
  1349 }
  1350 
  1351 DYNAMIC_API void release(PEP_SESSION session)
  1352 {
  1353     bool out_last = false;
  1354     int _count = --init_count;
  1355     
  1356     assert(_count >= -1);
  1357     assert(session);
  1358 
  1359     if (!((_count >= -1) && session))
  1360         return;
  1361 
  1362     // a small race condition but still a race condition
  1363     // mitigated by calling caveat (see documentation)
  1364     // (release() is to be guarded by a mutex by the caller)
  1365     if (_count == -1)
  1366         out_last = true;
  1367 
  1368     if (session) {
  1369 
  1370         if (session->db) {
  1371             if (session->log)
  1372                 sqlite3_finalize(session->log);
  1373             if (session->trustword)
  1374                 sqlite3_finalize(session->trustword);
  1375             if (session->get_identity)
  1376                 sqlite3_finalize(session->get_identity);
  1377             if (session->get_identity_without_trust_check)
  1378                 sqlite3_finalize(session->get_identity_without_trust_check);
  1379             if (session->get_identities_by_address)
  1380                 sqlite3_finalize(session->get_identities_by_address);            
  1381             if (session->get_user_default_key)
  1382                 sqlite3_finalize(session->get_user_default_key);    
  1383             if (session->get_default_own_userid)
  1384                 sqlite3_finalize(session->get_default_own_userid);
  1385             if (session->get_userid_alias_default)
  1386                 sqlite3_finalize(session->get_userid_alias_default);
  1387             if (session->add_userid_alias)
  1388                 sqlite3_finalize(session->add_userid_alias);
  1389             if (session->replace_identities_fpr)
  1390                 sqlite3_finalize(session->replace_identities_fpr);        
  1391             if (session->remove_fpr_as_default)
  1392                 sqlite3_finalize(session->remove_fpr_as_default);            
  1393             if (session->set_person)
  1394                 sqlite3_finalize(session->set_person);
  1395             if (session->set_as_pep_user)
  1396                 sqlite3_finalize(session->set_as_pep_user);
  1397             if (session->is_pep_user)
  1398                 sqlite3_finalize(session->is_pep_user);
  1399             if (session->exists_person)
  1400                 sqlite3_finalize(session->exists_person);                        
  1401             if (session->set_device_group)
  1402                 sqlite3_finalize(session->set_device_group);
  1403             if (session->get_device_group)
  1404                 sqlite3_finalize(session->get_device_group);
  1405             if (session->set_pgp_keypair)
  1406                 sqlite3_finalize(session->set_pgp_keypair);
  1407             if (session->exists_identity_entry)
  1408                 sqlite3_finalize(session->exists_identity_entry);                
  1409             if (session->set_identity_entry)
  1410                 sqlite3_finalize(session->set_identity_entry);
  1411             if (session->update_identity_entry)
  1412                 sqlite3_finalize(session->update_identity_entry);    
  1413             if (session->set_identity_flags)
  1414                 sqlite3_finalize(session->set_identity_flags);
  1415             if (session->unset_identity_flags)
  1416                 sqlite3_finalize(session->unset_identity_flags);
  1417             if (session->exists_trust_entry)
  1418                 sqlite3_finalize(session->exists_trust_entry);                                
  1419             if (session->set_trust)
  1420                 sqlite3_finalize(session->set_trust);
  1421             if (session->update_trust)
  1422                 sqlite3_finalize(session->update_trust);
  1423             if (session->update_trust_to_pep)
  1424                 sqlite3_finalize(session->update_trust_to_pep);                                                
  1425             if (session->update_trust_for_fpr)
  1426                 sqlite3_finalize(session->update_trust_for_fpr);
  1427             if (session->get_trust)
  1428                 sqlite3_finalize(session->get_trust);
  1429             if (session->least_trust)
  1430                 sqlite3_finalize(session->least_trust);
  1431             if (session->mark_compromised)
  1432                 sqlite3_finalize(session->mark_compromised);
  1433             if (session->crashdump)
  1434                 sqlite3_finalize(session->crashdump);
  1435             if (session->languagelist)
  1436                 sqlite3_finalize(session->languagelist);
  1437             if (session->i18n_token)
  1438                 sqlite3_finalize(session->i18n_token);
  1439             if (session->replace_userid)
  1440                 sqlite3_finalize(session->replace_userid);
  1441             if (session->replace_main_user_fpr)
  1442                 sqlite3_finalize(session->replace_main_user_fpr);                
  1443             if (session->get_main_user_fpr)
  1444                 sqlite3_finalize(session->get_main_user_fpr);
  1445             if (session->refresh_userid_default_key)
  1446                 sqlite3_finalize(session->refresh_userid_default_key);
  1447             if (session->blacklist_add)
  1448                 sqlite3_finalize(session->blacklist_add);
  1449             if (session->blacklist_delete)
  1450                 sqlite3_finalize(session->blacklist_delete);
  1451             if (session->blacklist_is_listed)
  1452                 sqlite3_finalize(session->blacklist_is_listed);
  1453             if (session->blacklist_retrieve)
  1454                 sqlite3_finalize(session->blacklist_retrieve);
  1455             if (session->own_key_is_listed)
  1456                 sqlite3_finalize(session->own_key_is_listed);
  1457             if (session->own_identities_retrieve)
  1458                 sqlite3_finalize(session->own_identities_retrieve);
  1459             if (session->own_keys_retrieve)
  1460                 sqlite3_finalize(session->own_keys_retrieve);
  1461             // if (session->set_own_key)
  1462             //     sqlite3_finalize(session->set_own_key);
  1463             if (session->sequence_value1)
  1464                 sqlite3_finalize(session->sequence_value1);
  1465             if (session->sequence_value2)
  1466                 sqlite3_finalize(session->sequence_value2);
  1467             if (session->sequence_value3)
  1468                 sqlite3_finalize(session->sequence_value3);
  1469             if (session->set_revoked)
  1470                 sqlite3_finalize(session->set_revoked);
  1471             if (session->get_revoked)
  1472                 sqlite3_finalize(session->get_revoked);
  1473 
  1474             if (session->add_mistrusted_key)
  1475                 sqlite3_finalize(session->add_mistrusted_key);
  1476             if (session->delete_mistrusted_key)
  1477                 sqlite3_finalize(session->delete_mistrusted_key);
  1478             if (session->is_mistrusted_key)
  1479                 sqlite3_finalize(session->is_mistrusted_key);
  1480                 
  1481             if (session->db) {
  1482                 sqlite3_exec(        
  1483                     session->db,
  1484                     "PRAGMA optimize;\n",
  1485                     NULL,
  1486                     NULL,
  1487                     NULL
  1488                 );
  1489                 sqlite3_close_v2(session->db);
  1490             }
  1491             if (session->system_db)
  1492                 sqlite3_close_v2(session->system_db);
  1493         }
  1494 
  1495         release_transport_system(session, out_last);
  1496         release_cryptotech(session, out_last);
  1497 
  1498 #ifdef DEBUG_ERRORSTACK
  1499         free_stringlist(session->errorstack);
  1500 #endif
  1501         free(session);
  1502     }
  1503 }
  1504 
  1505 DYNAMIC_API void config_passive_mode(PEP_SESSION session, bool enable)
  1506 {
  1507     assert(session);
  1508     session->passive_mode = enable;
  1509 }
  1510 
  1511 DYNAMIC_API void config_unencrypted_subject(PEP_SESSION session, bool enable)
  1512 {
  1513     assert(session);
  1514     session->unencrypted_subject = enable;
  1515 }
  1516 
  1517 DYNAMIC_API void config_keep_sync_msg(PEP_SESSION session, bool enable)
  1518 {
  1519     assert(session);
  1520     session->keep_sync_msg = enable;
  1521 }
  1522 
  1523 DYNAMIC_API void config_service_log(PEP_SESSION session, bool enable)
  1524 {
  1525     assert(session);
  1526     session->service_log = enable;
  1527 }
  1528 
  1529 DYNAMIC_API PEP_STATUS log_event(
  1530         PEP_SESSION session,
  1531         const char *title,
  1532         const char *entity,
  1533         const char *description,
  1534         const char *comment
  1535     )
  1536 {
  1537 //    PEP_STATUS status = PEP_STATUS_OK;
  1538     // int result;
  1539     // 
  1540     // assert(session);
  1541     // assert(title);
  1542     // assert(entity);
  1543     // 
  1544     // if (!(session && title && entity))
  1545     //     return PEP_ILLEGAL_VALUE;
  1546     // 
  1547     // sqlite3_reset(session->log);
  1548     // sqlite3_bind_text(session->log, 1, title, -1, SQLITE_STATIC);
  1549     // sqlite3_bind_text(session->log, 2, entity, -1, SQLITE_STATIC);
  1550     // if (description)
  1551     //     sqlite3_bind_text(session->log, 3, description, -1, SQLITE_STATIC);
  1552     // else
  1553     //     sqlite3_bind_null(session->log, 3);
  1554     // if (comment)
  1555     //     sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
  1556     // else
  1557     //     sqlite3_bind_null(session->log, 4);
  1558     // result = sqlite3_step(session->log);
  1559     // sqlite3_reset(session->log);
  1560     // 
  1561     return PEP_STATUS_OK; // We ignore errors for this function.
  1562 }
  1563 
  1564 DYNAMIC_API PEP_STATUS log_service(
  1565         PEP_SESSION session,
  1566         const char *title,
  1567         const char *entity,
  1568         const char *description,
  1569         const char *comment
  1570     )
  1571 {
  1572     assert(session);
  1573     if (!session)
  1574         return PEP_ILLEGAL_VALUE;
  1575 
  1576     if (session->service_log)
  1577         return log_event(session, title, entity, description, comment);
  1578     else
  1579         return PEP_STATUS_OK;
  1580 }
  1581 
  1582 DYNAMIC_API PEP_STATUS trustword(
  1583             PEP_SESSION session, uint16_t value, const char *lang,
  1584             char **word, size_t *wsize
  1585         )
  1586 {
  1587     PEP_STATUS status = PEP_STATUS_OK;
  1588 
  1589     assert(session);
  1590     assert(word);
  1591     assert(wsize);
  1592 
  1593     if (!(session && word && wsize))
  1594         return PEP_ILLEGAL_VALUE;
  1595 
  1596     *word = NULL;
  1597     *wsize = 0;
  1598 
  1599     if (lang == NULL)
  1600         lang = "en";
  1601 
  1602     assert((lang[0] >= 'A' && lang[0] <= 'Z')
  1603             || (lang[0] >= 'a' && lang[0] <= 'z'));
  1604     assert((lang[1] >= 'A' && lang[1] <= 'Z')
  1605             || (lang[1] >= 'a' && lang[1] <= 'z'));
  1606     assert(lang[2] == 0);
  1607 
  1608     sqlite3_reset(session->trustword);
  1609     sqlite3_bind_text(session->trustword, 1, lang, -1, SQLITE_STATIC);
  1610     sqlite3_bind_int(session->trustword, 2, value);
  1611 
  1612     const int result = sqlite3_step(session->trustword);
  1613     if (result == SQLITE_ROW) {
  1614         *word = strdup((const char *) sqlite3_column_text(session->trustword,
  1615                     1));
  1616         if (*word)
  1617             *wsize = sqlite3_column_bytes(session->trustword, 1);
  1618         else
  1619             status = PEP_OUT_OF_MEMORY;
  1620     } else
  1621         status = PEP_TRUSTWORD_NOT_FOUND;
  1622 
  1623     sqlite3_reset(session->trustword);
  1624     return status;
  1625 }
  1626 
  1627 DYNAMIC_API PEP_STATUS trustwords(
  1628         PEP_SESSION session, const char *fingerprint, const char *lang,
  1629         char **words, size_t *wsize, int max_words
  1630     )
  1631 {
  1632     const char *source = fingerprint;
  1633 
  1634     assert(session);
  1635     assert(fingerprint);
  1636     assert(words);
  1637     assert(wsize);
  1638     assert(max_words >= 0);
  1639 
  1640     if (!(session && fingerprint && words && wsize && max_words >= 0))
  1641         return PEP_ILLEGAL_VALUE;
  1642 
  1643     *words = NULL;
  1644     *wsize = 0;
  1645 
  1646     char *buffer = calloc(1, MAX_TRUSTWORDS_SPACE);
  1647     assert(buffer);
  1648     if (buffer == NULL)
  1649         return PEP_OUT_OF_MEMORY;
  1650     char *dest = buffer;
  1651 
  1652     const size_t fsize = strlen(fingerprint);
  1653 
  1654     if (!lang || !lang[0])
  1655         lang = "en";
  1656 
  1657     assert((lang[0] >= 'A' && lang[0] <= 'Z')
  1658             || (lang[0] >= 'a' && lang[0] <= 'z'));
  1659     assert((lang[1] >= 'A' && lang[1] <= 'Z')
  1660             || (lang[1] >= 'a' && lang[1] <= 'z'));
  1661     assert(lang[2] == 0);
  1662 
  1663     int n_words = 0;
  1664     while (source < fingerprint + fsize) {
  1665         PEP_STATUS _status;
  1666         uint16_t value;
  1667         char *word = NULL;
  1668         size_t _wsize = 0;
  1669         int j;
  1670 
  1671         for (value=0, j=0; j < 4 && source < fingerprint + fsize; ) {
  1672             if (*source >= 'a' && *source <= 'f')
  1673                 value += (*source - 'a' + 10) << (3 - j++) * 4;
  1674             else if (*source >= 'A' && *source <= 'F')
  1675                 value += (*source - 'A' + 10) << (3 - j++) * 4;
  1676             else if (*source >= '0' && *source <= '9')
  1677                 value += (*source - '0') << (3 - j++) * 4;
  1678             
  1679             source++;
  1680         }
  1681 
  1682         _status = trustword(session, value, lang, &word, &_wsize);
  1683         if (_status == PEP_OUT_OF_MEMORY) {
  1684             free(buffer);
  1685             return PEP_OUT_OF_MEMORY;
  1686         }
  1687         if (word == NULL) {
  1688             free(buffer);
  1689             return PEP_TRUSTWORD_NOT_FOUND;
  1690         }
  1691 
  1692         if (dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1) {
  1693             strncpy(dest, word, _wsize);
  1694             free(word);
  1695             dest += _wsize;
  1696         }
  1697         else {
  1698             free(word);
  1699             break; // buffer full
  1700         }
  1701 
  1702         if (source < fingerprint + fsize
  1703                 && dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1)
  1704             *dest++ = ' ';
  1705 
  1706         ++n_words;
  1707         if (max_words && n_words >= max_words)
  1708             break;
  1709     }
  1710 
  1711     *words = buffer;
  1712     *wsize = dest - buffer;
  1713     return PEP_STATUS_OK;
  1714 }
  1715 
  1716 pEp_identity *new_identity(
  1717         const char *address, const char *fpr, const char *user_id,
  1718         const char *username
  1719     )
  1720 {
  1721     pEp_identity *result = calloc(1, sizeof(pEp_identity));
  1722     assert(result);
  1723     if (result) {
  1724         if (address) {
  1725             result->address = strdup(address);
  1726             assert(result->address);
  1727             if (result->address == NULL) {
  1728                 free(result);
  1729                 return NULL;
  1730             }
  1731         }
  1732         if (fpr) {
  1733             result->fpr = strdup(fpr);
  1734             assert(result->fpr);
  1735             if (result->fpr == NULL) {
  1736                 free_identity(result);
  1737                 return NULL;
  1738             }
  1739         }
  1740         if (user_id) {
  1741             result->user_id = strdup(user_id);
  1742             assert(result->user_id);
  1743             if (result->user_id == NULL) {
  1744                 free_identity(result);
  1745                 return NULL;
  1746             }
  1747         }
  1748         if (username) {
  1749             result->username = strdup(username);
  1750             assert(result->username);
  1751             if (result->username == NULL) {
  1752                 free_identity(result);
  1753                 return NULL;
  1754             }
  1755         }
  1756     }
  1757     return result;
  1758 }
  1759 
  1760 pEp_identity *identity_dup(const pEp_identity *src)
  1761 {
  1762     assert(src);
  1763 
  1764     pEp_identity *dup = new_identity(src->address, src->fpr, src->user_id,
  1765             src->username);
  1766     assert(dup);
  1767     if (dup == NULL)
  1768         return NULL;
  1769     
  1770     dup->comm_type = src->comm_type;
  1771     dup->lang[0] = src->lang[0];
  1772     dup->lang[1] = src->lang[1];
  1773     dup->lang[2] = 0;
  1774     dup->flags = src->flags;
  1775     dup->me = src->me;
  1776     
  1777     return dup;
  1778 }
  1779 
  1780 void free_identity(pEp_identity *identity)
  1781 {
  1782     if (identity) {
  1783         free(identity->address);
  1784         free(identity->fpr);
  1785         free(identity->user_id);
  1786         free(identity->username);
  1787         free(identity);
  1788     }
  1789 }
  1790 
  1791 DYNAMIC_API PEP_STATUS get_default_own_userid(
  1792         PEP_SESSION session, 
  1793         char** userid
  1794     )
  1795 {
  1796     assert(session);
  1797     assert(userid);
  1798     
  1799     if (!session || !userid)
  1800         return PEP_ILLEGAL_VALUE;
  1801         
  1802     PEP_STATUS status = PEP_STATUS_OK;
  1803     char* retval = NULL;
  1804     
  1805     sqlite3_reset(session->get_default_own_userid);
  1806 
  1807     const int result = sqlite3_step(session->get_default_own_userid);
  1808     const char* id;
  1809     
  1810     switch (result) {
  1811         case SQLITE_ROW:
  1812             id = (const char *) sqlite3_column_text(session->get_default_own_userid, 0);
  1813             if (!id) {
  1814                 // Shouldn't happen.
  1815                 status = PEP_UNKNOWN_ERROR;
  1816             }
  1817             else {
  1818                 retval = strdup(id);
  1819                 if (!retval)
  1820                     status = PEP_OUT_OF_MEMORY;
  1821             }
  1822             break;
  1823         default:
  1824             // Technically true, given how we find it, but FIXME we need a more descriptive error
  1825             status = PEP_CANNOT_FIND_IDENTITY;
  1826             *userid = NULL;
  1827     }
  1828 
  1829     *userid = retval;
  1830 
  1831     sqlite3_reset(session->get_default_own_userid);
  1832     
  1833     return status;
  1834 }
  1835 
  1836 DYNAMIC_API PEP_STATUS get_userid_alias_default(
  1837         PEP_SESSION session, 
  1838         const char* alias_id,
  1839         char** default_id) {
  1840             
  1841     assert(session);
  1842     assert(alias_id);
  1843     assert(alias_id[0]);
  1844     assert(default_id);
  1845 
  1846     if (!(session && alias_id && alias_id[0] && default_id))
  1847         return PEP_ILLEGAL_VALUE;
  1848 
  1849     PEP_STATUS status = PEP_STATUS_OK;
  1850     char* retval = NULL;
  1851 
  1852     sqlite3_reset(session->get_userid_alias_default);
  1853     sqlite3_bind_text(session->get_userid_alias_default, 1, alias_id, -1, SQLITE_STATIC);
  1854 
  1855     const char* tempid;
  1856     
  1857     const int result = sqlite3_step(session->get_userid_alias_default);
  1858     switch (result) {
  1859     case SQLITE_ROW:
  1860         tempid = (const char *) sqlite3_column_text(session->get_userid_alias_default, 0);
  1861         if (tempid) {
  1862             retval = strdup(tempid);
  1863             assert(retval);
  1864             if (retval == NULL)
  1865                 return PEP_OUT_OF_MEMORY;
  1866         }
  1867     
  1868         *default_id = retval;
  1869         break;
  1870     default:
  1871         status = PEP_CANNOT_FIND_ALIAS;
  1872         *default_id = NULL;
  1873     }
  1874 
  1875     sqlite3_reset(session->get_userid_alias_default);
  1876     return status;            
  1877 }
  1878 
  1879 DYNAMIC_API PEP_STATUS set_userid_alias (
  1880         PEP_SESSION session, 
  1881         const char* default_id,
  1882         const char* alias_id) {
  1883             
  1884     int result;
  1885 
  1886     assert(session);
  1887     assert(default_id);
  1888     assert(alias_id);
  1889 
  1890     if (!(session && default_id && alias_id && 
  1891           default_id[0] != '\0' && alias_id[0] != '\0'))
  1892         return PEP_ILLEGAL_VALUE;
  1893     
  1894     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  1895 
  1896     sqlite3_reset(session->add_userid_alias);
  1897     sqlite3_bind_text(session->add_userid_alias, 1, default_id, -1,
  1898             SQLITE_STATIC);
  1899     sqlite3_bind_text(session->add_userid_alias, 2, alias_id, -1,
  1900             SQLITE_STATIC);
  1901         
  1902     result = sqlite3_step(session->add_userid_alias);
  1903 
  1904     sqlite3_reset(session->add_userid_alias);
  1905     if (result != SQLITE_DONE) {
  1906         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);        
  1907         return PEP_CANNOT_SET_ALIAS;
  1908     }
  1909     sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  1910         
  1911 
  1912     return PEP_STATUS_OK;
  1913 }
  1914 
  1915 DYNAMIC_API PEP_STATUS get_identity(
  1916         PEP_SESSION session,
  1917         const char *address,
  1918         const char *user_id,
  1919         pEp_identity **identity
  1920     )
  1921 {
  1922     PEP_STATUS status = PEP_STATUS_OK;
  1923     static pEp_identity *_identity;
  1924 
  1925     assert(session);
  1926     assert(address);
  1927     assert(address[0]);
  1928     assert(identity);
  1929 
  1930     if (!(session && address && address[0] && identity))
  1931         return PEP_ILLEGAL_VALUE;
  1932 
  1933     *identity = NULL;
  1934 
  1935     sqlite3_reset(session->get_identity);
  1936     sqlite3_bind_text(session->get_identity, 1, address, -1, SQLITE_STATIC);
  1937     sqlite3_bind_text(session->get_identity, 2, user_id, -1, SQLITE_STATIC);
  1938 
  1939     const int result = sqlite3_step(session->get_identity);
  1940     switch (result) {
  1941     case SQLITE_ROW:
  1942         _identity = new_identity(
  1943                 address,
  1944                 (const char *) sqlite3_column_text(session->get_identity, 0),
  1945                 user_id,
  1946                 (const char *) sqlite3_column_text(session->get_identity, 1)
  1947                 );
  1948         assert(_identity);
  1949         if (_identity == NULL) {
  1950             sqlite3_reset(session->get_identity);
  1951             return PEP_OUT_OF_MEMORY;
  1952         }
  1953 
  1954         _identity->comm_type = (PEP_comm_type)
  1955             sqlite3_column_int(session->get_identity, 2);
  1956         const char* const _lang = (const char *)
  1957             sqlite3_column_text(session->get_identity, 3);
  1958         if (_lang && _lang[0]) {
  1959             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  1960             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  1961             assert(_lang[2] == 0);
  1962             _identity->lang[0] = _lang[0];
  1963             _identity->lang[1] = _lang[1];
  1964             _identity->lang[2] = 0;
  1965         }
  1966         _identity->flags = (unsigned int)
  1967             sqlite3_column_int(session->get_identity, 4);
  1968         _identity->me = (unsigned int)
  1969             sqlite3_column_int(session->get_identity, 5);
  1970     
  1971         *identity = _identity;
  1972         break;
  1973     default:
  1974         sqlite3_reset(session->get_identity);
  1975         status = PEP_CANNOT_FIND_IDENTITY;
  1976         *identity = NULL;
  1977     }
  1978 
  1979     sqlite3_reset(session->get_identity);
  1980     return status;
  1981 }
  1982 
  1983 PEP_STATUS get_identity_without_trust_check(
  1984         PEP_SESSION session,
  1985         const char *address,
  1986         const char *user_id,
  1987         pEp_identity **identity
  1988     )
  1989 {
  1990     PEP_STATUS status = PEP_STATUS_OK;
  1991     static pEp_identity *_identity;
  1992 
  1993     assert(session);
  1994     assert(address);
  1995     assert(address[0]);
  1996     assert(identity);
  1997 
  1998     if (!(session && address && address[0] && identity))
  1999         return PEP_ILLEGAL_VALUE;
  2000 
  2001     *identity = NULL;
  2002 
  2003     sqlite3_reset(session->get_identity_without_trust_check);
  2004     sqlite3_bind_text(session->get_identity_without_trust_check, 1, address, -1, SQLITE_STATIC);
  2005     sqlite3_bind_text(session->get_identity_without_trust_check, 2, user_id, -1, SQLITE_STATIC);
  2006 
  2007     const int result = sqlite3_step(session->get_identity_without_trust_check);
  2008     switch (result) {
  2009     case SQLITE_ROW:
  2010         _identity = new_identity(
  2011                 address,
  2012                 (const char *) sqlite3_column_text(session->get_identity_without_trust_check, 0),
  2013                 user_id,
  2014                 (const char *) sqlite3_column_text(session->get_identity_without_trust_check, 1)
  2015                 );
  2016         assert(_identity);
  2017         if (_identity == NULL) {
  2018             sqlite3_reset(session->get_identity_without_trust_check);
  2019             return PEP_OUT_OF_MEMORY;
  2020         }
  2021 
  2022         _identity->comm_type = PEP_ct_unknown;
  2023         const char* const _lang = (const char *)
  2024             sqlite3_column_text(session->get_identity_without_trust_check, 2);
  2025         if (_lang && _lang[0]) {
  2026             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  2027             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  2028             assert(_lang[2] == 0);
  2029             _identity->lang[0] = _lang[0];
  2030             _identity->lang[1] = _lang[1];
  2031             _identity->lang[2] = 0;
  2032         }
  2033         _identity->flags = (unsigned int)
  2034             sqlite3_column_int(session->get_identity_without_trust_check, 3);
  2035         _identity->me = (unsigned int)
  2036             sqlite3_column_int(session->get_identity_without_trust_check, 4);
  2037     
  2038         *identity = _identity;
  2039         break;
  2040     default:
  2041         status = PEP_CANNOT_FIND_IDENTITY;
  2042         *identity = NULL;
  2043     }
  2044 
  2045     sqlite3_reset(session->get_identity_without_trust_check);
  2046     return status;
  2047 }
  2048 
  2049 PEP_STATUS get_identities_by_address(
  2050         PEP_SESSION session,
  2051         const char *address,
  2052         identity_list** id_list
  2053     )
  2054 {
  2055     pEp_identity* ident;
  2056 
  2057     assert(session);
  2058     assert(address);
  2059     assert(address[0]);
  2060     assert(id_list);
  2061 
  2062     if (!(session && address && address[0] && id_list))
  2063         return PEP_ILLEGAL_VALUE;
  2064 
  2065     *id_list = NULL;
  2066     identity_list* ident_list = NULL;
  2067 
  2068     sqlite3_reset(session->get_identities_by_address);
  2069     sqlite3_bind_text(session->get_identities_by_address, 1, address, -1, SQLITE_STATIC);
  2070     int result;
  2071 
  2072     while ((result = sqlite3_step(session->get_identities_by_address)) == SQLITE_ROW) {
  2073         //"select user_id, main_key_id, username, comm_type, lang,"
  2074         //"   identity.flags, is_own"
  2075         ident = new_identity(
  2076                 address,
  2077                 (const char *) sqlite3_column_text(session->get_identities_by_address, 1),
  2078                 (const char *) sqlite3_column_text(session->get_identities_by_address, 0),
  2079                 (const char *) sqlite3_column_text(session->get_identities_by_address, 2)
  2080                 );
  2081         assert(ident);
  2082         if (ident == NULL) {
  2083             sqlite3_reset(session->get_identities_by_address);
  2084             return PEP_OUT_OF_MEMORY;
  2085         }
  2086 
  2087         ident->comm_type = PEP_ct_unknown;
  2088         
  2089         const char* const _lang = (const char *)
  2090             sqlite3_column_text(session->get_identities_by_address, 3);
  2091         if (_lang && _lang[0]) {
  2092             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  2093             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  2094             assert(_lang[2] == 0);
  2095             ident->lang[0] = _lang[0];
  2096             ident->lang[1] = _lang[1];
  2097             ident->lang[2] = 0;
  2098         }
  2099         ident->flags = (unsigned int)
  2100             sqlite3_column_int(session->get_identities_by_address, 4);
  2101         ident->me = (unsigned int)
  2102             sqlite3_column_int(session->get_identities_by_address, 5);
  2103     
  2104         if (ident_list)
  2105             identity_list_add(ident_list, ident);
  2106         else
  2107             ident_list = new_identity_list(ident);
  2108     }
  2109 
  2110     sqlite3_reset(session->get_identities_by_address);
  2111     
  2112     *id_list = ident_list;
  2113     
  2114     if (!ident_list)
  2115         return PEP_CANNOT_FIND_IDENTITY;
  2116     
  2117     return PEP_STATUS_OK;
  2118 }
  2119 
  2120 PEP_STATUS exists_identity_entry(PEP_SESSION session, pEp_identity* identity,
  2121                                  bool* exists) {
  2122     assert(session);
  2123     assert(identity);
  2124     assert(!EMPTYSTR(identity->user_id));        
  2125     assert(!EMPTYSTR(identity->address));
  2126     if (!session || !exists || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->address))
  2127         return PEP_ILLEGAL_VALUE;
  2128     
  2129     *exists = false;
  2130     
  2131     PEP_STATUS status = PEP_STATUS_OK;
  2132     
  2133     sqlite3_reset(session->exists_identity_entry);
  2134     sqlite3_bind_text(session->exists_identity_entry, 1, identity->address, -1,
  2135                       SQLITE_STATIC);
  2136     sqlite3_bind_text(session->exists_identity_entry, 2, identity->user_id, -1,
  2137                       SQLITE_STATIC);
  2138                   
  2139     int result = sqlite3_step(session->exists_identity_entry);
  2140     switch (result) {
  2141         case SQLITE_ROW: {
  2142             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2143             *exists = (sqlite3_column_int(session->exists_identity_entry, 0) != 0);
  2144             break;
  2145         }
  2146         default: 
  2147             status = PEP_UNKNOWN_ERROR;
  2148     }
  2149 
  2150     sqlite3_reset(session->exists_identity_entry);
  2151     return status;
  2152 }
  2153 
  2154 PEP_STATUS exists_trust_entry(PEP_SESSION session, pEp_identity* identity,
  2155                               bool* exists) {
  2156     assert(session);
  2157     assert(identity);
  2158     assert(!EMPTYSTR(identity->user_id));        
  2159     assert(!EMPTYSTR(identity->fpr));
  2160     if (!session || !exists || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->fpr))
  2161         return PEP_ILLEGAL_VALUE;
  2162     
  2163     *exists = false;
  2164     
  2165     PEP_STATUS status = PEP_STATUS_OK;
  2166     
  2167     sqlite3_reset(session->exists_trust_entry);
  2168     sqlite3_bind_text(session->exists_trust_entry, 1, identity->user_id, -1,
  2169                       SQLITE_STATIC);
  2170     sqlite3_bind_text(session->exists_trust_entry, 2, identity->fpr, -1,
  2171                       SQLITE_STATIC);
  2172                   
  2173     int result = sqlite3_step(session->exists_trust_entry);
  2174     switch (result) {
  2175         case SQLITE_ROW: {
  2176             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2177             *exists = (sqlite3_column_int(session->exists_trust_entry, 0) != 0);
  2178             break;
  2179         }
  2180         default:
  2181             status = PEP_UNKNOWN_ERROR;
  2182     }
  2183     
  2184     sqlite3_reset(session->exists_trust_entry);
  2185     return status;
  2186 }
  2187 
  2188 // FIXME: We can rollback in set_identity on the return status,
  2189 // so we should probably do that.
  2190 PEP_STATUS set_pgp_keypair(PEP_SESSION session, const char* fpr) {
  2191     if (!session || EMPTYSTR(fpr))
  2192         return PEP_ILLEGAL_VALUE;
  2193         
  2194     int result;
  2195     
  2196     sqlite3_reset(session->set_pgp_keypair);
  2197     sqlite3_bind_text(session->set_pgp_keypair, 1, fpr, -1,
  2198             SQLITE_STATIC);
  2199     result = sqlite3_step(session->set_pgp_keypair);
  2200     sqlite3_reset(session->set_pgp_keypair);
  2201     if (result != SQLITE_DONE) {
  2202         return PEP_CANNOT_SET_PGP_KEYPAIR;
  2203     }
  2204     
  2205     return PEP_STATUS_OK;
  2206 }
  2207 
  2208 static PEP_STATUS _set_or_update_trust(PEP_SESSION session,
  2209                                        pEp_identity* identity,
  2210                                        sqlite3_stmt* set_or_update) {
  2211 
  2212     assert(session);
  2213     assert(identity);
  2214     assert(identity->user_id);
  2215     assert(identity->fpr);
  2216     
  2217     if (!session || !identity || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->fpr))
  2218         return PEP_ILLEGAL_VALUE;
  2219         
  2220     int result;
  2221                 
  2222     sqlite3_reset(set_or_update);
  2223     sqlite3_bind_text(set_or_update, 1, identity->user_id, -1,
  2224             SQLITE_STATIC);
  2225     sqlite3_bind_text(set_or_update, 2, identity->fpr, -1,
  2226             SQLITE_STATIC);
  2227     sqlite3_bind_int(set_or_update, 3, identity->comm_type);
  2228     result = sqlite3_step(set_or_update);
  2229     assert(result == SQLITE_DONE);
  2230     sqlite3_reset(set_or_update);
  2231     if (result != SQLITE_DONE)
  2232         return PEP_CANNOT_SET_TRUST;
  2233 
  2234     return PEP_STATUS_OK;
  2235 }
  2236 
  2237 static PEP_STATUS _set_or_update_identity_entry(PEP_SESSION session,
  2238                                                 pEp_identity* identity,
  2239                                                 sqlite3_stmt* set_or_update) {
  2240     assert(session);
  2241     assert(identity);
  2242     assert(set_or_update);
  2243                       
  2244     if (!session || !identity || !identity->user_id || !identity->address)
  2245         return PEP_ILLEGAL_VALUE;
  2246                                               
  2247     sqlite3_reset(set_or_update);
  2248     sqlite3_bind_text(set_or_update, 1, identity->address, -1,
  2249             SQLITE_STATIC);
  2250     sqlite3_bind_text(set_or_update, 2, identity->fpr, -1,
  2251             SQLITE_STATIC);
  2252     sqlite3_bind_text(set_or_update, 3, identity->user_id, -1,
  2253             SQLITE_STATIC);
  2254     sqlite3_bind_int(set_or_update, 4, identity->flags);
  2255     sqlite3_bind_int(set_or_update, 5, identity->me);
  2256     int result = sqlite3_step(set_or_update);
  2257     sqlite3_reset(set_or_update);
  2258     if (result != SQLITE_DONE)
  2259         return PEP_CANNOT_SET_IDENTITY;
  2260     
  2261     return PEP_STATUS_OK;
  2262 }
  2263 
  2264 static PEP_STATUS _set_or_update_person(PEP_SESSION session, 
  2265                                         pEp_identity* identity,
  2266                                         sqlite3_stmt* set_or_update) {
  2267     assert(session);
  2268     assert(identity);
  2269     assert(set_or_update);
  2270                         
  2271     if (!session || !identity || !identity->user_id || !identity->username)
  2272         return PEP_ILLEGAL_VALUE;
  2273         
  2274     sqlite3_reset(set_or_update);
  2275     sqlite3_bind_text(set_or_update, 1, identity->user_id, -1,
  2276             SQLITE_STATIC);
  2277     sqlite3_bind_text(set_or_update, 2, identity->username, -1,
  2278             SQLITE_STATIC);
  2279     if (identity->lang[0])
  2280         sqlite3_bind_text(set_or_update, 3, identity->lang, 2,
  2281                 SQLITE_STATIC);
  2282     else
  2283         sqlite3_bind_null(set_or_update, 3);
  2284     sqlite3_bind_text(set_or_update, 4, identity->fpr, -1,
  2285                       SQLITE_STATIC);
  2286     int result = sqlite3_step(set_or_update);
  2287     sqlite3_reset(set_or_update);
  2288     
  2289     if (result != SQLITE_DONE)
  2290         return PEP_CANNOT_SET_PERSON;
  2291     
  2292     return PEP_STATUS_OK;                                         
  2293 }
  2294 
  2295 PEP_STATUS set_or_update_with_identity(PEP_SESSION session,
  2296                                        pEp_identity* identity,
  2297                                        PEP_STATUS (* set_function)(PEP_SESSION, pEp_identity*, sqlite3_stmt*),
  2298                                        PEP_STATUS (* exists_function)(PEP_SESSION, pEp_identity*, bool*),                                       
  2299                                        sqlite3_stmt* update_query,
  2300                                        sqlite3_stmt* set_query,
  2301                                        bool guard_transaction) {
  2302 
  2303     if (guard_transaction) {
  2304         sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  2305     }
  2306     bool exists = false;
  2307     PEP_STATUS status = exists_function(session, identity, &exists);
  2308     
  2309     if (status == PEP_STATUS_OK) {
  2310         if (exists) {
  2311             status = set_function(session, identity, update_query);
  2312         }
  2313         else {
  2314             status = set_function(session, identity, set_query);                                              
  2315         }                    
  2316     }   
  2317     if (guard_transaction) {        
  2318         if (status != PEP_STATUS_OK)
  2319             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2320         else 
  2321             sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  2322     }                      
  2323     return status;
  2324 }
  2325 
  2326 PEP_STATUS _set_trust_internal(PEP_SESSION session, pEp_identity* identity,
  2327                                bool guard_transaction) {
  2328     return set_or_update_with_identity(session, identity,
  2329                                        _set_or_update_trust,
  2330                                         exists_trust_entry,
  2331                                         session->update_trust,
  2332                                         session->set_trust,
  2333                                         guard_transaction);
  2334 }
  2335 
  2336 // This is the TOP-LEVEL function. If you're calling from set_identity,
  2337 // you can't use this one.
  2338 PEP_STATUS set_trust(PEP_SESSION session, pEp_identity* identity) {
  2339     PEP_STATUS status = PEP_STATUS_OK;
  2340     
  2341     status = _set_trust_internal(session, identity, true);
  2342     if (status == PEP_STATUS_OK) {
  2343         if ((identity->comm_type | PEP_ct_confirmed) == PEP_ct_pEp)
  2344             status = set_as_pep_user(session, identity);
  2345     }
  2346     return status;
  2347 }
  2348 
  2349 PEP_STATUS set_person(PEP_SESSION session, pEp_identity* identity,
  2350                       bool guard_transaction) {
  2351     return set_or_update_with_identity(session, identity,
  2352                                        _set_or_update_person,
  2353                                        exists_person,
  2354                                        session->update_person,
  2355                                        session->set_person,
  2356                                        guard_transaction);
  2357 }
  2358 
  2359 PEP_STATUS set_identity_entry(PEP_SESSION session, pEp_identity* identity,
  2360                               bool guard_transaction) {
  2361     return set_or_update_with_identity(session, identity,
  2362                                        _set_or_update_identity_entry,
  2363                                        exists_identity_entry,
  2364                                        session->update_identity_entry,
  2365                                        session->set_identity_entry,
  2366                                        guard_transaction);
  2367 }
  2368 
  2369 // This will NOT call set_as_pep_user; you have to do that separately.
  2370 DYNAMIC_API PEP_STATUS set_identity(
  2371         PEP_SESSION session, const pEp_identity *identity
  2372     )
  2373 {
  2374     int result;
  2375 
  2376     assert(session);
  2377     assert(identity);
  2378     assert(identity->address);
  2379     assert(identity->user_id);
  2380     assert(identity->username);
  2381 
  2382     if (!(session && identity && identity->address &&
  2383                 identity->user_id && identity->username))
  2384         return PEP_ILLEGAL_VALUE;
  2385 
  2386     PEP_STATUS status = PEP_STATUS_OK;
  2387     
  2388     bool has_fpr = (!EMPTYSTR(identity->fpr));
  2389     
  2390     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  2391 
  2392     if (identity->lang[0]) {
  2393         assert(identity->lang[0] >= 'a' && identity->lang[0] <= 'z');
  2394         assert(identity->lang[1] >= 'a' && identity->lang[1] <= 'z');
  2395         assert(identity->lang[2] == 0);
  2396     }
  2397 
  2398     if (has_fpr) {
  2399         sqlite3_reset(session->set_pgp_keypair);
  2400         sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
  2401                 SQLITE_STATIC);
  2402         result = sqlite3_step(session->set_pgp_keypair);
  2403         sqlite3_reset(session->set_pgp_keypair);
  2404         if (result != SQLITE_DONE) {
  2405             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2406             return PEP_CANNOT_SET_PGP_KEYPAIR;
  2407         }
  2408     }
  2409 
  2410     // We do this because there are checks in set_person for
  2411     // aliases, which modify the identity object on return.
  2412     pEp_identity* ident_copy = identity_dup(identity); 
  2413     if (!ident_copy)
  2414         return PEP_OUT_OF_MEMORY;
  2415 
  2416     status = set_person(session, ident_copy, false);
  2417     if (status != PEP_STATUS_OK) {
  2418         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2419         goto pep_free;
  2420     }
  2421 
  2422     status = set_identity_entry(session, ident_copy, false);
  2423     if (status != PEP_STATUS_OK) {
  2424         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2425         goto pep_free;
  2426     }
  2427 
  2428     if (has_fpr) {
  2429         status = _set_trust_internal(session, ident_copy, false);
  2430         if (status != PEP_STATUS_OK) {
  2431             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2432             goto pep_free;
  2433         }
  2434     }
  2435     
  2436     result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  2437     if (result == SQLITE_OK)
  2438         status = PEP_STATUS_OK;
  2439     else
  2440         status = PEP_COMMIT_FAILED;
  2441 
  2442 pep_free:
  2443     free_identity(ident_copy);
  2444     return status;
  2445 }
  2446 
  2447 PEP_STATUS update_pep_user_trust_vals(PEP_SESSION session,
  2448                                       pEp_identity* user) {
  2449     if (!user->user_id)
  2450         return PEP_ILLEGAL_VALUE;
  2451     
  2452     sqlite3_reset(session->update_trust_to_pep);
  2453     sqlite3_bind_text(session->update_trust_to_pep, 1, user->user_id, -1,
  2454             SQLITE_STATIC);
  2455     int result = sqlite3_step(session->update_trust_to_pep);
  2456     sqlite3_reset(session->update_trust_to_pep);
  2457     if (result != SQLITE_DONE)
  2458         return PEP_CANNOT_SET_TRUST;
  2459 
  2460     return PEP_STATUS_OK;
  2461 }
  2462 
  2463 
  2464 // This ONLY sets the user flag. Must be called outside of a transaction.
  2465 PEP_STATUS set_as_pep_user(PEP_SESSION session, pEp_identity* user) {
  2466 
  2467     assert(session);
  2468     assert(user);
  2469     assert(!EMPTYSTR(user->user_id));
  2470         
  2471     if (!session || !user || EMPTYSTR(user->user_id))
  2472         return PEP_ILLEGAL_VALUE;
  2473             
  2474     PEP_STATUS status = PEP_STATUS_OK;
  2475     
  2476     bool person_exists = false;
  2477     
  2478     status = exists_person(session, user, &person_exists);
  2479     
  2480     if (status != PEP_STATUS_OK)
  2481         return status;
  2482         
  2483     if (!person_exists)
  2484         status = set_person(session, user, true);
  2485         
  2486     // Ok, let's set it.
  2487     sqlite3_reset(session->set_as_pep_user);
  2488     sqlite3_bind_text(session->set_as_pep_user, 1, user->user_id, -1,
  2489             SQLITE_STATIC);
  2490     int result = sqlite3_step(session->set_as_pep_user);
  2491     sqlite3_reset(session->set_as_pep_user);
  2492     
  2493     if (result != SQLITE_DONE)
  2494         return PEP_CANNOT_SET_PERSON;
  2495 
  2496     status = update_pep_user_trust_vals(session, user);
  2497         
  2498     return status;
  2499 }
  2500 
  2501 PEP_STATUS exists_person(PEP_SESSION session, pEp_identity* identity,
  2502                          bool* exists) {            
  2503     
  2504     // const char* user_id,
  2505     //                      char** default_id, bool* exists) {
  2506     assert(session);
  2507     assert(exists);
  2508     assert(identity);
  2509     assert(!EMPTYSTR(identity->user_id));
  2510         
  2511     if (!session || !exists || !identity || EMPTYSTR(identity->user_id))
  2512         return PEP_ILLEGAL_VALUE;
  2513     
  2514     *exists = false;
  2515 
  2516     const char* user_id = identity->user_id;
  2517     char* alias_default = NULL;
  2518     
  2519     PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
  2520     
  2521     if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
  2522         sqlite3_reset(session->exists_person);
  2523         sqlite3_bind_text(session->exists_person, 1, user_id, -1,
  2524                 SQLITE_STATIC);
  2525         int result = sqlite3_step(session->exists_person);
  2526         switch (result) {
  2527             case SQLITE_ROW: {
  2528                 // yeah yeah, I know, we could be lazy here, but it looks bad.
  2529                 *exists = (sqlite3_column_int(session->exists_person, 0) != 0);
  2530                 status = PEP_STATUS_OK;
  2531                 break;
  2532             }
  2533             default:
  2534                 sqlite3_reset(session->exists_person);
  2535                 return PEP_UNKNOWN_ERROR;
  2536         }
  2537         sqlite3_reset(session->exists_person);
  2538     }
  2539     else if (status == PEP_STATUS_OK) {
  2540         *exists = true; // thank you, delete on cascade!
  2541         // FIXME: Should we correct the userid default here? I think we should.
  2542         free(identity->user_id);
  2543         identity->user_id = alias_default; // ownership transfer
  2544     }
  2545     else
  2546         free(alias_default);
  2547             
  2548     return status;
  2549 }
  2550 
  2551 DYNAMIC_API PEP_STATUS is_pep_user(PEP_SESSION session, pEp_identity *identity, bool* is_pep)
  2552 {
  2553     assert(session);
  2554     assert(is_pep);
  2555     assert(identity);
  2556     assert(!EMPTYSTR(identity->user_id));
  2557 
  2558     if (!session || !is_pep || !identity || EMPTYSTR(identity->user_id))
  2559         return PEP_ILLEGAL_VALUE;
  2560     
  2561     *is_pep = false;
  2562             
  2563     const char* user_id = identity->user_id;
  2564     
  2565     if (!session || EMPTYSTR(user_id))
  2566         return PEP_ILLEGAL_VALUE;
  2567         
  2568     char* alias_default = NULL;
  2569     
  2570     PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
  2571     
  2572     if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
  2573         free(alias_default);
  2574         alias_default = strdup(user_id);
  2575     }
  2576     
  2577     sqlite3_reset(session->is_pep_user);
  2578     sqlite3_bind_text(session->is_pep_user, 1, user_id, -1,
  2579             SQLITE_STATIC);
  2580     int result = sqlite3_step(session->is_pep_user);
  2581     switch (result) {
  2582         case SQLITE_ROW: {
  2583             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2584             *is_pep = (sqlite3_column_int(session->is_pep_user, 0) != 0);
  2585             break;
  2586         }
  2587         default:
  2588             sqlite3_reset(session->is_pep_user);
  2589             free(alias_default);
  2590             return PEP_CANNOT_FIND_PERSON;
  2591     }
  2592 
  2593     sqlite3_reset(session->is_pep_user);
  2594     return PEP_STATUS_OK;
  2595 }
  2596 
  2597 
  2598 PEP_STATUS remove_fpr_as_default(PEP_SESSION session, 
  2599                                  const char* fpr) 
  2600 {
  2601     assert(fpr);
  2602     
  2603     if (!session || !fpr)
  2604         return PEP_ILLEGAL_VALUE;
  2605             
  2606     sqlite3_reset(session->remove_fpr_as_default);
  2607     sqlite3_bind_text(session->remove_fpr_as_default, 1, fpr, -1,
  2608                       SQLITE_STATIC);
  2609 
  2610     int result = sqlite3_step(session->remove_fpr_as_default);
  2611     sqlite3_reset(session->remove_fpr_as_default);
  2612     
  2613     if (result != SQLITE_DONE)
  2614         return PEP_CANNOT_SET_IDENTITY; // misleading - could also be person
  2615 
  2616     return PEP_STATUS_OK;
  2617 }
  2618 
  2619 
  2620 PEP_STATUS replace_identities_fpr(PEP_SESSION session, 
  2621                                  const char* old_fpr, 
  2622                                  const char* new_fpr) 
  2623 {
  2624     assert(old_fpr);
  2625     assert(new_fpr);
  2626     
  2627     if (!old_fpr || !new_fpr)
  2628         return PEP_ILLEGAL_VALUE;
  2629             
  2630     sqlite3_reset(session->replace_identities_fpr);
  2631     sqlite3_bind_text(session->replace_identities_fpr, 1, new_fpr, -1,
  2632                       SQLITE_STATIC);
  2633     sqlite3_bind_text(session->replace_identities_fpr, 2, old_fpr, -1,
  2634                       SQLITE_STATIC);
  2635 
  2636     int result = sqlite3_step(session->replace_identities_fpr);
  2637     sqlite3_reset(session->replace_identities_fpr);
  2638     
  2639     if (result != SQLITE_DONE)
  2640         return PEP_CANNOT_SET_IDENTITY;
  2641 
  2642     return PEP_STATUS_OK;
  2643 }
  2644 
  2645 PEP_STATUS update_trust_for_fpr(PEP_SESSION session, 
  2646                                 const char* fpr, 
  2647                                 PEP_comm_type comm_type)
  2648 {
  2649     if (!fpr)
  2650         return PEP_ILLEGAL_VALUE;
  2651         
  2652     sqlite3_reset(session->update_trust_for_fpr);
  2653     sqlite3_bind_int(session->update_trust_for_fpr, 1, comm_type);
  2654     sqlite3_bind_text(session->update_trust_for_fpr, 2, fpr, -1,
  2655             SQLITE_STATIC);
  2656     int result = sqlite3_step(session->update_trust_for_fpr);
  2657     sqlite3_reset(session->update_trust_for_fpr);
  2658     if (result != SQLITE_DONE) {
  2659         return PEP_CANNOT_SET_TRUST;
  2660     }
  2661     
  2662     return PEP_STATUS_OK;
  2663 }
  2664 
  2665 DYNAMIC_API PEP_STATUS set_device_group(
  2666         PEP_SESSION session,
  2667         const char *group_name
  2668     )
  2669 {
  2670     int result;
  2671 
  2672     assert(session);
  2673 
  2674     if (!(session && group_name))
  2675         return PEP_ILLEGAL_VALUE;
  2676 
  2677     // 1. Get own user_id
  2678     char* user_id = NULL;
  2679     PEP_STATUS status = get_default_own_userid(session, &user_id);
  2680     
  2681     // No user_id is returned in this case, no need to free;
  2682     if (status != PEP_STATUS_OK)
  2683         return status;
  2684         
  2685     // 2. Set device group
  2686     sqlite3_reset(session->set_device_group);
  2687     if(group_name){
  2688         sqlite3_bind_text(session->set_device_group, 1, group_name, -1,
  2689                 SQLITE_STATIC);
  2690     } else {
  2691         sqlite3_bind_null(session->set_device_group, 1);
  2692     }
  2693     
  2694     sqlite3_bind_text(session->set_device_group, 2, user_id, -1,
  2695             SQLITE_STATIC);
  2696 
  2697     result = sqlite3_step(session->set_device_group);
  2698     sqlite3_reset(session->set_device_group);
  2699     
  2700     free(user_id);
  2701     
  2702     if (result != SQLITE_DONE)
  2703         return PEP_CANNOT_SET_PERSON;
  2704 
  2705     return PEP_STATUS_OK;
  2706 }
  2707 
  2708 DYNAMIC_API PEP_STATUS get_device_group(PEP_SESSION session, char **group_name)
  2709 {
  2710     PEP_STATUS status = PEP_STATUS_OK;
  2711     int result;
  2712 
  2713     assert(session);
  2714     assert(group_name);
  2715 
  2716     if (!(session && group_name))
  2717         return PEP_ILLEGAL_VALUE;
  2718 
  2719     // 1. Get own user_id
  2720     char* user_id = NULL;
  2721     status = get_default_own_userid(session, &user_id);
  2722     
  2723     // No user_id is returned in this case, no need to free;
  2724     if (status != PEP_STATUS_OK)
  2725         return status;
  2726 
  2727     // 2. get device group
  2728     sqlite3_reset(session->get_device_group);
  2729     sqlite3_bind_text(session->get_device_group, 1, user_id, -1,
  2730             SQLITE_STATIC);
  2731 
  2732     result = sqlite3_step(session->get_device_group);
  2733     switch (result) {
  2734     case SQLITE_ROW: {
  2735         const char *_group_name = (const char *)sqlite3_column_text(session->get_device_group, 0);
  2736         if(_group_name){
  2737             *group_name = strdup(_group_name);
  2738                 if(*group_name == NULL)
  2739                     status = PEP_OUT_OF_MEMORY;
  2740         }
  2741         break;
  2742     }
  2743  
  2744     default:
  2745         status = PEP_RECORD_NOT_FOUND;
  2746     }
  2747 
  2748     free(user_id);
  2749     sqlite3_reset(session->get_device_group);
  2750     return status;
  2751 }
  2752 
  2753 DYNAMIC_API PEP_STATUS set_identity_flags(
  2754         PEP_SESSION session,
  2755         pEp_identity *identity,
  2756         unsigned int flags
  2757     )
  2758 {
  2759     int result;
  2760 
  2761     assert(session);
  2762     assert(identity);
  2763     assert(identity->address);
  2764     assert(identity->user_id);
  2765 
  2766     if (!(session && identity && identity->address && identity->user_id))
  2767         return PEP_ILLEGAL_VALUE;
  2768 
  2769     sqlite3_reset(session->set_identity_flags);
  2770     sqlite3_bind_int(session->set_identity_flags, 1, flags);
  2771     sqlite3_bind_text(session->set_identity_flags, 2, identity->address, -1,
  2772             SQLITE_STATIC);
  2773     sqlite3_bind_text(session->set_identity_flags, 3, identity->user_id, -1,
  2774         SQLITE_STATIC);
  2775         
  2776     result = sqlite3_step(session->set_identity_flags);
  2777 
  2778     sqlite3_reset(session->set_identity_flags);
  2779     if (result != SQLITE_DONE)
  2780         return PEP_CANNOT_SET_IDENTITY;
  2781 
  2782     identity->flags |= flags;
  2783     return PEP_STATUS_OK;
  2784 }
  2785 
  2786 DYNAMIC_API PEP_STATUS unset_identity_flags(
  2787         PEP_SESSION session,
  2788         pEp_identity *identity,
  2789         unsigned int flags
  2790     )
  2791 {
  2792     int result;
  2793 
  2794     assert(session);
  2795     assert(identity);
  2796     assert(identity->address);
  2797     assert(identity->user_id);
  2798 
  2799     if (!(session && identity && identity->address && identity->user_id))
  2800         return PEP_ILLEGAL_VALUE;
  2801 
  2802     sqlite3_reset(session->unset_identity_flags);
  2803     sqlite3_bind_int(session->unset_identity_flags, 1, flags);
  2804     sqlite3_bind_text(session->unset_identity_flags, 2, identity->address, -1,
  2805             SQLITE_STATIC);
  2806     sqlite3_bind_text(session->unset_identity_flags, 3, identity->user_id, -1,
  2807             SQLITE_STATIC);
  2808     result = sqlite3_step(session->unset_identity_flags);
  2809     sqlite3_reset(session->unset_identity_flags);
  2810     if (result != SQLITE_DONE)
  2811         return PEP_CANNOT_SET_IDENTITY;
  2812 
  2813     identity->flags &= ~flags;
  2814 
  2815     return PEP_STATUS_OK;
  2816 }
  2817 
  2818 
  2819 PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
  2820                               const char* new_uid) {
  2821     assert(session);
  2822     assert(old_uid);
  2823     assert(new_uid);
  2824     
  2825     if (!session || !old_uid || !new_uid)
  2826         return PEP_ILLEGAL_VALUE;
  2827 
  2828 
  2829     int result;
  2830 
  2831     sqlite3_reset(session->replace_userid);
  2832     sqlite3_bind_text(session->replace_userid, 1, new_uid, -1,
  2833             SQLITE_STATIC);
  2834     sqlite3_bind_text(session->replace_userid, 2, old_uid, -1,
  2835             SQLITE_STATIC);
  2836     result = sqlite3_step(session->replace_userid);
  2837     sqlite3_reset(session->replace_userid);
  2838     if (result != SQLITE_DONE)
  2839         return PEP_CANNOT_SET_PERSON; // May need clearer retval
  2840 
  2841     return PEP_STATUS_OK;
  2842 }
  2843 
  2844 PEP_STATUS refresh_userid_default_key(PEP_SESSION session, const char* user_id) {
  2845     assert(session);
  2846     assert(user_id);
  2847     
  2848     if (!session || !user_id)
  2849         return PEP_ILLEGAL_VALUE;
  2850 
  2851     int result;
  2852 
  2853     sqlite3_reset(session->refresh_userid_default_key);
  2854     sqlite3_bind_text(session->refresh_userid_default_key, 1, user_id, -1,
  2855             SQLITE_STATIC);
  2856     result = sqlite3_step(session->refresh_userid_default_key);
  2857     sqlite3_reset(session->refresh_userid_default_key);
  2858     if (result != SQLITE_DONE)
  2859         return PEP_CANNOT_SET_PERSON;
  2860 
  2861     return PEP_STATUS_OK;    
  2862 }
  2863 
  2864 PEP_STATUS replace_main_user_fpr(PEP_SESSION session, const char* user_id,
  2865                                  const char* new_fpr) {
  2866     assert(session);
  2867     assert(user_id);
  2868     assert(new_fpr);
  2869     
  2870     if (!session || !user_id || !new_fpr)
  2871         return PEP_ILLEGAL_VALUE;
  2872 
  2873     int result;
  2874 
  2875     sqlite3_reset(session->replace_main_user_fpr);
  2876     sqlite3_bind_text(session->replace_main_user_fpr, 1, new_fpr, -1,
  2877             SQLITE_STATIC);
  2878     sqlite3_bind_text(session->replace_main_user_fpr, 2, user_id, -1,
  2879             SQLITE_STATIC);
  2880     result = sqlite3_step(session->replace_main_user_fpr);
  2881     sqlite3_reset(session->replace_main_user_fpr);
  2882     if (result != SQLITE_DONE)
  2883         return PEP_CANNOT_SET_PERSON;
  2884 
  2885     return PEP_STATUS_OK;
  2886 }
  2887 
  2888 PEP_STATUS get_main_user_fpr(PEP_SESSION session, 
  2889                              const char* user_id,
  2890                              char** main_fpr)
  2891 {
  2892     PEP_STATUS status = PEP_STATUS_OK;
  2893     int result;
  2894     
  2895     assert(session);
  2896     assert(user_id);
  2897     assert(main_fpr);
  2898     
  2899     if (!(session && user_id && user_id[0] && main_fpr))
  2900         return PEP_ILLEGAL_VALUE;
  2901         
  2902     *main_fpr = NULL;
  2903     
  2904     sqlite3_reset(session->get_main_user_fpr);
  2905     sqlite3_bind_text(session->get_main_user_fpr, 1, user_id, -1,
  2906                       SQLITE_STATIC);
  2907     result = sqlite3_step(session->get_main_user_fpr);
  2908     switch (result) {
  2909     case SQLITE_ROW: {
  2910         const char* _fpr = 
  2911             (const char *) sqlite3_column_text(session->get_main_user_fpr, 0);
  2912         if (_fpr) {
  2913             *main_fpr = strdup(_fpr);
  2914             if (!(*main_fpr))
  2915                 status = PEP_OUT_OF_MEMORY;
  2916         }
  2917         else {
  2918             status = PEP_KEY_NOT_FOUND;
  2919         }
  2920         break;
  2921     }
  2922     default:
  2923         status = PEP_CANNOT_FIND_PERSON;
  2924     }
  2925 
  2926     sqlite3_reset(session->get_main_user_fpr);
  2927     return status;
  2928 }
  2929 
  2930 // Deprecated
  2931 DYNAMIC_API PEP_STATUS mark_as_compromized(
  2932         PEP_SESSION session,
  2933         const char *fpr
  2934     )
  2935 {
  2936     return mark_as_compromised(session, fpr);
  2937 }
  2938 
  2939 DYNAMIC_API PEP_STATUS mark_as_compromised(
  2940         PEP_SESSION session,
  2941         const char *fpr
  2942     )
  2943 {
  2944     int result;
  2945 
  2946     assert(session);
  2947     assert(fpr && fpr[0]);
  2948 
  2949     if (!(session && fpr && fpr[0]))
  2950         return PEP_ILLEGAL_VALUE;
  2951 
  2952     sqlite3_reset(session->mark_compromised);
  2953     sqlite3_bind_text(session->mark_compromised, 1, fpr, -1,
  2954             SQLITE_STATIC);
  2955     result = sqlite3_step(session->mark_compromised);
  2956     sqlite3_reset(session->mark_compromised);
  2957 
  2958     if (result != SQLITE_DONE)
  2959         return PEP_CANNOT_SET_TRUST;
  2960 
  2961     return PEP_STATUS_OK;
  2962 }
  2963 
  2964 void pEp_free(void *p)
  2965 {
  2966     free(p);
  2967 }
  2968 
  2969 
  2970 DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
  2971 {
  2972     PEP_STATUS status = PEP_STATUS_OK;
  2973     int result;
  2974 
  2975     // We need to be able to test that we break correctly without shutting
  2976     // asserts off everywhere.
  2977     // assert(session);
  2978     // assert(identity);
  2979     // assert(identity->user_id);
  2980     // assert(identity->user_id[0]);
  2981     // assert(identity->fpr);
  2982     // assert(identity->fpr[0]);
  2983 
  2984     if (!(session && identity && identity->user_id && identity->user_id[0] &&
  2985                 identity->fpr && identity->fpr[0]))
  2986         return PEP_ILLEGAL_VALUE;
  2987 
  2988     identity->comm_type = PEP_ct_unknown;
  2989 
  2990     sqlite3_reset(session->get_trust);
  2991     sqlite3_bind_text(session->get_trust, 1, identity->user_id, -1,
  2992             SQLITE_STATIC);
  2993     sqlite3_bind_text(session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
  2994 
  2995     result = sqlite3_step(session->get_trust);
  2996     switch (result) {
  2997     case SQLITE_ROW: {
  2998         int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust,
  2999                 0);
  3000         identity->comm_type = comm_type;
  3001         break;
  3002     }
  3003  
  3004     default:
  3005         status = PEP_CANNOT_FIND_IDENTITY;
  3006     }
  3007 
  3008     sqlite3_reset(session->get_trust);
  3009     return status;
  3010 }
  3011 
  3012 DYNAMIC_API PEP_STATUS least_trust(
  3013         PEP_SESSION session,
  3014         const char *fpr,
  3015         PEP_comm_type *comm_type
  3016     )
  3017 {
  3018     PEP_STATUS status = PEP_STATUS_OK;
  3019     int result;
  3020 
  3021     assert(session);
  3022     assert(fpr);
  3023     assert(comm_type);
  3024 
  3025     if (!(session && fpr && comm_type))
  3026         return PEP_ILLEGAL_VALUE;
  3027 
  3028     *comm_type = PEP_ct_unknown;
  3029 
  3030     sqlite3_reset(session->least_trust);
  3031     sqlite3_bind_text(session->least_trust, 1, fpr, -1, SQLITE_STATIC);
  3032 
  3033     result = sqlite3_step(session->least_trust);
  3034     switch (result) {
  3035         case SQLITE_ROW: {
  3036             int _comm_type = sqlite3_column_int(session->least_trust, 0);
  3037             *comm_type = (PEP_comm_type) _comm_type;
  3038             break;
  3039         }
  3040         default:
  3041             // never reached because of sql min()
  3042             status = PEP_CANNOT_FIND_IDENTITY;
  3043     }
  3044 
  3045     sqlite3_reset(session->least_trust);
  3046     return status;
  3047 }
  3048 
  3049 DYNAMIC_API PEP_STATUS decrypt_and_verify(
  3050     PEP_SESSION session, const char *ctext, size_t csize,
  3051     const char *dsigtext, size_t dsigsize,
  3052     char **ptext, size_t *psize, stringlist_t **keylist
  3053     )
  3054 {
  3055     assert(session);
  3056     assert(ctext);
  3057     assert(csize);
  3058     assert(ptext);
  3059     assert(psize);
  3060     assert(keylist);
  3061 
  3062     if (!(session && ctext && csize && ptext && psize && keylist))
  3063         return PEP_ILLEGAL_VALUE;
  3064 
  3065     return session->cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify(
  3066             session, ctext, csize, dsigtext, dsigsize, ptext, psize, keylist);
  3067 }
  3068 
  3069 DYNAMIC_API PEP_STATUS encrypt_and_sign(
  3070     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  3071     size_t psize, char **ctext, size_t *csize
  3072     )
  3073 {
  3074     assert(session);
  3075     assert(keylist);
  3076     assert(ptext);
  3077     assert(psize);
  3078     assert(ctext);
  3079     assert(csize);
  3080 
  3081     if (!(session && keylist && ptext && psize && ctext && csize))
  3082         return PEP_ILLEGAL_VALUE;
  3083 
  3084     return session->cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign(session,
  3085             keylist, ptext, psize, ctext, csize);
  3086 }
  3087 
  3088 PEP_STATUS encrypt_only(
  3089     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  3090     size_t psize, char **ctext, size_t *csize
  3091     )
  3092 {
  3093     assert(session);
  3094     assert(keylist);
  3095     assert(ptext);
  3096     assert(psize);
  3097     assert(ctext);
  3098     assert(csize);
  3099 
  3100     if (!(session && keylist && ptext && psize && ctext && csize))
  3101         return PEP_ILLEGAL_VALUE;
  3102 
  3103     return session->cryptotech[PEP_crypt_OpenPGP].encrypt_only(session,
  3104             keylist, ptext, psize, ctext, csize);
  3105 }
  3106 
  3107 
  3108 DYNAMIC_API PEP_STATUS verify_text(
  3109     PEP_SESSION session, const char *text, size_t size,
  3110     const char *signature, size_t sig_size, stringlist_t **keylist
  3111     )
  3112 {
  3113     assert(session);
  3114     assert(text);
  3115     assert(size);
  3116     assert(signature);
  3117     assert(sig_size);
  3118     assert(keylist);
  3119 
  3120     if (!(session && text && size && signature && sig_size && keylist))
  3121         return PEP_ILLEGAL_VALUE;
  3122 
  3123     return session->cryptotech[PEP_crypt_OpenPGP].verify_text(session, text,
  3124             size, signature, sig_size, keylist);
  3125 }
  3126 
  3127 DYNAMIC_API PEP_STATUS delete_keypair(PEP_SESSION session, const char *fpr)
  3128 {
  3129     assert(session);
  3130     assert(fpr);
  3131 
  3132     if (!(session && fpr))
  3133         return PEP_ILLEGAL_VALUE;
  3134 
  3135     return session->cryptotech[PEP_crypt_OpenPGP].delete_keypair(session, fpr);
  3136 }
  3137 
  3138 DYNAMIC_API PEP_STATUS export_key(
  3139         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  3140     )
  3141 {
  3142     assert(session);
  3143     assert(fpr);
  3144     assert(key_data);
  3145     assert(size);
  3146 
  3147     if (!(session && fpr && key_data && size))
  3148         return PEP_ILLEGAL_VALUE;
  3149 
  3150     return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  3151             key_data, size, false);
  3152 }
  3153 
  3154 DYNAMIC_API PEP_STATUS export_secret_key(
  3155         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  3156     )
  3157 {
  3158     assert(session);
  3159     assert(fpr);
  3160     assert(key_data);
  3161     assert(size);
  3162 
  3163     if (!(session && fpr && key_data && size))
  3164         return PEP_ILLEGAL_VALUE;
  3165 
  3166     // don't accept key IDs but full fingerprints only
  3167     if (strlen(fpr) < 16)
  3168         return PEP_ILLEGAL_VALUE;
  3169 
  3170     return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  3171             key_data, size, true);
  3172 }
  3173 
  3174 // Deprecated
  3175 DYNAMIC_API PEP_STATUS export_secrect_key(
  3176         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  3177     )
  3178 {
  3179     return export_secret_key(session, fpr, key_data, size);
  3180 }
  3181 
  3182 DYNAMIC_API PEP_STATUS find_keys(
  3183         PEP_SESSION session, const char *pattern, stringlist_t **keylist
  3184     )
  3185 {
  3186     assert(session);
  3187     assert(pattern);
  3188     assert(keylist);
  3189 
  3190     if (!(session && pattern && keylist))
  3191         return PEP_ILLEGAL_VALUE;
  3192 
  3193     return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern,
  3194             keylist);
  3195 }
  3196 
  3197 
  3198 DYNAMIC_API PEP_STATUS generate_keypair(
  3199         PEP_SESSION session, pEp_identity *identity
  3200     )
  3201 {
  3202     assert(session);
  3203     assert(identity);
  3204     assert(identity->address);
  3205     assert(identity->fpr == NULL || identity->fpr[0] == 0);
  3206     assert(identity->username);
  3207 
  3208     if (!(session && identity && identity->address &&
  3209             (identity->fpr == NULL || identity->fpr[0] == 0) &&
  3210             identity->username))
  3211         return PEP_ILLEGAL_VALUE;
  3212 
  3213     PEP_STATUS status =
  3214         session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session,
  3215                 identity);
  3216     if (status != PEP_STATUS_OK)
  3217         return status;
  3218 
  3219     if (identity->fpr)
  3220         status = set_pgp_keypair(session, identity->fpr);
  3221 
  3222     // add to known keypair DB, as this might not end up being a default
  3223     return status;
  3224 }
  3225 
  3226 DYNAMIC_API PEP_STATUS get_key_rating(
  3227         PEP_SESSION session,
  3228         const char *fpr,
  3229         PEP_comm_type *comm_type
  3230     )
  3231 {
  3232     assert(session);
  3233     assert(fpr);
  3234     assert(comm_type);
  3235 
  3236     if (!(session && fpr && comm_type))
  3237         return PEP_ILLEGAL_VALUE;
  3238 
  3239     return session->cryptotech[PEP_crypt_OpenPGP].get_key_rating(session, fpr,
  3240             comm_type);
  3241 }
  3242 
  3243 DYNAMIC_API PEP_STATUS import_key(
  3244         PEP_SESSION session,
  3245         const char *key_data,
  3246         size_t size,
  3247         identity_list **private_keys
  3248     )
  3249 {
  3250     assert(session);
  3251     assert(key_data);
  3252 
  3253     if (!(session && key_data))
  3254         return PEP_ILLEGAL_VALUE;
  3255 
  3256     return session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data,
  3257             size, private_keys);
  3258 }
  3259 
  3260 DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
  3261 {
  3262     assert(session);
  3263     assert(pattern);
  3264 
  3265     if (!(session && pattern))
  3266         return PEP_ILLEGAL_VALUE;
  3267 
  3268     return session->cryptotech[PEP_crypt_OpenPGP].recv_key(session, pattern);
  3269 }
  3270 
  3271 DYNAMIC_API PEP_STATUS send_key(PEP_SESSION session, const char *pattern)
  3272 {
  3273     assert(session);
  3274     assert(pattern);
  3275 
  3276     if (!(session && pattern))
  3277         return PEP_ILLEGAL_VALUE;
  3278 
  3279     return session->cryptotech[PEP_crypt_OpenPGP].send_key(session, pattern);
  3280 }
  3281 
  3282 DYNAMIC_API PEP_STATUS renew_key(
  3283         PEP_SESSION session,
  3284         const char *fpr,
  3285         const timestamp *ts
  3286     )
  3287 {
  3288     assert(session);
  3289     assert(fpr);
  3290 
  3291     if (!(session && fpr))
  3292         return PEP_ILLEGAL_VALUE;
  3293 
  3294     return session->cryptotech[PEP_crypt_OpenPGP].renew_key(session, fpr, ts);
  3295 }
  3296 
  3297 DYNAMIC_API PEP_STATUS revoke_key(
  3298         PEP_SESSION session,
  3299         const char *fpr,
  3300         const char *reason
  3301     )
  3302 {
  3303     assert(session);
  3304     assert(fpr);
  3305 
  3306     if (!(session && fpr))
  3307         return PEP_ILLEGAL_VALUE;
  3308 
  3309     return session->cryptotech[PEP_crypt_OpenPGP].revoke_key(session, fpr,
  3310             reason);
  3311 }
  3312 
  3313 DYNAMIC_API PEP_STATUS key_expired(
  3314         PEP_SESSION session,
  3315         const char *fpr,
  3316         const time_t when,
  3317         bool *expired
  3318     )
  3319 {
  3320     assert(session);
  3321     assert(fpr);
  3322     assert(expired);
  3323 
  3324     if (!(session && fpr && expired))
  3325         return PEP_ILLEGAL_VALUE;
  3326 
  3327     return session->cryptotech[PEP_crypt_OpenPGP].key_expired(session, fpr,
  3328             when, expired);
  3329 }
  3330 
  3331 DYNAMIC_API PEP_STATUS key_revoked(
  3332        PEP_SESSION session,
  3333        const char *fpr,
  3334        bool *revoked
  3335    )
  3336 {
  3337     assert(session);
  3338     assert(fpr);
  3339     assert(revoked);
  3340     
  3341     if (!(session && fpr && revoked))
  3342         return PEP_ILLEGAL_VALUE;
  3343     
  3344     return session->cryptotech[PEP_crypt_OpenPGP].key_revoked(session, fpr,
  3345             revoked);
  3346 }
  3347 
  3348 static void _clean_log_value(char *text)
  3349 {
  3350     if (text) {
  3351         for (char *c = text; *c; c++) {
  3352             if (*c < 32 && *c != '\n')
  3353                 *c = 32;
  3354             else if (*c == '"')
  3355                 *c = '\'';
  3356         }
  3357     }
  3358 }
  3359 
  3360 static char *_concat_string(char *str1, const char *str2, char delim)
  3361 {
  3362     str2 = str2 ? str2 : "";
  3363     size_t len1 = str1 ? strlen(str1) : 0;
  3364     size_t len2 = strlen(str2);
  3365     size_t len = len1 + len2 + 3;
  3366     char * result = realloc(str1, len + 1);
  3367 
  3368     if (result) {
  3369         result[len1] = '"';
  3370         strcpy(result + len1 + 1, str2);
  3371         result[len - 2] = '"';
  3372         result[len - 1] = delim;
  3373         result[len] = 0;
  3374     }
  3375     else {
  3376         free(str1);
  3377     }
  3378 
  3379     return result;
  3380 }
  3381 
  3382 DYNAMIC_API PEP_STATUS get_crashdump_log(
  3383         PEP_SESSION session,
  3384         int maxlines,
  3385         char **logdata
  3386     )
  3387 {
  3388     PEP_STATUS status = PEP_STATUS_OK;
  3389     char *_logdata= NULL;
  3390 
  3391     assert(session);
  3392     assert(maxlines >= 0 && maxlines <= CRASHDUMP_MAX_LINES);
  3393     assert(logdata);
  3394 
  3395     if (!(session && logdata && maxlines >= 0 && maxlines <=
  3396             CRASHDUMP_MAX_LINES))
  3397         return PEP_ILLEGAL_VALUE;
  3398 
  3399     *logdata = NULL;
  3400 
  3401     int limit = maxlines ? maxlines : CRASHDUMP_DEFAULT_LINES;
  3402     const char *timestamp = NULL;
  3403     const char *title = NULL;
  3404     const char *entity = NULL;
  3405     const char *desc = NULL;
  3406     const char *comment = NULL;
  3407 
  3408     sqlite3_reset(session->crashdump);
  3409     sqlite3_bind_int(session->crashdump, 1, limit);
  3410 
  3411     int result;
  3412 
  3413     do {
  3414         result = sqlite3_step(session->crashdump);
  3415         switch (result) {
  3416         case SQLITE_ROW:
  3417             timestamp = (const char *) sqlite3_column_text(session->crashdump,
  3418                     0);
  3419             title   = (const char *) sqlite3_column_text(session->crashdump,
  3420                     1);
  3421             entity  = (const char *) sqlite3_column_text(session->crashdump,
  3422                     2);
  3423             desc    = (const char *) sqlite3_column_text(session->crashdump,
  3424                     3);
  3425             comment = (const char *) sqlite3_column_text(session->crashdump,
  3426                     4);
  3427 
  3428             _logdata = _concat_string(_logdata, timestamp, ',');
  3429             if (_logdata == NULL)
  3430                 goto enomem;
  3431 
  3432             _logdata = _concat_string(_logdata, title, ',');
  3433             if (_logdata == NULL)
  3434                 goto enomem;
  3435 
  3436             _logdata = _concat_string(_logdata, entity, ',');
  3437             if (_logdata == NULL)
  3438                 goto enomem;
  3439 
  3440             _logdata = _concat_string(_logdata, desc, ',');
  3441             if (_logdata == NULL)
  3442                 goto enomem;
  3443 
  3444             _logdata = _concat_string(_logdata, comment, '\n');
  3445             if (_logdata == NULL)
  3446                 goto enomem;
  3447 
  3448             _clean_log_value(_logdata);
  3449             break;
  3450 
  3451         case SQLITE_DONE:
  3452             break;
  3453 
  3454         default:
  3455             status = PEP_UNKNOWN_ERROR;
  3456             result = SQLITE_DONE;
  3457         }
  3458     } while (result != SQLITE_DONE);
  3459 
  3460     sqlite3_reset(session->crashdump);
  3461     if (status == PEP_STATUS_OK) {
  3462         if (_logdata) {
  3463             *logdata = _logdata;
  3464         }
  3465         else {
  3466             *logdata = strdup("");
  3467             if (!*logdata)
  3468                 goto enomem;
  3469         }
  3470     }
  3471 
  3472     goto the_end;
  3473 
  3474 enomem:
  3475     status = PEP_OUT_OF_MEMORY;
  3476 
  3477 the_end:
  3478     return status;
  3479 }
  3480 
  3481 DYNAMIC_API PEP_STATUS get_languagelist(
  3482         PEP_SESSION session,
  3483         char **languages
  3484     )
  3485 {
  3486     PEP_STATUS status = PEP_STATUS_OK;
  3487     char *_languages= NULL;
  3488 
  3489     assert(session);
  3490     assert(languages);
  3491 
  3492     if (!(session && languages))
  3493         return PEP_ILLEGAL_VALUE;
  3494 
  3495     *languages = NULL;
  3496 
  3497     const char *lang = NULL;
  3498     const char *name = NULL;
  3499     const char *phrase = NULL;
  3500 
  3501     sqlite3_reset(session->languagelist);
  3502 
  3503     int result;
  3504 
  3505     do {
  3506         result = sqlite3_step(session->languagelist);
  3507         switch (result) {
  3508         case SQLITE_ROW:
  3509             lang = (const char *) sqlite3_column_text(session->languagelist,
  3510                     0);
  3511             name = (const char *) sqlite3_column_text(session->languagelist,
  3512                     1);
  3513             phrase = (const char *) sqlite3_column_text(session->languagelist,
  3514                     2);
  3515 
  3516             _languages = _concat_string(_languages, lang, ',');
  3517             if (_languages == NULL)
  3518                 goto enomem;
  3519 
  3520             _languages = _concat_string(_languages, name, ',');
  3521             if (_languages == NULL)
  3522                 goto enomem;
  3523 
  3524             _languages = _concat_string(_languages, phrase, '\n');
  3525             if (_languages == NULL)
  3526                 goto enomem;
  3527 
  3528             break;
  3529 
  3530         case SQLITE_DONE:
  3531             break;
  3532 
  3533         default:
  3534             status = PEP_UNKNOWN_ERROR;
  3535             result = SQLITE_DONE;
  3536         }
  3537     } while (result != SQLITE_DONE);
  3538 
  3539     sqlite3_reset(session->languagelist);
  3540     if (status == PEP_STATUS_OK)
  3541         *languages = _languages;
  3542 
  3543     goto the_end;
  3544 
  3545 enomem:
  3546     status = PEP_OUT_OF_MEMORY;
  3547 
  3548 the_end:
  3549     return status;
  3550 }
  3551 
  3552 DYNAMIC_API PEP_STATUS get_phrase(
  3553         PEP_SESSION session,
  3554         const char *lang,
  3555         int phrase_id,
  3556         char **phrase
  3557     )
  3558 {
  3559     PEP_STATUS status = PEP_STATUS_OK;
  3560 
  3561     assert(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase);
  3562     if (!(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase))
  3563         return PEP_ILLEGAL_VALUE;
  3564 
  3565     *phrase = NULL;
  3566 
  3567     sqlite3_reset(session->i18n_token);
  3568     sqlite3_bind_text(session->i18n_token, 1, lang, -1, SQLITE_STATIC);
  3569     sqlite3_bind_int(session->i18n_token, 2, phrase_id);
  3570 
  3571     const char *_phrase = NULL;
  3572     int result;
  3573 
  3574     result = sqlite3_step(session->i18n_token);
  3575     switch (result) {
  3576     case SQLITE_ROW:
  3577         _phrase = (const char *) sqlite3_column_text(session->i18n_token, 0);
  3578         break;
  3579 
  3580     case SQLITE_DONE:
  3581         status = PEP_PHRASE_NOT_FOUND;
  3582         break;
  3583 
  3584     default:
  3585         status = PEP_UNKNOWN_ERROR;
  3586     }
  3587 
  3588     if (status == PEP_STATUS_OK) {
  3589         *phrase = strdup(_phrase);
  3590         if (*phrase == NULL)
  3591             goto enomem;
  3592     }
  3593 
  3594     sqlite3_reset(session->i18n_token);
  3595     goto the_end;
  3596 
  3597 enomem:
  3598     status = PEP_OUT_OF_MEMORY;
  3599 
  3600 the_end:
  3601     return status;
  3602 }
  3603 
  3604 static PEP_STATUS _get_sequence_value(PEP_SESSION session, const char *name,
  3605         int32_t *value)
  3606 {
  3607     assert(session && name && value);
  3608     if (!(session && name && value))
  3609         return PEP_ILLEGAL_VALUE;
  3610 
  3611     PEP_STATUS status = PEP_STATUS_OK;
  3612 
  3613     sqlite3_reset(session->sequence_value2);
  3614     sqlite3_bind_text(session->sequence_value2, 1, name, -1,
  3615             SQLITE_STATIC);
  3616     int result = sqlite3_step(session->sequence_value2);
  3617     switch (result) {
  3618         case SQLITE_ROW: {
  3619             int32_t _value = (int32_t)
  3620                     sqlite3_column_int(session->sequence_value2, 0);
  3621             int _own = (int)
  3622                     sqlite3_column_int(session->sequence_value2, 1);
  3623             *value = _value;
  3624             if (_own)
  3625                 status = PEP_OWN_SEQUENCE;
  3626             break;
  3627         }
  3628         case SQLITE_DONE:
  3629             status = PEP_RECORD_NOT_FOUND;
  3630             break;
  3631         default:
  3632             status = PEP_UNKNOWN_ERROR;
  3633     }
  3634     sqlite3_reset(session->sequence_value2);
  3635 
  3636     return status;
  3637 }
  3638 
  3639 static PEP_STATUS _increment_sequence_value(PEP_SESSION session,
  3640         const char *name, int own)
  3641 {
  3642     assert(session && name);
  3643     if (!(session && name))
  3644         return PEP_ILLEGAL_VALUE;
  3645 
  3646     sqlite3_reset(session->sequence_value1);
  3647     sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
  3648     sqlite3_bind_int(session->sequence_value1, 2, own);
  3649     int result = sqlite3_step(session->sequence_value1);
  3650     assert(result == SQLITE_DONE);
  3651     sqlite3_reset(session->sequence_value1);
  3652     if (result == SQLITE_DONE)
  3653         return PEP_STATUS_OK;
  3654     else
  3655         return PEP_CANNOT_INCREASE_SEQUENCE;
  3656 }
  3657 
  3658 static PEP_STATUS _set_sequence_value(PEP_SESSION session,
  3659         const char *name, int32_t value, int own)
  3660 {
  3661     assert(session && name && value > 0);
  3662     if (!(session && name && value > 0))
  3663         return PEP_ILLEGAL_VALUE;
  3664 
  3665     sqlite3_reset(session->sequence_value3);
  3666     sqlite3_bind_text(session->sequence_value3, 1, name, -1, SQLITE_STATIC);
  3667     sqlite3_bind_int(session->sequence_value3, 2, value);
  3668     sqlite3_bind_int(session->sequence_value3, 3, own);
  3669     int result = sqlite3_step(session->sequence_value3);
  3670     assert(result == SQLITE_DONE);
  3671     sqlite3_reset(session->sequence_value3);
  3672     if (result == SQLITE_DONE)
  3673         return PEP_STATUS_OK;
  3674     else
  3675         return PEP_CANNOT_SET_SEQUENCE_VALUE;
  3676 }
  3677 
  3678 DYNAMIC_API PEP_STATUS sequence_value(
  3679         PEP_SESSION session,
  3680         char *name,
  3681         int32_t *value
  3682     )
  3683 {
  3684     PEP_STATUS status = PEP_STATUS_OK;
  3685     int result;
  3686 
  3687     assert(session);
  3688     assert(name && value && *value >= 0);
  3689 
  3690     if (!(session && name && value && *value >= 0))
  3691         return PEP_ILLEGAL_VALUE;
  3692 
  3693     int own = 0;
  3694     if (!name[0]) {
  3695         pEpUUID uuid;
  3696         uuid_generate_random(uuid);
  3697         uuid_unparse_upper(uuid, name);
  3698         own = 1;
  3699     }
  3700     else {
  3701         if (name == session->sync_session->sync_uuid || 
  3702             strcmp(name, session->sync_session->sync_uuid) == 0)
  3703             own = 1;
  3704     }
  3705 
  3706     if (*value) {
  3707         sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  3708         int32_t old_value = 0;
  3709         status = _get_sequence_value(session, name, &old_value);
  3710         if (status != PEP_STATUS_OK && status != PEP_RECORD_NOT_FOUND)
  3711         {
  3712             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3713             return status;
  3714         }
  3715 
  3716         if (old_value >= *value) {
  3717             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3718             return PEP_SEQUENCE_VIOLATED;
  3719         }
  3720         else {
  3721             status = _set_sequence_value(session, name, *value, own);
  3722             if (status == PEP_STATUS_OK) {
  3723                 result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  3724                 if (result == SQLITE_OK)
  3725                     return PEP_STATUS_OK;
  3726                 else
  3727                     return PEP_COMMIT_FAILED;
  3728             } else {
  3729                 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3730                 return status;
  3731             }
  3732         }
  3733     }
  3734 
  3735     assert(*value == 0);
  3736     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  3737     status = _increment_sequence_value(session, name, own);
  3738     if (status == PEP_STATUS_OK) {
  3739         status = _get_sequence_value(session, name, value);
  3740     }
  3741     if (status == PEP_STATUS_OK || status == PEP_OWN_SEQUENCE) {
  3742         result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  3743         if (result == SQLITE_OK){
  3744             assert(*value < INT32_MAX);
  3745             if (*value == INT32_MAX){
  3746                 return PEP_CANNOT_INCREASE_SEQUENCE;
  3747             }
  3748             return status;
  3749         } else {
  3750             return PEP_COMMIT_FAILED;
  3751         }
  3752     } else {
  3753         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3754         return status;
  3755     }
  3756     return status;
  3757 }
  3758 
  3759 DYNAMIC_API PEP_STATUS set_revoked(
  3760        PEP_SESSION session,
  3761        const char *revoked_fpr,
  3762        const char *replacement_fpr,
  3763        const uint64_t revocation_date
  3764     )
  3765 {
  3766     PEP_STATUS status = PEP_STATUS_OK;
  3767     
  3768     assert(session &&
  3769            revoked_fpr && revoked_fpr[0] &&
  3770            replacement_fpr && replacement_fpr[0]
  3771           );
  3772     
  3773     if (!(session &&
  3774           revoked_fpr && revoked_fpr[0] &&
  3775           replacement_fpr && replacement_fpr[0]
  3776          ))
  3777         return PEP_ILLEGAL_VALUE;
  3778     
  3779     sqlite3_reset(session->set_revoked);
  3780     sqlite3_bind_text(session->set_revoked, 1, revoked_fpr, -1, SQLITE_STATIC);
  3781     sqlite3_bind_text(session->set_revoked, 2, replacement_fpr, -1,
  3782             SQLITE_STATIC);
  3783     sqlite3_bind_int64(session->set_revoked, 3, revocation_date);
  3784 
  3785     int result;
  3786     
  3787     result = sqlite3_step(session->set_revoked);
  3788     switch (result) {
  3789         case SQLITE_DONE:
  3790             status = PEP_STATUS_OK;
  3791             break;
  3792             
  3793         default:
  3794             status = PEP_UNKNOWN_ERROR;
  3795     }
  3796     
  3797     sqlite3_reset(session->set_revoked);
  3798     return status;
  3799 }
  3800 
  3801 DYNAMIC_API PEP_STATUS get_revoked(
  3802         PEP_SESSION session,
  3803         const char *fpr,
  3804         char **revoked_fpr,
  3805         uint64_t *revocation_date
  3806     )
  3807 {
  3808     PEP_STATUS status = PEP_STATUS_OK;
  3809 
  3810     assert(session &&
  3811            revoked_fpr &&
  3812            fpr && fpr[0]
  3813           );
  3814     
  3815     if (!(session &&
  3816            revoked_fpr &&
  3817            fpr && fpr[0]
  3818           ))
  3819         return PEP_ILLEGAL_VALUE;
  3820 
  3821     *revoked_fpr = NULL;
  3822     *revocation_date = 0;
  3823 
  3824     sqlite3_reset(session->get_revoked);
  3825     sqlite3_bind_text(session->get_revoked, 1, fpr, -1, SQLITE_STATIC);
  3826 
  3827     int result;
  3828     
  3829     result = sqlite3_step(session->get_revoked);
  3830     switch (result) {
  3831         case SQLITE_ROW: {
  3832             *revoked_fpr = strdup((const char *)
  3833                     sqlite3_column_text(session->get_revoked, 0));
  3834             if(*revoked_fpr)
  3835                 *revocation_date = sqlite3_column_int64(session->get_revoked,
  3836                         1);
  3837             else
  3838                 status = PEP_OUT_OF_MEMORY;
  3839 
  3840             break;
  3841         }
  3842         default:
  3843             status = PEP_CANNOT_FIND_IDENTITY;
  3844     }
  3845 
  3846     sqlite3_reset(session->get_revoked);
  3847 
  3848     return status;
  3849 }
  3850 
  3851 PEP_STATUS key_created(
  3852         PEP_SESSION session,
  3853         const char *fpr,
  3854         time_t *created
  3855     )
  3856 {
  3857     assert(session && fpr && created);
  3858     if (!(session && fpr && created))
  3859         return PEP_ILLEGAL_VALUE;
  3860 
  3861     return session->cryptotech[PEP_crypt_OpenPGP].key_created(session, fpr,
  3862             created);
  3863 }
  3864 
  3865 PEP_STATUS find_private_keys(PEP_SESSION session, const char* pattern,
  3866                              stringlist_t **keylist) {
  3867     assert(session && keylist);
  3868     if (!(session && keylist))
  3869         return PEP_ILLEGAL_VALUE;
  3870     
  3871     return session->cryptotech[PEP_crypt_OpenPGP].find_private_keys(session, pattern,
  3872                                                                     keylist);
  3873 }
  3874 
  3875 DYNAMIC_API const char* get_engine_version() {
  3876     return PEP_ENGINE_VERSION;
  3877 }
  3878 
  3879 
  3880 DYNAMIC_API PEP_STATUS reset_peptest_hack(PEP_SESSION session)
  3881 {
  3882     assert(session);
  3883 
  3884     if (!session)
  3885         return PEP_ILLEGAL_VALUE;
  3886 
  3887     int int_result = sqlite3_exec(
  3888         session->db,
  3889         "delete from identity where address like '%@peptest.ch' ;",
  3890         NULL,
  3891         NULL,
  3892         NULL
  3893     );
  3894     assert(int_result == SQLITE_OK);
  3895 
  3896     if (int_result != SQLITE_OK)
  3897         return PEP_UNKNOWN_ERROR;
  3898 
  3899     return PEP_STATUS_OK;
  3900 }
  3901 
  3902 #ifdef DEBUG_ERRORSTACK
  3903 PEP_STATUS session_add_error(PEP_SESSION session, const char* file, unsigned line, PEP_STATUS status)
  3904 {
  3905     char logline[48];
  3906     if(status>0)
  3907     {
  3908         snprintf(logline,47, "%.24s:%u status=%u (0x%x)", file, line, status, status);
  3909     }else{
  3910         snprintf(logline,47, "%.24s:%u status=%i.", file, line, status);
  3911     }
  3912     stringlist_add(session->errorstack, logline); // logline is copied! :-)
  3913     return status;
  3914 }
  3915 
  3916 DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  3917 {
  3918     return session->errorstack;
  3919 }
  3920 
  3921 DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  3922 {
  3923     const int old_len = stringlist_length(session->errorstack);
  3924     char buf[48];
  3925     free_stringlist(session->errorstack);
  3926     snprintf(buf, 47, "(%i elements cleared)", old_len);
  3927     session->errorstack = new_stringlist(buf);
  3928 }
  3929 
  3930 #else
  3931 
  3932 static stringlist_t* dummy_errorstack = NULL;
  3933 
  3934 DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  3935 {
  3936     if(dummy_errorstack == NULL)
  3937     {
  3938         dummy_errorstack = new_stringlist("( Please recompile pEpEngine with -DDEBUG_ERRORSTACK )");
  3939     }
  3940 
  3941     return dummy_errorstack;
  3942 }
  3943 
  3944 DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  3945 {
  3946     // nothing to do here
  3947 }
  3948 
  3949 #endif