pssht  latest
SSH server library written in PHP
NEWKEYS.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\Handlers;
13 
15 
20 {
21  // SSH_MSG_NEWKEYS = 21
22  public function handle(
23  $msgType,
24  \fpoirotte\Pssht\Wire\Decoder $decoder,
25  \fpoirotte\Pssht\Transport $transport,
26  array &$context
27  ) {
28  unset($context['rekeying']);
29  $response = new \fpoirotte\Pssht\Messages\NEWKEYS();
30  $transport->writeMessage($response);
31  $logging = \Plop\Plop::getInstance();
32 
33  // Reset the various keys.
34  $kexAlgo = $context['kexAlgo'];
35  $kexAlgo = new $kexAlgo();
36  $encoder = new \fpoirotte\Pssht\Wire\Encoder();
37  $encoder->encodeMpint($context['DH']->getSharedSecret());
38  $sharedSecret = $encoder->getBuffer()->get(0);
39  $exchangeHash = $context['DH']->getExchangeHash();
40  $sessionId = $context['sessionIdentifier'];
41  $limiters = array(
42  'A' => array($context['C2S']['Encryption'], 'getIVSize'),
43  'B' => array($context['S2C']['Encryption'], 'getIVSize'),
44  'C' => array($context['C2S']['Encryption'], 'getKeySize'),
45  'D' => array($context['S2C']['Encryption'], 'getKeySize'),
46  'E' => array($context['C2S']['MAC'], 'getKeySize'),
47  'F' => array($context['C2S']['MAC'], 'getKeySize'),
48  );
49 
50  $shared = gmp_strval($context['DH']->getSharedSecret(), 16);
51  $shared = str_pad($shared, ((strlen($shared) + 1) >> 1) << 1, '0', STR_PAD_LEFT);
52  $logging->debug('Key exchange: %s', array($context['kexAlgo']));
53  $logging->debug(
54  'Shared secret: %s',
55  array(wordwrap($shared, 16, ' ', true))
56  );
57  $logging->debug(
58  'Hash: %s',
59  array(wordwrap(bin2hex($exchangeHash), 16, ' ', true))
60  );
61 
62  foreach (array('A', 'B', 'C', 'D', 'E', 'F') as $keyIndex) {
63  $key = $kexAlgo->hash($sharedSecret . $exchangeHash . $keyIndex . $sessionId);
64  $limit = call_user_func($limiters[$keyIndex]);
65  while (strlen($key) < $limit) {
66  $key .= $kexAlgo->hash($sharedSecret . $exchangeHash . $key);
67  }
68  $key = (string) substr($key, 0, $limit);
69  $context['keys'][$keyIndex] = $key;
70  $logging->debug(
71  'Key %(keyName)s: %(keyValue)s',
72  array(
73  'keyName' => $keyIndex,
74  'keyValue' => wordwrap(bin2hex($key), 16, ' ', true),
75  )
76  );
77  }
78 
79  // Encryption
80  $cls = $context['C2S']['Encryption'];
81  $transport->setDecryptor(
82  new $cls($context['keys']['A'], $context['keys']['C'])
83  );
84  $logging->debug('C2S Encryption: %s', array($cls));
85 
86  $cls = $context['S2C']['Encryption'];
87  $transport->setEncryptor(
88  new $cls($context['keys']['B'], $context['keys']['D'])
89  );
90  $logging->debug('S2C Encryption: %s', array($cls));
91 
92  // MAC
93  $cls = $context['C2S']['MAC'];
94  $transport->setInputMAC(new $cls($context['keys']['E']));
95  $logging->debug('C2S MAC: %s', array($cls));
96 
97  $cls = $context['S2C']['MAC'];
98  $transport->setOutputMAC(new $cls($context['keys']['F']));
99  $logging->debug('S2C MAC: %s', array($cls));
100 
101  // Compression
102  $cls = $context['C2S']['Compression'];
103  $transport->setUncompressor(
105  );
106  $logging->debug('C2S Compression: %s', array($cls));
107 
108  $cls = $context['S2C']['Compression'];
109  $transport->setCompressor(
111  );
112  $logging->debug('S2C Compression: %s', array($cls));
113 
114  return true;
115  }
116 }
const MODE_COMPRESS
Use the algorithm for compression.
handle($msgType,\fpoirotte\Pssht\Wire\Decoder $decoder,\fpoirotte\Pssht\Transport $transport, array &$context)
Definition: NEWKEYS.php:22
const MODE_UNCOMPRESS
Use the algorithm for decompression.