Key Reset1

Key reset encompasses a core piece of p≡p’s key management functionality. However, it also does several things that developers using the engine might not expect if they only understand one of its functions.

This document aims to explain the protocol as well as the functionality of side effects from various usage points of view.

What is key reset intended to do?

Key reset does many things, depending on the situation and the nature of the identity or user it is invoked for. In general, it is intended to reset trust information for a particular key, remove a key as the default for a user or identity, and, sometimes, inform partners (or other own devices) of these changes.

However, this quickly becomes confusing. The phrase “key reset” also refers to different pieces of functionality from within the same module, which can be confusing if the context is not clear from the conversation.

These pieces of functionality include the following:

  1. Revocation and replacement generation of a new own key
  2. Resetting the trust/mistrust status of a partner’s key and removing it as the default key for that user and identity
  3. The generation/processing/receipt of messages which communicate information to effect the above in 1. and 2.

When discussing key reset with a member of another team, please be sure to explain the context you intend before getting too far into the weeds of confusion.

The Protocol

The key reset protocol varies based upon whether we are talking about key reset of partner keys, or of own keys.

Partner keys

When we talk about doing a key reset of a partner key, we mean the following things:

  1. Resetting any trust information (comm_type) we have for this key. This means the following:
    • The “trust” bit - usually based on correct trustword exchange - that may be set on cryptographically valid keys is removed (so PEP_ct_OpenPGP might now become PEP_ct_OpenPGP_unconfirmed). 2
    • If the key is mistrusted in the database – as long as the key is not revoked – this mistrust information is removed, and the trust rating is reset to whatever the base key rating is, as above (e.g. without any trust bit set).
  2. Removing the key as a default for either a particular identity or both a user and all of that user’s identities which have this key as a default. 3
  3. Up through at least the 2.0 series of releases, we also mean deleting the user’s key from the keyring. With the removal of key election (intended for releases 2.1 or 2.2), this will no longer need to be the case. If we are sent another copy of this same public key, it will be reimported without issue, but also without the prior trust information. This is intended behaviour.

A partner-key key reset may be initiated either automatically (via a key reset email from the respective partner) or manually (for example, in an application, there may be an opportunity for the user to reset a partner key, due to, for example, accidental mistrust or a communication from the partner on another channel asking that the user stop using the current default key).

Own keys

When we talk about reset of our own keys, we are no longer talking about simply removing a key or resetting its trust. When we reset an own key, we want the following things to happen:

  1. We want to revoke the key (this is a crypto-engine action affecting the keyring)
  2. We want to generate a new key for each identity impacted by a particular key’s revocation and link it in the database as the replacement for the old key for that identity (see multiple own identities for information on how a single key’s revocation can impact more than one identity)
  3. We want to mistrust the key (this is an engine database action affecting the trust store)
  4. We want to communicate to recent partners4 with whom this specific identity has communicated that our key has been reset, and that we would like them to use the new key, along with the new key and the old key’s revocation. See Sending key reset messages to partners for information on what these messages look like, and Receiving a partner key reset message for information on how the receiving side will process them.

Resetting an own key shared by multiple own identities

Currently, the only way multiple identities share a single key is if this has been set from the outside (for example, by manual key import). While p≡p could just replace the key and then use the replacement as the global replacement for all of those identities, by design, we do not. If a single key shared by multiple own identities is revoked/reset, a new key will be generated individually for each affected identity. This is why it is important for us to know from which identity we were communicating for a given communications partner with when we send out the key reset messages.5

If Bob is initially sharing key K1 between multiple identities associated with bob@pep.foundation, fdik@pep.security, and jedifan191@posteo.de and calls key reset on that key, he will revoke and mistrust K1 and remove it globally as an own default, and then generate Kbob for bob@pep.foundation, Kvolker for fdik@pep.security, and Ktraitortotheempire for jedifan191@posteo.de. When he looks at the lists of people he has recently contacted, he must be certain to know which of his own identities has contacted which address in order to send the right key from the right identity to the right person.

Automated key reset: key reset messages

Key reset message send

At this point, we only ever send out key reset messages for our own keys. And, important, except in the case of device group key reset messages, we only send them to non-own identities.

For non-own communications partners, we send out key reset messages triggered by two events

Sending key reset messages to partners

Key reset messages are, as of release 2.0, special administrative messages which inform a p≡p partner6 that a particular key from a specific identity has been revoked and should be, on the recipient end, mistrusted and replaced as the default by the new key specified by and included with the message.

A key reset message contains the following information:

  1. The address the key is to be reset for
  2. The old key, containing its revocation certificate. This will be automatically imported on decryption by the partner, and, importantly, is only produceable by someone having the original private key7
  3. The new public key for this identity

The whole message is signed by the new key.

Obviously, it would be even better if the message were signed by the old key, but given that that key has been revoked, this is not possible (and is even less possible in the other cases we send such a message (see next section)). Given that we are also effectively claiming the old key may be compromised, this is also not necessarily any more meaningful than sending the revocation certificate8.

Sending a key reset message to recent partners

Right after doing a key reset on an own key, as mentioned above, for each own identity associated with this own key, we:

  1. look at the list of recent p≡p communications partners (simply by checking the timestamps of identity updates in the identity table)
  2. for each recent partner, check to see if we have contacted9 that partner from this identity
  3. for each partner meeting these criteria, send a key reset message as above.

This obviously means we don’t contact everyone who has ever used this key for this identity; this is just an opportunistic action. Additional key resets are performed when we receive a message to the reset key at a later point in time, as described in the next section.

Sending a key reset message on decryption from a revoked key

The other time we send a key reset message based on the reset of our own key is when we receive a p≡p email encrypted using an own revoked public key. We can obviously still decrypt the message, as we don’t discard revoked private keys, we just don’t use them anymore.

As this can come at some time distance from when we initially reset the key, this provides further reason for why we don’t/cannot sign key reset messages with the original (now revoked) private key, as this key no longer provides any meaningful guarantees and its lack of legitimacy has been announced to partners.

The only difference between the messages in Sending a key reset message to recent partners is the trigger for sending the message.

Receiving a partner key reset message

When we receive a key reset message from a partner, this will be an encrypted message that is not signed by the old partner key (see Caveats for discussion). However, it will contain an object signed by that key - namely, the key revocation (which is a certificate attached to the revoked public key and can only be generated by having the private key for this key).

When receiving a key reset message from a partner key, we:

  1. Check that is was in fact for a non-own key
  2. Check the validity of the key used to sign the message (which should have been attached to the key reset message, since it will be the replacement key)
  3. Check to see that the old key even has an entry in our database (i.e. ask if we have something to reset)
  4. Check to see that the old key has been revoked - this will only be the case if we have at some point imported a revocation certificate for this key (which is conveniently attached to the key reset message)
  5. Ensure that we have the new key
  6. Ensure that the new key has not been revoked
  7. Mistrust the old key for this user
  8. Remove the old key as the default for this identity, and, if applicable, the user
  9. Replace the new key as the default for this user
  10. If the old key was the user default, replace the user default with the new key
  11. Get the new key’s base rating (see get_key_rating - it is a rating based solely on the validity and properties of the key material)
  12. If the identity corresponds to a pEp user and the key is strong enough, add pEp user information to the key rating
  13. Ensure the resultant trust status is untrusted.
    This last step is vital, as even if trustwords were exchanged for the old key, they have not been exchanged for the new one, and this reset was transmitted on a yellow channel. We do not want someone during a replay attack to be able to replace a trusted key with their own trusted key.

Special for sync: own key reset message generate/receive

To be filled in sometime in the morning. I’m tired.


The main caveat for now deals with the receipt of partner key reset messages.

If we receive a key reset message from a non-own user, for now, we presume such key reset by email for non-own keys is ONLY in case of revoke-and-replace. This means we have, at a minimum, an object that once required the initial private key in order to replace that key with another.

However, the limitations on what this guarantees are known - this does not prevent, for example, replay attacks from someone with access to the original revocation cert. These are possible if a malicious person having this cert manages to get to Alice’s communications partners with a forged message containing this to-be-replayed cert which came originally from Alice and a new key at some point before Alice herself is able to send out the revocation object to us herself.

The best we can do in this case is to NOT trust the new key. Yes, it will be used by default, but if the original was trusted, the rating will visibly change for the sender, and even if it was not, if we do use it, the sender can report unreadable mails to us and detect it that way, hopefully limiting the harm done. In any event, this is always the difficulty with distributing revocations, whether using p≡p or not, and we do in fact have a solution for this.

That is, users need to check trustwords. If they haven’t checked trustwords, there is no trust. We may be able to further encourage such checks by having some kind of event to alert to the user when such a change occurs for their contacts beyond the changing of colour.

  1. This document is a draft written from memory for the purposes of discussion. It will probably need to be cleaned up and clarified in the future.↩︎

  2. Note - it’s important to remember here that trust is between a user and a key, not an identity (an address plus a user); thus, if key_reset is called on a specific identity for a user, if other identities for that user share that key, the key reset will change the trust value for all identities using it.↩︎

  3. Identities have a default key associated with them; however, users also have a default key. Thus, if, for example, Alice, with identities for her userid 123ABC at alice@pep.foundation and alice@pep.security, has two different default keys for these identities, K1 and K2 respectively. However, the userid 123ABC might have as its default key K1, K2, or even an unrelated K3. (The user default is currently used for situations where there is no identity default key.)↩︎

  4. “Recent” currently means partners from the last week or two; however, top-level applications should never need to be aware of this communication nor do they know or set the time interval. This is engine internal other than providing access to the send-message queue.↩︎

  5. It is possible that we were communicating from multiple own identities using the old to this communications partner. In this case, we send out multiple key reset messages with the respective new key per identity.↩︎

  6. Or in special cases other devices in a group - this is part of the sync protocol and is not discussed in detail here.↩︎

  7. See Caveats for limitations on what this guarantees for us↩︎

  8. See Caveats for limitations on what this guarantees for us↩︎

  9. by calling encrypt_message on a message with this partner as a recipient↩︎