1*0b3fd2d3SAndreas Gohr<?php 2*0b3fd2d3SAndreas Gohr 3*0b3fd2d3SAndreas Gohr/** 4*0b3fd2d3SAndreas Gohr * This file is part of the FreeDSx SASL package. 5*0b3fd2d3SAndreas Gohr * 6*0b3fd2d3SAndreas Gohr * (c) Chad Sikorra <Chad.Sikorra@gmail.com> 7*0b3fd2d3SAndreas Gohr * 8*0b3fd2d3SAndreas Gohr * For the full copyright and license information, please view the LICENSE 9*0b3fd2d3SAndreas Gohr * file that was distributed with this source code. 10*0b3fd2d3SAndreas Gohr */ 11*0b3fd2d3SAndreas Gohr 12*0b3fd2d3SAndreas Gohrnamespace FreeDSx\Sasl; 13*0b3fd2d3SAndreas Gohr 14*0b3fd2d3SAndreas Gohruse FreeDSx\Sasl\Exception\SaslBufferException; 15*0b3fd2d3SAndreas Gohruse FreeDSx\Sasl\Exception\SaslException; 16*0b3fd2d3SAndreas Gohr 17*0b3fd2d3SAndreas Gohr/** 18*0b3fd2d3SAndreas Gohr * Helper functions to decode a SASL buffer when a security layer is installed. These can be used when receiving data 19*0b3fd2d3SAndreas Gohr * over the wire with a SASL security layer to determine whether or not the buffer is complete, and then unwrap the data. 20*0b3fd2d3SAndreas Gohr * 21*0b3fd2d3SAndreas Gohr * @author Chad Sikorra <Chad.Sikorra@gmail.com> 22*0b3fd2d3SAndreas Gohr */ 23*0b3fd2d3SAndreas Gohrclass SaslBuffer 24*0b3fd2d3SAndreas Gohr{ 25*0b3fd2d3SAndreas Gohr /** 26*0b3fd2d3SAndreas Gohr * Wraps the buffer by pre-pending the data length. 27*0b3fd2d3SAndreas Gohr */ 28*0b3fd2d3SAndreas Gohr public static function wrap(string $data): string 29*0b3fd2d3SAndreas Gohr { 30*0b3fd2d3SAndreas Gohr return pack('N1', strlen($data)) . $data; 31*0b3fd2d3SAndreas Gohr } 32*0b3fd2d3SAndreas Gohr 33*0b3fd2d3SAndreas Gohr /** 34*0b3fd2d3SAndreas Gohr * Unwrap the buffer by removing pre-pended length and verifying we have enough data. Only the data is returned. 35*0b3fd2d3SAndreas Gohr * 36*0b3fd2d3SAndreas Gohr * @throws SaslBufferException 37*0b3fd2d3SAndreas Gohr * @throws SaslException 38*0b3fd2d3SAndreas Gohr */ 39*0b3fd2d3SAndreas Gohr public static function unwrap(string $data): string 40*0b3fd2d3SAndreas Gohr { 41*0b3fd2d3SAndreas Gohr $length = strlen($data); 42*0b3fd2d3SAndreas Gohr if ($length < 4) { 43*0b3fd2d3SAndreas Gohr throw new SaslBufferException('Not enough data to unwrap the SASL buffer.'); 44*0b3fd2d3SAndreas Gohr } 45*0b3fd2d3SAndreas Gohr $dataLength = $length - 4; 46*0b3fd2d3SAndreas Gohr $bufferLength = hexdec(bin2hex(substr($data, 0, 4))); 47*0b3fd2d3SAndreas Gohr if (!is_int($bufferLength)) { 48*0b3fd2d3SAndreas Gohr throw new SaslException('The buffer length exceeds the maximum allowed.'); 49*0b3fd2d3SAndreas Gohr } 50*0b3fd2d3SAndreas Gohr if ($dataLength < $bufferLength) { 51*0b3fd2d3SAndreas Gohr throw new SaslBufferException('The SASL buffer is incomplete.'); 52*0b3fd2d3SAndreas Gohr } 53*0b3fd2d3SAndreas Gohr 54*0b3fd2d3SAndreas Gohr return substr($data, 4, $bufferLength); 55*0b3fd2d3SAndreas Gohr } 56*0b3fd2d3SAndreas Gohr} 57