Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.12.03;
Скачать: CL | DM;

Вниз

Получение сертификата пользователя через Active Directory   Найти похожие ветки 

 
DmitrySukach ©   (2006-07-25 10:56) [0]

Операционка MS Server 2003, установлена Microsoft Certification Authority, в ней зарегестрирован сертификат. В Active Directory этот сертификат соотнесён с некоторым пользователем U1 (Console Root\Active Directory Users and Computers -> Actions->All tasks->Name mapping->X.509 Certificates). Необходимо ПРОГРАММНО (с помощью CryptoAPI) получить этот сертификат для данного пользователя. Единственное, что нашёл в MSDN для этого: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/seccrypto/security/retrieving_an_issued_certificate_from_the_active_directory.asp. Запускаю, возвращает для пользователя U1 и для любого пользователя из данной папки Active Directory одинаковый сертификат, который берёт непонятно откуда. Меняю CertFindCertificateInStore на CertEnumCertificatesInStore в цикле - результат тот же. Для любого пользователя находится только всё тот же один сертификат. Сертификат, который "примаплен" к U1, не находит.
Есть у кого дельные советы? Буду весьма благодарен.


 
Reindeer Moss Eater ©   (2006-07-25 12:08) [1]

В каком хранилище осуществляешь поиск?


 
DmitrySukach ©   (2006-07-25 13:12) [2]

Я не думаю, что стоит переписывать всё отсюда: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/seccrypto/security/retrieving_an_issued_certificate_from_the_active_directory.asp ...

Хранилище Active Directory открывается запросом к LDAP:

   GetUserNameEx(NameFullyQualifiedDN, wszDN, &cchDN))

   //  Build the LDAP query string.
   StringCchPrintf(wszQuery, cchQuery, L"ldap:///%s?%s",
                        wszDN, L"userCertificate"))

   //  Open the Active Directory certificate store.
   hStore = CertOpenStore(CERT_STORE_PROV_LDAP, 0, 0,
                                    CERT_STORE_READONLY_FLAG, wszQuery);


 
Reindeer Moss Eater ©   (2006-07-25 13:39) [3]

А какой запрос лежит в wszQuery?


 
DmitrySukach ©   (2006-07-25 13:43) [4]

В результате работы GetUserNameEx и StringCchPrintf на вход CertOpenStore в последнем параметре идёт запрос
ldap://CN=Вася Пупкин,OU=Users,OU=City,DC=firm,DC=main?userCertificate


 
Reindeer Moss Eater ©   (2006-07-25 14:06) [5]

У меня нет AD, не проверить.
Но есть сомнение, что реально параметры не те, которые ты ожидаешь.
Трассируй каждый вызов, проверяй возвращаемые значения и getlasterror.


 
DmitrySukach ©   (2006-07-25 14:09) [6]

Ошибок нет. В том-то и дело, что один сертификат возвращает, да не тот. Вопрос в том, как получить именно "примапленный" через Name mapping...


 
Reindeer Moss Eater ©   (2006-07-25 14:22) [7]

Так если хендл хранилища получен и ошибок нет, то перечисли все серификаты в хранилище, указав фильтр, скажем "только сертификаты".
А внутри перечисления проверяй DN, CN  или по чём ты там хочешь его найти.


 
DmitrySukach ©   (2006-07-26 10:38) [8]

И всё-таки как же с помощью CryptoAPI получить сертификат присвоенный пользователю в Console Root\Active Directory Users and Computers->Actions->All tasks->Name mapping->X.509 Certificates?


 
Reindeer Moss Eater ©   (2006-07-26 11:19) [9]

Как получить сертификат - вопрос простой.
Я думаю у тебя проблема не с этим, а с получением хранилища, в котором лежит искомый сертификат.
Вот :
ACertStore - открытое хранилище
pCertContext - контекст сертификата

перечисляем все сертификаты внутри:
repeat
 pCertContext := CertEnumCertificatesInStore(ACertStore,pCertContext);
 if pCertContext <> nil then
  begin
   ...
   //здесь читаешь любые интересные тебе  проперти из контекста сертификата и выводишь их в список
   например:
   AddToMemo("Subject : "+ CertName2StrA(@pCertContext^.pCertInfo^.Subject));
   AddToMemo("Issuer  : "+ CertName2StrA(@pCertContext^.pCertInfo^.Issuer));
  end;
until pCertContext = nil;

function CertName2StrA(pBlob : PCERT_NAME_BLOB) : string;
var EncodingType : DWORD; StrType : DWORD;
   dwSize : DWORD;
begin
EncodingType := X509_ASN_ENCODING or PKCS_7_ASN_ENCODING;
StrType      := CERT_X500_NAME_STR;
dwSize       := 0;
dwSize       := CertNameToStrA(EncodingType,pBlob,StrType,nil,dwSize);
if dwSize > 1 then
 begin
  SetLength(Result,dwSize - 1);
  CertNameToStrA(EncodingType,pBlob,StrType,PChar(Result),dwSize);
 end;
end;

Этот код покажет всё, что есть в открытом тобой хранилище.
И искомого сертификата там скорее всего нет.


 
DmitrySukach ©   (2006-07-26 11:52) [10]

Искомый сертификат хранится на сервере в хранилище ROOT. К серверу коннектится пользователь, к нему в Active Directory примаплен некоторый сертификат. COM-объект на сервере должен узнать по данным пользователя, какой именно, тогда можно получить его контекст из ROOT. Вопрос, как с помощью CryptoAPI или чего угодно узнать какой сертификат примаплен к данному юзеру?


 
Reindeer Moss Eater ©   (2006-07-26 13:13) [11]

У этого юзера может быть вагон и маленькая тележка его личных сертификатов.


 
Reindeer Moss Eater ©   (2006-07-26 13:17) [12]

Надо открывать хранилище и организовывать поиск по нему указывая желаемые параметры искомого сертификата.


 
Reindeer Moss Eater ©   (2006-07-26 13:29) [13]

Если у тебя в все лежит в руте, то зачем в лдап ходить?
hStoreHandle := CertOpenSystemStore(0,"ROOT");

Далее просто перечисляешь все, или запрашиваешь по требуемым параметрам.
Если все это нужно делать внутри COM, то для этого есть CAPICOM.



Страницы: 1 вся ветка

Текущий архив: 2006.12.03;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.062 c
2-1163529374
voin666
2006-11-14 21:36
2006.12.03
Помогите, пожалуйста!


6-1152518143
Antuan
2006-07-10 11:55
2006.12.03
проблемы с отправкой письма


15-1163590192
Click
2006-11-15 14:29
2006.12.03
Снова вопрос "организации алгоритма"


2-1163685869
Новый_Юзер
2006-11-16 17:04
2006.12.03
Drag n Drop в TreeView


2-1163596338
Vitebsky
2006-11-15 16:12
2006.12.03
Динамическое создание попап-меню