Browse Source

ENGINE-507: trust_own_key now in; read documentation

doc_update_sequoia
parent
commit
4b7e2505bc
4 changed files with 98 additions and 37 deletions
  1. +59
    -12
      src/keymanagement.c
  2. +27
    -0
      src/keymanagement.h
  3. +10
    -23
      test/src/engine_tests/DecryptAttachPrivateKeyTrustedTests.cc
  4. +2
    -2
      test/src/engine_tests/EncryptAttachPrivateKeyTests.cc

+ 59
- 12
src/keymanagement.c View File

@ -103,9 +103,14 @@ PEP_STATUS elect_pubkey(
return PEP_STATUS_OK;
}
// own_must_contain_private is usually true when calling;
// we only set it to false when we have the idea of
// possibly having an own pubkey that we need to check on its own
static PEP_STATUS validate_fpr(PEP_SESSION session,
pEp_identity* ident,
bool check_blacklist) {
bool check_blacklist,
bool own_must_contain_private) {
PEP_STATUS status = PEP_STATUS_OK;
@ -115,12 +120,14 @@ static PEP_STATUS validate_fpr(PEP_SESSION session,
char* fpr = ident->fpr;
bool has_private = false;
status = contains_priv_key(session, fpr, &has_private);
if (ident->me) {
status = contains_priv_key(session, fpr, &has_private);
if (ident->me && own_must_contain_private) {
if (status != PEP_STATUS_OK || !has_private)
return PEP_KEY_UNSUITABLE;
}
else if (status != PEP_STATUS_OK && has_private) // should never happen
has_private = false;
status = get_trust(session, ident);
if (status != PEP_STATUS_OK)
@ -196,7 +203,9 @@ static PEP_STATUS validate_fpr(PEP_SESSION session,
}
}
if (ident->me && (ct >= PEP_ct_strong_but_unconfirmed) && !revoked && expired) {
if (ident->me && has_private &&
(ct >= PEP_ct_strong_but_unconfirmed) &&
!revoked && expired) {
// extend key
timestamp *ts = new_timestamp(time(NULL) + KEY_EXPIRE_DELTA);
status = renew_key(session, fpr, ts);
@ -315,7 +324,7 @@ PEP_STATUS get_valid_pubkey(PEP_SESSION session,
// Input: stored identity retrieved from database
// if stored identity contains a default key
if (!EMPTYSTR(stored_fpr)) {
status = validate_fpr(session, stored_identity, check_blacklist);
status = validate_fpr(session, stored_identity, check_blacklist, true);
if (status == PEP_STATUS_OK && !EMPTYSTR(stored_identity->fpr)) {
*is_identity_default = *is_address_default = true;
return status;
@ -335,7 +344,7 @@ PEP_STATUS get_valid_pubkey(PEP_SESSION session,
if (!EMPTYSTR(user_fpr)) {
// There exists a default key for user, so validate
stored_identity->fpr = user_fpr;
status = validate_fpr(session, stored_identity, check_blacklist);
status = validate_fpr(session, stored_identity, check_blacklist, true);
if (status == PEP_STATUS_OK && stored_identity->fpr) {
*is_user_default = true;
*is_address_default = key_matches_address(session,
@ -352,7 +361,7 @@ PEP_STATUS get_valid_pubkey(PEP_SESSION session,
status = elect_pubkey(session, stored_identity, check_blacklist);
if (status == PEP_STATUS_OK) {
if (!EMPTYSTR(stored_identity->fpr))
validate_fpr(session, stored_identity, false); // blacklist already filtered of needed
validate_fpr(session, stored_identity, false, true); // blacklist already filtered of needed
}
else if (status != PEP_KEY_NOT_FOUND && first_reject_status != PEP_KEY_NOT_FOUND) {
first_reject_status = status;
@ -1036,7 +1045,7 @@ PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen,
// check stored identity
if (stored_identity && !EMPTYSTR(stored_identity->fpr)) {
// Fall back / retrieve
status = validate_fpr(session, stored_identity, false);
status = validate_fpr(session, stored_identity, false, true);
if (status == PEP_OUT_OF_MEMORY)
goto pep_free;
if (status == PEP_STATUS_OK) {
@ -1445,8 +1454,7 @@ DYNAMIC_API PEP_STATUS trust_personal_key(
// Set up a temp trusted identity for the input fpr without a comm type;
tmp_id = new_identity(ident->address, ident->fpr, ident->user_id, NULL);
// ->me isn't set, even if this is an own identity, so this will work.
status = validate_fpr(session, tmp_id, false);
status = validate_fpr(session, tmp_id, false, true);
if (status == PEP_STATUS_OK) {
// Validate fpr gets trust DB or, when that fails, key comm type. we checked
@ -1506,7 +1514,7 @@ DYNAMIC_API PEP_STATUS trust_personal_key(
if (!tmp_user_ident)
status = PEP_OUT_OF_MEMORY;
else {
status = validate_fpr(session, tmp_user_ident, false);
status = validate_fpr(session, tmp_user_ident, false, true);
if (status != PEP_STATUS_OK ||
tmp_user_ident->comm_type < PEP_ct_strong_but_unconfirmed ||
@ -1530,6 +1538,45 @@ pep_free:
return status;
}
DYNAMIC_API PEP_STATUS trust_own_key(
PEP_SESSION session,
pEp_identity* ident
)
{
assert(session);
assert(ident);
assert(!EMPTYSTR(ident->address));
assert(!EMPTYSTR(ident->user_id));
assert(!EMPTYSTR(ident->fpr));
if (!ident || EMPTYSTR(ident->address) || EMPTYSTR(ident->user_id) ||
EMPTYSTR(ident->fpr))
return PEP_ILLEGAL_VALUE;
if (!is_me(session, ident))
return PEP_ILLEGAL_VALUE;
// don't check blacklist or require a private key
PEP_STATUS status = validate_fpr(session, ident, false, false);
if (status != PEP_STATUS_OK)
return status;
status = set_pgp_keypair(session, ident->fpr);
if (status != PEP_STATUS_OK)
return status;
if (ident->comm_type < PEP_ct_strong_but_unconfirmed)
return PEP_KEY_UNSUITABLE;
ident->comm_type |= PEP_ct_confirmed;
status = set_trust(session, ident);
return status;
}
DYNAMIC_API PEP_STATUS own_key_is_listed(
PEP_SESSION session,
const char *fpr,
@ -1779,7 +1826,7 @@ DYNAMIC_API PEP_STATUS set_own_key(
if (!me->fpr)
return PEP_OUT_OF_MEMORY;
status = validate_fpr(session, me, false);
status = validate_fpr(session, me, false, true);
if (status)
return status;


+ 27
- 0
src/keymanagement.h View File

@ -245,6 +245,33 @@ DYNAMIC_API PEP_STATUS trust_personal_key(
pEp_identity *ident
);
// trust_own_key() - mark a key as trusted for self, generally
// used when we need to trust a public key
// associated with outselves for issues like
// manual key import
// parameters:
// session (in) session to use
// ident (in) own ident containing fpr to trust
//
// caveat:
// if this is a public key only, keep in mind that if
// the private part of the keypair is later added,
// it will not undergo separate trust evaluation. This
// is fine - even desired - as long as the semantics
// of this function are understood as both trusting
// the key and verifying it as an own key. This will
// NEVER cause replacement of or setting of a default
// *alone*. However, if a private key is ever associated
// with this fpr, please keep in mind that trusting it
// here makes it an eligible key for selection for
// encryption later. So use this function on purpose with
// an understanding of what you're doing!
//
DYNAMIC_API PEP_STATUS trust_own_key(
PEP_SESSION session,
pEp_identity *ident
);
// key_reset_trust() - reset trust bit or explicitly mistrusted status for an identity and
// its accompanying key/user_id pair.


+ 10
- 23
test/src/engine_tests/DecryptAttachPrivateKeyTrustedTests.cc View File

@ -45,40 +45,27 @@ void DecryptAttachPrivateKeyTrustedTests::check_decrypt_attach_private_key_trust
// 13A9F97964A2B52520CAA40E51BCA783C065A213
input_key = slurp("test_keys/pub/priv-key-import-test-main_0-0xC065A213_pub.asc");
status = import_key(session, input_key.c_str(), input_key.length(), NULL);
TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
input_key = slurp("test_keys/priv/priv-key-import-test-main_0-0xC065A213_priv.asc");
status = import_key(session, input_key.c_str(), input_key.length(), NULL);
TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
// ensure there's no private key - doesn't work in automated tests, sadly. Uncommon when running script manually.
bool has_priv = false;
// status = contains_priv_key(session, fpr_same_addr_same_uid, &has_priv);
// if (status == PEP_STATUS_OK && has_priv) {
// cout << "SORRY, have to delete keys here to run test correctly..." << endl;
// status = delete_keypair(session, fpr_same_addr_same_uid);
// if (status == PEP_STATUS_OK) {
// has_priv = false;
// status = contains_priv_key(session, fpr_same_addr_same_uid, &has_priv);
// TEST_ASSERT_MSG((has_priv == false), "has_priv == false");
// cout << "Successfully deleted keypair for " << fpr_same_addr_same_uid << " - will now import the public key only" << endl;
// }
// else
// cout << "Warning - delete keypair returned status " << tl_status_string(status) << ". This may or may not be an error, depending on what you expect." << endl;
// }
// key with same address and user_id
// 8AB616A3BD51DEF714B5E688EFFB540C3276D2E5
input_key = slurp("test_keys/pub/priv-key-import-test-main_0-0x3276D2E5_pub.asc");
status = import_key(session, input_key.c_str(), input_key.length(), NULL);
TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
cout << "Setting up own identity with default key " << fpr_main_me << endl;
// Own identity with default key etc
main_me = new_identity(main_addr, fpr_main_me, own_uid, "PrivateKey Import Test");
status = set_own_key(session, main_me, fpr_main_me);
TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
TEST_ASSERT_MSG((strcmp(main_me->fpr, fpr_main_me) == 0), "strcmp(main_me->fpr, fpr_main_me) == 0");
cout << "Done!" << endl << endl;
@ -86,8 +73,8 @@ void DecryptAttachPrivateKeyTrustedTests::check_decrypt_attach_private_key_trust
cout << "Setting up sender identities and resetting key trust." << endl;
cout << "Same address, same user_id - address: " << main_addr << ", user_id: " << own_uid << ", fpr: " << fpr_same_addr_same_uid << endl;
same_addr_same_uid = new_identity(main_addr, fpr_same_addr_same_uid, own_uid, "PrivateKey Import Test");
TEST_ASSERT_MSG((status == PEP_STATUS_OK || status == PEP_CANNOT_FIND_IDENTITY), "status == PEP_STATUS_OK || status == PEP_CANNOT_FIND_IDENTITY");
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");
TEST_ASSERT_MSG((status == PEP_STATUS_OK || status == PEP_CANNOT_FIND_IDENTITY), tl_status_string(status));
TEST_ASSERT_MSG(((same_addr_same_uid->comm_type & PEP_ct_confirmed) != PEP_ct_confirmed), tl_ct_string(same_addr_same_uid->comm_type));
status = key_reset_trust(session, same_addr_same_uid);
@ -107,10 +94,10 @@ void DecryptAttachPrivateKeyTrustedTests::check_decrypt_attach_private_key_trust
PEP_decrypt_flags_t flags = 0;
char* modified_src = NULL;
cout << "Trusting personal key for " << same_addr_same_uid->user_id << " and " << same_addr_same_uid->fpr << endl;
status = trust_personal_key(session, same_addr_same_uid);
cout << "Trusting own key for " << same_addr_same_uid->user_id << " and " << same_addr_same_uid->fpr << endl;
status = trust_own_key(session, same_addr_same_uid);
cout << "Status is " << tl_status_string(status) << endl;
TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
free(decrypted_text);
decrypted_text = NULL;
@ -135,7 +122,7 @@ void DecryptAttachPrivateKeyTrustedTests::check_decrypt_attach_private_key_trust
&modified_src);
cout << "Status: " << tl_status_string(status) << endl;
TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
cout << decrypted_text << endl;


+ 2
- 2
test/src/engine_tests/EncryptAttachPrivateKeyTests.cc View File

@ -161,7 +161,7 @@ void EncryptAttachPrivateKeyTests::check_encrypt_attach_private_key() {
// Case 2:
// Same address, same_user_id, trusted
cout << "Case 2: Same address, same user_id, trusted" << endl;
status = trust_personal_key(session, same_addr_same_uid);
status = trust_own_key(session, same_addr_same_uid);
cout << "Trust personal key for " << same_addr_same_uid << " gives status " << tl_status_string(status) << " (" << status << ")" << endl;
TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
message* enc_same_addr_same_uid_trusted = NULL;
@ -197,7 +197,7 @@ void EncryptAttachPrivateKeyTests::check_encrypt_attach_private_key() {
// Case 4:
// Different address, same user_id, trusted
cout << "Case 4: Different address, same user_id, trusted" << endl;
status = trust_personal_key(session, diff_addr_same_uid);
status = trust_own_key(session, diff_addr_same_uid);
TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
message* enc_diff_addr_same_uid_trusted = NULL;
status = encrypt_message_and_add_priv_key(session,


Loading…
Cancel
Save