From 90346f61bacf2c2e5867001d87f65e41ede9f651 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sat, 12 Sep 2020 20:54:37 +0200 Subject: [PATCH] Replace library/ASNValue.class.php with phpseclib functions --- library/ASNValue.class.php | 169 ---------------------------------- src/Util/Crypto.php | 63 ++----------- tests/src/Util/CryptoTest.php | 16 +++- 3 files changed, 22 insertions(+), 226 deletions(-) delete mode 100644 library/ASNValue.class.php diff --git a/library/ASNValue.class.php b/library/ASNValue.class.php deleted file mode 100644 index 7c17d10b40..0000000000 --- a/library/ASNValue.class.php +++ /dev/null @@ -1,169 +0,0 @@ -Tag = $Tag; - $this->Value = $Value; - } - - function Encode() - { - //Write type - $result = chr($this->Tag); - - //Write size - $size = strlen($this->Value); - if ($size < 127) { - //Write size as is - $result .= chr($size); - } - else { - //Prepare length sequence - $sizeBuf = self::IntToBin($size); - - //Write length sequence - $firstByte = 0x80 + strlen($sizeBuf); - $result .= chr($firstByte) . $sizeBuf; - } - - //Write value - $result .= $this->Value; - - return $result; - } - - function Decode(&$Buffer) - { - //Read type - $this->Tag = self::ReadByte($Buffer); - - //Read first byte - $firstByte = self::ReadByte($Buffer); - - if ($firstByte < 127) { - $size = $firstByte; - } - else if ($firstByte > 127) { - $sizeLen = $firstByte - 0x80; - //Read length sequence - $size = self::BinToInt(self::ReadBytes($Buffer, $sizeLen)); - } - else { - throw new Exception("Invalid ASN length value"); - } - - $this->Value = self::ReadBytes($Buffer, $size); - } - - protected static function ReadBytes(&$Buffer, $Length) - { - $result = substr($Buffer, 0, $Length); - $Buffer = substr($Buffer, $Length); - - return $result; - } - - protected static function ReadByte(&$Buffer) - { - return ord(self::ReadBytes($Buffer, 1)); - } - - protected static function BinToInt($Bin) - { - $len = strlen($Bin); - $result = 0; - for ($i=0; $i<$len; $i++) { - $curByte = self::ReadByte($Bin); - $result += $curByte << (($len-$i-1)*8); - } - - return $result; - } - - protected static function IntToBin($Int) - { - $result = ''; - do { - $curByte = $Int % 256; - $result .= chr($curByte); - - $Int = ($Int - $curByte) / 256; - } while ($Int > 0); - - $result = strrev($result); - - return $result; - } - - function SetIntBuffer($Value) - { - if (strlen($Value) > 1) { - $firstByte = ord($Value[0]); - if ($firstByte & 0x80) { //first bit set - $Value = chr(0x00) . $Value; - } - } - - $this->Value = $Value; - } - - function GetIntBuffer() - { - $result = $this->Value; - if (ord($result[0]) == 0x00) { - $result = substr($result, 1); - } - - return $result; - } - - function SetInt($Value) - { - $Value = self::IntToBin($Value); - - $this->SetIntBuffer($Value); - } - - function GetInt() - { - $result = $this->GetIntBuffer(); - $result = self::BinToInt($result); - - return $result; - } - - function SetSequence($Values) - { - $result = ''; - foreach ($Values as $item) { - $result .= $item->Encode(); - } - - $this->Value = $result; - } - - function GetSequence() - { - $result = array(); - $seq = $this->Value; - while (strlen($seq)) { - $val = new ASNValue(); - $val->Decode($seq); - $result[] = $val; - } - - return $result; - } -} diff --git a/src/Util/Crypto.php b/src/Util/Crypto.php index ab669823b5..0ff911ba79 100644 --- a/src/Util/Crypto.php +++ b/src/Util/Crypto.php @@ -21,12 +21,12 @@ namespace Friendica\Util; -use ASNValue; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\System; use Friendica\DI; use phpseclib\Crypt\RSA; +use phpseclib\Math\BigInteger; /** * Crypto class @@ -65,56 +65,6 @@ class Crypto } /** - * @param string $Der der formatted string - * @param bool $Private key type optional, default false - * @return string - */ - private static function DerToPem($Der, $Private = false) - { - //Encode: - $Der = base64_encode($Der); - //Split lines: - $lines = str_split($Der, 65); - $body = implode("\n", $lines); - //Get title: - $title = $Private ? 'RSA PRIVATE KEY' : 'PUBLIC KEY'; - //Add wrapping: - $result = "-----BEGIN {$title}-----\n"; - $result .= $body . "\n"; - $result .= "-----END {$title}-----\n"; - - return $result; - } - - /** - * @param string $Modulus modulo - * @param string $PublicExponent exponent - * @return string - */ - private static function pkcs8Encode($Modulus, $PublicExponent) - { - //Encode key sequence - $modulus = new ASNValue(ASNValue::TAG_INTEGER); - $modulus->SetIntBuffer($Modulus); - $publicExponent = new ASNValue(ASNValue::TAG_INTEGER); - $publicExponent->SetIntBuffer($PublicExponent); - $keySequenceItems = [$modulus, $publicExponent]; - $keySequence = new ASNValue(ASNValue::TAG_SEQUENCE); - $keySequence->SetSequence($keySequenceItems); - //Encode bit string - $bitStringValue = $keySequence->Encode(); - $bitStringValue = chr(0x00) . $bitStringValue; //Add unused bits byte - $bitString = new ASNValue(ASNValue::TAG_BITSTRING); - $bitString->Value = $bitStringValue; - //Encode body - $bodyValue = "\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00" . $bitString->Encode(); - $body = new ASNValue(ASNValue::TAG_SEQUENCE); - $body->Value = $bodyValue; - //Get DER encoded public key: - $PublicDER = $body->Encode(); - return $PublicDER; - } - /** * @param string $m modulo * @param string $e exponent @@ -122,9 +72,12 @@ class Crypto */ public static function meToPem($m, $e) { - $der = self::pkcs8Encode($m, $e); - $key = self::DerToPem($der, false); - return $key; + $rsa = new RSA(); + $rsa->loadKey([ + 'e' => new BigInteger($e, 256), + 'n' => new BigInteger($m, 256) + ]); + return $rsa->getPublicKey(); } /** @@ -151,7 +104,7 @@ class Crypto * * @return void */ - public static function pemToMe(string $key, string &$modulus, string &$exponent) + public static function pemToMe(string $key, &$modulus, &$exponent) { $publicKey = new RSA(); $publicKey->loadKey($key); diff --git a/tests/src/Util/CryptoTest.php b/tests/src/Util/CryptoTest.php index 51305337a9..73b3d5372e 100644 --- a/tests/src/Util/CryptoTest.php +++ b/tests/src/Util/CryptoTest.php @@ -73,7 +73,7 @@ class CryptoTest extends TestCase } - public function datePem() + public function dataPEM() { return [ 'diaspora' => [ @@ -83,7 +83,7 @@ class CryptoTest extends TestCase } /** - * @dataProvider datePem + * @dataProvider dataPEM */ public function testPemToMe(string $key) { @@ -97,6 +97,18 @@ class CryptoTest extends TestCase $this->assertEquals($expectedRSA->getPublicKey(), $key); } + + /** + * @dataProvider dataPEM + */ + public function testMeToPem(string $key) + { + Crypto::pemToMe($key, $m, $e); + + $checkKey = Crypto::meToPem($m, $e); + + $this->assertEquals($key, $checkKey); + } } /**