18.01.2006 20:25:07CertOpenStore из буфера Ответов: 10
Victor Y. SKlyar
я получаю по сети сертификат в буфер,
для того чтобы его установить я сохраняю его в файл и открываю с помощью CertOpenStore с флагом CERT_STORE_PROV_FILENAME.
Можно ли каким либо образом открыть хранилище из буфера не прибегая к созданию промежуточного файла?
 
Ответы:
19.01.2006 17:43:58Kirill Sobolev
Можно, но зависит от того как оно в буфер сохранено.
Посмотрите CERT_STORE_PROV_PKCS7 и CERT_STORE_PROV_SERIALIZED.
19.01.2006 17:59:39Victor Y. Sklyar
сертификат представлен в буфере таким образом:

-----BEGIN CERTIFICATE-----
MIICoDCCAgmgAwIBAgIBADANBgkqhkiG9w0BAQQFADBFMQswCQYDVQQGEwJBVTET
...
KRY9aYgKz3IUCXGF/Z6AFlT+4zrcutplMllu/wNDE9vNa1z8eUUC5kdGFSStuq2c
HE/TOQ==
-----END CERTIFICATE-----

19.01.2006 18:03:30Kirill Sobolev
Если это простой сертификат и не хочется возиться с временными файлами, то надо преобразовать из base64 в der и воспользоваться CertCreateCertificateContext.
19.01.2006 18:19:52Victor Y. Sklyar
в таком случае прийдется из буфера выделять непоследственно Base64 часть, т.е. убирать "-----BEGIN CERTIFICATE-----" и "-----END CERTIFICATE-----"?

Кстати чтобы экспортировать сертификат из хранилища в том же виде нужно проделать обратную операцию или есть другие методы?
19.01.2006 18:23:12Kirill Sobolev
Да, придется.
Если экспортировать в base64 то именно так.
19.01.2006 18:32:37Victor Y. Sklyar
TCHAR buf[1024]; //тут наш сертификат

TCHAR tszTempPath[MAX_PATH];
::GetTempPath(MAX_PATH, tszTempPath);

TCHAR tszTempFileName[MAX_PATH];
::GetTempFileName(tszTempPath, _T(""), 0, tszTempFileName);

//создаем такой файл который удалиться сразу по закрытию
HANDLE hFile = ::CreateFile(tszTempFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY, NULL);

//запишем буфер в файл
DWORD dwWritten;
::WriteFile(hFile, buf, 1024, &dwWritten, NULL);

//позиционируемся в начало
::SetFilePointer(hFile, 0, 0, FILE_BEGIN));

//открываем по handle
HCERTSTORE hCertStore = ::CertOpenStore(CERT_STORE_PROV_FILE, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, NULL, CERT_STORE_OPEN_EXISTING_FLAG, hFile);

но тут hCertStore = 0;
GetLastError() возвращает CRYPT_E_FILE_ERROR

почему?
вариант с CERT_STORE_PROV_FILENAME работает
19.01.2006 18:37:25Kirill Sobolev
Потому что
CERT_STORE_PROV_FILE:... This provider expects the file to contain only a serialized store and not either PKCS #7 signed messages or a single encoded certificate.
А CERT_STORE_PROV_FILENAME_A:... The provider opens the file and first attempts to read the file as a serialized store, then as a PKCS #7 signed message, and finally as a single encoded certificate.
19.01.2006 18:55:19Victor Y. Sklyar
не понял... :-/

получается что с CERT_STORE_PROV_FILE можно открывать только serialized store сертификат? а PKCS #7 signed messages и single encoded нельзя?..
А CERT_STORE_PROV_FILENAME_A:... The provider opens the file and first attempts to read the file as a serialized store, then as a PKCS #7 signed message, and finally as a single encoded certificate.
19.01.2006 18:56:57Kirill Sobolev
Да, все именно так.
19.01.2006 19:07:31Victor Y. Sklyar
спасибо за помощь, я потратил на это много времени...
еще раз спасибо