1 #include "pEp_internal.h"
2 #include "message_api.h"
12 #define MIN(A, B) ((B) > (A) ? (A) : (B))
15 #define MAX(A, B) ((B) > (A) ? (B) : (A))
19 static bool string_equality(const char *s1, const char *s2)
21 if (s1 == NULL || s2 == NULL)
26 return strcmp(s1, s2) == 0;
29 static bool is_mime_type(const bloblist_t *bl, const char *mt)
33 return bl && string_equality(bl->mime_type, mt);
36 static bool is_fileending(const bloblist_t *bl, const char *fe)
40 if (bl == NULL || bl->filename == NULL)
43 assert(bl && bl->filename);
45 size_t fe_len = strlen(fe);
46 size_t fn_len = strlen(bl->filename);
51 assert(fn_len > fe_len);
53 return strcmp(bl->filename + (fn_len - fe_len), fe) == 0;
56 static void add_opt_field(message *msg, const char *name, const char *value)
60 if (msg && name && value) {
61 stringpair_t *pair = new_stringpair(name, value);
65 stringpair_list_t *field = stringpair_list_add(msg->opt_fields, pair);
69 if (msg->opt_fields == NULL)
70 msg->opt_fields = field;
74 static char * combine_short_and_long(const char *shortmsg, const char *longmsg)
79 assert(strcmp(shortmsg, "pEp") != 0);
84 ptext = calloc(1, strlen(shortmsg) + strlen(longmsg) + 12);
89 strcpy(ptext, "Subject: ");
90 strcat(ptext, shortmsg);
91 strcat(ptext, "\n\n");
92 strcat(ptext, longmsg);
97 static int seperate_short_and_long(const char *src, char **shortmsg, char **longmsg)
99 char *_shortmsg = NULL;
100 char *_longmsg = NULL;
109 if (strncasecmp(src, "subject: ", 9) == 0) {
110 char *line_end = strchr(src, '\n');
112 if (line_end == NULL) {
113 _shortmsg = strdup(src + 9);
114 if (_shortmsg == NULL)
119 size_t n = line_end - src;
121 if (*(line_end - 1) == '\r')
122 _shortmsg = strndup(src + 9, n - 10);
124 _shortmsg = strndup(src + 9, n - 9);
126 if (_shortmsg == NULL)
129 while (*(src + n) && (*(src + n) == '\n' || *(src + n) == '\r'))
133 _longmsg = strdup(src + n);
134 if (_longmsg == NULL)
140 _shortmsg = strdup("");
141 if (_shortmsg == NULL)
143 _longmsg = strdup(src);
144 if (_longmsg == NULL)
148 *shortmsg = _shortmsg;
160 static PEP_STATUS copy_fields(message *dst, const message *src)
165 free_timestamp(dst->sent);
168 dst->sent = timestamp_dup(src->sent);
169 if (dst->sent == NULL)
170 return PEP_OUT_OF_MEMORY;
173 free_timestamp(dst->recv);
176 dst->recv = timestamp_dup(src->recv);
177 if (dst->recv == NULL)
178 return PEP_OUT_OF_MEMORY;
181 free_identity(dst->from);
184 dst->from = identity_dup(src->from);
185 if (dst->from == NULL)
186 return PEP_OUT_OF_MEMORY;
189 free_identity_list(dst->to);
191 if (src->to && src->to->ident) {
192 dst->to = identity_list_dup(src->to);
194 return PEP_OUT_OF_MEMORY;
197 free_identity(dst->recv_by);
200 dst->recv_by = identity_dup(src->recv_by);
201 if (dst->recv_by == NULL)
202 return PEP_OUT_OF_MEMORY;
205 free_identity_list(dst->cc);
207 if (src->cc && src->cc->ident) {
208 dst->cc = identity_list_dup(src->cc);
210 return PEP_OUT_OF_MEMORY;
213 free_identity_list(dst->bcc);
215 if (src->bcc && src->bcc->ident) {
216 dst->bcc = identity_list_dup(src->bcc);
217 if (dst->bcc == NULL)
218 return PEP_OUT_OF_MEMORY;
221 free_identity_list(dst->reply_to);
222 dst->reply_to = NULL;
223 if (src->reply_to && src->reply_to->ident) {
224 dst->reply_to = identity_list_dup(src->reply_to);
225 if (dst->reply_to == NULL)
226 return PEP_OUT_OF_MEMORY;
229 free_stringlist(dst->in_reply_to);
230 dst->in_reply_to = NULL;
231 if (src->in_reply_to && src->in_reply_to->value) {
232 dst->in_reply_to = stringlist_dup(src->in_reply_to);
233 if (dst->in_reply_to == NULL)
234 return PEP_OUT_OF_MEMORY;
237 free_stringlist(dst->references);
238 dst->references = NULL;
239 if (src->references) {
240 dst->references = stringlist_dup(src->references);
241 if (dst->references == NULL)
242 return PEP_OUT_OF_MEMORY;
245 free_stringlist(dst->keywords);
246 dst->keywords = NULL;
247 if (src->keywords && src->keywords->value) {
248 dst->keywords = stringlist_dup(src->keywords);
249 if (dst->keywords == NULL)
250 return PEP_OUT_OF_MEMORY;
254 dst->comments = NULL;
256 dst->comments = strdup(src->comments);
257 assert(dst->comments);
258 if (dst->comments == NULL)
259 return PEP_OUT_OF_MEMORY;
262 return PEP_STATUS_OK;
265 static message * clone_to_empty_message(const message * src)
268 message * msg = NULL;
272 msg = calloc(1, sizeof(message));
279 status = copy_fields(msg, src);
280 if (status != PEP_STATUS_OK)
290 static PEP_STATUS encrypt_PGP_MIME(
297 PEP_STATUS status = PEP_STATUS_OK;
298 bool free_ptext = false;
302 char *mimetext = NULL;
304 assert(dst->longmsg == NULL);
305 dst->enc_format = PEP_enc_PGP_MIME;
307 if (src->shortmsg && strcmp(src->shortmsg, "pEp") != 0) {
308 if (session->unencrypted_subject) {
309 dst->shortmsg = strdup(src->shortmsg);
310 if (dst->shortmsg == NULL)
312 ptext = src->longmsg;
315 ptext = combine_short_and_long(src->shortmsg, src->longmsg);
321 else if (src->longmsg) {
322 ptext = src->longmsg;
328 message *_src = calloc(1, sizeof(message));
332 _src->longmsg = ptext;
333 _src->longmsg_formatted = src->longmsg_formatted;
334 _src->attachments = src->attachments;
335 _src->enc_format = PEP_enc_none;
336 status = mime_encode_message(_src, true, &mimetext);
337 assert(status == PEP_STATUS_OK);
344 if (mimetext == NULL)
347 status = encrypt_and_sign(session, keys, mimetext, strlen(mimetext),
353 dst->longmsg = strdup("this message was encrypted with p≡p "
354 "http://pEp-project.org");
355 if (dst->longmsg == NULL)
358 char *v = strdup("Version: 1");
362 bloblist_t *_a = new_bloblist(v, 11, "application/pgp-encrypted", NULL);
365 dst->attachments = _a;
367 _ctext = malloc(csize);
371 memcpy(_ctext, ctext, csize);
373 _a = bloblist_add(_a, _ctext, csize, "application/octet-stream",
378 return PEP_STATUS_OK;
381 status = PEP_OUT_OF_MEMORY;
390 static PEP_STATUS encrypt_PGP_in_pieces(
397 PEP_STATUS status = PEP_STATUS_OK;
401 bool free_ptext = false;
403 assert(dst->longmsg == NULL);
404 assert(dst->attachments == NULL);
406 dst->enc_format = PEP_enc_pieces;
408 if (src->shortmsg && src->shortmsg[0] && strcmp(src->shortmsg, "pEp") != 0) {
409 if (session->unencrypted_subject) {
410 dst->shortmsg = strdup(src->shortmsg);
411 if (dst->shortmsg == NULL)
413 ptext = src->longmsg;
416 ptext = combine_short_and_long(src->shortmsg, src->longmsg);
422 status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
428 dst->longmsg = strndup(ctext, csize);
429 assert(dst->longmsg);
430 if (dst->longmsg == NULL)
437 else if (src->longmsg && src->longmsg[0]) {
438 ptext = src->longmsg;
439 status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
442 dst->longmsg = strndup(ctext, csize);
443 assert(dst->longmsg);
444 if (dst->longmsg == NULL)
452 dst->longmsg = strdup("");
453 if (dst->longmsg == NULL)
457 if (src->longmsg_formatted && src->longmsg_formatted[0]) {
458 ptext = src->longmsg_formatted;
459 status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
462 char *_ctext = malloc(csize);
466 memcpy(_ctext, ctext, csize);
468 bloblist_t *_a = bloblist_add(dst->attachments, _ctext, csize,
469 "application/octet-stream", "PGPexch.htm.pgp");
472 if (dst->attachments == NULL)
473 dst->attachments = _a;
480 if (src->attachments) {
481 if (dst->attachments == NULL) {
482 dst->attachments = new_bloblist(NULL, 0, NULL, NULL);
483 if (dst->attachments == NULL)
487 bloblist_t *_s = src->attachments;
488 bloblist_t *_d = dst->attachments;
490 for (int n = 0; _s && _s->value; _s = _s->next) {
491 size_t psize = _s->size;
493 status = encrypt_and_sign(session, keys, ptext, psize, &ctext,
496 char *filename = NULL;
499 size_t len = strlen(_s->filename);
500 filename = calloc(1, len + 5);
501 if (filename == NULL)
504 strcpy(filename, _s->filename);
505 strcpy(filename + len, ".pgp");
508 filename = calloc(1, 20);
509 if (filename == NULL)
514 snprintf(filename, 20, "Attachment%d.pgp", n);
517 char *_ctext = malloc(csize);
521 memcpy(_ctext, ctext, csize);
523 _d = bloblist_add(_d, _ctext, csize, "application/octet-stream",
534 return PEP_STATUS_OK;
537 status = PEP_OUT_OF_MEMORY;
545 static char * keylist_to_string(const stringlist_t *keylist)
548 size_t size = stringlist_length(keylist);
550 const stringlist_t *_kl;
551 for (_kl = keylist; _kl && _kl->value; _kl = _kl->next) {
552 size += strlen(_kl->value);
555 char *result = calloc(1, size);
560 for (_kl = keylist; _kl && _kl->value; _kl = _kl->next) {
561 _r = stpcpy(_r, _kl->value);
562 if (_kl->next && _kl->next->value)
563 _r = stpcpy(_r, ",");
573 static const char * color_to_string(PEP_color color)
576 case PEP_rating_cannot_decrypt:
577 return "cannot_decrypt";
578 case PEP_rating_have_no_key:
579 return "have_no_key";
580 case PEP_rating_unencrypted:
581 return "unencrypted";
582 case PEP_rating_unreliable:
584 case PEP_rating_reliable:
586 case PEP_rating_trusted:
588 case PEP_rating_trusted_and_anonymized:
589 return "trusted_and_anonymized";
590 case PEP_rating_fully_anonymous:
591 return "fully_anonymous";
592 case PEP_rating_mistrust:
594 case PEP_rating_b0rken:
596 case PEP_rating_under_attack:
597 return "unter_attack";
603 static void decorate_message(
606 stringlist_t *keylist
611 add_opt_field(msg, "X-pEp-Version", "1.0");
613 if (color != PEP_rating_undefined)
614 add_opt_field(msg, "X-EncStatus", color_to_string(color));
617 char *_keylist = keylist_to_string(keylist);
618 add_opt_field(msg, "X-KeyList", _keylist);
623 static PEP_color _rating(PEP_comm_type ct)
625 if (ct == PEP_ct_unknown)
626 return PEP_rating_undefined;
628 else if (ct == PEP_ct_compromized)
629 return PEP_rating_under_attack;
631 else if (ct == PEP_ct_mistrusted)
632 return PEP_rating_mistrust;
634 else if (ct >= PEP_ct_confirmed_enc_anon)
635 return PEP_rating_trusted_and_anonymized;
637 else if (ct >= PEP_ct_strong_encryption)
638 return PEP_rating_trusted;
640 else if (ct >= PEP_ct_strong_but_unconfirmed && ct < PEP_ct_confirmed)
641 return PEP_rating_reliable;
643 else if (ct == PEP_ct_no_encryption || ct == PEP_ct_no_encrypted_channel)
644 return PEP_rating_unencrypted;
647 return PEP_rating_unreliable;
650 static bool is_encrypted_attachment(const bloblist_t *blob)
656 if (blob->filename == NULL)
659 ext = strrchr(blob->filename, '.');
663 if (strcmp(blob->mime_type, "application/octet-stream") == 0) {
664 if (strcmp(ext, ".pgp") == 0 || strcmp(ext, ".gpg") == 0 ||
665 strcmp(ext, ".asc") == 0)
668 else if (strcmp(blob->mime_type, "text/plain") == 0) {
669 if (strcmp(ext, ".asc") == 0)
676 static bool is_encrypted_html_attachment(const bloblist_t *blob)
679 assert(blob->filename);
681 if (strncmp(blob->filename, "PGPexch.htm.", 12) == 0) {
682 if (strcmp(blob->filename + 11, ".pgp") == 0 ||
683 strcmp(blob->filename + 11, ".asc") == 0)
690 static char * without_double_ending(const char *filename)
696 ext = strrchr(filename, '.');
700 return strndup(filename, ext - filename);
703 static PEP_color decrypt_color(PEP_STATUS status)
706 case PEP_UNENCRYPTED:
708 case PEP_VERIFY_NO_KEY:
709 case PEP_VERIFIED_AND_TRUSTED:
710 return PEP_rating_unencrypted;
713 return PEP_rating_unreliable;
715 case PEP_DECRYPTED_AND_VERIFIED:
716 return PEP_rating_reliable;
718 case PEP_DECRYPT_NO_KEY:
719 return PEP_rating_have_no_key;
721 case PEP_DECRYPT_WRONG_FORMAT:
722 case PEP_CANNOT_DECRYPT_UNKNOWN:
723 return PEP_rating_cannot_decrypt;
726 return PEP_rating_undefined;
730 static PEP_color key_color(PEP_SESSION session, const char *fpr)
732 PEP_comm_type comm_type = PEP_ct_unknown;
737 PEP_STATUS status = get_key_rating(session, fpr, &comm_type);
738 if (status != PEP_STATUS_OK)
739 return PEP_rating_undefined;
741 return _rating(comm_type);
744 static PEP_color keylist_color(PEP_SESSION session, stringlist_t *keylist)
746 PEP_color color = PEP_rating_reliable;
748 assert(keylist && keylist->value);
749 if (keylist == NULL || keylist->value == NULL)
750 return PEP_rating_unencrypted;
753 for (_kl = keylist; _kl && _kl->value; _kl = _kl->next) {
757 color = key_color(session, _kl->value);
758 if (color == PEP_rating_under_attack)
759 return PEP_rating_under_attack;
761 if (color >= PEP_rating_reliable) {
762 status = least_trust(session, _kl->value, &ct);
763 if (status != PEP_STATUS_OK)
764 return PEP_rating_undefined;
765 if (ct == PEP_ct_unknown)
766 color = PEP_rating_unreliable;
775 static PEP_comm_type _get_comm_type(
777 PEP_comm_type max_comm_type,
781 PEP_STATUS status = update_identity(session, ident);
783 if (max_comm_type == PEP_ct_compromized)
784 return PEP_ct_compromized;
786 if (status == PEP_STATUS_OK) {
787 if (ident->comm_type == PEP_ct_compromized)
788 return PEP_ct_compromized;
790 return MIN(max_comm_type, ident->comm_type);
793 return PEP_ct_unknown;
797 void import_attached_keys(PEP_SESSION session, const message *msg)
803 for (bl = msg->attachments; bl && bl->value; bl = bl->next) {
804 assert(bl && bl->value && bl->size);
806 // workaround for Apple Mail bugs
807 if (is_mime_type(bl, "application/x-apple-msg-attachment")) {
808 if (is_fileending(bl, ".asc")) {
809 if (strlen(bl->filename) == 14 &&
810 bl->filename[0] == '0' && bl->filename[1] == 'x')
811 import_key(session, bl->value, bl->size);
812 else if (strlen(bl->filename) == 12)
813 import_key(session, bl->value, bl->size);
816 else if (bl->mime_type == NULL ||
817 is_mime_type(bl, "application/octet-stream")) {
818 if (is_fileending(bl, ".pgp") || is_fileending(bl, ".gpg") ||
819 is_fileending(bl, ".key") || is_fileending(bl, ".asc"))
820 import_key(session, bl->value, bl->size);
822 else if (is_mime_type(bl, "application/pgp-keys")) {
823 import_key(session, bl->value, bl->size);
825 else if (is_mime_type(bl, "text/plain")) {
826 if (is_fileending(bl, ".pgp") || is_fileending(bl, ".gpg") ||
827 is_fileending(bl, ".key") || is_fileending(bl, ".asc"))
828 import_key(session, bl->value, bl->size);
831 if(msg->from && msg->from->user_id && msg->from->address)
832 update_identity(session, msg->from);
835 void attach_own_key(PEP_SESSION session, message *msg)
844 if (msg->dir == PEP_dir_incoming)
847 assert(msg->from && msg->from->fpr);
848 if (msg->from == NULL || msg->from->fpr == NULL)
851 PEP_STATUS status = export_key(session, msg->from->fpr, &keydata, &size);
852 assert(status == PEP_STATUS_OK);
853 if (status != PEP_STATUS_OK)
857 bl = bloblist_add(msg->attachments, keydata, size, "application/pgp-keys",
859 if (msg->attachments == NULL && bl)
860 msg->attachments = bl;
863 PEP_cryptotech determine_encryption_format(message *msg)
867 if (is_PGP_message_text(msg->longmsg)) {
868 msg->enc_format = PEP_enc_pieces;
869 return PEP_crypt_OpenPGP;
871 else if (msg->attachments && msg->attachments->next &&
872 is_mime_type(msg->attachments, "application/pgp-encrypted") &&
873 is_PGP_message_text(msg->attachments->next->value)
875 msg->enc_format = PEP_enc_PGP_MIME;
876 return PEP_crypt_OpenPGP;
879 msg->enc_format = PEP_enc_none;
880 return PEP_crypt_none;
884 DYNAMIC_API PEP_STATUS encrypt_message(
887 stringlist_t * extra,
889 PEP_enc_format enc_format
892 PEP_STATUS status = PEP_STATUS_OK;
893 message * msg = NULL;
894 stringlist_t * keys = NULL;
899 assert(enc_format != PEP_enc_none);
901 if (!(session && src && dst && enc_format != PEP_enc_none))
902 return PEP_ILLEGAL_VALUE;
904 determine_encryption_format(src);
905 if (src->enc_format != PEP_enc_none)
906 return PEP_ILLEGAL_VALUE;
910 status = myself(session, src->from);
911 if (status != PEP_STATUS_OK)
914 keys = new_stringlist(src->from->fpr);
918 stringlist_t *_k = keys;
921 _k = stringlist_append(_k, extra);
926 bool dest_keys_found = true;
929 for (_il = src->to; _il && _il->ident; _il = _il->next) {
930 PEP_STATUS _status = update_identity(session, _il->ident);
931 if (_status != PEP_STATUS_OK) {
936 if (_il->ident->fpr && _il->ident->fpr[0]) {
937 _k = stringlist_add(_k, _il->ident->fpr);
942 dest_keys_found = false;
943 status = PEP_KEY_NOT_FOUND;
947 for (_il = src->cc; _il && _il->ident; _il = _il->next) {
948 PEP_STATUS _status = update_identity(session, _il->ident);
949 if (_status != PEP_STATUS_OK)
955 if (_il->ident->fpr && _il->ident->fpr[0]) {
956 _k = stringlist_add(_k, _il->ident->fpr);
961 dest_keys_found = false;
962 status = PEP_KEY_NOT_FOUND;
966 if (!dest_keys_found) {
967 free_stringlist(keys);
968 if (!session->passive_mode)
969 attach_own_key(session, src);
970 return PEP_UNENCRYPTED;
973 msg = clone_to_empty_message(src);
977 attach_own_key(session, src);
979 switch (enc_format) {
980 case PEP_enc_PGP_MIME:
981 case PEP_enc_PEP: // BUG: should be implemented extra
982 status = encrypt_PGP_MIME(session, src, keys, msg);
986 status = encrypt_PGP_in_pieces(session, src, keys, msg);
995 status = PEP_ILLEGAL_VALUE;
999 if (status == PEP_OUT_OF_MEMORY)
1002 if (status != PEP_STATUS_OK) {
1003 attach_own_key(session, src);
1008 free_stringlist(keys);
1010 if (msg && msg->shortmsg == NULL)
1011 msg->shortmsg = strdup("pEp");
1014 decorate_message(msg, PEP_rating_undefined, NULL);
1020 status = PEP_OUT_OF_MEMORY;
1023 free_stringlist(keys);
1029 DYNAMIC_API PEP_STATUS decrypt_message(
1030 PEP_SESSION session,
1033 stringlist_t **keylist,
1037 PEP_STATUS status = PEP_STATUS_OK;
1038 PEP_STATUS decrypt_status = PEP_CANNOT_DECRYPT_UNKNOWN;
1039 message *msg = NULL;
1044 stringlist_t *_keylist = NULL;
1052 if (!(session && src && dst && keylist && color))
1053 return PEP_ILLEGAL_VALUE;
1055 import_attached_keys(session, src);
1056 PEP_cryptotech crypto = determine_encryption_format(src);
1060 *color = PEP_rating_undefined;
1062 switch (src->enc_format) {
1064 *color = PEP_rating_unencrypted;
1065 return PEP_UNENCRYPTED;
1067 case PEP_enc_PGP_MIME:
1068 ctext = src->attachments->next->value;
1069 csize = src->attachments->next->size;
1072 case PEP_enc_pieces:
1073 ctext = src->longmsg;
1074 csize = strlen(ctext);
1080 status = cryptotech[crypto].decrypt_and_verify(session, ctext,
1081 csize, &ptext, &psize, &_keylist);
1082 if (status > PEP_CANNOT_DECRYPT_UNKNOWN)
1085 decrypt_status = status;
1088 switch (src->enc_format) {
1089 case PEP_enc_PGP_MIME:
1090 status = mime_decode_message(ptext, psize, &msg);
1091 if (status != PEP_STATUS_OK)
1095 case PEP_enc_pieces:
1096 msg = clone_to_empty_message(src);
1100 msg->longmsg = strdup(ptext);
1101 if (msg->longmsg == NULL)
1104 bloblist_t *_m = msg->attachments;
1105 if (_m == NULL && src->attachments && src->attachments->value) {
1106 msg->attachments = new_bloblist(NULL, 0, NULL, NULL);
1107 _m = msg->attachments;
1111 for (_s = src->attachments; _s && _s->value; _s = _s->next) {
1112 if (is_encrypted_attachment(_s)) {
1113 stringlist_t *_keylist = NULL;
1117 attctext = _s->value;
1118 attcsize = _s->size;
1120 status = decrypt_and_verify(session, attctext, attcsize,
1121 &ptext, &psize, &_keylist);
1122 free_stringlist(_keylist);
1125 if (is_encrypted_html_attachment(_s)) {
1126 msg->longmsg_formatted = strdup(ptext);
1127 if (msg->longmsg_formatted == NULL)
1131 char * mime_type = "application/octet-stream";
1133 without_double_ending(_s->filename);
1134 if (filename == NULL)
1137 char *_ptext = malloc(psize);
1141 memcpy(_ptext, ptext, psize);
1143 _m = bloblist_add(_m, _ptext, psize, mime_type,
1148 if (msg->attachments == NULL)
1149 msg->attachments = _m;
1153 char *copy = malloc(_s->size);
1157 memcpy(copy, _s->value, _s->size);
1158 _m = bloblist_add(_m, copy, _s->size, _s->mime_type, _s->filename);
1164 char *copy = malloc(_s->size);
1168 memcpy(copy, _s->value, _s->size);
1169 _m = bloblist_add(_m, copy, _s->size, _s->mime_type, _s->filename);
1178 // BUG: must implement more
1182 switch (src->enc_format) {
1183 case PEP_enc_PGP_MIME:
1184 case PEP_enc_pieces:
1185 status = copy_fields(msg, src);
1186 if (status != PEP_STATUS_OK)
1189 if (src->shortmsg == NULL || strcmp(src->shortmsg, "pEp") == 0)
1194 int r = seperate_short_and_long(msg->longmsg, &shortmsg,
1199 free(msg->shortmsg);
1202 msg->shortmsg = shortmsg;
1203 msg->longmsg = longmsg;
1206 msg->shortmsg = strdup(src->shortmsg);
1207 if (msg->shortmsg == NULL)
1213 // BUG: must implement more
1217 import_attached_keys(session, msg);
1219 if(decrypt_status == PEP_DECRYPTED){
1221 // In case message did decrypt, but no valid signature could be found
1222 // then retry decrypt+verify after importing key.
1223 // TODO optimize if import_attached_keys didn't import any key
1225 char *re_ptext = NULL;
1228 free_stringlist(_keylist);
1231 status = cryptotech[crypto].decrypt_and_verify(session, ctext,
1232 csize, &re_ptext, &re_psize, &_keylist);
1237 if (status > PEP_CANNOT_DECRYPT_UNKNOWN)
1240 decrypt_status = status;
1243 *color = decrypt_color(decrypt_status);
1245 if (*color != PEP_rating_under_attack) {
1246 PEP_color kl_color = PEP_rating_undefined;
1249 kl_color = keylist_color(session, _keylist);
1251 if (kl_color == PEP_rating_under_attack) {
1252 *color = PEP_rating_under_attack;
1254 else if (kl_color == PEP_rating_mistrust) {
1255 *color = PEP_rating_mistrust;
1257 else if (*color >= PEP_rating_reliable &&
1258 kl_color < PEP_rating_reliable) {
1259 *color = PEP_rating_unreliable;
1261 else if (*color >= PEP_rating_reliable &&
1262 kl_color >= PEP_rating_reliable) {
1263 if (!(src->from && src->from->user_id && src->from->user_id[0])) {
1264 *color = PEP_rating_unreliable;
1267 char *fpr = _keylist->value;
1268 pEp_identity *_from = new_identity(src->from->address, fpr,
1269 src->from->user_id, src->from->username);
1272 status = update_identity(session, _from);
1273 if (_from->comm_type != PEP_ct_unknown)
1274 *color = _rating(_from->comm_type);
1275 free_identity(_from);
1276 if (status != PEP_STATUS_OK)
1284 decorate_message(msg, *color, _keylist);
1287 *keylist = _keylist;
1289 return PEP_STATUS_OK;
1292 status = PEP_OUT_OF_MEMORY;
1296 free_stringlist(_keylist);
1301 DYNAMIC_API PEP_STATUS outgoing_message_color(
1302 PEP_SESSION session,
1307 PEP_STATUS status = PEP_STATUS_OK;
1308 PEP_comm_type max_comm_type = PEP_ct_pEp;
1309 bool comm_type_determined = false;
1315 assert(msg->dir == PEP_dir_outgoing);
1318 if (!(session && msg && color))
1319 return PEP_ILLEGAL_VALUE;
1321 if (msg->from == NULL || msg->dir != PEP_dir_outgoing)
1322 return PEP_ILLEGAL_VALUE;
1324 *color = PEP_rating_undefined;
1326 status = myself(session, msg->from);
1327 if (status != PEP_STATUS_OK)
1330 for (il = msg->to; il != NULL; il = il->next) {
1332 update_identity(session, il->ident);
1333 max_comm_type = _get_comm_type(session, max_comm_type,
1335 comm_type_determined = true;
1339 for (il = msg->cc; il != NULL; il = il->next) {
1341 update_identity(session, il->ident);
1342 max_comm_type = _get_comm_type(session, max_comm_type,
1344 comm_type_determined = true;
1348 if (comm_type_determined == false)
1349 *color = PEP_rating_undefined;
1351 *color = MAX(_rating(max_comm_type), PEP_rating_unencrypted);
1353 return PEP_STATUS_OK;
1356 DYNAMIC_API PEP_STATUS identity_color(
1357 PEP_SESSION session,
1358 pEp_identity *ident,
1362 PEP_STATUS status = PEP_STATUS_OK;
1368 if (!(session && ident && color))
1369 return PEP_ILLEGAL_VALUE;
1372 status = myself(session, ident);
1374 status = update_identity(session, ident);
1376 if (status == PEP_STATUS_OK)
1377 *color = _rating(ident->comm_type);