Kernel::System::PostMaster::Modifier::PGPMixedUpEncryption – Postmaster module to attempt to fix "Mixed up" PGP encrypted mails corrupted by MS-Exchange.


RFC 1847 Defines the correct structure of PGP MIME encrypted emails as:

2.2. Definition of Multipart/Encrypted

    (1)  MIME type name: multipart

    (2)  MIME subtype name: encrypted

    (3)  Required parameters: boundary, protocol

    (4)  Optional parameters: none

    (5)  Security considerations: none

    The multipart/encrypted content type contains exactly two body parts.
    The first body part contains the control information necessary to
    decrypt the data in the second body part and is labeled according to
    the value of the protocol parameter.  The second body part contains
    the data which was encrypted and is always labeled

Unfortunately this kind of mails when passed trough a MS-Exchange server might be altered, resulting in an out of compliance email structure for this use case.

Common PGP/MIME Message Mangling Describes a way to identify and fix this corrupted emails:

4.1. "Mixed Up" Encryption

    One common mangling takes an incoming multipart/encrypted e-mail and
    transforms it into a multipart/mixed e-mail, shuffling body parts at
    the same time.

    An encrypted message typically has this clean structure C (see
    example in Section 12.1):

    C   multipart/encrypted
    C.1  application/pgp-encrypted
    C.2  application/octet-stream

    But after processing, it has mangled structure M (see example in
    Section 12.2):

    M   multipart/mixed
    M.1  text/plain (0 bytes)
    M.2  application/pgp-encrypted
    M.3  application/octet-stream

    Some versions of Microsoft Exchange are known to do this.

4.1.1. Detection of "Mixed Up" Encryption

    Check that all of the following conditions hold:

    o  The message itself (M) is Content-Type: multipart/mixed.

    o  The message has exactly three MIME subparts, all direct children
       of the message itself.

    o  The first part (M.1) is Content-Type: text/plain, and has 0 bytes.

    o  The second part (M.2) is Content-Type: application/pgp-encrypted,
       and contains (after removing any Content-Transfer-Encoding)
       exactly the string "Version: 1"

    o  The third part (M.3) is Content-Type: application/octet-stream.

    o  After removing any Content-Transfer-Encoding, the decoded third
       part (M.3) is an ASCII-armored OpenPGP block of type "PGP MESSAGE"
       (see see section 6.2 of [RFC4880])

    Please see Section 13.1 for an example implementation.

4.1.2. Repair of "Mixed Up" Encryption

    If the detection is successful, repair can be attempted with the
    following steps:

    o  Convert the message's Content-Type: value to multipart/encrypted,
       while leaving any other parameters untouched.

    o  Add (or reset) the parameter protocol=application/pgp-encrypted to
       the Content-Type: header.

    o  Drop the first sub-part (M.1).



This module is not intended to be instantiated as a stand alone module, but as part of Kernel::System::Postmaster.

    my $ModifierObject = Kernel::System::PostMaster::Modifier::PGPMixedUpEncryption->new(
        ParserObject           => $ParserObject,            # L<Kernel::System::EmailParser>
        CommunicationLogObject => $CommunicationLogObject}  # L<Kernel::System::CommunicationLog>
                                                            #  with started 'message' log


Execute the module, Fixed email as a new Parser Object will be set as $ModifierObject{ParserObject} so it can be access later by the caller.

    my $Success = $ModifierObject->Run();



Determines if the current mail is considered as a "Mixed up" encrypted mail.

    my $Success = $Self->CheckMixedUpEmail();


    Mixed Up attachments (email parts) should look similar to:
    @Attachments (
            MimeType => 'text/plain',
            FileSize => '',
            Content  => '',
            # ...
            MimeType => 'text/html',
            FileSize => '12',
            Content => 'Version: 1',
            # ...
            MimeType => 'application/octet-stream',
            FileSize => '123',
            Content => '-----BEGIN PGP MESSAGE-----
                -----END PGP MESSAGE-----',
            # ...


Determines if the fixed mail complies with RFC 1847.

    my $Success = $Self->_CheckFixedEmail(
        ParserObject => $ParserObject,      # containing the already fixed email.
Scroll to Top