pssht  latest
SSH server library written in PHP
Decoder.php
1 <?php
2 
3 /*
4 * This file is part of pssht.
5 *
6 * (c) François Poirotte <clicky@erebot.net>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11 
12 namespace fpoirotte\Pssht\Wire;
13 
17 class Decoder
18 {
20  protected $buffer;
21 
29  public function __construct(\fpoirotte\Pssht\Buffer $buffer = null)
30  {
31  if ($buffer === null) {
32  $buffer = new \fpoirotte\Pssht\Buffer();
33  }
34 
35  $this->buffer = $buffer;
36  }
37 
44  public function getBuffer()
45  {
46  return $this->buffer;
47  }
48 
62  public function decodeBytes($count = 1)
63  {
64  if (!is_int($count) || $count < 0) {
65  throw new \InvalidArgumentException();
66  }
67 
68  if (!$count) {
69  return '';
70  }
71 
72  return $this->buffer->get($count);
73  }
74 
84  public function decodeBoolean()
85  {
86  $value = $this->decodeBytes();
87  if ($value === null) {
88  return null;
89  }
90  return ($value !== "\0");
91  }
92 
102  public function decodeUint32()
103  {
104  $value = $this->decodeBytes(4);
105  if ($value === null) {
106  return null;
107  }
108  $res = unpack('N', $value);
109  return array_pop($res);
110  }
111 
122  public function decodeUint64()
123  {
124  $value = $this->decodeBytes(8);
125  if ($value === null) {
126  return null;
127  }
128  return gmp_init(bin2hex($value), 16);
129  }
130 
140  public function decodeString()
141  {
142  $len = $this->decodeUint32();
143  if ($len === null) {
144  return null;
145  }
146  $value = $this->decodeBytes($len);
147  if ($value === null) {
148  $this->buffer->unget(pack('N', $len));
149  return null;
150  }
151  return $value;
152  }
153 
164  public function decodeMpint()
165  {
166  $s = $this->decodeString();
167  if ($s === null) {
168  return null;
169  }
170 
171  if ($s === '') {
172  return gmp_init(0);
173  }
174 
175  $n = gmp_init(bin2hex($s), 16);
176 
177  // Negative numbers: decode using two-complement.
178  if (ord($s[0]) & 0x80) {
179  // gmp_com() uses the number's size to compute
180  // the complement, which is right in our case.
181  $n = gmp_neg(gmp_add(gmp_com($n), "1"));
182  }
183  return $n;
184  }
185 
203  public function decodeNameList($validationCallback = null)
204  {
205  $s = $this->decodeString();
206  if ($s === null) {
207  return null;
208  }
209 
210  // Empty list.
211  if ($s === '') {
212  $l = array();
213  } else {
214  // All the names in the list MUST be in US-ASCII.
215  if (addcslashes($s, "\x80..\xFF") !== $s) {
216  throw new \InvalidArgumentException();
217  }
218 
219  // The names in the list MUST NOT be empty.
220  if ($s[0] === ',' || substr($s, -1) === ',' ||
221  strpos($s, ',,') !== false) {
222  throw new \InvalidArgumentException();
223  }
224 
225  $l = explode(',', $s);
226  }
227 
228  if ($validationCallback !== null) {
229  call_user_func($validationCallback, $l);
230  }
231  return $l;
232  }
233 }
__construct(\fpoirotte\Pssht\Buffer $buffer=null)
Definition: Decoder.php:29
$buffer
Buffer the encoded values are read from.
Definition: Decoder.php:20
decodeNameList($validationCallback=null)
Definition: Decoder.php:203