CryptoPro / libcore

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Mixed CSP certificate collection

Bykiev opened this issue · comments

Здравствуйте, при поиске сертификата иногда возникает следующая ошибка:

CoreCLR Version: 6.0.1623.17311
.NET Version: 6.0.16
Description: The process was terminated due to an unhandled exception.
Exception Info: System.InvalidOperationException: Mixed CSP certificate collection.
   at LibCore.Security.Cryptography.X509Certificates.Detours.Pal.StorePalDetour.PatchFindFromCollection.Prefix(X509Certificate2Collection coll, X509FindType findType, Object findValue, Boolean validOnly, Object& __result)
   at Internal.Cryptography.Pal.FindPal.FindFromCollection_Patch1(X509Certificate2Collection coll, X509FindType findType, Object findValue, Boolean validOnly)
   at System.Security.Cryptography.X509Certificates.X509Certificate2Collection.Find(X509FindType findType, Object findValue, Boolean validOnly)

Windows Server 2019
CryptoPro CSP 5.0.12600

Добрый день.

Данная ошибка возникает про поиске сертификата по коллекции, если в коллекции находятся одновременно сертификаты ГОСТ и RSA\DSA. При этом в случает работы с хранилищем данная ошибка не ожидается.

Можете поподробнее сообщить о сценарии, в котором выполняется данный поиск (откуда приходит коллекция для поиска, что делает вызывающий её код)? Используется последняя версия Libcore?

Здравствуйте, используется поиск по отпечатку в хранилище Личное Локального компьютера. Libcore последней версии 2023.5.30.1

var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var results = store.Certificates.Find(X509FindType.FindByThumbprint, thumbPrint, false);

Не используется ли сертификаты из инициализированного хранилища перед поиском?

Т.е. нет ли сценария, когда из коллекции производится поиск сертификата, он как либо используется (в том числе просто просматривая свойства в отладчике), затем опять производится поиск в этом же (без повторного создания объекта хранилища)?

Ошибка на фиксированной машине с фиксированным набором сертификатов воспроизводится постоянно?

Нет

Не используется ли сертификаты из инициализированного хранилища перед поиском?

Т.е. нет ли сценария, когда из коллекции производится поиск сертификата, он как либо используется (в том числе просто просматривая свойства в отладчике), затем опять производится поиск в этом же (без повторного создания объекта хранилища)?

Такого сценария нет.

Ошибка на фиксированной машине с фиксированным набором сертификатов воспроизводится постоянно?

Ошибка возникает редко, в большинстве случаев все работает корректно

Постараюсь в ближайшее время подробнее посмотреть код.

Как только будет сборка для тестов - отпишусь тут.

Сборка для тестов по ссылке:
https://file.cryptopro.ru/f/WD8vBvNgqkGN8QyvybqDFLjxplBxtdn5/LibCore.Windows.2023.7.26.1.nupkg

Всё ещё не понятно, как воспроизводится, но сценарий смешанной коллекции с инициализированным ключом ГОСТа поддержали для win.

Спасибо, будем тестировать!

Здравствуйте, тестировали поиском сертификата по отпечатку в цикле, в новой версии ошибка не воспроизводится. На старой версии проблема воспроизводится только на сервере, локально повторить не удалось

Отлично. Спасибо.

В "лабораторном" сценарии для детерминированного воспроизведения можно сделать что то такое:

using (var gostCert = GetGostCertificate())
using (var rsaCert = GetRsaCertificate())
{
    // трогаем закрытый ключ и заставляем его инициализироваться
    var gostKey = gostCert.PrivateKey;

    var collection = new X509Certificate2Collection(
        new X509Certificate2[] { rsaCert, gostCert });

    var resultGost = collection.Find(X509FindType.FindBySubjectName, "G2012512", false);

    var resultRsa = collection.Find(X509FindType.FindBySubjectName, "rsa_test", false);
}

Интересно то, что если не использовать метод Find, а искать через перебор, то ошибки со старой версией нет

var results = store.Certificates.Where(_=>_.Thumbprint.ToLower() == thumpPrint.ToLower()).ToList()

Да, метод Find был перенесён из форка 3.1, где он сделан ms, зачем то, очень хитро с поиском через нативные функции в созданном для этих целей in memory store, а не простым поиском по коллекции. В новых версиях уже заменили на поиск в коллекции, когда нибудь переедем на него.

Отлично. Спасибо.

В "лабораторном" сценарии для детерминированного воспроизведения можно сделать что то такое:

using (var gostCert = GetGostCertificate())
using (var rsaCert = GetRsaCertificate())
{
    // трогаем закрытый ключ и заставляем его инициализироваться
    var gostKey = gostCert.PrivateKey;

    var collection = new X509Certificate2Collection(
        new X509Certificate2[] { rsaCert, gostCert });

    var resultGost = collection.Find(X509FindType.FindBySubjectName, "G2012512", false);

    var resultRsa = collection.Find(X509FindType.FindBySubjectName, "rsa_test", false);
}

Ошибка "Mixed CSP certificate collection" падает на строке
var resultGost = collection.Find(X509FindType.FindBySubjectName, "G2012512", false);

Речь про старую, или новую сборку?

Про старую, в новой работает без ошибок

Понял, спасибо.

Багу закрываю, если будут какие то ошибки - можно переоткрыть.