gost-engine / engine

A reference implementation of the Russian GOST crypto algorithms for OpenSSL
Apache License 2.0
370 stars 170 forks source link

openssl 3.1.0 problem #442

Closed yjh-styx closed 1 year ago

yjh-styx commented 1 year ago

В windows вызов ENGINE_by_id("gost"); нормально работает с openssl 3.0.8, но приводит к "зависанию" с openssl 3.1.0. В linux этой проблемы нет (работает и с 3.1.0).

beldmit commented 1 year ago

Это надо в OpenSSL писать, engine не менялся

yjh-styx commented 1 year ago

Увы - нет. Во-первых любой другой engine прекрасно грузится, а, во-вторых, если удалить gostprov.dll, то зависание исчезает. Я посмотрел под отладчиком - "виснет" на вызове gostprov.OSSL_provider_init -> createNIDs -> OBJ_add_object

beldmit commented 1 year ago

Так не надо одновременно использовать engine и провайдер.

yjh-styx commented 1 year ago

Как? openssl3 автоматически грузит провайдеров (когда это прописано в конфиге). Вы предлагаете в каждой задаче где используется engine (поскольку подпись через провайдера не работает) использовать отдельный конфиг? Или имеется ввиду, что провайдером вообще лучше (пока) не пользоваться? Или есть способ "деактивировать" провайдера (активированного конфигом)?

На всякий случай - ПОЛНЫЙ тест для получения эффекта выглядит как: int main(void) { ENGINE_by_id("gost"); }

фрагмент конфига имеющий отношение к госту (и обеспечивающий эффект): ---cit--- [provider_sect] gostprov = gostprov_sect default = default_sect

[gostprov_sect] activate = 1 ---end---

И - повторюсь - с тем же конфигом и тот же тест вполне работает в 3.0.x

beldmit commented 1 year ago

Во-первых да, не надо одновременно использовать провайдер и engine, это сейчас в 3.x бесполезно. Во-вторых, не могли Вы попробовать патч из https://github.com/openssl/openssl/pull/20615, возможно, он закрывает проблему.

yjh-styx commented 1 year ago

2) Попробовал - не помогает. ато :) помогает вот такое: int main(void) { OSSL_PROVIDER_available(NULL, "gostprov"); ENGINE_by_id("gost"); return 0; }

"химия", конечно, но как временная заплатка...

1) Я понимаю что одновременно их не надо использовать. Не понимаю КАК это сделать. Вот если бы через gost-провайдера работала подпись... Однако если, например, в команде openssl smime -sign... заменить "-engine gost" на "-provider gostprov", то получаем

Could not read signing key from key.pem

И, как я понял, в обозримом будущем это Вы чинить не планируете :(.

beldmit commented 1 year ago

Ну вообще то, что Вы описываете, достаточно для того, чтобы пожаловаться в апстрим. А если gost engine не грузить, тоже будет виснуть?

Я сейчас, к сожалению, не могу выкроить кусок времени на ковыряние с провайдером. Но готов работу как-то координировать

yjh-styx commented 1 year ago

не будет. Более того (я ж писал), если сначачла проверить наличие провайдера то виснуть тоже не будет.

Написать в апстрим, может и стоит, но мне то что там происходит (без ссылок на гост :), не описать по английски. Да и, к тому же, "по результатам исследования" достаточно описать "метод лечения" (ниже) в каком-то TODO gost-engine

"Финал исследований" :). Проблема возникает из-за того, что когда gost_eng.c добавляет NID'ы (в create_NIDs), на первом же OBJ_add_object выполняется (в obj_lock_initialize):

/* Make sure we've loaded config before checking for any "added" objects */
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);

который грузит (когда они прописаны в конфиге) сначала провайдеров, а потом engine. А, поскольку gostprov тоже выполняет create_NID's, то получается рекурсивный вызов CRYPTO_THREAD_lock_new, а оно на такое не рассчитано.

Это и объясняет почему если сначала выполнить OSSL_PROVIDER_available зависания не происходит.


В отношении же правки провайдера... я, к сожалению, достаточно плохо представляю себе внутреннюю архитектуру всей этой системы. Сиречь, если Вы скажете "куда копать" (что бы понять почему не работают подписи) я могу попробовать это "протрассировать" и (если проблема в ошибках) поправить. А вот если там просто есть недописанные куски... боюсь не получится

beldmit commented 1 year ago

https://github.com/openssl/openssl/pull/20662 - потенциальный фикс. Можете попробовать?

yjh-styx commented 1 year ago

Это реальный фикс :). В смысле, проверил - с ним зависания нет и всё работает нормально. Спасибо!