From 05d934c89f3597d6c3b0a88892ea4f0d76c3ac6a Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 8 Jan 2021 08:46:38 -0600 Subject: [PATCH] RSA: improve identification of public / private PKCS1 / PKCS8 keys --- phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php | 15 ++++++++++++++- phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php | 20 ++++++++++++++++++-- tests/Unit/Crypt/RSA/LoadKeyTest.php | 10 ++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php b/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php index 64e707e0..5203e463 100644 --- a/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php +++ b/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php @@ -53,7 +53,13 @@ abstract class PKCS1 extends Progenitor throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } - $components = ['isPublicKey' => strpos($key, 'PUBLIC') !== false]; + if (strpos($key, 'PUBLIC') !== false) { + $components = ['isPublicKey' => true]; + } elseif (strpos($key, 'PRIVATE') !== false) { + $components = ['isPublicKey' => false]; + } else { + $components = []; + } $key = parent::load($key, $password); @@ -79,6 +85,9 @@ abstract class PKCS1 extends Progenitor $components['coefficients'][] = $primeInfo['coefficient']; } } + if (!isset($components['isPublicKey'])) { + $components['isPublicKey'] = false; + } return $components; } @@ -88,6 +97,10 @@ abstract class PKCS1 extends Progenitor throw new \RuntimeException('Unable to perform ASN1 mapping'); } + if (!isset($components['isPublicKey'])) { + $components['isPublicKey'] = true; + } + return $components + $key; } diff --git a/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php b/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php index 1fcfeae1..8ead2c95 100644 --- a/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php +++ b/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php @@ -79,11 +79,27 @@ abstract class PKCS8 extends Progenitor throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } - $components = ['isPublicKey' => strpos($key, 'PUBLIC') !== false]; + if (strpos($key, 'PUBLIC') !== false) { + $components = ['isPublicKey' => true]; + } elseif (strpos($key, 'PRIVATE') !== false) { + $components = ['isPublicKey' => false]; + } else { + $components = []; + } $key = parent::load($key, $password); - $type = isset($key['privateKey']) ? 'private' : 'public'; + if (isset($key['privateKey'])) { + if (!isset($components['isPublicKey'])) { + $components['isPublicKey'] = false; + } + $type = 'private'; + } else { + if (!isset($components['isPublicKey'])) { + $components['isPublicKey'] = true; + } + $type = 'public'; + } $result = $components + PKCS1::load($key[$type . 'Key']); diff --git a/tests/Unit/Crypt/RSA/LoadKeyTest.php b/tests/Unit/Crypt/RSA/LoadKeyTest.php index 8b20ebe0..64a7e669 100644 --- a/tests/Unit/Crypt/RSA/LoadKeyTest.php +++ b/tests/Unit/Crypt/RSA/LoadKeyTest.php @@ -1056,4 +1056,14 @@ n9dyFZYXxil/cgFG/PDMnuXy1Wcl8hb8iwQag4Y7ohiLXVTJa/0BAgMBAAE= $result = $key->toString('PKCS1'); $this->assertIsString($result); } + + /** + * @group github1579 + */ + public function testNakedPKCS1PublicKey() + { + $key = '3082020a0282020100d595c09fbc635612b3ef6a0067d74cb76fa9af62a9272400c2a896f1335b920b88a9accaffe915e38542d296c1a559a586223521da8977030888a8d076910f59489a3a4a10bf950bf2b83278810e4c3bfc027b6b6cb75736cfaabaa83de15c619b8e9f65a60f4cfeba11fb5bf5e93abff68468695948b1843e2e09504281651475f7eff1c30fcb17026f13f04109fc930e489c14a1ef80ec51be6bb73f1679d258c2db535b04f4be82790ac01b4b0e9cb68a9bb5afab4363b5f33ff143ef13d1b2a292a72881d68d765a6c1fc981da0a2644ed284607d19f39802b3967bf9308da1f6515b59a2b0a1c57c14d661a62672f3b9453f931b62c446267d912c0987b7fb4c4fe085e3573ddfd9761ec2c035fa560c6c98343e9d448667b724a919780be2fd8666115d8a75b29e6c1e216cd73a693192f551f72fdf9eac0bb5bda83b11b5159151419249915e6006e6018bc1cda20960d4f1c7df7d401afd322656b4f0810348b8d20d506b08dd8752a0a721efa750b785fb2cb40930d33dd70bd8ad83883470851bd664c648da3f102545f1c54fa803cea5ba3edb51c3b894bd8fbd48d4ed97c251b3eed1d4e636d487a711d3859946acc14f808d777bcc3c5594ac2cd7dcf278ef4e7d3badea740f757a0669f213dadf46e9ff0eeb10720af086ce29e27e0ca2a639f4f3c5825ea5e2774bb3e722ce40e7cf6e2075857797c13d2d50203010001'; + $key = PublicKeyLoader::load(hex2bin($key)); + $this->assertInstanceOf(PublicKey::class, $key); + } }