Skip to content

Commit

Permalink
Implement generateKey()
Browse files Browse the repository at this point in the history
Doesn't support passphrase encryption of the key yet
  • Loading branch information
slusarz committed Apr 13, 2015
1 parent c7e576f commit 14d1fa3
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 17 deletions.
21 changes: 8 additions & 13 deletions framework/Pgp/lib/Horde/Pgp.php
Expand Up @@ -54,38 +54,33 @@ public function __construct(array $params = array())
*
* @param string $name Full name.
* @param string $email E-mail.
* @param string $passphrase Passphrase.
* @param array $opts Additional options:
* - comment: (string) Comment.
* - expire: (integer) The expiration date (UNIX timestamp).
* - keylength: (integer) Key length (e.g. 1024).
* - key_type: (string) Key type (e.g. 'RSA').
* - subkey_type: (string) Subkey type (e.g. 'RSA').
* - expire: (integer) Expiration date (UNIX timestamp).
* - keylength: (integer) Key length.
* - passphrase: (string) Passphrase.
*
* @return Horde_Pgp_Key_Private The generated private key.
* @throws Horde_Pgp_Exception
*/
public function generateKey($name, $email, $passphrase,
array $opts = array())
public function generateKey($name, $email, array $opts = array())
{
$this->_initDrivers();

$opts = array_merge(array(
'comment' => '',
'keylength' => 1024,
'expire' => null,
'key_type' => 'RSA',
'subkey_type' => 'RSA'
'keylength' => 2048,
'passphrase' => null
), $opts, array(
'email' => $email,
'name' => $name,
'passphrase' => $passphrase
'name' => $name
));

return $this->_runInBackend(
'generateKey',
array($opts),
Horde_Pgp_Translation::t("Public/Private keypair not generated successfully.")
Horde_Pgp_Translation::t("PGP key not generated successfully.")
);
}

Expand Down
5 changes: 1 addition & 4 deletions framework/Pgp/lib/Horde/Pgp/Backend.php
Expand Up @@ -43,13 +43,10 @@ static public function supported()
* @param array $opts Configuration:
* - comment: (string) The comment to use.
* - email: (string) The email to use.
* - expire: (integer) The expiration date (UNIX timestamp). No
* expiration if empty.
* - expire: (integer) Expiration date (UNIX timestamp).
* - keylength: (integer) The keylength to use.
* - key_type: (string) Key type.
* - name: (string) The name to use.
* - passphrase: (string) The passphrase to use.
* - subkey_type: (string) Subkey type.
*
* @return Horde_Pgp_Key_Private The generated private key.
*/
Expand Down
53 changes: 53 additions & 0 deletions framework/Pgp/lib/Horde/Pgp/Backend/Openpgp.php
Expand Up @@ -50,6 +50,59 @@ public function __construct()
self::autoload();
}

/**
*/
public function generateKey($opts)
{
$rsa = new Crypt_RSA();
$k = $rsa->createKey($opts['keylength']);
$rsa->loadKey($k['privatekey']);

$nkey = new OpenPGP_SecretKeyPacket(array(
'n' => $rsa->modulus->toBytes(),
'e' => $rsa->publicExponent->toBytes(),
'd' => $rsa->exponent->toBytes(),
'p' => $rsa->primes[1]->toBytes(),
'q' => $rsa->primes[2]->toBytes(),
'u' => $rsa->coefficients[2]->toBytes()
));

$id = new Horde_Mail_Rfc822_Address($opts['email']);
if (strlen($opts['comment'])) {
$id->comment[] = $opts['comment'];
}
if (strlen($opts['name'])) {
$id->personal = $opts['name'];
}

$uid = new OpenPGP_UserIDPacket(
$id->writeAddress(array('comment' => true))
);

$wkey = new OpenPGP_Crypt_RSA($nkey);
$m = $wkey->sign_key_userid(array($nkey, $uid));

if (isset($opts['expire'])) {
foreach ($m as $k => $v) {
if ($v instanceof OpenPGP_SignaturePacket) {
/* Need to recalculate hash. No way of adding this packet
* to be factored into the sign_key_userid() call
* above. */
unset($m[$k]);
$sig = new OpenPGP_SignaturePacket($m, 'RSA', 'SHA256');
$sig->signature_type = $v->signature_type;
$sig->hashed_subpackets = $v->hashed_subpackets;
$sig->hashed_subpackets[] = new OpenPGP_SignaturePacket_KeyExpirationTimePacket($opts['expire'] - time());
$m[$k] = $sig;
$m = $wkey->sign_key_userid($m);
break;
}
}
}

return Horde_Pgp_Element_PrivateKey::createFromData($m);
}

/**
*/
public function encryptSymmetric($text, $passphrase)
Expand Down
7 changes: 7 additions & 0 deletions framework/Pgp/test/Horde/Pgp/Backend/PeclTest.php
Expand Up @@ -35,6 +35,13 @@ protected function _setUp()
return array(new Horde_Pgp_Backend_Pecl());
}

public function testGenerateKey()
{
$this->markTestSkipped(
'PECL extension does not support key generation'
);
}

public function testEncryptSymmetric()
{
$this->markTestSkipped(
Expand Down
20 changes: 20 additions & 0 deletions framework/Pgp/test/Horde/Pgp/Backend/TestBase.php
Expand Up @@ -38,6 +38,26 @@ protected function setUp()
));
}

public function testGenerateKey()
{
$key = $this->_pgp->generateKey(
'Foo',
'foo@example.com',
array(
'comment' => 'Sample Comment',
'expire' => time() + 60,
'keylength' => 512
)
);

$this->assertInstanceOf(
'Horde_Pgp_Element_PrivateKey',
$key
);

$this->assertTrue($key->containsEmail('foo@example.com'));
}

public function testEncrypt()
{
}
Expand Down

0 comments on commit 14d1fa3

Please sign in to comment.