src/pgp_netpgp.c
author Edouard Tisserant
Sat, 11 Apr 2015 18:22:33 +0200
changeset 185 f3142e40d9e7
parent 184 da3973ecb7b6
child 186 cfd6fe0e9dc5
permissions -rw-r--r--
netpgp : pgp_verify_text implemented. need more fixing in 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@179
     9
#include <netpgp/config.h>
Edouard@179
    10
#include <netpgp/memory.h>
Edouard@179
    11
#include <netpgp/crypto.h>
Edouard@180
    12
#include <netpgp/netpgpsdk.h>
Edouard@180
    13
#include <netpgp/validate.h>
Edouard@179
    14
Edouard@185
    15
#define PEP_NETPGP_DEBUG
Edouard@185
    16
Edouard@174
    17
PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
Edouard@174
    18
{
Edouard@179
    19
    netpgp_t *netpgp;
Edouard@174
    20
    PEP_STATUS status = PEP_STATUS_OK;
Edouard@175
    21
    const char *home = NULL;
Edouard@179
    22
Edouard@179
    23
    assert(session);
Edouard@179
    24
    if(!session) return PEP_UNKNOWN_ERROR;
Edouard@179
    25
Edouard@179
    26
    netpgp = &session->ctx;
Edouard@174
    27
   
Edouard@174
    28
    if (in_first) {
Edouard@175
    29
        if (strcmp(setlocale(LC_ALL, NULL), "C") == 0)
Edouard@175
    30
            setlocale(LC_ALL, "");
Edouard@174
    31
    }
Edouard@174
    32
Edouard@185
    33
    memset(netpgp, 0x0, sizeof(session->ctx));
Edouard@174
    34
Edouard@180
    35
    // netpgp_setvar(netpgp, "max mem alloc", "4194304");
Edouard@180
    36
    netpgp_setvar(netpgp, "need seckey", "1");
Edouard@180
    37
    netpgp_setvar(netpgp, "need userid", "1");
Edouard@180
    38
Edouard@175
    39
    // NetPGP shares home with GPG
Edouard@175
    40
    home = gpg_home();
Edouard@175
    41
    if(home){
Edouard@179
    42
        netpgp_set_homedir(netpgp,(char*)home, NULL, 0);
Edouard@175
    43
    }else{
Edouard@175
    44
        status = PEP_INIT_NO_GPG_HOME;
Edouard@175
    45
        goto pep_error;
Edouard@174
    46
    }
Edouard@174
    47
Edouard@175
    48
    // pair with gpg's cert-digest-algo
Edouard@185
    49
    netpgp_setvar(netpgp, "hash", "SHA256");
Edouard@175
    50
Edouard@175
    51
    // subset of gpg's personal-cipher-preferences
Edouard@175
    52
    // here only one cipher can be selected
Edouard@179
    53
    netpgp_setvar(netpgp, "cipher", "AES256");
Edouard@175
    54
Edouard@185
    55
    if (!netpgp_init(netpgp)) {
Edouard@175
    56
        status = PEP_INIT_NETPGP_INIT_FAILED;
Edouard@174
    57
        goto pep_error;
Edouard@174
    58
    }
Edouard@174
    59
Edouard@174
    60
    return PEP_STATUS_OK;
Edouard@174
    61
Edouard@174
    62
pep_error:
Edouard@174
    63
    pgp_release(session, in_first);
Edouard@174
    64
    return status;
Edouard@174
    65
}
Edouard@174
    66
Edouard@174
    67
void pgp_release(PEP_SESSION session, bool out_last)
Edouard@174
    68
{
Edouard@179
    69
    netpgp_t *netpgp;
Edouard@179
    70
Edouard@179
    71
    assert(session);
Edouard@179
    72
    if(!session) return;
Edouard@179
    73
Edouard@179
    74
    netpgp = &session->ctx;
Edouard@179
    75
Edouard@185
    76
    netpgp_end(netpgp);
Edouard@185
    77
    memset(netpgp, 0x0, sizeof(session->ctx));
Edouard@174
    78
Edouard@175
    79
    // out_last unused here
Edouard@174
    80
}
Edouard@174
    81
Edouard@185
    82
// Iterate through netpgp' reported valid signatures 
Edouard@185
    83
// fill a list of valid figerprints
Edouard@185
    84
// returns PEP_STATUS_OK if all sig reported valid
Edouard@185
    85
// error status otherwise.
Edouard@185
    86
static PEP_STATUS _validation_results(netpgp_t *netpgp, pgp_validation_t *vresult,
Edouard@185
    87
                                             stringlist_t **_keylist)
Edouard@185
    88
{
Edouard@185
    89
	time_t	now;
Edouard@185
    90
	time_t	t;
Edouard@185
    91
	char	buf[128];
Edouard@185
    92
Edouard@185
    93
	now = time(NULL);
Edouard@185
    94
	if (now < vresult->birthtime) {
Edouard@185
    95
		// signature is not valid yet
Edouard@185
    96
#ifdef PEP_NETPGP_DEBUG
Edouard@185
    97
		(void) printf(
Edouard@185
    98
			"signature not valid until %.24s\n",
Edouard@185
    99
			ctime(&vresult->birthtime));
Edouard@185
   100
#endif //PEP_NETPGP_DEBUG
Edouard@185
   101
		return PEP_UNENCRYPTED;
Edouard@185
   102
	}
Edouard@185
   103
	if (vresult->duration != 0 && now > vresult->birthtime + vresult->duration) {
Edouard@185
   104
		// signature has expired
Edouard@185
   105
		t = vresult->duration + vresult->birthtime;
Edouard@185
   106
#ifdef PEP_NETPGP_DEBUG
Edouard@185
   107
		(void) printf(
Edouard@185
   108
			"signature not valid after %.24s\n",
Edouard@185
   109
			ctime(&t));
Edouard@185
   110
#endif //PEP_NETPGP_DEBUG
Edouard@185
   111
		return PEP_UNENCRYPTED;
Edouard@185
   112
	}
Edouard@185
   113
    if (vresult->validc && vresult->valid_sigs &&
Edouard@185
   114
        !vresult->invalidc && !vresult->unknownc ) {
Edouard@185
   115
        unsigned    n;
Edouard@185
   116
        stringlist_t *k;
Edouard@185
   117
        // caller responsible to free
Edouard@185
   118
        *_keylist = new_stringlist(NULL);
Edouard@185
   119
        assert(*_keylist);
Edouard@185
   120
        if (*_keylist == NULL) {
Edouard@185
   121
            return PEP_OUT_OF_MEMORY;
Edouard@185
   122
        }
Edouard@185
   123
        k = *_keylist;
Edouard@185
   124
        for (n = 0; n < vresult->validc; ++n) {
Edouard@185
   125
            int i;
Edouard@185
   126
            char id[MAX_ID_LENGTH + 1];
Edouard@185
   127
            static const char *hexes = "0123456789abcdef";
Edouard@185
   128
            const uint8_t *userid = vresult->valid_sigs[n].signer_id;
Edouard@185
   129
Edouard@185
   130
#ifdef PEP_NETPGP_DEBUG
Edouard@185
   131
            const pgp_key_t *key;
Edouard@185
   132
            pgp_pubkey_t *sigkey;
Edouard@185
   133
	        unsigned from = 0;
Edouard@185
   134
            key = pgp_getkeybyid(netpgp->io, netpgp->pubring,
Edouard@185
   135
                (const uint8_t *) vresult->valid_sigs[n].signer_id,
Edouard@185
   136
                &from, &sigkey);
Edouard@185
   137
            pgp_print_keydata(netpgp->io, netpgp->pubring, key, "valid signature ", &key->key.pubkey, 0);
Edouard@185
   138
#endif //PEP_NETPGP_DEBUG
Edouard@185
   139
Edouard@185
   140
            for (i = 0; i < 8 ; i++) {
Edouard@185
   141
                id[i * 2] = hexes[(unsigned)(userid[i] & 0xf0) >> 4];
Edouard@185
   142
                id[(i * 2) + 1] = hexes[userid[i] & 0xf];
Edouard@185
   143
            }
Edouard@185
   144
            id[8 * 2] = 0x0;
Edouard@185
   145
Edouard@185
   146
            k = stringlist_add(k, id);
Edouard@185
   147
            if(!k){
Edouard@185
   148
                free_stringlist(*_keylist);
Edouard@185
   149
                return PEP_OUT_OF_MEMORY;
Edouard@185
   150
            }
Edouard@185
   151
        }
Edouard@185
   152
        return PEP_STATUS_OK;
Edouard@185
   153
    }
Edouard@185
   154
    if (vresult->validc + vresult->invalidc + vresult->unknownc == 0) {
Edouard@185
   155
        // No signatures found - is this memory signed?
Edouard@185
   156
        return PEP_VERIFY_NO_KEY; 
Edouard@185
   157
    } 
Edouard@185
   158
    
Edouard@185
   159
    if (vresult->invalidc) {
Edouard@185
   160
        // some invalid signatures
Edouard@185
   161
Edouard@185
   162
#ifdef PEP_NETPGP_DEBUG
Edouard@185
   163
        unsigned    n;
Edouard@185
   164
        for (n = 0; n < vresult->invalidc; ++n) {
Edouard@185
   165
            const pgp_key_t *key;
Edouard@185
   166
            pgp_pubkey_t *sigkey;
Edouard@185
   167
            unsigned from = 0;
Edouard@185
   168
            key = pgp_getkeybyid(netpgp->io, netpgp->pubring,
Edouard@185
   169
                (const uint8_t *) vresult->invalid_sigs[n].signer_id,
Edouard@185
   170
                &from, &sigkey);
Edouard@185
   171
            pgp_print_keydata(netpgp->io, netpgp->pubring, key, "invalid signature ", &key->key.pubkey, 0);
Edouard@185
   172
	        if (sigkey->duration != 0 && now > sigkey->birthtime + sigkey->duration) {
Edouard@185
   173
                printf("EXPIRED !\n");
Edouard@185
   174
            }
Edouard@185
   175
        }
Edouard@185
   176
#endif //PEP_NETPGP_DEBUG
Edouard@185
   177
Edouard@185
   178
        return PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
Edouard@185
   179
    }
Edouard@185
   180
    
Edouard@185
   181
    // only unknown sigs
Edouard@185
   182
    return PEP_DECRYPT_WRONG_FORMAT;
Edouard@185
   183
}
Edouard@185
   184
Edouard@174
   185
PEP_STATUS pgp_decrypt_and_verify(
Edouard@174
   186
    PEP_SESSION session, const char *ctext, size_t csize,
Edouard@174
   187
    char **ptext, size_t *psize, stringlist_t **keylist
Edouard@174
   188
    )
Edouard@174
   189
{
Edouard@179
   190
    netpgp_t *netpgp;
Edouard@185
   191
    pgp_memory_t *mem;
Edouard@185
   192
    pgp_memory_t *cat;
Edouard@185
   193
    pgp_validation_t *vresult;
Edouard@180
   194
    char *_ptext = NULL;
Edouard@180
   195
    size_t _psize = 0;
Edouard@185
   196
    int ret;
Edouard@179
   197
Edouard@174
   198
    PEP_STATUS result;
Edouard@174
   199
    stringlist_t *_keylist = NULL;
Edouard@174
   200
    int i_key = 0;
Edouard@174
   201
Edouard@174
   202
    assert(session);
Edouard@174
   203
    assert(ctext);
Edouard@174
   204
    assert(csize);
Edouard@174
   205
    assert(ptext);
Edouard@174
   206
    assert(psize);
Edouard@174
   207
    assert(keylist);
Edouard@174
   208
Edouard@179
   209
    if(!session || !ctext || !csize || !ptext || !psize || !keylist) 
Edouard@179
   210
        return PEP_UNKNOWN_ERROR;
Edouard@179
   211
Edouard@179
   212
    netpgp = &session->ctx;
Edouard@179
   213
Edouard@174
   214
    *ptext = NULL;
Edouard@174
   215
    *psize = 0;
Edouard@174
   216
    *keylist = NULL;
Edouard@174
   217
Edouard@183
   218
    vresult = malloc(sizeof(pgp_validation_t));
Edouard@185
   219
    memset(vresult, 0x0, sizeof(pgp_validation_t));
Edouard@182
   220
Edouard@183
   221
    mem = pgp_decrypt_and_validate_buf(netpgp->io, vresult, ctext, csize,
Edouard@179
   222
                netpgp->secring, netpgp->pubring,
Edouard@179
   223
                1 /* armoured */,
Edouard@179
   224
                0 /* sshkeys */,
Edouard@180
   225
                NULL, -1, NULL  /* pass fp,attempts,cb */);
Edouard@179
   226
    if (mem == NULL) {
Edouard@179
   227
        return PEP_OUT_OF_MEMORY;
Edouard@179
   228
    }
Edouard@179
   229
Edouard@185
   230
    _psize = pgp_mem_len(mem);
Edouard@182
   231
    if (_psize){
Edouard@182
   232
        if ((_ptext = calloc(1, _psize)) == NULL) {
Edouard@183
   233
            result = PEP_OUT_OF_MEMORY;
Edouard@183
   234
            goto free_pgp;
Edouard@182
   235
        }
Edouard@185
   236
        memcpy(_ptext, pgp_mem_data(mem), _psize);
Edouard@182
   237
        result = PEP_DECRYPTED;
Edouard@182
   238
    }else{
Edouard@183
   239
        result = PEP_DECRYPT_NO_KEY;
Edouard@183
   240
        goto free_pgp;
Edouard@182
   241
    }
Edouard@180
   242
Edouard@185
   243
    if (result == PEP_DECRYPTED) {
Edouard@185
   244
        result = _validation_results(netpgp, vresult, &_keylist);
Edouard@185
   245
        if (result != PEP_STATUS_OK) {
Edouard@185
   246
            goto free_ptext;
Edouard@183
   247
        }
Edouard@180
   248
        result = PEP_DECRYPTED_AND_VERIFIED;
Edouard@180
   249
    }
Edouard@174
   250
Edouard@180
   251
    if (result == PEP_DECRYPTED_AND_VERIFIED
Edouard@180
   252
        || result == PEP_DECRYPTED) {
Edouard@180
   253
        *ptext = _ptext;
Edouard@180
   254
        *psize = _psize;
Edouard@180
   255
        (*ptext)[*psize] = 0; // safeguard for naive users
Edouard@185
   256
        if (result == PEP_DECRYPTED_AND_VERIFIED) {
Edouard@185
   257
            *keylist = _keylist;
Edouard@185
   258
        }
Edouard@183
   259
Edouard@183
   260
        /* _ptext and _keylist ownership transfer, don't free */
Edouard@183
   261
        goto free_pgp;
Edouard@180
   262
    }
Edouard@183
   263
Edouard@183
   264
free_keylist:
Edouard@183
   265
    free_stringlist(_keylist);
Edouard@183
   266
Edouard@183
   267
free_ptext:
Edouard@183
   268
    free(_ptext);
Edouard@183
   269
Edouard@183
   270
free_pgp:
Edouard@185
   271
    pgp_memory_free(mem);
Edouard@183
   272
    pgp_validate_result_free(vresult);
Edouard@183
   273
Edouard@174
   274
    return result;
Edouard@174
   275
}
Edouard@174
   276
Edouard@174
   277
PEP_STATUS pgp_verify_text(
Edouard@174
   278
    PEP_SESSION session, const char *text, size_t size,
Edouard@174
   279
    const char *signature, size_t sig_size, stringlist_t **keylist
Edouard@174
   280
    )
Edouard@174
   281
{
Edouard@185
   282
    netpgp_t *netpgp;
Edouard@185
   283
    pgp_memory_t *signedmem;
Edouard@185
   284
    pgp_memory_t *sig;
Edouard@185
   285
    pgp_validation_t *vresult;
Edouard@185
   286
    pgp_io_t *io;
Edouard@185
   287
Edouard@174
   288
    PEP_STATUS result;
Edouard@174
   289
    stringlist_t *_keylist;
Edouard@174
   290
Edouard@174
   291
    assert(session);
Edouard@174
   292
    assert(text);
Edouard@174
   293
    assert(size);
Edouard@174
   294
    assert(signature);
Edouard@174
   295
    assert(sig_size);
Edouard@174
   296
    assert(keylist);
Edouard@174
   297
Edouard@185
   298
    if(!session || !text || !size || !signature || !sig_size || !keylist) 
Edouard@185
   299
        return PEP_UNKNOWN_ERROR;
Edouard@185
   300
Edouard@185
   301
    netpgp = &session->ctx;
Edouard@185
   302
Edouard@174
   303
    *keylist = NULL;
Edouard@185
   304
Edouard@185
   305
    vresult = malloc(sizeof(pgp_validation_t));
Edouard@185
   306
    memset(vresult, 0x0, sizeof(pgp_validation_t));
Edouard@185
   307
Edouard@185
   308
    signedmem = pgp_memory_new();
Edouard@185
   309
    if (signedmem == NULL) {
Edouard@185
   310
        return PEP_OUT_OF_MEMORY;
Edouard@185
   311
    }
Edouard@185
   312
    pgp_memory_add(signedmem, (const uint8_t*)text, size);
Edouard@185
   313
Edouard@185
   314
    sig = pgp_memory_new();
Edouard@185
   315
    if (sig == NULL) {
Edouard@185
   316
        pgp_memory_free(signedmem);
Edouard@185
   317
        return PEP_OUT_OF_MEMORY;
Edouard@185
   318
    }
Edouard@185
   319
    pgp_memory_add(sig, (const uint8_t*)signature, sig_size);
Edouard@185
   320
Edouard@185
   321
    pgp_validate_mem_detached(netpgp->io, vresult, sig,
Edouard@185
   322
                NULL,/* output */
Edouard@185
   323
                1,/* armored */
Edouard@185
   324
                netpgp->pubring,
Edouard@185
   325
                signedmem);
Edouard@185
   326
Edouard@185
   327
    result = _validation_results(netpgp, vresult, &_keylist);
Edouard@185
   328
    if (result != PEP_STATUS_OK) {
Edouard@185
   329
        goto free_pgp;
Edouard@185
   330
    }else{
Edouard@185
   331
        result = PEP_VERIFIED;
Edouard@185
   332
    }
Edouard@185
   333
Edouard@185
   334
    if (result == PEP_VERIFIED) {
Edouard@185
   335
        /* TODO : check trust level */
Edouard@185
   336
        result = PEP_VERIFIED_AND_TRUSTED;
Edouard@185
   337
    }
Edouard@185
   338
Edouard@185
   339
    if (result == PEP_VERIFIED || result == PEP_VERIFIED_AND_TRUSTED) {
Edouard@185
   340
        *keylist = _keylist;
Edouard@185
   341
Edouard@185
   342
        /* _keylist ownership transfer, don't free */
Edouard@185
   343
        goto free_pgp;
Edouard@185
   344
    }
Edouard@185
   345
Edouard@185
   346
free_keylist:
Edouard@185
   347
    free_stringlist(_keylist);
Edouard@185
   348
Edouard@185
   349
free_pgp:
Edouard@185
   350
    // pgp_memory_free(sig) done by pgp_validate_mem - why ?
Edouard@185
   351
    pgp_memory_free(signedmem);
Edouard@185
   352
    pgp_validate_result_free(vresult);
Edouard@185
   353
Edouard@185
   354
    return result;
Edouard@185
   355
Edouard@185
   356
    /* TODO check
Edouard@174
   357
    result = PEP_UNENCRYPTED;
Edouard@174
   358
    result = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
Edouard@174
   359
    result = PEP_VERIFIED_AND_TRUSTED;
Edouard@174
   360
    result = PEP_VERIFY_NO_KEY;
Edouard@174
   361
    result = PEP_UNENCRYPTED;
Edouard@174
   362
    result = PEP_DECRYPT_WRONG_FORMAT;
Edouard@174
   363
    return PEP_OUT_OF_MEMORY;
Edouard@174
   364
    */
Edouard@174
   365
}
Edouard@174
   366
Edouard@174
   367
PEP_STATUS pgp_encrypt_and_sign(
Edouard@174
   368
    PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
Edouard@174
   369
    size_t psize, char **ctext, size_t *csize
Edouard@174
   370
    )
Edouard@174
   371
{
Edouard@174
   372
    PEP_STATUS result;
Edouard@174
   373
    const stringlist_t *_keylist;
Edouard@174
   374
    int i, j;
Edouard@174
   375
Edouard@174
   376
    assert(session);
Edouard@174
   377
    assert(keylist);
Edouard@174
   378
    assert(ptext);
Edouard@174
   379
    assert(psize);
Edouard@174
   380
    assert(ctext);
Edouard@174
   381
    assert(csize);
Edouard@174
   382
Edouard@174
   383
    *ctext = NULL;
Edouard@174
   384
    *csize = 0;
Edouard@174
   385
Edouard@174
   386
    for (_keylist = keylist, i = 0; _keylist != NULL; _keylist = _keylist->next, i++) {
Edouard@174
   387
        assert(_keylist->value);
Edouard@174
   388
        /* TODO */
Edouard@174
   389
        /* get key from  _keylist->value */
Edouard@174
   390
        /* add key to recipients/signers */
Edouard@174
   391
    }
Edouard@174
   392
Edouard@174
   393
    /* Do encrypt and sign */ 
Edouard@175
   394
    char *_buffer = NULL;
Edouard@175
   395
    size_t length = /* TODO length*/ 0;
Edouard@175
   396
    assert(length != -1);
Edouard@174
   397
Edouard@175
   398
    /* Allocate transferable buffer */
Edouard@175
   399
    _buffer = malloc(length + 1);
Edouard@175
   400
    assert(_buffer);
Edouard@175
   401
    if (_buffer == NULL) {
Edouard@175
   402
        /* TODO clean */
Edouard@175
   403
        return PEP_OUT_OF_MEMORY;
Edouard@174
   404
    }
Edouard@174
   405
Edouard@175
   406
    *ctext = _buffer;
Edouard@175
   407
    *csize = length;
Edouard@175
   408
    (*ctext)[*csize] = 0; // safeguard for naive users
Edouard@175
   409
    result = PEP_STATUS_OK;
Edouard@175
   410
Edouard@174
   411
    
Edouard@175
   412
    result = PEP_UNKNOWN_ERROR;
Edouard@174
   413
    return result;
Edouard@174
   414
}
Edouard@174
   415
Edouard@174
   416
PEP_STATUS pgp_generate_keypair(
Edouard@174
   417
    PEP_SESSION session, pEp_identity *identity
Edouard@174
   418
    )
Edouard@174
   419
{
Edouard@174
   420
    char *parms;
Edouard@174
   421
    const char *template =
Edouard@174
   422
        "Key-Type: RSA\n"
Edouard@174
   423
        "Key-Length: 4096\n"
Edouard@174
   424
        "Name-Real: %s\n"
Edouard@174
   425
        "Name-Email: %s\n"
Edouard@174
   426
        /* "Passphrase: %s\n" */
Edouard@174
   427
        "Expire-Date: 1y\n";
Edouard@174
   428
    int result;
Edouard@174
   429
Edouard@174
   430
    assert(session);
Edouard@174
   431
    assert(identity);
Edouard@174
   432
    assert(identity->address);
Edouard@174
   433
    assert(identity->fpr == NULL);
Edouard@174
   434
    assert(identity->username);
Edouard@174
   435
Edouard@174
   436
    parms = calloc(1, PARMS_MAX);
Edouard@174
   437
    assert(parms);
Edouard@174
   438
    if (parms == NULL)
Edouard@174
   439
        return PEP_OUT_OF_MEMORY;
Edouard@174
   440
Edouard@174
   441
    result = snprintf(parms, PARMS_MAX, template, identity->username,
Edouard@174
   442
        identity->address);
Edouard@174
   443
    assert(result < PARMS_MAX);
Edouard@174
   444
    if (result >= PARMS_MAX) {
Edouard@174
   445
        free(parms);
Edouard@174
   446
        return PEP_BUFFER_TOO_SMALL;
Edouard@174
   447
    }
Edouard@174
   448
Edouard@174
   449
    /* TODO generate key */
Edouard@174
   450
Edouard@174
   451
    free(parms);
Edouard@174
   452
Edouard@174
   453
        return PEP_UNKNOWN_ERROR;
Edouard@174
   454
        return PEP_ILLEGAL_VALUE;
Edouard@174
   455
        return PEP_CANNOT_CREATE_KEY;
Edouard@174
   456
Edouard@174
   457
    identity->fpr = strdup("TODO generated key fpr");
Edouard@174
   458
Edouard@174
   459
    return PEP_STATUS_OK;
Edouard@174
   460
}
Edouard@174
   461
Edouard@174
   462
PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fpr)
Edouard@174
   463
{
Edouard@174
   464
    assert(session);
Edouard@174
   465
    assert(fpr);
Edouard@174
   466
Edouard@174
   467
    /* TODO get key with given fpr */
Edouard@174
   468
        return PEP_KEY_NOT_FOUND;
Edouard@174
   469
        return PEP_ILLEGAL_VALUE;
Edouard@174
   470
        return PEP_KEY_HAS_AMBIG_NAME;
Edouard@174
   471
        return PEP_OUT_OF_MEMORY;
Edouard@174
   472
        return PEP_UNKNOWN_ERROR;
Edouard@174
   473
Edouard@174
   474
    /* TODO delete that key */
Edouard@174
   475
        return PEP_UNKNOWN_ERROR;
Edouard@174
   476
        return PEP_KEY_NOT_FOUND;
Edouard@174
   477
        return PEP_KEY_HAS_AMBIG_NAME;
Edouard@174
   478
        return PEP_UNKNOWN_ERROR;
Edouard@174
   479
Edouard@174
   480
    return PEP_STATUS_OK;
Edouard@174
   481
}
Edouard@174
   482
Edouard@179
   483
PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data, size_t size)
Edouard@174
   484
{
Edouard@174
   485
    assert(session);
Edouard@174
   486
    assert(key_data);
Edouard@174
   487
Edouard@174
   488
    /* TODO import */
Edouard@174
   489
        return PEP_UNKNOWN_ERROR;
Edouard@174
   490
        return PEP_ILLEGAL_VALUE;
Edouard@174
   491
        return PEP_UNKNOWN_ERROR;
Edouard@174
   492
    return PEP_STATUS_OK;
Edouard@174
   493
}
Edouard@174
   494
Edouard@179
   495
PEP_STATUS pgp_export_keydata(
Edouard@174
   496
    PEP_SESSION session, const char *fpr, char **key_data, size_t *size
Edouard@174
   497
    )
Edouard@174
   498
{
Edouard@174
   499
    size_t _size;
Edouard@174
   500
    char *buffer;
Edouard@174
   501
    int reading;
Edouard@174
   502
Edouard@174
   503
    assert(session);
Edouard@174
   504
    assert(fpr);
Edouard@174
   505
    assert(key_data);
Edouard@174
   506
    assert(size);
Edouard@174
   507
Edouard@174
   508
Edouard@174
   509
    /* TODO export */
Edouard@174
   510
        return PEP_KEY_NOT_FOUND;
Edouard@174
   511
        return PEP_UNKNOWN_ERROR;
Edouard@174
   512
        return PEP_UNKNOWN_ERROR;
Edouard@174
   513
Edouard@174
   514
    _size = /* TODO */ 0;
Edouard@174
   515
    assert(_size != -1);
Edouard@174
   516
Edouard@174
   517
    buffer = malloc(_size + 1);
Edouard@174
   518
    assert(buffer);
Edouard@174
   519
    if (buffer == NULL) {
Edouard@174
   520
        /* TODO clean */
Edouard@174
   521
        return PEP_OUT_OF_MEMORY;
Edouard@174
   522
    }
Edouard@174
   523
Edouard@174
   524
    // safeguard for the naive user
Edouard@174
   525
    buffer[_size] = 0;
Edouard@174
   526
Edouard@174
   527
    *key_data = buffer;
Edouard@174
   528
    *size = _size;
Edouard@174
   529
Edouard@174
   530
    return PEP_STATUS_OK;
Edouard@174
   531
}
Edouard@174
   532
Edouard@175
   533
// "keyserver"
Edouard@175
   534
// "hkp://keys.gnupg.net"
Edouard@174
   535
PEP_STATUS pgp_recv_key(PEP_SESSION session, const char *pattern)
Edouard@174
   536
{
Edouard@174
   537
    assert(session);
Edouard@174
   538
    assert(pattern);
Edouard@174
   539
Edouard@174
   540
    /* TODO ask for key */
Edouard@174
   541
        return PEP_UNKNOWN_ERROR;
Edouard@174
   542
        return PEP_GET_KEY_FAILED;
Edouard@174
   543
Edouard@174
   544
    do {
Edouard@174
   545
Edouard@174
   546
        /* For each key */
Edouard@174
   547
        /* import key */
Edouard@174
   548
    } while (0);
Edouard@174
   549
Edouard@174
   550
    return PEP_STATUS_OK;
Edouard@174
   551
}
Edouard@174
   552
Edouard@174
   553
PEP_STATUS pgp_find_keys(
Edouard@174
   554
    PEP_SESSION session, const char *pattern, stringlist_t **keylist
Edouard@174
   555
    )
Edouard@174
   556
{
Edouard@174
   557
    stringlist_t *_keylist;
Edouard@174
   558
    char *fpr;
Edouard@174
   559
Edouard@174
   560
    assert(session);
Edouard@174
   561
    assert(pattern);
Edouard@174
   562
    assert(keylist);
Edouard@174
   563
Edouard@174
   564
    *keylist = NULL;
Edouard@174
   565
Edouard@174
   566
    /* Ask for key */
Edouard@174
   567
        return PEP_UNKNOWN_ERROR;
Edouard@174
   568
        return PEP_GET_KEY_FAILED;
Edouard@174
   569
Edouard@174
   570
    _keylist = new_stringlist(NULL);
Edouard@174
   571
    stringlist_t *_k = _keylist;
Edouard@174
   572
Edouard@174
   573
    do {
Edouard@174
   574
            fpr = "TODO key->subkeys->fpr";
Edouard@174
   575
            assert(fpr);
Edouard@174
   576
            _k = stringlist_add(_k, fpr);
Edouard@174
   577
            assert(_k);
Edouard@174
   578
            if (_k == NULL){
Edouard@174
   579
                free_stringlist(_keylist);
Edouard@174
   580
                return PEP_OUT_OF_MEMORY;
Edouard@174
   581
            }
Edouard@174
   582
    } while (0);
Edouard@174
   583
Edouard@174
   584
    *keylist = _keylist;
Edouard@174
   585
    return PEP_STATUS_OK;
Edouard@174
   586
}
Edouard@174
   587
Edouard@174
   588
PEP_STATUS pgp_send_key(PEP_SESSION session, const char *pattern)
Edouard@174
   589
{
Edouard@174
   590
    assert(session);
Edouard@174
   591
    assert(pattern);
Edouard@174
   592
Edouard@174
   593
    /* TODO send key */
Edouard@174
   594
Edouard@174
   595
        return PEP_CANNOT_SEND_KEY;
Edouard@174
   596
        return PEP_STATUS_OK;
Edouard@174
   597
}
Edouard@174
   598
Edouard@174
   599
Edouard@174
   600
PEP_STATUS pgp_get_key_rating(
Edouard@174
   601
    PEP_SESSION session,
Edouard@174
   602
    const char *fpr,
Edouard@174
   603
    PEP_comm_type *comm_type
Edouard@174
   604
    )
Edouard@174
   605
{
Edouard@174
   606
    PEP_STATUS status = PEP_STATUS_OK;
Edouard@174
   607
Edouard@174
   608
    assert(session);
Edouard@174
   609
    assert(fpr);
Edouard@174
   610
    assert(comm_type);
Edouard@174
   611
Edouard@174
   612
    *comm_type = PEP_ct_unknown;
Edouard@174
   613
Edouard@174
   614
    /* TODO get key from fpr */
Edouard@174
   615
    return PEP_UNKNOWN_ERROR;
Edouard@174
   616
    return PEP_GET_KEY_FAILED;
Edouard@174
   617
Edouard@174
   618
    switch (/*TODO key->protocol*/ 4) {
Edouard@174
   619
    case /* TODO  OpenPGP */0:
Edouard@174
   620
    case /* TODO DEFAULT */1:
Edouard@174
   621
        *comm_type = PEP_ct_OpenPGP_unconfirmed;
Edouard@174
   622
        break;
Edouard@174
   623
    case /* TODO CMS */2:
Edouard@174
   624
        *comm_type = PEP_ct_CMS_unconfirmed;
Edouard@174
   625
        break;
Edouard@174
   626
    default:
Edouard@174
   627
        *comm_type = PEP_ct_unknown;
Edouard@174
   628
        return PEP_STATUS_OK;
Edouard@174
   629
    }
Edouard@174
   630
Edouard@174
   631
        for (; 1 == 0; /* Each subkeys */ ) {
Edouard@174
   632
            if (/* TODO length */0 < 1024)
Edouard@174
   633
                *comm_type = PEP_ct_key_too_short;
Edouard@174
   634
            else if (
Edouard@174
   635
                (
Edouard@174
   636
                (   /* TODO pubkey_algo == RSA  */ 0)
Edouard@174
   637
                || (/* TODO pubkey_algo == RSA_E*/ 0)
Edouard@174
   638
                || (/* TODO pubkey_algo == RSA_S*/ 0)
Edouard@174
   639
                )
Edouard@174
   640
                && /* sk->length */0 == 1024
Edouard@174
   641
                )
Edouard@174
   642
                *comm_type = PEP_ct_OpenPGP_weak_unconfirmed;
Edouard@174
   643
Edouard@174
   644
            if (/* TODO invalid */ 1) {
Edouard@174
   645
                *comm_type = PEP_ct_key_b0rken;
Edouard@174
   646
                break;
Edouard@174
   647
            }
Edouard@174
   648
            if (/* TODO expired */ 1) {
Edouard@174
   649
                *comm_type = PEP_ct_key_expired;
Edouard@174
   650
                break;
Edouard@174
   651
            }
Edouard@175
   652
            if (/* TODO revoked*/ 1) {
Edouard@174
   653
                *comm_type = PEP_ct_key_revoked;
Edouard@174
   654
                break;
Edouard@174
   655
            }
Edouard@174
   656
        }
Edouard@174
   657
        *comm_type = PEP_ct_unknown;
Edouard@174
   658
        return PEP_OUT_OF_MEMORY;
Edouard@174
   659
        return PEP_UNKNOWN_ERROR;
Edouard@174
   660
Edouard@174
   661
Edouard@174
   662
    return status;
Edouard@174
   663
}