|
|
|
@ -973,31 +973,50 @@ static PEP_STATUS _dup_grouped_only(identity_list* idents, identity_list** filte
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static PEP_STATUS _check_own_reset_passphrase_readiness(PEP_SESSION session,
|
|
|
|
|
const char* key) {
|
|
|
|
|
// Before we do anything else, make sure the key to sign the
|
|
|
|
|
// revocation has the right passphrase set
|
|
|
|
|
PEP_STATUS status = probe_encrypt(session, key);
|
|
|
|
|
|
|
|
|
|
// We only care if this has signing-related issues; key could
|
|
|
|
|
// already be revoked and it will be fine below.
|
|
|
|
|
if (PASS_ERROR(status))
|
|
|
|
|
return status;
|
|
|
|
|
|
|
|
|
|
// Because of the above, we CAN support a signing passphrase
|
|
|
|
|
const char* key) {
|
|
|
|
|
|
|
|
|
|
// Check generation setup
|
|
|
|
|
// Because of the above, we can support a signing passphrase
|
|
|
|
|
// that differs from the generation passphrase. We'll
|
|
|
|
|
// just check to make sure everything is in order for
|
|
|
|
|
// later use, however
|
|
|
|
|
|
|
|
|
|
if (session->new_key_pass_enable) {
|
|
|
|
|
if (EMPTYSTR(session->generation_passphrase))
|
|
|
|
|
return PEP_PASSPHRASE_FOR_NEW_KEYS_REQUIRED;
|
|
|
|
|
|
|
|
|
|
if (EMPTYSTR(session->curr_passphrase)) {
|
|
|
|
|
// We'll need it as the current passphrase to sign
|
|
|
|
|
// messages with the generated keys
|
|
|
|
|
session->curr_passphrase = strdup(session->generation_passphrase);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stringlist_t* test_key = NULL;
|
|
|
|
|
|
|
|
|
|
// Be sure we HAVE this key
|
|
|
|
|
PEP_STATUS status = find_keys(session, key, &test_key);
|
|
|
|
|
bool exists_key = test_key != NULL;
|
|
|
|
|
free_stringlist(test_key);
|
|
|
|
|
|
|
|
|
|
if (!exists_key || status == PEP_KEY_NOT_FOUND) {
|
|
|
|
|
remove_fpr_as_default(session, key);
|
|
|
|
|
return PEP_KEY_NOT_FOUND;
|
|
|
|
|
}
|
|
|
|
|
if (status != PEP_STATUS_OK)
|
|
|
|
|
return status;
|
|
|
|
|
|
|
|
|
|
ensure_passphrase_t ensure_key_cb = session->ensure_passphrase;
|
|
|
|
|
|
|
|
|
|
// Check to see that this key has its passphrase set as the configured
|
|
|
|
|
// passphrase, IF it has one. If not, bail early.
|
|
|
|
|
status = probe_encrypt(session, key);
|
|
|
|
|
if (PASS_ERROR(status)) {
|
|
|
|
|
if (ensure_key_cb)
|
|
|
|
|
status = ensure_key_cb(session, key);
|
|
|
|
|
}
|
|
|
|
|
if (status != PEP_STATUS_OK)
|
|
|
|
|
return status;
|
|
|
|
|
|
|
|
|
|
if (EMPTYSTR(session->curr_passphrase) && !EMPTYSTR(session->generation_passphrase)) {
|
|
|
|
|
// We'll need it as the current passphrase to sign
|
|
|
|
|
// messages with the generated keys
|
|
|
|
|
session->curr_passphrase = strdup(session->generation_passphrase);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return PEP_STATUS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1024,27 +1043,21 @@ static PEP_STATUS _key_reset_device_group_for_shared_key(PEP_SESSION session,
|
|
|
|
|
|
|
|
|
|
if (!session || !key_idents || EMPTYSTR(old_key))
|
|
|
|
|
return PEP_ILLEGAL_VALUE;
|
|
|
|
|
|
|
|
|
|
message* enc_msg = NULL;
|
|
|
|
|
message* outmsg = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
messageToSend_t send_cb = session->messageToSend;
|
|
|
|
|
|
|
|
|
|
if (!send_cb)
|
|
|
|
|
return PEP_SYNC_NO_MESSAGE_SEND_CALLBACK;
|
|
|
|
|
|
|
|
|
|
PEP_STATUS status = PEP_STATUS_OK;
|
|
|
|
|
|
|
|
|
|
message* enc_msg = NULL;
|
|
|
|
|
message* outmsg = NULL;
|
|
|
|
|
stringlist_t* test_key = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// N.B. The mechanism here is that we make the caller, if
|
|
|
|
|
// necessary, keep trying until they give us the
|
|
|
|
|
// right password for the key we're going to reset/revoke.
|
|
|
|
|
// The revocation does not happen until later, but basically,
|
|
|
|
|
// if the key is unrevoked and still requires a correct
|
|
|
|
|
// password, we need to stop this before we get there.
|
|
|
|
|
//
|
|
|
|
|
// This allows us to switch the correct passphrase in
|
|
|
|
|
// and out if there are different generation and old
|
|
|
|
|
// key signing passwords. (Not a concern if already revoked)
|
|
|
|
|
|
|
|
|
|
// Make sure the signing password is set correctly and that
|
|
|
|
|
// we are also ready for keygen
|
|
|
|
|
status = _check_own_reset_passphrase_readiness(session, old_key);
|
|
|
|
|
if (status != PEP_STATUS_OK)
|
|
|
|
|
return status;
|
|
|
|
@ -1127,12 +1140,12 @@ static PEP_STATUS _key_reset_device_group_for_shared_key(PEP_SESSION session,
|
|
|
|
|
status = revoke_key(session, old_key, NULL);
|
|
|
|
|
|
|
|
|
|
// again, we should not have key-related issues here,
|
|
|
|
|
// as we tested for the correct password earlier
|
|
|
|
|
// as we ensured the correct password earlier
|
|
|
|
|
if (status != PEP_STATUS_OK)
|
|
|
|
|
return status;
|
|
|
|
|
|
|
|
|
|
// Ok, NOW - the current password needs to be swapped out
|
|
|
|
|
// because we're going to sign with keys using.
|
|
|
|
|
// because we're going to sign with keys using it.
|
|
|
|
|
//
|
|
|
|
|
// All new keys have the same passphrase, if any
|
|
|
|
|
//
|
|
|
|
@ -1207,9 +1220,9 @@ static PEP_STATUS _key_reset_device_group_for_shared_key(PEP_SESSION session,
|
|
|
|
|
return status;
|
|
|
|
|
|
|
|
|
|
pEp_error:
|
|
|
|
|
|
|
|
|
|
// Just in case
|
|
|
|
|
session->curr_passphrase = cached_passphrase;
|
|
|
|
|
free_stringlist(test_key);
|
|
|
|
|
free_message(outmsg);
|
|
|
|
|
free_message(enc_msg);
|
|
|
|
|
return status;
|
|
|
|
@ -1228,8 +1241,6 @@ static PEP_STATUS probe_signing_for_keylist(PEP_SESSION session,
|
|
|
|
|
return PEP_STATUS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This is simply NOT SAFE for multiple passwords on the extant
|
|
|
|
|
// keys. Cannot be called with multiple passwords for that purpose.
|
|
|
|
|
DYNAMIC_API PEP_STATUS key_reset_own_grouped_keys(PEP_SESSION session) {
|
|
|
|
|
assert(session);
|
|
|
|
|
|
|
|
|
@ -1247,12 +1258,7 @@ DYNAMIC_API PEP_STATUS key_reset_own_grouped_keys(PEP_SESSION session) {
|
|
|
|
|
status = get_all_keys_for_user(session, user_id, &keys);
|
|
|
|
|
|
|
|
|
|
// TODO: free
|
|
|
|
|
if (status == PEP_STATUS_OK) {
|
|
|
|
|
status = probe_signing_for_keylist(session, keys);
|
|
|
|
|
|
|
|
|
|
if (PASS_ERROR(status))
|
|
|
|
|
goto pEp_free;
|
|
|
|
|
|
|
|
|
|
if (status == PEP_STATUS_OK) {
|
|
|
|
|
stringlist_t* curr_key;
|
|
|
|
|
|
|
|
|
|
for (curr_key = keys; curr_key && curr_key->value; curr_key = curr_key->next) {
|
|
|
|
@ -1269,13 +1275,16 @@ DYNAMIC_API PEP_STATUS key_reset_own_grouped_keys(PEP_SESSION session) {
|
|
|
|
|
else
|
|
|
|
|
goto pEp_free;
|
|
|
|
|
|
|
|
|
|
// Because of the key check above, this should not happen unless we were
|
|
|
|
|
// UNLESS we required a passphrase for keygen and it's not set.
|
|
|
|
|
if (PASS_ERROR(status))
|
|
|
|
|
goto pEp_free;
|
|
|
|
|
|
|
|
|
|
// FIXME: what about other statuses, though???
|
|
|
|
|
|
|
|
|
|
// This is in a switch because our return statuses COULD get more
|
|
|
|
|
// complicated
|
|
|
|
|
switch (status) {
|
|
|
|
|
case PEP_STATUS_OK:
|
|
|
|
|
case PEP_KEY_NOT_FOUND: // call removed it as a default
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
goto pEp_free;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free_identity_list(key_idents);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1413,15 +1422,7 @@ PEP_STATUS key_reset(
|
|
|
|
|
// case of own identities with private keys.
|
|
|
|
|
|
|
|
|
|
if (is_own_private) {
|
|
|
|
|
|
|
|
|
|
// Make sure we can even progress - if there are passphrase issues,
|
|
|
|
|
// bounce back to the caller now.
|
|
|
|
|
status = _check_own_reset_passphrase_readiness(session, fpr_copy);
|
|
|
|
|
|
|
|
|
|
// These will always be passphrase errors.
|
|
|
|
|
if (status != PEP_STATUS_OK)
|
|
|
|
|
return status;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This is now the "is_own" base case - we don't do this
|
|
|
|
|
// per-identity, because all identities using this key will
|
|
|
|
|
// need new ones. That said, this is really only a problem
|
|
|
|
@ -1443,6 +1444,14 @@ PEP_STATUS key_reset(
|
|
|
|
|
if (is_grouped)
|
|
|
|
|
status = _key_reset_device_group_for_shared_key(session, key_idents, fpr_copy, false);
|
|
|
|
|
else if (status == PEP_STATUS_OK) {
|
|
|
|
|
// KB: FIXME_NOW - revoked?
|
|
|
|
|
// Make sure we can even progress - if there are passphrase issues,
|
|
|
|
|
// bounce back to the caller now, because our attempts to make it work failed,
|
|
|
|
|
// even possibly with callback.
|
|
|
|
|
status = _check_own_reset_passphrase_readiness(session, fpr_copy);
|
|
|
|
|
if (status != PEP_STATUS_OK)
|
|
|
|
|
return status;
|
|
|
|
|
|
|
|
|
|
// now have ident list, or should
|
|
|
|
|
identity_list* curr_ident;
|
|
|
|
|
|
|
|
|
@ -1453,7 +1462,7 @@ PEP_STATUS key_reset(
|
|
|
|
|
// Do the full reset on this identity
|
|
|
|
|
// Base case for is_own_private starts here
|
|
|
|
|
// Note that we reset this key for ANY own ident that has it. And if
|
|
|
|
|
// tmp_ident did NOT have this key, it won't matter. We will reset the
|
|
|
|
|
// tmp_ident did NOT have this key, it won't matter. We will reset this
|
|
|
|
|
// key for all idents for this user.
|
|
|
|
|
status = revoke_key(session, fpr_copy, NULL);
|
|
|
|
|
|
|
|
|
|