25.09.2006 12:22:40Как проинициализировать CAPICOMовский Certificate? Ответов: 9
Dmitry
Cоздаю CAPICOM.Certificate.3, получаю его ICertContext, заталкиваю с помощью CertContext имеющийся PCCERT_CONTEXT от CryptoAPI. Не работает, говорит The Certificate object has not been properly initialized.
 
Ответы:
25.09.2006 13:33:25Kirill Sobolev
Надо код смотреть.
25.09.2006 15:34:00Dmitry
...

#include <initguid.h>
DEFINE_GUID(CLSID_CAPICOM_Certificate_3, 0x9171C115, 0x7DD9, 0x46BA, 0xB1, 0xE5, 0x0E, 0xD5, 0x0A, 0xFF, 0xC1, 0xB8); // 9171C115-7DD9-46BA-B1E5-0ED50AFFC1B8
DEFINE_GUID(IID_ICertificate2, 0x6FE450DC, 0xAD32, 0x48D4, 0xA3, 0x66, 0x01, 0xEE, 0x7E, 0x0B, 0x13, 0x74); // 6FE450DC-AD32-48D4-A366-01EE7E0B1374
DEFINE_GUID(IID_ICertContext, 0x9E7D3477, 0x4F63, 0x423E, 0x8A, 0x45, 0xE1, 0x3B, 0x2B, 0xB8, 0x51, 0xA2); // 9E7D3477-4F63-423E-8A45-E13B2BB851A2
__interface ICertContext : IUnknown {
HRESULT _stdcall CertContext(long* ppCertContext);
HRESULT _stdcall CertContext(long ppCertContext);
HRESULT _stdcall FreeContext(long pCertContext);
};

...

STDMETHODIMP CCrypto::VerifyFile(BSTR FileName, IDispatch** Signer)
{

...

PCCERT_CONTEXT pSignerCert;
while (1)
{
if (!CryptVerifyMessageSignature(&cvmp, 0, mf.GetPtr(), mf.GetSize(), pbDecoded, &cbDecoded, &pSignerCert))

...

ICertContext *pCC;
CoCreateInstance(CLSID_CAPICOM_Certificate_3, NULL, CLSCTX_INPROC_SERVER, IID_ICertContext, (PVOID *)&pCC);
pCC->CertContext((long)pSignerCert);
pCC->QueryInterface(IID_ICertificate2, (PVOID *)Signer);
pCC->Release();

...
25.09.2006 16:58:30Kirill Sobolev
мб pSignerCert уже невалидный к моменту вызова pCC->CertContext?
25.09.2006 20:53:35Dmitry
Исключено. Разумеется ведь я это проверял. Даже дупликат делал. Не помогает. А есть пример реально работающего кода?
26.09.2006 10:11:05Kirill Sobolev
Есть, но с ATL.
26.09.2006 11:31:34Dmitry
Да без разницы. Очень хотелось бы посмотреть.
26.09.2006 15:31:22Kirill Sobolev
интерфейс ICPCertificate унаследован от ICertificate2

CComQIPtr<ICPCertificate> m_pSignerCert;
CComQIPtr<ICertContext, &IID_ICertContext> pIContext;
PCCERT_CONTEXT pCertContext = NULL;

m_pSignerCert.CoCreateInstance(__uuidof(Certificate20));
m_pSignerCert->QueryInterface(&pIContext);
pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,pIssuer->pbCertEncoded, pIssuer->cbCertEncoded);
pIContext->put_CertContext((LONG) pCertContext);
26.09.2006 17:20:27Dmitry
Разница только в том что у меня PCCERT_CONTEXT из подписанного сообщения, а тебя с нуля создается. Кстати pCC->CertContext((LONG)pSignerCert); возвращает ERROR_SXS_KEY_NOT_FOUND 14007L (The requested lookup key was not found in any active activation context.) Что бы это значило?
11.10.2006 16:58:53Dmitry
Наконец-то разобрался. Проблема была в декларации интерфейса. Правильный вариант:

__interface ICertContext : IUnknown {
HRESULT _stdcall CertContext(long ppCertContext);
HRESULT _stdcall CertContext(long* ppCertContext);
HRESULT _stdcall FreeContext(long pCertContext);
};

Вобщем лучше всегда всё импортируйте, даже самую мелочь...