SSH/Agent: use Strings::packSSH2() / Strings::unpackSSH2()

This commit is contained in:
terrafrost 2019-04-06 13:34:33 -05:00
parent cee3f3cd4a
commit 0e874f1d21
2 changed files with 25 additions and 24 deletions

View File

@ -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();

View File

@ -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;
}