src/message_api.c
author vb
Sun, 22 Feb 2015 13:40:25 +0100
changeset 63 f5b2641f4ae7
parent 62 ad5e484720e1
child 64 d393c205d201
permissions -rw-r--r--
some redesign and bugfixing
vb@37
     1
#include "message_api.h"
vb@37
     2
#include "keymanagement.h"
vb@62
     3
#include "mime.h"
vb@37
     4
vb@37
     5
#include <assert.h>
vb@37
     6
#include <string.h>
vb@39
     7
#include <stdlib.h>
vb@39
     8
vb@39
     9
#define NOT_IMPLEMENTED assert(0);
vb@37
    10
vb@62
    11
static char * combine_short_and_long(const message * src)
vb@62
    12
{
vb@62
    13
    char * ptext;
vb@63
    14
    char * longmsg;
vb@62
    15
    assert(src);
vb@63
    16
    assert(src->shortmsg && strcmp(src->shortmsg, "pEp") != 0);
vb@62
    17
vb@63
    18
    if (src->longmsg)
vb@63
    19
        longmsg = src->longmsg;
vb@63
    20
    else
vb@63
    21
        longmsg = "";
vb@63
    22
vb@63
    23
    ptext = calloc(1, strlen(src->shortmsg) + strlen(longmsg) + 12);
vb@62
    24
    if (ptext == NULL)
vb@62
    25
        return NULL;
vb@62
    26
vb@62
    27
    strcpy(ptext, "subject: ");
vb@62
    28
    strcat(ptext, src->shortmsg);
vb@62
    29
    strcat(ptext, "\n\n");
vb@63
    30
    strcat(ptext, longmsg);
vb@62
    31
vb@62
    32
    return ptext;
vb@62
    33
}
vb@44
    34
vb@48
    35
DYNAMIC_API PEP_STATUS encrypt_message(
vb@37
    36
        PEP_SESSION session,
vb@37
    37
        const message *src,
vb@37
    38
        stringlist_t * extra,
vb@38
    39
        message **dst,
vb@38
    40
        PEP_enc_format format
vb@37
    41
    )
vb@37
    42
{
vb@37
    43
    PEP_STATUS status = PEP_STATUS_OK;
vb@63
    44
    message * msg = NULL;
vb@63
    45
    stringlist_t * keys = NULL;
vb@37
    46
vb@37
    47
    assert(session);
vb@37
    48
    assert(src);
vb@37
    49
    assert(dst);
vb@37
    50
    *dst = NULL;
vb@38
    51
    assert(format != PEP_enc_none);
vb@37
    52
vb@40
    53
    pEp_identity *from = identity_dup(src->from);
vb@40
    54
    if (from == NULL)
vb@63
    55
        goto enomem;
vb@63
    56
    from->me = true;
vb@40
    57
vb@40
    58
    identity_list *to = identity_list_dup(src->to);
vb@40
    59
    if (to == NULL) {
vb@40
    60
        free_identity(from);
vb@63
    61
        goto enomem;
vb@40
    62
    }
vb@40
    63
vb@63
    64
    msg = new_message(src->dir, from, to, NULL);
vb@56
    65
    if (msg == NULL) {
vb@56
    66
        free_identity(from);
vb@56
    67
        free_identity_list(to);
vb@63
    68
        goto enomem;
vb@56
    69
    }
vb@48
    70
    msg->enc_format = PEP_enc_pieces;
vb@37
    71
vb@63
    72
    status = myself(session, from);
vb@63
    73
    if (status != PEP_STATUS_OK)
vb@63
    74
        goto pep_error;
vb@37
    75
vb@63
    76
    keys = new_stringlist(from->fpr);
vb@63
    77
    if (keys == NULL)
vb@63
    78
        goto enomem;
vb@37
    79
vb@39
    80
    stringlist_t *_k = keys;
vb@39
    81
vb@39
    82
    if (extra) {
vb@39
    83
        _k = stringlist_append(_k, extra);
vb@63
    84
        if (_k == NULL)
vb@63
    85
            goto enomem;
vb@37
    86
    }
vb@39
    87
vb@39
    88
    bool dest_keys_found = false;
vb@37
    89
    identity_list * _il;
vb@40
    90
    for (_il = to; _il && _il->ident; _il = _il->next) {
vb@63
    91
        PEP_STATUS status = update_identity(session, _il->ident);
vb@63
    92
        if (status != PEP_STATUS_OK)
vb@63
    93
            goto pep_error;
vb@63
    94
vb@37
    95
        if (_il->ident->fpr) {
vb@39
    96
            dest_keys_found = true;
vb@39
    97
            _k = stringlist_add(_k, _il->ident->fpr);
vb@63
    98
            if (_k == NULL)
vb@63
    99
                goto enomem;
vb@37
   100
        }
vb@37
   101
        else
vb@37
   102
            status = PEP_KEY_NOT_FOUND;
vb@37
   103
    }
vb@37
   104
vb@39
   105
    if (dest_keys_found) {
vb@38
   106
        char *ptext;
vb@37
   107
        char *ctext = NULL;
vb@37
   108
        size_t csize = 0;
vb@48
   109
        msg->enc_format = PEP_enc_pieces;
vb@37
   110
vb@38
   111
        switch (format) {
vb@44
   112
        case PEP_enc_MIME_multipart: {
vb@63
   113
            char *resulttext = NULL;
vb@62
   114
            bool free_ptext = false;
vb@48
   115
            msg->enc_format = PEP_enc_MIME_multipart;
vb@37
   116
vb@63
   117
            if (src->shortmsg && strcmp(src->shortmsg, "pEp") != 0) {
vb@62
   118
                ptext = combine_short_and_long(src);
vb@63
   119
                if (ptext == NULL)
vb@63
   120
                    goto enomem;
vb@62
   121
                free_ptext = true;
vb@62
   122
            }
vb@62
   123
            else if (src->longmsg) {
vb@62
   124
                ptext = src->longmsg;
vb@62
   125
            }
vb@62
   126
            else {
vb@63
   127
                assert(0);
vb@63
   128
                status = PEP_ILLEGAL_VALUE;
vb@63
   129
                goto pep_error;
vb@62
   130
            }
vb@62
   131
vb@62
   132
            status = mime_encode_text(ptext, src->longmsg_formatted,
vb@62
   133
                    src->attachments, &resulttext);
vb@62
   134
            assert(status == PEP_STATUS_OK);
vb@62
   135
            if (free_ptext)
vb@62
   136
                free(ptext);
vb@62
   137
            assert(resulttext);
vb@63
   138
            if (resulttext == NULL)
vb@63
   139
                goto pep_error;
vb@62
   140
            
vb@62
   141
            status = encrypt_and_sign(session, keys, resulttext, strlen(resulttext),
vb@62
   142
                    &ctext, &csize);
vb@62
   143
            free(resulttext);
vb@62
   144
            if (ctext) {
vb@62
   145
                msg->longmsg = strdup(ctext);
vb@62
   146
                msg->shortmsg = strdup("pEp");
vb@63
   147
                if (!(msg->longmsg && msg->shortmsg))
vb@63
   148
                    goto enomem;
vb@63
   149
            }
vb@63
   150
            else {
vb@63
   151
                goto pep_error;
vb@62
   152
            }
vb@62
   153
        }
vb@63
   154
        break;
vb@62
   155
vb@62
   156
        case PEP_enc_pieces:
vb@63
   157
            if (src->shortmsg && strcmp(src->shortmsg, "pEp") != 0) {
vb@62
   158
                ptext = combine_short_and_long(src);
vb@63
   159
                if (ptext == NULL)
vb@63
   160
                    goto enomem;
vb@63
   161
vb@39
   162
                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
vb@39
   163
                        &ctext, &csize);
vb@40
   164
                free(ptext);
vb@38
   165
                if (ctext) {
vb@40
   166
                    msg->longmsg = strdup(ctext);
vb@38
   167
                    msg->shortmsg = strdup("pEp");
vb@63
   168
                    if (!(msg->longmsg && msg->shortmsg))
vb@63
   169
                        goto enomem;
vb@38
   170
                }
vb@38
   171
                else {
vb@63
   172
                    goto pep_error;
vb@38
   173
                }
vb@38
   174
            }
vb@38
   175
            else if (src->longmsg) {
vb@38
   176
                ptext = src->longmsg;
vb@39
   177
                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
vb@39
   178
                        &ctext, &csize);
vb@38
   179
                if (ctext) {
vb@40
   180
                    msg->longmsg = strdup(ctext);
vb@38
   181
                    msg->shortmsg = strdup("pEp");
vb@63
   182
                    if (!(msg->longmsg && msg->shortmsg))
vb@63
   183
                        goto enomem;
vb@38
   184
                }
vb@38
   185
                else {
vb@63
   186
                    goto pep_error;
vb@38
   187
                }
vb@38
   188
            }
vb@63
   189
vb@63
   190
            if (msg->longmsg_formatted) {
vb@38
   191
                ptext = src->longmsg_formatted;
vb@39
   192
                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
vb@39
   193
                        &ctext, &csize);
vb@38
   194
                if (ctext) {
vb@40
   195
                    msg->longmsg_formatted = strdup(ctext);
vb@63
   196
                    if (msg->longmsg_formatted == NULL)
vb@63
   197
                        goto enomem;
vb@63
   198
                }
vb@63
   199
                else {
vb@63
   200
                    goto pep_error;
vb@63
   201
                }
vb@63
   202
            }
vb@63
   203
vb@63
   204
            if (src->attachments) {
vb@63
   205
                bloblist_t *_s;
vb@63
   206
                bloblist_t *_d = new_bloblist(NULL, 0, NULL, NULL);
vb@63
   207
                if (_d == NULL)
vb@63
   208
                    goto enomem;
vb@63
   209
vb@63
   210
                msg->attachments = _d;
vb@63
   211
                for (_s = src->attachments; _s && _s->data; _s = _s->next) {
vb@63
   212
                    int psize = _s->size;
vb@63
   213
                    ptext = _s->data;
vb@63
   214
                    status = encrypt_and_sign(session, keys, ptext, psize,
vb@63
   215
                            &ctext, &csize);
vb@63
   216
                    if (ctext) {
vb@63
   217
                        char * _c = strdup(ctext);
vb@63
   218
                        if (_c == NULL)
vb@63
   219
                            goto enomem;
vb@63
   220
vb@63
   221
                        _d = bloblist_add(_d, _c, csize, _s->mime_type,
vb@63
   222
                                _s->file_name);
vb@63
   223
                        if (_d == NULL)
vb@63
   224
                            goto enomem;
vb@63
   225
                    }
vb@63
   226
                    else {
vb@63
   227
                        goto pep_error;
vb@40
   228
                    }
vb@38
   229
                }
vb@38
   230
            }
vb@38
   231
            break;
vb@38
   232
vb@38
   233
        default:
vb@38
   234
            assert(0);
vb@63
   235
            status = PEP_ILLEGAL_VALUE;
vb@63
   236
            goto pep_error;
vb@37
   237
        }
vb@37
   238
    }
vb@37
   239
vb@37
   240
    free_stringlist(keys);
vb@63
   241
vb@63
   242
    *dst = msg;
vb@63
   243
    return PEP_STATUS_OK;
vb@63
   244
vb@63
   245
enomem:
vb@63
   246
    status = PEP_OUT_OF_MEMORY;
vb@63
   247
vb@63
   248
pep_error:
vb@63
   249
    free_stringlist(keys);
vb@63
   250
    free_message(msg);
vb@63
   251
vb@37
   252
    return status;
vb@37
   253
}
vb@37
   254
vb@48
   255
DYNAMIC_API PEP_STATUS decrypt_message(
vb@37
   256
        PEP_SESSION session,
vb@37
   257
        const message *src,
vb@37
   258
        message **dst
vb@37
   259
    )
vb@37
   260
{
vb@37
   261
    PEP_STATUS status = PEP_STATUS_OK;
vb@37
   262
vb@39
   263
    NOT_IMPLEMENTED
vb@39
   264
vb@37
   265
    return status;
vb@37
   266
}
vb@37
   267