Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.51 MB
Время: 0.008 c
2-1289747895
Анонимус
2010-11-14 18:18
2011.02.06
Пара вопросов по Дэльфи 7


2-1290085181
asdqwe
2010-11-18 15:59
2011.02.06
компонененты OverbyteIcs THttpCli


4-1244198418
GF
2009-06-05 14:40
2011.02.06
Курсор в определенной области. Отталкивание


11-1229287775
DenisArd
2008-12-14 23:49
2011.02.06
Как загрузить иконку нужного формата?


15-1287588436
Джо
2010-10-20 19:27
2011.02.06
Сайты с поиском работы (программист)