Crypt_GPG
[ class tree: Crypt_GPG ] [ index: Crypt_GPG ] [ all elements ]

Source for file KeyGenerator.php

Documentation is available at KeyGenerator.php

  1. <?php
  2.  
  3. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  4.  
  5. /**
  6.  * Crypt_GPG is a package to use GPG from PHP
  7.  *
  8.  * This file contains an object that handles GnuPG key generation.
  9.  *
  10.  * PHP version 5
  11.  *
  12.  * LICENSE:
  13.  *
  14.  * This library is free software; you can redistribute it and/or modify
  15.  * it under the terms of the GNU Lesser General Public License as
  16.  * published by the Free Software Foundation; either version 2.1 of the
  17.  * License, or (at your option) any later version.
  18.  *
  19.  * This library is distributed in the hope that it will be useful,
  20.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  22.  * Lesser General Public License for more details.
  23.  *
  24.  * You should have received a copy of the GNU Lesser General Public
  25.  * License along with this library; if not, write to the Free Software
  26.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  27.  *
  28.  * @category  Encryption
  29.  * @package   Crypt_GPG
  30.  * @author    Michael Gauthier <mike@silverorange.com>
  31.  * @copyright 2011-2013 silverorange
  32.  * @license   http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
  33.  * @version   CVS: $Id:$
  34.  * @link      http://pear.php.net/package/Crypt_GPG
  35.  * @link      http://www.gnupg.org/
  36.  */
  37.  
  38. /**
  39.  * Base class for GPG methods
  40.  */
  41. require_once 'Crypt/GPGAbstract.php';
  42.  
  43. /**
  44.  * Status output handler for key generation
  45.  */
  46. require_once 'Crypt/GPG/KeyGeneratorStatusHandler.php';
  47.  
  48. /**
  49.  * Error output handler for key generation
  50.  */
  51. require_once 'Crypt/GPG/KeyGeneratorErrorHandler.php';
  52.  
  53. // {{{ class Crypt_GPG_KeyGenerator
  54.  
  55. /**
  56.  * GnuPG key generator
  57.  *
  58.  * This class provides an object oriented interface for generating keys with
  59.  * the GNU Privacy Guard (GPG).
  60.  *
  61.  * Secure key generation requires true random numbers, and as such can be slow.
  62.  * If the operating system runs out of entropy, key generation will block until
  63.  * more entropy is available.
  64.  *
  65.  * If quick key generation is important, a hardware entropy generator, or an
  66.  * entropy gathering daemon may be installed. For example, administrators of
  67.  * Debian systems may want to install the 'randomsound' package.
  68.  *
  69.  * This class uses the experimental automated key generation support available
  70.  * in GnuPG. See <b>doc/DETAILS</b> in the
  71.  * {@link http://www.gnupg.org/download/ GPG distribution} for detailed
  72.  * information on the key generation format.
  73.  *
  74.  * @category  Encryption
  75.  * @package   Crypt_GPG
  76.  * @author    Nathan Fredrickson <nathan@silverorange.com>
  77.  * @author    Michael Gauthier <mike@silverorange.com>
  78.  * @copyright 2005-2013 silverorange
  79.  * @license   http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
  80.  * @link      http://pear.php.net/package/Crypt_GPG
  81.  * @link      http://www.gnupg.org/
  82.  */
  83. {
  84.     // {{{ protected properties
  85.  
  86.     /**
  87.      * The expiration date of generated keys
  88.      *
  89.      * @var integer 
  90.      *
  91.      * @see Crypt_GPG_KeyGenerator::setExpirationDate()
  92.      */
  93.     protected $expirationDate = 0;
  94.  
  95.     /**
  96.      * The passphrase of generated keys
  97.      *
  98.      * @var string 
  99.      *
  100.      * @see Crypt_GPG_KeyGenerator::setPassphrase()
  101.      */
  102.     protected $passphrase = '';
  103.  
  104.     /**
  105.      * The algorithm for generated primary keys
  106.      *
  107.      * @var integer 
  108.      *
  109.      * @see Crypt_GPG_KeyGenerator::setKeyParams()
  110.      */
  111.     protected $keyAlgorithm = Crypt_GPG_SubKey::ALGORITHM_DSA;
  112.  
  113.     /**
  114.      * The size of generated primary keys
  115.      *
  116.      * @var integer 
  117.      *
  118.      * @see Crypt_GPG_KeyGenerator::setKeyParams()
  119.      */
  120.     protected $keySize = 1024;
  121.  
  122.     /**
  123.      * The usages of generated primary keys
  124.      *
  125.      * This is a bitwise combination of the usage constants in
  126.      * {@link Crypt_GPG_SubKey}.
  127.      *
  128.      * @var integer 
  129.      *
  130.      * @see Crypt_GPG_KeyGenerator::setKeyParams()
  131.      */
  132.     protected $keyUsage = 6; // USAGE_SIGN | USAGE_CERTIFY
  133.  
  134.     /**
  135.      * The algorithm for generated sub-keys
  136.      *
  137.      * @var integer 
  138.      *
  139.      * @see Crypt_GPG_KeyGenerator::setSubKeyParams()
  140.      */
  141.     protected $subKeyAlgorithm = Crypt_GPG_SubKey::ALGORITHM_ELGAMAL_ENC;
  142.  
  143.     /**
  144.      * The size of generated sub-keys
  145.      *
  146.      * @var integer 
  147.      *
  148.      * @see Crypt_GPG_KeyGenerator::setSubKeyParams()
  149.      */
  150.     protected $subKeySize = 2048;
  151.  
  152.     /**
  153.      * The usages of generated sub-keys
  154.      *
  155.      * This is a bitwise combination of the usage constants in
  156.      * {@link Crypt_GPG_SubKey}.
  157.      *
  158.      * @var integer 
  159.      *
  160.      * @see Crypt_GPG_KeyGenerator::setSubKeyParams()
  161.      */
  162.     protected $subKeyUsage = Crypt_GPG_SubKey::USAGE_ENCRYPT;
  163.  
  164.     /**
  165.      * The GnuPG status handler to use for key generation
  166.      *
  167.      * @var Crypt_GPG_KeyGeneratorStatusHandler 
  168.      *
  169.      * @see Crypt_GPG_KeyGenerator::setStatusHandler()
  170.      */
  171.     protected $statusHandler = null;
  172.  
  173.     /**
  174.      * The GnuPG error handler to use for key generation
  175.      *
  176.      * @var Crypt_GPG_KeyGeneratorErrorHandler 
  177.      *
  178.      * @see Crypt_GPG_KeyGenerator::setErrorHandler()
  179.      */
  180.     protected $errorHandler = null;
  181.  
  182.     // }}}
  183.     // {{{ __construct()
  184.  
  185.     /**
  186.      * Creates a new GnuPG key generator
  187.      *
  188.      * Available options are:
  189.      *
  190.      * - <kbd>string  homedir</kbd>        - the directory where the GPG
  191.      *                                       keyring files are stored. If not
  192.      *                                       specified, Crypt_GPG uses the
  193.      *                                       default of <kbd>~/.gnupg</kbd>.
  194.      * - <kbd>string  publicKeyring</kbd>  - the file path of the public
  195.      *                                       keyring. Use this if the public
  196.      *                                       keyring is not in the homedir, or
  197.      *                                       if the keyring is in a directory
  198.      *                                       not writable by the process
  199.      *                                       invoking GPG (like Apache). Then
  200.      *                                       you can specify the path to the
  201.      *                                       keyring with this option
  202.      *                                       (/foo/bar/pubring.gpg), and specify
  203.      *                                       a writable directory (like /tmp)
  204.      *                                       using the <i>homedir</i> option.
  205.      * - <kbd>string  privateKeyring</kbd> - the file path of the private
  206.      *                                       keyring. Use this if the private
  207.      *                                       keyring is not in the homedir, or
  208.      *                                       if the keyring is in a directory
  209.      *                                       not writable by the process
  210.      *                                       invoking GPG (like Apache). Then
  211.      *                                       you can specify the path to the
  212.      *                                       keyring with this option
  213.      *                                       (/foo/bar/secring.gpg), and specify
  214.      *                                       a writable directory (like /tmp)
  215.      *                                       using the <i>homedir</i> option.
  216.      * - <kbd>string  trustDb</kbd>        - the file path of the web-of-trust
  217.      *                                       database. Use this if the trust
  218.      *                                       database is not in the homedir, or
  219.      *                                       if the database is in a directory
  220.      *                                       not writable by the process
  221.      *                                       invoking GPG (like Apache). Then
  222.      *                                       you can specify the path to the
  223.      *                                       trust database with this option
  224.      *                                       (/foo/bar/trustdb.gpg), and specify
  225.      *                                       a writable directory (like /tmp)
  226.      *                                       using the <i>homedir</i> option.
  227.      * - <kbd>string  binary</kbd>         - the location of the GPG binary. If
  228.      *                                       not specified, the driver attempts
  229.      *                                       to auto-detect the GPG binary
  230.      *                                       location using a list of known
  231.      *                                       default locations for the current
  232.      *                                       operating system. The option
  233.      *                                       <kbd>gpgBinary</kbd> is a
  234.      *                                       deprecated alias for this option.
  235.      * - <kbd>string  agent</kbd>          - the location of the GnuPG agent
  236.      *                                       binary. The gpg-agent is only
  237.      *                                       used for GnuPG 2.x. If not
  238.      *                                       specified, the engine attempts
  239.      *                                       to auto-detect the gpg-agent
  240.      *                                       binary location using a list of
  241.      *                                       know default locations for the
  242.      *                                       current operating system.
  243.      * - <kbd>boolean debug</kbd>          - whether or not to use debug mode.
  244.      *                                       When debug mode is on, all
  245.      *                                       communication to and from the GPG
  246.      *                                       subprocess is logged. This can be
  247.      *
  248.      * @param array $options optional. An array of options used to create the
  249.      *                        GPG object. All options are optional and are
  250.      *                        represented as key-value pairs.
  251.      *
  252.      * @throws Crypt_GPG_FileException if the <kbd>homedir</kbd> does not exist
  253.      *          and cannot be created. This can happen if <kbd>homedir</kbd> is
  254.      *          not specified, Crypt_GPG is run as the web user, and the web
  255.      *          user has no home directory. This exception is also thrown if any
  256.      *          of the options <kbd>publicKeyring</kbd>,
  257.      *          <kbd>privateKeyring</kbd> or <kbd>trustDb</kbd> options are
  258.      *          specified but the files do not exist or are are not readable.
  259.      *          This can happen if the user running the Crypt_GPG process (for
  260.      *          example, the Apache user) does not have permission to read the
  261.      *          files.
  262.      *
  263.      * @throws PEAR_Exception if the provided <kbd>binary</kbd> is invalid, or
  264.      *          if no <kbd>binary</kbd> is provided and no suitable binary could
  265.      *          be found.
  266.      *
  267.      * @throws PEAR_Exception if the provided <kbd>agent</kbd> is invalid, or
  268.      *          if no <kbd>agent</kbd> is provided and no suitable gpg-agent
  269.      *          cound be found.
  270.      */
  271.     public function __construct(array $options = array())
  272.     {
  273.         parent::__construct($options);
  274.  
  275.         $this->statusHandler = new Crypt_GPG_KeyGeneratorStatusHandler();
  276.         $this->errorHandler  = new Crypt_GPG_KeyGeneratorErrorHandler();
  277.     }
  278.  
  279.     // }}}
  280.     // {{{ setExpirationDate()
  281.  
  282.     /**
  283.      * Sets the expiration date of generated keys
  284.      *
  285.      * @param string|integer$date either a string that may be parsed by
  286.      *                              PHP's strtotime() function, or an integer
  287.      *                              timestamp representing the number of seconds
  288.      *                              since the UNIX epoch. This date must be at
  289.      *                              least one date in the future. Keys that
  290.      *                              expire in the past may not be generated. Use
  291.      *                              an expiration date of 0 for keys that do not
  292.      *                              expire.
  293.      *
  294.      * @throws InvalidArgumentException if the date is not a valid format, or
  295.      *                                   if the date is not at least one day in
  296.      *                                   the future, or if the date is greater
  297.      *                                   than 2038-01-19T03:14:07.
  298.      *
  299.      * @return Crypt_GPG_KeyGenerator the current object, for fluent interface.
  300.      */
  301.     public function setExpirationDate($date)
  302.     {
  303.         if (is_int($date|| ctype_digit(strval($date))) {
  304.             $expirationDate intval($date);
  305.         else {
  306.             $expirationDate strtotime($date);
  307.         }
  308.  
  309.         if ($expirationDate === false{
  310.             throw new InvalidArgumentException(
  311.                 sprintf(
  312.                     'Invalid expiration date format: "%s". Please use a ' .
  313.                     'format compatible with PHP\'s strtotime().',
  314.                     $date
  315.                 )
  316.             );
  317.         }
  318.  
  319.         if ($expirationDate !== 0 && $expirationDate time(+ 86400{
  320.             throw new InvalidArgumentException(
  321.                 'Expiration date must be at least a day in the future.'
  322.             );
  323.         }
  324.  
  325.         // GnuPG suffers from the 2038 bug
  326.         if ($expirationDate > 2147483647{
  327.             throw new InvalidArgumentException(
  328.                 'Expiration date must not be greater than 2038-01-19T03:14:07.'
  329.             );
  330.         }
  331.  
  332.         $this->expirationDate = $expirationDate;
  333.  
  334.         return $this;
  335.     }
  336.  
  337.     // }}}
  338.     // {{{ setPassphrase()
  339.  
  340.     /**
  341.      * Sets the passphrase of generated keys
  342.      *
  343.      * @param string $passphrase the passphrase to use for generated keys. Use
  344.      *                            null or an empty string for no passphrase.
  345.      *
  346.      * @return Crypt_GPG_KeyGenerator the current object, for fluent interface.
  347.      */
  348.     public function setPassphrase($passphrase)
  349.     {
  350.         $this->passphrase = strval($passphrase);
  351.         return $this;
  352.     }
  353.  
  354.     // }}}
  355.     // {{{ setKeyParams()
  356.  
  357.     /**
  358.      * Sets the parameters for the primary key of generated key-pairs
  359.      *
  360.      * @param integer $algorithm the algorithm used by the key. This should be
  361.      *                            one of the Crypt_GPG_SubKey::ALGORITHM_*
  362.      *                            constants.
  363.      * @param integer $size      optional. The size of the key. Different
  364.      *                            algorithms have different size requirements.
  365.      *                            If not specified, the default size for the
  366.      *                            specified algorithm will be used. If an
  367.      *                            invalid key size is used, GnuPG will do its
  368.      *                            best to round it to a valid size.
  369.      * @param integer $usage     optional. A bitwise combination of key usages.
  370.      *                            If not specified, the primary key will be used
  371.      *                            only to sign and certify. This is the default
  372.      *                            behavior of GnuPG in interactive mode. Use
  373.      *                            the Crypt_GPG_SubKey::USAGE_* constants here.
  374.      *                            The primary key may be used to certify even
  375.      *                            if the certify usage is not specified.
  376.      *
  377.      * @return Crypt_GPG_KeyGenerator the current object, for fluent interface.
  378.      */
  379.     public function setKeyParams($algorithm$size = 0$usage = 0)
  380.     {
  381.         $apgorithm intval($algorithm);
  382.  
  383.         if ($algorithm === Crypt_GPG_SubKey::ALGORITHM_ELGAMAL_ENC{
  384.             throw new Crypt_GPG_InvalidKeyParamsException(
  385.                 'Primary key algorithm must be capable of signing. The ' .
  386.                 'Elgamal algorithm can only encrypt.',
  387.                 0,
  388.                 $algorithm,
  389.                 $size,
  390.                 $usage
  391.             );
  392.         }
  393.  
  394.         if ($size != 0{
  395.             $size intval($size);
  396.         }
  397.  
  398.         if ($usage != 0{
  399.             $usage intval($usage);
  400.         }
  401.  
  402.         $usageEncrypt Crypt_GPG_SubKey::USAGE_ENCRYPT;
  403.  
  404.         if (   $algorithm === Crypt_GPG_SubKey::ALGORITHM_DSA
  405.             && ($usage $usageEncrypt=== $usageEncrypt
  406.         {
  407.             throw new Crypt_GPG_InvalidKeyParamsException(
  408.                 'The DSA algorithm is not capable of encrypting. Please ' .
  409.                 'specify a different algorithm or do not include encryption ' .
  410.                 'as a usage for the primary key.',
  411.                 0,
  412.                 $algorithm,
  413.                 $size,
  414.                 $usage
  415.             );
  416.         }
  417.  
  418.         $this->keyAlgorithm = $algorithm;
  419.  
  420.         if ($size != 0{
  421.             $this->keySize = $size;
  422.         }
  423.  
  424.         if ($usage != 0{
  425.             $this->keyUsage = $usage;
  426.         }
  427.  
  428.         return $this;
  429.     }
  430.  
  431.     // }}}
  432.     // {{{ setSubKeyParams()
  433.  
  434.     /**
  435.      * Sets the parameters for the sub-key of generated key-pairs
  436.      *
  437.      * @param integer $algorithm the algorithm used by the key. This should be
  438.      *                            one of the Crypt_GPG_SubKey::ALGORITHM_*
  439.      *                            constants.
  440.      * @param integer $size      optional. The size of the key. Different
  441.      *                            algorithms have different size requirements.
  442.      *                            If not specified, the default size for the
  443.      *                            specified algorithm will be used. If an
  444.      *                            invalid key size is used, GnuPG will do its
  445.      *                            best to round it to a valid size.
  446.      * @param integer $usage     optional. A bitwise combination of key usages.
  447.      *                            If not specified, the sub-key will be used
  448.      *                            only to encrypt. This is the default behavior
  449.      *                            of GnuPG in interactive mode. Use the
  450.      *                            Crypt_GPG_SubKey::USAGE_* constants here.
  451.      *
  452.      * @return Crypt_GPG_KeyGenerator the current object, for fluent interface.
  453.      */
  454.     public function setSubKeyParams($algorithm$size ''$usage = 0)
  455.     {
  456.         $apgorithm intval($algorithm);
  457.  
  458.         if ($size != 0{
  459.             $size intval($size);
  460.         }
  461.  
  462.         if ($usage != 0{
  463.             $usage intval($usage);
  464.         }
  465.  
  466.         $usageSign Crypt_GPG_SubKey::USAGE_SIGN;
  467.  
  468.         if (   $algorithm === Crypt_GPG_SubKey::ALGORITHM_ELGAMAL_ENC
  469.             && ($usage $usageSign=== $usageSign
  470.         {
  471.             throw new Crypt_GPG_InvalidKeyParamsException(
  472.                 'The Elgamal algorithm is not capable of signing. Please ' .
  473.                 'specify a different algorithm or do not include signing ' .
  474.                 'as a usage for the sub-key.',
  475.                 0,
  476.                 $algorithm,
  477.                 $size,
  478.                 $usage
  479.             );
  480.         }
  481.  
  482.         $usageEncrypt Crypt_GPG_SubKey::USAGE_ENCRYPT;
  483.  
  484.         if (   $algorithm === Crypt_GPG_SubKey::ALGORITHM_DSA
  485.             && ($usage $usageEncrypt=== $usageEncrypt
  486.         {
  487.             throw new Crypt_GPG_InvalidKeyParamsException(
  488.                 'The DSA algorithm is not capable of encrypting. Please ' .
  489.                 'specify a different algorithm or do not include encryption ' .
  490.                 'as a usage for the sub-key.',
  491.                 0,
  492.                 $algorithm,
  493.                 $size,
  494.                 $usage
  495.             );
  496.         }
  497.  
  498.         $this->subKeyAlgorithm = $algorithm;
  499.  
  500.         if ($size != 0{
  501.             $this->subKeySize = $size;
  502.         }
  503.  
  504.         if ($usage != 0{
  505.             $this->subKeyUsage = $usage;
  506.         }
  507.  
  508.         return $this;
  509.     }
  510.  
  511.     // }}}
  512.     // {{{ setStatusHandler()
  513.  
  514.     /**
  515.      * Sets the status handler to use for key generation
  516.      *
  517.      * Normally this method does not need to be used. It provides a means for
  518.      * dependency injection.
  519.      *
  520.      * @param Crypt_GPG_KeyStatusHandler $handler the key status handler to
  521.      *                                             use.
  522.      *
  523.      * @return Crypt_GPG_KeyGenerator the current object, for fluent interface.
  524.      */
  525.     public function setStatusHandler(
  526.         Crypt_GPG_KeyGeneratorStatusHandler $handler
  527.     {
  528.         $this->statusHandler = $handler;
  529.         return $this;
  530.     }
  531.  
  532.     // }}}
  533.     // {{{ setErrorHandler()
  534.  
  535.     /**
  536.      * Sets the error handler to use for key generation
  537.      *
  538.      * Normally this method does not need to be used. It provides a means for
  539.      * dependency injection.
  540.      *
  541.      * @param Crypt_GPG_KeyErrorHandler $handler the key error handler to
  542.      *                                            use.
  543.      *
  544.      * @return Crypt_GPG_KeyGenerator the current object, for fluent interface.
  545.      */
  546.     public function setErrorHandler(
  547.         Crypt_GPG_KeyGeneratorErrorHandler $handler
  548.     {
  549.         $this->errorHandler = $handler;
  550.         return $this;
  551.     }
  552.  
  553.     // }}}
  554.     // {{{ generateKey()
  555.  
  556.     /**
  557.      * Generates a new key-pair in the current keyring
  558.      *
  559.      * Secure key generation requires true random numbers, and as such can be
  560.      * solw. If the operating system runs out of entropy, key generation will
  561.      * block until more entropy is available.
  562.      *
  563.      * If quick key generation is important, a hardware entropy generator, or
  564.      * an entropy gathering daemon may be installed. For example,
  565.      * administrators of Debian systems may want to install the 'randomsound'
  566.      * package.
  567.      *
  568.      * @param string|Crypt_GPG_UserId$name    either a {@link Crypt_GPG_UserId}
  569.      *                                          object, or a string containing
  570.      *                                          the name of the user id.
  571.      * @param string                  $email   optional. If <i>$name</i> is
  572.      *                                          specified as a string, this is
  573.      *                                          the email address of the user id.
  574.      * @param string                  $comment optional. If <i>$name</i> is
  575.      *                                          specified as a string, this is
  576.      *                                          the comment of the user id.
  577.      *
  578.      * @return Crypt_GPG_Key the newly generated key.
  579.      *
  580.      * @throws Crypt_GPG_KeyNotCreatedException if the key parameters are
  581.      *          incorrect, if an unknown error occurs during key generation, or
  582.      *          if the newly generated key is not found in the keyring.
  583.      *
  584.      * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
  585.      *          Use the <kbd>debug</kbd> option and file a bug report if these
  586.      *          exceptions occur.
  587.      */
  588.     public function generateKey($name$email ''$comment '')
  589.     {
  590.         $handle uniqid('key'true);
  591.  
  592.         $userId $this->getUserId($name$email$comment);
  593.  
  594.         $keyParams = array(
  595.             'Key-Type'      => $this->keyAlgorithm,
  596.             'Key-Length'    => $this->keySize,
  597.             'Key-Usage'     => $this->getUsage($this->keyUsage),
  598.             'Subkey-Type'   => $this->subKeyAlgorithm,
  599.             'Subkey-Length' => $this->subKeySize,
  600.             'Subkey-Usage'  => $this->getUsage($this->subKeyUsage),
  601.             'Name-Real'     => $userId->getName(),
  602.             'Handle'        => $handle,
  603.         );
  604.  
  605.         if ($this->expirationDate != 0{
  606.             // GnuPG only accepts granularity of days
  607.             $expirationDate date('Y-m-d'$this->expirationDate);
  608.             $keyParams['Expire-Date'$expirationDate;
  609.         }
  610.  
  611.         if ($this->passphrase != ''{
  612.             $keyParams['Passphrase'$this->passphrase;
  613.         }
  614.  
  615.         if ($userId->getEmail(!= ''{
  616.             $keyParams['Name-Email'$userId->getEmail();
  617.         }
  618.  
  619.         if ($userId->getComment(!= ''{
  620.             $keyParams['Name-Comment'$userId->getComment();
  621.         }
  622.  
  623.  
  624.         $keyParamsFormatted = array();
  625.         foreach ($keyParams as $name => $value{
  626.             $keyParamsFormatted[$name ': ' $value;
  627.         }
  628.  
  629.         $input implode("\n"$keyParamsFormatted"\n%commit\n";
  630.  
  631.         $statusHandler = clone $this->statusHandler;
  632.         $statusHandler->setHandle($handle);
  633.  
  634.         $errorHandler = clone $this->errorHandler;
  635.  
  636.         $this->engine->reset();
  637.         $this->engine->addStatusHandler(array($statusHandler'handle'));
  638.         $this->engine->addErrorHandler(array($errorHandler'handle'));
  639.         $this->engine->setInput($input);
  640.         $this->engine->setOutput($output);
  641.         $this->engine->setOperation('--gen-key'array('--batch'));
  642.         $this->engine->run();
  643.  
  644.         $code $errorHandler->getErrorCode();
  645.         switch ($code{
  646.         case self::ERROR_BAD_KEY_PARAMS:
  647.             switch ($errorHandler->getLineNumber()) {
  648.             case 1:
  649.                 throw new Crypt_GPG_InvalidKeyParamsException(
  650.                     'Invalid primary key algorithm specified.',
  651.                     0,
  652.                     $this->keyAlgorithm,
  653.                     $this->keySize,
  654.                     $this->keyUsage
  655.                 );
  656.             case 4:
  657.                 throw new Crypt_GPG_InvalidKeyParamsException(
  658.                     'Invalid sub-key algorithm specified.',
  659.                     0,
  660.                     $this->subKeyAlgorithm,
  661.                     $this->subKeySize,
  662.                     $this->subKeyUsage
  663.                 );
  664.             default:
  665.                 throw new Crypt_GPG_InvalidKeyParamsException(
  666.                     'Invalid key algorithm specified.'
  667.                 );
  668.             }
  669.         }
  670.  
  671.         $code $this->engine->getErrorCode();
  672.  
  673.         switch ($code{
  674.         case self::ERROR_NONE:
  675.             break;
  676.         default:
  677.             throw new Crypt_GPG_Exception(
  678.                 'Unknown error generating key-pair. Please use the \'debug\' ' .
  679.                 'option when creating the Crypt_GPG object, and file a bug ' .
  680.                 'report at ' . self::BUG_URI,
  681.                 $code
  682.             );
  683.         }
  684.  
  685.         $code $statusHandler->getErrorCode();
  686.  
  687.         switch ($code{
  688.         case self::ERROR_NONE:
  689.             break;
  690.         case self::ERROR_KEY_NOT_CREATED:
  691.             throw new Crypt_GPG_KeyNotCreatedException(
  692.                 'Unable to create new key-pair. Invalid key parameters. ' .
  693.                 'Make sure the specified key algorithms and sizes are ' .
  694.                 'correct.',
  695.                 $code
  696.             );
  697.         }
  698.  
  699.         $fingerprint $statusHandler->getKeyFingerprint();
  700.         $keys        $this->_getKeys($fingerprint);
  701.  
  702.         if (count($keys=== 0{
  703.             throw new Crypt_GPG_KeyNotCreatedException(
  704.                 sprintf(
  705.                     'Newly created key "%s" not found in keyring.',
  706.                     $fingerprint
  707.                 )
  708.             );
  709.         }
  710.  
  711.         return $keys[0];
  712.     }
  713.  
  714.     // }}}
  715.     // {{{ getUsage()
  716.  
  717.     /**
  718.      * Builds a GnuPG key usage string suitable for key generation
  719.      *
  720.      * See <b>doc/DETAILS</b> in the
  721.      * {@link http://www.gnupg.org/download/ GPG distribution} for detailed
  722.      * information on the key usage format.
  723.      *
  724.      * @param integer $usage a bitwise combination of the key usages. This is
  725.      *                        a combination of the Crypt_GPG_SubKey::USAGE_*
  726.      *                        constants.
  727.      *
  728.      * @return string the key usage string.
  729.      */
  730.     protected function getUsage($usage)
  731.     {
  732.         $map = array(
  733.             Crypt_GPG_SubKey::USAGE_ENCRYPT        => 'encrypt',
  734.             Crypt_GPG_SubKey::USAGE_SIGN           => 'sign',
  735.             Crypt_GPG_SubKey::USAGE_CERTIFY        => 'cert',
  736.             Crypt_GPG_SubKey::USAGE_AUTHENTICATION => 'auth',
  737.         );
  738.  
  739.         // cert is always used for primary keys and does not need to be
  740.         // specified
  741.         $usage &= ~Crypt_GPG_SubKey::USAGE_CERTIFY;
  742.  
  743.         $usageArray = array();
  744.  
  745.         foreach ($map as $key => $value{
  746.             if (($usage $key=== $key{
  747.                 $usageArray[$value;
  748.             }
  749.         }
  750.  
  751.         return implode(','$usageArray);
  752.     }
  753.  
  754.     // }}}
  755.     // {{{ getUserId()
  756.  
  757.     /**
  758.      * Gets a user id object from parameters
  759.      *
  760.      * @param string|Crypt_GPG_UserId$name    either a {@link Crypt_GPG_UserId}
  761.      *                                          object, or a string containing
  762.      *                                          the name of the user id.
  763.      * @param string                  $email   optional. If <i>$name</i> is
  764.      *                                          specified as a string, this is
  765.      *                                          the email address of the user id.
  766.      * @param string                  $comment optional. If <i>$name</i> is
  767.      *                                          specified as a string, this is
  768.      *                                          the comment of the user id.
  769.      *
  770.      * @return Crypt_GPG_UserId a user id object for the specified parameters.
  771.      */
  772.     protected function getUserId($name$email ''$comment '')
  773.     {
  774.         if ($name instanceof Crypt_GPG_UserId{
  775.             $userId $name;
  776.         else {
  777.             $userId = new Crypt_GPG_UserId();
  778.             $userId->setName($name)->setEmail($email)->setComment($comment);
  779.         }
  780.  
  781.         return $userId;
  782.     }
  783.  
  784.     // }}}
  785. }
  786.  
  787. // }}}
  788.  
  789. ?>

Documentation generated on Wed, 13 Mar 2013 18:30:10 +0000 by phpDocumentor 1.4.3. PEAR Logo Copyright © PHP Group 2004.