ENGINE-507: trust_own_key now in; read documentation ENGINE-507
authorKrista 'DarthMama' Bennett <krista@pep.foundation>
Wed, 16 Jan 2019 16:24:40 +0100
branchENGINE-507
changeset 3222fcc3d6543681
parent 3221 47b815c5ba76
child 3223 eace10725457
child 3224 3b78b93682c3
ENGINE-507: trust_own_key now in; read documentation
src/keymanagement.c
src/keymanagement.h
test/src/engine_tests/DecryptAttachPrivateKeyTrustedTests.cc
test/src/engine_tests/EncryptAttachPrivateKeyTests.cc
     1.1 --- a/src/keymanagement.c	Mon Jan 14 18:54:27 2019 +0100
     1.2 +++ b/src/keymanagement.c	Wed Jan 16 16:24:40 2019 +0100
     1.3 @@ -103,9 +103,14 @@
     1.4      return PEP_STATUS_OK;
     1.5  }
     1.6  
     1.7 +
     1.8 +// own_must_contain_private is usually true when calling;
     1.9 +// we only set it to false when we have the idea of
    1.10 +// possibly having an own pubkey that we need to check on its own
    1.11  static PEP_STATUS validate_fpr(PEP_SESSION session, 
    1.12                                 pEp_identity* ident,
    1.13 -                               bool check_blacklist) {
    1.14 +                               bool check_blacklist,
    1.15 +                               bool own_must_contain_private) {
    1.16      
    1.17      PEP_STATUS status = PEP_STATUS_OK;
    1.18      
    1.19 @@ -115,12 +120,14 @@
    1.20      char* fpr = ident->fpr;
    1.21      
    1.22      bool has_private = false;
    1.23 +    status = contains_priv_key(session, fpr, &has_private);
    1.24      
    1.25 -    if (ident->me) {
    1.26 -        status = contains_priv_key(session, fpr, &has_private);
    1.27 +    if (ident->me && own_must_contain_private) {
    1.28          if (status != PEP_STATUS_OK || !has_private)
    1.29              return PEP_KEY_UNSUITABLE;
    1.30      }
    1.31 +    else if (status != PEP_STATUS_OK && has_private) // should never happen
    1.32 +        has_private = false;
    1.33      
    1.34      status = get_trust(session, ident);
    1.35      if (status != PEP_STATUS_OK)
    1.36 @@ -196,7 +203,9 @@
    1.37          }
    1.38      }
    1.39              
    1.40 -    if (ident->me && (ct >= PEP_ct_strong_but_unconfirmed) && !revoked && expired) {
    1.41 +    if (ident->me && has_private && 
    1.42 +        (ct >= PEP_ct_strong_but_unconfirmed) && 
    1.43 +        !revoked && expired) {
    1.44          // extend key
    1.45          timestamp *ts = new_timestamp(time(NULL) + KEY_EXPIRE_DELTA);
    1.46          status = renew_key(session, fpr, ts);
    1.47 @@ -315,7 +324,7 @@
    1.48      // Input: stored identity retrieved from database
    1.49      // if stored identity contains a default key
    1.50      if (!EMPTYSTR(stored_fpr)) {
    1.51 -        status = validate_fpr(session, stored_identity, check_blacklist);    
    1.52 +        status = validate_fpr(session, stored_identity, check_blacklist, true);    
    1.53          if (status == PEP_STATUS_OK && !EMPTYSTR(stored_identity->fpr)) {
    1.54              *is_identity_default = *is_address_default = true;
    1.55              return status;
    1.56 @@ -335,7 +344,7 @@
    1.57      if (!EMPTYSTR(user_fpr)) {             
    1.58          // There exists a default key for user, so validate
    1.59          stored_identity->fpr = user_fpr;
    1.60 -        status = validate_fpr(session, stored_identity, check_blacklist);
    1.61 +        status = validate_fpr(session, stored_identity, check_blacklist, true);
    1.62          if (status == PEP_STATUS_OK && stored_identity->fpr) {
    1.63              *is_user_default = true;
    1.64              *is_address_default = key_matches_address(session, 
    1.65 @@ -352,7 +361,7 @@
    1.66      status = elect_pubkey(session, stored_identity, check_blacklist);
    1.67      if (status == PEP_STATUS_OK) {
    1.68          if (!EMPTYSTR(stored_identity->fpr))
    1.69 -            validate_fpr(session, stored_identity, false); // blacklist already filtered of needed
    1.70 +            validate_fpr(session, stored_identity, false, true); // blacklist already filtered of needed
    1.71      }    
    1.72      else if (status != PEP_KEY_NOT_FOUND && first_reject_status != PEP_KEY_NOT_FOUND) {
    1.73          first_reject_status = status;
    1.74 @@ -1036,7 +1045,7 @@
    1.75      // check stored identity
    1.76      if (stored_identity && !EMPTYSTR(stored_identity->fpr)) {
    1.77          // Fall back / retrieve
    1.78 -        status = validate_fpr(session, stored_identity, false);
    1.79 +        status = validate_fpr(session, stored_identity, false, true);
    1.80          if (status == PEP_OUT_OF_MEMORY)
    1.81              goto pep_free;
    1.82          if (status == PEP_STATUS_OK) {
    1.83 @@ -1445,8 +1454,7 @@
    1.84      // Set up a temp trusted identity for the input fpr without a comm type;
    1.85      tmp_id = new_identity(ident->address, ident->fpr, ident->user_id, NULL);
    1.86      
    1.87 -    // ->me isn't set, even if this is an own identity, so this will work.
    1.88 -    status = validate_fpr(session, tmp_id, false);
    1.89 +    status = validate_fpr(session, tmp_id, false, true);
    1.90          
    1.91      if (status == PEP_STATUS_OK) {
    1.92          // Validate fpr gets trust DB or, when that fails, key comm type. we checked
    1.93 @@ -1506,7 +1514,7 @@
    1.94                      if (!tmp_user_ident)
    1.95                          status = PEP_OUT_OF_MEMORY;
    1.96                      else {
    1.97 -                        status = validate_fpr(session, tmp_user_ident, false);
    1.98 +                        status = validate_fpr(session, tmp_user_ident, false, true);
    1.99                          
   1.100                          if (status != PEP_STATUS_OK ||
   1.101                              tmp_user_ident->comm_type < PEP_ct_strong_but_unconfirmed ||
   1.102 @@ -1530,6 +1538,45 @@
   1.103      return status;
   1.104  }
   1.105  
   1.106 +DYNAMIC_API PEP_STATUS trust_own_key(
   1.107 +        PEP_SESSION session,
   1.108 +        pEp_identity* ident
   1.109 +    ) 
   1.110 +{
   1.111 +    assert(session);
   1.112 +    assert(ident);
   1.113 +    assert(!EMPTYSTR(ident->address));
   1.114 +    assert(!EMPTYSTR(ident->user_id));
   1.115 +    assert(!EMPTYSTR(ident->fpr));
   1.116 +    
   1.117 +    if (!ident || EMPTYSTR(ident->address) || EMPTYSTR(ident->user_id) ||
   1.118 +            EMPTYSTR(ident->fpr))
   1.119 +        return PEP_ILLEGAL_VALUE;
   1.120 +
   1.121 +    if (!is_me(session, ident))
   1.122 +        return PEP_ILLEGAL_VALUE;
   1.123 +
   1.124 +    // don't check blacklist or require a private key
   1.125 +    PEP_STATUS status = validate_fpr(session, ident, false, false);
   1.126 +
   1.127 +    if (status != PEP_STATUS_OK)
   1.128 +        return status;
   1.129 +
   1.130 +    status = set_pgp_keypair(session, ident->fpr);
   1.131 +    if (status != PEP_STATUS_OK)
   1.132 +        return status;
   1.133 +            
   1.134 +    if (ident->comm_type < PEP_ct_strong_but_unconfirmed)
   1.135 +        return PEP_KEY_UNSUITABLE;
   1.136 +
   1.137 +    ident->comm_type |= PEP_ct_confirmed;
   1.138 +    
   1.139 +    status = set_trust(session, ident);
   1.140 +
   1.141 +    return status;
   1.142 +}
   1.143 +
   1.144 +
   1.145  DYNAMIC_API PEP_STATUS own_key_is_listed(
   1.146          PEP_SESSION session,
   1.147          const char *fpr,
   1.148 @@ -1779,7 +1826,7 @@
   1.149      if (!me->fpr)
   1.150          return PEP_OUT_OF_MEMORY;
   1.151  
   1.152 -    status = validate_fpr(session, me, false);
   1.153 +    status = validate_fpr(session, me, false, true);
   1.154      if (status)
   1.155          return status;
   1.156  
     2.1 --- a/src/keymanagement.h	Mon Jan 14 18:54:27 2019 +0100
     2.2 +++ b/src/keymanagement.h	Wed Jan 16 16:24:40 2019 +0100
     2.3 @@ -245,6 +245,33 @@
     2.4          pEp_identity *ident
     2.5      );
     2.6  
     2.7 +// trust_own_key() - mark a key as trusted for self, generally
     2.8 +//                   used when we need to trust a public key
     2.9 +//                   associated with outselves for issues like
    2.10 +//                   manual key import
    2.11 +//  parameters:
    2.12 +//      session (in)        session to use
    2.13 +//      ident (in)          own ident containing fpr to trust
    2.14 +//
    2.15 +//  caveat:
    2.16 +//      if this is a public key only, keep in mind that if
    2.17 +//      the private part of the keypair is later added,
    2.18 +//      it will not undergo separate trust evaluation. This
    2.19 +//      is fine - even desired - as long as the semantics
    2.20 +//      of this function are understood as both trusting
    2.21 +//      the key and verifying it as an own key. This will
    2.22 +//      NEVER cause replacement of or setting of a default
    2.23 +//      *alone*. However, if a private key is ever associated
    2.24 +//      with this fpr, please keep in mind that trusting it
    2.25 +//      here makes it an eligible key for selection for    
    2.26 +//      encryption later. So use this function on purpose with
    2.27 +//      an understanding of what you're doing!
    2.28 +//
    2.29 +DYNAMIC_API PEP_STATUS trust_own_key(
    2.30 +        PEP_SESSION session,
    2.31 +        pEp_identity *ident
    2.32 +    );
    2.33 +
    2.34  
    2.35  // key_reset_trust() - reset trust bit or explicitly mistrusted status for an identity and
    2.36  //                     its accompanying key/user_id pair.
     3.1 --- a/test/src/engine_tests/DecryptAttachPrivateKeyTrustedTests.cc	Mon Jan 14 18:54:27 2019 +0100
     3.2 +++ b/test/src/engine_tests/DecryptAttachPrivateKeyTrustedTests.cc	Wed Jan 16 16:24:40 2019 +0100
     3.3 @@ -45,40 +45,27 @@
     3.4      // 13A9F97964A2B52520CAA40E51BCA783C065A213    
     3.5      input_key = slurp("test_keys/pub/priv-key-import-test-main_0-0xC065A213_pub.asc");
     3.6      status = import_key(session, input_key.c_str(), input_key.length(), NULL);
     3.7 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
     3.8 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
     3.9  
    3.10      input_key = slurp("test_keys/priv/priv-key-import-test-main_0-0xC065A213_priv.asc");
    3.11      status = import_key(session, input_key.c_str(), input_key.length(), NULL);
    3.12 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
    3.13 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
    3.14  
    3.15      // ensure there's no private key - doesn't work in automated tests, sadly. Uncommon when running script manually.
    3.16      bool has_priv = false;
    3.17 -    // status = contains_priv_key(session, fpr_same_addr_same_uid, &has_priv);
    3.18 -    // if (status == PEP_STATUS_OK && has_priv) {
    3.19 -    //     cout << "SORRY, have to delete keys here to run test correctly..." << endl;
    3.20 -    //     status = delete_keypair(session, fpr_same_addr_same_uid);
    3.21 -    //     if (status == PEP_STATUS_OK) {
    3.22 -    //         has_priv = false;
    3.23 -    //         status = contains_priv_key(session, fpr_same_addr_same_uid, &has_priv);
    3.24 -    //         TEST_ASSERT_MSG((has_priv == false), "has_priv == false");
    3.25 -    //         cout << "Successfully deleted keypair for " << fpr_same_addr_same_uid << " - will now import the public key only" << endl;
    3.26 -    //     }
    3.27 -    //     else
    3.28 -    //         cout << "Warning - delete keypair returned status " << tl_status_string(status) << ". This may or may not be an error, depending on what you expect." << endl;            
    3.29 -    // }
    3.30          
    3.31      // key with same address and user_id
    3.32      // 8AB616A3BD51DEF714B5E688EFFB540C3276D2E5
    3.33      input_key = slurp("test_keys/pub/priv-key-import-test-main_0-0x3276D2E5_pub.asc");
    3.34      status = import_key(session, input_key.c_str(), input_key.length(), NULL);
    3.35 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
    3.36 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
    3.37  
    3.38      
    3.39      cout << "Setting up own identity with default key " << fpr_main_me << endl;
    3.40      // Own identity with default key etc
    3.41      main_me = new_identity(main_addr, fpr_main_me, own_uid, "PrivateKey Import Test");
    3.42      status = set_own_key(session, main_me, fpr_main_me);
    3.43 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
    3.44 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
    3.45  
    3.46      TEST_ASSERT_MSG((strcmp(main_me->fpr, fpr_main_me) == 0), "strcmp(main_me->fpr, fpr_main_me) == 0");
    3.47      cout << "Done!" << endl << endl;
    3.48 @@ -86,8 +73,8 @@
    3.49      cout << "Setting up sender identities and resetting key trust." << endl;
    3.50      cout << "Same address, same user_id - address: " << main_addr << ", user_id: " << own_uid << ", fpr: " << fpr_same_addr_same_uid << endl;  
    3.51      same_addr_same_uid = new_identity(main_addr, fpr_same_addr_same_uid, own_uid, "PrivateKey Import Test");
    3.52 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK || status == PEP_CANNOT_FIND_IDENTITY), "status == PEP_STATUS_OK || status == PEP_CANNOT_FIND_IDENTITY");
    3.53 -    TEST_ASSERT_MSG(((same_addr_same_uid->comm_type & PEP_ct_confirmed) != PEP_ct_confirmed), "(same_addr_same_uid->comm_type & PEP_ct_confirmed) != PEP_ct_confirmed");
    3.54 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK || status == PEP_CANNOT_FIND_IDENTITY), tl_status_string(status));
    3.55 +    TEST_ASSERT_MSG(((same_addr_same_uid->comm_type & PEP_ct_confirmed) != PEP_ct_confirmed), tl_ct_string(same_addr_same_uid->comm_type));
    3.56  
    3.57      status = key_reset_trust(session, same_addr_same_uid);
    3.58      
    3.59 @@ -107,10 +94,10 @@
    3.60      PEP_decrypt_flags_t flags = 0;
    3.61      char* modified_src = NULL;
    3.62      
    3.63 -    cout << "Trusting personal key for " << same_addr_same_uid->user_id << " and " << same_addr_same_uid->fpr << endl;
    3.64 -    status = trust_personal_key(session, same_addr_same_uid);
    3.65 +    cout << "Trusting own key for " << same_addr_same_uid->user_id << " and " << same_addr_same_uid->fpr << endl;
    3.66 +    status = trust_own_key(session, same_addr_same_uid);
    3.67      cout << "Status is " << tl_status_string(status) << endl;  
    3.68 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
    3.69 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
    3.70      free(decrypted_text);
    3.71      decrypted_text = NULL;
    3.72  
    3.73 @@ -135,7 +122,7 @@
    3.74                                    &modified_src);
    3.75      
    3.76      cout << "Status: " << tl_status_string(status) << endl;
    3.77 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
    3.78 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
    3.79  
    3.80      cout << decrypted_text << endl;
    3.81      
     4.1 --- a/test/src/engine_tests/EncryptAttachPrivateKeyTests.cc	Mon Jan 14 18:54:27 2019 +0100
     4.2 +++ b/test/src/engine_tests/EncryptAttachPrivateKeyTests.cc	Wed Jan 16 16:24:40 2019 +0100
     4.3 @@ -161,7 +161,7 @@
     4.4      // Case 2:
     4.5      // Same address, same_user_id, trusted
     4.6      cout << "Case 2: Same address, same user_id, trusted" << endl;
     4.7 -    status = trust_personal_key(session, same_addr_same_uid);
     4.8 +    status = trust_own_key(session, same_addr_same_uid);
     4.9      cout << "Trust personal key for " << same_addr_same_uid << " gives status " << tl_status_string(status) << " (" << status << ")" << endl;
    4.10      TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
    4.11      message* enc_same_addr_same_uid_trusted = NULL;
    4.12 @@ -197,7 +197,7 @@
    4.13      // Case 4:
    4.14      // Different address, same user_id, trusted
    4.15      cout << "Case 4: Different address, same user_id, trusted" << endl;
    4.16 -    status = trust_personal_key(session, diff_addr_same_uid);
    4.17 +    status = trust_own_key(session, diff_addr_same_uid);
    4.18      TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
    4.19      message* enc_diff_addr_same_uid_trusted = NULL;
    4.20      status = encrypt_message_and_add_priv_key(session,