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