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 PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
18 PEP_STATUS status = PEP_STATUS_OK;
19 const char *home = NULL;
22 if(!session) return PEP_UNKNOWN_ERROR;
24 netpgp = &session->ctx;
27 if (strcmp(setlocale(LC_ALL, NULL), "C") == 0)
28 setlocale(LC_ALL, "");
31 memset(netpgp, 0x0, sizeof(session->ctx));
33 // netpgp_setvar(netpgp, "max mem alloc", "4194304");
34 netpgp_setvar(netpgp, "need seckey", "1");
35 netpgp_setvar(netpgp, "need userid", "1");
37 // NetPGP shares home with GPG
40 netpgp_set_homedir(netpgp,(char*)home, NULL, 0);
42 status = PEP_INIT_NO_GPG_HOME;
46 // pair with gpg's cert-digest-algo
47 netpgp_setvar(netpgp, "hash", "SHA256");
49 // subset of gpg's personal-cipher-preferences
50 // here only one cipher can be selected
51 netpgp_setvar(netpgp, "cipher", "AES256");
53 if (!netpgp_init(netpgp)) {
54 status = PEP_INIT_NETPGP_INIT_FAILED;
61 pgp_release(session, in_first);
65 void pgp_release(PEP_SESSION session, bool out_last)
72 netpgp = &session->ctx;
75 memset(netpgp, 0x0, sizeof(session->ctx));
77 // out_last unused here
80 PEP_STATUS pgp_decrypt_and_verify(
81 PEP_SESSION session, const char *ctext, size_t csize,
82 char **ptext, size_t *psize, stringlist_t **keylist
88 pgp_validation_t *vresult;
95 stringlist_t *_keylist = NULL;
105 if(!session || !ctext || !csize || !ptext || !psize || !keylist)
106 return PEP_UNKNOWN_ERROR;
108 netpgp = &session->ctx;
115 vresult = malloc(sizeof(pgp_validation_t));
116 memset(vresult, 0x0, sizeof(pgp_validation_t));
118 mem = pgp_decrypt_and_validate_buf(netpgp->io, vresult, ctext, csize,
119 netpgp->secring, netpgp->pubring,
122 NULL, -1, NULL /* pass fp,attempts,cb */);
124 return PEP_OUT_OF_MEMORY;
127 _psize = pgp_mem_len(mem);
129 if ((_ptext = calloc(1, _psize)) == NULL) {
130 result = PEP_OUT_OF_MEMORY;
133 memcpy(_ptext, pgp_mem_data(mem), _psize);
134 result = PEP_DECRYPTED;
136 result = PEP_DECRYPT_NO_KEY;
140 if (result == PEP_DECRYPTED &&
141 vresult->validc && vresult->valid_sigs &&
142 !vresult->invalidc && !vresult->unknownc ) {
145 _keylist = new_stringlist(NULL);
147 if (_keylist == NULL) {
148 result = PEP_OUT_OF_MEMORY;
152 for (n = 0; n < vresult->validc; ++n) {
154 static const char *hexes = "0123456789abcdef";
155 char id[MAX_ID_LENGTH + 1];
156 const uint8_t *userid = vresult->valid_sigs[n].signer_id;
158 for (i = 0; i < 8 ; i++) {
159 id[i * 2] = hexes[(unsigned)(userid[i] & 0xf0) >> 4];
160 id[(i * 2) + 1] = hexes[userid[i] & 0xf];
163 k = stringlist_add(k, id);
165 result = PEP_DECRYPTED_AND_VERIFIED;
167 if (vresult->validc + vresult->invalidc + vresult->unknownc == 0) {
168 // No signatures found - is this memory signed?
169 result = PEP_VERIFY_NO_KEY;
171 } else if (vresult->invalidc) {
173 result = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
177 // or valid sig not provided in result
178 result = PEP_DECRYPT_WRONG_FORMAT;
183 if (result == PEP_DECRYPTED_AND_VERIFIED
184 || result == PEP_DECRYPTED) {
187 (*ptext)[*psize] = 0; // safeguard for naive users
190 /* _ptext and _keylist ownership transfer, don't free */
195 free_stringlist(_keylist);
201 pgp_memory_free(mem);
202 pgp_validate_result_free(vresult);
207 PEP_STATUS pgp_verify_text(
208 PEP_SESSION session, const char *text, size_t size,
209 const char *signature, size_t sig_size, stringlist_t **keylist
213 stringlist_t *_keylist;
226 result = PEP_VERIFIED;
228 k = stringlist_add(k, "TODO");
230 free_stringlist(_keylist);
232 return PEP_OUT_OF_MEMORY;
234 } while (0 /*TODO*/);
237 result = PEP_UNENCRYPTED;
238 result = PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
239 result = PEP_VERIFIED_AND_TRUSTED;
240 result = PEP_VERIFY_NO_KEY;
241 result = PEP_UNENCRYPTED;
242 result = PEP_DECRYPT_WRONG_FORMAT;
243 return PEP_OUT_OF_MEMORY;
245 result = PEP_UNKNOWN_ERROR;
250 PEP_STATUS pgp_encrypt_and_sign(
251 PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
252 size_t psize, char **ctext, size_t *csize
256 const stringlist_t *_keylist;
269 for (_keylist = keylist, i = 0; _keylist != NULL; _keylist = _keylist->next, i++) {
270 assert(_keylist->value);
272 /* get key from _keylist->value */
273 /* add key to recipients/signers */
276 /* Do encrypt and sign */
277 char *_buffer = NULL;
278 size_t length = /* TODO length*/ 0;
279 assert(length != -1);
281 /* Allocate transferable buffer */
282 _buffer = malloc(length + 1);
284 if (_buffer == NULL) {
286 return PEP_OUT_OF_MEMORY;
291 (*ctext)[*csize] = 0; // safeguard for naive users
292 result = PEP_STATUS_OK;
295 result = PEP_UNKNOWN_ERROR;
299 PEP_STATUS pgp_generate_keypair(
300 PEP_SESSION session, pEp_identity *identity
304 const char *template =
309 /* "Passphrase: %s\n" */
315 assert(identity->address);
316 assert(identity->fpr == NULL);
317 assert(identity->username);
319 parms = calloc(1, PARMS_MAX);
322 return PEP_OUT_OF_MEMORY;
324 result = snprintf(parms, PARMS_MAX, template, identity->username,
326 assert(result < PARMS_MAX);
327 if (result >= PARMS_MAX) {
329 return PEP_BUFFER_TOO_SMALL;
332 /* TODO generate key */
336 return PEP_UNKNOWN_ERROR;
337 return PEP_ILLEGAL_VALUE;
338 return PEP_CANNOT_CREATE_KEY;
340 identity->fpr = strdup("TODO generated key fpr");
342 return PEP_STATUS_OK;
345 PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fpr)
350 /* TODO get key with given fpr */
351 return PEP_KEY_NOT_FOUND;
352 return PEP_ILLEGAL_VALUE;
353 return PEP_KEY_HAS_AMBIG_NAME;
354 return PEP_OUT_OF_MEMORY;
355 return PEP_UNKNOWN_ERROR;
357 /* TODO delete that key */
358 return PEP_UNKNOWN_ERROR;
359 return PEP_KEY_NOT_FOUND;
360 return PEP_KEY_HAS_AMBIG_NAME;
361 return PEP_UNKNOWN_ERROR;
363 return PEP_STATUS_OK;
366 PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data, size_t size)
372 return PEP_UNKNOWN_ERROR;
373 return PEP_ILLEGAL_VALUE;
374 return PEP_UNKNOWN_ERROR;
375 return PEP_STATUS_OK;
378 PEP_STATUS pgp_export_keydata(
379 PEP_SESSION session, const char *fpr, char **key_data, size_t *size
393 return PEP_KEY_NOT_FOUND;
394 return PEP_UNKNOWN_ERROR;
395 return PEP_UNKNOWN_ERROR;
397 _size = /* TODO */ 0;
400 buffer = malloc(_size + 1);
402 if (buffer == NULL) {
404 return PEP_OUT_OF_MEMORY;
407 // safeguard for the naive user
413 return PEP_STATUS_OK;
417 // "hkp://keys.gnupg.net"
418 PEP_STATUS pgp_recv_key(PEP_SESSION session, const char *pattern)
423 /* TODO ask for key */
424 return PEP_UNKNOWN_ERROR;
425 return PEP_GET_KEY_FAILED;
433 return PEP_STATUS_OK;
436 PEP_STATUS pgp_find_keys(
437 PEP_SESSION session, const char *pattern, stringlist_t **keylist
440 stringlist_t *_keylist;
450 return PEP_UNKNOWN_ERROR;
451 return PEP_GET_KEY_FAILED;
453 _keylist = new_stringlist(NULL);
454 stringlist_t *_k = _keylist;
457 fpr = "TODO key->subkeys->fpr";
459 _k = stringlist_add(_k, fpr);
462 free_stringlist(_keylist);
463 return PEP_OUT_OF_MEMORY;
468 return PEP_STATUS_OK;
471 PEP_STATUS pgp_send_key(PEP_SESSION session, const char *pattern)
478 return PEP_CANNOT_SEND_KEY;
479 return PEP_STATUS_OK;
483 PEP_STATUS pgp_get_key_rating(
486 PEP_comm_type *comm_type
489 PEP_STATUS status = PEP_STATUS_OK;
495 *comm_type = PEP_ct_unknown;
497 /* TODO get key from fpr */
498 return PEP_UNKNOWN_ERROR;
499 return PEP_GET_KEY_FAILED;
501 switch (/*TODO key->protocol*/ 4) {
502 case /* TODO OpenPGP */0:
503 case /* TODO DEFAULT */1:
504 *comm_type = PEP_ct_OpenPGP_unconfirmed;
506 case /* TODO CMS */2:
507 *comm_type = PEP_ct_CMS_unconfirmed;
510 *comm_type = PEP_ct_unknown;
511 return PEP_STATUS_OK;
514 for (; 1 == 0; /* Each subkeys */ ) {
515 if (/* TODO length */0 < 1024)
516 *comm_type = PEP_ct_key_too_short;
519 ( /* TODO pubkey_algo == RSA */ 0)
520 || (/* TODO pubkey_algo == RSA_E*/ 0)
521 || (/* TODO pubkey_algo == RSA_S*/ 0)
523 && /* sk->length */0 == 1024
525 *comm_type = PEP_ct_OpenPGP_weak_unconfirmed;
527 if (/* TODO invalid */ 1) {
528 *comm_type = PEP_ct_key_b0rken;
531 if (/* TODO expired */ 1) {
532 *comm_type = PEP_ct_key_expired;
535 if (/* TODO revoked*/ 1) {
536 *comm_type = PEP_ct_key_revoked;
540 *comm_type = PEP_ct_unknown;
541 return PEP_OUT_OF_MEMORY;
542 return PEP_UNKNOWN_ERROR;