OpenSSL SSL_CTX_NEW возвращает «нулевой метод ssl передан»

Код: TIdSSLIOHandlerSocketOpenSSL( ASMTP.IOHandler ).SSLOptions.SSLVersions := [sslvSSLv2,sslvSSLv23,sslvSSLv3,sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2]

Похоже, проблема заключается в методе TIdSSLOptions.SetSSLVersions, если вы устанавливаете что-то кроме одной версии, она устанавливает fMethod := sslvSSLv23. Если он недоступен, TIdSSLContext.SetSSLMethod возвращает nil, и вы получаете эту ошибку.

Indy, декабрь 2015 г., TIdSSLContext.SetSSLMethod может возвращать nil. Решение возвращено.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
83
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Что за вопрос? Нет, надеюсь, кто-то найдет это полезным.

Это сайт вопросов и ответов. Делиться знаниями — это хорошо, но это должно быть в формате вопросов и ответов. Смотрите Можно я сам отвечу на свой вопрос?

В любом случае, это больше похоже на отчет об ошибке, о котором нужно было сообщить в систему отслеживания проблем Indy, а не на публичный форум.

При этом вам НИКОГДА не следует включать протоколы SSLv2 или SSLv3, так как они больше не являются безопасными и даже больше не доступны во многих выпусках OpenSSL. А SSLv23 — это просто подстановочный знак, он предназначен для использования только в свойстве Method, а не в свойстве SSLVersions (на самом деле, если вы попытаетесь указать его с любой другой версией, он будет просто проигнорирован). Вы должны использовать только протоколы TLSv1+ в SSLVersions, позвольте Indy работать с SSLv23 внутри по мере необходимости.

TIdSSLIOHandlerSocketOpenSSL( ASMTP.IOHandler ).SSLOptions.SSLVersions := [sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2]

Похоже, проблема заключается в методе TIdSSLOptions.SetSSLVersions, если вы установите что-либо, кроме одной версии, он устанавливает fMethod := sslvSSLv23.

Так и должно быть, потому что метод SSLv23 — это то, как OpenSSL обеспечивает динамическое согласование версий во время рукопожатия SSL/TLS, позволяя клиенту и серверу согласовывать самую высокую версию TLS, которую они оба поддерживают. В противном случае, если клиент использует только определенную версию, и если сервер не поддерживает эту версию, рукопожатие TLS завершится ошибкой.

Если он недоступен, TIdSSLContext.SetSSLMethod возвращает nil, и вы получаете эту ошибку.

Во-первых, SetSSLMethod() никогда не вернется nil в SSL_CTX_new(). Если запрошенный метод не поддерживается OpenSSL, SetSSLMethod() вместо этого вызывает EIdOSSLGetMethodError исключение.

Во-вторых, это условие означает, что вы не можете выполнять согласование версий, поэтому вместо этого вы должны использовать определенную версию TLS. Исключение сделано по задумке, сообщая вам, что вы запросили согласование, но ваша версия OpenSSL не поддерживает его, поэтому попробуйте что-нибудь другое.

Самый простой обходной путь - установить метод после настройки SSLVersions.

Свойства Method и SSLVersions являются взаимоисключающими, установка одного из них обновляет другое. Однако Method устарел, вам действительно следует использовать только SSLVersions, даже для одиночных версий TLS.

Этого тоже может не быть, поэтому лучший обходной путь может быть в indy:

Ваш обходной путь полностью отключает согласование версий при запросе SSLv23. Это не лучший вариант для Indy.

Настоящим обходным решением было бы, если бы ваш собственный код перехватывал исключение EIdOSSLGetMethodError, когда SSLv23 недоступен, а затем вы могли бы повторно попытаться подключиться, используя отдельные версии TLS по мере необходимости. Никаких изменений в коде Indy для этого не требуется.

Спасибо, Реми. Я исправляюсь. Первоначально я хотел спросить, что означает SSLv23 и почему он не назначен, но потом было 4 часа ночи, квадратные глаза, и я придумал это «решение». SetSSLMethod() возврат nil будет означать, что приложение было создано с гораздо более старой версией Indy, но более новой, чем та, которая поставляется с D2007, у которого нет свойства SSLVersions. До сих пор не знаю, почему SSLv23 не назначен.

Robert 19.11.2022 11:28

Другие вопросы по теме