elggpg.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <?php
  2. /**
  3. * ElggPG -- Helpers library
  4. *
  5. * @package Lorea
  6. * @subpackage ElggPG
  7. *
  8. * Copyright 2011-2013 Lorea Faeries <federation@lorea.org>
  9. *
  10. * This file is part of the ElggPG plugin for Elgg.
  11. *
  12. * ElggPG is free software: you can redistribute it and/or modify it
  13. * under the terms of the GNU Affero General Public License as
  14. * published by the Free Software Foundation, either version 3 of the
  15. * License, or (at your option) any later version.
  16. *
  17. * ElggPG is distributed in the hope that it will be useful, but
  18. * WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  20. * Affero General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU Affero General Public
  23. * License along with this program. If not, see
  24. * <http://www.gnu.org/licenses/>.
  25. */
  26. putenv("GNUPGHOME=" . elggpg_get_gpg_home());
  27. function elggpg_get_gpg_home() {
  28. // try to find location of settings from environment file,
  29. // which means the gpg directory goes at the same level.
  30. $elgg_config = getenv("elgg_config");
  31. if ($elgg_config && is_dir(dirname($elgg_config)."/gpg")) {
  32. return dirname($elgg_config)."/gpg";
  33. }
  34. // otherwise create a gpg folder at the data folder
  35. // and store the keys there
  36. $gpg_path = elgg_get_data_path() . "gpg/";
  37. if (!file_exists($gpg_path)) {
  38. mkdir($gpg_path);
  39. }
  40. return $gpg_path;
  41. }
  42. function elggpg_import_key($public_key, $user) {
  43. $gpg = new gnupg();
  44. $info = $gpg->import($public_key);
  45. $new_fp = $info['fingerprint'];
  46. $user_fp = current(elgg_get_metadata(array(
  47. 'guid' => $user->guid,
  48. 'metadata_name' => 'openpgp_publickey',
  49. )));
  50. $access_id = ACCESS_LOGGED_IN;
  51. if ($user_fp && $user_fp->value != $new_fp) {
  52. update_metadata($user_fp->id, $user_fp->name, $new_fp, 'text', $user->guid, $access_id);
  53. $info['imported'] = 1;
  54. } elseif (!$user_fp) {
  55. create_metadata($user->guid, "openpgp_publickey", $new_fp, 'text', $user->guid, $access_id);
  56. $info['imported'] = 1;
  57. }
  58. $info['key_id'] = elggpg_fp2keyid($new_fp);
  59. return $info;
  60. }
  61. function elggpg_fp2keyid($fp) {
  62. return substr($fp, count($fp)-17, 16);
  63. }
  64. function elggpg_import_report($info) {
  65. $yes = elgg_echo('option:yes');
  66. $no = elgg_echo('option:no');
  67. $search = "\\n";
  68. $replace = "<br />";
  69. return str_replace($search, $replace, elgg_echo("elggpg:import:report", array(
  70. $info['imported'] ? $yes : $no,
  71. $info['unchanged'] ? $yes : $no,
  72. $info['newuserids'] ? $yes : $no,
  73. $info['newsubkeys'] ? $yes : $no,
  74. $info['secretimported'] ? $yes : $no,
  75. $info['secretunchanged'] ? $yes : $no,
  76. $info['newsignatures'] ? $yes : $no,
  77. $info['skippedkeys'] ? $yes : $no,
  78. )));
  79. }
  80. function elggpg_export_key($user) {
  81. $gpg = new gnupg();
  82. return $gpg->export($user->openpgp_publickey);
  83. }
  84. function elggpg_haskey($user) {
  85. return $user->openpgp_publickey;
  86. }
  87. function elggpg_keyinfo($user) {
  88. $gnupg = new gnupg();
  89. $fingerprint = $user->openpgp_publickey;
  90. if (!$fingerprint) {
  91. return false;
  92. }
  93. try {
  94. $info = $gnupg->keyinfo($fingerprint);
  95. } catch (Exception $e) {
  96. return false;
  97. }
  98. $simple_info = array(
  99. 'name' => $info[0]['uids'][0]['name'],
  100. 'comment' => $info[0]['uids'][0]['comment'],
  101. 'email' => $info[0]['uids'][0]['email'],
  102. 'fingerprint' => $info[0]['subkeys'][0]['fingerprint'],
  103. 'subkeys' => array(),
  104. );
  105. if (strlen($simple_info['fingerprint']) < 1) {
  106. return false;
  107. }
  108. foreach ($info[0]['subkeys'] as $subkey) {
  109. if ($subkey['can_encrypt']) {
  110. $type = 'encrypt';
  111. }
  112. if ($subkey['can_sign']) {
  113. $type .= 'sign';
  114. }
  115. $simple_info['subkeys'][] = array(
  116. 'keyid' => $subkey['keyid'],
  117. 'type' => $type,
  118. 'created' => $subkey['timestamp'],
  119. 'expires' => $subkey['expires'],
  120. );
  121. }
  122. return $simple_info;
  123. }
  124. function elggpg_delete_key($user) {
  125. if (!$user->openpgp_publickey) {
  126. return false;
  127. }
  128. $count = elgg_get_entities_from_metadata(array(
  129. 'type' => 'user',
  130. 'metadata_name' => 'openpgp_publickey',
  131. 'metadata_value' => $user->openpgp_publickey,
  132. 'count' => true,
  133. ));
  134. if ($count > 1) {
  135. $user->openpgp_publickey = NULL;
  136. return true;
  137. }
  138. $gpg = new gnupg();
  139. $info = $gpg->deletekey($user->openpgp_publickey);
  140. $user->openpgp_publickey = NULL;
  141. return $info;
  142. }
  143. function elggpg_encrypt($body, $user, $force = true) {
  144. $already_encrypted = strpos($body, "-----BEGIN PGP MESSAGE-----") !== false;
  145. try {
  146. if (!$already_encrypted) {
  147. $gpg = new gnupg();
  148. $gpg->addencryptkey($user->openpgp_publickey);
  149. if ($encrbody = $gpg->encrypt($body)) {
  150. $body = $encrbody;
  151. } elseif ($force) {
  152. return false;
  153. }
  154. }
  155. } catch (Exception $e) {
  156. if ($force) {
  157. return false;
  158. }
  159. }
  160. return $body;
  161. }