3 +-------------------------------------------------------------------------+
4 | GnuPG (PGP) driver for the Enigma Plugin |
6 | This program is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License version 2 |
8 | as published by the Free Software Foundation. |
10 | This program is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | GNU General Public License for more details. |
15 | You should have received a copy of the GNU General Public License along |
16 | with this program; if not, write to the Free Software Foundation, Inc., |
17 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
19 +-------------------------------------------------------------------------+
20 | Author: Aleksander Machniak <alec@alec.pl> |
21 +-------------------------------------------------------------------------+
24 require_once 'Crypt/GPG.php';
26 class enigma_driver_gnupg extends enigma_driver
33 function __construct($user)
35 $rcmail = rcmail::get_instance();
41 * Driver initialization and environment checking.
42 * Should only return critical errors.
44 * @return mixed NULL on success, enigma_error on failure
48 $homedir = $this->rc->config->get('enigma_pgp_homedir', INSTALL_PATH . '/plugins/enigma/home');
51 return new enigma_error(enigma_error::E_INTERNAL,
52 "Option 'enigma_pgp_homedir' not specified");
54 // check if homedir exists (create it if not) and is readable
55 if (!file_exists($homedir))
56 return new enigma_error(enigma_error::E_INTERNAL,
57 "Keys directory doesn't exists: $homedir");
58 if (!is_writable($homedir))
59 return new enigma_error(enigma_error::E_INTERNAL,
60 "Keys directory isn't writeable: $homedir");
62 $homedir = $homedir . '/' . $this->user;
64 // check if user's homedir exists (create it if not) and is readable
65 if (!file_exists($homedir))
66 mkdir($homedir, 0700);
68 if (!file_exists($homedir))
69 return new enigma_error(enigma_error::E_INTERNAL,
70 "Unable to create keys directory: $homedir");
71 if (!is_writable($homedir))
72 return new enigma_error(enigma_error::E_INTERNAL,
73 "Unable to write to keys directory: $homedir");
75 $this->homedir = $homedir;
77 // Create Crypt_GPG object
79 $this->gpg = new Crypt_GPG(array(
80 'homedir' => $this->homedir,
84 catch (Exception $e) {
85 return $this->get_error_from_exception($e);
89 function encrypt($text, $keys)
92 foreach ($keys as $key) {
93 $this->gpg->addEncryptKey($key);
95 $enc = $this->gpg->encrypt($text);
100 function decrypt($text, $key, $passwd)
102 // $this->gpg->addDecryptKey($key, $passwd);
104 $dec = $this->gpg->decrypt($text);
107 catch (Exception $e) {
108 return $this->get_error_from_exception($e);
112 function sign($text, $key, $passwd)
115 $this->gpg->addSignKey($key, $passwd);
116 $signed = $this->gpg->sign($text, Crypt_GPG::SIGN_MODE_DETACHED);
121 function verify($text, $signature)
124 $verified = $this->gpg->verify($text, $signature);
125 return $this->parse_signature($verified[0]);
127 catch (Exception $e) {
128 return $this->get_error_from_exception($e);
132 public function import($content, $isfile=false)
136 return $this->gpg->importKeyFile($content);
138 return $this->gpg->importKey($content);
140 catch (Exception $e) {
141 return $this->get_error_from_exception($e);
145 public function list_keys($pattern='')
148 $keys = $this->gpg->getKeys($pattern);
151 foreach ($keys as $idx => $key) {
152 $result[] = $this->parse_key($key);
158 catch (Exception $e) {
159 return $this->get_error_from_exception($e);
163 public function get_key($keyid)
165 $list = $this->list_keys($keyid);
168 return array_shift($list);
174 public function gen_key($data)
178 public function del_key($keyid)
180 // $this->get_key($keyid);
185 public function del_privkey($keyid)
188 $this->gpg->deletePrivateKey($keyid);
191 catch (Exception $e) {
192 return $this->get_error_from_exception($e);
196 public function del_pubkey($keyid)
199 $this->gpg->deletePublicKey($keyid);
202 catch (Exception $e) {
203 return $this->get_error_from_exception($e);
208 * Converts Crypt_GPG exception into Enigma's error object
210 * @param mixed Exception object
212 * @return enigma_error Error object
214 private function get_error_from_exception($e)
218 if ($e instanceof Crypt_GPG_KeyNotFoundException) {
219 $error = enigma_error::E_KEYNOTFOUND;
220 $data['id'] = $e->getKeyId();
222 else if ($e instanceof Crypt_GPG_BadPassphraseException) {
223 $error = enigma_error::E_BADPASS;
224 $data['bad'] = $e->getBadPassphrases();
225 $data['missing'] = $e->getMissingPassphrases();
227 else if ($e instanceof Crypt_GPG_NoDataException)
228 $error = enigma_error::E_NODATA;
229 else if ($e instanceof Crypt_GPG_DeletePrivateKeyException)
230 $error = enigma_error::E_DELKEY;
232 $error = enigma_error::E_INTERNAL;
234 $msg = $e->getMessage();
236 return new enigma_error($error, $msg, $data);
240 * Converts Crypt_GPG_Signature object into Enigma's signature object
242 * @param Crypt_GPG_Signature Signature object
244 * @return enigma_signature Signature object
246 private function parse_signature($sig)
248 $user = $sig->getUserId();
250 $data = new enigma_signature();
251 $data->id = $sig->getId();
252 $data->valid = $sig->isValid();
253 $data->fingerprint = $sig->getKeyFingerprint();
254 $data->created = $sig->getCreationDate();
255 $data->expires = $sig->getExpirationDate();
256 $data->name = $user->getName();
257 $data->comment = $user->getComment();
258 $data->email = $user->getEmail();
264 * Converts Crypt_GPG_Key object into Enigma's key object
266 * @param Crypt_GPG_Key Key object
268 * @return enigma_key Key object
270 private function parse_key($key)
272 $ekey = new enigma_key();
274 foreach ($key->getUserIds() as $idx => $user) {
275 $id = new enigma_userid();
276 $id->name = $user->getName();
277 $id->comment = $user->getComment();
278 $id->email = $user->getEmail();
279 $id->valid = $user->isValid();
280 $id->revoked = $user->isRevoked();
282 $ekey->users[$idx] = $id;
285 $ekey->name = trim($ekey->users[0]->name . ' <' . $ekey->users[0]->email . '>');
287 foreach ($key->getSubKeys() as $idx => $subkey) {
288 $skey = new enigma_subkey();
289 $skey->id = $subkey->getId();
290 $skey->revoked = $subkey->isRevoked();
291 $skey->created = $subkey->getCreationDate();
292 $skey->expires = $subkey->getExpirationDate();
293 $skey->fingerprint = $subkey->getFingerprint();
294 $skey->has_private = $subkey->hasPrivate();
295 $skey->can_sign = $subkey->canSign();
296 $skey->can_encrypt = $subkey->canEncrypt();
298 $ekey->subkeys[$idx] = $skey;
301 $ekey->id = $ekey->subkeys[0]->id;