Example #1
0
 /**
  * Update statistics about the number of bytes
  * written to the client.
  *
  *  \param int $written
  *      Number of additional bytes written.
  *
  *  \return
  *      This method does not return anything.
  */
 public function updateWriteStats($written)
 {
     if (!is_int($written)) {
         throw new \InvalidArgumentException('Not an integer');
     }
     $time = time();
     $this->context['rekeyingBytes'] += $written;
     if (isset($this->context['rekeying'])) {
         // Do not restart key exchange
         // if already rekeying.
         return;
     }
     $logging = \Plop\Plop::getInstance();
     $stats = array('bytes' => $this->context['rekeyingBytes'], 'duration' => $time - $this->context['rekeyingTime'] + $this->rekeyingTime);
     $logging->debug('%(bytes)d bytes sent in %(duration)d seconds', $stats);
     if ($this->context['rekeyingBytes'] >= $this->rekeyingBytes || $time >= $this->context['rekeyingTime']) {
         $logging->debug('Initiating rekeying');
         $this->context['rekeying'] = 'server';
         $this->context['rekeyingBytes'] = 0;
         $this->context['rekeyingTime'] = $time + $this->rekeyingTime;
         $kexinit = new \fpoirotte\Pssht\Handlers\InitialState();
         $kexinit->handleKEXINIT($this, $this->context);
     }
 }
Example #2
0
 public function handle($msgType, \fpoirotte\Pssht\Wire\Decoder $decoder, \fpoirotte\Pssht\Transport $transport, array &$context)
 {
     $algos = \fpoirotte\Pssht\Algorithms::factory();
     $kex = \fpoirotte\Pssht\Messages\KEXINIT::unserialize($decoder);
     $context['kex']['client'] = $kex;
     if (!isset($context['rekeying'])) {
         $context['rekeying'] = 'client';
     }
     // KEX method
     $context['kexAlgo'] = null;
     foreach ($kex->getKEXAlgos() as $algo) {
         if ($algos->getClass('KEX', $algo) !== null) {
             $kexCls = $context['kexAlgo'] = $algos->getClass('KEX', $algo);
             break;
         }
     }
     // No suitable KEX algorithm found.
     if (!isset($context['kexAlgo'])) {
         throw new \RuntimeException();
     }
     $kexCls::addHandlers($transport);
     // C2S encryption
     $context['C2S']['Encryption'] = null;
     foreach ($kex->getC2SEncryptionAlgos() as $algo) {
         if ($algos->getClass('Encryption', $algo) !== null) {
             $context['C2S']['Encryption'] = $algos->getClass('Encryption', $algo);
             break;
         }
     }
     // No suitable C2S encryption cipher found.
     if (!isset($context['C2S']['Encryption'])) {
         throw new \RuntimeException();
     }
     // C2S compression
     $context['C2S']['Compression'] = null;
     foreach ($kex->getC2SCompressionAlgos() as $algo) {
         if ($algos->getClass('Compression', $algo) !== null) {
             $context['C2S']['Compression'] = $algos->getClass('Compression', $algo);
             break;
         }
     }
     // No suitable C2S compression found.
     if (!isset($context['C2S']['Compression'])) {
         throw new \RuntimeException();
     }
     // C2S MAC
     $context['C2S']['MAC'] = null;
     $reflector = new \ReflectionClass($context['C2S']['Encryption']);
     // Skip MAC algorithm selection for AEAD.
     if ($reflector->implementsInterface('\\fpoirotte\\Pssht\\AEADInterface')) {
         $context['C2S']['MAC'] = '\\fpoirotte\\Pssht\\MAC\\None';
     } else {
         foreach ($kex->getC2SMACAlgos() as $algo) {
             if ($algos->getClass('MAC', $algo) !== null) {
                 $context['C2S']['MAC'] = $algos->getClass('MAC', $algo);
                 break;
             }
         }
     }
     // No suitable C2S MAC found.
     if (!isset($context['C2S']['MAC'])) {
         throw new \RuntimeException();
     }
     // S2C encryption
     $context['S2C']['Encryption'] = null;
     foreach ($kex->getS2CEncryptionAlgos() as $algo) {
         if ($algos->getClass('Encryption', $algo) !== null) {
             $context['S2C']['Encryption'] = $algos->getClass('Encryption', $algo);
             break;
         }
     }
     // No suitable S2C encryption cipher found.
     if (!isset($context['S2C']['Encryption'])) {
         throw new \RuntimeException();
     }
     // S2C compression
     $context['S2C']['Compression'] = null;
     foreach ($kex->getS2CCompressionAlgos() as $algo) {
         if ($algos->getClass('Compression', $algo) !== null) {
             $context['S2C']['Compression'] = $algos->getClass('Compression', $algo);
             break;
         }
     }
     // No suitable S2C compression found.
     if (!isset($context['S2C']['Compression'])) {
         throw new \RuntimeException();
     }
     // S2C MAC
     $context['S2C']['MAC'] = null;
     $reflector = new \ReflectionClass($context['S2C']['Encryption']);
     // Skip MAC algorithm selection for AEAD.
     if ($reflector->implementsInterface('\\fpoirotte\\Pssht\\AEADInterface')) {
         $context['S2C']['MAC'] = '\\fpoirotte\\Pssht\\MAC\\None';
     } else {
         foreach ($kex->getS2CMACAlgos() as $algo) {
             if ($algos->getClass('MAC', $algo) !== null) {
                 $context['S2C']['MAC'] = $algos->getClass('MAC', $algo);
                 break;
             }
         }
     }
     // No suitable S2C MAC found.
     if (!isset($context['S2C']['MAC'])) {
         throw new \RuntimeException();
     }
     if ($context['rekeying'] === 'client') {
         $kexinit = new \fpoirotte\Pssht\Handlers\InitialState();
         return $kexinit->handleKEXINIT($transport, $context);
     }
     return true;
 }