package.xml 0000664 0001750 0001750 00000122467 12242643672 011323 0 ustar jan jan
* - http: (Horde_Http_Client) The HTTP client object to use.
* - keyserver: (string) The public PGP keyserver to use.
* - port: (integer) The public PGP keyserver port.
*
*/
public function __construct(Horde_Crypt_Pgp $pgp, array $params = array())
{
$this->_pgp = $pgp;
$this->_http = (isset($params['http']) && ($params['http'] instanceof Horde_Http_Client))
? $params['http']
: new Horde_Http_Client();
$this->_keyserver = isset($params['keyserver'])
? $params['keyserver']
: 'pool.sks-keyservers.net';
$this->_keyserver .= ':' . (isset($params['port']) ? $params['port'] : '11371');
}
/**
* Returns PGP public key data retrieved from a public keyserver.
*
* @param string $keyid The key ID of the PGP key.
*
* @return string The PGP public key.
* @throws Horde_Crypt_Exception
*/
public function get($keyid)
{
/* Connect to the public keyserver. */
$url = $this->_createUrl('/pks/lookup', array(
'op' => 'get',
'search' => $this->_pgp->getKeyIDString($keyid)
));
try {
$output = $this->_http->get($url)->getBody();
} catch (Horde_Http_Exception $e) {
throw new Horde_Crypt_Exception($e);
}
/* Grab PGP key from output. */
if (($start = strstr($output, '-----BEGIN'))) {
$length = strpos($start, '-----END') + 34;
return substr($start, 0, $length);
}
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Could not obtain public key from the keyserver."));
}
/**
* Sends a PGP public key to a public keyserver.
*
* @param string $pubkey The PGP public key
*
* @throws Horde_Crypt_Exception
*/
public function put($pubkey)
{
/* Get the key ID of the public key. */
$info = $this->_pgp->pgpPacketInformation($pubkey);
/* See if the public key already exists on the keyserver. */
try {
$this->get($info['keyid']);
} catch (Horde_Crypt_Exception $e) {
$pubkey = 'keytext=' . urlencode(rtrim($pubkey));
try {
$this->_http->post(
$this->_createUrl('/pks/add'),
$pubkey,
array(
'User-Agent: Horde Application Framework',
'Content-Type: application/x-www-form-urlencoded',
'Content-Length: ' . strlen($pubkey),
'Connection: close'
)
);
} catch (Horde_Http_Exception $e) {
throw new Horde_Crypt_Exception($e);
}
}
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Key already exists on the public keyserver."));
}
/**
* Returns the first matching key ID for an email address from a public
* keyserver.
*
* @param string $address The email address of the PGP key.
*
* @return string The PGP key ID.
* @throws Horde_Crypt_Exception
*/
public function getKeyId($address)
{
$pubkey = null;
/* Connect to the public keyserver. */
$url = $this->_createUrl('/pks/lookup', array(
'op' => 'index',
'options' => 'mr',
'search' => $address
));
try {
$output = $this->_http->get($url)->getBody();
} catch (Horde_Http_Exception $e) {
throw new Horde_Crypt_Exception($e);
}
if (strpos($output, '-----BEGIN PGP PUBLIC KEY BLOCK') !== false) {
$pubkey = $output;
} elseif (strpos($output, 'pub:') !== false) {
$output = explode("\n", $output);
$keyids = $keyuids = array();
$curid = null;
foreach ($output as $line) {
if (substr($line, 0, 4) == 'pub:') {
$line = explode(':', $line);
/* Ignore invalid lines and expired keys. */
if (count($line) != 7 ||
(!empty($line[5]) && $line[5] <= time())) {
continue;
}
$curid = $line[4];
$keyids[$curid] = $line[1];
} elseif (!is_null($curid) && substr($line, 0, 4) == 'uid:') {
preg_match("/<([^>]+)>/", $line, $matches);
$keyuids[$curid][] = $matches[1];
}
}
/* Remove keys without a matching UID. */
foreach ($keyuids as $id => $uids) {
$match = false;
foreach ($uids as $uid) {
if ($uid == $address) {
$match = true;
break;
}
}
if (!$match) {
unset($keyids[$id]);
}
}
/* Sort by timestamp to use the newest key. */
if (count($keyids)) {
ksort($keyids);
$pubkey = $this->get(array_pop($keyids));
}
}
if ($pubkey) {
$sig = $this->_pgp->pgpPacketSignature($pubkey, $address);
if (!empty($sig['keyid']) &&
(empty($sig['public_key']['expires']) ||
$sig['public_key']['expires'] > time())) {
return substr($this->_pgp->getKeyIDString($sig['keyid']), 2);
}
}
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Could not obtain public key from the keyserver."));
}
/**
* Create the URL for the keyserver.
*
* @param string $uri Action URI.
* @param array $params List of parameters to add to URL.
*
* @return Horde_Url Keyserver URL.
*/
protected function _createUrl($uri, array $params = array())
{
$url = new Horde_Url($this->_keyserver . $uri, true);
return $url->add($params);
}
}
Horde_Crypt-2.4.0/lib/Horde/Crypt/Pgp/Parse.php 0000664 0001750 0001750 00000017466 12242643672 017312 0 ustar jan jan
* @category Horde
* @copyright 2002-2013 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt
* @since 2.4.0
*/
class Horde_Crypt_Pgp_Parse
{
/**
* Armor Header Lines - From RFC 2440:
*
* An Armor Header Line consists of the appropriate header line text
* surrounded by five (5) dashes ('-', 0x2D) on either side of the header
* line text. The header line text is chosen based upon the type of data
* that is being encoded in Armor, and how it is being encoded.
*
* All Armor Header Lines are prefixed with 'PGP'.
*
* The Armor Tail Line is composed in the same manner as the Armor Header
* Line, except the string "BEGIN" is replaced by the string "END."
*/
/* Used for signed, encrypted, or compressed files. */
const ARMOR_MESSAGE = 1;
/* Used for signed files. */
const ARMOR_SIGNED_MESSAGE = 2;
/* Used for armoring public keys. */
const ARMOR_PUBLIC_KEY = 3;
/* Used for armoring private keys. */
const ARMOR_PRIVATE_KEY = 4;
/* Used for detached signatures, PGP/MIME signatures, and natures
* following clearsigned messages. */
const ARMOR_SIGNATURE = 5;
/* 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.
*
* @var array
*/
protected $_armor = array(
'MESSAGE' => self::ARMOR_MESSAGE,
'SIGNED MESSAGE' => self::ARMOR_SIGNED_MESSAGE,
'PUBLIC KEY BLOCK' => self::ARMOR_PUBLIC_KEY,
'PRIVATE KEY BLOCK' => self::ARMOR_PRIVATE_KEY,
'SIGNATURE' => self::ARMOR_SIGNATURE
);
/**
* Parses a message into text and PGP components.
*
* @param mixed $text Either the text to parse or a Horde_Stream object.
*
* @return array An array with the parsed text, returned in blocks of
* text corresponding to their actual order. Keys:
*
* - data: (array) The data for each section. Each line has been
* stripped of EOL characters.
* - type: (integer) The type of data contained in block. Valid types
* are the class ARMOR_* constants.
*
*/
public function parse($text)
{
$data = array();
$temp = array(
'type' => self::ARMOR_TEXT
);
if ($text instanceof Horde_Stream) {
$stream = $text;
$stream->rewind();
} else {
$stream = new Horde_Stream_Temp();
$stream->add($text, true);
}
while (!$stream->eof()) {
$val = rtrim($stream->getToChar("\n", false), "\r");
if (preg_match('/^-----(BEGIN|END) PGP ([^-]+)-----\s*$/', $val, $matches)) {
if (isset($temp['data'])) {
$data[] = $temp;
}
$temp = array();
if ($matches[1] == 'BEGIN') {
$temp['type'] = $this->_armor[$matches[2]];
$temp['data'][] = $val;
} elseif ($matches[1] == 'END') {
$temp['type'] = self::ARMOR_TEXT;
$data[count($data) - 1]['data'][] = $val;
}
} else {
$temp['data'][] = $val;
}
}
if (isset($temp['data']) &&
((count($temp['data']) > 1) || !empty($temp['data'][0]))) {
$data[] = $temp;
}
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;
}
}
Horde_Crypt-2.4.0/lib/Horde/Crypt/Exception.php 0000664 0001750 0001750 00000000744 12242643672 017437 0 ustar jan jan
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt
*/
class Horde_Crypt_Exception extends Horde_Exception_Wrapped
{
}
Horde_Crypt-2.4.0/lib/Horde/Crypt/Pgp.php 0000664 0001750 0001750 00000154132 12242643672 016230 0 ustar jan jan
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt
*/
/**
* Horde_Crypt_Pgp:: provides a framework for Horde applications to interact
* with the GNU Privacy Guard program ("GnuPG"). GnuPG implements the OpenPGP
* standard (RFC 2440).
*
* GnuPG Website: http://www.gnupg.org/
*
* This class has been developed with, and is only guaranteed to work with,
* Version 1.21 or above of GnuPG.
*
* @author Michael Slusarz
* 'program' - (string) [REQUIRED] The path to the GnuPG binary.
* 'proxy_host - (string) Proxy host. (@deprecated)
* 'proxy_port - (integer) Proxy port. (@deprecated)
*
*
* @throws InvalidArgumentException
*/
public function __construct($params = array())
{
parent::__construct($params);
if (empty($params['program'])) {
throw new InvalidArgumentException('The location of the GnuPG binary must be given to the Horde_Crypt_Pgp:: class.');
}
/* Store the location of GnuPG and set common options. */
$this->_gnupg = array(
$params['program'],
'--no-tty',
'--no-secmem-warning',
'--no-options',
'--no-default-keyring',
'--yes',
'--homedir ' . $this->_tempdir
);
if (strncasecmp(PHP_OS, 'WIN', 3)) {
array_unshift($this->_gnupg, 'LANG= ;');
}
$this->_params = $params;
}
/**
* Generates a personal Public/Private keypair combination.
*
* @param string $realname The name to use for the key.
* @param string $email The email to use for the key.
* @param string $passphrase The passphrase to use for the key.
* @param string $comment The comment to use for the key.
* @param integer $keylength The keylength to use for the key.
* @param integer $expire The expiration date (UNIX timestamp). No
* expiration if empty.
* @param string $key_type Key type (since 2.2.0).
* @param string $subkey_type Subkey type (since 2.2.0).
*
* @return array An array consisting of:
*
* Key Value
* --------------------------
* 'public' => Public Key
* 'private' => Private Key
*
* @throws Horde_Crypt_Exception
*/
public function generateKey($realname, $email, $passphrase, $comment = '',
$keylength = 1024, $expire = null,
$key_type = 'RSA', $subkey_type = 'RSA')
{
/* Create temp files to hold the generated keys. */
$pub_file = $this->_createTempFile('horde-pgp');
$secret_file = $this->_createTempFile('horde-pgp');
$expire = empty($expire)
? 0
: date('Y-m-d', $expire);
/* Create the config file necessary for GnuPG to run in batch mode. */
/* TODO: Sanitize input, More user customizable? */
$input = array(
'%pubring ' . $pub_file,
'%secring ' . $secret_file,
'Key-Type: ' . $key_type,
'Key-Length: ' . $keylength,
'Subkey-Type: ' . $subkey_type,
'Subkey-Length: ' . $keylength,
'Name-Real: ' . $realname,
'Name-Email: ' . $email,
'Expire-Date: ' . $expire,
'Passphrase: ' . $passphrase,
'Preferences: AES256 AES192 AES CAST5 3DES SHA256 SHA512 SHA384 SHA224 SHA1 ZLIB BZIP2 ZIP Uncompressed'
);
if (!empty($comment)) {
$input[] = 'Name-Comment: ' . $comment;
}
$input[] = '%commit';
/* Run through gpg binary. */
$cmdline = array(
'--gen-key',
'--batch',
'--armor'
);
$result = $this->_callGpg($cmdline, 'w', $input, true, true);
/* Get the keys from the temp files. */
$public_key = file_get_contents($pub_file);
$secret_key = file_get_contents($secret_file);
/* If either key is empty, something went wrong. */
if (empty($public_key) || empty($secret_key)) {
$msg = Horde_Crypt_Translation::t("Public/Private keypair not generated successfully.");
if (!empty($result->stderr)) {
$msg .= ' ' . Horde_Crypt_Translation::t("Returned error message:") . ' ' . $result->stderr;
}
throw new Horde_Crypt_Exception($msg);
}
return array('public' => $public_key, 'private' => $secret_key);
}
/**
* Returns information on a PGP data block.
*
* @param string $pgpdata The PGP data block.
*
* @return array An array with information on the PGP data block. If an
* element is not present in the data block, it will
* likewise not be set in the array.
*
* Array Format:
* -------------
* [public_key]/[secret_key] => Array
* (
* [created] => Key creation - UNIX timestamp
* [expires] => Key expiration - UNIX timestamp (0 = never expires)
* [size] => Size of the key in bits
* )
*
* [keyid] => Key ID of the PGP data (if available)
* 16-bit hex value
*
* [signature] => Array (
* [id{n}/'_SIGNATURE'] => Array (
* [name] => Full Name
* [comment] => Comment
* [email] => E-mail Address
* [keyid] => 16-bit hex value
* [created] => Signature creation - UNIX timestamp
* [expires] => Signature expiration - UNIX timestamp
* [micalg] => The hash used to create the signature
* [sig_{hex}] => Array [details of a sig verifying the ID] (
* [created] => Signature creation - UNIX timestamp
* [expires] => Signature expiration - UNIX timestamp
* [keyid] => 16-bit hex value
* [micalg] => The hash used to create the signature
* )
* )
* )
*
*
* Each user ID will be stored in the array 'signature' and have data
* associated with it, including an array for information on each
* signature that has signed that UID. Signatures not associated with a
* UID (e.g. revocation signatures and sub keys) will be stored under the
* special keyword '_SIGNATURE'.
*
* @throws Horde_Crypt_Exception
*/
public function pgpPacketInformation($pgpdata)
{
$data_array = array();
$keyid = '';
$header = null;
$input = $this->_createTempFile('horde-pgp');
$sig_id = $uid_idx = 0;
/* Store message in temporary file. */
file_put_contents($input, $pgpdata);
$cmdline = array(
'--list-packets',
$input
);
$result = $this->_callGpg($cmdline, 'r');
foreach (explode("\n", $result->stdout) as $line) {
/* Headers are prefaced with a ':' as the first character on the
line. */
if (strpos($line, ':') === 0) {
$lowerLine = Horde_String::lower($line);
/* If we have a key (rather than a signature block), get the
key's ID */
if (strpos($lowerLine, ':public key packet:') !== false ||
strpos($lowerLine, ':secret key packet:') !== false) {
$cmdline = array(
'--with-colons',
$input
);
$data = $this->_callGpg($cmdline, 'r');
if (preg_match("/(sec|pub):.*:.*:.*:([A-F0-9]{16}):/", $data->stdout, $matches)) {
$keyid = $matches[2];
}
}
if (strpos($lowerLine, ':public key packet:') !== false) {
$header = 'public_key';
} elseif (strpos($lowerLine, ':secret key packet:') !== false) {
$header = 'secret_key';
} elseif (strpos($lowerLine, ':user id packet:') !== false) {
$uid_idx++;
$line = preg_replace_callback('/\\\\x([0-9a-f]{2})/', array($this, '_pgpPacketInformationHelper'), $line);
if (preg_match("/\"([^\<]+)\<([^\>]+)\>\"/", $line, $matches)) {
$header = 'id' . $uid_idx;
if (preg_match('/([^\(]+)\((.+)\)$/', trim($matches[1]), $comment_matches)) {
$data_array['signature'][$header]['name'] = trim($comment_matches[1]);
$data_array['signature'][$header]['comment'] = $comment_matches[2];
} else {
$data_array['signature'][$header]['name'] = trim($matches[1]);
$data_array['signature'][$header]['comment'] = '';
}
$data_array['signature'][$header]['email'] = $matches[2];
$data_array['signature'][$header]['keyid'] = $keyid;
}
} elseif (strpos($lowerLine, ':signature packet:') !== false) {
if (empty($header) || empty($uid_idx)) {
$header = '_SIGNATURE';
}
if (preg_match("/keyid\s+([0-9A-F]+)/i", $line, $matches)) {
$sig_id = $matches[1];
$data_array['signature'][$header]['sig_' . $sig_id]['keyid'] = $matches[1];
$data_array['keyid'] = $matches[1];
}
} elseif (strpos($lowerLine, ':literal data packet:') !== false) {
$header = 'literal';
} elseif (strpos($lowerLine, ':encrypted data packet:') !== false) {
$header = 'encrypted';
} else {
$header = null;
}
} else {
if ($header == 'secret_key' || $header == 'public_key') {
if (preg_match("/created\s+(\d+),\s+expires\s+(\d+)/i", $line, $matches)) {
$data_array[$header]['created'] = $matches[1];
$data_array[$header]['expires'] = $matches[2];
} elseif (preg_match("/\s+[sp]key\[0\]:\s+\[(\d+)/i", $line, $matches)) {
$data_array[$header]['size'] = $matches[1];
}
} elseif ($header == 'literal' || $header == 'encrypted') {
$data_array[$header] = true;
} elseif ($header) {
if (preg_match("/version\s+\d+,\s+created\s+(\d+)/i", $line, $matches)) {
$data_array['signature'][$header]['sig_' . $sig_id]['created'] = $matches[1];
} elseif (isset($data_array['signature'][$header]['sig_' . $sig_id]['created']) &&
preg_match('/expires after (\d+y\d+d\d+h\d+m)\)$/', $line, $matches)) {
$expires = $matches[1];
preg_match('/^(\d+)y(\d+)d(\d+)h(\d+)m$/', $expires, $matches);
list(, $years, $days, $hours, $minutes) = $matches;
$data_array['signature'][$header]['sig_' . $sig_id]['expires'] =
strtotime('+ ' . $years . ' years + ' . $days . ' days + ' . $hours . ' hours + ' . $minutes . ' minutes', $data_array['signature'][$header]['sig_' . $sig_id]['created']);
} elseif (preg_match("/digest algo\s+(\d{1})/", $line, $matches)) {
$micalg = $this->_hashAlg[$matches[1]];
$data_array['signature'][$header]['sig_' . $sig_id]['micalg'] = $micalg;
if ($header == '_SIGNATURE') {
/* Likely a signature block, not a key. */
$data_array['signature']['_SIGNATURE']['micalg'] = $micalg;
}
if ($sig_id == $keyid) {
/* Self signing signature - we can assume
* the micalg value from this signature is
* that for the key */
$data_array['signature']['_SIGNATURE']['micalg'] = $micalg;
$data_array['signature'][$header]['micalg'] = $micalg;
}
}
}
}
}
$keyid && $data_array['keyid'] = $keyid;
return $data_array;
}
/**
* TODO
*/
protected function _pgpPacketInformationHelper($a)
{
return chr(hexdec($a[1]));
}
/**
* Returns human readable information on a PGP key.
*
* @param string $pgpdata The PGP data block.
*
* @return string Tabular information on the PGP key.
* @throws Horde_Crypt_Exception
*/
public function pgpPrettyKey($pgpdata)
{
$msg = '';
$packet_info = $this->pgpPacketInformation($pgpdata);
$fingerprints = $this->getFingerprintsFromKey($pgpdata);
if (!empty($packet_info['signature'])) {
/* Making the property names the same width for all
* localizations .*/
$leftrow = array(
Horde_Crypt_Translation::t("Name"),
Horde_Crypt_Translation::t("Key Type"),
Horde_Crypt_Translation::t("Key Creation"),
Horde_Crypt_Translation::t("Expiration Date"),
Horde_Crypt_Translation::t("Key Length"),
Horde_Crypt_Translation::t("Comment"),
Horde_Crypt_Translation::t("E-Mail"),
Horde_Crypt_Translation::t("Hash-Algorithm"),
Horde_Crypt_Translation::t("Key ID"),
Horde_Crypt_Translation::t("Key Fingerprint")
);
$leftwidth = array_map('strlen', $leftrow);
$maxwidth = max($leftwidth) + 2;
array_walk($leftrow, array($this, '_pgpPrettyKeyFormatter'), $maxwidth);
foreach ($packet_info['signature'] as $uid_idx => $val) {
if ($uid_idx == '_SIGNATURE') {
continue;
}
$key_info = $this->pgpPacketSignatureByUidIndex($pgpdata, $uid_idx);
$keyid = empty($key_info['keyid'])
? null
: $this->getKeyIDString($key_info['keyid']);
$fingerprint = isset($fingerprints[$keyid])
? $fingerprints[$keyid]
: null;
$sig_key = 'sig_' . $key_info['keyid'];
$msg .= $leftrow[0] . (isset($key_info['name']) ? stripcslashes($key_info['name']) : '') . "\n"
. $leftrow[1] . (($key_info['key_type'] == 'public_key') ? Horde_Crypt_Translation::t("Public Key") : Horde_Crypt_Translation::t("Private Key")) . "\n"
. $leftrow[2] . strftime("%D", $val[$sig_key]['created']) . "\n"
. $leftrow[3] . (empty($val[$sig_key]['expires']) ? '[' . Horde_Crypt_Translation::t("Never") . ']' : strftime("%D", $val[$sig_key]['expires'])) . "\n"
. $leftrow[4] . $key_info['key_size'] . " Bytes\n"
. $leftrow[5] . (empty($key_info['comment']) ? '[' . Horde_Crypt_Translation::t("None") . ']' : $key_info['comment']) . "\n"
. $leftrow[6] . (empty($key_info['email']) ? '[' . Horde_Crypt_Translation::t("None") . ']' : $key_info['email']) . "\n"
. $leftrow[7] . (empty($key_info['micalg']) ? '[' . Horde_Crypt_Translation::t("Unknown") . ']' : $key_info['micalg']) . "\n"
. $leftrow[8] . (empty($keyid) ? '[' . Horde_Crypt_Translation::t("Unknown") . ']' : $keyid) . "\n"
. $leftrow[9] . (empty($fingerprint) ? '[' . Horde_Crypt_Translation::t("Unknown") . ']' : $fingerprint) . "\n\n";
}
}
return $msg;
}
/**
* TODO
*/
protected function _pgpPrettyKeyFormatter(&$s, $k, $m)
{
$s .= ':' . str_repeat(' ', $m - Horde_String::length($s));
}
/**
* TODO
*
* @since 2.4.0
*/
public function getKeyIDString($keyid)
{
/* Get the 8 character key ID string. */
if (strpos($keyid, '0x') === 0) {
$keyid = substr($keyid, 2);
}
if (strlen($keyid) > 8) {
$keyid = substr($keyid, -8);
}
return '0x' . $keyid;
}
/**
* Returns only information on the first ID that matches the email address
* input.
*
* @param string $pgpdata The PGP data block.
* @param string $email An e-mail address.
*
* @return array An array with information on the PGP data block. If an
* element is not present in the data block, it will
* likewise not be set in the array.
*
* Array Fields:
* -------------
* key_created => Key creation - UNIX timestamp
* key_expires => Key expiration - UNIX timestamp (0 = never expires)
* key_size => Size of the key in bits
* key_type => The key type (public_key or secret_key)
* name => Full Name
* comment => Comment
* email => E-mail Address
* keyid => 16-bit hex value
* created => Signature creation - UNIX timestamp
* micalg => The hash used to create the signature
*
* @throws Horde_Crypt_Exception
*/
public function pgpPacketSignature($pgpdata, $email)
{
$data = $this->pgpPacketInformation($pgpdata);
$return_array = array();
/* Check that [signature] key exists. */
if (!isset($data['signature'])) {
return $return_array;
}
/* Store the signature information now. */
if (($email == '_SIGNATURE') &&
isset($data['signature']['_SIGNATURE'])) {
foreach ($data['signature'][$email] as $key => $value) {
$return_array[$key] = $value;
}
} else {
$uid_idx = 1;
while (isset($data['signature']['id' . $uid_idx])) {
if ($data['signature']['id' . $uid_idx]['email'] == $email) {
foreach ($data['signature']['id' . $uid_idx] as $key => $val) {
$return_array[$key] = $val;
}
break;
}
$uid_idx++;
}
}
return $this->_pgpPacketSignature($data, $return_array);
}
/**
* Returns information on a PGP signature embedded in PGP data. Similar
* to pgpPacketSignature(), but returns information by unique User ID
* Index (format id{n} where n is an integer of 1 or greater).
*
* @param string $pgpdata See pgpPacketSignature().
* @param string $uid_idx The UID index.
*
* @return array See pgpPacketSignature().
* @throws Horde_Crypt_Exception
*/
public function pgpPacketSignatureByUidIndex($pgpdata, $uid_idx)
{
$data = $this->pgpPacketInformation($pgpdata);
return isset($data['signature'][$uid_idx])
? $this->_pgpPacketSignature($data, $data['signature'][$uid_idx])
: array();
}
/**
* Adds some data to the pgpPacketSignature*() function array.
*
* @param array $data See pgpPacketSignature().
* @param array $retarray The return array.
*
* @return array The return array.
*/
protected function _pgpPacketSignature($data, $retarray)
{
/* If empty, return now. */
if (empty($retarray)) {
return $retarray;
}
$key_type = null;
/* Store any public/private key information. */
if (isset($data['public_key'])) {
$key_type = 'public_key';
} elseif (isset($data['secret_key'])) {
$key_type = 'secret_key';
}
if ($key_type) {
$retarray['key_type'] = $key_type;
if (isset($data[$key_type]['created'])) {
$retarray['key_created'] = $data[$key_type]['created'];
}
if (isset($data[$key_type]['expires'])) {
$retarray['key_expires'] = $data[$key_type]['expires'];
}
if (isset($data[$key_type]['size'])) {
$retarray['key_size'] = $data[$key_type]['size'];
}
}
return $retarray;
}
/**
* Returns the key ID of the key used to sign a block of PGP data.
*
* @param string $text The PGP signed text block.
*
* @return string The key ID of the key used to sign $text.
* @throws Horde_Crypt_Exception
*/
public function getSignersKeyID($text)
{
$keyid = null;
$input = $this->_createTempFile('horde-pgp');
file_put_contents($input, $text);
$cmdline = array(
'--verify',
$input
);
$result = $this->_callGpg($cmdline, 'r', null, true, true);
if (preg_match('/gpg:\sSignature\smade.*ID\s+([A-F0-9]{8})\s+/', $result->stderr, $matches)) {
$keyid = $matches[1];
}
return $keyid;
}
/**
* Verify a passphrase for a given public/private keypair.
*
* @param string $public_key The user's PGP public key.
* @param string $private_key The user's PGP private key.
* @param string $passphrase The user's passphrase.
*
* @return boolean Returns true on valid passphrase, false on invalid
* passphrase.
* @throws Horde_Crypt_Exception
*/
public function verifyPassphrase($public_key, $private_key, $passphrase)
{
/* Get e-mail address of public key. */
$key_info = $this->pgpPacketInformation($public_key);
if (!isset($key_info['signature']['id1']['email'])) {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Could not determine the recipient's e-mail address."));
}
/* Encrypt a test message. */
try {
$result = $this->encrypt('Test', array('type' => 'message', 'pubkey' => $public_key, 'recips' => array($key_info['signature']['id1']['email'] => $public_key)));
} catch (Horde_Crypt_Exception $e) {
return false;
}
/* Try to decrypt the message. */
try {
$this->decrypt($result, array('type' => 'message', 'pubkey' => $public_key, 'privkey' => $private_key, 'passphrase' => $passphrase));
} catch (Horde_Crypt_Exception $e) {
return false;
}
return true;
}
/**
* Parses a message into text and PGP components.
*
* @deprecated Use Horde_Crypt_Pgp_Parse instead.
*
* @param mixed $text Either the text to parse or a Horde_Stream object
* (@since 2.3.0).
*
* @return array An array with the parsed text, returned in blocks of
* text corresponding to their actual order. Keys:
*
* - data: (array) The data for each section. Each line has been
* stripped of EOL characters.
* - type: (integer) The type of data contained in block. Valid types
* are the class ARMOR_* constants.
*
*/
public function parsePGPData($text)
{
$parse = new Horde_Crypt_Pgp_Parse();
return $parse->parse($text);
}
/**
* Returns a PGP public key from a public keyserver.
*
* @deprecated Use Horde_Crypt_Pgp_Keyserver instead.
*
* @param string $keyid The key ID of the PGP key.
* @param string $server The keyserver to use.
* @param float $timeout The keyserver timeout.
* @param string $address The email address of the PGP key.
*
* @return string The PGP public key.
* @throws Horde_Crypt_Exception
*/
public function getPublicKeyserver($keyid,
$server = self::KEYSERVER_PUBLIC,
$timeout = self::KEYSERVER_TIMEOUT,
$address = null)
{
$keyserver = $this->_getKeyserverOb($server);
if (empty($keyid) && !empty($address)) {
$keyid = $keyserver->getKeyID($address);
}
return $keyserver->get($keyid);
}
/**
* Sends a PGP public key to a public keyserver.
*
* @param string $pubkey The PGP public key
* @param string $server The keyserver to use.
* @param float $timeout The keyserver timeout.
*
* @throws Horde_Crypt_Exception
*/
public function putPublicKeyserver($pubkey,
$server = self::KEYSERVER_PUBLIC,
$timeout = self::KEYSERVER_TIMEOUT)
{
return $this->_getKeyserverOb($server)->put($pubkey);
}
/**
* Returns the first matching key ID for an email address from a
* public keyserver.
*
* @param string $address The email address of the PGP key.
* @param string $server The keyserver to use.
* @param float $timeout The keyserver timeout.
*
* @return string The PGP key ID.
* @throws Horde_Crypt_Exception
*/
public function getKeyID($address, $server = self::KEYSERVER_PUBLIC,
$timeout = self::KEYSERVER_TIMEOUT)
{
return $this->_getKeyserverOb($server)->getKeyId($address);
}
/**
* @deprecated
* @internal
*/
protected function _getKeyserverOb($server)
{
$params = array(
'keyserver' => $server,
'http' => new Horde_Http_Client()
);
if (!empty($this->_params['proxy_host'])) {
$params['http']->{'request.proxyServer'} = $this->_params['proxy_host'];
if (isset($this->_params['proxy_port'])) {
$params['http']->{'request.proxyPort'} = $this->_params['proxy_port'];
}
}
return new Horde_Crypt_Pgp_Keyserver($this, $params);
}
/**
* Get the fingerprints from a key block.
*
* @param string $pgpdata The PGP data block.
*
* @return array The fingerprints in $pgpdata indexed by key id.
* @throws Horde_Crypt_Exception
*/
public function getFingerprintsFromKey($pgpdata)
{
$fingerprints = array();
/* Store the key in a temporary keyring. */
$keyring = $this->_putInKeyring($pgpdata);
/* Options for the GPG binary. */
$cmdline = array(
'--fingerprint',
$keyring,
);
$result = $this->_callGpg($cmdline, 'r');
if (!$result || !$result->stdout) {
return $fingerprints;
}
/* Parse fingerprints and key ids from output. */
$lines = explode("\n", $result->stdout);
$keyid = null;
foreach ($lines as $line) {
if (preg_match('/pub\s+\w+\/(\w{8})/', $line, $matches)) {
$keyid = '0x' . $matches[1];
} elseif ($keyid && preg_match('/^\s+[\s\w]+=\s*([\w\s]+)$/m', $line, $matches)) {
$fingerprints[$keyid] = trim($matches[1]);
$keyid = null;
}
}
return $fingerprints;
}
/**
* Encrypts text using PGP.
*
* @param string $text The text to be PGP encrypted.
* @param array $params The parameters needed for encryption.
* See the individual _encrypt*() functions for the
* parameter requirements.
*
* @return string The encrypted message.
* @throws Horde_Crypt_Exception
*/
public function encrypt($text, $params = array())
{
if (isset($params['type'])) {
if ($params['type'] === 'message') {
return $this->_encryptMessage($text, $params);
} elseif ($params['type'] === 'signature') {
return $this->_encryptSignature($text, $params);
}
}
}
/**
* Decrypts text using PGP.
*
* @param string $text The text to be PGP decrypted.
* @param array $params The parameters needed for decryption.
* See the individual _decrypt*() functions for the
* parameter requirements.
*
* @return stdClass An object with the following properties:
*
* 'message' - (string) The signature result text.
* 'result' - (boolean) The result of the signature test.
*
* @throws Horde_Crypt_Exception
*/
public function decrypt($text, $params = array())
{
if (isset($params['type'])) {
if ($params['type'] === 'message') {
return $this->_decryptMessage($text, $params);
} elseif (($params['type'] === 'signature') ||
($params['type'] === 'detached-signature')) {
return $this->_decryptSignature($text, $params);
}
}
}
/**
* Returns whether a text has been encrypted symmetrically.
*
* @param string $text The PGP encrypted text.
*
* @return boolean True if the text is symmetricallly encrypted.
* @throws Horde_Crypt_Exception
*/
public function encryptedSymmetrically($text)
{
$cmdline = array(
'--decrypt',
'--batch',
'--passphrase ""'
);
$result = $this->_callGpg($cmdline, 'w', $text, true, true, true);
return strpos($result->stderr, 'gpg: encrypted with 1 passphrase') !== false;
}
/**
* Creates a temporary gpg keyring.
*
* @param string $type The type of key to analyze. Either 'public'
* (Default) or 'private'
*
* @return string Command line keystring option to use with gpg program.
*/
protected function _createKeyring($type = 'public')
{
$type = Horde_String::lower($type);
if ($type === 'public') {
if (empty($this->_publicKeyring)) {
$this->_publicKeyring = $this->_createTempFile('horde-pgp');
}
return '--keyring ' . $this->_publicKeyring;
} elseif ($type === 'private') {
if (empty($this->_privateKeyring)) {
$this->_privateKeyring = $this->_createTempFile('horde-pgp');
}
return '--secret-keyring ' . $this->_privateKeyring;
}
}
/**
* Adds PGP keys to the keyring.
*
* @param mixed $keys A single key or an array of key(s) to add to the
* keyring.
* @param string $type The type of key(s) to add. Either 'public'
* (Default) or 'private'
*
* @return string Command line keystring option to use with gpg program.
* @throws Horde_Crypt_Exception
*/
protected function _putInKeyring($keys = array(), $type = 'public')
{
$type = Horde_String::lower($type);
if (!is_array($keys)) {
$keys = array($keys);
}
/* Create the keyrings if they don't already exist. */
$keyring = $this->_createKeyring($type);
/* Store the key(s) in the keyring. */
$cmdline = array(
'--allow-secret-key-import',
'--fast-import',
$keyring
);
$this->_callGpg($cmdline, 'w', array_values($keys));
return $keyring;
}
/**
* Encrypts a message in PGP format using a public key.
*
* @param string $text The text to be encrypted.
* @param array $params The parameters needed for encryption.
*
* Parameters:
* ===========
* 'type' => 'message' (REQUIRED)
* 'symmetric' => Whether to use symmetric instead of asymmetric
* encryption (defaults to false)
* 'recips' => An array with the e-mail address of the recipient as
* the key and that person's public key as the value.
* (REQUIRED if 'symmetric' is false)
* 'passphrase' => The passphrase for the symmetric encryption (REQUIRED if
* 'symmetric' is true)
*
*
* @return string The encrypted message.
* @throws Horde_Crypt_Exception
*/
protected function _encryptMessage($text, $params)
{
/* Create temp files for input. */
$input = $this->_createTempFile('horde-pgp');
file_put_contents($input, $text);
/* Build command line. */
$cmdline = array(
'--armor',
'--batch',
'--always-trust'
);
if (empty($params['symmetric'])) {
/* Store public key in temporary keyring. */
$keyring = $this->_putInKeyring(array_values($params['recips']));
$cmdline[] = $keyring;
$cmdline[] = '--encrypt';
foreach (array_keys($params['recips']) as $val) {
$cmdline[] = '--recipient ' . $val;
}
} else {
$cmdline[] = '--symmetric';
$cmdline[] = '--passphrase-fd 0';
}
$cmdline[] = $input;
/* Encrypt the document. */
$result = $this->_callGpg($cmdline, 'w', empty($params['symmetric']) ? null : $params['passphrase'], true, true);
if (empty($result->output)) {
$error = preg_replace('/\n.*/', '', $result->stderr);
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Could not PGP encrypt message: ") . $error);
}
return $result->output;
}
/**
* Signs a message in PGP format using a private key.
*
* @param string $text The text to be signed.
* @param array $params The parameters needed for signing.
*
* Parameters:
* ===========
* 'type' => 'signature' (REQUIRED)
* 'pubkey' => PGP public key. (REQUIRED)
* 'privkey' => PGP private key. (REQUIRED)
* 'passphrase' => Passphrase for PGP Key. (REQUIRED)
* 'sigtype' => Determine the signature type to use. (Optional)
* 'cleartext' -- Make a clear text signature
* 'detach' -- Make a detached signature (DEFAULT)
*
*
* @return string The signed message.
* @throws Horde_Crypt_Exception
*/
protected function _encryptSignature($text, $params)
{
/* Check for required parameters. */
if (!isset($params['pubkey']) ||
!isset($params['privkey']) ||
!isset($params['passphrase'])) {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("A public PGP key, private PGP key, and passphrase are required to sign a message."));
}
/* Create temp files for input. */
$input = $this->_createTempFile('horde-pgp');
/* Encryption requires both keyrings. */
$pub_keyring = $this->_putInKeyring(array($params['pubkey']));
$sec_keyring = $this->_putInKeyring(array($params['privkey']), 'private');
/* Store message in temporary file. */
file_put_contents($input, $text);
/* Determine the signature type to use. */
$cmdline = array();
if (isset($params['sigtype']) &&
$params['sigtype'] == 'cleartext') {
$sign_type = '--clearsign';
} else {
$sign_type = '--detach-sign';
}
/* Additional GPG options. */
$cmdline += array(
'--armor',
'--batch',
'--passphrase-fd 0',
$sec_keyring,
$pub_keyring,
$sign_type,
$input
);
/* Sign the document. */
$result = $this->_callGpg($cmdline, 'w', $params['passphrase'], true, true);
if (empty($result->output)) {
$error = preg_replace('/\n.*/', '', $result->stderr);
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Could not PGP sign message: ") . $error);
}
return $result->output;
}
/**
* Decrypts an PGP encrypted message using a private/public keypair and a
* passhprase.
*
* @param string $text The text to be decrypted.
* @param array $params The parameters needed for decryption.
*
* Parameters:
* ===========
* 'type' => 'message' (REQUIRED)
* 'pubkey' => PGP public key. (REQUIRED for asymmetric encryption)
* 'privkey' => PGP private key. (REQUIRED for asymmetric encryption)
* 'passphrase' => Passphrase for PGP Key. (REQUIRED)
*
*
* @return stdClass An object with the following properties:
*
* 'message' - (string) The signature result text.
* 'result' - (boolean) The result of the signature test.
*
* @throws Horde_Crypt_Exception
*/
protected function _decryptMessage($text, $params)
{
/* Check for required parameters. */
if (!isset($params['passphrase']) && empty($params['no_passphrase'])) {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("A passphrase is required to decrypt a message."));
}
/* Create temp files. */
$input = $this->_createTempFile('horde-pgp');
/* Store message in file. */
file_put_contents($input, $text);
/* Build command line. */
$cmdline = array(
'--always-trust',
'--armor',
'--batch'
);
if (empty($params['no_passphrase'])) {
$cmdline[] = '--passphrase-fd 0';
}
if (!empty($params['pubkey']) && !empty($params['privkey'])) {
/* Decryption requires both keyrings. */
$pub_keyring = $this->_putInKeyring(array($params['pubkey']));
$sec_keyring = $this->_putInKeyring(array($params['privkey']), 'private');
$cmdline[] = $sec_keyring;
$cmdline[] = $pub_keyring;
}
$cmdline[] = '--decrypt';
$cmdline[] = $input;
/* Decrypt the document now. */
$language = getenv('LC_MESSAGES');
putenv('LC_MESSAGES=C');
if (empty($params['no_passphrase'])) {
$result = $this->_callGpg($cmdline, 'w', $params['passphrase'], true, true);
} else {
$result = $this->_callGpg($cmdline, 'r', null, true, true);
}
putenv('LC_MESSAGES=' . $language);
if (empty($result->output)) {
$error = preg_replace('/\n.*/', '', $result->stderr);
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Could not decrypt PGP data: ") . $error);
}
/* Create the return object. */
return $this->_checkSignatureResult($result->stderr, $result->output);
}
/**
* Decrypts an PGP signed message using a public key.
*
* @param string $text The text to be verified.
* @param array $params The parameters needed for verification.
*
* Parameters:
* ===========
* 'type' => 'signature' or 'detached-signature' (REQUIRED)
* 'pubkey' => PGP public key. (REQUIRED)
* 'signature' => PGP signature block. (REQUIRED for detached signature)
* 'charset' => charset of the message body (OPTIONAL)
*
*
* @return stdClass An object with the following properties:
*
* 'message' - (string) The signature result text.
* 'result' - (boolean) The result of the signature test.
*
* @throws Horde_Crypt_Exception
*/
protected function _decryptSignature($text, $params)
{
/* Check for required parameters. */
if (!isset($params['pubkey'])) {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("A public PGP key is required to verify a signed message."));
}
if (($params['type'] === 'detached-signature') &&
!isset($params['signature'])) {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("The detached PGP signature block is required to verify the signed message."));
}
/* Create temp files for input. */
$input = $this->_createTempFile('horde-pgp');
/* Store public key in temporary keyring. */
$keyring = $this->_putInKeyring($params['pubkey']);
/* Store the message in a temporary file. */
file_put_contents($input, $text);
/* Options for the GPG binary. */
$cmdline = array(
'--armor',
'--always-trust',
'--batch',
'--charset ' . (isset($params['charset']) ? $params['charset'] : 'UTF-8'),
$keyring,
'--verify'
);
/* Extra stuff to do if we are using a detached signature. */
if ($params['type'] === 'detached-signature') {
$sigfile = $this->_createTempFile('horde-pgp');
$cmdline[] = $sigfile . ' ' . $input;
file_put_contents($sigfile, $params['signature']);
} else {
$cmdline[] = $input;
}
/* Verify the signature. We need to catch standard error output,
* since this is where the signature information is sent. */
$language = getenv('LC_MESSAGES');
putenv('LC_MESSAGES=C');
$result = $this->_callGpg($cmdline, 'r', null, true, true);
putenv('LC_MESSAGES=' . $language);
return $this->_checkSignatureResult($result->stderr, $result->stderr);
}
/**
* Checks signature result from the GnuPG binary.
*
* @param string $result The signature result.
* @param string $message The decrypted message data.
*
* @return stdClass An object with the following properties:
* - message: (string) The signature result text.
* - result: (string) The result of the signature test.
*
* @throws Horde_Crypt_Exception
*/
protected function _checkSignatureResult($result, $message = null)
{
/* Good signature:
* gpg: Good signature from "blah blah blah (Comment)"
* Bad signature:
* gpg: BAD signature from "blah blah blah (Comment)" */
if (strpos($result, 'gpg: BAD signature') !== false) {
throw new Horde_Crypt_Exception($result);
}
$ob = new stdClass;
$ob->message = $message;
$ob->result = $result;
return $ob;
}
/**
* Signs a MIME part using PGP.
*
* @param Horde_Mime_Part $mime_part The object to sign.
* @param array $params The parameters required for signing.
* @see _encryptSignature().
*
* @return mixed A Horde_Mime_Part object that is signed according to RFC
* 3156.
* @throws Horde_Crypt_Exception
*/
public function signMIMEPart($mime_part, $params = array())
{
$params = array_merge($params, array('type' => 'signature', 'sigtype' => 'detach'));
/* RFC 3156 Requirements for a PGP signed message:
* + Content-Type params 'micalg' & 'protocol' are REQUIRED.
* + The digitally signed message MUST be constrained to 7 bits.
* + The MIME headers MUST be a part of the signed data. */
$msg_sign = $this->encrypt($mime_part->toString(array('headers' => true, 'canonical' => true, 'encode' => Horde_Mime_Part::ENCODE_7BIT)), $params);
/* Add the PGP signature. */
$pgp_sign = new Horde_Mime_Part();
$pgp_sign->setType('application/pgp-signature');
$pgp_sign->setHeaderCharset('UTF-8');
$pgp_sign->setDisposition('inline');
$pgp_sign->setDescription(Horde_Crypt_Translation::t("PGP Digital Signature"));
$pgp_sign->setContents($msg_sign, array('encoding' => '7bit'));
/* Get the algorithim information from the signature. Since we are
* analyzing a signature packet, we need to use the special keyword
* '_SIGNATURE' - see Horde_Crypt_Pgp. */
$sig_info = $this->pgpPacketSignature($msg_sign, '_SIGNATURE');
/* Setup the multipart MIME Part. */
$part = new Horde_Mime_Part();
$part->setType('multipart/signed');
$part->setContents("This message is in MIME format and has been PGP signed.\n");
$part->addPart($mime_part);
$part->addPart($pgp_sign);
$part->setContentTypeParameter('protocol', 'application/pgp-signature');
$part->setContentTypeParameter('micalg', $sig_info['micalg']);
return $part;
}
/**
* Encrypts a MIME part using PGP.
*
* @param Horde_Mime_Part $mime_part The object to encrypt.
* @param array $params The parameters required for
* encryption.
* @see _encryptMessage().
*
* @return mixed A Horde_Mime_Part object that is encrypted according to
* RFC 3156.
* @throws Horde_Crypt_Exception
*/
public function encryptMIMEPart($mime_part, $params = array())
{
$params = array_merge($params, array('type' => 'message'));
$signenc_body = $mime_part->toString(array('headers' => true, 'canonical' => true));
$message_encrypt = $this->encrypt($signenc_body, $params);
/* Set up MIME Structure according to RFC 3156. */
$part = new Horde_Mime_Part();
$part->setType('multipart/encrypted');
$part->setHeaderCharset('UTF-8');
$part->setContentTypeParameter('protocol', 'application/pgp-encrypted');
$part->setDescription(Horde_Crypt_Translation::t("PGP Encrypted Data"));
$part->setContents("This message is in MIME format and has been PGP encrypted.\n");
$part1 = new Horde_Mime_Part();
$part1->setType('application/pgp-encrypted');
$part1->setCharset(null);
$part1->setContents("Version: 1\n", array('encoding' => '7bit'));
$part->addPart($part1);
$part2 = new Horde_Mime_Part();
$part2->setType('application/octet-stream');
$part2->setCharset(null);
$part2->setContents($message_encrypt, array('encoding' => '7bit'));
$part2->setDisposition('inline');
$part->addPart($part2);
return $part;
}
/**
* Signs and encrypts a MIME part using PGP.
*
* @param Horde_Mime_Part $mime_part The object to sign and encrypt.
* @param array $sign_params The parameters required for
* signing. @see _encryptSignature().
* @param array $encrypt_params The parameters required for
* encryption. @see _encryptMessage().
*
* @return mixed A Horde_Mime_Part object that is signed and encrypted
* according to RFC 3156.
* @throws Horde_Crypt_Exception
*/
public function signAndEncryptMIMEPart($mime_part, $sign_params = array(),
$encrypt_params = array())
{
/* RFC 3156 requires that the entire signed message be encrypted. We
* need to explicitly call using Horde_Crypt_Pgp:: because we don't
* know whether a subclass has extended these methods. */
$part = $this->signMIMEPart($mime_part, $sign_params);
$part = $this->encryptMIMEPart($part, $encrypt_params);
$part->setContents("This message is in MIME format and has been PGP signed and encrypted.\n");
$part->setCharset($this->_params['email_charset']);
$part->setDescription(Horde_String::convertCharset(Horde_Crypt_Translation::t("PGP Signed/Encrypted Data"), 'UTF-8', $this->_params['email_charset']));
return $part;
}
/**
* Generates a Horde_Mime_Part object, in accordance with RFC 3156, that
* contains a public key.
*
* @param string $key The public key.
*
* @return Horde_Mime_Part An object that contains the public key.
*/
public function publicKeyMIMEPart($key)
{
$part = new Horde_Mime_Part();
$part->setType('application/pgp-keys');
$part->setHeaderCharset('UTF-8');
$part->setDescription(Horde_Crypt_Translation::t("PGP Public Key"));
$part->setContents($key, array('encoding' => '7bit'));
return $part;
}
/**
* Function that handles interfacing with the GnuPG binary.
*
* @param array $options Options and commands to pass to GnuPG.
* @param string $mode 'r' to read from stdout, 'w' to write to
* stdin.
* @param array $input Input to write to stdin.
* @param boolean $output Collect and store output in object returned?
* @param boolean $stderr Collect and store stderr in object returned?
* @param boolean $verbose Run GnuPG with verbose flag?
*
* @return stdClass Class with members output, stderr, and stdout.
* @throws Horde_Crypt_Exception
*/
protected function _callGpg($options, $mode, $input = array(),
$output = false, $stderr = false,
$verbose = false)
{
$data = new stdClass;
$data->output = null;
$data->stderr = null;
$data->stdout = null;
/* Verbose output? */
if (!$verbose) {
array_unshift($options, '--quiet');
}
/* Create temp files for output. */
if ($output) {
$output_file = $this->_createTempFile('horde-pgp', false);
array_unshift($options, '--output ' . $output_file);
/* Do we need standard error output? */
if ($stderr) {
$stderr_file = $this->_createTempFile('horde-pgp', false);
$options[] = '2> ' . $stderr_file;
}
}
/* Silence errors if not requested. */
if (!$output || !$stderr) {
$options[] = '2> /dev/null';
}
/* Build the command line string now. */
$cmdline = implode(' ', array_merge($this->_gnupg, $options));
if ($mode == 'w') {
if ($fp = popen($cmdline, 'w')) {
$win32 = !strncasecmp(PHP_OS, 'WIN', 3);
if (!is_array($input)) {
$input = array($input);
}
foreach ($input as $line) {
if ($win32 && (strpos($line, "\x0d\x0a") !== false)) {
$chunks = explode("\x0d\x0a", $line);
foreach ($chunks as $chunk) {
fputs($fp, $chunk . "\n");
}
} else {
fputs($fp, $line . "\n");
}
}
} else {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Error while talking to pgp binary."));
}
} elseif ($mode == 'r') {
if ($fp = popen($cmdline, 'r')) {
while (!feof($fp)) {
$data->stdout .= fgets($fp, 1024);
}
} else {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Error while talking to pgp binary."));
}
}
pclose($fp);
if ($output) {
$data->output = file_get_contents($output_file);
unlink($output_file);
if ($stderr) {
$data->stderr = file_get_contents($stderr_file);
unlink($stderr_file);
}
}
return $data;
}
/**
* Generates a public key from a private key.
*
* @param string $data Armor text of private key.
*
* @return string Armor text of public key, or null if it could not be
* generated.
*/
public function getPublicKeyFromPrivateKey($data)
{
$this->_putInKeyring(array($data), 'private');
$fingerprints = $this->getFingerprintsFromKey($data);
reset($fingerprints);
$cmdline = array(
'--armor',
'--export',
key($fingerprints)
);
$result = $this->_callGpg($cmdline, 'r', array(), true, true);
return empty($result->output)
? null
: $result->output;
}
/**
* @deprecated
*/
public function generateRevocation($key, $email, $passphrase)
{
throw new Horde_Crypt_Exception('Not supported');
}
}
Horde_Crypt-2.4.0/lib/Horde/Crypt/Smime.php 0000664 0001750 0001750 00000072444 12242643672 016561 0 ustar jan jan
* @author Michael Slusarz
* cert - (string) The certificate of the signer stored in the message (in
* PEM format).
* email - (string) The email of the signing person.
* msg - (string) Status string.
* verify - (boolean) True if certificate was verified.
*
* @throws Horde_Crypt_Exception
*/
public function verify($text, $certs)
{
/* Check for availability of OpenSSL PHP extension. */
$this->checkForOpenSSL();
/* Create temp files for input/output. */
$input = $this->_createTempFile('horde-smime');
$output = $this->_createTempFile('horde-smime');
/* Write text to file */
file_put_contents($input, $text);
unset($text);
$root_certs = array();
if (!is_array($certs)) {
$certs = array($certs);
}
foreach ($certs as $file) {
if (file_exists($file)) {
$root_certs[] = $file;
}
}
$ob = new stdClass;
if (!empty($root_certs) &&
(openssl_pkcs7_verify($input, 0, $output, $root_certs) === true)) {
/* Message verified */
$ob->msg = Horde_Crypt_Translation::t("Message verified successfully.");
$ob->verify = true;
} else {
/* Try again without verfying the signer's cert */
$result = openssl_pkcs7_verify($input, PKCS7_NOVERIFY, $output);
if ($result === -1) {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Verification failed - an unknown error has occurred."));
} elseif ($result === false) {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Verification failed - this message may have been tampered with."));
}
$ob->msg = Horde_Crypt_Translation::t("Message verified successfully but the signer's certificate could not be verified.");
$ob->verify = false;
}
$ob->cert = file_get_contents($output);
$ob->email = $this->getEmailFromKey($ob->cert);
return $ob;
}
/**
* Extract the contents from signed S/MIME data.
*
* @param string $data The signed S/MIME data.
* @param string $sslpath The path to the OpenSSL binary.
*
* @return string The contents embedded in the signed data.
* @throws Horde_Crypt_Exception
*/
public function extractSignedContents($data, $sslpath)
{
/* Check for availability of OpenSSL PHP extension. */
$this->checkForOpenSSL();
/* Create temp files for input/output. */
$input = $this->_createTempFile('horde-smime');
$output = $this->_createTempFile('horde-smime');
/* Write text to file. */
file_put_contents($input, $data);
unset($data);
exec($sslpath . ' smime -verify -noverify -nochain -in ' . $input . ' -out ' . $output);
$ret = file_get_contents($output);
if ($ret) {
return $ret;
}
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("OpenSSL error: Could not extract data from signed S/MIME part."));
}
/**
* Sign a MIME part using S/MIME. This produces S/MIME Version 3.2
* compatible data (see RFC 5751 [3.4]).
*
* @param Horde_Mime_Part $mime_part The object to sign.
* @param array $params The parameters required for signing.
*
* @return Horde_Mime_Part A signed MIME part object.
* @throws Horde_Crypt_Exception
*/
public function signMIMEPart($mime_part, $params)
{
/* Sign the part as a message */
$message = $this->encrypt($mime_part->toString(array('headers' => true, 'canonical' => true)), $params);
/* Break the result into its components */
$mime_message = Horde_Mime_Part::parseMessage($message, array('forcemime' => true));
$smime_sign = $mime_message->getPart('2');
$smime_sign->setDescription(Horde_Crypt_Translation::t("S/MIME Signature"));
$smime_sign->setTransferEncoding('base64', array('send' => true));
$smime_part = new Horde_Mime_Part();
$smime_part->setType('multipart/signed');
$smime_part->setContents("This is a cryptographically signed message in MIME format.\n");
$smime_part->setContentTypeParameter('protocol', 'application/pkcs7-signature');
// Per RFC 5751 [3.4.3.2], 'sha1' has been deprecated for 'sha-1'.
$smime_part->setContentTypeParameter('micalg', 'sha-1');
$smime_part->addPart($mime_part);
$smime_part->addPart($smime_sign);
return $smime_part;
}
/**
* Encrypt a MIME part using S/MIME. This produces S/MIME Version 3.2
* compatible data (see RFC 5751 [3.3]).
*
* @param Horde_Mime_Part $mime_part The object to encrypt.
* @param array $params The parameters required for
* encryption.
*
* @return Horde_Mime_Part An encrypted MIME part object.
* @throws Horde_Crypt_Exception
*/
public function encryptMIMEPart($mime_part, $params = array())
{
/* Sign the part as a message */
$message = $this->encrypt($mime_part->toString(array('headers' => true, 'canonical' => true)), $params);
$msg = new Horde_Mime_Part();
$msg->setCharset($this->_params['email_charset']);
$msg->setHeaderCharset('UTF-8');
$msg->setDescription(Horde_Crypt_Translation::t("S/MIME Encrypted Message"));
$msg->setDisposition('inline');
$msg->setType('application/pkcs7-mime');
$msg->setContentTypeParameter('smime-type', 'enveloped-data');
$msg->setContents(substr($message, strpos($message, "\n\n") + 2), array('encoding' => 'base64'));
return $msg;
}
/**
* Encrypt a message in S/MIME format using a public key.
*
* @param string $text The text to be encrypted.
* @param array $params The parameters needed for encryption.
*
* Parameters:
* ===========
* 'type' => 'message' (REQUIRED)
* 'pubkey' => public key (REQUIRED)
*
*
* @return string The encrypted message.
* @throws Horde_Crypt_Exception
*/
protected function _encryptMessage($text, $params)
{
/* Check for required parameters. */
if (!isset($params['pubkey'])) {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("A public S/MIME key is required to encrypt a message."));
}
/* Create temp files for input/output. */
$input = $this->_createTempFile('horde-smime');
$output = $this->_createTempFile('horde-smime');
/* Store message in file. */
file_put_contents($input, $text);
unset($text);
/* Encrypt the document. */
$ciphers = array(
OPENSSL_CIPHER_3DES,
OPENSSL_CIPHER_DES,
OPENSSL_CIPHER_RC2_128,
OPENSSL_CIPHER_RC2_64,
OPENSSL_CIPHER_RC2_40
);
foreach ($ciphers as $val) {
if (openssl_pkcs7_encrypt($input, $output, $params['pubkey'], array(), 0, $val)) {
$result = file_get_contents($output);
if (!empty($result)) {
return $this->_fixContentType($result, 'encrypt');
}
}
}
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Could not S/MIME encrypt message."));
}
/**
* Sign a message in S/MIME format using a private key.
*
* @param string $text The text to be signed.
* @param array $params The parameters needed for signing.
*
* Parameters:
* ===========
* 'certs' => Additional signing certs (Optional)
* 'passphrase' => Passphrase for key (REQUIRED)
* 'privkey' => Private key (REQUIRED)
* 'pubkey' => Public key (REQUIRED)
* 'sigtype' => Determine the signature type to use. (Optional)
* 'cleartext' -- Make a clear text signature
* 'detach' -- Make a detached signature (DEFAULT)
* 'type' => 'signature' (REQUIRED)
*
*
* @return string The signed message.
* @throws Horde_Crypt_Exception
*/
protected function _encryptSignature($text, $params)
{
/* Check for required parameters. */
if (!isset($params['pubkey']) ||
!isset($params['privkey']) ||
!array_key_exists('passphrase', $params)) {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("A public S/MIME key, private S/MIME key, and passphrase are required to sign a message."));
}
/* Create temp files for input/output/certificates. */
$input = $this->_createTempFile('horde-smime');
$output = $this->_createTempFile('horde-smime');
$certs = $this->_createTempFile('horde-smime');
/* Store message in temporary file. */
file_put_contents($input, $text);
unset($text);
/* Store additional certs in temporary file. */
if (!empty($params['certs'])) {
file_put_contents($certs, $params['certs']);
}
/* Determine the signature type to use. */
$flags = (isset($params['sigtype']) && ($params['sigtype'] == 'cleartext'))
? PKCS7_TEXT
: PKCS7_DETACHED;
$privkey = (is_null($params['passphrase'])) ? $params['privkey'] : array($params['privkey'], $params['passphrase']);
if (empty($params['certs'])) {
$res = openssl_pkcs7_sign($input, $output, $params['pubkey'], $privkey, array(), $flags);
} else {
$res = openssl_pkcs7_sign($input, $output, $params['pubkey'], $privkey, array(), $flags, $certs);
}
if (!$res) {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Could not S/MIME sign message."));
}
/* Output from openssl_pkcs7_sign may contain both \n and \r\n EOLs.
* Canonicalize to \r\n. */
$fp = fopen($output, 'r');
stream_filter_register('horde_eol', 'Horde_Stream_Filter_Eol');
stream_filter_append($fp, 'horde_eol');
$data = stream_get_contents($fp);
fclose($fp);
return $this->_fixContentType($data, 'signature');
}
/**
* Decrypt an S/MIME encrypted message using a private/public keypair
* and a passhprase.
*
* @param string $text The text to be decrypted.
* @param array $params The parameters needed for decryption.
*
* Parameters:
* ===========
* 'type' => 'message' (REQUIRED)
* 'pubkey' => public key. (REQUIRED)
* 'privkey' => private key. (REQUIRED)
* 'passphrase' => Passphrase for Key. (REQUIRED)
*
*
* @return string The decrypted message.
* @throws Horde_Crypt_Exception
*/
protected function _decryptMessage($text, $params)
{
/* Check for required parameters. */
if (!isset($params['pubkey']) ||
!isset($params['privkey']) ||
!array_key_exists('passphrase', $params)) {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("A public S/MIME key, private S/MIME key, and passphrase are required to decrypt a message."));
}
/* Create temp files for input/output. */
$input = $this->_createTempFile('horde-smime');
$output = $this->_createTempFile('horde-smime');
/* Store message in file. */
file_put_contents($input, $text);
unset($text);
$privkey = is_null($params['passphrase'])
? $params['privkey']
: array($params['privkey'], $params['passphrase']);
if (openssl_pkcs7_decrypt($input, $output, $params['pubkey'], $privkey)) {
return file_get_contents($output);
}
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Could not decrypt S/MIME data."));
}
/**
* Sign and Encrypt a MIME part using S/MIME.
*
* @param Horde_Mime_Part $mime_part The object to sign and encrypt.
* @param array $sign_params The parameters required for
* signing. @see _encryptSignature().
* @param array $encrypt_params The parameters required for
* encryption.
* @see _encryptMessage().
*
* @return mixed A Horde_Mime_Part object that is signed and encrypted.
* @throws Horde_Crypt_Exception
*/
public function signAndEncryptMIMEPart($mime_part, $sign_params = array(),
$encrypt_params = array())
{
$part = $this->signMIMEPart($mime_part, $sign_params);
return $this->encryptMIMEPart($part, $encrypt_params);
}
/**
* Convert a PEM format certificate to readable HTML version.
*
* @param string $cert PEM format certificate.
*
* @return string HTML detailing the certificate.
*/
public function certToHTML($cert)
{
$fieldnames = array(
/* Common Fields */
'description' => Horde_Crypt_Translation::t("Description"),
'emailAddress' => Horde_Crypt_Translation::t("Email Address"),
'commonName' => Horde_Crypt_Translation::t("Common Name"),
'organizationName' => Horde_Crypt_Translation::t("Organisation"),
'organizationalUnitName' => Horde_Crypt_Translation::t("Organisational Unit"),
'countryName' => Horde_Crypt_Translation::t("Country"),
'stateOrProvinceName' => Horde_Crypt_Translation::t("State or Province"),
'localityName' => Horde_Crypt_Translation::t("Location"),
'streetAddress' => Horde_Crypt_Translation::t("Street Address"),
'telephoneNumber' => Horde_Crypt_Translation::t("Telephone Number"),
'surname' => Horde_Crypt_Translation::t("Surname"),
'givenName' => Horde_Crypt_Translation::t("Given Name"),
/* X590v3 Extensions */
'exendedtKeyUsage' => Horde_Crypt_Translation::t("X509v3 Extended Key Usage"),
'basicConstraints' => Horde_Crypt_Translation::t("X509v3 Basic Constraints"),
'subjectAltName' => Horde_Crypt_Translation::t("X509v3 Subject Alternative Name"),
'subjectKeyIdentifier' => Horde_Crypt_Translation::t("X509v3 Subject Key Identifier"),
'certificatePolicies' => Horde_Crypt_Translation::t("Certificate Policies"),
'crlDistributionPoints' => Horde_Crypt_Translation::t("CRL Distribution Points"),
'keyUsage' => Horde_Crypt_Translation::t("Key Usage")
);
$details = $this->parseCert($cert);
$text = '';
/* Subject (a/k/a Certificate Owner) */
$text .= "" . Horde_Crypt_Translation::t("Certificate Owner") . ":\n";
foreach ($details['subject'] as $key => $value) {
$value = htmlspecialchars($this->_implodeValues($value));
$text .= isset($fieldnames[$key])
? sprintf(" %s: %s\n", htmlspecialchars($fieldnames[$key]), $value)
: sprintf(" *%s: %s\n", htmlspecialchars($key), $value);
}
$text .= "\n";
/* Issuer */
$text .= "" . Horde_Crypt_Translation::t("Issuer") . ":\n";
foreach ($details['issuer'] as $key => $value) {
$value = htmlspecialchars($this->_implodeValues($value));
$text .= isset($fieldnames[$key])
? sprintf(" %s: %s\n", htmlspecialchars($fieldnames[$key]), $value)
: sprintf(" *%s: %s\n", htmlspecialchars($key), $value);
}
$text .= "\n";
/* Dates */
$text .= "" . Horde_Crypt_Translation::t("Validity") . ":\n" .
sprintf(" %s: %s\n", Horde_Crypt_Translation::t("Not Before"), strftime("%x %X", $details['validity']['notbefore']->getTimestamp())) .
sprintf(" %s: %s\n", Horde_Crypt_Translation::t("Not After"), strftime("%x %X", $details['validity']['notafter']->getTimestamp())) .
"\n";
/* X509v3 extensions */
if (!empty($details['extensions'])) {
$text .= "" . Horde_Crypt_Translation::t("X509v3 extensions") . ":\n";
foreach ($details['extensions'] as $key => $value) {
$value = htmlspecialchars(trim($this->_implodeValues($value, 6)));
$text .= isset($fieldnames[$key])
? sprintf(" %s:\n %s\n", htmlspecialchars($fieldnames[$key]), $value)
: sprintf(" *%s:\n %s\n", htmlspecialchars($key), $value);
}
$text .= "\n";
}
/* Certificate Details */
$text .= "" . Horde_Crypt_Translation::t("Certificate Details") . ":\n" .
sprintf(" %s: %d\n", Horde_Crypt_Translation::t("Version"), $details['version']) .
sprintf(" %s: %d\n", Horde_Crypt_Translation::t("Serial Number"), $details['serialNumber']);
return $text . "\n";
}
/**
* Formats a multi-value cert field.
*
* @param array|string $value A cert field value.
* @param integer $indent The indention level.
*
* @return string The formatted cert field value(s).
*/
protected function _implodeValues($value, $indent = 4)
{
if (is_array($value)) {
$value = "\n" . str_repeat(' ', $indent)
. implode("\n" . str_repeat(' ', $indent), $value);
}
return $value;
}
/**
* Extract the contents of a PEM format certificate to an array.
*
* @param string $cert PEM format certificate.
*
* @return array All extractable information about the certificate.
*/
public function parseCert($cert)
{
$data = openssl_x509_parse($cert, false);
if (!$data) {
throw new Horde_Crypt_Exception(sprintf(Horde_Crypt_Translation::t("Error parsing S/MIME certficate: %s"), openssl_error_string()));
}
$details = array(
'extensions' => $data['extensions'],
'issuer' => $data['issuer'],
'serialNumber' => $data['serialNumber'],
'subject' => $data['subject'],
'validity' => array(
'notafter' => new DateTime('@' . $data['validTo_time_t']),
'notbefore' => new DateTime('@' . $data['validFrom_time_t'])
),
'version' => $data['version']
);
// Add additional fields for BC purposes.
$details['certificate'] = $details;
$bc_changes = array(
'emailAddress' => 'Email',
'commonName' => 'CommonName',
'organizationName' => 'Organisation',
'organizationalUnitName' => 'OrganisationalUnit',
'countryName' => 'Country',
'stateOrProvinceName' => 'StateOrProvince',
'localityName' => 'Location',
'streetAddress' => 'StreetAddress',
'telephoneNumber' => 'TelephoneNumber',
'surname' => 'Surname',
'givenName' => 'GivenName'
);
foreach (array('issuer', 'subject') as $val) {
foreach (array_keys($details[$val]) as $key) {
if (isset($bc_changes[$key])) {
$details['certificate'][$val][$bc_changes[$key]] = $details[$val][$key];
unset($details['certificate'][$val][$key]);
}
}
}
return $details;
}
/**
* Decrypt an S/MIME signed message using a public key.
*
* @param string $text The text to be verified.
* @param array $params The parameters needed for verification.
*
* @return string The verification message.
* @throws Horde_Crypt_Exception
*/
protected function _decryptSignature($text, $params)
{
throw new Horde_Crypt_Exception('_decryptSignature() ' . Horde_Crypt_Translation::t("not yet implemented"));
}
/**
* Check for the presence of the OpenSSL extension to PHP.
*
* @throws Horde_Crypt_Exception
*/
public function checkForOpenSSL()
{
if (!Horde_Util::extensionExists('openssl')) {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("The openssl module is required for the Horde_Crypt_Smime:: class."));
}
}
/**
* Extract the email address from a public key.
*
* @param string $key The public key.
*
* @return mixed Returns the first email address found, or null if
* there are none.
*/
public function getEmailFromKey($key)
{
$key_info = openssl_x509_parse($key);
if (!is_array($key_info)) {
return null;
}
if (isset($key_info['subject'])) {
if (isset($key_info['subject']['Email'])) {
return $key_info['subject']['Email'];
} elseif (isset($key_info['subject']['emailAddress'])) {
return $key_info['subject']['emailAddress'];
}
}
// Check subjectAltName per http://www.ietf.org/rfc/rfc3850.txt
if (isset($key_info['extensions']['subjectAltName'])) {
$names = preg_split('/\s*,\s*/', $key_info['extensions']['subjectAltName'], -1, PREG_SPLIT_NO_EMPTY);
foreach ($names as $name) {
if (strpos($name, ':') === false) {
continue;
}
list($kind, $value) = explode(':', $name, 2);
if (Horde_String::lower($kind) == 'email') {
return $value;
}
}
}
return null;
}
/**
* Convert a PKCS 12 encrypted certificate package into a private key,
* public key, and any additional keys.
*
* @param string $pkcs12 The PKCS 12 data.
* @param array $params The parameters needed for parsing.
*
* Parameters:
* ===========
* 'sslpath' => The path to the OpenSSL binary. (REQUIRED)
* 'password' => The password to use to decrypt the data. (Optional)
* 'newpassword' => The password to use to encrypt the private key.
* (Optional)
*
*
* @return stdClass An object.
* 'private' - The private key in PEM format.
* 'public' - The public key in PEM format.
* 'certs' - An array of additional certs.
* @throws Horde_Crypt_Exception
*/
public function parsePKCS12Data($pkcs12, $params)
{
/* Check for availability of OpenSSL PHP extension. */
$this->checkForOpenSSL();
if (!isset($params['sslpath'])) {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("No path to the OpenSSL binary provided. The OpenSSL binary is necessary to work with PKCS 12 data."));
}
$sslpath = escapeshellcmd($params['sslpath']);
/* Create temp files for input/output. */
$input = $this->_createTempFile('horde-smime');
$output = $this->_createTempFile('horde-smime');
$ob = new stdClass;
/* Write text to file */
file_put_contents($input, $pkcs12);
unset($pkcs12);
/* Extract the private key from the file first. */
$cmdline = $sslpath . ' pkcs12 -in ' . $input . ' -out ' . $output . ' -nocerts';
if (isset($params['password'])) {
$cmdline .= ' -passin stdin';
if (!empty($params['newpassword'])) {
$cmdline .= ' -passout stdin';
} else {
$cmdline .= ' -nodes';
}
} else {
$cmdline .= ' -nodes';
}
if ($fd = popen($cmdline, 'w')) {
fwrite($fd, $params['password'] . "\n");
if (!empty($params['newpassword'])) {
fwrite($fd, $params['newpassword'] . "\n");
}
pclose($fd);
} else {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Error while talking to smime binary."));
}
$ob->private = trim(file_get_contents($output));
if (empty($ob->private)) {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Password incorrect"));
}
/* Extract the client public key next. */
$cmdline = $sslpath . ' pkcs12 -in ' . $input . ' -out ' . $output . ' -nokeys -clcerts';
if (isset($params['password'])) {
$cmdline .= ' -passin stdin';
}
if ($fd = popen($cmdline, 'w')) {
fwrite($fd, $params['password'] . "\n");
pclose($fd);
} else {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Error while talking to smime binary."));
}
$ob->public = trim(file_get_contents($output));
/* Extract the CA public key next. */
$cmdline = $sslpath . ' pkcs12 -in ' . $input . ' -out ' . $output . ' -nokeys -cacerts';
if (isset($params['password'])) {
$cmdline .= ' -passin stdin';
}
if ($fd = popen($cmdline, 'w')) {
fwrite($fd, $params['password'] . "\n");
pclose($fd);
} else {
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("Error while talking to smime binary."));
}
$ob->certs = trim(file_get_contents($output));
return $ob;
}
/**
* The Content-Type parameters PHP's openssl_pkcs7_* functions return are
* deprecated. Fix these headers to the correct ones (see RFC 2311).
*
* @param string $text The PKCS7 data.
* @param string $type Is this 'message' or 'signature' data?
*
* @return string The PKCS7 data with the correct Content-Type parameter.
*/
protected function _fixContentType($text, $type)
{
if ($type == 'message') {
$from = 'application/x-pkcs7-mime';
$to = 'application/pkcs7-mime';
} else {
$from = 'application/x-pkcs7-signature';
$to = 'application/pkcs7-signature';
}
return str_replace('Content-Type: ' . $from, 'Content-Type: ' . $to, $text);
}
}
Horde_Crypt-2.4.0/lib/Horde/Crypt/Translation.php 0000664 0001750 0001750 00000003356 12242643672 020001 0 ustar jan jan
* @category Horde
* @package Crypt
*/
class Horde_Crypt_Translation extends Horde_Translation
{
/**
* Returns the translation of a message.
*
* @var string $message The string to translate.
*
* @return string The string translation, or the original string if no
* translation exists.
*/
static public function t($message)
{
self::$_domain = 'Horde_Crypt';
self::$_directory = '@data_dir@' == '@'.'data_dir'.'@' ? __DIR__ . '/../../../locale' : '@data_dir@/Horde_Crypt/locale';
return parent::t($message);
}
/**
* Returns the plural translation of a message.
*
* @param string $singular The singular version to translate.
* @param string $plural The plural version to translate.
* @param integer $number The number that determines singular vs. plural.
*
* @return string The string translation, or the original string if no
* translation exists.
*/
static public function ngettext($singular, $plural, $number)
{
self::$_domain = 'Horde_Crypt';
self::$_directory = '@data_dir@' == '@'.'data_dir'.'@' ? __DIR__ . '/../../../locale' : '@data_dir@/Horde_Crypt/locale';
return parent::ngettext($singular, $plural, $number);
}
}
Horde_Crypt-2.4.0/lib/Horde/Crypt.php 0000664 0001750 0001750 00000007663 12242643672 015510 0 ustar jan jan
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Crypt
*/
class Horde_Crypt
{
/**
* Configuration parameters.
*
* @var array
*/
protected $_params = array();
/**
* The temporary directory to use.
*
* @var string
*/
protected $_tempdir;
/**
* Attempts to return a concrete Horde_Crypt instance based on $driver.
*
* @param string $driver Either a driver name, or the full class name to
* use (class must extend Horde_Crypt).
* @param array $params A hash containing any additional configuration
* or parameters a subclass might need.
*
* @return Horde_Crypt The newly created concrete instance.
* @throws Horde_Crypt_Exception
*/
static public function factory($driver, $params = array())
{
/* Return a base Horde_Crypt object if no driver is specified. */
if (empty($driver) || (strcasecmp($driver, 'none') == 0)) {
return new Horde_Crypt();
}
/* Base drivers (in Crypt/ directory). */
$class = __CLASS__ . '_' . ucfirst(basename($driver));
if (class_exists($class)) {
return new $class($params);
}
/* Explicit class name, */
$class = $driver;
if (class_exists($class)) {
return new $class($params);
}
throw new Horde_Crypt_Exception(__CLASS__ . ': Class definition of ' . $driver . ' not found.');
}
/**
* Constructor.
*
* @param array $params Configuration parameters:
*
* email_charset - (string) The default email charset.
* DEFAULT: NONE
* temp - (string) [REQUIRED] Location of temporary directory.
*
*
* @throws InvalidArgumentException
*/
public function __construct(array $params = array())
{
if (empty($params['temp'])) {
throw new InvalidArgumentException('A temporary directory must be provided.');
}
$this->_tempdir = Horde_Util::createTempDir(true, $params['temp']);
$this->_params = array_merge(array(
'email_charset' => null,
), $params);
}
/**
* Encrypt the requested data.
* This method should be provided by all classes that extend Horde_Crypt.
*
* @param string $data The data to encrypt.
* @param array $params An array of arguments needed to encrypt the data.
*
* @return array The encrypted data.
*/
public function encrypt($data, $params = array())
{
return $data;
}
/**
* Decrypt the requested data.
* This method should be provided by all classes that extend Horde_Crypt.
*
* @param string $data The data to decrypt.
* @param array $params An array of arguments needed to decrypt the data.
*
* @return array The decrypted data.
* @throws Horde_Crypt_Exception
*/
public function decrypt($data, $params = array())
{
return $data;
}
/**
* Create a temporary file that will be deleted at the end of this
* process.
*
* @param string $descrip Description string to use in filename.
* @param boolean $delete Delete the file automatically?
*
* @return string Filename of a temporary file.
*/
protected function _createTempFile($descrip = 'horde-crypt',
$delete = true)
{
return Horde_Util::getTempFile($descrip, $delete, $this->_tempdir, true);
}
}
Horde_Crypt-2.4.0/locale/ar/LC_MESSAGES/Horde_Crypt.mo 0000664 0001750 0001750 00000000705 12242643672 020262 0 ustar jan jan 4 L ` a f B l
Name Never Project-Id-Version: Horde_Crypt
Report-Msgid-Bugs-To: dev@lists.horde.org
POT-Creation-Date: 2010-10-13 01:27+0200
PO-Revision-Date: 2010-10-13 01:27+0200
Last-Translator: Automatically generated
Language-Team: i18n@lists.horde.org
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
الاسم أبداً Horde_Crypt-2.4.0/locale/ar/LC_MESSAGES/Horde_Crypt.po 0000664 0001750 0001750 00000021375 12242643672 020273 0 ustar jan jan # Arabic translations for Horde_Crypt module.
# Copyright 2010-2013 Horde LLC (http://www.horde.org/)
# This file is distributed under the same license as the Horde_Crypt module.
# Automatically generated, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: Horde_Crypt\n"
"Report-Msgid-Bugs-To: dev@lists.horde.org\n"
"POT-Creation-Date: 2010-10-13 01:27+0200\n"
"PO-Revision-Date: 2010-10-13 01:27+0200\n"
"Last-Translator: Automatically generated\n"
"Language-Team: i18n@lists.horde.org\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: lib/Horde/Crypt/Smime.php:614
#, php-format
msgid "%s Fingerprint"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1240
msgid "A passphrase is required to decrypt a message."
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1307
msgid "A public PGP key is required to verify a signed message."
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1164
msgid ""
"A public PGP key, private PGP key, and passphrase are required to sign a "
"message."
msgstr ""
#: lib/Horde/Crypt/Smime.php:311
msgid "A public S/MIME key is required to encrypt a message."
msgstr ""
#: lib/Horde/Crypt/Smime.php:422
msgid ""
"A public S/MIME key, private S/MIME key, and passphrase are required to "
"decrypt a message."
msgstr ""
#: lib/Horde/Crypt/Smime.php:360
msgid ""
"A public S/MIME key, private S/MIME key, and passphrase are required to sign "
"a message."
msgstr ""
#: lib/Horde/Crypt/Smime.php:506
msgid "CRL Distribution Points"
msgstr ""
#: lib/Horde/Crypt/Smime.php:609
msgid "Certificate Details"
msgstr ""
#: lib/Horde/Crypt/Smime.php:520
msgid "Certificate Owner"
msgstr ""
#: lib/Horde/Crypt/Smime.php:505
msgid "Certificate Policies"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:426
#, fuzzy
msgid "Comment"
msgstr "الأوامر:"
#: lib/Horde/Crypt/Smime.php:475
msgid "Common Name"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:939
#, fuzzy
msgid "Connection refused to the public keyserver."
msgstr "حصل خطأ خلال الإتصال بمخدم الـ FTP."
#: lib/Horde/Crypt/Pgp.php:950
#, php-format
msgid "Connection refused to the public keyserver. Reason: %s (%s)"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1132
msgid "Could not PGP encrypt message: "
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1201
msgid "Could not PGP sign message: "
msgstr ""
#: lib/Horde/Crypt/Smime.php:330
msgid "Could not S/MIME encrypt message."
msgstr ""
#: lib/Horde/Crypt/Smime.php:391
msgid "Could not S/MIME sign message."
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1276
#, fuzzy
msgid "Could not decrypt PGP data: "
msgstr "لا إمكانية لنسخ %s إلى %s"
#: lib/Horde/Crypt/Smime.php:440
msgid "Could not decrypt S/MIME data."
msgstr ""
#: lib/Horde/Crypt/Pgp.php:659
msgid "Could not determine the recipient's e-mail address."
msgstr ""
#: lib/Horde/Crypt/Pgp.php:759 lib/Horde/Crypt/Pgp.php:848
msgid "Could not obtain public key from the keyserver."
msgstr ""
#: lib/Horde/Crypt/Smime.php:478
msgid "Country"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:426
#, fuzzy
msgid "E-Mail"
msgstr "البريد"
#: lib/Horde/Crypt/Smime.php:474
#, fuzzy
msgid "Email Address"
msgstr "عنوان بريدك الإلكتروني:"
#: lib/Horde/Crypt/Pgp.php:1584 lib/Horde/Crypt/Pgp.php:1592
msgid "Error while talking to pgp binary."
msgstr ""
#: lib/Horde/Crypt/Smime.php:1251 lib/Horde/Crypt/Smime.php:1269
#: lib/Horde/Crypt/Smime.php:1284
msgid "Error while talking to smime binary."
msgstr ""
#: lib/Horde/Crypt/Pgp.php:425
msgid "Expiration Date"
msgstr ""
#: lib/Horde/Crypt/Smime.php:586
msgid "Exponent"
msgstr ""
#: lib/Horde/Crypt/Smime.php:484
msgid "Given Name"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:426
msgid "Hash-Algorithm"
msgstr ""
#: lib/Horde/Crypt/Smime.php:534
msgid "Issuer"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:424
msgid "Key Creation"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:427
msgid "Key Fingerprint"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:427
msgid "Key ID"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:425
msgid "Key Length"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:424
msgid "Key Type"
msgstr ""
#: lib/Horde/Crypt/Smime.php:507
#, fuzzy
msgid "Key Usage"
msgstr "حجم الاستخدام:"
#: lib/Horde/Crypt/Pgp.php:782
msgid "Key already exists on the public keyserver."
msgstr ""
#: lib/Horde/Crypt/Smime.php:480
msgid "Location"
msgstr ""
#: lib/Horde/Crypt/Smime.php:189
msgid ""
"Message Verified Successfully but the signer's certificate could not be "
"verified."
msgstr ""
#: lib/Horde/Crypt/Smime.php:583
msgid "Modulus"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:424
msgid "Name"
msgstr "الاسم"
#: lib/Horde/Crypt/Smime.php:490
msgid "Netscape Base URL"
msgstr ""
#: lib/Horde/Crypt/Smime.php:492
msgid "Netscape CA Revocation URL"
msgstr ""
#: lib/Horde/Crypt/Smime.php:494
msgid "Netscape CA policy URL"
msgstr ""
#: lib/Horde/Crypt/Smime.php:493
msgid "Netscape Renewal URL"
msgstr ""
#: lib/Horde/Crypt/Smime.php:491
msgid "Netscape Revocation URL"
msgstr ""
#: lib/Horde/Crypt/Smime.php:495
msgid "Netscape SSL server name"
msgstr ""
#: lib/Horde/Crypt/Smime.php:496
msgid "Netscape certificate comment"
msgstr ""
#: lib/Horde/Crypt/Smime.php:489
msgid "Netscape certificate type"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:449
msgid "Never"
msgstr "أبداً"
#: lib/Horde/Crypt/Smime.php:1217
msgid ""
"No path to the OpenSSL binary provided. The OpenSSL binary is necessary to "
"work with PKCS 12 data."
msgstr ""
#: lib/Horde/Crypt/Pgp.php:451 lib/Horde/Crypt/Pgp.php:452
msgid "None"
msgstr ""
#: lib/Horde/Crypt/Smime.php:549
msgid "Not After"
msgstr ""
#: lib/Horde/Crypt/Smime.php:548
msgid "Not Before"
msgstr ""
#: lib/Horde/Crypt/Smime.php:231
msgid "OpenSSL error: Could not extract data from signed S/MIME part."
msgstr ""
#: lib/Horde/Crypt/Smime.php:476
msgid "Organisation"
msgstr ""
#: lib/Horde/Crypt/Smime.php:477
msgid "Organisational Unit"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1406
msgid "PGP Digital Signature"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1450
msgid "PGP Encrypted Data"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1511
msgid "PGP Public Key"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1493
msgid "PGP Signed/Encrypted Data"
msgstr ""
#: lib/Horde/Crypt/Smime.php:1256
#, fuzzy
msgid "Password incorrect"
msgstr "كلمة المرور"
#: lib/Horde/Crypt/Pgp.php:447
msgid "Private Key"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:447
msgid "Public Key"
msgstr ""
#: lib/Horde/Crypt/Smime.php:554
msgid "Public Key Algorithm"
msgstr ""
#: lib/Horde/Crypt/Smime.php:553
msgid "Public Key Info"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:225
msgid "Public/Private keypair not generated successfully."
msgstr ""
#: lib/Horde/Crypt/Smime.php:572
#, php-format
msgid "RSA Public Key (%d bit)"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:227
msgid "Returned error message:"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1644
msgid "Revocation key not generated successfully."
msgstr ""
#: lib/Horde/Crypt/Smime.php:252
msgid "S/MIME Cryptographic Signature"
msgstr ""
#: lib/Horde/Crypt/Smime.php:283
msgid "S/MIME Encrypted Message"
msgstr ""
#: lib/Horde/Crypt/Smime.php:611
msgid "Serial Number"
msgstr ""
#: lib/Horde/Crypt/Smime.php:622
msgid "Signature"
msgstr ""
#: lib/Horde/Crypt/Smime.php:621
msgid "Signature Algorithm"
msgstr ""
#: lib/Horde/Crypt/Smime.php:479
msgid "State or Province"
msgstr ""
#: lib/Horde/Crypt/Smime.php:481
#, fuzzy
msgid "Street Address"
msgstr "عنوان المنزل"
#: lib/Horde/Crypt/Smime.php:483
#, fuzzy
msgid "Surname"
msgstr "الاسم"
#: lib/Horde/Crypt/Smime.php:482
msgid "Telephone Number"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1311
msgid ""
"The detached PGP signature block is required to verify the signed message."
msgstr ""
#: lib/Horde/Crypt/Smime.php:1146
msgid "The openssl module is required for the Horde_Crypt_Smime:: class."
msgstr ""
#: lib/Horde/Crypt/Smime.php:512
msgid "Unable to extract certificate details"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:453 lib/Horde/Crypt/Pgp.php:454
#: lib/Horde/Crypt/Pgp.php:455
msgid "Unknown"
msgstr ""
#: lib/Horde/Crypt/Smime.php:596 lib/Horde/Crypt/Smime.php:844
#: lib/Horde/Crypt/Smime.php:850
msgid "Unsupported Extension"
msgstr ""
#: lib/Horde/Crypt/Smime.php:547
msgid "Validity"
msgstr ""
#: lib/Horde/Crypt/Smime.php:191
msgid "Verification failed - an unknown error has occurred."
msgstr ""
#: lib/Horde/Crypt/Smime.php:193
msgid "Verification failed - this message may have been tampered with."
msgstr ""
#: lib/Horde/Crypt/Smime.php:610
msgid "Version"
msgstr ""
#: lib/Horde/Crypt/Smime.php:502
msgid "X509v3 Basic Constraints"
msgstr ""
#: lib/Horde/Crypt/Smime.php:501
msgid "X509v3 Extended Key Usage"
msgstr ""
#: lib/Horde/Crypt/Smime.php:503
msgid "X509v3 Subject Alternative Name"
msgstr ""
#: lib/Horde/Crypt/Smime.php:504
msgid "X509v3 Subject Key Identifier"
msgstr ""
#: lib/Horde/Crypt/Smime.php:592
msgid "X509v3 extensions"
msgstr ""
#: lib/Horde/Crypt/Smime.php:1135
msgid "not yet implemented"
msgstr ""
Horde_Crypt-2.4.0/locale/bg/LC_MESSAGES/Horde_Crypt.mo 0000664 0001750 0001750 00000004115 12242643672 020247 0 ustar jan jan
0 8 1 Q j + 3 /
L + Z 2 J ? B O ^ L @ k { T f ] n
A public PGP key is required to verify a signed message. A public PGP key, private PGP key, and passphrase are required to sign a message. Connection refused to the public keyserver. Could not determine the recipient's e-mail address. Could not obtain public key from the keyserver. Email Address Key already exists on the public keyserver. Name Never Public/Private keypair not generated successfully. The detached PGP signature block is required to verify the signed message. Verification failed - this message may have been tampered with. Project-Id-Version: Horde_Crypt
Report-Msgid-Bugs-To: dev@lists.horde.org
POT-Creation-Date: 2010-10-13 01:27+0200
PO-Revision-Date: 2010-10-13 01:27+0200
Last-Translator: Automatically generated
Language-Team: i18n@lists.horde.org
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
За да проверите подписано писмо е необходим PGP ключ. За да подпишете писмо са необходими: публичен ключ, личен ключ и ключова фраза. Достъпа до публичния сървър беше отказан. Некоректен email адрес на получателя. Грешка при получаването на публичния ключ от ключ-сървъра. Еmail адрес Ключа вече съществува в публичния ключсървър. Име Никога Ключова двойка публичен/частен ключ не беше генерирана. Прикрепеният PGP подпис е необходим за да се провери подписаното писмо. Грешка при проверката - това писмо може да е било подправено. Horde_Crypt-2.4.0/locale/bg/LC_MESSAGES/Horde_Crypt.po 0000664 0001750 0001750 00000026101 12242643672 020251 0 ustar jan jan # Bulgarian translations for Horde_Crypt module.
# Copyright 2010-2013 Horde LLC (http://www.horde.org/)
# This file is distributed under the same license as the Horde_Crypt module.
# Automatically generated, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: Horde_Crypt\n"
"Report-Msgid-Bugs-To: dev@lists.horde.org\n"
"POT-Creation-Date: 2010-10-13 01:27+0200\n"
"PO-Revision-Date: 2010-10-13 01:27+0200\n"
"Last-Translator: Automatically generated\n"
"Language-Team: i18n@lists.horde.org\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: lib/Horde/Crypt/Smime.php:614
#, php-format
msgid "%s Fingerprint"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1240
#, fuzzy
msgid "A passphrase is required to decrypt a message."
msgstr "За да криптирате писмо е необходим публичен PGP ключ."
#: lib/Horde/Crypt/Pgp.php:1307
msgid "A public PGP key is required to verify a signed message."
msgstr "За да проверите подписано писмо е необходим PGP ключ."
#: lib/Horde/Crypt/Pgp.php:1164
msgid ""
"A public PGP key, private PGP key, and passphrase are required to sign a "
"message."
msgstr ""
"За да подпишете писмо са необходими: публичен ключ, личен ключ и ключова "
"фраза."
#: lib/Horde/Crypt/Smime.php:311
#, fuzzy
msgid "A public S/MIME key is required to encrypt a message."
msgstr "За да криптирате писмо е необходим публичен SMIME ключ."
#: lib/Horde/Crypt/Smime.php:422
#, fuzzy
msgid ""
"A public S/MIME key, private S/MIME key, and passphrase are required to "
"decrypt a message."
msgstr ""
"За да декриптирате писмо са необходими: публичен SMIME ключ, личен SMIME "
"ключ и ключова фраза."
#: lib/Horde/Crypt/Smime.php:360
#, fuzzy
msgid ""
"A public S/MIME key, private S/MIME key, and passphrase are required to sign "
"a message."
msgstr ""
"За да подпишете писмо са необходими: публичен SMIME ключ, личен SMIME ключ и "
"ключова фраза."
#: lib/Horde/Crypt/Smime.php:506
msgid "CRL Distribution Points"
msgstr ""
#: lib/Horde/Crypt/Smime.php:609
msgid "Certificate Details"
msgstr ""
#: lib/Horde/Crypt/Smime.php:520
msgid "Certificate Owner"
msgstr ""
#: lib/Horde/Crypt/Smime.php:505
msgid "Certificate Policies"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:426
#, fuzzy
msgid "Comment"
msgstr "Команди:"
#: lib/Horde/Crypt/Smime.php:475
msgid "Common Name"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:939
msgid "Connection refused to the public keyserver."
msgstr "Достъпа до публичния сървър беше отказан."
#: lib/Horde/Crypt/Pgp.php:950
#, fuzzy, php-format
msgid "Connection refused to the public keyserver. Reason: %s (%s)"
msgstr "Достъпа до публичния сървър беше отказан."
#: lib/Horde/Crypt/Pgp.php:1132
#, fuzzy
msgid "Could not PGP encrypt message: "
msgstr "Грешка при PGP криптирането на писмо."
#: lib/Horde/Crypt/Pgp.php:1201
#, fuzzy
msgid "Could not PGP sign message: "
msgstr "Грешка при PGP подписването на писмо."
#: lib/Horde/Crypt/Smime.php:330
#, fuzzy
msgid "Could not S/MIME encrypt message."
msgstr "Грешка при SMIME криптирането на писмо."
#: lib/Horde/Crypt/Smime.php:391
#, fuzzy
msgid "Could not S/MIME sign message."
msgstr "Грешка при SMIME подписването на писмо."
#: lib/Horde/Crypt/Pgp.php:1276
#, fuzzy
msgid "Could not decrypt PGP data: "
msgstr "Грешка при декриптирането на PGP данни."
#: lib/Horde/Crypt/Smime.php:440
#, fuzzy
msgid "Could not decrypt S/MIME data."
msgstr "Грешка при декриптирането на SMIME данни."
#: lib/Horde/Crypt/Pgp.php:659
msgid "Could not determine the recipient's e-mail address."
msgstr "Некоректен email адрес на получателя."
#: lib/Horde/Crypt/Pgp.php:759 lib/Horde/Crypt/Pgp.php:848
msgid "Could not obtain public key from the keyserver."
msgstr "Грешка при получаването на публичния ключ от ключ-сървъра."
#: lib/Horde/Crypt/Smime.php:478
msgid "Country"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:426
#, fuzzy
msgid "E-Mail"
msgstr "Поща"
#: lib/Horde/Crypt/Smime.php:474
msgid "Email Address"
msgstr "Еmail адрес"
#: lib/Horde/Crypt/Pgp.php:1584 lib/Horde/Crypt/Pgp.php:1592
msgid "Error while talking to pgp binary."
msgstr ""
#: lib/Horde/Crypt/Smime.php:1251 lib/Horde/Crypt/Smime.php:1269
#: lib/Horde/Crypt/Smime.php:1284
msgid "Error while talking to smime binary."
msgstr ""
#: lib/Horde/Crypt/Pgp.php:425
msgid "Expiration Date"
msgstr ""
#: lib/Horde/Crypt/Smime.php:586
msgid "Exponent"
msgstr ""
#: lib/Horde/Crypt/Smime.php:484
#, fuzzy
msgid "Given Name"
msgstr "Име на файл"
#: lib/Horde/Crypt/Pgp.php:426
msgid "Hash-Algorithm"
msgstr ""
#: lib/Horde/Crypt/Smime.php:534
msgid "Issuer"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:424
msgid "Key Creation"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:427
msgid "Key Fingerprint"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:427
msgid "Key ID"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:425
msgid "Key Length"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:424
#, fuzzy
msgid "Key Type"
msgstr "Mime тип"
#: lib/Horde/Crypt/Smime.php:507
#, fuzzy
msgid "Key Usage"
msgstr "Използване::"
#: lib/Horde/Crypt/Pgp.php:782
msgid "Key already exists on the public keyserver."
msgstr "Ключа вече съществува в публичния ключсървър."
#: lib/Horde/Crypt/Smime.php:480
msgid "Location"
msgstr ""
#: lib/Horde/Crypt/Smime.php:189
#, fuzzy
msgid ""
"Message Verified Successfully but the signer's certificate could not be "
"verified."
msgstr ""
"Писмото беше проверено успешно, но сертификата на подписа не беше потвърден."
#: lib/Horde/Crypt/Smime.php:583
msgid "Modulus"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:424
msgid "Name"
msgstr "Име"
#: lib/Horde/Crypt/Smime.php:490
msgid "Netscape Base URL"
msgstr ""
#: lib/Horde/Crypt/Smime.php:492
msgid "Netscape CA Revocation URL"
msgstr ""
#: lib/Horde/Crypt/Smime.php:494
msgid "Netscape CA policy URL"
msgstr ""
#: lib/Horde/Crypt/Smime.php:493
msgid "Netscape Renewal URL"
msgstr ""
#: lib/Horde/Crypt/Smime.php:491
msgid "Netscape Revocation URL"
msgstr ""
#: lib/Horde/Crypt/Smime.php:495
msgid "Netscape SSL server name"
msgstr ""
#: lib/Horde/Crypt/Smime.php:496
msgid "Netscape certificate comment"
msgstr ""
#: lib/Horde/Crypt/Smime.php:489
msgid "Netscape certificate type"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:449
msgid "Never"
msgstr "Никога"
#: lib/Horde/Crypt/Smime.php:1217
msgid ""
"No path to the OpenSSL binary provided. The OpenSSL binary is necessary to "
"work with PKCS 12 data."
msgstr ""
#: lib/Horde/Crypt/Pgp.php:451 lib/Horde/Crypt/Pgp.php:452
msgid "None"
msgstr ""
#: lib/Horde/Crypt/Smime.php:549
msgid "Not After"
msgstr ""
#: lib/Horde/Crypt/Smime.php:548
msgid "Not Before"
msgstr ""
#: lib/Horde/Crypt/Smime.php:231
msgid "OpenSSL error: Could not extract data from signed S/MIME part."
msgstr ""
#: lib/Horde/Crypt/Smime.php:476
#, fuzzy
msgid "Organisation"
msgstr "Администриране"
#: lib/Horde/Crypt/Smime.php:477
msgid "Organisational Unit"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1406
msgid "PGP Digital Signature"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1450
msgid "PGP Encrypted Data"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1511
msgid "PGP Public Key"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1493
msgid "PGP Signed/Encrypted Data"
msgstr ""
#: lib/Horde/Crypt/Smime.php:1256
#, fuzzy
msgid "Password incorrect"
msgstr "Парола: "
#: lib/Horde/Crypt/Pgp.php:447
msgid "Private Key"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:447
msgid "Public Key"
msgstr ""
#: lib/Horde/Crypt/Smime.php:554
msgid "Public Key Algorithm"
msgstr ""
#: lib/Horde/Crypt/Smime.php:553
msgid "Public Key Info"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:225
msgid "Public/Private keypair not generated successfully."
msgstr "Ключова двойка публичен/частен ключ не беше генерирана."
#: lib/Horde/Crypt/Smime.php:572
#, php-format
msgid "RSA Public Key (%d bit)"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:227
msgid "Returned error message:"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1644
#, fuzzy
msgid "Revocation key not generated successfully."
msgstr "Ключова двойка публичен/частен ключ не беше генерирана."
#: lib/Horde/Crypt/Smime.php:252
msgid "S/MIME Cryptographic Signature"
msgstr ""
#: lib/Horde/Crypt/Smime.php:283
#, fuzzy
msgid "S/MIME Encrypted Message"
msgstr "Грешка при SMIME криптирането на писмо."
#: lib/Horde/Crypt/Smime.php:611
msgid "Serial Number"
msgstr ""
#: lib/Horde/Crypt/Smime.php:622
msgid "Signature"
msgstr ""
#: lib/Horde/Crypt/Smime.php:621
msgid "Signature Algorithm"
msgstr ""
#: lib/Horde/Crypt/Smime.php:479
msgid "State or Province"
msgstr ""
#: lib/Horde/Crypt/Smime.php:481
#, fuzzy
msgid "Street Address"
msgstr "Домашен адрес"
#: lib/Horde/Crypt/Smime.php:483
#, fuzzy
msgid "Surname"
msgstr "без име"
#: lib/Horde/Crypt/Smime.php:482
msgid "Telephone Number"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1311
msgid ""
"The detached PGP signature block is required to verify the signed message."
msgstr ""
"Прикрепеният PGP подпис е необходим за да се провери подписаното писмо."
#: lib/Horde/Crypt/Smime.php:1146
#, fuzzy
msgid "The openssl module is required for the Horde_Crypt_Smime:: class."
msgstr "Модулът OpenSSL е необходим за Crypt_smime:: class."
#: lib/Horde/Crypt/Smime.php:512
msgid "Unable to extract certificate details"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:453 lib/Horde/Crypt/Pgp.php:454
#: lib/Horde/Crypt/Pgp.php:455
msgid "Unknown"
msgstr ""
#: lib/Horde/Crypt/Smime.php:596 lib/Horde/Crypt/Smime.php:844
#: lib/Horde/Crypt/Smime.php:850
msgid "Unsupported Extension"
msgstr ""
#: lib/Horde/Crypt/Smime.php:547
msgid "Validity"
msgstr ""
#: lib/Horde/Crypt/Smime.php:191
msgid "Verification failed - an unknown error has occurred."
msgstr ""
#: lib/Horde/Crypt/Smime.php:193
msgid "Verification failed - this message may have been tampered with."
msgstr "Грешка при проверката - това писмо може да е било подправено."
#: lib/Horde/Crypt/Smime.php:610
#, fuzzy
msgid "Version"
msgstr "Права"
#: lib/Horde/Crypt/Smime.php:502
msgid "X509v3 Basic Constraints"
msgstr ""
#: lib/Horde/Crypt/Smime.php:501
msgid "X509v3 Extended Key Usage"
msgstr ""
#: lib/Horde/Crypt/Smime.php:503
msgid "X509v3 Subject Alternative Name"
msgstr ""
#: lib/Horde/Crypt/Smime.php:504
msgid "X509v3 Subject Key Identifier"
msgstr ""
#: lib/Horde/Crypt/Smime.php:592
msgid "X509v3 extensions"
msgstr ""
#: lib/Horde/Crypt/Smime.php:1135
msgid "not yet implemented"
msgstr ""
Horde_Crypt-2.4.0/locale/bs/LC_MESSAGES/Horde_Crypt.mo 0000664 0001750 0001750 00000001150 12242643672 020257 0 ustar jan jan T
B 1 > G K R
Z Email Address Location Name Never None Serial Number Project-Id-Version: Horde_Crypt
Report-Msgid-Bugs-To: dev@lists.horde.org
POT-Creation-Date: 2010-10-13 01:27+0200
PO-Revision-Date: 2010-10-13 01:27+0200
Last-Translator: Automatically generated
Language-Team: i18n@lists.horde.org
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Email adresa Lokacija Ime Nikada Nijedan Serijski broj Horde_Crypt-2.4.0/locale/bs/LC_MESSAGES/Horde_Crypt.po 0000664 0001750 0001750 00000021705 12242643672 020272 0 ustar jan jan # Bosnian translations for Horde_Crypt module.
# Copyright 2010-2013 Horde LLC (http://www.horde.org/)
# This file is distributed under the same license as the Horde_Crypt module.
# Automatically generated, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: Horde_Crypt\n"
"Report-Msgid-Bugs-To: dev@lists.horde.org\n"
"POT-Creation-Date: 2010-10-13 01:27+0200\n"
"PO-Revision-Date: 2010-10-13 01:27+0200\n"
"Last-Translator: Automatically generated\n"
"Language-Team: i18n@lists.horde.org\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: lib/Horde/Crypt/Smime.php:614
#, php-format
msgid "%s Fingerprint"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1240
msgid "A passphrase is required to decrypt a message."
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1307
msgid "A public PGP key is required to verify a signed message."
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1164
msgid ""
"A public PGP key, private PGP key, and passphrase are required to sign a "
"message."
msgstr ""
#: lib/Horde/Crypt/Smime.php:311
msgid "A public S/MIME key is required to encrypt a message."
msgstr ""
#: lib/Horde/Crypt/Smime.php:422
msgid ""
"A public S/MIME key, private S/MIME key, and passphrase are required to "
"decrypt a message."
msgstr ""
#: lib/Horde/Crypt/Smime.php:360
msgid ""
"A public S/MIME key, private S/MIME key, and passphrase are required to sign "
"a message."
msgstr ""
#: lib/Horde/Crypt/Smime.php:506
msgid "CRL Distribution Points"
msgstr ""
#: lib/Horde/Crypt/Smime.php:609
msgid "Certificate Details"
msgstr ""
#: lib/Horde/Crypt/Smime.php:520
msgid "Certificate Owner"
msgstr ""
#: lib/Horde/Crypt/Smime.php:505
msgid "Certificate Policies"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:426
msgid "Comment"
msgstr ""
#: lib/Horde/Crypt/Smime.php:475
#, fuzzy
msgid "Common Name"
msgstr "Vaše ime"
#: lib/Horde/Crypt/Pgp.php:939
msgid "Connection refused to the public keyserver."
msgstr ""
#: lib/Horde/Crypt/Pgp.php:950
#, php-format
msgid "Connection refused to the public keyserver. Reason: %s (%s)"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1132
msgid "Could not PGP encrypt message: "
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1201
msgid "Could not PGP sign message: "
msgstr ""
#: lib/Horde/Crypt/Smime.php:330
msgid "Could not S/MIME encrypt message."
msgstr ""
#: lib/Horde/Crypt/Smime.php:391
msgid "Could not S/MIME sign message."
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1276
#, fuzzy
msgid "Could not decrypt PGP data: "
msgstr "Nije bilo moguce obrisati poruke od %s: %s"
#: lib/Horde/Crypt/Smime.php:440
msgid "Could not decrypt S/MIME data."
msgstr ""
#: lib/Horde/Crypt/Pgp.php:659
#, fuzzy
msgid "Could not determine the recipient's e-mail address."
msgstr "Nedozvoljena slova u email adresi."
#: lib/Horde/Crypt/Pgp.php:759 lib/Horde/Crypt/Pgp.php:848
msgid "Could not obtain public key from the keyserver."
msgstr ""
#: lib/Horde/Crypt/Smime.php:478
msgid "Country"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:426
#, fuzzy
msgid "E-Mail"
msgstr "Sanduce"
#: lib/Horde/Crypt/Smime.php:474
msgid "Email Address"
msgstr "Email adresa"
#: lib/Horde/Crypt/Pgp.php:1584 lib/Horde/Crypt/Pgp.php:1592
msgid "Error while talking to pgp binary."
msgstr ""
#: lib/Horde/Crypt/Smime.php:1251 lib/Horde/Crypt/Smime.php:1269
#: lib/Horde/Crypt/Smime.php:1284
msgid "Error while talking to smime binary."
msgstr ""
#: lib/Horde/Crypt/Pgp.php:425
msgid "Expiration Date"
msgstr ""
#: lib/Horde/Crypt/Smime.php:586
msgid "Exponent"
msgstr ""
#: lib/Horde/Crypt/Smime.php:484
#, fuzzy
msgid "Given Name"
msgstr "Ime datoteke"
#: lib/Horde/Crypt/Pgp.php:426
msgid "Hash-Algorithm"
msgstr ""
#: lib/Horde/Crypt/Smime.php:534
msgid "Issuer"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:424
msgid "Key Creation"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:427
msgid "Key Fingerprint"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:427
msgid "Key ID"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:425
msgid "Key Length"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:424
#, fuzzy
msgid "Key Type"
msgstr "Mime tip"
#: lib/Horde/Crypt/Smime.php:507
#, fuzzy
msgid "Key Usage"
msgstr "Poruka"
#: lib/Horde/Crypt/Pgp.php:782
msgid "Key already exists on the public keyserver."
msgstr ""
#: lib/Horde/Crypt/Smime.php:480
msgid "Location"
msgstr "Lokacija"
#: lib/Horde/Crypt/Smime.php:189
msgid ""
"Message Verified Successfully but the signer's certificate could not be "
"verified."
msgstr ""
#: lib/Horde/Crypt/Smime.php:583
#, fuzzy
msgid "Modulus"
msgstr "Prebaci"
#: lib/Horde/Crypt/Pgp.php:424
msgid "Name"
msgstr "Ime"
#: lib/Horde/Crypt/Smime.php:490
msgid "Netscape Base URL"
msgstr ""
#: lib/Horde/Crypt/Smime.php:492
msgid "Netscape CA Revocation URL"
msgstr ""
#: lib/Horde/Crypt/Smime.php:494
msgid "Netscape CA policy URL"
msgstr ""
#: lib/Horde/Crypt/Smime.php:493
msgid "Netscape Renewal URL"
msgstr ""
#: lib/Horde/Crypt/Smime.php:491
msgid "Netscape Revocation URL"
msgstr ""
#: lib/Horde/Crypt/Smime.php:495
msgid "Netscape SSL server name"
msgstr ""
#: lib/Horde/Crypt/Smime.php:496
msgid "Netscape certificate comment"
msgstr ""
#: lib/Horde/Crypt/Smime.php:489
msgid "Netscape certificate type"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:449
msgid "Never"
msgstr "Nikada"
#: lib/Horde/Crypt/Smime.php:1217
msgid ""
"No path to the OpenSSL binary provided. The OpenSSL binary is necessary to "
"work with PKCS 12 data."
msgstr ""
#: lib/Horde/Crypt/Pgp.php:451 lib/Horde/Crypt/Pgp.php:452
msgid "None"
msgstr "Nijedan"
#: lib/Horde/Crypt/Smime.php:549
#, fuzzy
msgid "Not After"
msgstr "Not Draft"
#: lib/Horde/Crypt/Smime.php:548
#, fuzzy
msgid "Not Before"
msgstr "Not Draft"
#: lib/Horde/Crypt/Smime.php:231
msgid "OpenSSL error: Could not extract data from signed S/MIME part."
msgstr ""
#: lib/Horde/Crypt/Smime.php:476
#, fuzzy
msgid "Organisation"
msgstr "Registracija korisnika"
#: lib/Horde/Crypt/Smime.php:477
msgid "Organisational Unit"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1406
#, fuzzy
msgid "PGP Digital Signature"
msgstr "Zatamni potpise?"
#: lib/Horde/Crypt/Pgp.php:1450
msgid "PGP Encrypted Data"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1511
msgid "PGP Public Key"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:1493
msgid "PGP Signed/Encrypted Data"
msgstr ""
#: lib/Horde/Crypt/Smime.php:1256
#, fuzzy
msgid "Password incorrect"
msgstr "Password"
#: lib/Horde/Crypt/Pgp.php:447
msgid "Private Key"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:447
msgid "Public Key"
msgstr ""
#: lib/Horde/Crypt/Smime.php:554
msgid "Public Key Algorithm"
msgstr ""
#: lib/Horde/Crypt/Smime.php:553
msgid "Public Key Info"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:225
msgid "Public/Private keypair not generated successfully."
msgstr ""
#: lib/Horde/Crypt/Smime.php:572
#, php-format
msgid "RSA Public Key (%d bit)"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:227
#, fuzzy
msgid "Returned error message:"
msgstr "Čitanje poruka"
#: lib/Horde/Crypt/Pgp.php:1644
msgid "Revocation key not generated successfully."
msgstr ""
#: lib/Horde/Crypt/Smime.php:252
msgid "S/MIME Cryptographic Signature"
msgstr ""
#: lib/Horde/Crypt/Smime.php:283
msgid "S/MIME Encrypted Message"
msgstr ""
#: lib/Horde/Crypt/Smime.php:611
msgid "Serial Number"
msgstr "Serijski broj"
#: lib/Horde/Crypt/Smime.php:622
#, fuzzy
msgid "Signature"
msgstr "Vaš potpis:"
#: lib/Horde/Crypt/Smime.php:621
#, fuzzy
msgid "Signature Algorithm"
msgstr "Vaš potpis:"
#: lib/Horde/Crypt/Smime.php:479
msgid "State or Province"
msgstr ""
#: lib/Horde/Crypt/Smime.php:481
#, fuzzy
msgid "Street Address"
msgstr "Od adrese"
#: lib/Horde/Crypt/Smime.php:483
#, fuzzy
msgid "Surname"
msgstr "Username"
#: lib/Horde/Crypt/Smime.php:482
#, fuzzy
msgid "Telephone Number"
msgstr "Serijski broj"
#: lib/Horde/Crypt/Pgp.php:1311
msgid ""
"The detached PGP signature block is required to verify the signed message."
msgstr ""
#: lib/Horde/Crypt/Smime.php:1146
msgid "The openssl module is required for the Horde_Crypt_Smime:: class."
msgstr ""
#: lib/Horde/Crypt/Smime.php:512
msgid "Unable to extract certificate details"
msgstr ""
#: lib/Horde/Crypt/Pgp.php:453 lib/Horde/Crypt/Pgp.php:454
#: lib/Horde/Crypt/Pgp.php:455
msgid "Unknown"
msgstr ""
#: lib/Horde/Crypt/Smime.php:596 lib/Horde/Crypt/Smime.php:844
#: lib/Horde/Crypt/Smime.php:850
msgid "Unsupported Extension"
msgstr ""
#: lib/Horde/Crypt/Smime.php:547
msgid "Validity"
msgstr ""
#: lib/Horde/Crypt/Smime.php:191
#, fuzzy
msgid "Verification failed - an unknown error has occurred."
msgstr "Došlo je do fatalne greške"
#: lib/Horde/Crypt/Smime.php:193
msgid "Verification failed - this message may have been tampered with."
msgstr ""
#: lib/Horde/Crypt/Smime.php:610
#, fuzzy
msgid "Version"
msgstr "Lično"
#: lib/Horde/Crypt/Smime.php:502
msgid "X509v3 Basic Constraints"
msgstr ""
#: lib/Horde/Crypt/Smime.php:501
msgid "X509v3 Extended Key Usage"
msgstr ""
#: lib/Horde/Crypt/Smime.php:503
msgid "X509v3 Subject Alternative Name"
msgstr ""
#: lib/Horde/Crypt/Smime.php:504
msgid "X509v3 Subject Key Identifier"
msgstr ""
#: lib/Horde/Crypt/Smime.php:592
msgid "X509v3 extensions"
msgstr ""
#: lib/Horde/Crypt/Smime.php:1135
#, fuzzy
msgid "not yet implemented"
msgstr "Ne izbrisana"
Horde_Crypt-2.4.0/locale/ca/LC_MESSAGES/Horde_Crypt.mo 0000664 0001750 0001750 00000016000 12242643672 020236 0 ustar jan jan V | x y 8 Q Z W n ! + - ; Y ! 3 / )
Y
a
h
v
+
Q r z & @ b F
>
#
9
L
[
u
2
.
G U _ s J % & < ? E B $ g D | c l % i 0 G d n ; x I ( ( ' ) P @ z > ( : C O a i {
8 d p w { # $ $ 6 [ { m K
R ` u
! A > #
3 : P N 2
G H P m ' U L ) 0 O 1 > 3 K : I R D
5 ' $ 2 7 4 + A <