merged in default ENGINE-633
authorKrista 'DarthMama' Bennett <krista@pep.foundation>
Tue, 14 Jul 2020 12:57:49 +0200
branchENGINE-633
changeset 48573541011d4311
parent 4849 c49e137cab74
parent 4856 82cdd7551965
child 4869 d6fabf937a84
merged in default
src/keymanagement.c
src/keymanagement.h
src/pEpEngine.c
src/pEpEngine.h
src/pgp_sequoia.c
     1.1 --- a/.hgtags	Mon Jul 13 11:52:04 2020 +0200
     1.2 +++ b/.hgtags	Tue Jul 14 12:57:49 2020 +0200
     1.3 @@ -53,3 +53,5 @@
     1.4  89e31ecdc61b25533eb7d00d09f1d44afcddf7e4 Release_2.1.0-RC13
     1.5  64797b875a00d3167a4a53c6c80298141ed37376 Release_2.1.0-RC14
     1.6  2c94359b432679702352ecd8705f4321eca3328a Release_2.1.0-RC15
     1.7 +ddded8784a8f482a41ef45c09b563a6cf9902bcf Release_2.1.0-RC16
     1.8 +22153e06e4cd688e1596439eb37d789ad1fe0241 Release_2.1.0-RC17
     2.1 --- a/src/keymanagement.c	Mon Jul 13 11:52:04 2020 +0200
     2.2 +++ b/src/keymanagement.c	Tue Jul 14 12:57:49 2020 +0200
     2.3 @@ -2072,7 +2072,7 @@
     2.4      return status;                                        
     2.5  }
     2.6  
     2.7 -PEP_STATUS clean_own_key_defaults(PEP_SESSION session) {
     2.8 +DYNAMIC_API PEP_STATUS clean_own_key_defaults(PEP_SESSION session) {
     2.9      identity_list* idents = NULL;
    2.10      PEP_STATUS status = own_identities_retrieve(session, &idents);
    2.11      if (status != PEP_STATUS_OK)
     3.1 --- a/src/keymanagement.h	Mon Jul 13 11:52:04 2020 +0200
     3.2 +++ b/src/keymanagement.h	Tue Jul 14 12:57:49 2020 +0200
     3.3 @@ -381,6 +381,25 @@
     3.4         const char *fpr
     3.5      );
     3.6  
     3.7 +//
     3.8 +// clean_own_key_defaults()
     3.9 +//
    3.10 +// Remove any broken, unrenewable expired, or revoked 
    3.11 +// own keys from identity and user defaults in the database.
    3.12 +//  
    3.13 +//  parameters:
    3.14 +//      session (in)          session to use
    3.15 +//
    3.16 +//  return value:
    3.17 +//      PEP_STATUS_OK if all went well
    3.18 +//      PEP_PASSPHRASE_REQUIRED if a key needs to be renewed 
    3.19 +//                              but cached passphrase isn't present 
    3.20 +//      PEP_WRONG_PASSPHRASE if passphrase required for expired key renewal 
    3.21 +//                           but passphrase is the wrong one
    3.22 +//      Otherwise, database and keyring errors as appropriate 
    3.23 +//
    3.24 +DYNAMIC_API PEP_STATUS clean_own_key_defaults(PEP_SESSION session);
    3.25 +
    3.26  PEP_STATUS get_all_keys_for_user(PEP_SESSION session, 
    3.27                                   const char* user_id,
    3.28                                   stringlist_t** keys);
    3.29 @@ -415,9 +434,6 @@
    3.30                          bool check_blacklist,
    3.31                          bool own_must_contain_private);
    3.32  
    3.33 -
    3.34 -PEP_STATUS clean_own_key_defaults(PEP_SESSION session);
    3.35 -
    3.36  #ifdef __cplusplus
    3.37  }
    3.38  #endif
     4.1 --- a/src/pEpEngine.c	Mon Jul 13 11:52:04 2020 +0200
     4.2 +++ b/src/pEpEngine.c	Tue Jul 14 12:57:49 2020 +0200
     4.3 @@ -2099,11 +2099,12 @@
     4.4          goto pEp_error;
     4.5  
     4.6      // runtime config
     4.7 -    
     4.8 -    // clean up invalid keys 
     4.9 -    status = clean_own_key_defaults(_session);
    4.10 -    if (status != PEP_STATUS_OK)
    4.11 -        goto pEp_error;
    4.12 +
    4.13 +    // Will now be called by adapter.
    4.14 +    // // clean up invalid keys 
    4.15 +    // status = clean_own_key_defaults(_session);
    4.16 +    // if (status != PEP_STATUS_OK)
    4.17 +    //     goto pEp_error;
    4.18  
    4.19      *session = _session;
    4.20      
     5.1 --- a/src/pEpEngine.h	Mon Jul 13 11:52:04 2020 +0200
     5.2 +++ b/src/pEpEngine.h	Tue Jul 14 12:57:49 2020 +0200
     5.3 @@ -25,7 +25,7 @@
     5.4  #define PEP_ENGINE_VERSION_MAJOR 2
     5.5  #define PEP_ENGINE_VERSION_MINOR 1
     5.6  #define PEP_ENGINE_VERSION_PATCH 0
     5.7 -#define PEP_ENGINE_VERSION_RC    16
     5.8 +#define PEP_ENGINE_VERSION_RC    18
     5.9  
    5.10  
    5.11  #define PEP_OWN_USERID "pEp_own_userId"
     6.1 --- a/src/pgp_sequoia.c	Mon Jul 13 11:52:04 2020 +0200
     6.2 +++ b/src/pgp_sequoia.c	Tue Jul 14 12:57:49 2020 +0200
     6.3 @@ -231,6 +231,84 @@
     6.4      return result;
     6.5  }
     6.6  
     6.7 +static PEP_STATUS _pgp_get_decrypted_key(PEP_SESSION session,
     6.8 +                                         pgp_cert_valid_key_iter_t iter,
     6.9 +                                         pgp_key_t* decrypted_key) {
    6.10 +
    6.11 +    if (!iter)
    6.12 +        return PEP_UNKNOWN_ERROR; // ???
    6.13 +    
    6.14 +    if (!decrypted_key)
    6.15 +        return PEP_ILLEGAL_VALUE;
    6.16 +        
    6.17 +    PEP_STATUS status = PEP_STATUS_OK;
    6.18 +    
    6.19 +    pgp_error_t err = NULL;    
    6.20 +    bool bad_pass = false;
    6.21 +    bool missing_pass = false;
    6.22 +    pgp_key_t key = NULL;
    6.23 +    *decrypted_key = NULL;
    6.24 +
    6.25 +    pgp_valid_key_amalgamation_t ka = pgp_cert_valid_key_iter_next (iter, NULL, NULL);
    6.26 +
    6.27 +    // FIXME: better error!!!
    6.28 +    if (! ka)
    6.29 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR,
    6.30 +                   "%s has no capable key", fpr);
    6.31 +
    6.32 +    // pgp_key_into_key_pair needs to own the key, but here we
    6.33 +    // only get a reference (which we still need to free).
    6.34 +    
    6.35 +    for ( ; ka ; (ka = pgp_cert_valid_key_iter_next(iter, NULL, NULL))) {                       
    6.36 +        // pgp_key_into_key_pair needs to own the key, but here we
    6.37 +        // only get a reference (which we still need to free).
    6.38 +        key = pgp_valid_key_amalgamation_key (ka);
    6.39 +
    6.40 +        if (pgp_key_has_unencrypted_secret(key)) 
    6.41 +            break;
    6.42 +        else {
    6.43 +            const char* pass = session->curr_passphrase;
    6.44 +            if (pass && pass[0]) {
    6.45 +                pgp_key_t decrypted_key = NULL;
    6.46 +                decrypted_key = pgp_key_decrypt_secret(&err, pgp_key_clone(key), (uint8_t*)session->curr_passphrase,
    6.47 +                                                        strlen(session->curr_passphrase));                             
    6.48 +                pgp_key_free(key);
    6.49 +                key = NULL;
    6.50 +                
    6.51 +                if (!decrypted_key) {                               
    6.52 +                    bad_pass = true;
    6.53 +                    continue;
    6.54 +                }    
    6.55 +                else {
    6.56 +                    key = decrypted_key;
    6.57 +                    break;
    6.58 +                }
    6.59 +            }
    6.60 +            else {
    6.61 +                pgp_key_free(key);
    6.62 +                key = NULL;
    6.63 +                missing_pass = true;
    6.64 +                continue;
    6.65 +            }
    6.66 +        }
    6.67 +    }
    6.68 +    if (!key) {
    6.69 +        if (bad_pass)
    6.70 +            ERROR_OUT(err, PEP_WRONG_PASSPHRASE, "pgp_key_decrypt_secret");
    6.71 +        else if (missing_pass)    
    6.72 +            ERROR_OUT(err, PEP_PASSPHRASE_REQUIRED, "pgp_key_decrypt_secret");
    6.73 +        else        
    6.74 +            ERROR_OUT(err, PEP_UNKNOWN_ERROR, "pgp_valid_key_amalgamation_key");            
    6.75 +    }   
    6.76 +    
    6.77 +out:
    6.78 +    pgp_valid_key_amalgamation_free (ka);
    6.79 +    *decrypted_key = key;
    6.80 +
    6.81 +    T("(%s)-> %s", fpr, pEp_status_to_string(status));
    6.82 +    return status;                                                 
    6.83 +}
    6.84 +
    6.85  PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
    6.86  {
    6.87      PEP_STATUS status = PEP_STATUS_OK;
    6.88 @@ -1851,10 +1929,7 @@
    6.89      pgp_key_pair_t signing_keypair = NULL;
    6.90      pgp_signer_t signer = NULL;
    6.91      pgp_writer_stack_t ws = NULL;
    6.92 -
    6.93 -    bool bad_pass = false;
    6.94 -    bool missing_pass = false;                    
    6.95 -
    6.96 +    
    6.97      status = cert_find_by_fpr_hex(session, fpr, true, &signer_cert, NULL);
    6.98      ERROR_OUT(NULL, status, "Looking up key '%s'", fpr);
    6.99  
   6.100 @@ -1862,60 +1937,14 @@
   6.101      pgp_cert_valid_key_iter_alive(iter);
   6.102      pgp_cert_valid_key_iter_revoked(iter, false);
   6.103      pgp_cert_valid_key_iter_for_signing (iter);
   6.104 -//    pgp_cert_valid_key_iter_unencrypted_secret (iter);
   6.105 -
   6.106 -    // If there are multiple signing capable subkeys, we just take
   6.107 -    // the first one, whichever one that happens to be.
   6.108 -    ka = pgp_cert_valid_key_iter_next (iter, NULL, NULL);
   6.109 -    if (! ka)
   6.110 -        ERROR_OUT (err, PEP_UNKNOWN_ERROR,
   6.111 +
   6.112 +    pgp_key_t key = NULL;
   6.113 +    status = _pgp_get_decrypted_key(session, iter, &key);
   6.114 +
   6.115 +    if (!key || status != PEP_STATUS_OK) {
   6.116 +        ERROR_OUT (err, status,
   6.117                     "%s has no signing capable key", fpr);
   6.118 -
   6.119 -    // pgp_key_into_key_pair needs to own the key, but here we
   6.120 -    // only get a reference (which we still need to free).
   6.121 -    
   6.122 -    pgp_key_t key = NULL;
   6.123 -    for ( ; ka ; (ka = pgp_cert_valid_key_iter_next(iter, NULL, NULL))) {                       
   6.124 -        // pgp_key_into_key_pair needs to own the key, but here we
   6.125 -        // only get a reference (which we still need to free).
   6.126 -        key = pgp_valid_key_amalgamation_key (ka);
   6.127 -
   6.128 -        if (pgp_key_has_unencrypted_secret(key)) 
   6.129 -            break;
   6.130 -        else {
   6.131 -            const char* pass = session->curr_passphrase;
   6.132 -            if (pass && pass[0]) {
   6.133 -                pgp_key_t decrypted_key = NULL;
   6.134 -                decrypted_key = pgp_key_decrypt_secret(&err, pgp_key_clone(key), (uint8_t*)session->curr_passphrase,
   6.135 -                                                        strlen(session->curr_passphrase));                             
   6.136 -                pgp_key_free(key);
   6.137 -                key = NULL;
   6.138 -                
   6.139 -                if (!decrypted_key) {                               
   6.140 -                    bad_pass = true;
   6.141 -                    continue;
   6.142 -                }    
   6.143 -                else {
   6.144 -                    key = decrypted_key;
   6.145 -                    break;
   6.146 -                }
   6.147 -            }
   6.148 -            else {
   6.149 -                pgp_key_free(key);
   6.150 -                key = NULL;
   6.151 -                missing_pass = true;
   6.152 -                continue;
   6.153 -            }
   6.154 -        }
   6.155 -    }
   6.156 -    if (!key) {
   6.157 -        if (bad_pass)
   6.158 -            ERROR_OUT(err, PEP_WRONG_PASSPHRASE, "pgp_key_decrypt_secret");
   6.159 -        else if (missing_pass)    
   6.160 -            ERROR_OUT(err, PEP_PASSPHRASE_REQUIRED, "pgp_key_decrypt_secret");
   6.161 -        else        
   6.162 -            ERROR_OUT(err, PEP_UNKNOWN_ERROR, "pgp_valid_key_amalgamation_key");            
   6.163 -    }    
   6.164 +    }               
   6.165      
   6.166      signing_keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
   6.167      pgp_key_free (key);
   6.168 @@ -2118,68 +2147,20 @@
   6.169      // pgp_encrypt_new consumes the recipients (but not the keys).
   6.170      recipient_count = 0;
   6.171  
   6.172 -    bool bad_pass = false;
   6.173 -    bool missing_pass = false;                
   6.174 -
   6.175      if (sign) {            
   6.176          
   6.177          iter = pgp_cert_valid_key_iter(signer_cert, session->policy, 0);
   6.178          pgp_cert_valid_key_iter_alive(iter);
   6.179          pgp_cert_valid_key_iter_revoked(iter, false);
   6.180          pgp_cert_valid_key_iter_for_signing (iter);
   6.181 -//        pgp_cert_valid_key_iter_unencrypted_secret (iter);
   6.182 -
   6.183 -        
   6.184 -        // If there are multiple signing capable subkeys, we just take
   6.185 -        // the first one, whichever one that happens to be.            
   6.186 -            
   6.187 -        ka = pgp_cert_valid_key_iter_next (iter, NULL, NULL);
   6.188 -        if (! ka)
   6.189 -            ERROR_OUT (err, PEP_UNKNOWN_ERROR,
   6.190 -                       "%s has no signing capable key", keylist->value);
   6.191  
   6.192          pgp_key_t key = NULL;
   6.193 -        for ( ; ka ; (ka = pgp_cert_valid_key_iter_next(iter, NULL, NULL))) {                       
   6.194 -            // pgp_key_into_key_pair needs to own the key, but here we
   6.195 -            // only get a reference (which we still need to free).
   6.196 -            key = pgp_valid_key_amalgamation_key (ka);
   6.197 -
   6.198 -            if (pgp_key_has_unencrypted_secret(key)) 
   6.199 -                break;
   6.200 -            else {
   6.201 -                const char* pass = session->curr_passphrase;
   6.202 -                if (pass && pass[0]) {
   6.203 -                    pgp_key_t decrypted_key = NULL;
   6.204 -                    decrypted_key = pgp_key_decrypt_secret(&err, pgp_key_clone(key), (uint8_t*)session->curr_passphrase,
   6.205 -                                                            strlen(session->curr_passphrase));                             
   6.206 -                    pgp_key_free(key);
   6.207 -                    key = NULL;
   6.208 -                    
   6.209 -                    if (!decrypted_key) {                               
   6.210 -                        bad_pass = true;
   6.211 -                        continue;
   6.212 -                    }    
   6.213 -                    else {
   6.214 -                        key = decrypted_key;
   6.215 -                        break;
   6.216 -                    }
   6.217 -                }
   6.218 -                else {
   6.219 -                    pgp_key_free(key);
   6.220 -                    key = NULL;
   6.221 -                    missing_pass = true;
   6.222 -                    continue;
   6.223 -                }
   6.224 -            }
   6.225 -        }
   6.226 -        if (!key) {
   6.227 -            if (bad_pass)
   6.228 -                ERROR_OUT(err, PEP_WRONG_PASSPHRASE, "pgp_key_decrypt_secret");
   6.229 -            else if (missing_pass)    
   6.230 -                ERROR_OUT(err, PEP_PASSPHRASE_REQUIRED, "pgp_key_decrypt_secret");
   6.231 -            else        
   6.232 -                ERROR_OUT(err, PEP_UNKNOWN_ERROR, "pgp_valid_key_amalgamation_key");            
   6.233 -        }
   6.234 +        status = _pgp_get_decrypted_key(session, iter, &key);
   6.235 +
   6.236 +        if (!key || status != PEP_STATUS_OK) {
   6.237 +            ERROR_OUT (err, status,
   6.238 +                       "%s has no signing capable key", fpr);
   6.239 +        }               
   6.240                  
   6.241                      
   6.242          signing_keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
   6.243 @@ -3071,19 +3052,18 @@
   6.244  
   6.245      iter = pgp_cert_valid_key_iter(cert, session->policy, 0);
   6.246      pgp_cert_valid_key_iter_for_certification (iter);
   6.247 -    pgp_cert_valid_key_iter_unencrypted_secret (iter);
   6.248      pgp_cert_valid_key_iter_revoked(iter, false);
   6.249  
   6.250 -    // If there are multiple certification capable subkeys, we just
   6.251 -    // take the first one, whichever one that happens to be.
   6.252 -    primary = pgp_cert_valid_key_iter_next (iter, NULL, NULL);
   6.253 -    if (! primary)
   6.254 -        ERROR_OUT (err, PEP_UNKNOWN_ERROR,
   6.255 -                   "%s has no usable certification capable key", fpr);
   6.256 +    pgp_key_t key = NULL;
   6.257 +    status = _pgp_get_decrypted_key(session, iter, &key);
   6.258 +
   6.259 +    if (!key || status != PEP_STATUS_OK) {
   6.260 +        ERROR_OUT (err, status,
   6.261 +                   "%s has no signing capable key", fpr);
   6.262 +    }               
   6.263  
   6.264      // pgp_key_into_key_pair needs to own the key, but here we
   6.265      // only get a reference (which we still need to free).
   6.266 -    pgp_key_t key = pgp_valid_key_amalgamation_key (primary);
   6.267      keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
   6.268      pgp_key_free (key);
   6.269      if (! keypair)
   6.270 @@ -3197,18 +3177,17 @@
   6.271      pgp_cert_valid_key_iter_alive(iter);
   6.272      pgp_cert_valid_key_iter_revoked(iter, false);
   6.273      pgp_cert_valid_key_iter_for_certification (iter);
   6.274 -    pgp_cert_valid_key_iter_unencrypted_secret (iter);
   6.275 -
   6.276 -    // If there are multiple certification capable subkeys, we just
   6.277 -    // take the first one, whichever one that happens to be.
   6.278 -    ka = pgp_cert_valid_key_iter_next (iter, NULL, NULL);
   6.279 -    if (! ka)
   6.280 +
   6.281 +    // pgp_key_into_key_pair needs to own the key, but here we
   6.282 +    // only get a reference (which we still need to free).    
   6.283 +    pgp_key_t key = NULL;
   6.284 +    status = _pgp_get_decrypted_key(session, iter, &key);
   6.285 +
   6.286 +    if (!key || status != PEP_STATUS_OK) {
   6.287          ERROR_OUT (err, PEP_UNKNOWN_ERROR,
   6.288 -                   "%s has no usable certification capable key", fpr);
   6.289 -
   6.290 -    // pgp_key_into_key_pair needs to own the key, but here we
   6.291 -    // only get a reference (which we still need to free).
   6.292 -    pgp_key_t key = pgp_valid_key_amalgamation_key (ka);
   6.293 +                   "%s has no usable certification capable key", fpr);           
   6.294 +    }               
   6.295 +                
   6.296      keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
   6.297      pgp_key_free (key);
   6.298      if (! keypair)
     7.1 --- a/test/src/CleanInvalidOwnKeysTest.cc	Mon Jul 13 11:52:04 2020 +0200
     7.2 +++ b/test/src/CleanInvalidOwnKeysTest.cc	Tue Jul 14 12:57:49 2020 +0200
     7.3 @@ -82,10 +82,11 @@
     7.4  
     7.5  
     7.6  TEST_F(CleanInvalidOwnKeysTest, check_clean_invalid_own_keys_no_alts_revoked) {
     7.7 -    // This is just a dummy test case. The convention is check_whatever_you_are_checking
     7.8 -    // so for multiple test cases in a suite, be more explicit ;)   
     7.9 +    PEP_STATUS status = clean_own_key_defaults(session);
    7.10 +    ASSERT_EQ(status, PEP_STATUS_OK);    
    7.11 +
    7.12      pEp_identity* alice = NULL;
    7.13 -    PEP_STATUS status = get_identity(session, "pep.test.alice@pep-project.org", "ALICE", &alice);
    7.14 +    status = get_identity(session, "pep.test.alice@pep-project.org", "ALICE", &alice);
    7.15      ASSERT_EQ(status, PEP_STATUS_OK);
    7.16      ASSERT_STRNE(alice->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97");
    7.17      char* fpr = NULL;
    7.18 @@ -95,10 +96,11 @@
    7.19  }
    7.20  
    7.21  TEST_F(CleanInvalidOwnKeysTest, check_clean_invalid_own_keys_no_alts_mistrusted) {
    7.22 -    // This is just a dummy test case. The convention is check_whatever_you_are_checking
    7.23 -    // so for multiple test cases in a suite, be more explicit ;)   
    7.24 +    PEP_STATUS status = clean_own_key_defaults(session);
    7.25 +    ASSERT_EQ(status, PEP_STATUS_OK);    
    7.26 +
    7.27      pEp_identity* alice = NULL;
    7.28 -    PEP_STATUS status = get_identity(session, "pep.test.alice@pep-project.org", "ALICE", &alice);
    7.29 +    status = get_identity(session, "pep.test.alice@pep-project.org", "ALICE", &alice);
    7.30      ASSERT_EQ(status, PEP_STATUS_OK);
    7.31      ASSERT_STRNE(alice->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97");
    7.32      char* fpr = NULL;
    7.33 @@ -108,10 +110,11 @@
    7.34  }
    7.35  
    7.36  TEST_F(CleanInvalidOwnKeysTest, check_clean_invalid_own_keys_no_alts_expired) {
    7.37 -    // This is just a dummy test case. The convention is check_whatever_you_are_checking
    7.38 -    // so for multiple test cases in a suite, be more explicit ;)   
    7.39 +    PEP_STATUS status = clean_own_key_defaults(session);
    7.40 +    ASSERT_EQ(status, PEP_STATUS_OK);    
    7.41 +
    7.42      pEp_identity* bob = NULL;
    7.43 -    PEP_STATUS status = get_identity(session, "expired_bob_0@darthmama.org", "BOB", &bob);
    7.44 +    status = get_identity(session, "expired_bob_0@darthmama.org", "BOB", &bob);
    7.45      ASSERT_EQ(status, PEP_STATUS_OK);
    7.46      ASSERT_STREQ(bob->fpr, "E4A8CD51C25D0ED5BAD0834BD2FDE305A35FE3F5");
    7.47      char* fpr = NULL;