LINUX.ORG.RU

M2crypto не видит ГОСТовые шифрсьюты

 python openssl


0

1

Мужики, помогите кто знает - третьи сутки бьюсь.

Ситуация такая: установлен m2crypto, делаю:

from M2Crypto import Engine, httpslib, SSL

e = Engine.load_dynamic_engine('gost', '/usr/lib64/engines/libgost.so')
e.init()
e.set_default()

r = file('request.xml', "rb").read()

ctx = SSL.Context()

conn = httpslib.HTTPSConnection(host="icrs.nbki.ru", ssl_context = ctx)
conn.request("POST", "/products/B2BRequestServlet/", body=r)

Получаю SSLError: unknown cipher returned

То есть ситуация такая, что сайт отвечает пакетом данных, который расшифровать невозможно поскольку шифрсьют неизвестен

А сайт НБКИ использует шифрсьют GOST2001-GOST89-GOST89. Это совершенно точно, - я это проверил курлом, в смысле. И, само собой, он поддерживается ГОСТовским движком который есть и который можно загрузить принудительно.

Методом проб и ошибок я понял, что шифрсьюты не видит интерфейс SSL

In [12]: SSL.m2.engine_init(m2.engine_by_id("gost"))
Out[12]: 1

In [13]: SSL.m2.ssl_ctx_set_cipher_list(ctx.ctx, 'GOST2001-GOST89-GOST89')
Out[13]: 0

Может кто знает как победить эту хрень?

★★★

Последнее исправление: k0valenk0_igor (всего исправлений: 5)

Ответ на: комментарий от anonymous

Да. И шифрсьюты тоже.

Вот список движков, которые видит openssl

~/ $ openssl engine
(rsax) RSAX engine support
(dynamic) Dynamic engine loading support
(gost) Reference implementation of GOST engine

А вот шифрсьюты относящиеся к делу:

~/ $ openssl ciphers
:GOST2001-GOST89-GOST89 GOST94-GOST89-GOST89:

k0valenk0_igor ★★★
() автор топика
Последнее исправление: k0valenk0_igor (всего исправлений: 1)

Я вроде разобрался почему так происходит.

M2Crypto - это обвязка над OpenSSL и коль скоро это так, она не проводит инициализацию OpenSSL, оставляя это на долю автора приложения, что в общем-то вроде как находится в полном согласии с мануалом OpenSSL

It is strongly recommended that all new applications call OPENSSL_config() or the more sophisticated functions such as CONF_modules_load() during initialization (that is before starting any threads). By doing this an application does not need to keep track of all configuration options and some new functionality can be supported automatically. It is also possible to automatically call OPENSSL_config() when an application calls OPENSSL_add_all_algorithms() by compiling an application with the preprocessor symbol OPENSSL_LOAD_CONF #define'd. In this way configuration can be added without source changes.

Однако проблема в том, что доступа ни к OPENSSL_config(), ни к OPENSSL_add_all_algorithms() обвязка M2Crypto не предоставляет. За бортом оказались и ряд других весьма полезных функций позволяющих на ручнике добавлять алгоритмы и шифрсьюты. Например OPENSSL_add_all_algorithms и OPENSSL_add_all_ciphers

Обычно эта проблема себя не проявляет, однако в ситуации когда шифрсьюты и алгоритмы обитают во внешнем движке, она встает в полный рост. Потому что без этих функций становится невозможным ни подключить движок путем объявления его в конфиге, ни заявить о движке, алгоритмах и шифрсьютах на ручнике.

Причем M2Crypto отнюдь не одинок в таких косяках. Две остальные известные мне обвязки предоставляют доступ к еще меньшему количеству функционала, а автор curl (который вроде как полноценное приложение и должен делать инициализацию сам) багу на который ему указали присвоил статус «closed-later» и на этом расслабился, как я понимаю... Во всяком случае внешние движки openssl'я curl не видит до сих пор.

Короче, все очень грустно.

k0valenk0_igor ★★★
() автор топика
Последнее исправление: k0valenk0_igor (всего исправлений: 2)

Проблема решена!

Для тех, кому интересно: проблема была в том, что M2Crypto инициализирует интерфейс SSL до того как будет подгружен динамический движок GOST. Соответственно алгоритмы и шифрсьюты не подгружаются, а функции OpenSSL дающих возможность подгрузки алгоритмов и повторной инициализации в M2Crypto нет.

Проблема решилась добавлением в M2Crypto функций openssl_add_all_algorithms_conf, openssl_add_all_algorithms_noconf, ssl_library_init и последовательным вызовом их

До:

In [1]: from M2Crypto import SSL, m2, Engine

In [2]: Engine.load_dynamic()

In [3]: ctx = SSL.Context()

In [4]: SSL.m2.engine_init(m2.engine_by_id("gost"))
Out[4]: 1

In [5]: SSL.m2.ssl_ctx_set_cipher_list(ctx.ctx, 'GOST2001-GOST89-GOST89')
Out[5]: 0

После:

In [1]: from M2Crypto import m2, SSL

In [2]: m2.openssl_add_all_algorithms_conf()

In [3]: m2.ssl_library_init()
Out[3]: 1

In [4]: ctx = SSL.Context()

In [5]: SSL.m2.ssl_ctx_set_cipher_list(ctx.ctx, 'GOST2001-GOST89-GOST89')
Out[5]: 1

Проблема была заявлена тут, код был подан майентенеру проекта тут

k0valenk0_igor ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.