ENGINE-423: partial implementation of reencrypt functionality. Stashing changes to check another bug. ENGINE-423
authorKrista Bennett <krista@pep-project.org>
Wed, 18 Apr 2018 20:39:11 +0200
branchENGINE-423
changeset 26122c6bad8b4a69
parent 2611 5ca43900bc58
child 2614 3ea0f7f89ac3
ENGINE-423: partial implementation of reencrypt functionality. Stashing changes to check another bug.
src/keymanagement.c
src/message_api.c
src/message_api.h
src/pEp_internal.h
     1.1 --- a/src/keymanagement.c	Wed Apr 18 09:44:21 2018 +0200
     1.2 +++ b/src/keymanagement.c	Wed Apr 18 20:39:11 2018 +0200
     1.3 @@ -15,8 +15,6 @@
     1.4  #include "sync_fsm.h"
     1.5  #include "blacklist.h"
     1.6  
     1.7 -#define KEY_EXPIRE_DELTA (60 * 60 * 24 * 365)
     1.8 -
     1.9  static bool key_matches_address(PEP_SESSION session, const char* address,
    1.10                                  const char* fpr) {
    1.11      if (!session || !address || !fpr)
     2.1 --- a/src/message_api.c	Wed Apr 18 09:44:21 2018 +0200
     2.2 +++ b/src/message_api.c	Wed Apr 18 20:39:11 2018 +0200
     2.3 @@ -2030,11 +2030,15 @@
     2.4              target_id->user_id = own_id; // ownership transfer
     2.5          }
     2.6      }
     2.7 -
     2.8 -    status = myself(session, target_id);
     2.9 -    if (status != PEP_STATUS_OK)
    2.10 -        goto pep_error;
    2.11 -
    2.12 +    
    2.13 +    if (target_id->address) {
    2.14 +        status = myself(session, target_id);
    2.15 +        if (status != PEP_STATUS_OK)
    2.16 +            goto pep_error;
    2.17 +    }
    2.18 +    else if (!target_fpr)
    2.19 +        return PEP_ILLEGAL_VALUE;
    2.20 +    
    2.21      *dst = NULL;
    2.22  
    2.23      // PEP_STATUS _status = update_identity(session, target_id);
    2.24 @@ -2853,6 +2857,84 @@
    2.25      // FIXME - are there any flags or anything else we need to be sure are carried?
    2.26  }
    2.27  
    2.28 +static bool is_trusted_own_priv_fpr(PEP_SESSION session, 
    2.29 +                       const char* own_id, 
    2.30 +                       const char* fpr
    2.31 +    ) 
    2.32 +{   
    2.33 +    bool retval = false;
    2.34 +    if (!EMPTYSTR(fpr)) {
    2.35 +        pEp_identity* test_identity = new_identity(NULL, fpr, own_id, NULL);
    2.36 +        if (test_identity) {
    2.37 +            PEP_STATUS status = get_trust(session, test_identity);
    2.38 +            if (status == PEP_STATUS_OK) {
    2.39 +                if (test_identity->comm_type & PEP_ct_confirmed) {
    2.40 +                    bool has_priv = false;
    2.41 +                    status = contains_priv_key(session, fpr, &has_priv);
    2.42 +                    if (status == PEP_STATUS_OK && has_priv)
    2.43 +                        retval = true;
    2.44 +                }
    2.45 +            }
    2.46 +            free(test_identity);
    2.47 +        }
    2.48 +    }
    2.49 +    return retval;
    2.50 +}
    2.51 +
    2.52 +static bool reject_fpr(PEP_SESSION session, const char* fpr) {
    2.53 +    bool reject = true;
    2.54 +
    2.55 +    PEP_STATUS status = key_revoked(session, fpr, &reject);
    2.56 +
    2.57 +    if (!reject) {
    2.58 +        status = key_expired(session, fpr, &reject);
    2.59 +        if (reject) {
    2.60 +            timestamp *ts = new_timestamp(time(NULL) + KEY_EXPIRE_DELTA);
    2.61 +            status = renew_key(session, fpr, ts);
    2.62 +            free_timestamp(ts);
    2.63 +            if (status == PEP_STATUS_OK)
    2.64 +                reject = false;
    2.65 +        }
    2.66 +    }
    2.67 +    return reject;
    2.68 +}
    2.69 +
    2.70 +static char* seek_good_trusted_private_fpr(PEP_SESSION session, char* own_id, 
    2.71 +                                           stringlist_t* keylist) {
    2.72 +    if (!own_id || !keylist)
    2.73 +        return NULL;
    2.74 +        
    2.75 +    stringlist_t* kl_curr = keylist;
    2.76 +    char* retval = NULL;
    2.77 +    while (kl_curr) {
    2.78 +        char* fpr = kl_curr->value;
    2.79 +        
    2.80 +        if (is_own_trusted_private_fpr(fpr)) { 
    2.81 +            if (!reject_fpr(fpr))
    2.82 +                return strdup(fpr);
    2.83 +        }
    2.84 +            
    2.85 +        kl_curr = kl_curr->next;
    2.86 +    }
    2.87 +
    2.88 +    char* target_own_fpr = NULL;
    2.89 +    
    2.90 +    // Last shot...
    2.91 +    status = get_user_default_key(session, own_id, 
    2.92 +                                  &target_own_fpr);
    2.93 +
    2.94 +    if (status == PEP_STATUS_OK && !EMPTYSTR(target_own_fpr)) {
    2.95 +        if (is_own_trusted_private_fpr(target_own_fpr)) { 
    2.96 +            if (!reject_fpr(target_own_fpr))
    2.97 +                return target_own_fpr;
    2.98 +        }
    2.99 +    }
   2.100 +    
   2.101 +    // TODO: We can also go through all of the other available fprs for the
   2.102 +    // own identity, but then I submit this function requires a little refactoring
   2.103 +        
   2.104 +    return NULL;
   2.105 +}
   2.106  
   2.107  DYNAMIC_API PEP_STATUS _decrypt_message(
   2.108          PEP_SESSION session,
   2.109 @@ -2888,11 +2970,21 @@
   2.110      char* signer_fpr = NULL;
   2.111      bool is_pep_msg = is_a_pEpmessage(src);
   2.112  
   2.113 +    // Grab input flags
   2.114 +    bool reencrypt = (*flags & PEP_decrypt_flag_untrusted_server > 0);
   2.115 +    
   2.116 +    // We own this pointer, and we take control of *keylist if reencrypting.
   2.117 +    stringlist_t* extra = NULL;
   2.118 +    if (reencrypt) {
   2.119 +        if (*keylist) {
   2.120 +            extra = *keylist;
   2.121 +        }
   2.122 +    }
   2.123 +            
   2.124      *dst = NULL;
   2.125      *keylist = NULL;
   2.126      *rating = PEP_rating_undefined;
   2.127 -
   2.128 -    *flags = 0;
   2.129 +//    *flags = 0;
   2.130      
   2.131      /*** End init ***/
   2.132  
   2.133 @@ -3230,6 +3322,41 @@
   2.134      *dst = msg;
   2.135      *keylist = _keylist;
   2.136  
   2.137 +    if (reencrypt) {
   2.138 +        if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED) {
   2.139 +            PEP_STATUS reencrypt_status = PEP_CANNOT_REENCRYPT;
   2.140 +            char* own_id = NULL;
   2.141 +            status = get_default_own_userid(session, &own_id);
   2.142 +            if (own_id) {
   2.143 +                char* target_own_fpr = seek_good_trusted_private_fpr(session,
   2.144 +                                                                     own_id,
   2.145 +                                                                     _keylist);
   2.146 +                if (target_own_fpr) {
   2.147 +                    pEp_identity* target_id = new_identity(NULL, own_id, 
   2.148 +                                                           target_own_fpr, NULL);
   2.149 +                    if (target_id) {
   2.150 +                        *dst = NULL;
   2.151 +                        reencrypt_status = encrypt_message_for_self(session, target_id, msg,
   2.152 +                                                                    extra, dst, PEP_enc_PGP_MIME,
   2.153 +                                                                    0);
   2.154 +                        if (reencrypt_status != PEP_STATUS_OK)
   2.155 +                            reencrypt_status = PEP_CANNOT_REENCRYPT;
   2.156 +                            
   2.157 +                        free_identity(target_id);
   2.158 +                    }
   2.159 +                    free(target_own_fpr);
   2.160 +                }     
   2.161 +                free(own_id);
   2.162 +            }
   2.163 +        }
   2.164 +        free_stringlist(extra); // This was an input variable for us. Keylist is overwritten above.
   2.165 +        if (reencrypt_status == PEP_CANNOT_REENCRYPT)
   2.166 +            decrypt_status = reencrypt_status;
   2.167 +        else {
   2.168 +            // Copy msg into src
   2.169 +        }
   2.170 +    }
   2.171 +        
   2.172      if(decrypt_status == PEP_DECRYPTED_AND_VERIFIED)
   2.173          return PEP_STATUS_OK;
   2.174      else
     3.1 --- a/src/message_api.h	Wed Apr 18 09:44:21 2018 +0200
     3.2 +++ b/src/message_api.h	Wed Apr 18 20:39:11 2018 +0200
     3.3 @@ -38,6 +38,7 @@
     3.4      // This is used for outer messages (used to wrap the real message)
     3.5      // This is only used internally and (eventually) by transport functions
     3.6      PEP_encrypt_flag_inner_message = 0x8
     3.7 +    
     3.8  } PEP_encrypt_flags; 
     3.9  
    3.10  typedef unsigned int PEP_encrypt_flags_t;
    3.11 @@ -229,7 +230,8 @@
    3.12  typedef enum _PEP_decrypt_flags {
    3.13      PEP_decrypt_flag_own_private_key = 0x1,
    3.14      PEP_decrypt_flag_consume = 0x2,
    3.15 -    PEP_decrypt_flag_ignore = 0x4
    3.16 +    PEP_decrypt_flag_ignore = 0x4,    
    3.17 +    PEP_decrypt_flag_untrusted_server = 0x8
    3.18  } PEP_decrypt_flags; 
    3.19  
    3.20  typedef unsigned int PEP_decrypt_flags_t;
    3.21 @@ -243,7 +245,7 @@
    3.22  //      dst (out)           pointer to new decrypted message or NULL on failure
    3.23  //      keylist (out)       stringlist with keyids
    3.24  //      rating (out)        rating for the message
    3.25 -//      flags (out)         flags to signal special decryption features
    3.26 +//      flags (in/out)         flags to signal special decryption features
    3.27  //
    3.28  //  return value:
    3.29  //      error status 
     4.1 --- a/src/pEp_internal.h	Wed Apr 18 09:44:21 2018 +0200
     4.2 +++ b/src/pEp_internal.h	Wed Apr 18 20:39:11 2018 +0200
     4.3 @@ -8,6 +8,8 @@
     4.4  #define MAX_KEY_SIZE (1024 * 1024)
     4.5  #define MAX_KEYS_TO_IMPORT  20
     4.6  
     4.7 +#define KEY_EXPIRE_DELTA (60 * 60 * 24 * 365)
     4.8 +
     4.9  // this is 20 trustwords with 79 chars max
    4.10  #define MAX_TRUSTWORDS_SPACE (20 * 80)
    4.11