sync/cond_act_sync.yml2
author Volker Birk <vb@pep-project.org>
Sat, 18 May 2019 21:26:41 +0200
branchsync
changeset 3722 0f31947b826d
parent 3609 548e7dd045e5
child 3754 7d9c7bc6f412
permissions -rw-r--r--
needed for implementations with persistant identities
vb@2831
     1
// This file is under GNU General Public License 3.0
vb@2831
     2
// see LICENSE.txt
vb@2831
     3
vb@2831
     4
// generate conditions and actions
vb@2831
     5
vb@3512
     6
// Copyleft (c) 2017-2019, p≡p foundation
vb@2831
     7
vb@2831
     8
// Written by Volker Birk
vb@2831
     9
vb@2831
    10
vb@2844
    11
include ./sql_func.yml2
vb@2831
    12
vb@2831
    13
// condition: PEP_STATUS «@name»(PEP_SESSION session, bool *result)
vb@2831
    14
vb@2831
    15
condition deviceGrouped {
vb@2831
    16
    call "exec_sql_int" with "sql"
vb@3525
    17
        > "select count(*) from identity where is_own = 1 and (flags & 0x100) = 0x100;"
vb@2831
    18
    |> *result = _result > 0;
vb@2831
    19
}
vb@2831
    20
vb@2902
    21
condition weAreFirst
vb@2902
    22
||
vb@2902
    23
    TID_t *t1 = &session->sync_state.keysync.challenge;
vb@2902
    24
    TID_t *t2 = &session->own_sync_state.challenge;
vb@2902
    25
vb@2905
    26
    *result = _TID_greater(t1, t2);
vb@2902
    27
||
vb@2902
    28
vb@2831
    29
condition partnerIsGrouped
vb@2831
    30
|> *result = session->sync_state.keysync.is_group;
vb@2831
    31
vb@2831
    32
condition challengeAccepted
vb@2831
    33
||
vb@2831
    34
    TID_t *t1 = &session->sync_state.keysync.challenge;
vb@2831
    35
    TID_t *t2 = &session->own_sync_state.challenge;
vb@2831
    36
vb@2831
    37
    *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
vb@2831
    38
||
vb@2831
    39
vb@3514
    40
condition sameChallenge
vb@3514
    41
||
vb@3514
    42
    TID_t *t1 = &session->sync_state.keysync.challenge;
vb@3514
    43
    TID_t *t2 = &session->own_sync_state.challenge;
vb@3514
    44
vb@3514
    45
    *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
vb@3514
    46
||
vb@3514
    47
vb@3510
    48
condition sameTransaction
vb@3510
    49
||
vb@3550
    50
    TID_t *t1 = &session->sync_state.keysync.negotiation;
vb@3550
    51
    TID_t *t2 = &session->own_sync_state.negotiation;
vb@3510
    52
vb@3591
    53
    // test if TID is identical
vb@3510
    54
    *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
vb@3510
    55
||
vb@3510
    56
vb@3591
    57
condition sameTransactionAndPartner
vb@3591
    58
||
vb@3591
    59
    TID_t *t1 = &session->sync_state.keysync.negotiation;
vb@3591
    60
    TID_t *t2 = &session->own_sync_state.negotiation;
vb@3591
    61
vb@3591
    62
    const char *s1 = session->sync_state.common.signature_fpr;
vb@3591
    63
    const char *s2 = session->own_sync_state.signature_fpr;
vb@3591
    64
vb@3591
    65
    // test if TID is identical
vb@3591
    66
    *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0
vb@3591
    67
    // and test if we're talking to the same sender
vb@3591
    68
            && s1 && s2 && strcmp(s1, s2) == 0;
vb@3591
    69
||
vb@3591
    70
vb@2831
    71
condition keyElectionWon
vb@2831
    72
||
vb@2838
    73
    pEp_identity *from = session->sync_state.common.from;
vb@3389
    74
    char *signature_fpr = session->sync_state.common.signature_fpr;
vb@2831
    75
vb@3389
    76
    assert(from && from->address && from->address[0] && from->user_id &&
vb@3389
    77
            from->user_id[0]);
vb@3389
    78
    if (!(from && from->address && from->address[0] && from->user_id &&
vb@3389
    79
            from->user_id[0]))
vb@2831
    80
        return PEP_ILLEGAL_VALUE;
vb@2831
    81
vb@2831
    82
    pEp_identity *me = NULL;
vb@2901
    83
    PEP_STATUS status = get_identity(session, from->address, from->user_id, &me);
vb@2831
    84
    assert(status == PEP_STATUS_OK);
vb@2831
    85
    if (status)
vb@2831
    86
        return status;
vb@2831
    87
vb@2831
    88
    assert(me->fpr && me->fpr[0]);
vb@2831
    89
    if (!(me->fpr && me->fpr[0])) {
vb@2831
    90
        free_identity(me);
vb@2831
    91
        return PEP_ILLEGAL_VALUE;
vb@2831
    92
    }
vb@2831
    93
vb@3389
    94
    size_t len = MIN(strlen(signature_fpr), strlen(me->fpr));
vb@3389
    95
    *result = strncasecmp(signature_fpr, me->fpr, len) > 0;
vb@2831
    96
    free_identity(me);
vb@2831
    97
||
vb@2831
    98
vb@2831
    99
// action: PEP_STATUS «@name»(PEP_SESSION session)
vb@2831
   100
vb@2831
   101
function "new_UUID" {
vb@2831
   102
    param "dst";
vb@2831
   103
    ||
vb@2831
   104
        pEpUUID c;
vb@2831
   105
        uuid_generate_random(c);
vb@2831
   106
vb@2831
   107
        OCTET_STRING_fromBuf(«$dst», (char *) c, 16);
vb@2831
   108
    ||
vb@2831
   109
}
vb@2831
   110
vb@2831
   111
function "copy_UUID" {
vb@2831
   112
    param "src", param "dst";
vb@2831
   113
    ||
vb@3605
   114
        {
vb@3605
   115
            TID_t *src = «$src»;
vb@3605
   116
            TID_t *dst = «$dst»;
vb@2831
   117
vb@3605
   118
            assert(src->size == 16);
vb@3605
   119
            if (!(src->size == 16))
vb@3605
   120
                return PEP_UNKNOWN_ERROR;
vb@2831
   121
vb@3605
   122
            OCTET_STRING_fromBuf(dst, (char *) src->buf, src->size);
vb@3605
   123
        }
vb@3605
   124
    ||
vb@3605
   125
}
vb@3605
   126
vb@3605
   127
function "xor_UUID" {
vb@3605
   128
    param "src", param "dst";
vb@3605
   129
    ||
vb@3605
   130
        {
vb@3605
   131
            TID_t *src = «$src»;
vb@3605
   132
            TID_t *dst = «$dst»;
vb@3605
   133
vb@3605
   134
            assert(src->size == 16 && dst->size == 16);
vb@3605
   135
            if (!(src->size == 16 && dst->size == 16))
vb@3605
   136
                return PEP_UNKNOWN_ERROR;
vb@3605
   137
vb@3605
   138
            for (int i=0; i < src->size; ++i)
vb@3605
   139
                dst->buf[i] ^= src->buf[i];
vb@3605
   140
        }
vb@2831
   141
    ||
vb@2831
   142
}
vb@2831
   143
vb@3601
   144
action newChallenge {
vb@3601
   145
    // random new challenge
vb@2831
   146
    call "new_UUID" with "dst" > &session->own_sync_state.challenge
vb@3601
   147
    // store a copy of this challenge
vb@3601
   148
    call "copy_UUID" {
vb@3601
   149
        with "src" > &session->own_sync_state.challenge
vb@3601
   150
        with "dst" > &session->sync_state.common.challenge
vb@3601
   151
    }
vb@3601
   152
}
vb@2831
   153
vb@3601
   154
action replyChallenge call "copy_UUID" {
vb@2831
   155
    with "src" > &session->sync_state.keysync.challenge
vb@2831
   156
    with "dst" > &session->own_sync_state.challenge
vb@2831
   157
}
vb@2831
   158
vb@3601
   159
action useOwnChallenge call "copy_UUID" {
vb@3601
   160
    with "src" > &session->sync_state.common.challenge
vb@3601
   161
    with "dst" > &session->own_sync_state.challenge
vb@3601
   162
}
vb@3601
   163
vb@3591
   164
action newTransaction {
vb@3510
   165
||
vb@3590
   166
    // sender key must be stable while transaction
vb@3591
   167
    assert(session->sync_state.common.signature_fpr);
vb@3591
   168
    free(session->own_sync_state.signature_fpr);
vb@3591
   169
    session->own_sync_state.signature_fpr
vb@3591
   170
            = strdup(session->sync_state.common.signature_fpr);
vb@3591
   171
    assert(session->own_sync_state.signature_fpr);
vb@3591
   172
    if (!session->own_sync_state.signature_fpr)
vb@3591
   173
        return PEP_OUT_OF_MEMORY;
vb@3590
   174
vb@3510
   175
||
vb@3605
   176
    call "copy_UUID" {
vb@3605
   177
        with "src" > &session->sync_state.keysync.challenge
vb@3605
   178
        with "dst" > &session->sync_state.keysync.negotiation
vb@3605
   179
    }
vb@3605
   180
    call "xor_UUID" {
vb@3605
   181
        with "src" > &session->own_sync_state.challenge
vb@3605
   182
        with "dst" > &session->sync_state.keysync.negotiation
vb@3605
   183
    }
vb@3591
   184
    call "copy_UUID" {
vb@3591
   185
        with "src" > &session->sync_state.keysync.negotiation
vb@3591
   186
        with "dst" > &session->own_sync_state.negotiation
vb@3591
   187
    }
vb@3510
   188
}
vb@3510
   189
vb@3510
   190
action closeTransaction
vb@3510
   191
||
vb@3550
   192
    memset(session->sync_state.keysync.negotiation.buf, 0,
vb@3550
   193
            session->sync_state.keysync.negotiation.size);
vb@3594
   194
    memset(session->own_sync_state.negotiation.buf, 0,
vb@3594
   195
            session->own_sync_state.negotiation.size);
vb@3510
   196
||
vb@2831
   197
vb@3591
   198
action storeTransaction {
vb@3591
   199
||
vb@3591
   200
    // sender key must be stable while transaction
vb@3591
   201
    assert(session->sync_state.common.signature_fpr);
vb@3591
   202
    free(session->own_sync_state.signature_fpr);
vb@3591
   203
    session->own_sync_state.signature_fpr
vb@3591
   204
            = strdup(session->sync_state.common.signature_fpr);
vb@3591
   205
    assert(session->own_sync_state.signature_fpr);
vb@3591
   206
    if (!session->own_sync_state.signature_fpr)
vb@3591
   207
        return PEP_OUT_OF_MEMORY;
vb@3591
   208
vb@3591
   209
||
vb@3591
   210
    call "copy_UUID" {
vb@3591
   211
        with "src" > &session->sync_state.keysync.negotiation
vb@3591
   212
        with "dst" > &session->own_sync_state.negotiation
vb@3591
   213
    }
vb@2831
   214
}
vb@2831
   215
vb@2831
   216
function "show_handshake" {
vb@2831
   217
    param "type";
vb@2831
   218
    ||
vb@2831
   219
        assert(session->notifyHandshake);
vb@2831
   220
        if (!session->notifyHandshake)
vb@2831
   221
            return PEP_SYNC_NO_NOTIFY_CALLBACK;
vb@2831
   222
     
vb@3525
   223
    ||
vb@3525
   224
    choose {
vb@3525
   225
    when "$type = 'SYNC_NOTIFY_TIMEOUT' or $type = 'SYNC_NOTIFY_SOLE' or $type = 'SYNC_NOTIFY_IN_GROUP'"
vb@3525
   226
    ||
vb@3525
   227
        pEp_identity *me = new_identity(NULL, NULL, NULL, NULL);
vb@3525
   228
        pEp_identity *partner = new_identity(NULL, NULL, NULL, NULL);
vb@3525
   229
        assert(me && partner);
vb@3525
   230
        if (!(me && partner)) {
vb@3525
   231
            free_identity(me);
vb@3525
   232
            free_identity(partner);
vb@3525
   233
            return PEP_OUT_OF_MEMORY;
vb@3525
   234
        }
vb@3525
   235
vb@3525
   236
        PEP_STATUS status = session->notifyHandshake(me, partner, «$type»);
vb@3525
   237
        if (status)
vb@3525
   238
            return status;
vb@3525
   239
    ||
vb@3525
   240
    otherwise
vb@3525
   241
    ||
vb@2838
   242
        assert(session->sync_state.common.from);
vb@2838
   243
        if (!session->sync_state.common.from)
vb@2831
   244
            return PEP_ILLEGAL_VALUE;
vb@2831
   245
vb@2838
   246
        pEp_identity *from = session->sync_state.common.from;
vb@2831
   247
        pEp_identity *me = NULL;
vb@2901
   248
        PEP_STATUS status = get_identity(session, from->address, from->user_id, &me);
vb@2831
   249
        assert(status == PEP_STATUS_OK);
vb@2831
   250
        if (status)
vb@2831
   251
            return status;
vb@2831
   252
vb@2831
   253
        assert(me->fpr && me->fpr[0]);
vb@2831
   254
        if (!(me->fpr && me->fpr[0])) {
vb@2831
   255
            free_identity(me);
vb@2831
   256
            return PEP_ILLEGAL_VALUE;
vb@2831
   257
        }
vb@2831
   258
vb@2831
   259
        pEp_identity *partner = identity_dup(from);
vb@2831
   260
        if (!partner) {
vb@2831
   261
            free_identity(me);
vb@2831
   262
            return PEP_OUT_OF_MEMORY;
vb@2831
   263
        }
vb@3365
   264
vb@3379
   265
        assert(session->sync_state.common.signature_fpr);
vb@3379
   266
        if (session->sync_state.common.signature_fpr) {
vb@3379
   267
            free(partner->fpr);
vb@3379
   268
            partner->fpr = strdup(session->sync_state.common.signature_fpr);
vb@3379
   269
            if (!partner->fpr) {
vb@3379
   270
                free_identity(me);
vb@3379
   271
                free_identity(partner);
vb@3379
   272
                return PEP_OUT_OF_MEMORY;
vb@3379
   273
            }
vb@3364
   274
        }
vb@2831
   275
vb@3722
   276
        free(partner->user_id);
vb@3722
   277
        partner->user_id = strdup("#NV");
vb@3722
   278
        assert(partner->user_id);
vb@3722
   279
        if (!partner->user_id) {
vb@3722
   280
            free_identity(me);
vb@3722
   281
            free_identity(partner);
vb@3722
   282
            return PEP_OUT_OF_MEMORY;
vb@3722
   283
        }
vb@3722
   284
vb@3047
   285
        status = session->notifyHandshake(me, partner, «$type»);
vb@2831
   286
        if (status)
vb@2831
   287
            return status;
vb@2831
   288
    ||
vb@3525
   289
    }
vb@2831
   290
}
vb@2831
   291
vb@2831
   292
action showSoleHandshake
vb@2831
   293
    call "show_handshake" with "type" > SYNC_NOTIFY_INIT_FORM_GROUP
vb@2831
   294
vb@2831
   295
action showJoinGroupHandshake
vb@2831
   296
    call "show_handshake" with "type" > SYNC_NOTIFY_INIT_ADD_OUR_DEVICE
vb@2831
   297
vb@2831
   298
action showGroupedHandshake
vb@2831
   299
    call "show_handshake" with "type" > SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE
vb@2831
   300
vb@3522
   301
action hideHandshakeDialog
vb@3522
   302
    call "show_handshake" with "type" > SYNC_NOTIFY_OVERTAKEN
vb@3522
   303
vb@3524
   304
action showDeviceAdded
vb@3524
   305
    call "show_handshake" with "type" > SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED
vb@3524
   306
vb@3524
   307
action showGroupCreated
vb@3524
   308
    call "show_handshake" with "type" > SYNC_NOTIFY_ACCEPTED_GROUP_CREATED
vb@3524
   309
vb@3525
   310
action showBeingSole
vb@3525
   311
    call "show_handshake" with "type" > SYNC_NOTIFY_SOLE
vb@3525
   312
vb@3525
   313
action showBeingInGroup
vb@3525
   314
    call "show_handshake" with "type" > SYNC_NOTIFY_IN_GROUP
vb@3525
   315
vb@2914
   316
timeout KeySync
vb@2913
   317
    call "show_handshake" with "type" > SYNC_NOTIFY_TIMEOUT
vb@2913
   318
vb@3390
   319
action prepareOwnKeys
vb@3390
   320
||
vb@3390
   321
    stringlist_t *own_keys;
krista@3583
   322
    PEP_STATUS status = _own_keys_retrieve(session, &own_keys, PEP_idf_not_for_sync, true);
vb@3390
   323
    if (status)
vb@3390
   324
        return status;
vb@3390
   325
vb@3594
   326
    if (session->own_sync_state.own_keys)
vb@3594
   327
        free_stringlist(session->own_sync_state.own_keys);
vb@3594
   328
    session->own_sync_state.own_keys = own_keys;
vb@3394
   329
vb@3394
   330
    identity_list *il;
vb@3394
   331
    status = _own_identities_retrieve(session, &il, PEP_idf_not_for_sync);
vb@3394
   332
    if (status)
vb@3394
   333
        return status;
vb@3394
   334
vb@3394
   335
    IdentityList_from_identity_list(il, &session->sync_state.keysync.ownIdentities);
vb@3609
   336
    free_identity_list(il);
vb@3390
   337
||
vb@3390
   338
vb@2831
   339
action saveGroupKeys
vb@2831
   340
||
vb@3390
   341
    identity_list *il = IdentityList_to_identity_list(&session->sync_state.keysync.ownIdentities, NULL);
vb@2831
   342
    if (!il)
vb@2831
   343
        return PEP_OUT_OF_MEMORY;
vb@2831
   344
    
vb@2831
   345
    // BUG: this should be a transaction and been rolled back completely on error
vb@2831
   346
    for (identity_list *_il = il; _il && _il->ident; _il = _il->next) {
vb@2831
   347
        PEP_STATUS status = set_identity(session, _il->ident);
vb@2831
   348
        if (status) {
vb@2831
   349
            free_identity_list(il);
vb@2831
   350
            return status;
vb@2831
   351
        }
vb@2831
   352
    }
vb@2831
   353
vb@2831
   354
    free_identity_list(il);
vb@2831
   355
||
vb@2831
   356
vb@3434
   357
action ownKeysAreGroupKeys
vb@3434
   358
||
vb@3434
   359
    PEP_STATUS status = PEP_STATUS_OK;
vb@3434
   360
vb@3434
   361
    // set flag for current keys
vb@3594
   362
    for (identity_list *il = session->own_sync_state.own_identities; il && il->ident ; il = il->next) {
vb@3434
   363
        if (!(il->ident->flags && PEP_idf_not_for_sync)) {
vb@3434
   364
            status = set_identity_flags(session, il->ident, PEP_idf_devicegroup);
vb@3434
   365
            if (status)
vb@3434
   366
                return status;
vb@3434
   367
        }
vb@2831
   368
    }
vb@3434
   369
||
vb@2831
   370
vb@3525
   371
action receivedKeysAreGroupKeys
vb@3525
   372
||
vb@3525
   373
    PEP_STATUS status = PEP_STATUS_OK;
vb@3527
   374
vb@3527
   375
    // set flag for current keys
vb@3594
   376
    for (identity_list *il = session->own_sync_state.own_identities; il && il->ident ; il = il->next) {
vb@3527
   377
        if (!(il->ident->flags && PEP_idf_not_for_sync)) {
vb@3527
   378
            status = set_identity_flags(session, il->ident, PEP_idf_devicegroup);
vb@3527
   379
            if (status)
vb@3527
   380
                return status;
vb@3527
   381
        }
vb@3527
   382
    }
vb@3527
   383
vb@3525
   384
    identity_list *il = IdentityList_to_identity_list(&session->sync_state.keysync.ownIdentities, NULL);
vb@3525
   385
    if (!il)
vb@3525
   386
        return PEP_OUT_OF_MEMORY;
vb@3525
   387
vb@3594
   388
    for (il = session->own_sync_state.own_identities; il && il->ident ; il = il->next) {
vb@3525
   389
        // replace partner's user_id with own user_id
vb@3525
   390
        free(il->ident->user_id);
vb@3525
   391
        il->ident->user_id = strdup(session->sync_state.common.from->user_id);
vb@3525
   392
        if (!il->ident->user_id) {
vb@3525
   393
            free_identity_list(il);
vb@3525
   394
            return PEP_OUT_OF_MEMORY;
vb@3525
   395
        }
vb@3525
   396
vb@3525
   397
        status = myself(session, il->ident);
vb@3525
   398
        if (status) {
vb@3525
   399
            free_identity_list(il);
vb@3525
   400
            return status;
vb@3525
   401
        }
vb@3525
   402
vb@3525
   403
        status = set_identity_flags(session, il->ident, PEP_idf_devicegroup);
vb@3525
   404
        if (status) {
vb@3525
   405
            free_identity_list(il);
vb@3525
   406
            return status;
vb@3525
   407
        }
vb@3525
   408
    }
vb@3525
   409
vb@3525
   410
    free_identity_list(il);
vb@3525
   411
||
vb@3406
   412
vb@3516
   413
action trustThisKey
vb@3516
   414
||
vb@3516
   415
    assert(session->sync_state.common.from && session->sync_state.common.signature_fpr);
vb@3516
   416
    if (!(session->sync_state.common.from && session->sync_state.common.signature_fpr))
vb@3516
   417
        return PEP_ILLEGAL_VALUE;
vb@3516
   418
vb@3516
   419
    pEp_identity *ident = session->sync_state.common.from;
vb@3516
   420
    free(ident->fpr);
vb@3516
   421
    ident->fpr = strdup(session->sync_state.common.signature_fpr);
vb@3516
   422
    assert(ident->fpr);
vb@3516
   423
    if (!ident->fpr)
vb@3516
   424
        return PEP_OUT_OF_MEMORY;
vb@3516
   425
vb@3516
   426
    PEP_STATUS status = trust_own_key(session, ident);
vb@3516
   427
    if (status)
vb@3516
   428
        return status;
vb@3523
   429
vb@3523
   430
    OCTET_STRING_fromBuf(&session->sync_state.keysync.key, ident->fpr, strlen(ident->fpr));
vb@3516
   431
||
vb@3516
   432
vb@3524
   433
action untrustThisKey
vb@3524
   434
||
vb@3524
   435
    assert(session->sync_state.common.from && session->sync_state.common.signature_fpr);
vb@3524
   436
    if (!(session->sync_state.common.from && session->sync_state.common.signature_fpr))
vb@3524
   437
        return PEP_ILLEGAL_VALUE;
vb@3524
   438
vb@3524
   439
    pEp_identity *ident = session->sync_state.common.from;
vb@3524
   440
    free(ident->fpr);
vb@3524
   441
    ident->fpr = strdup(session->sync_state.common.signature_fpr);
vb@3524
   442
    assert(ident->fpr);
vb@3524
   443
    if (!ident->fpr)
vb@3524
   444
        return PEP_OUT_OF_MEMORY;
vb@3524
   445
vb@3524
   446
    PEP_STATUS status = key_reset_trust(session, ident);
vb@3524
   447
    if (status)
vb@3524
   448
        return status;
vb@3524
   449
vb@3524
   450
    OCTET_STRING_fromBuf(&session->sync_state.keysync.key, "", 0);
vb@3524
   451
||
vb@3524
   452
vb@3518
   453
action tellWeAreGrouped
vb@3518
   454
||
vb@3518
   455
    session->sync_state.keysync.is_group = true;
vb@3518
   456
||
vb@3518
   457
vb@3518
   458
action tellWeAreNotGrouped
vb@3518
   459
||
vb@3518
   460
    session->sync_state.keysync.is_group = false;
vb@3518
   461
||
vb@3518
   462
vb@2831
   463
action disable;
vb@2831
   464