src/pEpEngine.c
author Krista Bennett <krista@pep-project.org>
Fri, 16 Feb 2018 08:35:04 +0100
changeset 2509 dde6a233c9dd
parent 2506 876532219d20
child 2514 0616c62d04a9
permissions -rw-r--r--
ENGINE-382: changed alter table with non-constant default for timestamp to copy-insert-drop for version 8
     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 SELECT * FROM _identity_old;\n"
   997                     "DROP TABLE _identity_old;\n"
   998                     "COMMIT;\n"
   999                     "\n"
  1000                     "PRAGMA foreign_keys=on;\n"
  1001                     ,
  1002                     NULL,
  1003                     NULL,
  1004                     NULL
  1005                 );
  1006                 assert(int_result == SQLITE_OK);    
  1007             }
  1008         }        
  1009         else { 
  1010             // Version from DB was 0, it means this is initial setup.
  1011             // DB has just been created, and all tables are empty.
  1012             very_first = true;
  1013         }
  1014 
  1015         if (version < atoi(_DDL_USER_VERSION)) {
  1016             int_result = sqlite3_exec(
  1017                 _session->db,
  1018                 "pragma user_version = "_DDL_USER_VERSION";\n"
  1019                 "insert or replace into version_info (id, version)"
  1020                     "values (1, '" PEP_ENGINE_VERSION "');",
  1021                 NULL,
  1022                 NULL,
  1023                 NULL
  1024             );
  1025             assert(int_result == SQLITE_OK);
  1026         }
  1027         
  1028         // We need to init a few globals for message id that we'd rather not
  1029         // calculate more than once.
  1030         _init_globals();
  1031     }
  1032 
  1033     int_result = sqlite3_prepare_v2(_session->db, sql_log,
  1034             (int)strlen(sql_log), &_session->log, NULL);
  1035     assert(int_result == SQLITE_OK);
  1036 
  1037     int_result = sqlite3_prepare_v2(_session->system_db, sql_trustword,
  1038             (int)strlen(sql_trustword), &_session->trustword, NULL);
  1039     assert(int_result == SQLITE_OK);
  1040 
  1041     int_result = sqlite3_prepare_v2(_session->db, sql_get_identity,
  1042             (int)strlen(sql_get_identity), &_session->get_identity, NULL);
  1043     assert(int_result == SQLITE_OK);
  1044 
  1045     int_result = sqlite3_prepare_v2(_session->db, sql_get_identity_without_trust_check,
  1046             (int)strlen(sql_get_identity_without_trust_check), 
  1047             &_session->get_identity_without_trust_check, NULL);
  1048     assert(int_result == SQLITE_OK);
  1049 
  1050     int_result = sqlite3_prepare_v2(_session->db, sql_get_identities_by_address,
  1051             (int)strlen(sql_get_identities_by_address), 
  1052             &_session->get_identities_by_address, NULL);
  1053     assert(int_result == SQLITE_OK);
  1054 
  1055     int_result = sqlite3_prepare_v2(_session->db, sql_get_user_default_key,
  1056             (int)strlen(sql_get_user_default_key), &_session->get_user_default_key, NULL);
  1057     assert(int_result == SQLITE_OK);
  1058 
  1059     int_result = sqlite3_prepare_v2(_session->db, sql_get_default_own_userid,
  1060             (int)strlen(sql_get_default_own_userid), &_session->get_default_own_userid, NULL);
  1061     assert(int_result == SQLITE_OK);
  1062     
  1063     int_result = sqlite3_prepare_v2(_session->db, sql_get_userid_alias_default,
  1064             (int)strlen(sql_get_userid_alias_default), &_session->get_userid_alias_default, NULL);
  1065     assert(int_result == SQLITE_OK);
  1066 
  1067     int_result = sqlite3_prepare_v2(_session->db, sql_add_userid_alias,
  1068             (int)strlen(sql_add_userid_alias), &_session->add_userid_alias, NULL);
  1069     assert(int_result == SQLITE_OK);
  1070 
  1071     int_result = sqlite3_prepare_v2(_session->db, sql_replace_userid,
  1072             (int)strlen(sql_replace_userid), &_session->replace_userid, NULL);
  1073     assert(int_result == SQLITE_OK);
  1074 
  1075     int_result = sqlite3_prepare_v2(_session->db, sql_replace_main_user_fpr,
  1076             (int)strlen(sql_replace_main_user_fpr), &_session->replace_main_user_fpr, NULL);
  1077     assert(int_result == SQLITE_OK);
  1078 
  1079     int_result = sqlite3_prepare_v2(_session->db, sql_get_main_user_fpr,
  1080             (int)strlen(sql_get_main_user_fpr), &_session->get_main_user_fpr, NULL);
  1081     assert(int_result == SQLITE_OK);
  1082 
  1083     int_result = sqlite3_prepare_v2(_session->db, sql_refresh_userid_default_key,
  1084             (int)strlen(sql_refresh_userid_default_key), &_session->refresh_userid_default_key, NULL);
  1085     assert(int_result == SQLITE_OK);
  1086 
  1087     int_result = sqlite3_prepare_v2(_session->db, sql_replace_identities_fpr,
  1088             (int)strlen(sql_replace_identities_fpr), 
  1089             &_session->replace_identities_fpr, NULL);
  1090     assert(int_result == SQLITE_OK);
  1091     
  1092     int_result = sqlite3_prepare_v2(_session->db, sql_remove_fpr_as_default,
  1093             (int)strlen(sql_remove_fpr_as_default), 
  1094             &_session->remove_fpr_as_default, NULL);
  1095     assert(int_result == SQLITE_OK);
  1096 
  1097     int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
  1098             (int)strlen(sql_set_person), &_session->set_person, NULL);
  1099     assert(int_result == SQLITE_OK);
  1100 
  1101     int_result = sqlite3_prepare_v2(_session->db, sql_update_person,
  1102             (int)strlen(sql_update_person), &_session->update_person, NULL);
  1103     assert(int_result == SQLITE_OK);
  1104 
  1105     int_result = sqlite3_prepare_v2(_session->db, sql_exists_person,
  1106             (int)strlen(sql_exists_person), &_session->exists_person, NULL);
  1107     assert(int_result == SQLITE_OK);
  1108 
  1109     int_result = sqlite3_prepare_v2(_session->db, sql_set_as_pep_user,
  1110             (int)strlen(sql_set_as_pep_user), &_session->set_as_pep_user, NULL);
  1111     assert(int_result == SQLITE_OK);
  1112     
  1113     int_result = sqlite3_prepare_v2(_session->db, sql_is_pep_user,
  1114             (int)strlen(sql_is_pep_user), &_session->is_pep_user, NULL);
  1115     assert(int_result == SQLITE_OK);
  1116 
  1117     int_result = sqlite3_prepare_v2(_session->db, sql_set_device_group,
  1118             (int)strlen(sql_set_device_group), &_session->set_device_group, NULL);
  1119     assert(int_result == SQLITE_OK);
  1120 
  1121     int_result = sqlite3_prepare_v2(_session->db, sql_get_device_group,
  1122             (int)strlen(sql_get_device_group), &_session->get_device_group, NULL);
  1123     assert(int_result == SQLITE_OK);
  1124 
  1125     int_result = sqlite3_prepare_v2(_session->db, sql_set_pgp_keypair,
  1126             (int)strlen(sql_set_pgp_keypair), &_session->set_pgp_keypair,
  1127             NULL);
  1128     assert(int_result == SQLITE_OK);
  1129 
  1130     int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_entry,
  1131             (int)strlen(sql_set_identity_entry), &_session->set_identity_entry, NULL);
  1132     assert(int_result == SQLITE_OK);
  1133 
  1134     int_result = sqlite3_prepare_v2(_session->db, sql_update_identity_entry,
  1135             (int)strlen(sql_update_identity_entry), &_session->update_identity_entry, NULL);
  1136     assert(int_result == SQLITE_OK);
  1137 
  1138     int_result = sqlite3_prepare_v2(_session->db, sql_exists_identity_entry,
  1139             (int)strlen(sql_exists_identity_entry), &_session->exists_identity_entry, NULL);
  1140     assert(int_result == SQLITE_OK);
  1141 
  1142     int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_flags,
  1143             (int)strlen(sql_set_identity_flags), &_session->set_identity_flags,
  1144             NULL);
  1145     assert(int_result == SQLITE_OK);
  1146 
  1147     int_result = sqlite3_prepare_v2(_session->db, sql_unset_identity_flags,
  1148             (int)strlen(sql_unset_identity_flags), &_session->unset_identity_flags,
  1149             NULL);
  1150     assert(int_result == SQLITE_OK);
  1151 
  1152     int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
  1153             (int)strlen(sql_set_trust), &_session->set_trust, NULL);
  1154     assert(int_result == SQLITE_OK);
  1155 
  1156     int_result = sqlite3_prepare_v2(_session->db, sql_update_trust,
  1157             (int)strlen(sql_update_trust), &_session->update_trust, NULL);
  1158     assert(int_result == SQLITE_OK);
  1159 
  1160     int_result = sqlite3_prepare_v2(_session->db, sql_exists_trust_entry,
  1161                  (int)strlen(sql_exists_trust_entry), &_session->exists_trust_entry, NULL);
  1162     assert(int_result == SQLITE_OK);
  1163 
  1164     int_result = sqlite3_prepare_v2(_session->db, sql_update_trust_for_fpr,
  1165             (int)strlen(sql_update_trust_for_fpr), &_session->update_trust_for_fpr, NULL);
  1166     assert(int_result == SQLITE_OK);
  1167 
  1168     int_result = sqlite3_prepare_v2(_session->db, sql_get_trust,
  1169             (int)strlen(sql_get_trust), &_session->get_trust, NULL);
  1170     assert(int_result == SQLITE_OK);
  1171 
  1172     int_result = sqlite3_prepare_v2(_session->db, sql_least_trust,
  1173             (int)strlen(sql_least_trust), &_session->least_trust, NULL);
  1174     assert(int_result == SQLITE_OK);
  1175 
  1176     int_result = sqlite3_prepare_v2(_session->db, sql_mark_as_compromized,
  1177             (int)strlen(sql_mark_as_compromized), &_session->mark_compromized,
  1178             NULL);
  1179     assert(int_result == SQLITE_OK);
  1180 
  1181     int_result = sqlite3_prepare_v2(_session->db, sql_crashdump,
  1182             (int)strlen(sql_crashdump), &_session->crashdump, NULL);
  1183     assert(int_result == SQLITE_OK);
  1184 
  1185     int_result = sqlite3_prepare_v2(_session->system_db, sql_languagelist,
  1186             (int)strlen(sql_languagelist), &_session->languagelist, NULL);
  1187     assert(int_result == SQLITE_OK);
  1188 
  1189     int_result = sqlite3_prepare_v2(_session->system_db, sql_i18n_token,
  1190             (int)strlen(sql_i18n_token), &_session->i18n_token, NULL);
  1191     assert(int_result == SQLITE_OK);
  1192     
  1193     // blacklist
  1194 
  1195     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_add,
  1196             (int)strlen(sql_blacklist_add), &_session->blacklist_add, NULL);
  1197     assert(int_result == SQLITE_OK);
  1198 
  1199     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_delete,
  1200             (int)strlen(sql_blacklist_delete), &_session->blacklist_delete,
  1201             NULL);
  1202     assert(int_result == SQLITE_OK);
  1203 
  1204     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_is_listed,
  1205             (int)strlen(sql_blacklist_is_listed),
  1206             &_session->blacklist_is_listed, NULL);
  1207     assert(int_result == SQLITE_OK);
  1208 
  1209     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_retrieve,
  1210             (int)strlen(sql_blacklist_retrieve), &_session->blacklist_retrieve,
  1211             NULL);
  1212     assert(int_result == SQLITE_OK);
  1213     
  1214     // Own keys
  1215     
  1216     int_result = sqlite3_prepare_v2(_session->db, sql_own_key_is_listed,
  1217             (int)strlen(sql_own_key_is_listed), &_session->own_key_is_listed,
  1218             NULL);
  1219     assert(int_result == SQLITE_OK);
  1220     
  1221     int_result = sqlite3_prepare_v2(_session->db, sql_own_identities_retrieve,
  1222             (int)strlen(sql_own_identities_retrieve),
  1223             &_session->own_identities_retrieve, NULL);
  1224     assert(int_result == SQLITE_OK);
  1225  
  1226     int_result = sqlite3_prepare_v2(_session->db, sql_own_keys_retrieve,
  1227             (int)strlen(sql_own_keys_retrieve),
  1228             &_session->own_keys_retrieve, NULL);
  1229     assert(int_result == SQLITE_OK);
  1230  
  1231     // int_result = sqlite3_prepare_v2(_session->db, sql_set_own_key,
  1232     //         (int)strlen(sql_set_own_key),
  1233     //         &_session->set_own_key, NULL);
  1234     // assert(int_result == SQLITE_OK);
  1235  
  1236     // Sequence
  1237 
  1238     int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value1,
  1239             (int)strlen(sql_sequence_value1), &_session->sequence_value1,
  1240             NULL);
  1241     assert(int_result == SQLITE_OK);
  1242 
  1243     int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value2,
  1244             (int)strlen(sql_sequence_value2), &_session->sequence_value2,
  1245             NULL);
  1246     assert(int_result == SQLITE_OK);
  1247 
  1248     int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value3,
  1249             (int)strlen(sql_sequence_value3), &_session->sequence_value3,
  1250             NULL);
  1251     assert(int_result == SQLITE_OK);
  1252 
  1253     // Revocation tracking
  1254     
  1255     int_result = sqlite3_prepare_v2(_session->db, sql_set_revoked,
  1256             (int)strlen(sql_set_revoked), &_session->set_revoked, NULL);
  1257     assert(int_result == SQLITE_OK);
  1258     
  1259     int_result = sqlite3_prepare_v2(_session->db, sql_get_revoked,
  1260             (int)strlen(sql_get_revoked), &_session->get_revoked, NULL);
  1261     assert(int_result == SQLITE_OK);
  1262     
  1263     int_result = sqlite3_prepare_v2(_session->db, sql_add_mistrusted_key,
  1264             (int)strlen(sql_add_mistrusted_key), &_session->add_mistrusted_key, NULL);
  1265     assert(int_result == SQLITE_OK);
  1266 
  1267     int_result = sqlite3_prepare_v2(_session->db, sql_delete_mistrusted_key,
  1268             (int)strlen(sql_delete_mistrusted_key), &_session->delete_mistrusted_key, NULL);
  1269     assert(int_result == SQLITE_OK);
  1270 
  1271     int_result = sqlite3_prepare_v2(_session->db, sql_is_mistrusted_key,
  1272             (int)strlen(sql_is_mistrusted_key), &_session->is_mistrusted_key, NULL);
  1273     assert(int_result == SQLITE_OK);
  1274     
  1275     status = init_cryptotech(_session, in_first);
  1276     if (status != PEP_STATUS_OK)
  1277         goto pep_error;
  1278 
  1279     status = init_transport_system(_session, in_first);
  1280     if (status != PEP_STATUS_OK)
  1281         goto pep_error;
  1282 
  1283     status = log_event(_session, "init", "pEp " PEP_ENGINE_VERSION, NULL, NULL);
  1284     if (status != PEP_STATUS_OK)
  1285         goto pep_error;
  1286 
  1287     // runtime config
  1288 
  1289     if (very_first)
  1290     {
  1291         // On first run, all private keys already present in PGP keyring 
  1292         // are taken as own in order to seamlessly integrate with
  1293         // pre-existing GPG setup.
  1294 
  1295         // Note: earlier fears about danger because of DB reinitialisation should
  1296         // be a non-issue here, as we ONLY take the ultimately trusted keys now.
  1297         // Thus, unless the user has assigned ultimate trust through PGP, there is
  1298         // no chance of automatically imported pEp keys from a previous run making
  1299         // their way into PEP trusted status without explicit action (Bare imported
  1300         // private keys have an 'unknown' trust designation in PGP).
  1301 
  1302         // We don't really worry about the status here.
  1303         status = import_trusted_own_keys(_session);        
  1304     }
  1305 
  1306     // sync_session set to own session by default
  1307     // sync_session is then never null on a valid session
  1308     _session->sync_session = _session;
  1309 
  1310     *session = _session;
  1311     
  1312     // Note: Following statement is NOT for any cryptographic/secure functionality; it is
  1313     //       ONLY used for some randomness in generated outer message ID, which are
  1314     //       required by the RFC to be globally unique!
  1315     srand(time(NULL));
  1316     
  1317     return PEP_STATUS_OK;
  1318 
  1319 enomem:
  1320     status = PEP_OUT_OF_MEMORY;
  1321 
  1322 pep_error:
  1323     release(_session);
  1324     return status;
  1325 }
  1326 
  1327 DYNAMIC_API void release(PEP_SESSION session)
  1328 {
  1329     bool out_last = false;
  1330     int _count = --init_count;
  1331     
  1332     assert(_count >= -1);
  1333     assert(session);
  1334 
  1335     if (!((_count >= -1) && session))
  1336         return;
  1337 
  1338     // a small race condition but still a race condition
  1339     // mitigated by calling caveat (see documentation)
  1340     // (release() is to be guarded by a mutex by the caller)
  1341     if (_count == -1)
  1342         out_last = true;
  1343 
  1344     if (session) {
  1345 
  1346         if (session->db) {
  1347             if (session->log)
  1348                 sqlite3_finalize(session->log);
  1349             if (session->trustword)
  1350                 sqlite3_finalize(session->trustword);
  1351             if (session->get_identity)
  1352                 sqlite3_finalize(session->get_identity);
  1353             if (session->get_identity_without_trust_check)
  1354                 sqlite3_finalize(session->get_identity_without_trust_check);
  1355             if (session->get_identities_by_address)
  1356                 sqlite3_finalize(session->get_identities_by_address);            
  1357             if (session->get_user_default_key)
  1358                 sqlite3_finalize(session->get_user_default_key);    
  1359             if (session->get_default_own_userid)
  1360                 sqlite3_finalize(session->get_default_own_userid);
  1361             if (session->get_userid_alias_default)
  1362                 sqlite3_finalize(session->get_userid_alias_default);
  1363             if (session->add_userid_alias)
  1364                 sqlite3_finalize(session->add_userid_alias);
  1365             if (session->replace_identities_fpr)
  1366                 sqlite3_finalize(session->replace_identities_fpr);        
  1367             if (session->remove_fpr_as_default)
  1368                 sqlite3_finalize(session->remove_fpr_as_default);            
  1369             if (session->set_person)
  1370                 sqlite3_finalize(session->set_person);
  1371             if (session->set_as_pep_user)
  1372                 sqlite3_finalize(session->set_as_pep_user);
  1373             if (session->is_pep_user)
  1374                 sqlite3_finalize(session->is_pep_user);
  1375             if (session->exists_person)
  1376                 sqlite3_finalize(session->exists_person);                        
  1377             if (session->set_device_group)
  1378                 sqlite3_finalize(session->set_device_group);
  1379             if (session->get_device_group)
  1380                 sqlite3_finalize(session->get_device_group);
  1381             if (session->set_pgp_keypair)
  1382                 sqlite3_finalize(session->set_pgp_keypair);
  1383             if (session->exists_identity_entry)
  1384                 sqlite3_finalize(session->exists_identity_entry);                
  1385             if (session->set_identity_entry)
  1386                 sqlite3_finalize(session->set_identity_entry);
  1387             if (session->update_identity_entry)
  1388                 sqlite3_finalize(session->update_identity_entry);    
  1389             if (session->set_identity_flags)
  1390                 sqlite3_finalize(session->set_identity_flags);
  1391             if (session->unset_identity_flags)
  1392                 sqlite3_finalize(session->unset_identity_flags);
  1393             if (session->exists_trust_entry)
  1394                 sqlite3_finalize(session->exists_trust_entry);                                
  1395             if (session->set_trust)
  1396                 sqlite3_finalize(session->set_trust);
  1397             if (session->update_trust)
  1398                 sqlite3_finalize(session->update_trust);                
  1399             if (session->update_trust_for_fpr)
  1400                 sqlite3_finalize(session->update_trust_for_fpr);
  1401             if (session->get_trust)
  1402                 sqlite3_finalize(session->get_trust);
  1403             if (session->least_trust)
  1404                 sqlite3_finalize(session->least_trust);
  1405             if (session->mark_compromized)
  1406                 sqlite3_finalize(session->mark_compromized);
  1407             if (session->crashdump)
  1408                 sqlite3_finalize(session->crashdump);
  1409             if (session->languagelist)
  1410                 sqlite3_finalize(session->languagelist);
  1411             if (session->i18n_token)
  1412                 sqlite3_finalize(session->i18n_token);
  1413             if (session->replace_userid)
  1414                 sqlite3_finalize(session->replace_userid);
  1415             if (session->replace_main_user_fpr)
  1416                 sqlite3_finalize(session->replace_main_user_fpr);                
  1417             if (session->get_main_user_fpr)
  1418                 sqlite3_finalize(session->get_main_user_fpr);
  1419             if (session->refresh_userid_default_key)
  1420                 sqlite3_finalize(session->refresh_userid_default_key);
  1421             if (session->blacklist_add)
  1422                 sqlite3_finalize(session->blacklist_add);
  1423             if (session->blacklist_delete)
  1424                 sqlite3_finalize(session->blacklist_delete);
  1425             if (session->blacklist_is_listed)
  1426                 sqlite3_finalize(session->blacklist_is_listed);
  1427             if (session->blacklist_retrieve)
  1428                 sqlite3_finalize(session->blacklist_retrieve);
  1429             if (session->own_key_is_listed)
  1430                 sqlite3_finalize(session->own_key_is_listed);
  1431             if (session->own_identities_retrieve)
  1432                 sqlite3_finalize(session->own_identities_retrieve);
  1433             if (session->own_keys_retrieve)
  1434                 sqlite3_finalize(session->own_keys_retrieve);
  1435             // if (session->set_own_key)
  1436             //     sqlite3_finalize(session->set_own_key);
  1437             if (session->sequence_value1)
  1438                 sqlite3_finalize(session->sequence_value1);
  1439             if (session->sequence_value2)
  1440                 sqlite3_finalize(session->sequence_value2);
  1441             if (session->sequence_value3)
  1442                 sqlite3_finalize(session->sequence_value3);
  1443             if (session->set_revoked)
  1444                 sqlite3_finalize(session->set_revoked);
  1445             if (session->get_revoked)
  1446                 sqlite3_finalize(session->get_revoked);
  1447 
  1448             if (session->add_mistrusted_key)
  1449                 sqlite3_finalize(session->add_mistrusted_key);
  1450             if (session->delete_mistrusted_key)
  1451                 sqlite3_finalize(session->delete_mistrusted_key);
  1452             if (session->is_mistrusted_key)
  1453                 sqlite3_finalize(session->is_mistrusted_key);
  1454 
  1455             if (session->db)
  1456                 sqlite3_close_v2(session->db);
  1457             if (session->system_db)
  1458                 sqlite3_close_v2(session->system_db);
  1459         }
  1460 
  1461         release_transport_system(session, out_last);
  1462         release_cryptotech(session, out_last);
  1463 
  1464 #ifdef DEBUG_ERRORSTACK
  1465         free_stringlist(session->errorstack);
  1466 #endif
  1467         free(session);
  1468     }
  1469 }
  1470 
  1471 DYNAMIC_API void config_passive_mode(PEP_SESSION session, bool enable)
  1472 {
  1473     assert(session);
  1474     session->passive_mode = enable;
  1475 }
  1476 
  1477 DYNAMIC_API void config_unencrypted_subject(PEP_SESSION session, bool enable)
  1478 {
  1479     assert(session);
  1480     session->unencrypted_subject = enable;
  1481 }
  1482 
  1483 DYNAMIC_API void config_keep_sync_msg(PEP_SESSION session, bool enable)
  1484 {
  1485     assert(session);
  1486     session->keep_sync_msg = enable;
  1487 }
  1488 
  1489 DYNAMIC_API void config_service_log(PEP_SESSION session, bool enable)
  1490 {
  1491     assert(session);
  1492     session->service_log = enable;
  1493 }
  1494 
  1495 DYNAMIC_API PEP_STATUS log_event(
  1496         PEP_SESSION session,
  1497         const char *title,
  1498         const char *entity,
  1499         const char *description,
  1500         const char *comment
  1501     )
  1502 {
  1503 //    PEP_STATUS status = PEP_STATUS_OK;
  1504     int result;
  1505 
  1506     assert(session);
  1507     assert(title);
  1508     assert(entity);
  1509 
  1510     if (!(session && title && entity))
  1511         return PEP_ILLEGAL_VALUE;
  1512 
  1513     sqlite3_reset(session->log);
  1514     sqlite3_bind_text(session->log, 1, title, -1, SQLITE_STATIC);
  1515     sqlite3_bind_text(session->log, 2, entity, -1, SQLITE_STATIC);
  1516     if (description)
  1517         sqlite3_bind_text(session->log, 3, description, -1, SQLITE_STATIC);
  1518     else
  1519         sqlite3_bind_null(session->log, 3);
  1520     if (comment)
  1521         sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
  1522     else
  1523         sqlite3_bind_null(session->log, 4);
  1524     result = sqlite3_step(session->log);
  1525     sqlite3_reset(session->log);
  1526 
  1527     return PEP_STATUS_OK; // We ignore errors for this function.
  1528 }
  1529 
  1530 DYNAMIC_API PEP_STATUS log_service(
  1531         PEP_SESSION session,
  1532         const char *title,
  1533         const char *entity,
  1534         const char *description,
  1535         const char *comment
  1536     )
  1537 {
  1538     assert(session);
  1539     if (!session)
  1540         return PEP_ILLEGAL_VALUE;
  1541 
  1542     if (session->service_log)
  1543         return log_event(session, title, entity, description, comment);
  1544     else
  1545         return PEP_STATUS_OK;
  1546 }
  1547 
  1548 DYNAMIC_API PEP_STATUS trustword(
  1549             PEP_SESSION session, uint16_t value, const char *lang,
  1550             char **word, size_t *wsize
  1551         )
  1552 {
  1553     PEP_STATUS status = PEP_STATUS_OK;
  1554 
  1555     assert(session);
  1556     assert(word);
  1557     assert(wsize);
  1558 
  1559     if (!(session && word && wsize))
  1560         return PEP_ILLEGAL_VALUE;
  1561 
  1562     *word = NULL;
  1563     *wsize = 0;
  1564 
  1565     if (lang == NULL)
  1566         lang = "en";
  1567 
  1568     assert((lang[0] >= 'A' && lang[0] <= 'Z')
  1569             || (lang[0] >= 'a' && lang[0] <= 'z'));
  1570     assert((lang[1] >= 'A' && lang[1] <= 'Z')
  1571             || (lang[1] >= 'a' && lang[1] <= 'z'));
  1572     assert(lang[2] == 0);
  1573 
  1574     sqlite3_reset(session->trustword);
  1575     sqlite3_bind_text(session->trustword, 1, lang, -1, SQLITE_STATIC);
  1576     sqlite3_bind_int(session->trustword, 2, value);
  1577 
  1578     const int result = sqlite3_step(session->trustword);
  1579     if (result == SQLITE_ROW) {
  1580         *word = strdup((const char *) sqlite3_column_text(session->trustword,
  1581                     1));
  1582         if (*word)
  1583             *wsize = sqlite3_column_bytes(session->trustword, 1);
  1584         else
  1585             status = PEP_OUT_OF_MEMORY;
  1586     } else
  1587         status = PEP_TRUSTWORD_NOT_FOUND;
  1588 
  1589     sqlite3_reset(session->trustword);
  1590     return status;
  1591 }
  1592 
  1593 DYNAMIC_API PEP_STATUS trustwords(
  1594         PEP_SESSION session, const char *fingerprint, const char *lang,
  1595         char **words, size_t *wsize, int max_words
  1596     )
  1597 {
  1598     const char *source = fingerprint;
  1599 
  1600     assert(session);
  1601     assert(fingerprint);
  1602     assert(words);
  1603     assert(wsize);
  1604     assert(max_words >= 0);
  1605 
  1606     if (!(session && fingerprint && words && wsize && max_words >= 0))
  1607         return PEP_ILLEGAL_VALUE;
  1608 
  1609     *words = NULL;
  1610     *wsize = 0;
  1611 
  1612     char *buffer = calloc(1, MAX_TRUSTWORDS_SPACE);
  1613     assert(buffer);
  1614     if (buffer == NULL)
  1615         return PEP_OUT_OF_MEMORY;
  1616     char *dest = buffer;
  1617 
  1618     const size_t fsize = strlen(fingerprint);
  1619 
  1620     if (!lang || !lang[0])
  1621         lang = "en";
  1622 
  1623     assert((lang[0] >= 'A' && lang[0] <= 'Z')
  1624             || (lang[0] >= 'a' && lang[0] <= 'z'));
  1625     assert((lang[1] >= 'A' && lang[1] <= 'Z')
  1626             || (lang[1] >= 'a' && lang[1] <= 'z'));
  1627     assert(lang[2] == 0);
  1628 
  1629     int n_words = 0;
  1630     while (source < fingerprint + fsize) {
  1631         PEP_STATUS _status;
  1632         uint16_t value;
  1633         char *word = NULL;
  1634         size_t _wsize = 0;
  1635         int j;
  1636 
  1637         for (value=0, j=0; j < 4 && source < fingerprint + fsize; ) {
  1638             if (*source >= 'a' && *source <= 'f')
  1639                 value += (*source - 'a' + 10) << (3 - j++) * 4;
  1640             else if (*source >= 'A' && *source <= 'F')
  1641                 value += (*source - 'A' + 10) << (3 - j++) * 4;
  1642             else if (*source >= '0' && *source <= '9')
  1643                 value += (*source - '0') << (3 - j++) * 4;
  1644             
  1645             source++;
  1646         }
  1647 
  1648         _status = trustword(session, value, lang, &word, &_wsize);
  1649         if (_status == PEP_OUT_OF_MEMORY) {
  1650             free(buffer);
  1651             return PEP_OUT_OF_MEMORY;
  1652         }
  1653         if (word == NULL) {
  1654             free(buffer);
  1655             return PEP_TRUSTWORD_NOT_FOUND;
  1656         }
  1657 
  1658         if (dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1) {
  1659             strncpy(dest, word, _wsize);
  1660             free(word);
  1661             dest += _wsize;
  1662         }
  1663         else {
  1664             free(word);
  1665             break; // buffer full
  1666         }
  1667 
  1668         if (source < fingerprint + fsize
  1669                 && dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1)
  1670             *dest++ = ' ';
  1671 
  1672         ++n_words;
  1673         if (max_words && n_words >= max_words)
  1674             break;
  1675     }
  1676 
  1677     *words = buffer;
  1678     *wsize = dest - buffer;
  1679     return PEP_STATUS_OK;
  1680 }
  1681 
  1682 pEp_identity *new_identity(
  1683         const char *address, const char *fpr, const char *user_id,
  1684         const char *username
  1685     )
  1686 {
  1687     pEp_identity *result = calloc(1, sizeof(pEp_identity));
  1688     assert(result);
  1689     if (result) {
  1690         if (address) {
  1691             result->address = strdup(address);
  1692             assert(result->address);
  1693             if (result->address == NULL) {
  1694                 free(result);
  1695                 return NULL;
  1696             }
  1697         }
  1698         if (fpr) {
  1699             result->fpr = strdup(fpr);
  1700             assert(result->fpr);
  1701             if (result->fpr == NULL) {
  1702                 free_identity(result);
  1703                 return NULL;
  1704             }
  1705         }
  1706         if (user_id) {
  1707             result->user_id = strdup(user_id);
  1708             assert(result->user_id);
  1709             if (result->user_id == NULL) {
  1710                 free_identity(result);
  1711                 return NULL;
  1712             }
  1713         }
  1714         if (username) {
  1715             result->username = strdup(username);
  1716             assert(result->username);
  1717             if (result->username == NULL) {
  1718                 free_identity(result);
  1719                 return NULL;
  1720             }
  1721         }
  1722     }
  1723     return result;
  1724 }
  1725 
  1726 pEp_identity *identity_dup(const pEp_identity *src)
  1727 {
  1728     assert(src);
  1729 
  1730     pEp_identity *dup = new_identity(src->address, src->fpr, src->user_id,
  1731             src->username);
  1732     assert(dup);
  1733     if (dup == NULL)
  1734         return NULL;
  1735     
  1736     dup->comm_type = src->comm_type;
  1737     dup->lang[0] = src->lang[0];
  1738     dup->lang[1] = src->lang[1];
  1739     dup->lang[2] = 0;
  1740     dup->flags = src->flags;
  1741     dup->me = src->me;
  1742     
  1743     return dup;
  1744 }
  1745 
  1746 void free_identity(pEp_identity *identity)
  1747 {
  1748     if (identity) {
  1749         free(identity->address);
  1750         free(identity->fpr);
  1751         free(identity->user_id);
  1752         free(identity->username);
  1753         free(identity);
  1754     }
  1755 }
  1756 
  1757 DYNAMIC_API PEP_STATUS get_default_own_userid(
  1758         PEP_SESSION session, 
  1759         char** userid
  1760     )
  1761 {
  1762     assert(session);
  1763     assert(userid);
  1764     
  1765     if (!session || !userid)
  1766         return PEP_ILLEGAL_VALUE;
  1767         
  1768     PEP_STATUS status = PEP_STATUS_OK;
  1769     char* retval = NULL;
  1770     
  1771     sqlite3_reset(session->get_default_own_userid);
  1772 
  1773     const int result = sqlite3_step(session->get_default_own_userid);
  1774     const char* id;
  1775     
  1776     switch (result) {
  1777         case SQLITE_ROW:
  1778             id = (const char *) sqlite3_column_text(session->get_default_own_userid, 0);
  1779             if (!id) {
  1780                 // Shouldn't happen.
  1781                 status = PEP_UNKNOWN_ERROR;
  1782             }
  1783             else {
  1784                 retval = strdup(id);
  1785                 if (!retval)
  1786                     status = PEP_OUT_OF_MEMORY;
  1787             }
  1788             break;
  1789         default:
  1790             // Technically true, given how we find it, but FIXME we need a more descriptive error
  1791             status = PEP_CANNOT_FIND_IDENTITY;
  1792             *userid = NULL;
  1793     }
  1794 
  1795     *userid = retval;
  1796 
  1797     sqlite3_reset(session->get_default_own_userid);
  1798     
  1799     return status;
  1800 }
  1801 
  1802 DYNAMIC_API PEP_STATUS get_userid_alias_default(
  1803         PEP_SESSION session, 
  1804         const char* alias_id,
  1805         char** default_id) {
  1806             
  1807     assert(session);
  1808     assert(alias_id);
  1809     assert(alias_id[0]);
  1810     assert(default_id);
  1811 
  1812     if (!(session && alias_id && alias_id[0] && default_id))
  1813         return PEP_ILLEGAL_VALUE;
  1814 
  1815     PEP_STATUS status = PEP_STATUS_OK;
  1816     char* retval = NULL;
  1817 
  1818     sqlite3_reset(session->get_userid_alias_default);
  1819     sqlite3_bind_text(session->get_userid_alias_default, 1, alias_id, -1, SQLITE_STATIC);
  1820 
  1821     const char* tempid;
  1822     
  1823     const int result = sqlite3_step(session->get_userid_alias_default);
  1824     switch (result) {
  1825     case SQLITE_ROW:
  1826         tempid = (const char *) sqlite3_column_text(session->get_userid_alias_default, 0);
  1827         if (tempid) {
  1828             retval = strdup(tempid);
  1829             assert(retval);
  1830             if (retval == NULL)
  1831                 return PEP_OUT_OF_MEMORY;
  1832         }
  1833     
  1834         *default_id = retval;
  1835         break;
  1836     default:
  1837         status = PEP_CANNOT_FIND_ALIAS;
  1838         *default_id = NULL;
  1839     }
  1840 
  1841     sqlite3_reset(session->get_userid_alias_default);
  1842     return status;            
  1843 }
  1844 
  1845 DYNAMIC_API PEP_STATUS set_userid_alias (
  1846         PEP_SESSION session, 
  1847         const char* default_id,
  1848         const char* alias_id) {
  1849             
  1850     int result;
  1851 
  1852     assert(session);
  1853     assert(default_id);
  1854     assert(alias_id);
  1855 
  1856     if (!(session && default_id && alias_id && 
  1857           default_id[0] != '\0' && alias_id[0] != '\0'))
  1858         return PEP_ILLEGAL_VALUE;
  1859     
  1860     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  1861 
  1862     sqlite3_reset(session->add_userid_alias);
  1863     sqlite3_bind_text(session->add_userid_alias, 1, default_id, -1,
  1864             SQLITE_STATIC);
  1865     sqlite3_bind_text(session->add_userid_alias, 2, alias_id, -1,
  1866             SQLITE_STATIC);
  1867         
  1868     result = sqlite3_step(session->add_userid_alias);
  1869 
  1870     sqlite3_reset(session->add_userid_alias);
  1871     if (result != SQLITE_DONE) {
  1872         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);        
  1873         return PEP_CANNOT_SET_ALIAS;
  1874     }
  1875     sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  1876         
  1877 
  1878     return PEP_STATUS_OK;
  1879 }
  1880 
  1881 DYNAMIC_API PEP_STATUS get_identity(
  1882         PEP_SESSION session,
  1883         const char *address,
  1884         const char *user_id,
  1885         pEp_identity **identity
  1886     )
  1887 {
  1888     PEP_STATUS status = PEP_STATUS_OK;
  1889     static pEp_identity *_identity;
  1890 
  1891     assert(session);
  1892     assert(address);
  1893     assert(address[0]);
  1894     assert(identity);
  1895 
  1896     if (!(session && address && address[0] && identity))
  1897         return PEP_ILLEGAL_VALUE;
  1898 
  1899     *identity = NULL;
  1900 
  1901     sqlite3_reset(session->get_identity);
  1902     sqlite3_bind_text(session->get_identity, 1, address, -1, SQLITE_STATIC);
  1903     sqlite3_bind_text(session->get_identity, 2, user_id, -1, SQLITE_STATIC);
  1904 
  1905     const int result = sqlite3_step(session->get_identity);
  1906     switch (result) {
  1907     case SQLITE_ROW:
  1908         _identity = new_identity(
  1909                 address,
  1910                 (const char *) sqlite3_column_text(session->get_identity, 0),
  1911                 user_id,
  1912                 (const char *) sqlite3_column_text(session->get_identity, 1)
  1913                 );
  1914         assert(_identity);
  1915         if (_identity == NULL)
  1916             return PEP_OUT_OF_MEMORY;
  1917 
  1918         _identity->comm_type = (PEP_comm_type)
  1919             sqlite3_column_int(session->get_identity, 2);
  1920         const char* const _lang = (const char *)
  1921             sqlite3_column_text(session->get_identity, 3);
  1922         if (_lang && _lang[0]) {
  1923             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  1924             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  1925             assert(_lang[2] == 0);
  1926             _identity->lang[0] = _lang[0];
  1927             _identity->lang[1] = _lang[1];
  1928             _identity->lang[2] = 0;
  1929         }
  1930         _identity->flags = (unsigned int)
  1931             sqlite3_column_int(session->get_identity, 4);
  1932         _identity->me = (unsigned int)
  1933             sqlite3_column_int(session->get_identity, 5);
  1934     
  1935         *identity = _identity;
  1936         break;
  1937     default:
  1938         status = PEP_CANNOT_FIND_IDENTITY;
  1939         *identity = NULL;
  1940     }
  1941 
  1942     sqlite3_reset(session->get_identity);
  1943     return status;
  1944 }
  1945 
  1946 PEP_STATUS get_identity_without_trust_check(
  1947         PEP_SESSION session,
  1948         const char *address,
  1949         const char *user_id,
  1950         pEp_identity **identity
  1951     )
  1952 {
  1953     PEP_STATUS status = PEP_STATUS_OK;
  1954     static pEp_identity *_identity;
  1955 
  1956     assert(session);
  1957     assert(address);
  1958     assert(address[0]);
  1959     assert(identity);
  1960 
  1961     if (!(session && address && address[0] && identity))
  1962         return PEP_ILLEGAL_VALUE;
  1963 
  1964     *identity = NULL;
  1965 
  1966     sqlite3_reset(session->get_identity_without_trust_check);
  1967     sqlite3_bind_text(session->get_identity_without_trust_check, 1, address, -1, SQLITE_STATIC);
  1968     sqlite3_bind_text(session->get_identity_without_trust_check, 2, user_id, -1, SQLITE_STATIC);
  1969 
  1970     const int result = sqlite3_step(session->get_identity_without_trust_check);
  1971     switch (result) {
  1972     case SQLITE_ROW:
  1973         _identity = new_identity(
  1974                 address,
  1975                 (const char *) sqlite3_column_text(session->get_identity_without_trust_check, 0),
  1976                 user_id,
  1977                 (const char *) sqlite3_column_text(session->get_identity_without_trust_check, 1)
  1978                 );
  1979         assert(_identity);
  1980         if (_identity == NULL)
  1981             return PEP_OUT_OF_MEMORY;
  1982 
  1983         _identity->comm_type = PEP_ct_unknown;
  1984         const char* const _lang = (const char *)
  1985             sqlite3_column_text(session->get_identity_without_trust_check, 2);
  1986         if (_lang && _lang[0]) {
  1987             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  1988             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  1989             assert(_lang[2] == 0);
  1990             _identity->lang[0] = _lang[0];
  1991             _identity->lang[1] = _lang[1];
  1992             _identity->lang[2] = 0;
  1993         }
  1994         _identity->flags = (unsigned int)
  1995             sqlite3_column_int(session->get_identity_without_trust_check, 3);
  1996         _identity->me = (unsigned int)
  1997             sqlite3_column_int(session->get_identity_without_trust_check, 4);
  1998     
  1999         *identity = _identity;
  2000         break;
  2001     default:
  2002         status = PEP_CANNOT_FIND_IDENTITY;
  2003         *identity = NULL;
  2004     }
  2005 
  2006     sqlite3_reset(session->get_identity_without_trust_check);
  2007     return status;
  2008 }
  2009 
  2010 PEP_STATUS get_identities_by_address(
  2011         PEP_SESSION session,
  2012         const char *address,
  2013         identity_list** id_list
  2014     )
  2015 {
  2016     pEp_identity* ident;
  2017 
  2018     assert(session);
  2019     assert(address);
  2020     assert(address[0]);
  2021     assert(id_list);
  2022 
  2023     if (!(session && address && address[0] && id_list))
  2024         return PEP_ILLEGAL_VALUE;
  2025 
  2026     *id_list = NULL;
  2027     identity_list* ident_list = NULL;
  2028 
  2029     sqlite3_reset(session->get_identities_by_address);
  2030     sqlite3_bind_text(session->get_identities_by_address, 1, address, -1, SQLITE_STATIC);
  2031     int result;
  2032 
  2033     while ((result = sqlite3_step(session->get_identities_by_address)) == SQLITE_ROW) {
  2034         //"select user_id, main_key_id, username, comm_type, lang,"
  2035         //"   identity.flags, is_own"
  2036         ident = new_identity(
  2037                 address,
  2038                 (const char *) sqlite3_column_text(session->get_identities_by_address, 1),
  2039                 (const char *) sqlite3_column_text(session->get_identities_by_address, 0),
  2040                 (const char *) sqlite3_column_text(session->get_identities_by_address, 2)
  2041                 );
  2042         assert(ident);
  2043         if (ident == NULL)
  2044             return PEP_OUT_OF_MEMORY;
  2045 
  2046         ident->comm_type = PEP_ct_unknown;
  2047         
  2048         const char* const _lang = (const char *)
  2049             sqlite3_column_text(session->get_identities_by_address, 3);
  2050         if (_lang && _lang[0]) {
  2051             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  2052             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  2053             assert(_lang[2] == 0);
  2054             ident->lang[0] = _lang[0];
  2055             ident->lang[1] = _lang[1];
  2056             ident->lang[2] = 0;
  2057         }
  2058         ident->flags = (unsigned int)
  2059             sqlite3_column_int(session->get_identities_by_address, 4);
  2060         ident->me = (unsigned int)
  2061             sqlite3_column_int(session->get_identities_by_address, 5);
  2062     
  2063         if (ident_list)
  2064             identity_list_add(ident_list, ident);
  2065         else
  2066             ident_list = new_identity_list(ident);
  2067     }
  2068 
  2069     sqlite3_reset(session->get_identities_by_address);
  2070     
  2071     *id_list = ident_list;
  2072     
  2073     if (!ident_list)
  2074         return PEP_CANNOT_FIND_IDENTITY;
  2075     
  2076     return PEP_STATUS_OK;
  2077 }
  2078 
  2079 PEP_STATUS exists_identity_entry(PEP_SESSION session, pEp_identity* identity,
  2080                                  bool* exists) {
  2081     assert(session);
  2082     assert(identity);
  2083     assert(!EMPTYSTR(identity->user_id));        
  2084     assert(!EMPTYSTR(identity->address));
  2085     if (!session || !exists || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->address))
  2086         return PEP_ILLEGAL_VALUE;
  2087     
  2088     *exists = false;
  2089     
  2090     sqlite3_reset(session->exists_identity_entry);
  2091     sqlite3_bind_text(session->exists_identity_entry, 1, identity->address, -1,
  2092                       SQLITE_STATIC);
  2093     sqlite3_bind_text(session->exists_identity_entry, 2, identity->user_id, -1,
  2094                       SQLITE_STATIC);
  2095                   
  2096     int result = sqlite3_step(session->exists_identity_entry);
  2097     switch (result) {
  2098         case SQLITE_ROW: {
  2099             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2100             *exists = (sqlite3_column_int(session->exists_identity_entry, 0) != 0);
  2101             break;
  2102         }
  2103         default:
  2104             return PEP_UNKNOWN_ERROR;
  2105     }
  2106 
  2107     return PEP_STATUS_OK;
  2108 }
  2109 
  2110 PEP_STATUS exists_trust_entry(PEP_SESSION session, pEp_identity* identity,
  2111                               bool* exists) {
  2112     assert(session);
  2113     assert(identity);
  2114     assert(!EMPTYSTR(identity->user_id));        
  2115     assert(!EMPTYSTR(identity->fpr));
  2116     if (!session || !exists || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->fpr))
  2117         return PEP_ILLEGAL_VALUE;
  2118     
  2119     *exists = false;
  2120     
  2121     sqlite3_reset(session->exists_trust_entry);
  2122     sqlite3_bind_text(session->exists_trust_entry, 1, identity->user_id, -1,
  2123                       SQLITE_STATIC);
  2124     sqlite3_bind_text(session->exists_trust_entry, 2, identity->fpr, -1,
  2125                       SQLITE_STATIC);
  2126                   
  2127     int result = sqlite3_step(session->exists_trust_entry);
  2128     switch (result) {
  2129         case SQLITE_ROW: {
  2130             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2131             *exists = (sqlite3_column_int(session->exists_trust_entry, 0) != 0);
  2132             break;
  2133         }
  2134         default:
  2135             return PEP_UNKNOWN_ERROR;
  2136     }
  2137 
  2138     return PEP_STATUS_OK;
  2139 }
  2140 
  2141 // FIXME: We can rollback in set_identity on the return status,
  2142 // so we should probably do that.
  2143 PEP_STATUS set_pgp_keypair(PEP_SESSION session, const char* fpr) {
  2144     if (!session || EMPTYSTR(fpr))
  2145         return PEP_ILLEGAL_VALUE;
  2146         
  2147     int result;
  2148     
  2149     sqlite3_reset(session->set_pgp_keypair);
  2150     sqlite3_bind_text(session->set_pgp_keypair, 1, fpr, -1,
  2151             SQLITE_STATIC);
  2152     result = sqlite3_step(session->set_pgp_keypair);
  2153     sqlite3_reset(session->set_pgp_keypair);
  2154     if (result != SQLITE_DONE) {
  2155         return PEP_CANNOT_SET_PGP_KEYPAIR;
  2156     }
  2157     
  2158     return PEP_STATUS_OK;
  2159 }
  2160 
  2161 static PEP_STATUS _set_or_update_trust(PEP_SESSION session,
  2162                                        pEp_identity* identity,
  2163                                        sqlite3_stmt* set_or_update) {
  2164 
  2165     assert(session);
  2166     assert(identity);
  2167     assert(identity->user_id);
  2168     assert(identity->fpr);
  2169     
  2170     if (!session || !identity || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->fpr))
  2171         return PEP_ILLEGAL_VALUE;
  2172         
  2173     int result;
  2174                 
  2175     sqlite3_reset(set_or_update);
  2176     sqlite3_bind_text(set_or_update, 1, identity->user_id, -1,
  2177             SQLITE_STATIC);
  2178     sqlite3_bind_text(set_or_update, 2, identity->fpr, -1,
  2179             SQLITE_STATIC);
  2180     sqlite3_bind_int(set_or_update, 3, identity->comm_type);
  2181     result = sqlite3_step(set_or_update);
  2182     assert(result == SQLITE_DONE);
  2183     sqlite3_reset(set_or_update);
  2184     if (result != SQLITE_DONE)
  2185         return PEP_CANNOT_SET_TRUST;
  2186 
  2187     return PEP_STATUS_OK;
  2188 }
  2189 
  2190 static PEP_STATUS _set_or_update_identity_entry(PEP_SESSION session,
  2191                                                 pEp_identity* identity,
  2192                                                 sqlite3_stmt* set_or_update) {
  2193     assert(session);
  2194     assert(identity);
  2195     assert(set_or_update);
  2196                       
  2197     if (!session || !identity || !identity->user_id || !identity->address)
  2198         return PEP_ILLEGAL_VALUE;
  2199                                               
  2200     sqlite3_reset(set_or_update);
  2201     sqlite3_bind_text(set_or_update, 1, identity->address, -1,
  2202             SQLITE_STATIC);
  2203     sqlite3_bind_text(set_or_update, 2, identity->fpr, -1,
  2204             SQLITE_STATIC);
  2205     sqlite3_bind_text(set_or_update, 3, identity->user_id, -1,
  2206             SQLITE_STATIC);
  2207     sqlite3_bind_int(set_or_update, 4, identity->flags);
  2208     sqlite3_bind_int(set_or_update, 5, identity->me);
  2209     int result = sqlite3_step(set_or_update);
  2210     sqlite3_reset(set_or_update);
  2211     if (result != SQLITE_DONE)
  2212         return PEP_CANNOT_SET_IDENTITY;
  2213     
  2214     return PEP_STATUS_OK;
  2215 }
  2216 
  2217 static PEP_STATUS _set_or_update_person(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->username)
  2225         return PEP_ILLEGAL_VALUE;
  2226         
  2227     sqlite3_reset(set_or_update);
  2228     sqlite3_bind_text(set_or_update, 1, identity->user_id, -1,
  2229             SQLITE_STATIC);
  2230     sqlite3_bind_text(set_or_update, 2, identity->username, -1,
  2231             SQLITE_STATIC);
  2232     if (identity->lang[0])
  2233         sqlite3_bind_text(set_or_update, 3, identity->lang, 2,
  2234                 SQLITE_STATIC);
  2235     else
  2236         sqlite3_bind_null(set_or_update, 3);
  2237     sqlite3_bind_text(set_or_update, 4, identity->fpr, -1,
  2238                       SQLITE_STATIC);
  2239     int result = sqlite3_step(set_or_update);
  2240     sqlite3_reset(set_or_update);
  2241     
  2242     if (result != SQLITE_DONE)
  2243         return PEP_CANNOT_SET_PERSON;
  2244     
  2245     return PEP_STATUS_OK;                                         
  2246 }
  2247 
  2248 PEP_STATUS set_or_update_with_identity(PEP_SESSION session,
  2249                                        pEp_identity* identity,
  2250                                        PEP_STATUS (* set_function)(PEP_SESSION, pEp_identity*, sqlite3_stmt*),
  2251                                        PEP_STATUS (* exists_function)(PEP_SESSION, pEp_identity*, bool*),                                       
  2252                                        sqlite3_stmt* update_query,
  2253                                        sqlite3_stmt* set_query,
  2254                                        bool guard_transaction) {
  2255 
  2256     if (guard_transaction) {
  2257         sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  2258     }
  2259     bool exists = false;
  2260     PEP_STATUS status = exists_function(session, identity, &exists);
  2261     
  2262     if (status == PEP_STATUS_OK) {
  2263         if (exists) {
  2264             status = set_function(session, identity, update_query);
  2265         }
  2266         else {
  2267             status = set_function(session, identity, set_query);                                              
  2268         }                    
  2269     }   
  2270     if (guard_transaction) {        
  2271         if (status != PEP_STATUS_OK)
  2272             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2273         else 
  2274             sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  2275     }                      
  2276     return status;
  2277 }
  2278 
  2279 PEP_STATUS _set_trust_internal(PEP_SESSION session, pEp_identity* identity,
  2280                                bool guard_transaction) {
  2281     return set_or_update_with_identity(session, identity,
  2282                                        _set_or_update_trust,
  2283                                         exists_trust_entry,
  2284                                         session->update_trust,
  2285                                         session->set_trust,
  2286                                         guard_transaction);
  2287 }
  2288 
  2289 // This is the TOP-LEVEL function. If you're calling from set_identity,
  2290 // you can't use this one.
  2291 PEP_STATUS set_trust(PEP_SESSION session, pEp_identity* identity) {
  2292     PEP_STATUS status = PEP_STATUS_OK;
  2293     
  2294     status = _set_trust_internal(session, identity, true);
  2295     if (status == PEP_STATUS_OK) {
  2296         if ((identity->comm_type | PEP_ct_confirmed) == PEP_ct_pEp)
  2297             status = set_as_pep_user(session, identity);
  2298     }
  2299     return status;
  2300 }
  2301 
  2302 PEP_STATUS set_person(PEP_SESSION session, pEp_identity* identity,
  2303                       bool guard_transaction) {
  2304     return set_or_update_with_identity(session, identity,
  2305                                        _set_or_update_person,
  2306                                        exists_person,
  2307                                        session->update_person,
  2308                                        session->set_person,
  2309                                        guard_transaction);
  2310 }
  2311 
  2312 PEP_STATUS set_identity_entry(PEP_SESSION session, pEp_identity* identity,
  2313                               bool guard_transaction) {
  2314     return set_or_update_with_identity(session, identity,
  2315                                        _set_or_update_identity_entry,
  2316                                        exists_identity_entry,
  2317                                        session->update_identity_entry,
  2318                                        session->set_identity_entry,
  2319                                        guard_transaction);
  2320 }
  2321 
  2322 // This will NOT call set_as_pep_user; you have to do that separately.
  2323 DYNAMIC_API PEP_STATUS set_identity(
  2324         PEP_SESSION session, const pEp_identity *identity
  2325     )
  2326 {
  2327     int result;
  2328 
  2329     assert(session);
  2330     assert(identity);
  2331     assert(identity->address);
  2332     assert(identity->user_id);
  2333     assert(identity->username);
  2334 
  2335     if (!(session && identity && identity->address &&
  2336                 identity->user_id && identity->username))
  2337         return PEP_ILLEGAL_VALUE;
  2338 
  2339     PEP_STATUS status = PEP_STATUS_OK;
  2340     
  2341     bool listed;
  2342 
  2343     bool has_fpr = (!EMPTYSTR(identity->fpr));
  2344     
  2345     if (has_fpr) {    
  2346         // blacklist check - FIXME: ENGINE-294 will remove
  2347         status = blacklist_is_listed(session, identity->fpr, &listed);
  2348         assert(status == PEP_STATUS_OK);
  2349         if (status != PEP_STATUS_OK)
  2350             return status;
  2351 
  2352         if (listed)
  2353             return PEP_KEY_BLACKLISTED;
  2354     }
  2355 
  2356     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  2357 
  2358     if (identity->lang[0]) {
  2359         assert(identity->lang[0] >= 'a' && identity->lang[0] <= 'z');
  2360         assert(identity->lang[1] >= 'a' && identity->lang[1] <= 'z');
  2361         assert(identity->lang[2] == 0);
  2362     }
  2363 
  2364     if (has_fpr) {
  2365         sqlite3_reset(session->set_pgp_keypair);
  2366         sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
  2367                 SQLITE_STATIC);
  2368         result = sqlite3_step(session->set_pgp_keypair);
  2369         sqlite3_reset(session->set_pgp_keypair);
  2370         if (result != SQLITE_DONE) {
  2371             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2372             return PEP_CANNOT_SET_PGP_KEYPAIR;
  2373         }
  2374     }
  2375 
  2376     // We do this because there are checks in set_person for
  2377     // aliases, which modify the identity object on return.
  2378     pEp_identity* ident_copy = identity_dup(identity); 
  2379     if (!ident_copy)
  2380         return PEP_OUT_OF_MEMORY;
  2381 
  2382     status = set_person(session, ident_copy, false);
  2383     if (status != PEP_STATUS_OK) {
  2384         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2385         goto pep_free;
  2386     }
  2387 
  2388     status = set_identity_entry(session, ident_copy, false);
  2389     if (status != PEP_STATUS_OK) {
  2390         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2391         goto pep_free;
  2392     }
  2393 
  2394     if (has_fpr) {
  2395         status = _set_trust_internal(session, ident_copy, false);
  2396         if (status != PEP_STATUS_OK) {
  2397             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2398             goto pep_free;
  2399         }
  2400     }
  2401     
  2402     result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  2403     if (result == SQLITE_OK)
  2404         status = PEP_STATUS_OK;
  2405     else
  2406         status = PEP_COMMIT_FAILED;
  2407 
  2408 pep_free:
  2409     free_identity(ident_copy);
  2410     return status;
  2411 }
  2412 
  2413 // This ONLY sets the user flag. Must be called outside of a transaction.
  2414 PEP_STATUS set_as_pep_user(PEP_SESSION session, pEp_identity* user) {
  2415 
  2416     assert(session);
  2417     assert(user);
  2418     assert(!EMPTYSTR(user->user_id));
  2419         
  2420     if (!session || !user || EMPTYSTR(user->user_id))
  2421         return PEP_ILLEGAL_VALUE;
  2422             
  2423     PEP_STATUS status = PEP_STATUS_OK;
  2424     
  2425     bool person_exists = false;
  2426     
  2427     status = exists_person(session, user, &person_exists);
  2428     
  2429     if (status != PEP_STATUS_OK)
  2430         return status;
  2431         
  2432     if (!person_exists)
  2433         status = set_person(session, user, true);
  2434         
  2435     // Ok, let's set it.
  2436     sqlite3_reset(session->set_as_pep_user);
  2437     sqlite3_bind_text(session->set_as_pep_user, 1, user->user_id, -1,
  2438             SQLITE_STATIC);
  2439     int result = sqlite3_step(session->set_as_pep_user);
  2440     sqlite3_reset(session->set_as_pep_user);
  2441     
  2442     if (result != SQLITE_DONE)
  2443         return PEP_CANNOT_SET_PERSON;
  2444         
  2445     return PEP_STATUS_OK;    
  2446 }
  2447 
  2448 PEP_STATUS exists_person(PEP_SESSION session, pEp_identity* identity,
  2449                          bool* exists) {            
  2450     
  2451     // const char* user_id,
  2452     //                      char** default_id, bool* exists) {
  2453     assert(session);
  2454     assert(exists);
  2455     assert(identity);
  2456     assert(!EMPTYSTR(identity->user_id));
  2457         
  2458     if (!session || !exists || !identity || EMPTYSTR(identity->user_id))
  2459         return PEP_ILLEGAL_VALUE;
  2460     
  2461     *exists = false;
  2462 
  2463     const char* user_id = identity->user_id;
  2464     char* alias_default = NULL;
  2465     
  2466     PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
  2467     
  2468     if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
  2469         sqlite3_reset(session->exists_person);
  2470         sqlite3_bind_text(session->exists_person, 1, user_id, -1,
  2471                 SQLITE_STATIC);
  2472         int result = sqlite3_step(session->exists_person);
  2473         switch (result) {
  2474             case SQLITE_ROW: {
  2475                 // yeah yeah, I know, we could be lazy here, but it looks bad.
  2476                 *exists = (sqlite3_column_int(session->exists_person, 0) != 0);
  2477                 status = PEP_STATUS_OK;
  2478                 break;
  2479             }
  2480             default:
  2481                 return PEP_UNKNOWN_ERROR;
  2482         }
  2483     }
  2484     else if (status == PEP_STATUS_OK) {
  2485         *exists = true; // thank you, delete on cascade!
  2486         // FIXME: Should we correct the userid default here? I think we should.
  2487         free(identity->user_id);
  2488         identity->user_id = alias_default; // ownership transfer
  2489     }
  2490     else
  2491         free(alias_default);
  2492         
  2493     return status;
  2494 }
  2495 
  2496 DYNAMIC_API PEP_STATUS is_pep_user(PEP_SESSION session, pEp_identity *identity, bool* is_pep)
  2497 {
  2498     assert(session);
  2499     assert(is_pep);
  2500     assert(identity);
  2501     assert(!EMPTYSTR(identity->user_id));
  2502 
  2503     if (!session || !is_pep || !identity || EMPTYSTR(identity->user_id))
  2504         return PEP_ILLEGAL_VALUE;
  2505     
  2506     *is_pep = false;
  2507     
  2508     const char* user_id = identity->user_id;
  2509     
  2510     if (!session || EMPTYSTR(user_id))
  2511         return PEP_ILLEGAL_VALUE;
  2512         
  2513     char* alias_default = NULL;
  2514     
  2515     PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
  2516     
  2517     if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
  2518         free(alias_default);
  2519         alias_default = strdup(user_id);
  2520     }
  2521     
  2522     sqlite3_reset(session->is_pep_user);
  2523     sqlite3_bind_text(session->is_pep_user, 1, user_id, -1,
  2524             SQLITE_STATIC);
  2525     int result = sqlite3_step(session->is_pep_user);
  2526     switch (result) {
  2527         case SQLITE_ROW: {
  2528             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2529             *is_pep = (sqlite3_column_int(session->is_pep_user, 0) != 0);
  2530             break;
  2531         }
  2532         default:
  2533             free(alias_default);
  2534             return PEP_CANNOT_FIND_PERSON;
  2535     }
  2536 
  2537     return PEP_STATUS_OK;
  2538 }
  2539 
  2540 
  2541 PEP_STATUS remove_fpr_as_default(PEP_SESSION session, 
  2542                                  const char* fpr) 
  2543 {
  2544     assert(fpr);
  2545     
  2546     if (!session || !fpr)
  2547         return PEP_ILLEGAL_VALUE;
  2548             
  2549     sqlite3_reset(session->remove_fpr_as_default);
  2550     sqlite3_bind_text(session->remove_fpr_as_default, 1, fpr, -1,
  2551                       SQLITE_STATIC);
  2552 
  2553     int result = sqlite3_step(session->remove_fpr_as_default);
  2554     sqlite3_reset(session->remove_fpr_as_default);
  2555     
  2556     if (result != SQLITE_DONE)
  2557         return PEP_CANNOT_SET_IDENTITY; // misleading - could also be person
  2558 
  2559     return PEP_STATUS_OK;
  2560 }
  2561 
  2562 
  2563 PEP_STATUS replace_identities_fpr(PEP_SESSION session, 
  2564                                  const char* old_fpr, 
  2565                                  const char* new_fpr) 
  2566 {
  2567     assert(old_fpr);
  2568     assert(new_fpr);
  2569     
  2570     if (!old_fpr || !new_fpr)
  2571         return PEP_ILLEGAL_VALUE;
  2572             
  2573     sqlite3_reset(session->replace_identities_fpr);
  2574     sqlite3_bind_text(session->replace_identities_fpr, 1, new_fpr, -1,
  2575                       SQLITE_STATIC);
  2576     sqlite3_bind_text(session->replace_identities_fpr, 2, old_fpr, -1,
  2577                       SQLITE_STATIC);
  2578 
  2579     int result = sqlite3_step(session->replace_identities_fpr);
  2580     sqlite3_reset(session->replace_identities_fpr);
  2581     
  2582     if (result != SQLITE_DONE)
  2583         return PEP_CANNOT_SET_IDENTITY;
  2584 
  2585     return PEP_STATUS_OK;
  2586 }
  2587 
  2588 PEP_STATUS update_trust_for_fpr(PEP_SESSION session, 
  2589                                 const char* fpr, 
  2590                                 PEP_comm_type comm_type)
  2591 {
  2592     if (!fpr)
  2593         return PEP_ILLEGAL_VALUE;
  2594         
  2595     sqlite3_reset(session->update_trust_for_fpr);
  2596     sqlite3_bind_int(session->update_trust_for_fpr, 1, comm_type);
  2597     sqlite3_bind_text(session->update_trust_for_fpr, 2, fpr, -1,
  2598             SQLITE_STATIC);
  2599     int result = sqlite3_step(session->update_trust_for_fpr);
  2600     sqlite3_reset(session->update_trust_for_fpr);
  2601     if (result != SQLITE_DONE) {
  2602         return PEP_CANNOT_SET_TRUST;
  2603     }
  2604     
  2605     return PEP_STATUS_OK;
  2606 }
  2607 
  2608 DYNAMIC_API PEP_STATUS set_device_group(
  2609         PEP_SESSION session,
  2610         const char *group_name
  2611     )
  2612 {
  2613     int result;
  2614 
  2615     assert(session);
  2616 
  2617     if (!(session && group_name))
  2618         return PEP_ILLEGAL_VALUE;
  2619 
  2620     // 1. Get own user_id
  2621     char* user_id = NULL;
  2622     PEP_STATUS status = get_default_own_userid(session, &user_id);
  2623     
  2624     // No user_id is returned in this case, no need to free;
  2625     if (status != PEP_STATUS_OK)
  2626         return status;
  2627         
  2628     // 2. Set device group
  2629     sqlite3_reset(session->set_device_group);
  2630     if(group_name){
  2631         sqlite3_bind_text(session->set_device_group, 1, group_name, -1,
  2632                 SQLITE_STATIC);
  2633     } else {
  2634         sqlite3_bind_null(session->set_device_group, 1);
  2635     }
  2636     
  2637     sqlite3_bind_text(session->set_device_group, 2, user_id, -1,
  2638             SQLITE_STATIC);
  2639 
  2640     result = sqlite3_step(session->set_device_group);
  2641     sqlite3_reset(session->set_device_group);
  2642     
  2643     free(user_id);
  2644     
  2645     if (result != SQLITE_DONE)
  2646         return PEP_CANNOT_SET_PERSON;
  2647 
  2648     return PEP_STATUS_OK;
  2649 }
  2650 
  2651 DYNAMIC_API PEP_STATUS get_device_group(PEP_SESSION session, char **group_name)
  2652 {
  2653     PEP_STATUS status = PEP_STATUS_OK;
  2654     int result;
  2655 
  2656     assert(session);
  2657     assert(group_name);
  2658 
  2659     if (!(session && group_name))
  2660         return PEP_ILLEGAL_VALUE;
  2661 
  2662     // 1. Get own user_id
  2663     char* user_id = NULL;
  2664     status = get_default_own_userid(session, &user_id);
  2665     
  2666     // No user_id is returned in this case, no need to free;
  2667     if (status != PEP_STATUS_OK)
  2668         return status;
  2669 
  2670     // 2. get device group
  2671     sqlite3_reset(session->get_device_group);
  2672     sqlite3_bind_text(session->get_device_group, 1, user_id, -1,
  2673             SQLITE_STATIC);
  2674 
  2675     result = sqlite3_step(session->get_device_group);
  2676     switch (result) {
  2677     case SQLITE_ROW: {
  2678         const char *_group_name = (const char *)sqlite3_column_text(session->get_device_group, 0);
  2679         if(_group_name){
  2680             *group_name = strdup(_group_name);
  2681                 if(*group_name == NULL)
  2682                     status = PEP_OUT_OF_MEMORY;
  2683         }
  2684         break;
  2685     }
  2686  
  2687     default:
  2688         status = PEP_RECORD_NOT_FOUND;
  2689     }
  2690 
  2691     free(user_id);
  2692     sqlite3_reset(session->get_device_group);
  2693     return status;
  2694 }
  2695 
  2696 DYNAMIC_API PEP_STATUS set_identity_flags(
  2697         PEP_SESSION session,
  2698         pEp_identity *identity,
  2699         unsigned int flags
  2700     )
  2701 {
  2702     int result;
  2703 
  2704     assert(session);
  2705     assert(identity);
  2706     assert(identity->address);
  2707     assert(identity->user_id);
  2708 
  2709     if (!(session && identity && identity->address && identity->user_id))
  2710         return PEP_ILLEGAL_VALUE;
  2711 
  2712     sqlite3_reset(session->set_identity_flags);
  2713     sqlite3_bind_int(session->set_identity_flags, 1, flags);
  2714     sqlite3_bind_text(session->set_identity_flags, 2, identity->address, -1,
  2715             SQLITE_STATIC);
  2716     sqlite3_bind_text(session->set_identity_flags, 3, identity->user_id, -1,
  2717         SQLITE_STATIC);
  2718         
  2719     result = sqlite3_step(session->set_identity_flags);
  2720 
  2721     sqlite3_reset(session->set_identity_flags);
  2722     if (result != SQLITE_DONE)
  2723         return PEP_CANNOT_SET_IDENTITY;
  2724 
  2725     identity->flags |= flags;
  2726     return PEP_STATUS_OK;
  2727 }
  2728 
  2729 DYNAMIC_API PEP_STATUS unset_identity_flags(
  2730         PEP_SESSION session,
  2731         pEp_identity *identity,
  2732         unsigned int flags
  2733     )
  2734 {
  2735     int result;
  2736 
  2737     assert(session);
  2738     assert(identity);
  2739     assert(identity->address);
  2740     assert(identity->user_id);
  2741 
  2742     if (!(session && identity && identity->address && identity->user_id))
  2743         return PEP_ILLEGAL_VALUE;
  2744 
  2745     sqlite3_reset(session->unset_identity_flags);
  2746     sqlite3_bind_int(session->unset_identity_flags, 1, flags);
  2747     sqlite3_bind_text(session->unset_identity_flags, 2, identity->address, -1,
  2748             SQLITE_STATIC);
  2749     sqlite3_bind_text(session->unset_identity_flags, 3, identity->user_id, -1,
  2750             SQLITE_STATIC);
  2751     result = sqlite3_step(session->unset_identity_flags);
  2752     sqlite3_reset(session->unset_identity_flags);
  2753     if (result != SQLITE_DONE)
  2754         return PEP_CANNOT_SET_IDENTITY;
  2755         identity->flags &= ~flags;
  2756 
  2757     return PEP_STATUS_OK;
  2758 }
  2759 
  2760 
  2761 PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
  2762                               const char* new_uid) {
  2763     assert(session);
  2764     assert(old_uid);
  2765     assert(new_uid);
  2766     
  2767     if (!session || !old_uid || !new_uid)
  2768         return PEP_ILLEGAL_VALUE;
  2769 
  2770 
  2771     int result;
  2772 
  2773     sqlite3_reset(session->replace_userid);
  2774     sqlite3_bind_text(session->replace_userid, 1, new_uid, -1,
  2775             SQLITE_STATIC);
  2776     sqlite3_bind_text(session->replace_userid, 2, old_uid, -1,
  2777             SQLITE_STATIC);
  2778     result = sqlite3_step(session->replace_userid);
  2779     sqlite3_reset(session->replace_userid);
  2780     if (result != SQLITE_DONE)
  2781         return PEP_CANNOT_SET_PERSON; // May need clearer retval
  2782 
  2783     return PEP_STATUS_OK;
  2784 }
  2785 
  2786 PEP_STATUS refresh_userid_default_key(PEP_SESSION session, const char* user_id) {
  2787     assert(session);
  2788     assert(user_id);
  2789     
  2790     if (!session || !user_id)
  2791         return PEP_ILLEGAL_VALUE;
  2792 
  2793     int result;
  2794 
  2795     sqlite3_reset(session->refresh_userid_default_key);
  2796     sqlite3_bind_text(session->refresh_userid_default_key, 1, user_id, -1,
  2797             SQLITE_STATIC);
  2798     result = sqlite3_step(session->refresh_userid_default_key);
  2799     sqlite3_reset(session->refresh_userid_default_key);
  2800     if (result != SQLITE_DONE)
  2801         return PEP_CANNOT_SET_PERSON;
  2802 
  2803     return PEP_STATUS_OK;    
  2804 }
  2805 
  2806 PEP_STATUS replace_main_user_fpr(PEP_SESSION session, const char* user_id,
  2807                                  const char* new_fpr) {
  2808     assert(session);
  2809     assert(user_id);
  2810     assert(new_fpr);
  2811     
  2812     if (!session || !user_id || !new_fpr)
  2813         return PEP_ILLEGAL_VALUE;
  2814 
  2815     int result;
  2816 
  2817     sqlite3_reset(session->replace_main_user_fpr);
  2818     sqlite3_bind_text(session->replace_main_user_fpr, 1, new_fpr, -1,
  2819             SQLITE_STATIC);
  2820     sqlite3_bind_text(session->replace_main_user_fpr, 2, user_id, -1,
  2821             SQLITE_STATIC);
  2822     result = sqlite3_step(session->replace_main_user_fpr);
  2823     sqlite3_reset(session->replace_main_user_fpr);
  2824     if (result != SQLITE_DONE)
  2825         return PEP_CANNOT_SET_PERSON;
  2826 
  2827     return PEP_STATUS_OK;
  2828 }
  2829 
  2830 PEP_STATUS get_main_user_fpr(PEP_SESSION session, 
  2831                              const char* user_id,
  2832                              char** main_fpr)
  2833 {
  2834     PEP_STATUS status = PEP_STATUS_OK;
  2835     int result;
  2836     
  2837     assert(session);
  2838     assert(user_id);
  2839     assert(main_fpr);
  2840     
  2841     if (!(session && user_id && user_id[0] && main_fpr))
  2842         return PEP_ILLEGAL_VALUE;
  2843         
  2844     *main_fpr = NULL;
  2845     
  2846     sqlite3_reset(session->get_main_user_fpr);
  2847     sqlite3_bind_text(session->get_main_user_fpr, 1, user_id, -1,
  2848                       SQLITE_STATIC);
  2849     result = sqlite3_step(session->get_main_user_fpr);
  2850     switch (result) {
  2851     case SQLITE_ROW: {
  2852         const char* _fpr = 
  2853             (const char *) sqlite3_column_text(session->get_main_user_fpr, 0);
  2854         if (_fpr)
  2855             *main_fpr = strdup(_fpr);
  2856         if (!(*main_fpr))
  2857             status = PEP_OUT_OF_MEMORY;
  2858         break;
  2859     }
  2860     default:
  2861         status = PEP_CANNOT_FIND_PERSON;
  2862     }
  2863 
  2864     sqlite3_reset(session->get_main_user_fpr);
  2865     return status;
  2866 }
  2867 
  2868 
  2869 DYNAMIC_API PEP_STATUS mark_as_compromized(
  2870         PEP_SESSION session,
  2871         const char *fpr
  2872     )
  2873 {
  2874     int result;
  2875 
  2876     assert(session);
  2877     assert(fpr && fpr[0]);
  2878 
  2879     if (!(session && fpr && fpr[0]))
  2880         return PEP_ILLEGAL_VALUE;
  2881 
  2882     sqlite3_reset(session->mark_compromized);
  2883     sqlite3_bind_text(session->mark_compromized, 1, fpr, -1,
  2884             SQLITE_STATIC);
  2885     result = sqlite3_step(session->mark_compromized);
  2886     sqlite3_reset(session->mark_compromized);
  2887 
  2888     if (result != SQLITE_DONE)
  2889         return PEP_CANNOT_SET_TRUST;
  2890 
  2891     return PEP_STATUS_OK;
  2892 }
  2893 
  2894 void pEp_free(void *p)
  2895 {
  2896     free(p);
  2897 }
  2898 
  2899 
  2900 DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
  2901 {
  2902     PEP_STATUS status = PEP_STATUS_OK;
  2903     int result;
  2904 
  2905     // We need to be able to test that we break correctly without shutting
  2906     // asserts off everywhere.
  2907     // assert(session);
  2908     // assert(identity);
  2909     // assert(identity->user_id);
  2910     // assert(identity->user_id[0]);
  2911     // assert(identity->fpr);
  2912     // assert(identity->fpr[0]);
  2913 
  2914     if (!(session && identity && identity->user_id && identity->user_id[0] &&
  2915                 identity->fpr && identity->fpr[0]))
  2916         return PEP_ILLEGAL_VALUE;
  2917 
  2918     identity->comm_type = PEP_ct_unknown;
  2919 
  2920     sqlite3_reset(session->get_trust);
  2921     sqlite3_bind_text(session->get_trust, 1, identity->user_id, -1,
  2922             SQLITE_STATIC);
  2923     sqlite3_bind_text(session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
  2924 
  2925     result = sqlite3_step(session->get_trust);
  2926     switch (result) {
  2927     case SQLITE_ROW: {
  2928         int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust,
  2929                 0);
  2930         identity->comm_type = comm_type;
  2931         break;
  2932     }
  2933  
  2934     default:
  2935         status = PEP_CANNOT_FIND_IDENTITY;
  2936     }
  2937 
  2938     sqlite3_reset(session->get_trust);
  2939     return status;
  2940 }
  2941 
  2942 DYNAMIC_API PEP_STATUS least_trust(
  2943         PEP_SESSION session,
  2944         const char *fpr,
  2945         PEP_comm_type *comm_type
  2946     )
  2947 {
  2948     PEP_STATUS status = PEP_STATUS_OK;
  2949     int result;
  2950 
  2951     assert(session);
  2952     assert(fpr);
  2953     assert(comm_type);
  2954 
  2955     if (!(session && fpr && comm_type))
  2956         return PEP_ILLEGAL_VALUE;
  2957 
  2958     *comm_type = PEP_ct_unknown;
  2959 
  2960     sqlite3_reset(session->least_trust);
  2961     sqlite3_bind_text(session->least_trust, 1, fpr, -1, SQLITE_STATIC);
  2962 
  2963     result = sqlite3_step(session->least_trust);
  2964     switch (result) {
  2965         case SQLITE_ROW: {
  2966             int _comm_type = sqlite3_column_int(session->least_trust, 0);
  2967             *comm_type = (PEP_comm_type) _comm_type;
  2968             break;
  2969         }
  2970         default:
  2971             // never reached because of sql min()
  2972             status = PEP_CANNOT_FIND_IDENTITY;
  2973     }
  2974 
  2975     sqlite3_reset(session->least_trust);
  2976     return status;
  2977 }
  2978 
  2979 DYNAMIC_API PEP_STATUS decrypt_and_verify(
  2980     PEP_SESSION session, const char *ctext, size_t csize,
  2981     const char *dsigtext, size_t dsigsize,
  2982     char **ptext, size_t *psize, stringlist_t **keylist
  2983     )
  2984 {
  2985     assert(session);
  2986     assert(ctext);
  2987     assert(csize);
  2988     assert(ptext);
  2989     assert(psize);
  2990     assert(keylist);
  2991 
  2992     if (!(session && ctext && csize && ptext && psize && keylist))
  2993         return PEP_ILLEGAL_VALUE;
  2994 
  2995     return session->cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify(
  2996             session, ctext, csize, dsigtext, dsigsize, ptext, psize, keylist);
  2997 }
  2998 
  2999 DYNAMIC_API PEP_STATUS encrypt_and_sign(
  3000     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  3001     size_t psize, char **ctext, size_t *csize
  3002     )
  3003 {
  3004     assert(session);
  3005     assert(keylist);
  3006     assert(ptext);
  3007     assert(psize);
  3008     assert(ctext);
  3009     assert(csize);
  3010 
  3011     if (!(session && keylist && ptext && psize && ctext && csize))
  3012         return PEP_ILLEGAL_VALUE;
  3013 
  3014     return session->cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign(session,
  3015             keylist, ptext, psize, ctext, csize);
  3016 }
  3017 
  3018 PEP_STATUS encrypt_only(
  3019     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  3020     size_t psize, char **ctext, size_t *csize
  3021     )
  3022 {
  3023     assert(session);
  3024     assert(keylist);
  3025     assert(ptext);
  3026     assert(psize);
  3027     assert(ctext);
  3028     assert(csize);
  3029 
  3030     if (!(session && keylist && ptext && psize && ctext && csize))
  3031         return PEP_ILLEGAL_VALUE;
  3032 
  3033     return session->cryptotech[PEP_crypt_OpenPGP].encrypt_only(session,
  3034             keylist, ptext, psize, ctext, csize);
  3035 }
  3036 
  3037 
  3038 DYNAMIC_API PEP_STATUS verify_text(
  3039     PEP_SESSION session, const char *text, size_t size,
  3040     const char *signature, size_t sig_size, stringlist_t **keylist
  3041     )
  3042 {
  3043     assert(session);
  3044     assert(text);
  3045     assert(size);
  3046     assert(signature);
  3047     assert(sig_size);
  3048     assert(keylist);
  3049 
  3050     if (!(session && text && size && signature && sig_size && keylist))
  3051         return PEP_ILLEGAL_VALUE;
  3052 
  3053     return session->cryptotech[PEP_crypt_OpenPGP].verify_text(session, text,
  3054             size, signature, sig_size, keylist);
  3055 }
  3056 
  3057 DYNAMIC_API PEP_STATUS delete_keypair(PEP_SESSION session, const char *fpr)
  3058 {
  3059     assert(session);
  3060     assert(fpr);
  3061 
  3062     if (!(session && fpr))
  3063         return PEP_ILLEGAL_VALUE;
  3064 
  3065     return session->cryptotech[PEP_crypt_OpenPGP].delete_keypair(session, fpr);
  3066 }
  3067 
  3068 DYNAMIC_API PEP_STATUS export_key(
  3069         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  3070     )
  3071 {
  3072     assert(session);
  3073     assert(fpr);
  3074     assert(key_data);
  3075     assert(size);
  3076 
  3077     if (!(session && fpr && key_data && size))
  3078         return PEP_ILLEGAL_VALUE;
  3079 
  3080     return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  3081             key_data, size, false);
  3082 }
  3083 
  3084 DYNAMIC_API PEP_STATUS export_secrect_key(
  3085         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  3086     )
  3087 {
  3088     assert(session);
  3089     assert(fpr);
  3090     assert(key_data);
  3091     assert(size);
  3092 
  3093     if (!(session && fpr && key_data && size))
  3094         return PEP_ILLEGAL_VALUE;
  3095 
  3096     // don't accept key IDs but full fingerprints only
  3097     if (strlen(fpr) < 16)
  3098         return PEP_ILLEGAL_VALUE;
  3099 
  3100     return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  3101             key_data, size, true);
  3102 }
  3103 
  3104 DYNAMIC_API PEP_STATUS find_keys(
  3105         PEP_SESSION session, const char *pattern, stringlist_t **keylist
  3106     )
  3107 {
  3108     assert(session);
  3109     assert(pattern);
  3110     assert(keylist);
  3111 
  3112     if (!(session && pattern && keylist))
  3113         return PEP_ILLEGAL_VALUE;
  3114 
  3115     return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern,
  3116             keylist);
  3117 }
  3118 
  3119 
  3120 DYNAMIC_API PEP_STATUS generate_keypair(
  3121         PEP_SESSION session, pEp_identity *identity
  3122     )
  3123 {
  3124     assert(session);
  3125     assert(identity);
  3126     assert(identity->address);
  3127     assert(identity->fpr == NULL || identity->fpr[0] == 0);
  3128     assert(identity->username);
  3129 
  3130     if (!(session && identity && identity->address &&
  3131             (identity->fpr == NULL || identity->fpr[0] == 0) &&
  3132             identity->username))
  3133         return PEP_ILLEGAL_VALUE;
  3134 
  3135     PEP_STATUS status =
  3136         session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session,
  3137                 identity);
  3138     if (status != PEP_STATUS_OK)
  3139         return status;
  3140 
  3141     if (identity->fpr)
  3142         status = set_pgp_keypair(session, identity->fpr);
  3143 
  3144     // add to known keypair DB, as this might not end up being a default
  3145     return status;
  3146 }
  3147 
  3148 DYNAMIC_API PEP_STATUS get_key_rating(
  3149         PEP_SESSION session,
  3150         const char *fpr,
  3151         PEP_comm_type *comm_type
  3152     )
  3153 {
  3154     assert(session);
  3155     assert(fpr);
  3156     assert(comm_type);
  3157 
  3158     if (!(session && fpr && comm_type))
  3159         return PEP_ILLEGAL_VALUE;
  3160 
  3161     return session->cryptotech[PEP_crypt_OpenPGP].get_key_rating(session, fpr,
  3162             comm_type);
  3163 }
  3164 
  3165 DYNAMIC_API PEP_STATUS import_key(
  3166         PEP_SESSION session,
  3167         const char *key_data,
  3168         size_t size,
  3169         identity_list **private_keys
  3170     )
  3171 {
  3172     assert(session);
  3173     assert(key_data);
  3174 
  3175     if (!(session && key_data))
  3176         return PEP_ILLEGAL_VALUE;
  3177 
  3178     return session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data,
  3179             size, private_keys);
  3180 }
  3181 
  3182 DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
  3183 {
  3184     assert(session);
  3185     assert(pattern);
  3186 
  3187     if (!(session && pattern))
  3188         return PEP_ILLEGAL_VALUE;
  3189 
  3190     return session->cryptotech[PEP_crypt_OpenPGP].recv_key(session, pattern);
  3191 }
  3192 
  3193 DYNAMIC_API PEP_STATUS send_key(PEP_SESSION session, const char *pattern)
  3194 {
  3195     assert(session);
  3196     assert(pattern);
  3197 
  3198     if (!(session && pattern))
  3199         return PEP_ILLEGAL_VALUE;
  3200 
  3201     return session->cryptotech[PEP_crypt_OpenPGP].send_key(session, pattern);
  3202 }
  3203 
  3204 DYNAMIC_API PEP_STATUS renew_key(
  3205         PEP_SESSION session,
  3206         const char *fpr,
  3207         const timestamp *ts
  3208     )
  3209 {
  3210     assert(session);
  3211     assert(fpr);
  3212 
  3213     if (!(session && fpr))
  3214         return PEP_ILLEGAL_VALUE;
  3215 
  3216     return session->cryptotech[PEP_crypt_OpenPGP].renew_key(session, fpr, ts);
  3217 }
  3218 
  3219 DYNAMIC_API PEP_STATUS revoke_key(
  3220         PEP_SESSION session,
  3221         const char *fpr,
  3222         const char *reason
  3223     )
  3224 {
  3225     assert(session);
  3226     assert(fpr);
  3227 
  3228     if (!(session && fpr))
  3229         return PEP_ILLEGAL_VALUE;
  3230 
  3231     return session->cryptotech[PEP_crypt_OpenPGP].revoke_key(session, fpr,
  3232             reason);
  3233 }
  3234 
  3235 DYNAMIC_API PEP_STATUS key_expired(
  3236         PEP_SESSION session,
  3237         const char *fpr,
  3238         const time_t when,
  3239         bool *expired
  3240     )
  3241 {
  3242     assert(session);
  3243     assert(fpr);
  3244     assert(expired);
  3245 
  3246     if (!(session && fpr && expired))
  3247         return PEP_ILLEGAL_VALUE;
  3248 
  3249     return session->cryptotech[PEP_crypt_OpenPGP].key_expired(session, fpr,
  3250             when, expired);
  3251 }
  3252 
  3253 DYNAMIC_API PEP_STATUS key_revoked(
  3254        PEP_SESSION session,
  3255        const char *fpr,
  3256        bool *revoked
  3257    )
  3258 {
  3259     assert(session);
  3260     assert(fpr);
  3261     assert(revoked);
  3262     
  3263     if (!(session && fpr && revoked))
  3264         return PEP_ILLEGAL_VALUE;
  3265     
  3266     return session->cryptotech[PEP_crypt_OpenPGP].key_revoked(session, fpr,
  3267             revoked);
  3268 }
  3269 
  3270 static void _clean_log_value(char *text)
  3271 {
  3272     if (text) {
  3273         for (char *c = text; *c; c++) {
  3274             if (*c < 32 && *c != '\n')
  3275                 *c = 32;
  3276             else if (*c == '"')
  3277                 *c = '\'';
  3278         }
  3279     }
  3280 }
  3281 
  3282 static char *_concat_string(char *str1, const char *str2, char delim)
  3283 {
  3284     str2 = str2 ? str2 : "";
  3285     size_t len1 = str1 ? strlen(str1) : 0;
  3286     size_t len2 = strlen(str2);
  3287     size_t len = len1 + len2 + 3;
  3288     char * result = realloc(str1, len + 1);
  3289 
  3290     if (result) {
  3291         result[len1] = '"';
  3292         strcpy(result + len1 + 1, str2);
  3293         result[len - 2] = '"';
  3294         result[len - 1] = delim;
  3295         result[len] = 0;
  3296     }
  3297     else {
  3298         free(str1);
  3299     }
  3300 
  3301     return result;
  3302 }
  3303 
  3304 DYNAMIC_API PEP_STATUS get_crashdump_log(
  3305         PEP_SESSION session,
  3306         int maxlines,
  3307         char **logdata
  3308     )
  3309 {
  3310     PEP_STATUS status = PEP_STATUS_OK;
  3311     char *_logdata= NULL;
  3312 
  3313     assert(session);
  3314     assert(maxlines >= 0 && maxlines <= CRASHDUMP_MAX_LINES);
  3315     assert(logdata);
  3316 
  3317     if (!(session && logdata && maxlines >= 0 && maxlines <=
  3318             CRASHDUMP_MAX_LINES))
  3319         return PEP_ILLEGAL_VALUE;
  3320 
  3321     *logdata = NULL;
  3322 
  3323     int limit = maxlines ? maxlines : CRASHDUMP_DEFAULT_LINES;
  3324     const char *timestamp = NULL;
  3325     const char *title = NULL;
  3326     const char *entity = NULL;
  3327     const char *desc = NULL;
  3328     const char *comment = NULL;
  3329 
  3330     sqlite3_reset(session->crashdump);
  3331     sqlite3_bind_int(session->crashdump, 1, limit);
  3332 
  3333     int result;
  3334 
  3335     do {
  3336         result = sqlite3_step(session->crashdump);
  3337         switch (result) {
  3338         case SQLITE_ROW:
  3339             timestamp = (const char *) sqlite3_column_text(session->crashdump,
  3340                     0);
  3341             title   = (const char *) sqlite3_column_text(session->crashdump,
  3342                     1);
  3343             entity  = (const char *) sqlite3_column_text(session->crashdump,
  3344                     2);
  3345             desc    = (const char *) sqlite3_column_text(session->crashdump,
  3346                     3);
  3347             comment = (const char *) sqlite3_column_text(session->crashdump,
  3348                     4);
  3349 
  3350             _logdata = _concat_string(_logdata, timestamp, ',');
  3351             if (_logdata == NULL)
  3352                 goto enomem;
  3353 
  3354             _logdata = _concat_string(_logdata, title, ',');
  3355             if (_logdata == NULL)
  3356                 goto enomem;
  3357 
  3358             _logdata = _concat_string(_logdata, entity, ',');
  3359             if (_logdata == NULL)
  3360                 goto enomem;
  3361 
  3362             _logdata = _concat_string(_logdata, desc, ',');
  3363             if (_logdata == NULL)
  3364                 goto enomem;
  3365 
  3366             _logdata = _concat_string(_logdata, comment, '\n');
  3367             if (_logdata == NULL)
  3368                 goto enomem;
  3369 
  3370             _clean_log_value(_logdata);
  3371             break;
  3372 
  3373         case SQLITE_DONE:
  3374             break;
  3375 
  3376         default:
  3377             status = PEP_UNKNOWN_ERROR;
  3378             result = SQLITE_DONE;
  3379         }
  3380     } while (result != SQLITE_DONE);
  3381 
  3382     sqlite3_reset(session->crashdump);
  3383     if (status == PEP_STATUS_OK)
  3384         *logdata = _logdata;
  3385 
  3386     goto the_end;
  3387 
  3388 enomem:
  3389     status = PEP_OUT_OF_MEMORY;
  3390 
  3391 the_end:
  3392     return status;
  3393 }
  3394 
  3395 DYNAMIC_API PEP_STATUS get_languagelist(
  3396         PEP_SESSION session,
  3397         char **languages
  3398     )
  3399 {
  3400     PEP_STATUS status = PEP_STATUS_OK;
  3401     char *_languages= NULL;
  3402 
  3403     assert(session);
  3404     assert(languages);
  3405 
  3406     if (!(session && languages))
  3407         return PEP_ILLEGAL_VALUE;
  3408 
  3409     *languages = NULL;
  3410 
  3411     const char *lang = NULL;
  3412     const char *name = NULL;
  3413     const char *phrase = NULL;
  3414 
  3415     sqlite3_reset(session->languagelist);
  3416 
  3417     int result;
  3418 
  3419     do {
  3420         result = sqlite3_step(session->languagelist);
  3421         switch (result) {
  3422         case SQLITE_ROW:
  3423             lang = (const char *) sqlite3_column_text(session->languagelist,
  3424                     0);
  3425             name = (const char *) sqlite3_column_text(session->languagelist,
  3426                     1);
  3427             phrase = (const char *) sqlite3_column_text(session->languagelist,
  3428                     2);
  3429 
  3430             _languages = _concat_string(_languages, lang, ',');
  3431             if (_languages == NULL)
  3432                 goto enomem;
  3433 
  3434             _languages = _concat_string(_languages, name, ',');
  3435             if (_languages == NULL)
  3436                 goto enomem;
  3437 
  3438             _languages = _concat_string(_languages, phrase, '\n');
  3439             if (_languages == NULL)
  3440                 goto enomem;
  3441 
  3442             break;
  3443 
  3444         case SQLITE_DONE:
  3445             break;
  3446 
  3447         default:
  3448             status = PEP_UNKNOWN_ERROR;
  3449             result = SQLITE_DONE;
  3450         }
  3451     } while (result != SQLITE_DONE);
  3452 
  3453     sqlite3_reset(session->languagelist);
  3454     if (status == PEP_STATUS_OK)
  3455         *languages = _languages;
  3456 
  3457     goto the_end;
  3458 
  3459 enomem:
  3460     status = PEP_OUT_OF_MEMORY;
  3461 
  3462 the_end:
  3463     return status;
  3464 }
  3465 
  3466 DYNAMIC_API PEP_STATUS get_phrase(
  3467         PEP_SESSION session,
  3468         const char *lang,
  3469         int phrase_id,
  3470         char **phrase
  3471     )
  3472 {
  3473     PEP_STATUS status = PEP_STATUS_OK;
  3474 
  3475     assert(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase);
  3476     if (!(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase))
  3477         return PEP_ILLEGAL_VALUE;
  3478 
  3479     *phrase = NULL;
  3480 
  3481     sqlite3_reset(session->i18n_token);
  3482     sqlite3_bind_text(session->i18n_token, 1, lang, -1, SQLITE_STATIC);
  3483     sqlite3_bind_int(session->i18n_token, 2, phrase_id);
  3484 
  3485     const char *_phrase = NULL;
  3486     int result;
  3487 
  3488     result = sqlite3_step(session->i18n_token);
  3489     switch (result) {
  3490     case SQLITE_ROW:
  3491         _phrase = (const char *) sqlite3_column_text(session->i18n_token, 0);
  3492         break;
  3493 
  3494     case SQLITE_DONE:
  3495         status = PEP_PHRASE_NOT_FOUND;
  3496         break;
  3497 
  3498     default:
  3499         status = PEP_UNKNOWN_ERROR;
  3500     }
  3501 
  3502     if (status == PEP_STATUS_OK) {
  3503         *phrase = strdup(_phrase);
  3504         if (*phrase == NULL)
  3505             goto enomem;
  3506     }
  3507 
  3508     sqlite3_reset(session->i18n_token);
  3509     goto the_end;
  3510 
  3511 enomem:
  3512     status = PEP_OUT_OF_MEMORY;
  3513 
  3514 the_end:
  3515     return status;
  3516 }
  3517 
  3518 static PEP_STATUS _get_sequence_value(PEP_SESSION session, const char *name,
  3519         int32_t *value)
  3520 {
  3521     assert(session && name && value);
  3522     if (!(session && name && value))
  3523         return PEP_ILLEGAL_VALUE;
  3524 
  3525     PEP_STATUS status = PEP_STATUS_OK;
  3526 
  3527     sqlite3_reset(session->sequence_value2);
  3528     sqlite3_bind_text(session->sequence_value2, 1, name, -1,
  3529             SQLITE_STATIC);
  3530     int result = sqlite3_step(session->sequence_value2);
  3531     switch (result) {
  3532         case SQLITE_ROW: {
  3533             int32_t _value = (int32_t)
  3534                     sqlite3_column_int(session->sequence_value2, 0);
  3535             int _own = (int)
  3536                     sqlite3_column_int(session->sequence_value2, 1);
  3537             *value = _value;
  3538             if (_own)
  3539                 status = PEP_OWN_SEQUENCE;
  3540             break;
  3541         }
  3542         case SQLITE_DONE:
  3543             status = PEP_RECORD_NOT_FOUND;
  3544             break;
  3545         default:
  3546             status = PEP_UNKNOWN_ERROR;
  3547     }
  3548     sqlite3_reset(session->sequence_value2);
  3549 
  3550     return status;
  3551 }
  3552 
  3553 static PEP_STATUS _increment_sequence_value(PEP_SESSION session,
  3554         const char *name, int own)
  3555 {
  3556     assert(session && name);
  3557     if (!(session && name))
  3558         return PEP_ILLEGAL_VALUE;
  3559 
  3560     sqlite3_reset(session->sequence_value1);
  3561     sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
  3562     sqlite3_bind_int(session->sequence_value1, 2, own);
  3563     int result = sqlite3_step(session->sequence_value1);
  3564     assert(result == SQLITE_DONE);
  3565     sqlite3_reset(session->sequence_value1);
  3566     if (result == SQLITE_DONE)
  3567         return PEP_STATUS_OK;
  3568     else
  3569         return PEP_CANNOT_INCREASE_SEQUENCE;
  3570 }
  3571 
  3572 static PEP_STATUS _set_sequence_value(PEP_SESSION session,
  3573         const char *name, int32_t value, int own)
  3574 {
  3575     assert(session && name && value > 0);
  3576     if (!(session && name && value > 0))
  3577         return PEP_ILLEGAL_VALUE;
  3578 
  3579     sqlite3_reset(session->sequence_value3);
  3580     sqlite3_bind_text(session->sequence_value3, 1, name, -1, SQLITE_STATIC);
  3581     sqlite3_bind_int(session->sequence_value3, 2, value);
  3582     sqlite3_bind_int(session->sequence_value3, 3, own);
  3583     int result = sqlite3_step(session->sequence_value3);
  3584     assert(result == SQLITE_DONE);
  3585     sqlite3_reset(session->sequence_value3);
  3586     if (result == SQLITE_DONE)
  3587         return PEP_STATUS_OK;
  3588     else
  3589         return PEP_CANNOT_SET_SEQUENCE_VALUE;
  3590 }
  3591 
  3592 DYNAMIC_API PEP_STATUS sequence_value(
  3593         PEP_SESSION session,
  3594         char *name,
  3595         int32_t *value
  3596     )
  3597 {
  3598     PEP_STATUS status = PEP_STATUS_OK;
  3599     int result;
  3600 
  3601     assert(session);
  3602     assert(name && value && *value >= 0);
  3603 
  3604     if (!(session && name && value && *value >= 0))
  3605         return PEP_ILLEGAL_VALUE;
  3606 
  3607     int own = 0;
  3608     if (!name[0]) {
  3609         pEpUUID uuid;
  3610         uuid_generate_random(uuid);
  3611         uuid_unparse_upper(uuid, name);
  3612         own = 1;
  3613     }
  3614     else {
  3615         if (name == session->sync_session->sync_uuid || 
  3616             strcmp(name, session->sync_session->sync_uuid) == 0)
  3617             own = 1;
  3618     }
  3619 
  3620     if (*value) {
  3621         sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  3622         int32_t old_value = 0;
  3623         status = _get_sequence_value(session, name, &old_value);
  3624         if (status != PEP_STATUS_OK && status != PEP_RECORD_NOT_FOUND)
  3625         {
  3626             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3627             return status;
  3628         }
  3629 
  3630         if (old_value >= *value) {
  3631             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3632             return PEP_SEQUENCE_VIOLATED;
  3633         }
  3634         else {
  3635             status = _set_sequence_value(session, name, *value, own);
  3636             if (status == PEP_STATUS_OK) {
  3637                 result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  3638                 if (result == SQLITE_OK)
  3639                     return PEP_STATUS_OK;
  3640                 else
  3641                     return PEP_COMMIT_FAILED;
  3642             } else {
  3643                 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3644                 return status;
  3645             }
  3646         }
  3647     }
  3648 
  3649     assert(*value == 0);
  3650     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  3651     status = _increment_sequence_value(session, name, own);
  3652     if (status == PEP_STATUS_OK) {
  3653         status = _get_sequence_value(session, name, value);
  3654     }
  3655     if (status == PEP_STATUS_OK || status == PEP_OWN_SEQUENCE) {
  3656         result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  3657         if (result == SQLITE_OK){
  3658             assert(*value < INT32_MAX);
  3659             if (*value == INT32_MAX){
  3660                 return PEP_CANNOT_INCREASE_SEQUENCE;
  3661             }
  3662             return status;
  3663         } else {
  3664             return PEP_COMMIT_FAILED;
  3665         }
  3666     } else {
  3667         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3668         return status;
  3669     }
  3670     return status;
  3671 }
  3672 
  3673 DYNAMIC_API PEP_STATUS set_revoked(
  3674        PEP_SESSION session,
  3675        const char *revoked_fpr,
  3676        const char *replacement_fpr,
  3677        const uint64_t revocation_date
  3678     )
  3679 {
  3680     PEP_STATUS status = PEP_STATUS_OK;
  3681     
  3682     assert(session &&
  3683            revoked_fpr && revoked_fpr[0] &&
  3684            replacement_fpr && replacement_fpr[0]
  3685           );
  3686     
  3687     if (!(session &&
  3688           revoked_fpr && revoked_fpr[0] &&
  3689           replacement_fpr && replacement_fpr[0]
  3690          ))
  3691         return PEP_ILLEGAL_VALUE;
  3692     
  3693     sqlite3_reset(session->set_revoked);
  3694     sqlite3_bind_text(session->set_revoked, 1, revoked_fpr, -1, SQLITE_STATIC);
  3695     sqlite3_bind_text(session->set_revoked, 2, replacement_fpr, -1,
  3696             SQLITE_STATIC);
  3697     sqlite3_bind_int64(session->set_revoked, 3, revocation_date);
  3698 
  3699     int result;
  3700     
  3701     result = sqlite3_step(session->set_revoked);
  3702     switch (result) {
  3703         case SQLITE_DONE:
  3704             status = PEP_STATUS_OK;
  3705             break;
  3706             
  3707         default:
  3708             status = PEP_UNKNOWN_ERROR;
  3709     }
  3710     
  3711     sqlite3_reset(session->set_revoked);
  3712     return status;
  3713 }
  3714 
  3715 DYNAMIC_API PEP_STATUS get_revoked(
  3716         PEP_SESSION session,
  3717         const char *fpr,
  3718         char **revoked_fpr,
  3719         uint64_t *revocation_date
  3720     )
  3721 {
  3722     PEP_STATUS status = PEP_STATUS_OK;
  3723 
  3724     assert(session &&
  3725            revoked_fpr &&
  3726            fpr && fpr[0]
  3727           );
  3728     
  3729     if (!(session &&
  3730            revoked_fpr &&
  3731            fpr && fpr[0]
  3732           ))
  3733         return PEP_ILLEGAL_VALUE;
  3734 
  3735     *revoked_fpr = NULL;
  3736     *revocation_date = 0;
  3737 
  3738     sqlite3_reset(session->get_revoked);
  3739     sqlite3_bind_text(session->get_revoked, 1, fpr, -1, SQLITE_STATIC);
  3740 
  3741     int result;
  3742     
  3743     result = sqlite3_step(session->get_revoked);
  3744     switch (result) {
  3745         case SQLITE_ROW: {
  3746             *revoked_fpr = strdup((const char *)
  3747                     sqlite3_column_text(session->get_revoked, 0));
  3748             if(*revoked_fpr)
  3749                 *revocation_date = sqlite3_column_int64(session->get_revoked,
  3750                         1);
  3751             else
  3752                 status = PEP_OUT_OF_MEMORY;
  3753 
  3754             break;
  3755         }
  3756         default:
  3757             status = PEP_CANNOT_FIND_IDENTITY;
  3758     }
  3759 
  3760     sqlite3_reset(session->get_revoked);
  3761 
  3762     return status;
  3763 }
  3764 
  3765 PEP_STATUS key_created(
  3766         PEP_SESSION session,
  3767         const char *fpr,
  3768         time_t *created
  3769     )
  3770 {
  3771     assert(session && fpr && created);
  3772     if (!(session && fpr && created))
  3773         return PEP_ILLEGAL_VALUE;
  3774 
  3775     return session->cryptotech[PEP_crypt_OpenPGP].key_created(session, fpr,
  3776             created);
  3777 }
  3778 
  3779 PEP_STATUS find_private_keys(PEP_SESSION session, const char* pattern,
  3780                              stringlist_t **keylist) {
  3781     assert(session && keylist);
  3782     if (!(session && keylist))
  3783         return PEP_ILLEGAL_VALUE;
  3784     
  3785     return session->cryptotech[PEP_crypt_OpenPGP].find_private_keys(session, pattern,
  3786                                                                     keylist);
  3787 }
  3788 
  3789 PEP_STATUS import_trusted_own_keys(PEP_SESSION session) {
  3790     assert(session);
  3791     if (!session)
  3792         return PEP_ILLEGAL_VALUE;
  3793         
  3794     return session->cryptotech[PEP_crypt_OpenPGP].import_trusted_own_keys(session); 
  3795 }
  3796 
  3797 DYNAMIC_API const char* get_engine_version() {
  3798     return PEP_ENGINE_VERSION;
  3799 }
  3800 
  3801 
  3802 DYNAMIC_API PEP_STATUS reset_peptest_hack(PEP_SESSION session)
  3803 {
  3804     assert(session);
  3805 
  3806     if (!session)
  3807         return PEP_ILLEGAL_VALUE;
  3808 
  3809     int int_result = sqlite3_exec(
  3810         session->db,
  3811         "delete from identity where address like '%@peptest.ch' ;",
  3812         NULL,
  3813         NULL,
  3814         NULL
  3815     );
  3816     assert(int_result == SQLITE_OK);
  3817 
  3818     if (int_result != SQLITE_OK)
  3819         return PEP_UNKNOWN_ERROR;
  3820 
  3821     return PEP_STATUS_OK;
  3822 }
  3823 
  3824 #ifdef DEBUG_ERRORSTACK
  3825 PEP_STATUS session_add_error(PEP_SESSION session, const char* file, unsigned line, PEP_STATUS status)
  3826 {
  3827     char logline[48];
  3828     if(status>0)
  3829     {
  3830         snprintf(logline,47, "%.24s:%u status=%u (0x%x)", file, line, status, status);
  3831     }else{
  3832         snprintf(logline,47, "%.24s:%u status=%i.", file, line, status);
  3833     }
  3834     stringlist_add(session->errorstack, logline); // logline is copied! :-)
  3835     return status;
  3836 }
  3837 
  3838 DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  3839 {
  3840     return session->errorstack;
  3841 }
  3842 
  3843 DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  3844 {
  3845     const int old_len = stringlist_length(session->errorstack);
  3846     char buf[48];
  3847     free_stringlist(session->errorstack);
  3848     snprintf(buf, 47, "(%i elements cleared)", old_len);
  3849     session->errorstack = new_stringlist(buf);
  3850 }
  3851 
  3852 #else
  3853 
  3854 static stringlist_t* dummy_errorstack = NULL;
  3855 
  3856 DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  3857 {
  3858     if(dummy_errorstack == NULL)
  3859     {
  3860         dummy_errorstack = new_stringlist("( Please recompile pEpEngine with -DDEBUG_ERRORSTACK )");
  3861     }
  3862 
  3863     return dummy_errorstack;
  3864 }
  3865 
  3866 DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  3867 {
  3868     // nothing to do here
  3869 }
  3870 
  3871 #endif