xref: /plugin/pureldap/vendor/freedsx/sasl/src/FreeDSx/Sasl/SaslBuffer.php (revision 0b3fd2d31e4d1997548a8fbc53fa771027c4a47f)
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