Как динамически загрузить Crypto Api (capi.dll) в openSSL 1.0.0 Win32 через Indy? - PullRequest
0 голосов
/ 29 августа 2011

Я использую Indy 10 и хочу, чтобы мой http-клиент использовал сертификат магазина Windows.Я использую библиотеки openssl 1.0.0d, которые должны позволять мне загружать capi.dll, но загрузка всегда терпит неудачу.

procedure TIdSSLContext.InitContext(CtxMode: TIdSSLCtxMode);
var FEngine : PENgine; 
...
FEngine := f_ENGINE_by_id('dynamic');
status := f_ENGINE_ctrl_cmd_string(FEngine, 'SO_PATH', 'capi', 0);
if status>0 then //never!
 begin
  status := f_ENGINE_ctrl_cmd_string(FEngine, 'LOAD', nil, 0);
  if status>0 then
   begin
    fContext.client_cert_engine := FEngine;
    status := f_ENGINE_set_default(FEngine, ENGINE_METHOD_ALL);
   end;
  end;
...

есть идеи?

спасибо

1 Ответ

0 голосов
/ 31 августа 2011

Мне удалось заставить его работать.Для http-сервера требуется сертификат клиента, и сертификат устанавливается в хранилище Windows.

f_ENGINE_load_builtin_engines;
FCapiEngine := f_ENGINE_by_id('dynamic');
if (FCapiEngine<>nil) then
 begin
  if (f_ENGINE_ctrl_cmd_string(FCapiEngine, 'SO_PATH', '.\capi.dll', 0)<=0) or
     (f_ENGINE_ctrl_cmd_string(FCapiEngine, 'LOAD', nil, 0)<=0) or
     (f_ENGINE_init(FCapiEngine)<=0)     then
   begin
    f_ENGINE_free(FCapiEngine);//Structural reference
    FCapiEngine := nil;
   end;
 end;    

и callBack

function client_cert_cb(SSL : PSSL; x509 : PPX509; pkey : PPEVP_PKEY) : TIdC_INT; cdecl;
begin
 result := f_ENGINE_load_ssl_client_cert(FCapiEngine,ssl,nil,x509,pkey,nil,nil,nil);
end;

Я также добавил несколько методов

fn_ENGINE_load_builtin_engines     = 'ENGINE_load_builtin_engines'    ;
  fn_ENGINE_register_all_complete    = 'ENGINE_register_all_complete'   ;
  fn_ENGINE_cleanup                  = 'ENGINE_cleanup'                 ;
  fn_ENGINE_by_id                    = 'ENGINE_by_id'                   ;
  fn_ENGINE_init                     = 'ENGINE_init'                    ;
  fn_ENGINE_finish                   = 'ENGINE_finish'                  ;
  fn_ENGINE_set_default              = 'ENGINE_set_default'             ;
  fn_ENGINE_ctrl_cmd_string          = 'ENGINE_ctrl_cmd_string'         ;
  fn_ENGINE_free                     = 'ENGINE_free'                    ;
  fn_ENGINE_load_ssl_client_cert     = 'ENGINE_load_ssl_client_cert'    ;

  @f_ENGINE_load_builtin_engines     := LoadFunctionCLib(fn_ENGINE_load_builtin_engines);
  @f_ENGINE_register_all_complete    := LoadFunctionCLib(fn_ENGINE_register_all_complete);
  @f_ENGINE_cleanup                  := LoadFunctionCLib(fn_ENGINE_cleanup);
  @f_ENGINE_by_id                    := LoadFunctionCLib(fn_ENGINE_by_id);
  @f_ENGINE_init                     := LoadFunctionCLib(fn_ENGINE_init);
  @f_ENGINE_finish                   := LoadFunctionCLib(fn_ENGINE_finish);
  @f_ENGINE_set_default              := LoadFunctionCLib(fn_ENGINE_set_default);
  @f_ENGINE_ctrl_cmd_string          := LoadFunctionCLib(fn_ENGINE_ctrl_cmd_string);
  @f_ENGINE_free                     := LoadFunctionCLib(fn_ENGINE_free);
  @f_ENGINE_load_ssl_client_cert     := LoadFunctionCLib(fn_ENGINE_load_ssl_client_cert);

  f_ENGINE_load_builtin_engines :            procedure; cdecl = nil;
  f_ENGINE_register_all_complete :           procedure; cdecl = nil;
  f_ENGINE_cleanup :                         procedure; cdecl = nil;
  f_ENGINE_by_id :                           function(const id: PAnsiChar): PENGINE; cdecl = nil;
  f_ENGINE_init :                            function(e: PENGINE): Integer; cdecl = nil;
  f_ENGINE_finish :                          function(e: PENGINE): Integer; cdecl = nil;
  f_ENGINE_set_default :                     function(e: PENGINE; flags: Cardinal): Integer; cdecl = nil;
  f_ENGINE_ctrl_cmd_string :                 function(e: PENGINE; const cmd_name: PAnsiChar; const arg: PAnsiChar; cmd_optional: Integer): Integer; cdecl = nil;
  f_ENGINE_free :                            function(e: PENGINE): Integer; cdecl = nil;
  f_ENGINE_load_ssl_client_cert :            function(e: PENGINE; s : PSSL;  ca_dn : PSTACK_OF_X509_NAME; pcert : PPX509; key : PPEVP_PKEY; pother : PPSTACK_OF_X509;ui_method : PUI_METHOD; callback_data:pointer): Integer; cdecl = nil;
...