pssht  latest
SSH server library written in PHP
REPLY.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 
13 
18 {
20  protected $H;
21 
23  protected $f;
24 
26  protected $K;
27 
29  protected $K_S;
30 
32  protected $kexDHInit;
33 
35  protected $kexAlgo;
36 
38  protected $serverKEX;
39 
41  protected $clientKEX;
42 
44  protected $serverIdent;
45 
47  protected $clientIdent;
48 
49 
77  public function __construct(
78  \fpoirotte\Pssht\Messages\KEXDH\INIT $kexDHInit,
79  \fpoirotte\Pssht\Key\KeyInterface $key,
80  \fpoirotte\Pssht\Encryption\EncryptionInterface $encryptionAlgo,
81  \fpoirotte\Pssht\KEX\KEXInterface $kexAlgo,
82  \fpoirotte\Pssht\Messages\KEXINIT $serverKEX,
83  \fpoirotte\Pssht\Messages\KEXINIT $clientKEX,
86  ) {
87  if (!is_string($serverIdent)) {
88  throw new \InvalidArgumentException();
89  }
90 
91  if (!is_string($clientIdent)) {
92  throw new \InvalidArgumentException();
93  }
94 
95  $keyLength = min(20, max($encryptionAlgo->getKeySize(), 16));
96  $randBytes = openssl_random_pseudo_bytes(2 * $keyLength);
97  $y = gmp_init(bin2hex($randBytes), 16);
98  $prime = gmp_init($kexAlgo::getPrime(), 16);
99  $this->f = gmp_powm($kexAlgo::getGenerator(), $y, $prime);
100  $this->K = gmp_powm($kexDHInit->getE(), $y, $prime);
101  $this->K_S = $key;
102  $this->kexDHInit = $kexDHInit;
103  $this->kexAlgo = $kexAlgo;
104  $this->serverKEX = $serverKEX;
105  $this->clientKEX = $clientKEX;
106  $this->serverIdent = $serverIdent;
107  $this->clientIdent = $clientIdent;
108 
109  $msgId = chr(\fpoirotte\Pssht\Messages\KEXINIT::getMessageId());
110  // $sub is used to create the structure for the hashing function.
111  $sub = new \fpoirotte\Pssht\Wire\Encoder(new \fpoirotte\Pssht\Buffer());
112  $this->K_S->serialize($sub);
113  $K_S = $sub->getBuffer()->get(0);
114  $sub->encodeString($this->clientIdent);
115  $sub->encodeString($this->serverIdent);
116  // $sub2 is used to compute the value
117  // of various fields inside the structure.
118  $sub2 = new \fpoirotte\Pssht\Wire\Encoder(new \fpoirotte\Pssht\Buffer());
119  $sub2->encodeBytes($msgId); // Add message identifier.
120  $this->clientKEX->serialize($sub2);
121  $sub->encodeString($sub2->getBuffer()->get(0));
122  $sub2->encodeBytes($msgId); // Add message identifier.
123  $this->serverKEX->serialize($sub2);
124  $sub->encodeString($sub2->getBuffer()->get(0));
125  $sub->encodeString($K_S);
126  $sub->encodeMpint($this->kexDHInit->getE());
127  $sub->encodeMpint($this->f);
128  $sub->encodeMpint($this->K);
129 
130  $logging = \Plop\Plop::getInstance();
131  $origData = $sub->getBuffer()->get(0);
132  $data = wordwrap(bin2hex($origData), 4, ' ', true);
133  $data = wordwrap($data, 32 + 7, PHP_EOL, true);
134  $logging->debug("Signature payload:\r\n%s", array($data));
135 
136  $this->H = $this->kexAlgo->hash($origData);
137  }
138 
139  public static function getMessageId()
140  {
141  return 31;
142  }
143 
144  public function serialize(\fpoirotte\Pssht\Wire\Encoder $encoder)
145  {
146  $sub = new \fpoirotte\Pssht\Wire\Encoder(new \fpoirotte\Pssht\Buffer());
147  $this->K_S->serialize($sub);
148 
149  $encoder->encodeString($sub->getBuffer()->get(0));
150  $encoder->encodeMpint($this->f);
151 
152  $sub->encodeString($this->K_S->getName());
153  $sub->encodeString($this->K_S->sign($this->H));
154  $encoder->encodeString($sub->getBuffer()->get(0));
155  return $this;
156  }
157 
158  public static function unserialize(\fpoirotte\Pssht\Wire\Decoder $decoder)
159  {
161  throw new \RuntimeException();
162  }
163 
171  public function getSharedSecret()
172  {
173  return $this->K;
174  }
175 
182  public function getExchangeHash()
183  {
184  return $this->H;
185  }
186 }
$clientKEX
Algorithms supported by the client.
Definition: REPLY.php:41
$kexDHInit
Client&#39;s contribution to the Diffie-Hellman Key Exchange.
Definition: REPLY.php:32
static unserialize(\fpoirotte\Pssht\Wire\Decoder $decoder)
Definition: REPLY.php:158
$clientIdent
Client&#39;s identification string.
Definition: REPLY.php:47
$K_S
Server&#39;s public host key.
Definition: REPLY.php:29
serialize(\fpoirotte\Pssht\Wire\Encoder $encoder)
Definition: REPLY.php:144
$f
Server&#39;s public exponent as a GMP resource.
Definition: REPLY.php:23
__construct(\fpoirotte\Pssht\Messages\KEXDH\INIT $kexDHInit,\fpoirotte\Pssht\Key\KeyInterface $key,\fpoirotte\Pssht\Encryption\EncryptionInterface $encryptionAlgo,\fpoirotte\Pssht\KEX\KEXInterface $kexAlgo,\fpoirotte\Pssht\Messages\KEXINIT $serverKEX,\fpoirotte\Pssht\Messages\KEXINIT $clientKEX, $serverIdent, $clientIdent)
Definition: REPLY.php:77
$kexAlgo
Key exchange algorithm to use.
Definition: REPLY.php:35
$serverKEX
Algorithms supported by the server.
Definition: REPLY.php:38
$serverIdent
Server&#39;s identification string.
Definition: REPLY.php:44