Skip to content

Add PKCS#12 RFC 9337 / RFC 9548 GOST-native support#527

Open
ilya-maltsev wants to merge 9 commits into
gost-engine:masterfrom
ilya-maltsev:pkcs12-rfc-9337-9548
Open

Add PKCS#12 RFC 9337 / RFC 9548 GOST-native support#527
ilya-maltsev wants to merge 9 commits into
gost-engine:masterfrom
ilya-maltsev:pkcs12-rfc-9337-9548

Conversation

@ilya-maltsev
Copy link
Copy Markdown

Based on #128

Поддержка PKCS#12 (PFX) с алгоритмами ГОСТ

Экспорт и импорт PFX-контейнеров через стандартный openssl pkcs12:

  • Legacy GOST PBE (RFC 7292 + ГОСТ 28147-89) — шифр gost89 под обвязкой RFC 7292; внешний MAC — HMAC под ГОСТ-хэшем.
  • RFC 9337 / 9548 (ТК-26) — Кузнечик и Магма в режиме CTR-ACPKM под PBES2 + PBKDF2 (PRF — HMAC-Streebog-256/512); внешний MAC по KDF из RFC 9548 §3.
  • Декодирование PFX с проприетарным CryptoPro keybag PBE OID 1.2.840.113549.1.12.1.80.

Реализации

  • Engine (gost.so) — OpenSSL 3.x без патчей libcrypto.
  • Provider (gostprov.so) — OpenSSL 3.4 / 3.6 / 4.0; Требует libcrypto-патч patches/pkcs12/openssl-pkcs12-provider-pbe-${MAJOR}.${MINOR}.patch (поставляется для каждой версии отдельно).

OMAC-варианты (kuznyechik-ctr-acpkm-omac, magma-ctr-acpkm-omac) работают в engine-режиме на 3.x. В provider-режиме они заблокированы на gost2015_acpkm_omac_init (нужен отдельный рефакторинг engine-исходников на EVP_MAC_fetch).

Состав

  • Реализация шифров, MAC и provider-функций (gost_cryptopro_keybag*.c, gost_prov_*.c, и др.).
  • 3 patch-файла libcrypto в patches/pkcs12/.
  • Dev-окружение docker/dev_pkcs12/: контейнеры под три версии OpenSSL + соседний CryptoPro CSP.
  • Скрипты воспроизведения проверочных матриц: engine_to_csp_matrix.sh, cryptopro_keybag_decode.sh.

Документация

  • README.pkcs12.md / README.pkcs12.ru.md — обзор + CLI-примеры + переменные окружения.
  • patches/pkcs12/README.md / README.ru.md — описание патчей и воспроизведение проверочных матриц.
  • docker/dev_pkcs12/README.md / README.ru.md — поднятие dev-стека.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds end-to-end PKCS#12 (PFX) support for GOST algorithms, covering both RFC 9337/9548 (TK-26 PBES2/PBKDF2 + CTR-ACPKM) and CryptoPro’s proprietary keybag PBE OID 1.2.840.113549.1.12.1.80, with parity tests across engine/provider modes and a Docker dev stack to reproduce validation matrices (including CryptoPro CSP).

Changes:

  • Introduces RFC 9337/9548 PKCS#12 conformance + CLI smoke tests, plus an engine-vs-provider structural parity check.
  • Adds provider-side plumbing for CryptoPro proprietary keybag decode (OID binding + provider cipher dispatch).
  • Ships per-OpenSSL-version libcrypto patch files (3.4/3.6/4.0) plus extensive documentation and a multi-version Docker dev environment.

Reviewed changes

Copilot reviewed 41 out of 42 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/pkcs12_rfc9337.sh CLI-level smoke test for openssl pkcs12 -export/-in using RFC 9337/9548 ciphers/digests.
test/pkcs12_cross_mode_parity.sh Runs the RFC9337 test binary under engine/provider configs and diffs structural fingerprints.
test_pkcs12_rfc9337.c Core RFC 9337/9548 matrix test using libcrypto APIs + structural fingerprint output mode.
README.pkcs12.ru.md Russian PKCS#12 documentation: modes, OIDs, env knobs, provider patch requirement, CryptoPro decode notes.
README.pkcs12.md English PKCS#12 documentation mirroring the RU version.
README.md Links the repository root README to the new PKCS#12 docs.
patches/pkcs12/README.ru.md Russian documentation for the per-version OpenSSL libcrypto PKCS#12 provider-mode patches.
patches/pkcs12/README.md English documentation for the per-version OpenSSL libcrypto PKCS#12 provider-mode patches.
patches/pkcs12/openssl-pkcs12-provider-pbe-4.0.patch OpenSSL 4.0 libcrypto patch enabling provider-mode PKCS#12 PBE paths for GOST.
patches/pkcs12/openssl-pkcs12-provider-pbe-3.6.patch OpenSSL 3.6 libcrypto patch enabling provider-mode PKCS#12 PBE paths for GOST.
patches/pkcs12/openssl-pkcs12-provider-pbe-3.4.patch OpenSSL 3.4 libcrypto patch enabling provider-mode PKCS#12 PBE paths for GOST.
gost_prov.c Provider init/teardown wiring for CryptoPro keybag OID/PBE registration lifecycle.
gost_prov_digest.c Adds LN aliases to provider digest names to satisfy PKCS#12 internal lookups via long name.
gost_prov_cipher.c Provider cipher enhancements: custom alg-id params emission, PRF NID exposure, (inactive) OMAC ads.
gost_grasshopper_cipher.c Engine-side cipher fixes: deterministic UKM seed lifecycle + PRF ctrl + AEAD ctrl trio for OMAC.
gost_gost2015.c Fixes ACPKM+OMAC seed generation to avoid post-AI re-randomization (round-trip correctness).
gost_cryptopro_keybag.h Declares CryptoPro proprietary keybag OID/NID/PBE registration API and unwrap cipher dispatch.
gost_cryptopro_keybag_asn1.h ASN.1 schema declarations for CryptoPro keybag decode pipeline.
gost_cryptopro_keybag_asn1.c ASN.1 template implementations for CryptoPro keybag decode pipeline.
gost_crypt.c Engine-side updates for Magma: PRF ctrl + OMAC AEAD ctrl trio + deterministic UKM seed serialization.
docker/dev_pkcs12/scripts/run-full-check.sh Dev helper: strict rebuild + ctest + cppcheck + valgrind sweep of test binaries.
docker/dev_pkcs12/scripts/fetch-openssl.sh Fetches OpenSSL source tarballs used by the multi-version dev stack.
docker/dev_pkcs12/scripts/entrypoint.sh Dev container bootstrap: patch+build OpenSSL in-volume and build/install engine/provider.
docker/dev_pkcs12/scripts/engine_to_csp_matrix.sh Provider-mode matrix: generate PFX in dev stacks and import into CryptoPro CSP (Tier-1 validation).
docker/dev_pkcs12/scripts/cryptopro_keybag_decode.sh CSP→OpenSSL decode matrix for proprietary keybag .80 across 3.4/3.6/4.0 stacks.
docker/dev_pkcs12/README.ru.md Russian docs for dev stack layout, bootstrap, and test invocation.
docker/dev_pkcs12/README.md English docs for dev stack layout, bootstrap, and test invocation.
docker/dev_pkcs12/Dockerfile.test Minimal test runner image for ctest against the dev-built OpenSSL prefix.
docker/dev_pkcs12/Dockerfile.dev Dev image for building OpenSSL + engine/provider with debugging tools.
docker/dev_pkcs12/docker-compose.yml Orchestrates 3 OpenSSL-version dev containers plus CryptoPro CSP sibling container.
docker/dev_pkcs12/cryptopro/test_gamma/kpim Seed material for CSP RNG (dev/test-only).
docker/dev_pkcs12/cryptopro/test_gamma/db1/kis_1 Baked CPSD gamma seed file for headless CryptoPro CSP keygen (dev/test-only).
docker/dev_pkcs12/cryptopro/readme.keygen.md Verified CSP key+cert+PFX export flow documentation for the test container.
docker/dev_pkcs12/cryptopro/readme.dockerfile.md Describes the CryptoPro container build and runtime quirks.
docker/dev_pkcs12/cryptopro/readme.certmgr.md Reference for certmgr CLI surface used by matrix scripts.
docker/dev_pkcs12/cryptopro/entrypoint.cryptopro.sh CryptoPro container init: seed RNG gamma, drop interactive RNG, log license.
docker/dev_pkcs12/cryptopro/Dockerfile.cryptopro Builds the CryptoPro CSP image from a user-provided proprietary archive.
docker/dev_pkcs12/cryptopro/data/.gitkeep Keeps the PFX swap directory in git.
docker/dev_pkcs12/.gitignore Ignores some local dev artifacts under docker/dev_pkcs12/.
cmake/tests.cmake Registers the new RFC9337 test(s) and engine/provider parity/CLI tests with ctest.
cmake/provider.cmake Adds CryptoPro keybag source files to the provider build.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread gost_prov.c
Comment thread test_pkcs12_rfc9337.c Outdated
Comment thread docker/dev_pkcs12/.gitignore
Comment thread gost_prov_digest.c
@li0ard
Copy link
Copy Markdown

li0ard commented May 9, 2026

Весьма приятно, что спустя столько лет после выхода моих статей, описывающих экспорт приватного ключа из PFX с этим проприетарным PBE, наконец будет добавлено решение в движок

@ilya-maltsev
Copy link
Copy Markdown
Author

@chipitsine
для применения патчей OpenSSL пришлось поправить CI

@chipitsine
Copy link
Copy Markdown
Contributor

я локально воспроизвел падения. там упиралось в Applink. и каких-то идей, как правильно это чинить (или наоборот игнорировать) не было.

@chipitsine
Copy link
Copy Markdown
Contributor

у вас, кстати, несколько докер образов включены. они не участвуют в ci/cd насколько я понял ?

@chipitsine
Copy link
Copy Markdown
Contributor

copilot-овские ревью посмотрите ? они иногда бывают по делу

те, которые можно закрыть, смело закрывайте

@ilya-maltsev
Copy link
Copy Markdown
Author

у вас, кстати, несколько докер образов включены. они не участвуют в ci/cd насколько я понял ?

они только для локальной разработки и тестирования

Comment thread .github/workflows/windows.yml
@chipitsine
Copy link
Copy Markdown
Contributor

@ilya-maltsev
попробовал лог упавшего теста обработать copilot-ом

https://github.com/chipitsine/engine/agents/pull/2?session_id=4a0dce9c-5fd6-4262-86d9-69131d5f1196

он каждый раз справляется лучше и лучше

@ilya-maltsev
Copy link
Copy Markdown
Author

https://github.com/chipitsine/engine/agents/pull/2?session_id=4a0dce9c-5fd6-4262-86d9-69131d5f1196

эта ссылка мне недоступна.

Если речь идет о CI / gcc-provider-openssl-master (pull_request)Failing after 2m
то так и должно быть - для master-ветки openssl никакой из патчей не применяется, таков скрипт CI.
Но при желании, можно, конечно, и еще допилить CI

@chipitsine
Copy link
Copy Markdown
Contributor

chipitsine#2

@chipitsine
Copy link
Copy Markdown
Contributor

я не настолько доверяю AI инструментам, чтобы переносить то, что они нагенерили ))

поправите то, что падает ?

@ilya-maltsev
Copy link
Copy Markdown
Author

поправите то, что падает ?

просто не применялся патч для мастер-ветки openssl, сейчас будет применяться тот же патч, что и для 4.0.0, но в дальнейшем развитии openssl это может снова привести падению на данном шаге.
Тут возможны два пути: либо пропускать вообще проверку для мастер-ветки openssl либо все время актуализировать состояние патчей для последней версии openssl

@chipitsine
Copy link
Copy Markdown
Contributor

chipitsine commented May 13, 2026

поправите то, что падает ?

просто не применялся патч для мастер-ветки openssl, сейчас будет применяться тот же патч, что и для 4.0.0, но в дальнейшем развитии openssl это может снова привести падению на данном шаге. Тут возможны два пути: либо пропускать вообще проверку для мастер-ветки openssl либо все время актуализировать состояние патчей для последней версии openssl

политика openssl заключается в том, что они могут гарантировать что-то только в рамках стабильных веток. и оставляют за собой право вносить брейкин ченжи в мастер: openssl/openssl#29925

я бы сказал, что логичнее выглядит просто завязаться на стабильные ветки и не запускать тесты на мастере вообще

@ilya-maltsev
Copy link
Copy Markdown
Author

логичнее выглядит просто завязаться на стабильные ветки и не запускать тесты на мастере вообще

согласен

@ilya-maltsev
Copy link
Copy Markdown
Author

@chipitsine
если ли еще какие-то вопросы по PR?

@chipitsine
Copy link
Copy Markdown
Contributor

image

тест не исключился, по прежнему пытается запустить его (и падает)

@Mironenko
Copy link
Copy Markdown
Contributor

Добрый день! Простите, что влезаю. Хотелось бы задать вопросы:

  1. Какова планируемая судьба патчей openssl? Они будут переноситься в upstream openssl?
  2. В коде появляются объемные комментарии. Они имеют смысл вне рамок текущей задачи?
  3. Вносится проприетарный алгоритм cryptopro keybag. Это соответствует духу "gost-engine -- A reference implementation of the Russian GOST crypto algorithms for OpenSSL"?

Очень здорово, что решается наболевшая задача, но, может быть, архитектурно/инфраструктурно ее нужно решать немного иначе?

@chipitsine
Copy link
Copy Markdown
Contributor

Добрый день! Простите, что влезаю. Хотелось бы задать вопросы:

  1. Какова планируемая судьба патчей openssl? Они будут переноситься в upstream openssl?
  2. В коде появляются объемные комментарии. Они имеют смысл вне рамок текущей задачи?
  3. Вносится проприетарный алгоритм cryptopro keybag. Это соответствует духу "gost-engine -- A reference implementation of the Russian GOST crypto algorithms for OpenSSL"?

Очень здорово, что решается наболевшая задача, но, может быть, архитектурно/инфраструктурно ее нужно решать немного иначе?

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

я предлагаю относиться к контрибьюшену несколько проще. пока есть желающие мейнтейнить этот pkcs12 функционал - он будет. если желающие переключатся на другие проекты и код будет обузой - он будет выпилен ))

@chipitsine
Copy link
Copy Markdown
Contributor

@ilya-maltsev

image

выглядит так, будто вы вообще предлагаете отключить этот джоб.
вроде речь была не запускать rfc9337 тесты на нем

@ilya-maltsev
Copy link
Copy Markdown
Author

@chipitsine

выглядит так, будто вы вообще предлагаете отключить этот джоб. вроде речь была не запускать rfc9337 тесты на нем

исправил

@chipitsine
Copy link
Copy Markdown
Contributor

@Mironenko @ilya-maltsev , предлагаю взять неделю-две на подумать, и потом или вмержить, или аргументированно поймем, почему нет. с оценкой среднесрочной перспективы.

@ilya-maltsev
Copy link
Copy Markdown
Author

@chipitsine

выглядит так, будто вы вообще предлагаете отключить этот джоб.

OpenSSL master сломал X509_TRUST_set в crypto/x509/x509_trust.c:120.
тут либо также как и с pkcs12-тестами - отключать их для мастер ветки либо отключать сборку с мастер-веткой openssl насовсем.

я бы сказал, что логичнее выглядит просто завязаться на стабильные ветки и не запускать тесты на мастере вообще

если не запускать тесты на мастере вообще - зачем тогда вообще нужен этот шаг?

@ilya-maltsev
Copy link
Copy Markdown
Author

@Mironenko

может быть, архитектурно/инфраструктурно ее нужно решать немного иначе

у вас есть конкретные предложения? - что бы было лучше/быстрее/сильнее - welcome)

@chipitsine
Copy link
Copy Markdown
Contributor

@chipitsine

выглядит так, будто вы вообще предлагаете отключить этот джоб.

OpenSSL master сломал X509_TRUST_set в crypto/x509/x509_trust.c:120. тут либо также как и с pkcs12-тестами - отключать их для мастер ветки либо отключать сборку с мастер-веткой openssl насовсем.

crypto/x509/x509_trust.c:120 пусть пдает. это не входит в данный пул реквест.
в прошлый раз падало на чем-то связанном с rfc9337

я бы сказал, что логичнее выглядит просто завязаться на стабильные ветки и не запускать тесты на мастере вообще

если не запускать тесты на мастере вообще - зачем тогда вообще нужен этот шаг?

я думаю, что логика тут примерно такая.
rfc9337 вообще не предполагается на мастере.
в то время как остальная функциональность проекта - скорее предполагается до тех пор, пока мастер не сломают. и чтобы ловить эти брейкин ченжи оно и сделано.

@Mironenko
Copy link
Copy Markdown
Contributor

у вас есть конкретные предложения? - что бы было лучше/быстрее/сильнее - welcome)

Предложения

Не тянуть патчи openssl в проект gost-engine

То, что сейчас тут есть патчи -- ошибка. Когда надо было показать, что provider теперь поддерживает TLS1.3, если подправить OpenSSL, имело смысл ссылаться в CI на фиксированный коммит во внешнем репозитории, форке OpenSSL.

Вместо патча, как мне кажется, имеет смысл сделать форк openssl, и в нем добавить изменения. Это проще читается и поддерживается. При этом предложил бы ограничить поддержку: openssl 3.5 + engine (низкий приоритет, потому что LTS до 2030), openssl 4.0 + provider.

Реализовать программный тест и sample

Программный тест:

  1. Расшифрование предварительно зашифрованных внешним ПО PKCS12-контейнеров.
  2. Зашифрование и расшифрование контейнеров через API OpenSSL.

Если с непатченным openssl тест работает только с engine, оставить на CI только запуск с engine.

Для провайдера написать тест, проверяющий введенные инварианты (поддерживается новый алгоритм шифрования, поддерживаются новые параметры).

Дополнительные тесты и CI (с провайдером) вынести в форк OpenSSL.

Sample: опционально; те же возможности, что представляет pkcs12 для отечественных криптоалгоритмов. Печатать дисклеймер, что с провайдером работает только с патченной версией openssl (со ссылкой).

Не тянуть docker/dev_pkcs12

При желании, эти артефакты оставить в вашем форке openssl.

Убрать многословные комментарии

Выглядит так, будто текущие комментарии демонстрируют, как ИИ решал задачу. Они не сильно помогут в будущем.

Предложить изменения в OpenSSL

Выглядит так, будто патчи -- это просто обеспечение корректной работы pkcs#12 с подключенным провайдером. Это не ГОСТ-специфичная функциональность, поэтому, как мне кажется, может быть адекватно воспринята мейнтейнерами OpenSSL.

Переразместить документацию

В файлах README.gost и README.prov.md упоминаниям PKCS#12 как будто будет лучше.

@ilya-maltsev
Copy link
Copy Markdown
Author

мейнтейнерами OpenSSL.

Я так понимаю в этом словосочетании заключается ваш основной лейб-мотив - засунуть имплементацию стандартов pkcs12, разработанных ТК 26, в мейнстрим OpenSSL. Но, по моему мнению, этого никогда не будет, по крайней мере, в этой версии этой вселенной :)
Исходя из вышеизложенного мной выбран именно тот путь, который и реализован в данном PR.
Что касается комментариев - они нужны для последующей доработки OMAC-шифров.
А все необходимые тесты лежат как раз в docker/dev_pkcs12.

P.S.

Выглядит так, будто патчи -- это просто обеспечение корректной работы pkcs#12 с подключенным провайдером.

Бинго! Эти патчи openssl нужны как раз для этого, а то, что было с TLS1.3 ранее, использовано как прецедент:

Когда надо было показать, что provider теперь поддерживает TLS1.3, если подправить OpenSSL

P.P.S.

Если с непатченным openssl тест работает только с engine, оставить на CI только запуск с engine.

Так ведь engine не будет в следующих версиях OpenSSL - зачем привязываться к legacy? - это риторический вопрос, если что...

Надеюсь я расставил все точки над i - к дальнейшей полемике вне рамок конкретных решений по данному PR не готов. Спасибо за внимание.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants