Could not create SSL/TLS secure channel from .NET C# - c#

I'm trying to call an API on my server windows 2008 R2, but I keep getting this error :
Could not create SSL/TLS secure channel
I'm launching the app as a Windows service, with the LocalSystem account.
I tried many things from some Question from Stack Overflow to get it started but none of these works:
With AppContext Switch
Without AppContext Switch
With only SSL Protocol 1.2 on Security protocol
Without SecurityProcotol changed
With ExpectContinue = 100
//Config
const string DontEnableSystemDefaultTlsVersions = #"Switch.System.Net.DontEnableSystemDefaultTlsVersions";
const string DontEnableSchUseStrongCryptoName = #"Switch.System.Net.DontEnableSchUseStrongCrypto";
const string DisableUsingServicePointManagerSecurityProtocols = #"Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols";
const string DontEnableSystemDefaultTlsVersionsServiceModel = #"Switch.System.ServiceModel.DontEnableSystemDefaultTlsVersions";
AppContext.SetSwitch(DontEnableSchUseStrongCryptoName, false);
AppContext.SetSwitch(DontEnableSystemDefaultTlsVersions, true);
AppContext.SetSwitch(DisableUsingServicePointManagerSecurityProtocols, false);
AppContext.SetSwitch(DontEnableSystemDefaultTlsVersionsServiceModel, true);
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
//API config and Call
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(message.Url);
request.Credentials = CredentialCache.DefaultCredentials;
request.Method = message.Method;
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
Byte[] byteArray = encoding.GetBytes(message.Content);
request.ContentLength = byteArray.Length;
request.ContentType = message.ContentType;
request.UserAgent = message.UserAgent;
request.Accept = message.Accept;
using (Stream dataStream = request.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
}
The API need TLS 1.2+ to be called.
I have tested Internet Explorer to see if we can call TLS 1.2, and it seems that it can call, I used this https://browserleaks.com/ssl :
BrowserLeak
I tried to call the API from Postman online (with Chrome) and the Postman app on the server, both are calling the API without an issue.
Same with SoapUI, it works.
It works on my computer (Windows 10), it doesn't work on the server, with the same C# Code.
I tried to change the framework, 4.0, 4.5, 4.6, 4.8, doesn't seem to change something.
I have the SSL Handshake, but it doesn't help very much, it said that there was a Handshake failure (02 28):
System.Net.Sockets Verbose: 0 : [51080] Exiting Socket#40535505::Send() -> Int32#174
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.5541547Z
System.Net.Sockets Verbose: 0 : [51080] Entering Socket#40535505::Receive()
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.5541547Z
System.Net.Sockets Verbose: 0 : [51080] Data from Socket#40535505::Receive
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6151608Z
System.Net.Sockets Verbose: 0 : [51080] 00000000 : 15 03 03 00 02 : .....
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6151608Z
System.Net.Sockets Verbose: 0 : [51080] Exiting Socket#40535505::Receive() -> Int32#5
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6151608Z
System.Net.Sockets Verbose: 0 : [51080] Entering Socket#40535505::Receive()
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6161609Z
System.Net.Sockets Verbose: 0 : [51080] Data from Socket#40535505::Receive
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6161609Z
System.Net.Sockets Verbose: 0 : [51080] 00000005 : 02 28 : .(
ProcessId=46588
ThreadId=6
DateTime=2021-11-24T09:05:57.6161609Z
The Cipher suite seems to be good, I have the first 3 Cipher suite that are required by the API on the beginning of the suite.
The API need the ISRG Root X1 Certificate, which is in the Trusted Root Certification Authorities store.
I used the tool from windows to modify the registry
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
Which enabled the TLS 1.2, it wasn't activated in browserleaks before I launch the tool.
Also SSL 2.0 and SSL3.0 are disabled and TLS1.0, TLS1.1 and TLS1.2 are activated:
Secure channel registry
I can't seem to find a solution to get it worked.
How can I try to find a clue to the issue?

We found the issue, the cipher suite required for the API isn't compatible with the windows server 2008 R2, we verified the cipher suite with
https://www.ssllabs.com/ssltest/ with the url of the api
then compared it with the cipher suites on the server located here :
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers
and none of them were matching.

Related

C# .NET 4.8 RestClient call with certificate, basic auth and proxy, fails with an "AcquireCredentialsHandle() failed with error 0X8009030D" error

I am trying to call a webservice from a C# .NET 4.8 application. The web service is secured via a certificate and basic authentication. When I make the call it is failing with a
System.Net Error: 0 : [3564] AcquireCredentialsHandle() failed with
error 0X8009030D.
error which leads to a
The request was aborted: Could not create SSL/TLS secure channel.
error being thrown.
I have looked at several post but have not been able to make any progress.
ServicePointManager.SecurityProtocol = spt;
ServicePointManager.Expect100Continue = true;
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
RestClient client = new RestClient(uri);
client.Authenticator = new HttpBasicAuthenticator(username, password);
client.ClientCertificates = new X509CertificateCollection();
client.ClientCertificates.Add(new X509Certificate(certificate, certificatePassword));
client.Proxy = new WebProxy(proxy, port);
client.Proxy.Credentials = CredentialCache.DefaultCredentials;
request = new RestRequest(Method.POST);
request.AddHeader("Message-Key", messageKey);
request.RequestFormat = DataFormat.Json;
request.AddParameter("application/json", json, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
The certificate is a pfx file and when I make the same call using SoapUI it is successful.
I have configured it to produce a System.Net trace log.
The first error is
System.Net Error: 0 : [3564] Can't retrieve proxy settings for Uri
'https://dev.api.sydney.edu.au/usyd-message-handler-exp-api-v1/v1/messages'.
Error code: 12180.
I assume this is not an issue as when I didn't have the proxy details the call would timeout.
At the bottom of the log I get:
[Thumbprint] 0C1EFA37718255EE6DEF3A8A980CD30939762EA6 . System.Net
Information: 0 : [3564] SecureChannel#14353717 - Found the certificate
in the LocalMachine store. System.Net Information: 0 : [3564]
SecureChannel#14353717::.AcquireClientCredentials, new
SecureCredential() (flags=(ValidateManual, NoDefaultCred,
SendAuxRecord, UseStrongCrypto), m_ProtocolFlags=(Ssl3Client,
Tls12Client), m_EncryptionPolicy=RequireEncryption) System.Net
Information: 0 : [3564] AcquireCredentialsHandle(package = Microsoft
Unified Security Protocol Provider, intent = Outbound, scc =
System.Net.SecureCredential) System.Net Error: 0 : [3564]
AcquireCredentialsHandle() failed with error 0X8009030D. System.Net
Information: 0 : [3564] AcquireCredentialsHandle(package = Microsoft
Unified Security Protocol Provider, intent = Outbound, scc =
System.Net.SecureCredential) System.Net Error: 0 : [3564]
AcquireCredentialsHandle() failed with error 0X8009030D.
System.Net.Sockets Verbose: 0 : [3564] Entering
Socket#32115247::Dispose() System.Net Error: 0 : [3564] Exception in
HttpWebRequest#24230272:: - The request was aborted: Could not create
SSL/TLS secure channel.. System.Net Error: 0 : [3564] Exception in
HttpWebRequest#24230272::EndGetRequestStream - The request was
aborted: Could not create SSL/TLS secure channel.. System.Net
Information: 0 : [10700] ServicePoint#16495015 - Closed as idle.
For the ServicePointManager.SecurityProtocol setting I have tried every possible combination, if I do not set it or if I at least include Tls12 then I get this issue otherwise I get an underlying connection was closed error.
Can anyone provide any pointers, please?
The "Could not create SSL/TLS secure channel" error message typically indicates that the HTTPS connection could not be established due to a certificate validation issue. To fix this issue, you can add the following code to your application before making the HTTPS request:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

How to diagnose why async TCP System.Net.Socket send (Begin/End Send) not actually sending anything?

I have an HTTP server and client (they are my code both, C#, HttpListener on the server, HttpWebrequest on a client).
Every client makes approx 6 HTTP requests to the server per minute (if all is OK). There can be up to 10000 clients per server. The server should respond less than 1 second. Server logic is simple (there are no CPU issues). The most code is async.
All works fine in several environments (Intranet).
But in some Intranet environment, approximately 1 of 3 POST HTTP web requests hangs.
The issue is manifested on single client computer under VMware (Win 8.1 Professional, 6.3.9600 build 9600 .net 4.7.1)
I cannot reproduce it on another computer and cannot move this VM to another network environment. So I need to get some more detailed info.
The issue is detailed below. It is very like as described at
Async TCP System.Net.Socket send (Begin/End Send) not actually sending anything several years ago.
I have got WireShark and detailed System.Net logs from client and server as recommended by Microsoft.
<source name="LowLevelDesign" switchValue="Verbose">
<source name="System.Net.Http" switchValue="Verbose">
<source name="System.Net.HttpListener" switchValue="Verbose">
<source name="System.Net" switchValue="Verbose">
<source name="System.Net.Sockets" switchValue="Verbose">
Several POST HttpWebRequests from client on the same socket work fine, i.e. log shows the same client port and socket ID between requests.
I see all TCP packets in Wireshark OK both on server and client (The only warning on the server is Checksum: 0xd28c incorrect, should be 0xb54c(maybe caused by "TCP checksum offload"?).
The server responds greatly less than 1 sec for all requests.
Then after 3 or 4 successful requests, the client tries to send the next request.
But there are no TCP packets in Wireshark (nor at server nor at the client). So there is no answer from the server due to it does not see the request.
My code detects timeout (10 seconds) without answer and aborts the HttpWebRequest.
Then the same (new) requests works well on other new sockets (i.e. new client port). But after 3-6 requests the issue repeats.
There are no messages with length > 1500. The hanged request is short message too (<100 bytes for headers and <200 bytes for POST request stream data, <400 bytes for response). I see no differences between OK and Hanged requests except OK is first and Hanged is second with 100-continue. All other requests has no request data (i.e. request content-length==0). I see that the second request with 100-continue is hanged always in that environment.
The old connection is not disposed properly due to I see that server sends [RST, ACK] to the old socket (old client port) 2 minutes later. And I do not know how to close it gracefully.
...
System.Net.Sockets Verbose: 0 : [6420] Data from Socket#11429296::PostCompletion
DateTime=2019-06-24T06:43:08.7370581Z
...
System.Net.Sockets Verbose: 0 : [6420] 000000A0 : 35 0D 0A 45 78 70 65 63-74 3A 20 31 30 30 2D 63 : 5..Expect: 100-c
DateTime=2019-06-24T06:43:08.7410625Z
System.Net.Sockets Verbose: 0 : [6420] Socket#11429296::EndSend(OverlappedAsyncResult#13804354)
DateTime=2019-06-24T06:43:08.7420738Z
System.Net.Sockets Verbose: 0 : [6420] Exiting Socket#11429296::EndSend() -> Int32#187
DateTime=2019-06-24T06:43:08.7420738Z
System.Net.Sockets Verbose: 0 : [6420] Socket#11429296::UnsafeBeginReceive()
DateTime=2019-06-24T06:43:08.7420738Z
System.Net.Sockets Verbose: 0 : [6420] Exiting Socket#11429296::UnsafeBeginReceive() -> OverlappedAsyncResult#47962264
DateTime=2019-06-24T06:43:08.7431561Z
System.Net Verbose: 0 : [5896] HttpWebRequest#52253787::EndGetRequestStream()
DateTime=2019-06-24T06:43:09.1071980Z
System.Net Verbose: 0 : [5896] Exiting HttpWebRequest#52253787::EndGetRequestStream() -> ConnectStream#17987329
DateTime=2019-06-24T06:43:09.1081881Z
System.Net Verbose: 0 : [5896] ConnectStream#17987329::BeginWrite()
DateTime=2019-06-24T06:43:09.1081881Z
System.Net Verbose: 0 : [5896] Data from ConnectStream#17987329::BeginWrite
DateTime=2019-06-24T06:43:09.1091858Z
System.Net Verbose: 0 : [5896] 00000000 : 7B 22 43 6F 6E 6E 65 63-74 69 6F 6E 73 22 3A 7B : {"Connections":{
DateTime=2019-06-24T06:43:09.1091858Z
...
System.Net.Sockets Verbose: 0 : [5896] Socket#11429296::BeginSend()
DateTime=2019-06-24T06:43:09.1140970Z
System.Net.Sockets Verbose: 0 : [5896] Exiting Socket#11429296::BeginSend() -> OverlappedAsyncResult#60375305
DateTime=2019-06-24T06:43:09.1151910Z
System.Net Verbose: 0 : [5896] Exiting ConnectStream#17987329::BeginWrite() -> NestedSingleAsyncResult#46228029
DateTime=2019-06-24T06:43:09.1160992Z
System.Net.Sockets Verbose: 0 : [6420] Data from Socket#11429296::PostCompletion
DateTime=2019-06-24T06:43:09.1180991Z
System.Net.Sockets Verbose: 0 : [6420] 00000000 : 7B 22 43 6F 6E 6E 65 63-74 69 6F 6E 73 22 3A 7B : {"Connections":{
DateTime=2019-06-24T06:43:09.1180991Z
...
System.Net.Sockets Verbose: 0 : [6420] Socket#11429296::EndSend(OverlappedAsyncResult#60375305)
DateTime=2019-06-24T06:43:09.1212220Z
System.Net.Sockets Verbose: 0 : [6420] Exiting Socket#11429296::EndSend() -> Int32#125
DateTime=2019-06-24T06:43:09.1212220Z
System.Net Verbose: 0 : [6420] ConnectStream#17987329::EndWrite()
DateTime=2019-06-24T06:43:09.1212220Z
System.Net Verbose: 0 : [6420] Exiting ConnectStream#17987329::EndWrite()
DateTime=2019-06-24T06:43:09.1222229Z
System.Net Verbose: 0 : [6420] ConnectStream#17987329::Close()
DateTime=2019-06-24T06:43:09.1222229Z
System.Net Verbose: 0 : [6420] Exiting ConnectStream#17987329::Close()
DateTime=2019-06-24T06:43:09.1232215Z
System.Net Verbose: 0 : [7368] HttpWebRequest#52253787::BeginGetResponse()
DateTime=2019-06-24T06:43:09.1232215Z
System.Net Verbose: 0 : [7368] Exiting HttpWebRequest#52253787::BeginGetResponse() -> ContextAwareResult#13009416
DateTime=2019-06-24T06:43:09.1241884Z
System.Net Verbose: 0 : [7368] HttpWebRequest#52253787::Abort()
DateTime=2019-06-24T06:43:18.7330583Z
Wireshark:
Protocol Length Info
TCP 66 56916 → 33444 [SYN] Seq=0 Win=8192 Len=0 MSS=1432 WS=256 SACK_PERM=1
TCP 66 33444 → 56916 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1404 WS=256 SACK_PERM=1
TCP 54 56916 → 33444 [ACK] Seq=1 Ack=1 Win=65792 Len=0
HTTP 248 POST /Service_v2/GetServerInformation/ HTTP/1.1
TCP 60 33444 → 56916 [ACK] Seq=1 Ack=195 Win=65792 Len=0
HTTP 438 HTTP/1.1 200 OK (text/plain)
TCP 54 56916 → 33444 [ACK] Seq=195 Ack=385 Win=65536 Len=0
HTTP 220 POST /Service_v2/GetServerLicense/ HTTP/1.1
TCP 60 33444 → 56916 [ACK] Seq=385 Ack=361 Win=65792 Len=0
HTTP 1252 HTTP/1.1 200 OK (text/plain)
TCP 54 56916 → 33444 [ACK] Seq=361 Ack=1583 Win=65792 Len=0
HTTP 220 POST /Service_v2/GetSecondMessage/ HTTP/1.1
TCP 60 33444 → 56916 [ACK] Seq=1583 Ack=527 Win=65536 Len=0
HTTP 858 HTTP/1.1 200 OK (text/plain)
HTTP 265 POST /Service_v2/GetMainMessage/?messageid=10d5d406-634e-4b65-9d99-f614e8b8398b HTTP/1.1
TCP 60 33444 → 56916 [ACK] Seq=2387 Ack=738 Win=65280 Len=0
HTTP 836 HTTP/1.1 200 OK (text/plain)
TCP 241 56916 → 33444 [PSH, ACK] Seq=738 Ack=3169 Win=65792 Len=187 [TCP segment of a reassembled PDU]
TCP 60 33444 → 56916 [ACK] Seq=3169 Ack=925 Win=65024 Len=0
HTTP 79 HTTP/1.1 100 Continue
HTTP 181 POST /Service_v2/ProcessMessage/ HTTP/1.1 (application/raw)
TCP 60 33444 → 56916 [ACK] Seq=3194 Ack=1052 Win=65024 Len=0
HTTP 372 HTTP/1.1 200 OK (text/plain)
TCP 54 56916 → 33444 [ACK] Seq=1052 Ack=3512 Win=65536 Len=0
HTTP 220 POST /Service_v2/GetSecondMessage/ HTTP/1.1
TCP 60 33444 → 56916 [ACK] Seq=3512 Ack=1218 Win=64768 Len=0
HTTP 882 HTTP/1.1 200 OK (text/plain)
TCP 54 56916 → 33444 [ACK] Seq=1218 Ack=4340 Win=64768 Len=0
Here I try to make new POST /Service_v2/ProcessMessage/ HTTP/1.1 (application/raw) but there are NO data in WireShark
I see only next line ([RST, ACK]) after 2 minutes, no [FIN], no [ASK], no [PSH]
TCP 60 33444 → 56916 [RST, ACK] Seq=4340 Ack=1218 Win=0 Len=0
Source code:
public ServerHttpRequest(string methodSuffix, NameValueCollection requestParams = null, string requestBody = null)
{
if (methodSuffix == null)
throw new AggregateException(nameof(methodSuffix));
_methodSuffix = methodSuffix;
_requestParams = requestParams;
_requestBody = requestBody;
}
public async Task<string> SendRequest()
{
var sendRequestTask = Send();
if (await Task.WhenAny(sendRequestTask, Task.Delay(TimeSpan.FromSeconds(Configuration.ServerTimeout))) == sendRequestTask)
return await sendRequestTask.ConfigureAwait(false);
ThreadPool.QueueUserWorkItem(this.Abort);
throw new TimeoutException("HttpRequest timeout exceeded. Probably having problems connecting to the server.");
}
private void Abort(object obj)
{
try
{
_httpRequest?.Abort();
}
catch (Exception ex)
{
Log(ex);
}
}
private HttpWebRequest CreateRequest(string methodSuffix, NameValueCollection requestParams = null)
{
string url = GetUrl(methodSuffix)
if (requestParams != null && requestParams.Count > 0)
serviceAdress = AddParamsToUrl(url, requestParams);
var webRequest = WebRequest.CreateHttp(licServiceAdress);
webRequest.Method = "POST";
//The Timeout property indicates the length of time, in milliseconds,
//until the request times out and throws a WebException.
//The Timeout property affects only synchronous requests made with the GetResponse method.
//https://learn.microsoft.com/en-us/dotnet/api/system.net.webrequest.timeout?view=netframework-4.8#remarks
webRequest.Timeout = (int)TimeSpan.FromSeconds(Configuration.ServerTimeout).TotalMilliseconds;
webRequest.Proxy = null;
webRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
webRequest.Headers.Add("Accept-Encoding", "gzip");
return webRequest;
}
private async Task<string> Send()
{
try
{
_httpRequest = await Task.Run(() => CreateRequest(_methodSuffix, _requestParams)).ConfigureAwait(false);
UTF8Encoding encoding = new UTF8Encoding();
byte[] requestBodyBytes = null;
if (_requestBody == null)
requestBodyBytes = encoding.GetBytes("");
else
requestBodyBytes = encoding.GetBytes(_requestBody);
_httpRequest.ContentType = "application/raw";
_httpRequest.ContentLength = requestBodyBytes.Length;
using (Stream newStream = await _httpRequest.GetRequestStreamAsync().ConfigureAwait(false))
{
await newStream.WriteAsync(requestBodyBytes, 0, requestBodyBytes.Length).ConfigureAwait(false);
}
using (var webResponse = (HttpWebResponse)await _httpRequest.GetResponseAsync().ConfigureAwait(false))
{
using (var responseStream = webResponse.GetResponseStream())
if (responseStream != null)
using (var reader = new StreamReader(responseStream))
return await reader.ReadToEndAsync().ConfigureAwait(false);
return "";
}
}
catch (Exception ex)
{
Log($"Request failed. Uri: '{_httpRequest.RequestUri.AbsoluteUri}'. {ex}");
throw;
}
}
I need to know why socket data are not shown in Wireshark. How to diagnose this?

401 when calling Web Service only on particular machines

We have developed a WPF Application with C# and are using RestSharp to communicate with a simple Web Service like this:
Client = new RestClient(serviceUri.AbsoluteUri);
Client.Authenticator = new NtlmAuthenticator(SvcUserName, SvcPassword.GetString());
It all worked great until we received calls that on some machines (most work) the app can't connect to the service.
A direct call to the service method with fiddler worked. Then we extracted a small .net console app and tried the service call with RestSharp and directly with a HttpWebRequest and it failed again with 401.
Now we enabled System.Net tracing and noticed something. After the first 401, which is normal,the faulty machine produces this log:
System.Net Information: 0 : [4480] Connection#3741682 - Received headers
{
Connection: Keep-Alive
Content-Length: 1293
Content-Type: text/html
Date: Mon, 10 Aug 2015 12:37:49 GMT
Server: Microsoft-IIS/8.0
WWW-Authenticate: Negotiate,NTLM
X-Powered-By: ASP.NET
}.
System.Net Information: 0 : [4480] ConnectStream#39451090::ConnectStream(Buffered 1293 bytes.)
System.Net Information: 0 : [4480] Associating HttpWebRequest#2383799 with ConnectStream#39451090
System.Net Information: 0 : [4480] Associating HttpWebRequest#2383799 with HttpWebResponse#19515494
System.Net Information: 0 : [4480] Enumerating security packages:
System.Net Information: 0 : [4480] Negotiate
System.Net Information: 0 : [4480] NegoExtender
System.Net Information: 0 : [4480] Kerberos
System.Net Information: 0 : [4480] NTLM
System.Net Information: 0 : [4480] Schannel
System.Net Information: 0 : [4480] Microsoft Unified Security Protocol Provider
System.Net Information: 0 : [4480] WDigest
System.Net Information: 0 : [4480] TSSSP
System.Net Information: 0 : [4480] pku2u
System.Net Information: 0 : [4480] CREDSSP
System.Net Information: 0 : [4480] AcquireCredentialsHandle(package =
NTLM, intent = Outbound, authdata =
(string.empty)\corp\svc_account)
System.Net Information: 0 : [4480]
InitializeSecurityContext(credential =
System.Net.SafeFreeCredential_SECURITY, context = (null), targetName =
HTTP/mysvc.mycorp.com, inFlags = Delegate, MutualAuth,
Connection) System.Net Information: 0 : [4480]
InitializeSecurityContext(In-Buffers count=1, Out-Buffer length=40,
returned code=ContinueNeeded).
A working machine produces this output:
System.Net Information: 0 : [3432] Connection#57733168 - Empfangene Statusleiste: Version = 1.1, StatusCode = 401, StatusDescription = Unauthorized.
System.Net Information: 0 : [3432] Connection#57733168 - Header
{
Content-Type: text/html
Server: Microsoft-IIS/8.0
WWW-Authenticate: Negotiate,NTLM
X-Powered-By: ASP.NET
Date: Mon, 10 Aug 2015 15:15:11 GMT
Content-Length: 1293
} wurden empfangen.
System.Net Information: 0 : [3432] ConnectStream#35016340::ConnectStream(Es wurden 1293 Bytes gepuffert.)
System.Net Information: 0 : [3432] Associating HttpWebRequest#64062224 with ConnectStream#35016340
System.Net Information: 0 : [3432] Associating HttpWebRequest#64062224 with HttpWebResponse#64254500
System.Net Information: 0 : [3432] Sicherheitspakete werden enumeriert:
System.Net Information: 0 : [3432] Negotiate
System.Net Information: 0 : [3432] NegoExtender
System.Net Information: 0 : [3432] Kerberos
System.Net Information: 0 : [3432] NTLM
System.Net Information: 0 : [3432] Schannel
System.Net Information: 0 : [3432] Microsoft Unified Security Protocol Provider
System.Net Information: 0 : [3432] WDigest
System.Net Information: 0 : [3432] TSSSP
System.Net Information: 0 : [3432] pku2u
System.Net Information: 0 : [3432] CREDSSP
System.Net Information: 0 : [3432] AcquireCredentialsHandle(package =
Negotiate, intent = Outbound, authdata =
System.Net.SafeSspiAuthDataHandle) System.Net Information: 0 : [3432]
InitializeSecurityContext(credential =
System.Net.SafeFreeCredential_SECURITY, context = (null), targetName =
HTTP/mysvc.mycorp.com, inFlags = Delegate, MutualAuth, Connection)
System.Net Information: 0 : [3432] InitializeSecurityContext(Anzahl
von In-Buffers = 1, Länge von Out-Buffer = 40, zurückgegebener Code =
ContinueNeeded).
I wonder if some configuration on the faulty machine would cause this. At the moment I am not sure where to look next.
Update:
Here is the Code of our simple test tool:
RestClient Client = new RestClient("https://mysvc.mycorp.com/service.svc");
Client.Authenticator = new NtlmAuthenticator("corp\\svc_account", "mypassword");
var request = new RestRequest("api/Method", Method.POST);
request.RequestFormat = DataFormat.Json;
request.AddBody(new { Device_Key = "somestring" });
request.Timeout = 200000;
RestResponse response = (RestResponse)Client.Execute(request);
Update 2:
We have now confirmed that this Problem only occurs on newly installed win 7 machines that have an updated corporate Image. Almost Looks like some update in the last 2 months is screwing with us.
This is crazy: Turns out, as soon as I installed .net 4.5 on the Windows 7 machine, the WebRequest worked! We believe that the culprit was a missing patch of the .NET 4.0 Framework that is deployed to all client machines.
So, patch your machines :)

HttpWebRequest vs Fiddler using SSL

I have a web app using HttpWebRequest to send some data to a third party service. It is failing when I run it through the web code but when I send pretty much the exact same data using Fiddler's composer it works.
I say "pretty much" because the data contains a password digest and nonce and timestamp that change for every message. I have put a break point and taken the data the web app was about to send and pasted it into Fiddler and it works.
I have set up my code to run through Fiddler's proxy too, which is great - I can see the "raw" data being sent - it still fails, but it's enabled me to check that the headers are all exactly the same and mess with them a bit (didn't find anything useful).
WebProxy myproxy = new WebProxy("127.0.0.1:8889", false);
req.Proxy = myproxy;
I've disabled Fiddler's "automatically authenticate" and "follow redirects" options (have left on "fix content-length header"), just in case one of those was causing Fiddler to act smart.
This post is to a https URL so I did have to add the following lines to ignore Fiddler's certificate problems when decrypting the HTTPS traffic
ServicePointManager
.ServerCertificateValidationCallback +=
(sender, cert, chain, sslPolicyErrors) => true;
Does anyone know of any options on HttpWebRequest that I should enable or disable to make it act as Fiddler does? As the actual content seems to be same, maybe there's a difference in the security/authentication options?
Changing Fiddler's "decrypt HTTPS" setting doesn't seem to affect anything, except mean I can't view the data.
Would using something other than HttpWebRequest be an option? What other libraries are there that don't just use HttpWebRequest under the hood? I don't need async but does HttpClient use a newer library that handles things better?
I've seen other posts about connections and making HttpWebRequest more performant, but at the moment I'm just POSTing a single message.
If it helps here's what the headers look like:
POST https://www.server.com/enterprise/soap?ServiceName=PassportService&auth=1 HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: http://www.server.com/ws/passport/2008/04/PassportService#publishDocumentWithParameters
Host: vha.server.com
Content-Length: 4601
Expect: 100-continue
Connection: Keep-Alive
the body of the message is just SOAP xml
Here is some data from implementing .NET Network Tracing
System.Net Information: 0 : [8864] ConnectStream#7307007 - Sending headers
{
Content-Type: text/xml; charset=utf-8
SOAPAction: http://www.server.com/ws/passport/2008/04/PassportService#publishDocumentWithParameters
Host: vha.server.com
Content-Length: 4393
Expect: 100-continue
Connection: Keep-Alive
}.
System.Net Information: 0 : [8864] SecureChannel#63848051::.ctor(hostname=vha.server.com, #clientCertificates=0, encryptionPolicy=RequireEncryption)
System.Net Information: 0 : [8864] Enumerating security packages:
System.Net Information: 0 : [8864] Negotiate
System.Net Information: 0 : [8864] NegoExtender
System.Net Information: 0 : [8864] Kerberos
System.Net Information: 0 : [8864] NTLM
System.Net Information: 0 : [8864] Schannel
System.Net Information: 0 : [8864] Microsoft Unified Security Protocol Provider
System.Net Information: 0 : [8864] WDigest
System.Net Information: 0 : [8864] TSSSP
System.Net Information: 0 : [8864] pku2u
System.Net Information: 0 : [8864] CREDSSP
System.Net Information: 0 : [8864] SecureChannel#63848051 - Left with 0 client certificates to choose from.
System.Net Information: 0 : [8864] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent = Outbound, scc = System.Net.SecureCredential)
System.Net Information: 0 : [8864] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = (null), targetName = vha.server.com, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [8864] InitializeSecurityContext(In-Buffer length=0, Out-Buffer length=112, returned code=ContinueNeeded).
System.Net.Sockets Verbose: 0 : [8864] Socket#55285825::Send()
... then there is some certificate back and forth ...
System.Net Information: 0 : [8864] SecureChannel#63848051 - Remote certificate was verified as valid by the user.
System.Net Information: 0 : [8864] ProcessAuthentication(Protocol=Tls, Cipher=Rc4 128 bit strength, Hash=Md5 128 bit strength, Key Exchange=RsaKeyX 2048 bit strength).
System.Net.Sockets Verbose: 0 : [8864] Socket#55285825::Send()
... then some more stuff ...
System.Net Verbose: 0 : [8864] Exiting HttpWebRequest#49916336::GetRequestStream() -> ConnectStream#7307007
System.Net Verbose: 0 : [8864] ConnectStream#7307007::Write()
System.Net Verbose: 0 : [8864] Data from ConnectStream#7307007::Write
System.Net Verbose: 0 : [8864] 00000000 : 3C 73 6F 61 70 65 6E 76-3A 45 6E 76 65 6C 6F 70 : <soapenv:Envelop
... more SOAP data follows (and what looks like encrypted version ...
... encrypted reply comes back, then it's decrypted ...
System.Net Information: 0 : [8864] Connection#4562529 - Received status line: Version=1.1, StatusCode=401, StatusDescription=Unauthorized.
System.Net Information: 0 : [8864] Connection#4562529 - Received headers
{
Vary: Accept-Encoding
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Length: 666
Content-Type: text/xml;charset=UTF-8
Date: Thu, 07 Aug 2014 06:21:40 GMT
Server: XXXX Web Server 8
}.
System.Net Information: 0 : [8864] ConnectStream#27021036::ConnectStream(Buffered 666 bytes.)
System.Net Information: 0 : [8864] Associating HttpWebRequest#49916336 with ConnectStream#27021036
System.Net Information: 0 : [8864] Associating HttpWebRequest#49916336 with HttpWebResponse#16709290
... with some XML with some error info (that the 3rd party doesn't seem to be able to use to pinpoint the issue ...
The short answer is that there is no difference.
Thanks to help from #EricLaw I was able to rule out any other variables he could think of.
The problem was the timestamp in the password digest. My machine time was slightly off and theirs was too (but the other way). So the result was that it worked when I pasted the data into Fiddler because I was delaying it a bit (but not too much). There's a 37 second window for these requests, and when it ran from the code it looked like it was a time from the future to their server.
When there's only one variable, that's probably the problem!
Thanks for your patience and help Eric.

HTTPS POST in C#, Winforms (Stream Writer, HttpWebResponse, HttpWebRequest)

UPDATE: I am trying to POST data to https URI. The POST works for HTTP but it fails for HTTPS uri
Hi I am creating a c# winforms exe to post data to a website. The code is below. The issue is, the stream duplicates my post data..
eg: suppose I want to post this -> username=bob
Then when I check the traffic, what is actually sent is, username=bobusername=bob
See? It duplicates, it adds the same line once more to the end of the buffer and sends it.
I am going crazy trying to find the issue from two days.. Can any body solve this or give me some hints please? thank you..
(content length is correctly set to 12, but it sends 24 bytes, after appending same data once again to the tail of buffer)
There are the headers
POST /login/ HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Host: abc.test.com
Content-Length: 12
username=bobusername=bob
-
This is the code I am currently using
string post_data = "username=bob";
string uri = "https://abc.test.com/login/";
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create(uri);
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
request.Method = "POST";
byte[] postBytes = Encoding.ASCII.GetBytes(post_data);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postBytes.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(postBytes, 0, postBytes.Length);
MessageBox.Show(postBytes.Length.ToString());
requestStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
string tmp = sr.ReadToEnd().Trim();
I put a breakpoint on line byte[] postBytes = Encoding.ASCII.GetBytes(post_data); and postBytes contains the correct data... but it gets output twice.
Why is this happening? I hope I am clear..
I tried out your code and it seemed to work as expected (sent a HTTP Post with a 12byte payload) after I changed the host in the URI to something that was addressable (used http://adsf.com/login). Here's the trace from wireshark:
You might try out the URI I used to see what you get, this will at least rule out your computer or code as possible sources of the problem. If the problem disappears when using a different URI then the problem might be between your network equipment and the web server (reverse-proxy configuration, webserver configuration, network switch configuration, etc).
You can try to get more information by setting trace configuration as described in this page. When I tried your code, I get the following output:
System.Net Verbose: 0 : [2324] Data from ConnectStream#26756241::Write
System.Net Verbose: 0 : [2324] 00000000 : 75 73 65 72 6E 61 6D 65-3D 62 6F 62 : username=bob
System.Net Verbose: 0 : [2324] Exiting ConnectStream#26756241::Write()
Looks like data is correctly written to the ConnectStream. Something wrong somewhere else?
And don't forget to close the WebResponse object.

Categories

Resources