src/keymanagement.c
author vb
Wed, 25 Jun 2014 18:44:58 +0200
changeset 0 16f27efbef98
child 8 26cc9f0228f4
permissions -rw-r--r--
initial commit
     1 #ifndef WIN32 // UNIX
     2 #define _POSIX_C_SOURCE 200809L
     3 #else
     4 #include "platform_windows.h"
     5 #endif
     6 
     7 #include <string.h>
     8 #include <stdio.h>
     9 #include <stdlib.h>
    10 #include <assert.h>
    11 
    12 #define _EXPORT_PEP_ENGINE_DLL
    13 #include "pEpEngine.h"
    14 #include "keymanagement.h"
    15 
    16 #ifndef MIN
    17 #define MIN(A, B) ((B) > (A) ? (A) : (B))
    18 #endif
    19 
    20 DYNAMIC_API PEP_STATUS update_identity(
    21         PEP_SESSION session, pEp_identity * identity
    22     )
    23 {
    24     pEp_identity *stored_identity;
    25     PEP_STATUS status;
    26     bool bDirty;
    27 
    28     assert(session);
    29     assert(identity);
    30     assert(identity->address);
    31 
    32     status = get_identity(session, identity->address, &stored_identity);
    33     assert(status != PEP_OUT_OF_MEMORY);
    34     if (status == PEP_OUT_OF_MEMORY)
    35         return PEP_OUT_OF_MEMORY;
    36 
    37     if (stored_identity) {
    38         if (identity->username == NULL || identity->username[0] == 0) {
    39             free(identity->username);
    40             identity->username = strdup(stored_identity->username);
    41         }
    42         if (identity->user_id == NULL || identity->user_id[0] == 0) {
    43             free(identity->user_id);
    44             identity->user_id = strdup(stored_identity->user_id);
    45         }
    46         if (identity->fpr != NULL && identity->fpr[0] != 0) {
    47             if (strcmp(identity->fpr, stored_identity->fpr) != 0)
    48                 identity->comm_type = PEP_ct_unknown;
    49         }
    50     }
    51     else
    52         identity->comm_type = PEP_ct_unknown;
    53 
    54     status = set_identity(session, identity);
    55 
    56     return PEP_STATUS_OK;
    57 }
    58 
    59 DYNAMIC_API PEP_STATUS outgoing_comm_type(
    60         PEP_SESSION session,
    61         const stringlist_t *addresses,
    62         PEP_comm_type *comm_type
    63     )
    64 {
    65     int i;
    66     const stringlist_t *l;
    67 
    68     assert(session);
    69     assert(addresses);
    70     assert(addresses->value);
    71     assert(comm_type);
    72 
    73     *comm_type = PEP_ct_unknown;
    74 
    75     for (l=addresses; l && l->value; l = l->next) {
    76         PEP_STATUS _status;
    77         pEp_identity *identity;
    78 
    79         _status = get_identity(session, l->value, &identity);
    80         assert(_status != PEP_OUT_OF_MEMORY);
    81 
    82         if (identity == NULL) {
    83             *comm_type = PEP_ct_no_encryption;
    84             return PEP_STATUS_OK;
    85         }
    86         else if (identity->comm_type == PEP_ct_unknown) {
    87             *comm_type = PEP_ct_no_encryption;
    88             free_identity(identity);
    89             return PEP_STATUS_OK;
    90         }
    91         else if (*comm_type == PEP_ct_unknown) {
    92             *comm_type = identity->comm_type;
    93         }
    94         else if (*comm_type != identity->comm_type) {
    95             PEP_comm_type min = MIN(*comm_type, identity->comm_type);
    96             if (min < PEP_ct_unconfirmed_encryption) {
    97                 *comm_type = PEP_ct_no_encryption;
    98                 free_identity(identity);
    99                 return PEP_STATUS_OK;
   100             }
   101             else if (min < PEP_ct_unconfirmed_enc_anon)
   102                 *comm_type = PEP_ct_unconfirmed_encryption;
   103             else if (min < PEP_ct_confirmed_encryption)
   104                 *comm_type = PEP_ct_unconfirmed_enc_anon;
   105             else if (min < PEP_ct_confirmed_enc_anon)
   106                 *comm_type = PEP_ct_confirmed_encryption;
   107             else
   108                 *comm_type = PEP_ct_confirmed_enc_anon;
   109         }
   110 
   111         free_identity(identity);
   112     }
   113 
   114     return PEP_STATUS_OK;
   115 }
   116 
   117 DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity)
   118 {
   119     PEP_STATUS status;
   120     stringlist_t *keylist;
   121 
   122     assert(session);
   123     assert(identity);
   124     assert(identity->address);
   125     assert(identity->username);
   126     assert(identity->user_id);
   127 
   128     identity->comm_type = PEP_ct_pEp;
   129     identity->me = true;
   130 
   131     pEp_identity *_identity;
   132 
   133     log_event(session, "myself", "debug", identity->address, NULL);
   134     status = get_identity(session, identity->address, &_identity);
   135     assert(status != PEP_OUT_OF_MEMORY);
   136     if (status == PEP_OUT_OF_MEMORY)
   137         return PEP_OUT_OF_MEMORY;
   138 
   139     status = find_keys(session, identity->address, &keylist);
   140     assert(status != PEP_OUT_OF_MEMORY);
   141     if (status == PEP_OUT_OF_MEMORY)
   142         return PEP_OUT_OF_MEMORY;
   143 
   144     if (keylist == NULL || keylist->value == NULL) {
   145         log_event(session, "generating key pair", "debug", identity->address, NULL);
   146         status = generate_keypair(session, identity);
   147         assert(status != PEP_OUT_OF_MEMORY);
   148         if (status != PEP_STATUS_OK) {
   149             char buf[11];
   150             snprintf(buf, 11, "%d", status);
   151             log_event(session, "generating key pair failed", "debug", buf, NULL);
   152             return status;
   153         }
   154 
   155         status = find_keys(session, identity->address, &keylist);
   156         assert(status != PEP_OUT_OF_MEMORY);
   157         if (status == PEP_OUT_OF_MEMORY)
   158             return PEP_OUT_OF_MEMORY;
   159 
   160         assert(keylist);
   161     }
   162 
   163     if (identity->fpr)
   164         free(identity->fpr);
   165     identity->fpr = strdup(keylist->value);
   166     assert(identity->fpr);
   167     free_stringlist(keylist);
   168     if (identity->fpr == NULL)
   169         return PEP_OUT_OF_MEMORY;
   170 
   171     status = set_identity(session, identity);
   172     assert(status == PEP_STATUS_OK);
   173 
   174     return PEP_STATUS_OK;
   175 }
   176 
   177 DYNAMIC_API PEP_STATUS do_keymanagement(
   178         retrieve_next_identity_t retrieve_next_identity,
   179         void *management
   180     )
   181 {
   182     PEP_SESSION session;
   183     pEp_identity *identity;
   184     PEP_STATUS status = init(&session);
   185 
   186     assert(status == PEP_STATUS_OK);
   187     if (status != PEP_STATUS_OK)
   188         return status;
   189 
   190     log_event(session, "keymanagement thread started", "pEp engine", NULL, NULL);
   191 
   192     while (identity = retrieve_next_identity(management)) {
   193         assert(identity->address);
   194         log_event(session, "do_keymanagement", "debug", identity->address, NULL);
   195         if (identity->me) {
   196             status = myself(session, identity);
   197             assert(status != PEP_OUT_OF_MEMORY);
   198         } else {
   199             status = recv_key(session, identity->address);
   200             assert(status != PEP_OUT_OF_MEMORY);
   201         }
   202         free_identity(identity);
   203     }
   204 
   205     log_event(session, "keymanagement thread shutdown", "pEp engine", NULL, NULL);
   206 
   207     release(session);
   208     return PEP_STATUS_OK;
   209 }
   210