You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GPG.php 75KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * Crypt_GPG is a package to use GPG from PHP
  5. *
  6. * This package provides an object oriented interface to GNU Privacy
  7. * Guard (GPG). It requires the GPG executable to be on the system.
  8. *
  9. * Though GPG can support symmetric-key cryptography, this package is intended
  10. * only to facilitate public-key cryptography.
  11. *
  12. * This file contains the main GPG class. The class in this file lets you
  13. * encrypt, decrypt, sign and verify data; import and delete keys; and perform
  14. * other useful GPG tasks.
  15. *
  16. * Example usage:
  17. * <code>
  18. * <?php
  19. * // encrypt some data
  20. * $gpg = new Crypt_GPG();
  21. * $gpg->addEncryptKey($mySecretKeyId);
  22. * $encryptedData = $gpg->encrypt($data);
  23. * ?>
  24. * </code>
  25. *
  26. * PHP version 5
  27. *
  28. * LICENSE:
  29. *
  30. * This library is free software; you can redistribute it and/or modify
  31. * it under the terms of the GNU Lesser General Public License as
  32. * published by the Free Software Foundation; either version 2.1 of the
  33. * License, or (at your option) any later version.
  34. *
  35. * This library is distributed in the hope that it will be useful,
  36. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  37. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  38. * Lesser General Public License for more details.
  39. *
  40. * You should have received a copy of the GNU Lesser General Public
  41. * License along with this library; if not, see
  42. * <http://www.gnu.org/licenses/>
  43. *
  44. * @category Encryption
  45. * @package Crypt_GPG
  46. * @author Nathan Fredrickson <nathan@silverorange.com>
  47. * @author Michael Gauthier <mike@silverorange.com>
  48. * @copyright 2005-2013 silverorange
  49. * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
  50. * @link http://pear.php.net/package/Crypt_GPG
  51. * @link http://pear.php.net/manual/en/package.encryption.crypt-gpg.php
  52. * @link http://www.gnupg.org/
  53. */
  54. /**
  55. * Base class for GPG methods
  56. */
  57. require_once 'Crypt/GPGAbstract.php';
  58. /**
  59. * GPG exception classes.
  60. */
  61. require_once 'Crypt/GPG/Exceptions.php';
  62. // {{{ class Crypt_GPG
  63. /**
  64. * A class to use GPG from PHP
  65. *
  66. * This class provides an object oriented interface to GNU Privacy Guard (GPG).
  67. *
  68. * Though GPG can support symmetric-key cryptography, this class is intended
  69. * only to facilitate public-key cryptography.
  70. *
  71. * @category Encryption
  72. * @package Crypt_GPG
  73. * @author Nathan Fredrickson <nathan@silverorange.com>
  74. * @author Michael Gauthier <mike@silverorange.com>
  75. * @copyright 2005-2013 silverorange
  76. * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
  77. * @link http://pear.php.net/package/Crypt_GPG
  78. * @link http://www.gnupg.org/
  79. */
  80. class Crypt_GPG extends Crypt_GPGAbstract
  81. {
  82. // {{{ class constants for data signing modes
  83. /**
  84. * Signing mode for normal signing of data. The signed message will not
  85. * be readable without special software.
  86. *
  87. * This is the default signing mode.
  88. *
  89. * @see Crypt_GPG::sign()
  90. * @see Crypt_GPG::signFile()
  91. */
  92. const SIGN_MODE_NORMAL = 1;
  93. /**
  94. * Signing mode for clearsigning data. Clearsigned signatures are ASCII
  95. * armored data and are readable without special software. If the signed
  96. * message is unencrypted, the message will still be readable. The message
  97. * text will be in the original encoding.
  98. *
  99. * @see Crypt_GPG::sign()
  100. * @see Crypt_GPG::signFile()
  101. */
  102. const SIGN_MODE_CLEAR = 2;
  103. /**
  104. * Signing mode for creating a detached signature. When using detached
  105. * signatures, only the signature data is returned. The original message
  106. * text may be distributed separately from the signature data. This is
  107. * useful for miltipart/signed email messages as per
  108. * {@link http://www.ietf.org/rfc/rfc3156.txt RFC 3156}.
  109. *
  110. * @see Crypt_GPG::sign()
  111. * @see Crypt_GPG::signFile()
  112. */
  113. const SIGN_MODE_DETACHED = 3;
  114. // }}}
  115. // {{{ class constants for fingerprint formats
  116. /**
  117. * No formatting is performed.
  118. *
  119. * Example: C3BC615AD9C766E5A85C1F2716D27458B1BBA1C4
  120. *
  121. * @see Crypt_GPG::getFingerprint()
  122. */
  123. const FORMAT_NONE = 1;
  124. /**
  125. * Fingerprint is formatted in the format used by the GnuPG gpg command's
  126. * default output.
  127. *
  128. * Example: C3BC 615A D9C7 66E5 A85C 1F27 16D2 7458 B1BB A1C4
  129. *
  130. * @see Crypt_GPG::getFingerprint()
  131. */
  132. const FORMAT_CANONICAL = 2;
  133. /**
  134. * Fingerprint is formatted in the format used when displaying X.509
  135. * certificates
  136. *
  137. * Example: C3:BC:61:5A:D9:C7:66:E5:A8:5C:1F:27:16:D2:74:58:B1:BB:A1:C4
  138. *
  139. * @see Crypt_GPG::getFingerprint()
  140. */
  141. const FORMAT_X509 = 3;
  142. // }}}
  143. // {{{ class constants for boolean options
  144. /**
  145. * Use to specify ASCII armored mode for returned data
  146. */
  147. const ARMOR_ASCII = true;
  148. /**
  149. * Use to specify binary mode for returned data
  150. */
  151. const ARMOR_BINARY = false;
  152. /**
  153. * Use to specify that line breaks in signed text should be normalized
  154. */
  155. const TEXT_NORMALIZED = true;
  156. /**
  157. * Use to specify that line breaks in signed text should not be normalized
  158. */
  159. const TEXT_RAW = false;
  160. // }}}
  161. // {{{ protected class properties
  162. /**
  163. * Keys used to encrypt
  164. *
  165. * The array is of the form:
  166. * <code>
  167. * array(
  168. * $key_id => array(
  169. * 'fingerprint' => $fingerprint,
  170. * 'passphrase' => null
  171. * )
  172. * );
  173. * </code>
  174. *
  175. * @var array
  176. * @see Crypt_GPG::addEncryptKey()
  177. * @see Crypt_GPG::clearEncryptKeys()
  178. */
  179. protected $encryptKeys = array();
  180. /**
  181. * Keys used to decrypt
  182. *
  183. * The array is of the form:
  184. * <code>
  185. * array(
  186. * $key_id => array(
  187. * 'fingerprint' => $fingerprint,
  188. * 'passphrase' => $passphrase
  189. * )
  190. * );
  191. * </code>
  192. *
  193. * @var array
  194. * @see Crypt_GPG::addSignKey()
  195. * @see Crypt_GPG::clearSignKeys()
  196. */
  197. protected $signKeys = array();
  198. /**
  199. * Keys used to sign
  200. *
  201. * The array is of the form:
  202. * <code>
  203. * array(
  204. * $key_id => array(
  205. * 'fingerprint' => $fingerprint,
  206. * 'passphrase' => $passphrase
  207. * )
  208. * );
  209. * </code>
  210. *
  211. * @var array
  212. * @see Crypt_GPG::addDecryptKey()
  213. * @see Crypt_GPG::clearDecryptKeys()
  214. */
  215. protected $decryptKeys = array();
  216. /**
  217. * Passphrases used on import/export of private keys in GnuPG 2.1
  218. *
  219. * The array is of the form:
  220. * <code>
  221. * array($key_id => $passphrase);
  222. * </code>
  223. *
  224. * @var array
  225. * @see Crypt_GPG::addPassphrase()
  226. * @see Crypt_GPG::clearPassphrases()
  227. */
  228. protected $passphrases = array();
  229. // }}}
  230. // {{{ importKey()
  231. /**
  232. * Imports a public or private key into the keyring
  233. *
  234. * Keys may be removed from the keyring using
  235. * {@link Crypt_GPG::deletePublicKey()} or
  236. * {@link Crypt_GPG::deletePrivateKey()}.
  237. *
  238. * @param string $data the key data to be imported.
  239. *
  240. * @return array an associative array containing the following elements:
  241. * - <kbd>fingerprint</kbd> - the fingerprint of the
  242. * imported key,
  243. * - <kbd>public_imported</kbd> - the number of public
  244. * keys imported,
  245. * - <kbd>public_unchanged</kbd> - the number of unchanged
  246. * public keys,
  247. * - <kbd>private_imported</kbd> - the number of private
  248. * keys imported,
  249. * - <kbd>private_unchanged</kbd> - the number of unchanged
  250. * private keys.
  251. *
  252. * @throws Crypt_GPG_NoDataException if the key data is missing or if the
  253. * data is is not valid key data.
  254. *
  255. * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
  256. * incorrect or if a required passphrase is not specified. See
  257. * {@link Crypt_GPG::addPassphrase()}.
  258. *
  259. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  260. * Use the <kbd>debug</kbd> option and file a bug report if these
  261. * exceptions occur.
  262. *
  263. * @see Crypt_GPG::addPassphrase()
  264. * @see Crypt_GPG::clearPassphrases()
  265. */
  266. public function importKey($data)
  267. {
  268. return $this->_importKey($data, false);
  269. }
  270. // }}}
  271. // {{{ importKeyFile()
  272. /**
  273. * Imports a public or private key file into the keyring
  274. *
  275. * Keys may be removed from the keyring using
  276. * {@link Crypt_GPG::deletePublicKey()} or
  277. * {@link Crypt_GPG::deletePrivateKey()}.
  278. *
  279. * @param string $filename the key file to be imported.
  280. *
  281. * @return array an associative array containing the following elements:
  282. * - <kbd>fingerprint</kbd> - the fingerprint of the
  283. * imported key,
  284. * - <kbd>public_imported</kbd> - the number of public
  285. * keys imported,
  286. * - <kbd>public_unchanged</kbd> - the number of unchanged
  287. * public keys,
  288. * - <kbd>private_imported</kbd> - the number of private
  289. * keys imported,
  290. * - <kbd>private_unchanged</kbd> - the number of unchanged
  291. * private keys.
  292. * private keys.
  293. *
  294. * @throws Crypt_GPG_NoDataException if the key data is missing or if the
  295. * data is is not valid key data.
  296. *
  297. * @throws Crypt_GPG_FileException if the key file is not readable.
  298. *
  299. * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
  300. * incorrect or if a required passphrase is not specified. See
  301. * {@link Crypt_GPG::addPassphrase()}.
  302. *
  303. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  304. * Use the <kbd>debug</kbd> option and file a bug report if these
  305. * exceptions occur.
  306. */
  307. public function importKeyFile($filename)
  308. {
  309. return $this->_importKey($filename, true);
  310. }
  311. // }}}
  312. // {{{ exportPrivateKey()
  313. /**
  314. * Exports a private key from the keyring
  315. *
  316. * The exported key remains on the keyring. To delete the key, use
  317. * {@link Crypt_GPG::deletePrivateKey()}.
  318. *
  319. * If more than one key fingerprint is available for the specified
  320. * <kbd>$keyId</kbd> (for example, if you use a non-unique uid) only the
  321. * first private key is exported.
  322. *
  323. * @param string $keyId either the full uid of the private key, the email
  324. * part of the uid of the private key or the key id of
  325. * the private key. For example,
  326. * "Test User (example) <test@example.com>",
  327. * "test@example.com" or a hexadecimal string.
  328. * @param boolean $armor optional. If true, ASCII armored data is returned;
  329. * otherwise, binary data is returned. Defaults to
  330. * true.
  331. *
  332. * @return string the private key data.
  333. *
  334. * @throws Crypt_GPG_KeyNotFoundException if a private key with the given
  335. * <kbd>$keyId</kbd> is not found.
  336. *
  337. * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
  338. * incorrect or if a required passphrase is not specified. See
  339. * {@link Crypt_GPG::addPassphrase()}.
  340. *
  341. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  342. * Use the <kbd>debug</kbd> option and file a bug report if these
  343. * exceptions occur.
  344. */
  345. public function exportPrivateKey($keyId, $armor = true)
  346. {
  347. return $this->_exportKey($keyId, $armor, true);
  348. }
  349. // }}}
  350. // {{{ exportPublicKey()
  351. /**
  352. * Exports a public key from the keyring
  353. *
  354. * The exported key remains on the keyring. To delete the public key, use
  355. * {@link Crypt_GPG::deletePublicKey()}.
  356. *
  357. * If more than one key fingerprint is available for the specified
  358. * <kbd>$keyId</kbd> (for example, if you use a non-unique uid) only the
  359. * first public key is exported.
  360. *
  361. * @param string $keyId either the full uid of the public key, the email
  362. * part of the uid of the public key or the key id of
  363. * the public key. For example,
  364. * "Test User (example) <test@example.com>",
  365. * "test@example.com" or a hexadecimal string.
  366. * @param boolean $armor optional. If true, ASCII armored data is returned;
  367. * otherwise, binary data is returned. Defaults to
  368. * true.
  369. *
  370. * @return string the public key data.
  371. *
  372. * @throws Crypt_GPG_KeyNotFoundException if a public key with the given
  373. * <kbd>$keyId</kbd> is not found.
  374. *
  375. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  376. * Use the <kbd>debug</kbd> option and file a bug report if these
  377. * exceptions occur.
  378. */
  379. public function exportPublicKey($keyId, $armor = true)
  380. {
  381. return $this->_exportKey($keyId, $armor, false);
  382. }
  383. // }}}
  384. // {{{ deletePublicKey()
  385. /**
  386. * Deletes a public key from the keyring
  387. *
  388. * If more than one key fingerprint is available for the specified
  389. * <kbd>$keyId</kbd> (for example, if you use a non-unique uid) only the
  390. * first public key is deleted.
  391. *
  392. * The private key must be deleted first or an exception will be thrown.
  393. * In GnuPG >= 2.1 this limitation does not exist.
  394. * See {@link Crypt_GPG::deletePrivateKey()}.
  395. *
  396. * @param string $keyId either the full uid of the public key, the email
  397. * part of the uid of the public key or the key id of
  398. * the public key. For example,
  399. * "Test User (example) <test@example.com>",
  400. * "test@example.com" or a hexadecimal string.
  401. *
  402. * @return void
  403. *
  404. * @throws Crypt_GPG_KeyNotFoundException if a public key with the given
  405. * <kbd>$keyId</kbd> is not found.
  406. *
  407. * @throws Crypt_GPG_DeletePrivateKeyException if the specified public key
  408. * has an associated private key on the keyring. The private key
  409. * must be deleted first (when using GnuPG < 2.1).
  410. *
  411. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  412. * Use the <kbd>debug</kbd> option and file a bug report if these
  413. * exceptions occur.
  414. */
  415. public function deletePublicKey($keyId)
  416. {
  417. $fingerprint = $this->getFingerprint($keyId);
  418. if ($fingerprint === null) {
  419. throw new Crypt_GPG_KeyNotFoundException(
  420. 'Public key not found: ' . $keyId,
  421. self::ERROR_KEY_NOT_FOUND,
  422. $keyId
  423. );
  424. }
  425. $operation = '--delete-key ' . escapeshellarg($fingerprint);
  426. $arguments = array(
  427. '--batch',
  428. '--yes'
  429. );
  430. $this->engine->reset();
  431. $this->engine->setOperation($operation, $arguments);
  432. $this->engine->run();
  433. }
  434. // }}}
  435. // {{{ deletePrivateKey()
  436. /**
  437. * Deletes a private key from the keyring
  438. *
  439. * If more than one key fingerprint is available for the specified
  440. * <kbd>$keyId</kbd> (for example, if you use a non-unique uid) only the
  441. * first private key is deleted.
  442. *
  443. * Calls GPG with the <kbd>--delete-secret-key</kbd> command.
  444. *
  445. * @param string $keyId either the full uid of the private key, the email
  446. * part of the uid of the private key or the key id of
  447. * the private key. For example,
  448. * "Test User (example) <test@example.com>",
  449. * "test@example.com" or a hexadecimal string.
  450. *
  451. * @return void
  452. *
  453. * @throws Crypt_GPG_KeyNotFoundException if a private key with the given
  454. * <kbd>$keyId</kbd> is not found.
  455. *
  456. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  457. * Use the <kbd>debug</kbd> option and file a bug report if these
  458. * exceptions occur.
  459. */
  460. public function deletePrivateKey($keyId)
  461. {
  462. $fingerprint = $this->getFingerprint($keyId);
  463. if ($fingerprint === null) {
  464. throw new Crypt_GPG_KeyNotFoundException(
  465. 'Private key not found: ' . $keyId,
  466. self::ERROR_KEY_NOT_FOUND,
  467. $keyId
  468. );
  469. }
  470. $operation = '--delete-secret-key ' . escapeshellarg($fingerprint);
  471. $arguments = array(
  472. '--batch',
  473. '--yes'
  474. );
  475. $this->engine->reset();
  476. $this->engine->setOperation($operation, $arguments);
  477. $this->engine->run();
  478. }
  479. // }}}
  480. // {{{ getKeys()
  481. /**
  482. * Gets the available keys in the keyring
  483. *
  484. * Calls GPG with the <kbd>--list-keys</kbd> command and grabs keys. See
  485. * the first section of <b>doc/DETAILS</b> in the
  486. * {@link http://www.gnupg.org/download/ GPG package} for a detailed
  487. * description of how the GPG command output is parsed.
  488. *
  489. * @param string $keyId optional. Only keys with that match the specified
  490. * pattern are returned. The pattern may be part of
  491. * a user id, a key id or a key fingerprint. If not
  492. * specified, all keys are returned.
  493. *
  494. * @return array an array of {@link Crypt_GPG_Key} objects. If no keys
  495. * match the specified <kbd>$keyId</kbd> an empty array is
  496. * returned.
  497. *
  498. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  499. * Use the <kbd>debug</kbd> option and file a bug report if these
  500. * exceptions occur.
  501. *
  502. * @see Crypt_GPG_Key
  503. */
  504. public function getKeys($keyId = '')
  505. {
  506. return parent::_getKeys($keyId);
  507. }
  508. // }}}
  509. // {{{ getFingerprint()
  510. /**
  511. * Gets a key fingerprint from the keyring
  512. *
  513. * If more than one key fingerprint is available (for example, if you use
  514. * a non-unique user id) only the first key fingerprint is returned.
  515. *
  516. * Calls the GPG <kbd>--list-keys</kbd> command with the
  517. * <kbd>--with-fingerprint</kbd> option to retrieve a public key
  518. * fingerprint.
  519. *
  520. * @param string $keyId either the full user id of the key, the email
  521. * part of the user id of the key, or the key id of
  522. * the key. For example,
  523. * "Test User (example) <test@example.com>",
  524. * "test@example.com" or a hexadecimal string.
  525. * @param integer $format optional. How the fingerprint should be formatted.
  526. * Use {@link Crypt_GPG::FORMAT_X509} for X.509
  527. * certificate format,
  528. * {@link Crypt_GPG::FORMAT_CANONICAL} for the format
  529. * used by GnuPG output and
  530. * {@link Crypt_GPG::FORMAT_NONE} for no formatting.
  531. * Defaults to <code>Crypt_GPG::FORMAT_NONE</code>.
  532. *
  533. * @return string the fingerprint of the key, or null if no fingerprint
  534. * is found for the given <kbd>$keyId</kbd>.
  535. *
  536. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  537. * Use the <kbd>debug</kbd> option and file a bug report if these
  538. * exceptions occur.
  539. */
  540. public function getFingerprint($keyId, $format = self::FORMAT_NONE)
  541. {
  542. $output = '';
  543. $operation = '--list-keys ' . escapeshellarg($keyId);
  544. $arguments = array(
  545. '--with-colons',
  546. '--with-fingerprint'
  547. );
  548. $this->engine->reset();
  549. $this->engine->setOutput($output);
  550. $this->engine->setOperation($operation, $arguments);
  551. $this->engine->run();
  552. $fingerprint = null;
  553. foreach (explode(PHP_EOL, $output) as $line) {
  554. if (mb_substr($line, 0, 3, '8bit') == 'fpr') {
  555. $lineExp = explode(':', $line);
  556. $fingerprint = $lineExp[9];
  557. switch ($format) {
  558. case self::FORMAT_CANONICAL:
  559. $fingerprintExp = str_split($fingerprint, 4);
  560. $format = '%s %s %s %s %s %s %s %s %s %s';
  561. $fingerprint = vsprintf($format, $fingerprintExp);
  562. break;
  563. case self::FORMAT_X509:
  564. $fingerprintExp = str_split($fingerprint, 2);
  565. $fingerprint = implode(':', $fingerprintExp);
  566. break;
  567. }
  568. break;
  569. }
  570. }
  571. return $fingerprint;
  572. }
  573. // }}}
  574. // {{{ getLastSignatureInfo()
  575. /**
  576. * Get information about the last signature that was created.
  577. *
  578. * @return Crypt_GPG_SignatureCreationInfo
  579. */
  580. public function getLastSignatureInfo()
  581. {
  582. return $this->engine->getProcessData('SignatureInfo');
  583. }
  584. // }}}
  585. // {{{ encrypt()
  586. /**
  587. * Encrypts string data
  588. *
  589. * Data is ASCII armored by default but may optionally be returned as
  590. * binary.
  591. *
  592. * @param string $data the data to be encrypted.
  593. * @param boolean $armor optional. If true, ASCII armored data is returned;
  594. * otherwise, binary data is returned. Defaults to
  595. * true.
  596. *
  597. * @return string the encrypted data.
  598. *
  599. * @throws Crypt_GPG_KeyNotFoundException if no encryption key is specified.
  600. * See {@link Crypt_GPG::addEncryptKey()}.
  601. *
  602. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  603. * Use the <kbd>debug</kbd> option and file a bug report if these
  604. * exceptions occur.
  605. *
  606. * @sensitive $data
  607. */
  608. public function encrypt($data, $armor = self::ARMOR_ASCII)
  609. {
  610. return $this->_encrypt($data, false, null, $armor);
  611. }
  612. // }}}
  613. // {{{ encryptFile()
  614. /**
  615. * Encrypts a file
  616. *
  617. * Encrypted data is ASCII armored by default but may optionally be saved
  618. * as binary.
  619. *
  620. * @param string $filename the filename of the file to encrypt.
  621. * @param string $encryptedFile optional. The filename of the file in
  622. * which to store the encrypted data. If null
  623. * or unspecified, the encrypted data is
  624. * returned as a string.
  625. * @param boolean $armor optional. If true, ASCII armored data is
  626. * returned; otherwise, binary data is
  627. * returned. Defaults to true.
  628. *
  629. * @return void|string if the <kbd>$encryptedFile</kbd> parameter is null,
  630. * a string containing the encrypted data is returned.
  631. *
  632. * @throws Crypt_GPG_KeyNotFoundException if no encryption key is specified.
  633. * See {@link Crypt_GPG::addEncryptKey()}.
  634. *
  635. * @throws Crypt_GPG_FileException if the output file is not writeable or
  636. * if the input file is not readable.
  637. *
  638. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  639. * Use the <kbd>debug</kbd> option and file a bug report if these
  640. * exceptions occur.
  641. */
  642. public function encryptFile(
  643. $filename,
  644. $encryptedFile = null,
  645. $armor = self::ARMOR_ASCII
  646. ) {
  647. return $this->_encrypt($filename, true, $encryptedFile, $armor);
  648. }
  649. // }}}
  650. // {{{ encryptAndSign()
  651. /**
  652. * Encrypts and signs data
  653. *
  654. * Data is encrypted and signed in a single pass.
  655. *
  656. * NOTE: Until GnuPG version 1.4.10, it was not possible to verify
  657. * encrypted-signed data without decrypting it at the same time. If you try
  658. * to use {@link Crypt_GPG::verify()} method on encrypted-signed data with
  659. * earlier GnuPG versions, you will get an error. Please use
  660. * {@link Crypt_GPG::decryptAndVerify()} to verify encrypted-signed data.
  661. *
  662. * @param string $data the data to be encrypted and signed.
  663. * @param boolean $armor optional. If true, ASCII armored data is returned;
  664. * otherwise, binary data is returned. Defaults to
  665. * true.
  666. *
  667. * @return string the encrypted signed data.
  668. *
  669. * @throws Crypt_GPG_KeyNotFoundException if no encryption key is specified
  670. * or if no signing key is specified. See
  671. * {@link Crypt_GPG::addEncryptKey()} and
  672. * {@link Crypt_GPG::addSignKey()}.
  673. *
  674. * @throws Crypt_GPG_BadPassphraseException if a specified passphrase is
  675. * incorrect or if a required passphrase is not specified.
  676. *
  677. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  678. * Use the <kbd>debug</kbd> option and file a bug report if these
  679. * exceptions occur.
  680. *
  681. * @see Crypt_GPG::decryptAndVerify()
  682. */
  683. public function encryptAndSign($data, $armor = self::ARMOR_ASCII)
  684. {
  685. return $this->_encryptAndSign($data, false, null, $armor);
  686. }
  687. // }}}
  688. // {{{ encryptAndSignFile()
  689. /**
  690. * Encrypts and signs a file
  691. *
  692. * The file is encrypted and signed in a single pass.
  693. *
  694. * NOTE: Until GnuPG version 1.4.10, it was not possible to verify
  695. * encrypted-signed files without decrypting them at the same time. If you
  696. * try to use {@link Crypt_GPG::verify()} method on encrypted-signed files
  697. * with earlier GnuPG versions, you will get an error. Please use
  698. * {@link Crypt_GPG::decryptAndVerifyFile()} to verify encrypted-signed
  699. * files.
  700. *
  701. * @param string $filename the name of the file containing the data to
  702. * be encrypted and signed.
  703. * @param string $signedFile optional. The name of the file in which the
  704. * encrypted, signed data should be stored. If
  705. * null or unspecified, the encrypted, signed
  706. * data is returned as a string.
  707. * @param boolean $armor optional. If true, ASCII armored data is
  708. * returned; otherwise, binary data is returned.
  709. * Defaults to true.
  710. *
  711. * @return void|string if the <kbd>$signedFile</kbd> parameter is null, a
  712. * string containing the encrypted, signed data is
  713. * returned.
  714. *
  715. * @throws Crypt_GPG_KeyNotFoundException if no encryption key is specified
  716. * or if no signing key is specified. See
  717. * {@link Crypt_GPG::addEncryptKey()} and
  718. * {@link Crypt_GPG::addSignKey()}.
  719. *
  720. * @throws Crypt_GPG_BadPassphraseException if a specified passphrase is
  721. * incorrect or if a required passphrase is not specified.
  722. *
  723. * @throws Crypt_GPG_FileException if the output file is not writeable or
  724. * if the input file is not readable.
  725. *
  726. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  727. * Use the <kbd>debug</kbd> option and file a bug report if these
  728. * exceptions occur.
  729. *
  730. * @see Crypt_GPG::decryptAndVerifyFile()
  731. */
  732. public function encryptAndSignFile(
  733. $filename,
  734. $signedFile = null,
  735. $armor = self::ARMOR_ASCII
  736. ) {
  737. return $this->_encryptAndSign($filename, true, $signedFile, $armor);
  738. }
  739. // }}}
  740. // {{{ decrypt()
  741. /**
  742. * Decrypts string data
  743. *
  744. * This method assumes the required private key is available in the keyring
  745. * and throws an exception if the private key is not available. To add a
  746. * private key to the keyring, use the {@link Crypt_GPG::importKey()} or
  747. * {@link Crypt_GPG::importKeyFile()} methods.
  748. *
  749. * @param string $encryptedData the data to be decrypted.
  750. *
  751. * @return string the decrypted data.
  752. *
  753. * @throws Crypt_GPG_KeyNotFoundException if the private key needed to
  754. * decrypt the data is not in the user's keyring.
  755. *
  756. * @throws Crypt_GPG_NoDataException if specified data does not contain
  757. * GPG encrypted data.
  758. *
  759. * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
  760. * incorrect or if a required passphrase is not specified. See
  761. * {@link Crypt_GPG::addDecryptKey()}.
  762. *
  763. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  764. * Use the <kbd>debug</kbd> option and file a bug report if these
  765. * exceptions occur.
  766. */
  767. public function decrypt($encryptedData)
  768. {
  769. return $this->_decrypt($encryptedData, false, null);
  770. }
  771. // }}}
  772. // {{{ decryptFile()
  773. /**
  774. * Decrypts a file
  775. *
  776. * This method assumes the required private key is available in the keyring
  777. * and throws an exception if the private key is not available. To add a
  778. * private key to the keyring, use the {@link Crypt_GPG::importKey()} or
  779. * {@link Crypt_GPG::importKeyFile()} methods.
  780. *
  781. * @param string $encryptedFile the name of the encrypted file data to
  782. * decrypt.
  783. * @param string $decryptedFile optional. The name of the file to which the
  784. * decrypted data should be written. If null
  785. * or unspecified, the decrypted data is
  786. * returned as a string.
  787. *
  788. * @return void|string if the <kbd>$decryptedFile</kbd> parameter is null,
  789. * a string containing the decrypted data is returned.
  790. *
  791. * @throws Crypt_GPG_KeyNotFoundException if the private key needed to
  792. * decrypt the data is not in the user's keyring.
  793. *
  794. * @throws Crypt_GPG_NoDataException if specified data does not contain
  795. * GPG encrypted data.
  796. *
  797. * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
  798. * incorrect or if a required passphrase is not specified. See
  799. * {@link Crypt_GPG::addDecryptKey()}.
  800. *
  801. * @throws Crypt_GPG_FileException if the output file is not writeable or
  802. * if the input file is not readable.
  803. *
  804. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  805. * Use the <kbd>debug</kbd> option and file a bug report if these
  806. * exceptions occur.
  807. */
  808. public function decryptFile($encryptedFile, $decryptedFile = null)
  809. {
  810. return $this->_decrypt($encryptedFile, true, $decryptedFile);
  811. }
  812. // }}}
  813. // {{{ decryptAndVerify()
  814. /**
  815. * Decrypts and verifies string data
  816. *
  817. * This method assumes the required private key is available in the keyring
  818. * and throws an exception if the private key is not available. To add a
  819. * private key to the keyring, use the {@link Crypt_GPG::importKey()} or
  820. * {@link Crypt_GPG::importKeyFile()} methods.
  821. *
  822. * @param string $encryptedData the encrypted, signed data to be decrypted
  823. * and verified.
  824. * @param boolean $ignoreVerifyErrors enables ignoring of signature
  825. * verification errors caused by missing public key
  826. * When enabled Crypt_GPG_KeyNotFoundException
  827. * will not be thrown.
  828. *
  829. * @return array two element array. The array has an element 'data'
  830. * containing the decrypted data and an element
  831. * 'signatures' containing an array of
  832. * {@link Crypt_GPG_Signature} objects for the signed data.
  833. *
  834. * @throws Crypt_GPG_KeyNotFoundException if the private key needed to
  835. * decrypt the data or the public key to verify the signature
  836. * is not in the user's keyring.
  837. *
  838. * @throws Crypt_GPG_NoDataException if specified data does not contain
  839. * GPG encrypted data.
  840. *
  841. * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
  842. * incorrect or if a required passphrase is not specified. See
  843. * {@link Crypt_GPG::addDecryptKey()}.
  844. *
  845. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  846. * Use the <kbd>debug</kbd> option and file a bug report if these
  847. * exceptions occur.
  848. */
  849. public function decryptAndVerify($encryptedData, $ignoreVerifyErrors = false)
  850. {
  851. return $this->_decryptAndVerify($encryptedData, false, null, $ignoreVerifyErrors);
  852. }
  853. // }}}
  854. // {{{ decryptAndVerifyFile()
  855. /**
  856. * Decrypts and verifies a signed, encrypted file
  857. *
  858. * This method assumes the required private key is available in the keyring
  859. * and throws an exception if the private key is not available. To add a
  860. * private key to the keyring, use the {@link Crypt_GPG::importKey()} or
  861. * {@link Crypt_GPG::importKeyFile()} methods.
  862. *
  863. * @param string $encryptedFile the name of the signed, encrypted file to
  864. * to decrypt and verify.
  865. * @param string $decryptedFile optional. The name of the file to which the
  866. * decrypted data should be written. If null
  867. * or unspecified, the decrypted data is
  868. * returned in the results array.
  869. * @param boolean $ignoreVerifyErrors enables ignoring of signature
  870. * verification errors caused by missing public key
  871. * When enabled Crypt_GPG_KeyNotFoundException
  872. * will not be thrown.
  873. *
  874. * @return array two element array. The array has an element 'data'
  875. * containing the decrypted data and an element
  876. * 'signatures' containing an array of
  877. * {@link Crypt_GPG_Signature} objects for the signed data.
  878. * If the decrypted data is written to a file, the 'data'
  879. * element is null.
  880. *
  881. * @throws Crypt_GPG_KeyNotFoundException if the private key needed to
  882. * decrypt the data or the public key to verify the signature
  883. * is not in the user's keyring.
  884. *
  885. * @throws Crypt_GPG_NoDataException if specified data does not contain
  886. * GPG encrypted data.
  887. *
  888. * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
  889. * incorrect or if a required passphrase is not specified. See
  890. * {@link Crypt_GPG::addDecryptKey()}.
  891. *
  892. * @throws Crypt_GPG_FileException if the output file is not writeable or
  893. * if the input file is not readable.
  894. *
  895. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  896. * Use the <kbd>debug</kbd> option and file a bug report if these
  897. * exceptions occur.
  898. */
  899. public function decryptAndVerifyFile($encryptedFile, $decryptedFile = null, $ignoreVerifyErrors = false)
  900. {
  901. return $this->_decryptAndVerify($encryptedFile, true, $decryptedFile, $ignoreVerifyErrors);
  902. }
  903. // }}}
  904. // {{{ sign()
  905. /**
  906. * Signs data
  907. *
  908. * Data may be signed using any one of the three available signing modes:
  909. * - {@link Crypt_GPG::SIGN_MODE_NORMAL}
  910. * - {@link Crypt_GPG::SIGN_MODE_CLEAR}
  911. * - {@link Crypt_GPG::SIGN_MODE_DETACHED}
  912. *
  913. * @param string $data the data to be signed.
  914. * @param boolean $mode optional. The data signing mode to use. Should
  915. * be one of {@link Crypt_GPG::SIGN_MODE_NORMAL},
  916. * {@link Crypt_GPG::SIGN_MODE_CLEAR} or
  917. * {@link Crypt_GPG::SIGN_MODE_DETACHED}. If not
  918. * specified, defaults to
  919. * <kbd>Crypt_GPG::SIGN_MODE_NORMAL</kbd>.
  920. * @param boolean $armor optional. If true, ASCII armored data is
  921. * returned; otherwise, binary data is returned.
  922. * Defaults to true. This has no effect if the
  923. * mode <kbd>Crypt_GPG::SIGN_MODE_CLEAR</kbd> is
  924. * used.
  925. * @param boolean $textmode optional. If true, line-breaks in signed data
  926. * are normalized. Use this option when signing
  927. * e-mail, or for greater compatibility between
  928. * systems with different line-break formats.
  929. * Defaults to false. This has no effect if the
  930. * mode <kbd>Crypt_GPG::SIGN_MODE_CLEAR</kbd> is
  931. * used as clear-signing always uses textmode.
  932. *
  933. * @return string the signed data, or the signature data if a detached
  934. * signature is requested.
  935. *
  936. * @throws Crypt_GPG_KeyNotFoundException if no signing key is specified.
  937. * See {@link Crypt_GPG::addSignKey()}.
  938. *
  939. * @throws Crypt_GPG_BadPassphraseException if a specified passphrase is
  940. * incorrect or if a required passphrase is not specified.
  941. *
  942. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  943. * Use the <kbd>debug</kbd> option and file a bug report if these
  944. * exceptions occur.
  945. */
  946. public function sign(
  947. $data,
  948. $mode = self::SIGN_MODE_NORMAL,
  949. $armor = self::ARMOR_ASCII,
  950. $textmode = self::TEXT_RAW
  951. ) {
  952. return $this->_sign($data, false, null, $mode, $armor, $textmode);
  953. }
  954. // }}}
  955. // {{{ signFile()
  956. /**
  957. * Signs a file
  958. *
  959. * The file may be signed using any one of the three available signing
  960. * modes:
  961. * - {@link Crypt_GPG::SIGN_MODE_NORMAL}
  962. * - {@link Crypt_GPG::SIGN_MODE_CLEAR}
  963. * - {@link Crypt_GPG::SIGN_MODE_DETACHED}
  964. *
  965. * @param string $filename the name of the file containing the data to
  966. * be signed.
  967. * @param string $signedFile optional. The name of the file in which the
  968. * signed data should be stored. If null or
  969. * unspecified, the signed data is returned as a
  970. * string.
  971. * @param boolean $mode optional. The data signing mode to use. Should
  972. * be one of {@link Crypt_GPG::SIGN_MODE_NORMAL},
  973. * {@link Crypt_GPG::SIGN_MODE_CLEAR} or
  974. * {@link Crypt_GPG::SIGN_MODE_DETACHED}. If not
  975. * specified, defaults to
  976. * <kbd>Crypt_GPG::SIGN_MODE_NORMAL</kbd>.
  977. * @param boolean $armor optional. If true, ASCII armored data is
  978. * returned; otherwise, binary data is returned.
  979. * Defaults to true. This has no effect if the
  980. * mode <kbd>Crypt_GPG::SIGN_MODE_CLEAR</kbd> is
  981. * used.
  982. * @param boolean $textmode optional. If true, line-breaks in signed data
  983. * are normalized. Use this option when signing
  984. * e-mail, or for greater compatibility between
  985. * systems with different line-break formats.
  986. * Defaults to false. This has no effect if the
  987. * mode <kbd>Crypt_GPG::SIGN_MODE_CLEAR</kbd> is
  988. * used as clear-signing always uses textmode.
  989. *
  990. * @return void|string if the <kbd>$signedFile</kbd> parameter is null, a
  991. * string containing the signed data (or the signature
  992. * data if a detached signature is requested) is
  993. * returned.
  994. *
  995. * @throws Crypt_GPG_KeyNotFoundException if no signing key is specified.
  996. * See {@link Crypt_GPG::addSignKey()}.
  997. *
  998. * @throws Crypt_GPG_BadPassphraseException if a specified passphrase is
  999. * incorrect or if a required passphrase is not specified.
  1000. *
  1001. * @throws Crypt_GPG_FileException if the output file is not writeable or
  1002. * if the input file is not readable.
  1003. *
  1004. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  1005. * Use the <kbd>debug</kbd> option and file a bug report if these
  1006. * exceptions occur.
  1007. */
  1008. public function signFile(
  1009. $filename,
  1010. $signedFile = null,
  1011. $mode = self::SIGN_MODE_NORMAL,
  1012. $armor = self::ARMOR_ASCII,
  1013. $textmode = self::TEXT_RAW
  1014. ) {
  1015. return $this->_sign(
  1016. $filename,
  1017. true,
  1018. $signedFile,
  1019. $mode,
  1020. $armor,
  1021. $textmode
  1022. );
  1023. }
  1024. // }}}
  1025. // {{{ verify()
  1026. /**
  1027. * Verifies signed data
  1028. *
  1029. * The {@link Crypt_GPG::decrypt()} method may be used to get the original
  1030. * message if the signed data is not clearsigned and does not use a
  1031. * detached signature.
  1032. *
  1033. * @param string $signedData the signed data to be verified.
  1034. * @param string $signature optional. If verifying data signed using a
  1035. * detached signature, this must be the detached
  1036. * signature data. The data that was signed is
  1037. * specified in <kbd>$signedData</kbd>.
  1038. *
  1039. * @return array an array of {@link Crypt_GPG_Signature} objects for the
  1040. * signed data. For each signature that is valid, the
  1041. * {@link Crypt_GPG_Signature::isValid()} will return true.
  1042. *
  1043. * @throws Crypt_GPG_KeyNotFoundException if the public key needed for
  1044. * signature verification is not in the user's keyring.
  1045. *
  1046. * @throws Crypt_GPG_NoDataException if the provided data is not signed
  1047. * data.
  1048. *
  1049. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  1050. * Use the <kbd>debug</kbd> option and file a bug report if these
  1051. * exceptions occur.
  1052. *
  1053. * @see Crypt_GPG_Signature
  1054. */
  1055. public function verify($signedData, $signature = '')
  1056. {
  1057. return $this->_verify($signedData, false, $signature);
  1058. }
  1059. // }}}
  1060. // {{{ verifyFile()
  1061. /**
  1062. * Verifies a signed file
  1063. *
  1064. * The {@link Crypt_GPG::decryptFile()} method may be used to get the
  1065. * original message if the signed data is not clearsigned and does not use
  1066. * a detached signature.
  1067. *
  1068. * @param string $filename the signed file to be verified.
  1069. * @param string $signature optional. If verifying a file signed using a
  1070. * detached signature, this must be the detached
  1071. * signature data. The file that was signed is
  1072. * specified in <kbd>$filename</kbd>.
  1073. *
  1074. * @return array an array of {@link Crypt_GPG_Signature} objects for the
  1075. * signed data. For each signature that is valid, the
  1076. * {@link Crypt_GPG_Signature::isValid()} will return true.
  1077. *
  1078. * @throws Crypt_GPG_KeyNotFoundException if the public key needed for
  1079. * signature verification is not in the user's keyring.
  1080. *
  1081. * @throws Crypt_GPG_NoDataException if the provided data is not signed
  1082. * data.
  1083. *
  1084. * @throws Crypt_GPG_FileException if the input file is not readable.
  1085. *
  1086. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  1087. * Use the <kbd>debug</kbd> option and file a bug report if these
  1088. * exceptions occur.
  1089. *
  1090. * @see Crypt_GPG_Signature
  1091. */
  1092. public function verifyFile($filename, $signature = '')
  1093. {
  1094. return $this->_verify($filename, true, $signature);
  1095. }
  1096. // }}}
  1097. // {{{ addDecryptKey()
  1098. /**
  1099. * Adds a key to use for decryption
  1100. *
  1101. * @param mixed $key the key to use. This may be a key identifier,
  1102. * user id, fingerprint, {@link Crypt_GPG_Key} or
  1103. * {@link Crypt_GPG_SubKey}. The key must be able
  1104. * to encrypt.
  1105. * @param string $passphrase optional. The passphrase of the key required
  1106. * for decryption.
  1107. *
  1108. * @return Crypt_GPG the current object, for fluent interface.
  1109. *
  1110. * @see Crypt_GPG::decrypt()
  1111. * @see Crypt_GPG::decryptFile()
  1112. * @see Crypt_GPG::clearDecryptKeys()
  1113. * @see Crypt_GPG::_addKey()
  1114. *
  1115. * @sensitive $passphrase
  1116. */
  1117. public function addDecryptKey($key, $passphrase = null)
  1118. {
  1119. $this->_addKey($this->decryptKeys, false, false, $key, $passphrase);
  1120. return $this;
  1121. }
  1122. // }}}
  1123. // {{{ addEncryptKey()
  1124. /**
  1125. * Adds a key to use for encryption
  1126. *
  1127. * @param mixed $key the key to use. This may be a key identifier, user id
  1128. * user id, fingerprint, {@link Crypt_GPG_Key} or
  1129. * {@link Crypt_GPG_SubKey}. The key must be able to
  1130. * encrypt.
  1131. *
  1132. * @return Crypt_GPG the current object, for fluent interface.
  1133. *
  1134. * @see Crypt_GPG::encrypt()
  1135. * @see Crypt_GPG::encryptFile()
  1136. * @see Crypt_GPG::clearEncryptKeys()
  1137. * @see Crypt_GPG::_addKey()
  1138. */
  1139. public function addEncryptKey($key)
  1140. {
  1141. $this->_addKey($this->encryptKeys, true, false, $key);
  1142. return $this;
  1143. }
  1144. // }}}
  1145. // {{{ addSignKey()
  1146. /**
  1147. * Adds a key to use for signing
  1148. *
  1149. * @param mixed $key the key to use. This may be a key identifier,
  1150. * user id, fingerprint, {@link Crypt_GPG_Key} or
  1151. * {@link Crypt_GPG_SubKey}. The key must be able
  1152. * to sign.
  1153. * @param string $passphrase optional. The passphrase of the key required
  1154. * for signing.
  1155. *
  1156. * @return Crypt_GPG the current object, for fluent interface.
  1157. *
  1158. * @see Crypt_GPG::sign()
  1159. * @see Crypt_GPG::signFile()
  1160. * @see Crypt_GPG::clearSignKeys()
  1161. * @see Crypt_GPG::_addKey()
  1162. *
  1163. * @sensitive $passphrase
  1164. */
  1165. public function addSignKey($key, $passphrase = null)
  1166. {
  1167. $this->_addKey($this->signKeys, false, true, $key, $passphrase);
  1168. return $this;
  1169. }
  1170. // }}}
  1171. // {{{ addPassphrase()
  1172. /**
  1173. * Register a private key passphrase for import/export (GnuPG 2.1)
  1174. *
  1175. * @param mixed $key The key to use. This must be a key identifier,
  1176. * or fingerprint.
  1177. * @param string $passphrase The passphrase of the key.
  1178. *
  1179. * @return Crypt_GPG the current object, for fluent interface.
  1180. *
  1181. * @see Crypt_GPG::clearPassphrases()
  1182. * @see Crypt_GPG::importKey()
  1183. * @see Crypt_GPG::exportKey()
  1184. *
  1185. * @sensitive $passphrase
  1186. */
  1187. public function addPassphrase($key, $passphrase)
  1188. {
  1189. $this->passphrases[$key] = $passphrase;
  1190. return $this;
  1191. }
  1192. // }}}
  1193. // {{{ clearDecryptKeys()
  1194. /**
  1195. * Clears all decryption keys
  1196. *
  1197. * @return Crypt_GPG the current object, for fluent interface.
  1198. *
  1199. * @see Crypt_GPG::decrypt()
  1200. * @see Crypt_GPG::addDecryptKey()
  1201. */
  1202. public function clearDecryptKeys()
  1203. {
  1204. $this->decryptKeys = array();
  1205. return $this;
  1206. }
  1207. // }}}
  1208. // {{{ clearEncryptKeys()
  1209. /**
  1210. * Clears all encryption keys
  1211. *
  1212. * @return Crypt_GPG the current object, for fluent interface.
  1213. *
  1214. * @see Crypt_GPG::encrypt()
  1215. * @see Crypt_GPG::addEncryptKey()
  1216. */
  1217. public function clearEncryptKeys()
  1218. {
  1219. $this->encryptKeys = array();
  1220. return $this;
  1221. }
  1222. // }}}
  1223. // {{{ clearSignKeys()
  1224. /**
  1225. * Clears all signing keys
  1226. *
  1227. * @return Crypt_GPG the current object, for fluent interface.
  1228. *
  1229. * @see Crypt_GPG::sign()
  1230. * @see Crypt_GPG::addSignKey()
  1231. */
  1232. public function clearSignKeys()
  1233. {
  1234. $this->signKeys = array();
  1235. return $this;
  1236. }
  1237. // }}}
  1238. // {{{ clearPassphrases()
  1239. /**
  1240. * Clears all private key passphrases
  1241. *
  1242. * @return Crypt_GPG the current object, for fluent interface.
  1243. *
  1244. * @see Crypt_GPG::importKey()
  1245. * @see Crypt_GPG::exportKey()
  1246. * @see Crypt_GPG::addPassphrase()
  1247. */
  1248. public function clearPassphrases()
  1249. {
  1250. $this->passphrases = array();
  1251. return $this;
  1252. }
  1253. // }}}
  1254. // {{{ hasEncryptKeys()
  1255. /**
  1256. * Tell if there are encryption keys registered
  1257. *
  1258. * @return boolean True if the data shall be encrypted
  1259. */
  1260. public function hasEncryptKeys()
  1261. {
  1262. return count($this->encryptKeys) > 0;
  1263. }
  1264. // }}}
  1265. // {{{ hasSignKeys()
  1266. /**
  1267. * Tell if there are signing keys registered
  1268. *
  1269. * @return boolean True if the data shall be signed
  1270. */
  1271. public function hasSignKeys()
  1272. {
  1273. return count($this->signKeys) > 0;
  1274. }
  1275. // }}}
  1276. // {{{ _addKey()
  1277. /**
  1278. * Adds a key to one of the internal key arrays
  1279. *
  1280. * This handles resolving full key objects from the provided
  1281. * <kbd>$key</kbd> value.
  1282. *
  1283. * @param array &$array the array to which the key should be added.
  1284. * @param boolean $encrypt whether or not the key must be able to
  1285. * encrypt.
  1286. * @param boolean $sign whether or not the key must be able to sign.
  1287. * @param mixed $key the key to add. This may be a key identifier,
  1288. * user id, fingerprint, {@link Crypt_GPG_Key} or
  1289. * {@link Crypt_GPG_SubKey}.
  1290. * @param string $passphrase optional. The passphrase associated with the
  1291. * key.
  1292. *
  1293. * @return void
  1294. *
  1295. * @sensitive $passphrase
  1296. */
  1297. protected function _addKey(array &$array, $encrypt, $sign, $key,
  1298. $passphrase = null
  1299. ) {
  1300. $subKeys = array();
  1301. if (is_scalar($key)) {
  1302. $keys = $this->getKeys($key);
  1303. if (count($keys) == 0) {
  1304. throw new Crypt_GPG_KeyNotFoundException(
  1305. 'Key not found: ' . $key,
  1306. self::ERROR_KEY_NOT_FOUND,
  1307. $key
  1308. );
  1309. }
  1310. $key = $keys[0];
  1311. }
  1312. if ($key instanceof Crypt_GPG_Key) {
  1313. if ($encrypt && !$key->canEncrypt()) {
  1314. throw new InvalidArgumentException(
  1315. 'Key "' . $key . '" cannot encrypt.'
  1316. );
  1317. }
  1318. if ($sign && !$key->canSign()) {
  1319. throw new InvalidArgumentException(
  1320. 'Key "' . $key . '" cannot sign.'
  1321. );
  1322. }
  1323. foreach ($key->getSubKeys() as $subKey) {
  1324. $canEncrypt = $subKey->canEncrypt();
  1325. $canSign = $subKey->canSign();
  1326. if (($encrypt && $sign && $canEncrypt && $canSign)
  1327. || ($encrypt && !$sign && $canEncrypt)
  1328. || (!$encrypt && $sign && $canSign)
  1329. || (!$encrypt && !$sign)
  1330. ) {
  1331. // We add all subkeys that meet the requirements because we
  1332. // were not told which subkey is required.
  1333. $subKeys[] = $subKey;
  1334. }
  1335. }
  1336. } elseif ($key instanceof Crypt_GPG_SubKey) {
  1337. $subKeys[] = $key;
  1338. }
  1339. if (count($subKeys) === 0) {
  1340. throw new InvalidArgumentException(
  1341. 'Key "' . $key . '" is not in a recognized format.'
  1342. );
  1343. }
  1344. foreach ($subKeys as $subKey) {
  1345. if ($encrypt && !$subKey->canEncrypt()) {
  1346. throw new InvalidArgumentException(
  1347. 'Key "' . $key . '" cannot encrypt.'
  1348. );
  1349. }
  1350. if ($sign && !$subKey->canSign()) {
  1351. throw new InvalidArgumentException(
  1352. 'Key "' . $key . '" cannot sign.'
  1353. );
  1354. }
  1355. $array[$subKey->getId()] = array(
  1356. 'fingerprint' => $subKey->getFingerprint(),
  1357. 'passphrase' => $passphrase
  1358. );
  1359. }
  1360. }
  1361. // }}}
  1362. // {{{ _importKey()
  1363. /**
  1364. * Imports a public or private key into the keyring
  1365. *
  1366. * @param string $key the key to be imported.
  1367. * @param boolean $isFile whether or not the input is a filename.
  1368. *
  1369. * @return array an associative array containing the following elements:
  1370. * - <kbd>fingerprint</kbd> - the fingerprint of the
  1371. * imported key,
  1372. * - <kbd>public_imported</kbd> - the number of public
  1373. * keys imported,
  1374. * - <kbd>public_unchanged</kbd> - the number of unchanged
  1375. * public keys,
  1376. * - <kbd>private_imported</kbd> - the number of private
  1377. * keys imported,
  1378. * - <kbd>private_unchanged</kbd> - the number of unchanged
  1379. * private keys.
  1380. *
  1381. * @throws Crypt_GPG_NoDataException if the key data is missing or if the
  1382. * data is is not valid key data.
  1383. *
  1384. * @throws Crypt_GPG_FileException if the key file is not readable.
  1385. *
  1386. * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
  1387. * incorrect or if a required passphrase is not specified. See
  1388. * {@link Crypt_GPG::addPassphrase()}.
  1389. *
  1390. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  1391. * Use the <kbd>debug</kbd> option and file a bug report if these
  1392. * exceptions occur.
  1393. */
  1394. protected function _importKey($key, $isFile)
  1395. {
  1396. $result = array();
  1397. $arguments = array();
  1398. $input = $this->_prepareInput($key, $isFile, false);
  1399. $version = $this->engine->getVersion();
  1400. if (version_compare($version, '1.0.5', 'ge')
  1401. && version_compare($version, '1.0.7', 'lt')
  1402. ) {
  1403. $arguments[] = '--allow-secret-key-import';
  1404. }
  1405. if (empty($this->passphrases)) {
  1406. $arguments[] = '--batch';
  1407. }
  1408. $this->engine->reset();
  1409. $this->engine->setPins($this->passphrases);
  1410. $this->engine->setOperation('--import', $arguments);
  1411. $this->engine->setInput($input);
  1412. $this->engine->run();
  1413. return $this->engine->getProcessData('Import');
  1414. }
  1415. // }}}
  1416. // {{{ _exportKey()
  1417. /**
  1418. * Exports a private or public key from the keyring
  1419. *
  1420. * If more than one key fingerprint is available for the specified
  1421. * <kbd>$keyId</kbd> (for example, if you use a non-unique uid) only the
  1422. * first key is exported.
  1423. *
  1424. * @param string $keyId either the full uid of the key, the email
  1425. * part of the uid of the key or the key id.
  1426. * @param boolean $armor optional. If true, ASCII armored data is returned;
  1427. * otherwise, binary data is returned. Defaults to
  1428. * true.
  1429. * @param boolean $private return private instead of public key
  1430. *
  1431. * @return string the key data.
  1432. *
  1433. * @throws Crypt_GPG_KeyNotFoundException if a key with the given
  1434. * <kbd>$keyId</kbd> is not found.
  1435. *
  1436. * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
  1437. * incorrect or if a required passphrase is not specified. See
  1438. * {@link Crypt_GPG::addPassphrase()}.
  1439. *
  1440. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  1441. * Use the <kbd>debug</kbd> option and file a bug report if these
  1442. * exceptions occur.
  1443. */
  1444. protected function _exportKey($keyId, $armor = true, $private = false)
  1445. {
  1446. $fingerprint = $this->getFingerprint($keyId);
  1447. if ($fingerprint === null) {
  1448. throw new Crypt_GPG_KeyNotFoundException(
  1449. 'Key not found: ' . $keyId,
  1450. self::ERROR_KEY_NOT_FOUND,
  1451. $keyId
  1452. );
  1453. }
  1454. $keyData = '';
  1455. $operation = $private ? '--export-secret-keys' : '--export';
  1456. $operation .= ' ' . escapeshellarg($fingerprint);
  1457. $arguments = $armor ? array('--armor') : array();
  1458. $this->engine->reset();
  1459. $this->engine->setPins($this->passphrases);
  1460. $this->engine->setOutput($keyData);
  1461. $this->engine->setOperation($operation, $arguments);
  1462. $this->engine->run();
  1463. return $keyData;
  1464. }
  1465. // }}}
  1466. // {{{ _encrypt()
  1467. /**
  1468. * Encrypts data
  1469. *
  1470. * @param string $data the data to encrypt.
  1471. * @param boolean $isFile whether or not the data is a filename.
  1472. * @param string $outputFile the filename of the file in which to store
  1473. * the encrypted data. If null, the encrypted
  1474. * data is returned as a string.
  1475. * @param boolean $armor if true, ASCII armored data is returned;
  1476. * otherwise, binary data is returned.
  1477. *
  1478. * @return void|string if the <kbd>$outputFile</kbd> parameter is null, a
  1479. * string containing the encrypted data is returned.
  1480. *
  1481. * @throws Crypt_GPG_KeyNotFoundException if no encryption key is specified.
  1482. * See {@link Crypt_GPG::addEncryptKey()}.
  1483. *
  1484. * @throws Crypt_GPG_FileException if the output file is not writeable or
  1485. * if the input file is not readable.
  1486. *
  1487. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  1488. * Use the <kbd>debug</kbd> option and file a bug report if these
  1489. * exceptions occur.
  1490. */
  1491. protected function _encrypt($data, $isFile, $outputFile, $armor)
  1492. {
  1493. if (!$this->hasEncryptKeys()) {
  1494. throw new Crypt_GPG_KeyNotFoundException(
  1495. 'No encryption keys specified.'
  1496. );
  1497. }
  1498. $input = $this->_prepareInput($data, $isFile);
  1499. $output = $this->_prepareOutput($outputFile, $input);
  1500. $arguments = $armor ? array('--armor') : array();
  1501. foreach ($this->encryptKeys as $key) {
  1502. $arguments[] = '--recipient ' . escapeshellarg($key['fingerprint']);
  1503. }
  1504. $this->engine->reset();
  1505. $this->engine->setInput($input);
  1506. $this->engine->setOutput($output);
  1507. $this->engine->setOperation('--encrypt', $arguments);
  1508. $this->engine->run();
  1509. if ($outputFile === null) {
  1510. return $output;
  1511. }
  1512. }
  1513. // }}}
  1514. // {{{ _decrypt()
  1515. /**
  1516. * Decrypts data
  1517. *
  1518. * @param string $data the data to be decrypted.
  1519. * @param boolean $isFile whether or not the data is a filename.
  1520. * @param string $outputFile the name of the file to which the decrypted
  1521. * data should be written. If null, the decrypted
  1522. * data is returned as a string.
  1523. *
  1524. * @return void|string if the <kbd>$outputFile</kbd> parameter is null, a
  1525. * string containing the decrypted data is returned.
  1526. *
  1527. * @throws Crypt_GPG_KeyNotFoundException if the private key needed to
  1528. * decrypt the data is not in the user's keyring.
  1529. *
  1530. * @throws Crypt_GPG_NoDataException if specified data does not contain
  1531. * GPG encrypted data.
  1532. *
  1533. * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
  1534. * incorrect or if a required passphrase is not specified. See
  1535. * {@link Crypt_GPG::addDecryptKey()}.
  1536. *
  1537. * @throws Crypt_GPG_FileException if the output file is not writeable or
  1538. * if the input file is not readable.
  1539. *
  1540. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  1541. * Use the <kbd>debug</kbd> option and file a bug report if these
  1542. * exceptions occur.
  1543. */
  1544. protected function _decrypt($data, $isFile, $outputFile)
  1545. {
  1546. $input = $this->_prepareInput($data, $isFile, false);
  1547. $output = $this->_prepareOutput($outputFile, $input);
  1548. $this->engine->reset();
  1549. $this->engine->setPins($this->decryptKeys);
  1550. $this->engine->setOperation('--decrypt --skip-verify');
  1551. $this->engine->setInput($input);
  1552. $this->engine->setOutput($output);
  1553. $this->engine->run();
  1554. if ($outputFile === null) {
  1555. return $output;
  1556. }
  1557. }
  1558. // }}}
  1559. // {{{ _sign()
  1560. /**
  1561. * Signs data
  1562. *
  1563. * @param string $data the data to be signed.
  1564. * @param boolean $isFile whether or not the data is a filename.
  1565. * @param string $outputFile the name of the file in which the signed data
  1566. * should be stored. If null, the signed data is
  1567. * returned as a string.
  1568. * @param boolean $mode the data signing mode to use. Should be one of
  1569. * {@link Crypt_GPG::SIGN_MODE_NORMAL},
  1570. * {@link Crypt_GPG::SIGN_MODE_CLEAR} or
  1571. * {@link Crypt_GPG::SIGN_MODE_DETACHED}.
  1572. * @param boolean $armor if true, ASCII armored data is returned;
  1573. * otherwise, binary data is returned. This has
  1574. * no effect if the mode
  1575. * <kbd>Crypt_GPG::SIGN_MODE_CLEAR</kbd> is
  1576. * used.
  1577. * @param boolean $textmode if true, line-breaks in signed data be
  1578. * normalized. Use this option when signing
  1579. * e-mail, or for greater compatibility between
  1580. * systems with different line-break formats.
  1581. * Defaults to false. This has no effect if the
  1582. * mode <kbd>Crypt_GPG::SIGN_MODE_CLEAR</kbd> is
  1583. * used as clear-signing always uses textmode.
  1584. *
  1585. * @return void|string if the <kbd>$outputFile</kbd> parameter is null, a
  1586. * string containing the signed data (or the signature
  1587. * data if a detached signature is requested) is
  1588. * returned.
  1589. *
  1590. * @throws Crypt_GPG_KeyNotFoundException if no signing key is specified.
  1591. * See {@link Crypt_GPG::addSignKey()}.
  1592. *
  1593. * @throws Crypt_GPG_BadPassphraseException if a specified passphrase is
  1594. * incorrect or if a required passphrase is not specified.
  1595. *
  1596. * @throws Crypt_GPG_FileException if the output file is not writeable or
  1597. * if the input file is not readable.
  1598. *
  1599. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  1600. * Use the <kbd>debug</kbd> option and file a bug report if these
  1601. * exceptions occur.
  1602. */
  1603. protected function _sign($data, $isFile, $outputFile, $mode, $armor,
  1604. $textmode
  1605. ) {
  1606. if (!$this->hasSignKeys()) {
  1607. throw new Crypt_GPG_KeyNotFoundException(
  1608. 'No signing keys specified.'
  1609. );
  1610. }
  1611. $input = $this->_prepareInput($data, $isFile);
  1612. $output = $this->_prepareOutput($outputFile, $input);
  1613. switch ($mode) {
  1614. case self::SIGN_MODE_DETACHED:
  1615. $operation = '--detach-sign';
  1616. break;
  1617. case self::SIGN_MODE_CLEAR:
  1618. $operation = '--clearsign';
  1619. break;
  1620. case self::SIGN_MODE_NORMAL:
  1621. default:
  1622. $operation = '--sign';
  1623. break;
  1624. }
  1625. $arguments = array();
  1626. if ($armor) {
  1627. $arguments[] = '--armor';
  1628. }
  1629. if ($textmode) {
  1630. $arguments[] = '--textmode';
  1631. }
  1632. foreach ($this->signKeys as $key) {
  1633. $arguments[] = '--local-user ' .
  1634. escapeshellarg($key['fingerprint']);
  1635. }
  1636. $this->engine->reset();
  1637. $this->engine->setPins($this->signKeys);
  1638. $this->engine->setInput($input);
  1639. $this->engine->setOutput($output);
  1640. $this->engine->setOperation($operation, $arguments);
  1641. $this->engine->run();
  1642. if ($outputFile === null) {
  1643. return $output;
  1644. }
  1645. }
  1646. // }}}
  1647. // {{{ _encryptAndSign()
  1648. /**
  1649. * Encrypts and signs data
  1650. *
  1651. * @param string $data the data to be encrypted and signed.
  1652. * @param boolean $isFile whether or not the data is a filename.
  1653. * @param string $outputFile the name of the file in which the encrypted,
  1654. * signed data should be stored. If null, the
  1655. * encrypted, signed data is returned as a
  1656. * string.
  1657. * @param boolean $armor if true, ASCII armored data is returned;
  1658. * otherwise, binary data is returned.
  1659. *
  1660. * @return void|string if the <kbd>$outputFile</kbd> parameter is null, a
  1661. * string containing the encrypted, signed data is
  1662. * returned.
  1663. *
  1664. * @throws Crypt_GPG_KeyNotFoundException if no encryption key is specified
  1665. * or if no signing key is specified. See
  1666. * {@link Crypt_GPG::addEncryptKey()} and
  1667. * {@link Crypt_GPG::addSignKey()}.
  1668. *
  1669. * @throws Crypt_GPG_BadPassphraseException if a specified passphrase is
  1670. * incorrect or if a required passphrase is not specified.
  1671. *
  1672. * @throws Crypt_GPG_FileException if the output file is not writeable or
  1673. * if the input file is not readable.
  1674. *
  1675. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  1676. * Use the <kbd>debug</kbd> option and file a bug report if these
  1677. * exceptions occur.
  1678. */
  1679. protected function _encryptAndSign($data, $isFile, $outputFile, $armor)
  1680. {
  1681. if (!$this->hasSignKeys()) {
  1682. throw new Crypt_GPG_KeyNotFoundException(
  1683. 'No signing keys specified.'
  1684. );
  1685. }
  1686. if (!$this->hasEncryptKeys()) {
  1687. throw new Crypt_GPG_KeyNotFoundException(
  1688. 'No encryption keys specified.'
  1689. );
  1690. }
  1691. $input = $this->_prepareInput($data, $isFile);
  1692. $output = $this->_prepareOutput($outputFile, $input);
  1693. $arguments = $armor ? array('--armor') : array();
  1694. foreach ($this->signKeys as $key) {
  1695. $arguments[] = '--local-user ' .
  1696. escapeshellarg($key['fingerprint']);
  1697. }
  1698. foreach ($this->encryptKeys as $key) {
  1699. $arguments[] = '--recipient ' . escapeshellarg($key['fingerprint']);
  1700. }
  1701. $this->engine->reset();
  1702. $this->engine->setPins($this->signKeys);
  1703. $this->engine->setInput($input);
  1704. $this->engine->setOutput($output);
  1705. $this->engine->setOperation('--encrypt --sign', $arguments);
  1706. $this->engine->run();
  1707. if ($outputFile === null) {
  1708. return $output;
  1709. }
  1710. }
  1711. // }}}
  1712. // {{{ _verify()
  1713. /**
  1714. * Verifies data
  1715. *
  1716. * @param string $data the signed data to be verified.
  1717. * @param boolean $isFile whether or not the data is a filename.
  1718. * @param string $signature if verifying a file signed using a detached
  1719. * signature, this must be the detached signature
  1720. * data. Otherwise, specify ''.
  1721. *
  1722. * @return array an array of {@link Crypt_GPG_Signature} objects for the
  1723. * signed data.
  1724. *
  1725. * @throws Crypt_GPG_KeyNotFoundException if the public key needed for
  1726. * signature verification is not in the user's keyring.
  1727. *
  1728. * @throws Crypt_GPG_NoDataException if the provided data is not signed
  1729. * data.
  1730. *
  1731. * @throws Crypt_GPG_FileException if the input file is not readable.
  1732. *
  1733. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  1734. * Use the <kbd>debug</kbd> option and file a bug report if these
  1735. * exceptions occur.
  1736. *
  1737. * @see Crypt_GPG_Signature
  1738. */
  1739. protected function _verify($data, $isFile, $signature)
  1740. {
  1741. if ($signature == '') {
  1742. $operation = '--verify';
  1743. $arguments = array();
  1744. } else {
  1745. // Signed data goes in FD_MESSAGE, detached signature data goes in
  1746. // FD_INPUT.
  1747. $operation = '--verify - "-&' . Crypt_GPG_Engine::FD_MESSAGE. '"';
  1748. $arguments = array('--enable-special-filenames');
  1749. }
  1750. $input = $this->_prepareInput($data, $isFile, false);
  1751. $this->engine->reset();
  1752. if ($signature == '') {
  1753. // signed or clearsigned data
  1754. $this->engine->setInput($input);
  1755. } else {
  1756. // detached signature
  1757. $this->engine->setInput($signature);
  1758. $this->engine->setMessage($input);
  1759. }
  1760. $this->engine->setOperation($operation, $arguments);
  1761. $this->engine->run();
  1762. return $this->engine->getProcessData('Signatures');
  1763. }
  1764. // }}}
  1765. // {{{ _decryptAndVerify()
  1766. /**
  1767. * Decrypts and verifies encrypted, signed data
  1768. *
  1769. * @param string $data the encrypted signed data to be decrypted and
  1770. * verified.
  1771. * @param boolean $isFile whether or not the data is a filename.
  1772. * @param string $outputFile the name of the file to which the decrypted
  1773. * data should be written. If null, the decrypted
  1774. * data is returned in the results array.
  1775. * @param boolean $ignoreVerifyErrors enables ignoring of signature verification
  1776. * errors caused by missing public key.
  1777. * When enabled Crypt_GPG_KeyNotFoundException
  1778. * will not be thrown.
  1779. *
  1780. * @return array two element array. The array has an element 'data'
  1781. * containing the decrypted data and an element
  1782. * 'signatures' containing an array of
  1783. * {@link Crypt_GPG_Signature} objects for the signed data.
  1784. * If the decrypted data is written to a file, the 'data'
  1785. * element is null.
  1786. *
  1787. * @throws Crypt_GPG_KeyNotFoundException if the private key needed to
  1788. * decrypt the data is not in the user's keyring or if the public
  1789. * key needed for verification is not in the user's keyring.
  1790. *
  1791. * @throws Crypt_GPG_NoDataException if specified data does not contain
  1792. * GPG signed, encrypted data.
  1793. *
  1794. * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
  1795. * incorrect or if a required passphrase is not specified. See
  1796. * {@link Crypt_GPG::addDecryptKey()}.
  1797. *
  1798. * @throws Crypt_GPG_FileException if the output file is not writeable or
  1799. * if the input file is not readable.
  1800. *
  1801. * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  1802. * Use the <kbd>debug</kbd> option and file a bug report if these
  1803. * exceptions occur.
  1804. *
  1805. * @see Crypt_GPG_Signature
  1806. */
  1807. protected function _decryptAndVerify($data, $isFile, $outputFile, $ignoreVerifyErrors = false)
  1808. {
  1809. $input = $this->_prepareInput($data, $isFile, false);
  1810. $output = $this->_prepareOutput($outputFile, $input);
  1811. $this->engine->reset();
  1812. $this->engine->setPins($this->decryptKeys);
  1813. $this->engine->setInput($input);
  1814. $this->engine->setOutput($output);
  1815. $this->engine->setOperation('--decrypt');
  1816. $this->engine->setProcessData('IgnoreVerifyErrors', $ignoreVerifyErrors);
  1817. $this->engine->run();
  1818. $return = array(
  1819. 'data' => null,
  1820. 'signatures' => $this->engine->getProcessData('Signatures')
  1821. );
  1822. if ($outputFile === null) {
  1823. $return['data'] = $output;
  1824. }
  1825. return $return;
  1826. }
  1827. // }}}
  1828. // {{{ _prepareInput()
  1829. /**
  1830. * Prepares command input
  1831. *
  1832. * @param string $data the input data.
  1833. * @param boolean $isFile whether or not the input is a filename.
  1834. * @param boolean $allowEmpty whether to check if the input is not empty.
  1835. *
  1836. * @throws Crypt_GPG_NoDataException if the key data is missing.
  1837. * @throws Crypt_GPG_FileException if the file is not readable.
  1838. */
  1839. protected function _prepareInput($data, $isFile = false, $allowEmpty = true)
  1840. {
  1841. if ($isFile) {
  1842. $input = @fopen($data, 'rb');
  1843. if ($input === false) {
  1844. throw new Crypt_GPG_FileException(
  1845. 'Could not open input file "' . $data . '"',
  1846. 0,
  1847. $data
  1848. );
  1849. }
  1850. } else {
  1851. $input = strval($data);
  1852. if (!$allowEmpty && $input === '') {
  1853. throw new Crypt_GPG_NoDataException(
  1854. 'No valid input data found.',
  1855. self::ERROR_NO_DATA
  1856. );
  1857. }
  1858. }
  1859. return $input;
  1860. }
  1861. // }}}
  1862. // {{{ _prepareOutput()
  1863. /**
  1864. * Prepares command output
  1865. *
  1866. * @param string $outputFile the name of the file in which the output
  1867. * data should be stored. If null, the output
  1868. * data is returned as a string.
  1869. * @param boolean $input the input resource, in case it would need
  1870. * to be released (closed) on exception.
  1871. *
  1872. * @throws Crypt_GPG_FileException if the file is not writeable.
  1873. */
  1874. protected function _prepareOutput($outputFile, $input = null)
  1875. {
  1876. if ($outputFile === null) {
  1877. $output = '';
  1878. } else {
  1879. $output = @fopen($outputFile, 'wb');
  1880. if ($output === false) {
  1881. if (is_resource($input)) {
  1882. fclose($input);
  1883. }
  1884. throw new Crypt_GPG_FileException(
  1885. 'Could not open output file "' . $outputFile . '"',
  1886. 0,
  1887. $outputFile
  1888. );
  1889. }
  1890. }
  1891. return $output;
  1892. }
  1893. // }}}
  1894. }
  1895. // }}}
  1896. ?>