Search code examples
securitydelphinetwork-programmingdelphi-7winhttp

Winhttp - Prevent successful handshake if peer certificate is invalid


Edit: The thread : https://security.stackexchange.com/questions/179352/winhttp-prevent-successful-handshake-if-peer-certificate-is-invalid discusses and answers the concern. This can be closed for now

Using windows platform-provided WinHTTP on a delphi project to make calls over to the server.

Script:

userAgent := 'TestClient.exe';
  hsession := WinHttpOpen(pwidechar(userAgent), WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, nil, nil, 0);
  if(hsession = nil) then ShowMessage('Failed WinhttpOpen');
  p := 'https';
  port := 443;
  requestflags := WINHTTP_FLAG_SECURE;
  server := '10.0.0.221';

  hconnection := WinHttpConnect(hsession, PWideChar(server), port, 0);
  if(hconnection = nil) then
  begin
    le := GetLastError;
    ShowMessage('Failed to connect: ' + IntToStr(le));
  end;

  Action := 'GET';
  hInetRequest := WinHttpOpenRequest(hconnection, pwidechar(Action), nil, nil, nil, nil, WINHTTP_FLAG_SECURE);
  if(hInetRequest = nil) then
  begin
    le := GetLastError;
    ShowMessage('Failed to connect: ' + IntToStr(le));
  end;

  WinResult:=WinHttpSendRequest(hInetRequest, nil,0, 0, 0,0,0);

  if(not WinResult) then
  begin
    le := GetLastError;
    WinHttpCloseHandle(hInetRequest);
    ShowMessage('No result obtained : ' + IntToStr(le));
  end;

Required; For security compliance, connection must terminate right after SSL handshake. Incase peer certificate is deemed invalid.

Actual: Whats' happening is that, the client (using winhttp) makes a call and successfuly confirm TLS handshake even when the certificate is invalid. However, right after handshake and before completing request, it terminates the connection throwing '12175' error. Which is the error for invalid certificates. Which is right.

Problem: For compliance to pass, WinHTTP must not allow successful handshake, and hence terminate connection earlier.

Wireshark Screen attached below: (10.0.0.221 is the server) enter image description here


Solution

  • I think you're just out of luck here because that is how WinHTTP is designed. What happens is in a way described at the nServerPort parameter's value INTERNET_DEFAULT_HTTPS_PORT in the WinHttpConnect function documentation (emphasized):

    INTERNET_DEFAULT_HTTPS_PORT

    Uses the default port for HTTPS servers (port 443). Selecting this port does not automatically establish a secure connection. You must still specify the use of secure transaction semantics by using the WINHTTP_FLAG_SECURE flag with WinHttpOpenRequest.

    Which translates as that you need to open (and send) request with the WINHTTP_FLAG_SECURE flag specified to establish a secure connection.