如何通过Indy在openSSL 1.0.0 Win32中动态加载Crypto Api(capi.dll)?

时间:2011-08-29 14:03:23

标签: openssl indy10 mscapi

我使用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 :(得分:0)

我设法让它有效。 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;