CryptoPro / libcore

44 stars 0 forks source link

Наше приложение нормально работает на Ubuntu 22.04, но валится на RED OS 7.3.2 #28

Closed Cyber-Watcher closed 1 year ago

Cyber-Watcher commented 1 year ago

Добрый день! Эта ошибка повторяется постоянно, и подпись соответственно не делается. Версия вашей либы 2023.5.30.1

На убунту 22.04 мой код прекрасно работает и подписывает документы и строки, а на РЕД ОС 7.3.2 не хочет.

Версия КриптоПРо Ver:5.0.12600 (на 12800 тоже не пошло на ред ос)

Сразу вводные данные:

NAME="RED OS" VERSION="MUROM (7.3.2)" PLATFORM_ID="platform:el7" ID="redos" ID_LIKE="rhel centos fedora" VERSION_ID="7.3.2" PRETTY_NAME="RED OS MUROM (7.3.2)" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:redos:redos:7" HOME_URL="http://red-soft.ru/ru/main_products.html#redos" BUG_REPORT_URL="http://redos-support.red-soft.ru" EDITION="Standard"

На РЕД ОС такая ошибка:

2023-07-27 11:46:38.035 [INF] CommandManager:SetCommand - user System - message - Decompose queue message for cryptosigning
2023-07-27 11:46:38.136 [INF] CommandManager:SetCommand - user System - message - Begin cryptosigning CryptoSignerLinux
2023-07-27 11:46:39.017 [INF] LibCoreInitializer:Initialize - user System - message - LibCore is Initialized!
2023-07-27 11:46:39.017 [INF] CryptoSignerLinux:Sign - user System - message - Try to find certificate with serial number = 022B1FF500C3ACD1AD426EE14AD51C042B
2023-07-27 11:46:39.034 [INF] CryptoSignerLinux:Sign - user System - message - storeCerts.Count = 2
2023-07-27 11:46:39.035 [INF] CryptoSignerLinux:Sign - user System - message - Found ceritificate with SerialNumber = 03BC40E20023AF11874BCDDE2F194565E5
2023-07-27 11:46:39.035 [INF] CryptoSignerLinux:Sign - user System - message - Found ceritificate with SerialNumber = 022B1FF500C3ACD1AD426EE14AD51C042B
2023-07-27 11:46:39.038 [INF] CryptoSignerLinux:Sign - user System - message - For singnature will be used certificate with SubjectName.Name = CN="ООО ""xxxxx РОССИЯ""", SN=xxxxx, G=xxxxx, C=RU, S=77 г. Москва, L=Москва, STREET="xxx", O="ООО ""xxxxx РОССИЯ""", T=xxxxxx, OGRN=xxxxxx, SNILS=xxxxx, INN=xxxxx, E=xxxxxv@xxxxx.com
2023-07-27 11:46:39.038 [INF] CryptoSignerLinux:Sign - user System - message - This certificate HasPrivateKey = True
2023-07-27 11:46:39.143 [ERR] An unhandled exception has occurred while executing the request.
LibCore.Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Cryptography error
at LibCore.Internal.NativeCrypto.CapiHelper.SignValue(SafeProvHandle hProv, SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash)
at LibCore.Security.Cryptography.Gost3410_2012_256CryptoServiceProvider.SignHash(Byte[] rgbHash)
at LibCore.Security.Cryptography.Gost3410_2012_256CryptoServiceProvider.SignHash(Byte[] rgbHash, HashAlgorithmName hashAlgName)
at LibCore.Security.Cryptography.Gost3410_2012_256.TrySignHash(ReadOnlySpan`1 hash, Span`1 destination, HashAlgorithmName hashAlgorithm, Int32& bytesWritten)
at LibCore.Security.Cryptography.GostCmsSignature.Gost2012_256CmsSignature.Sign(ReadOnlySpan`1 dataHash, HashAlgorithmName hashAlgorithmName, X509Certificate2 certificate, AsymmetricAlgorithm key, Boolean silent, String& signatureAlgorithm, Byte[]& signatureValue)
at LibCore.Security.Cryptography.GostCmsSignature.Sign(ReadOnlySpan`1 dataHash, HashAlgorithmName hashAlgorithmName, X509Certificate2 certificate, AsymmetricAlgorithm key, Boolean silent, String& oid, ReadOnlyMemory`1& signatureValue)
at LibCore.Security.Cryptography.Pkcs.Detours.CmsSignerDetour.Prefix(ReadOnlyMemory`1 data, String contentTypeOid, Boolean silent, X509Certificate2Collection& chainCerts, CmsSigner __instance, Object& __result)
at System.Security.Cryptography.Pkcs.CmsSigner.Sign_Patch1(CmsSigner this, IntPtr retbuf, ReadOnlyMemory`1 data, String contentTypeOid, Boolean silent, X509Certificate2Collection& chainCerts)
at System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner signer, Boolean silent)
at Vekas.CryptoSignerService.Business.CryptoSignerLinux.Sign(String text) in E:\TempGit\CryptoSigner_master_2023-07-27_10-44-10\Software\Vekas.CryptoSignerService\Business\CryptoSignerLinux.cs:line 79
at CryptoSignerService.Managers.CommandManager.SetCommand(BaseCSDto`1 apiCommand) in E:\TempGit\CryptoSigner_master_2023-07-27_10-44-10\Software\Vekas.CryptoSignerService\Managers\CommandManager.cs:line 64
at lambda_method2(Closure , Object , Object[] )
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
2023-07-27 11:46:39.180 [ERR] Connection id "0HMSEFNUO0TE3", Request id "0HMSEFNUO0TE3:00000002": An unhandled exception was thrown by the application.
System.InvalidOperationException: The exception handler configured on ExceptionHandlerOptions produced a 404 status response. This InvalidOperationException containing the original exception was thrown since this is often due to a misconfigured ExceptionHandlingPath. If the exception handler is expected to return 404 status responses then set AllowStatusCode404Response to true.
---> LibCore.Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Cryptography error
at LibCore.Internal.NativeCrypto.CapiHelper.SignValue(SafeProvHandle hProv, SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash)
at LibCore.Security.Cryptography.Gost3410_2012_256CryptoServiceProvider.SignHash(Byte[] rgbHash)
at LibCore.Security.Cryptography.Gost3410_2012_256CryptoServiceProvider.SignHash(Byte[] rgbHash, HashAlgorithmName hashAlgName)
at LibCore.Security.Cryptography.Gost3410_2012_256.TrySignHash(ReadOnlySpan`1 hash, Span`1 destination, HashAlgorithmName hashAlgorithm, Int32& bytesWritten)
at LibCore.Security.Cryptography.GostCmsSignature.Gost2012_256CmsSignature.Sign(ReadOnlySpan`1 dataHash, HashAlgorithmName hashAlgorithmName, X509Certificate2 certificate, AsymmetricAlgorithm key, Boolean silent, String& signatureAlgorithm, Byte[]& signatureValue)
at LibCore.Security.Cryptography.GostCmsSignature.Sign(ReadOnlySpan`1 dataHash, HashAlgorithmName hashAlgorithmName, X509Certificate2 certificate, AsymmetricAlgorithm key, Boolean silent, String& oid, ReadOnlyMemory`1& signatureValue)
at LibCore.Security.Cryptography.Pkcs.Detours.CmsSignerDetour.Prefix(ReadOnlyMemory`1 data, String contentTypeOid, Boolean silent, X509Certificate2Collection& chainCerts, CmsSigner __instance, Object& __result)
at System.Security.Cryptography.Pkcs.CmsSigner.Sign_Patch1(CmsSigner this, IntPtr retbuf, ReadOnlyMemory`1 data, String contentTypeOid, Boolean silent, X509Certificate2Collection& chainCerts)
at System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner signer, Boolean silent)
at Vekas.CryptoSignerService.Business.CryptoSignerLinux.Sign(String text) in E:\TempGit\CryptoSigner_master_2023-07-27_10-44-10\Software\Vekas.CryptoSignerService\Business\CryptoSignerLinux.cs:line 79
at CryptoSignerService.Managers.CommandManager.SetCommand(BaseCSDto`1 apiCommand) in E:\TempGit\CryptoSigner_master_2023-07-27_10-44-10\Software\Vekas.CryptoSignerService\Managers\CommandManager.cs:line 64
at lambda_method2(Closure , Object , Object[] )

64 строка: foreach (var crt in storeCerts) 79 строка: signedCms.ComputeSignature(cmsSigner);

Более подобно описывал проблему тут https://www.cryptopro.ru/forum2/default.aspx?g=posts&m=142158#post142158

using (var store = new CpX509Store(StoreName.My, StoreLocation.CurrentUser))
{
    store.Open(OpenFlags.ReadOnly);
    var storeCerts = store.Certificates;
    Logger.Info(this, "storeCerts.Count = " + storeCerts.Count);
    if (storeCerts.Count > 0)
    {
        foreach (var crt in storeCerts)
        {
            Logger.Info(this, "Found ceritificate with SerialNumber = " + crt.SerialNumber);
            if (crt.SerialNumber != null && crt.SerialNumber.Equals(CryptoKey.Thumbprint))
            {
                cert = crt;
                Logger.Info(this,
                    "For singnature will be used certificate with SubjectName.Name = " + cert.SubjectName.Name);
                Logger.Info(this, "This certificate HasPrivateKey = " + cert.HasPrivateKey);
                byte[] bytesToHash = Encoding.Default.GetBytes(text);
                using (var gostCert = cert)
                {
                    var contentInfo = new ContentInfo(bytesToHash);
                    var signedCms = new SignedCms(contentInfo, Detached);
                    CmsSigner cmsSigner = new CmsSigner(gostCert);
                    signedCms.ComputeSignature(cmsSigner);
                    signature = signedCms.Encode();
                    Logger.Info(this, $"CMS Sign: {Convert.ToBase64String(signature)}");
                    signedCms.Decode(signature);
                    signedCms.CheckSignature(true);
                    return Result<string>.Success(Convert.ToBase64String(signature));
                }
            }
        }

        Logger.Info(this, $"Can't find certificate with serial number = " + CryptoKey.Thumbprint);
        return Result<string>.Fail(this,
            "Can't find certificate with serial number = " + CryptoKey.Thumbprint);
    }

    Logger.Info(this, $"Thehre is no certificates in storage");
    return Result<string>.Fail(this, "Thehre is no certificates in storage");
}
Bykiev commented 1 year ago

https://github.com/CryptoPro/libcore/issues/7

Fasjeit commented 1 year ago

Добрый день.

Для начала можно попробовать выключить TieredCompilation в csproj проекта:

<PropertyGroup>
  <TieredCompilation>false</TieredCompilation>
</PropertyGroup>

Также поможет, если есть возможность встать отладчиком в ToCryptographicException (символы не обязательно подтягивать) и посмотреть, что за код ошибки в hr.

Также если есть возможность - приложить pfx сертификата, на котором воспроизводится ошибка.

Cyber-Watcher commented 1 year ago

Разве эта та же самая ошибка?

В файле проекта я добавил то что рекомендовалось

`

false
</PropertyGroup>`

Это не помогло. Кстати тестировал уже и с последней либой LibCore 2023.7.31.1

И это только на РЕД ОС, такая ерунда

Fasjeit commented 1 year ago

На Fedora 38 + ГОСТ 2012_256 пока не воспроизводим, RedOs посмотрим чуть позже.

Также на всякий случай уточню - введена лицензия на csp? Успешно ли проходить проверка контейнера ключа?

Cyber-Watcher commented 1 year ago

Лицензия не введена. Проверка контейнера ключа проходит

Cyber-Watcher commented 1 year ago

CSP (Type:80) v5.0.10012 KC1 Release Ver:5.0.12800 OS:Linux CPU:AMD64 FastCode:READY:AVX,AVX2. DISABLED:RSA; AcquireContext: OK. HCRYPTPROV: 6840723 GetProvParam(PP_NAME): Crypto-Pro GOST R 34.10-2012 KC1 CSP Container name: "xxxxxxx" Check header passed. Signature key is not available. Exchange key is available. HCRYPTKEY: 0x687ef3 Symmetric key is not available. UEC key is not available. License: Good license (expires in 161 days) Check container passed. Check sign passed. Check verify signature on private key passed. Check verify signature on public key passed. Check import passed. Certificate in container matches AT_KEYEXCHANGE key. Keys in container: exchange key Extensions: OID: 1.2.643.2.2.37.3.10 PrivKey: Not specified - 09.04.2024 20:38:14 (UTC) Total: SYS: 0,000 sec USR: 0,020 sec UTC: 0,030 sec [ErrorCode: 0x00000000]

Cyber-Watcher commented 1 year ago

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

System.Exception: Can not find Pal.RawData property at LibCore.Security.Cryptography.X509Certificates.X509CertificateExtensions.get_RawDataPropertyInfo() at LibCore.Security.Cryptography.X509Certificates.X509CertificateExtensions.OriginalPalRawData(X509Certificate cert) at LibCore.Security.Cryptography.X509Certificates.Detours.Pal.CertificatePalProxyHelper.SubstitutePalForInstanceWithNew(X509Certificate intance) at LibCore.Security.Cryptography.X509Certificates.X509CertificateExtensions.Pal(X509Certificate cert, Boolean substitutePalIfNull) at LibCore.Internal.Cryptography.Pal.CertificateExtensionsCommon.GetPublicKey[T](X509Certificate2 certificate, Predicate1 matchesConstraints) at LibCore.Security.Cryptography.X509Certificates.Gost3410CertificateExtensions.GetGost3410_2012_256PublicKey(X509Certificate2 certificate) at LibCore.Security.Cryptography.GostCmsSignature.Gost2012_256CmsSignature.VerifySignature(ReadOnlySpan1 valueHash, ReadOnlyMemory1 signature, String digestAlgorithmOid, HashAlgorithmName digestAlgorithmName, Nullable1 signatureParameters, X509Certificate2 certificate) at LibCore.Security.Cryptography.Pkcs.Detours.SignerInfoDetour.VerifySignature(GostCmsSignature signatureProcessor, X509Certificate2 certificate, Boolean compatMode, SignerInfo instance) at LibCore.Security.Cryptography.Pkcs.Detours.SignerInfoDetour.Prefix(X509Certificate2Collection extraStore, X509Certificate2 certificate, Boolean verifySignatureOnly, SignerInfo __instance) at System.Security.Cryptography.Pkcs.SignerInfo.Verify_Patch1(SignerInfo this, X509Certificate2Collection extraStore, X509Certificate2 certificate, Boolean verifySignatureOnly) at System.Security.Cryptography.Pkcs.SignerInfo.CheckSignature(X509Certificate2Collection extraStore, Boolean verifySignatureOnly) at System.Security.Cryptography.Pkcs.SignedCms.CheckSignatures(SignerInfoCollection signers, X509Certificate2Collection extraStore, Boolean verifySignatureOnly) at System.Security.Cryptography.Pkcs.SignedCms.CheckSignature(X509Certificate2Collection extraStore, Boolean verifySignatureOnly) at Vekas.CryptoSignerService.Business.CryptoSignerLinux.Sign(String text) in E:\TempGit\CryptoSigner_master_2023-07-31_12-51-30\Software\Vekas.CryptoSignerService\Business\CryptoSignerLinux.cs:line 83 at CryptoSignerService.Managers.CommandManager.SetCommand(BaseCSDto`1 apiCommand) in E:\TempGit\CryptoSigner_master_2023-07-31_12-51-30\Software\Vekas.CryptoSignerService\Managers\CommandManager.cs:line 64

83 строка у меня вот так выглядит signedCms.CheckSignature(true);

64 так Logger.Info(this, "Begin cryptosigning " + cryptoProSigner.GetType().Name);

Fasjeit commented 1 year ago

Про "Pal.RawData" - вчера дополнительно выпустили релиз с hotfix данной проблемы (в релизах последний доступный релиз с минорной компонентой версии ".2", данная ошибка должна уйти на нём.

Cyber-Watcher commented 1 year ago

и еще один момент пробовал и с версией 12600, все тоже самое. Минорную не пробовал. Сейчас затестим.

Cyber-Watcher commented 1 year ago

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

Fasjeit commented 1 year ago

На редос 7.3.2 с сертификатом ГОСТ 2012 256 не воспроизводим

Сертификат: пароль на pfx - пустой. test_gost_256_client_2022_GOST R 34.10.2012-256.pfx.zip

using (var store = new CpX509Store(StoreName.My, StoreLocation.CurrentUser))
{
    store.Open(OpenFlags.ReadOnly);
    if (store.Certificates > 0)
    {
        var cert = storeCerts.Find(X509FindType.FindByThumbprint, "476a5547559ad9df06b091548632626ab123401a", false)[0];
        byte[] bytesToHash = Encoding.Default.GetBytes("DATA");
        using (var gostCert = cert)
        {
            var contentInfo = new ContentInfo(bytesToHash);
            var signedCms = new SignedCms(contentInfo, false);
            CmsSigner cmsSigner = new CmsSigner(gostCert);
            signedCms.ComputeSignature(cmsSigner);
            var signature = signedCms.Encode();
            signedCms.Decode(signature);
            signedCms.CheckSignature(true);
            var d = Convert.ToBase64String(signature);
            return;
        }
    }
    throw new Exception();
}

Посмотрите пожалуйста код ошибки в исключении WindowsCryptographicException, которое у вас пробрасывается, он должен быть в поле HResult.

Cyber-Watcher commented 1 year ago

Да у меня сейчас после последнего вашего патча ошибки ушли. Все вроде бы подписалось у меня на тестовом стенде. На неделе буду у заказчика развертывать уже в продакшене если что-то вылезет отпишусь. И я уже запускаю готовую сборку под РедОС, а рабочая станция у меня Linux Mint 21.2 + Rider. На набочей станции у меня таких ошибок вообще не возникало, это только под РедОС началось, когда заказчик сказал что он наше ПО будер разворачивать под этой ОС. Хотя мы рекомендовали Ubuntu 22.04. Заработало на КриптоПро 12600 и вашей либе с последним фиксом. На КриптоПро 12800 тоже глючило. Но собственно я с вами не прощаюсь :). Так как модуль работы с КриптоПро, это важная часть нашего ПО, то я тут еще буду вам ✍

Fasjeit commented 1 year ago

C csp 12800 ожидаемы некоторые проблемы, в следующем релизе должны уйти.

В текущей опубликованной ночной сборке их быть не должно - можно потестировать ещё и на ней https://github.com/CryptoPro/libcore/issues/17#issuecomment-1656585403

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

Cyber-Watcher commented 1 year ago

Добрый день! Появилась другая ошибка. Воодные данные по версии КриптоПро и либы те же что и выше.

2023-08-03 16:41:55.950 [INF] CryptoSignerLinux:Sign - user System - message - This certificate HasPrivateKey = True 2023-08-03 16:42:26.118 [ERR] An unhandled exception has occurred while executing the request. System.Security.Cryptography.CryptographicException: The certificate chain is incomplete, the self-signed root authority could not be determined. at LibCore.Security.Cryptography.Pkcs.Detours.CmsSignerDetour.Prefix(ReadOnlyMemory1 data, String contentTypeOid, Boolean silent, X509Certificate2Collection& chainCerts, CmsSigner __instance, Object& __result) at System.Security.Cryptography.Pkcs.CmsSigner.Sign_Patch1(CmsSigner this, IntPtr retbuf, ReadOnlyMemory1 data, String contentTypeOid, Boolean silent, X509Certificate2Collection& chainCerts) at System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner signer, Boolean silent) at Vekas.CryptoSignerService.Business.CryptoSignerLinux.Sign(String text) in E:\TempGit\CryptoSigner_master_2023-08-01_14-19-46\Software\Vekas.CryptoSignerService\Business\CryptoSignerLinux.cs:line 79 at CryptoSignerService.Managers.CommandManager.SetCommand(BaseCSDto`1 apiCommand) in E:\TempGit\CryptoSigner_master_2023-08-01_14-19-46\Software\Vekas.CryptoSignerService\Managers\CommandManager.cs:line 64 at lambda_method2(Closure , Object , Object[] )