Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2011.02.06;
Скачать: [xml.tar.bz2];

Вниз

самописный 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 вся ветка

Форум: "WinAPI";
Текущий архив: 2011.02.06;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.005 c
15-1287415882
ocean
2010-10-18 19:31
2011.02.06
Флешка 4Г стала 4М


15-1283595848
Jee
2010-09-04 14:24
2011.02.06
Запустить одну процедуру несколькими потоками


2-1290091924
NewZ
2010-11-18 17:52
2011.02.06
Компонент TScrollBox.


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


8-1210184448
Nizam
2008-05-07 22:20
2011.02.06
TrackBar





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский