src/pEpEngine.c
author Krista 'DarthMama' Bennett <krista@pep.foundation>
Fri, 17 May 2019 17:05:47 +0200
branchENGINE-559
changeset 3727 d926613299bf
parent 3699 e2aa6fdbd20b
child 3728 3e8c536a1634
permissions -rw-r--r--
ENGINE-559: modified DDL version to 12, added pep_version column to identity (and put in the upgrade code)
     1 // This file is under GNU General Public License 3.0
     2 // see LICENSE.txt
     3 
     4 #include "pEp_internal.h"
     5 #include "dynamic_api.h"
     6 #include "cryptotech.h"
     7 #include "transport.h"
     8 #include "blacklist.h"
     9 #include "KeySync_fsm.h"
    10 
    11 #include <time.h>
    12 #include <stdlib.h>
    13 
    14 #define _PEP_SQLITE_DEBUG 0
    15 #if _PEP_SQLITE_DEBUG
    16 #include <sqlite3.h>
    17 #endif
    18 
    19 static volatile int init_count = -1;
    20 
    21 // sql overloaded functions - modified from sqlite3.c
    22 static void _sql_lower(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
    23     const char *z2;
    24     int 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         char *z1 = (char*)sqlite3_malloc(n+1);
    31         if( z1 ){
    32             for(int 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 // FIXME?: problems if we don't have a key for the user - we get nothing
    83 static const char *sql_get_identity =  
    84     "select fpr, username, comm_type, lang,"
    85     "   identity.flags | pgp_keypair.flags,"
    86     "   is_own"
    87     "   from identity"
    88     "   join person on id = identity.user_id"
    89     "   join pgp_keypair on fpr = identity.main_key_id"
    90     "   join trust on id = trust.user_id"
    91     "       and pgp_keypair_fpr = identity.main_key_id"    
    92     "   where (case when (address = ?1) then (1)"
    93     "               when (lower(address) = lower(?1)) then (1)"
    94     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
    95     "               else 0"
    96     "          end) = 1"
    97     "   and identity.user_id = ?2" 
    98     "   order by is_own desc, "
    99     "   timestamp desc; ";
   100 
   101 static const char *sql_get_identities_by_main_key_id =  
   102     "select address, identity.user_id, username, comm_type, lang,"
   103     "   identity.flags | pgp_keypair.flags,"
   104     "   is_own"
   105     "   from identity"
   106     "   join person on id = identity.user_id"
   107     "   join pgp_keypair on fpr = identity.main_key_id"
   108     "   join trust on id = trust.user_id"
   109     "       and pgp_keypair_fpr = identity.main_key_id"    
   110     "   where identity.main_key_id = ?1" 
   111     "   order by is_own desc, "
   112     "   timestamp desc; ";
   113 
   114 static const char *sql_get_identity_without_trust_check =  
   115     "select 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     "   and identity.user_id = ?2 "
   125     "   order by is_own desc, "
   126     "   timestamp desc; ";
   127 
   128 static const char *sql_get_identities_by_address =  
   129     "select user_id, identity.main_key_id, username, lang,"
   130     "   identity.flags, is_own"
   131     "   from identity"
   132     "   join person on id = identity.user_id"
   133     "   where (case when (address = ?1) then (1)"
   134     "               when (lower(address) = lower(?1)) then (1)"
   135     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   136     "               else 0"
   137     "          end) = 1 "
   138     "   order by is_own desc, "
   139     "   timestamp desc; ";
   140     
   141 static const char *sql_get_identities_by_userid =  
   142     "select address, fpr, username, comm_type, lang,"
   143     "   identity.flags | pgp_keypair.flags,"
   144     "   is_own"
   145     "   from identity"
   146     "   join person on id = identity.user_id"
   147     "   join pgp_keypair on fpr = identity.main_key_id"
   148     "   join trust on id = trust.user_id"
   149     "       and pgp_keypair_fpr = identity.main_key_id"    
   150     "   where identity.user_id = ?1" 
   151     "   order by is_own desc, "
   152     "   timestamp desc; ";
   153 
   154 static const char *sql_replace_identities_fpr =  
   155     "update identity"
   156     "   set main_key_id = ?1 "
   157     "   where main_key_id = ?2 ;";
   158     
   159 static const char *sql_remove_fpr_as_default =
   160     "update person set main_key_id = NULL where main_key_id = ?1 ;"
   161     "update identity set main_key_id = NULL where main_key_id = ?1 ;";
   162 
   163 // Set person, but if already exist, only update.
   164 // if main_key_id already set, don't touch.
   165 static const char *sql_set_person = 
   166      "insert into person (id, username, lang, main_key_id)"
   167      "  values (?1, ?2, ?3, ?4) ;";
   168 
   169 static const char *sql_update_person = 
   170     "update person "
   171     "   set username = ?2, "
   172     "       lang = ?3, "
   173     "       main_key_id =  "
   174     "           (select coalesce( "
   175     "               (select main_key_id from person where id = ?1), " 
   176     "                upper(replace(?4,' ',''))))"         
   177     "   where id = ?1 ;";
   178 
   179 // Will cascade.
   180 static const char *sql_delete_person = 
   181      "delete from person where id = ?1 ;";
   182 
   183 static const char *sql_set_as_pEp_user =
   184     "update person set is_pEp_user = 1 "
   185     "   where id = ?1 ; ";
   186 
   187 static const char *sql_is_pEp_user =
   188     "select is_pEp_user from person "
   189     "   where id = ?1 ; ";
   190 
   191 static const char* sql_exists_person = 
   192     "select count(*) from person "
   193     "   where id = ?1 ;";
   194 
   195 // This will cascade to identity and trust
   196 static const char* sql_replace_userid =
   197     "update person set id = ?1 " 
   198     "   where id = ?2;";
   199 
   200 // Hopefully this cascades and removes trust entries...
   201 static const char *sql_delete_key =
   202     "delete from pgp_keypair "
   203     "   where fpr = ?1 ; ";
   204 
   205 static const char *sql_replace_main_user_fpr =  
   206     "update person "
   207     "   set main_key_id = ?1 "
   208     "   where id = ?2 ;";
   209 
   210 static const char *sql_get_main_user_fpr =  
   211     "select main_key_id from person"
   212     "   where id = ?1 ;";
   213 
   214 static const char *sql_refresh_userid_default_key =
   215     "update person "
   216     "   set main_key_id = "
   217     "       (select identity.main_key_id from identity "
   218     "           join trust on trust.user_id = identity.user_id "
   219     "               and trust.pgp_keypair_fpr = identity.main_key_id "
   220     "           join person on identity.user_id = identity.user_id "
   221     "       where identity.user_id = ?1 "
   222     "       order by trust.comm_type desc "
   223     "       limit 1) "
   224     "where id = ?1 ; ";
   225 
   226 static const char *sql_set_pgp_keypair = 
   227     "insert or ignore into pgp_keypair (fpr) "
   228     "values (upper(replace(?1,' ',''))) ;";
   229 
   230 static const char* sql_exists_identity_entry = 
   231     "select count(*) from identity "
   232     "   where (case when (address = ?1) then (1)"
   233     "               when (lower(address) = lower(?1)) then (1)"
   234     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   235     "               else 0"
   236     "          end) = 1"
   237     "    and user_id = ?2;";
   238  
   239 static const char *sql_set_identity_entry = 
   240     "insert into identity ("
   241     "       address, main_key_id, "
   242     "       user_id, flags, is_own"
   243     "   ) values ("
   244     "       ?1,"
   245     "       upper(replace(?2,' ','')),"
   246     "       ?3,"
   247     "       ?4,"
   248     "       ?5"
   249     "   );";
   250     
   251 static const char* sql_update_identity_entry =    
   252     "update identity "
   253     "   set main_key_id = upper(replace(?2,' ','')), "
   254     "       flags = ?4, " 
   255     "       is_own = ?5 "
   256     "   where (case when (address = ?1) then (1)"
   257     "               when (lower(address) = lower(?1)) then (1)"
   258     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1) "
   259     "               else 0 "
   260     "          end) = 1 "
   261     "          and user_id = ?3 ;";
   262 
   263     // " (select"
   264     // "   coalesce("
   265     // "    (select flags from identity"
   266     // "     where address = ?1 and"
   267     // "           user_id = ?3),"
   268     // "    0)"
   269     // " ) | (?4 & 255)"
   270     /* set_identity ignores previous flags, and doesn't filter machine flags */
   271         
   272 static const char *sql_set_identity_flags = 
   273     "update identity set flags = "
   274     "    ((?1 & 65535) | (select flags from identity"
   275     "                    where (case when (address = ?2) then (1)"
   276     "                                when (lower(address) = lower(?2)) then (1)"
   277     "                                when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   278     "                                else 0 "    
   279     "                           end) = 1 "
   280     "                           and user_id = ?3)) "
   281     "   where (case when (address = ?2) then (1)"
   282     "               when (lower(address) = lower(?2)) then (1)"
   283     "               when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   284     "               else 0"
   285     "          end) = 1"
   286     "          and user_id = ?3 ;";
   287 
   288 static const char *sql_unset_identity_flags = 
   289     "update identity set flags = "
   290     "    ( ~(?1 & 65535) & (select flags from identity"
   291     "                    where (case when (address = ?2) then (1)"
   292     "                                when (lower(address) = lower(?2)) then (1)"
   293     "                                when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   294     "                                else 0 "    
   295     "                           end) = 1 "
   296     "                           and user_id = ?3)) "
   297     "   where (case when (address = ?2) then (1)"
   298     "               when (lower(address) = lower(?2)) then (1)"
   299     "               when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   300     "               else 0"
   301     "          end) = 1"
   302     "          and user_id = ?3 ;";
   303 
   304 static const char *sql_set_trust =
   305     "insert into trust (user_id, pgp_keypair_fpr, comm_type) "
   306     "values (?1, upper(replace(?2,' ','')), ?3) ;";
   307 
   308 static const char *sql_update_trust =
   309     "update trust set comm_type = ?3 " 
   310     "   where user_id = ?1 and pgp_keypair_fpr = upper(replace(?2,' ',''));";
   311 
   312 static const char *sql_update_trust_to_pEp =
   313     "update trust set comm_type = comm_type + 71 "
   314     "   where (user_id = ?1 "
   315     "          and (case when (comm_type = 56) then (1) "
   316     "                    when (comm_type = 184) then (1) "
   317     "                    else 0"
   318     "               end) = 1); ";
   319 
   320 static const char* sql_exists_trust_entry = 
   321     "select count(*) from trust "
   322     "   where user_id = ?1 and pgp_keypair_fpr = upper(replace(?2,' ',''));";
   323     
   324 static const char *sql_update_trust_for_fpr =
   325     "update trust "
   326     "set comm_type = ?1 "
   327     "where pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
   328 
   329 static const char *sql_get_trust = 
   330     "select comm_type from trust where user_id = ?1 "
   331     "and pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
   332 
   333 static const char *sql_get_trust_by_userid = 
   334     "select pgp_keypair_fpr, comm_type from trust where user_id = ?1 ";
   335 
   336 static const char *sql_least_trust = 
   337     "select min(comm_type) from trust where"
   338     " pgp_keypair_fpr = upper(replace(?1,' ',''))"
   339     " and comm_type != 0;"; // ignores PEP_ct_unknown
   340     // returns PEP_ct_unknown only when no known trust is recorded
   341 
   342 static const char *sql_mark_as_compromised = 
   343     "update trust not indexed set comm_type = 15"
   344     " where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
   345     
   346 static const char *sql_crashdump = 
   347     "select timestamp, title, entity, description, comment"
   348     " from log order by timestamp desc limit ?1 ;";
   349 
   350 static const char *sql_languagelist = 
   351     "select i18n_language.lang, name, phrase" 
   352     " from i18n_language join i18n_token using (lang) where i18n_token.id = 1000;" ;
   353 
   354 static const char *sql_i18n_token = 
   355     "select phrase from i18n_token where lang = lower(?1) and id = ?2 ;";
   356 
   357 // blacklist
   358 static const char *sql_blacklist_add = 
   359     "insert or ignore into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
   360     "delete from identity where main_key_id = upper(replace(?1,' ','')) ;"
   361     "delete from pgp_keypair where fpr = upper(replace(?1,' ','')) ;";
   362 
   363 static const char *sql_blacklist_delete =
   364     "delete from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
   365 
   366 static const char *sql_blacklist_is_listed = 
   367     "select count(*) from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
   368 
   369 static const char *sql_blacklist_retrieve = 
   370     "select * from blacklist_keys ;";
   371                 
   372 
   373 // Own keys
   374 // We only care if it's 0 or non-zero
   375 static const char *sql_own_key_is_listed = 
   376     "select count(*) from ("
   377     "   select pgp_keypair_fpr from trust"
   378     "      join identity on trust.user_id = identity.user_id"
   379     "      where pgp_keypair_fpr = upper(replace(?1,' ',''))"
   380     "           and identity.is_own = 1"
   381     ");";
   382     
   383 static const char *sql_is_own_address =
   384     "select count(*) from ("
   385     "   select address from identity"
   386     "       where (case when (address = ?1) then (1)"
   387     "                   when (lower(address) = lower(?1)) then (1)"
   388     "                   when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   389     "                   else 0"
   390     "           end) = 1 "
   391     "           and identity.is_own = 1"
   392     ");";
   393 
   394 static const char *sql_own_identities_retrieve =  
   395     "select address, fpr, identity.user_id, username,"
   396     "   lang, identity.flags | pgp_keypair.flags"
   397     "   from identity"
   398     "   join person on id = identity.user_id"
   399     "   join pgp_keypair on fpr = identity.main_key_id"
   400     "   join trust on id = trust.user_id"
   401     "       and pgp_keypair_fpr = identity.main_key_id"
   402     "   where identity.is_own = 1"
   403     "       and (identity.flags & ?1) = 0;";
   404 
   405 static const char *sql_own_keys_retrieve = 
   406     "select pgp_keypair_fpr from trust"
   407     "   join identity on trust.user_id = identity.user_id"
   408     "   where identity.is_own = 1";
   409 
   410 static const char* sql_get_user_default_key =
   411     "select main_key_id from person" 
   412     "   where id = ?1;";
   413 
   414 static const char* sql_get_all_keys_for_user =
   415     "select pgp_keypair_fpr from trust"
   416     "   where user_id = ?1; ";
   417 
   418 static const char* sql_get_default_own_userid =
   419     "select id from person"
   420     "   join identity on id = identity.user_id"
   421     "   where identity.is_own = 1";
   422 
   423 // Sequence
   424 static const char *sql_sequence_value1 = 
   425     "insert or replace into sequences (name, value) "
   426     "values (?1, "
   427     "       (select coalesce((select value + 1 from sequences "
   428     "           where name = ?1), 1 ))); ";
   429 
   430 static const char *sql_sequence_value2 = 
   431     "select value from sequences where name = ?1 ;";
   432 
   433 // Revocation tracking
   434 static const char *sql_set_revoked =
   435     "insert or replace into revoked_keys ("
   436     "    revoked_fpr, replacement_fpr, revocation_date) "
   437     "values (upper(replace(?1,' ','')),"
   438     "        upper(replace(?2,' ','')),"
   439     "        ?3) ;";
   440         
   441 static const char *sql_get_revoked = 
   442     "select revoked_fpr, revocation_date from revoked_keys"
   443     "    where replacement_fpr = upper(replace(?1,' ','')) ;";
   444 
   445 static const char *sql_get_replacement_fpr = 
   446     "select replacement_fpr, revocation_date from revoked_keys"
   447     "    where revoked_fpr = upper(replace(?1,' ','')) ;";
   448 
   449 static const char *sql_get_userid_alias_default =
   450     "select default_id from alternate_user_id "
   451     "   where alternate_id = ?1 ; ";
   452 
   453 // Revocation tracking
   454 static const char *sql_add_mistrusted_key =
   455     "insert or replace into mistrusted_keys (fpr) "
   456     "   values (upper(replace(?1,' ',''))) ;";
   457         
   458 static const char *sql_delete_mistrusted_key = 
   459     "delete from mistrusted_keys where fpr = upper(replace(?1,' ','')) ;";
   460 
   461 static const char *sql_is_mistrusted_key = 
   462     "select count(*) from mistrusted_keys where fpr = upper(replace(?1,' ','')) ;";
   463 
   464 static const char *sql_add_userid_alias =
   465     "insert or replace into alternate_user_id (alternate_id, default_id) "
   466     "values (?2, ?1) ;";
   467 
   468 static const char *sql_add_into_social_graph =
   469     "insert or replace into social_graph(own_userid, own_address, contact_userid) "
   470     "values (?1, ?2, ?3) ;";
   471 
   472 static const char *sql_get_own_address_binding_from_contact =
   473     "select own_address from social_graph where own_userid = ?1 and contact_userid = ?2 ;";
   474 
   475 static const char *sql_set_revoke_contact_as_notified =
   476     "insert or replace into revocation_contact_list(fpr, contact_id) values (?1, ?2) ;";
   477     
   478 static const char *sql_get_contacted_ids_from_revoke_fpr =
   479     "select * from revocation_contact_list where fpr = ?1 ;";
   480 
   481 static const char *sql_was_id_for_revoke_contacted = 
   482     "select count(*) from revocation_contact_list where fpr = ?1 and contact_id = ?2 ;";
   483 
   484 // We only need user_id and address, since in the main usage, we'll call update_identity
   485 // on this anyway when sending out messages.
   486 static const char *sql_get_last_contacted =
   487     "select user_id, address from identity where datetime('now') < datetime(timestamp, '+14 days') ; ";
   488     
   489 static int user_version(void *_version, int count, char **text, char **name)
   490 {
   491     assert(_version);
   492     assert(count == 1);
   493     assert(text && text[0]);
   494     if (!(_version && count == 1 && text && text[0]))
   495         return -1;
   496 
   497     int *version = (int *) _version;
   498     *version = atoi(text[0]);
   499     return 0;
   500 }
   501 
   502 // TODO: refactor and generalise these two functions if possible.
   503 static int db_contains_table(PEP_SESSION session, const char* table_name) {
   504     if (!session || !table_name)
   505         return -1;
   506     
   507     // Table names can't be SQL parameters, so we do it this way.
   508     
   509     // these two must be the same number.
   510     char sql_buf[500];
   511     const size_t max_q_len = 500;
   512     
   513     size_t t_size, q_size;
   514     
   515     const char* q1 = "SELECT name FROM sqlite_master WHERE type='table' AND name='{"; // 61
   516     const char* q2 = "}';";       // 3
   517     
   518     q_size = 64;
   519     t_size = strlen(table_name);
   520     
   521     size_t query_len = q_size + t_size + 1;
   522 
   523     if (query_len > max_q_len)
   524         return -1;
   525 
   526     strlcpy(sql_buf, q1, max_q_len);
   527     strlcat(sql_buf, table_name, max_q_len);
   528     strlcat(sql_buf, q2, max_q_len);
   529 
   530     sqlite3_stmt *stmt; 
   531 
   532     sqlite3_prepare_v2(session->db, sql_buf, -1, &stmt, NULL);
   533 
   534     int retval = 0;
   535 
   536     int rc = sqlite3_step(stmt);  
   537     if (rc == SQLITE_DONE || rc == SQLITE_OK || rc == SQLITE_ROW) {
   538         retval = 1;
   539     }
   540 
   541     sqlite3_finalize(stmt);      
   542         
   543     return retval;
   544         
   545 }
   546 
   547 static int table_contains_column(PEP_SESSION session, const char* table_name,
   548                                                       const char* col_name) {
   549 
   550 
   551     if (!session || !table_name || !col_name)
   552         return -1;
   553         
   554     // Table names can't be SQL parameters, so we do it this way.
   555     
   556     // these two must be the same number.
   557     char sql_buf[500];
   558     const size_t max_q_len = 500;
   559     
   560     size_t t_size, c_size, q_size;
   561     
   562     const char* q1 = "SELECT "; // 7
   563     const char* q2 = " from "; // 6
   564     const char* q3 = ";";       // 1
   565     
   566     q_size = 14;
   567     t_size = strlen(table_name);
   568     c_size = strlen(col_name);
   569     
   570     size_t query_len = q_size + c_size + t_size + 1;
   571     
   572     if (query_len > max_q_len)
   573         return -1;
   574 
   575     strlcpy(sql_buf, q1, max_q_len);
   576     strlcat(sql_buf, col_name, max_q_len);
   577     strlcat(sql_buf, q2, max_q_len);
   578     strlcat(sql_buf, table_name, max_q_len);
   579     strlcat(sql_buf, q3, max_q_len);
   580 
   581     sqlite3_stmt *stmt; 
   582 
   583     sqlite3_prepare_v2(session->db, sql_buf, -1, &stmt, NULL);
   584 
   585     int retval = 0;
   586 
   587     int rc = sqlite3_step(stmt);  
   588     if (rc == SQLITE_DONE || rc == SQLITE_OK || rc == SQLITE_ROW) {
   589         retval = 1;
   590     }
   591 
   592     sqlite3_finalize(stmt);      
   593         
   594     return retval;
   595 }
   596 
   597 PEP_STATUS repair_altered_tables(PEP_SESSION session) {
   598     PEP_STATUS status = PEP_STATUS_OK;
   599     
   600     const unsigned int _PEP_MAX_AFFECTED = 5;
   601     char** table_names = calloc(_PEP_MAX_AFFECTED, sizeof(char*));
   602     if (!table_names)
   603         return PEP_OUT_OF_MEMORY;
   604 
   605     const char* sql_query = "select tbl_name from sqlite_master WHERE sql LIKE '%REFERENCES%' AND sql LIKE '%_old%';";
   606     sqlite3_stmt *stmt; 
   607     sqlite3_prepare_v2(session->db, sql_query, -1, &stmt, NULL);
   608     int i = 0;
   609     int int_result = 0;
   610     while ((int_result = sqlite3_step(stmt)) == SQLITE_ROW && i < _PEP_MAX_AFFECTED) {
   611         table_names[i++] = strdup((const char*)(sqlite3_column_text(stmt, 0)));
   612     }
   613     
   614     sqlite3_finalize(stmt);      
   615 
   616     if ((int_result != SQLITE_DONE && int_result != SQLITE_OK) || i > (_PEP_MAX_AFFECTED + 1)) {
   617         status = PEP_UNKNOWN_DB_ERROR;
   618         goto pEp_free;
   619     }
   620         
   621     for (i = 0; i < _PEP_MAX_AFFECTED; i++) {
   622         const char* table_name = table_names[i];
   623         if (!table_name)
   624             break;
   625             
   626         if (strcmp(table_name, "identity") == 0) {
   627             int_result = sqlite3_exec(session->db,
   628                 "PRAGMA foreign_keys=off;\n"
   629                 "BEGIN TRANSACTION;\n"
   630                 "create table _identity_new (\n"
   631                 "   address text,\n"
   632                 "   user_id text\n"
   633                 "       references person (id)\n"
   634                 "       on delete cascade on update cascade,\n"
   635                 "   main_key_id text\n"
   636                 "       references pgp_keypair (fpr)\n"
   637                 "       on delete set null,\n"
   638                 "   comment text,\n"
   639                 "   flags integer default 0,\n"
   640                 "   is_own integer default 0,\n"
   641                 "   timestamp integer default (datetime('now')),\n"
   642                 "   primary key (address, user_id)\n"
   643                 ");\n"
   644                 "INSERT INTO _identity_new SELECT * from identity;\n"
   645                 "DROP TABLE identity;\n"
   646                 "ALTER TABLE _identity_new RENAME TO identity;\n"
   647                 "COMMIT;\n"
   648                 "PRAGMA foreign_keys=on;"
   649                 ,
   650                 NULL,
   651                 NULL,
   652                 NULL
   653             );
   654             assert(int_result == PEP_STATUS_OK);
   655         }
   656         else if (strcmp(table_name, "trust") == 0) {
   657             int_result = sqlite3_exec(session->db,
   658                 "PRAGMA foreign_keys=off;\n"
   659                 "BEGIN TRANSACTION;\n"
   660                 "create table _trust_new (\n"
   661                 "   user_id text not null\n"
   662                 "       references person (id)\n"
   663                 "       on delete cascade on update cascade,\n"
   664                 "   pgp_keypair_fpr text not null\n"
   665                 "       references pgp_keypair (fpr)\n"
   666                 "       on delete cascade,\n"
   667                 "   comm_type integer not null,\n"
   668                 "   comment text,\n"
   669                 "   primary key (user_id, pgp_keypair_fpr)\n"                
   670                 ");\n"
   671                 "INSERT INTO _trust_new SELECT * from trust;\n"
   672                 "DROP TABLE trust;\n"
   673                 "ALTER TABLE _trust_new RENAME TO trust;\n"
   674                 "COMMIT;\n"
   675                 "PRAGMA foreign_keys=on;"
   676                 ,
   677                 NULL,
   678                 NULL,
   679                 NULL
   680             );             
   681             assert(int_result == PEP_STATUS_OK);                       
   682         }
   683         else if (strcmp(table_name, "alternate_user_id") == 0) {
   684             int_result = sqlite3_exec(session->db,
   685                 "PRAGMA foreign_keys=off;\n"
   686                 "BEGIN TRANSACTION;\n"
   687                 "create table _alternate_user_id_new (\n"
   688                 "    default_id text references person (id)\n"
   689                 "       on delete cascade on update cascade,\n"
   690                 "    alternate_id text primary key\n"
   691                 ");\n"
   692                 "INSERT INTO _alternate_user_id_new SELECT * from alternate_user_id;\n"
   693                 "DROP TABLE alternate_user_id;\n"
   694                 "ALTER TABLE _alternate_user_id_new RENAME TO alternate_user_id;\n"
   695                 "COMMIT;\n"
   696                 "PRAGMA foreign_keys=on;"                
   697                 ,
   698                 NULL,
   699                 NULL,
   700                 NULL
   701             );
   702             assert(int_result == PEP_STATUS_OK);
   703         }
   704         else if (strcmp(table_name, "revocation_contact_list") == 0) {
   705             int_result = sqlite3_exec(session->db,
   706                 "PRAGMA foreign_keys=off;\n"
   707                 "BEGIN TRANSACTION;\n"
   708                 "create table _revocation_contact_list_new (\n"
   709                 "   fpr text not null references pgp_keypair (fpr)\n"
   710                 "       on delete cascade,\n"
   711                 "   contact_id text not null references person (id)\n"
   712                 "       on delete cascade on update cascade,\n"
   713                 "   timestamp integer default (datetime('now')),\n"
   714                 "   PRIMARY KEY(fpr, contact_id)\n"            
   715                 ");\n"
   716                 "INSERT INTO _revocation_contact_list_new SELECT * from revocation_contact_list;\n"
   717                 "DROP TABLE revocation_contact_list;\n"
   718                 "ALTER TABLE _revocation_contact_list_new RENAME TO revocation_contact_list;\n"
   719                 "COMMIT;\n"
   720                 "PRAGMA foreign_keys=on;"                
   721                 ,
   722                 NULL,
   723                 NULL,
   724                 NULL
   725             );      
   726             assert(int_result == PEP_STATUS_OK);                              
   727         }
   728         else if (strcmp(table_name, "social_graph")) {
   729             int_result = sqlite3_exec(session->db,
   730                 "PRAGMA foreign_keys=off;\n"
   731                 "BEGIN TRANSACTION;\n"
   732                 "create table _social_new (\n"
   733                 "    own_userid text,\n"
   734                 "    own_address text,\n"
   735                 "    contact_userid text,\n"
   736                 "    CONSTRAINT fk_own_identity\n"
   737                 "       FOREIGN KEY(own_address, own_userid)\n" 
   738                 "       REFERENCES identity(address, user_id)\n"
   739                 "       ON DELETE CASCADE ON UPDATE CASCADE\n"
   740                 ");\n"
   741                 "INSERT INTO _social_graph_new SELECT * from social_graph;\n"
   742                 "DROP TABLE social_graph;\n"
   743                 "ALTER TABLE _social_graph_new RENAME TO social_graph;\n"
   744                 "COMMIT;\n"
   745                 "PRAGMA foreign_keys=on;"                
   746                 ,
   747                 NULL,
   748                 NULL,
   749                 NULL
   750             );
   751             assert(int_result == PEP_STATUS_OK);                                    
   752         }        
   753     }
   754     
   755     int_result = sqlite3_exec(
   756         session->db,
   757         "PRAGMA foreign_key_check;\n"
   758         ,
   759         NULL,
   760         NULL,
   761         NULL
   762     );
   763     assert(int_result == SQLITE_OK);
   764 
   765 pEp_free:
   766     for (i = 0; i < _PEP_MAX_AFFECTED; i++) {
   767         if (table_names[i])
   768             free(table_names[i]);
   769         else
   770             break;
   771     }
   772     free(table_names);
   773     return status;
   774 }
   775 void errorLogCallback(void *pArg, int iErrCode, const char *zMsg){
   776   fprintf(stderr, "(%d) %s\n", iErrCode, zMsg);
   777 }
   778 
   779 #ifdef USE_GPG
   780 PEP_STATUS pgp_import_ultimately_trusted_keypairs(PEP_SESSION session);
   781 #endif // USE_GPG
   782 
   783 DYNAMIC_API PEP_STATUS init(
   784         PEP_SESSION *session,
   785         messageToSend_t messageToSend,
   786         inject_sync_event_t inject_sync_event
   787     )
   788 {
   789     PEP_STATUS status = PEP_STATUS_OK;
   790     int int_result;
   791     
   792     bool in_first = false;
   793     bool very_first = false;
   794 
   795     assert(sqlite3_threadsafe());
   796     if (!sqlite3_threadsafe())
   797         return PEP_INIT_SQLITE3_WITHOUT_MUTEX;
   798 
   799     // a little race condition - but still a race condition
   800     // mitigated by calling caveat (see documentation)
   801 
   802     // this increment is made atomic IN THE ADAPTERS by
   803     // guarding the call to init with the appropriate mutex.
   804     int _count = ++init_count;
   805     if (_count == 0)
   806         in_first = true;
   807     
   808     // Race condition mitigated by calling caveat starts here :
   809     // If another call to init() preempts right now, then preemptive call
   810     // will have in_first false, will not create SQL tables, and following
   811     // calls relying on those tables will fail.
   812     //
   813     // Therefore, as above, adapters MUST guard init() with a mutex.
   814     // 
   815     // Therefore, first session
   816     // is to be created and last session to be deleted alone, and not
   817     // concurently to other sessions creation or deletion.
   818     // We expect adapters to enforce this either by implicitely creating a
   819     // client session, or by using synchronization primitive to protect
   820     // creation/deletion of first/last session from the app.
   821 
   822     assert(session);
   823     if (session == NULL)
   824         return PEP_ILLEGAL_VALUE;
   825 
   826     *session = NULL;
   827 
   828     pEpSession *_session = calloc(1, sizeof(pEpSession));
   829     assert(_session);
   830     if (_session == NULL)
   831         goto enomem;
   832 
   833     _session->version = PEP_ENGINE_VERSION;
   834     _session->messageToSend = messageToSend;
   835     _session->inject_sync_event = inject_sync_event;
   836 
   837 #ifdef DEBUG_ERRORSTACK
   838     _session->errorstack = new_stringlist("init()");
   839 #endif
   840 
   841     assert(LOCAL_DB);
   842     if (LOCAL_DB == NULL) {
   843         status = PEP_INIT_CANNOT_OPEN_DB;
   844         goto pEp_error;
   845     }
   846     
   847 #if _PEP_SQLITE_DEBUG    
   848     sqlite3_config(SQLITE_CONFIG_LOG, errorLogCallback, NULL);
   849 #endif
   850 
   851     int_result = sqlite3_open_v2(
   852             LOCAL_DB,
   853             &_session->db,
   854             SQLITE_OPEN_READWRITE
   855                 | SQLITE_OPEN_CREATE
   856                 | SQLITE_OPEN_FULLMUTEX
   857                 | SQLITE_OPEN_PRIVATECACHE,
   858             NULL 
   859         );
   860 
   861     if (int_result != SQLITE_OK) {
   862         status = PEP_INIT_CANNOT_OPEN_DB;
   863         goto pEp_error;
   864     }
   865 
   866     int_result = sqlite3_exec(
   867             _session->db,
   868             "PRAGMA locking_mode=NORMAL;\n"
   869             "PRAGMA journal_mode=WAL;\n",
   870             NULL,
   871             NULL,
   872             NULL
   873         );
   874 
   875 
   876     sqlite3_busy_timeout(_session->db, BUSY_WAIT_TIME);
   877 
   878 #if _PEP_SQLITE_DEBUG
   879     sqlite3_trace_v2(_session->db, 
   880         SQLITE_TRACE_STMT | SQLITE_TRACE_ROW | SQLITE_TRACE_CLOSE,
   881         sql_trace_callback,
   882         NULL);
   883 #endif
   884 
   885     assert(SYSTEM_DB);
   886     if (SYSTEM_DB == NULL) {
   887         status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
   888         goto pEp_error;
   889     }
   890 
   891     int_result = sqlite3_open_v2(
   892             SYSTEM_DB, &_session->system_db,
   893             SQLITE_OPEN_READONLY
   894                 | SQLITE_OPEN_FULLMUTEX
   895                 | SQLITE_OPEN_SHAREDCACHE,
   896             NULL
   897         );
   898 
   899     if (int_result != SQLITE_OK) {
   900         status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
   901         goto pEp_error;
   902     }
   903 
   904     sqlite3_busy_timeout(_session->system_db, 1000);
   905 
   906 // increment this when patching DDL
   907 #define _DDL_USER_VERSION "12"
   908 
   909     if (in_first) {
   910 
   911         int_result = sqlite3_exec(
   912             _session->db,
   913                 "create table if not exists version_info (\n"
   914                 "   id integer primary key,\n"
   915                 "   timestamp integer default (datetime('now')),\n"
   916                 "   version text,\n"
   917                 "   comment text\n"
   918                 ");\n",
   919                 NULL,
   920                 NULL,
   921                 NULL
   922         );
   923         int_result = sqlite3_exec(
   924             _session->db,
   925                 "PRAGMA application_id = 0x23423423;\n"
   926                 "create table if not exists log (\n"
   927                 "   timestamp integer default (datetime('now')),\n"
   928                 "   title text not null,\n"
   929                 "   description text,\n"
   930                 "   entity text not null,\n"
   931                 "   comment text\n"
   932                 ");\n"
   933                 "create index if not exists log_timestamp on log (\n"
   934                 "   timestamp\n"
   935                 ");\n"
   936                 "create table if not exists pgp_keypair (\n"
   937                 "   fpr text primary key,\n"
   938                 "   created integer,\n"
   939                 "   expires integer,\n"
   940                 "   comment text,\n"
   941                 "   flags integer default 0\n"
   942                 ");\n"
   943                 "create index if not exists pgp_keypair_expires on pgp_keypair (\n"
   944                 "   expires\n"
   945                 ");\n"
   946                 "create table if not exists person (\n"
   947                 "   id text primary key,\n"
   948                 "   username text not null,\n"
   949                 "   main_key_id text\n"
   950                 "       references pgp_keypair (fpr)\n"
   951                 "       on delete set null,\n"
   952                 "   lang text,\n"
   953                 "   comment text,\n"
   954 //                "   device_group text,\n"
   955                 "   is_pEp_user integer default 0\n"
   956                 ");\n"
   957                 "create table if not exists identity (\n"
   958                 "   address text,\n"
   959                 "   user_id text\n"
   960                 "       references person (id)\n"
   961                 "       on delete cascade on update cascade,\n"
   962                 "   main_key_id text\n"
   963                 "       references pgp_keypair (fpr)\n"
   964                 "       on delete set null,\n"
   965                 "   comment text,\n"
   966                 "   flags integer default 0,\n"
   967                 "   is_own integer default 0,\n"
   968                 "   pep_version real default 0,\n"                
   969                 "   timestamp integer default (datetime('now')),\n"
   970                 "   primary key (address, user_id)\n"
   971                 ");\n"
   972                 "create table if not exists trust (\n"
   973                 "   user_id text not null\n"
   974                 "       references person (id)\n"
   975                 "       on delete cascade on update cascade,\n"
   976                 "   pgp_keypair_fpr text not null\n"
   977                 "       references pgp_keypair (fpr)\n"
   978                 "       on delete cascade,\n"
   979                 "   comm_type integer not null,\n"
   980                 "   comment text,\n"
   981                 "   primary key (user_id, pgp_keypair_fpr)\n"
   982                 ");\n"
   983                 // blacklist
   984                 "create table if not exists blacklist_keys (\n"
   985                 "   fpr text primary key\n"
   986                 ");\n"
   987                 // sequences
   988                 "create table if not exists sequences(\n"
   989                 "   name text primary key,\n"
   990                 "   value integer default 0\n"
   991                 ");\n"
   992                 "create table if not exists revoked_keys (\n"
   993                 "   revoked_fpr text primary key,\n"
   994                 "   replacement_fpr text not null\n"
   995                 "       references pgp_keypair (fpr)\n"
   996                 "       on delete cascade,\n"
   997                 "   revocation_date integer\n"
   998                 ");\n"
   999                 // user id aliases
  1000                 "create table if not exists alternate_user_id (\n"
  1001                 "    default_id text references person (id)\n"
  1002                 "       on delete cascade on update cascade,\n"
  1003                 "    alternate_id text primary key\n"
  1004                 ");\n"
  1005                 // mistrusted keys
  1006                 "create table if not exists mistrusted_keys (\n"
  1007                 "    fpr text primary key\n"
  1008                 ");\n"
  1009                 // social graph for key resets
  1010                 "create table if not exists social_graph (\n"
  1011                 "    own_userid text,\n"
  1012                 "    own_address text,\n"
  1013                 "    contact_userid text,\n"
  1014                 "    CONSTRAINT fk_own_identity\n"
  1015                 "       FOREIGN KEY(own_address, own_userid)\n" 
  1016                 "       REFERENCES identity(address, user_id)\n"
  1017                 "       ON DELETE CASCADE ON UPDATE CASCADE\n"
  1018                 ");\n"
  1019                 // list of user_ids sent revocation
  1020                 "create table if not exists revocation_contact_list (\n"
  1021                 "   fpr text not null references pgp_keypair (fpr)\n"
  1022                 "       on delete cascade,\n"
  1023                 "   contact_id text not null references person (id)\n"
  1024                 "       on delete cascade on update cascade,\n"
  1025                 "   timestamp integer default (datetime('now')),\n"
  1026                 "   PRIMARY KEY(fpr, contact_id)\n"
  1027                 ");\n"
  1028                 ,
  1029             NULL,
  1030             NULL,
  1031             NULL
  1032         );
  1033         assert(int_result == SQLITE_OK);
  1034 
  1035         int version;
  1036         int_result = sqlite3_exec(
  1037             _session->db,
  1038             "pragma user_version;",
  1039             user_version,
  1040             &version,
  1041             NULL
  1042         );
  1043 
  1044         assert(int_result == SQLITE_OK);
  1045         
  1046         void (*xFunc_lower)(sqlite3_context*,int,sqlite3_value**) = &_sql_lower;
  1047         
  1048         int_result = sqlite3_create_function_v2(
  1049             _session->db,
  1050             "lower",
  1051             1,
  1052             SQLITE_UTF8 | SQLITE_DETERMINISTIC,
  1053             NULL,
  1054             xFunc_lower,
  1055             NULL,
  1056             NULL,
  1057             NULL);
  1058         assert(int_result == SQLITE_OK);
  1059 
  1060         int_result = sqlite3_exec(
  1061             _session->db,
  1062             "pragma foreign_keys=ON;\n",
  1063             NULL,
  1064             NULL,
  1065             NULL
  1066         );
  1067 
  1068         assert(int_result == SQLITE_OK);
  1069 
  1070         
  1071         // Sometimes the user_version wasn't set correctly. 
  1072         if (version == 1) {
  1073             bool version_changed = true;
  1074             if (table_contains_column(_session, "identity", "pep_version") > 0) {
  1075                 version = 12;
  1076             } // N.B. Version 11 was a DB internal fix; there's no identifying information, but this is only one extra exec.
  1077             else if (db_contains_table(_session, "social_graph") > 0) {
  1078                 if (!table_contains_column(_session, "person", "device_group"))
  1079                     version = 10;
  1080                 else
  1081                     version = 9;
  1082             }            
  1083             else if (table_contains_column(_session, "identity", "timestamp") > 0) {
  1084                 version = 8;
  1085             }            
  1086             else if (table_contains_column(_session, "person", "is_pEp_user") > 0) {
  1087                 version = 7;
  1088             }            
  1089             else if (table_contains_column(_session, "identity", "is_own") > 0) {
  1090                 version = 6;
  1091             }
  1092             else if (table_contains_column(_session, "pgp_keypair", "flags") > 0) {
  1093                 version = 2;
  1094             }
  1095             else {
  1096                 version_changed = false;
  1097             }
  1098             
  1099             if (version_changed) {
  1100                 // set it in the DB, finally. Yeesh.
  1101                 char verbuf[21]; // enough digits for a max-sized 64 bit int, cmon. 
  1102                 sprintf(verbuf,"%d",version);
  1103                 
  1104                 size_t query_size = strlen(verbuf) + 25;
  1105                 char* query = calloc(query_size, 1);
  1106                 
  1107                 strlcpy(query, "pragma user_version = ", query_size);
  1108                 strlcat(query, verbuf, query_size);
  1109                 strlcat(query, ";", query_size);
  1110                 
  1111                 int_result = sqlite3_exec(
  1112                     _session->db,
  1113                     query,
  1114                     user_version,
  1115                     &version,
  1116                     NULL
  1117                 );
  1118                 free(query);
  1119             }
  1120         }
  1121 
  1122 
  1123         if(version != 0) { 
  1124             // Version has been already set
  1125 
  1126             // Early mistake : version 0 shouldn't have existed.
  1127             // Numbering should have started at 1 to detect newly created DB.
  1128             // Version 0 DBs are not anymore compatible.
  1129 
  1130             // // Was version 0 compat code.
  1131             // if (version < 1) {
  1132             //     int_result = sqlite3_exec(
  1133             //         _session->db,
  1134             //         "alter table identity\n"
  1135             //         "   add column flags integer default 0;\n",
  1136             //         NULL,
  1137             //         NULL,
  1138             //         NULL
  1139             //     );
  1140             //     assert(int_result == SQLITE_OK);
  1141             // }
  1142             
  1143             if (version < 2) {
  1144                 // N.B. addition of device_group column removed in DDL v10
  1145                 int_result = sqlite3_exec(
  1146                     _session->db,
  1147                     "alter table pgp_keypair\n"
  1148                     "   add column flags integer default 0;\n",
  1149                     // "alter table person\n"
  1150                     // "   add column device_group text;\n",
  1151                     NULL,
  1152                     NULL,
  1153                     NULL
  1154                 );
  1155                 assert(int_result == SQLITE_OK);
  1156             }
  1157 
  1158             if (version < 5) {
  1159                 int_result = sqlite3_exec(
  1160                     _session->db,
  1161                     "delete from pgp_keypair where fpr = '';",
  1162                     NULL,
  1163                     NULL,
  1164                     NULL
  1165                 );
  1166                 assert(int_result == SQLITE_OK);
  1167                 int_result = sqlite3_exec(
  1168                     _session->db,
  1169                     "delete from trust where pgp_keypair_fpr = '';",
  1170                     NULL,
  1171                     NULL,
  1172                     NULL
  1173                 );
  1174                 assert(int_result == SQLITE_OK);
  1175             }
  1176             
  1177             if (version < 6) {
  1178                 int_result = sqlite3_exec(
  1179                     _session->db,
  1180                     "alter table identity\n"
  1181                     "   add column is_own integer default 0;\n",
  1182                     NULL,
  1183                     NULL,
  1184                     NULL
  1185                 );
  1186                 assert(int_result == SQLITE_OK);                
  1187                 int_result = sqlite3_exec(
  1188                     _session->db,
  1189                     "update identity\n"
  1190                     "   set is_own = 1\n"
  1191                     "   where (user_id = '" PEP_OWN_USERID "');\n",
  1192                     NULL,
  1193                     NULL,
  1194                     NULL
  1195                 );
  1196                 assert(int_result == SQLITE_OK);    
  1197 
  1198                 // Turns out that just adding "on update cascade" in
  1199                 // sqlite is a PITA. We need to be able to cascade
  1200                 // person->id replacements (for temp ids like "TOFU_")
  1201                 // so here we go...
  1202                 int_result = sqlite3_exec(
  1203                     _session->db,
  1204                     "PRAGMA foreign_keys=off;\n"
  1205                     "BEGIN TRANSACTION;\n"
  1206                     "create table _identity_new (\n"
  1207                     "   address text,\n"
  1208                     "   user_id text\n"
  1209                     "       references person (id)\n"
  1210                     "       on delete cascade on update cascade,\n"
  1211                     "   main_key_id text\n"
  1212                     "       references pgp_keypair (fpr)\n"
  1213                     "       on delete set null,\n"
  1214                     "   comment text,\n"
  1215                     "   flags integer default 0,\n"
  1216                     "   is_own integer default 0,\n"
  1217                     "   primary key (address, user_id)\n"
  1218                     ");\n"                    
  1219                     "INSERT INTO _identity_new SELECT * FROM identity;\n"
  1220                     "DROP TABLE identity;\n"
  1221                     "ALTER TABLE _identity_new RENAME TO identity;\n"
  1222                     "COMMIT;\n"
  1223                     "\n"
  1224                     "BEGIN TRANSACTION;\n"
  1225                     "create table _trust_new (\n"
  1226                     "   user_id text not null\n"
  1227                     "       references person (id)\n"
  1228                     "       on delete cascade on update cascade,\n"
  1229                     "   pgp_keypair_fpr text not null\n"
  1230                     "       references pgp_keypair (fpr)\n"
  1231                     "       on delete cascade,\n"
  1232                     "   comm_type integer not null,\n"
  1233                     "   comment text,\n"
  1234                     "   primary key (user_id, pgp_keypair_fpr)\n"
  1235                     ");\n"
  1236                     "INSERT INTO _trust_new SELECT * FROM trust;\n"
  1237                     "DROP TABLE trust;\n"
  1238                     "ALTER TABLE _trust_new RENAME TO trust;\n"
  1239                     "COMMIT;\n"
  1240                     "\n"
  1241                     "PRAGMA foreign_keys=on;\n"
  1242                     "create table if not exists alternate_user_id (\n"
  1243                     "    default_id text references person (id)\n"
  1244                     "       on delete cascade on update cascade,\n"
  1245                     "    alternate_id text primary key\n"
  1246                     ");\n"
  1247                     ,
  1248                     NULL,
  1249                     NULL,
  1250                     NULL
  1251                 );
  1252                 assert(int_result == SQLITE_OK);   
  1253                 
  1254                 int_result = sqlite3_exec(
  1255                     _session->db,
  1256                     "PRAGMA foreign_key_check;\n"
  1257                     ,
  1258                     NULL,
  1259                     NULL,
  1260                     NULL
  1261                 );
  1262                 assert(int_result == SQLITE_OK);
  1263 
  1264                 // FIXME: foreign key check here 
  1265             }
  1266             if (version < 7) {
  1267                 int_result = sqlite3_exec(
  1268                     _session->db,
  1269                     "alter table person\n"
  1270                     "   add column is_pEp_user integer default 0;\n",
  1271                     NULL,
  1272                     NULL,
  1273                     NULL
  1274                 );
  1275                 assert(int_result == SQLITE_OK);
  1276                 int_result = sqlite3_exec(
  1277                     _session->db,
  1278                     "update person\n"
  1279                     "   set is_pEp_user = 1\n"
  1280                     "   where id = "
  1281                     "       (select distinct id from person "
  1282                     "               join trust on id = user_id "
  1283                     "               where (case when (comm_type = 127) then (id) "
  1284                     "                           when (comm_type = 255) then (id) "
  1285                     "                           else 0"
  1286                     "                      end) = id );\n",
  1287                     NULL,
  1288                     NULL,
  1289                     NULL
  1290                 );
  1291                 assert(int_result == SQLITE_OK);
  1292                 
  1293                 int_result = sqlite3_exec(
  1294                     _session->db,
  1295                     "create table if not exists mistrusted_keys (\n"
  1296                     "    fpr text primary key\n"
  1297                     ");\n",            
  1298                     NULL,
  1299                     NULL,
  1300                     NULL
  1301                 );
  1302                 assert(int_result == SQLITE_OK);    
  1303             }
  1304             if (version < 8) {
  1305                 int_result = sqlite3_exec(
  1306                     _session->db,
  1307                     "PRAGMA foreign_keys=off;\n"
  1308                     "BEGIN TRANSACTION;\n"
  1309                     "create table _identity_new (\n"
  1310                     "   address text,\n"
  1311                     "   user_id text\n"
  1312                     "       references person (id)\n"
  1313                     "       on delete cascade on update cascade,\n"
  1314                     "   main_key_id text\n"
  1315                     "       references pgp_keypair (fpr)\n"
  1316                     "       on delete set null,\n"
  1317                     "   comment text,\n"
  1318                     "   flags integer default 0,\n"
  1319                     "   is_own integer default 0,\n"
  1320                     "   timestamp integer default (datetime('now')),\n"
  1321                     "   primary key (address, user_id)\n"
  1322                     ");\n"
  1323                     "INSERT INTO _identity_new (address, user_id, main_key_id, "
  1324                     "                      comment, flags, is_own) "
  1325                     "   SELECT identity.address, identity.user_id, "
  1326                     "          identity.main_key_id, identity.comment, "
  1327                     "          identity.flags, identity.is_own "
  1328                     "   FROM identity "
  1329                     "   WHERE 1;\n"
  1330                     "DROP TABLE identity;\n"
  1331                     "ALTER TABLE _identity_new RENAME TO identity;\n"
  1332                     "COMMIT;\n"
  1333                     "\n"
  1334                     "PRAGMA foreign_keys=on;\n"
  1335                     ,
  1336                     NULL,
  1337                     NULL,
  1338                     NULL
  1339                 );
  1340                 assert(int_result == SQLITE_OK);    
  1341                 
  1342                 int_result = sqlite3_exec(
  1343                     _session->db,
  1344                     "PRAGMA foreign_key_check;\n"
  1345                     ,
  1346                     NULL,
  1347                     NULL,
  1348                     NULL
  1349                 );
  1350                 assert(int_result == SQLITE_OK);
  1351 
  1352                 // FIXME: foreign key check
  1353             }
  1354             if (version < 9) {
  1355                 int_result = sqlite3_exec(
  1356                     _session->db,
  1357                     "create table if not exists social_graph (\n"
  1358                     "    own_userid text,\n"
  1359                     "    own_address text,\n"
  1360                     "    contact_userid text,\n"
  1361                     "    CONSTRAINT fk_own_identity\n"
  1362                     "       FOREIGN KEY(own_address, own_userid)\n" 
  1363                     "       REFERENCES identity(address, user_id)\n"
  1364                     "       ON DELETE CASCADE ON UPDATE CASCADE\n"
  1365                     ");\n"
  1366                     "create table if not exists revocation_contact_list (\n"
  1367                     "   fpr text not null references pgp_keypair (fpr)\n"
  1368                     "       on delete cascade,\n"
  1369                     "   contact_id text not null references person (id)\n"
  1370                     "       on delete cascade on update cascade,\n"
  1371                     "   timestamp integer default (datetime('now')),\n"
  1372                     "   PRIMARY KEY(fpr, contact_id)\n"
  1373                     ");\n"
  1374                     ,
  1375                     NULL,
  1376                     NULL,
  1377                     NULL
  1378                 );
  1379                 assert(int_result == SQLITE_OK);    
  1380             }
  1381             if (version < 10 && version > 1) {
  1382                 int_result = sqlite3_exec(
  1383                     _session->db,
  1384                     "PRAGMA foreign_keys=off;\n"
  1385                     "BEGIN TRANSACTION;\n"
  1386                     "create table _person_new (\n"
  1387                     "   id text primary key,\n"
  1388                     "   username text not null,\n"
  1389                     "   main_key_id text\n"
  1390                     "       references pgp_keypair (fpr)\n"
  1391                     "       on delete set null,\n"
  1392                     "   lang text,\n"
  1393                     "   comment text,\n"
  1394                     "   is_pEp_user integer default 0\n"
  1395                     ");\n"
  1396                     "INSERT INTO _person_new (id, username, main_key_id, "
  1397                     "                    lang, comment, is_pEp_user) "
  1398                     "   SELECT person.id, person.username, "
  1399                     "          person.main_key_id, person.lang, "
  1400                     "          person.comment, person.is_pEp_user "
  1401                     "   FROM person "
  1402                     "   WHERE 1;\n"
  1403                     "DROP TABLE person;\n"
  1404                     "ALTER TABLE _person_new RENAME TO person;\n"
  1405                     "COMMIT;\n"
  1406                     "\n"
  1407                     "PRAGMA foreign_keys=on;\n"
  1408                     ,
  1409                     NULL,
  1410                     NULL,
  1411                     NULL
  1412                 );
  1413                 assert(int_result == SQLITE_OK);    
  1414                 int_result = sqlite3_exec(
  1415                     _session->db,
  1416                     "PRAGMA foreign_key_check;\n"
  1417                     ,
  1418                     NULL,
  1419                     NULL,
  1420                     NULL
  1421                 );
  1422                 assert(int_result == SQLITE_OK);
  1423             }
  1424             if (version < 11) {
  1425                 status = repair_altered_tables(_session);
  1426                 assert(status == PEP_STATUS_OK);
  1427                 if (status != PEP_STATUS_OK)
  1428                     return status;
  1429             }
  1430             if (version < 12) {
  1431                 int_result = sqlite3_exec(
  1432                     _session->db,
  1433                     "alter table identity\n"
  1434                     "   add column pep_version real default 0;\n",
  1435                     NULL,
  1436                     NULL,
  1437                     NULL
  1438                 );
  1439                 assert(int_result == SQLITE_OK);                
  1440             }
  1441         }        
  1442         else { 
  1443             // Version from DB was 0, it means this is initial setup.
  1444             // DB has just been created, and all tables are empty.
  1445             very_first = true;
  1446         }
  1447 
  1448         if (version < atoi(_DDL_USER_VERSION)) {
  1449             int_result = sqlite3_exec(
  1450                 _session->db,
  1451                 "pragma user_version = "_DDL_USER_VERSION";\n"
  1452                 "insert or replace into version_info (id, version)"
  1453                     "values (1, '" PEP_ENGINE_VERSION "');",
  1454                 NULL,
  1455                 NULL,
  1456                 NULL
  1457             );
  1458             assert(int_result == SQLITE_OK);
  1459         }
  1460         
  1461         // We need to init a few globals for message id that we'd rather not
  1462         // calculate more than once.
  1463         _init_globals();
  1464     }
  1465 
  1466     int_result = sqlite3_prepare_v2(_session->db, sql_log,
  1467             (int)strlen(sql_log), &_session->log, NULL);
  1468     assert(int_result == SQLITE_OK);
  1469 
  1470     int_result = sqlite3_prepare_v2(_session->system_db, sql_trustword,
  1471             (int)strlen(sql_trustword), &_session->trustword, NULL);
  1472     assert(int_result == SQLITE_OK);
  1473 
  1474     int_result = sqlite3_prepare_v2(_session->db, sql_get_identity,
  1475             (int)strlen(sql_get_identity), &_session->get_identity, NULL);
  1476     assert(int_result == SQLITE_OK);
  1477 
  1478     int_result = sqlite3_prepare_v2(_session->db, sql_get_identity_without_trust_check,
  1479             (int)strlen(sql_get_identity_without_trust_check), 
  1480             &_session->get_identity_without_trust_check, NULL);
  1481     assert(int_result == SQLITE_OK);
  1482 
  1483     int_result = sqlite3_prepare_v2(_session->db, sql_get_identities_by_address,
  1484             (int)strlen(sql_get_identities_by_address), 
  1485             &_session->get_identities_by_address, NULL);
  1486     assert(int_result == SQLITE_OK);
  1487     
  1488     int_result = sqlite3_prepare_v2(_session->db, sql_get_identities_by_userid,
  1489             (int)strlen(sql_get_identities_by_userid), 
  1490             &_session->get_identities_by_userid, NULL);
  1491     assert(int_result == SQLITE_OK);
  1492 
  1493     int_result = sqlite3_prepare_v2(_session->db, sql_get_identities_by_main_key_id,
  1494             (int)strlen(sql_get_identities_by_main_key_id), 
  1495             &_session->get_identities_by_main_key_id, NULL);
  1496     assert(int_result == SQLITE_OK);
  1497 
  1498     int_result = sqlite3_prepare_v2(_session->db, sql_get_user_default_key,
  1499             (int)strlen(sql_get_user_default_key), &_session->get_user_default_key, NULL);
  1500     assert(int_result == SQLITE_OK);
  1501 
  1502     int_result = sqlite3_prepare_v2(_session->db, sql_get_all_keys_for_user,
  1503             (int)strlen(sql_get_all_keys_for_user), &_session->get_all_keys_for_user, NULL);
  1504     assert(int_result == SQLITE_OK);
  1505 
  1506     int_result = sqlite3_prepare_v2(_session->db, sql_get_default_own_userid,
  1507             (int)strlen(sql_get_default_own_userid), &_session->get_default_own_userid, NULL);
  1508     assert(int_result == SQLITE_OK);
  1509     
  1510     int_result = sqlite3_prepare_v2(_session->db, sql_get_userid_alias_default,
  1511             (int)strlen(sql_get_userid_alias_default), &_session->get_userid_alias_default, NULL);
  1512     assert(int_result == SQLITE_OK);
  1513 
  1514     int_result = sqlite3_prepare_v2(_session->db, sql_add_userid_alias,
  1515             (int)strlen(sql_add_userid_alias), &_session->add_userid_alias, NULL);
  1516     assert(int_result == SQLITE_OK);
  1517 
  1518     int_result = sqlite3_prepare_v2(_session->db, sql_replace_userid,
  1519             (int)strlen(sql_replace_userid), &_session->replace_userid, NULL);
  1520     assert(int_result == SQLITE_OK);
  1521 
  1522     int_result = sqlite3_prepare_v2(_session->db, sql_delete_key,
  1523             (int)strlen(sql_delete_key), &_session->delete_key, NULL);
  1524     assert(int_result == SQLITE_OK);
  1525 
  1526     int_result = sqlite3_prepare_v2(_session->db, sql_replace_main_user_fpr,
  1527             (int)strlen(sql_replace_main_user_fpr), &_session->replace_main_user_fpr, NULL);
  1528     assert(int_result == SQLITE_OK);
  1529 
  1530     int_result = sqlite3_prepare_v2(_session->db, sql_get_main_user_fpr,
  1531             (int)strlen(sql_get_main_user_fpr), &_session->get_main_user_fpr, NULL);
  1532     assert(int_result == SQLITE_OK);
  1533 
  1534     int_result = sqlite3_prepare_v2(_session->db, sql_refresh_userid_default_key,
  1535             (int)strlen(sql_refresh_userid_default_key), &_session->refresh_userid_default_key, NULL);
  1536     assert(int_result == SQLITE_OK);
  1537 
  1538     int_result = sqlite3_prepare_v2(_session->db, sql_replace_identities_fpr,
  1539             (int)strlen(sql_replace_identities_fpr), 
  1540             &_session->replace_identities_fpr, NULL);
  1541     assert(int_result == SQLITE_OK);
  1542     
  1543     int_result = sqlite3_prepare_v2(_session->db, sql_remove_fpr_as_default,
  1544             (int)strlen(sql_remove_fpr_as_default), 
  1545             &_session->remove_fpr_as_default, NULL);
  1546     assert(int_result == SQLITE_OK);
  1547 
  1548     int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
  1549             (int)strlen(sql_set_person), &_session->set_person, NULL);
  1550     assert(int_result == SQLITE_OK);
  1551 
  1552     int_result = sqlite3_prepare_v2(_session->db, sql_update_person,
  1553             (int)strlen(sql_update_person), &_session->update_person, NULL);
  1554     assert(int_result == SQLITE_OK);
  1555 
  1556     int_result = sqlite3_prepare_v2(_session->db, sql_delete_person,
  1557             (int)strlen(sql_delete_person), &_session->delete_person, NULL);
  1558     assert(int_result == SQLITE_OK);
  1559 
  1560     int_result = sqlite3_prepare_v2(_session->db, sql_exists_person,
  1561             (int)strlen(sql_exists_person), &_session->exists_person, NULL);
  1562     assert(int_result == SQLITE_OK);
  1563 
  1564     int_result = sqlite3_prepare_v2(_session->db, sql_set_as_pEp_user,
  1565             (int)strlen(sql_set_as_pEp_user), &_session->set_as_pEp_user, NULL);
  1566     assert(int_result == SQLITE_OK);
  1567     
  1568     int_result = sqlite3_prepare_v2(_session->db, sql_is_pEp_user,
  1569             (int)strlen(sql_is_pEp_user), &_session->is_pEp_user, NULL);
  1570     assert(int_result == SQLITE_OK);
  1571 
  1572     int_result = sqlite3_prepare_v2(_session->db, sql_add_into_social_graph,
  1573             (int)strlen(sql_add_into_social_graph), &_session->add_into_social_graph, NULL);
  1574     assert(int_result == SQLITE_OK);
  1575 
  1576     int_result = sqlite3_prepare_v2(_session->db, 
  1577             sql_get_own_address_binding_from_contact,
  1578             (int)strlen(sql_get_own_address_binding_from_contact), 
  1579             &_session->get_own_address_binding_from_contact, NULL);
  1580     assert(int_result == SQLITE_OK);
  1581 
  1582     int_result = sqlite3_prepare_v2(_session->db, 
  1583             sql_set_revoke_contact_as_notified,
  1584             (int)strlen(sql_set_revoke_contact_as_notified), 
  1585             &_session->set_revoke_contact_as_notified, NULL);
  1586     assert(int_result == SQLITE_OK);
  1587 
  1588     int_result = sqlite3_prepare_v2(_session->db, 
  1589             sql_get_contacted_ids_from_revoke_fpr,
  1590             (int)strlen(sql_get_contacted_ids_from_revoke_fpr), 
  1591             &_session->get_contacted_ids_from_revoke_fpr, NULL);
  1592     assert(int_result == SQLITE_OK);
  1593 
  1594     int_result = sqlite3_prepare_v2(_session->db, 
  1595             sql_was_id_for_revoke_contacted,
  1596             (int)strlen(sql_was_id_for_revoke_contacted), 
  1597             &_session->was_id_for_revoke_contacted, NULL);
  1598     assert(int_result == SQLITE_OK);
  1599 
  1600     int_result = sqlite3_prepare_v2(_session->db, 
  1601             sql_get_last_contacted,
  1602             (int)strlen(sql_get_last_contacted), 
  1603             &_session->get_last_contacted, NULL);
  1604     assert(int_result == SQLITE_OK);
  1605 
  1606     int_result = sqlite3_prepare_v2(_session->db, 
  1607             sql_get_own_address_binding_from_contact,
  1608             (int)strlen(sql_get_own_address_binding_from_contact), 
  1609             &_session->get_own_address_binding_from_contact, NULL);
  1610     assert(int_result == SQLITE_OK);
  1611 
  1612     int_result = sqlite3_prepare_v2(_session->db, sql_set_pgp_keypair,
  1613             (int)strlen(sql_set_pgp_keypair), &_session->set_pgp_keypair,
  1614             NULL);
  1615     assert(int_result == SQLITE_OK);
  1616 
  1617     int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_entry,
  1618             (int)strlen(sql_set_identity_entry), &_session->set_identity_entry, NULL);
  1619     assert(int_result == SQLITE_OK);
  1620 
  1621     int_result = sqlite3_prepare_v2(_session->db, sql_update_identity_entry,
  1622             (int)strlen(sql_update_identity_entry), &_session->update_identity_entry, NULL);
  1623     assert(int_result == SQLITE_OK);
  1624 
  1625     int_result = sqlite3_prepare_v2(_session->db, sql_exists_identity_entry,
  1626             (int)strlen(sql_exists_identity_entry), &_session->exists_identity_entry, NULL);
  1627     assert(int_result == SQLITE_OK);
  1628 
  1629     int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_flags,
  1630             (int)strlen(sql_set_identity_flags), &_session->set_identity_flags,
  1631             NULL);
  1632     assert(int_result == SQLITE_OK);
  1633 
  1634     int_result = sqlite3_prepare_v2(_session->db, sql_unset_identity_flags,
  1635             (int)strlen(sql_unset_identity_flags), &_session->unset_identity_flags,
  1636             NULL);
  1637     assert(int_result == SQLITE_OK);
  1638 
  1639     int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
  1640             (int)strlen(sql_set_trust), &_session->set_trust, NULL);
  1641     assert(int_result == SQLITE_OK);
  1642 
  1643     int_result = sqlite3_prepare_v2(_session->db, sql_update_trust,
  1644             (int)strlen(sql_update_trust), &_session->update_trust, NULL);
  1645     assert(int_result == SQLITE_OK);
  1646 
  1647     int_result = sqlite3_prepare_v2(_session->db, sql_update_trust_to_pEp,
  1648             (int)strlen(sql_update_trust_to_pEp), &_session->update_trust_to_pEp, NULL);
  1649     assert(int_result == SQLITE_OK);
  1650 
  1651     int_result = sqlite3_prepare_v2(_session->db, sql_exists_trust_entry,
  1652                  (int)strlen(sql_exists_trust_entry), &_session->exists_trust_entry, NULL);
  1653     assert(int_result == SQLITE_OK);
  1654 
  1655     int_result = sqlite3_prepare_v2(_session->db, sql_update_trust_for_fpr,
  1656             (int)strlen(sql_update_trust_for_fpr), &_session->update_trust_for_fpr, NULL);
  1657     assert(int_result == SQLITE_OK);
  1658 
  1659     int_result = sqlite3_prepare_v2(_session->db, sql_get_trust,
  1660             (int)strlen(sql_get_trust), &_session->get_trust, NULL);
  1661     assert(int_result == SQLITE_OK);
  1662 
  1663     int_result = sqlite3_prepare_v2(_session->db, sql_get_trust_by_userid,
  1664             (int)strlen(sql_get_trust_by_userid), &_session->get_trust_by_userid, NULL);
  1665     assert(int_result == SQLITE_OK);
  1666 
  1667     int_result = sqlite3_prepare_v2(_session->db, sql_least_trust,
  1668             (int)strlen(sql_least_trust), &_session->least_trust, NULL);
  1669     assert(int_result == SQLITE_OK);
  1670 
  1671     int_result = sqlite3_prepare_v2(_session->db, sql_mark_as_compromised,
  1672             (int)strlen(sql_mark_as_compromised), &_session->mark_compromised,
  1673             NULL);
  1674     assert(int_result == SQLITE_OK);
  1675 
  1676     int_result = sqlite3_prepare_v2(_session->db, sql_crashdump,
  1677             (int)strlen(sql_crashdump), &_session->crashdump, NULL);
  1678     assert(int_result == SQLITE_OK);
  1679 
  1680     int_result = sqlite3_prepare_v2(_session->system_db, sql_languagelist,
  1681             (int)strlen(sql_languagelist), &_session->languagelist, NULL);
  1682     assert(int_result == SQLITE_OK);
  1683 
  1684     int_result = sqlite3_prepare_v2(_session->system_db, sql_i18n_token,
  1685             (int)strlen(sql_i18n_token), &_session->i18n_token, NULL);
  1686     assert(int_result == SQLITE_OK);
  1687     
  1688     // blacklist
  1689 
  1690     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_add,
  1691             (int)strlen(sql_blacklist_add), &_session->blacklist_add, NULL);
  1692     assert(int_result == SQLITE_OK);
  1693 
  1694     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_delete,
  1695             (int)strlen(sql_blacklist_delete), &_session->blacklist_delete,
  1696             NULL);
  1697     assert(int_result == SQLITE_OK);
  1698 
  1699     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_is_listed,
  1700             (int)strlen(sql_blacklist_is_listed),
  1701             &_session->blacklist_is_listed, NULL);
  1702     assert(int_result == SQLITE_OK);
  1703 
  1704     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_retrieve,
  1705             (int)strlen(sql_blacklist_retrieve), &_session->blacklist_retrieve,
  1706             NULL);
  1707     assert(int_result == SQLITE_OK);
  1708     
  1709     // Own keys
  1710     
  1711     int_result = sqlite3_prepare_v2(_session->db, sql_own_key_is_listed,
  1712             (int)strlen(sql_own_key_is_listed), &_session->own_key_is_listed,
  1713             NULL);
  1714     assert(int_result == SQLITE_OK);
  1715 
  1716     int_result = sqlite3_prepare_v2(_session->db, sql_is_own_address,
  1717             (int)strlen(sql_is_own_address), &_session->is_own_address,
  1718             NULL);
  1719     assert(int_result == SQLITE_OK);
  1720     
  1721     int_result = sqlite3_prepare_v2(_session->db, sql_own_identities_retrieve,
  1722             (int)strlen(sql_own_identities_retrieve),
  1723             &_session->own_identities_retrieve, NULL);
  1724     assert(int_result == SQLITE_OK);
  1725  
  1726     int_result = sqlite3_prepare_v2(_session->db, sql_own_keys_retrieve,
  1727             (int)strlen(sql_own_keys_retrieve),
  1728             &_session->own_keys_retrieve, NULL);
  1729     assert(int_result == SQLITE_OK);
  1730  
  1731     // int_result = sqlite3_prepare_v2(_session->db, sql_set_own_key,
  1732     //         (int)strlen(sql_set_own_key),
  1733     //         &_session->set_own_key, NULL);
  1734     // assert(int_result == SQLITE_OK);
  1735  
  1736     // Sequence
  1737 
  1738     int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value1,
  1739             (int)strlen(sql_sequence_value1), &_session->sequence_value1,
  1740             NULL);
  1741     assert(int_result == SQLITE_OK);
  1742 
  1743     int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value2,
  1744             (int)strlen(sql_sequence_value2), &_session->sequence_value2,
  1745             NULL);
  1746     assert(int_result == SQLITE_OK);
  1747 
  1748     // Revocation tracking
  1749     
  1750     int_result = sqlite3_prepare_v2(_session->db, sql_set_revoked,
  1751             (int)strlen(sql_set_revoked), &_session->set_revoked, NULL);
  1752     assert(int_result == SQLITE_OK);
  1753     
  1754     int_result = sqlite3_prepare_v2(_session->db, sql_get_revoked,
  1755             (int)strlen(sql_get_revoked), &_session->get_revoked, NULL);
  1756     assert(int_result == SQLITE_OK);
  1757     
  1758     int_result = sqlite3_prepare_v2(_session->db, sql_get_replacement_fpr,
  1759             (int)strlen(sql_get_replacement_fpr), &_session->get_replacement_fpr, NULL);
  1760     assert(int_result == SQLITE_OK);
  1761 
  1762     int_result = sqlite3_prepare_v2(_session->db, sql_add_mistrusted_key,
  1763             (int)strlen(sql_add_mistrusted_key), &_session->add_mistrusted_key, NULL);
  1764     assert(int_result == SQLITE_OK);
  1765 
  1766     int_result = sqlite3_prepare_v2(_session->db, sql_delete_mistrusted_key,
  1767             (int)strlen(sql_delete_mistrusted_key), &_session->delete_mistrusted_key, NULL);
  1768     assert(int_result == SQLITE_OK);
  1769 
  1770     int_result = sqlite3_prepare_v2(_session->db, sql_is_mistrusted_key,
  1771             (int)strlen(sql_is_mistrusted_key), &_session->is_mistrusted_key, NULL);
  1772     assert(int_result == SQLITE_OK);
  1773     
  1774     status = init_cryptotech(_session, in_first);
  1775     if (status != PEP_STATUS_OK)
  1776         goto pEp_error;
  1777 
  1778     status = init_transport_system(_session, in_first);
  1779     if (status != PEP_STATUS_OK)
  1780         goto pEp_error;
  1781 
  1782     status = log_event(_session, "init", "pEp " PEP_ENGINE_VERSION, NULL, NULL);
  1783     if (status != PEP_STATUS_OK)
  1784         goto pEp_error;
  1785 
  1786     // runtime config
  1787 
  1788     if (very_first)
  1789     {
  1790 #ifdef USE_GPG
  1791         // On first run, all private keys already present in PGP keyring 
  1792         // are taken as own in order to seamlessly integrate with
  1793         // pre-existing GPG setup.
  1794 
  1795         // Note: earlier fears about danger because of DB reinitialisation should
  1796         // be a non-issue here, as we ONLY take the ultimately trusted keys now.
  1797         // Thus, unless the user has assigned ultimate trust through PGP, there is
  1798         // no chance of automatically imported pEp keys from a previous run making
  1799         // their way into PEP trusted status without explicit action (Bare imported
  1800         // private keys have an 'unknown' trust designation in PGP).
  1801 
  1802         // We don't really worry about the status here.
  1803         status = pgp_import_ultimately_trusted_keypairs(_session);        
  1804 #endif // USE_GPG
  1805     }
  1806 
  1807     *session = _session;
  1808     
  1809     // Note: Following statement is NOT for any cryptographic/secure functionality; it is
  1810     //       ONLY used for some randomness in generated outer message ID, which are
  1811     //       required by the RFC to be globally unique!
  1812     srand((unsigned int) time(NULL));
  1813     
  1814     return PEP_STATUS_OK;
  1815 
  1816 enomem:
  1817     status = PEP_OUT_OF_MEMORY;
  1818 
  1819 pEp_error:
  1820     release(_session);
  1821     return status;
  1822 }
  1823 
  1824 DYNAMIC_API void release(PEP_SESSION session)
  1825 {
  1826     bool out_last = false;
  1827     int _count = --init_count;
  1828     
  1829     assert(_count >= -1);
  1830     assert(session);
  1831 
  1832     if (!((_count >= -1) && session))
  1833         return;
  1834 
  1835     // a small race condition but still a race condition
  1836     // mitigated by calling caveat (see documentation)
  1837     // (release() is to be guarded by a mutex by the caller)
  1838     if (_count == -1)
  1839         out_last = true;
  1840 
  1841     if (session) {
  1842         free_Sync_state(session);
  1843 
  1844         if (session->db) {
  1845             if (session->log)
  1846                 sqlite3_finalize(session->log);
  1847             if (session->trustword)
  1848                 sqlite3_finalize(session->trustword);
  1849             if (session->get_identity)
  1850                 sqlite3_finalize(session->get_identity);
  1851             if (session->get_identity_without_trust_check)
  1852                 sqlite3_finalize(session->get_identity_without_trust_check);
  1853             if (session->get_identities_by_address)
  1854                 sqlite3_finalize(session->get_identities_by_address);            
  1855             if (session->get_identities_by_userid)
  1856                 sqlite3_finalize(session->get_identities_by_userid);                
  1857             if (session->get_identities_by_main_key_id)
  1858                 sqlite3_finalize(session->get_identities_by_main_key_id);                                
  1859             if (session->get_user_default_key)
  1860                 sqlite3_finalize(session->get_user_default_key);
  1861             if (session->get_all_keys_for_user)
  1862                 sqlite3_finalize(session->get_all_keys_for_user);                        
  1863             if (session->get_default_own_userid)
  1864                 sqlite3_finalize(session->get_default_own_userid);
  1865             if (session->get_userid_alias_default)
  1866                 sqlite3_finalize(session->get_userid_alias_default);
  1867             if (session->add_userid_alias)
  1868                 sqlite3_finalize(session->add_userid_alias);
  1869             if (session->replace_identities_fpr)
  1870                 sqlite3_finalize(session->replace_identities_fpr);        
  1871             if (session->remove_fpr_as_default)
  1872                 sqlite3_finalize(session->remove_fpr_as_default);            
  1873             if (session->set_person)
  1874                 sqlite3_finalize(session->set_person);
  1875             if (session->delete_person)
  1876                 sqlite3_finalize(session->delete_person);                
  1877             if (session->set_as_pEp_user)
  1878                 sqlite3_finalize(session->set_as_pEp_user);
  1879             if (session->is_pEp_user)
  1880                 sqlite3_finalize(session->is_pEp_user);
  1881             if (session->exists_person)
  1882                 sqlite3_finalize(session->exists_person);
  1883             if (session->add_into_social_graph)
  1884                 sqlite3_finalize(session->add_into_social_graph);  
  1885             if (session->get_own_address_binding_from_contact)
  1886                 sqlite3_finalize(session->get_own_address_binding_from_contact);  
  1887             if (session->set_revoke_contact_as_notified)
  1888                 sqlite3_finalize(session->set_revoke_contact_as_notified);  
  1889             if (session->get_contacted_ids_from_revoke_fpr)
  1890                 sqlite3_finalize(session->get_contacted_ids_from_revoke_fpr);  
  1891             if (session->was_id_for_revoke_contacted)
  1892                 sqlite3_finalize(session->was_id_for_revoke_contacted);   
  1893             if (session->get_last_contacted)
  1894                 sqlite3_finalize(session->get_last_contacted);                                       
  1895             if (session->set_pgp_keypair)
  1896                 sqlite3_finalize(session->set_pgp_keypair);
  1897             if (session->exists_identity_entry)
  1898                 sqlite3_finalize(session->exists_identity_entry);                
  1899             if (session->set_identity_entry)
  1900                 sqlite3_finalize(session->set_identity_entry);
  1901             if (session->update_identity_entry)
  1902                 sqlite3_finalize(session->update_identity_entry);    
  1903             if (session->set_identity_flags)
  1904                 sqlite3_finalize(session->set_identity_flags);
  1905             if (session->unset_identity_flags)
  1906                 sqlite3_finalize(session->unset_identity_flags);
  1907             if (session->exists_trust_entry)
  1908                 sqlite3_finalize(session->exists_trust_entry);                                
  1909             if (session->set_trust)
  1910                 sqlite3_finalize(session->set_trust);
  1911             if (session->update_trust)
  1912                 sqlite3_finalize(session->update_trust);
  1913             if (session->update_trust_to_pEp)
  1914                 sqlite3_finalize(session->update_trust_to_pEp);                                                
  1915             if (session->update_trust_for_fpr)
  1916                 sqlite3_finalize(session->update_trust_for_fpr);
  1917             if (session->get_trust)
  1918                 sqlite3_finalize(session->get_trust);
  1919             if (session->get_trust_by_userid)
  1920                 sqlite3_finalize(session->get_trust_by_userid);                
  1921             if (session->least_trust)
  1922                 sqlite3_finalize(session->least_trust);
  1923             if (session->mark_compromised)
  1924                 sqlite3_finalize(session->mark_compromised);
  1925             if (session->crashdump)
  1926                 sqlite3_finalize(session->crashdump);
  1927             if (session->languagelist)
  1928                 sqlite3_finalize(session->languagelist);
  1929             if (session->i18n_token)
  1930                 sqlite3_finalize(session->i18n_token);
  1931             if (session->replace_userid)
  1932                 sqlite3_finalize(session->replace_userid);
  1933             if (session->delete_key)
  1934                 sqlite3_finalize(session->delete_key);                
  1935             if (session->replace_main_user_fpr)
  1936                 sqlite3_finalize(session->replace_main_user_fpr);                
  1937             if (session->get_main_user_fpr)
  1938                 sqlite3_finalize(session->get_main_user_fpr);
  1939             if (session->refresh_userid_default_key)
  1940                 sqlite3_finalize(session->refresh_userid_default_key);
  1941             if (session->blacklist_add)
  1942                 sqlite3_finalize(session->blacklist_add);
  1943             if (session->blacklist_delete)
  1944                 sqlite3_finalize(session->blacklist_delete);
  1945             if (session->blacklist_is_listed)
  1946                 sqlite3_finalize(session->blacklist_is_listed);
  1947             if (session->blacklist_retrieve)
  1948                 sqlite3_finalize(session->blacklist_retrieve);
  1949             if (session->own_key_is_listed)
  1950                 sqlite3_finalize(session->own_key_is_listed);
  1951             if (session->is_own_address)
  1952                 sqlite3_finalize(session->is_own_address);
  1953             if (session->own_identities_retrieve)
  1954                 sqlite3_finalize(session->own_identities_retrieve);
  1955             if (session->own_keys_retrieve)
  1956                 sqlite3_finalize(session->own_keys_retrieve);
  1957             // if (session->set_own_key)
  1958             //     sqlite3_finalize(session->set_own_key);
  1959             if (session->sequence_value1)
  1960                 sqlite3_finalize(session->sequence_value1);
  1961             if (session->sequence_value2)
  1962                 sqlite3_finalize(session->sequence_value2);
  1963             if (session->set_revoked)
  1964                 sqlite3_finalize(session->set_revoked);
  1965             if (session->get_revoked)
  1966                 sqlite3_finalize(session->get_revoked);
  1967             if (session->get_replacement_fpr)
  1968                 sqlite3_finalize(session->get_replacement_fpr);                
  1969             if (session->add_mistrusted_key)
  1970                 sqlite3_finalize(session->add_mistrusted_key);
  1971             if (session->delete_mistrusted_key)
  1972                 sqlite3_finalize(session->delete_mistrusted_key);
  1973             if (session->is_mistrusted_key)
  1974                 sqlite3_finalize(session->is_mistrusted_key);
  1975                 
  1976             if (session->db) {
  1977                 sqlite3_exec(        
  1978                     session->db,
  1979                     "PRAGMA optimize;\n",
  1980                     NULL,
  1981                     NULL,
  1982                     NULL
  1983                 );
  1984                 sqlite3_close_v2(session->db);
  1985             }
  1986             if (session->system_db)
  1987                 sqlite3_close_v2(session->system_db);
  1988         }
  1989 
  1990         release_transport_system(session, out_last);
  1991         release_cryptotech(session, out_last);
  1992 
  1993 #ifdef DEBUG_ERRORSTACK
  1994         free_stringlist(session->errorstack);
  1995 #endif
  1996         free(session);
  1997     }
  1998 }
  1999 
  2000 DYNAMIC_API void config_passive_mode(PEP_SESSION session, bool enable)
  2001 {
  2002     assert(session);
  2003     if (session)
  2004         session->passive_mode = enable;
  2005 }
  2006 
  2007 DYNAMIC_API void config_unencrypted_subject(PEP_SESSION session, bool enable)
  2008 {
  2009     assert(session);
  2010     if (session)
  2011         session->unencrypted_subject = enable;
  2012 }
  2013 
  2014 DYNAMIC_API void config_service_log(PEP_SESSION session, bool enable)
  2015 {
  2016     assert(session);
  2017     if (session)
  2018         session->service_log = enable;
  2019 }
  2020 
  2021 DYNAMIC_API PEP_STATUS log_event(
  2022         PEP_SESSION session,
  2023         const char *title,
  2024         const char *entity,
  2025         const char *description,
  2026         const char *comment
  2027     )
  2028 {
  2029 
  2030 // N.B. If testing (so NDEBUG not defined) but this message is spam,
  2031 //      put -D_PEP_SERVICE_LOG_OFF into CFLAGS/CXXFLAGS     
  2032 #if !defined(NDEBUG) && !defined(_PEP_SERVICE_LOG_OFF)
  2033     fprintf(stdout, "\n*** %s %s %s %s\n", title, entity, description, comment);
  2034     session->service_log = true;
  2035 #endif
  2036 
  2037     // PEP_STATUS status = PEP_STATUS_OK;
  2038     // int result;
  2039     // 
  2040     // assert(session);
  2041     // assert(title);
  2042     // assert(entity);
  2043     // 
  2044     // if (!(session && title && entity))
  2045     //     return PEP_ILLEGAL_VALUE;
  2046     // 
  2047     // sqlite3_reset(session->log);
  2048     // sqlite3_bind_text(session->log, 1, title, -1, SQLITE_STATIC);
  2049     // sqlite3_bind_text(session->log, 2, entity, -1, SQLITE_STATIC);
  2050     // if (description)
  2051     //     sqlite3_bind_text(session->log, 3, description, -1, SQLITE_STATIC);
  2052     // else
  2053     //     sqlite3_bind_null(session->log, 3);
  2054     // if (comment)
  2055     //     sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
  2056     // else
  2057     //     sqlite3_bind_null(session->log, 4);
  2058     // result = sqlite3_step(session->log);
  2059     // sqlite3_reset(session->log);
  2060     // 
  2061     return PEP_STATUS_OK; // We ignore errors for this function.
  2062 }
  2063 
  2064 DYNAMIC_API PEP_STATUS log_service(
  2065         PEP_SESSION session,
  2066         const char *title,
  2067         const char *entity,
  2068         const char *description,
  2069         const char *comment
  2070     )
  2071 {
  2072     assert(session);
  2073     if (!session)
  2074         return PEP_ILLEGAL_VALUE;
  2075 
  2076     if (session->service_log)
  2077         return log_event(session, title, entity, description, comment);
  2078     else
  2079         return PEP_STATUS_OK;
  2080 }
  2081 
  2082 DYNAMIC_API PEP_STATUS trustword(
  2083             PEP_SESSION session, uint16_t value, const char *lang,
  2084             char **word, size_t *wsize
  2085         )
  2086 {
  2087     PEP_STATUS status = PEP_STATUS_OK;
  2088 
  2089     assert(session);
  2090     assert(word);
  2091     assert(wsize);
  2092 
  2093     if (!(session && word && wsize))
  2094         return PEP_ILLEGAL_VALUE;
  2095 
  2096     *word = NULL;
  2097     *wsize = 0;
  2098 
  2099     if (lang == NULL)
  2100         lang = "en";
  2101 
  2102     assert((lang[0] >= 'A' && lang[0] <= 'Z')
  2103             || (lang[0] >= 'a' && lang[0] <= 'z'));
  2104     assert((lang[1] >= 'A' && lang[1] <= 'Z')
  2105             || (lang[1] >= 'a' && lang[1] <= 'z'));
  2106     assert(lang[2] == 0);
  2107 
  2108     sqlite3_reset(session->trustword);
  2109     sqlite3_bind_text(session->trustword, 1, lang, -1, SQLITE_STATIC);
  2110     sqlite3_bind_int(session->trustword, 2, value);
  2111 
  2112     const int result = sqlite3_step(session->trustword);
  2113     if (result == SQLITE_ROW) {
  2114         *word = strdup((const char *) sqlite3_column_text(session->trustword,
  2115                     1));
  2116         if (*word)
  2117             *wsize = sqlite3_column_bytes(session->trustword, 1);
  2118         else
  2119             status = PEP_OUT_OF_MEMORY;
  2120     } else
  2121         status = PEP_TRUSTWORD_NOT_FOUND;
  2122 
  2123     sqlite3_reset(session->trustword);
  2124     return status;
  2125 }
  2126 
  2127 DYNAMIC_API PEP_STATUS trustwords(
  2128         PEP_SESSION session, const char *fingerprint, const char *lang,
  2129         char **words, size_t *wsize, int max_words
  2130     )
  2131 {
  2132     const char *source = fingerprint;
  2133 
  2134     assert(session);
  2135     assert(fingerprint);
  2136     assert(words);
  2137     assert(wsize);
  2138     assert(max_words >= 0);
  2139 
  2140     if (!(session && fingerprint && words && wsize && max_words >= 0))
  2141         return PEP_ILLEGAL_VALUE;
  2142 
  2143     *words = NULL;
  2144     *wsize = 0;
  2145 
  2146     char *buffer = calloc(1, MAX_TRUSTWORDS_SPACE);
  2147     assert(buffer);
  2148     if (buffer == NULL)
  2149         return PEP_OUT_OF_MEMORY;
  2150     char *dest = buffer;
  2151 
  2152     const size_t fsize = strlen(fingerprint);
  2153 
  2154     if (!lang || !lang[0])
  2155         lang = "en";
  2156 
  2157     assert((lang[0] >= 'A' && lang[0] <= 'Z')
  2158             || (lang[0] >= 'a' && lang[0] <= 'z'));
  2159     assert((lang[1] >= 'A' && lang[1] <= 'Z')
  2160             || (lang[1] >= 'a' && lang[1] <= 'z'));
  2161     assert(lang[2] == 0);
  2162 
  2163     int n_words = 0;
  2164     while (source < fingerprint + fsize) {
  2165         PEP_STATUS _status;
  2166         uint16_t value;
  2167         char *word = NULL;
  2168         size_t _wsize = 0;
  2169         int j;
  2170 
  2171         for (value=0, j=0; j < 4 && source < fingerprint + fsize; ) {
  2172             if (*source >= 'a' && *source <= 'f')
  2173                 value += (*source - 'a' + 10) << (3 - j++) * 4;
  2174             else if (*source >= 'A' && *source <= 'F')
  2175                 value += (*source - 'A' + 10) << (3 - j++) * 4;
  2176             else if (*source >= '0' && *source <= '9')
  2177                 value += (*source - '0') << (3 - j++) * 4;
  2178             
  2179             source++;
  2180         }
  2181 
  2182         _status = trustword(session, value, lang, &word, &_wsize);
  2183         if (_status == PEP_OUT_OF_MEMORY) {
  2184             free(buffer);
  2185             return PEP_OUT_OF_MEMORY;
  2186         }
  2187         if (word == NULL) {
  2188             free(buffer);
  2189             return PEP_TRUSTWORD_NOT_FOUND;
  2190         }
  2191 
  2192         if (dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1) {
  2193             strncpy(dest, word, _wsize);
  2194             free(word);
  2195             dest += _wsize;
  2196         }
  2197         else {
  2198             free(word);
  2199             break; // buffer full
  2200         }
  2201 
  2202         if (source < fingerprint + fsize
  2203                 && dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1)
  2204             *dest++ = ' ';
  2205 
  2206         ++n_words;
  2207         if (max_words && n_words >= max_words)
  2208             break;
  2209     }
  2210 
  2211     *words = buffer;
  2212     *wsize = dest - buffer;
  2213     return PEP_STATUS_OK;
  2214 }
  2215 
  2216 pEp_identity *new_identity(
  2217         const char *address, const char *fpr, const char *user_id,
  2218         const char *username
  2219     )
  2220 {
  2221     pEp_identity *result = calloc(1, sizeof(pEp_identity));
  2222     assert(result);
  2223     if (result) {
  2224         if (address) {
  2225             result->address = strdup(address);
  2226             assert(result->address);
  2227             if (result->address == NULL) {
  2228                 free(result);
  2229                 return NULL;
  2230             }
  2231         }
  2232         if (fpr) {
  2233             result->fpr = strdup(fpr);
  2234             assert(result->fpr);
  2235             if (result->fpr == NULL) {
  2236                 free_identity(result);
  2237                 return NULL;
  2238             }
  2239         }
  2240         if (user_id) {
  2241             result->user_id = strdup(user_id);
  2242             assert(result->user_id);
  2243             if (result->user_id == NULL) {
  2244                 free_identity(result);
  2245                 return NULL;
  2246             }
  2247         }
  2248         if (username) {
  2249             result->username = strdup(username);
  2250             assert(result->username);
  2251             if (result->username == NULL) {
  2252                 free_identity(result);
  2253                 return NULL;
  2254             }
  2255         }
  2256     }
  2257     return result;
  2258 }
  2259 
  2260 pEp_identity *identity_dup(const pEp_identity *src)
  2261 {
  2262     assert(src);
  2263 
  2264     pEp_identity *dup = new_identity(src->address, src->fpr, src->user_id,
  2265             src->username);
  2266     assert(dup);
  2267     if (dup == NULL)
  2268         return NULL;
  2269     
  2270     dup->comm_type = src->comm_type;
  2271     dup->lang[0] = src->lang[0];
  2272     dup->lang[1] = src->lang[1];
  2273     dup->lang[2] = 0;
  2274     dup->flags = src->flags;
  2275     dup->me = src->me;
  2276     
  2277     return dup;
  2278 }
  2279 
  2280 void free_identity(pEp_identity *identity)
  2281 {
  2282     if (identity) {
  2283         free(identity->address);
  2284         free(identity->fpr);
  2285         free(identity->user_id);
  2286         free(identity->username);
  2287         free(identity);
  2288     }
  2289 }
  2290 
  2291 DYNAMIC_API PEP_STATUS get_default_own_userid(
  2292         PEP_SESSION session, 
  2293         char** userid
  2294     )
  2295 {
  2296     assert(session);
  2297     assert(userid);
  2298     
  2299     if (!session || !userid)
  2300         return PEP_ILLEGAL_VALUE;
  2301         
  2302     PEP_STATUS status = PEP_STATUS_OK;
  2303     char* retval = NULL;
  2304     
  2305     sqlite3_reset(session->get_default_own_userid);
  2306 
  2307     const int result = sqlite3_step(session->get_default_own_userid);
  2308     const char* id;
  2309     
  2310     switch (result) {
  2311         case SQLITE_ROW:
  2312             id = (const char *) sqlite3_column_text(session->get_default_own_userid, 0);
  2313             if (!id) {
  2314                 // Shouldn't happen.
  2315                 status = PEP_UNKNOWN_ERROR;
  2316             }
  2317             else {
  2318                 retval = strdup(id);
  2319                 if (!retval)
  2320                     status = PEP_OUT_OF_MEMORY;
  2321             }
  2322             break;
  2323         default:
  2324             // Technically true, given how we find it, but FIXME we need a more descriptive error
  2325             status = PEP_CANNOT_FIND_IDENTITY;
  2326     }
  2327 
  2328     *userid = retval;
  2329 
  2330     sqlite3_reset(session->get_default_own_userid);
  2331     
  2332     return status;
  2333 }
  2334 
  2335 DYNAMIC_API PEP_STATUS get_userid_alias_default(
  2336         PEP_SESSION session, 
  2337         const char* alias_id,
  2338         char** default_id) {
  2339             
  2340     assert(session);
  2341     assert(alias_id);
  2342     assert(alias_id[0]);
  2343     assert(default_id);
  2344 
  2345     if (!(session && alias_id && alias_id[0] && default_id))
  2346         return PEP_ILLEGAL_VALUE;
  2347 
  2348     PEP_STATUS status = PEP_STATUS_OK;
  2349     char* retval = NULL;
  2350 
  2351     sqlite3_reset(session->get_userid_alias_default);
  2352     sqlite3_bind_text(session->get_userid_alias_default, 1, alias_id, -1, SQLITE_STATIC);
  2353 
  2354     const char* tempid;
  2355     
  2356     const int result = sqlite3_step(session->get_userid_alias_default);
  2357     switch (result) {
  2358     case SQLITE_ROW:
  2359         tempid = (const char *) sqlite3_column_text(session->get_userid_alias_default, 0);
  2360         if (tempid) {
  2361             retval = strdup(tempid);
  2362             assert(retval);
  2363             if (retval == NULL)
  2364                 return PEP_OUT_OF_MEMORY;
  2365         }
  2366     
  2367         *default_id = retval;
  2368         break;
  2369     default:
  2370         status = PEP_CANNOT_FIND_ALIAS;
  2371         *default_id = NULL;
  2372     }
  2373 
  2374     sqlite3_reset(session->get_userid_alias_default);
  2375     return status;            
  2376 }
  2377 
  2378 DYNAMIC_API PEP_STATUS set_userid_alias (
  2379         PEP_SESSION session, 
  2380         const char* default_id,
  2381         const char* alias_id) {
  2382             
  2383     int result;
  2384 
  2385     assert(session);
  2386     assert(default_id);
  2387     assert(alias_id);
  2388 
  2389     if (!(session && default_id && alias_id && 
  2390           default_id[0] != '\0' && alias_id[0] != '\0'))
  2391         return PEP_ILLEGAL_VALUE;
  2392     
  2393     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  2394 
  2395     sqlite3_reset(session->add_userid_alias);
  2396     sqlite3_bind_text(session->add_userid_alias, 1, default_id, -1,
  2397             SQLITE_STATIC);
  2398     sqlite3_bind_text(session->add_userid_alias, 2, alias_id, -1,
  2399             SQLITE_STATIC);
  2400         
  2401     result = sqlite3_step(session->add_userid_alias);
  2402 
  2403     sqlite3_reset(session->add_userid_alias);
  2404     if (result != SQLITE_DONE) {
  2405         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);        
  2406         return PEP_CANNOT_SET_ALIAS;
  2407     }
  2408     sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  2409         
  2410 
  2411     return PEP_STATUS_OK;
  2412 }
  2413 
  2414 DYNAMIC_API PEP_STATUS get_identity(
  2415         PEP_SESSION session,
  2416         const char *address,
  2417         const char *user_id,
  2418         pEp_identity **identity
  2419     )
  2420 {
  2421     PEP_STATUS status = PEP_STATUS_OK;
  2422     static pEp_identity *_identity;
  2423 
  2424     assert(session);
  2425     assert(address);
  2426     assert(address[0]);
  2427     assert(identity);
  2428 
  2429     if (!(session && address && address[0] && identity))
  2430         return PEP_ILLEGAL_VALUE;
  2431 
  2432     *identity = NULL;
  2433 
  2434     sqlite3_reset(session->get_identity);
  2435     sqlite3_bind_text(session->get_identity, 1, address, -1, SQLITE_STATIC);
  2436     sqlite3_bind_text(session->get_identity, 2, user_id, -1, SQLITE_STATIC);
  2437 
  2438     const int result = sqlite3_step(session->get_identity);
  2439     switch (result) {
  2440     case SQLITE_ROW:
  2441         _identity = new_identity(
  2442                 address,
  2443                 (const char *) sqlite3_column_text(session->get_identity, 0),
  2444                 user_id,
  2445                 (const char *) sqlite3_column_text(session->get_identity, 1)
  2446                 );
  2447         assert(_identity);
  2448         if (_identity == NULL) {
  2449             sqlite3_reset(session->get_identity);
  2450             return PEP_OUT_OF_MEMORY;
  2451         }
  2452 
  2453         _identity->comm_type = (PEP_comm_type)
  2454             sqlite3_column_int(session->get_identity, 2);
  2455         const char* const _lang = (const char *)
  2456             sqlite3_column_text(session->get_identity, 3);
  2457         if (_lang && _lang[0]) {
  2458             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  2459             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  2460             assert(_lang[2] == 0);
  2461             _identity->lang[0] = _lang[0];
  2462             _identity->lang[1] = _lang[1];
  2463             _identity->lang[2] = 0;
  2464         }
  2465         _identity->flags = (unsigned int)
  2466             sqlite3_column_int(session->get_identity, 4);
  2467         _identity->me = (unsigned int)
  2468             sqlite3_column_int(session->get_identity, 5);
  2469     
  2470         *identity = _identity;
  2471         break;
  2472     default:
  2473         sqlite3_reset(session->get_identity);
  2474         status = PEP_CANNOT_FIND_IDENTITY;
  2475         *identity = NULL;
  2476     }
  2477 
  2478     sqlite3_reset(session->get_identity);
  2479     return status;
  2480 }
  2481 
  2482 PEP_STATUS get_identities_by_userid(
  2483         PEP_SESSION session,
  2484         const char *user_id,
  2485         identity_list **identities
  2486     )
  2487 {
  2488     if (!session || !identities || EMPTYSTR(user_id))
  2489         return PEP_ILLEGAL_VALUE;
  2490 
  2491     PEP_STATUS status = PEP_STATUS_OK;
  2492     
  2493     pEp_identity* ident = NULL;
  2494 
  2495     *identities = new_identity_list(NULL);
  2496 
  2497     sqlite3_reset(session->get_identities_by_userid);
  2498     sqlite3_bind_text(session->get_identities_by_userid, 1, user_id, -1, SQLITE_STATIC);
  2499 
  2500     int result = -1;
  2501     while ((result = sqlite3_step(session->get_identities_by_userid)) == SQLITE_ROW) {
  2502             // "select address, fpr, username, comm_type, lang,"
  2503             // "   identity.flags | pgp_keypair.flags,"
  2504             // "   is_own"
  2505             // "   from identity"
  2506             // "   join person on id = identity.user_id"
  2507             // "   join pgp_keypair on fpr = identity.main_key_id"
  2508             // "   join trust on id = trust.user_id"
  2509             // "       and pgp_keypair_fpr = identity.main_key_id"    
  2510             // "   where identity.user_id = ?1" 
  2511             // "   order by is_own desc, "
  2512             // "   timestamp desc; ";
  2513 
  2514         ident = new_identity(
  2515                     (const char *) sqlite3_column_text(session->get_identities_by_userid, 0),
  2516                     (const char *) sqlite3_column_text(session->get_identities_by_userid, 1),                
  2517                     user_id,
  2518                     (const char *) sqlite3_column_text(session->get_identities_by_userid, 2)
  2519                 );
  2520                 
  2521         assert(ident);
  2522         if (ident == NULL) {
  2523             sqlite3_reset(session->get_identities_by_userid);
  2524             return PEP_OUT_OF_MEMORY;
  2525         }
  2526 
  2527         ident->comm_type = (PEP_comm_type)
  2528             sqlite3_column_int(session->get_identities_by_userid, 3);
  2529         const char* const _lang = (const char *)
  2530             sqlite3_column_text(session->get_identities_by_userid, 4);
  2531         if (_lang && _lang[0]) {
  2532             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  2533             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  2534             assert(_lang[2] == 0);
  2535             ident->lang[0] = _lang[0];
  2536             ident->lang[1] = _lang[1];
  2537             ident->lang[2] = 0;
  2538         }
  2539         ident->flags = (unsigned int)
  2540             sqlite3_column_int(session->get_identities_by_userid, 5);
  2541         ident->me = (unsigned int)
  2542             sqlite3_column_int(session->get_identities_by_userid, 6);
  2543     
  2544         identity_list_add(*identities, ident);
  2545         ident = NULL;
  2546     }
  2547 
  2548     if ((*identities)->ident == NULL) {
  2549         free_identity_list(*identities);
  2550         *identities = NULL;
  2551         status = PEP_CANNOT_FIND_IDENTITY;
  2552     }
  2553             
  2554     sqlite3_reset(session->get_identities_by_userid);
  2555 
  2556     return status;
  2557 }
  2558 
  2559 PEP_STATUS get_identities_by_main_key_id(
  2560         PEP_SESSION session,
  2561         const char *fpr,
  2562         identity_list **identities
  2563     )
  2564 {
  2565     if (!session || !identities || EMPTYSTR(fpr))
  2566         return PEP_ILLEGAL_VALUE;
  2567 
  2568     PEP_STATUS status = PEP_STATUS_OK;
  2569     
  2570     pEp_identity* ident = NULL;
  2571 
  2572     *identities = new_identity_list(NULL);
  2573 
  2574     sqlite3_reset(session->get_identities_by_main_key_id);
  2575     sqlite3_bind_text(session->get_identities_by_main_key_id, 1, fpr, -1, SQLITE_STATIC);
  2576 
  2577     int result = -1;
  2578     
  2579     while ((result = sqlite3_step(session->get_identities_by_main_key_id)) == SQLITE_ROW) {
  2580         ident = new_identity(
  2581                     (const char *) sqlite3_column_text(session->get_identities_by_main_key_id, 0),
  2582                     fpr,
  2583                     (const char *) sqlite3_column_text(session->get_identities_by_main_key_id, 1),                
  2584                     (const char *) sqlite3_column_text(session->get_identities_by_main_key_id, 2)
  2585                 );
  2586                 
  2587         assert(ident);
  2588         if (ident == NULL) {
  2589             sqlite3_reset(session->get_identities_by_main_key_id);
  2590             return PEP_OUT_OF_MEMORY;
  2591         }
  2592 
  2593         ident->comm_type = (PEP_comm_type)
  2594             sqlite3_column_int(session->get_identities_by_main_key_id, 3);
  2595         const char* const _lang = (const char *)
  2596             sqlite3_column_text(session->get_identities_by_main_key_id, 4);
  2597         if (_lang && _lang[0]) {
  2598             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  2599             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  2600             assert(_lang[2] == 0);
  2601             ident->lang[0] = _lang[0];
  2602             ident->lang[1] = _lang[1];
  2603             ident->lang[2] = 0;
  2604         }
  2605         ident->flags = (unsigned int)
  2606             sqlite3_column_int(session->get_identities_by_main_key_id, 5);
  2607         ident->me = (unsigned int)
  2608             sqlite3_column_int(session->get_identities_by_main_key_id, 6);
  2609     
  2610         identity_list_add(*identities, ident);
  2611         ident = NULL;
  2612     }
  2613 
  2614     if ((*identities)->ident == NULL) {
  2615         free_identity_list(*identities);
  2616         *identities = NULL;
  2617         status = PEP_CANNOT_FIND_IDENTITY;
  2618     }
  2619             
  2620     sqlite3_reset(session->get_identities_by_main_key_id);
  2621 
  2622     return status;
  2623 }
  2624 
  2625 PEP_STATUS get_identity_without_trust_check(
  2626         PEP_SESSION session,
  2627         const char *address,
  2628         const char *user_id,
  2629         pEp_identity **identity
  2630     )
  2631 {
  2632     PEP_STATUS status = PEP_STATUS_OK;
  2633     static pEp_identity *_identity;
  2634 
  2635     assert(session);
  2636     assert(address);
  2637     assert(address[0]);
  2638     assert(identity);
  2639 
  2640     if (!(session && address && address[0] && identity))
  2641         return PEP_ILLEGAL_VALUE;
  2642 
  2643     *identity = NULL;
  2644 
  2645     sqlite3_reset(session->get_identity_without_trust_check);
  2646     sqlite3_bind_text(session->get_identity_without_trust_check, 1, address, -1, SQLITE_STATIC);
  2647     sqlite3_bind_text(session->get_identity_without_trust_check, 2, user_id, -1, SQLITE_STATIC);
  2648 
  2649     const int result = sqlite3_step(session->get_identity_without_trust_check);
  2650     switch (result) {
  2651     case SQLITE_ROW:
  2652         _identity = new_identity(
  2653                 address,
  2654                 (const char *) sqlite3_column_text(session->get_identity_without_trust_check, 0),
  2655                 user_id,
  2656                 (const char *) sqlite3_column_text(session->get_identity_without_trust_check, 1)
  2657                 );
  2658         assert(_identity);
  2659         if (_identity == NULL) {
  2660             sqlite3_reset(session->get_identity_without_trust_check);
  2661             return PEP_OUT_OF_MEMORY;
  2662         }
  2663 
  2664         _identity->comm_type = PEP_ct_unknown;
  2665         const char* const _lang = (const char *)
  2666             sqlite3_column_text(session->get_identity_without_trust_check, 2);
  2667         if (_lang && _lang[0]) {
  2668             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  2669             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  2670             assert(_lang[2] == 0);
  2671             _identity->lang[0] = _lang[0];
  2672             _identity->lang[1] = _lang[1];
  2673             _identity->lang[2] = 0;
  2674         }
  2675         _identity->flags = (unsigned int)
  2676             sqlite3_column_int(session->get_identity_without_trust_check, 3);
  2677         _identity->me = (unsigned int)
  2678             sqlite3_column_int(session->get_identity_without_trust_check, 4);
  2679     
  2680         *identity = _identity;
  2681         break;
  2682     default:
  2683         status = PEP_CANNOT_FIND_IDENTITY;
  2684         *identity = NULL;
  2685     }
  2686 
  2687     sqlite3_reset(session->get_identity_without_trust_check);
  2688     return status;
  2689 }
  2690 
  2691 
  2692 PEP_STATUS get_identities_by_address(
  2693         PEP_SESSION session,
  2694         const char *address,
  2695         identity_list** id_list
  2696     )
  2697 {
  2698     assert(session);
  2699     assert(address);
  2700     assert(address[0]);
  2701     assert(id_list);
  2702 
  2703     if (!(session && address && address[0] && id_list))
  2704         return PEP_ILLEGAL_VALUE;
  2705 
  2706     *id_list = NULL;
  2707     identity_list* ident_list = NULL;
  2708 
  2709     sqlite3_reset(session->get_identities_by_address);
  2710     sqlite3_bind_text(session->get_identities_by_address, 1, address, -1, SQLITE_STATIC);
  2711     int result;
  2712 
  2713     while ((result = sqlite3_step(session->get_identities_by_address)) == SQLITE_ROW) {
  2714         //"select user_id, main_key_id, username, comm_type, lang,"
  2715         //"   identity.flags, is_own"
  2716         pEp_identity *ident = new_identity(
  2717                 address,
  2718                 (const char *) sqlite3_column_text(session->get_identities_by_address, 1),
  2719                 (const char *) sqlite3_column_text(session->get_identities_by_address, 0),
  2720                 (const char *) sqlite3_column_text(session->get_identities_by_address, 2)
  2721                 );
  2722         assert(ident);
  2723         if (ident == NULL) {
  2724             sqlite3_reset(session->get_identities_by_address);
  2725             return PEP_OUT_OF_MEMORY;
  2726         }
  2727 
  2728         ident->comm_type = PEP_ct_unknown;
  2729         
  2730         const char* const _lang = (const char *)
  2731             sqlite3_column_text(session->get_identities_by_address, 3);
  2732         if (_lang && _lang[0]) {
  2733             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  2734             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  2735             assert(_lang[2] == 0);
  2736             ident->lang[0] = _lang[0];
  2737             ident->lang[1] = _lang[1];
  2738             ident->lang[2] = 0;
  2739         }
  2740         ident->flags = (unsigned int)
  2741             sqlite3_column_int(session->get_identities_by_address, 4);
  2742         ident->me = (unsigned int)
  2743             sqlite3_column_int(session->get_identities_by_address, 5);
  2744     
  2745         if (ident_list)
  2746             identity_list_add(ident_list, ident);
  2747         else
  2748             ident_list = new_identity_list(ident);
  2749     }
  2750 
  2751     sqlite3_reset(session->get_identities_by_address);
  2752     
  2753     *id_list = ident_list;
  2754     
  2755     if (!ident_list)
  2756         return PEP_CANNOT_FIND_IDENTITY;
  2757     
  2758     return PEP_STATUS_OK;
  2759 }
  2760 
  2761 PEP_STATUS exists_identity_entry(PEP_SESSION session, pEp_identity* identity,
  2762                                  bool* exists) {
  2763     assert(session);
  2764     assert(identity);
  2765     assert(!EMPTYSTR(identity->user_id));        
  2766     assert(!EMPTYSTR(identity->address));
  2767     if (!session || !exists || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->address))
  2768         return PEP_ILLEGAL_VALUE;
  2769     
  2770     *exists = false;
  2771     
  2772     PEP_STATUS status = PEP_STATUS_OK;
  2773     
  2774     sqlite3_reset(session->exists_identity_entry);
  2775     sqlite3_bind_text(session->exists_identity_entry, 1, identity->address, -1,
  2776                       SQLITE_STATIC);
  2777     sqlite3_bind_text(session->exists_identity_entry, 2, identity->user_id, -1,
  2778                       SQLITE_STATIC);
  2779                   
  2780     int result = sqlite3_step(session->exists_identity_entry);
  2781 
  2782     switch (result) {
  2783         case SQLITE_ROW: {
  2784             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2785             *exists = (sqlite3_column_int(session->exists_identity_entry, 0) != 0);
  2786             break;
  2787         }
  2788         default: 
  2789             status = PEP_UNKNOWN_DB_ERROR;
  2790     }
  2791 
  2792     sqlite3_reset(session->exists_identity_entry);
  2793     return status;
  2794 }
  2795 
  2796 PEP_STATUS exists_trust_entry(PEP_SESSION session, pEp_identity* identity,
  2797                               bool* exists) {
  2798     assert(session);
  2799     assert(identity);
  2800     assert(!EMPTYSTR(identity->user_id));        
  2801     assert(!EMPTYSTR(identity->fpr));
  2802     if (!session || !exists || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->fpr))
  2803         return PEP_ILLEGAL_VALUE;
  2804     
  2805     *exists = false;
  2806     
  2807     PEP_STATUS status = PEP_STATUS_OK;
  2808     
  2809     sqlite3_reset(session->exists_trust_entry);
  2810     sqlite3_bind_text(session->exists_trust_entry, 1, identity->user_id, -1,
  2811                       SQLITE_STATIC);
  2812     sqlite3_bind_text(session->exists_trust_entry, 2, identity->fpr, -1,
  2813                       SQLITE_STATIC);
  2814                   
  2815     int result = sqlite3_step(session->exists_trust_entry);
  2816     switch (result) {
  2817         case SQLITE_ROW: {
  2818             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2819             *exists = (sqlite3_column_int(session->exists_trust_entry, 0) != 0);
  2820             break;
  2821         }
  2822         default:
  2823             status = PEP_UNKNOWN_DB_ERROR;
  2824     }
  2825     
  2826     sqlite3_reset(session->exists_trust_entry);
  2827     return status;
  2828 }
  2829 
  2830 PEP_STATUS set_pgp_keypair(PEP_SESSION session, const char* fpr) {
  2831     if (!session || EMPTYSTR(fpr))
  2832         return PEP_ILLEGAL_VALUE;
  2833         
  2834     int result;
  2835     
  2836     sqlite3_reset(session->set_pgp_keypair);
  2837     sqlite3_bind_text(session->set_pgp_keypair, 1, fpr, -1,
  2838             SQLITE_STATIC);
  2839     result = sqlite3_step(session->set_pgp_keypair);
  2840     sqlite3_reset(session->set_pgp_keypair);
  2841     if (result != SQLITE_DONE) {
  2842         return PEP_CANNOT_SET_PGP_KEYPAIR;
  2843     }
  2844     
  2845     return PEP_STATUS_OK;
  2846 }
  2847 
  2848 static PEP_STATUS _set_or_update_trust(PEP_SESSION session,
  2849                                        pEp_identity* identity,
  2850                                        sqlite3_stmt* set_or_update) {
  2851 
  2852     assert(session);
  2853     assert(identity);
  2854     assert(identity->user_id);
  2855     assert(identity->fpr);
  2856     
  2857     if (!session || !identity || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->fpr))
  2858         return PEP_ILLEGAL_VALUE;
  2859         
  2860     PEP_STATUS status = set_pgp_keypair(session, identity->fpr);
  2861     if (status != PEP_STATUS_OK)
  2862         return status;
  2863         
  2864     int result;
  2865                 
  2866     sqlite3_reset(set_or_update);
  2867     sqlite3_bind_text(set_or_update, 1, identity->user_id, -1,
  2868             SQLITE_STATIC);
  2869     sqlite3_bind_text(set_or_update, 2, identity->fpr, -1,
  2870             SQLITE_STATIC);
  2871     sqlite3_bind_int(set_or_update, 3, identity->comm_type);
  2872     result = sqlite3_step(set_or_update);
  2873     assert(result == SQLITE_DONE);
  2874     sqlite3_reset(set_or_update);
  2875     if (result != SQLITE_DONE)
  2876         return PEP_CANNOT_SET_TRUST;
  2877 
  2878     return PEP_STATUS_OK;
  2879 }
  2880 
  2881 static PEP_STATUS _set_or_update_identity_entry(PEP_SESSION session,
  2882                                                 pEp_identity* identity,
  2883                                                 sqlite3_stmt* set_or_update) {
  2884     assert(session);
  2885     assert(identity);
  2886     assert(set_or_update);
  2887                       
  2888     if (!session || !identity || !identity->user_id || !identity->address)
  2889         return PEP_ILLEGAL_VALUE;
  2890                                               
  2891     sqlite3_reset(set_or_update);
  2892     sqlite3_bind_text(set_or_update, 1, identity->address, -1,
  2893             SQLITE_STATIC);
  2894     sqlite3_bind_text(set_or_update, 2, identity->fpr, -1,
  2895             SQLITE_STATIC);
  2896     sqlite3_bind_text(set_or_update, 3, identity->user_id, -1,
  2897             SQLITE_STATIC);
  2898     sqlite3_bind_int(set_or_update, 4, identity->flags);
  2899     sqlite3_bind_int(set_or_update, 5, identity->me);
  2900     int result = sqlite3_step(set_or_update);
  2901     sqlite3_reset(set_or_update);
  2902     if (result != SQLITE_DONE)
  2903         return PEP_CANNOT_SET_IDENTITY;
  2904     
  2905     return PEP_STATUS_OK;
  2906 }
  2907 
  2908 static PEP_STATUS _set_or_update_person(PEP_SESSION session, 
  2909                                         pEp_identity* identity,
  2910                                         sqlite3_stmt* set_or_update) {
  2911     assert(session);
  2912     assert(identity);
  2913     assert(set_or_update);
  2914                         
  2915     if (!session || !identity || !identity->user_id || !identity->username)
  2916         return PEP_ILLEGAL_VALUE;
  2917         
  2918     sqlite3_reset(set_or_update);
  2919     sqlite3_bind_text(set_or_update, 1, identity->user_id, -1,
  2920             SQLITE_STATIC);
  2921     sqlite3_bind_text(set_or_update, 2, identity->username, -1,
  2922             SQLITE_STATIC);
  2923     if (identity->lang[0])
  2924         sqlite3_bind_text(set_or_update, 3, identity->lang, 2,
  2925                 SQLITE_STATIC);
  2926     else
  2927         sqlite3_bind_null(set_or_update, 3);
  2928     sqlite3_bind_text(set_or_update, 4, identity->fpr, -1,
  2929                       SQLITE_STATIC);
  2930     int result = sqlite3_step(set_or_update);
  2931     sqlite3_reset(set_or_update);
  2932     
  2933     if (result != SQLITE_DONE)
  2934         return PEP_CANNOT_SET_PERSON;
  2935     
  2936     return PEP_STATUS_OK;                                         
  2937 }
  2938 
  2939 PEP_STATUS set_or_update_with_identity(PEP_SESSION session,
  2940                                        pEp_identity* identity,
  2941                                        PEP_STATUS (* set_function)(PEP_SESSION, pEp_identity*, sqlite3_stmt*),
  2942                                        PEP_STATUS (* exists_function)(PEP_SESSION, pEp_identity*, bool*),                                       
  2943                                        sqlite3_stmt* update_query,
  2944                                        sqlite3_stmt* set_query,
  2945                                        bool guard_transaction) {
  2946 
  2947     if (guard_transaction) {
  2948         sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  2949     }
  2950     bool exists = false;
  2951     PEP_STATUS status = exists_function(session, identity, &exists);
  2952     
  2953     if (status == PEP_STATUS_OK) {
  2954         if (exists) {
  2955             status = set_function(session, identity, update_query);
  2956         }
  2957         else {
  2958             status = set_function(session, identity, set_query);                                              
  2959         }                    
  2960     }   
  2961     if (guard_transaction) {        
  2962         if (status != PEP_STATUS_OK)
  2963             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2964         else 
  2965             sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  2966     }                      
  2967     return status;
  2968 }
  2969 
  2970 PEP_STATUS _set_trust_internal(PEP_SESSION session, pEp_identity* identity,
  2971                                bool guard_transaction) {
  2972     return set_or_update_with_identity(session, identity,
  2973                                        _set_or_update_trust,
  2974                                         exists_trust_entry,
  2975                                         session->update_trust,
  2976                                         session->set_trust,
  2977                                         guard_transaction);
  2978 }
  2979 
  2980 // This is the TOP-LEVEL function. If you're calling from set_identity,
  2981 // you can't use this one.
  2982 PEP_STATUS set_trust(PEP_SESSION session, pEp_identity* identity) {
  2983     PEP_STATUS status = PEP_STATUS_OK;
  2984     
  2985     status = _set_trust_internal(session, identity, true);
  2986     if (status == PEP_STATUS_OK) {
  2987         if ((identity->comm_type | PEP_ct_confirmed) == PEP_ct_pEp)
  2988             status = set_as_pEp_user(session, identity);
  2989     }
  2990     return status;
  2991 }
  2992 
  2993 PEP_STATUS set_person(PEP_SESSION session, pEp_identity* identity,
  2994                       bool guard_transaction) {
  2995     return set_or_update_with_identity(session, identity,
  2996                                        _set_or_update_person,
  2997                                        exists_person,
  2998                                        session->update_person,
  2999                                        session->set_person,
  3000                                        guard_transaction);
  3001 }
  3002 
  3003 PEP_STATUS set_identity_entry(PEP_SESSION session, pEp_identity* identity,
  3004                               bool guard_transaction) {
  3005     return set_or_update_with_identity(session, identity,
  3006                                        _set_or_update_identity_entry,
  3007                                        exists_identity_entry,
  3008                                        session->update_identity_entry,
  3009                                        session->set_identity_entry,
  3010                                        guard_transaction);
  3011 }
  3012 
  3013 // This will NOT call set_as_pEp_user; you have to do that separately.
  3014 DYNAMIC_API PEP_STATUS set_identity(
  3015         PEP_SESSION session, const pEp_identity *identity
  3016     )
  3017 {
  3018     int result;
  3019 
  3020     assert(session);
  3021     assert(identity);
  3022     assert(identity->address);
  3023     assert(identity->user_id);
  3024     assert(identity->username);
  3025 
  3026     if (!(session && identity && identity->address &&
  3027                 identity->user_id && identity->username))
  3028         return PEP_ILLEGAL_VALUE;
  3029 
  3030     PEP_STATUS status = PEP_STATUS_OK;
  3031     
  3032     bool has_fpr = (!EMPTYSTR(identity->fpr));
  3033     
  3034     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  3035 
  3036     if (identity->lang[0]) {
  3037         assert(identity->lang[0] >= 'a' && identity->lang[0] <= 'z');
  3038         assert(identity->lang[1] >= 'a' && identity->lang[1] <= 'z');
  3039         assert(identity->lang[2] == 0);
  3040     }
  3041 
  3042     if (has_fpr) {
  3043         sqlite3_reset(session->set_pgp_keypair);
  3044         sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
  3045                 SQLITE_STATIC);
  3046         result = sqlite3_step(session->set_pgp_keypair);
  3047         sqlite3_reset(session->set_pgp_keypair);
  3048         if (result != SQLITE_DONE) {
  3049             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3050             return PEP_CANNOT_SET_PGP_KEYPAIR;
  3051         }
  3052     }
  3053 
  3054     // We do this because there are checks in set_person for
  3055     // aliases, which modify the identity object on return.
  3056     pEp_identity* ident_copy = identity_dup(identity); 
  3057     if (!ident_copy)
  3058         return PEP_OUT_OF_MEMORY;
  3059 
  3060     status = set_person(session, ident_copy, false);
  3061     if (status != PEP_STATUS_OK) {
  3062         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3063         goto pEp_free;
  3064     }
  3065 
  3066     status = set_identity_entry(session, ident_copy, false);
  3067     if (status != PEP_STATUS_OK) {
  3068         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3069         goto pEp_free;
  3070     }
  3071 
  3072     if (has_fpr) {
  3073         status = _set_trust_internal(session, ident_copy, false);
  3074         if (status != PEP_STATUS_OK) {
  3075             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3076             goto pEp_free;
  3077         }
  3078     }
  3079     
  3080     result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  3081     if (result == SQLITE_OK)
  3082         status = PEP_STATUS_OK;
  3083     else
  3084         status = PEP_COMMIT_FAILED;
  3085 
  3086 pEp_free:
  3087     free_identity(ident_copy);
  3088     return status;
  3089 }
  3090 
  3091 PEP_STATUS update_pEp_user_trust_vals(PEP_SESSION session,
  3092                                       pEp_identity* user) {
  3093     if (!user->user_id)
  3094         return PEP_ILLEGAL_VALUE;
  3095     
  3096     sqlite3_reset(session->update_trust_to_pEp);
  3097     sqlite3_bind_text(session->update_trust_to_pEp, 1, user->user_id, -1,
  3098             SQLITE_STATIC);
  3099     int result = sqlite3_step(session->update_trust_to_pEp);
  3100     sqlite3_reset(session->update_trust_to_pEp);
  3101     if (result != SQLITE_DONE)
  3102         return PEP_CANNOT_SET_TRUST;
  3103 
  3104     return PEP_STATUS_OK;
  3105 }
  3106 
  3107 
  3108 // This ONLY sets the user flag. Must be called outside of a transaction.
  3109 DYNAMIC_API PEP_STATUS set_as_pEp_user(PEP_SESSION session, pEp_identity* user) {
  3110 
  3111     assert(session);
  3112     assert(user);
  3113     assert(!EMPTYSTR(user->user_id));
  3114         
  3115     if (!session || !user || EMPTYSTR(user->user_id))
  3116         return PEP_ILLEGAL_VALUE;
  3117             
  3118     PEP_STATUS status = PEP_STATUS_OK;
  3119     
  3120     bool person_exists = false;
  3121     
  3122     status = exists_person(session, user, &person_exists);
  3123     
  3124     if (status != PEP_STATUS_OK)
  3125         return status;
  3126         
  3127     if (!person_exists)
  3128         status = set_person(session, user, true);
  3129         
  3130     // Ok, let's set it.
  3131     sqlite3_reset(session->set_as_pEp_user);
  3132     sqlite3_bind_text(session->set_as_pEp_user, 1, user->user_id, -1,
  3133             SQLITE_STATIC);
  3134     int result = sqlite3_step(session->set_as_pEp_user);
  3135     sqlite3_reset(session->set_as_pEp_user);
  3136     
  3137     if (result != SQLITE_DONE)
  3138         return PEP_CANNOT_SET_PERSON;
  3139 
  3140     status = update_pEp_user_trust_vals(session, user);
  3141         
  3142     return status;
  3143 }
  3144 
  3145 PEP_STATUS exists_person(PEP_SESSION session, pEp_identity* identity,
  3146                          bool* exists) {            
  3147     
  3148     // const char* user_id,
  3149     //                      char** default_id, bool* exists) {
  3150     assert(session);
  3151     assert(exists);
  3152     assert(identity);
  3153     assert(!EMPTYSTR(identity->user_id));
  3154         
  3155     if (!session || !exists || !identity || EMPTYSTR(identity->user_id))
  3156         return PEP_ILLEGAL_VALUE;
  3157     
  3158     *exists = false;
  3159 
  3160     const char* user_id = identity->user_id;
  3161     char* alias_default = NULL;
  3162     
  3163     PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
  3164     
  3165     if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
  3166         sqlite3_reset(session->exists_person);
  3167         sqlite3_bind_text(session->exists_person, 1, user_id, -1,
  3168                 SQLITE_STATIC);
  3169         int result = sqlite3_step(session->exists_person);
  3170         switch (result) {
  3171             case SQLITE_ROW: {
  3172                 // yeah yeah, I know, we could be lazy here, but it looks bad.
  3173                 *exists = (sqlite3_column_int(session->exists_person, 0) != 0);
  3174                 status = PEP_STATUS_OK;
  3175                 break;
  3176             }
  3177             default:
  3178                 sqlite3_reset(session->exists_person);
  3179                 return PEP_UNKNOWN_DB_ERROR;
  3180         }
  3181         sqlite3_reset(session->exists_person);
  3182     }
  3183     else if (status == PEP_STATUS_OK) {
  3184         *exists = true; // thank you, delete on cascade!
  3185         // FIXME: Should we correct the userid default here? I think we should.
  3186         free(identity->user_id);
  3187         identity->user_id = alias_default; // ownership transfer
  3188     }
  3189     else
  3190         free(alias_default);
  3191             
  3192     return status;
  3193 }
  3194 
  3195 PEP_STATUS delete_person(PEP_SESSION session, const char* user_id) {
  3196     assert(session);
  3197     assert(!EMPTYSTR(user_id));        
  3198     if (!session || EMPTYSTR(user_id))
  3199         return PEP_ILLEGAL_VALUE;
  3200         
  3201     PEP_STATUS status = PEP_STATUS_OK;
  3202     
  3203     sqlite3_reset(session->delete_person);
  3204     sqlite3_bind_text(session->delete_person, 1, user_id, -1,
  3205                       SQLITE_STATIC);
  3206                       
  3207     int result = sqlite3_step(session->delete_person);
  3208     
  3209     if (result != SQLITE_DONE)
  3210         status = PEP_UNKNOWN_ERROR;
  3211         
  3212     sqlite3_reset(session->delete_person);
  3213     return status;
  3214 }
  3215 
  3216 DYNAMIC_API PEP_STATUS is_pEp_user(PEP_SESSION session, pEp_identity *identity, bool* is_pEp)
  3217 {
  3218     assert(session);
  3219     assert(is_pEp);
  3220     assert(identity);
  3221     assert(!EMPTYSTR(identity->user_id));
  3222 
  3223     if (!session || !is_pEp || !identity || EMPTYSTR(identity->user_id))
  3224         return PEP_ILLEGAL_VALUE;
  3225     
  3226     *is_pEp = false;
  3227             
  3228     const char* user_id = identity->user_id;
  3229             
  3230     char* alias_default = NULL;
  3231     
  3232     PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
  3233     
  3234     if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
  3235         free(alias_default);
  3236         alias_default = strdup(user_id);
  3237     }
  3238     
  3239     sqlite3_reset(session->is_pEp_user);
  3240     sqlite3_bind_text(session->is_pEp_user, 1, user_id, -1,
  3241             SQLITE_STATIC);
  3242     int result = sqlite3_step(session->is_pEp_user);
  3243     switch (result) {
  3244         case SQLITE_ROW: {
  3245             // yeah yeah, I know, we could be lazy here, but it looks bad.
  3246             *is_pEp = (sqlite3_column_int(session->is_pEp_user, 0) != 0);
  3247             break;
  3248         }
  3249         default:
  3250             sqlite3_reset(session->is_pEp_user);
  3251             free(alias_default);
  3252             return PEP_CANNOT_FIND_PERSON;
  3253     }
  3254 
  3255     sqlite3_reset(session->is_pEp_user);
  3256     
  3257     free(alias_default);
  3258     return PEP_STATUS_OK;
  3259 }
  3260 
  3261 PEP_STATUS is_own_address(PEP_SESSION session, const char* address, bool* is_own_addr)
  3262 {
  3263     assert(session);
  3264     assert(is_own_addr);
  3265     assert(!EMPTYSTR(address));
  3266 
  3267     if (!session || !is_own_addr || EMPTYSTR(address))
  3268         return PEP_ILLEGAL_VALUE;
  3269     
  3270     *is_own_addr = false;
  3271                 
  3272     if (!session || EMPTYSTR(address))
  3273         return PEP_ILLEGAL_VALUE;
  3274         
  3275     sqlite3_reset(session->is_own_address);
  3276     sqlite3_bind_text(session->is_own_address, 1, address, -1,
  3277             SQLITE_STATIC);
  3278     int result = sqlite3_step(session->is_own_address);
  3279     switch (result) {
  3280         case SQLITE_ROW: {
  3281             // yeah yeah, I know, we could be lazy here, but it looks bad.
  3282             *is_own_addr = (sqlite3_column_int(session->is_own_address, 0) != 0);
  3283             break;
  3284         }
  3285         default:
  3286             sqlite3_reset(session->is_own_address);
  3287             return PEP_RECORD_NOT_FOUND;
  3288     }
  3289 
  3290     sqlite3_reset(session->is_own_address);
  3291     
  3292     return PEP_STATUS_OK;
  3293 }
  3294 
  3295 PEP_STATUS bind_own_ident_with_contact_ident(PEP_SESSION session,
  3296                                              pEp_identity* own_ident, 
  3297                                              pEp_identity* contact_ident) {
  3298     if (!own_ident || !contact_ident || 
  3299         !own_ident->address || !own_ident->user_id || !contact_ident->user_id)
  3300         return PEP_ILLEGAL_VALUE;
  3301         
  3302     sqlite3_reset(session->add_into_social_graph);
  3303     sqlite3_bind_text(session->add_into_social_graph, 1, own_ident->user_id, -1,
  3304             SQLITE_STATIC);
  3305     sqlite3_bind_text(session->add_into_social_graph, 2, own_ident->address, -1,
  3306             SQLITE_STATIC);
  3307     sqlite3_bind_text(session->add_into_social_graph, 3, contact_ident->user_id, -1,
  3308             SQLITE_STATIC);
  3309         
  3310     int result = sqlite3_step(session->add_into_social_graph);
  3311     sqlite3_reset(session->add_into_social_graph);
  3312     
  3313     if (result != SQLITE_DONE)
  3314         return PEP_CANNOT_SET_PERSON;
  3315 
  3316     return PEP_STATUS_OK;
  3317 }
  3318 
  3319 PEP_STATUS get_own_ident_for_contact_id(PEP_SESSION session,
  3320                                           const pEp_identity* contact,
  3321                                           pEp_identity** own_ident) {
  3322                                               
  3323     if (!contact || !contact->user_id || !own_ident)
  3324         return PEP_ILLEGAL_VALUE;
  3325         
  3326     char* own_user_id = NULL;
  3327     *own_ident = NULL;
  3328     PEP_STATUS status = get_default_own_userid(session, &own_user_id);
  3329     
  3330     if (status != PEP_STATUS_OK)
  3331         return status;
  3332 
  3333     sqlite3_reset(session->get_own_address_binding_from_contact);
  3334     sqlite3_bind_text(session->get_own_address_binding_from_contact, 1, own_user_id, -1,
  3335             SQLITE_STATIC);
  3336     sqlite3_bind_text(session->get_own_address_binding_from_contact, 2, contact->user_id, -1,
  3337             SQLITE_STATIC);
  3338 
  3339     int result = sqlite3_step(session->get_own_address_binding_from_contact);
  3340     
  3341     const char* own_address = NULL;
  3342     
  3343     switch (result) {
  3344         case SQLITE_ROW:
  3345             own_address = (const char *)
  3346                 sqlite3_column_text(session->get_own_address_binding_from_contact, 0);
  3347             if (own_address) {
  3348                 status = get_identity(session, own_address, own_user_id, own_ident);
  3349                 if (status == PEP_STATUS_OK) {
  3350                     if (!own_ident)
  3351                         status = PEP_CANNOT_FIND_IDENTITY;
  3352                 }
  3353             }
  3354             break;
  3355         default:
  3356             status = PEP_CANNOT_FIND_IDENTITY;
  3357     }
  3358     
  3359     free(own_user_id);
  3360     return status;
  3361 }
  3362 
  3363 PEP_STATUS remove_fpr_as_default(PEP_SESSION session, 
  3364                                  const char* fpr) 
  3365 {
  3366     assert(fpr);
  3367     
  3368     if (!session || !fpr)
  3369         return PEP_ILLEGAL_VALUE;
  3370             
  3371     sqlite3_reset(session->remove_fpr_as_default);
  3372     sqlite3_bind_text(session->remove_fpr_as_default, 1, fpr, -1,
  3373                       SQLITE_STATIC);
  3374 
  3375     int result = sqlite3_step(session->remove_fpr_as_default);
  3376     sqlite3_reset(session->remove_fpr_as_default);
  3377     
  3378     if (result != SQLITE_DONE)
  3379         return PEP_CANNOT_SET_IDENTITY; // misleading - could also be person
  3380 
  3381     return PEP_STATUS_OK;
  3382 }
  3383 
  3384 
  3385 PEP_STATUS replace_identities_fpr(PEP_SESSION session, 
  3386                                  const char* old_fpr, 
  3387                                  const char* new_fpr) 
  3388 {
  3389     assert(old_fpr);
  3390     assert(new_fpr);
  3391     
  3392     if (!old_fpr || !new_fpr)
  3393         return PEP_ILLEGAL_VALUE;
  3394             
  3395     sqlite3_reset(session->replace_identities_fpr);
  3396     sqlite3_bind_text(session->replace_identities_fpr, 1, new_fpr, -1,
  3397                       SQLITE_STATIC);
  3398     sqlite3_bind_text(session->replace_identities_fpr, 2, old_fpr, -1,
  3399                       SQLITE_STATIC);
  3400 
  3401     int result = sqlite3_step(session->replace_identities_fpr);
  3402     sqlite3_reset(session->replace_identities_fpr);
  3403     
  3404     if (result != SQLITE_DONE)
  3405         return PEP_CANNOT_SET_IDENTITY;
  3406 
  3407     return PEP_STATUS_OK;
  3408 }
  3409 
  3410 PEP_STATUS update_trust_for_fpr(PEP_SESSION session, 
  3411                                 const char* fpr, 
  3412                                 PEP_comm_type comm_type)
  3413 {
  3414     if (!fpr)
  3415         return PEP_ILLEGAL_VALUE;
  3416         
  3417     sqlite3_reset(session->update_trust_for_fpr);
  3418     sqlite3_bind_int(session->update_trust_for_fpr, 1, comm_type);
  3419     sqlite3_bind_text(session->update_trust_for_fpr, 2, fpr, -1,
  3420             SQLITE_STATIC);
  3421     int result = sqlite3_step(session->update_trust_for_fpr);
  3422     sqlite3_reset(session->update_trust_for_fpr);
  3423     if (result != SQLITE_DONE) {
  3424         return PEP_CANNOT_SET_TRUST;
  3425     }
  3426     
  3427     return PEP_STATUS_OK;
  3428 }
  3429 
  3430 DYNAMIC_API PEP_STATUS set_identity_flags(
  3431         PEP_SESSION session,
  3432         pEp_identity *identity,
  3433         unsigned int flags
  3434     )
  3435 {
  3436     int result;
  3437 
  3438     assert(session);
  3439     assert(identity);
  3440     assert(identity->address);
  3441     assert(identity->user_id);
  3442 
  3443     if (!(session && identity && identity->address && identity->user_id))
  3444         return PEP_ILLEGAL_VALUE;
  3445 
  3446     sqlite3_reset(session->set_identity_flags);
  3447     sqlite3_bind_int(session->set_identity_flags, 1, flags);
  3448     sqlite3_bind_text(session->set_identity_flags, 2, identity->address, -1,
  3449             SQLITE_STATIC);
  3450     sqlite3_bind_text(session->set_identity_flags, 3, identity->user_id, -1,
  3451         SQLITE_STATIC);
  3452         
  3453     result = sqlite3_step(session->set_identity_flags);
  3454 
  3455     sqlite3_reset(session->set_identity_flags);
  3456     if (result != SQLITE_DONE)
  3457         return PEP_CANNOT_SET_IDENTITY;
  3458 
  3459     identity->flags |= flags;
  3460     return PEP_STATUS_OK;
  3461 }
  3462 
  3463 DYNAMIC_API PEP_STATUS unset_identity_flags(
  3464         PEP_SESSION session,
  3465         pEp_identity *identity,
  3466         unsigned int flags
  3467     )
  3468 {
  3469     int result;
  3470 
  3471     assert(session);
  3472     assert(identity);
  3473     assert(identity->address);
  3474     assert(identity->user_id);
  3475 
  3476     if (!(session && identity && identity->address && identity->user_id))
  3477         return PEP_ILLEGAL_VALUE;
  3478 
  3479     sqlite3_reset(session->unset_identity_flags);
  3480     sqlite3_bind_int(session->unset_identity_flags, 1, flags);
  3481     sqlite3_bind_text(session->unset_identity_flags, 2, identity->address, -1,
  3482             SQLITE_STATIC);
  3483     sqlite3_bind_text(session->unset_identity_flags, 3, identity->user_id, -1,
  3484             SQLITE_STATIC);
  3485     result = sqlite3_step(session->unset_identity_flags);
  3486     sqlite3_reset(session->unset_identity_flags);
  3487     if (result != SQLITE_DONE)
  3488         return PEP_CANNOT_SET_IDENTITY;
  3489 
  3490     identity->flags &= ~flags;
  3491 
  3492     return PEP_STATUS_OK;
  3493 }
  3494 
  3495 PEP_STATUS get_trust_by_userid(PEP_SESSION session, const char* user_id,
  3496                                            labeled_int_list_t** trust_list)
  3497 {
  3498     int result;
  3499 
  3500     if (!(session && user_id && user_id[0]))
  3501         return PEP_ILLEGAL_VALUE;
  3502 
  3503     *trust_list = NULL;
  3504     labeled_int_list_t* t_list = NULL;
  3505 
  3506     sqlite3_reset(session->get_trust_by_userid);
  3507     sqlite3_bind_text(session->get_trust_by_userid, 1, user_id, -1, SQLITE_STATIC);
  3508 
  3509     while ((result = sqlite3_step(session->get_trust_by_userid)) == SQLITE_ROW) {
  3510         if (!t_list)
  3511             t_list = new_labeled_int_list(sqlite3_column_int(session->get_trust_by_userid, 1),
  3512                                          (const char *) sqlite3_column_text(session->get_trust_by_userid, 0));
  3513         else
  3514             labeled_int_list_add(t_list, sqlite3_column_int(session->get_trust_by_userid, 1),
  3515                                 (const char *) sqlite3_column_text(session->get_trust_by_userid, 0));
  3516     }
  3517 
  3518     sqlite3_reset(session->get_trust_by_userid);
  3519 
  3520     *trust_list = t_list;
  3521         
  3522     return PEP_STATUS_OK;
  3523 }
  3524 
  3525 PEP_comm_type reconcile_trust(PEP_comm_type t_old, PEP_comm_type t_new) {
  3526     switch (t_new) {
  3527         case PEP_ct_mistrusted:
  3528         case PEP_ct_key_revoked:
  3529         case PEP_ct_compromised:
  3530         case PEP_ct_key_b0rken:
  3531             return t_new;
  3532         default:
  3533             break;
  3534     }
  3535     switch (t_old) {
  3536         case PEP_ct_mistrusted:
  3537         case PEP_ct_key_revoked:
  3538         case PEP_ct_compromised:
  3539         case PEP_ct_key_b0rken:
  3540             return t_old;
  3541         default:
  3542             break;
  3543     }
  3544     if (t_old < PEP_ct_strong_but_unconfirmed && t_new >= PEP_ct_strong_but_unconfirmed)
  3545         return t_new;
  3546     
  3547     bool confirmed = (t_old & PEP_ct_confirmed) || (t_new & PEP_ct_confirmed);
  3548     PEP_comm_type result = _MAX(t_old, t_new);
  3549     if (confirmed)
  3550         result |= PEP_ct_confirmed;
  3551     return result;
  3552 }
  3553 
  3554 PEP_STATUS reconcile_pEp_status(PEP_SESSION session, const char* old_uid, 
  3555                                 const char* new_uid) {
  3556     PEP_STATUS status = PEP_STATUS_OK;
  3557     // We'll make this easy - if the old one has a pEp status, we set no matter
  3558     // what.
  3559     pEp_identity* ident = new_identity(NULL, NULL, old_uid, NULL);
  3560     bool is_pEp_peep = false;
  3561     status = is_pEp_user(session, ident, &is_pEp_peep);
  3562     if (is_pEp_peep) {
  3563         free(ident->user_id);
  3564         ident->user_id = strdup(new_uid);
  3565         if (!ident->user_id) {
  3566             status = PEP_OUT_OF_MEMORY;
  3567             goto pEp_free;
  3568         }
  3569         status = set_as_pEp_user(session, ident);
  3570     }
  3571 pEp_free:
  3572     free_identity(ident);
  3573     return status;
  3574 }
  3575 
  3576 const char* reconcile_usernames(const char* old_name, const char* new_name, 
  3577                                 const char* address) {
  3578     if (EMPTYSTR(old_name)) {
  3579         if (EMPTYSTR(new_name))
  3580             return address;
  3581         else
  3582             return new_name;
  3583     }
  3584     if (EMPTYSTR(new_name))
  3585         return old_name;        
  3586     if (strcmp(new_name, address) == 0)
  3587         return old_name;
  3588     return new_name;        
  3589 }
  3590 
  3591 PEP_STATUS reconcile_default_keys(PEP_SESSION session, pEp_identity* old_ident,
  3592                                   pEp_identity* new_ident) {
  3593     PEP_STATUS status = PEP_STATUS_OK;
  3594                                       
  3595     const char* old_fpr = old_ident->fpr;
  3596     const char* new_fpr = new_ident->fpr;
  3597     if (!old_fpr)
  3598         return status;
  3599 
  3600     PEP_comm_type old_ct = old_ident->comm_type;    
  3601     PEP_comm_type new_ct = new_ident->comm_type;
  3602     
  3603     if (!new_fpr) {
  3604         new_ident->fpr = strdup(old_fpr);
  3605         if (!new_ident->fpr)
  3606             status = PEP_OUT_OF_MEMORY;
  3607         else    
  3608             new_ident->comm_type = old_ct;
  3609         return status;
  3610     }        
  3611     
  3612     if (strcmp(old_fpr, new_fpr) == 0) {
  3613         new_ident->comm_type = reconcile_trust(old_ct, new_ct);
  3614         return status;
  3615     }
  3616     
  3617     bool old_confirmed = old_ct & PEP_ct_confirmed;
  3618     bool new_confirmed = new_ct & PEP_ct_confirmed;
  3619     
  3620     if (new_confirmed)
  3621         return status;
  3622     else if (old_confirmed) {
  3623         free(new_ident->fpr);
  3624         new_ident->fpr = strdup(old_fpr);
  3625         if (!new_ident->fpr)
  3626             status = PEP_OUT_OF_MEMORY;
  3627         else    
  3628             new_ident->comm_type = old_ct;
  3629         return status;
  3630     }
  3631     
  3632     if (old_ct > new_ct) {
  3633         free(new_ident->fpr);
  3634         new_ident->fpr = strdup(old_fpr);
  3635         if (!new_ident->fpr)
  3636             status = PEP_OUT_OF_MEMORY;
  3637         else    
  3638             new_ident->comm_type = old_ct;
  3639     }
  3640     return status;
  3641 }
  3642 
  3643 void reconcile_language(pEp_identity* old_ident,
  3644                         pEp_identity* new_ident) {
  3645     if (new_ident->lang[0] == 0) {
  3646         if (old_ident->lang[0] != 0) {
  3647             new_ident->lang[0] = old_ident->lang[0];
  3648             new_ident->lang[1] = old_ident->lang[1];
  3649             new_ident->lang[2] = old_ident->lang[2];
  3650         }
  3651     }
  3652 }
  3653 
  3654 // ONLY CALL THIS IF BOTH IDs ARE IN THE PERSON DB, FOOL! </Mr_T>
  3655 PEP_STATUS merge_records(PEP_SESSION session, const char* old_uid,
  3656                          const char* new_uid) {
  3657     PEP_STATUS status = PEP_STATUS_OK;
  3658     
  3659     pEp_identity* new_ident = NULL;
  3660     identity_list* old_identities = NULL;
  3661     labeled_int_list_t* trust_list = NULL;
  3662     stringlist_t* touched_keys = new_stringlist(NULL);
  3663     char* main_user_fpr = NULL;
  3664 
  3665     status = reconcile_pEp_status(session, old_uid, new_uid);
  3666     if (status != PEP_STATUS_OK)
  3667         goto pEp_free;
  3668                         
  3669     bool new_is_pEp = false;
  3670     new_ident = new_identity(NULL, NULL, new_uid, NULL);
  3671     status = is_pEp_user(session, new_ident, &new_is_pEp);
  3672     if (status != PEP_STATUS_OK)
  3673         goto pEp_free;
  3674     free(new_ident);
  3675     new_ident = NULL;
  3676         
  3677     status = get_identities_by_userid(session, old_uid, &old_identities);
  3678     if (status == PEP_STATUS_OK && old_identities) {
  3679         identity_list* curr_old = old_identities;
  3680         for (; curr_old && curr_old->ident; curr_old = curr_old->next) {
  3681             pEp_identity* old_ident = curr_old->ident;
  3682             const char* address = old_ident->address;
  3683             status = get_identity(session, address, new_uid, &new_ident);
  3684             if (status == PEP_CANNOT_FIND_IDENTITY) {
  3685                 // No new identity matching the old one, so we just set one w. new user_id
  3686                 free(old_ident->user_id);
  3687                 old_ident->user_id = strdup(new_uid);
  3688                 if (!old_ident->user_id) {
  3689                     status = PEP_OUT_OF_MEMORY;
  3690                     goto pEp_free;
  3691                 }
  3692                 if (new_is_pEp) {
  3693                     PEP_comm_type confirmed_bit = old_ident->comm_type & PEP_ct_confirmed;
  3694                     if ((old_ident->comm_type | PEP_ct_confirmed) == PEP_ct_OpenPGP)
  3695                         old_ident->comm_type = PEP_ct_pEp_unconfirmed | confirmed_bit;
  3696                 }
  3697                 
  3698                 status = set_identity(session, old_ident);
  3699                 if (status != PEP_STATUS_OK)
  3700                     goto pEp_free;
  3701             }
  3702             else if (status != PEP_STATUS_OK)
  3703                 goto pEp_free;
  3704             else {
  3705                 // Ok, so we have two idents which might be in conflict. Have to merge them.
  3706                 const char* username = reconcile_usernames(old_ident->username,
  3707                                                            new_ident->username,
  3708                                                            address);
  3709                                                            
  3710                 if (!new_ident->username || strcmp(username, new_ident->username) != 0) {
  3711                     free(new_ident->username);
  3712                     new_ident->username = strdup(username);
  3713                     if (!new_ident->username) {
  3714                         status = PEP_OUT_OF_MEMORY;
  3715                         goto pEp_free;
  3716                     }
  3717                 }
  3718         
  3719                 // Reconcile default keys if they differ, trust if they don't
  3720                 status = reconcile_default_keys(session, old_ident, new_ident);
  3721                 if (status != PEP_STATUS_OK)
  3722                     goto pEp_free;
  3723                     
  3724                 // reconcile languages
  3725                 reconcile_language(old_ident, new_ident);
  3726 
  3727                 // reconcile flags - FIXME - is this right?
  3728                 new_ident->flags |= old_ident->flags;
  3729                 
  3730                 // NOTE: In principle, this is only called from update_identity,
  3731                 // which would never have me flags set. So I am ignoring them here.
  3732                 // if this function is ever USED for that, though, you'll have
  3733                 // to go through making sure that the user ids are appropriately
  3734                 // aliased, etc. So be careful.
  3735                 
  3736                 // Set the reconciled record
  3737                     
  3738                 status = set_identity(session, new_ident);
  3739                 if (status != PEP_STATUS_OK)
  3740                     goto pEp_free;
  3741 
  3742                 if (new_ident->fpr)
  3743                     stringlist_add(touched_keys, new_ident->fpr);
  3744                         
  3745                 free_identity(new_ident);
  3746                 new_ident = NULL;    
  3747             }
  3748         }
  3749     }
  3750     // otherwise, no need to reconcile identity records. But maybe trust...    
  3751     new_ident = new_identity(NULL, NULL, new_uid, NULL);
  3752     if (!new_ident) {
  3753         status = PEP_OUT_OF_MEMORY;
  3754         goto pEp_free;
  3755     }
  3756     status = get_trust_by_userid(session, old_uid, &trust_list);
  3757 
  3758     labeled_int_list_t* trust_curr = trust_list;
  3759     for (; trust_curr && trust_curr->label; trust_curr = trust_curr->next) {
  3760         const char* curr_fpr = trust_curr->label;
  3761         new_ident->fpr = strdup(curr_fpr); 
  3762         status = get_trust(session, new_ident);
  3763         switch (status) {
  3764             case PEP_STATUS_OK:
  3765                 new_ident->comm_type = reconcile_trust(trust_curr->value,
  3766                                                        new_ident->comm_type);
  3767                 break;
  3768             case PEP_CANNOT_FIND_IDENTITY:
  3769                 new_ident->comm_type = trust_curr->value;
  3770                 break;
  3771             default:
  3772                 goto pEp_free;
  3773         }
  3774         new_ident->comm_type = reconcile_trust(trust_curr->value,
  3775                                                new_ident->comm_type);
  3776         if (new_is_pEp) {
  3777             PEP_comm_type confirmed_bit = new_ident->comm_type & PEP_ct_confirmed;
  3778             if ((new_ident->comm_type | PEP_ct_confirmed) == PEP_ct_OpenPGP)
  3779                 new_ident->comm_type = PEP_ct_pEp_unconfirmed | confirmed_bit;
  3780         }
  3781 
  3782         status = set_trust(session, new_ident);
  3783         if (status != PEP_STATUS_OK) {
  3784             goto pEp_free;
  3785         }                  
  3786                               
  3787         free(new_ident->fpr);
  3788         new_ident->fpr = NULL;
  3789         new_ident->comm_type = 0;
  3790     }
  3791 
  3792     // reconcile the default keys if the new id doesn't have one?
  3793     status = get_main_user_fpr(session, new_uid, &main_user_fpr);
  3794     if (status == PEP_KEY_NOT_FOUND || (status == PEP_STATUS_OK && !main_user_fpr)) {
  3795         status = get_main_user_fpr(session, old_uid, &main_user_fpr);
  3796         if (status == PEP_STATUS_OK && main_user_fpr)
  3797             status = replace_main_user_fpr(session, new_uid, main_user_fpr);
  3798         if (status != PEP_STATUS_OK)
  3799             goto pEp_free;
  3800     }
  3801     
  3802     // delete the old user
  3803     status = delete_person(session, old_uid);
  3804     
  3805 pEp_free:
  3806     free_identity(new_ident);
  3807     free_identity_list(old_identities);
  3808     free_labeled_int_list(trust_list);
  3809     free_stringlist(touched_keys);
  3810     free(main_user_fpr);
  3811     return status;
  3812 }
  3813 
  3814 PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
  3815                           const char* new_uid) {
  3816     assert(session);
  3817     assert(old_uid);
  3818     assert(new_uid);
  3819     
  3820     if (!session || !old_uid || !new_uid)
  3821         return PEP_ILLEGAL_VALUE;
  3822 
  3823     pEp_identity* temp_ident = new_identity(NULL, NULL, new_uid, NULL);
  3824     bool new_exists = false;
  3825     PEP_STATUS status = exists_person(session, temp_ident, &new_exists);
  3826     free_identity(temp_ident);
  3827     if (status != PEP_STATUS_OK) // DB error
  3828         return status;
  3829         
  3830     if (new_exists)
  3831         return merge_records(session, old_uid, new_uid);
  3832 
  3833     int result;
  3834 
  3835     sqlite3_reset(session->replace_userid);
  3836     sqlite3_bind_text(session->replace_userid, 1, new_uid, -1,
  3837             SQLITE_STATIC);
  3838     sqlite3_bind_text(session->replace_userid, 2, old_uid, -1,
  3839             SQLITE_STATIC);
  3840     result = sqlite3_step(session->replace_userid);
  3841 #ifndef NDEBUG
  3842     if (result) {
  3843         const char *errmsg = sqlite3_errmsg(session->db);
  3844         log_event(session, "SQLite3 error", "replace_userid", errmsg, NULL);
  3845     }
  3846 #endif // !NDEBUG
  3847     sqlite3_reset(session->replace_userid);
  3848     if (result != SQLITE_DONE)
  3849         return PEP_CANNOT_SET_PERSON; // May need clearer retval
  3850 
  3851     return PEP_STATUS_OK;
  3852 }
  3853 
  3854 PEP_STATUS remove_key(PEP_SESSION session, const char* fpr) {
  3855     assert(session);
  3856     assert(fpr);
  3857     
  3858     if (!session || EMPTYSTR(fpr))
  3859         return PEP_ILLEGAL_VALUE;
  3860 
  3861     int result;
  3862 
  3863     sqlite3_reset(session->delete_key);
  3864     sqlite3_bind_text(session->delete_key, 1, fpr, -1,
  3865             SQLITE_STATIC);
  3866     result = sqlite3_step(session->delete_key);
  3867     sqlite3_reset(session->delete_key);
  3868     if (result != SQLITE_DONE)
  3869         return PEP_CANNOT_SET_PGP_KEYPAIR;
  3870 
  3871     return PEP_STATUS_OK;
  3872 }
  3873 
  3874 
  3875 PEP_STATUS refresh_userid_default_key(PEP_SESSION session, const char* user_id) {
  3876     assert(session);
  3877     assert(user_id);
  3878     
  3879     if (!session || !user_id)
  3880         return PEP_ILLEGAL_VALUE;
  3881 
  3882     int result;
  3883 
  3884     sqlite3_reset(session->refresh_userid_default_key);
  3885     sqlite3_bind_text(session->refresh_userid_default_key, 1, user_id, -1,
  3886             SQLITE_STATIC);
  3887     result = sqlite3_step(session->refresh_userid_default_key);
  3888     sqlite3_reset(session->refresh_userid_default_key);
  3889     if (result != SQLITE_DONE)
  3890         return PEP_CANNOT_SET_PERSON;
  3891 
  3892     return PEP_STATUS_OK;    
  3893 }
  3894 
  3895 PEP_STATUS replace_main_user_fpr(PEP_SESSION session, const char* user_id,
  3896                                  const char* new_fpr) {
  3897     assert(session);
  3898     assert(user_id);
  3899     assert(new_fpr);
  3900     
  3901     if (!session || !user_id || !new_fpr)
  3902         return PEP_ILLEGAL_VALUE;
  3903 
  3904     int result;
  3905 
  3906     sqlite3_reset(session->replace_main_user_fpr);
  3907     sqlite3_bind_text(session->replace_main_user_fpr, 1, new_fpr, -1,
  3908             SQLITE_STATIC);
  3909     sqlite3_bind_text(session->replace_main_user_fpr, 2, user_id, -1,
  3910             SQLITE_STATIC);
  3911     result = sqlite3_step(session->replace_main_user_fpr);
  3912     sqlite3_reset(session->replace_main_user_fpr);
  3913     if (result != SQLITE_DONE)
  3914         return PEP_CANNOT_SET_PERSON;
  3915 
  3916     return PEP_STATUS_OK;
  3917 }
  3918 
  3919 PEP_STATUS get_main_user_fpr(PEP_SESSION session, 
  3920                              const char* user_id,
  3921                              char** main_fpr)
  3922 {
  3923     PEP_STATUS status = PEP_STATUS_OK;
  3924     int result;
  3925     
  3926     assert(session);
  3927     assert(user_id);
  3928     assert(main_fpr);
  3929     
  3930     if (!(session && user_id && user_id[0] && main_fpr))
  3931         return PEP_ILLEGAL_VALUE;
  3932         
  3933     *main_fpr = NULL;
  3934     
  3935     sqlite3_reset(session->get_main_user_fpr);
  3936     sqlite3_bind_text(session->get_main_user_fpr, 1, user_id, -1,
  3937                       SQLITE_STATIC);
  3938     result = sqlite3_step(session->get_main_user_fpr);
  3939     switch (result) {
  3940     case SQLITE_ROW: {
  3941         const char* _fpr = 
  3942             (const char *) sqlite3_column_text(session->get_main_user_fpr, 0);
  3943         if (_fpr) {
  3944             *main_fpr = strdup(_fpr);
  3945             if (!(*main_fpr))
  3946                 status = PEP_OUT_OF_MEMORY;
  3947         }
  3948         else {
  3949             status = PEP_KEY_NOT_FOUND;
  3950         }
  3951         break;
  3952     }
  3953     default:
  3954         status = PEP_CANNOT_FIND_PERSON;
  3955     }
  3956 
  3957     sqlite3_reset(session->get_main_user_fpr);
  3958     return status;
  3959 }
  3960 
  3961 // Deprecated
  3962 DYNAMIC_API PEP_STATUS mark_as_compromized(
  3963         PEP_SESSION session,
  3964         const char *fpr
  3965     )
  3966 {
  3967     return mark_as_compromised(session, fpr);
  3968 }
  3969 
  3970 DYNAMIC_API PEP_STATUS mark_as_compromised(
  3971         PEP_SESSION session,
  3972         const char *fpr
  3973     )
  3974 {
  3975     int result;
  3976 
  3977     assert(session);
  3978     assert(fpr && fpr[0]);
  3979 
  3980     if (!(session && fpr && fpr[0]))
  3981         return PEP_ILLEGAL_VALUE;
  3982 
  3983     sqlite3_reset(session->mark_compromised);
  3984     sqlite3_bind_text(session->mark_compromised, 1, fpr, -1,
  3985             SQLITE_STATIC);
  3986     result = sqlite3_step(session->mark_compromised);
  3987     sqlite3_reset(session->mark_compromised);
  3988 
  3989     if (result != SQLITE_DONE)
  3990         return PEP_CANNOT_SET_TRUST;
  3991 
  3992     return PEP_STATUS_OK;
  3993 }
  3994 
  3995 void pEp_free(void *p)
  3996 {
  3997     free(p);
  3998 }
  3999 
  4000 
  4001 DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
  4002 {
  4003     PEP_STATUS status = PEP_STATUS_OK;
  4004     int result;
  4005 
  4006     // We need to be able to test that we break correctly without shutting
  4007     // asserts off everywhere.
  4008     // assert(session);
  4009     // assert(identity);
  4010     // assert(identity->user_id);
  4011     // assert(identity->user_id[0]);
  4012     // assert(identity->fpr);
  4013     // assert(identity->fpr[0]);
  4014 
  4015     if (!(session && identity && identity->user_id && identity->user_id[0] &&
  4016                 identity->fpr && identity->fpr[0]))
  4017         return PEP_ILLEGAL_VALUE;
  4018 
  4019     identity->comm_type = PEP_ct_unknown;
  4020     sqlite3_reset(session->get_trust);
  4021 
  4022     sqlite3_bind_text(session->get_trust, 1, identity->user_id, -1,
  4023             SQLITE_STATIC);
  4024     sqlite3_bind_text(session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
  4025 
  4026     result = sqlite3_step(session->get_trust);
  4027     switch (result) {
  4028     case SQLITE_ROW: {
  4029         int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust,
  4030                 0);
  4031         identity->comm_type = comm_type;
  4032         break;
  4033     }
  4034  
  4035     default:
  4036         status = PEP_CANNOT_FIND_IDENTITY;
  4037     }
  4038 
  4039     sqlite3_reset(session->get_trust);
  4040     return status;
  4041 }
  4042 
  4043 
  4044 DYNAMIC_API PEP_STATUS least_trust(
  4045         PEP_SESSION session,
  4046         const char *fpr,
  4047         PEP_comm_type *comm_type
  4048     )
  4049 {
  4050     PEP_STATUS status = PEP_STATUS_OK;
  4051     int result;
  4052 
  4053     assert(session);
  4054     assert(fpr);
  4055     assert(comm_type);
  4056 
  4057     if (!(session && fpr && comm_type))
  4058         return PEP_ILLEGAL_VALUE;
  4059 
  4060     *comm_type = PEP_ct_unknown;
  4061 
  4062     sqlite3_reset(session->least_trust);
  4063     sqlite3_bind_text(session->least_trust, 1, fpr, -1, SQLITE_STATIC);
  4064 
  4065     result = sqlite3_step(session->least_trust);
  4066     switch (result) {
  4067         case SQLITE_ROW: {
  4068             int _comm_type = sqlite3_column_int(session->least_trust, 0);
  4069             *comm_type = (PEP_comm_type) _comm_type;
  4070             break;
  4071         }
  4072         default:
  4073             // never reached because of sql min()
  4074             status = PEP_CANNOT_FIND_IDENTITY;
  4075     }
  4076 
  4077     sqlite3_reset(session->least_trust);
  4078     return status;
  4079 }
  4080 
  4081 DYNAMIC_API PEP_STATUS decrypt_and_verify(
  4082     PEP_SESSION session, const char *ctext, size_t csize,
  4083     const char *dsigtext, size_t dsigsize,
  4084     char **ptext, size_t *psize, stringlist_t **keylist,
  4085     char** filename_ptr
  4086     )
  4087 {
  4088     assert(session);
  4089     assert(ctext);
  4090     assert(csize);
  4091     assert(ptext);
  4092     assert(psize);
  4093     assert(keylist);
  4094 
  4095     if (!(session && ctext && csize && ptext && psize && keylist))
  4096         return PEP_ILLEGAL_VALUE;
  4097 
  4098     PEP_STATUS status = session->cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify(
  4099             session, ctext, csize, dsigtext, dsigsize, ptext, psize, keylist,
  4100             filename_ptr);
  4101 
  4102     if (status == PEP_DECRYPT_NO_KEY)
  4103         signal_Sync_event(session, Sync_PR_keysync, CannotDecrypt, NULL);
  4104 
  4105     return status;
  4106 }
  4107 
  4108 DYNAMIC_API PEP_STATUS encrypt_and_sign(
  4109     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  4110     size_t psize, char **ctext, size_t *csize
  4111     )
  4112 {
  4113     assert(session);
  4114     assert(keylist);
  4115     assert(ptext);
  4116     assert(psize);
  4117     assert(ctext);
  4118     assert(csize);
  4119 
  4120     if (!(session && keylist && ptext && psize && ctext && csize))
  4121         return PEP_ILLEGAL_VALUE;
  4122 
  4123     return session->cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign(session,
  4124             keylist, ptext, psize, ctext, csize);
  4125 }
  4126 
  4127 PEP_STATUS encrypt_only(
  4128     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  4129     size_t psize, char **ctext, size_t *csize
  4130     )
  4131 {
  4132     assert(session);
  4133     assert(keylist);
  4134     assert(ptext);
  4135     assert(psize);
  4136     assert(ctext);
  4137     assert(csize);
  4138 
  4139     if (!(session && keylist && ptext && psize && ctext && csize))
  4140         return PEP_ILLEGAL_VALUE;
  4141 
  4142     return session->cryptotech[PEP_crypt_OpenPGP].encrypt_only(session,
  4143             keylist, ptext, psize, ctext, csize);
  4144 }
  4145 
  4146 PEP_STATUS sign_only(PEP_SESSION session, 
  4147                      const char *data, 
  4148                      size_t data_size, 
  4149                      const char *fpr, 
  4150                      char **sign, 
  4151                      size_t *sign_size) {
  4152     assert(session);
  4153     assert(fpr);
  4154     assert(data);
  4155     assert(data_size);
  4156     assert(sign);
  4157     assert(sign_size);
  4158 
  4159     if (!(session && fpr && data && data_size && sign && sign_size))
  4160         return PEP_ILLEGAL_VALUE;
  4161 
  4162     return session->cryptotech[PEP_crypt_OpenPGP].sign_only(session,
  4163                                 fpr, data, data_size, sign, sign_size);
  4164                          
  4165 }
  4166 
  4167 
  4168 
  4169 DYNAMIC_API PEP_STATUS verify_text(
  4170     PEP_SESSION session, const char *text, size_t size,
  4171     const char *signature, size_t sig_size, stringlist_t **keylist
  4172     )
  4173 {
  4174     assert(session);
  4175     assert(text);
  4176     assert(size);
  4177     assert(signature);
  4178     assert(sig_size);
  4179     assert(keylist);
  4180 
  4181     if (!(session && text && size && signature && sig_size && keylist))
  4182         return PEP_ILLEGAL_VALUE;
  4183 
  4184     return session->cryptotech[PEP_crypt_OpenPGP].verify_text(session, text,
  4185             size, signature, sig_size, keylist);
  4186 }
  4187 
  4188 DYNAMIC_API PEP_STATUS delete_keypair(PEP_SESSION session, const char *fpr)
  4189 {
  4190     assert(session);
  4191     assert(fpr);
  4192 
  4193     if (!(session && fpr))
  4194         return PEP_ILLEGAL_VALUE;
  4195 
  4196     return session->cryptotech[PEP_crypt_OpenPGP].delete_keypair(session, fpr);
  4197 }
  4198 
  4199 DYNAMIC_API PEP_STATUS export_key(
  4200         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  4201     )
  4202 {
  4203     assert(session);
  4204     assert(fpr);
  4205     assert(key_data);
  4206     assert(size);
  4207 
  4208     if (!(session && fpr && key_data && size))
  4209         return PEP_ILLEGAL_VALUE;
  4210 
  4211     return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  4212             key_data, size, false);
  4213 }
  4214 
  4215 DYNAMIC_API PEP_STATUS export_secret_key(
  4216         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  4217     )
  4218 {
  4219     assert(session);
  4220     assert(fpr);
  4221     assert(key_data);
  4222     assert(size);
  4223 
  4224     if (!(session && fpr && key_data && size))
  4225         return PEP_ILLEGAL_VALUE;
  4226 
  4227     // don't accept key IDs but full fingerprints only
  4228     if (strlen(fpr) < 16)
  4229         return PEP_ILLEGAL_VALUE;
  4230 
  4231     return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  4232             key_data, size, true);
  4233 }
  4234 
  4235 // Deprecated
  4236 DYNAMIC_API PEP_STATUS export_secrect_key(
  4237         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  4238     )
  4239 {
  4240     return export_secret_key(session, fpr, key_data, size);
  4241 }
  4242 
  4243 DYNAMIC_API PEP_STATUS find_keys(
  4244         PEP_SESSION session, const char *pattern, stringlist_t **keylist
  4245     )
  4246 {
  4247     assert(session);
  4248     assert(pattern);
  4249     assert(keylist);
  4250 
  4251     if (!(session && pattern && keylist))
  4252         return PEP_ILLEGAL_VALUE;
  4253 
  4254     return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern,
  4255             keylist);
  4256 }
  4257 
  4258 
  4259 DYNAMIC_API PEP_STATUS generate_keypair(
  4260         PEP_SESSION session, pEp_identity *identity
  4261     )
  4262 {
  4263     assert(session);
  4264     assert(identity);
  4265     assert(identity->address);
  4266     assert(identity->fpr == NULL || identity->fpr[0] == 0);
  4267     assert(identity->username);
  4268 
  4269     if (!(session && identity && identity->address &&
  4270             (identity->fpr == NULL || identity->fpr[0] == 0) &&
  4271             identity->username))
  4272         return PEP_ILLEGAL_VALUE;
  4273 
  4274     PEP_STATUS status =
  4275         session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session,
  4276                 identity);
  4277     if (status != PEP_STATUS_OK)
  4278         return status;
  4279 
  4280     if (identity->fpr)
  4281         status = set_pgp_keypair(session, identity->fpr);
  4282 
  4283     signal_Sync_event(session, Sync_PR_keysync, KeyGen, NULL);
  4284 
  4285     // add to known keypair DB, as this might not end up being a default
  4286     return status;
  4287 }
  4288 
  4289 DYNAMIC_API PEP_STATUS get_key_rating(
  4290         PEP_SESSION session,
  4291         const char *fpr,
  4292         PEP_comm_type *comm_type
  4293     )
  4294 {
  4295     assert(session);
  4296     assert(fpr);
  4297     assert(comm_type);
  4298 
  4299     if (!(session && fpr && comm_type))
  4300         return PEP_ILLEGAL_VALUE;
  4301 
  4302     return session->cryptotech[PEP_crypt_OpenPGP].get_key_rating(session, fpr,
  4303             comm_type);
  4304 }
  4305 
  4306 DYNAMIC_API PEP_STATUS import_key(
  4307         PEP_SESSION session,
  4308         const char *key_data,
  4309         size_t size,
  4310         identity_list **private_keys
  4311     )
  4312 {
  4313     assert(session);
  4314     assert(key_data);
  4315 
  4316     if (!(session && key_data))
  4317         return PEP_ILLEGAL_VALUE;
  4318 
  4319     return session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data,
  4320             size, private_keys);
  4321 }
  4322 
  4323 DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
  4324 {
  4325     assert(session);
  4326     assert(pattern);
  4327 
  4328     if (!(session && pattern))
  4329         return PEP_ILLEGAL_VALUE;
  4330 
  4331     return session->cryptotech[PEP_crypt_OpenPGP].recv_key(session, pattern);
  4332 }
  4333 
  4334 DYNAMIC_API PEP_STATUS send_key(PEP_SESSION session, const char *pattern)
  4335 {
  4336     assert(session);
  4337     assert(pattern);
  4338 
  4339     if (!(session && pattern))
  4340         return PEP_ILLEGAL_VALUE;
  4341 
  4342     return session->cryptotech[PEP_crypt_OpenPGP].send_key(session, pattern);
  4343 }
  4344 
  4345 DYNAMIC_API PEP_STATUS renew_key(
  4346         PEP_SESSION session,
  4347         const char *fpr,
  4348         const timestamp *ts
  4349     )
  4350 {
  4351     assert(session);
  4352     assert(fpr);
  4353 
  4354     if (!(session && fpr))
  4355         return PEP_ILLEGAL_VALUE;
  4356 
  4357     return session->cryptotech[PEP_crypt_OpenPGP].renew_key(session, fpr, ts);
  4358 }
  4359 
  4360 DYNAMIC_API PEP_STATUS revoke_key(
  4361         PEP_SESSION session,
  4362         const char *fpr,
  4363         const char *reason
  4364     )
  4365 {
  4366     assert(session);
  4367     assert(fpr);
  4368 
  4369     if (!(session && fpr))
  4370         return PEP_ILLEGAL_VALUE;
  4371 
  4372     // Check to see first if it is revoked
  4373     bool revoked = false;
  4374     PEP_STATUS status = key_revoked(session, fpr, &revoked);
  4375     if (status != PEP_STATUS_OK)
  4376         return status;
  4377         
  4378     if (revoked)
  4379         return PEP_STATUS_OK;
  4380 
  4381     return session->cryptotech[PEP_crypt_OpenPGP].revoke_key(session, fpr,
  4382             reason);
  4383 }
  4384 
  4385 DYNAMIC_API PEP_STATUS key_expired(
  4386         PEP_SESSION session,
  4387         const char *fpr,
  4388         const time_t when,
  4389         bool *expired
  4390     )
  4391 {
  4392     assert(session);
  4393     assert(fpr);
  4394     assert(expired);
  4395 
  4396     if (!(session && fpr && expired))
  4397         return PEP_ILLEGAL_VALUE;
  4398 
  4399     return session->cryptotech[PEP_crypt_OpenPGP].key_expired(session, fpr,
  4400             when, expired);
  4401 }
  4402 
  4403 DYNAMIC_API PEP_STATUS key_revoked(
  4404        PEP_SESSION session,
  4405        const char *fpr,
  4406        bool *revoked
  4407    )
  4408 {
  4409     assert(session);
  4410     assert(fpr);
  4411     assert(revoked);
  4412     
  4413     if (!(session && fpr && revoked))
  4414         return PEP_ILLEGAL_VALUE;
  4415     
  4416     return session->cryptotech[PEP_crypt_OpenPGP].key_revoked(session, fpr,
  4417             revoked);
  4418 }
  4419 
  4420 DYNAMIC_API PEP_STATUS config_cipher_suite(PEP_SESSION session,
  4421         PEP_CIPHER_SUITE suite)
  4422 {
  4423     assert(session);
  4424     if (!session)
  4425         return PEP_ILLEGAL_VALUE;
  4426 
  4427     return session->cryptotech[PEP_crypt_OpenPGP].config_cipher_suite(session, suite);
  4428 }
  4429 
  4430 static void _clean_log_value(char *text)
  4431 {
  4432     if (text) {
  4433         for (char *c = text; *c; c++) {
  4434             if (*c < 32 && *c != '\n')
  4435                 *c = 32;
  4436             else if (*c == '"')
  4437                 *c = '\'';
  4438         }
  4439     }
  4440 }
  4441 
  4442 static char *_concat_string(char *str1, const char *str2, char delim)
  4443 {
  4444     str2 = str2 ? str2 : "";
  4445     size_t len1 = str1 ? strlen(str1) : 0;
  4446     size_t len2 = strlen(str2);
  4447     size_t len = len1 + len2 + 3;
  4448     char * result = realloc(str1, len + 1);
  4449 
  4450     if (result) {
  4451         result[len1] = '"';
  4452         strcpy(result + len1 + 1, str2);
  4453         result[len - 2] = '"';
  4454         result[len - 1] = delim;
  4455         result[len] = 0;
  4456     }
  4457     else {
  4458         free(str1);
  4459     }
  4460 
  4461     return result;
  4462 }
  4463 
  4464 DYNAMIC_API PEP_STATUS get_crashdump_log(
  4465         PEP_SESSION session,
  4466         int maxlines,
  4467         char **logdata
  4468     )
  4469 {
  4470     PEP_STATUS status = PEP_STATUS_OK;
  4471     char *_logdata= NULL;
  4472 
  4473     assert(session);
  4474     assert(maxlines >= 0 && maxlines <= CRASHDUMP_MAX_LINES);
  4475     assert(logdata);
  4476 
  4477     if (!(session && logdata && maxlines >= 0 && maxlines <=
  4478             CRASHDUMP_MAX_LINES))
  4479         return PEP_ILLEGAL_VALUE;
  4480 
  4481     *logdata = NULL;
  4482 
  4483     int limit = maxlines ? maxlines : CRASHDUMP_DEFAULT_LINES;
  4484     const char *timestamp = NULL;
  4485     const char *title = NULL;
  4486     const char *entity = NULL;
  4487     const char *desc = NULL;
  4488     const char *comment = NULL;
  4489 
  4490     sqlite3_reset(session->crashdump);
  4491     sqlite3_bind_int(session->crashdump, 1, limit);
  4492 
  4493     int result;
  4494 
  4495     do {
  4496         result = sqlite3_step(session->crashdump);
  4497         switch (result) {
  4498         case SQLITE_ROW:
  4499             timestamp = (const char *) sqlite3_column_text(session->crashdump,
  4500                     0);
  4501             title   = (const char *) sqlite3_column_text(session->crashdump,
  4502                     1);
  4503             entity  = (const char *) sqlite3_column_text(session->crashdump,
  4504                     2);
  4505             desc    = (const char *) sqlite3_column_text(session->crashdump,
  4506                     3);
  4507             comment = (const char *) sqlite3_column_text(session->crashdump,
  4508                     4);
  4509 
  4510             _logdata = _concat_string(_logdata, timestamp, ',');
  4511             if (_logdata == NULL)
  4512                 goto enomem;
  4513 
  4514             _logdata = _concat_string(_logdata, title, ',');
  4515             if (_logdata == NULL)
  4516                 goto enomem;
  4517 
  4518             _logdata = _concat_string(_logdata, entity, ',');
  4519             if (_logdata == NULL)
  4520                 goto enomem;
  4521 
  4522             _logdata = _concat_string(_logdata, desc, ',');
  4523             if (_logdata == NULL)
  4524                 goto enomem;
  4525 
  4526             _logdata = _concat_string(_logdata, comment, '\n');
  4527             if (_logdata == NULL)
  4528                 goto enomem;
  4529 
  4530             _clean_log_value(_logdata);
  4531             break;
  4532 
  4533         case SQLITE_DONE:
  4534             break;
  4535 
  4536         default:
  4537             status = PEP_UNKNOWN_ERROR;
  4538             result = SQLITE_DONE;
  4539         }
  4540     } while (result != SQLITE_DONE);
  4541 
  4542     sqlite3_reset(session->crashdump);
  4543     if (status == PEP_STATUS_OK) {
  4544         if (_logdata) {
  4545             *logdata = _logdata;
  4546         }
  4547         else {
  4548             *logdata = strdup("");
  4549             if (!*logdata)
  4550                 goto enomem;
  4551         }
  4552     }
  4553 
  4554     goto the_end;
  4555 
  4556 enomem:
  4557     status = PEP_OUT_OF_MEMORY;
  4558 
  4559 the_end:
  4560     return status;
  4561 }
  4562 
  4563 DYNAMIC_API PEP_STATUS get_languagelist(
  4564         PEP_SESSION session,
  4565         char **languages
  4566     )
  4567 {
  4568     PEP_STATUS status = PEP_STATUS_OK;
  4569     char *_languages= NULL;
  4570 
  4571     assert(session);
  4572     assert(languages);
  4573 
  4574     if (!(session && languages))
  4575         return PEP_ILLEGAL_VALUE;
  4576 
  4577     *languages = NULL;
  4578 
  4579     const char *lang = NULL;
  4580     const char *name = NULL;
  4581     const char *phrase = NULL;
  4582 
  4583     sqlite3_reset(session->languagelist);
  4584 
  4585     int result;
  4586 
  4587     do {
  4588         result = sqlite3_step(session->languagelist);
  4589         switch (result) {
  4590         case SQLITE_ROW:
  4591             lang = (const char *) sqlite3_column_text(session->languagelist,
  4592                     0);
  4593             name = (const char *) sqlite3_column_text(session->languagelist,
  4594                     1);
  4595             phrase = (const char *) sqlite3_column_text(session->languagelist,
  4596                     2);
  4597 
  4598             _languages = _concat_string(_languages, lang, ',');
  4599             if (_languages == NULL)
  4600                 goto enomem;
  4601 
  4602             _languages = _concat_string(_languages, name, ',');
  4603             if (_languages == NULL)
  4604                 goto enomem;
  4605 
  4606             _languages = _concat_string(_languages, phrase, '\n');
  4607             if (_languages == NULL)
  4608                 goto enomem;
  4609 
  4610             break;
  4611 
  4612         case SQLITE_DONE:
  4613             break;
  4614 
  4615         default:
  4616             status = PEP_UNKNOWN_DB_ERROR;
  4617             result = SQLITE_DONE;
  4618         }
  4619     } while (result != SQLITE_DONE);
  4620 
  4621     sqlite3_reset(session->languagelist);
  4622     if (status == PEP_STATUS_OK)
  4623         *languages = _languages;
  4624 
  4625     goto the_end;
  4626 
  4627 enomem:
  4628     status = PEP_OUT_OF_MEMORY;
  4629 
  4630 the_end:
  4631     return status;
  4632 }
  4633 
  4634 DYNAMIC_API PEP_STATUS get_phrase(
  4635         PEP_SESSION session,
  4636         const char *lang,
  4637         int phrase_id,
  4638         char **phrase
  4639     )
  4640 {
  4641     PEP_STATUS status = PEP_STATUS_OK;
  4642 
  4643     assert(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase);
  4644     if (!(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase))
  4645         return PEP_ILLEGAL_VALUE;
  4646 
  4647     *phrase = NULL;
  4648 
  4649     sqlite3_reset(session->i18n_token);
  4650     sqlite3_bind_text(session->i18n_token, 1, lang, -1, SQLITE_STATIC);
  4651     sqlite3_bind_int(session->i18n_token, 2, phrase_id);
  4652 
  4653     const char *_phrase = NULL;
  4654     int result;
  4655 
  4656     result = sqlite3_step(session->i18n_token);
  4657     switch (result) {
  4658     case SQLITE_ROW:
  4659         _phrase = (const char *) sqlite3_column_text(session->i18n_token, 0);
  4660         break;
  4661 
  4662     case SQLITE_DONE:
  4663         status = PEP_PHRASE_NOT_FOUND;
  4664         break;
  4665 
  4666     default:
  4667         status = PEP_UNKNOWN_DB_ERROR;
  4668     }
  4669 
  4670     if (status == PEP_STATUS_OK) {
  4671         *phrase = strdup(_phrase);
  4672         if (*phrase == NULL)
  4673             goto enomem;
  4674     }
  4675 
  4676     sqlite3_reset(session->i18n_token);
  4677     goto the_end;
  4678 
  4679 enomem:
  4680     status = PEP_OUT_OF_MEMORY;
  4681 
  4682 the_end:
  4683     return status;
  4684 }
  4685 
  4686 static PEP_STATUS _get_sequence_value(PEP_SESSION session, const char *name,
  4687         int32_t *value)
  4688 {
  4689     assert(session && name && value);
  4690     if (!(session && name && value))
  4691         return PEP_ILLEGAL_VALUE;
  4692 
  4693     PEP_STATUS status = PEP_STATUS_OK;
  4694 
  4695     sqlite3_reset(session->sequence_value2);
  4696     sqlite3_bind_text(session->sequence_value2, 1, name, -1,
  4697             SQLITE_STATIC);
  4698     int result = sqlite3_step(session->sequence_value2);
  4699     switch (result) {
  4700         case SQLITE_ROW: {
  4701             int32_t _value = (int32_t)
  4702                     sqlite3_column_int(session->sequence_value2, 0);
  4703             *value = _value;
  4704             break;
  4705         }
  4706         case SQLITE_DONE:
  4707             status = PEP_RECORD_NOT_FOUND;
  4708             break;
  4709         default:
  4710             status = PEP_UNKNOWN_DB_ERROR;
  4711     }
  4712     sqlite3_reset(session->sequence_value2);
  4713 
  4714     return status;
  4715 }
  4716 
  4717 static PEP_STATUS _increment_sequence_value(PEP_SESSION session,
  4718         const char *name)
  4719 {
  4720     assert(session && name);
  4721     if (!(session && name))
  4722         return PEP_ILLEGAL_VALUE;
  4723 
  4724     sqlite3_reset(session->sequence_value1);
  4725     sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
  4726     int result = sqlite3_step(session->sequence_value1);
  4727     assert(result == SQLITE_DONE);
  4728     sqlite3_reset(session->sequence_value1);
  4729     if (result == SQLITE_DONE)
  4730         return PEP_STATUS_OK;
  4731     else
  4732         return PEP_CANNOT_INCREASE_SEQUENCE;
  4733 }
  4734 
  4735 DYNAMIC_API PEP_STATUS sequence_value(
  4736         PEP_SESSION session,
  4737         const char *name,
  4738         int32_t *value
  4739     )
  4740 {
  4741     PEP_STATUS status = PEP_STATUS_OK;
  4742 
  4743     assert(session);
  4744     assert(name && value);
  4745 
  4746     if (!(session && name && name[0] && value))
  4747         return PEP_ILLEGAL_VALUE;
  4748 
  4749     *value = 0;
  4750     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  4751     status = _increment_sequence_value(session, name);
  4752     if (status == PEP_STATUS_OK)
  4753         status = _get_sequence_value(session, name, value);
  4754 
  4755     if (status == PEP_STATUS_OK) {
  4756         int result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  4757         if (result == SQLITE_OK){
  4758             assert(*value < INT32_MAX);
  4759             if (*value == INT32_MAX){
  4760                 return PEP_CANNOT_INCREASE_SEQUENCE;
  4761             }
  4762             return status;
  4763         } else {
  4764             return PEP_COMMIT_FAILED;
  4765         }
  4766     } else {
  4767         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  4768         return status;
  4769     }
  4770 
  4771     return status;
  4772 }
  4773 
  4774 PEP_STATUS is_own_key(PEP_SESSION session, const char* fpr, bool* own_key) {
  4775     
  4776     assert(session);
  4777     assert(!EMPTYSTR(fpr));
  4778 
  4779     if (!session || EMPTYSTR(fpr))
  4780         return PEP_ILLEGAL_VALUE;
  4781     
  4782     *own_key = false;
  4783     sqlite3_reset(session->own_key_is_listed);
  4784     
  4785     sqlite3_bind_text(session->own_key_is_listed, 1, fpr, -1,
  4786             SQLITE_STATIC);
  4787     int result = sqlite3_step(session->own_key_is_listed);
  4788     switch (result) {
  4789         case SQLITE_ROW: {
  4790             *own_key = (sqlite3_column_int(session->own_key_is_listed, 0) != 0);
  4791             break;
  4792         }
  4793         default:
  4794             sqlite3_reset(session->own_key_is_listed);
  4795             return PEP_UNKNOWN_DB_ERROR;
  4796     }
  4797 
  4798     sqlite3_reset(session->own_key_is_listed);
  4799     return PEP_STATUS_OK;
  4800 
  4801 }
  4802 
  4803 DYNAMIC_API PEP_STATUS set_revoked(
  4804        PEP_SESSION session,
  4805        const char *revoked_fpr,
  4806        const char *replacement_fpr,
  4807        const uint64_t revocation_date
  4808     )
  4809 {
  4810     PEP_STATUS status = PEP_STATUS_OK;
  4811     
  4812     assert(session &&
  4813            revoked_fpr && revoked_fpr[0] &&
  4814            replacement_fpr && replacement_fpr[0]
  4815           );
  4816     
  4817     if (!(session &&
  4818           revoked_fpr && revoked_fpr[0] &&
  4819           replacement_fpr && replacement_fpr[0]
  4820          ))
  4821         return PEP_ILLEGAL_VALUE;
  4822     
  4823     sqlite3_reset(session->set_revoked);
  4824     sqlite3_bind_text(session->set_revoked, 1, revoked_fpr, -1, SQLITE_STATIC);
  4825     sqlite3_bind_text(session->set_revoked, 2, replacement_fpr, -1,
  4826             SQLITE_STATIC);
  4827     sqlite3_bind_int64(session->set_revoked, 3, revocation_date);
  4828 
  4829     int result;
  4830     
  4831     result = sqlite3_step(session->set_revoked);
  4832     switch (result) {
  4833         case SQLITE_DONE:
  4834             status = PEP_STATUS_OK;
  4835             break;
  4836             
  4837         default:
  4838             status = PEP_UNKNOWN_DB_ERROR;
  4839     }
  4840     
  4841     sqlite3_reset(session->set_revoked);
  4842     return status;
  4843 }
  4844 
  4845 DYNAMIC_API PEP_STATUS get_revoked(
  4846         PEP_SESSION session,
  4847         const char *fpr,
  4848         char **revoked_fpr,
  4849         uint64_t *revocation_date
  4850     )
  4851 {
  4852     PEP_STATUS status = PEP_STATUS_OK;
  4853 
  4854     assert(session &&
  4855            revoked_fpr &&
  4856            fpr && fpr[0]
  4857           );
  4858     
  4859     if (!(session &&
  4860            revoked_fpr &&
  4861            fpr && fpr[0]
  4862           ))
  4863         return PEP_ILLEGAL_VALUE;
  4864 
  4865     *revoked_fpr = NULL;
  4866     *revocation_date = 0;
  4867 
  4868     sqlite3_reset(session->get_revoked);
  4869     sqlite3_bind_text(session->get_revoked, 1, fpr, -1, SQLITE_STATIC);
  4870 
  4871     int result;
  4872     
  4873     result = sqlite3_step(session->get_revoked);
  4874     switch (result) {
  4875         case SQLITE_ROW: {
  4876             *revoked_fpr = strdup((const char *)
  4877                     sqlite3_column_text(session->get_revoked, 0));
  4878             if(*revoked_fpr)
  4879                 *revocation_date = sqlite3_column_int64(session->get_revoked,
  4880                         1);
  4881             else
  4882                 status = PEP_OUT_OF_MEMORY;
  4883 
  4884             break;
  4885         }
  4886         default:
  4887             status = PEP_CANNOT_FIND_IDENTITY;
  4888     }
  4889 
  4890     sqlite3_reset(session->get_revoked);
  4891 
  4892     return status;
  4893 }
  4894 
  4895 DYNAMIC_API PEP_STATUS get_replacement_fpr(
  4896         PEP_SESSION session,
  4897         const char *fpr,
  4898         char **revoked_fpr,
  4899         uint64_t *revocation_date
  4900     )
  4901 {
  4902     PEP_STATUS status = PEP_STATUS_OK;
  4903 
  4904     assert(session && revoked_fpr && !EMPTYSTR(fpr) && revocation_date);
  4905     
  4906     if (!session || !revoked_fpr || EMPTYSTR(fpr) || !revocation_date)
  4907         return PEP_ILLEGAL_VALUE;
  4908 
  4909     *revoked_fpr = NULL;
  4910     *revocation_date = 0;
  4911 
  4912     sqlite3_reset(session->get_replacement_fpr);
  4913     sqlite3_bind_text(session->get_replacement_fpr, 1, fpr, -1, SQLITE_STATIC);
  4914 
  4915     int result;
  4916     
  4917     result = sqlite3_step(session->get_replacement_fpr);
  4918     switch (result) {
  4919         case SQLITE_ROW: {
  4920             *revoked_fpr = strdup((const char *)
  4921                     sqlite3_column_text(session->get_replacement_fpr, 0));
  4922             if(*revoked_fpr)
  4923                 *revocation_date = sqlite3_column_int64(session->get_replacement_fpr,
  4924                         1);
  4925             else
  4926                 status = PEP_OUT_OF_MEMORY;
  4927 
  4928             break;
  4929         }
  4930         default:
  4931             status = PEP_CANNOT_FIND_IDENTITY;
  4932     }
  4933 
  4934     sqlite3_reset(session->get_replacement_fpr);
  4935 
  4936     return status;
  4937 }
  4938 
  4939 PEP_STATUS get_last_contacted(
  4940         PEP_SESSION session,
  4941         identity_list** id_list
  4942     )
  4943 {
  4944     assert(session);
  4945     assert(id_list);
  4946 
  4947     if (!(session && id_list))
  4948         return PEP_ILLEGAL_VALUE;
  4949 
  4950     *id_list = NULL;
  4951     identity_list* ident_list = NULL;
  4952 
  4953     sqlite3_reset(session->get_last_contacted);
  4954     int result;
  4955 
  4956     while ((result = sqlite3_step(session->get_last_contacted)) == SQLITE_ROW) {
  4957         pEp_identity *ident = new_identity(
  4958                 (const char *) sqlite3_column_text(session->get_last_contacted, 1),
  4959                 NULL,
  4960                 (const char *) sqlite3_column_text(session->get_last_contacted, 0),
  4961                 NULL);
  4962                 
  4963         assert(ident);
  4964         if (ident == NULL) {
  4965             sqlite3_reset(session->get_last_contacted);
  4966             return PEP_OUT_OF_MEMORY;
  4967         }
  4968     
  4969         if (ident_list)
  4970             identity_list_add(ident_list, ident);
  4971         else
  4972             ident_list = new_identity_list(ident);
  4973     }
  4974 
  4975     sqlite3_reset(session->get_last_contacted);
  4976     
  4977     *id_list = ident_list;
  4978     
  4979     if (!ident_list)
  4980         return PEP_CANNOT_FIND_IDENTITY;
  4981     
  4982     return PEP_STATUS_OK;    
  4983 }
  4984 
  4985 
  4986 PEP_STATUS key_created(
  4987         PEP_SESSION session,
  4988         const char *fpr,
  4989         time_t *created
  4990     )
  4991 {
  4992     assert(session && fpr && created);
  4993     if (!(session && fpr && created))
  4994         return PEP_ILLEGAL_VALUE;
  4995 
  4996     return session->cryptotech[PEP_crypt_OpenPGP].key_created(session, fpr,
  4997             created);
  4998 }
  4999 
  5000 PEP_STATUS find_private_keys(PEP_SESSION session, const char* pattern,
  5001                              stringlist_t **keylist) {
  5002     assert(session && keylist);
  5003     if (!(session && keylist))
  5004         return PEP_ILLEGAL_VALUE;
  5005     
  5006     return session->cryptotech[PEP_crypt_OpenPGP].find_private_keys(session, pattern,
  5007                                                                     keylist);
  5008 }
  5009 
  5010 
  5011 DYNAMIC_API const char* get_engine_version() {
  5012     return PEP_ENGINE_VERSION;
  5013 }
  5014 
  5015 
  5016 DYNAMIC_API PEP_STATUS reset_pEptest_hack(PEP_SESSION session)
  5017 {
  5018     assert(session);
  5019 
  5020     if (!session)
  5021         return PEP_ILLEGAL_VALUE;
  5022 
  5023     int int_result = sqlite3_exec(
  5024         session->db,
  5025         "delete from identity where address like '%@pEptest.ch' ;",
  5026         NULL,
  5027         NULL,
  5028         NULL
  5029     );
  5030     assert(int_result == SQLITE_OK);
  5031 
  5032     if (int_result != SQLITE_OK)
  5033         return PEP_UNKNOWN_DB_ERROR;
  5034 
  5035     return PEP_STATUS_OK;
  5036 }
  5037 
  5038 #ifdef DEBUG_ERRORSTACK
  5039 PEP_STATUS session_add_error(PEP_SESSION session, const char* file, unsigned line, PEP_STATUS status)
  5040 {
  5041     char logline[48];
  5042     if(status>0)
  5043     {
  5044         snprintf(logline,47, "%.24s:%u status=%u (0x%x)", file, line, status, status);
  5045     }else{
  5046         snprintf(logline,47, "%.24s:%u status=%i.", file, line, status);
  5047     }
  5048     stringlist_add(session->errorstack, logline); // logline is copied! :-)
  5049     return status;
  5050 }
  5051 
  5052 DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  5053 {
  5054     return session->errorstack;
  5055 }
  5056 
  5057 DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  5058 {
  5059     const int old_len = stringlist_length(session->errorstack);
  5060     char buf[48];
  5061     free_stringlist(session->errorstack);
  5062     snprintf(buf, 47, "(%i elements cleared)", old_len);
  5063     session->errorstack = new_stringlist(buf);
  5064 }
  5065 
  5066 #else
  5067 
  5068 static stringlist_t* dummy_errorstack = NULL;
  5069 
  5070 DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  5071 {
  5072     if(dummy_errorstack == NULL)
  5073     {
  5074         dummy_errorstack = new_stringlist("( Please recompile pEpEngine with -DDEBUG_ERRORSTACK )");
  5075     }
  5076 
  5077     return dummy_errorstack;
  5078 }
  5079 
  5080 DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  5081 {
  5082     // nothing to do here
  5083 }
  5084 
  5085 #endif