src/pgp_netpgp.c
author Edouard Tisserant
Wed, 01 Apr 2015 16:38:20 +0200
changeset 174 9c3d0eaa8ea1
child 175 59c8eabab690
permissions -rw-r--r--
empty netpgp
Edouard@174
     1
#include "pEp_internal.h"
Edouard@174
     2
#include "pgp_netpgp.h"
Edouard@174
     3
Edouard@174
     4
#include <limits.h>
Edouard@174
     5
Edouard@174
     6
#include "wrappers.h"
Edouard@174
     7
Edouard@174
     8
#include <netpgp.h>
Edouard@174
     9
PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
Edouard@174
    10
{
Edouard@174
    11
    PEP_STATUS status = PEP_STATUS_OK;
Edouard@174
    12
   
Edouard@174
    13
    if (in_first) {
Edouard@174
    14
        /* TODO something maybe */
Edouard@174
    15
    }
Edouard@174
    16
Edouard@174
    17
        // TODO ensure minimal config
Edouard@174
    18
          
Edouard@174
    19
        // "keyserver"
Edouard@174
    20
        // "hkp://keys.gnupg.net"
Edouard@174
    21
Edouard@174
    22
        // "cert-digest-algo"
Edouard@174
    23
        // "SHA256"
Edouard@174
    24
Edouard@174
    25
        // "no-emit-version"
Edouard@174
    26
        // ""
Edouard@174
    27
Edouard@174
    28
        // "no-comments"
Edouard@174
    29
        // ""
Edouard@174
    30
Edouard@174
    31
        // "personal-cipher-preferences"
Edouard@174
    32
        // "AES AES256 AES192 CAST5"
Edouard@174
    33
Edouard@174
    34
        // "personal-digest-preferences"
Edouard@174
    35
        // "SHA512 SHA384 SHA256 SHA224"
Edouard@174
    36
        
Edouard@174
    37
        if (strcmp(setlocale(LC_ALL, NULL), "C") == 0)
Edouard@174
    38
            setlocale(LC_ALL, "");
Edouard@174
    39
Edouard@174
    40
        // TODO unsset netpgp locale if any
Edouard@174
    41
        // LC_CTYPE
Edouard@174
    42
#ifdef LC_MESSAGES // Windoze
Edouard@174
    43
        // LC_MESSAGES
Edouard@174
    44
#endif
Edouard@174
    45
    }
Edouard@174
    46
Edouard@174
    47
    // TODO Create netpgp handle
Edouard@174
    48
    // session->ctx = ...
Edouard@174
    49
    if (/* create error */) {
Edouard@174
    50
        status = PEP_INIT_GPGME_INIT_FAILED;
Edouard@174
    51
        goto pep_error;
Edouard@174
    52
    }
Edouard@174
    53
    assert(session->ctx);
Edouard@174
    54
Edouard@174
    55
    // TODO set protocol to OpenPGP
Edouard@174
    56
    // TODO set to use armoring
Edouard@174
    57
Edouard@174
    58
    return PEP_STATUS_OK;
Edouard@174
    59
Edouard@174
    60
pep_error:
Edouard@174
    61
    pgp_release(session, in_first);
Edouard@174
    62
    return status;
Edouard@174
    63
}
Edouard@174
    64
Edouard@174
    65
void pgp_release(PEP_SESSION session, bool out_last)
Edouard@174
    66
{
Edouard@174
    67
    if (session->ctx) {
Edouard@174
    68
        // TODO : release session->ctx
Edouard@174
    69
        session->ctx = NULL;
Edouard@174
    70
    }
Edouard@174
    71
Edouard@174
    72
    if (out_last){
Edouard@174
    73
        // TODO anything ?
Edouard@174
    74
    }
Edouard@174
    75
Edouard@174
    76
}
Edouard@174
    77
Edouard@174
    78
PEP_STATUS pgp_decrypt_and_verify(
Edouard@174
    79
    PEP_SESSION session, const char *ctext, size_t csize,
Edouard@174
    80
    char **ptext, size_t *psize, stringlist_t **keylist
Edouard@174
    81
    )
Edouard@174
    82
{
Edouard@174
    83
    PEP_STATUS result;
Edouard@174
    84
Edouard@174
    85
    stringlist_t *_keylist = NULL;
Edouard@174
    86
    int i_key = 0;
Edouard@174
    87
Edouard@174
    88
    assert(session);
Edouard@174
    89
    assert(ctext);
Edouard@174
    90
    assert(csize);
Edouard@174
    91
    assert(ptext);
Edouard@174
    92
    assert(psize);
Edouard@174
    93
    assert(keylist);
Edouard@174
    94
Edouard@174
    95
    *ptext = NULL;
Edouard@174
    96
    *psize = 0;
Edouard@174
    97
    *keylist = NULL;
Edouard@174
    98
Edouard@174
    99
    /* TODO identify cipher text */
Edouard@174
   100
    /* if recognized */
Edouard@174
   101
    /* decrypt */
Edouard@174
   102
    /* if OK, verify */
Edouard@174
   103
    /*
Edouard@174
   104
    result = PEP_DECRYPTED_AND_VERIFIED;
Edouard@174
   105
    result = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
Edouard@174
   106
    result = PEP_DECRYPTED;
Edouard@174
   107
    result = PEP_DECRYPT_WRONG_FORMAT;
Edouard@174
   108
    result = PEP_DECRYPT_NO_KEY;
Edouard@174
   109
    return PEP_OUT_OF_MEMORY;
Edouard@174
   110
    */
Edouard@174
   111
    result = PEP_UNKNOWN_ERROR;
Edouard@174
   112
                stringlist_t *k;
Edouard@174
   113
                _keylist = new_stringlist(NULL);
Edouard@174
   114
                assert(_keylist);
Edouard@174
   115
                if (_keylist == NULL) {
Edouard@174
   116
                    /* TODO */
Edouard@174
   117
                    return PEP_OUT_OF_MEMORY;
Edouard@174
   118
                }
Edouard@174
   119
                k = _keylist;
Edouard@174
   120
                do {
Edouard@174
   121
                        k = stringlist_add(k, "SIGNATURE FPR"/*TODO*/);
Edouard@174
   122
                } while (0 /* TODO sign next*/);
Edouard@174
   123
Edouard@174
   124
    return result;
Edouard@174
   125
}
Edouard@174
   126
Edouard@174
   127
PEP_STATUS pgp_verify_text(
Edouard@174
   128
    PEP_SESSION session, const char *text, size_t size,
Edouard@174
   129
    const char *signature, size_t sig_size, stringlist_t **keylist
Edouard@174
   130
    )
Edouard@174
   131
{
Edouard@174
   132
    PEP_STATUS result;
Edouard@174
   133
    gpgme_error_t gpgme_error;
Edouard@174
   134
    gpgme_data_t d_text, d_sig;
Edouard@174
   135
    stringlist_t *_keylist;
Edouard@174
   136
Edouard@174
   137
    assert(session);
Edouard@174
   138
    assert(text);
Edouard@174
   139
    assert(size);
Edouard@174
   140
    assert(signature);
Edouard@174
   141
    assert(sig_size);
Edouard@174
   142
    assert(keylist);
Edouard@174
   143
Edouard@174
   144
    *keylist = NULL;
Edouard@174
   145
    /* if OK, verify */
Edouard@174
   146
            stringlist_t *k;
Edouard@174
   147
            k = _keylist;
Edouard@174
   148
            result = PEP_VERIFIED;
Edouard@174
   149
            do {
Edouard@174
   150
                k = stringlist_add(k, "TODO");
Edouard@174
   151
                if (k == NULL) {
Edouard@174
   152
                    free_stringlist(_keylist);
Edouard@174
   153
                    /* TODO */
Edouard@174
   154
                    return PEP_OUT_OF_MEMORY;
Edouard@174
   155
                }
Edouard@174
   156
            } while (0 /*TODO*/);
Edouard@174
   157
            *keylist = _keylist;
Edouard@174
   158
    /*
Edouard@174
   159
    result = PEP_UNENCRYPTED;
Edouard@174
   160
    result = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
Edouard@174
   161
    result = PEP_VERIFIED_AND_TRUSTED;
Edouard@174
   162
    result = PEP_VERIFY_NO_KEY;
Edouard@174
   163
    result = PEP_UNENCRYPTED;
Edouard@174
   164
    result = PEP_DECRYPT_WRONG_FORMAT;
Edouard@174
   165
    return PEP_OUT_OF_MEMORY;
Edouard@174
   166
    */
Edouard@174
   167
    result = PEP_UNKNOWN_ERROR;
Edouard@174
   168
Edouard@174
   169
    return result;
Edouard@174
   170
}
Edouard@174
   171
Edouard@174
   172
PEP_STATUS pgp_encrypt_and_sign(
Edouard@174
   173
    PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
Edouard@174
   174
    size_t psize, char **ctext, size_t *csize
Edouard@174
   175
    )
Edouard@174
   176
{
Edouard@174
   177
    PEP_STATUS result;
Edouard@174
   178
    const stringlist_t *_keylist;
Edouard@174
   179
    int i, j;
Edouard@174
   180
Edouard@174
   181
    assert(session);
Edouard@174
   182
    assert(keylist);
Edouard@174
   183
    assert(ptext);
Edouard@174
   184
    assert(psize);
Edouard@174
   185
    assert(ctext);
Edouard@174
   186
    assert(csize);
Edouard@174
   187
Edouard@174
   188
    *ctext = NULL;
Edouard@174
   189
    *csize = 0;
Edouard@174
   190
Edouard@174
   191
    for (_keylist = keylist, i = 0; _keylist != NULL; _keylist = _keylist->next, i++) {
Edouard@174
   192
        assert(_keylist->value);
Edouard@174
   193
        /* TODO */
Edouard@174
   194
        /* get key from  _keylist->value */
Edouard@174
   195
        /* add key to recipients/signers */
Edouard@174
   196
    }
Edouard@174
   197
Edouard@174
   198
    /* Do encrypt and sign */ 
Edouard@174
   199
        char *_buffer = NULL;
Edouard@174
   200
        size_t length = /* TODO length*/ 0;
Edouard@174
   201
        assert(length != -1);
Edouard@174
   202
Edouard@174
   203
        /* Allocate transferable buffer */
Edouard@174
   204
        _buffer = malloc(length + 1);
Edouard@174
   205
        assert(_buffer);
Edouard@174
   206
        if (_buffer == NULL) {
Edouard@174
   207
            /* TODO clean */
Edouard@174
   208
            return PEP_OUT_OF_MEMORY;
Edouard@174
   209
        }
Edouard@174
   210
Edouard@174
   211
        *ctext = _buffer;
Edouard@174
   212
        *csize = length;
Edouard@174
   213
        (*ctext)[*csize] = 0; // safeguard for naive users
Edouard@174
   214
        result = PEP_STATUS_OK;
Edouard@174
   215
    }
Edouard@174
   216
Edouard@174
   217
    
Edouard@174
   218
        result = PEP_UNKNOWN_ERROR;
Edouard@174
   219
    return result;
Edouard@174
   220
}
Edouard@174
   221
Edouard@174
   222
PEP_STATUS pgp_generate_keypair(
Edouard@174
   223
    PEP_SESSION session, pEp_identity *identity
Edouard@174
   224
    )
Edouard@174
   225
{
Edouard@174
   226
    char *parms;
Edouard@174
   227
    const char *template =
Edouard@174
   228
        "Key-Type: RSA\n"
Edouard@174
   229
        "Key-Length: 4096\n"
Edouard@174
   230
        "Name-Real: %s\n"
Edouard@174
   231
        "Name-Email: %s\n"
Edouard@174
   232
        /* "Passphrase: %s\n" */
Edouard@174
   233
        "Expire-Date: 1y\n";
Edouard@174
   234
    int result;
Edouard@174
   235
Edouard@174
   236
    assert(session);
Edouard@174
   237
    assert(identity);
Edouard@174
   238
    assert(identity->address);
Edouard@174
   239
    assert(identity->fpr == NULL);
Edouard@174
   240
    assert(identity->username);
Edouard@174
   241
Edouard@174
   242
    parms = calloc(1, PARMS_MAX);
Edouard@174
   243
    assert(parms);
Edouard@174
   244
    if (parms == NULL)
Edouard@174
   245
        return PEP_OUT_OF_MEMORY;
Edouard@174
   246
Edouard@174
   247
    result = snprintf(parms, PARMS_MAX, template, identity->username,
Edouard@174
   248
        identity->address);
Edouard@174
   249
    assert(result < PARMS_MAX);
Edouard@174
   250
    if (result >= PARMS_MAX) {
Edouard@174
   251
        free(parms);
Edouard@174
   252
        return PEP_BUFFER_TOO_SMALL;
Edouard@174
   253
    }
Edouard@174
   254
Edouard@174
   255
    /* TODO generate key */
Edouard@174
   256
Edouard@174
   257
    free(parms);
Edouard@174
   258
Edouard@174
   259
        return PEP_UNKNOWN_ERROR;
Edouard@174
   260
        return PEP_ILLEGAL_VALUE;
Edouard@174
   261
        return PEP_CANNOT_CREATE_KEY;
Edouard@174
   262
Edouard@174
   263
    identity->fpr = strdup("TODO generated key fpr");
Edouard@174
   264
Edouard@174
   265
    return PEP_STATUS_OK;
Edouard@174
   266
}
Edouard@174
   267
Edouard@174
   268
PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fpr)
Edouard@174
   269
{
Edouard@174
   270
    assert(session);
Edouard@174
   271
    assert(fpr);
Edouard@174
   272
Edouard@174
   273
    /* TODO get key with given fpr */
Edouard@174
   274
        return PEP_KEY_NOT_FOUND;
Edouard@174
   275
        return PEP_ILLEGAL_VALUE;
Edouard@174
   276
        return PEP_KEY_HAS_AMBIG_NAME;
Edouard@174
   277
        return PEP_OUT_OF_MEMORY;
Edouard@174
   278
        return PEP_UNKNOWN_ERROR;
Edouard@174
   279
Edouard@174
   280
    /* TODO delete that key */
Edouard@174
   281
        return PEP_UNKNOWN_ERROR;
Edouard@174
   282
        return PEP_KEY_NOT_FOUND;
Edouard@174
   283
        return PEP_KEY_HAS_AMBIG_NAME;
Edouard@174
   284
        return PEP_UNKNOWN_ERROR;
Edouard@174
   285
Edouard@174
   286
    return PEP_STATUS_OK;
Edouard@174
   287
}
Edouard@174
   288
Edouard@174
   289
PEP_STATUS pgp_import_key(PEP_SESSION session, const char *key_data, size_t size)
Edouard@174
   290
{
Edouard@174
   291
    assert(session);
Edouard@174
   292
    assert(key_data);
Edouard@174
   293
Edouard@174
   294
    /* TODO import */
Edouard@174
   295
        return PEP_UNKNOWN_ERROR;
Edouard@174
   296
        return PEP_ILLEGAL_VALUE;
Edouard@174
   297
        return PEP_UNKNOWN_ERROR;
Edouard@174
   298
    return PEP_STATUS_OK;
Edouard@174
   299
}
Edouard@174
   300
Edouard@174
   301
PEP_STATUS pgp_export_key(
Edouard@174
   302
    PEP_SESSION session, const char *fpr, char **key_data, size_t *size
Edouard@174
   303
    )
Edouard@174
   304
{
Edouard@174
   305
    size_t _size;
Edouard@174
   306
    char *buffer;
Edouard@174
   307
    int reading;
Edouard@174
   308
Edouard@174
   309
    assert(session);
Edouard@174
   310
    assert(fpr);
Edouard@174
   311
    assert(key_data);
Edouard@174
   312
    assert(size);
Edouard@174
   313
Edouard@174
   314
Edouard@174
   315
    /* TODO export */
Edouard@174
   316
        return PEP_KEY_NOT_FOUND;
Edouard@174
   317
        return PEP_UNKNOWN_ERROR;
Edouard@174
   318
        return PEP_UNKNOWN_ERROR;
Edouard@174
   319
Edouard@174
   320
    _size = /* TODO */ 0;
Edouard@174
   321
    assert(_size != -1);
Edouard@174
   322
Edouard@174
   323
    buffer = malloc(_size + 1);
Edouard@174
   324
    assert(buffer);
Edouard@174
   325
    if (buffer == NULL) {
Edouard@174
   326
        /* TODO clean */
Edouard@174
   327
        return PEP_OUT_OF_MEMORY;
Edouard@174
   328
    }
Edouard@174
   329
Edouard@174
   330
    // safeguard for the naive user
Edouard@174
   331
    buffer[_size] = 0;
Edouard@174
   332
Edouard@174
   333
    *key_data = buffer;
Edouard@174
   334
    *size = _size;
Edouard@174
   335
Edouard@174
   336
    return PEP_STATUS_OK;
Edouard@174
   337
}
Edouard@174
   338
Edouard@174
   339
PEP_STATUS pgp_recv_key(PEP_SESSION session, const char *pattern)
Edouard@174
   340
{
Edouard@174
   341
    assert(session);
Edouard@174
   342
    assert(pattern);
Edouard@174
   343
Edouard@174
   344
    /* TODO ask for key */
Edouard@174
   345
        return PEP_UNKNOWN_ERROR;
Edouard@174
   346
        return PEP_GET_KEY_FAILED;
Edouard@174
   347
Edouard@174
   348
    do {
Edouard@174
   349
Edouard@174
   350
        /* For each key */
Edouard@174
   351
        /* import key */
Edouard@174
   352
    } while (0);
Edouard@174
   353
Edouard@174
   354
    return PEP_STATUS_OK;
Edouard@174
   355
}
Edouard@174
   356
Edouard@174
   357
PEP_STATUS pgp_find_keys(
Edouard@174
   358
    PEP_SESSION session, const char *pattern, stringlist_t **keylist
Edouard@174
   359
    )
Edouard@174
   360
{
Edouard@174
   361
    stringlist_t *_keylist;
Edouard@174
   362
    char *fpr;
Edouard@174
   363
Edouard@174
   364
    assert(session);
Edouard@174
   365
    assert(pattern);
Edouard@174
   366
    assert(keylist);
Edouard@174
   367
Edouard@174
   368
    *keylist = NULL;
Edouard@174
   369
Edouard@174
   370
    /* Ask for key */
Edouard@174
   371
        return PEP_UNKNOWN_ERROR;
Edouard@174
   372
        return PEP_GET_KEY_FAILED;
Edouard@174
   373
Edouard@174
   374
    _keylist = new_stringlist(NULL);
Edouard@174
   375
    stringlist_t *_k = _keylist;
Edouard@174
   376
Edouard@174
   377
    do {
Edouard@174
   378
            fpr = "TODO key->subkeys->fpr";
Edouard@174
   379
            assert(fpr);
Edouard@174
   380
            _k = stringlist_add(_k, fpr);
Edouard@174
   381
            assert(_k);
Edouard@174
   382
            if (_k == NULL){
Edouard@174
   383
                free_stringlist(_keylist);
Edouard@174
   384
                return PEP_OUT_OF_MEMORY;
Edouard@174
   385
            }
Edouard@174
   386
    } while (0);
Edouard@174
   387
Edouard@174
   388
    *keylist = _keylist;
Edouard@174
   389
    return PEP_STATUS_OK;
Edouard@174
   390
}
Edouard@174
   391
Edouard@174
   392
PEP_STATUS pgp_send_key(PEP_SESSION session, const char *pattern)
Edouard@174
   393
{
Edouard@174
   394
    assert(session);
Edouard@174
   395
    assert(pattern);
Edouard@174
   396
Edouard@174
   397
    /* TODO send key */
Edouard@174
   398
Edouard@174
   399
        return PEP_CANNOT_SEND_KEY;
Edouard@174
   400
        return PEP_STATUS_OK;
Edouard@174
   401
}
Edouard@174
   402
Edouard@174
   403
Edouard@174
   404
PEP_STATUS pgp_get_key_rating(
Edouard@174
   405
    PEP_SESSION session,
Edouard@174
   406
    const char *fpr,
Edouard@174
   407
    PEP_comm_type *comm_type
Edouard@174
   408
    )
Edouard@174
   409
{
Edouard@174
   410
    PEP_STATUS status = PEP_STATUS_OK;
Edouard@174
   411
Edouard@174
   412
    assert(session);
Edouard@174
   413
    assert(fpr);
Edouard@174
   414
    assert(comm_type);
Edouard@174
   415
Edouard@174
   416
    *comm_type = PEP_ct_unknown;
Edouard@174
   417
Edouard@174
   418
    /* TODO get key from fpr */
Edouard@174
   419
    return PEP_UNKNOWN_ERROR;
Edouard@174
   420
    return PEP_GET_KEY_FAILED;
Edouard@174
   421
Edouard@174
   422
    switch (/*TODO key->protocol*/ 4) {
Edouard@174
   423
    case /* TODO  OpenPGP */0:
Edouard@174
   424
    case /* TODO DEFAULT */1:
Edouard@174
   425
        *comm_type = PEP_ct_OpenPGP_unconfirmed;
Edouard@174
   426
        break;
Edouard@174
   427
    case /* TODO CMS */2:
Edouard@174
   428
        *comm_type = PEP_ct_CMS_unconfirmed;
Edouard@174
   429
        break;
Edouard@174
   430
    default:
Edouard@174
   431
        *comm_type = PEP_ct_unknown;
Edouard@174
   432
        return PEP_STATUS_OK;
Edouard@174
   433
    }
Edouard@174
   434
Edouard@174
   435
        for (; 1 == 0; /* Each subkeys */ ) {
Edouard@174
   436
            if (/* TODO length */0 < 1024)
Edouard@174
   437
                *comm_type = PEP_ct_key_too_short;
Edouard@174
   438
            else if (
Edouard@174
   439
                (
Edouard@174
   440
                (   /* TODO pubkey_algo == RSA  */ 0)
Edouard@174
   441
                || (/* TODO pubkey_algo == RSA_E*/ 0)
Edouard@174
   442
                || (/* TODO pubkey_algo == RSA_S*/ 0)
Edouard@174
   443
                )
Edouard@174
   444
                && /* sk->length */0 == 1024
Edouard@174
   445
                )
Edouard@174
   446
                *comm_type = PEP_ct_OpenPGP_weak_unconfirmed;
Edouard@174
   447
Edouard@174
   448
            if (/* TODO invalid */ 1) {
Edouard@174
   449
                *comm_type = PEP_ct_key_b0rken;
Edouard@174
   450
                break;
Edouard@174
   451
            }
Edouard@174
   452
            if (/* TODO expired */ 1) {
Edouard@174
   453
                *comm_type = PEP_ct_key_expired;
Edouard@174
   454
                break;
Edouard@174
   455
            }
Edouard@174
   456
            if (/* TODO revoked*/) {
Edouard@174
   457
                *comm_type = PEP_ct_key_revoked;
Edouard@174
   458
                break;
Edouard@174
   459
            }
Edouard@174
   460
        }
Edouard@174
   461
        *comm_type = PEP_ct_unknown;
Edouard@174
   462
        return PEP_OUT_OF_MEMORY;
Edouard@174
   463
        return PEP_UNKNOWN_ERROR;
Edouard@174
   464
Edouard@174
   465
Edouard@174
   466
    return status;
Edouard@174
   467
}