Skip to content

Commit

Permalink
[mms] Add Horde_Crypt_Pgp_Parse#parseToPart().
Browse files Browse the repository at this point in the history
  • Loading branch information
slusarz authored and mrubinsk committed Nov 14, 2013
1 parent 56177ef commit 9b71b73
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 0 deletions.
103 changes: 103 additions & 0 deletions framework/Crypt/lib/Horde/Crypt/Pgp/Parse.php
Expand Up @@ -56,6 +56,12 @@ class Horde_Crypt_Pgp_Parse
/* Regular text contained in an PGP message. */
const ARMOR_TEXT = 6;

/**
* Metadata names for signature data.
*/
const SIG_CHARSET = 'pgp_sig_charset';
const SIG_RAW = 'pgp_sig_raw';

/**
* Strings in armor header lines used to distinguish between the different
* types of PGP decryption/encryption.
Expand Down Expand Up @@ -127,4 +133,101 @@ public function parse($text)
return $data;
}

/**
* Parses an armored message into a Horde_Mime_Part object.
*
* @param mixed $text Either the text to parse or a Horde_Stream object.
*
* @return mixed Either null if no PGP data was found, or a
* Horde_Mime_Part object. For detached signature data:
* the full contents of the armored text (data + sig) is
* contained in the SIG_RAW metadata, and the charset is
* contained in the SIG_CHARSET metadata, within the
* application/pgp-signature part.
*/
public function parseToPart($text, $charset = 'UTF-8')
{
$parts = $this->parse($text);

if (empty($parts) ||
((count($parts) == 1) && ($parts[0]['type'] == self::ARMOR_TEXT))) {
return null;
}

$new_part = new Horde_Mime_Part();
$new_part->setType('multipart/mixed');

foreach ($parts as $val) {
switch ($val['type']) {
case self::ARMOR_TEXT:
$part = new Horde_Mime_Part();
$part->setType('text/plain');
$part->setCharset($charset);
$part->setContents(implode("\n", $val['data']));
$new_part->addPart($part);
break;

case self::ARMOR_PUBLIC_KEY:
$part = new Horde_Mime_Part();
$part->setType('application/pgp-keys');
$part->setContents(implode("\n", $val['data']));
$new_part->addPart($part);
break;

case self::ARMOR_MESSAGE:
$part = new Horde_Mime_Part();
$part->setType('multipart/encrypted');
$part->setMetadata(IMP_Mime_Viewer_Pgp::PGP_ARMOR, true);
$part->setContentTypeParameter('protocol', 'application/pgp-encrypted');

$part1 = new Horde_Mime_Part();
$part1->setType('application/pgp-encrypted');
$part1->setContents("Version: 1\n");

$part2 = new Horde_Mime_Part();
$part2->setType('application/octet-stream');
$part2->setContents(implode("\n", $val['data']));
$part2->setDisposition('inline');

$part->addPart($part1);
$part->addPart($part2);

$new_part->addPart($part);
break;

case self::ARMOR_SIGNED_MESSAGE:
if (($sig = current($parts)) &&
($sig['type'] == self::ARMOR_SIGNATURE)) {
$part = new Horde_Mime_Part();
$part->setType('multipart/signed');
// TODO: add micalg parameter
$part->setContentTypeParameter('protocol', 'application/pgp-signature');

$part1 = new Horde_Mime_Part();
$part1->setType('text/plain');
$part1->setCharset($charset);

$part1_data = implode("\n", $val['data']);
$part1->setContents(substr($part1_data, strpos($part1_data, "\n\n") + 2));

$part2 = new Horde_Mime_Part();

$part2->setType('application/pgp-signature');
$part2->setContents(implode("\n", $sig['data']));

$part2->setMetadata(self::SIG_CHARSET, $charset);
$part2->setMetadata(self::SIG_RAW, implode("\n", $val['data']) . "\n" . implode("\n", $sig['data']));

$part->addPart($part1);
$part->addPart($part2);
$new_part->addPart($part);

next($parts);
}
}
}

return $new_part;
}

}
2 changes: 2 additions & 0 deletions framework/Crypt/package.xml
Expand Up @@ -27,6 +27,7 @@
</stability>
<license uri="http://www.horde.org/licenses/lgpl21">LGPL-2.1</license>
<notes>
* [mms] Add Horde_Crypt_Pgp_Parse#parseToPart().
* [mms] Move Horde_Crypt_Pgp#parsePGPData() to separate class (Horde_Crypt_Pgp_Parse), since it can be used even if GnuPG binary is not available.
</notes>
<contents>
Expand Down Expand Up @@ -956,6 +957,7 @@ Initial release as a PEAR package
<date>2013-11-12</date>
<license uri="http://www.horde.org/licenses/lgpl21">LGPL-2.1</license>
<notes>
* [mms] Add Horde_Crypt_Pgp_Parse#parseToPart().
* [mms] Move Horde_Crypt_Pgp#parsePGPData() to separate class (Horde_Crypt_Pgp_Parse), since it can be used even if GnuPG binary is not available.
</notes>
</release>
Expand Down

0 comments on commit 9b71b73

Please sign in to comment.