src/pEp_internal.h
author Krista Bennett <krista@pep-project.org>
Fri, 02 Feb 2018 11:03:20 +0100
branchENGINE-352
changeset 2468 3a10b4f8ba41
parent 2462 48b526a0daac
child 2473 6ca62f99148e
permissions -rw-r--r--
ENGINE-352: put in the mechanism to attach an is_pep mechanism for the user; tacking pEp messages is complicated, however, as it seems we've also always fouled up when we checked on that (we don't check what key it's encrypted with before we declare whatever key gets retrieved by update_identity is the same, and then set the comm_type on that, which could be the wrong key.) So that's the next fix.
vb@1517
     1
// This file is under GNU General Public License 3.0
vb@1517
     2
// see LICENSE.txt
vb@1517
     3
krista@2150
     4
#define PEP_ENGINE_VERSION "0.9.0"
vb@908
     5
vb@908
     6
// maximum attachment size to import as key 1MB, maximum of 20 attachments
vb@908
     7
vb@908
     8
#define MAX_KEY_SIZE (1024 * 1024)
vb@908
     9
#define MAX_KEYS_TO_IMPORT  20
vb@24
    10
vb@233
    11
// this is 20 trustwords with 79 chars max
vb@251
    12
#define MAX_TRUSTWORDS_SPACE (20 * 80)
vb@24
    13
vb@24
    14
// XML parameters string
vb@24
    15
#define PARMS_MAX 32768
vb@24
    16
vb@24
    17
// maximum busy wait time in ms
vb@24
    18
#define BUSY_WAIT_TIME 5000
vb@24
    19
vb@24
    20
// maximum line length for reading gpg.conf
vb@24
    21
#define MAX_LINELENGTH 1024
vb@24
    22
vb@24
    23
// default keyserver
vb@450
    24
#ifndef DEFAULT_KEYSERVER
vb@24
    25
#define DEFAULT_KEYSERVER "hkp://keys.gnupg.net"
vb@450
    26
#endif
vb@450
    27
vb@450
    28
// crashdump constants
vb@450
    29
#ifndef CRASHDUMP_DEFAULT_LINES
vb@450
    30
#define CRASHDUMP_DEFAULT_LINES 100
vb@450
    31
#endif
vb@450
    32
#define CRASHDUMP_MAX_LINES 32767
vb@24
    33
krista@2045
    34
// p≡p full string, NUL-terminated
krista@2045
    35
#ifndef PEP_SUBJ_STRING
krista@2045
    36
#define PEP_SUBJ_STRING {0x70,0xE2,0x89,0xA1,0x70,0x00}
krista@2045
    37
#define PEP_SUBJ_BYTELEN 5
krista@2045
    38
#endif
krista@2045
    39
krista@2078
    40
#ifndef PEP_SUBJ_KEY
krista@2078
    41
#define PEP_SUBJ_KEY "Subject: "
krista@2078
    42
#define PEP_SUBJ_KEY_LC "subject: "
krista@2078
    43
#define PEP_SUBJ_KEY_LEN 9
krista@2078
    44
#endif
krista@2078
    45
krista@2120
    46
#ifndef PEP_MSG_WRAP_KEY
krista@2120
    47
#define PEP_MSG_WRAP_KEY "pEp-Wrapped-Message-Info: "
krista@2120
    48
#define PEP_MSG_WRAP_KEY_LC "pep-wrapped-message-info: "
krista@2120
    49
#define PEP_MSG_WRAP_KEY_LEN 26
krista@2078
    50
#endif
krista@2078
    51
krista@2078
    52
vb@130
    53
#include "platform.h"
vb@130
    54
vb@24
    55
#ifdef WIN32
vb@24
    56
#define LOCAL_DB windoze_local_db()
vb@24
    57
#define SYSTEM_DB windoze_system_db()
vb@24
    58
#define LIBGPGME "libgpgme-11.dll"
vb@24
    59
#else // UNIX
vb@24
    60
#define _POSIX_C_SOURCE 200809L
vb@24
    61
#include <dlfcn.h>
vb@24
    62
#define LOCAL_DB unix_local_db()
vb@24
    63
#ifndef SYSTEM_DB
vb@24
    64
#define SYSTEM_DB "/usr/share/pEp/system.db"
vb@24
    65
#endif
vb@24
    66
#ifndef LIBGPGME
vb@24
    67
#define LIBGPGME "libgpgme-pthread.so"
vb@24
    68
#endif
vb@24
    69
#endif
vb@24
    70
vb@24
    71
#include <locale.h>
vb@24
    72
#include <stdlib.h>
vb@24
    73
#include <string.h>
vb@24
    74
#include <assert.h>
vb@24
    75
#include <stdio.h>
edouard@1521
    76
#include <ctype.h>
krista@2176
    77
#include <math.h>
vb@24
    78
damiano@1997
    79
#ifdef SQLITE3_FROM_OS
damiano@1997
    80
#include <sqlite3.h>
damiano@1997
    81
#else
vb@24
    82
#include "sqlite3.h"
damiano@1997
    83
#endif
vb@24
    84
vb@24
    85
#include "pEpEngine.h"
Edouard@168
    86
Edouard@168
    87
// If not specified, build for GPG
Edouard@168
    88
#ifndef USE_NETPGP
Edouard@168
    89
#ifndef USE_GPG
Edouard@168
    90
#define USE_GPG
Edouard@168
    91
#endif
Edouard@168
    92
#endif
Edouard@168
    93
Edouard@168
    94
#ifdef USE_GPG
vb@24
    95
#include "pgp_gpg_internal.h"
vb@229
    96
#elif defined(USE_NETPGP)
Edouard@168
    97
#include "pgp_netpgp_internal.h"
vb@24
    98
#endif
vb@24
    99
vb@292
   100
#include "keymanagement.h"
vb@28
   101
#include "cryptotech.h"
vb@28
   102
#include "transport.h"
krista@2271
   103
#include "sync.h"
vb@28
   104
vb@125
   105
#define NOT_IMPLEMENTED assert(0); return PEP_UNKNOWN_ERROR;
vb@24
   106
edouard@1603
   107
struct _pEpSession;
edouard@1603
   108
typedef struct _pEpSession pEpSession;
edouard@1603
   109
struct _pEpSession {
vb@24
   110
    const char *version;
Edouard@168
   111
#ifdef USE_GPG
vb@24
   112
    gpgme_ctx_t ctx;
vb@229
   113
#elif defined(USE_NETPGP)
Edouard@252
   114
    pEpNetPGPSession ctx;
vb@24
   115
#endif
vb@24
   116
vb@62
   117
    PEP_cryptotech_t *cryptotech;
vb@62
   118
    PEP_transport_t *transports;
vb@28
   119
vb@24
   120
    sqlite3 *db;
vb@24
   121
    sqlite3 *system_db;
vb@24
   122
vb@24
   123
    sqlite3_stmt *log;
vb@233
   124
    sqlite3_stmt *trustword;
vb@24
   125
    sqlite3_stmt *get_identity;
krista@2461
   126
    sqlite3_stmt *get_identity_without_trust_check;
krista@2461
   127
    sqlite3_stmt *get_identities_by_address;
krista@1799
   128
    sqlite3_stmt *replace_identities_fpr;
krista@2461
   129
    sqlite3_stmt *replace_main_user_fpr;
krista@2461
   130
    sqlite3_stmt *get_main_user_fpr;
krista@2461
   131
    sqlite3_stmt *refresh_userid_default_key;
krista@2461
   132
    sqlite3_stmt *remove_fpr_as_default;
vb@24
   133
    sqlite3_stmt *set_person;
krista@2468
   134
    sqlite3_stmt *set_as_pep_user;
krista@2468
   135
    sqlite3_stmt *is_pep_user;
krista@2468
   136
    sqlite3_stmt *exists_person;
edouard@1234
   137
    sqlite3_stmt *set_device_group;
edouard@1235
   138
    sqlite3_stmt *get_device_group;
vb@24
   139
    sqlite3_stmt *set_pgp_keypair;
vb@24
   140
    sqlite3_stmt *set_identity;
vb@932
   141
    sqlite3_stmt *set_identity_flags;
edouard@1394
   142
    sqlite3_stmt *unset_identity_flags;
vb@24
   143
    sqlite3_stmt *set_trust;
krista@1799
   144
    sqlite3_stmt *update_trust_for_fpr;
vb@24
   145
    sqlite3_stmt *get_trust;
vb@251
   146
    sqlite3_stmt *least_trust;
vb@357
   147
    sqlite3_stmt *mark_compromized;
Edouard@409
   148
    sqlite3_stmt *reset_trust;
vb@450
   149
    sqlite3_stmt *crashdump;
vb@458
   150
    sqlite3_stmt *languagelist;
vb@458
   151
    sqlite3_stmt *i18n_token;
krista@2461
   152
    sqlite3_stmt *replace_userid;
fdik@494
   153
fdik@494
   154
    // blacklist
fdik@494
   155
    sqlite3_stmt *blacklist_add;
fdik@494
   156
    sqlite3_stmt *blacklist_delete;
fdik@494
   157
    sqlite3_stmt *blacklist_is_listed;
fdik@494
   158
    sqlite3_stmt *blacklist_retrieve;
Edouard@584
   159
    
Edouard@584
   160
    // Own keys
Edouard@584
   161
    sqlite3_stmt *own_key_is_listed;
vb@955
   162
    sqlite3_stmt *own_identities_retrieve;
edouard@1394
   163
    sqlite3_stmt *own_keys_retrieve;
krista@2461
   164
    sqlite3_stmt *get_user_default_key;
krista@2461
   165
        
krista@2461
   166
    sqlite3_stmt *get_default_own_userid;
krista@2461
   167
krista@2461
   168
//    sqlite3_stmt *set_own_key;
vb@292
   169
vb@632
   170
    // sequence value
vb@633
   171
    sqlite3_stmt *sequence_value1;
vb@633
   172
    sqlite3_stmt *sequence_value2;
vb@1085
   173
    sqlite3_stmt *sequence_value3;
vb@632
   174
edouard@1236
   175
    // revoked keys
Edouard@693
   176
    sqlite3_stmt *set_revoked;
Edouard@693
   177
    sqlite3_stmt *get_revoked;
Edouard@693
   178
krista@2461
   179
    // aliases
krista@2461
   180
    sqlite3_stmt *get_userid_alias_default;
krista@2461
   181
    sqlite3_stmt *add_userid_alias;
krista@2461
   182
Edouard@693
   183
    // callbacks
vb@292
   184
    examine_identity_t examine_identity;
vb@292
   185
    void *examine_management;
edouard@1462
   186
    void *sync_management;
vb@599
   187
    void *sync_obj;
krista@2271
   188
    messageToSend_t messageToSend;
krista@2271
   189
    notifyHandshake_t notifyHandshake;
krista@2271
   190
    inject_sync_msg_t inject_sync_msg;
krista@2271
   191
    retrieve_next_sync_msg_t retrieve_next_sync_msg;
vb@464
   192
edouard@1236
   193
    // key sync
edouard@1603
   194
    pEpSession* sync_session;
krista@2271
   195
    DeviceState_state sync_state;
edouard@1460
   196
    void* sync_state_payload;
edouard@1236
   197
    char sync_uuid[37];
edouard@1316
   198
    time_t LastCannotDecrypt;
edouard@1316
   199
    time_t LastUpdateRequest;
vb@690
   200
vb@464
   201
    // runtime config
vb@464
   202
vb@464
   203
    bool passive_mode;
vb@464
   204
    bool unencrypted_subject;
vb@1110
   205
    bool keep_sync_msg;
vb@1819
   206
    bool service_log;
krista@2129
   207
krista@2129
   208
    // mistrust undo cache
krista@2129
   209
    pEp_identity* cached_mistrusted;
Edouard@720
   210
    
roker@1722
   211
#ifdef DEBUG_ERRORSTACK
roker@1722
   212
    stringlist_t* errorstack;
roker@1722
   213
#endif
edouard@1603
   214
};
vb@48
   215
roker@1722
   216
vb@62
   217
PEP_STATUS init_transport_system(PEP_SESSION session, bool in_first);
vb@62
   218
void release_transport_system(PEP_SESSION session, bool out_last);
vb@48
   219
krista@1639
   220
/* NOT to be exposed to the outside!!! */
krista@1639
   221
PEP_STATUS encrypt_only(
krista@1639
   222
        PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
krista@1639
   223
        size_t psize, char **ctext, size_t *csize
krista@1639
   224
);
krista@1639
   225
krista@2047
   226
#if defined(NDEBUG) || defined(NOLOG)
vb@216
   227
#define DEBUG_LOG(TITLE, ENTITY, DESC)
vb@216
   228
#else
huss@1571
   229
#ifdef ANDROID
huss@1571
   230
#include <android/log.h>
vb@1819
   231
#define  LOG_MORE(...)  __android_log_print(ANDROID_LOG_DEBUG, "pEpEngine", " %s :: %s :: %s :: %s ", __VA_ARGS__);
edouard@1630
   232
#else
edouard@1630
   233
#include <stdio.h>
vb@1819
   234
#define  LOG_MORE(...)  fprintf(stderr, "pEpEngine DEBUG_LOG('%s','%s','%s','%s')\n", __VA_ARGS__);
huss@1571
   235
#endif
edouard@1630
   236
#define DEBUG_LOG(TITLE, ENTITY, DESC) {\
vb@1819
   237
    log_event(session, (TITLE), (ENTITY), (DESC), "debug " __FILE__ ":" S_LINE);\
vb@1819
   238
    LOG_MORE((TITLE), (ENTITY), (DESC), __FILE__ ":" S_LINE)\
edouard@1630
   239
}
vb@216
   240
#endif
vb@216
   241
edouard@1746
   242
typedef enum _normalize_hex_rest_t {
edouard@1746
   243
    accept_hex,
edouard@1746
   244
    ignore_hex,
edouard@1746
   245
    reject_hex
edouard@1746
   246
} normalize_hex_res_t;
edouard@1746
   247
edouard@1746
   248
static inline normalize_hex_res_t _normalize_hex(char *hex) 
edouard@1746
   249
{
edouard@1746
   250
    if (*hex >= '0' && *hex <= '9')
edouard@1746
   251
        return accept_hex;
edouard@1746
   252
edouard@1746
   253
    if (*hex >= 'A' && *hex <= 'F') {
edouard@1746
   254
        *hex += 'a' - 'A';
edouard@1746
   255
        return accept_hex;
edouard@1746
   256
    }
edouard@1746
   257
edouard@1746
   258
    if (*hex >= 'a' && *hex <= 'f') 
edouard@1746
   259
        return accept_hex;
edouard@1746
   260
edouard@1746
   261
    if (*hex == ' ') 
edouard@1746
   262
        return ignore_hex;
edouard@1746
   263
edouard@1746
   264
    return reject_hex;
edouard@1746
   265
}
edouard@1746
   266
edouard@1521
   267
// Space tolerant and case insensitive fingerprint string compare
edouard@1746
   268
static inline PEP_STATUS _compare_fprs(
edouard@1746
   269
        const char* fpra,
edouard@1746
   270
        size_t fpras,
edouard@1746
   271
        const char* fprb,
edouard@1746
   272
        size_t fprbs,
edouard@1746
   273
        int* comparison)
edouard@1746
   274
{
edouard@1746
   275
edouard@1746
   276
    size_t ai = 0;
edouard@1746
   277
    size_t bi = 0;
edouard@1746
   278
    size_t significant = 0;
edouard@1746
   279
    int _comparison = 0;
edouard@1746
   280
    const int _FULL_FINGERPRINT_LENGTH = 40;
edouard@1746
   281
   
edouard@1746
   282
    // First compare every non-ignored chars until an end is reached
edouard@1746
   283
    while(ai < fpras && bi < fprbs)
edouard@1746
   284
    {
edouard@1746
   285
        char fprac = fpra[ai];
edouard@1746
   286
        char fprbc = fprb[bi];
edouard@1746
   287
        normalize_hex_res_t fprah = _normalize_hex(&fprac);
edouard@1746
   288
        normalize_hex_res_t fprbh = _normalize_hex(&fprbc);
edouard@1746
   289
edouard@1746
   290
        if(fprah == reject_hex || fprbh == reject_hex)
edouard@1746
   291
            return PEP_ILLEGAL_VALUE;
edouard@1746
   292
edouard@1746
   293
        if ( fprah == ignore_hex )
edouard@1746
   294
        {
edouard@1746
   295
            ai++;
edouard@1746
   296
        }
edouard@1746
   297
        else if ( fprbh == ignore_hex )
edouard@1746
   298
        {
edouard@1746
   299
            bi++;
edouard@1746
   300
        }
edouard@1746
   301
        else
edouard@1746
   302
        {
edouard@1746
   303
            if(fprac != fprbc && _comparison == 0 )
edouard@1746
   304
            {
edouard@1746
   305
                _comparison = fprac > fprbc ? 1 : -1;
edouard@1746
   306
            }
edouard@1746
   307
edouard@1746
   308
            significant++;
edouard@1746
   309
            ai++;
edouard@1746
   310
            bi++;
edouard@1746
   311
edouard@1746
   312
        } 
edouard@1746
   313
    }
edouard@1746
   314
edouard@1746
   315
    // Bail out if we didn't got enough significnt chars
edouard@1746
   316
    if (significant != _FULL_FINGERPRINT_LENGTH )
edouard@1746
   317
        return PEP_TRUSTWORDS_FPR_WRONG_LENGTH;
edouard@1746
   318
edouard@1746
   319
    // Then purge remaining chars, all must be ignored chars
edouard@1746
   320
    while ( ai < fpras )
edouard@1746
   321
    {
edouard@1746
   322
        char fprac = fpra[ai];
edouard@1746
   323
        normalize_hex_res_t fprah = _normalize_hex(&fprac);
edouard@1746
   324
        if( fprah == reject_hex )
edouard@1746
   325
            return PEP_ILLEGAL_VALUE;
edouard@1746
   326
        if ( fprah != ignore_hex )
edouard@1746
   327
            return PEP_TRUSTWORDS_FPR_WRONG_LENGTH;
edouard@1746
   328
        ai++;
edouard@1746
   329
    }
edouard@1746
   330
    while ( bi < fprbs )
edouard@1746
   331
    {
edouard@1746
   332
        char fprbc = fprb[bi];
edouard@1746
   333
        normalize_hex_res_t fprbh = _normalize_hex(&fprbc);
edouard@1746
   334
        if( fprbh == reject_hex )
edouard@1746
   335
            return PEP_ILLEGAL_VALUE;
edouard@1746
   336
        if ( fprbh != ignore_hex )
edouard@1746
   337
            return PEP_TRUSTWORDS_FPR_WRONG_LENGTH;
edouard@1746
   338
        bi++;
edouard@1746
   339
    }
edouard@1746
   340
edouard@1746
   341
    *comparison = _comparison;
edouard@1746
   342
    return PEP_STATUS_OK;
edouard@1746
   343
}
edouard@1746
   344
edouard@1521
   345
static inline int _same_fpr(
edouard@1521
   346
        const char* fpra,
edouard@1521
   347
        size_t fpras,
edouard@1521
   348
        const char* fprb,
edouard@1521
   349
        size_t fprbs
edouard@1521
   350
    )
edouard@1521
   351
{
edouard@1746
   352
    // illegal values are ignored, and considered not same.
edouard@1746
   353
    int comparison = 1;
edouard@1746
   354
edouard@1746
   355
    _compare_fprs(fpra, fpras, fprb, fprbs, &comparison);
edouard@1746
   356
edouard@1746
   357
    return comparison == 0;
edouard@1521
   358
}
roker@1722
   359
krista@2045
   360
// size is the length of the bytestr that's coming in. This is really only intended
krista@2045
   361
// for comparing two full strings. If charstr's length is different from bytestr_size,
krista@2045
   362
// we'll return a non-zero value.
krista@2045
   363
static inline int _unsigned_signed_strcmp(const unsigned char* bytestr, const char* charstr, int bytestr_size) {
krista@2045
   364
    int charstr_len = strlen(charstr);
krista@2045
   365
    if (charstr_len != bytestr_size)
krista@2045
   366
        return -1; // we don't actually care except that it's non-zero
krista@2045
   367
    return memcmp(bytestr, charstr, bytestr_size);
krista@2045
   368
}
krista@2045
   369
krista@2045
   370
// This is just a horrible example of C type madness. UTF-8 made me do it.
krista@2045
   371
static inline char* _pep_subj_copy() {
krista@2285
   372
#ifndef WIN32
krista@2045
   373
    unsigned char pepstr[] = PEP_SUBJ_STRING;
krista@2045
   374
    void* retval = calloc(1, sizeof(unsigned char)*PEP_SUBJ_BYTELEN + 1);
krista@2045
   375
    memcpy(retval, pepstr, PEP_SUBJ_BYTELEN);
krista@2045
   376
    return (char*)retval;
krista@2285
   377
#else
krista@2285
   378
    return strdup("pEp");
krista@2285
   379
#endif
krista@2045
   380
}
krista@2045
   381
krista@2461
   382
static inline bool is_me(PEP_SESSION session, pEp_identity* test_ident) {
krista@2461
   383
    bool retval = false;
krista@2461
   384
    if (test_ident && test_ident->user_id) {
krista@2461
   385
        char* def_id = NULL;
krista@2461
   386
        get_default_own_userid(session, &def_id);
krista@2461
   387
        if (test_ident->me || 
krista@2461
   388
            (def_id && strcmp(def_id, test_ident->user_id) == 0)) {
krista@2461
   389
            retval = true;
krista@2461
   390
        }
krista@2461
   391
        free(def_id);
krista@2461
   392
    }
krista@2461
   393
    return retval;
krista@2461
   394
}
krista@2461
   395
krista@2461
   396
#ifndef EMPTYSTR
krista@2461
   397
#define EMPTYSTR(STR) ((STR) == NULL || (STR)[0] == '\0')
krista@2461
   398
#endif
krista@2461
   399
krista@2461
   400
#ifndef _MIN
krista@2461
   401
#define _MIN(A, B) ((B) > (A) ? (A) : (B))
krista@2461
   402
#endif
krista@2461
   403
#ifndef _MAX
krista@2461
   404
#define _MAX(A, B) ((B) > (A) ? (B) : (A))
krista@2461
   405
#endif
krista@2461
   406
krista@2461
   407
krista@2176
   408
// These are globals used in generating message IDs and should only be
krista@2176
   409
// computed once, as they're either really constants or OS-dependent
krista@2176
   410
krista@2176
   411
int _pEp_rand_max_bits;
krista@2176
   412
double _pEp_log2_36;
krista@2176
   413
krista@2176
   414
static inline void _init_globals() {
krista@2176
   415
    _pEp_rand_max_bits = ceil(log2(RAND_MAX));
krista@2176
   416
    _pEp_log2_36 = log2(36);
krista@2176
   417
}
krista@2176
   418
roker@1722
   419
#ifdef DEBUG_ERRORSTACK
roker@1722
   420
    PEP_STATUS session_add_error(PEP_SESSION session, const char* file, unsigned line, PEP_STATUS status);
roker@1853
   421
    #define ADD_TO_LOG(status)   session_add_error(session, __FILE__, __LINE__, (status))
roker@1853
   422
    #define GOTO(label)          do{ (void)session_add_error(session, __FILE__, __LINE__, status); goto label; }while(0)
roker@1722
   423
#else
roker@1853
   424
    #define ADD_TO_LOG(status)   (status)
roker@1853
   425
    #define GOTO(label)          goto label
roker@1722
   426
#endif