0sra%Ң6 [h@ V.ِ;ϫÜIšxFg=);x,7[Sjw岷Q'l=Ԑ$3[K$t|b]۴Ғ\x4IjKID"EYi8czu !IK xm,`z - .-Fp|tiHvbkN0<&?(HL !s9 ڥ#@ԁk~\zМwsftEP?ji*н HBqBH kˎeP8T^%>p9}7v<+\s̹1 1c_ɁGLt uRەMޒU4L+aD_@. ]Pzn͚d`r~D?0 y S_R`aL1J6)4iIJ$(Gt<{;6␽uFY*PUr_>Hw|KB _{qW,A_*KXÐV"`򴝫 #[w} Z/]xGMq©:~=H㧞1\ `Uu@فTn\zIr"x&dv\+AUvi) ګ5%2%JM{hC&}!&ִ )֖11ex/s%WcȇÝs!Ζe&lˈDތStG{O.cw33J>{QNz Vݘ)YA~a[hI W"Vф5GKăڮ ت;!b[wt=det˂Ckv$ā7PH6`v5*vlBtrR]ڡP,O~^<~ـV&-rBV&PjnE36I9/40kkurm< [?fY>=EN%yj`akL{@eE,HD^8+3}X8fN4}j<u3ū- =dbq ǬU.Ѭpm-b QF@mr*h2GsK Pv|yU.Ѭp6 /4ě?ӶٝB$fU~jέ۟?ė(߱Xd{qYe!\shhݾ;zWw|Y i߳~"m&θq@6!K^sNO[ 2\ |SG7 S.!1A~ g)9Yu\&/ ZmfrA 7G}~*<-d܈;kzB{;'Yݨv˺*>`gؐzqшYkԍS`$J7A-)fM]qJZNv6~z7FlV#M7Cfz+Q=&4GdN~*ܯ;AhCL>j̮_M%p4N+ vvtx%mU[HU}$6\zS@ߑڌ`E@+9O@#Фfڳ0xS0]ؠBf :OV9Z5 3-Na(HvNNvCzoGb8&#~73B !vSq ͭN¥{xֲ`$3|L+ "})KnwDJÖ9uZz/"]F~0n."3W.ڢdhW*i-c4S tW~Tx:Z@(U,r w/odݳ"s/bAK8`GA7qLL5DadU![6gr<֢EXe(߶d`$E9w%{C?.oK-q|Yb-s7GAq\0qd/Ϩ ڜA"P xgJ7ƂtxkrHR|odݳ"sYsr[+@'{+ -9DK0!dp@Ɯt!k<=b)"@:KR"- ej0ls.vQ3Y2 pʓOQ@$*vR y-&à.F;TunviC*=ֿju5FgXĒYCg9wqK@[=h}`X~h3vO6HȨ:f.y.aʢxlRړ(Q4QS6{-,X#֐gAj۩G\0a膄3{nN0] 2.!79Mts Ι*/*#$ϱde']bfS)2FnzFs "Eo6)pAf[&l=/,1yNa˹l4,*b@bDOZWѓajY64Jked{χ|4J?P$qUZ-p w'舛b#4"Ry5ZٺԝuXLp Iĝ ( MY9^T irk9k] 2%M&qP3f2Fzrl+_0qd/Ϩ 7]ZŦ*!g0b[Ђc^ӟnʉȸsa \<)l/Istring homedir - the directory where the GPG keyring files are * stored. If not specified, Crypt_GPG uses the default * of ~/.gnupg. * - string publicKeyring - the file path of the public keyring. * Use this if the public keyring is not in the homedir, * or if the keyring is in a directory not writable * by the process invoking GPG (like Apache). Then you * can specify the path to the keyring with this option * (/foo/bar/pubring.gpg), and specify a writable directory * (like /tmp) using the homedir option. * - string privateKeyring - the file path of the private keyring. * Use this if the private keyring is not in the homedir, * or if the keyring is in a directory not writable * by the process invoking GPG (like Apache). Then * you can specify the path to the keyring with this option * (/foo/bar/secring.gpg), and specify a writable directory * (like /tmp) using the homedir option. * - string trustDb - the file path of the web-of-trust database. * Use this if the trust database is not in the homedir, or * if the database is in a directory not writable * by the process invoking GPG (like Apache). Then you can * specify the path to the trust database with this option * (/foo/bar/trustdb.gpg), and specify a writable directory * (like /tmp) using the homedir option. * - string binary - the location of the GPG binary. * If not specified, the driver attempts to auto-detect * the GPG binary location using a list of known default * locations for the current operating system. The option * gpgBinary is a deprecated alias. * - string agent - the location of the GnuPG agent binary. * The gpg-agent is only used for GnuPG 2.x. If not * specified, the engine attempts to auto-detect * the gpg-agent binary location using a list of * know default locations for the current operating system. * - string|false gpgconf - the location of the GnuPG conf binary. * The gpgconf is only used for GnuPG >= 2.1. If not * specified, the engine attempts to auto-detect * the location using a list of know default locations. * When set to FALSE `gpgconf --kill` will not be executed * via destructor. * - string digest-algo - Sets the message digest algorithm. * - string cipher-algo - Sets the symmetric cipher. * - string compress-algo - Sets the compression algorithm. * - boolean strict - In strict mode clock problems on subkeys * and signatures are not ignored (--ignore-time-conflict * and --ignore-valid-from options). * - mixed debug - whether or not to use debug mode. * When debug mode is on, all communication to and from * the GPG subprocess is logged. This can be useful to * diagnose errors when using Crypt_GPG. * - array options - additional per-command options to the GPG * command. Key of the array is a command (e.g. * gen-key, import, sign, encrypt, list-keys). * Value is a string containing command line arguments to be * added to the related command. For example: * array('sign' => '--emit-version'). * * @param array $options optional. An array of options used to create the * GPG object. All options are optional and are * represented as key-value pairs. * * @throws Crypt_GPG_FileException if the homedir does not exist * and cannot be created. This can happen if homedir is * not specified, Crypt_GPG is run as the web user, and the web * user has no home directory. This exception is also thrown if any * of the options publicKeyring, * privateKeyring or trustDb options are * specified but the files do not exist or are are not readable. * This can happen if the user running the Crypt_GPG process (for * example, the Apache user) does not have permission to read the * files. * * @throws PEAR_Exception if the provided binary is invalid, or * if no binary is provided and no suitable binary could * be found. * * @throws PEAR_Exception if the provided agent is invalid, or * if no agent is provided and no suitable gpg-agent * could be found. */ public function __construct(array $options = array()) { $this->setEngine(new Crypt_GPG_Engine($options)); } /** * Sets the I/O engine to use for GnuPG operations * * Normally this method does not need to be used. It provides a means for * dependency injection. * * @param Crypt_GPG_Engine $engine the engine to use. * * @return Crypt_GPGAbstract the current object, for fluent interface. */ public function setEngine(Crypt_GPG_Engine $engine) { $this->engine = $engine; return $this; } /** * Sets per-command additional arguments * * @param array $options Additional per-command options for GPG command. * Note: This will unset options set previously. * Key of the array is a command (e.g. * gen-key, import, sign, encrypt, list-keys). * Value is a string containing command line arguments to be * added to the related command. For example: * array('sign' => '--emit-version'). * * @return Crypt_GPGAbstract the current object, for fluent interface. */ public function setEngineOptions(array $options) { $this->engine->setOptions($options); return $this; } /** * Returns version of the engine (GnuPG) used for operation. * * @return string GnuPG version. * * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs. * Use the debug option and file a bug report if these * exceptions occur. */ public function getVersion() { return $this->engine->getVersion(); } /** * Gets the available keys in the keyring * * Calls GPG with the --list-keys command and grabs keys. See * the first section of doc/DETAILS in the * {@link http://www.gnupg.org/download/ GPG package} for a detailed * description of how the GPG command output is parsed. * * @param string $keyId optional. Only keys with that match the specified * pattern are returned. The pattern may be part of * a user id, a key id or a key fingerprint. If not * specified, all keys are returned. * * @return array an array of {@link Crypt_GPG_Key} objects. If no keys * match the specified $keyId an empty array is * returned. * * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs. * Use the debug option and file a bug report if these * exceptions occur. * * @see Crypt_GPG_Key */ protected function _getKeys($keyId = '') { // get private key fingerprints if ($keyId == '') { $operation = '--list-secret-keys'; } else { $operation = '--utf8-strings --list-secret-keys -- ' . escapeshellarg($keyId); } // According to The file 'doc/DETAILS' in the GnuPG distribution, using // double '--with-fingerprint' also prints the fingerprint for subkeys. $arguments = array( '--with-colons', '--with-fingerprint', '--with-fingerprint', '--fixed-list-mode' ); $output = ''; $this->engine->reset(); $this->engine->setOutput($output); $this->engine->setOperation($operation, $arguments); $this->engine->run(); $privateKeyFingerprints = array(); foreach (explode(PHP_EOL, $output) as $line) { $lineExp = explode(':', $line); if ($lineExp[0] == 'fpr') { $privateKeyFingerprints[] = $lineExp[9]; } } // get public keys if ($keyId == '') { $operation = '--list-public-keys'; } else { $operation = '--utf8-strings --list-public-keys -- ' . escapeshellarg($keyId); } $output = ''; $this->engine->reset(); $this->engine->setOutput($output); $this->engine->setOperation($operation, $arguments); $this->engine->run(); $keys = array(); $key = null; // current key $subKey = null; // current sub-key foreach (explode(PHP_EOL, $output) as $line) { $lineExp = explode(':', $line); if ($lineExp[0] == 'pub') { // new primary key means last key should be added to the array if ($key !== null) { $keys[] = $key; } $key = new Crypt_GPG_Key(); $subKey = Crypt_GPG_SubKey::parse($line); $key->addSubKey($subKey); } elseif ($lineExp[0] == 'sub') { $subKey = Crypt_GPG_SubKey::parse($line); $key->addSubKey($subKey); } elseif ($lineExp[0] == 'fpr') { $fingerprint = $lineExp[9]; // set current sub-key fingerprint $subKey->setFingerprint($fingerprint); // if private key exists, set has private to true if (in_array($fingerprint, $privateKeyFingerprints)) { $subKey->setHasPrivate(true); } } elseif ($lineExp[0] == 'uid') { $string = stripcslashes($lineExp[9]); // as per documentation $userId = new Crypt_GPG_UserId($string); if ($lineExp[1] == 'r') { $userId->setRevoked(true); } $key->addUserId($userId); } } // add last key if ($key !== null) { $keys[] = $key; } return $keys; } }