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