diff --git a/plugins/enigma/lib/enigma_driver_gnupg.php b/plugins/enigma/lib/enigma_driver_gnupg.php index 4046bdd7b..c41c6c192 100644 --- a/plugins/enigma/lib/enigma_driver_gnupg.php +++ b/plugins/enigma/lib/enigma_driver_gnupg.php @@ -299,7 +299,7 @@ class enigma_driver_gnupg extends enigma_driver else if ($code == enigma_error::DELKEY) { $key = $this->get_key($keyid); for ($i = count($key->subkeys) - 1; $i >= 0; $i--) { - $type = $key->subkeys[$i]->can_encrypt ? 'priv' : 'pub'; + $type = ($key->subkeys[$i]->usage & enigma_key::CAN_ENCRYPT) ? 'priv' : 'pub'; $result = $this->{'delete_' . $type . 'key'}($key->subkeys[$i]->id); if ($result !== true) { return $result; @@ -423,6 +423,14 @@ class enigma_driver_gnupg extends enigma_driver $ekey->name = trim($ekey->users[0]->name . ' <' . $ekey->users[0]->email . '>'); foreach ($key->getSubKeys() as $idx => $subkey) { + $usage = 0; + if ($subkey->canSign()) { + $usage += enigma_key::CAN_SIGN; + } + if ($subkey->canEncrypt()) { + $usage += enigma_key::CAN_ENCRYPT; + } + $skey = new enigma_subkey(); $skey->id = $subkey->getId(); $skey->revoked = $subkey->isRevoked(); @@ -430,8 +438,9 @@ class enigma_driver_gnupg extends enigma_driver $skey->expires = $subkey->getExpirationDate(); $skey->fingerprint = $subkey->getFingerprint(); $skey->has_private = $subkey->hasPrivate(); - $skey->can_sign = $subkey->canSign(); - $skey->can_encrypt = $subkey->canEncrypt(); + $skey->algorithm = $subkey->getAlgorithm(); + $skey->length = $subkey->getLength(); + $skey->usage = $usage; $ekey->subkeys[$idx] = $skey; }; diff --git a/plugins/enigma/lib/enigma_driver_phpssl.php b/plugins/enigma/lib/enigma_driver_phpssl.php index d2e2044b3..a5aa6de13 100644 --- a/plugins/enigma/lib/enigma_driver_phpssl.php +++ b/plugins/enigma/lib/enigma_driver_phpssl.php @@ -183,8 +183,6 @@ class enigma_driver_phpssl extends enigma_driver $skey->expires = $subkey->getExpirationDate(); $skey->fingerprint = $subkey->getFingerprint(); $skey->has_private = $subkey->hasPrivate(); - $skey->can_sign = $subkey->canSign(); - $skey->can_encrypt = $subkey->canEncrypt(); $ekey->subkeys[$idx] = $skey; }; diff --git a/plugins/enigma/lib/enigma_key.php b/plugins/enigma/lib/enigma_key.php index 734cbb8c7..b687e626c 100644 --- a/plugins/enigma/lib/enigma_key.php +++ b/plugins/enigma/lib/enigma_key.php @@ -28,6 +28,9 @@ class enigma_key const CAN_SIGN = 1; const CAN_ENCRYPT = 2; + const CAN_CERTIFY = 4; + const CAN_AUTH = 8; + /** * Keys list sorting callback for usort() @@ -99,9 +102,7 @@ class enigma_key if ($user->email === $email && $user->valid && !$user->revoked) { foreach ($this->subkeys as $subkey) { if (!$subkey->revoked && (!$subkey->expires || $subkey->expires > $now)) { - if (($mode == self::CAN_ENCRYPT && $subkey->can_encrypt) - || ($mode == self::CAN_SIGN && $subkey->has_private) - ) { + if ($subkey->usage & $mode) { return $subkey; } } @@ -147,5 +148,4 @@ class enigma_key return $result; } - } diff --git a/plugins/enigma/lib/enigma_subkey.php b/plugins/enigma/lib/enigma_subkey.php index 90557d5af..dfcfebf65 100644 --- a/plugins/enigma/lib/enigma_subkey.php +++ b/plugins/enigma/lib/enigma_subkey.php @@ -23,8 +23,9 @@ class enigma_subkey public $created; public $revoked; public $has_private; - public $can_sign; - public $can_encrypt; + public $algorithm; + public $length; + public $usage; /** * Converts internal ID to short ID @@ -47,4 +48,31 @@ class enigma_subkey { return enigma_key::format_fingerprint($this->fingerprint); } + + /** + * Returns human-readable name of the key's algorithm + * + * @return string Algorithm name + */ + function get_algorithm() + { + // http://tools.ietf.org/html/rfc4880#section-9.1 + switch ($this->algorithm) { + case 1: + case 2: + case 3: + return 'RSA'; + case 16: + case 20: + return 'Elgamal'; + case 17: + return 'DSA'; + case 18: + return 'Elliptic Curve'; + case 19: + return 'ECDSA'; + case 21: + return 'Diffie-Hellman'; + } + } } diff --git a/plugins/enigma/lib/enigma_ui.php b/plugins/enigma/lib/enigma_ui.php index f0ab713a6..e596fdea9 100644 --- a/plugins/enigma/lib/enigma_ui.php +++ b/plugins/enigma/lib/enigma_ui.php @@ -357,7 +357,7 @@ class enigma_ui function tpl_key_data($attrib) { $out = ''; - $table = new html_table(array('cols' => 2)); + $table = new html_table(array('cols' => 2)); // Key user ID $table->add('title', $this->enigma->gettext('keyuserid')); @@ -385,23 +385,72 @@ class enigma_ui $out .= html::tag('fieldset', null, html::tag('legend', null, $this->enigma->gettext('basicinfo')) . $table->show($attrib)); -/* + // Subkeys - $table = new html_table(array('cols' => 6)); - // Columns: Type, ID, Algorithm, Size, Created, Expires + $table = new html_table(array('cols' => 5, 'id' => 'enigmasubkeytable', 'class' => 'records-table')); + + $table->add_header('id', $this->enigma->gettext('subkeyid')); + $table->add_header('algo', $this->enigma->gettext('subkeyalgo')); + $table->add_header('created', $this->enigma->gettext('subkeycreated')); + $table->add_header('expires', $this->enigma->gettext('subkeyexpires')); + $table->add_header('usage', $this->enigma->gettext('subkeyusage')); + + $now = time(); + $date_format = $this->rc->config->get('date_format', 'Y-m-d'); + $usage_map = array( + enigma_key::CAN_ENCRYPT => $this->enigma->gettext('typeencrypt'), + enigma_key::CAN_SIGN => $this->enigma->gettext('typesign'), + enigma_key::CAN_CERTIFY => $this->enigma->gettext('typecert'), + enigma_key::CAN_AUTH => $this->enigma->gettext('typeauth'), + ); + + foreach ($this->data->subkeys as $subkey) { + $algo = $subkey->get_algorithm(); + if ($algo && $subkey->length) { + $algo .= ' (' . $subkey->length . ')'; + } + + $usage = array(); + foreach ($usage_map as $key => $text) { + if ($subkey->usage & $key) { + $usage[] = $text; + } + } + + $table->add('id', $subkey->get_short_id()); + $table->add('algo', $algo); + $table->add('created', $subkey->created ? $this->rc->format_date($subkey->created, $date_format, false) : ''); + $table->add('expires', $subkey->expires ? $this->rc->format_date($subkey->expires, $date_format, false) : $this->enigma->gettext('expiresnever')); + $table->add('usage', implode(',', $usage)); + $table->set_row_attribs($subkey->revoked || ($subkey->expires && $subkey->expires < $now) ? 'deleted' : ''); + } $out .= html::tag('fieldset', null, - html::tag('legend', null, - $this->enigma->gettext('subkeys')) . $table->show($attrib)); + html::tag('legend', null, + $this->enigma->gettext('subkeys')) . $table->show()); // Additional user IDs - $table = new html_table(array('cols' => 2)); - // Columns: User ID, Validity + $table = new html_table(array('cols' => 2, 'id' => 'enigmausertable', 'class' => 'records-table')); + + $table->add_header('id', $this->enigma->gettext('userid')); + $table->add_header('valid', $this->enigma->gettext('uservalid')); + + foreach ($this->data->users as $user) { + $username = $user->name; + if ($user->comment) { + $username .= ' (' . $user->comment . ')'; + } + $username .= ' <' . $user->email . '>'; + + $table->add('id', rcube::Q(trim($username))); + $table->add('valid', $this->enigma->gettext($user->valid ? 'valid' : 'unknown')); + $table->set_row_attribs($user->revoked || !$user->valid ? 'deleted' : ''); + } $out .= html::tag('fieldset', null, - html::tag('legend', null, - $this->enigma->gettext('userids')) . $table->show($attrib)); -*/ + html::tag('legend', null, + $this->enigma->gettext('userids')) . $table->show()); + return $out; } diff --git a/plugins/enigma/localization/en_US.inc b/plugins/enigma/localization/en_US.inc index 7cf376125..dd1d09093 100644 --- a/plugins/enigma/localization/en_US.inc +++ b/plugins/enigma/localization/en_US.inc @@ -28,11 +28,25 @@ $labels['keytype'] = 'Key type'; $labels['fingerprint'] = 'Fingerprint'; $labels['subkeys'] = 'Subkeys'; $labels['basicinfo'] = 'Basic Information'; -$labels['userids'] = 'Additional User IDs'; +$labels['userids'] = 'Additional Users'; $labels['typepublickey'] = 'public key'; $labels['typekeypair'] = 'key pair'; $labels['keyattfound'] = 'This message contains attached PGP key(s).'; $labels['keyattimport'] = 'Import key(s)'; +$labels['typesign'] = 'Sign'; +$labels['typeencrypt'] = 'Encrypt'; +$labels['typecert'] = 'Certify'; +$labels['typeauth'] = 'Authentication'; +$labels['subkeyid'] = 'ID'; +$labels['subkeyalgo'] = 'Algorithm'; +$labels['subkeycreated'] = 'Created'; +$labels['subkeyexpires'] = 'Expires'; +$labels['subkeyusage'] = 'Usage'; +$labels['expiresnever'] = 'never'; +$labels['unknown'] = 'unknown'; +$labels['uservalid'] = 'Valid'; +$labels['userid'] = 'ID'; +$labels['valid'] = 'valid'; $labels['supportencryption'] = 'Enable message encryption and signing'; $labels['supportsignatures'] = 'Enable message signatures verification'; diff --git a/plugins/enigma/skins/classic/enigma.css b/plugins/enigma/skins/classic/enigma.css index 2f5d331e4..68505065f 100644 --- a/plugins/enigma/skins/classic/enigma.css +++ b/plugins/enigma/skins/classic/enigma.css @@ -142,6 +142,15 @@ div.enigmascreen text-align: right; } +#key-details table { + width: 100%; +} + +#key-details table td, +#key-details table th { + border: 0; +} + #keystoolbar { position: absolute;