Метод IBackgroundCopyServerCertificateValidationCallback::ValidateServerCertificate (bits10_3.h)

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

Синтаксис

HRESULT ValidateServerCertificate(
  IBackgroundCopyJob  *job,
  IBackgroundCopyFile *file,
  DWORD               certLength,
  const BYTE []       certData,
  DWORD               certEncodingType,
  DWORD               certStoreLength,
  const BYTE []       certStoreData
);

Параметры

job

Тип: IBackgroundCopyJob*

Задание.

file

Тип: IBackgroundCopyFile*

Передаваемый файл.

certLength

Тип: DWORD

Длина данных сертификата в байтах.

certData

Тип: const BYTE []

Массив байтов, содержащий данные сертификата. Число байтов должно соответствовать certLength.

certEncodingType

Тип: DWORD

Тип кодирования сертификата.

certStoreLength

Тип: DWORD

Длина данных хранилища сертификатов в байтах.

certStoreData

Тип: const BYTE []

Массив байтов, содержащий данные хранилища сертификатов. Число байтов должно соответствовать certStoreLength.

Возвращаемое значение

Верните S_OK , чтобы указать, что сертификат является допустимым. В противном случае верните код ошибкиHRESULT, чтобы указать, что сертификат неприемлем.

Комментарии

Проверка сертификата выполняется в два этапа. Первый этап — это этап операционной системы (ОС), на котором ОС выполняет стандартный набор проверок сертификата. После этого, если этап ОС пройдет сертификат, будет вызван обратный вызов для выполнения дополнительной проверки.

Реализуйте этот метод проверки, если требуется выполнить собственные проверки сертификата сервера. Ваши собственные проверки являются дополнением к обычным проверкам сертификатов ОС.

Если метод проверки отклоняет сертификат, задание перейдет в BG_JOB_STATE_TRANSIENT_ERROR с контекстом ошибки задания BG_ERROR_CONTEXT_SERVER_CERTIFICATE_CALLBACK и ошибкой HRESULT из обратного вызова. Если не удалось вызвать обратный вызов (например, из-за того, что для проверки сертификата сервера после завершения программы требуется BITS), код ошибки задания будет BG_E_SERVER_CERT_VALIDATION_INTERFACE_REQUIRED. При следующем запуске приложение может исправить эту ошибку, настроив обратный вызов проверки и возобновив задание.

BITS вызывает этот метод обратного вызова, только если вы реализуете интерфейс IBackgroundCopyServerCertificateValidationCallback и передаете его в IBackgroundCopyJobHttpOptions3::SetServerCertificateValidationInterface.

Интерфейс проверки становится недопустимым при завершении работы приложения; BITS не поддерживает запись интерфейса проверки. В результате процесс инициализации приложения должен вызывать SetServerCertificateValidationInterface для существующих заданий, для которых требуется получать запросы на проверку сертификата.

Если несколько приложений вызывают SetServerCertificateValidationInterface , чтобы задать интерфейс уведомлений для задания, последнее вызывающее его приложение будет получать уведомления. Другие приложения не будут получать уведомления.

Ниже приведены общие действия по проверке сертификата. Имейте в виду, что эти шаги являются лишь примером. Фактическая проверка находится под вашим контролем. Кроме того, шаги 5–7 в значительной степени совпадают с тем, что делает ОС на этапе проверки ОС.

  1. Вызовите CertCreateCertificateContext с certEncodingTypeпомощью , certDataи certLength , чтобы получить CERT_CONTEXT.

  2. Объявите и инициализируйте структуру CRYPT_DATA_BLOB (определенную в wincrypt.h) с помощью сериализованного большого двоичного объекта памяти, переданного через certStoreLength и certStoreData.

DATA_BLOB storeData{};
storeData.cbData = certStoreLength;
storeData.pbData = const_cast<PBYTE>(certStoreData);
  1. Получите дескриптор цепочки сертификатов, вызвав CertOpenStore с CERT_STORE_PROV_SERIALIZED, 0, nullptr, флагами и указателем на CRYPT_DATA_BLOB из шага 2.
  2. Получите указатель на контекст цепочки сертификатов, вызвав CertGetCertificateChain с nullptr, certContext, nullptr, дескриптором из шага 3, параметрами цепочки, флагами и nullptr.
  3. Создайте политику проверки сертификатов.
CERT_CHAIN_POLICY_PARA policyParams{};
policyParams.cbSize = sizeof(policyParams);
policyParams.dwFlags =
    CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG |
    CERT_CHAIN_POLICY_IGNORE_WRONG_USAGE_FLAG |
    CERT_CHAIN_POLICY_IGNORE_INVALID_NAME_FLAG |
    CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG;
  1. Вызовите CertVerifyCertificateChainPolicy с типом политики, контекстом цепочки, параметрами политики и состоянием политики.
  2. Преобразуйте ошибку Win32 (policyStatus.dwError) в HRESULT и верните ее.

Ниже описано поведение кэширования проверки BITS. BITS поддерживает кэш для каждого задания сертификатов, прошедших пользовательскую проверку. Это позволяет избежать избыточной и потенциально дорогостоящей повторной проверки в течение всего времени существования задания. Кэш состоит из конечной <точки сервера, кортежей хэша> сертификатов, где конечная точка определяется как имя сервера:порт. Если задание уже разрешило определенный сертификат из определенной конечной точки, обратный вызов больше не будет вызываться.

Конечно, сертификат должен будет проходить через логику проверки ОС при каждой попытке подключения (вы можете настроить логику проверки ОС с помощью вызова метода IBackgroundCopyJobHttpOptions::SetSecurityFlags), в котором рассматриваются чувствительные к времени угловые случаи, например, когда сертификат был действителен совсем недавно (с точки зрения секунд), но срок действия сертификата истек.

BITS не кэширует сертификаты, которые считаются недействительными обратным вызовом проверки, предоставленным приложением. Важно знать обо всех неудачных попытках подключения, чтобы обнаруживать вредоносные развертывания на уровне приложения. Например, одноразовый недопустимый сертификат имеет гораздо меньшее значение, чем тысячи недопустимых сертификатов с того же сервера.

Кэш сертификатов задания очищается при каждом вызове SetServerCertificateValidationInterface, так как он указывает на то, что логика проверки сертификата сервера приложения изменилась.

Требования

Требование Значение
Минимальная версия клиента Windows 10, версия 1809 [только классические приложения]
Минимальная версия сервера Windows Server 2016 [только классические приложения]
Верхняя часть bits10_3.h (включая Bits.h)
Библиотека Bits.lib
DLL Bits.dll

См. также раздел

IBackgroundCopyJobHttpOptions3::SetServerCertificateValidationInterface