pssht  latest
SSH server library written in PHP
KEXINIT.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 
18 {
19  // SSH_MSG_KEXINIT = 20
20  public function handle(
21  $msgType,
22  \fpoirotte\Pssht\Wire\Decoder $decoder,
23  \fpoirotte\Pssht\Transport $transport,
24  array &$context
25  ) {
28  $context['kex']['client'] = $kex;
29 
30  if (!isset($context['rekeying'])) {
31  $context['rekeying'] = 'client';
32  }
33 
34  // KEX method
35  $context['kexAlgo'] = null;
36  foreach ($kex->getKEXAlgos() as $algo) {
37  if ($algos->getClass('KEX', $algo) !== null) {
38  $kexCls = $context['kexAlgo'] = $algos->getClass('KEX', $algo);
39  break;
40  }
41  }
42  // No suitable KEX algorithm found.
43  if (!isset($context['kexAlgo'])) {
44  throw new \RuntimeException();
45  }
46  $kexCls::addHandlers($transport);
47 
48  // C2S encryption
49  $context['C2S']['Encryption'] = null;
50  foreach ($kex->getC2SEncryptionAlgos() as $algo) {
51  if ($algos->getClass('Encryption', $algo) !== null) {
52  $context['C2S']['Encryption'] = $algos->getClass('Encryption', $algo);
53  break;
54  }
55  }
56  // No suitable C2S encryption cipher found.
57  if (!isset($context['C2S']['Encryption'])) {
58  throw new \RuntimeException();
59  }
60 
61  // C2S compression
62  $context['C2S']['Compression'] = null;
63  foreach ($kex->getC2SCompressionAlgos() as $algo) {
64  if ($algos->getClass('Compression', $algo) !== null) {
65  $context['C2S']['Compression'] = $algos->getClass('Compression', $algo);
66  break;
67  }
68  }
69  // No suitable C2S compression found.
70  if (!isset($context['C2S']['Compression'])) {
71  throw new \RuntimeException();
72  }
73 
74  // C2S MAC
75  $context['C2S']['MAC'] = null;
76  $reflector = new \ReflectionClass($context['C2S']['Encryption']);
77  // Skip MAC algorithm selection for AEAD.
78  if ($reflector->implementsInterface('\\fpoirotte\\Pssht\\Algorithms\\AEAD\\AEADInterface')) {
79  $context['C2S']['MAC'] = '\\fpoirotte\\Pssht\\MAC\\None';
80  } else {
81  foreach ($kex->getC2SMACAlgos() as $algo) {
82  if ($algos->getClass('MAC', $algo) !== null) {
83  $context['C2S']['MAC'] = $algos->getClass('MAC', $algo);
84  break;
85  }
86  }
87  }
88  // No suitable C2S MAC found.
89  if (!isset($context['C2S']['MAC'])) {
90  throw new \RuntimeException();
91  }
92 
93  // S2C encryption
94  $context['S2C']['Encryption'] = null;
95  foreach ($kex->getS2CEncryptionAlgos() as $algo) {
96  if ($algos->getClass('Encryption', $algo) !== null) {
97  $context['S2C']['Encryption'] = $algos->getClass('Encryption', $algo);
98  break;
99  }
100  }
101  // No suitable S2C encryption cipher found.
102  if (!isset($context['S2C']['Encryption'])) {
103  throw new \RuntimeException();
104  }
105 
106  // S2C compression
107  $context['S2C']['Compression'] = null;
108  foreach ($kex->getS2CCompressionAlgos() as $algo) {
109  if ($algos->getClass('Compression', $algo) !== null) {
110  $context['S2C']['Compression'] = $algos->getClass('Compression', $algo);
111  break;
112  }
113  }
114  // No suitable S2C compression found.
115  if (!isset($context['S2C']['Compression'])) {
116  throw new \RuntimeException();
117  }
118 
119  // S2C MAC
120  $context['S2C']['MAC'] = null;
121  $reflector = new \ReflectionClass($context['S2C']['Encryption']);
122  // Skip MAC algorithm selection for AEAD.
123  if ($reflector->implementsInterface('\\fpoirotte\\Pssht\\Algorithms\\AEAD\\AEADInterface')) {
124  $context['S2C']['MAC'] = '\\fpoirotte\\Pssht\\MAC\\None';
125  } else {
126  foreach ($kex->getS2CMACAlgos() as $algo) {
127  if ($algos->getClass('MAC', $algo) !== null) {
128  $context['S2C']['MAC'] = $algos->getClass('MAC', $algo);
129  break;
130  }
131  }
132  }
133  // No suitable S2C MAC found.
134  if (!isset($context['S2C']['MAC'])) {
135  throw new \RuntimeException();
136  }
137 
138  if ($context['rekeying'] === 'client') {
139  $kexinit = new \fpoirotte\Pssht\Handlers\InitialState();
140  return $kexinit->handleKEXINIT($transport, $context);
141  }
142 
143  return true;
144  }
145 }
static unserialize(\fpoirotte\Pssht\Wire\Decoder $decoder)
Definition: KEXINIT.php:161
handle($msgType,\fpoirotte\Pssht\Wire\Decoder $decoder,\fpoirotte\Pssht\Transport $transport, array &$context)
Definition: KEXINIT.php:20