ENGINE-140: now send all keys that have been at some point used as own key _on that device_
authorEdouard Tisserant <edouard@pep-project.org>
Tue, 08 Nov 2016 23:04:26 +0100
changeset 13642ba0f96f6c0e
parent 1361 0c721d383dcd
child 1365 9e45d9a7583b
child 1366 7fe33611a1bb
ENGINE-140: now send all keys that have been at some point used as own key _on that device_
src/keymanagement.c
src/keymanagement.h
src/pEpEngine.c
src/pEpEngine.h
src/pEp_internal.h
src/sync_impl.c
     1.1 --- a/src/keymanagement.c	Tue Nov 08 16:51:32 2016 +0100
     1.2 +++ b/src/keymanagement.c	Tue Nov 08 23:04:26 2016 +0100
     1.3 @@ -848,3 +848,68 @@
     1.4      return status;
     1.5  }
     1.6  
     1.7 +DYNAMIC_API PEP_STATUS keys_retrieve_by_flag(
     1.8 +        PEP_SESSION session,
     1.9 +        keypair_flags_t flags,
    1.10 +        stringlist_t **keylist
    1.11 +      )
    1.12 +{
    1.13 +    PEP_STATUS status = PEP_STATUS_OK;
    1.14 +    
    1.15 +    assert(session && keylist);
    1.16 +    if (!(session && keylist))
    1.17 +        return PEP_ILLEGAL_VALUE;
    1.18 +    
    1.19 +    *keylist = NULL;
    1.20 +    stringlist_t *_keylist = NULL;
    1.21 +    
    1.22 +    sqlite3_reset(session->keys_retrieve_by_flag);
    1.23 +    sqlite3_bind_int(session->keys_retrieve_by_flag, 1, flags);
    1.24 +    
    1.25 +    int result;
    1.26 +    char *fpr = NULL;
    1.27 +    
    1.28 +    stringlist_t *_bl = _keylist;
    1.29 +    do {
    1.30 +        result = sqlite3_step(session->keys_retrieve_by_flag);
    1.31 +        switch (result) {
    1.32 +            case SQLITE_ROW:
    1.33 +                fpr = strdup((const char *) sqlite3_column_text(session->keys_retrieve_by_flag, 0));
    1.34 +                if(fpr == NULL)
    1.35 +                    goto enomem;
    1.36 +
    1.37 +                _bl = stringlist_add(_bl, fpr);
    1.38 +                if (_bl == NULL) {
    1.39 +                    free(fpr);
    1.40 +                    goto enomem;
    1.41 +                }
    1.42 +                if (_keylist == NULL)
    1.43 +                    _keylist = _bl;
    1.44 +                
    1.45 +                break;
    1.46 +                
    1.47 +            case SQLITE_DONE:
    1.48 +                break;
    1.49 +                
    1.50 +            default:
    1.51 +                status = PEP_UNKNOWN_ERROR;
    1.52 +                result = SQLITE_DONE;
    1.53 +        }
    1.54 +    } while (result != SQLITE_DONE);
    1.55 +    
    1.56 +    sqlite3_reset(session->keys_retrieve_by_flag);
    1.57 +    if (status == PEP_STATUS_OK)
    1.58 +        *keylist = _keylist;
    1.59 +    else
    1.60 +        free_stringlist(_keylist);
    1.61 +    
    1.62 +    goto the_end;
    1.63 +    
    1.64 +enomem:
    1.65 +    free_stringlist(_keylist);
    1.66 +    status = PEP_OUT_OF_MEMORY;
    1.67 +    
    1.68 +the_end:
    1.69 +    return status;
    1.70 +}
    1.71 +
     2.1 --- a/src/keymanagement.h	Tue Nov 08 16:51:32 2016 +0100
     2.2 +++ b/src/keymanagement.h	Tue Nov 08 23:04:26 2016 +0100
     2.3 @@ -189,6 +189,21 @@
     2.4          identity_list **own_identities
     2.5      );
     2.6  
     2.7 +// keys_retrieve_by_flag() - retrieve all flagged keypair fingerprints 
     2.8 +//
     2.9 +//  parameters:
    2.10 +//      session (in)            session to use
    2.11 +//      flags                   flags to compare pgp keypair's flags to
    2.12 +//      keylist (out)           list of fingerprints
    2.13 +//
    2.14 +//  caveat:
    2.15 +//      the ownership of the list goes to the caller
    2.16 +DYNAMIC_API PEP_STATUS keys_retrieve_by_flag(
    2.17 +        PEP_SESSION session,
    2.18 +        keypair_flags_t flags,
    2.19 +        stringlist_t **keylist
    2.20 +      );
    2.21 +
    2.22  #ifdef __cplusplus
    2.23  }
    2.24  #endif
     3.1 --- a/src/pEpEngine.c	Tue Nov 08 16:51:32 2016 +0100
     3.2 +++ b/src/pEpEngine.c	Tue Nov 08 23:04:26 2016 +0100
     3.3 @@ -52,6 +52,7 @@
     3.4      // Own keys
     3.5      static const char *sql_own_key_is_listed;
     3.6      static const char *sql_own_identities_retrieve;
     3.7 +    static const char *sql_keys_retrieve_by_flag;
     3.8  
     3.9      // Sequence
    3.10      static const char *sql_sequence_value1;
    3.11 @@ -331,8 +332,8 @@
    3.12          sql_get_device_group = "select device_group from person "
    3.13                                 "where id = '" PEP_OWN_USERID "';";
    3.14  
    3.15 -        sql_set_pgp_keypair = "insert or replace into pgp_keypair (fpr) "
    3.16 -                              "values (upper(replace(?1,' ',''))) ;";
    3.17 +        sql_set_pgp_keypair = "insert or replace into pgp_keypair (fpr, flags) "
    3.18 +                              "values (upper(replace(?1,' ','')), ?2) ;";
    3.19  
    3.20          sql_set_identity = "insert or replace into identity (address, main_key_id, "
    3.21                             "user_id, flags) values (?1, upper(replace(?2,' ','')),"
    3.22 @@ -380,8 +381,7 @@
    3.23                  
    3.24          // Own keys
    3.25          
    3.26 -        sql_own_key_is_listed =
    3.27 -                                "select count(*) from ("
    3.28 +        sql_own_key_is_listed = "select count(*) from ("
    3.29                                  " select main_key_id from person "
    3.30                                  "   where main_key_id = upper(replace(?1,' ',''))"
    3.31                                  "    and id = '" PEP_OWN_USERID "' "
    3.32 @@ -390,7 +390,8 @@
    3.33                                  "   where main_key_id = upper(replace(?1,' ',''))"
    3.34                                  "    and user_id = '" PEP_OWN_USERID "' );";
    3.35  
    3.36 -        sql_own_identities_retrieve =  "select address, fpr, username, "
    3.37 +        sql_own_identities_retrieve =  
    3.38 +                            "select address, fpr, username, "
    3.39                              "   lang, identity.flags | pgp_keypair.flags"
    3.40                              "   from identity"
    3.41                              "   join person on id = identity.user_id"
    3.42 @@ -399,6 +400,10 @@
    3.43                              "       and pgp_keypair_fpr = identity.main_key_id"
    3.44                              "   where identity.user_id = '" PEP_OWN_USERID "';";
    3.45          
    3.46 +        sql_keys_retrieve_by_flag =  
    3.47 +                            "select fpr from pgp_keypair"
    3.48 +                            "  where (flags & ?1) = ?1;";
    3.49 +
    3.50          sql_sequence_value1 = "insert or replace into sequences (name, value, own) "
    3.51                                "values (?1, "
    3.52                                "(select coalesce((select value + 1 from sequences "
    3.53 @@ -526,6 +531,11 @@
    3.54              &_session->own_identities_retrieve, NULL);
    3.55      assert(int_result == SQLITE_OK);
    3.56   
    3.57 +    int_result = sqlite3_prepare_v2(_session->db, sql_keys_retrieve_by_flag,
    3.58 +            (int)strlen(sql_keys_retrieve_by_flag),
    3.59 +            &_session->keys_retrieve_by_flag, NULL);
    3.60 +    assert(int_result == SQLITE_OK);
    3.61 + 
    3.62      // Sequence
    3.63  
    3.64      int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value1,
    3.65 @@ -652,6 +662,8 @@
    3.66                  sqlite3_finalize(session->own_key_is_listed);
    3.67              if (session->own_identities_retrieve)
    3.68                  sqlite3_finalize(session->own_identities_retrieve);
    3.69 +            if (session->keys_retrieve_by_flag)
    3.70 +                sqlite3_finalize(session->keys_retrieve_by_flag);
    3.71              if (session->sequence_value1)
    3.72                  sqlite3_finalize(session->sequence_value1);
    3.73              if (session->sequence_value2)
    3.74 @@ -1124,6 +1136,9 @@
    3.75      sqlite3_reset(session->set_pgp_keypair);
    3.76      sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
    3.77              SQLITE_STATIC);
    3.78 +    sqlite3_bind_int(session->set_pgp_keypair, 2, 
    3.79 +                     strcmp(identity->user_id, PEP_OWN_USERID) == 0 ?
    3.80 +                        PEP_kpf_own_key : 0);
    3.81      result = sqlite3_step(session->set_pgp_keypair);
    3.82      sqlite3_reset(session->set_pgp_keypair);
    3.83      if (result != SQLITE_DONE) {
     4.1 --- a/src/pEpEngine.h	Tue Nov 08 16:51:32 2016 +0100
     4.2 +++ b/src/pEpEngine.h	Tue Nov 08 23:04:26 2016 +0100
     4.3 @@ -421,6 +421,15 @@
     4.4  
     4.5  typedef unsigned int identity_flags_t;
     4.6  
     4.7 +typedef enum _keypair_flags {
     4.8 +    // the first octet flags are app defined settings
     4.9 +
    4.10 +    // the second octet flags are calculated
    4.11 +    PEP_kpf_own_key = 512   // key (was) used for own identity
    4.12 +} keypair_flags;
    4.13 +
    4.14 +typedef unsigned int keypair_flags_t;
    4.15 +
    4.16  typedef struct _pEp_identity {
    4.17      char *address;              // C string with address UTF-8 encoded
    4.18      char *fpr;                  // C string with fingerprint UTF-8 encoded
     5.1 --- a/src/pEp_internal.h	Tue Nov 08 16:51:32 2016 +0100
     5.2 +++ b/src/pEp_internal.h	Tue Nov 08 23:04:26 2016 +0100
     5.3 @@ -120,6 +120,7 @@
     5.4      // Own keys
     5.5      sqlite3_stmt *own_key_is_listed;
     5.6      sqlite3_stmt *own_identities_retrieve;
     5.7 +    sqlite3_stmt *keys_retrieve_by_flag;
     5.8  
     5.9      // sequence value
    5.10      sqlite3_stmt *sequence_value1;
     6.1 --- a/src/sync_impl.c	Tue Nov 08 16:51:32 2016 +0100
     6.2 +++ b/src/sync_impl.c	Tue Nov 08 23:04:26 2016 +0100
     6.3 @@ -576,18 +576,13 @@
     6.4                  goto error;
     6.5              }
     6.6              
     6.7 -            IdentityList_t *list = 
     6.8 -                msg->payload.present == 
     6.9 -                  DeviceGroup_Protocol__payload_PR_groupKeys ?
    6.10 -                  &msg->payload.choice.groupKeys.ownIdentities :
    6.11 -                  &msg->payload.choice.groupUpdate.ownIdentities;
    6.12 +            stringlist_t *keylist = NULL;
    6.13 +            status = keys_retrieve_by_flag(session, PEP_kpf_own_key, &keylist);
    6.14 +            if (status != PEP_STATUS_OK)
    6.15 +                goto error;
    6.16  
    6.17 -            for (int i=0; i<list->list.count; i++) {
    6.18 -                Identity_t *ident = list->list.array[i];
    6.19 -                char *fpr = strndup((const char *)ident->fpr.buf, ident->fpr.size);
    6.20 -                assert(fpr);
    6.21 -                if (!fpr)
    6.22 -                    goto enomem;
    6.23 +            for (stringlist_t *_keylist=keylist; _keylist!=NULL; _keylist=_keylist->next) {
    6.24 +                char *fpr = _keylist->value;
    6.25                  static char filename[MAX_LINELENGTH];
    6.26                  int result = snprintf(filename, MAX_LINELENGTH, "%s-sec.asc", fpr);
    6.27                  if (result < 0)
    6.28 @@ -595,7 +590,6 @@
    6.29                  char *key = NULL;
    6.30                  size_t size = 0;
    6.31                  status = export_secrect_key(session, fpr, &key, &size);
    6.32 -                free(fpr);
    6.33                  if (status != PEP_STATUS_OK)
    6.34                      goto error;
    6.35                  bloblist_t *bl = bloblist_add(_message->attachments,