Расширение функциональных возможностей CertOpenStore
Хранилище сертификатов является центральным для всех операций управления сертификатами. Функциональные возможности функции CertOpenStore можно расширить с помощью устанавливаемой (или зарегистрированной) функции certificate-store-provider. Общие сведения об установке или регистрации функций для использования с CryptoAPI см. в разделе Общие сведения об OID.
Примечание
Пользовательские хранилища сертификатов не переносятся автоматически при выполнении автоматических развертываний. Чтобы перенести пользовательские хранилища сертификатов, необходимо создать манифест для переноса пользовательских хранилищ и использовать средство миграции пользовательской среды Windows (USMT).
CertOpenStore открывает пустое хранилище в памяти и вызывает функцию поставщика хранилища (если она зарегистрирована или установлена) с помощью идентификатора объекта (OID), переданного в параметре lpszStoreProvider . Список стандартных типов поставщиков, которые предоставляются вместе с CryptoAPI, см. в разделе CertOpenStore.
Функция поставщика хранилища копирует свои сертификаты и списки отзыва сертификатов (CRL) в хранилище в памяти, указанное переданным ей дескриптором hCertStore . Новая функция поставщика хранилища может использовать любую из функций хранилища сертификатов CryptoAPI, например CertAddCertificateContextToStore или CertAddSerializedElementToStore, чтобы добавить свои сертификаты и списки отзыва сертификатов в хранилище в памяти. Кроме того, функция store-provider при необходимости возвращает значения для всех элементов данных структуры CERT_STORE_PROV_INFO . Функция должна обновить эту структуру только в том случае, если она поддерживает дополнительные функции обратного вызова. Например, если хранилище должно было быть хранилищем только для чтения, поддержка других функций обратного вызова, скорее всего, не потребуется. Дополнительные сведения и прототипы возможных функций обратного вызова см. в разделе Функции обратного вызова поставщика хранилища сертификатов.
Хранилище TrustedPeople на пользователя ограничено предопределенными физическими хранилищами. Невозможно расширить хранилище TrustedPeople для каждого пользователя. Однако вы можете расширить хранилище TrustedPeople на локальном компьютере.
Windows XP и Windows Server 2003: Хранилище TrustedPeople для каждого пользователя не ограничивается предварительно определенными физическими хранилищами.
Одним из элементов данных структуры CERT_STORE_PROV_INFO является массив rgpvStoreProvFunc . Если функция поставщика хранилища должна поддерживать одну или несколько функций обратного вызова, она должна предоставлять указатели для этого массива. Эти указатели должны указывать на функции обратного вызова, которые будут использоваться для других действий хранилища сертификатов (например, закрытия хранилища). На следующем рисунке показан поток этого процесса.
Как показано на следующем рисунке, после открытия хранилища другие функции CryptoAPI (например , CertCloseStore) используют массив указателей для доступа к функциям обратного вызова, которые выполняют требуемую задачу. Определение структуры CERT_STORE_PROV_INFO и прототипы функций обратного вызова по умолчанию, поставляемых с CryptoAPI, отображаются в разделе Функции обратного вызова поставщика хранилища сертификатов.
API хранилища позволяют поставщику хранилища поддерживать сертификаты, списки отзыва сертификатов и списки доверия сертификатов (CCL) за пределами кэша хранилища (например, внешней базы данных сертификатов, предоставляемой базой данных сервера сертификатов Майкрософт).
CertOpenStore отправляет с помощью параметра pszStoreProvider соответствующую функцию поставщика CertDllOpenStoreProv . Поставщик возвращает сведения в параметре pStoreProvInfo , указывающие на структуру CERT_STORE_PROV_INFO . Структура CERT_STORE_PROV_INFO содержит элемент dwStoreProvFlags . Добавлен флаг CERT_STORE_PROV_EXTERNAL_FLAG, позволяющий поставщику указать, что сертификаты, списки отзыва сертификатов и списки сертификатов являются внешними по сравнению с кэшем хранилища.
CertDllOpenStoreProv возвращает массив функций обратного вызова. Поставщик может реализовать следующие функции обратного вызова:
- CERT_STORE_PROV_CLOSE_FUNC
- CERT_STORE_PROV_READ_CERT_FUNC
- CERT_STORE_PROV_WRITE_CERT_FUNC
- CERT_STORE_PROV_DELETE_CERT_FUNC
- CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC
- CERT_STORE_PROV_READ_CRL_FUNC
- CERT_STORE_PROV_WRITE_CRL_FUNC
- CERT_STORE_PROV_DELETE_CRL_FUNC
- CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC
- CERT_STORE_PROV_READ_CTL_FUNC
- CERT_STORE_PROV_WRITE_CTL_FUNC
- CERT_STORE_PROV_DELETE_CTL_FUNC
- CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC
При вызовах функций обратного вызова WRITE_CERT, WRITE_CRL и WRITE_CTL при установке CERT_STORE_PROV_WRITE_ADD_FLAG верхние 16 бит параметра dwFlags содержат значение dwAddDisposition . Для поддержки внешних хранилищ поставщик может реализовать следующие функции обратного вызова:
- CERT_STORE_PROV_FIND_CERT_FUNC
- CERT_STORE_PROV_FREE_FIND_CERT_FUNC
- CERT_STORE_PROV_GET_CERT_PROPERTY_FUNC
- CERT_STORE_PROV_FIND_CRL_FUNC
- CERT_STORE_PROV_FREE_FIND_CRL_FUNC
- CERT_STORE_PROV_GET_CRL_PROPERTY_FUNC
- CERT_STORE_PROV_FIND_CTL_FUNC
- CERT_STORE_PROV_FREE_FIND_CTL_FUNC
- CERT_STORE_PROV_GET_CTL_PROPERTY_FUNC
Функции обратного вызова сертификата имеют следующие подписи:
typedef struct _CERT_STORE_PROV_FIND_INFO {
DWORD cbSize;
DWORD dwMsgAndCertEncodingType;
DWORD dwFindFlags;
DWORD dwFindType;
const void *pvFindPara;
} CERT_STORE_PROV_FIND_INFO, *PCERT_STORE_PROV_FIND_INFO;
typedef const CERT_STORE_PROV_FIND_INFO CCERT_STORE_PROV_FIND_INFO,
*PCCERT_STORE_PROV_FIND_INFO;
typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_FIND_CERT)(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_STORE_PROV_FIND_INFO pFindInfo,
IN PCCERT_CONTEXT pPrevCertContext,
IN DWORD dwFlags,
IN OUT void **ppvStoreProvFindInfo,
OUT PCCERT_CONTEXT *ppProvCertContext
);
typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_FREE_FIND_CERT)(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pCertContext,
IN void *pvStoreProvFindInfo,
IN DWORD dwFlags
);
typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_GET_CERT_PROPERTY)(
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pCertContext,
IN DWORD dwPropId,
IN DWORD dwFlags,
OUT void *pvData,
IN OUT DWORD *pcbData
);
Сигнатуры для функций обратного вызова CRL и CTL идентичны приведенным выше с указателем на CERT_CONTEXT заменен указателем на CRL_CONTEXT или CTL_CONTEXT.
Обратный вызов FIND_CERT вызывается при перечислении, поиске или добавлении сертификатов API хранилища. PPrevCertContext и ppvStoreProvFindInfo имеют значение NULL , чтобы инициировать новый метод FIND. Возвращенный ppvStoreProvFindInfo передается обратно при следующем поиске, когда поставщик может освободить его. Поставщик может задать все, некоторые или никакие свойства сертификата. Поставщик может отложить до вызова обратного вызова GET_CERT_PROPERTY. Поставщикам рекомендуется задать как можно больше свойств, чтобы разрешить копирование в другое хранилище.
В CertFindCertificateInStore поддерживаются следующие типы поиска сертификатов:
- CERT_FIND_ANY
- CERT_FIND_SHA1_HASH
- CERT_FIND_MD5_HASH
- CERT_FIND_PROPERTY
- CERT_FIND_PUBLIC_KEY
- CERT_FIND_SUBJECT_NAME
- CERT_FIND_SUBJECT_ATTR
- CERT_FIND_ISSUER_NAME
- CERT_FIND_ISSUER_ATTR
- CERT_FIND_SUBJECT_STR_A
- CERT_FIND_SUBJECT_STR_W
- CERT_FIND_ISSUER_STR_A
- CERT_FIND_ISSUER_STR_W
- CERT_FIND_KEY_SPEC
- CERT_FIND_ENHKEY_USAGE
Обратный вызов FIND_CERT вызывается для каждого из указанных выше типов поиска. Параметры, передаваемые в CertFindCertificateInStore , копируются непосредственно в структуру CERT_STORE_PROV_FIND_INFO перед вызовом обратного вызова FIND_CERT. Дополнительные сведения о значениях полей для различных типов поиска структуры CERT_STORE_PROV_FIND_INFO см. в разделе CertFindCertificateInStore.
Следующие типы поиска сертификатов поддерживают API CertGetSubjectCertificateFromStore и CertGetIssuerCertificateFromStore и помогают определить, существует ли сертификат в хранилище перед добавлением:
- CERT_FIND_SUBJECT_CERT
- CERT_FIND_ISSUER_OF
- CERT_FIND_EXISTING
Для CERT_FIND_SUBJECT_CERT параметр pvFindPara указывает на структуру CERT_INFO , содержащую issuer и SerialNumber субъекта. Для CERT_FIND_ISSUER_OF pvFindPara указывает на CERT_CONTEXT структуру субъекта. Для CERT_FIND_EXISTING pvFindPara указывает на CERT_CONTEXT сертификата, проверка его существования в хранилище.
Обратный вызов FREE_FIND_CERT вызывается, когда сертификат, возвращенный обратным вызовом FIND_CERT, не был освобожден путем использования в последующих следующих FIND_CERT, что приводит к уменьшению числа ссылок до нуля или путем освобождения путем вызова CertCloseStore. Перед вызовом обратного вызова CLOSE все сертификаты, возвращенные обратным вызовом FIND_CERT, должны быть освобождены поставщику путем передачи в вызов обратного вызова FIND_CERT или вызова обратного вызова FREE_FIND_CERT. То же самое относится к обратным вызовам CRL и CTL.
Обратный вызов GET_CERT_PROPERTY вызывается CertGetCertificateContextProperty , если не удается найти указанное свойство для параметра pCertContext . То же самое относится к GET_CRL_PROPERTY и GET_CTL_PROPERTY.
Обратный вызов FIND_CRL вызывается, когда API хранилища перечисляют или получают списки отзыва сертификатов и перед добавлением списка отзыва сертификатов. Будут определены следующие типы поиска списка отзыва сертификатов:
Для CRL_FIND_ISSUED_BY pvFindPara — это указатель на CERT_CONTEXT издателя списка отзыва сертификатов. Для CRL_FIND_EXISTING pvFindPara — это указатель на CRL_CONTEXT списка отзыва сертификатов, чтобы определить, существует ли он уже в хранилище.
Обратный вызов FIND_CTL вызывается, когда API-интерфейсы хранилища перечисляют или находят списки CCL. В CertFindCTLInStore поддерживаются следующие типы поиска CTL:
- CTL_FIND_ANY
- CTL_FIND_SHA1_HASH
- CTL_FIND_MD5_HASH
- CTL_FIND_USAGE
- CTL_FIND_SUBJECT
- CTL_FIND_EXISTING
Обратный вызов FIND_CTL вызывается для каждого из указанных выше типов поиска. Параметры, передаваемые в CertFindCTLInStore , копируются непосредственно в структуру CERT_STORE_PROV_FIND_INFO перед вызовом обратного вызова FIND_CTL. Дополнительные сведения о значениях полей для различных типов поиска структуры CERT_STORE_PROV_FIND_INFO см. в разделе CertFindCTLInStore.
Тип поиска CTL_FIND_EXISTING CTL помогает определить, существует ли список CTL в хранилище перед добавлением CTL.
Для CTL_FIND_EXISTING pvFindPara — это указатель на CTL_CONTEXT структуру CTL, чтобы определить, существует ли он уже в хранилище.