Сертификат X.509 содержит данные в нескольких разделах (называемых триплетами Tag-Length-Value).Каждый раздел начинается с байта тега, который указывает формат данных раздела.Вы можете увидеть список этих типов данных здесь .
0x03 - это байт тега для типа данных BIT STRING и 0x30 - это байт тега для типа данных SEQUENCE .
Таким образом, этот код предназначен для обработки типов данных BIT STRING и SEQUENCE.Если вы посмотрите на эту часть:
if($seq == 0x03)
{
return substr($bin,3 + $bytes, $len);
}
else // $seq == 0x30
{
$bin = substr($bin,2 + $bytes + $len);
}
, вы увидите, что функция предназначена для пропуска последовательностей (0x30) до тех пор, пока не найдет битовую строку (0x03), после чего она возвращает значениебитовая строка.
Возможно, вам интересно, почему магическое число составляет 3 для Битовая строка и 2 для Последовательность .Это связано с тем, что в Bit String первый байт значения является специальным дополнительным полем, которое указывает, сколько битов не используется в последнем байте данных.(Например, если вы отправляете 13 бит данных, это займет 2 байта = 16 бит, а поле « неиспользуемые биты » будет равно 3.)
Следующая проблема: поле длины.Когда длина значения меньше 128 байтов, длина просто указывается с использованием одного байта (самый старший бит будет равен 0).Если длина составляет 128 или больше, то первый байт длины имеет установленный бит 7, а оставшиеся 7 битов указывают, сколько следующих байтов содержат длину (в порядке с прямым порядком байтов).Больше описания здесь .Синтаксический анализ поля длины происходит в этом разделе кода:
$len = ord($bin[1]);
$bytes = 0;
if ($len & 0x80)
{
// length is greater than 127!
$bytes = ($len & 0x0f);
$len = 0;
for ($i = 0; $i < $bytes; $i++)
{
$len = ($len << 8) | ord($bin[$i + 2]);
}
}
После этого $bytes
содержит количество дополнительных байтов, используемых полем длины, а $len
содержит длинуПоле значения (в байтах).
Вы обнаружили ошибку в коде?Помните,
Если длина равна 128 или больше, то для первого байта длины установлен бит 7, а оставшиеся 7 битов указывают, сколько следующих байтов содержат длину.
, но код говорит $bytes = ($len & 0x0f)
, что занимает только младшие 4 бита байта!Должно быть:
$bytes = ($len & 0x7f);
Конечно, эта ошибка является проблемой только для длинных сообщений чрезвычайно : она будет работать нормально, пока значение длины будет соответствовать 0x0f = 15 байт.Это означает, что данные должны быть не более 256 ^ 15 байт.Это примерно триллион йотбайт, что должно быть достаточно для всех.