Статус: Новичок
Группы: Участники
Зарегистрирован: 30.08.2012(UTC) Сообщений: 3 Откуда: Novosibirsk
|
Всем доброго времени суток! Я пытаюсь сгенерировать запрос на сертификат посредством WinAPI, на C++. Не суть важно зачем, но все-таки. Ранее у меня был кусок javascript-кода, выдраный невесть откуда, который генерировал запросы на сертификат в браузере посредством обращения к COM-интерфейсам Windows (соответственно с разделением XEnroll и CertEnroll) и я не мудрствуя лукаво решил передрать вызовы методов и интерфейсов в точности оттуда. Вот какой получился код. Код:
#define PROV_GOST_2001_DH 75
#define CRYPTOPRO_PROVIDER_NAME "Crypto-Pro"
LPCTSTR ConstructRequest(LPCTSTR commaDelemitedOIDs, LPCTSTR strDN,LPTSTR containerName) const {
BSTR dn = _bstr_t(strDN).copy();
BSTR cname = _bstr_t(containerName).copy();
BSTR* req = NULL;
BSTR provName = _bstr_t(CRYPTOPRO_PROVIDER_NAME).copy();
HR(CoInitialize(NULL));
if ((m_hResult!=S_OK)&&(m_hResult!=S_FALSE)){
m_logger.Error(_T("Не удалось инициализировать COM"));
}
CO(X500DistinguishedName,m_pSubjectName);
ERRCHK("Не удалось создать элемент управления DN");
HR(m_pSubjectName->Encode(dn,XCN_CERT_NAME_STR_FORWARD_FLAG));
ERRCHK("Не удалось задать DN элемент управления запросом на сертификат");
CO(X509PrivateKey,m_pPrivateKey);
ERRCHK("Не удалось создать элемент управления личным ключом");
HR(m_pPrivateKey->put_ProviderType((X509ProviderType)PROV_GOST_2001_DH));
HR(m_pPrivateKey->put_ExportPolicy(XCN_NCRYPT_ALLOW_EXPORT_FLAG));
HR(m_pPrivateKey->put_KeySpec(XCN_AT_KEYEXCHANGE));
HR(m_pPrivateKey->put_ContainerName(cname));
CO(X509CertificateRequestPkcs10,m_pRequest);
ERRCHK("Не удалось создать элемент управления запросом на сертификат");
HR(m_pRequest->put_Subject(m_pSubjectName));
HR(m_pRequest->InitializeFromPrivateKey(X509CertificateEnrollmentContext::ContextUser,m_pPrivateKey,NULL));
CO(X509Enrollment,m_pEnroll);
ERRCHK("Не удалось создать элемент управления сертификатами");
HR(m_pEnroll->InitializeFromRequest(m_pRequest));
m_pEnroll->CreateRequest(XCN_CRYPT_STRING_BASE64,req);
return NULL;
}
Макрос ERRCHK - для обработки ошибок, макрос HR - для установки HRESULT, CO - для создания COM-объекта. Все по идет по плану до вот этой строчки: HR(m_pRequest->InitializeFromPrivateKey(X509CertificateEnrollmentContext::ContextUser,m_pPrivateKey,NULL));на которой благополучно падает с Access Violation. В связи с чем у меня возникает несколько вопросов: 1. Как правильно конструировать из кода запросы на сертификаты? Что обязательно надо указать в ключе и реквесте? 2. Я не специалист в COM - Занимаюсь им по стольку, по скольку. Как в вышеописанных ситуациях определять источник ошибки и ее описание? В HRESULT разумеется ничего не падает. 3. Есть ли какие-либо особенности в работе с CryptoAPI на C++ в отличие, скажем, от .NET? 4. Где лучше всего читать на такие темы? Заранее спасибо за совет! Отредактировано пользователем 30 августа 2012 г. 16:59:45(UTC)
| Причина: Не указана
|
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 25.12.2007(UTC) Сообщений: 1,733  Откуда: КРИПТО-ПРО Поблагодарили: 177 раз в 168 постах
|
Цитата:HR(m_pRequest->InitializeFromPrivateKey(X509CertificateEnrollmentContext::ContextUser,m_pPrivateKey,NULL)); В качестве последнего параметра передавайте пустую строку, а не NULL. |
|
|
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 30.08.2012(UTC) Сообщений: 3 Откуда: Novosibirsk
|
Пробовал. Результат тот же, только адреса другие.
|
|
|
|
|
|
Статус: Сотрудник
Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC) Сообщений: 6,457  Откуда: КРИПТО-ПРО Сказал «Спасибо»: 39 раз Поблагодарили: 750 раз в 645 постах
|
так - работает: Цитата:HRESULT VistaEnroll::createPKCS10( BSTR rdn, BSTR usage, BSTR *Request) { HRESULT hr; IX509Enrollment* pEnroll = NULL; IX509CertificateRequestPkcs10* pPkcs10 = NULL; IX509Extensions* pExtensions = NULL; IX509ExtensionEnhancedKeyUsage* pExtensionEKU = NULL; IX509ExtensionKeyUsage * pExtensionKU = NULL; IObjectId *pEKUObjectId = NULL; IObjectIds *pEKUObjectIds = NULL; IObjectId *hashAlg = NULL; IX500DistinguishedName* provName = NULL;
//Инициализация COM hr = CoInitializeEx(NULL,COINIT_APARTMENTTHREADED); ENROLL_ERROR(hr);
IX509PrivateKey* pKey = NULL; // Create IX509PrivateKey hr = CoCreateInstance( __uuidof(CX509PrivateKey), NULL, // pUnkOuter CLSCTX_INPROC_SERVER, __uuidof(IX509PrivateKey), (void **) &pKey); ENROLL_ERROR(hr);
hr = pKey->put_ProviderType((X509ProviderType)providerType_); ENROLL_ERROR(hr);
if(providerName_) hr = pKey->put_ProviderName(providerName_); ENROLL_ERROR(hr);
if(containerName_) hr = pKey->put_ContainerName(containerName_); ENROLL_ERROR(hr);
// Create IX509ExtensionKeyUsage hr = CoCreateInstance( __uuidof(CX509ExtensionKeyUsage), NULL, CLSCTX_INPROC_SERVER, __uuidof(IX509ExtensionKeyUsage), (void **) &pExtensionKU); ENROLL_ERROR(hr);
if(atSignature) { hr = pKey->put_KeySpec(XCN_AT_SIGNATURE); ENROLL_ERROR(hr); } else { hr = pKey->put_KeySpec(XCN_AT_KEYEXCHANGE); ENROLL_ERROR(hr); }
if(LimitExchangeKeyToEncipherment) { hr = pExtensionKU->InitializeEncode((X509KeyUsageFlags) (XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE | XCN_CERT_DATA_ENCIPHERMENT_KEY_USAGE)); ENROLL_ERROR(hr); } else { hr = pExtensionKU->InitializeEncode((X509KeyUsageFlags) (XCN_CERT_KEY_ENCIPHERMENT_KEY_USAGE | XCN_CERT_DATA_ENCIPHERMENT_KEY_USAGE | XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE | XCN_CERT_NON_REPUDIATION_KEY_USAGE)); ENROLL_ERROR(hr); }
hr = pKey->put_MachineContext((provFlags_ & CRYPT_MACHINE_KEYSET) != 0); ENROLL_ERROR(hr);
hr = pKey->put_Silent((provFlags_ & CRYPT_SILENT) != 0); ENROLL_ERROR(hr);
if(useExisting_) hr = pKey->Open(); else { if(Exportable) pKey->put_ExportPolicy(XCN_NCRYPT_ALLOW_EXPORT_FLAG); hr = pKey->Create(); } ENROLL_ERROR(hr); if(!containerName_) { hr = pKey->get_ContainerName(&containerName_); ENROLL_ERROR(hr); }
// Create IX509Enrollment hr = CoCreateInstance( __uuidof(CX509CertificateRequestPkcs10), NULL, // pUnkOuter CLSCTX_INPROC_SERVER, __uuidof(IX509CertificateRequestPkcs10), (void **) &pPkcs10); ENROLL_ERROR(hr);
if(provFlags_ & CRYPT_MACHINE_KEYSET) hr = pPkcs10->InitializeFromPrivateKey(ContextMachine, pKey, NULL); else hr = pPkcs10->InitializeFromPrivateKey(ContextUser, pKey, NULL); ENROLL_ERROR(hr);
} Отредактировано пользователем 31 августа 2012 г. 3:25:29(UTC)
| Причина: Не указана |
|
|
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 30.08.2012(UTC) Сообщений: 3 Откуда: Novosibirsk
|
maxdm, спасибо большое! Буду разбираться.
|
|
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close