Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

самописный CSP [WinXP]


василий иванович ©   (2009-06-15 14:49:00) 

Реализую собственный криптопровайдер для тестовых целей(так надо)
Написал DLL, реализовал все функции CP*** из этого списка http://msdn.microsoft.com/en-us/library/aa382022(VS.85).aspx

Затем пропатчил advapi32.dll, подписал длл и зарегистрировал все в реестре.

В тестовом приложении вызываю CryptAcquireContextдля моего провайдера.
После этого я вижу (по текстовому логу), что криптоапи загрузило мою длл и вызвало из нее CPAcquireContext
внутри CPAcquireContext я вижу правильные значения всех инпут параметров, которые передаю из тестового приложения.
Проблема:
Значение, присваиваемое вар-параметру hProv не возвращается наружу (в хост-приложение)
Причем похоже на то, что криптоапи само затирает это значение (я его перед вызовом CryptAcquireContext устанавливаю в некое отличное от нуля значение)

Т.е внутрь длл оно приходит уже как нулевое, я его изменяю на другое, отличное от нуля, но в хост-приложение оно не попадает.

Чего я еще не учел?


василий иванович   (2009-06-16 12:22:00) [1]

Принципально конечно ничего не изменилось.
За исключением того, что контекст (ненулевой) теперь возвращается в тестовое приложение.

Раньше же когда в тестовом проекте я вызывал последовательно CryptAcquire CryptReleaseContext, то криптоапи даже не дергало мою реализацию CPReleaseContext (упроавление туда просто не передавалось)

Теперь же я внутри своего ксп получаю "честный" контекст от любого первого попавшегося провайдера с типом PROV_RSA_FULL и криптоапи уже начинает "верить" в то, что мой фэйковый ксп возвращает валидный криптоконтекст.

В общем механизма все же завелась и поехала.
Спасибо за участие.

:)


Сергей М.   (2009-06-16 12:14:00) [2]


> потом вдруг меня осенило


А что принципиально изменилось ?

if Result then AProv := h;

На месте hс тем же "успехом" ты писал и 1234)..


василий иванович   (2009-06-16 11:34:00) [3]

Пробовал и так, с той разницей, что создавал экземпляр TObject и возвращал его адрес. Не прокатывает. В том числе и с SysGetMem.

А потом вдруг меня осенило :)

function CPAcquireContext(var AProv : HCRYPTPROV; PContainer : PChar; Flags : DWORD; VTable : PVTableProvStruc) : boolean; stdcall;
var h : HCRYPTPROV;
begin
Result := False;
Log('CPAcquireContext',Format('%s dwFlags : %d prov type %d',[PChar(PContainer),Flags,VTable.dwProvType]));
Result := CryptAcquireContext(@h,nil,nil,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT);
if Result then AProv := h;
end;


Сергей М.   (2009-06-16 10:00:00) [4]

http://www.derkeiler.com/Newsgroups/microsoft.public.platformsdk.security/2004-10/0287.html

Попробуй так:

function CPAcquireContext(AProv : PHCRYPTPROV; PContainer : PChar; Flags : DWORD; VTable : PVTableProvStruc) : boolean; stdcall;
begin
 AProv^ := SysGetMem(4); //возвращаемый хэндл контекста - валидный указатель на некий блок данных, содержащих запрашиваемый контекст
 Result := True;
end;


Сергей М.   (2009-06-16 09:47:00) [5]

Ну пока у меня остается только одно предположение - КриптоАПИ рассматривает возвращенное тобой значение как инвалидный хэндл ..


василий иванович   (2009-06-15 23:52:00) [6]

Адреса параметров перед вызовом и внутри длл не совпадают.
Но это ничего нам не дает.
Приложение вызывает CryptAcquireContext
А далее уже криптоапи вызывает CPAcquireContext.

И как именно там криптоапи обходится с вар-параметром нам неизвестно.
Она может использовать свой аргумент для передачи в CPAcquireContext и копировать его значение в аргумент переданный ей самой в CryptAcquireContext.

Патч библиотеки необходим для обхода проверки эцп нового криптопровайдера. Путей два: либо два компьютера и кернел дебуг режим, либо правка четырех байт самой библиотеки.

пропатченные версии своих длл публикует сама ms в своем csp sdk


Сергей М.   (2009-06-15 18:32:00) [7]


> пропатчил advapi32.dll


Кстати, есть смутные подозрения, а не напортачил ли ты чего с этим "патчем"..


Сергей М.   (2009-06-15 18:30:00) [8]


> на самом деле была и инициализация перед вызовом
> но ..Внутри провайдера я при этом читал ноль


Т.е. инициализировал заведомо не нулем, а получил ноль ?
И адреса при этом совпадают ?


василий иванович   (2009-06-15 18:23:00) [9]

на самом деле была и инициализация перед вызовом.
но это уже просто от безысходности.
Внутри провайдера я при этом читал ноль.

А вообще инициализация hProv не требуется.
Главная засада в том, что присвоенное вутри провайдера значение контекста не транслируется в вызывающий код.


Сергей М.   (2009-06-15 17:56:00) [10]

Тогда утверждение

> внутрь длл оно приходит уже как нулевое

не обязано соответствовать действительности.

Явно эту переменную перед передачей параметром вызова ты не инициализируешь, а содержимое ее не определено, ибо она в стеке.

Вот если ты явно инициализируешь ее перед вызовом, например, "шахматами" ($5A5A5A5A), и получишь эти же самые  "шахматы" в своем провайдере, вот тогда можно утвершжать, что прямая передача факт.параметра осуществилась успешьно. Только после этого можно рассуждать, возвращает ли твой провайдер это самое тестовое 1234 и передает ли его КриптоАПИ назад без искажений


василий иванович   (2009-06-15 17:20:00) [11]

Это локальная переменная обработчика OnButton1Click.
Все происходит в нем.


Сергей М.   (2009-06-15 16:19:00) [12]

hProv - это у тебя локальная переменная или статическая ?


василий иванович   (2009-06-15 15:17:00) [13]

Вот вызов:

var hProv : HCRYPTPROV;
begin
if CryptAcquireContext(@hProv,'Вася','Fake CryptoProvider',100,0) then
 begin
  Edit1.Text := IntToStr(hProv);
 end
else
 RaiseLastWin32Error;

Вот прототип :
function CryptAcquireContextA(phProv       :PHCRYPTPROV;
                             pszContainer :PAnsiChar;
                             pszProvider  :PAnsiChar;
                             dwProvType   :DWORD;
                             dwFlags      :DWORD) :BOOL;stdcall;

'Вася' - имя контейнера
100 - тип моего фэйкового провайдера

Внутри самого провайдера я все эти параметры получаю благополучно.


Сергей М.   (2009-06-15 15:12:00) [14]


> изменяю на другое, отличное от нуля, но в хост-приложение
> оно не попадает


Покажи соотв.фрагмент тестового хост-приложения..


василий иванович   (2009-06-15 15:07:00) [15]

Перепробовал несколько вариантов
вот два последних

function CPAcquireContext(var AProv : HCRYPTPROV; PContainer : PChar; Flags : DWORD; VTable : PVTableProvStruc) : boolean; stdcall;

function CPAcquireContext(AProv : PHCRYPTPROV; PContainer : PChar; Flags : DWORD; VTable : PVTableProvStruc) : boolean; stdcall;
begin
Log('CPAcquireContext',Format('%s dwFlags : %d prov type %d',[PChar(PContainer),Flags,VTable.dwProvType]));
AProv^ := 1234;
Result := True;
end;


KSergey   (2009-06-15 15:01:00) [16]

Может беда в банальном неправильно описанном интерфейсе? как описана CPAcquireContext в дельфи?


Наверх

Титульная страница Поиск, карта сайта Написать письмо