0

I have some inherited code written in vb.net which does the following.

  1. Create a web request
  2. Set the headers etc from a database
  3. Sets the securityProtocol
  4. Sends the request

However, at the point of setting the headers, it may do another web request to get a token from a 3rd party API, which recursively calls the same function.

The issue I have is that the call in the header uses SSL3, and the call in the main function uses TLS12. I cannot get the security protocol to update on the 2nd occasion if it has been set when retrieving the headers. (ie on the main call).

At what point does should the security protocol be set? Is there a way of setting it on a specific webrequest? Please don't advise that webrequest is out-dated, I'm working with inherited code here.

req = HttpWebRequest.Create(Uri)

            req.Timeout = HTTPCredentials.Timeout
            req.ReadWriteTimeout = HTTPCredentials.Timeout
            req.Method = HTTPCredentials.Method



            For Each credential As HTTPHeaderCredential In HTTPCredentials.HeaderCredentials
                If IsNothing(OldHeader) Then
                    OldHeader = New HTTPHeaderCredential
                    OldHeader = credential
                End If
                If OldHeader.HeaderName = credential.HeaderName Then
                    'concatenate header
                    CredentialString += processHeader(credential.HeaderValue, credential.CredentialID, Guid, OptionalParams)
                Else
                    'apply header
                    If CredentialString <> "" Then
                        If OldHeader.Validate Then
                            req.Headers.Add(OldHeader.HeaderName, CredentialString)
                        Else
                            priMethod = req.Headers.[GetType]().GetMethod("AddWithoutValidate", BindingFlags.Instance Or BindingFlags.NonPublic)
                            priMethod.Invoke(req.Headers, {OldHeader.HeaderName, CredentialString})
                        End If
                        CredentialString = ""
                    End If
                    'new header
                    CredentialString = processHeader(credential.HeaderValue, credential.CredentialID, Guid, OptionalParams)
                    OldHeader = credential
                End If
            Next
            'Apply last header
            If CredentialString <> "" Then
                If OldHeader.Validate Then
                    req.Headers.Add(OldHeader.HeaderName, CredentialString)
                Else
                    priMethod = req.Headers.[GetType]().GetMethod("AddWithoutValidate", BindingFlags.Instance Or BindingFlags.NonPublic)
                    priMethod.Invoke(req.Headers, {OldHeader.HeaderName, CredentialString})
                End If
            End If

            If HTTPCredentials.Method = "POST" Then
                Select Case HTTPCredentials.ContentType.ToUpper
                    Case "JSON"
                        req.ContentType = "application/json"
                        req.ContentLength = data.Length
                        req.Accept = "application/json"
                    Case "XML"
                        req.ContentType = "application/xml"
                        req.ContentLength = data.Length
                    Case "PLAIN TEXT"
                        If HTTPCredentials.Method.ToUpper = "POST" Then
                            req.ContentLength = data.Length
                        End If
                End Select

                ServicePointManager.SecurityProtocol = HTTPCredentials.SecurityProtocol

                stream = req.GetRequestStream()

                stream.Write(data, 0, data.Length)

                stream.Close()

ProcessHeader() can recursively call this function to do an API lookup for a token for example

Stu
  • 1
  • `ServicePointManager` manages the `ServicePoint` pool. A ServicePoint is assigned to a connection when the code asks one. The SecurityProtocol (and all other settings) used to create the connection, in answer to the request, is the current `ServicePointManager` setting (if not set, it's the System's default). You have to set it before a **new** connection is created. You have no control over the connection generation itself. The `ServicePointManager` may decide to use an existing one. If the EndPoint is new, you probably will receive a new connection, which will use the current settings. – Jimi Nov 20 '19 at 16:05
  • So, if you need a specific SecurityProtocol for a specific EndPoint, make sure that the protocol is selected before the request is created. It will probably remain the same for all connections to the same EndPoint for the life-time of the connection (see the 2 different TimeOuts that can be specified). You can specify more that one SecurityProtocol, the handshake will try to negotiate the best one (but you have to rely on this *choice*). See the notes here: [Which TLS version was negotiated?](https://stackoverflow.com/a/48675492/7444103) – Jimi Nov 20 '19 at 16:20

0 Answers0