Текущий архив: 2011.02.06;
Скачать: CL | DM;
Внизсамописный CSP Найти похожие ветки
← →
василий иванович (2009-06-15 14:49) [0]Реализую собственный криптопровайдер для тестовых целей(так надо)
Написал DLL, реализовал все функции CP*** из этого списка http://msdn.microsoft.com/en-us/library/aa382022(VS.85).aspx
Затем пропатчил advapi32.dll, подписал длл и зарегистрировал все в реестре.
В тестовом приложении вызываю CryptAcquireContext для моего провайдера.
После этого я вижу (по текстовому логу), что криптоапи загрузило мою длл и вызвало из нее CPAcquireContext
внутри CPAcquireContext я вижу правильные значения всех инпут параметров, которые передаю из тестового приложения.
Проблема:
Значение, присваиваемое вар-параметру hProv не возвращается наружу (в хост-приложение)
Причем похоже на то, что криптоапи само затирает это значение (я его перед вызовом CryptAcquireContext устанавливаю в некое отличное от нуля значение)
Т.е внутрь длл оно приходит уже как нулевое, я его изменяю на другое, отличное от нуля, но в хост-приложение оно не попадает.
Чего я еще не учел?
← →
KSergey © (2009-06-15 15:01) [1]Может беда в банальном неправильно описанном интерфейсе? как описана CPAcquireContext в дельфи?
← →
василий иванович (2009-06-15 15:07) [2]Перепробовал несколько вариантов
вот два последних
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;
← →
Сергей М. © (2009-06-15 15:12) [3]
> изменяю на другое, отличное от нуля, но в хост-приложение
> оно не попадает
Покажи соотв.фрагмент тестового хост-приложения..
← →
василий иванович (2009-06-15 15:17) [4]Вот вызов:
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 16:19) [5]hProv - это у тебя локальная переменная или статическая ?
← →
василий иванович (2009-06-15 17:20) [6]Это локальная переменная обработчика OnButton1Click.
Все происходит в нем.
← →
Сергей М. © (2009-06-15 17:56) [7]Тогда утверждение
> внутрь длл оно приходит уже как нулевое
не обязано соответствовать действительности.
Явно эту переменную перед передачей параметром вызова ты не инициализируешь, а содержимое ее не определено, ибо она в стеке.
Вот если ты явно инициализируешь ее перед вызовом, например, "шахматами" ($5A5A5A5A), и получишь эти же самые "шахматы" в своем провайдере, вот тогда можно утвершжать, что прямая передача факт.параметра осуществилась успешьно. Только после этого можно рассуждать, возвращает ли твой провайдер это самое тестовое 1234 и передает ли его КриптоАПИ назад без искажений
← →
василий иванович (2009-06-15 18:23) [8]на самом деле была и инициализация перед вызовом.
но это уже просто от безысходности.
Внутри провайдера я при этом читал ноль.
А вообще инициализация hProv не требуется.
Главная засада в том, что присвоенное вутри провайдера значение контекста не транслируется в вызывающий код.
← →
Сергей М. © (2009-06-15 18:30) [9]
> на самом деле была и инициализация перед вызовом
> но ..Внутри провайдера я при этом читал ноль
Т.е. инициализировал заведомо не нулем, а получил ноль ?
И адреса при этом совпадают ?
← →
Сергей М. © (2009-06-15 18:32) [10]
> пропатчил advapi32.dll
Кстати, есть смутные подозрения, а не напортачил ли ты чего с этим "патчем"..
← →
василий иванович (2009-06-15 23:52) [11]Адреса параметров перед вызовом и внутри длл не совпадают.
Но это ничего нам не дает.
Приложение вызывает CryptAcquireContext
А далее уже криптоапи вызывает CPAcquireContext.
И как именно там криптоапи обходится с вар-параметром нам неизвестно.
Она может использовать свой аргумент для передачи в CPAcquireContext и копировать его значение в аргумент переданный ей самой в CryptAcquireContext.
Патч библиотеки необходим для обхода проверки эцп нового криптопровайдера. Путей два: либо два компьютера и кернел дебуг режим, либо правка четырех байт самой библиотеки.
пропатченные версии своих длл публикует сама ms в своем csp sdk
← →
Сергей М. © (2009-06-16 09:47) [12]Ну пока у меня остается только одно предположение - КриптоАПИ рассматривает возвращенное тобой значение как инвалидный хэндл ..
← →
Сергей М. © (2009-06-16 10:00) [13]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 11:34) [14]Пробовал и так, с той разницей, что создавал экземпляр 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 12:14) [15]
> потом вдруг меня осенило
А что принципиально изменилось ?
if Result then AProv := h;
На месте h с тем же "успехом" ты писал и 1234)..
← →
василий иванович (2009-06-16 12:22) [16]Принципально конечно ничего не изменилось.
За исключением того, что контекст (ненулевой) теперь возвращается в тестовое приложение.
Раньше же когда в тестовом проекте я вызывал последовательно CryptAcquire CryptReleaseContext, то криптоапи даже не дергало мою реализацию CPReleaseContext (упроавление туда просто не передавалось)
Теперь же я внутри своего ксп получаю "честный" контекст от любого первого попавшегося провайдера с типом PROV_RSA_FULL и криптоапи уже начинает "верить" в то, что мой фэйковый ксп возвращает валидный криптоконтекст.
В общем механизма все же завелась и поехала.
Спасибо за участие.
:)
Страницы: 1 вся ветка
Текущий архив: 2011.02.06;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.004 c