Статус: Активный участник
Группы: Участники
Зарегистрирован: 13.06.2019(UTC) Сообщений: 30 Откуда: Самара Сказал(а) «Спасибо»: 4 раз
|
Есть задача получить список сертификтов и связанных с ними имена контейнеров. Можно запросить certmgr для просмотра сертификатов и распарсить вывод но это костыль. У меня вопрос как сделать через p/invoke данную задачу и возможно ли это? Пишу под .NET Core 2.1 Отредактировано пользователем 28 июня 2019 г. 8:49:48(UTC)
| Причина: точно указал платформу
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 13.06.2019(UTC) Сообщений: 30 Откуда: Самара Сказал(а) «Спасибо»: 4 раз
|
Нашел как через P/Invoke сделать вызов информации по сертификатам но вылетает access violation exception. Не совсем понимаю по чему. Код:
[DllImport("CRYPT32.DLL", SetLastError = true)]
public static extern IntPtr CertOpenStore(
uint lpszStoreProvider,
uint dwEncodingType,
IntPtr hCryptProv, //HCRYPTPROV_LEGACY
uint dwFlags,
String pvPara //const void*
);
[DllImport("CRYPT32.DLL", SetLastError = true)]
public static extern CERT_CONTEXT CertEnumCertificatesInStore(
[In]IntPtr hCertStore,
[In]CERT_CONTEXT pPrevCertContext);
[DllImport("CRYPT32.DLL", SetLastError = true, CharSet =CharSet.Auto)]
public static extern uint CertGetNameString(
[In]CERT_CONTEXT pCertContext,
uint dwType,
uint dvFlags,
IntPtr pvTypePara,
StringBuilder pszNameString,
uint cchNameString);
Код:
IntPtr hStoreHandle = IntPtr.Zero;
CERT_CONTEXT pCertContext = new CERT_CONTEXT();
var pszStoreName = ("My");
var CERT_STORE_PROV_SYSTEM = 10U;
var CERT_SYSTEM_STORE_CURRENT_USER = (uint)(1 << 16);
hStoreHandle = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
IntPtr.Zero,
CERT_SYSTEM_STORE_CURRENT_USER,
pszStoreName);
var cchNameString = 256U;
var pszNameString = new StringBuilder((int)cchNameString);
var list = new List<uint>();
do
{
pCertContext = CertEnumCertificatesInStore(hStoreHandle, pCertContext);
var chars = CertGetNameString(
pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
0,
IntPtr.Zero,
pszNameString,
cchNameString);
list.Add(chars);
} while (!pCertContext.Equals(default(CERT_CONTEXT)));
Аccess Violation вылетает при попытке получить имя. Я пробовал разные флаги передавать но он кидает эксепшн. Может кто помочь? CertInfo из pCertContext содержит IssuerId но не содержит указател на Issuer(он равен 0 остается). Отредактировано пользователем 21 июня 2019 г. 9:21:24(UTC)
| Причина: Информация о CertInfo
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,255 Сказал «Спасибо»: 545 раз Поблагодарили: 2193 раз в 1712 постах
|
Здравствуйте. Цитата: CERT_KEY_PROV_INFO_PROP_ID = 2;
Certificate: PCCERT_CONTEXT;
KeyInfo: PCRYPT_KEY_PROV_INFO; ... CertGetCertificateContextProperty(Certificate, CERT_KEY_PROV_INFO_PROP_ID, nil, pcbData) выделить память для KeyInfo CertGetCertificateContextProperty(Certificate, CERT_KEY_PROV_INFO_PROP_ID, KeyInfo, pcbData) ProvName := KeyInfo.pwszProvName; ProvType := KeyInfo.dwProvType; ContainerName := KeyInfo.pwszContainerName; освободить память KeyInfo |
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 13.06.2019(UTC) Сообщений: 30 Откуда: Самара Сказал(а) «Спасибо»: 4 раз
|
Автор: Андрей Писарев Здравствуйте. Цитата: CERT_KEY_PROV_INFO_PROP_ID = 2;
Certificate: PCCERT_CONTEXT;
KeyInfo: PCRYPT_KEY_PROV_INFO; ... CertGetCertificateContextProperty(Certificate, CERT_KEY_PROV_INFO_PROP_ID, nil, pcbData) выделить память для KeyInfo CertGetCertificateContextProperty(Certificate, CERT_KEY_PROV_INFO_PROP_ID, KeyInfo, pcbData) ProvName := KeyInfo.pwszProvName; ProvType := KeyInfo.dwProvType; ContainerName := KeyInfo.pwszContainerName; освободить память KeyInfo CertGetCertificateContextProperty кидает AccessViolation. Код:
var pcbData = 0U;
var ptr = IntPtr.Zero;
pCertContext = CertEnumCertificatesInStore(hStoreHandle, pCertContext);
CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, ptr, ref pcbData);
|
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602 Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 395 раз в 366 постах
|
Что-то я подозреваю такую схему: У Вас проверка pСertContext только в самом цикле, после перечисления всех сертификатов функция CertEnumCertificatesInStore возвращает nil как признак что все закончилось, но Вы без проверки на nil передаете полученное на получение имени или на получение свойства контекста, тут и вылетает исключение доступа к nil. Исправить легко - добавьте проверку на не nil перед действиями с pCertContext. Отредактировано пользователем 21 июня 2019 г. 11:50:27(UTC)
| Причина: Не указана
|
1 пользователь поблагодарил two_oceans за этот пост.
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 13.06.2019(UTC) Сообщений: 30 Откуда: Самара Сказал(а) «Спасибо»: 4 раз
|
Автор: two_oceans Что-то я подозреваю такую схему: У Вас проверка pСertContext только в самом цикле, после перечисления всех сертификатов функция CertEnumCertificatesInStore возвращает nil как признак что все закончилось, но Вы без проверки на nil передаете полученное на получение имени или на получение свойства контекста, тут и вылетает исключение доступа к nil. Исправить легко - добавьте проверку на не nil перед действиями с pCertContext. Спасибо, разобрался. Но есть последняя загвоздка. На Линукс машине некорректныйй вывод. Есть идеи? linuxOutput.png (15kb) загружен 14 раз(а).
|
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602 Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 395 раз в 366 постах
|
Выглядит как первая буква каждого имени.. идеи: 1) возможно дело в вариациях A W функций (когда не юникод-программа получает юникод данные для вывода в консоль); 2) неправильно выставлена длина строки (возвращается CertGetNameString).
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 13.06.2019(UTC) Сообщений: 30 Откуда: Самара Сказал(а) «Спасибо»: 4 раз
|
Автор: two_oceans Выглядит как первая буква каждого имени.. идеи: 1) возможно дело в вариациях A W функций (когда не юникод-программа получает юникод данные для вывода в консоль); 2) неправильно выставлена длина строки (возвращается CertGetNameString). Проблема решена. В Windows используется Unicode а в Linux(проверял на CentOS 7) UTF32
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close