29.08.2005 12:29:33имена контейнеров Ответов: 4
zebra
Здравствуйте. Подскажите, пожалуйста, что можно сделать в сл. ситуации.

...HCERTSTORE* hSystemStore, HCRYPTPROV* hProv, PCCERT_CONTEXT* pCertContext....

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

if (!CryptAcquireContext(hProv, strContainerName,strCSPName,dwCSPType , 0))
{
::MessageBox(NULL,"CryptAcquireContext ERROR:01 ",
NULL,MB_OK|MB_ICONERROR);
return FALSE;
}

if (!(*hSystemStore = CertOpenSystemStore(*hProv, "MY")))//"MY"
{
::MessageBox(NULL,"CertOpenSystemStore ERROR: can not open.",
NULL,MB_OK|MB_ICONERROR);
return FALSE;
}

*pCertContext=CertFindCertificateInStore (*hSystemStore,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0, CERT_FIND_SUBJECT_STR,
lpCertSubjectUnicode , NULL);

...........Получается сл. ситуация. Вне зависимости от имени контейнера (указанного при CryptAcquireContext (...strContainerName...), с помощью CertFindCertificateInStore могу получить любой сертификат (для данного пользователя и данного криптопровайдера).
Даже, если он не лежит в контейнере strContainerName... так получается?!

Тогда для работы с любым сертификатом в Store могу указать любое lpCertSubjectUnicode. И буду работать с этим сертификатом. Тогда значение имени контейнера (CryptAcquireContext (...strContainerName...), сводится к нулю. Могу просто указать любой контейнер для данного пользователя (имя возьму из ветки реестра), а работать все равно с другими. Получается, так?

спасибо.
 
Ответы:
29.08.2005 12:56:05Василий
Не вполне понятный вопрос. Если Вы хотите самостоятельно открывать контейнер (по имени) и сертификат - пожалуйста. Но, при этом Вы и заботитесь об их соответствии друг другу. Не получится использовать сертификат со значением открытого ключа, которое не соответствует закрытому ключу в контейнере.

Собственно, я уже указывал Вам, как получить хендл контейнера по сертификату, открытому из хранилища сертификатов (или из файла сертификата при условии, что в хранилище сертификат установлен). При этом имя контейнера не нужно знать. Весь смысл высокоуровневых функций в том, что функциям задаются только сертификаты, а они уже самостоятельно, когда нужно, работают с контейнерами.
29.08.2005 13:29:44zebra
да получается так, что я могу открыть один контейнер - CryptAcquireContext,, а работать с сертификатом из другого совершенно контейнера, указав, например, владельца сертификата в функцию CertFindCertificateInStore...
29.08.2005 13:33:43zebra
и не подскажите, пожалуйста, каким образом открыть из файла сертификат (функция и т.д).

29.08.2005 14:03:03Василий
Можно, но зачем?
А если не требуется доступ к секретному ключу в контейнере, можно CryptAcquireContext вызвать с флажком CRYPT_VERIFYCONTEXT и с указанием только типа CSP, например,
CryptAcquireContext(
&hProv,
NULL,
NULL,
75,
CRYPT_VERIFYCONTEXT)

По второму.
DWORD dwCertLen;
BYTE *bCert;
PCCERT_CONTEXT pCert = 0;

dwCertLen = ...//размер файла сертификата

hFile=fopen("...","rb");
fread(bCert,1,dwCertLen,hFile);
fclose(hFile);

pCert = CertCreateCertificateContext (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, bCert, dwCertLen);