diff options
Diffstat (limited to 'vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php')
-rw-r--r-- | vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php index 122d281a8..fec689585 100644 --- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php +++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php @@ -570,6 +570,7 @@ class RSA $publickey = call_user_func_array(array($this, '_convertPublicKey'), array_values($this->_parseKey($publickey, self::PUBLIC_FORMAT_PKCS1))); // clear the buffer of error strings stemming from a minimalistic openssl.cnf + // https://github.com/php/php-src/issues/11054 talks about other errors this'll pick up while (openssl_error_string() !== false) { } @@ -1388,6 +1389,10 @@ class RSA // http://en.wikipedia.org/wiki/XML_Signature case self::PRIVATE_FORMAT_XML: case self::PUBLIC_FORMAT_XML: + if (!extension_loaded('xml')) { + return false; + } + $this->components = array(); $xml = xml_parser_create('UTF-8'); @@ -1522,14 +1527,44 @@ class RSA if ($magic !== "openssh-key-v1\0") { return false; } - $options = $this->_string_shift($decoded, 24); - // \0\0\0\4none = ciphername - // \0\0\0\4none = kdfname - // \0\0\0\0 = kdfoptions - // \0\0\0\1 = numkeys - if ($options != "\0\0\0\4none\0\0\0\4none\0\0\0\0\0\0\0\1") { + extract(unpack('Nlength', $this->_string_shift($decoded, 4))); + if (strlen($decoded) < $length) { + return false; + } + $ciphername = $this->_string_shift($decoded, $length); + extract(unpack('Nlength', $this->_string_shift($decoded, 4))); + if (strlen($decoded) < $length) { return false; } + $kdfname = $this->_string_shift($decoded, $length); + extract(unpack('Nlength', $this->_string_shift($decoded, 4))); + if (strlen($decoded) < $length) { + return false; + } + $kdfoptions = $this->_string_shift($decoded, $length); + extract(unpack('Nnumkeys', $this->_string_shift($decoded, 4))); + if ($numkeys != 1 || ($ciphername != 'none' && $kdfname != 'bcrypt')) { + return false; + } + switch ($ciphername) { + case 'none': + break; + case 'aes256-ctr': + extract(unpack('Nlength', $this->_string_shift($kdfoptions, 4))); + if (strlen($kdfoptions) < $length) { + return false; + } + $salt = $this->_string_shift($kdfoptions, $length); + extract(unpack('Nrounds', $this->_string_shift($kdfoptions, 4))); + $crypto = new AES(AES::MODE_CTR); + $crypto->disablePadding(); + if (!$crypto->setPassword($this->password, 'bcrypt', $salt, $rounds, 32)) { + return false; + } + break; + default: + return false; + } extract(unpack('Nlength', $this->_string_shift($decoded, 4))); if (strlen($decoded) < $length) { return false; @@ -1539,12 +1574,16 @@ class RSA if (strlen($decoded) < $length) { return false; } - $paddedKey = $this->_string_shift($decoded, $length); if ($this->_string_shift($publicKey, 11) !== "\0\0\0\7ssh-rsa") { return false; } + $paddedKey = $this->_string_shift($decoded, $length); + if (isset($crypto)) { + $paddedKey = $crypto->decrypt($paddedKey); + } + $checkint1 = $this->_string_shift($paddedKey, 4); $checkint2 = $this->_string_shift($paddedKey, 4); if (strlen($checkint1) != 4 || $checkint1 !== $checkint2) { |