synopse / mORMot

Synopse mORMot 1 ORM/SOA/MVC framework - Please upgrade to mORMot 2 !
https://synopse.info
785 stars 323 forks source link

Problem in SynCrtSock.TWinHTTP.InternalSendRequest if the server asks for a client certificate #413

Closed FeelAirSlow closed 2 years ago

FeelAirSlow commented 2 years ago

Hello,

I have a test server where https port is set to ask for a client certificate (it can be done via command line : netsh http add sslcert ipport=0.0.0.0:443 certhash=XXhashXX appid={XXappidXX} clientcertnegotiation=enable).

When I send an https request with THttpRequest.Request, I should have a 12044 error (ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED), but I have an error 12019 (ERROR_INTERNET_INCORRECT_HANDLE_STATE). I think there is a problem with the conditions in procedure TWinHTTP.InternalSendRequest. I propose the following modification :

  L := length(aData);
  if not _SendRequest(L) or
     not WinHttpAPI.ReceiveResponse(fRequest,nil) then begin
    **if fHTTPS and IgnoreSSLCertificateErrors and (GetLastError=ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED) then begin**
      if not WinHttpAPI.SetOption(fRequest,WINHTTP_OPTION_SECURITY_FLAGS,
         @SECURITY_FLAT_IGNORE_CERTIFICATES,SizeOf(SECURITY_FLAT_IGNORE_CERTIFICATES)) then
        RaiseLastModuleError(winhttpdll,EWinHTTP);
      if not WinHttpAPI.SetOption(fRequest,WINHTTP_OPTION_CLIENT_CERT_CONTEXT,
         pointer(WINHTTP_NO_CLIENT_CERT_CONTEXT),0) then
        RaiseLastModuleError(winhttpdll,EWinHTTP);
      if not _SendRequest(L) or
         not WinHttpAPI.ReceiveResponse(fRequest,nil) then
        RaiseLastModuleError(winhttpdll,EWinHTTP);
    **end else
       RaiseLastModuleError(winhttpdll,EWinHTTP);**
  end;

Thank you !

synopse commented 2 years ago

Fair enough.

Also backported to mORMot 2.

FeelAirSlow commented 2 years ago

I tested your modifications of SynCrtSock.pas : that's perfect, thank you !