internal static void FreeHandleCertificate(IntPtr certHandle) { if (IsUnix) { CApiExtUnix.CertFreeCertificateContext(certHandle); } else { CApiExtWin.CertFreeCertificateContext(certHandle); } }
internal bool VerifyDetachedMessage(byte[] signatureData, byte[] messageData, bool isCheckTrusted, ref X509Certificate2 certFromSign) { log.LogDebug("Запущен метод проверки открепленной подписи под Windows платформой."); // Заполняем буфер с информацией о данных на основе которых получена подпись IntPtr messagePtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(byte)) * messageData.Length); Marshal.Copy(messageData, 0, messagePtr, messageData.Length); IntPtr[] rgpbToBeSigned = new IntPtr[1] { messagePtr }; int[] rgcbToBeSigned = new int[1] { messageData.Length }; GCHandle pCertContext = GCHandle.Alloc(IntPtr.Zero, GCHandleType.Pinned); CRYPT_VERIFY_MESSAGE_PARA verifyParams = new CRYPT_VERIFY_MESSAGE_PARA() { cbSize = (int)Marshal.SizeOf(typeof(CRYPT_VERIFY_MESSAGE_PARA)), dwMsgAndCertEncodingType = PKCS_7_OR_X509_ASN_ENCODING, hCryptProv = 0, pfnGetSignerCertificate = IntPtr.Zero, pvGetArg = IntPtr.Zero }; try { log.LogDebug("Выполняем проверку открепленной подписи используя метод CryptVerifyDetachedMessageSignature."); bool result = CApiExtWin.CryptVerifyDetachedMessageSignature( ref verifyParams, // Verify parameters. 0, // Signer index. signatureData, // Buffer for decoded message. signatureData.Length, // Size of buffer. 1, rgpbToBeSigned, // Pointer to signed BLOB. rgcbToBeSigned, // Size of signed BLOB. pCertContext.AddrOfPinnedObject() ); if (!result) { log.LogError($"Метод проверки подписи CryptVerifyDetachedMessageSignature вернул ошибку. Статус код ошибки: {Marshal.GetLastWin32Error()}."); return(result); } log.LogDebug($"Метод CryptVerifyDetachedMessageSignature вернул true. Пытаемся получить сертификат из подписи."); try { log.LogDebug($"Флаг проверки сертификата в списке доверенных издателей {(isCheckTrusted ? "установлен" : "не установлен")}"); // Информацию о сертификате из подписи можно получить только если проверка вернула true, иначе возникнет исключение certFromSign = new X509Certificate2((IntPtr)pCertContext.Target); if (isCheckTrusted) { log.LogDebug("Сертификат из подписи успешно получен. Проверяем наличие сертификата в списке доверенных издателей."); var trustedCerts = GetTrustedCertificates(); if (trustedCerts.Count <= 0) { log.LogError("Список доверенных издателей пуст. Отсутствует доверие к сертификату."); return(false); } if (!trustedCerts.Contains(certFromSign)) { log.LogError("Сертификат указанный в подписи не найден среди доверенных издателей."); return(false); } } } catch (Exception ex) { log.LogError($"Необработанная ошибка при попытке проверить сертификат из подписи на наличие в списке доверенных. {ex.Message}."); return(false); } finally { CApiExtWin.CertFreeCertificateContext((IntPtr)pCertContext.Target); } log.LogDebug("Проверка выполнена. Подпись корректна."); return(result); } finally { pCertContext.Free(); } }
protected override bool ReleaseHandle() { CApiExtWin.CertFreeCertificateContext(handle); return(true); }