Связано с #531 (после патчей в 531 и этом issue проблема уходит)
Описание
Верификация цепочки сертификатов с ГОСТ-подписями (Streebog-256/512)
не работает с provider-based реализациями OpenSSL 3.x по двум причинам:
-
x509_sig_info_init() (crypto/x509/x509_set.c) — функция, вычисляющая security bits для signature digest, не имеет явных значений для NID_id_GostR3411_2012_256 и NID_id_GostR3411_2012_512. Они попадают в секцию default, где EVP_get_digestbynid(mdnid) возвращает NULL (потому что provider digest-ы не регистрируются в legacy OBJ_NAME). Результат: X509_V_ERR_CA_MD_TOO_WEAK.
-
ASN1_item_verify_ctx() (crypto/asn1/a_verify.c) — при верификации подписи сертификата вызывает EVP_get_digestbynid(mdnid), что также возвращает NULL для Streebog-256/512. Результат: X509_V_ERR_CERT_SIGNATURE_FAILURE (ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM).
Исправление
x509_set.c — добавлены case-ветки для Streebog NID с явными secbits:
- NID_id_GostR3411_2012_256 → 128 (256/2 = 128 birthday bound)
- NID_id_GostR3411_2012_512 → 256 (512/2 = 256 birthday bound)
По аналогии с существующей веткой NID_id_GostR3411_94 (secbits=105).
a_verify.c — при failure EVP_get_digestbynid() добавлен fallback: преобразовать NID → short name через OBJ_nid2sn() → EVP_MD_fetch().
Это работает для любых провайдерских дайджестов, а не только ГОСТ.
Альтернативы
- SecurityLevel=0 в openssl.cnf — маскирует симптом.
- EVP_add_digest() — не работает с provider-fetched EVP_MD
(разная внутренняя структура, potential UB при OBJ_NAME_add).
Патч
diff --git a/crypto/x509/x509_set.c b/crypto/x509/x509_set.c
index 3234824807..6954404560 100644
--- a/crypto/x509/x509_set.c
+++ b/crypto/x509/x509_set.c
@@ -278,6 +278,14 @@ static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
*/
siginf->secbits = 105;
break;
+ case NID_id_GostR3411_2012_256:
+ /* Birthday bound: 256 / 2 = 128 bits */
+ siginf->secbits = 128;
+ break;
+ case NID_id_GostR3411_2012_512:
+ /* Birthday bound: 512 / 2 = 256 bits */
+ siginf->secbits = 256;
+ break;
default:
/* Security bits: half number of bits in digest */
if ((md = EVP_get_digestbynid(mdnid)) == NULL) {
diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c
index 3d882c5f25..9d645e7b59 100644
--- a/crypto/asn1/a_verify.c
+++ b/crypto/asn1/a_verify.c
@@ -177,12 +177,17 @@ int ASN1_item_verify_ctx(const ASN1_ITEM *it, const X509_ALGOR *alg,
}
if (mdnid != NID_undef) {
- type = EVP_get_digestbynid(mdnid);
+ if ((type = EVP_get_digestbynid(mdnid)) == NULL) {
+ const char *md_name = OBJ_nid2sn(mdnid);
+ if (md_name != NULL)
+ type = EVP_MD_fetch(NULL, md_name, NULL);
+ }
if (type == NULL) {
ERR_raise_data(ERR_LIB_ASN1,
ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM,
"nid=0x%x", mdnid);
goto err;
}
}
Связано с #531 (после патчей в 531 и этом issue проблема уходит)
Описание
Верификация цепочки сертификатов с ГОСТ-подписями (Streebog-256/512)
не работает с provider-based реализациями OpenSSL 3.x по двум причинам:
x509_sig_info_init() (crypto/x509/x509_set.c) — функция, вычисляющая security bits для signature digest, не имеет явных значений для NID_id_GostR3411_2012_256 и NID_id_GostR3411_2012_512. Они попадают в секцию default, где EVP_get_digestbynid(mdnid) возвращает NULL (потому что provider digest-ы не регистрируются в legacy OBJ_NAME). Результат: X509_V_ERR_CA_MD_TOO_WEAK.
ASN1_item_verify_ctx() (crypto/asn1/a_verify.c) — при верификации подписи сертификата вызывает EVP_get_digestbynid(mdnid), что также возвращает NULL для Streebog-256/512. Результат: X509_V_ERR_CERT_SIGNATURE_FAILURE (ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM).
Исправление
x509_set.c — добавлены case-ветки для Streebog NID с явными secbits:
По аналогии с существующей веткой NID_id_GostR3411_94 (secbits=105).
a_verify.c — при failure EVP_get_digestbynid() добавлен fallback: преобразовать NID → short name через OBJ_nid2sn() → EVP_MD_fetch().
Это работает для любых провайдерских дайджестов, а не только ГОСТ.
Альтернативы
(разная внутренняя структура, potential UB при OBJ_NAME_add).
Патч