Skip to content

Commit

Permalink
Crypt/PKCS8: rm duplicate code and improve detection of public keys
Browse files Browse the repository at this point in the history
  • Loading branch information
terrafrost committed Mar 5, 2023
1 parent b9996fd commit cf69b29
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 62 deletions.
11 changes: 11 additions & 0 deletions phpseclib/Crypt/Common/Formats/Keys/PKCS8.php
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,9 @@ protected static function load($key, $password = '')
{
$decoded = self::preParse($key);

$isPublic = strpos($key, 'PUBLIC') !== false;
$isPrivate = strpos($key, 'PRIVATE') !== false;

$meta = [];

$decrypted = ASN1::asn1map($decoded[0], Maps\EncryptedPrivateKeyInfo::MAP);
Expand Down Expand Up @@ -445,6 +448,10 @@ protected static function load($key, $password = '')

$private = ASN1::asn1map($decoded[0], Maps\OneAsymmetricKey::MAP);
if (is_array($private)) {
if ($isPublic) {
throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key');
}

if (isset($private['privateKeyAlgorithm']['parameters']) && !$private['privateKeyAlgorithm']['parameters'] instanceof ASN1\Element && isset($decoded[0]['content'][1]['content'][1])) {
$temp = $decoded[0]['content'][1]['content'][1];
$private['privateKeyAlgorithm']['parameters'] = new ASN1\Element(substr($key, $temp['start'], $temp['length']));
Expand Down Expand Up @@ -474,6 +481,10 @@ protected static function load($key, $password = '')
$public = ASN1::asn1map($decoded[0], Maps\PublicKeyInfo::MAP);

if (is_array($public)) {
if ($isPrivate) {
throw new \UnexpectedValueException('Human readable string claims private key but DER encoded string claims public key');
}

if ($public['publicKey'][0] != "\0") {
throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($public['publicKey'][0]));
}
Expand Down
14 changes: 0 additions & 14 deletions phpseclib/Crypt/DH/Formats/Keys/PKCS8.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

namespace phpseclib3\Crypt\DH\Formats\Keys;

use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor;
use phpseclib3\File\ASN1;
use phpseclib3\File\ASN1\Maps;
Expand Down Expand Up @@ -62,23 +61,10 @@ abstract class PKCS8 extends Progenitor
*/
public static function load($key, $password = '')
{
if (!Strings::is_stringable($key)) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
}

$isPublic = strpos($key, 'PUBLIC') !== false;

$key = parent::load($key, $password);

$type = isset($key['privateKey']) ? 'privateKey' : 'publicKey';

switch (true) {
case !$isPublic && $type == 'publicKey':
throw new \UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key');
case $isPublic && $type == 'privateKey':
throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key');
}

$decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element);
if (empty($decoded)) {
throw new \RuntimeException('Unable to decode BER of parameters');
Expand Down
14 changes: 0 additions & 14 deletions phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

namespace phpseclib3\Crypt\DSA\Formats\Keys;

use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor;
use phpseclib3\File\ASN1;
use phpseclib3\File\ASN1\Maps;
Expand Down Expand Up @@ -66,23 +65,10 @@ abstract class PKCS8 extends Progenitor
*/
public static function load($key, $password = '')
{
if (!Strings::is_stringable($key)) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
}

$isPublic = strpos($key, 'PUBLIC') !== false;

$key = parent::load($key, $password);

$type = isset($key['privateKey']) ? 'privateKey' : 'publicKey';

switch (true) {
case !$isPublic && $type == 'publicKey':
throw new \UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key');
case $isPublic && $type == 'privateKey':
throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key');
}

$decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element);
if (!$decoded) {
throw new \RuntimeException('Unable to decode BER of parameters');
Expand Down
16 changes: 1 addition & 15 deletions phpseclib/Crypt/EC/Formats/Keys/PKCS8.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

namespace phpseclib3\Crypt\EC\Formats\Keys;

use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor;
use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve;
use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve;
Expand Down Expand Up @@ -74,23 +73,10 @@ public static function load($key, $password = '')
// one that's called
self::initialize_static_variables();

if (!Strings::is_stringable($key)) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
}

$isPublic = strpos($key, 'PUBLIC') !== false;

$key = parent::load($key, $password);

$type = isset($key['privateKey']) ? 'privateKey' : 'publicKey';

switch (true) {
case !$isPublic && $type == 'publicKey':
throw new \UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key');
case $isPublic && $type == 'privateKey':
throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key');
}

switch ($key[$type . 'Algorithm']['algorithm']) {
case 'id-Ed25519':
case 'id-Ed448':
Expand All @@ -109,7 +95,7 @@ public static function load($key, $password = '')
$components = [];
$components['curve'] = self::loadCurveByParam($params);

if ($isPublic) {
if ($type == 'publicKey') {
$components['QA'] = self::extractPoint("\0" . $key['publicKey'], $components['curve']);

return $components;
Expand Down
21 changes: 2 additions & 19 deletions phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

namespace phpseclib3\Crypt\RSA\Formats\Keys;

use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor;
use phpseclib3\File\ASN1;
use phpseclib3\Math\BigInteger;
Expand Down Expand Up @@ -67,29 +66,13 @@ abstract class PKCS8 extends Progenitor
*/
public static function load($key, $password = '')
{
if (!Strings::is_stringable($key)) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
}

if (strpos($key, 'PUBLIC') !== false) {
$components = ['isPublicKey' => true];
} elseif (strpos($key, 'PRIVATE') !== false) {
$components = ['isPublicKey' => false];
} else {
$components = [];
}

$key = parent::load($key, $password);

if (isset($key['privateKey'])) {
if (!isset($components['isPublicKey'])) {
$components['isPublicKey'] = false;
}
$components['isPublicKey'] = false;
$type = 'private';
} else {
if (!isset($components['isPublicKey'])) {
$components['isPublicKey'] = true;
}
$components['isPublicKey'] = true;
$type = 'public';
}

Expand Down

0 comments on commit cf69b29

Please sign in to comment.