src/pgp_netpgp.c
author Volker Birk <vb@pep-project.org>
Wed, 29 Apr 2015 14:51:33 +0200
changeset 229 313d152239bf
parent 228 4e6728cddb3f
child 243 c38813173fc7
permissions -rw-r--r--
fixing preprocessor
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@228
    14
#include <netpgp/readerwriter.h>
Edouard@179
    15
Edouard@188
    16
#include <regex.h>
Edouard@188
    17
Edouard@185
    18
#define PEP_NETPGP_DEBUG
Edouard@185
    19
Edouard@174
    20
PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
Edouard@174
    21
{
Edouard@179
    22
    netpgp_t *netpgp;
Edouard@174
    23
    PEP_STATUS status = PEP_STATUS_OK;
Edouard@175
    24
    const char *home = NULL;
Edouard@179
    25
Edouard@179
    26
    assert(session);
Edouard@179
    27
    if(!session) return PEP_UNKNOWN_ERROR;
Edouard@179
    28
Edouard@179
    29
    netpgp = &session->ctx;
Edouard@174
    30
   
Edouard@174
    31
    if (in_first) {
Edouard@175
    32
        if (strcmp(setlocale(LC_ALL, NULL), "C") == 0)
Edouard@175
    33
            setlocale(LC_ALL, "");
Edouard@174
    34
    }
Edouard@174
    35
Edouard@185
    36
    memset(netpgp, 0x0, sizeof(session->ctx));
Edouard@174
    37
Edouard@180
    38
    // netpgp_setvar(netpgp, "max mem alloc", "4194304");
Edouard@180
    39
    netpgp_setvar(netpgp, "need seckey", "1");
Edouard@180
    40
    netpgp_setvar(netpgp, "need userid", "1");
Edouard@180
    41
Edouard@175
    42
    // NetPGP shares home with GPG
Edouard@175
    43
    home = gpg_home();
Edouard@175
    44
    if(home){
Edouard@179
    45
        netpgp_set_homedir(netpgp,(char*)home, NULL, 0);
Edouard@175
    46
    }else{
Edouard@175
    47
        status = PEP_INIT_NO_GPG_HOME;
Edouard@175
    48
        goto pep_error;
Edouard@174
    49
    }
Edouard@174
    50
Edouard@175
    51
    // pair with gpg's cert-digest-algo
Edouard@185
    52
    netpgp_setvar(netpgp, "hash", "SHA256");
Edouard@175
    53
Edouard@175
    54
    // subset of gpg's personal-cipher-preferences
Edouard@175
    55
    // here only one cipher can be selected
Edouard@225
    56
    netpgp_setvar(netpgp, "cipher", "CAST5");
Edouard@175
    57
Edouard@185
    58
    if (!netpgp_init(netpgp)) {
Edouard@175
    59
        status = PEP_INIT_NETPGP_INIT_FAILED;
Edouard@174
    60
        goto pep_error;
Edouard@174
    61
    }
Edouard@174
    62
Edouard@174
    63
    return PEP_STATUS_OK;
Edouard@174
    64
Edouard@174
    65
pep_error:
Edouard@174
    66
    pgp_release(session, in_first);
Edouard@174
    67
    return status;
Edouard@174
    68
}
Edouard@174
    69
Edouard@174
    70
void pgp_release(PEP_SESSION session, bool out_last)
Edouard@174
    71
{
Edouard@179
    72
    netpgp_t *netpgp;
Edouard@179
    73
Edouard@179
    74
    assert(session);
Edouard@179
    75
    if(!session) return;
Edouard@179
    76
Edouard@179
    77
    netpgp = &session->ctx;
Edouard@179
    78
Edouard@185
    79
    netpgp_end(netpgp);
Edouard@185
    80
    memset(netpgp, 0x0, sizeof(session->ctx));
Edouard@174
    81
Edouard@175
    82
    // out_last unused here
Edouard@174
    83
}
Edouard@174
    84
Edouard@207
    85
// return 1 if the file contains ascii-armoured text 
Edouard@207
    86
// buf MUST be \0 terminated to be checked for armour
Edouard@188
    87
static unsigned
Edouard@188
    88
_armoured(const char *buf, size_t size, const char *pattern)
Edouard@188
    89
{
Edouard@188
    90
    unsigned armoured = 0;
Edouard@188
    91
    if(buf[size]=='\0'){
Edouard@188
    92
        regex_t r;
Edouard@188
    93
        regcomp(&r, pattern, REG_EXTENDED|REG_NEWLINE|REG_NOSUB);
Edouard@188
    94
        if (regexec(&r, buf, 0, NULL, 0) == 0) {
Edouard@188
    95
            armoured = 1;
Edouard@188
    96
        }
Edouard@188
    97
        regfree(&r);
Edouard@188
    98
    }
Edouard@188
    99
    return armoured;
Edouard@188
   100
}
Edouard@188
   101
Edouard@227
   102
/* return key ID's hexdump as a string */
Edouard@227
   103
static void id_to_str(const uint8_t *userid, char *fpr)
Edouard@225
   104
{
Edouard@225
   105
    int i;
Edouard@225
   106
    static const char *hexes = "0123456789abcdef";
Edouard@225
   107
    for (i = 0; i < 8 ; i++) {
Edouard@225
   108
        fpr[i * 2] = hexes[(unsigned)(userid[i] & 0xf0) >> 4];
Edouard@225
   109
        fpr[(i * 2) + 1] = hexes[userid[i] & 0xf];
Edouard@225
   110
    }
Edouard@225
   111
    fpr[8 * 2] = 0x0;
Edouard@225
   112
}
Edouard@225
   113
Edouard@185
   114
// Iterate through netpgp' reported valid signatures 
Edouard@185
   115
// fill a list of valid figerprints
Edouard@185
   116
// returns PEP_STATUS_OK if all sig reported valid
Edouard@185
   117
// error status otherwise.
Edouard@185
   118
static PEP_STATUS _validation_results(netpgp_t *netpgp, pgp_validation_t *vresult,
Edouard@185
   119
                                             stringlist_t **_keylist)
Edouard@185
   120
{
Edouard@188
   121
    time_t    now;
Edouard@188
   122
    time_t    t;
Edouard@188
   123
    char    buf[128];
Edouard@185
   124
Edouard@188
   125
    now = time(NULL);
Edouard@188
   126
    if (now < vresult->birthtime) {
Edouard@188
   127
        // signature is not valid yet
Edouard@185
   128
#ifdef PEP_NETPGP_DEBUG
Edouard@188
   129
        (void) printf(
Edouard@188
   130
            "signature not valid until %.24s\n",
Edouard@188
   131
            ctime(&vresult->birthtime));
Edouard@185
   132
#endif //PEP_NETPGP_DEBUG
Edouard@188
   133
        return PEP_UNENCRYPTED;
Edouard@188
   134
    }
Edouard@188
   135
    if (vresult->duration != 0 && now > vresult->birthtime + vresult->duration) {
Edouard@188
   136
        // signature has expired
Edouard@188
   137
        t = vresult->duration + vresult->birthtime;
Edouard@185
   138
#ifdef PEP_NETPGP_DEBUG
Edouard@188
   139
        (void) printf(
Edouard@188
   140
            "signature not valid after %.24s\n",
Edouard@188
   141
            ctime(&t));
Edouard@185
   142
#endif //PEP_NETPGP_DEBUG
Edouard@188
   143
        return PEP_UNENCRYPTED;
Edouard@188
   144
    }
Edouard@185
   145
    if (vresult->validc && vresult->valid_sigs &&
Edouard@185
   146
        !vresult->invalidc && !vresult->unknownc ) {
Edouard@185
   147
        unsigned    n;
Edouard@185
   148
        stringlist_t *k;
Edouard@185
   149
        // caller responsible to free
Edouard@185
   150
        *_keylist = new_stringlist(NULL);
Edouard@185
   151
        assert(*_keylist);
Edouard@185
   152
        if (*_keylist == NULL) {
Edouard@185
   153
            return PEP_OUT_OF_MEMORY;
Edouard@185
   154
        }
Edouard@185
   155
        k = *_keylist;
Edouard@185
   156
        for (n = 0; n < vresult->validc; ++n) {
Edouard@185
   157
            char id[MAX_ID_LENGTH + 1];
Edouard@185
   158
            const uint8_t *userid = vresult->valid_sigs[n].signer_id;
Edouard@185
   159
Edouard@185
   160
#ifdef PEP_NETPGP_DEBUG
Edouard@185
   161
            const pgp_key_t *key;
Edouard@185
   162
            pgp_pubkey_t *sigkey;
Edouard@188
   163
            unsigned from = 0;
Edouard@185
   164
            key = pgp_getkeybyid(netpgp->io, netpgp->pubring,
Edouard@185
   165
                (const uint8_t *) vresult->valid_sigs[n].signer_id,
Edouard@185
   166
                &from, &sigkey);
Edouard@185
   167
            pgp_print_keydata(netpgp->io, netpgp->pubring, key, "valid signature ", &key->key.pubkey, 0);
Edouard@185
   168
#endif //PEP_NETPGP_DEBUG
Edouard@185
   169
Edouard@227
   170
            id_to_str(userid, id);
Edouard@185
   171
Edouard@185
   172
            k = stringlist_add(k, id);
Edouard@185
   173
            if(!k){
Edouard@185
   174
                free_stringlist(*_keylist);
Edouard@185
   175
                return PEP_OUT_OF_MEMORY;
Edouard@185
   176
            }
Edouard@185
   177
        }
Edouard@185
   178
        return PEP_STATUS_OK;
Edouard@185
   179
    }
Edouard@185
   180
    if (vresult->validc + vresult->invalidc + vresult->unknownc == 0) {
Edouard@185
   181
        // No signatures found - is this memory signed?
Edouard@185
   182
        return PEP_VERIFY_NO_KEY; 
Edouard@185
   183
    } 
Edouard@185
   184
    
Edouard@185
   185
    if (vresult->invalidc) {
Edouard@185
   186
        // some invalid signatures
Edouard@185
   187
Edouard@185
   188
#ifdef PEP_NETPGP_DEBUG
Edouard@185
   189
        unsigned    n;
Edouard@185
   190
        for (n = 0; n < vresult->invalidc; ++n) {
Edouard@185
   191
            const pgp_key_t *key;
Edouard@185
   192
            pgp_pubkey_t *sigkey;
Edouard@185
   193
            unsigned from = 0;
Edouard@185
   194
            key = pgp_getkeybyid(netpgp->io, netpgp->pubring,
Edouard@185
   195
                (const uint8_t *) vresult->invalid_sigs[n].signer_id,
Edouard@185
   196
                &from, &sigkey);
Edouard@185
   197
            pgp_print_keydata(netpgp->io, netpgp->pubring, key, "invalid signature ", &key->key.pubkey, 0);
Edouard@188
   198
            if (sigkey->duration != 0 && now > sigkey->birthtime + sigkey->duration) {
Edouard@185
   199
                printf("EXPIRED !\n");
Edouard@185
   200
            }
Edouard@185
   201
        }
Edouard@185
   202
#endif //PEP_NETPGP_DEBUG
Edouard@185
   203
Edouard@185
   204
        return PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
Edouard@185
   205
    }
Edouard@185
   206
    
Edouard@185
   207
    // only unknown sigs
Edouard@185
   208
    return PEP_DECRYPT_WRONG_FORMAT;
Edouard@185
   209
}
Edouard@185
   210
Edouard@207
   211
#define ARMOR_HEAD    "^-----BEGIN PGP MESSAGE-----\\s*$"
Edouard@174
   212
PEP_STATUS pgp_decrypt_and_verify(
Edouard@174
   213
    PEP_SESSION session, const char *ctext, size_t csize,
Edouard@174
   214
    char **ptext, size_t *psize, stringlist_t **keylist
Edouard@174
   215
    )
Edouard@174
   216
{
Edouard@179
   217
    netpgp_t *netpgp;
Edouard@185
   218
    pgp_memory_t *mem;
Edouard@185
   219
    pgp_memory_t *cat;
Edouard@185
   220
    pgp_validation_t *vresult;
Edouard@180
   221
    char *_ptext = NULL;
Edouard@180
   222
    size_t _psize = 0;
Edouard@185
   223
    int ret;
Edouard@179
   224
Edouard@174
   225
    PEP_STATUS result;
Edouard@174
   226
    stringlist_t *_keylist = NULL;
Edouard@174
   227
    int i_key = 0;
Edouard@174
   228
Edouard@174
   229
    assert(session);
Edouard@174
   230
    assert(ctext);
Edouard@174
   231
    assert(csize);
Edouard@174
   232
    assert(ptext);
Edouard@174
   233
    assert(psize);
Edouard@174
   234
    assert(keylist);
Edouard@174
   235
Edouard@179
   236
    if(!session || !ctext || !csize || !ptext || !psize || !keylist) 
Edouard@179
   237
        return PEP_UNKNOWN_ERROR;
Edouard@179
   238
Edouard@179
   239
    netpgp = &session->ctx;
Edouard@179
   240
Edouard@174
   241
    *ptext = NULL;
Edouard@174
   242
    *psize = 0;
Edouard@174
   243
    *keylist = NULL;
Edouard@174
   244
Edouard@183
   245
    vresult = malloc(sizeof(pgp_validation_t));
Edouard@185
   246
    memset(vresult, 0x0, sizeof(pgp_validation_t));
Edouard@182
   247
Edouard@183
   248
    mem = pgp_decrypt_and_validate_buf(netpgp->io, vresult, ctext, csize,
Edouard@179
   249
                netpgp->secring, netpgp->pubring,
Edouard@188
   250
                _armoured(ctext, csize, ARMOR_HEAD),
Edouard@179
   251
                0 /* sshkeys */,
Edouard@180
   252
                NULL, -1, NULL  /* pass fp,attempts,cb */);
Edouard@179
   253
    if (mem == NULL) {
Edouard@179
   254
        return PEP_OUT_OF_MEMORY;
Edouard@179
   255
    }
Edouard@179
   256
Edouard@185
   257
    _psize = pgp_mem_len(mem);
Edouard@182
   258
    if (_psize){
Edouard@182
   259
        if ((_ptext = calloc(1, _psize)) == NULL) {
Edouard@183
   260
            result = PEP_OUT_OF_MEMORY;
Edouard@183
   261
            goto free_pgp;
Edouard@182
   262
        }
Edouard@185
   263
        memcpy(_ptext, pgp_mem_data(mem), _psize);
Edouard@182
   264
        result = PEP_DECRYPTED;
Edouard@182
   265
    }else{
Edouard@183
   266
        result = PEP_DECRYPT_NO_KEY;
Edouard@183
   267
        goto free_pgp;
Edouard@182
   268
    }
Edouard@180
   269
Edouard@185
   270
    if (result == PEP_DECRYPTED) {
Edouard@185
   271
        result = _validation_results(netpgp, vresult, &_keylist);
Edouard@185
   272
        if (result != PEP_STATUS_OK) {
Edouard@185
   273
            goto free_ptext;
Edouard@183
   274
        }
Edouard@180
   275
        result = PEP_DECRYPTED_AND_VERIFIED;
Edouard@180
   276
    }
Edouard@174
   277
Edouard@180
   278
    if (result == PEP_DECRYPTED_AND_VERIFIED
Edouard@180
   279
        || result == PEP_DECRYPTED) {
Edouard@180
   280
        *ptext = _ptext;
Edouard@180
   281
        *psize = _psize;
Edouard@180
   282
        (*ptext)[*psize] = 0; // safeguard for naive users
Edouard@185
   283
        if (result == PEP_DECRYPTED_AND_VERIFIED) {
Edouard@185
   284
            *keylist = _keylist;
Edouard@185
   285
        }
Edouard@183
   286
Edouard@183
   287
        /* _ptext and _keylist ownership transfer, don't free */
Edouard@183
   288
        goto free_pgp;
Edouard@180
   289
    }
Edouard@183
   290
Edouard@183
   291
free_keylist:
Edouard@183
   292
    free_stringlist(_keylist);
Edouard@183
   293
Edouard@183
   294
free_ptext:
Edouard@183
   295
    free(_ptext);
Edouard@183
   296
Edouard@183
   297
free_pgp:
Edouard@185
   298
    pgp_memory_free(mem);
Edouard@183
   299
    pgp_validate_result_free(vresult);
Edouard@183
   300
Edouard@174
   301
    return result;
Edouard@174
   302
}
Edouard@174
   303
Edouard@207
   304
#define ARMOR_SIG_HEAD    "^-----BEGIN PGP (SIGNATURE|SIGNED MESSAGE)-----\\s*$"
Edouard@174
   305
PEP_STATUS pgp_verify_text(
Edouard@174
   306
    PEP_SESSION session, const char *text, size_t size,
Edouard@174
   307
    const char *signature, size_t sig_size, stringlist_t **keylist
Edouard@174
   308
    )
Edouard@174
   309
{
Edouard@185
   310
    netpgp_t *netpgp;
Edouard@185
   311
    pgp_memory_t *signedmem;
Edouard@185
   312
    pgp_memory_t *sig;
Edouard@185
   313
    pgp_validation_t *vresult;
Edouard@185
   314
Edouard@174
   315
    PEP_STATUS result;
Edouard@174
   316
    stringlist_t *_keylist;
Edouard@174
   317
Edouard@174
   318
    assert(session);
Edouard@174
   319
    assert(text);
Edouard@174
   320
    assert(size);
Edouard@174
   321
    assert(signature);
Edouard@174
   322
    assert(sig_size);
Edouard@174
   323
    assert(keylist);
Edouard@174
   324
Edouard@185
   325
    if(!session || !text || !size || !signature || !sig_size || !keylist) 
Edouard@185
   326
        return PEP_UNKNOWN_ERROR;
Edouard@185
   327
Edouard@185
   328
    netpgp = &session->ctx;
Edouard@185
   329
Edouard@174
   330
    *keylist = NULL;
Edouard@185
   331
Edouard@185
   332
    vresult = malloc(sizeof(pgp_validation_t));
Edouard@185
   333
    memset(vresult, 0x0, sizeof(pgp_validation_t));
Edouard@185
   334
Edouard@185
   335
    signedmem = pgp_memory_new();
Edouard@185
   336
    if (signedmem == NULL) {
Edouard@185
   337
        return PEP_OUT_OF_MEMORY;
Edouard@185
   338
    }
Edouard@185
   339
    pgp_memory_add(signedmem, (const uint8_t*)text, size);
Edouard@185
   340
Edouard@185
   341
    sig = pgp_memory_new();
Edouard@185
   342
    if (sig == NULL) {
Edouard@185
   343
        pgp_memory_free(signedmem);
Edouard@185
   344
        return PEP_OUT_OF_MEMORY;
Edouard@185
   345
    }
Edouard@185
   346
    pgp_memory_add(sig, (const uint8_t*)signature, sig_size);
Edouard@185
   347
Edouard@185
   348
    pgp_validate_mem_detached(netpgp->io, vresult, sig,
Edouard@185
   349
                NULL,/* output */
Edouard@207
   350
                _armoured(signature, sig_size, ARMOR_SIG_HEAD),
Edouard@185
   351
                netpgp->pubring,
Edouard@185
   352
                signedmem);
Edouard@185
   353
Edouard@185
   354
    result = _validation_results(netpgp, vresult, &_keylist);
Edouard@185
   355
    if (result != PEP_STATUS_OK) {
Edouard@185
   356
        goto free_pgp;
Edouard@185
   357
    }else{
Edouard@185
   358
        result = PEP_VERIFIED;
Edouard@185
   359
    }
Edouard@185
   360
Edouard@185
   361
    if (result == PEP_VERIFIED) {
Edouard@185
   362
        /* TODO : check trust level */
Edouard@185
   363
        result = PEP_VERIFIED_AND_TRUSTED;
Edouard@185
   364
    }
Edouard@185
   365
Edouard@185
   366
    if (result == PEP_VERIFIED || result == PEP_VERIFIED_AND_TRUSTED) {
Edouard@185
   367
        *keylist = _keylist;
Edouard@185
   368
Edouard@185
   369
        /* _keylist ownership transfer, don't free */
Edouard@185
   370
        goto free_pgp;
Edouard@185
   371
    }
Edouard@185
   372
Edouard@185
   373
free_keylist:
Edouard@185
   374
    free_stringlist(_keylist);
Edouard@185
   375
Edouard@185
   376
free_pgp:
Edouard@187
   377
    // free done by pgp_validate_mem_detached
Edouard@187
   378
    // pgp_memory_free(sig);
Edouard@187
   379
    // pgp_memory_free(signedmem);
Edouard@185
   380
    pgp_validate_result_free(vresult);
Edouard@185
   381
Edouard@185
   382
    return result;
Edouard@174
   383
}
Edouard@174
   384
Edouard@174
   385
PEP_STATUS pgp_encrypt_and_sign(
Edouard@174
   386
    PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
Edouard@174
   387
    size_t psize, char **ctext, size_t *csize
Edouard@174
   388
    )
Edouard@174
   389
{
Edouard@207
   390
    netpgp_t *netpgp;
Edouard@207
   391
    const pgp_key_t *keypair;
Edouard@207
   392
    pgp_seckey_t *seckey;
Edouard@209
   393
    pgp_memory_t *signedmem;
Edouard@209
   394
    pgp_memory_t *cmem;
Edouard@207
   395
    const char *userid;
Edouard@207
   396
    const char *hashalg;
Edouard@209
   397
    pgp_keyring_t *rcpts;
Edouard@207
   398
Edouard@174
   399
    PEP_STATUS result;
Edouard@174
   400
    const stringlist_t *_keylist;
Edouard@174
   401
Edouard@174
   402
    assert(session);
Edouard@174
   403
    assert(keylist);
Edouard@174
   404
    assert(ptext);
Edouard@174
   405
    assert(psize);
Edouard@174
   406
    assert(ctext);
Edouard@174
   407
    assert(csize);
Edouard@174
   408
Edouard@207
   409
    if(!session || !ptext || !psize || !ctext || !csize || !keylist) 
Edouard@207
   410
        return PEP_UNKNOWN_ERROR;
Edouard@207
   411
Edouard@208
   412
    netpgp = &session->ctx;
Edouard@208
   413
Edouard@174
   414
    *ctext = NULL;
Edouard@174
   415
    *csize = 0;
Edouard@174
   416
Edouard@207
   417
    // Get signing details from netpgp
Edouard@207
   418
    if ((userid = netpgp_getvar(netpgp, "userid")) == NULL || 
Edouard@207
   419
        (keypair = pgp_getkeybyname(netpgp->io, netpgp->secring, userid)) == NULL ||
Edouard@207
   420
        (seckey = pgp_decrypt_seckey(keypair, NULL /*passfp*/)) == NULL) {
Edouard@207
   421
        return PEP_UNKNOWN_ERROR;
Edouard@207
   422
    }
Edouard@209
   423
Edouard@207
   424
    hashalg = netpgp_getvar(netpgp, "hash");
Edouard@209
   425
    // netpgp (l)imitation - XXX why ? 
Edouard@207
   426
    if (seckey->pubkey.alg == PGP_PKA_DSA) {
Edouard@209
   427
        hashalg = "sha1";
Edouard@207
   428
    }
Edouard@207
   429
Edouard@207
   430
    // Sign data
Edouard@207
   431
    signedmem = pgp_sign_buf(netpgp->io, ptext, psize, seckey,
Edouard@209
   432
                time(NULL), /* birthtime */
Edouard@209
   433
                0 /* duration */,
Edouard@209
   434
                hashalg, 
Edouard@207
   435
                0 /* armored */,
Edouard@207
   436
                0 /* cleartext */);
Edouard@207
   437
Edouard@207
   438
    pgp_forget(seckey, (unsigned)sizeof(*seckey));
Edouard@207
   439
Edouard@207
   440
    if (!signedmem) {
Edouard@207
   441
        return PEP_UNENCRYPTED;
Edouard@207
   442
    }
Edouard@207
   443
Edouard@207
   444
    // Encrypt signed data
Edouard@209
   445
    if ((rcpts = calloc(1, sizeof(*rcpts))) == NULL) {
Edouard@209
   446
        result = PEP_OUT_OF_MEMORY;
Edouard@209
   447
        goto free_signedmem;
Edouard@209
   448
    }
Edouard@209
   449
    for (_keylist = keylist; _keylist != NULL; _keylist = _keylist->next) {
Edouard@174
   450
        assert(_keylist->value);
Edouard@209
   451
        // get key from netpgp's pubring
Edouard@209
   452
        const pgp_key_t *key;
Edouard@209
   453
        key = pgp_getkeybyname(netpgp->io,
Edouard@209
   454
                               netpgp->pubring,
Edouard@209
   455
                               _keylist->value);
Edouard@209
   456
Edouard@209
   457
        if(key == NULL){
Edouard@209
   458
            result = PEP_KEY_NOT_FOUND;
Edouard@209
   459
            goto free_rcpts;
Edouard@209
   460
        }
Edouard@209
   461
#ifdef PEP_NETPGP_DEBUG
Edouard@209
   462
        pgp_print_keydata(netpgp->io, netpgp->pubring, key,
Edouard@209
   463
                          "recipient pubkey ", &key->key.pubkey, 0);
Edouard@209
   464
#endif //PEP_NETPGP_DEBUG
Edouard@209
   465
Edouard@209
   466
        // add key to recipients/signers
Edouard@209
   467
        pgp_keyring_add(rcpts, key);
Edouard@209
   468
        if(rcpts->keys == NULL){
Edouard@209
   469
            result = PEP_OUT_OF_MEMORY;
Edouard@209
   470
            goto free_signedmem;
Edouard@209
   471
        }
Edouard@174
   472
    }
Edouard@174
   473
Edouard@209
   474
    cmem = pgp_encrypt_buf(netpgp->io, pgp_mem_data(signedmem),
Edouard@209
   475
            pgp_mem_len(signedmem), rcpts, 1 /* armored */,
Edouard@209
   476
            netpgp_getvar(netpgp, "cipher"), 
Edouard@209
   477
            1 /* takes raw OpenPGP message */);
Edouard@209
   478
Edouard@209
   479
    if (cmem == NULL) {
Edouard@209
   480
        result = PEP_OUT_OF_MEMORY;
Edouard@209
   481
        goto free_signedmem;
Edouard@209
   482
    }else{
Edouard@209
   483
Edouard@209
   484
        char *_buffer = NULL;
Edouard@209
   485
        size_t length = pgp_mem_len(cmem);
Edouard@174
   486
Edouard@209
   487
        // Allocate transferable buffer
Edouard@209
   488
        _buffer = malloc(length + 1);
Edouard@209
   489
        assert(_buffer);
Edouard@209
   490
        if (_buffer == NULL) {
Edouard@209
   491
            result = PEP_OUT_OF_MEMORY;
Edouard@209
   492
            goto free_cmem;
Edouard@209
   493
        }
Edouard@209
   494
Edouard@209
   495
        memcpy(_buffer, pgp_mem_data(cmem), length);
Edouard@209
   496
Edouard@209
   497
        *ctext = _buffer;
Edouard@209
   498
        *csize = length;
Edouard@209
   499
        (*ctext)[*csize] = 0; // safeguard for naive users
Edouard@209
   500
        result = PEP_STATUS_OK;
Edouard@174
   501
    }
Edouard@174
   502
Edouard@209
   503
free_cmem :
Edouard@209
   504
    pgp_memory_free(cmem);
Edouard@209
   505
free_rcpts :
Edouard@209
   506
    pgp_keyring_free(rcpts);
Edouard@209
   507
free_signedmem :
Edouard@209
   508
    pgp_memory_free(signedmem);
Edouard@175
   509
Edouard@174
   510
    return result;
Edouard@174
   511
}
Edouard@174
   512
Edouard@227
   513
/* return the hexdump as a string */
Edouard@227
   514
static unsigned
Edouard@227
   515
fpr_to_str (char **str, const uint8_t *fpr, size_t length)
Edouard@227
   516
{
Edouard@228
   517
    unsigned i;
Edouard@228
   518
    int	n;
Edouard@227
   519
Edouard@227
   520
    /* 5 char per byte (hexes + space) tuple -1 space at the end + null */
Edouard@227
   521
    *str = malloc((length / 2) * 5 - 1 + 1);
Edouard@227
   522
Edouard@227
   523
    if(*str == NULL)
Edouard@227
   524
        return 0;
Edouard@227
   525
Edouard@228
   526
    for (n = 0, i = 0 ; i < length - 1; i += 2) {
Edouard@228
   527
    	n += snprintf(&((*str)[n]), 6, "%02x%02x ", *fpr++, *fpr++);
Edouard@228
   528
    }
Edouard@227
   529
    snprintf(&((*str)[n]), 5, "%02x%02x", *fpr++, *fpr++);
Edouard@227
   530
Edouard@228
   531
    return 1;
Edouard@227
   532
}
Edouard@227
   533
Edouard@227
   534
static unsigned
Edouard@227
   535
str_to_fpr (const char *str, uint8_t *fpr, size_t *length)
Edouard@227
   536
{
Edouard@227
   537
    unsigned i,j;
Edouard@227
   538
Edouard@227
   539
    *length = 0;
Edouard@227
   540
Edouard@227
   541
    while(*str && *length < PGP_FINGERPRINT_SIZE){
Edouard@227
   542
        while (*str == ' ') str++;
Edouard@227
   543
        for (j = 0; j < 2; j++) {
Edouard@227
   544
            uint8_t *byte = &fpr[*length];
Edouard@227
   545
            for (i = 0; i < 2; i++) {
Edouard@227
   546
                if (i > 0)
Edouard@227
   547
                    *byte *= 16;
Edouard@227
   548
                if (*str >= 'a' && *str <= 'f')
Edouard@227
   549
                    *byte += 10 + *str - 'a';
Edouard@227
   550
                else if (*str >= 'A' && *str <= 'F')
Edouard@227
   551
                    *byte += 10 + *str - 'A';
Edouard@227
   552
                else if (*str >= '0' && *str <= '9')
Edouard@227
   553
                    *byte += *str - '0';
Edouard@227
   554
                else 
Edouard@227
   555
                    return 0;
Edouard@227
   556
                str++;
Edouard@227
   557
            }
Edouard@227
   558
            *length++;
Edouard@227
   559
        }
Edouard@227
   560
    }
Edouard@227
   561
    return 1;
Edouard@227
   562
}
Edouard@227
   563
Edouard@228
   564
static PEP_STATUS import_key_or_keypair(netpgp_t *netpgp, pgp_key_t *newkey){
Edouard@228
   565
    pgp_key_t	pubkey;
Edouard@228
   566
    unsigned public;
Edouard@228
   567
    PEP_STATUS result;
Edouard@228
   568
Edouard@228
   569
    if ((public = (newkey->type == PGP_PTAG_CT_PUBLIC_KEY))){
Edouard@228
   570
        pubkey = *newkey;
Edouard@228
   571
    } else {
Edouard@228
   572
        // Duplicate key as public only
Edouard@228
   573
        if (!pgp_keydata_dup(&pubkey, newkey, 1 /* make_public */)){
Edouard@228
   574
            return PEP_OUT_OF_MEMORY;
Edouard@228
   575
        }
Edouard@228
   576
    }
Edouard@228
   577
Edouard@228
   578
    // Append generated key to netpgp's rings (key ownership transfered)
Edouard@228
   579
    if (!public && !pgp_keyring_add(netpgp->secring, newkey)){
Edouard@228
   580
        result = PEP_OUT_OF_MEMORY;
Edouard@228
   581
        goto free_pubkey;
Edouard@228
   582
    } else if (!pgp_keyring_add(netpgp->pubring, &pubkey)){
Edouard@228
   583
        result = PEP_OUT_OF_MEMORY;
Edouard@228
   584
        goto pop_secring;
Edouard@228
   585
    }
Edouard@228
   586
Edouard@228
   587
    // save rings 
Edouard@228
   588
    if (netpgp_save_pubring(netpgp) && 
Edouard@228
   589
        (!public || netpgp_save_secring(netpgp)))
Edouard@228
   590
    {
Edouard@228
   591
        /* free nothing, everything transfered */
Edouard@228
   592
        return PEP_STATUS_OK;
Edouard@228
   593
    } else {
Edouard@228
   594
        /* XXX in case only pubring save succeed
Edouard@228
   595
         * pubring file is left as-is, but backup restore
Edouard@228
   596
         * could be attempted if such corner case matters */
Edouard@228
   597
        result = PEP_UNKNOWN_ERROR;
Edouard@228
   598
    }
Edouard@228
   599
Edouard@228
   600
pop_pubring:
Edouard@228
   601
    ((pgp_keyring_t *)netpgp->pubring)->keyc--;
Edouard@228
   602
pop_secring:
Edouard@228
   603
    ((pgp_keyring_t *)netpgp->secring)->keyc--;
Edouard@228
   604
free_pubkey:
Edouard@228
   605
    pgp_key_free(&pubkey);
Edouard@228
   606
Edouard@228
   607
    return result;
Edouard@228
   608
}
Edouard@228
   609
Edouard@174
   610
PEP_STATUS pgp_generate_keypair(
Edouard@174
   611
    PEP_SESSION session, pEp_identity *identity
Edouard@174
   612
    )
Edouard@174
   613
{
Edouard@225
   614
    netpgp_t *netpgp;
Edouard@228
   615
    pgp_key_t	newkey;
Edouard@228
   616
    pgp_key_t	pubkey;
Edouard@225
   617
Edouard@225
   618
    PEP_STATUS result;
Edouard@228
   619
    char newid[1024];
Edouard@225
   620
    const char *hashalg;
Edouard@225
   621
    const char *cipher;
Edouard@228
   622
    char *fprstr = NULL;
Edouard@174
   623
Edouard@174
   624
    assert(session);
Edouard@174
   625
    assert(identity);
Edouard@174
   626
    assert(identity->address);
Edouard@174
   627
    assert(identity->fpr == NULL);
Edouard@174
   628
    assert(identity->username);
Edouard@174
   629
Edouard@225
   630
    if(!session || !identity || 
Edouard@225
   631
       !identity->address || identity->fpr || !identity->username)
Edouard@225
   632
        return PEP_UNKNOWN_ERROR;
Edouard@174
   633
Edouard@225
   634
    netpgp = &session->ctx;
Edouard@225
   635
Edouard@225
   636
    if(snprintf(newid, sizeof(newid),
Edouard@225
   637
        "%s <%s>", identity->username, identity->address) >= sizeof(newid)){
Edouard@174
   638
        return PEP_BUFFER_TOO_SMALL;
Edouard@174
   639
    }
Edouard@225
   640
    
Edouard@225
   641
    hashalg = netpgp_getvar(netpgp, "hash");
Edouard@225
   642
    cipher = netpgp_getvar(netpgp, "cipher");
Edouard@174
   643
Edouard@225
   644
    bzero(&newkey, sizeof(newkey));
Edouard@225
   645
    bzero(&pubkey, sizeof(pubkey));
Edouard@174
   646
Edouard@225
   647
    // Generate the key
Edouard@225
   648
    if (!pgp_rsa_generate_keypair(&newkey, 4096, 65537UL, hashalg, cipher,
Edouard@225
   649
                                  (const uint8_t *) "", (const size_t) 0) ||
Edouard@228
   650
        !pgp_add_selfsigned_userid(&newkey, (uint8_t *)newid)) {
Edouard@228
   651
        result = PEP_CANNOT_CREATE_KEY;
Edouard@228
   652
        goto free_newkey;
Edouard@228
   653
    }
Edouard@225
   654
Edouard@225
   655
    // TODO "Expire-Date: 1y\n";
Edouard@225
   656
Edouard@228
   657
    fpr_to_str(&fprstr,
Edouard@228
   658
               newkey.sigfingerprint.fingerprint,
Edouard@228
   659
               newkey.sigfingerprint.length);
Edouard@228
   660
    if (fprstr == NULL) {
Edouard@228
   661
        result = PEP_OUT_OF_MEMORY;
Edouard@228
   662
        goto free_newkey;
Edouard@228
   663
    } 
Edouard@174
   664
Edouard@228
   665
    result = import_key_or_keypair(netpgp, &newkey);
Edouard@225
   666
Edouard@228
   667
    if (result == PEP_STATUS_OK) {
Edouard@228
   668
        identity->fpr = fprstr;
Edouard@228
   669
        /* free nothing, everything transfered */
Edouard@228
   670
        return PEP_STATUS_OK;
Edouard@225
   671
    }
Edouard@174
   672
Edouard@228
   673
free_fprstr:
Edouard@228
   674
    free(fprstr);
Edouard@228
   675
free_newkey:
Edouard@228
   676
    pgp_key_free(&newkey);
Edouard@228
   677
Edouard@225
   678
    return result;
Edouard@174
   679
}
Edouard@174
   680
Edouard@227
   681
PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fprstr)
Edouard@174
   682
{
Edouard@227
   683
    netpgp_t *netpgp;
Edouard@227
   684
    uint8_t fpr[PGP_FINGERPRINT_SIZE];
Edouard@227
   685
    size_t length;
Edouard@227
   686
    unsigned res;
Edouard@227
   687
Edouard@227
   688
    PEP_STATUS result;
Edouard@227
   689
Edouard@174
   690
    assert(session);
Edouard@174
   691
    assert(fpr);
Edouard@174
   692
Edouard@227
   693
    if (!session || !fpr)
Edouard@174
   694
        return PEP_UNKNOWN_ERROR;
Edouard@174
   695
Edouard@227
   696
    netpgp = &session->ctx;
Edouard@227
   697
    
Edouard@227
   698
    if (str_to_fpr(fprstr, fpr, &length)) {
Edouard@227
   699
        if (!pgp_deletekeybyfpr(netpgp->io,
Edouard@228
   700
                                (pgp_keyring_t *)netpgp->secring, 
Edouard@228
   701
                                (const uint8_t *)fpr, length)) {
Edouard@227
   702
            return PEP_KEY_NOT_FOUND;
Edouard@227
   703
        }
Edouard@227
   704
    }else{
Edouard@227
   705
        return PEP_OUT_OF_MEMORY;
Edouard@227
   706
    }
Edouard@174
   707
Edouard@227
   708
    /* pair was found in secring delete also corresponding pubkey 
Edouard@227
   709
     * in pubring if it exists */
Edouard@227
   710
    if(res) {
Edouard@227
   711
        pgp_deletekeybyfpr(netpgp->io,
Edouard@228
   712
                           (pgp_keyring_t *)netpgp->pubring, 
Edouard@228
   713
                           (const uint8_t *)fpr, length);
Edouard@227
   714
    }
Edouard@227
   715
Edouard@227
   716
    // save rings (key ownership transfered)
Edouard@227
   717
    if (netpgp_save_pubring(netpgp) && 
Edouard@227
   718
        netpgp_save_secring(netpgp))
Edouard@227
   719
    {
Edouard@227
   720
        result = PEP_STATUS_OK;
Edouard@227
   721
    }else{
Edouard@227
   722
        result = PEP_UNKNOWN_ERROR;
Edouard@227
   723
    }
Edouard@227
   724
Edouard@227
   725
    return result;
Edouard@174
   726
}
Edouard@174
   727
Edouard@228
   728
#define ARMOR_KEY_HEAD    "^-----BEGIN PGP (PUBLIC|PRIVATE) KEY BLOCK-----\\s*$"
Edouard@179
   729
PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data, size_t size)
Edouard@174
   730
{
Edouard@228
   731
Edouard@228
   732
    netpgp_t *netpgp;
Edouard@228
   733
    pgp_memory_t *mem;
Edouard@228
   734
    pgp_keyring_t tmpring;
Edouard@228
   735
Edouard@228
   736
    PEP_STATUS result;
Edouard@228
   737
Edouard@174
   738
    assert(session);
Edouard@174
   739
    assert(key_data);
Edouard@174
   740
Edouard@228
   741
    if(!session || !key_data) 
Edouard@174
   742
        return PEP_UNKNOWN_ERROR;
Edouard@228
   743
Edouard@228
   744
    netpgp = &session->ctx;
Edouard@228
   745
Edouard@228
   746
    mem = pgp_memory_new();
Edouard@228
   747
    if (mem == NULL) {
Edouard@228
   748
        return PEP_OUT_OF_MEMORY;
Edouard@228
   749
    }
Edouard@228
   750
    pgp_memory_add(mem, (const uint8_t*)key_data, size);
Edouard@228
   751
Edouard@228
   752
    if (pgp_keyring_read_from_mem(netpgp->io, &tmpring, 
Edouard@228
   753
                                  _armoured(key_data, size, ARMOR_KEY_HEAD),
Edouard@228
   754
                                  mem) == 0){
Edouard@228
   755
        result = PEP_ILLEGAL_VALUE;
Edouard@228
   756
    }else if (tmpring.keyc == 0){
Edouard@228
   757
        result = PEP_UNKNOWN_ERROR;
Edouard@228
   758
    }else if (tmpring.keyc > 1){
Edouard@228
   759
        /* too many keys given */
Edouard@228
   760
        result = PEP_ILLEGAL_VALUE;
Edouard@228
   761
    }else{
Edouard@228
   762
        result = import_key_or_keypair(netpgp, &tmpring.keys[0]);
Edouard@228
   763
    }
Edouard@228
   764
    
Edouard@228
   765
    pgp_memory_free(mem);
Edouard@228
   766
Edouard@228
   767
    if (result != PEP_STATUS_OK){
Edouard@228
   768
        pgp_keyring_purge(&tmpring);
Edouard@228
   769
    }
Edouard@228
   770
Edouard@228
   771
    return result;
Edouard@174
   772
}
Edouard@174
   773
Edouard@179
   774
PEP_STATUS pgp_export_keydata(
Edouard@228
   775
    PEP_SESSION session, const char *fprstr, char **key_data, size_t *size
Edouard@174
   776
    )
Edouard@174
   777
{
Edouard@228
   778
    netpgp_t *netpgp;
Edouard@228
   779
    pgp_key_t *key;
Edouard@228
   780
	pgp_output_t *output;
Edouard@228
   781
    pgp_memory_t *mem;
Edouard@228
   782
    uint8_t fpr[PGP_FINGERPRINT_SIZE];
Edouard@228
   783
    size_t fprlen;
Edouard@228
   784
Edouard@228
   785
    PEP_STATUS result;
Edouard@174
   786
    char *buffer;
Edouard@228
   787
    size_t buflen;
Edouard@174
   788
Edouard@174
   789
    assert(session);
Edouard@174
   790
    assert(fpr);
Edouard@174
   791
    assert(key_data);
Edouard@174
   792
    assert(size);
Edouard@174
   793
Edouard@228
   794
    netpgp = &session->ctx;
Edouard@174
   795
Edouard@228
   796
    if (!session || !fpr || !key_data || !size)
Edouard@174
   797
        return PEP_UNKNOWN_ERROR;
Edouard@174
   798
Edouard@228
   799
    if (str_to_fpr(fprstr, fpr, &fprlen)) {
Edouard@228
   800
        unsigned from = 0;
Edouard@228
   801
        if ((key = (pgp_key_t *)pgp_getkeybyfpr(netpgp->io, netpgp->pubring, 
Edouard@228
   802
                                                fpr, fprlen,
Edouard@228
   803
                                                &from, NULL)) == NULL) {
Edouard@228
   804
            return PEP_KEY_NOT_FOUND;
Edouard@228
   805
        }
Edouard@228
   806
    }else{
Edouard@228
   807
        return PEP_OUT_OF_MEMORY;
Edouard@228
   808
    }
Edouard@228
   809
    
Edouard@228
   810
	pgp_setup_memory_write(&output, &mem, 128);
Edouard@174
   811
Edouard@228
   812
    if (mem == NULL || output == NULL) {
Edouard@174
   813
        return PEP_OUT_OF_MEMORY;
Edouard@174
   814
    }
Edouard@174
   815
Edouard@228
   816
    if (!pgp_write_xfer_pubkey(output, key, 1)) {
Edouard@228
   817
        result = PEP_UNKNOWN_ERROR;
Edouard@228
   818
        goto free_mem;
Edouard@228
   819
    }
Edouard@228
   820
Edouard@228
   821
    buffer = NULL;
Edouard@228
   822
    buflen = pgp_mem_len(mem);
Edouard@228
   823
Edouard@228
   824
    // Allocate transferable buffer
Edouard@228
   825
    buffer = malloc(buflen + 1);
Edouard@228
   826
    assert(buffer);
Edouard@228
   827
    if (buffer == NULL) {
Edouard@228
   828
        result = PEP_OUT_OF_MEMORY;
Edouard@228
   829
        goto free_mem;
Edouard@228
   830
    }
Edouard@228
   831
Edouard@228
   832
    memcpy(buffer, pgp_mem_data(mem), buflen);
Edouard@174
   833
Edouard@174
   834
    *key_data = buffer;
Edouard@228
   835
    *size = buflen;
Edouard@228
   836
    (*key_data)[*size] = 0; // safeguard for naive users
Edouard@228
   837
    result = PEP_STATUS_OK;
Edouard@174
   838
Edouard@228
   839
free_mem :
Edouard@228
   840
	pgp_teardown_memory_write(output, mem);
Edouard@228
   841
Edouard@228
   842
    return result;
Edouard@174
   843
}
Edouard@174
   844
Edouard@175
   845
// "keyserver"
Edouard@175
   846
// "hkp://keys.gnupg.net"
Edouard@174
   847
PEP_STATUS pgp_recv_key(PEP_SESSION session, const char *pattern)
Edouard@174
   848
{
Edouard@174
   849
    assert(session);
Edouard@174
   850
    assert(pattern);
Edouard@174
   851
Edouard@174
   852
    /* TODO ask for key */
Edouard@174
   853
        return PEP_UNKNOWN_ERROR;
Edouard@174
   854
        return PEP_GET_KEY_FAILED;
Edouard@174
   855
Edouard@174
   856
    do {
Edouard@174
   857
Edouard@174
   858
        /* For each key */
Edouard@174
   859
        /* import key */
Edouard@174
   860
    } while (0);
Edouard@174
   861
Edouard@174
   862
    return PEP_STATUS_OK;
Edouard@174
   863
}
Edouard@174
   864
Edouard@174
   865
PEP_STATUS pgp_find_keys(
Edouard@174
   866
    PEP_SESSION session, const char *pattern, stringlist_t **keylist
Edouard@174
   867
    )
Edouard@174
   868
{
Edouard@174
   869
    stringlist_t *_keylist;
Edouard@174
   870
    char *fpr;
Edouard@174
   871
Edouard@174
   872
    assert(session);
Edouard@174
   873
    assert(pattern);
Edouard@174
   874
    assert(keylist);
Edouard@174
   875
Edouard@174
   876
    *keylist = NULL;
Edouard@174
   877
Edouard@174
   878
    /* Ask for key */
Edouard@174
   879
        return PEP_UNKNOWN_ERROR;
Edouard@174
   880
        return PEP_GET_KEY_FAILED;
Edouard@174
   881
Edouard@174
   882
    _keylist = new_stringlist(NULL);
Edouard@174
   883
    stringlist_t *_k = _keylist;
Edouard@174
   884
Edouard@174
   885
    do {
Edouard@174
   886
            fpr = "TODO key->subkeys->fpr";
Edouard@174
   887
            assert(fpr);
Edouard@174
   888
            _k = stringlist_add(_k, fpr);
Edouard@174
   889
            assert(_k);
Edouard@174
   890
            if (_k == NULL){
Edouard@174
   891
                free_stringlist(_keylist);
Edouard@174
   892
                return PEP_OUT_OF_MEMORY;
Edouard@174
   893
            }
Edouard@174
   894
    } while (0);
Edouard@174
   895
Edouard@174
   896
    *keylist = _keylist;
Edouard@174
   897
    return PEP_STATUS_OK;
Edouard@174
   898
}
Edouard@174
   899
Edouard@174
   900
PEP_STATUS pgp_send_key(PEP_SESSION session, const char *pattern)
Edouard@174
   901
{
Edouard@174
   902
    assert(session);
Edouard@174
   903
    assert(pattern);
Edouard@174
   904
Edouard@174
   905
    /* TODO send key */
Edouard@174
   906
Edouard@174
   907
        return PEP_CANNOT_SEND_KEY;
Edouard@174
   908
        return PEP_STATUS_OK;
Edouard@174
   909
}
Edouard@174
   910
Edouard@174
   911
Edouard@174
   912
PEP_STATUS pgp_get_key_rating(
Edouard@174
   913
    PEP_SESSION session,
Edouard@174
   914
    const char *fpr,
Edouard@174
   915
    PEP_comm_type *comm_type
Edouard@174
   916
    )
Edouard@174
   917
{
Edouard@174
   918
    PEP_STATUS status = PEP_STATUS_OK;
Edouard@174
   919
Edouard@174
   920
    assert(session);
Edouard@174
   921
    assert(fpr);
Edouard@174
   922
    assert(comm_type);
Edouard@174
   923
Edouard@174
   924
    *comm_type = PEP_ct_unknown;
Edouard@174
   925
Edouard@174
   926
    /* TODO get key from fpr */
Edouard@174
   927
    return PEP_UNKNOWN_ERROR;
Edouard@174
   928
    return PEP_GET_KEY_FAILED;
Edouard@174
   929
Edouard@174
   930
    switch (/*TODO key->protocol*/ 4) {
Edouard@174
   931
    case /* TODO  OpenPGP */0:
Edouard@174
   932
    case /* TODO DEFAULT */1:
Edouard@174
   933
        *comm_type = PEP_ct_OpenPGP_unconfirmed;
Edouard@174
   934
        break;
Edouard@174
   935
    case /* TODO CMS */2:
Edouard@174
   936
        *comm_type = PEP_ct_CMS_unconfirmed;
Edouard@174
   937
        break;
Edouard@174
   938
    default:
Edouard@174
   939
        *comm_type = PEP_ct_unknown;
Edouard@174
   940
        return PEP_STATUS_OK;
Edouard@174
   941
    }
Edouard@174
   942
Edouard@174
   943
        for (; 1 == 0; /* Each subkeys */ ) {
Edouard@174
   944
            if (/* TODO length */0 < 1024)
Edouard@174
   945
                *comm_type = PEP_ct_key_too_short;
Edouard@174
   946
            else if (
Edouard@174
   947
                (
Edouard@174
   948
                (   /* TODO pubkey_algo == RSA  */ 0)
Edouard@174
   949
                || (/* TODO pubkey_algo == RSA_E*/ 0)
Edouard@174
   950
                || (/* TODO pubkey_algo == RSA_S*/ 0)
Edouard@174
   951
                )
Edouard@174
   952
                && /* sk->length */0 == 1024
Edouard@174
   953
                )
Edouard@174
   954
                *comm_type = PEP_ct_OpenPGP_weak_unconfirmed;
Edouard@174
   955
Edouard@174
   956
            if (/* TODO invalid */ 1) {
Edouard@174
   957
                *comm_type = PEP_ct_key_b0rken;
Edouard@174
   958
                break;
Edouard@174
   959
            }
Edouard@174
   960
            if (/* TODO expired */ 1) {
Edouard@174
   961
                *comm_type = PEP_ct_key_expired;
Edouard@174
   962
                break;
Edouard@174
   963
            }
Edouard@175
   964
            if (/* TODO revoked*/ 1) {
Edouard@174
   965
                *comm_type = PEP_ct_key_revoked;
Edouard@174
   966
                break;
Edouard@174
   967
            }
Edouard@174
   968
        }
Edouard@174
   969
        *comm_type = PEP_ct_unknown;
Edouard@174
   970
        return PEP_OUT_OF_MEMORY;
Edouard@174
   971
        return PEP_UNKNOWN_ERROR;
Edouard@174
   972
Edouard@174
   973
Edouard@174
   974
    return status;
Edouard@174
   975
}
Edouard@210
   976
Edouard@210
   977
PEP_STATUS pgp_renew_key(
Edouard@210
   978
        PEP_SESSION session,
Edouard@210
   979
        const char *fpr,
Edouard@210
   980
        const timestamp *ts
Edouard@210
   981
    )
Edouard@210
   982
{
Edouard@210
   983
    PEP_STATUS status = PEP_STATUS_OK;
Edouard@210
   984
    char date_text[12];
Edouard@210
   985
Edouard@210
   986
    assert(session);
Edouard@210
   987
    assert(fpr);
Edouard@210
   988
Edouard@210
   989
    snprintf(date_text, 12, "%.4d-%.2d-%.2d\n", ts->tm_year + 1900,
Edouard@210
   990
            ts->tm_mon + 1, ts->tm_mday);
Edouard@210
   991
Edouard@210
   992
Edouard@210
   993
        return PEP_UNKNOWN_ERROR;
Edouard@210
   994
    return PEP_STATUS_OK;
Edouard@210
   995
}
Edouard@210
   996
Edouard@226
   997
PEP_STATUS pgp_revoke_key(
Edouard@226
   998
        PEP_SESSION session,
Edouard@226
   999
        const char *fpr,
Edouard@226
  1000
        const char *reason
Edouard@226
  1001
    )
Edouard@210
  1002
{
Edouard@210
  1003
    PEP_STATUS status = PEP_STATUS_OK;
Edouard@210
  1004
    
Edouard@210
  1005
    assert(session);
Edouard@210
  1006
    assert(fpr);
Edouard@210
  1007
Edouard@210
  1008
        return PEP_UNKNOWN_ERROR;
Edouard@210
  1009
Edouard@210
  1010
    return PEP_STATUS_OK;
Edouard@210
  1011
}
Edouard@210
  1012
Edouard@226
  1013
PEP_STATUS pgp_key_expired(
Edouard@226
  1014
        PEP_SESSION session,
Edouard@226
  1015
        const char *fpr,
Edouard@226
  1016
        bool *expired
Edouard@226
  1017
    )
Edouard@226
  1018
{
Edouard@226
  1019
    PEP_STATUS status = PEP_STATUS_OK;
Edouard@226
  1020
Edouard@226
  1021
    assert(session);
Edouard@226
  1022
    assert(fpr);
Edouard@226
  1023
    assert(expired);
Edouard@226
  1024
Edouard@226
  1025
    *expired = false;
Edouard@226
  1026
Edouard@226
  1027
    if (status != PEP_STATUS_OK)
Edouard@226
  1028
        return status;
Edouard@226
  1029
Edouard@226
  1030
    return PEP_STATUS_OK;
Edouard@226
  1031
}
Edouard@226
  1032