p≡p engine fork for my own dirty testing of stuff
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

267 lines
7.1 KiB

#include "message_api.h"
#include "keymanagement.h"
#include "mime.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#define NOT_IMPLEMENTED assert(0);
static char * combine_short_and_long(const message * src)
{
char * ptext;
char * longmsg;
assert(src);
assert(src->shortmsg && strcmp(src->shortmsg, "pEp") != 0);
if (src->longmsg)
longmsg = src->longmsg;
else
longmsg = "";
ptext = calloc(1, strlen(src->shortmsg) + strlen(longmsg) + 12);
if (ptext == NULL)
return NULL;
strcpy(ptext, "subject: ");
strcat(ptext, src->shortmsg);
strcat(ptext, "\n\n");
strcat(ptext, longmsg);
return ptext;
}
DYNAMIC_API PEP_STATUS encrypt_message(
PEP_SESSION session,
const message *src,
stringlist_t * extra,
message **dst,
PEP_enc_format format
)
{
PEP_STATUS status = PEP_STATUS_OK;
message * msg = NULL;
stringlist_t * keys = NULL;
assert(session);
assert(src);
assert(dst);
*dst = NULL;
assert(format != PEP_enc_none);
pEp_identity *from = identity_dup(src->from);
if (from == NULL)
goto enomem;
from->me = true;
identity_list *to = identity_list_dup(src->to);
if (to == NULL) {
free_identity(from);
goto enomem;
}
msg = new_message(src->dir, from, to, NULL);
if (msg == NULL) {
free_identity(from);
free_identity_list(to);
goto enomem;
}
msg->enc_format = PEP_enc_pieces;
status = myself(session, from);
if (status != PEP_STATUS_OK)
goto pep_error;
keys = new_stringlist(from->fpr);
if (keys == NULL)
goto enomem;
stringlist_t *_k = keys;
if (extra) {
_k = stringlist_append(_k, extra);
if (_k == NULL)
goto enomem;
}
bool dest_keys_found = false;
identity_list * _il;
for (_il = to; _il && _il->ident; _il = _il->next) {
PEP_STATUS status = update_identity(session, _il->ident);
if (status != PEP_STATUS_OK)
goto pep_error;
if (_il->ident->fpr) {
dest_keys_found = true;
_k = stringlist_add(_k, _il->ident->fpr);
if (_k == NULL)
goto enomem;
}
else
status = PEP_KEY_NOT_FOUND;
}
if (dest_keys_found) {
char *ptext;
char *ctext = NULL;
size_t csize = 0;
msg->enc_format = PEP_enc_pieces;
switch (format) {
case PEP_enc_MIME_multipart: {
char *resulttext = NULL;
bool free_ptext = false;
msg->enc_format = PEP_enc_MIME_multipart;
if (src->shortmsg && strcmp(src->shortmsg, "pEp") != 0) {
ptext = combine_short_and_long(src);
if (ptext == NULL)
goto enomem;
free_ptext = true;
}
else if (src->longmsg) {
ptext = src->longmsg;
}
else {
assert(0);
status = PEP_ILLEGAL_VALUE;
goto pep_error;
}
status = mime_encode_text(ptext, src->longmsg_formatted,
src->attachments, &resulttext);
assert(status == PEP_STATUS_OK);
if (free_ptext)
free(ptext);
assert(resulttext);
if (resulttext == NULL)
goto pep_error;
status = encrypt_and_sign(session, keys, resulttext, strlen(resulttext),
&ctext, &csize);
free(resulttext);
if (ctext) {
msg->longmsg = strdup(ctext);
msg->shortmsg = strdup("pEp");
if (!(msg->longmsg && msg->shortmsg))
goto enomem;
}
else {
goto pep_error;
}
}
break;
case PEP_enc_pieces:
if (src->shortmsg && strcmp(src->shortmsg, "pEp") != 0) {
ptext = combine_short_and_long(src);
if (ptext == NULL)
goto enomem;
status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
&ctext, &csize);
free(ptext);
if (ctext) {
msg->longmsg = strdup(ctext);
msg->shortmsg = strdup("pEp");
if (!(msg->longmsg && msg->shortmsg))
goto enomem;
}
else {
goto pep_error;
}
}
else if (src->longmsg) {
ptext = src->longmsg;
status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
&ctext, &csize);
if (ctext) {
msg->longmsg = strdup(ctext);
msg->shortmsg = strdup("pEp");
if (!(msg->longmsg && msg->shortmsg))
goto enomem;
}
else {
goto pep_error;
}
}
if (msg->longmsg_formatted) {
ptext = src->longmsg_formatted;
status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
&ctext, &csize);
if (ctext) {
msg->longmsg_formatted = strdup(ctext);
if (msg->longmsg_formatted == NULL)
goto enomem;
}
else {
goto pep_error;
}
}
if (src->attachments) {
bloblist_t *_s;
bloblist_t *_d = new_bloblist(NULL, 0, NULL, NULL);
if (_d == NULL)
goto enomem;
msg->attachments = _d;
for (_s = src->attachments; _s && _s->data; _s = _s->next) {
int psize = _s->size;
ptext = _s->data;
status = encrypt_and_sign(session, keys, ptext, psize,
&ctext, &csize);
if (ctext) {
char * _c = strdup(ctext);
if (_c == NULL)
goto enomem;
_d = bloblist_add(_d, _c, csize, _s->mime_type,
_s->file_name);
if (_d == NULL)
goto enomem;
}
else {
goto pep_error;
}
}
}
break;
default:
assert(0);
status = PEP_ILLEGAL_VALUE;
goto pep_error;
}
}
free_stringlist(keys);
*dst = msg;
return PEP_STATUS_OK;
enomem:
status = PEP_OUT_OF_MEMORY;
pep_error:
free_stringlist(keys);
free_message(msg);
return status;
}
DYNAMIC_API PEP_STATUS decrypt_message(
PEP_SESSION session,
const message *src,
message **dst
)
{
PEP_STATUS status = PEP_STATUS_OK;
NOT_IMPLEMENTED
return status;
}