BoringSSL — это производная от OpenSSL, в основном совместимая на уровне исходного кода для поддерживаемого подмножества OpenSSL. Библиотеки в идеале требуют минимальных изменений или вообще не требуют их для поддержки BoringSSL при условии, что они не используют удалённые API. В общем случае проверьте, компилируется ли библиотека, и в случае неудачи обратитесь к документации в заголовочных файлах и посмотрите, можно ли удалить проблемные функции.
Значение OPENSSL_VERSION_NUMBER
в BoringSSL соответствует версии OpenSSL, на которую он ориентирован. Проверки версий для OpenSSL в идеале должны работать как есть в BoringSSL. BoringSSL также определяет макросы функций OPENSSL_NO_*
восходящего потока, соответствующие удалённым функциям. Если необходим препроцессор, используйте эти проверки версий или макросы функций там, где это возможно, особенно при исправлении сторонних проектов. Такие исправления более полезны для пользователей OpenSSL и поэтому более подходят для отправки восходящему потоку.
В некоторых случаях может потребоваться специфичный для BoringSSL код. Используйте препроцессорный макрос OPENSSL_IS_BORINGSSL
в #ifdef
. Однако сначала свяжитесь с сопровождающими BoringSSL по поводу отсутствующих API. Мы обычно добавляем функции совместимости для удобства. В частности, свяжитесь с сопровождающими BoringSSL перед тем, как обойти отсутствующие аксессоры OpenSSL 1.1.0. BoringSSL изначально был получен из OpenSSL 1.0.2, но теперь ориентирован на OpenSSL 1.1.0. Некоторые более новые API могут отсутствовать, но могут быть добавлены по запросу. (Не все проекты были перенесены на OpenSSL 1.1.0, поэтому BoringSSL также остаётся в значительной степени совместимым с OpenSSL 1.0.2.)
Макрос OPENSSL_IS_BORINGSSL
также можно использовать для различения OpenSSL и BoringSSL в сценариях настройки. Не используйте наличие или отсутствие определённых символов для обнаружения BoringSSL.
Примечание: BoringSSL не имеет стабильного API или ABI. Он должен обновляться вместе со своими потребителями. Он не подходит, скажем, для системной библиотеки в традиционном дистрибутиве Linux. Например, Chromium статически связывает конкретную версию BoringSSL, против которой он был собран. Аналогично, внутренняя копия BoringSSL для Android не предоставляется NDK и не должна использоваться сторонними приложениями.
Некоторые API были преобразованы для использования size_t
для согласованности и во избежание переполнения целых чисел на границе API. (Существующая логика использует смесь int
, long
и unsigned
). По большей части неявные приведения означают, что существующий код продолжает компилироваться. В некоторых случаях это может потребовать специфичного для BoringSSL кода, особенно для того, чтобы избежать предупреждений компилятора.
Прежде всего, все типы STACK_OF(T)
были преобразованы в использование size_t
вместо int
для индексов и длин.
Некоторые внешние потребители увеличивают счётчики ссылок напрямую, вызывая CRYPTO_add
с соответствующим значением CRYPTO_LOCK_*
. Эти API больше не существуют в BoringSSL. Вместо этого код, который увеличивает счётчики ссылок, должен вызывать соответствующую функцию FOO_up_ref
, такую как EVP_PKEY_up_ref
.
BoringSSL также скрывает некоторые структуры, которые ранее были открыты в OpenSSL 1.0.2, особенно в libssl. Вместо них следует использовать соответствующие аксессоры.
Обратите внимание, что некоторые из этих API были добавлены в OpenSSL 1.1.0, так что проектам, которые ещё не поддерживают 1.1.0, могут потребоваться дополнительные #ifdef
. Проекты, поддерживающие OpenSSL 1.1.0, не должны требовать модификации.
Ошибки OpenSSL чрезвычайно специфичны, раскрывая внутреннюю информацию библиотеки, включая даже код функции для функции, которая выдала ошибку! Поскольку некоторая логика в BoringSSL была переписана, код, основанный на ошибке, может сломаться (ищите ERR_GET_REASON
и ERR_GET_FUNC
). Эта опасность также существует при обновлении версий OpenSSL.
По возможности избегайте условий на точную причину ошибки. В противном случае может потребоваться #ifdef
BoringSSL. Как лучше всего решить эту проблему, всё ещё определяется. Возможно, в будущем будут добавлены некоторые новые API.
Коды функций были полностью удалены. Удалите код, зависящий от них, поскольку он сломается при малейшем изменении в библиотеке, OpenSSL или BoringSSL.
_ctrl
Некоторые... API OpenSSL реализованы с помощью функций в стиле ioctl, таких как SSL_ctrl и EVP_PKEY_CTX_ctrl, в сочетании с удобными макросами, такими как:
# define SSL_CTX_set_mode(ctx,op) \
SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
В BoringSSL эти макросы были заменены соответствующими функциями. Вспомогательные функции _ctrl были удалены.
Для удобства значения SSL_CTRL_* сохраняются в виде макросов для doesn't_exist, чтобы существующий код, который использует их (или макросы-обёртки) в выражениях #ifdef, продолжал работать. Однако сами макросы не будут работать.
Замените любые вызовы *_ctrl на версии макросов/функций. Это работает как в OpenSSL, так и в BoringSSL. Обратите внимание, что версии функций BoringSSL будут проверяться на тип и могут потребовать большей осторожности с типами. См. конец этого документа для таблицы используемых функций.
EVP_PKEY_HMAC удалён. Вместо этого используйте функции HMAC_* в hmac.h. Это совместимо с OpenSSL.
EVP_PKEY_DSA устарел. На данный момент всё ещё возможно анализировать DER в DSA EVP_PKEY, но подписывать или проверять с этими объектами не получится.
Тип DES_cblock был переключён с массива на структуру, чтобы избежать подводных камней, связанных с массивами в C. Там, где функции, требующие DES, не могут быть отключены, могут потребоваться специфические пути кода BoringSSL.
OpenSSL по умолчанию включает повторное согласование TLS и прозрачно принимает запросы повторного согласования от однорангового узла. Повторное согласование — чрезвычайно проблемная функция протокола, поэтому BoringSSL по умолчанию отклоняет повторные согласования одноранговых узлов.
Чтобы включить повторное согласование, вызовите SSL_set_renegotiate_mode и установите его в ssl_renegotiate_once или ssl_renegotiate_freely. Повторное согласование поддерживается только в качестве клиента в TLS, и HelloRequest должен быть получен в спокойной точке протокола прикладного уровня. Этого достаточно для поддержки общего использования запроса нового сертификата клиента между HTTP-запросом и ответом в (не конвейерном) HTTP/1.1.
Что не работает:
Нет поддержки повторного согласования в качестве сервера. (Попытки клиентов приведут к фатальному предупреждению, чтобы сообщения ClientHello нельзя было использовать для переполнения сервера и выхода за пределы более высоких уровней.)
Нет поддержки повторного согласования в DTLS.
Нет поддержки инициирования повторного согласования; SSL_renegotiate всегда завершается ошибкой, а SSL_set_state ничего не делает.
Смешивание данных приложения с новым рукопожатием запрещено.
Если HelloRequest получен, пока SSL_write имеет неотправленные данные приложения, повторное согласование отклоняется.
Повторное согласование не участвует в возобновлении сеанса. Клиент не будет предлагать сеанс при повторном согласовании или возобновлять любой сеанс, установленный посредством рукопожатия повторного согласования.
Сервер может не менять свой сертификат при повторном согласовании. Это смягчает атаку тройного рукопожатия. Любой новый прикреплённый ответ OCSP и список SCT будут проигнорированы. Поскольку состояние аутентификации не может измениться, BoringSSL не будет повторно проверять сертификат при повторном согласовании. Обратные вызовы, такие как SSL_CTX_set_custom_verify, будут выполняться только при первоначальном рукопожатии.
Функция BoringSSL BN_bn2hex использует шестнадцатеричные цифры нижнего регистра вместо верхнего. Некоторый код может потребовать изменений, чтобы не зависеть от этой разницы.
Стек ASN.1 OpenSSL использует функции d2i для анализа. Они имеют форму:
RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len);
Помимо возврата результата, OpenSSL помещает его в *out, если *out не равно NULL. При вводе, если *out не равен NULL, OpenSSL обычно (но не всегда) повторно использует этот объект, а не выделяет новый. В BoringSSL эти функции являются совместимыми оболочками поверх более нового стека ASN.1. Даже если *out не равен NULL, эти оболочки всегда будут выделять новый объект и освобождать предыдущий.
Убедитесь, что вызывающие объекты не полагаются на это поведение объекта. Рекомендуется избегать out. Параметр всегда должен передаваться как NULL.
Обратите внимание, что существуют менее подверженные ошибкам API для специфичного кода BoringSSL (см. ниже).
OpenSSL предоставляет оболочки OPENSSL_malloc и OPENSSL_free поверх стандартных malloc и free. Память, выделенная OpenSSL, должна освобождаться с помощью OPENSSL_free, а не стандартного free. Однако по умолчанию они реализованы напрямую с использованием malloc и free, поэтому код, который их смешивает, обычно работает.
В BoringSSL эти функции поддерживают дополнительную бухгалтерию для обнуления памяти при OPENSSL_free, поэтому любые ошибки должны быть исправлены.
BoringSSL вносит некоторые изменения в OpenSSL, которые упрощают API, но остаются совместимыми с потребителями OpenSSL. В целом, обратитесь к документации BoringSSL для любых функций в новом коде, предназначенном только для BoringSSL.
Большинство API-интерфейсов OpenSSL возвращают 1 при успешном выполнении и либо 0, либо -1 при ошибке. BoringSSL сузил большинство из них до 1 при успехе и 0 при неудаче. Код, специфичный для BoringSSL, может воспользоваться менее подверженными ошибкам API и использовать ! для проверки ошибок.
У OpenSSL есть несколько различных функций инициализации для настройки строк ошибок и загрузки алгоритмов и т. д. Все эти функции всё ещё существуют в BoringSSL для удобства, но они ничего не делают и не нужны.
Единственным исключением является CRYPTO_library_init. В сборках BORINGSSL_NO_STATIC_INITIALIZER он должен вызываться для запроса возможностей ЦП перед остальной частью библиотеки. В конфигурации по умолчанию это делается с помощью статического инициализатора и также не требуется.
OpenSSL предоставляет ряд API для настройки обратных вызовов потоков и установки блокировок. Без их инициализации библиотека не является потокобезопасной. Настройка этих параметров в BoringSSL ничего не делает. Вместо этого BoringSSL внутренне вызывает pthreads и соответствующие Windows API и всегда является потокобезопасным там, где это гарантирует API.
BoringSSL находится в процессе отказа от d2i и i2d OpenSSL в пользу новых функций, использующих гораздо менее подверженные ошибкам типы CBS и CBB. Код, предназначенный только для BoringSSL, должен использовать эти функции там, где они доступны.
Замены для значений CTRL
При переносе кода, использующего SSL_CTX_ctrl или SSL_ctrl, используйте указанные ниже функции замены. Если у функции есть варианты SSL_CTX и SSL, то указан только вариант SSL_CTX.
Обратите внимание: некоторые значения соответствуют нескольким функциям в зависимости от параметра larg. Значительные дополнения к API
В некоторых местах BoringSSL добавил значительные API. Использование этих API выходит за рамки «портирования» и означает отказ от совместимости с OpenSSL.
Один из примеров этого уже упоминался: функции CBS и CBB следует использовать при анализе или сериализации данных.
CRYPTO_BUFFER
С помощью стандартных API OpenSSL при создании множества TLS-соединений данные сертификата для каждого соединения сохраняются в памяти в дорогостоящей структуре X509. Кроме того, общие сертификаты часто появляются в цепочках для нескольких соединений и без необходимости дублируются в памяти.
CRYPTO_BUFFER
— это просто непрозрачная строка байтов. CRYPTO_BUFFER_POOL
— это внутренняя таблица для этих буферов, то есть она гарантирует, что для каждого пула сохраняется только одна копия любой заданной строки байтов.
Функция TLS_with_buffers_method
возвращает метод SSL_METHOD
, который позволяет избежать создания объектов X509
для сертификатов. Кроме того, можно использовать SSL_CTX_set0_buffer_pool
для установки пула на SSL_CTX
, чтобы сертификаты можно было дедуплицировать между соединениями и между SSL_CTXs
.
При использовании этих функций приложение также должно гарантировать, что оно не вызывает другие функции, которые работают с объектами X509
или X509_NAME
. Например, SSL_get_peer_certificate
или SSL_get_peer_cert_chain
. Это вызовет утверждение в режиме отладки и приведёт к NULL в режиме выпуска. Вместо этого вызывайте основанные на буферах альтернативы, такие как SSL_get0_peer_certificates
. (См. ssl.h для функций, принимающих или возвращающих CRYPTO_BUFFER
.) Основанные на буфере альтернативные функции будут работать, даже если не используется TLS_with_buffers_method
, поэтому код приложения может постепенно переходить на них.
Чтобы использовать буферы, код приложения также должен реализовать собственную проверку сертификата с помощью SSL_[CTX_]set_custom_verify
. В противном случае все подключения завершатся ошибкой проверки. Автоматическое связывание также отключается при использовании буферов.
После внесения этих изменений весь код OpenSSL X.509 и ASN.1 должен быть удалён компоновщиком, если BoringSSL связан статически.
Асинхронные и непрозрачные закрытые ключи
OpenSSL предлагает ENGINE API для реализации непрозрачных закрытых ключей (то есть закрытых ключей, где программное обеспечение имеет доступ только к оракулу, потому что секреты хранятся в специальном оборудовании или на другом устройстве). Хотя ENGINE API в основном был удалён из BoringSSL, таким образом всё ещё можно поддерживать непрозрачные ключи. Однако при использовании таких ключей с TLS и BoringSSL настоятельно рекомендуется использовать SSL_PRIVATE_KEY_METHOD
через SSL[_CTX]_set_private_key_method
. Это позволяет приостановить рукопожатие во время выполнения частной операции. Также поддерживается больше форм непрозрачного ключа, поскольку он предоставляет более высокоуровневую информацию о выполняемой операции.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )