Skip to content
This repository has been archived by the owner on Dec 30, 2020. It is now read-only.

Commit

Permalink
Private keys from APN support (#146)
Browse files Browse the repository at this point in the history
* Bug fixed and test added
* PKCS#8 key loader added
* Applied fixes from StyleCI
  • Loading branch information
Spomky authored Oct 18, 2016
1 parent 229c6ca commit 4b1cb24
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 3 deletions.
41 changes: 39 additions & 2 deletions src/KeyConverter/ECKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,11 @@ private function loadPEM($data)
$asnObject = Object::fromBinary($data);

Assertion::isInstanceOf($asnObject, Sequence::class);

$children = $asnObject->getChildren();
if (self::isPKCS8($children)) {
$children = self::loadPKCS8($children);
}

if (4 === count($children)) {
return $this->loadPrivatePEM($children);
} elseif (2 === count($children)) {
Expand All @@ -77,6 +80,41 @@ private function loadPEM($data)
throw new \Exception('Unable to load the key');
}

/**
* @param array $children
*
* @return array
*/
private function loadPKCS8(array $children)
{
$binary = hex2bin($children[2]->getContent());
$asnObject = Object::fromBinary($binary);
Assertion::isInstanceOf($asnObject, Sequence::class);

return $asnObject->getChildren();
}

/**
* @param array $children
*
* @return bool
*/
private function isPKCS8(array $children)
{
if (3 !== count($children)) {
return false;
}

$classes = [0 => Integer::class, 1 => Sequence::class, 2 => OctetString::class];
foreach ($classes as $k => $class) {
if (!$children[$k] instanceof $class) {
return false;
}
}

return true;
}

/**
* @param array $jwk
*/
Expand Down Expand Up @@ -202,7 +240,6 @@ private function getD(Object $children)
private function loadPrivatePEM(array $children)
{
$this->verifyVersion($children[0]);

$x = null;
$y = null;
$d = $this->getD($children[1]);
Expand Down
17 changes: 17 additions & 0 deletions src/KeyConverter/KeyConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ private static function loadKeyFromPEM($pem, $password = null)
$pem = self::decodePem($pem, $matches, $password);
}

self::sanitizePEM($pem);

$res = openssl_pkey_get_private($pem);
if ($res === false) {
$res = openssl_pkey_get_public($pem);
Expand All @@ -173,6 +175,21 @@ private static function loadKeyFromPEM($pem, $password = null)
}
}

/**
* This method modify the PEM to get 64 char lines and fix bug with old OpenSSL versions.
*
* @param string $pem
*/
private static function sanitizePEM(&$pem)
{
preg_match_all('#(-.*-)#', $pem, $matches, PREG_PATTERN_ORDER);
$ciphertext = preg_replace('#-.*-|\r|\n| #', '', $pem);

$pem = $matches[0][0].PHP_EOL;
$pem .= chunk_split($ciphertext, 64, PHP_EOL);
$pem .= $matches[0][1].PHP_EOL;
}

/**
* @param array $x5c
*
Expand Down
3 changes: 3 additions & 0 deletions tests/Unit/Keys/EC/private.es256.from.APN.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-----BEGIN PRIVATE KEY-----
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg13n3isfsEktzl+CtH5ECpRrKk+40prVuCbldkP77gamgCgYIKoZIzj0DAQehRANCAARhwgxSRqXBt54BWRQXoU/doFWULOWrER3uLS43/iugDW1PMDliQZEzWetYAdf+Mafq/PrlbEAfA+l7JfmijAsv
-----END PRIVATE KEY-----
18 changes: 17 additions & 1 deletion tests/Unit/Keys/ECKeysTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,23 @@ public function testKeyTypeNotSupported()
KeyConverter::loadFromKeyFile($file);
}

/**
* @see https://github.com/Spomky-Labs/jose/issues/141
* @see https://gist.github.com/Spomky/246eca6aaeeb7a40f11d3a2d98960282
*/
public function testLoadPrivateEC256KeyGenerateByAPN()
{
$pem = file_get_contents('file://'.__DIR__.DIRECTORY_SEPARATOR.'EC'.DIRECTORY_SEPARATOR.'private.es256.from.APN.key');
$details = KeyConverter::loadFromKey($pem);
$this->assertEquals($details, [
'kty' => 'EC',
'crv' => 'P-256',
'd' => '13n3isfsEktzl-CtH5ECpRrKk-40prVuCbldkP77gak',
'x' => 'YcIMUkalwbeeAVkUF6FP3aBVlCzlqxEd7i0uN_4roA0',
'y' => 'bU8wOWJBkTNZ61gB1_4xp-r8-uVsQB8D6Xsl-aKMCy8',
]);
}

public function testLoadPublicEC256Key()
{
$pem = file_get_contents('file://'.__DIR__.DIRECTORY_SEPARATOR.'EC'.DIRECTORY_SEPARATOR.'public.es256.key');
Expand All @@ -38,7 +55,6 @@ public function testLoadPublicEC256Key()
'crv' => 'P-256',
'x' => 'vuYsP-QnrqAbM7Iyhzjt08hFSuzapyojCB_gFsBt65U',
'y' => 'oq-E2K-X0kPeqGuKnhlXkxc5fnxomRSC6KLby7Ij8AE',

]);

$ec_key = new ECKey($details);
Expand Down

0 comments on commit 4b1cb24

Please sign in to comment.