Engine/Media keys

Introduction and rationale

Media keys serve to protect otherwise unencrypted messages sent to recipients for whom no public key is known yet.

The intended use case consists in associating a media key to a domain, or local organisation. Media keys are currently OpenPGP keys, just like the other keys used normally in p≡p, but can be thought of as if they were symmetric.

Media keys are configured manually from the application, and are not shared over the network.

Security considerations

Media keys must be shared out of band. Since possibly many people across a large organisation will use the same secret, many points of failure exist: the protection provided by this facility is weak. Still such weak protection is only used when a message would otherwise be unprotected.

A message protected by a media key has the rating specified by the constant media_key_message_rating, and uses the enc_format specified by the constant media_key_enc_format.

A remark about media keys, keys attached to messages and the management database

A message protected by a media key will not contain the media key as an attachment: the media key is not shared online. An attached sender_key will be the key of the sending identity.

A media key is not included in the Trust table in the management database, nor anywhere else in the management database: a media key is not directly tied to identities and has no trust. (Media key material is stored in the key database.)


A p≡p session contains a media key map. A map is a simple associative data structure associating address patterns to media key FPRs. An address pattern is a p≡p address, with an optional “mailto:” prefix, using the Unix wildcard characters ‘?’ and ‘*’ as recognised by fnmatch(3).

A map may be seen as an ordered list of (address pattern, FPR) pairs.

Any identity whose address matches a media-key pattern is silently assumed to use p≡p, and in particular a p≡p version sufficiently recent to support media keys.

An example

Let the following be a map:

[( "*@abelson.ageinghacker.net", "97B69752A72FC5036971F5C83AC51FA45F01DA6C" );
 ( "*ageinghacker.net", "C90E4DC0A1835B161062852597179D2D8C3D09EA" );
 ( "*@pep.foundation", "40B18D34C2720073674EE04F759EB6DB56E88512" )]


  • the address alice@ageinghacker.net has media key C90E4DC0A1835B161062852597179D2D8C3D09EA;
  • the address bob@ageinghacker.net has the same media key C90E4DC0A1835B161062852597179D2D8C3D09EA;
  • the address jerry@sussman.ageinghacker.net has again the same media key C90E4DC0A1835B161062852597179D2D8C3D09EA;
  • the address charles@younghacker.net has no media key;
  • the address luca@pep.foundation has media key 40B18D34C2720073674EE04F759EB6DB56E88512;
  • the address j.random.hacker@abelson.ageinghacker.net has media key 97B69752A72FC5036971F5C83AC51FA45F01DA6C;
  • the address j.random.hacker@hal.abelson.ageinghacker.net has media key C90E4DC0A1835B161062852597179D2D8C3D09EA.

If the first two pairs of the map were exchanged then no address would have the media key 97B69752A72FC5036971F5C83AC51FA45F01DA6C, since the pattern *ageinghacker.net is more general than the pattern *@abelson.ageinghacker.net.

Engine API

The key material is imported like any other p≡p key, by calling import_key or import_key_with_fpr_return (always pass NULL identities). The private key must be imported as well.

The function below serve to associate each address pattern with a media key (imported separately by import_key or import_key_with_fpr_return (again: always pass NULL identities)).

Apart from this configuration function the use of media keys is transparent: a media key, when present in the configuration, is automatically used for decryption and automatically used in encryption when all recipients are known to support it and no other key is available which is suitable for all the recipients.


 *  <!--       config_media_keys()       -->
 *  @brief Replace the session map with the given map.
 *  @param[in]   session   session
 *  @param[in]   new_map   an list of pairs <pattern, media key FPR>,
 *                         to be searched for in order with the first
 *                         match winning.
 *                         Pairs must not be NULL, and no key or value
 *                         must be NULL; however the entire list is allowed
 *                         to be NULL.
 *                         Address patterns may contain the Unix-style
 *                         wildcards '?' and '*', and an optional "mailto:"
 *                         prefix.
 *  @retval PEP_STATUS_OK         success
 *  @retval PEP_ILLEGAL_VALUE     session NULL, any address pattern or FPR
 *                                NULL, any FPR an empty string.  Notice
 *                                that the entire map is allowed to be NULL
 *                                and so is any pair in the map.
 *  @retval PEP_OUT_OF_MEMORY     memory allocation failed
DYNAMIC_API PEP_STATUS config_media_keys(PEP_SESSION session,
                                         const stringpair_list_t *new_map);

Here is a usage example, with only one media key being used for every address on the domain ageinghacker.net:

    const char *media_key_fpr = /* the FPR of the media key */;
    stringpair_list_t *media_key_map
        = new_stringpair_list(new_stringpair("*@ageinghacker.net",
    status = config_media_keys(session, media_key_map);
    if (status != PEP_STATUS_OK)
        goto error;


/* The rating of a message protected (only) by a media key. */
extern const PEP_rating media_key_message_rating;

The rating of an outgoing message protected by a media key.

Since the protection provided by media keys is weak in practice the rating is the new value PEP_rating_media_key_protected; PEP_rating_media_key_protected is just barely better than PEP_rating_unreliable, and its colour is still no colour.


/* The comm_type for an identity using a media key. */
extern const PEP_comm_type media_key_comm_type;

The comm_type of an identity known to be protected by a media key. This is PEP_ct_unconfirmed_encryption.


/* The enc_format of an outgoing message protected by a media key. */
extern const PEP_enc_format media_key_enc_format;

The enc_format of a message protected by a media key. In practice this is PEP_enc_PEP.

Important warning: never use set_own_key with a media key

Applications and adapters must not call set_own_key with a media key.

Media keys do not enter the management database at all, and should never be confused with an identity’s own keys. Since they are shared media keys are inherently less secure and are only used in a communication when no other alternative to an unencrypted message exists. Using set_own_key would promote a media key to an own key, ultimately causing one’s communication partners to use it in messages intended to be secret.

See also

Media keys are useful in the Echo protocol since they allow a p≡p communication partner to recognise some still-unknown identities as other p≡p-using identities.