You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
791 lines
29 KiB
PHP
791 lines
29 KiB
PHP
<?php
|
|
|
|
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
|
|
|
/**
|
|
* Crypt_GPG is a package to use GPG from PHP
|
|
*
|
|
* This file contains an object that handles GnuPG key generation.
|
|
*
|
|
* PHP version 5
|
|
*
|
|
* LICENSE:
|
|
*
|
|
* This library is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as
|
|
* published by the Free Software Foundation; either version 2.1 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* @category Encryption
|
|
* @package Crypt_GPG
|
|
* @author Michael Gauthier <mike@silverorange.com>
|
|
* @copyright 2011-2013 silverorange
|
|
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
|
* @version CVS: $Id:$
|
|
* @link http://pear.php.net/package/Crypt_GPG
|
|
* @link http://www.gnupg.org/
|
|
*/
|
|
|
|
/**
|
|
* Base class for GPG methods
|
|
*/
|
|
require_once 'Crypt/GPGAbstract.php';
|
|
|
|
/**
|
|
* Status output handler for key generation
|
|
*/
|
|
require_once 'Crypt/GPG/KeyGeneratorStatusHandler.php';
|
|
|
|
/**
|
|
* Error output handler for key generation
|
|
*/
|
|
require_once 'Crypt/GPG/KeyGeneratorErrorHandler.php';
|
|
|
|
// {{{ class Crypt_GPG_KeyGenerator
|
|
|
|
/**
|
|
* GnuPG key generator
|
|
*
|
|
* This class provides an object oriented interface for generating keys with
|
|
* the GNU Privacy Guard (GPG).
|
|
*
|
|
* Secure key generation requires true random numbers, and as such can be slow.
|
|
* If the operating system runs out of entropy, key generation will block until
|
|
* more entropy is available.
|
|
*
|
|
* If quick key generation is important, a hardware entropy generator, or an
|
|
* entropy gathering daemon may be installed. For example, administrators of
|
|
* Debian systems may want to install the 'randomsound' package.
|
|
*
|
|
* This class uses the experimental automated key generation support available
|
|
* in GnuPG. See <b>doc/DETAILS</b> in the
|
|
* {@link http://www.gnupg.org/download/ GPG distribution} for detailed
|
|
* information on the key generation format.
|
|
*
|
|
* @category Encryption
|
|
* @package Crypt_GPG
|
|
* @author Nathan Fredrickson <nathan@silverorange.com>
|
|
* @author Michael Gauthier <mike@silverorange.com>
|
|
* @copyright 2005-2013 silverorange
|
|
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
|
|
* @link http://pear.php.net/package/Crypt_GPG
|
|
* @link http://www.gnupg.org/
|
|
*/
|
|
class Crypt_GPG_KeyGenerator extends Crypt_GPGAbstract
|
|
{
|
|
// {{{ protected properties
|
|
|
|
/**
|
|
* The expiration date of generated keys
|
|
*
|
|
* @var integer
|
|
*
|
|
* @see Crypt_GPG_KeyGenerator::setExpirationDate()
|
|
*/
|
|
protected $expirationDate = 0;
|
|
|
|
/**
|
|
* The passphrase of generated keys
|
|
*
|
|
* @var string
|
|
*
|
|
* @see Crypt_GPG_KeyGenerator::setPassphrase()
|
|
*/
|
|
protected $passphrase = '';
|
|
|
|
/**
|
|
* The algorithm for generated primary keys
|
|
*
|
|
* @var integer
|
|
*
|
|
* @see Crypt_GPG_KeyGenerator::setKeyParams()
|
|
*/
|
|
protected $keyAlgorithm = Crypt_GPG_SubKey::ALGORITHM_DSA;
|
|
|
|
/**
|
|
* The size of generated primary keys
|
|
*
|
|
* @var integer
|
|
*
|
|
* @see Crypt_GPG_KeyGenerator::setKeyParams()
|
|
*/
|
|
protected $keySize = 1024;
|
|
|
|
/**
|
|
* The usages of generated primary keys
|
|
*
|
|
* This is a bitwise combination of the usage constants in
|
|
* {@link Crypt_GPG_SubKey}.
|
|
*
|
|
* @var integer
|
|
*
|
|
* @see Crypt_GPG_KeyGenerator::setKeyParams()
|
|
*/
|
|
protected $keyUsage = 6; // USAGE_SIGN | USAGE_CERTIFY
|
|
|
|
/**
|
|
* The algorithm for generated sub-keys
|
|
*
|
|
* @var integer
|
|
*
|
|
* @see Crypt_GPG_KeyGenerator::setSubKeyParams()
|
|
*/
|
|
protected $subKeyAlgorithm = Crypt_GPG_SubKey::ALGORITHM_ELGAMAL_ENC;
|
|
|
|
/**
|
|
* The size of generated sub-keys
|
|
*
|
|
* @var integer
|
|
*
|
|
* @see Crypt_GPG_KeyGenerator::setSubKeyParams()
|
|
*/
|
|
protected $subKeySize = 2048;
|
|
|
|
/**
|
|
* The usages of generated sub-keys
|
|
*
|
|
* This is a bitwise combination of the usage constants in
|
|
* {@link Crypt_GPG_SubKey}.
|
|
*
|
|
* @var integer
|
|
*
|
|
* @see Crypt_GPG_KeyGenerator::setSubKeyParams()
|
|
*/
|
|
protected $subKeyUsage = Crypt_GPG_SubKey::USAGE_ENCRYPT;
|
|
|
|
/**
|
|
* The GnuPG status handler to use for key generation
|
|
*
|
|
* @var Crypt_GPG_KeyGeneratorStatusHandler
|
|
*
|
|
* @see Crypt_GPG_KeyGenerator::setStatusHandler()
|
|
*/
|
|
protected $statusHandler = null;
|
|
|
|
/**
|
|
* The GnuPG error handler to use for key generation
|
|
*
|
|
* @var Crypt_GPG_KeyGeneratorErrorHandler
|
|
*
|
|
* @see Crypt_GPG_KeyGenerator::setErrorHandler()
|
|
*/
|
|
protected $errorHandler = null;
|
|
|
|
// }}}
|
|
// {{{ __construct()
|
|
|
|
/**
|
|
* Creates a new GnuPG key generator
|
|
*
|
|
* Available options are:
|
|
*
|
|
* - <kbd>string homedir</kbd> - the directory where the GPG
|
|
* keyring files are stored. If not
|
|
* specified, Crypt_GPG uses the
|
|
* default of <kbd>~/.gnupg</kbd>.
|
|
* - <kbd>string publicKeyring</kbd> - 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 <i>homedir</i> option.
|
|
* - <kbd>string privateKeyring</kbd> - 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 <i>homedir</i> option.
|
|
* - <kbd>string trustDb</kbd> - 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 <i>homedir</i> option.
|
|
* - <kbd>string binary</kbd> - 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
|
|
* <kbd>gpgBinary</kbd> is a
|
|
* deprecated alias for this option.
|
|
* - <kbd>string agent</kbd> - 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.
|
|
* - <kbd>boolean debug</kbd> - 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
|
|
*
|
|
* @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 <kbd>homedir</kbd> does not exist
|
|
* and cannot be created. This can happen if <kbd>homedir</kbd> 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 <kbd>publicKeyring</kbd>,
|
|
* <kbd>privateKeyring</kbd> or <kbd>trustDb</kbd> 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 <kbd>binary</kbd> is invalid, or
|
|
* if no <kbd>binary</kbd> is provided and no suitable binary could
|
|
* be found.
|
|
*
|
|
* @throws PEAR_Exception if the provided <kbd>agent</kbd> is invalid, or
|
|
* if no <kbd>agent</kbd> is provided and no suitable gpg-agent
|
|
* cound be found.
|
|
*/
|
|
public function __construct(array $options = array())
|
|
{
|
|
parent::__construct($options);
|
|
|
|
$this->statusHandler = new Crypt_GPG_KeyGeneratorStatusHandler();
|
|
$this->errorHandler = new Crypt_GPG_KeyGeneratorErrorHandler();
|
|
}
|
|
|
|
// }}}
|
|
// {{{ setExpirationDate()
|
|
|
|
/**
|
|
* Sets the expiration date of generated keys
|
|
*
|
|
* @param string|integer $date either a string that may be parsed by
|
|
* PHP's strtotime() function, or an integer
|
|
* timestamp representing the number of seconds
|
|
* since the UNIX epoch. This date must be at
|
|
* least one date in the future. Keys that
|
|
* expire in the past may not be generated. Use
|
|
* an expiration date of 0 for keys that do not
|
|
* expire.
|
|
*
|
|
* @throws InvalidArgumentException if the date is not a valid format, or
|
|
* if the date is not at least one day in
|
|
* the future, or if the date is greater
|
|
* than 2038-01-19T03:14:07.
|
|
*
|
|
* @return Crypt_GPG_KeyGenerator the current object, for fluent interface.
|
|
*/
|
|
public function setExpirationDate($date)
|
|
{
|
|
if (is_int($date) || ctype_digit(strval($date))) {
|
|
$expirationDate = intval($date);
|
|
} else {
|
|
$expirationDate = strtotime($date);
|
|
}
|
|
|
|
if ($expirationDate === false) {
|
|
throw new InvalidArgumentException(
|
|
sprintf(
|
|
'Invalid expiration date format: "%s". Please use a ' .
|
|
'format compatible with PHP\'s strtotime().',
|
|
$date
|
|
)
|
|
);
|
|
}
|
|
|
|
if ($expirationDate !== 0 && $expirationDate < time() + 86400) {
|
|
throw new InvalidArgumentException(
|
|
'Expiration date must be at least a day in the future.'
|
|
);
|
|
}
|
|
|
|
// GnuPG suffers from the 2038 bug
|
|
if ($expirationDate > 2147483647) {
|
|
throw new InvalidArgumentException(
|
|
'Expiration date must not be greater than 2038-01-19T03:14:07.'
|
|
);
|
|
}
|
|
|
|
$this->expirationDate = $expirationDate;
|
|
|
|
return $this;
|
|
}
|
|
|
|
// }}}
|
|
// {{{ setPassphrase()
|
|
|
|
/**
|
|
* Sets the passphrase of generated keys
|
|
*
|
|
* @param string $passphrase the passphrase to use for generated keys. Use
|
|
* null or an empty string for no passphrase.
|
|
*
|
|
* @return Crypt_GPG_KeyGenerator the current object, for fluent interface.
|
|
*/
|
|
public function setPassphrase($passphrase)
|
|
{
|
|
$this->passphrase = strval($passphrase);
|
|
return $this;
|
|
}
|
|
|
|
// }}}
|
|
// {{{ setKeyParams()
|
|
|
|
/**
|
|
* Sets the parameters for the primary key of generated key-pairs
|
|
*
|
|
* @param integer $algorithm the algorithm used by the key. This should be
|
|
* one of the Crypt_GPG_SubKey::ALGORITHM_*
|
|
* constants.
|
|
* @param integer $size optional. The size of the key. Different
|
|
* algorithms have different size requirements.
|
|
* If not specified, the default size for the
|
|
* specified algorithm will be used. If an
|
|
* invalid key size is used, GnuPG will do its
|
|
* best to round it to a valid size.
|
|
* @param integer $usage optional. A bitwise combination of key usages.
|
|
* If not specified, the primary key will be used
|
|
* only to sign and certify. This is the default
|
|
* behavior of GnuPG in interactive mode. Use
|
|
* the Crypt_GPG_SubKey::USAGE_* constants here.
|
|
* The primary key may be used to certify even
|
|
* if the certify usage is not specified.
|
|
*
|
|
* @return Crypt_GPG_KeyGenerator the current object, for fluent interface.
|
|
*/
|
|
public function setKeyParams($algorithm, $size = 0, $usage = 0)
|
|
{
|
|
$apgorithm = intval($algorithm);
|
|
|
|
if ($algorithm === Crypt_GPG_SubKey::ALGORITHM_ELGAMAL_ENC) {
|
|
throw new Crypt_GPG_InvalidKeyParamsException(
|
|
'Primary key algorithm must be capable of signing. The ' .
|
|
'Elgamal algorithm can only encrypt.',
|
|
0,
|
|
$algorithm,
|
|
$size,
|
|
$usage
|
|
);
|
|
}
|
|
|
|
if ($size != 0) {
|
|
$size = intval($size);
|
|
}
|
|
|
|
if ($usage != 0) {
|
|
$usage = intval($usage);
|
|
}
|
|
|
|
$usageEncrypt = Crypt_GPG_SubKey::USAGE_ENCRYPT;
|
|
|
|
if ( $algorithm === Crypt_GPG_SubKey::ALGORITHM_DSA
|
|
&& ($usage & $usageEncrypt) === $usageEncrypt
|
|
) {
|
|
throw new Crypt_GPG_InvalidKeyParamsException(
|
|
'The DSA algorithm is not capable of encrypting. Please ' .
|
|
'specify a different algorithm or do not include encryption ' .
|
|
'as a usage for the primary key.',
|
|
0,
|
|
$algorithm,
|
|
$size,
|
|
$usage
|
|
);
|
|
}
|
|
|
|
$this->keyAlgorithm = $algorithm;
|
|
|
|
if ($size != 0) {
|
|
$this->keySize = $size;
|
|
}
|
|
|
|
if ($usage != 0) {
|
|
$this->keyUsage = $usage;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
// }}}
|
|
// {{{ setSubKeyParams()
|
|
|
|
/**
|
|
* Sets the parameters for the sub-key of generated key-pairs
|
|
*
|
|
* @param integer $algorithm the algorithm used by the key. This should be
|
|
* one of the Crypt_GPG_SubKey::ALGORITHM_*
|
|
* constants.
|
|
* @param integer $size optional. The size of the key. Different
|
|
* algorithms have different size requirements.
|
|
* If not specified, the default size for the
|
|
* specified algorithm will be used. If an
|
|
* invalid key size is used, GnuPG will do its
|
|
* best to round it to a valid size.
|
|
* @param integer $usage optional. A bitwise combination of key usages.
|
|
* If not specified, the sub-key will be used
|
|
* only to encrypt. This is the default behavior
|
|
* of GnuPG in interactive mode. Use the
|
|
* Crypt_GPG_SubKey::USAGE_* constants here.
|
|
*
|
|
* @return Crypt_GPG_KeyGenerator the current object, for fluent interface.
|
|
*/
|
|
public function setSubKeyParams($algorithm, $size = '', $usage = 0)
|
|
{
|
|
$apgorithm = intval($algorithm);
|
|
|
|
if ($size != 0) {
|
|
$size = intval($size);
|
|
}
|
|
|
|
if ($usage != 0) {
|
|
$usage = intval($usage);
|
|
}
|
|
|
|
$usageSign = Crypt_GPG_SubKey::USAGE_SIGN;
|
|
|
|
if ( $algorithm === Crypt_GPG_SubKey::ALGORITHM_ELGAMAL_ENC
|
|
&& ($usage & $usageSign) === $usageSign
|
|
) {
|
|
throw new Crypt_GPG_InvalidKeyParamsException(
|
|
'The Elgamal algorithm is not capable of signing. Please ' .
|
|
'specify a different algorithm or do not include signing ' .
|
|
'as a usage for the sub-key.',
|
|
0,
|
|
$algorithm,
|
|
$size,
|
|
$usage
|
|
);
|
|
}
|
|
|
|
$usageEncrypt = Crypt_GPG_SubKey::USAGE_ENCRYPT;
|
|
|
|
if ( $algorithm === Crypt_GPG_SubKey::ALGORITHM_DSA
|
|
&& ($usage & $usageEncrypt) === $usageEncrypt
|
|
) {
|
|
throw new Crypt_GPG_InvalidKeyParamsException(
|
|
'The DSA algorithm is not capable of encrypting. Please ' .
|
|
'specify a different algorithm or do not include encryption ' .
|
|
'as a usage for the sub-key.',
|
|
0,
|
|
$algorithm,
|
|
$size,
|
|
$usage
|
|
);
|
|
}
|
|
|
|
$this->subKeyAlgorithm = $algorithm;
|
|
|
|
if ($size != 0) {
|
|
$this->subKeySize = $size;
|
|
}
|
|
|
|
if ($usage != 0) {
|
|
$this->subKeyUsage = $usage;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
// }}}
|
|
// {{{ setStatusHandler()
|
|
|
|
/**
|
|
* Sets the status handler to use for key generation
|
|
*
|
|
* Normally this method does not need to be used. It provides a means for
|
|
* dependency injection.
|
|
*
|
|
* @param Crypt_GPG_KeyStatusHandler $handler the key status handler to
|
|
* use.
|
|
*
|
|
* @return Crypt_GPG_KeyGenerator the current object, for fluent interface.
|
|
*/
|
|
public function setStatusHandler(
|
|
Crypt_GPG_KeyGeneratorStatusHandler $handler
|
|
) {
|
|
$this->statusHandler = $handler;
|
|
return $this;
|
|
}
|
|
|
|
// }}}
|
|
// {{{ setErrorHandler()
|
|
|
|
/**
|
|
* Sets the error handler to use for key generation
|
|
*
|
|
* Normally this method does not need to be used. It provides a means for
|
|
* dependency injection.
|
|
*
|
|
* @param Crypt_GPG_KeyErrorHandler $handler the key error handler to
|
|
* use.
|
|
*
|
|
* @return Crypt_GPG_KeyGenerator the current object, for fluent interface.
|
|
*/
|
|
public function setErrorHandler(
|
|
Crypt_GPG_KeyGeneratorErrorHandler $handler
|
|
) {
|
|
$this->errorHandler = $handler;
|
|
return $this;
|
|
}
|
|
|
|
// }}}
|
|
// {{{ generateKey()
|
|
|
|
/**
|
|
* Generates a new key-pair in the current keyring
|
|
*
|
|
* Secure key generation requires true random numbers, and as such can be
|
|
* solw. If the operating system runs out of entropy, key generation will
|
|
* block until more entropy is available.
|
|
*
|
|
* If quick key generation is important, a hardware entropy generator, or
|
|
* an entropy gathering daemon may be installed. For example,
|
|
* administrators of Debian systems may want to install the 'randomsound'
|
|
* package.
|
|
*
|
|
* @param string|Crypt_GPG_UserId $name either a {@link Crypt_GPG_UserId}
|
|
* object, or a string containing
|
|
* the name of the user id.
|
|
* @param string $email optional. If <i>$name</i> is
|
|
* specified as a string, this is
|
|
* the email address of the user id.
|
|
* @param string $comment optional. If <i>$name</i> is
|
|
* specified as a string, this is
|
|
* the comment of the user id.
|
|
*
|
|
* @return Crypt_GPG_Key the newly generated key.
|
|
*
|
|
* @throws Crypt_GPG_KeyNotCreatedException if the key parameters are
|
|
* incorrect, if an unknown error occurs during key generation, or
|
|
* if the newly generated key is not found in the keyring.
|
|
*
|
|
* @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
|
|
* Use the <kbd>debug</kbd> option and file a bug report if these
|
|
* exceptions occur.
|
|
*/
|
|
public function generateKey($name, $email = '', $comment = '')
|
|
{
|
|
$handle = uniqid('key', true);
|
|
|
|
$userId = $this->getUserId($name, $email, $comment);
|
|
|
|
$keyParams = array(
|
|
'Key-Type' => $this->keyAlgorithm,
|
|
'Key-Length' => $this->keySize,
|
|
'Key-Usage' => $this->getUsage($this->keyUsage),
|
|
'Subkey-Type' => $this->subKeyAlgorithm,
|
|
'Subkey-Length' => $this->subKeySize,
|
|
'Subkey-Usage' => $this->getUsage($this->subKeyUsage),
|
|
'Name-Real' => $userId->getName(),
|
|
'Handle' => $handle,
|
|
);
|
|
|
|
if ($this->expirationDate != 0) {
|
|
// GnuPG only accepts granularity of days
|
|
$expirationDate = date('Y-m-d', $this->expirationDate);
|
|
$keyParams['Expire-Date'] = $expirationDate;
|
|
}
|
|
|
|
if ($this->passphrase != '') {
|
|
$keyParams['Passphrase'] = $this->passphrase;
|
|
}
|
|
|
|
if ($userId->getEmail() != '') {
|
|
$keyParams['Name-Email'] = $userId->getEmail();
|
|
}
|
|
|
|
if ($userId->getComment() != '') {
|
|
$keyParams['Name-Comment'] = $userId->getComment();
|
|
}
|
|
|
|
|
|
$keyParamsFormatted = array();
|
|
foreach ($keyParams as $name => $value) {
|
|
$keyParamsFormatted[] = $name . ': ' . $value;
|
|
}
|
|
|
|
$input = implode("\n", $keyParamsFormatted) . "\n%commit\n";
|
|
|
|
$statusHandler = clone $this->statusHandler;
|
|
$statusHandler->setHandle($handle);
|
|
|
|
$errorHandler = clone $this->errorHandler;
|
|
|
|
$this->engine->reset();
|
|
$this->engine->addStatusHandler(array($statusHandler, 'handle'));
|
|
$this->engine->addErrorHandler(array($errorHandler, 'handle'));
|
|
$this->engine->setInput($input);
|
|
$this->engine->setOutput($output);
|
|
$this->engine->setOperation('--gen-key', array('--batch'));
|
|
$this->engine->run();
|
|
|
|
$code = $errorHandler->getErrorCode();
|
|
switch ($code) {
|
|
case self::ERROR_BAD_KEY_PARAMS:
|
|
switch ($errorHandler->getLineNumber()) {
|
|
case 1:
|
|
throw new Crypt_GPG_InvalidKeyParamsException(
|
|
'Invalid primary key algorithm specified.',
|
|
0,
|
|
$this->keyAlgorithm,
|
|
$this->keySize,
|
|
$this->keyUsage
|
|
);
|
|
case 4:
|
|
throw new Crypt_GPG_InvalidKeyParamsException(
|
|
'Invalid sub-key algorithm specified.',
|
|
0,
|
|
$this->subKeyAlgorithm,
|
|
$this->subKeySize,
|
|
$this->subKeyUsage
|
|
);
|
|
default:
|
|
throw new Crypt_GPG_InvalidKeyParamsException(
|
|
'Invalid key algorithm specified.'
|
|
);
|
|
}
|
|
}
|
|
|
|
$code = $this->engine->getErrorCode();
|
|
|
|
switch ($code) {
|
|
case self::ERROR_NONE:
|
|
break;
|
|
default:
|
|
throw new Crypt_GPG_Exception(
|
|
'Unknown error generating key-pair. Please use the \'debug\' ' .
|
|
'option when creating the Crypt_GPG object, and file a bug ' .
|
|
'report at ' . self::BUG_URI,
|
|
$code
|
|
);
|
|
}
|
|
|
|
$code = $statusHandler->getErrorCode();
|
|
|
|
switch ($code) {
|
|
case self::ERROR_NONE:
|
|
break;
|
|
case self::ERROR_KEY_NOT_CREATED:
|
|
throw new Crypt_GPG_KeyNotCreatedException(
|
|
'Unable to create new key-pair. Invalid key parameters. ' .
|
|
'Make sure the specified key algorithms and sizes are ' .
|
|
'correct.',
|
|
$code
|
|
);
|
|
}
|
|
|
|
$fingerprint = $statusHandler->getKeyFingerprint();
|
|
$keys = $this->_getKeys($fingerprint);
|
|
|
|
if (count($keys) === 0) {
|
|
throw new Crypt_GPG_KeyNotCreatedException(
|
|
sprintf(
|
|
'Newly created key "%s" not found in keyring.',
|
|
$fingerprint
|
|
)
|
|
);
|
|
}
|
|
|
|
return $keys[0];
|
|
}
|
|
|
|
// }}}
|
|
// {{{ getUsage()
|
|
|
|
/**
|
|
* Builds a GnuPG key usage string suitable for key generation
|
|
*
|
|
* See <b>doc/DETAILS</b> in the
|
|
* {@link http://www.gnupg.org/download/ GPG distribution} for detailed
|
|
* information on the key usage format.
|
|
*
|
|
* @param integer $usage a bitwise combination of the key usages. This is
|
|
* a combination of the Crypt_GPG_SubKey::USAGE_*
|
|
* constants.
|
|
*
|
|
* @return string the key usage string.
|
|
*/
|
|
protected function getUsage($usage)
|
|
{
|
|
$map = array(
|
|
Crypt_GPG_SubKey::USAGE_ENCRYPT => 'encrypt',
|
|
Crypt_GPG_SubKey::USAGE_SIGN => 'sign',
|
|
Crypt_GPG_SubKey::USAGE_CERTIFY => 'cert',
|
|
Crypt_GPG_SubKey::USAGE_AUTHENTICATION => 'auth',
|
|
);
|
|
|
|
// cert is always used for primary keys and does not need to be
|
|
// specified
|
|
$usage &= ~Crypt_GPG_SubKey::USAGE_CERTIFY;
|
|
|
|
$usageArray = array();
|
|
|
|
foreach ($map as $key => $value) {
|
|
if (($usage & $key) === $key) {
|
|
$usageArray[] = $value;
|
|
}
|
|
}
|
|
|
|
return implode(',', $usageArray);
|
|
}
|
|
|
|
// }}}
|
|
// {{{ getUserId()
|
|
|
|
/**
|
|
* Gets a user id object from parameters
|
|
*
|
|
* @param string|Crypt_GPG_UserId $name either a {@link Crypt_GPG_UserId}
|
|
* object, or a string containing
|
|
* the name of the user id.
|
|
* @param string $email optional. If <i>$name</i> is
|
|
* specified as a string, this is
|
|
* the email address of the user id.
|
|
* @param string $comment optional. If <i>$name</i> is
|
|
* specified as a string, this is
|
|
* the comment of the user id.
|
|
*
|
|
* @return Crypt_GPG_UserId a user id object for the specified parameters.
|
|
*/
|
|
protected function getUserId($name, $email = '', $comment = '')
|
|
{
|
|
if ($name instanceof Crypt_GPG_UserId) {
|
|
$userId = $name;
|
|
} else {
|
|
$userId = new Crypt_GPG_UserId();
|
|
$userId->setName($name)->setEmail($email)->setComment($comment);
|
|
}
|
|
|
|
return $userId;
|
|
}
|
|
|
|
// }}}
|
|
}
|
|
|
|
// }}}
|
|
|
|
?>
|