1<?php 2 3/** 4 +-------------------------------------------------------------------------+ 5 | Key class for the Enigma Plugin | 6 | | 7 | Copyright (C) The Roundcube Dev Team | 8 | | 9 | Licensed under the GNU General Public License version 3 or | 10 | any later version with exceptions for skins & plugins. | 11 | See the README file for a full license statement. | 12 +-------------------------------------------------------------------------+ 13 | Author: Aleksander Machniak <alec@alec.pl> | 14 +-------------------------------------------------------------------------+ 15*/ 16 17class enigma_key 18{ 19 public $id; 20 public $name; 21 public $users = []; 22 public $subkeys = []; 23 public $reference; 24 public $password; 25 26 const TYPE_UNKNOWN = 0; 27 const TYPE_KEYPAIR = 1; 28 const TYPE_PUBLIC = 2; 29 30 const CAN_ENCRYPT = 1; 31 const CAN_SIGN = 2; 32 const CAN_CERTIFY = 4; 33 const CAN_AUTHENTICATE = 8; 34 35 36 /** 37 * Keys list sorting callback for usort() 38 */ 39 static function cmp($a, $b) 40 { 41 return strcmp($a->name, $b->name); 42 } 43 44 /** 45 * Returns key type 46 * 47 * @return int One of self::TYPE_* constant values 48 */ 49 function get_type() 50 { 51 if (!empty($this->subkeys[0]) && $this->subkeys[0]->has_private) { 52 return enigma_key::TYPE_KEYPAIR; 53 } 54 else if (!empty($this->subkeys[0])) { 55 return enigma_key::TYPE_PUBLIC; 56 } 57 58 return enigma_key::TYPE_UNKNOWN; 59 } 60 61 /** 62 * Returns true if all subkeys are revoked 63 * 64 * @return bool 65 */ 66 function is_revoked() 67 { 68 foreach ($this->subkeys as $subkey) { 69 if (!$subkey->revoked) { 70 return false; 71 } 72 } 73 74 return !empty($this->subkeys); 75 } 76 77 /** 78 * Returns true if any user ID is valid 79 * 80 * @return bool 81 */ 82 function is_valid() 83 { 84 foreach ($this->users as $user) { 85 if ($user->valid) { 86 return true; 87 } 88 } 89 90 return false; 91 } 92 93 /** 94 * Returns true if any of subkeys is a private key 95 * 96 * @return bool 97 */ 98 function is_private() 99 { 100 foreach ($this->subkeys as $subkey) { 101 if ($subkey->has_private) { 102 return true; 103 } 104 } 105 106 return false; 107 } 108 109 /** 110 * Get key ID by user email 111 * 112 * @param string $email Email address 113 * @param int $mode Key mode (see self::CAN_* constants) 114 * 115 * @return enigma_subkey|null Subkey object 116 */ 117 function find_subkey($email, $mode) 118 { 119 foreach ($this->users as $user) { 120 if (strcasecmp($user->email, $email) === 0 && $user->valid && !$user->revoked) { 121 foreach ($this->subkeys as $subkey) { 122 if (!$subkey->revoked && !$subkey->is_expired()) { 123 if ($subkey->usage & $mode) { 124 return $subkey; 125 } 126 } 127 } 128 } 129 } 130 } 131 132 /** 133 * Converts long ID or Fingerprint to short ID 134 * Crypt_GPG uses internal, but e.g. Thunderbird's Enigmail displays short ID 135 * 136 * @param string $id Key ID or fingerprint 137 * 138 * @return string Key short ID 139 */ 140 static function format_id($id) 141 { 142 // E.g. 04622F2089E037A5 => 89E037A5 143 144 return substr($id, -8); 145 } 146 147 /** 148 * Formats fingerprint string 149 * 150 * @param string $fingerprint Key fingerprint 151 * 152 * @return string Formatted fingerprint (with spaces) 153 */ 154 static function format_fingerprint($fingerprint) 155 { 156 if (!$fingerprint) { 157 return ''; 158 } 159 160 $result = ''; 161 for ($i=0; $i<40; $i++) { 162 if ($i % 4 == 0) { 163 $result .= ' '; 164 } 165 $result .= $fingerprint[$i]; 166 } 167 168 return $result; 169 } 170} 171