src/baseprotocol.c
author Neal H. Walfield <neal@pep.foundation>
Wed, 08 May 2019 12:20:37 +0200
branchemail_comparison
changeset 3649 1dd837adc30b
parent 3544 70eae1a189c3
child 3817 c2cb0ab6040a
permissions -rw-r--r--
Fix public key.
vb@1513
     1
// This file is under GNU General Public License 3.0
vb@1513
     2
// see LICENSE.txt
vb@1513
     3
vb@585
     4
#include "pEp_internal.h"
vb@952
     5
#include "message_api.h"
vb@585
     6
vb@2846
     7
PEP_STATUS base_decorate_message(
vb@3143
     8
        PEP_SESSION session,
vb@587
     9
        message *msg,
vb@587
    10
        char *payload,
vb@3129
    11
        size_t size,
vb@3544
    12
        const char *fpr
vb@587
    13
    )
vb@587
    14
{
vb@3143
    15
    PEP_STATUS status = PEP_STATUS_OK;
vb@3143
    16
vb@587
    17
    assert(msg);
vb@587
    18
    assert(payload);
vb@587
    19
    assert(size);
vb@587
    20
vb@587
    21
    if (!(msg && payload && size))
vb@587
    22
        return PEP_ILLEGAL_VALUE;
vb@587
    23
vb@587
    24
    bloblist_t *bl = bloblist_add(msg->attachments, payload, size,
krista@1871
    25
            "application/pEp.sync", "ignore_this_attachment.pEp");
vb@587
    26
    if (bl == NULL)
vb@587
    27
        goto enomem;
krista@3154
    28
    else if (!msg->attachments) {
krista@3154
    29
        msg->attachments = bl;
krista@3154
    30
    }
vb@587
    31
vb@3129
    32
    if (fpr) {
vb@3143
    33
        char *sign;
vb@3143
    34
        size_t sign_size;
vb@3143
    35
        status = sign_only(session,  payload, size, fpr, &sign, &sign_size);
vb@3143
    36
        if (status)
vb@3143
    37
            goto error;
vb@3143
    38
vb@3143
    39
        assert(sign && sign_size);
vb@3143
    40
vb@3143
    41
        bl = bloblist_add(bl, sign, sign_size,
vb@3312
    42
                "application/pEp.sign", "electronic_signature.asc");
vb@3143
    43
        if (!bl)
vb@3143
    44
            goto enomem;
vb@3129
    45
    }
vb@3129
    46
vb@3393
    47
    return status;
vb@587
    48
vb@587
    49
enomem:
vb@3143
    50
    status = PEP_OUT_OF_MEMORY;
vb@3143
    51
vb@3143
    52
error:
vb@3143
    53
    return status;
vb@587
    54
}
vb@587
    55
vb@2846
    56
PEP_STATUS base_prepare_message(
vb@3143
    57
        PEP_SESSION session,
vb@585
    58
        const pEp_identity *me,
vb@585
    59
        const pEp_identity *partner,
vb@585
    60
        char *payload,
vb@585
    61
        size_t size,
vb@3393
    62
        const char *fpr,
vb@585
    63
        message **result
vb@585
    64
    )
vb@585
    65
{
vb@587
    66
    PEP_STATUS status = PEP_STATUS_OK;
vb@587
    67
vb@585
    68
    assert(me);
vb@585
    69
    assert(partner);
vb@585
    70
    assert(payload);
vb@587
    71
    assert(size);
vb@587
    72
    assert(result);
vb@587
    73
vb@587
    74
    if (!(me && partner && payload && size && result))
vb@587
    75
        return PEP_ILLEGAL_VALUE;
vb@585
    76
vb@585
    77
    *result = NULL;
vb@585
    78
vb@585
    79
    message *msg = new_message(PEP_dir_outgoing);
vb@585
    80
    if (!msg)
vb@585
    81
        goto enomem;
vb@585
    82
vb@1132
    83
    add_opt_field(msg, "pEp-auto-consume", "yes");
vb@952
    84
vb@585
    85
    msg->from = identity_dup(me);
vb@585
    86
    if (!msg->from)
vb@585
    87
        goto enomem;
vb@585
    88
vb@585
    89
    msg->to = new_identity_list(identity_dup(partner));
vb@585
    90
    if (!msg->to)
vb@585
    91
        goto enomem;
vb@585
    92
vb@952
    93
    msg->shortmsg = strdup("p≡p synchronization message - please ignore");
vb@585
    94
    assert(msg->shortmsg);
vb@585
    95
    if (!msg->shortmsg)
vb@585
    96
        goto enomem;
vb@585
    97
vb@585
    98
    msg->longmsg = strdup("This message is part of p≡p's concept to synchronize.\n\n"
vb@585
    99
                        "You can safely ignore it. It will be deleted automatically.\n");
vb@585
   100
    assert(msg->longmsg);
vb@585
   101
    if (!msg->longmsg)
vb@585
   102
        goto enomem;
vb@585
   103
vb@3544
   104
    status = base_decorate_message(session, msg, payload, size, fpr);
vb@587
   105
    if (status == PEP_STATUS_OK)
vb@587
   106
        *result = msg;
vb@587
   107
    return status;
vb@585
   108
vb@585
   109
enomem:
vb@585
   110
    free_message(msg);
vb@585
   111
    return PEP_OUT_OF_MEMORY;
vb@585
   112
}
krista@1871
   113
vb@3143
   114
PEP_STATUS base_extract_message(
vb@3143
   115
        PEP_SESSION session,
vb@3143
   116
        message *msg,
vb@3143
   117
        size_t *size,
vb@3143
   118
        const char **payload,
vb@3143
   119
        char **fpr
vb@3143
   120
    )
vb@3130
   121
{
vb@3130
   122
    PEP_STATUS status = PEP_STATUS_OK;
vb@3130
   123
vb@3143
   124
    assert(session && msg && size && payload && fpr);
vb@3143
   125
    if (!(session && msg && size && payload && fpr))
vb@3130
   126
        return PEP_ILLEGAL_VALUE;
vb@3130
   127
vb@3130
   128
    *size = 0;
vb@3130
   129
    *payload = NULL;
vb@3157
   130
    *fpr = NULL;
vb@3130
   131
vb@3143
   132
    const char *_payload = NULL;
vb@3143
   133
    size_t _payload_size = 0;
vb@3143
   134
    const char *_sign = NULL;
vb@3143
   135
    size_t _sign_size = 0;
vb@3143
   136
    stringlist_t *keylist = NULL;
vb@3143
   137
vb@3130
   138
    for (bloblist_t *bl = msg->attachments; bl ; bl = bl->next) {
vb@3130
   139
        if (bl->mime_type && strcasecmp(bl->mime_type, "application/pEp.sync") == 0) {
vb@3143
   140
            if (!_payload) {
vb@3143
   141
                _payload = bl->value;
vb@3143
   142
                _payload_size = bl->size;
vb@3143
   143
            }
vb@3143
   144
            else {
vb@3143
   145
                status = PEP_DECRYPT_WRONG_FORMAT;
vb@3143
   146
                goto the_end;
vb@3143
   147
            }
vb@3143
   148
        }
vb@3143
   149
        else if (bl->mime_type && strcasecmp(bl->mime_type, "application/pEp.sign") == 0) {
vb@3143
   150
            if (!_sign) {
vb@3143
   151
                _sign = bl->value;
vb@3143
   152
                _sign_size = bl->size;
vb@3143
   153
            }
vb@3143
   154
            else {
vb@3143
   155
                status = PEP_DECRYPT_WRONG_FORMAT;
vb@3143
   156
                goto the_end;
vb@3143
   157
            }
vb@3130
   158
        }
vb@3130
   159
    }
vb@3143
   160
    
vb@3143
   161
    if (!(_payload && _payload_size))
vb@3143
   162
        goto the_end;
vb@3130
   163
vb@3157
   164
    char *_fpr = NULL;
vb@3143
   165
    if (_sign) {
vb@3143
   166
        status = verify_text(session, _payload, _payload_size, _sign, _sign_size, &keylist);
vb@3143
   167
        if (status != PEP_VERIFIED || !keylist || !keylist->value) {
vb@3143
   168
            // signature invalid or does not match; ignore sync message
vb@3143
   169
            status = PEP_STATUS_OK;
vb@3143
   170
            goto the_end;
vb@3143
   171
        }
vb@3143
   172
vb@3157
   173
        _fpr = strdup(keylist->value);
vb@3143
   174
        assert(_fpr);
vb@3143
   175
        if (!_fpr) {
vb@3143
   176
            status = PEP_OUT_OF_MEMORY;
vb@3143
   177
            goto the_end;
vb@3143
   178
        }
vb@3143
   179
    }
vb@3143
   180
vb@3143
   181
    *size = _payload_size;
vb@3143
   182
    *payload = _payload;
vb@3157
   183
    *fpr = _fpr;
vb@3143
   184
    status = PEP_STATUS_OK;
vb@3143
   185
vb@3143
   186
the_end:
vb@3143
   187
    free_stringlist(keylist);
vb@3130
   188
    return status;
vb@3130
   189
}
vb@3130
   190