Engine/ElevatedAttachments

Elevated Attachments

Concept

p≡p protocol messages are transported as attachments to the very messages, which p≡p is protecting, therefore tunneling through the same channel than they payload it protects. But there are Message Transports, which cannot transport attachments. Therefore, with such Message Transports there is a need for transporting p≡p protocol messages inline. Because p≡p protocol messages then are elevated from being transported as attachment to being transported inline this is called Elevated Attachments.

p≡p protocols are based on of four types of messages:

Key material

Depending on Crypto tech p≡p is using different types of Key material. In common setups p≡p is using OpenPGP compliant Keys.

The MIME type for Key material is the MIME type of the standard, which is defining the Key format, or “application/keys” if there is no other definition. I.e. for OpenPGP compliant keys it is “application/pgp-keys”.

p≡p Sync

Sync messages are defined in ASN.1. In common setups Sync messages are PER encoded. Sync messages are defined for communication in Device groups of one single User.

The MIME type for p≡p Sync messages is “application/pEp.sync”.

p≡p Distribution

Distribution messages are defined in ASN.1. In common setups Distribution messages are PER encoded. Distribution messages are defined for communication between the Own User and Communication Partners.

The MIME type for p≡p Distribution messages is “application/pEp.distribution”. When reading a MIME type of “application/pEp.keyreset” will be accepted as an alternative for compatibility reasons.

Authentication material

Authentication material is delivering the possibility to check if a message is authenticated by its Sender or by other Users. In common setups the used Authentication material is OpenPGP compliant Digital Signatures.

The MIME type for Authentication material is the MIME type of the standard, which is defining the Authentication format, or “application/auth” if there is no other definition. I.e. for OpenPGP compliant signatures it is “application/pgp-signature”.

Unencrypted and Encrypted transport

To transport p≡p protocol messages inline there must be definitions how to transport such data unencrypted and how to transport it encrypted. How p≡p protocol messages are being transported unencrypted is part of the p≡p Message Format definition of the transport, respectively. But in case of encrypted inline transport there is a problem for the receiver in case of Elevated Attachments: how can the receiver decide if the transported data was an Elevated Attachment or if it was the legitimate content of a transported payload without basing on unencrypted meta data in the format? Because of security and privacy reasons encrypted p≡p messages are not relying on any unencrypted or unauthenticated data.

For solving this problem p≡p is defining an Internal Message Format for p≡p protocol messages, which can be used to determine between Payload and each p≡p protocol message type.

struct _message and Elevated Attachments

p≡p is defined for text messages only. In case of transports with binary messages p≡p is requiring a text representation of the messages to protect. In struct _message p≡p is supporting the fields .shortmsg, .longmsg and .longmsg_formatted to transport different representations of a text message. Attachments are described in .attachments.

To elevate an attachment with a p≡p protocol message its .value will be encoded in a textual format and being sent in .longmsg. Meta data like .filename or .disposition will not be transported. For unencrypted transport the p≡p message format is defining how to encode the four different values for .mime_type. For encrypted transport the p≡p message format will define how to encode an encrypted message. The definition is valid for all types of encrypted messages no matter what they’re transporting. Hence an Internal Message Format is required, which can be used to determine which type of data was encrypted and transported, either payload or an Elevated Attachment.

Because .longmsg is defined as UTF-8 string no valid text is beginning with a leading 0 byte. Hence the Internal Message Format is always using a leading 0 byte for all four message types followed by a byte with an ASCII character to select the message type, followed by a byte for subtype number, followed by a byte (reserved, must be 0).

Internal Message Format

Key material

Key material is encoded with 0 ‘K’ subtype 0 followed by the binary representation of the .value of the attachment for transports.

p≡p Sync

A p≡p Sync message is encoded with 0 ‘S’ subtype 0 followed by the binary representation of the .value of the attachment.

p≡p Distribution

A p≡p Distribution message is encoded with 0 ‘D’ subtype 0 followed by the binary representation of the .value of the attachment.

Authentication material

Key material is encoded with 0 ‘A’ subtype 0 followed by the binary representation of the .value of the attachment.

Supported subtypes and MIME types

static struct _internal_message_type {
    char type;
    char subtype;
    const char *mime_type;
} message_type[] = {
    // Keys
    { 'K',  0, "application/keys" },

    // OpenPGP
    { 'K',  2, "application/pgp-keys" },

    // x.509
    { 'K',  3, "application/pkcs10" },
    { 'K',  4, "application/pkix-cert" },
    { 'K',  5, "application/pkix-crl" },
    { 'K',  6, "application/pkcs7-mime" },
    { 'K',  7, "application/x-x509-ca-cert" },
    { 'K',  8, "application/x-x509-user-cert" },
    { 'K',  9, "application/x-pkcs7-crl" },
    { 'K', 10, "application/x-pem-file" },
    { 'K', 11, "application/x-pkcs12" },
    { 'K', 12, "application/x-pkcs7-certificates" },
    { 'K', 13, "application/x-pkcs7-certreqresp" },

    // Sync
    { 'S', 0, "application/pEp.sync" },

    // Distribution
    { 'D', 0, "application/pEp.distribution" },
    { 'D', 0, "application/pEp.keyreset" },

    // Authentication
    { 'A', 0, "application/auth" },
    { 'A', 1, "application/signature" },

    // OpenPGP
    { 'A', 2, "application/pgp-signature" },

    // x.509
    { 'A', 3, "application/pkcs7-signature" },
    { 'A', 3, "application/x-pkcs7-signature" },
    
    // end marker
    { 0, 0, NULL }
};

Support in Message API

Encryption

To enable the functionality of Elevated Attachments, encrypt_message() has to be called with enc_format = PEP_enc_inline.

Attachments with supported MIME types will be encrypted using the Internal Message Format for Elevated Attachments.

This is how to use it:

  1. put payload into .longmsg
  2. call encrypt_message() with enc_format = PEP_enc_inline_EA
  3. you’re getting back crypto text in .longmsg and possibly ASCII encoded crypto text in .value of attachments in .attachments; .enc_format is PEP_enc_inline_EA
  4. send one message with the crypto text of .longmsg
  5. send messages for each attachment in .attachments with the crypto text of .value, respectively

Decryption

To enable the functionality of Elevated Attachments, before calling decrypt_message() the .enc_format of the encrypted message has to be set to PEP_enc_inline_EA. In this case decrypt_message() is expecting that .longmsg may contain crypto text for an elevated message. To determine if this is the case it is expecting the Internal Message Format for an Elevated Attachment.

If an Elevated Attachment was detected while decryption then decrypt_message() will create a struct _message with one attachment in .attachments. .longmsg and .longmsg_formatted will be empty.

In this case all supported message types will be processed. Additionally, pEp-auto-consume: yes will be set in .opt_fields so the application gets informed that this was processed already.

This is how to use it:

  1. you’re receiving a message with crypto text
  2. put the crypto text into .longmsg
  3. set .enc_format = PEP_enc_inline_EA
  4. call decrypt_message()
  5. there’s two different possible results:
  • payload in .longmsg, which has to be delivered to the system
  • .longmsg empty and one attachment in .attachments, which does not need to be delivered to the system

See also

  • ENGINE-746
  • internal_format in pEpEngine