1

I want to establish a secure connection with my server which only supports TLS 1.2 and upwards.

I am adding the following line to my VB.NET applications to enable communication with my https server:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12

However, I also still have some VB6 apps which also need to use https server.

And the above line is not available for VB6, and the code throws "Error Occurred in the Secure Channel Support". If I use it on http instead of https, it works fine.

How could I achieve the same for VB6?

Thank you!

Btw, this is my code:

Public Function GetHTTPResponse(Byval uSomeInput) As String

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 'required in order to use https!!!

    Dim nReq As Net.WebRequest = Net.WebRequest.Create("https://domain.xyz/answer.php")

    nReq.Method = "Post"
    nReq.ContentType = "application/x-www-form-urlencoded"

    Dim nReqStream As IO.Stream = nReq.GetRequestStream()

    Dim nASCIIEncoding As New System.Text.ASCIIEncoding

    Dim btPostData As Byte() = Nothing

    btPostData = nASCIIEncoding.GetBytes("&MyPHPInput=" & uSomeInput)
    nReqStream.Write(btPostData, 0, btPostData.Length)

    nReqStream.Close()

    Dim reader As New IO.StreamReader(nReq.GetResponse().GetResponseStream())
    Dim sRet As String = reader.ReadToEnd

    Return sRet

End Function

And this is the same code in VB6, but in VB6, I can't (to my knowledge) not set the Tls12 security protocol:

Public Function GetHTTPResponse(ByVal uSomeInput) As String

   'How do I set Tls12 protocol here??
   
    Dim xmlhttp As Object
    Set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP")

    xmlhttp.Open "POST", "https://domain.xyz", False

    xmlhttp.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded" & VBA.Chr(10) & VBA.Chr(13)

    xmlhttp.Send pConvertStringToByte("https://domain.xyz/answer.php?MyPHPInput=" & uSomeInput)

    GetHTTPResponse = xmlhttp.responseText

End Function

Edit:

I have followed the advice to try using WinHttp.WinHttpRequest.5.1 instead as discussed here.

It seems to work, but for some reason, the variables are not being transferred / recognized by the script, while they were recognized with my old approach using MSXML2.ServerXMLHTTP.

This is my code:

Public Function GetHTTPResponse(ByVal uSomeInput) As String

    Dim xmlhttp As Object
    Set xmlhttp = CreateObject("WinHttp.WinHttpRequest.5.1")

    'force TLS 1.2
    xmlhttp.Option(9) = 2048
    xmlhttp.Option(6) = True

    xmlhttp.Open "POST", "https://domain.xyz", False

    xmlhttp.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded" & VBA.Chr(10) & VBA.Chr(13)

    xmlhttp.Send pConvertStringToByte("https://domain.xyz/answer.php?MyPHPInput=" & uSomeInput)

    GetHTTPResponse = xmlhttp.responseText

 End Function

Does anybody see why my old byte array is not accepted for "WinHttp.WinHttpRequest.5.1" while it work for "MSXML2.ServerXMLHTTP"?

tmighty
  • 10,734
  • 21
  • 104
  • 218
  • You need to show us the portion of your VB6 code that does the connection and tell us which component you use to talk to the webserver. – Hel O'Ween Jul 26 '21 at 08:39
  • @HelO'Ween I have added my VB6 code. I use MSML2.ServerXMLHTTP. I don't know how to set Tls12 protocol in VB6. – tmighty Jul 26 '21 at 10:47
  • MSXML uses the system's (i.e. IE's) TLS settings. See [this lengthy thread](https://www.vbforums.com/showthread.php?879227-MSXML2-ServerXMLHTTP60-with-TLS-1-2-support-XP-POSReady) for how to configure the OS and what MSXML options to set in code. – Hel O'Ween Jul 26 '21 at 11:11
  • You only need that line in VB.NET when you are [targeting FW older than 4.7](https://stackoverflow.com/a/36454717/11683), and only because of an unfortunate default that exists in FW only. The `ServerXMLHTTP` is not subject to any .NET FW defaults, so there is no need to set anything there. – GSerg Jul 26 '21 at 11:21
  • I am not sure if we are talking about the same problem here. I don't want to deal with the user's firewall, I just want to establish a secure connection to my server which only supports TLS 1.2 and upwards. – tmighty Jul 26 '21 at 14:33
  • @GSerg What do you mean by "there is no need to set anything there"? If use ServerXMLHTTP on my https server, it throws an "Error Occurred in the Secure Channel Support" error. If I use it on http, it works fine. – tmighty Jul 26 '21 at 14:37
  • Yes we are talking about the same problem @tmighty, no one says anything about user's firewalls. If your Windows is new enough, it should [just work](https://stackoverflow.com/q/58223243/11683). If it doesn't, then see the link mentioned in https://stackoverflow.com/questions/68522917/securityprotocoltype-tls12-in-vb6#comment121109993_68522917 or https://stackoverflow.com/questions/58223243/does-msxml2-xmlhttp-object-support-tls-1-2-vba-excel#comment106361335_58223243. – GSerg Jul 26 '21 at 14:53
  • @GSerg You mean that it should not raise the error if the Windows is new enough, correct? – tmighty Jul 26 '21 at 16:56
  • 1
    FW = Frame Work i.e. the version of the .Net Framework. Not firewall – MarkJ Jul 27 '21 at 16:31
  • @tmighty: have you read the link I posted, specifically form [this post](https://www.vbforums.com/showthread.php?879227-MSXML2-ServerXMLHTTP60-with-TLS-1-2-support-XP-POSReady&p=5421369&viewfull=1#post5421369) onwards? – Hel O'Ween Jul 29 '21 at 08:27
  • @HelO'Ween Thank you. I have tried it. I have changed my post / question accordingly. It seems to work, but for some reason, the variables are not transported over. My php script doesn't get them. Do you know what I have to change to make it work? – tmighty Jul 29 '21 at 22:57

1 Answers1

1

Try this one:

' Define uSomeInput's data type, otherwise it's passed as a Variant, which might or might not be what we intended
Public Function GetHTTPResponse(ByVal uSomeInput As String) As String
    
    
    ' Use early instead of late binding
    Dim xmlhttp As WinHttp.WinHttpRequest
    Set xmlhttp = New WinHttpRequest

    ' force TLS 1.2
    xmlhttp.Option(9) = 2048
    xmlhttp.Option(6) = True

    xmlhttp.Open "POST", "https://domain.xyz", False

    xmlhttp.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded" & vbNewLine
    ' Let the webserver know the size of the data
    xmlhttp.SetRequestHeader "Content-Length", CStr(LenB(uSomeInput)) & vbNewLine

    xmlhttp.Send pConvertStringToByte("https://domain.xyz/answer.php?MyPHPInput=" & uSomeInput)

    ' Not sure why the string to byte array conversion is necessary
    ' Could just try the string as well
    xmlhttp.Send "https://domain.xyz/answer.php?MyPHPInput=" & uSomeInput

    GetHTTPResponse = xmlhttp.ResponseText

 End Function

If everything else fails and you require a VB6 solution and therefore are willing (or forced) to spend money ($ 395) on a commercial component, have a look at SocketTools. Although tempting, I suggest taking the Library over the ActiveX edition (which is just a wrapper of the former, IMHO). I've used SocketTools in VB6 with great success in the past (since its 6.x version, IIRC). I started using it, because I faced a very similar task to yours: I had to support SFTP transfer in my VB6 application.

Hel O'Ween
  • 1,423
  • 9
  • 15
  • Thank you. On Windows 7, this code fails in the line xmlhttp.Option(9) = 2048. The error is "Invalid procedure call or argument". – tmighty Jul 30 '21 at 15:45
  • 1
    [Windows 7 needs to be manually configured](https://support.microsoft.com/en-us/topic/update-to-enable-tls-1-1-and-tls-1-2-as-default-secure-protocols-in-winhttp-in-windows-c4bd73d2-31d7-761e-0178-11268bb10392). – Hel O'Ween Aug 02 '21 at 07:44