src/pEpEngine.c
author Volker Birk <vb@pep.foundation>
Sat, 24 Feb 2018 10:57:24 +0100
changeset 2532 4d46b7dd0fce
parent 2526 c254f28206de
child 2539 58c77e002d60
child 2542 b7f6df848795
permissions -rw-r--r--
empty crash log shouldn't crash itself
     1 // This file is under GNU General Public License 3.0
     2 // see LICENSE.txt
     3 
     4 #include "pEp_internal.h"
     5 #include "dynamic_api.h"
     6 #include "cryptotech.h"
     7 #include "transport.h"
     8 #include "blacklist.h"
     9 
    10 #include <time.h>
    11 #include <stdlib.h>
    12 
    13 #define _PEP_SQLITE_DEBUG 0
    14 #if _PEP_SQLITE_DEBUG
    15 #include <sqlite3.h>
    16 #endif
    17 
    18 static volatile int init_count = -1;
    19 
    20 // sql overloaded functions - modified from sqlite3.c
    21 static void _sql_lower(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
    22     char *z1;
    23     const char *z2;
    24     int i, n;
    25     z2 = (char*)sqlite3_value_text(argv[0]);
    26     n = sqlite3_value_bytes(argv[0]);
    27     /* Verify that the call to _bytes() does not invalidate the _text() pointer */
    28     assert( z2==(char*)sqlite3_value_text(argv[0]) );
    29     if( z2 ){
    30         z1 = (char*)sqlite3_malloc(n+1);
    31         if( z1 ){
    32             for(i=0; i<n; i++){
    33                 char c = z2[i];
    34                 char c_mod = c | 0x20;
    35                 if (c_mod < 0x61 || c_mod > 0x7a)
    36                     c_mod = c;
    37                 z1[i] = c_mod;
    38             }
    39             z1[n] = '\0';
    40             sqlite3_result_text(ctx, z1, n, sqlite3_free);
    41         }
    42     }
    43 }
    44 
    45 #if _PEP_SQLITE_DEBUG
    46 int sql_trace_callback (unsigned trace_constant, 
    47                         void* context_ptr,
    48                         void* P,
    49                         void* X) {
    50     switch (trace_constant) {
    51         case SQLITE_TRACE_STMT:
    52             fprintf(stderr, "SQL_DEBUG: STMT - ");
    53             const char* X_str = (const char*) X;
    54             if (!EMPTYSTR(X_str) && X_str[0] == '-' && X_str[1] == '-')
    55                 fprintf(stderr, "%s\n", X_str);
    56             else
    57                 fprintf(stderr, "%s\n", sqlite3_expanded_sql((sqlite3_stmt*)P));
    58             break;
    59         case SQLITE_TRACE_ROW:
    60             fprintf(stderr, "SQL_DEBUG: ROW - ");
    61             fprintf(stderr, "%s\n", sqlite3_expanded_sql((sqlite3_stmt*)P));
    62             break;            
    63         case SQLITE_TRACE_CLOSE:
    64             fprintf(stderr, "SQL_DEBUG: CLOSE - ");
    65             break;
    66         default:
    67             break;
    68     }
    69     return 0;
    70 }
    71 #endif
    72 
    73 // sql manipulation statements
    74 static const char *sql_log = 
    75     "insert into log (title, entity, description, comment)"
    76      "values (?1, ?2, ?3, ?4);";
    77 
    78 static const char *sql_trustword = 
    79     "select id, word from wordlist where lang = lower(?1) "
    80     "and id = ?2 ;";
    81 
    82 static const char *sql_get_identity =  
    83     "select fpr, username, comm_type, lang,"
    84     "   identity.flags | pgp_keypair.flags,"
    85     "   is_own"
    86     "   from identity"
    87     "   join person on id = identity.user_id"
    88     "   join pgp_keypair on fpr = identity.main_key_id"
    89     "   join trust on id = trust.user_id"
    90     "       and pgp_keypair_fpr = identity.main_key_id"    
    91     "   where (case when (address = ?1) then (1)"
    92     "               when (lower(address) = lower(?1)) then (1)"
    93     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
    94     "               else 0"
    95     "          end) = 1"
    96     "   and identity.user_id = ?2" 
    97     "   order by is_own desc, "
    98     "   timestamp desc; ";
    99 
   100 static const char *sql_get_identity_without_trust_check =  
   101     "select identity.main_key_id, username, lang,"
   102     "   identity.flags, is_own"
   103     "   from identity"
   104     "   join person on id = identity.user_id"
   105     "   where (case when (address = ?1) then (1)"
   106     "               when (lower(address) = lower(?1)) then (1)"
   107     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   108     "               else 0"
   109     "          end) = 1"
   110     "   and identity.user_id = ?2 "
   111     "   order by is_own desc, "
   112     "   timestamp desc; ";
   113 
   114 static const char *sql_get_identities_by_address =  
   115     "select user_id, identity.main_key_id, username, lang,"
   116     "   identity.flags, is_own"
   117     "   from identity"
   118     "   join person on id = identity.user_id"
   119     "   where (case when (address = ?1) then (1)"
   120     "               when (lower(address) = lower(?1)) then (1)"
   121     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   122     "               else 0"
   123     "          end) = 1 "
   124     "   order by is_own desc, "
   125     "   timestamp desc; ";
   126 
   127 static const char *sql_replace_identities_fpr =  
   128     "update identity"
   129     "   set main_key_id = ?1 "
   130     "   where main_key_id = ?2 ;";
   131     
   132 static const char *sql_remove_fpr_as_default =
   133     "update person set main_key_id = NULL where main_key_id = ?1 ;"
   134     "update identity set main_key_id = NULL where main_key_id = ?1 ;";
   135 
   136 // Set person, but if already exist, only update.
   137 // if main_key_id already set, don't touch.
   138 static const char *sql_set_person = 
   139      "insert into person (id, username, lang, main_key_id, device_group)"
   140      "  values (?1, ?2, ?3, ?4, "
   141      "          (select device_group from person where id = ?1)) ;";
   142 
   143 static const char *sql_update_person = 
   144     "update person "
   145     "   set username = ?2, "
   146     "       lang = ?3, "
   147     "       main_key_id =  "
   148     "           (select coalesce( "
   149     "               (select main_key_id from person where id = ?1), " 
   150     "                upper(replace(?4,' ','')))),"         
   151     "       device_group = "
   152     "           (select device_group from person where id = ?1)"
   153     "   where id = ?1 ;";
   154     
   155 static const char *sql_set_as_pep_user =
   156     "update person set is_pep_user = 1 "
   157     "   where id = ?1 ; ";
   158 
   159 static const char *sql_is_pep_user =
   160     "select is_pep_user from person "
   161     "   where id = ?1 ; ";
   162 
   163 static const char* sql_exists_person = 
   164     "select count(*) from person "
   165     "   where id = ?1 ;";
   166 
   167 static const char *sql_set_device_group = 
   168     "update person set device_group = ?1 "
   169     "   where id = ?2;";
   170 
   171 // This will cascade to identity and trust
   172 static const char* sql_replace_userid =
   173     "update person set id = ?1 " 
   174     "   where id = ?2;";
   175 
   176 static const char *sql_replace_main_user_fpr =  
   177     "update person "
   178     "   set main_key_id = ?1 "
   179     "   where id = ?2 ;";
   180 
   181 static const char *sql_get_main_user_fpr =  
   182     "select main_key_id from person"
   183     "   where id = ?1 ;";
   184 
   185 static const char *sql_refresh_userid_default_key =
   186     "update person "
   187     "   set main_key_id = "
   188     "       (select identity.main_key_id from identity "
   189     "           join trust on trust.user_id = identity.user_id "
   190     "               and trust.pgp_keypair_fpr = identity.main_key_id "
   191     "           join person on identity.user_id = identity.user_id "
   192     "       where identity.user_id = ?1 "
   193     "       order by trust.comm_type desc "
   194     "       limit 1) "
   195     "where id = ?1 ; ";
   196 
   197 static const char *sql_get_device_group = 
   198     "select device_group from person "
   199     "where id = ?1;";
   200 
   201 static const char *sql_set_pgp_keypair = 
   202     "insert or ignore into pgp_keypair (fpr) "
   203     "values (upper(replace(?1,' ',''))) ;";
   204 
   205 static const char* sql_exists_identity_entry = 
   206     "select count(*) from identity "
   207     "   where (case when (address = ?1) then (1)"
   208     "               when (lower(address) = lower(?1)) then (1)"
   209     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   210     "               else 0"
   211     "          end) = 1"
   212     "    and user_id = ?2;";
   213  
   214 static const char *sql_set_identity_entry = 
   215     "insert into identity ("
   216     "       address, main_key_id, "
   217     "       user_id, flags, is_own"
   218     "   ) values ("
   219     "       ?1,"
   220     "       upper(replace(?2,' ','')),"
   221     "       ?3,"
   222     "       ?4,"
   223     "       ?5"
   224     "   );";
   225     
   226 static const char* sql_update_identity_entry =    
   227     "update identity "
   228     "   set main_key_id = upper(replace(?2,' ','')), "
   229     "       flags = ?4, " 
   230     "       is_own = ?5 "
   231     "   where (case when (address = ?1) then (1)"
   232     "               when (lower(address) = lower(?1)) then (1)"
   233     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1) "
   234     "               else 0 "
   235     "          end) = 1 "
   236     "          and user_id = ?3 ;";
   237 
   238     // " (select"
   239     // "   coalesce("
   240     // "    (select flags from identity"
   241     // "     where address = ?1 and"
   242     // "           user_id = ?3),"
   243     // "    0)"
   244     // " ) | (?4 & 255)"
   245     /* set_identity ignores previous flags, and doesn't filter machine flags */
   246         
   247 static const char *sql_set_identity_flags = 
   248     "update identity set flags = "
   249     "    ((?1 & 255) | (select flags from identity"
   250     "                    where (case when (address = ?2) then (1)"
   251     "                                when (lower(address) = lower(?2)) then (1)"
   252     "                                when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   253     "                                else 0 "    
   254     "                           end) = 1 "
   255     "                           and user_id = ?3)) "
   256     "   where (case when (address = ?2) then (1)"
   257     "               when (lower(address) = lower(?2)) then (1)"
   258     "               when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   259     "               else 0"
   260     "          end) = 1"
   261     "          and user_id = ?3 ;";
   262 
   263 static const char *sql_unset_identity_flags = 
   264     "update identity set flags = "
   265     "    ( ~(?1 & 255) & (select flags from identity"
   266     "                    where (case when (address = ?2) then (1)"
   267     "                                when (lower(address) = lower(?2)) then (1)"
   268     "                                when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   269     "                                else 0 "    
   270     "                           end) = 1 "
   271     "                           and user_id = ?3)) "
   272     "   where (case when (address = ?2) then (1)"
   273     "               when (lower(address) = lower(?2)) then (1)"
   274     "               when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   275     "               else 0"
   276     "          end) = 1"
   277     "          and user_id = ?3 ;";
   278 
   279 static const char *sql_set_trust =
   280     "insert into trust (user_id, pgp_keypair_fpr, comm_type) "
   281     "values (?1, upper(replace(?2,' ','')), ?3) ;";
   282 
   283 static const char *sql_update_trust =
   284     "update trust set comm_type = ?3 " 
   285     "   where user_id = ?1 and pgp_keypair_fpr = upper(replace(?2,' ',''));";
   286 
   287 static const char* sql_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_exec(        
  1463                     session->db,
  1464                     "PRAGMA optimize;\n",
  1465                     NULL,
  1466                     NULL,
  1467                     NULL
  1468                 );
  1469                 sqlite3_close_v2(session->db);
  1470             }
  1471             if (session->system_db)
  1472                 sqlite3_close_v2(session->system_db);
  1473         }
  1474 
  1475         release_transport_system(session, out_last);
  1476         release_cryptotech(session, out_last);
  1477 
  1478 #ifdef DEBUG_ERRORSTACK
  1479         free_stringlist(session->errorstack);
  1480 #endif
  1481         free(session);
  1482     }
  1483 }
  1484 
  1485 DYNAMIC_API void config_passive_mode(PEP_SESSION session, bool enable)
  1486 {
  1487     assert(session);
  1488     session->passive_mode = enable;
  1489 }
  1490 
  1491 DYNAMIC_API void config_unencrypted_subject(PEP_SESSION session, bool enable)
  1492 {
  1493     assert(session);
  1494     session->unencrypted_subject = enable;
  1495 }
  1496 
  1497 DYNAMIC_API void config_keep_sync_msg(PEP_SESSION session, bool enable)
  1498 {
  1499     assert(session);
  1500     session->keep_sync_msg = enable;
  1501 }
  1502 
  1503 DYNAMIC_API void config_service_log(PEP_SESSION session, bool enable)
  1504 {
  1505     assert(session);
  1506     session->service_log = enable;
  1507 }
  1508 
  1509 DYNAMIC_API PEP_STATUS log_event(
  1510         PEP_SESSION session,
  1511         const char *title,
  1512         const char *entity,
  1513         const char *description,
  1514         const char *comment
  1515     )
  1516 {
  1517 //    PEP_STATUS status = PEP_STATUS_OK;
  1518     // int result;
  1519     // 
  1520     // assert(session);
  1521     // assert(title);
  1522     // assert(entity);
  1523     // 
  1524     // if (!(session && title && entity))
  1525     //     return PEP_ILLEGAL_VALUE;
  1526     // 
  1527     // sqlite3_reset(session->log);
  1528     // sqlite3_bind_text(session->log, 1, title, -1, SQLITE_STATIC);
  1529     // sqlite3_bind_text(session->log, 2, entity, -1, SQLITE_STATIC);
  1530     // if (description)
  1531     //     sqlite3_bind_text(session->log, 3, description, -1, SQLITE_STATIC);
  1532     // else
  1533     //     sqlite3_bind_null(session->log, 3);
  1534     // if (comment)
  1535     //     sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
  1536     // else
  1537     //     sqlite3_bind_null(session->log, 4);
  1538     // result = sqlite3_step(session->log);
  1539     // sqlite3_reset(session->log);
  1540     // 
  1541     return PEP_STATUS_OK; // We ignore errors for this function.
  1542 }
  1543 
  1544 DYNAMIC_API PEP_STATUS log_service(
  1545         PEP_SESSION session,
  1546         const char *title,
  1547         const char *entity,
  1548         const char *description,
  1549         const char *comment
  1550     )
  1551 {
  1552     assert(session);
  1553     if (!session)
  1554         return PEP_ILLEGAL_VALUE;
  1555 
  1556     if (session->service_log)
  1557         return log_event(session, title, entity, description, comment);
  1558     else
  1559         return PEP_STATUS_OK;
  1560 }
  1561 
  1562 DYNAMIC_API PEP_STATUS trustword(
  1563             PEP_SESSION session, uint16_t value, const char *lang,
  1564             char **word, size_t *wsize
  1565         )
  1566 {
  1567     PEP_STATUS status = PEP_STATUS_OK;
  1568 
  1569     assert(session);
  1570     assert(word);
  1571     assert(wsize);
  1572 
  1573     if (!(session && word && wsize))
  1574         return PEP_ILLEGAL_VALUE;
  1575 
  1576     *word = NULL;
  1577     *wsize = 0;
  1578 
  1579     if (lang == NULL)
  1580         lang = "en";
  1581 
  1582     assert((lang[0] >= 'A' && lang[0] <= 'Z')
  1583             || (lang[0] >= 'a' && lang[0] <= 'z'));
  1584     assert((lang[1] >= 'A' && lang[1] <= 'Z')
  1585             || (lang[1] >= 'a' && lang[1] <= 'z'));
  1586     assert(lang[2] == 0);
  1587 
  1588     sqlite3_reset(session->trustword);
  1589     sqlite3_bind_text(session->trustword, 1, lang, -1, SQLITE_STATIC);
  1590     sqlite3_bind_int(session->trustword, 2, value);
  1591 
  1592     const int result = sqlite3_step(session->trustword);
  1593     if (result == SQLITE_ROW) {
  1594         *word = strdup((const char *) sqlite3_column_text(session->trustword,
  1595                     1));
  1596         if (*word)
  1597             *wsize = sqlite3_column_bytes(session->trustword, 1);
  1598         else
  1599             status = PEP_OUT_OF_MEMORY;
  1600     } else
  1601         status = PEP_TRUSTWORD_NOT_FOUND;
  1602 
  1603     sqlite3_reset(session->trustword);
  1604     return status;
  1605 }
  1606 
  1607 DYNAMIC_API PEP_STATUS trustwords(
  1608         PEP_SESSION session, const char *fingerprint, const char *lang,
  1609         char **words, size_t *wsize, int max_words
  1610     )
  1611 {
  1612     const char *source = fingerprint;
  1613 
  1614     assert(session);
  1615     assert(fingerprint);
  1616     assert(words);
  1617     assert(wsize);
  1618     assert(max_words >= 0);
  1619 
  1620     if (!(session && fingerprint && words && wsize && max_words >= 0))
  1621         return PEP_ILLEGAL_VALUE;
  1622 
  1623     *words = NULL;
  1624     *wsize = 0;
  1625 
  1626     char *buffer = calloc(1, MAX_TRUSTWORDS_SPACE);
  1627     assert(buffer);
  1628     if (buffer == NULL)
  1629         return PEP_OUT_OF_MEMORY;
  1630     char *dest = buffer;
  1631 
  1632     const size_t fsize = strlen(fingerprint);
  1633 
  1634     if (!lang || !lang[0])
  1635         lang = "en";
  1636 
  1637     assert((lang[0] >= 'A' && lang[0] <= 'Z')
  1638             || (lang[0] >= 'a' && lang[0] <= 'z'));
  1639     assert((lang[1] >= 'A' && lang[1] <= 'Z')
  1640             || (lang[1] >= 'a' && lang[1] <= 'z'));
  1641     assert(lang[2] == 0);
  1642 
  1643     int n_words = 0;
  1644     while (source < fingerprint + fsize) {
  1645         PEP_STATUS _status;
  1646         uint16_t value;
  1647         char *word = NULL;
  1648         size_t _wsize = 0;
  1649         int j;
  1650 
  1651         for (value=0, j=0; j < 4 && source < fingerprint + fsize; ) {
  1652             if (*source >= 'a' && *source <= 'f')
  1653                 value += (*source - 'a' + 10) << (3 - j++) * 4;
  1654             else if (*source >= 'A' && *source <= 'F')
  1655                 value += (*source - 'A' + 10) << (3 - j++) * 4;
  1656             else if (*source >= '0' && *source <= '9')
  1657                 value += (*source - '0') << (3 - j++) * 4;
  1658             
  1659             source++;
  1660         }
  1661 
  1662         _status = trustword(session, value, lang, &word, &_wsize);
  1663         if (_status == PEP_OUT_OF_MEMORY) {
  1664             free(buffer);
  1665             return PEP_OUT_OF_MEMORY;
  1666         }
  1667         if (word == NULL) {
  1668             free(buffer);
  1669             return PEP_TRUSTWORD_NOT_FOUND;
  1670         }
  1671 
  1672         if (dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1) {
  1673             strncpy(dest, word, _wsize);
  1674             free(word);
  1675             dest += _wsize;
  1676         }
  1677         else {
  1678             free(word);
  1679             break; // buffer full
  1680         }
  1681 
  1682         if (source < fingerprint + fsize
  1683                 && dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1)
  1684             *dest++ = ' ';
  1685 
  1686         ++n_words;
  1687         if (max_words && n_words >= max_words)
  1688             break;
  1689     }
  1690 
  1691     *words = buffer;
  1692     *wsize = dest - buffer;
  1693     return PEP_STATUS_OK;
  1694 }
  1695 
  1696 pEp_identity *new_identity(
  1697         const char *address, const char *fpr, const char *user_id,
  1698         const char *username
  1699     )
  1700 {
  1701     pEp_identity *result = calloc(1, sizeof(pEp_identity));
  1702     assert(result);
  1703     if (result) {
  1704         if (address) {
  1705             result->address = strdup(address);
  1706             assert(result->address);
  1707             if (result->address == NULL) {
  1708                 free(result);
  1709                 return NULL;
  1710             }
  1711         }
  1712         if (fpr) {
  1713             result->fpr = strdup(fpr);
  1714             assert(result->fpr);
  1715             if (result->fpr == NULL) {
  1716                 free_identity(result);
  1717                 return NULL;
  1718             }
  1719         }
  1720         if (user_id) {
  1721             result->user_id = strdup(user_id);
  1722             assert(result->user_id);
  1723             if (result->user_id == NULL) {
  1724                 free_identity(result);
  1725                 return NULL;
  1726             }
  1727         }
  1728         if (username) {
  1729             result->username = strdup(username);
  1730             assert(result->username);
  1731             if (result->username == NULL) {
  1732                 free_identity(result);
  1733                 return NULL;
  1734             }
  1735         }
  1736     }
  1737     return result;
  1738 }
  1739 
  1740 pEp_identity *identity_dup(const pEp_identity *src)
  1741 {
  1742     assert(src);
  1743 
  1744     pEp_identity *dup = new_identity(src->address, src->fpr, src->user_id,
  1745             src->username);
  1746     assert(dup);
  1747     if (dup == NULL)
  1748         return NULL;
  1749     
  1750     dup->comm_type = src->comm_type;
  1751     dup->lang[0] = src->lang[0];
  1752     dup->lang[1] = src->lang[1];
  1753     dup->lang[2] = 0;
  1754     dup->flags = src->flags;
  1755     dup->me = src->me;
  1756     
  1757     return dup;
  1758 }
  1759 
  1760 void free_identity(pEp_identity *identity)
  1761 {
  1762     if (identity) {
  1763         free(identity->address);
  1764         free(identity->fpr);
  1765         free(identity->user_id);
  1766         free(identity->username);
  1767         free(identity);
  1768     }
  1769 }
  1770 
  1771 DYNAMIC_API PEP_STATUS get_default_own_userid(
  1772         PEP_SESSION session, 
  1773         char** userid
  1774     )
  1775 {
  1776     assert(session);
  1777     assert(userid);
  1778     
  1779     if (!session || !userid)
  1780         return PEP_ILLEGAL_VALUE;
  1781         
  1782     PEP_STATUS status = PEP_STATUS_OK;
  1783     char* retval = NULL;
  1784     
  1785     sqlite3_reset(session->get_default_own_userid);
  1786 
  1787     const int result = sqlite3_step(session->get_default_own_userid);
  1788     const char* id;
  1789     
  1790     switch (result) {
  1791         case SQLITE_ROW:
  1792             id = (const char *) sqlite3_column_text(session->get_default_own_userid, 0);
  1793             if (!id) {
  1794                 // Shouldn't happen.
  1795                 status = PEP_UNKNOWN_ERROR;
  1796             }
  1797             else {
  1798                 retval = strdup(id);
  1799                 if (!retval)
  1800                     status = PEP_OUT_OF_MEMORY;
  1801             }
  1802             break;
  1803         default:
  1804             // Technically true, given how we find it, but FIXME we need a more descriptive error
  1805             status = PEP_CANNOT_FIND_IDENTITY;
  1806             *userid = NULL;
  1807     }
  1808 
  1809     *userid = retval;
  1810 
  1811     sqlite3_reset(session->get_default_own_userid);
  1812     
  1813     return status;
  1814 }
  1815 
  1816 DYNAMIC_API PEP_STATUS get_userid_alias_default(
  1817         PEP_SESSION session, 
  1818         const char* alias_id,
  1819         char** default_id) {
  1820             
  1821     assert(session);
  1822     assert(alias_id);
  1823     assert(alias_id[0]);
  1824     assert(default_id);
  1825 
  1826     if (!(session && alias_id && alias_id[0] && default_id))
  1827         return PEP_ILLEGAL_VALUE;
  1828 
  1829     PEP_STATUS status = PEP_STATUS_OK;
  1830     char* retval = NULL;
  1831 
  1832     sqlite3_reset(session->get_userid_alias_default);
  1833     sqlite3_bind_text(session->get_userid_alias_default, 1, alias_id, -1, SQLITE_STATIC);
  1834 
  1835     const char* tempid;
  1836     
  1837     const int result = sqlite3_step(session->get_userid_alias_default);
  1838     switch (result) {
  1839     case SQLITE_ROW:
  1840         tempid = (const char *) sqlite3_column_text(session->get_userid_alias_default, 0);
  1841         if (tempid) {
  1842             retval = strdup(tempid);
  1843             assert(retval);
  1844             if (retval == NULL)
  1845                 return PEP_OUT_OF_MEMORY;
  1846         }
  1847     
  1848         *default_id = retval;
  1849         break;
  1850     default:
  1851         status = PEP_CANNOT_FIND_ALIAS;
  1852         *default_id = NULL;
  1853     }
  1854 
  1855     sqlite3_reset(session->get_userid_alias_default);
  1856     return status;            
  1857 }
  1858 
  1859 DYNAMIC_API PEP_STATUS set_userid_alias (
  1860         PEP_SESSION session, 
  1861         const char* default_id,
  1862         const char* alias_id) {
  1863             
  1864     int result;
  1865 
  1866     assert(session);
  1867     assert(default_id);
  1868     assert(alias_id);
  1869 
  1870     if (!(session && default_id && alias_id && 
  1871           default_id[0] != '\0' && alias_id[0] != '\0'))
  1872         return PEP_ILLEGAL_VALUE;
  1873     
  1874     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  1875 
  1876     sqlite3_reset(session->add_userid_alias);
  1877     sqlite3_bind_text(session->add_userid_alias, 1, default_id, -1,
  1878             SQLITE_STATIC);
  1879     sqlite3_bind_text(session->add_userid_alias, 2, alias_id, -1,
  1880             SQLITE_STATIC);
  1881         
  1882     result = sqlite3_step(session->add_userid_alias);
  1883 
  1884     sqlite3_reset(session->add_userid_alias);
  1885     if (result != SQLITE_DONE) {
  1886         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);        
  1887         return PEP_CANNOT_SET_ALIAS;
  1888     }
  1889     sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  1890         
  1891 
  1892     return PEP_STATUS_OK;
  1893 }
  1894 
  1895 DYNAMIC_API PEP_STATUS get_identity(
  1896         PEP_SESSION session,
  1897         const char *address,
  1898         const char *user_id,
  1899         pEp_identity **identity
  1900     )
  1901 {
  1902     PEP_STATUS status = PEP_STATUS_OK;
  1903     static pEp_identity *_identity;
  1904 
  1905     assert(session);
  1906     assert(address);
  1907     assert(address[0]);
  1908     assert(identity);
  1909 
  1910     if (!(session && address && address[0] && identity))
  1911         return PEP_ILLEGAL_VALUE;
  1912 
  1913     *identity = NULL;
  1914 
  1915     sqlite3_reset(session->get_identity);
  1916     sqlite3_bind_text(session->get_identity, 1, address, -1, SQLITE_STATIC);
  1917     sqlite3_bind_text(session->get_identity, 2, user_id, -1, SQLITE_STATIC);
  1918 
  1919     const int result = sqlite3_step(session->get_identity);
  1920     switch (result) {
  1921     case SQLITE_ROW:
  1922         _identity = new_identity(
  1923                 address,
  1924                 (const char *) sqlite3_column_text(session->get_identity, 0),
  1925                 user_id,
  1926                 (const char *) sqlite3_column_text(session->get_identity, 1)
  1927                 );
  1928         assert(_identity);
  1929         if (_identity == NULL) {
  1930             sqlite3_reset(session->get_identity);
  1931             return PEP_OUT_OF_MEMORY;
  1932         }
  1933 
  1934         _identity->comm_type = (PEP_comm_type)
  1935             sqlite3_column_int(session->get_identity, 2);
  1936         const char* const _lang = (const char *)
  1937             sqlite3_column_text(session->get_identity, 3);
  1938         if (_lang && _lang[0]) {
  1939             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  1940             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  1941             assert(_lang[2] == 0);
  1942             _identity->lang[0] = _lang[0];
  1943             _identity->lang[1] = _lang[1];
  1944             _identity->lang[2] = 0;
  1945         }
  1946         _identity->flags = (unsigned int)
  1947             sqlite3_column_int(session->get_identity, 4);
  1948         _identity->me = (unsigned int)
  1949             sqlite3_column_int(session->get_identity, 5);
  1950     
  1951         *identity = _identity;
  1952         break;
  1953     default:
  1954         sqlite3_reset(session->get_identity);
  1955         status = PEP_CANNOT_FIND_IDENTITY;
  1956         *identity = NULL;
  1957     }
  1958 
  1959     sqlite3_reset(session->get_identity);
  1960     return status;
  1961 }
  1962 
  1963 PEP_STATUS get_identity_without_trust_check(
  1964         PEP_SESSION session,
  1965         const char *address,
  1966         const char *user_id,
  1967         pEp_identity **identity
  1968     )
  1969 {
  1970     PEP_STATUS status = PEP_STATUS_OK;
  1971     static pEp_identity *_identity;
  1972 
  1973     assert(session);
  1974     assert(address);
  1975     assert(address[0]);
  1976     assert(identity);
  1977 
  1978     if (!(session && address && address[0] && identity))
  1979         return PEP_ILLEGAL_VALUE;
  1980 
  1981     *identity = NULL;
  1982 
  1983     sqlite3_reset(session->get_identity_without_trust_check);
  1984     sqlite3_bind_text(session->get_identity_without_trust_check, 1, address, -1, SQLITE_STATIC);
  1985     sqlite3_bind_text(session->get_identity_without_trust_check, 2, user_id, -1, SQLITE_STATIC);
  1986 
  1987     const int result = sqlite3_step(session->get_identity_without_trust_check);
  1988     switch (result) {
  1989     case SQLITE_ROW:
  1990         _identity = new_identity(
  1991                 address,
  1992                 (const char *) sqlite3_column_text(session->get_identity_without_trust_check, 0),
  1993                 user_id,
  1994                 (const char *) sqlite3_column_text(session->get_identity_without_trust_check, 1)
  1995                 );
  1996         assert(_identity);
  1997         if (_identity == NULL) {
  1998             sqlite3_reset(session->get_identity_without_trust_check);
  1999             return PEP_OUT_OF_MEMORY;
  2000         }
  2001 
  2002         _identity->comm_type = PEP_ct_unknown;
  2003         const char* const _lang = (const char *)
  2004             sqlite3_column_text(session->get_identity_without_trust_check, 2);
  2005         if (_lang && _lang[0]) {
  2006             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  2007             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  2008             assert(_lang[2] == 0);
  2009             _identity->lang[0] = _lang[0];
  2010             _identity->lang[1] = _lang[1];
  2011             _identity->lang[2] = 0;
  2012         }
  2013         _identity->flags = (unsigned int)
  2014             sqlite3_column_int(session->get_identity_without_trust_check, 3);
  2015         _identity->me = (unsigned int)
  2016             sqlite3_column_int(session->get_identity_without_trust_check, 4);
  2017     
  2018         *identity = _identity;
  2019         break;
  2020     default:
  2021         status = PEP_CANNOT_FIND_IDENTITY;
  2022         *identity = NULL;
  2023     }
  2024 
  2025     sqlite3_reset(session->get_identity_without_trust_check);
  2026     return status;
  2027 }
  2028 
  2029 PEP_STATUS get_identities_by_address(
  2030         PEP_SESSION session,
  2031         const char *address,
  2032         identity_list** id_list
  2033     )
  2034 {
  2035     pEp_identity* ident;
  2036 
  2037     assert(session);
  2038     assert(address);
  2039     assert(address[0]);
  2040     assert(id_list);
  2041 
  2042     if (!(session && address && address[0] && id_list))
  2043         return PEP_ILLEGAL_VALUE;
  2044 
  2045     *id_list = NULL;
  2046     identity_list* ident_list = NULL;
  2047 
  2048     sqlite3_reset(session->get_identities_by_address);
  2049     sqlite3_bind_text(session->get_identities_by_address, 1, address, -1, SQLITE_STATIC);
  2050     int result;
  2051 
  2052     while ((result = sqlite3_step(session->get_identities_by_address)) == SQLITE_ROW) {
  2053         //"select user_id, main_key_id, username, comm_type, lang,"
  2054         //"   identity.flags, is_own"
  2055         ident = new_identity(
  2056                 address,
  2057                 (const char *) sqlite3_column_text(session->get_identities_by_address, 1),
  2058                 (const char *) sqlite3_column_text(session->get_identities_by_address, 0),
  2059                 (const char *) sqlite3_column_text(session->get_identities_by_address, 2)
  2060                 );
  2061         assert(ident);
  2062         if (ident == NULL) {
  2063             sqlite3_reset(session->get_identities_by_address);
  2064             return PEP_OUT_OF_MEMORY;
  2065         }
  2066 
  2067         ident->comm_type = PEP_ct_unknown;
  2068         
  2069         const char* const _lang = (const char *)
  2070             sqlite3_column_text(session->get_identities_by_address, 3);
  2071         if (_lang && _lang[0]) {
  2072             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  2073             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  2074             assert(_lang[2] == 0);
  2075             ident->lang[0] = _lang[0];
  2076             ident->lang[1] = _lang[1];
  2077             ident->lang[2] = 0;
  2078         }
  2079         ident->flags = (unsigned int)
  2080             sqlite3_column_int(session->get_identities_by_address, 4);
  2081         ident->me = (unsigned int)
  2082             sqlite3_column_int(session->get_identities_by_address, 5);
  2083     
  2084         if (ident_list)
  2085             identity_list_add(ident_list, ident);
  2086         else
  2087             ident_list = new_identity_list(ident);
  2088     }
  2089 
  2090     sqlite3_reset(session->get_identities_by_address);
  2091     
  2092     *id_list = ident_list;
  2093     
  2094     if (!ident_list)
  2095         return PEP_CANNOT_FIND_IDENTITY;
  2096     
  2097     return PEP_STATUS_OK;
  2098 }
  2099 
  2100 PEP_STATUS exists_identity_entry(PEP_SESSION session, pEp_identity* identity,
  2101                                  bool* exists) {
  2102     assert(session);
  2103     assert(identity);
  2104     assert(!EMPTYSTR(identity->user_id));        
  2105     assert(!EMPTYSTR(identity->address));
  2106     if (!session || !exists || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->address))
  2107         return PEP_ILLEGAL_VALUE;
  2108     
  2109     *exists = false;
  2110     
  2111     PEP_STATUS status = PEP_STATUS_OK;
  2112     
  2113     sqlite3_reset(session->exists_identity_entry);
  2114     sqlite3_bind_text(session->exists_identity_entry, 1, identity->address, -1,
  2115                       SQLITE_STATIC);
  2116     sqlite3_bind_text(session->exists_identity_entry, 2, identity->user_id, -1,
  2117                       SQLITE_STATIC);
  2118                   
  2119     int result = sqlite3_step(session->exists_identity_entry);
  2120     switch (result) {
  2121         case SQLITE_ROW: {
  2122             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2123             *exists = (sqlite3_column_int(session->exists_identity_entry, 0) != 0);
  2124             break;
  2125         }
  2126         default: 
  2127             status = PEP_UNKNOWN_ERROR;
  2128     }
  2129 
  2130     sqlite3_reset(session->exists_identity_entry);
  2131     return status;
  2132 }
  2133 
  2134 PEP_STATUS exists_trust_entry(PEP_SESSION session, pEp_identity* identity,
  2135                               bool* exists) {
  2136     assert(session);
  2137     assert(identity);
  2138     assert(!EMPTYSTR(identity->user_id));        
  2139     assert(!EMPTYSTR(identity->fpr));
  2140     if (!session || !exists || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->fpr))
  2141         return PEP_ILLEGAL_VALUE;
  2142     
  2143     *exists = false;
  2144     
  2145     PEP_STATUS status = PEP_STATUS_OK;
  2146     
  2147     sqlite3_reset(session->exists_trust_entry);
  2148     sqlite3_bind_text(session->exists_trust_entry, 1, identity->user_id, -1,
  2149                       SQLITE_STATIC);
  2150     sqlite3_bind_text(session->exists_trust_entry, 2, identity->fpr, -1,
  2151                       SQLITE_STATIC);
  2152                   
  2153     int result = sqlite3_step(session->exists_trust_entry);
  2154     switch (result) {
  2155         case SQLITE_ROW: {
  2156             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2157             *exists = (sqlite3_column_int(session->exists_trust_entry, 0) != 0);
  2158             break;
  2159         }
  2160         default:
  2161             status = PEP_UNKNOWN_ERROR;
  2162     }
  2163     
  2164     sqlite3_reset(session->exists_trust_entry);
  2165     return status;
  2166 }
  2167 
  2168 // FIXME: We can rollback in set_identity on the return status,
  2169 // so we should probably do that.
  2170 PEP_STATUS set_pgp_keypair(PEP_SESSION session, const char* fpr) {
  2171     if (!session || EMPTYSTR(fpr))
  2172         return PEP_ILLEGAL_VALUE;
  2173         
  2174     int result;
  2175     
  2176     sqlite3_reset(session->set_pgp_keypair);
  2177     sqlite3_bind_text(session->set_pgp_keypair, 1, fpr, -1,
  2178             SQLITE_STATIC);
  2179     result = sqlite3_step(session->set_pgp_keypair);
  2180     sqlite3_reset(session->set_pgp_keypair);
  2181     if (result != SQLITE_DONE) {
  2182         return PEP_CANNOT_SET_PGP_KEYPAIR;
  2183     }
  2184     
  2185     return PEP_STATUS_OK;
  2186 }
  2187 
  2188 static PEP_STATUS _set_or_update_trust(PEP_SESSION session,
  2189                                        pEp_identity* identity,
  2190                                        sqlite3_stmt* set_or_update) {
  2191 
  2192     assert(session);
  2193     assert(identity);
  2194     assert(identity->user_id);
  2195     assert(identity->fpr);
  2196     
  2197     if (!session || !identity || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->fpr))
  2198         return PEP_ILLEGAL_VALUE;
  2199         
  2200     int result;
  2201                 
  2202     sqlite3_reset(set_or_update);
  2203     sqlite3_bind_text(set_or_update, 1, identity->user_id, -1,
  2204             SQLITE_STATIC);
  2205     sqlite3_bind_text(set_or_update, 2, identity->fpr, -1,
  2206             SQLITE_STATIC);
  2207     sqlite3_bind_int(set_or_update, 3, identity->comm_type);
  2208     result = sqlite3_step(set_or_update);
  2209     assert(result == SQLITE_DONE);
  2210     sqlite3_reset(set_or_update);
  2211     if (result != SQLITE_DONE)
  2212         return PEP_CANNOT_SET_TRUST;
  2213 
  2214     return PEP_STATUS_OK;
  2215 }
  2216 
  2217 static PEP_STATUS _set_or_update_identity_entry(PEP_SESSION session,
  2218                                                 pEp_identity* identity,
  2219                                                 sqlite3_stmt* set_or_update) {
  2220     assert(session);
  2221     assert(identity);
  2222     assert(set_or_update);
  2223                       
  2224     if (!session || !identity || !identity->user_id || !identity->address)
  2225         return PEP_ILLEGAL_VALUE;
  2226                                               
  2227     sqlite3_reset(set_or_update);
  2228     sqlite3_bind_text(set_or_update, 1, identity->address, -1,
  2229             SQLITE_STATIC);
  2230     sqlite3_bind_text(set_or_update, 2, identity->fpr, -1,
  2231             SQLITE_STATIC);
  2232     sqlite3_bind_text(set_or_update, 3, identity->user_id, -1,
  2233             SQLITE_STATIC);
  2234     sqlite3_bind_int(set_or_update, 4, identity->flags);
  2235     sqlite3_bind_int(set_or_update, 5, identity->me);
  2236     int result = sqlite3_step(set_or_update);
  2237     sqlite3_reset(set_or_update);
  2238     if (result != SQLITE_DONE)
  2239         return PEP_CANNOT_SET_IDENTITY;
  2240     
  2241     return PEP_STATUS_OK;
  2242 }
  2243 
  2244 static PEP_STATUS _set_or_update_person(PEP_SESSION session, 
  2245                                         pEp_identity* identity,
  2246                                         sqlite3_stmt* set_or_update) {
  2247     assert(session);
  2248     assert(identity);
  2249     assert(set_or_update);
  2250                         
  2251     if (!session || !identity || !identity->user_id || !identity->username)
  2252         return PEP_ILLEGAL_VALUE;
  2253         
  2254     sqlite3_reset(set_or_update);
  2255     sqlite3_bind_text(set_or_update, 1, identity->user_id, -1,
  2256             SQLITE_STATIC);
  2257     sqlite3_bind_text(set_or_update, 2, identity->username, -1,
  2258             SQLITE_STATIC);
  2259     if (identity->lang[0])
  2260         sqlite3_bind_text(set_or_update, 3, identity->lang, 2,
  2261                 SQLITE_STATIC);
  2262     else
  2263         sqlite3_bind_null(set_or_update, 3);
  2264     sqlite3_bind_text(set_or_update, 4, identity->fpr, -1,
  2265                       SQLITE_STATIC);
  2266     int result = sqlite3_step(set_or_update);
  2267     sqlite3_reset(set_or_update);
  2268     
  2269     if (result != SQLITE_DONE)
  2270         return PEP_CANNOT_SET_PERSON;
  2271     
  2272     return PEP_STATUS_OK;                                         
  2273 }
  2274 
  2275 PEP_STATUS set_or_update_with_identity(PEP_SESSION session,
  2276                                        pEp_identity* identity,
  2277                                        PEP_STATUS (* set_function)(PEP_SESSION, pEp_identity*, sqlite3_stmt*),
  2278                                        PEP_STATUS (* exists_function)(PEP_SESSION, pEp_identity*, bool*),                                       
  2279                                        sqlite3_stmt* update_query,
  2280                                        sqlite3_stmt* set_query,
  2281                                        bool guard_transaction) {
  2282 
  2283     if (guard_transaction) {
  2284         sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  2285     }
  2286     bool exists = false;
  2287     PEP_STATUS status = exists_function(session, identity, &exists);
  2288     
  2289     if (status == PEP_STATUS_OK) {
  2290         if (exists) {
  2291             status = set_function(session, identity, update_query);
  2292         }
  2293         else {
  2294             status = set_function(session, identity, set_query);                                              
  2295         }                    
  2296     }   
  2297     if (guard_transaction) {        
  2298         if (status != PEP_STATUS_OK)
  2299             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2300         else 
  2301             sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  2302     }                      
  2303     return status;
  2304 }
  2305 
  2306 PEP_STATUS _set_trust_internal(PEP_SESSION session, pEp_identity* identity,
  2307                                bool guard_transaction) {
  2308     return set_or_update_with_identity(session, identity,
  2309                                        _set_or_update_trust,
  2310                                         exists_trust_entry,
  2311                                         session->update_trust,
  2312                                         session->set_trust,
  2313                                         guard_transaction);
  2314 }
  2315 
  2316 // This is the TOP-LEVEL function. If you're calling from set_identity,
  2317 // you can't use this one.
  2318 PEP_STATUS set_trust(PEP_SESSION session, pEp_identity* identity) {
  2319     PEP_STATUS status = PEP_STATUS_OK;
  2320     
  2321     status = _set_trust_internal(session, identity, true);
  2322     if (status == PEP_STATUS_OK) {
  2323         if ((identity->comm_type | PEP_ct_confirmed) == PEP_ct_pEp)
  2324             status = set_as_pep_user(session, identity);
  2325     }
  2326     return status;
  2327 }
  2328 
  2329 PEP_STATUS set_person(PEP_SESSION session, pEp_identity* identity,
  2330                       bool guard_transaction) {
  2331     return set_or_update_with_identity(session, identity,
  2332                                        _set_or_update_person,
  2333                                        exists_person,
  2334                                        session->update_person,
  2335                                        session->set_person,
  2336                                        guard_transaction);
  2337 }
  2338 
  2339 PEP_STATUS set_identity_entry(PEP_SESSION session, pEp_identity* identity,
  2340                               bool guard_transaction) {
  2341     return set_or_update_with_identity(session, identity,
  2342                                        _set_or_update_identity_entry,
  2343                                        exists_identity_entry,
  2344                                        session->update_identity_entry,
  2345                                        session->set_identity_entry,
  2346                                        guard_transaction);
  2347 }
  2348 
  2349 // This will NOT call set_as_pep_user; you have to do that separately.
  2350 DYNAMIC_API PEP_STATUS set_identity(
  2351         PEP_SESSION session, const pEp_identity *identity
  2352     )
  2353 {
  2354     int result;
  2355 
  2356     assert(session);
  2357     assert(identity);
  2358     assert(identity->address);
  2359     assert(identity->user_id);
  2360     assert(identity->username);
  2361 
  2362     if (!(session && identity && identity->address &&
  2363                 identity->user_id && identity->username))
  2364         return PEP_ILLEGAL_VALUE;
  2365 
  2366     PEP_STATUS status = PEP_STATUS_OK;
  2367     
  2368     bool listed;
  2369 
  2370     bool has_fpr = (!EMPTYSTR(identity->fpr));
  2371     
  2372     if (has_fpr) {    
  2373         // blacklist check - FIXME: ENGINE-294 will remove
  2374         status = blacklist_is_listed(session, identity->fpr, &listed);
  2375         assert(status == PEP_STATUS_OK);
  2376         if (status != PEP_STATUS_OK)
  2377             return status;
  2378 
  2379         if (listed)
  2380             return PEP_KEY_BLACKLISTED;
  2381     }
  2382 
  2383     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  2384 
  2385     if (identity->lang[0]) {
  2386         assert(identity->lang[0] >= 'a' && identity->lang[0] <= 'z');
  2387         assert(identity->lang[1] >= 'a' && identity->lang[1] <= 'z');
  2388         assert(identity->lang[2] == 0);
  2389     }
  2390 
  2391     if (has_fpr) {
  2392         sqlite3_reset(session->set_pgp_keypair);
  2393         sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
  2394                 SQLITE_STATIC);
  2395         result = sqlite3_step(session->set_pgp_keypair);
  2396         sqlite3_reset(session->set_pgp_keypair);
  2397         if (result != SQLITE_DONE) {
  2398             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2399             return PEP_CANNOT_SET_PGP_KEYPAIR;
  2400         }
  2401     }
  2402 
  2403     // We do this because there are checks in set_person for
  2404     // aliases, which modify the identity object on return.
  2405     pEp_identity* ident_copy = identity_dup(identity); 
  2406     if (!ident_copy)
  2407         return PEP_OUT_OF_MEMORY;
  2408 
  2409     status = set_person(session, ident_copy, false);
  2410     if (status != PEP_STATUS_OK) {
  2411         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2412         goto pep_free;
  2413     }
  2414 
  2415     status = set_identity_entry(session, ident_copy, false);
  2416     if (status != PEP_STATUS_OK) {
  2417         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2418         goto pep_free;
  2419     }
  2420 
  2421     if (has_fpr) {
  2422         status = _set_trust_internal(session, ident_copy, false);
  2423         if (status != PEP_STATUS_OK) {
  2424             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2425             goto pep_free;
  2426         }
  2427     }
  2428     
  2429     result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  2430     if (result == SQLITE_OK)
  2431         status = PEP_STATUS_OK;
  2432     else
  2433         status = PEP_COMMIT_FAILED;
  2434 
  2435 pep_free:
  2436     free_identity(ident_copy);
  2437     return status;
  2438 }
  2439 
  2440 // This ONLY sets the user flag. Must be called outside of a transaction.
  2441 PEP_STATUS set_as_pep_user(PEP_SESSION session, pEp_identity* user) {
  2442 
  2443     assert(session);
  2444     assert(user);
  2445     assert(!EMPTYSTR(user->user_id));
  2446         
  2447     if (!session || !user || EMPTYSTR(user->user_id))
  2448         return PEP_ILLEGAL_VALUE;
  2449             
  2450     PEP_STATUS status = PEP_STATUS_OK;
  2451     
  2452     bool person_exists = false;
  2453     
  2454     status = exists_person(session, user, &person_exists);
  2455     
  2456     if (status != PEP_STATUS_OK)
  2457         return status;
  2458         
  2459     if (!person_exists)
  2460         status = set_person(session, user, true);
  2461         
  2462     // Ok, let's set it.
  2463     sqlite3_reset(session->set_as_pep_user);
  2464     sqlite3_bind_text(session->set_as_pep_user, 1, user->user_id, -1,
  2465             SQLITE_STATIC);
  2466     int result = sqlite3_step(session->set_as_pep_user);
  2467     sqlite3_reset(session->set_as_pep_user);
  2468     
  2469     if (result != SQLITE_DONE)
  2470         return PEP_CANNOT_SET_PERSON;
  2471         
  2472     return PEP_STATUS_OK;    
  2473 }
  2474 
  2475 PEP_STATUS exists_person(PEP_SESSION session, pEp_identity* identity,
  2476                          bool* exists) {            
  2477     
  2478     // const char* user_id,
  2479     //                      char** default_id, bool* exists) {
  2480     assert(session);
  2481     assert(exists);
  2482     assert(identity);
  2483     assert(!EMPTYSTR(identity->user_id));
  2484         
  2485     if (!session || !exists || !identity || EMPTYSTR(identity->user_id))
  2486         return PEP_ILLEGAL_VALUE;
  2487     
  2488     *exists = false;
  2489 
  2490     const char* user_id = identity->user_id;
  2491     char* alias_default = NULL;
  2492     
  2493     PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
  2494     
  2495     if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
  2496         sqlite3_reset(session->exists_person);
  2497         sqlite3_bind_text(session->exists_person, 1, user_id, -1,
  2498                 SQLITE_STATIC);
  2499         int result = sqlite3_step(session->exists_person);
  2500         switch (result) {
  2501             case SQLITE_ROW: {
  2502                 // yeah yeah, I know, we could be lazy here, but it looks bad.
  2503                 *exists = (sqlite3_column_int(session->exists_person, 0) != 0);
  2504                 status = PEP_STATUS_OK;
  2505                 break;
  2506             }
  2507             default:
  2508                 sqlite3_reset(session->exists_person);
  2509                 return PEP_UNKNOWN_ERROR;
  2510         }
  2511         sqlite3_reset(session->exists_person);
  2512     }
  2513     else if (status == PEP_STATUS_OK) {
  2514         *exists = true; // thank you, delete on cascade!
  2515         // FIXME: Should we correct the userid default here? I think we should.
  2516         free(identity->user_id);
  2517         identity->user_id = alias_default; // ownership transfer
  2518     }
  2519     else
  2520         free(alias_default);
  2521             
  2522     return status;
  2523 }
  2524 
  2525 DYNAMIC_API PEP_STATUS is_pep_user(PEP_SESSION session, pEp_identity *identity, bool* is_pep)
  2526 {
  2527     assert(session);
  2528     assert(is_pep);
  2529     assert(identity);
  2530     assert(!EMPTYSTR(identity->user_id));
  2531 
  2532     if (!session || !is_pep || !identity || EMPTYSTR(identity->user_id))
  2533         return PEP_ILLEGAL_VALUE;
  2534     
  2535     *is_pep = false;
  2536             
  2537     const char* user_id = identity->user_id;
  2538     
  2539     if (!session || EMPTYSTR(user_id))
  2540         return PEP_ILLEGAL_VALUE;
  2541         
  2542     char* alias_default = NULL;
  2543     
  2544     PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
  2545     
  2546     if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
  2547         free(alias_default);
  2548         alias_default = strdup(user_id);
  2549     }
  2550     
  2551     sqlite3_reset(session->is_pep_user);
  2552     sqlite3_bind_text(session->is_pep_user, 1, user_id, -1,
  2553             SQLITE_STATIC);
  2554     int result = sqlite3_step(session->is_pep_user);
  2555     switch (result) {
  2556         case SQLITE_ROW: {
  2557             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2558             *is_pep = (sqlite3_column_int(session->is_pep_user, 0) != 0);
  2559             break;
  2560         }
  2561         default:
  2562             sqlite3_reset(session->is_pep_user);
  2563             free(alias_default);
  2564             return PEP_CANNOT_FIND_PERSON;
  2565     }
  2566 
  2567     sqlite3_reset(session->is_pep_user);
  2568     return PEP_STATUS_OK;
  2569 }
  2570 
  2571 
  2572 PEP_STATUS remove_fpr_as_default(PEP_SESSION session, 
  2573                                  const char* fpr) 
  2574 {
  2575     assert(fpr);
  2576     
  2577     if (!session || !fpr)
  2578         return PEP_ILLEGAL_VALUE;
  2579             
  2580     sqlite3_reset(session->remove_fpr_as_default);
  2581     sqlite3_bind_text(session->remove_fpr_as_default, 1, fpr, -1,
  2582                       SQLITE_STATIC);
  2583 
  2584     int result = sqlite3_step(session->remove_fpr_as_default);
  2585     sqlite3_reset(session->remove_fpr_as_default);
  2586     
  2587     if (result != SQLITE_DONE)
  2588         return PEP_CANNOT_SET_IDENTITY; // misleading - could also be person
  2589 
  2590     return PEP_STATUS_OK;
  2591 }
  2592 
  2593 
  2594 PEP_STATUS replace_identities_fpr(PEP_SESSION session, 
  2595                                  const char* old_fpr, 
  2596                                  const char* new_fpr) 
  2597 {
  2598     assert(old_fpr);
  2599     assert(new_fpr);
  2600     
  2601     if (!old_fpr || !new_fpr)
  2602         return PEP_ILLEGAL_VALUE;
  2603             
  2604     sqlite3_reset(session->replace_identities_fpr);
  2605     sqlite3_bind_text(session->replace_identities_fpr, 1, new_fpr, -1,
  2606                       SQLITE_STATIC);
  2607     sqlite3_bind_text(session->replace_identities_fpr, 2, old_fpr, -1,
  2608                       SQLITE_STATIC);
  2609 
  2610     int result = sqlite3_step(session->replace_identities_fpr);
  2611     sqlite3_reset(session->replace_identities_fpr);
  2612     
  2613     if (result != SQLITE_DONE)
  2614         return PEP_CANNOT_SET_IDENTITY;
  2615 
  2616     return PEP_STATUS_OK;
  2617 }
  2618 
  2619 PEP_STATUS update_trust_for_fpr(PEP_SESSION session, 
  2620                                 const char* fpr, 
  2621                                 PEP_comm_type comm_type)
  2622 {
  2623     if (!fpr)
  2624         return PEP_ILLEGAL_VALUE;
  2625         
  2626     sqlite3_reset(session->update_trust_for_fpr);
  2627     sqlite3_bind_int(session->update_trust_for_fpr, 1, comm_type);
  2628     sqlite3_bind_text(session->update_trust_for_fpr, 2, fpr, -1,
  2629             SQLITE_STATIC);
  2630     int result = sqlite3_step(session->update_trust_for_fpr);
  2631     sqlite3_reset(session->update_trust_for_fpr);
  2632     if (result != SQLITE_DONE) {
  2633         return PEP_CANNOT_SET_TRUST;
  2634     }
  2635     
  2636     return PEP_STATUS_OK;
  2637 }
  2638 
  2639 DYNAMIC_API PEP_STATUS set_device_group(
  2640         PEP_SESSION session,
  2641         const char *group_name
  2642     )
  2643 {
  2644     int result;
  2645 
  2646     assert(session);
  2647 
  2648     if (!(session && group_name))
  2649         return PEP_ILLEGAL_VALUE;
  2650 
  2651     // 1. Get own user_id
  2652     char* user_id = NULL;
  2653     PEP_STATUS status = get_default_own_userid(session, &user_id);
  2654     
  2655     // No user_id is returned in this case, no need to free;
  2656     if (status != PEP_STATUS_OK)
  2657         return status;
  2658         
  2659     // 2. Set device group
  2660     sqlite3_reset(session->set_device_group);
  2661     if(group_name){
  2662         sqlite3_bind_text(session->set_device_group, 1, group_name, -1,
  2663                 SQLITE_STATIC);
  2664     } else {
  2665         sqlite3_bind_null(session->set_device_group, 1);
  2666     }
  2667     
  2668     sqlite3_bind_text(session->set_device_group, 2, user_id, -1,
  2669             SQLITE_STATIC);
  2670 
  2671     result = sqlite3_step(session->set_device_group);
  2672     sqlite3_reset(session->set_device_group);
  2673     
  2674     free(user_id);
  2675     
  2676     if (result != SQLITE_DONE)
  2677         return PEP_CANNOT_SET_PERSON;
  2678 
  2679     return PEP_STATUS_OK;
  2680 }
  2681 
  2682 DYNAMIC_API PEP_STATUS get_device_group(PEP_SESSION session, char **group_name)
  2683 {
  2684     PEP_STATUS status = PEP_STATUS_OK;
  2685     int result;
  2686 
  2687     assert(session);
  2688     assert(group_name);
  2689 
  2690     if (!(session && group_name))
  2691         return PEP_ILLEGAL_VALUE;
  2692 
  2693     // 1. Get own user_id
  2694     char* user_id = NULL;
  2695     status = get_default_own_userid(session, &user_id);
  2696     
  2697     // No user_id is returned in this case, no need to free;
  2698     if (status != PEP_STATUS_OK)
  2699         return status;
  2700 
  2701     // 2. get device group
  2702     sqlite3_reset(session->get_device_group);
  2703     sqlite3_bind_text(session->get_device_group, 1, user_id, -1,
  2704             SQLITE_STATIC);
  2705 
  2706     result = sqlite3_step(session->get_device_group);
  2707     switch (result) {
  2708     case SQLITE_ROW: {
  2709         const char *_group_name = (const char *)sqlite3_column_text(session->get_device_group, 0);
  2710         if(_group_name){
  2711             *group_name = strdup(_group_name);
  2712                 if(*group_name == NULL)
  2713                     status = PEP_OUT_OF_MEMORY;
  2714         }
  2715         break;
  2716     }
  2717  
  2718     default:
  2719         status = PEP_RECORD_NOT_FOUND;
  2720     }
  2721 
  2722     free(user_id);
  2723     sqlite3_reset(session->get_device_group);
  2724     return status;
  2725 }
  2726 
  2727 DYNAMIC_API PEP_STATUS set_identity_flags(
  2728         PEP_SESSION session,
  2729         pEp_identity *identity,
  2730         unsigned int flags
  2731     )
  2732 {
  2733     int result;
  2734 
  2735     assert(session);
  2736     assert(identity);
  2737     assert(identity->address);
  2738     assert(identity->user_id);
  2739 
  2740     if (!(session && identity && identity->address && identity->user_id))
  2741         return PEP_ILLEGAL_VALUE;
  2742 
  2743     sqlite3_reset(session->set_identity_flags);
  2744     sqlite3_bind_int(session->set_identity_flags, 1, flags);
  2745     sqlite3_bind_text(session->set_identity_flags, 2, identity->address, -1,
  2746             SQLITE_STATIC);
  2747     sqlite3_bind_text(session->set_identity_flags, 3, identity->user_id, -1,
  2748         SQLITE_STATIC);
  2749         
  2750     result = sqlite3_step(session->set_identity_flags);
  2751 
  2752     sqlite3_reset(session->set_identity_flags);
  2753     if (result != SQLITE_DONE)
  2754         return PEP_CANNOT_SET_IDENTITY;
  2755 
  2756     identity->flags |= flags;
  2757     return PEP_STATUS_OK;
  2758 }
  2759 
  2760 DYNAMIC_API PEP_STATUS unset_identity_flags(
  2761         PEP_SESSION session,
  2762         pEp_identity *identity,
  2763         unsigned int flags
  2764     )
  2765 {
  2766     int result;
  2767 
  2768     assert(session);
  2769     assert(identity);
  2770     assert(identity->address);
  2771     assert(identity->user_id);
  2772 
  2773     if (!(session && identity && identity->address && identity->user_id))
  2774         return PEP_ILLEGAL_VALUE;
  2775 
  2776     sqlite3_reset(session->unset_identity_flags);
  2777     sqlite3_bind_int(session->unset_identity_flags, 1, flags);
  2778     sqlite3_bind_text(session->unset_identity_flags, 2, identity->address, -1,
  2779             SQLITE_STATIC);
  2780     sqlite3_bind_text(session->unset_identity_flags, 3, identity->user_id, -1,
  2781             SQLITE_STATIC);
  2782     result = sqlite3_step(session->unset_identity_flags);
  2783     sqlite3_reset(session->unset_identity_flags);
  2784     if (result != SQLITE_DONE)
  2785         return PEP_CANNOT_SET_IDENTITY;
  2786         identity->flags &= ~flags;
  2787 
  2788     return PEP_STATUS_OK;
  2789 }
  2790 
  2791 
  2792 PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
  2793                               const char* new_uid) {
  2794     assert(session);
  2795     assert(old_uid);
  2796     assert(new_uid);
  2797     
  2798     if (!session || !old_uid || !new_uid)
  2799         return PEP_ILLEGAL_VALUE;
  2800 
  2801 
  2802     int result;
  2803 
  2804     sqlite3_reset(session->replace_userid);
  2805     sqlite3_bind_text(session->replace_userid, 1, new_uid, -1,
  2806             SQLITE_STATIC);
  2807     sqlite3_bind_text(session->replace_userid, 2, old_uid, -1,
  2808             SQLITE_STATIC);
  2809     result = sqlite3_step(session->replace_userid);
  2810     sqlite3_reset(session->replace_userid);
  2811     if (result != SQLITE_DONE)
  2812         return PEP_CANNOT_SET_PERSON; // May need clearer retval
  2813 
  2814     return PEP_STATUS_OK;
  2815 }
  2816 
  2817 PEP_STATUS refresh_userid_default_key(PEP_SESSION session, const char* user_id) {
  2818     assert(session);
  2819     assert(user_id);
  2820     
  2821     if (!session || !user_id)
  2822         return PEP_ILLEGAL_VALUE;
  2823 
  2824     int result;
  2825 
  2826     sqlite3_reset(session->refresh_userid_default_key);
  2827     sqlite3_bind_text(session->refresh_userid_default_key, 1, user_id, -1,
  2828             SQLITE_STATIC);
  2829     result = sqlite3_step(session->refresh_userid_default_key);
  2830     sqlite3_reset(session->refresh_userid_default_key);
  2831     if (result != SQLITE_DONE)
  2832         return PEP_CANNOT_SET_PERSON;
  2833 
  2834     return PEP_STATUS_OK;    
  2835 }
  2836 
  2837 PEP_STATUS replace_main_user_fpr(PEP_SESSION session, const char* user_id,
  2838                                  const char* new_fpr) {
  2839     assert(session);
  2840     assert(user_id);
  2841     assert(new_fpr);
  2842     
  2843     if (!session || !user_id || !new_fpr)
  2844         return PEP_ILLEGAL_VALUE;
  2845 
  2846     int result;
  2847 
  2848     sqlite3_reset(session->replace_main_user_fpr);
  2849     sqlite3_bind_text(session->replace_main_user_fpr, 1, new_fpr, -1,
  2850             SQLITE_STATIC);
  2851     sqlite3_bind_text(session->replace_main_user_fpr, 2, user_id, -1,
  2852             SQLITE_STATIC);
  2853     result = sqlite3_step(session->replace_main_user_fpr);
  2854     sqlite3_reset(session->replace_main_user_fpr);
  2855     if (result != SQLITE_DONE)
  2856         return PEP_CANNOT_SET_PERSON;
  2857 
  2858     return PEP_STATUS_OK;
  2859 }
  2860 
  2861 PEP_STATUS get_main_user_fpr(PEP_SESSION session, 
  2862                              const char* user_id,
  2863                              char** main_fpr)
  2864 {
  2865     PEP_STATUS status = PEP_STATUS_OK;
  2866     int result;
  2867     
  2868     assert(session);
  2869     assert(user_id);
  2870     assert(main_fpr);
  2871     
  2872     if (!(session && user_id && user_id[0] && main_fpr))
  2873         return PEP_ILLEGAL_VALUE;
  2874         
  2875     *main_fpr = NULL;
  2876     
  2877     sqlite3_reset(session->get_main_user_fpr);
  2878     sqlite3_bind_text(session->get_main_user_fpr, 1, user_id, -1,
  2879                       SQLITE_STATIC);
  2880     result = sqlite3_step(session->get_main_user_fpr);
  2881     switch (result) {
  2882     case SQLITE_ROW: {
  2883         const char* _fpr = 
  2884             (const char *) sqlite3_column_text(session->get_main_user_fpr, 0);
  2885         if (_fpr)
  2886             *main_fpr = strdup(_fpr);
  2887         if (!(*main_fpr))
  2888             status = PEP_OUT_OF_MEMORY;
  2889         break;
  2890     }
  2891     default:
  2892         status = PEP_CANNOT_FIND_PERSON;
  2893     }
  2894 
  2895     sqlite3_reset(session->get_main_user_fpr);
  2896     return status;
  2897 }
  2898 
  2899 
  2900 DYNAMIC_API PEP_STATUS mark_as_compromized(
  2901         PEP_SESSION session,
  2902         const char *fpr
  2903     )
  2904 {
  2905     int result;
  2906 
  2907     assert(session);
  2908     assert(fpr && fpr[0]);
  2909 
  2910     if (!(session && fpr && fpr[0]))
  2911         return PEP_ILLEGAL_VALUE;
  2912 
  2913     sqlite3_reset(session->mark_compromized);
  2914     sqlite3_bind_text(session->mark_compromized, 1, fpr, -1,
  2915             SQLITE_STATIC);
  2916     result = sqlite3_step(session->mark_compromized);
  2917     sqlite3_reset(session->mark_compromized);
  2918 
  2919     if (result != SQLITE_DONE)
  2920         return PEP_CANNOT_SET_TRUST;
  2921 
  2922     return PEP_STATUS_OK;
  2923 }
  2924 
  2925 void pEp_free(void *p)
  2926 {
  2927     free(p);
  2928 }
  2929 
  2930 
  2931 DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
  2932 {
  2933     PEP_STATUS status = PEP_STATUS_OK;
  2934     int result;
  2935 
  2936     // We need to be able to test that we break correctly without shutting
  2937     // asserts off everywhere.
  2938     // assert(session);
  2939     // assert(identity);
  2940     // assert(identity->user_id);
  2941     // assert(identity->user_id[0]);
  2942     // assert(identity->fpr);
  2943     // assert(identity->fpr[0]);
  2944 
  2945     if (!(session && identity && identity->user_id && identity->user_id[0] &&
  2946                 identity->fpr && identity->fpr[0]))
  2947         return PEP_ILLEGAL_VALUE;
  2948 
  2949     identity->comm_type = PEP_ct_unknown;
  2950 
  2951     sqlite3_reset(session->get_trust);
  2952     sqlite3_bind_text(session->get_trust, 1, identity->user_id, -1,
  2953             SQLITE_STATIC);
  2954     sqlite3_bind_text(session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
  2955 
  2956     result = sqlite3_step(session->get_trust);
  2957     switch (result) {
  2958     case SQLITE_ROW: {
  2959         int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust,
  2960                 0);
  2961         identity->comm_type = comm_type;
  2962         break;
  2963     }
  2964  
  2965     default:
  2966         status = PEP_CANNOT_FIND_IDENTITY;
  2967     }
  2968 
  2969     sqlite3_reset(session->get_trust);
  2970     return status;
  2971 }
  2972 
  2973 DYNAMIC_API PEP_STATUS least_trust(
  2974         PEP_SESSION session,
  2975         const char *fpr,
  2976         PEP_comm_type *comm_type
  2977     )
  2978 {
  2979     PEP_STATUS status = PEP_STATUS_OK;
  2980     int result;
  2981 
  2982     assert(session);
  2983     assert(fpr);
  2984     assert(comm_type);
  2985 
  2986     if (!(session && fpr && comm_type))
  2987         return PEP_ILLEGAL_VALUE;
  2988 
  2989     *comm_type = PEP_ct_unknown;
  2990 
  2991     sqlite3_reset(session->least_trust);
  2992     sqlite3_bind_text(session->least_trust, 1, fpr, -1, SQLITE_STATIC);
  2993 
  2994     result = sqlite3_step(session->least_trust);
  2995     switch (result) {
  2996         case SQLITE_ROW: {
  2997             int _comm_type = sqlite3_column_int(session->least_trust, 0);
  2998             *comm_type = (PEP_comm_type) _comm_type;
  2999             break;
  3000         }
  3001         default:
  3002             // never reached because of sql min()
  3003             status = PEP_CANNOT_FIND_IDENTITY;
  3004     }
  3005 
  3006     sqlite3_reset(session->least_trust);
  3007     return status;
  3008 }
  3009 
  3010 DYNAMIC_API PEP_STATUS decrypt_and_verify(
  3011     PEP_SESSION session, const char *ctext, size_t csize,
  3012     const char *dsigtext, size_t dsigsize,
  3013     char **ptext, size_t *psize, stringlist_t **keylist
  3014     )
  3015 {
  3016     assert(session);
  3017     assert(ctext);
  3018     assert(csize);
  3019     assert(ptext);
  3020     assert(psize);
  3021     assert(keylist);
  3022 
  3023     if (!(session && ctext && csize && ptext && psize && keylist))
  3024         return PEP_ILLEGAL_VALUE;
  3025 
  3026     return session->cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify(
  3027             session, ctext, csize, dsigtext, dsigsize, ptext, psize, keylist);
  3028 }
  3029 
  3030 DYNAMIC_API PEP_STATUS encrypt_and_sign(
  3031     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  3032     size_t psize, char **ctext, size_t *csize
  3033     )
  3034 {
  3035     assert(session);
  3036     assert(keylist);
  3037     assert(ptext);
  3038     assert(psize);
  3039     assert(ctext);
  3040     assert(csize);
  3041 
  3042     if (!(session && keylist && ptext && psize && ctext && csize))
  3043         return PEP_ILLEGAL_VALUE;
  3044 
  3045     return session->cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign(session,
  3046             keylist, ptext, psize, ctext, csize);
  3047 }
  3048 
  3049 PEP_STATUS encrypt_only(
  3050     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  3051     size_t psize, char **ctext, size_t *csize
  3052     )
  3053 {
  3054     assert(session);
  3055     assert(keylist);
  3056     assert(ptext);
  3057     assert(psize);
  3058     assert(ctext);
  3059     assert(csize);
  3060 
  3061     if (!(session && keylist && ptext && psize && ctext && csize))
  3062         return PEP_ILLEGAL_VALUE;
  3063 
  3064     return session->cryptotech[PEP_crypt_OpenPGP].encrypt_only(session,
  3065             keylist, ptext, psize, ctext, csize);
  3066 }
  3067 
  3068 
  3069 DYNAMIC_API PEP_STATUS verify_text(
  3070     PEP_SESSION session, const char *text, size_t size,
  3071     const char *signature, size_t sig_size, stringlist_t **keylist
  3072     )
  3073 {
  3074     assert(session);
  3075     assert(text);
  3076     assert(size);
  3077     assert(signature);
  3078     assert(sig_size);
  3079     assert(keylist);
  3080 
  3081     if (!(session && text && size && signature && sig_size && keylist))
  3082         return PEP_ILLEGAL_VALUE;
  3083 
  3084     return session->cryptotech[PEP_crypt_OpenPGP].verify_text(session, text,
  3085             size, signature, sig_size, keylist);
  3086 }
  3087 
  3088 DYNAMIC_API PEP_STATUS delete_keypair(PEP_SESSION session, const char *fpr)
  3089 {
  3090     assert(session);
  3091     assert(fpr);
  3092 
  3093     if (!(session && fpr))
  3094         return PEP_ILLEGAL_VALUE;
  3095 
  3096     return session->cryptotech[PEP_crypt_OpenPGP].delete_keypair(session, fpr);
  3097 }
  3098 
  3099 DYNAMIC_API PEP_STATUS export_key(
  3100         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  3101     )
  3102 {
  3103     assert(session);
  3104     assert(fpr);
  3105     assert(key_data);
  3106     assert(size);
  3107 
  3108     if (!(session && fpr && key_data && size))
  3109         return PEP_ILLEGAL_VALUE;
  3110 
  3111     return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  3112             key_data, size, false);
  3113 }
  3114 
  3115 DYNAMIC_API PEP_STATUS export_secrect_key(
  3116         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  3117     )
  3118 {
  3119     assert(session);
  3120     assert(fpr);
  3121     assert(key_data);
  3122     assert(size);
  3123 
  3124     if (!(session && fpr && key_data && size))
  3125         return PEP_ILLEGAL_VALUE;
  3126 
  3127     // don't accept key IDs but full fingerprints only
  3128     if (strlen(fpr) < 16)
  3129         return PEP_ILLEGAL_VALUE;
  3130 
  3131     return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  3132             key_data, size, true);
  3133 }
  3134 
  3135 DYNAMIC_API PEP_STATUS find_keys(
  3136         PEP_SESSION session, const char *pattern, stringlist_t **keylist
  3137     )
  3138 {
  3139     assert(session);
  3140     assert(pattern);
  3141     assert(keylist);
  3142 
  3143     if (!(session && pattern && keylist))
  3144         return PEP_ILLEGAL_VALUE;
  3145 
  3146     return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern,
  3147             keylist);
  3148 }
  3149 
  3150 
  3151 DYNAMIC_API PEP_STATUS generate_keypair(
  3152         PEP_SESSION session, pEp_identity *identity
  3153     )
  3154 {
  3155     assert(session);
  3156     assert(identity);
  3157     assert(identity->address);
  3158     assert(identity->fpr == NULL || identity->fpr[0] == 0);
  3159     assert(identity->username);
  3160 
  3161     if (!(session && identity && identity->address &&
  3162             (identity->fpr == NULL || identity->fpr[0] == 0) &&
  3163             identity->username))
  3164         return PEP_ILLEGAL_VALUE;
  3165 
  3166     PEP_STATUS status =
  3167         session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session,
  3168                 identity);
  3169     if (status != PEP_STATUS_OK)
  3170         return status;
  3171 
  3172     if (identity->fpr)
  3173         status = set_pgp_keypair(session, identity->fpr);
  3174 
  3175     // add to known keypair DB, as this might not end up being a default
  3176     return status;
  3177 }
  3178 
  3179 DYNAMIC_API PEP_STATUS get_key_rating(
  3180         PEP_SESSION session,
  3181         const char *fpr,
  3182         PEP_comm_type *comm_type
  3183     )
  3184 {
  3185     assert(session);
  3186     assert(fpr);
  3187     assert(comm_type);
  3188 
  3189     if (!(session && fpr && comm_type))
  3190         return PEP_ILLEGAL_VALUE;
  3191 
  3192     return session->cryptotech[PEP_crypt_OpenPGP].get_key_rating(session, fpr,
  3193             comm_type);
  3194 }
  3195 
  3196 DYNAMIC_API PEP_STATUS import_key(
  3197         PEP_SESSION session,
  3198         const char *key_data,
  3199         size_t size,
  3200         identity_list **private_keys
  3201     )
  3202 {
  3203     assert(session);
  3204     assert(key_data);
  3205 
  3206     if (!(session && key_data))
  3207         return PEP_ILLEGAL_VALUE;
  3208 
  3209     return session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data,
  3210             size, private_keys);
  3211 }
  3212 
  3213 DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
  3214 {
  3215     assert(session);
  3216     assert(pattern);
  3217 
  3218     if (!(session && pattern))
  3219         return PEP_ILLEGAL_VALUE;
  3220 
  3221     return session->cryptotech[PEP_crypt_OpenPGP].recv_key(session, pattern);
  3222 }
  3223 
  3224 DYNAMIC_API PEP_STATUS send_key(PEP_SESSION session, const char *pattern)
  3225 {
  3226     assert(session);
  3227     assert(pattern);
  3228 
  3229     if (!(session && pattern))
  3230         return PEP_ILLEGAL_VALUE;
  3231 
  3232     return session->cryptotech[PEP_crypt_OpenPGP].send_key(session, pattern);
  3233 }
  3234 
  3235 DYNAMIC_API PEP_STATUS renew_key(
  3236         PEP_SESSION session,
  3237         const char *fpr,
  3238         const timestamp *ts
  3239     )
  3240 {
  3241     assert(session);
  3242     assert(fpr);
  3243 
  3244     if (!(session && fpr))
  3245         return PEP_ILLEGAL_VALUE;
  3246 
  3247     return session->cryptotech[PEP_crypt_OpenPGP].renew_key(session, fpr, ts);
  3248 }
  3249 
  3250 DYNAMIC_API PEP_STATUS revoke_key(
  3251         PEP_SESSION session,
  3252         const char *fpr,
  3253         const char *reason
  3254     )
  3255 {
  3256     assert(session);
  3257     assert(fpr);
  3258 
  3259     if (!(session && fpr))
  3260         return PEP_ILLEGAL_VALUE;
  3261 
  3262     return session->cryptotech[PEP_crypt_OpenPGP].revoke_key(session, fpr,
  3263             reason);
  3264 }
  3265 
  3266 DYNAMIC_API PEP_STATUS key_expired(
  3267         PEP_SESSION session,
  3268         const char *fpr,
  3269         const time_t when,
  3270         bool *expired
  3271     )
  3272 {
  3273     assert(session);
  3274     assert(fpr);
  3275     assert(expired);
  3276 
  3277     if (!(session && fpr && expired))
  3278         return PEP_ILLEGAL_VALUE;
  3279 
  3280     return session->cryptotech[PEP_crypt_OpenPGP].key_expired(session, fpr,
  3281             when, expired);
  3282 }
  3283 
  3284 DYNAMIC_API PEP_STATUS key_revoked(
  3285        PEP_SESSION session,
  3286        const char *fpr,
  3287        bool *revoked
  3288    )
  3289 {
  3290     assert(session);
  3291     assert(fpr);
  3292     assert(revoked);
  3293     
  3294     if (!(session && fpr && revoked))
  3295         return PEP_ILLEGAL_VALUE;
  3296     
  3297     return session->cryptotech[PEP_crypt_OpenPGP].key_revoked(session, fpr,
  3298             revoked);
  3299 }
  3300 
  3301 static void _clean_log_value(char *text)
  3302 {
  3303     if (text) {
  3304         for (char *c = text; *c; c++) {
  3305             if (*c < 32 && *c != '\n')
  3306                 *c = 32;
  3307             else if (*c == '"')
  3308                 *c = '\'';
  3309         }
  3310     }
  3311 }
  3312 
  3313 static char *_concat_string(char *str1, const char *str2, char delim)
  3314 {
  3315     str2 = str2 ? str2 : "";
  3316     size_t len1 = str1 ? strlen(str1) : 0;
  3317     size_t len2 = strlen(str2);
  3318     size_t len = len1 + len2 + 3;
  3319     char * result = realloc(str1, len + 1);
  3320 
  3321     if (result) {
  3322         result[len1] = '"';
  3323         strcpy(result + len1 + 1, str2);
  3324         result[len - 2] = '"';
  3325         result[len - 1] = delim;
  3326         result[len] = 0;
  3327     }
  3328     else {
  3329         free(str1);
  3330     }
  3331 
  3332     return result;
  3333 }
  3334 
  3335 DYNAMIC_API PEP_STATUS get_crashdump_log(
  3336         PEP_SESSION session,
  3337         int maxlines,
  3338         char **logdata
  3339     )
  3340 {
  3341     PEP_STATUS status = PEP_STATUS_OK;
  3342     char *_logdata= NULL;
  3343 
  3344     assert(session);
  3345     assert(maxlines >= 0 && maxlines <= CRASHDUMP_MAX_LINES);
  3346     assert(logdata);
  3347 
  3348     if (!(session && logdata && maxlines >= 0 && maxlines <=
  3349             CRASHDUMP_MAX_LINES))
  3350         return PEP_ILLEGAL_VALUE;
  3351 
  3352     *logdata = NULL;
  3353 
  3354     int limit = maxlines ? maxlines : CRASHDUMP_DEFAULT_LINES;
  3355     const char *timestamp = NULL;
  3356     const char *title = NULL;
  3357     const char *entity = NULL;
  3358     const char *desc = NULL;
  3359     const char *comment = NULL;
  3360 
  3361     sqlite3_reset(session->crashdump);
  3362     sqlite3_bind_int(session->crashdump, 1, limit);
  3363 
  3364     int result;
  3365 
  3366     do {
  3367         result = sqlite3_step(session->crashdump);
  3368         switch (result) {
  3369         case SQLITE_ROW:
  3370             timestamp = (const char *) sqlite3_column_text(session->crashdump,
  3371                     0);
  3372             title   = (const char *) sqlite3_column_text(session->crashdump,
  3373                     1);
  3374             entity  = (const char *) sqlite3_column_text(session->crashdump,
  3375                     2);
  3376             desc    = (const char *) sqlite3_column_text(session->crashdump,
  3377                     3);
  3378             comment = (const char *) sqlite3_column_text(session->crashdump,
  3379                     4);
  3380 
  3381             _logdata = _concat_string(_logdata, timestamp, ',');
  3382             if (_logdata == NULL)
  3383                 goto enomem;
  3384 
  3385             _logdata = _concat_string(_logdata, title, ',');
  3386             if (_logdata == NULL)
  3387                 goto enomem;
  3388 
  3389             _logdata = _concat_string(_logdata, entity, ',');
  3390             if (_logdata == NULL)
  3391                 goto enomem;
  3392 
  3393             _logdata = _concat_string(_logdata, desc, ',');
  3394             if (_logdata == NULL)
  3395                 goto enomem;
  3396 
  3397             _logdata = _concat_string(_logdata, comment, '\n');
  3398             if (_logdata == NULL)
  3399                 goto enomem;
  3400 
  3401             _clean_log_value(_logdata);
  3402             break;
  3403 
  3404         case SQLITE_DONE:
  3405             break;
  3406 
  3407         default:
  3408             status = PEP_UNKNOWN_ERROR;
  3409             result = SQLITE_DONE;
  3410         }
  3411     } while (result != SQLITE_DONE);
  3412 
  3413     sqlite3_reset(session->crashdump);
  3414     if (status == PEP_STATUS_OK) {
  3415         if (_logdata) {
  3416             *logdata = _logdata;
  3417         }
  3418         else {
  3419             *logdata = strdup("");
  3420             if (!*logdata)
  3421                 goto enomem;
  3422         }
  3423     }
  3424 
  3425     goto the_end;
  3426 
  3427 enomem:
  3428     status = PEP_OUT_OF_MEMORY;
  3429 
  3430 the_end:
  3431     return status;
  3432 }
  3433 
  3434 DYNAMIC_API PEP_STATUS get_languagelist(
  3435         PEP_SESSION session,
  3436         char **languages
  3437     )
  3438 {
  3439     PEP_STATUS status = PEP_STATUS_OK;
  3440     char *_languages= NULL;
  3441 
  3442     assert(session);
  3443     assert(languages);
  3444 
  3445     if (!(session && languages))
  3446         return PEP_ILLEGAL_VALUE;
  3447 
  3448     *languages = NULL;
  3449 
  3450     const char *lang = NULL;
  3451     const char *name = NULL;
  3452     const char *phrase = NULL;
  3453 
  3454     sqlite3_reset(session->languagelist);
  3455 
  3456     int result;
  3457 
  3458     do {
  3459         result = sqlite3_step(session->languagelist);
  3460         switch (result) {
  3461         case SQLITE_ROW:
  3462             lang = (const char *) sqlite3_column_text(session->languagelist,
  3463                     0);
  3464             name = (const char *) sqlite3_column_text(session->languagelist,
  3465                     1);
  3466             phrase = (const char *) sqlite3_column_text(session->languagelist,
  3467                     2);
  3468 
  3469             _languages = _concat_string(_languages, lang, ',');
  3470             if (_languages == NULL)
  3471                 goto enomem;
  3472 
  3473             _languages = _concat_string(_languages, name, ',');
  3474             if (_languages == NULL)
  3475                 goto enomem;
  3476 
  3477             _languages = _concat_string(_languages, phrase, '\n');
  3478             if (_languages == NULL)
  3479                 goto enomem;
  3480 
  3481             break;
  3482 
  3483         case SQLITE_DONE:
  3484             break;
  3485 
  3486         default:
  3487             status = PEP_UNKNOWN_ERROR;
  3488             result = SQLITE_DONE;
  3489         }
  3490     } while (result != SQLITE_DONE);
  3491 
  3492     sqlite3_reset(session->languagelist);
  3493     if (status == PEP_STATUS_OK)
  3494         *languages = _languages;
  3495 
  3496     goto the_end;
  3497 
  3498 enomem:
  3499     status = PEP_OUT_OF_MEMORY;
  3500 
  3501 the_end:
  3502     return status;
  3503 }
  3504 
  3505 DYNAMIC_API PEP_STATUS get_phrase(
  3506         PEP_SESSION session,
  3507         const char *lang,
  3508         int phrase_id,
  3509         char **phrase
  3510     )
  3511 {
  3512     PEP_STATUS status = PEP_STATUS_OK;
  3513 
  3514     assert(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase);
  3515     if (!(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase))
  3516         return PEP_ILLEGAL_VALUE;
  3517 
  3518     *phrase = NULL;
  3519 
  3520     sqlite3_reset(session->i18n_token);
  3521     sqlite3_bind_text(session->i18n_token, 1, lang, -1, SQLITE_STATIC);
  3522     sqlite3_bind_int(session->i18n_token, 2, phrase_id);
  3523 
  3524     const char *_phrase = NULL;
  3525     int result;
  3526 
  3527     result = sqlite3_step(session->i18n_token);
  3528     switch (result) {
  3529     case SQLITE_ROW:
  3530         _phrase = (const char *) sqlite3_column_text(session->i18n_token, 0);
  3531         break;
  3532 
  3533     case SQLITE_DONE:
  3534         status = PEP_PHRASE_NOT_FOUND;
  3535         break;
  3536 
  3537     default:
  3538         status = PEP_UNKNOWN_ERROR;
  3539     }
  3540 
  3541     if (status == PEP_STATUS_OK) {
  3542         *phrase = strdup(_phrase);
  3543         if (*phrase == NULL)
  3544             goto enomem;
  3545     }
  3546 
  3547     sqlite3_reset(session->i18n_token);
  3548     goto the_end;
  3549 
  3550 enomem:
  3551     status = PEP_OUT_OF_MEMORY;
  3552 
  3553 the_end:
  3554     return status;
  3555 }
  3556 
  3557 static PEP_STATUS _get_sequence_value(PEP_SESSION session, const char *name,
  3558         int32_t *value)
  3559 {
  3560     assert(session && name && value);
  3561     if (!(session && name && value))
  3562         return PEP_ILLEGAL_VALUE;
  3563 
  3564     PEP_STATUS status = PEP_STATUS_OK;
  3565 
  3566     sqlite3_reset(session->sequence_value2);
  3567     sqlite3_bind_text(session->sequence_value2, 1, name, -1,
  3568             SQLITE_STATIC);
  3569     int result = sqlite3_step(session->sequence_value2);
  3570     switch (result) {
  3571         case SQLITE_ROW: {
  3572             int32_t _value = (int32_t)
  3573                     sqlite3_column_int(session->sequence_value2, 0);
  3574             int _own = (int)
  3575                     sqlite3_column_int(session->sequence_value2, 1);
  3576             *value = _value;
  3577             if (_own)
  3578                 status = PEP_OWN_SEQUENCE;
  3579             break;
  3580         }
  3581         case SQLITE_DONE:
  3582             status = PEP_RECORD_NOT_FOUND;
  3583             break;
  3584         default:
  3585             status = PEP_UNKNOWN_ERROR;
  3586     }
  3587     sqlite3_reset(session->sequence_value2);
  3588 
  3589     return status;
  3590 }
  3591 
  3592 static PEP_STATUS _increment_sequence_value(PEP_SESSION session,
  3593         const char *name, int own)
  3594 {
  3595     assert(session && name);
  3596     if (!(session && name))
  3597         return PEP_ILLEGAL_VALUE;
  3598 
  3599     sqlite3_reset(session->sequence_value1);
  3600     sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
  3601     sqlite3_bind_int(session->sequence_value1, 2, own);
  3602     int result = sqlite3_step(session->sequence_value1);
  3603     assert(result == SQLITE_DONE);
  3604     sqlite3_reset(session->sequence_value1);
  3605     if (result == SQLITE_DONE)
  3606         return PEP_STATUS_OK;
  3607     else
  3608         return PEP_CANNOT_INCREASE_SEQUENCE;
  3609 }
  3610 
  3611 static PEP_STATUS _set_sequence_value(PEP_SESSION session,
  3612         const char *name, int32_t value, int own)
  3613 {
  3614     assert(session && name && value > 0);
  3615     if (!(session && name && value > 0))
  3616         return PEP_ILLEGAL_VALUE;
  3617 
  3618     sqlite3_reset(session->sequence_value3);
  3619     sqlite3_bind_text(session->sequence_value3, 1, name, -1, SQLITE_STATIC);
  3620     sqlite3_bind_int(session->sequence_value3, 2, value);
  3621     sqlite3_bind_int(session->sequence_value3, 3, own);
  3622     int result = sqlite3_step(session->sequence_value3);
  3623     assert(result == SQLITE_DONE);
  3624     sqlite3_reset(session->sequence_value3);
  3625     if (result == SQLITE_DONE)
  3626         return PEP_STATUS_OK;
  3627     else
  3628         return PEP_CANNOT_SET_SEQUENCE_VALUE;
  3629 }
  3630 
  3631 DYNAMIC_API PEP_STATUS sequence_value(
  3632         PEP_SESSION session,
  3633         char *name,
  3634         int32_t *value
  3635     )
  3636 {
  3637     PEP_STATUS status = PEP_STATUS_OK;
  3638     int result;
  3639 
  3640     assert(session);
  3641     assert(name && value && *value >= 0);
  3642 
  3643     if (!(session && name && value && *value >= 0))
  3644         return PEP_ILLEGAL_VALUE;
  3645 
  3646     int own = 0;
  3647     if (!name[0]) {
  3648         pEpUUID uuid;
  3649         uuid_generate_random(uuid);
  3650         uuid_unparse_upper(uuid, name);
  3651         own = 1;
  3652     }
  3653     else {
  3654         if (name == session->sync_session->sync_uuid || 
  3655             strcmp(name, session->sync_session->sync_uuid) == 0)
  3656             own = 1;
  3657     }
  3658 
  3659     if (*value) {
  3660         sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  3661         int32_t old_value = 0;
  3662         status = _get_sequence_value(session, name, &old_value);
  3663         if (status != PEP_STATUS_OK && status != PEP_RECORD_NOT_FOUND)
  3664         {
  3665             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3666             return status;
  3667         }
  3668 
  3669         if (old_value >= *value) {
  3670             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3671             return PEP_SEQUENCE_VIOLATED;
  3672         }
  3673         else {
  3674             status = _set_sequence_value(session, name, *value, own);
  3675             if (status == PEP_STATUS_OK) {
  3676                 result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  3677                 if (result == SQLITE_OK)
  3678                     return PEP_STATUS_OK;
  3679                 else
  3680                     return PEP_COMMIT_FAILED;
  3681             } else {
  3682                 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3683                 return status;
  3684             }
  3685         }
  3686     }
  3687 
  3688     assert(*value == 0);
  3689     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  3690     status = _increment_sequence_value(session, name, own);
  3691     if (status == PEP_STATUS_OK) {
  3692         status = _get_sequence_value(session, name, value);
  3693     }
  3694     if (status == PEP_STATUS_OK || status == PEP_OWN_SEQUENCE) {
  3695         result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  3696         if (result == SQLITE_OK){
  3697             assert(*value < INT32_MAX);
  3698             if (*value == INT32_MAX){
  3699                 return PEP_CANNOT_INCREASE_SEQUENCE;
  3700             }
  3701             return status;
  3702         } else {
  3703             return PEP_COMMIT_FAILED;
  3704         }
  3705     } else {
  3706         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3707         return status;
  3708     }
  3709     return status;
  3710 }
  3711 
  3712 DYNAMIC_API PEP_STATUS set_revoked(
  3713        PEP_SESSION session,
  3714        const char *revoked_fpr,
  3715        const char *replacement_fpr,
  3716        const uint64_t revocation_date
  3717     )
  3718 {
  3719     PEP_STATUS status = PEP_STATUS_OK;
  3720     
  3721     assert(session &&
  3722            revoked_fpr && revoked_fpr[0] &&
  3723            replacement_fpr && replacement_fpr[0]
  3724           );
  3725     
  3726     if (!(session &&
  3727           revoked_fpr && revoked_fpr[0] &&
  3728           replacement_fpr && replacement_fpr[0]
  3729          ))
  3730         return PEP_ILLEGAL_VALUE;
  3731     
  3732     sqlite3_reset(session->set_revoked);
  3733     sqlite3_bind_text(session->set_revoked, 1, revoked_fpr, -1, SQLITE_STATIC);
  3734     sqlite3_bind_text(session->set_revoked, 2, replacement_fpr, -1,
  3735             SQLITE_STATIC);
  3736     sqlite3_bind_int64(session->set_revoked, 3, revocation_date);
  3737 
  3738     int result;
  3739     
  3740     result = sqlite3_step(session->set_revoked);
  3741     switch (result) {
  3742         case SQLITE_DONE:
  3743             status = PEP_STATUS_OK;
  3744             break;
  3745             
  3746         default:
  3747             status = PEP_UNKNOWN_ERROR;
  3748     }
  3749     
  3750     sqlite3_reset(session->set_revoked);
  3751     return status;
  3752 }
  3753 
  3754 DYNAMIC_API PEP_STATUS get_revoked(
  3755         PEP_SESSION session,
  3756         const char *fpr,
  3757         char **revoked_fpr,
  3758         uint64_t *revocation_date
  3759     )
  3760 {
  3761     PEP_STATUS status = PEP_STATUS_OK;
  3762 
  3763     assert(session &&
  3764            revoked_fpr &&
  3765            fpr && fpr[0]
  3766           );
  3767     
  3768     if (!(session &&
  3769            revoked_fpr &&
  3770            fpr && fpr[0]
  3771           ))
  3772         return PEP_ILLEGAL_VALUE;
  3773 
  3774     *revoked_fpr = NULL;
  3775     *revocation_date = 0;
  3776 
  3777     sqlite3_reset(session->get_revoked);
  3778     sqlite3_bind_text(session->get_revoked, 1, fpr, -1, SQLITE_STATIC);
  3779 
  3780     int result;
  3781     
  3782     result = sqlite3_step(session->get_revoked);
  3783     switch (result) {
  3784         case SQLITE_ROW: {
  3785             *revoked_fpr = strdup((const char *)
  3786                     sqlite3_column_text(session->get_revoked, 0));
  3787             if(*revoked_fpr)
  3788                 *revocation_date = sqlite3_column_int64(session->get_revoked,
  3789                         1);
  3790             else
  3791                 status = PEP_OUT_OF_MEMORY;
  3792 
  3793             break;
  3794         }
  3795         default:
  3796             status = PEP_CANNOT_FIND_IDENTITY;
  3797     }
  3798 
  3799     sqlite3_reset(session->get_revoked);
  3800 
  3801     return status;
  3802 }
  3803 
  3804 PEP_STATUS key_created(
  3805         PEP_SESSION session,
  3806         const char *fpr,
  3807         time_t *created
  3808     )
  3809 {
  3810     assert(session && fpr && created);
  3811     if (!(session && fpr && created))
  3812         return PEP_ILLEGAL_VALUE;
  3813 
  3814     return session->cryptotech[PEP_crypt_OpenPGP].key_created(session, fpr,
  3815             created);
  3816 }
  3817 
  3818 PEP_STATUS find_private_keys(PEP_SESSION session, const char* pattern,
  3819                              stringlist_t **keylist) {
  3820     assert(session && keylist);
  3821     if (!(session && keylist))
  3822         return PEP_ILLEGAL_VALUE;
  3823     
  3824     return session->cryptotech[PEP_crypt_OpenPGP].find_private_keys(session, pattern,
  3825                                                                     keylist);
  3826 }
  3827 
  3828 PEP_STATUS import_trusted_own_keys(PEP_SESSION session) {
  3829     assert(session);
  3830     if (!session)
  3831         return PEP_ILLEGAL_VALUE;
  3832         
  3833     return session->cryptotech[PEP_crypt_OpenPGP].import_trusted_own_keys(session); 
  3834 }
  3835 
  3836 DYNAMIC_API const char* get_engine_version() {
  3837     return PEP_ENGINE_VERSION;
  3838 }
  3839 
  3840 
  3841 DYNAMIC_API PEP_STATUS reset_peptest_hack(PEP_SESSION session)
  3842 {
  3843     assert(session);
  3844 
  3845     if (!session)
  3846         return PEP_ILLEGAL_VALUE;
  3847 
  3848     int int_result = sqlite3_exec(
  3849         session->db,
  3850         "delete from identity where address like '%@peptest.ch' ;",
  3851         NULL,
  3852         NULL,
  3853         NULL
  3854     );
  3855     assert(int_result == SQLITE_OK);
  3856 
  3857     if (int_result != SQLITE_OK)
  3858         return PEP_UNKNOWN_ERROR;
  3859 
  3860     return PEP_STATUS_OK;
  3861 }
  3862 
  3863 #ifdef DEBUG_ERRORSTACK
  3864 PEP_STATUS session_add_error(PEP_SESSION session, const char* file, unsigned line, PEP_STATUS status)
  3865 {
  3866     char logline[48];
  3867     if(status>0)
  3868     {
  3869         snprintf(logline,47, "%.24s:%u status=%u (0x%x)", file, line, status, status);
  3870     }else{
  3871         snprintf(logline,47, "%.24s:%u status=%i.", file, line, status);
  3872     }
  3873     stringlist_add(session->errorstack, logline); // logline is copied! :-)
  3874     return status;
  3875 }
  3876 
  3877 DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  3878 {
  3879     return session->errorstack;
  3880 }
  3881 
  3882 DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  3883 {
  3884     const int old_len = stringlist_length(session->errorstack);
  3885     char buf[48];
  3886     free_stringlist(session->errorstack);
  3887     snprintf(buf, 47, "(%i elements cleared)", old_len);
  3888     session->errorstack = new_stringlist(buf);
  3889 }
  3890 
  3891 #else
  3892 
  3893 static stringlist_t* dummy_errorstack = NULL;
  3894 
  3895 DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  3896 {
  3897     if(dummy_errorstack == NULL)
  3898     {
  3899         dummy_errorstack = new_stringlist("( Please recompile pEpEngine with -DDEBUG_ERRORSTACK )");
  3900     }
  3901 
  3902     return dummy_errorstack;
  3903 }
  3904 
  3905 DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  3906 {
  3907     // nothing to do here
  3908 }
  3909 
  3910 #endif