netpgp : ...
1 #include "pEp_internal.h"
2 #include "pgp_netpgp.h"
9 #include <netpgp/config.h>
10 #include <netpgp/memory.h>
11 #include <netpgp/crypto.h>
12 #include <netpgp/netpgpsdk.h>
13 #include <netpgp/validate.h>
15 #define PEP_NETPGP_DEBUG
17 PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
20 PEP_STATUS status = PEP_STATUS_OK;
21 const char *home = NULL;
24 if(!session) return PEP_UNKNOWN_ERROR;
26 netpgp = &session->ctx;
29 if (strcmp(setlocale(LC_ALL, NULL), "C") == 0)
30 setlocale(LC_ALL, "");
33 memset(netpgp, 0x0, sizeof(session->ctx));
35 // netpgp_setvar(netpgp, "max mem alloc", "4194304");
36 netpgp_setvar(netpgp, "need seckey", "1");
37 netpgp_setvar(netpgp, "need userid", "1");
39 // NetPGP shares home with GPG
42 netpgp_set_homedir(netpgp,(char*)home, NULL, 0);
44 status = PEP_INIT_NO_GPG_HOME;
48 // pair with gpg's cert-digest-algo
49 netpgp_setvar(netpgp, "hash", "SHA256");
51 // subset of gpg's personal-cipher-preferences
52 // here only one cipher can be selected
53 netpgp_setvar(netpgp, "cipher", "AES256");
55 if (!netpgp_init(netpgp)) {
56 status = PEP_INIT_NETPGP_INIT_FAILED;
63 pgp_release(session, in_first);
67 void pgp_release(PEP_SESSION session, bool out_last)
74 netpgp = &session->ctx;
77 memset(netpgp, 0x0, sizeof(session->ctx));
79 // out_last unused here
82 // Iterate through netpgp' reported valid signatures
83 // fill a list of valid figerprints
84 // returns PEP_STATUS_OK if all sig reported valid
85 // error status otherwise.
86 static PEP_STATUS _validation_results(netpgp_t *netpgp, pgp_validation_t *vresult,
87 stringlist_t **_keylist)
94 if (now < vresult->birthtime) {
95 // signature is not valid yet
96 #ifdef PEP_NETPGP_DEBUG
98 "signature not valid until %.24s\n",
99 ctime(&vresult->birthtime));
100 #endif //PEP_NETPGP_DEBUG
101 return PEP_UNENCRYPTED;
103 if (vresult->duration != 0 && now > vresult->birthtime + vresult->duration) {
104 // signature has expired
105 t = vresult->duration + vresult->birthtime;
106 #ifdef PEP_NETPGP_DEBUG
108 "signature not valid after %.24s\n",
110 #endif //PEP_NETPGP_DEBUG
111 return PEP_UNENCRYPTED;
113 if (vresult->validc && vresult->valid_sigs &&
114 !vresult->invalidc && !vresult->unknownc ) {
117 // caller responsible to free
118 *_keylist = new_stringlist(NULL);
120 if (*_keylist == NULL) {
121 return PEP_OUT_OF_MEMORY;
124 for (n = 0; n < vresult->validc; ++n) {
126 char id[MAX_ID_LENGTH + 1];
127 static const char *hexes = "0123456789abcdef";
128 const uint8_t *userid = vresult->valid_sigs[n].signer_id;
130 #ifdef PEP_NETPGP_DEBUG
131 const pgp_key_t *key;
132 pgp_pubkey_t *sigkey;
134 key = pgp_getkeybyid(netpgp->io, netpgp->pubring,
135 (const uint8_t *) vresult->valid_sigs[n].signer_id,
137 pgp_print_keydata(netpgp->io, netpgp->pubring, key, "valid signature ", &key->key.pubkey, 0);
138 #endif //PEP_NETPGP_DEBUG
140 for (i = 0; i < 8 ; i++) {
141 id[i * 2] = hexes[(unsigned)(userid[i] & 0xf0) >> 4];
142 id[(i * 2) + 1] = hexes[userid[i] & 0xf];
146 k = stringlist_add(k, id);
148 free_stringlist(*_keylist);
149 return PEP_OUT_OF_MEMORY;
152 return PEP_STATUS_OK;
154 if (vresult->validc + vresult->invalidc + vresult->unknownc == 0) {
155 // No signatures found - is this memory signed?
156 return PEP_VERIFY_NO_KEY;
159 if (vresult->invalidc) {
160 // some invalid signatures
162 #ifdef PEP_NETPGP_DEBUG
164 for (n = 0; n < vresult->invalidc; ++n) {
165 const pgp_key_t *key;
166 pgp_pubkey_t *sigkey;
168 key = pgp_getkeybyid(netpgp->io, netpgp->pubring,
169 (const uint8_t *) vresult->invalid_sigs[n].signer_id,
171 pgp_print_keydata(netpgp->io, netpgp->pubring, key, "invalid signature ", &key->key.pubkey, 0);
172 if (sigkey->duration != 0 && now > sigkey->birthtime + sigkey->duration) {
173 printf("EXPIRED !\n");
176 #endif //PEP_NETPGP_DEBUG
178 return PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
182 return PEP_DECRYPT_WRONG_FORMAT;
185 PEP_STATUS pgp_decrypt_and_verify(
186 PEP_SESSION session, const char *ctext, size_t csize,
187 char **ptext, size_t *psize, stringlist_t **keylist
193 pgp_validation_t *vresult;
199 stringlist_t *_keylist = NULL;
209 if(!session || !ctext || !csize || !ptext || !psize || !keylist)
210 return PEP_UNKNOWN_ERROR;
212 netpgp = &session->ctx;
218 vresult = malloc(sizeof(pgp_validation_t));
219 memset(vresult, 0x0, sizeof(pgp_validation_t));
221 mem = pgp_decrypt_and_validate_buf(netpgp->io, vresult, ctext, csize,
222 netpgp->secring, netpgp->pubring,
225 NULL, -1, NULL /* pass fp,attempts,cb */);
227 return PEP_OUT_OF_MEMORY;
230 _psize = pgp_mem_len(mem);
232 if ((_ptext = calloc(1, _psize)) == NULL) {
233 result = PEP_OUT_OF_MEMORY;
236 memcpy(_ptext, pgp_mem_data(mem), _psize);
237 result = PEP_DECRYPTED;
239 result = PEP_DECRYPT_NO_KEY;
243 if (result == PEP_DECRYPTED) {
244 result = _validation_results(netpgp, vresult, &_keylist);
245 if (result != PEP_STATUS_OK) {
248 result = PEP_DECRYPTED_AND_VERIFIED;
251 if (result == PEP_DECRYPTED_AND_VERIFIED
252 || result == PEP_DECRYPTED) {
255 (*ptext)[*psize] = 0; // safeguard for naive users
256 if (result == PEP_DECRYPTED_AND_VERIFIED) {
260 /* _ptext and _keylist ownership transfer, don't free */
265 free_stringlist(_keylist);
271 pgp_memory_free(mem);
272 pgp_validate_result_free(vresult);
277 PEP_STATUS pgp_verify_text(
278 PEP_SESSION session, const char *text, size_t size,
279 const char *signature, size_t sig_size, stringlist_t **keylist
283 pgp_memory_t *signedmem;
285 pgp_validation_t *vresult;
289 stringlist_t *_keylist;
298 if(!session || !text || !size || !signature || !sig_size || !keylist)
299 return PEP_UNKNOWN_ERROR;
301 netpgp = &session->ctx;
305 vresult = malloc(sizeof(pgp_validation_t));
306 memset(vresult, 0x0, sizeof(pgp_validation_t));
308 signedmem = pgp_memory_new();
309 if (signedmem == NULL) {
310 return PEP_OUT_OF_MEMORY;
312 pgp_memory_add(signedmem, (const uint8_t*)text, size);
314 sig = pgp_memory_new();
316 pgp_memory_free(signedmem);
317 return PEP_OUT_OF_MEMORY;
319 pgp_memory_add(sig, (const uint8_t*)signature, sig_size);
321 pgp_validate_mem_detached(netpgp->io, vresult, sig,
327 result = _validation_results(netpgp, vresult, &_keylist);
328 if (result != PEP_STATUS_OK) {
331 result = PEP_VERIFIED;
334 if (result == PEP_VERIFIED) {
335 /* TODO : check trust level */
336 result = PEP_VERIFIED_AND_TRUSTED;
339 if (result == PEP_VERIFIED || result == PEP_VERIFIED_AND_TRUSTED) {
342 /* _keylist ownership transfer, don't free */
347 free_stringlist(_keylist);
350 // free done by pgp_validate_mem_detached
351 // pgp_memory_free(sig);
352 // pgp_memory_free(signedmem);
353 pgp_validate_result_free(vresult);
358 PEP_STATUS pgp_encrypt_and_sign(
359 PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
360 size_t psize, char **ctext, size_t *csize
364 const stringlist_t *_keylist;
377 for (_keylist = keylist, i = 0; _keylist != NULL; _keylist = _keylist->next, i++) {
378 assert(_keylist->value);
380 /* get key from _keylist->value */
381 /* add key to recipients/signers */
384 /* Do encrypt and sign */
385 char *_buffer = NULL;
386 size_t length = /* TODO length*/ 0;
387 assert(length != -1);
389 /* Allocate transferable buffer */
390 _buffer = malloc(length + 1);
392 if (_buffer == NULL) {
394 return PEP_OUT_OF_MEMORY;
399 (*ctext)[*csize] = 0; // safeguard for naive users
400 result = PEP_STATUS_OK;
403 result = PEP_UNKNOWN_ERROR;
407 PEP_STATUS pgp_generate_keypair(
408 PEP_SESSION session, pEp_identity *identity
412 const char *template =
417 /* "Passphrase: %s\n" */
423 assert(identity->address);
424 assert(identity->fpr == NULL);
425 assert(identity->username);
427 parms = calloc(1, PARMS_MAX);
430 return PEP_OUT_OF_MEMORY;
432 result = snprintf(parms, PARMS_MAX, template, identity->username,
434 assert(result < PARMS_MAX);
435 if (result >= PARMS_MAX) {
437 return PEP_BUFFER_TOO_SMALL;
440 /* TODO generate key */
444 return PEP_UNKNOWN_ERROR;
445 return PEP_ILLEGAL_VALUE;
446 return PEP_CANNOT_CREATE_KEY;
448 identity->fpr = strdup("TODO generated key fpr");
450 return PEP_STATUS_OK;
453 PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fpr)
458 /* TODO get key with given fpr */
459 return PEP_KEY_NOT_FOUND;
460 return PEP_ILLEGAL_VALUE;
461 return PEP_KEY_HAS_AMBIG_NAME;
462 return PEP_OUT_OF_MEMORY;
463 return PEP_UNKNOWN_ERROR;
465 /* TODO delete that key */
466 return PEP_UNKNOWN_ERROR;
467 return PEP_KEY_NOT_FOUND;
468 return PEP_KEY_HAS_AMBIG_NAME;
469 return PEP_UNKNOWN_ERROR;
471 return PEP_STATUS_OK;
474 PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data, size_t size)
480 return PEP_UNKNOWN_ERROR;
481 return PEP_ILLEGAL_VALUE;
482 return PEP_UNKNOWN_ERROR;
483 return PEP_STATUS_OK;
486 PEP_STATUS pgp_export_keydata(
487 PEP_SESSION session, const char *fpr, char **key_data, size_t *size
501 return PEP_KEY_NOT_FOUND;
502 return PEP_UNKNOWN_ERROR;
503 return PEP_UNKNOWN_ERROR;
505 _size = /* TODO */ 0;
508 buffer = malloc(_size + 1);
510 if (buffer == NULL) {
512 return PEP_OUT_OF_MEMORY;
515 // safeguard for the naive user
521 return PEP_STATUS_OK;
525 // "hkp://keys.gnupg.net"
526 PEP_STATUS pgp_recv_key(PEP_SESSION session, const char *pattern)
531 /* TODO ask for key */
532 return PEP_UNKNOWN_ERROR;
533 return PEP_GET_KEY_FAILED;
541 return PEP_STATUS_OK;
544 PEP_STATUS pgp_find_keys(
545 PEP_SESSION session, const char *pattern, stringlist_t **keylist
548 stringlist_t *_keylist;
558 return PEP_UNKNOWN_ERROR;
559 return PEP_GET_KEY_FAILED;
561 _keylist = new_stringlist(NULL);
562 stringlist_t *_k = _keylist;
565 fpr = "TODO key->subkeys->fpr";
567 _k = stringlist_add(_k, fpr);
570 free_stringlist(_keylist);
571 return PEP_OUT_OF_MEMORY;
576 return PEP_STATUS_OK;
579 PEP_STATUS pgp_send_key(PEP_SESSION session, const char *pattern)
586 return PEP_CANNOT_SEND_KEY;
587 return PEP_STATUS_OK;
591 PEP_STATUS pgp_get_key_rating(
594 PEP_comm_type *comm_type
597 PEP_STATUS status = PEP_STATUS_OK;
603 *comm_type = PEP_ct_unknown;
605 /* TODO get key from fpr */
606 return PEP_UNKNOWN_ERROR;
607 return PEP_GET_KEY_FAILED;
609 switch (/*TODO key->protocol*/ 4) {
610 case /* TODO OpenPGP */0:
611 case /* TODO DEFAULT */1:
612 *comm_type = PEP_ct_OpenPGP_unconfirmed;
614 case /* TODO CMS */2:
615 *comm_type = PEP_ct_CMS_unconfirmed;
618 *comm_type = PEP_ct_unknown;
619 return PEP_STATUS_OK;
622 for (; 1 == 0; /* Each subkeys */ ) {
623 if (/* TODO length */0 < 1024)
624 *comm_type = PEP_ct_key_too_short;
627 ( /* TODO pubkey_algo == RSA */ 0)
628 || (/* TODO pubkey_algo == RSA_E*/ 0)
629 || (/* TODO pubkey_algo == RSA_S*/ 0)
631 && /* sk->length */0 == 1024
633 *comm_type = PEP_ct_OpenPGP_weak_unconfirmed;
635 if (/* TODO invalid */ 1) {
636 *comm_type = PEP_ct_key_b0rken;
639 if (/* TODO expired */ 1) {
640 *comm_type = PEP_ct_key_expired;
643 if (/* TODO revoked*/ 1) {
644 *comm_type = PEP_ct_key_revoked;
648 *comm_type = PEP_ct_unknown;
649 return PEP_OUT_OF_MEMORY;
650 return PEP_UNKNOWN_ERROR;