From 0e874f1d2165f3c95944f5de65a77004643ce1d6 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 6 Apr 2019 13:34:33 -0500 Subject: [PATCH] SSH/Agent: use Strings::packSSH2() / Strings::unpackSSH2() --- phpseclib/System/SSH/Agent.php | 23 ++++++++++++---------- phpseclib/System/SSH/Agent/Identity.php | 26 ++++++++++++------------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/phpseclib/System/SSH/Agent.php b/phpseclib/System/SSH/Agent.php index 27faca82..38d92907 100644 --- a/phpseclib/System/SSH/Agent.php +++ b/phpseclib/System/SSH/Agent.php @@ -37,6 +37,7 @@ use ParagonIE\ConstantTime\Base64; use phpseclib\Crypt\RSA; use phpseclib\Exception\BadConfigurationException; use phpseclib\System\SSH\Agent\Identity; +use phpseclib\Common\Functions\Strings; /** * Pure-PHP ssh-agent client identity factory @@ -177,23 +178,25 @@ class Agent } $length = current(unpack('N', fread($this->fsock, 4))); - $type = ord(fread($this->fsock, 1)); + $packet = fread($this->fsock, $length); + if (strlen($packet) != $length) { + throw new \LengthException("Expected $length bytes; got " . strlen($packet)); + } + + list($type, $keyCount) = Strings::unpackSSH2('CN', $packet); if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) { throw new \RuntimeException('Unable to request identities'); } $identities = []; - $keyCount = current(unpack('N', fread($this->fsock, 4))); for ($i = 0; $i < $keyCount; $i++) { - $length = current(unpack('N', fread($this->fsock, 4))); - $key_blob = fread($this->fsock, $length); - $key_str = 'ssh-rsa ' . Base64::encode($key_blob); - $length = current(unpack('N', fread($this->fsock, 4))); - if ($length) { - $key_str.= ' ' . fread($this->fsock, $length); + list($key_blob, $comment) = Strings::unpackSSH2('ss', $packet); + $key_str = 'ssh-rsa ' . base64_encode($key_blob); + if (strlen($comment)) { + $key_str.= " $comment"; } - $length = current(unpack('N', substr($key_blob, 0, 4))); - $key_type = substr($key_blob, 4, $length); + $temp = $key_blob; + list($key_type) = Strings::unpackSSH2('s', $temp); switch ($key_type) { case 'ssh-rsa': $key = new RSA(); diff --git a/phpseclib/System/SSH/Agent/Identity.php b/phpseclib/System/SSH/Agent/Identity.php index 017073a4..7f35a821 100644 --- a/phpseclib/System/SSH/Agent/Identity.php +++ b/phpseclib/System/SSH/Agent/Identity.php @@ -182,29 +182,27 @@ class Identity } // the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE - $packet = pack('CNa*Na*N', Agent::SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, $this->flags); - $packet = pack('Na*', strlen($packet), $packet); + $packet = Strings::packSSH2( + 'CssN', + Agent::SSH_AGENTC_SIGN_REQUEST, + $this->key_blob, + $message, + $this->flags + ); + $packet = Strings::packSSH2('s', $packet); if (strlen($packet) != fputs($this->fsock, $packet)) { throw new \RuntimeException('Connection closed during signing'); } $length = current(unpack('N', fread($this->fsock, 4))); - $type = ord(fread($this->fsock, 1)); + $packet = fread($this->fsock, $length); + + list($type, $signature_blob) = Strings::unpackSSH2('Cs', $packet); if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) { throw new \RuntimeException('Unable to retrieve signature'); } - $signature_blob = fread($this->fsock, $length - 1); - $length = current(unpack('N', Strings::shift($signature_blob, 4))); - if ($length != strlen($signature_blob)) { - throw new \RuntimeException('Malformed signature blob'); - } - $length = current(unpack('N', Strings::shift($signature_blob, 4))); - if ($length > strlen($signature_blob) + 4) { - throw new \RuntimeException('Malformed signature blob'); - } - $type = Strings::shift($signature_blob, $length); - Strings::shift($signature_blob, 4); + list($type, $signature_blob) = Strings::unpackSSH2('ss', $signature_blob); return $signature_blob; }