![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
самописный 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 в дельфи?