Вопрос или проблема
Я создаю IoT-приложение для STM32F429 на C, которое использует WolfSSL для создания TLS-соединения с MQTT-брокером, размещенным в облаке. У меня есть корневой сертификат CA для сервера, на котором размещен брокер, и правильный SNI. WolfSSL настроен на самостоятельный выбор набора шифров и получает SNI и CA.
При попытке выполнить рукопожатие выводится следующая отладочная информация:
wolfSSL Вход в TLSv1_2_client_method_ex
wolfSSL Вход в wolfSSL_CTX_new_ex
wolfSSL Вход в wolfSSL_Init
wolfSSL Вход в wolfCrypt_Init
wolfSSL Вход в wolfSSL_CertManagerNew
heap "параметр равен нулю
DYNAMIC_TYPE_CERT_MANAGER Выделение = 100 байт
wolfSSL Выход из wolfSSL_CTX_new_ex, возврат 0
wolfSSL Вход в wolfSSL_CTX_loadverify_buffer_ex Обработка CA PE] файла
wolfSSL Вход в PemToDer
Добавление CA
Получение имени сертификата
Получение имени сертификата
wolfSSL Вход в GetAlgoId
wolfSSL Вход в DecodeCertExtensions
wolfSSL Вход в DecodeKeyUsage
wolfSSL Вход в DecodeBasicCaConstraint
wolfSSL Вход в DecodeSubjKeyId
Проанализирован новый CA
Освобождение проанализированного CA Освобождение der CA
OK Освобождение der CA
wolfSSL Выход из AtdCA, возврат 0
Обработан CA
Обработан хотя бы один действительный CA. Другие данные в порядке wolfSSL Выход из wolfSSL_CTX_Load_verify_buffer_ex, возврат 1
wolfSSL Вход в wolfSSL_new
wolfSSL Вход в R_initSSL
RNG_HEALTH_TEST_CHECK_SIZE = 128
sizeof(seedB_data) = 128
wolfSSL Вход в SetSSL_CTX
wolfSSL Вход в wolfSSL_NewSession
InitSSL выполнен. возврат 0 (успех)
wolfSSL_new InitSSL успешно
wolfSSL Выход из wolfSSL_new InitSSL =, возврат 0
TLS 1.2 или ниже
wolfSSL Вход в wolfSSL_connect
wolfSSL Вход в ReinitSSL
wolfSSL Вход в RetrySendAlert
wolfSSL Вход в SendClientHello
Добавление расширения signature0algorithms
Увеличение выходного буфера
Расширение Signature Algorithms для записи
Расширение Point Formats для записи
Расширение Supported Groups для записи
Расширение Encrypt-Then-Mac для записи
Расширение SNI для записи
Расширение EMS для записи
Сужение выходного буфера wolfSSL Выход из SendClientHello, возврат 0
состояние подключения: CLIENT_HELLO_SENT
Состояние сервера до необходимого состояния.
Продвижение состояния сервера...
Обработка ответа...
wolfSSL Вход в RetrySendAlert
Ошибка версии SSL
wolfSSL Вход в SendAlert
wolfSSL Вход в SendAlert
SendAlert: 70 protocol_version
увеличение выходного буфера
Сужение выходного буфера
wolfSSL Выход из SendAlert, возврат 0
Произошла ошибка wolfSSL, ошибка = -326
wolfSSL Вход в wolfSSL_get_error
wolfSSL Выход из wolfSSL_get_error, возврат -326
wolfSSL Вход в wolfSSL_ERR_error_string
wolfSSL Вход в wolfSSL_shutdown
wolfSSL Выход из wolfSSL_shutdown, возврат -1
wolfSSL Вход в wolfSSL_free
Освобождение SSL: 0xd0300880
Освобождение клиентского ssl
Расширение Signature Algorithms для освобождения
Расширение Point Formats для освобождения
Расширение Supported Groups для освобождения
Расширение Encrypt-Then-Mac для освобождения
wolfSSL Вход в wolfSSL_freeSession
wolfSSL_FreeSession полное освобождение
Счетчик ссылок CTX не равен 0, освобождение не выполнено
wolfSSL Выход из wolfSSL_free, возврат 0
wolfSSL Вход в wolfSSL_CTX_free
wolfSSL Выход из wolfSSL_CTX_free, возврат 0
Я могу подключиться к брокеру с тем же корневым CA, используя, например, MQTTX.
Ответ или решение
Во-первых, давайте рассмотрим, почему ваш клиент на основе WolfSSL не может успешно завершить TLS-рукопожатие с MQTT-брокером, несмотря на наличие корректного корневого сертификата (CA) и имени виртуального хоста (SNI).
-
Ошибка версии протокола TLS:
В ваших сообщениях об отладке есть ключевая строка:SendAlert: 70 protocol_version
. Эта ошибка указывает на то, что сервер не поддерживает версию TLS, которую запрашивает ваш клиент. Убедитесь, что вы используете последнюю версию библиотеки WolfSSL и что она настроена на поддержку TLS 1.2 или, если это возможно, TLS 1.3, так как многие серверы больше не поддерживают более старые версии протокола (такие как TLS 1.0 и 1.1). -
Настройки шифрования:
Проверьте, какие шифровые наборы поддерживает сервер. Возможно, что определенные шифры, которые ваш клиент пытается использовать, не поддерживаются сервером. Вам следует явно указать, какой набор шифров использовать, если такая возможность есть в вашей реализации WolfSSL. -
Проблемы с сертификацией:
Хотя вы указали, что используете правильный CA, убедитесь, что сертификаты корректно загружены в контекст WolfSSL и что на стороне сервера установлен действующий сертификат. Иногда проблемы с цепочками сертификатов могут привести к сбоям в рукопожатии. -
Использование SNI (Server Name Indication):
Поскольку SNI является важным аспектом при установлении соединения с многими брокерами, удостоверьтесь, что вы правильно передаете SNI в своем коде. Проверьте, что значение SNI совпадает с тем, что ожидает ваш сервер MQTT. -
Логи и отладка:
Рассмотрите возможность увеличения уровня детализации логов для WolfSSL, чтобы получить более полное представление о том, что происходит во время рукопожатия. Удостоверьтесь, что у вас включено логирование ошибок, что поможет лучше диагностировать проблемы. -
Сравнение с другим клиентом:
Поскольку вы можете успешно подключиться к брокеру с помощью MQTTX, попробуйте захватить трафик с помощью инструментов вроде Wireshark, чтобы увидеть, какие детали использует успешный клиент и в чем разница с WolfSSL. Это может помочь вам определить, какие параметры соединения отличны. -
Обновление библиотеки и документации:
Убедитесь, что у вас установлена последняя версия библиотеки WolfSSL, так как в ней могут быть исправлены ошибки, влияющие на обработку TLS. Кроме того, рекомендуется ознакомиться с документацией WolfSSL, чтобы подтвердить, что все вызовы функций реализованы корректно.
В заключение, проблемы с TLS-рукопожатием часто могут быть сложными и многофакторными. Начните с проверки версии протокола и правил конфигурации шифров, затем перейдите к вопросам сертификации и правильности передачи SNI. Если вы будете следовать шагам, описанным выше, это должно помочь решить вашу проблему.