xojo.net.httpsocket and TLS 1.2 on Windows 7?

I recently switched from the old httpSecureSocket to the xojo.net.httpsocket for connecting to a particular webservice API that my app needs. I was forced to do this because the old httpSecureSocket does not support http/1.1, while the new one does. However, now my users on Windows 7 are reporting that they are unable to use the services of this specific webservice, and I’m trying to track down why.

The socket attempts to send a request, and an error event is raised with a message of “The connection with the server was terminated abnormally”, along with an error code of -2147483648. Banging around on Google leads me to believe that the webservice is refusing to connect because of a TLS 1.1 or 1.2 incompatibility with my socket.

I note in the documentation for xojo.net.httpsocket it says: “In order to use HTTPSocket with TLSv1.2 on Windows 7, KB3140245 needs to be installed using Windows Update.” I’ve verified that this update was already installed on 2 separate windows 7 user’s machines, yet I’m still unable to use this webservice.

Has anyone else seen this error before?

Is it finally time for me to completely ditch all things sockets in Xojo and just use CURL?

I should note that I’m building this Windows app with Xojo 2017R3, because the drawing changes in 2018+ for Windows have made it impossible for me to build there.

I seem to remember that in addition to that KB, there’s a place in Internet Options that the user needs yo enable TLSv1.2.

It looks like a DefaultSecureProtocols registry subkey also needs to be configured.

https://support.microsoft.com/en-us/help/3140245/update-to-enable-tls-1-1-and-tls-1-2-as-a-default-secure-protocols-in

cPanel has some good instructions here: https://confluence1.cpanel.net/plugins/servlet/mobile?contentId=13999842#content/view/13999842

I have my InnoSetup script try to handle this for the user, but I’m not confident I have it 100% correct. I’ll be looking into improving this part of it soon. https://github.com/thommcgrath/Beacon/blob/master/Installers/Windows/Setup.iss

Oh, and I find it completely asinine that Microsoft doesn’t just enable TLS 1.1 and 1.2 without all these bullshit steps.

So… from my setup script at https://github.com/thommcgrath/Beacon/blob/master/Installers/Windows/Setup.iss here are the relevant bits for a 64-bit installer. Should be similar for a 32-bit or combo installer, but things will need to be tweaked.

First of all, in my last reply I mentioned the instructions from cPanel. They’re good, except completely wrong about the qword vs dword type on 64-bit machines. Ignore that advice, it should be dword.

In the Files section, you’ll need Source: "Files\\windows6.1-kb3140245-x64.msu"; DestDir: "{tmp}" to copy the Windows Update file into temp for use later. Google search for kb3140245 to find the files, or my GitHub repo has the 64-bit file. Of course, if your msu file is not in a Files folder like mine is, change the path as necessary.

Your Registry section will need the following lines to create the entries on Windows 7 only.

Root: HKLM; Subkey: "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\WinHttp"; ValueType: dword; ValueName: "DefaultSecureProtocols"; ValueData: 2560; OnlyBelowVersion: 6.2
Root: HKLM; Subkey: "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\WinHttp"; ValueType: dword; ValueName: "DefaultSecureProtocols"; ValueData: 2560; OnlyBelowVersion: 6.2
Root: HKLM; Subkey: "SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\SCHANNEL\\Protocols\\TLS 1.1\\Client"; ValueType: dword; ValueName: "DisabledByDefault"; ValueData: 0; OnlyBelowVersion: 6.2
Root: HKLM; Subkey: "SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\SCHANNEL\\Protocols\\TLS 1.2\\Client"; ValueType: dword; ValueName: "DisabledByDefault"; ValueData: 0; OnlyBelowVersion: 6.2

I’m honestly not 100% on the Wow6432Node version for 64-bit only software, but it’s a good idea to include it anyway since this affects the whole machine, not just your app.

In Run you’ll need this row to actually install KB3140245 if it isn’t already installed.

Filename: "wusa.exe"; Parameters: "{tmp}\\windows6.1-kb3140245-x64.msu /quiet /norestart"; StatusMsg: "Installing KB3140245..."; Flags: waituntilterminated; OnlyBelowVersion: 6.2; Check: IsKBNeeded('KB3140245')

And lastly, here is the Pascal code, which goes into a Code section, to support the IsKBNeeded check and the system restart if the update is required.

var
  RestartRequired: Boolean;

function IsKBNeeded(KB: string): Boolean;
var
  WbemLocator: Variant;
  WbemServices: Variant;
  WQLQuery: string;
  WbemObjectSet: Variant;
begin
  WbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  WbemServices := WbemLocator.ConnectServer('', 'root\\CIMV2');

  WQLQuery := 'select * from Win32_QuickFixEngineering where HotFixID = ''' + KB + '''';

  WbemObjectSet := WbemServices.ExecQuery(WQLQuery);
  Result := (VarIsNull(WbemObjectSet)) or (WbemObjectSet.Count = 0);
end;

function InitializeSetup(): Boolean;
begin
  RestartRequired := IsKBNeeded('KB3140245');
  Result := True;
  if RestartRequired then begin
	  if not MsgBox('A restart will be required when finished. Continue?', mbConfirmation, MB_YESNO) = IDYES then begin
	    Result := False;
	  end;
  end;
end;

function NeedRestart(): Boolean;
begin
  Result := RestartRequired;
end;

Seriously Microsoft… from the bottom of my heart… thanks for making this necessary. I had a blast updating my installer to fix your crappy security.

While I’m sure the registry workarounds etc are lovely, I’ve decided to punt and ditch the built-in sockets all together. I’m working on migrating (at least these socket calls) to CURL using the excellent MBS plugin. The new xojo.net.httpsocket is just too… fisher price for what I need. CURL gives me access to everything the socket does through all phases of communication, which makes debugging VERY easy.

Also, it seems to reliably handle http/1.1 as well as TLS 1.1/2/3 with aplomb. Even on Windows 7.

[quote=411042:@Kimball Larsen]While I’m sure the registry workarounds etc are lovely, I’ve decided to punt and ditch the built-in sockets all together. I’m working on migrating (at least these socket calls) to CURL using the excellent MBS plugin. The new xojo.net.httpsocket is just too… fisher price for what I need. CURL gives me access to everything the socket does through all phases of communication, which makes debugging VERY easy.

Also, it seems to reliably handle http/1.1 as well as TLS 1.1/2/3 with aplomb. Even on Windows 7.[/quote]
Yeah, when I heard that Xojo.Net.HTTPSocket was going to be using curl, I expected the curl library in a plugin that would be consistent between platforms. Instead, we got lowest-common-denominator wrappers on system libraries. The number of problems I’ve found on Windows due to WinHTTP is insane. In many of my projects, I’ve resorted to a wrapper class that uses the classic socket on Windows and Xojo.Net.HTTPSocket on Mac. For the projects where I can use MBS, I’ll probably follow the same route and use MBS sockets instead.

This would have been a MUCH better solution than we currently have built into Xojo.

I’d like to take this opportunity to plug my open source libcurl wrapper: https://github.com/charonn0/RB-libcURL :slight_smile:

It definitely has my curiosity, but my big problem is lack of binaries stable binaries for macOS. So I’d have to build them myself. Then there’s always dependencies, and their dependencies, and… it’s not worth it to me.