Ignore SSL self signed certificate errors Restful httpclient - c#

I have done tons of searching and reading on this, there are so many different ways to achieve this. However, things have changed a bit since a lot of the posts. Ultimately, I am using a UWP (10586 minimum target) app. I have wrapped my httpclient code into a .net standard library which my UWP app consumes. However, because of the 10586 SDK version, my .net standard library must be 1.4 or lower.
I need to post json to a web service in a RESTful way. Tjis web service uses SSL but has a self signed certificate. So, I get certificate errors. I simply want to ignore them so I can make my calls. Using 3rd party web service test utility (Postman), I have confirmed the calls will work if SSL errors are simply ignored.
Based on my UWP and .net standard setup, I cannot use the X509 namespace to ignore SSL errors. This is one method but X509 is not available.
So, this looked most promising: https://blog.roushtech.net/2016/12/20/ignoring-ssl-certificate-errors-net-core-httpclient/
It has no compiler errors, but at runtime I get a "platform not supported" exception.
Is there any way to work around all of this given my configurations?
EDIT: The exact snippet I am using that seems to be the supported method in the future but gives platform error on UWP is the same in the link I copied above. For reference, this is what I am doing:
using (var httpClientHandler = new HttpClientHandler())
{
httpClientHandler.ServerCertificateCustomValidationCallback = (message,
cert, chain, errors) => { return true; };
using (var client = new HttpClient(httpClientHandler))
{
// Make request here.
}
}
Also, yes my code does work with non ssl (http) calls. It had been working fine for some time until I needed to access a new/different web service which is configured as ssl.
Thanks!!!

Related

How do i Set the System.ServiceModel.ClientBase<TChannel> to Ignore CERT Errors

I am moving an application that communicates with a WCF service from .net 4.8 to net5 i ran the utility SvcUtil.exe (importing a WDSL File) which generated the Reference.cs file which created the classes and object from the WSDL file. In net5 it is now using the System.ServiceModel.ClientBase class to interact with the WCF Service, where as in net48 it was using 'System.Web.Services.Protocols.SoapHttpClientProtocol'. Code compiles but there remains two problems that I'm experiencing right now that i cannot seem to find the answer for using the new 'System.ServiceModel.ClientBase' implementation generated by the SvcUtil.exe tool.
When the connection is trying to be established i am always getting the following Exception:
{"Could not establish trust relationship for the SSL/TLS secure channel with authority 'xxx.xxx.xxx.xxx'."} InnerException => {"The SSL connection could not be established, see inner exception."} InnerException => {"The remote certificate is invalid according to the validation procedure: RemoteCertificateNameMismatch, RemoteCertificateChainErrors"}
Also the in the net48 version i store the cookie in the cookie container like So:
Cookie cookie = new Cookie(cookieParts[0], cookieParts[1],
serviceUri.LocalPath, serviceUri.Host);
cookie.Expires = DateTime.Now.AddHours(1);
_xieServiceRef.CookieContainer = new CookieContainer();
_xieServiceRef.CookieContainer.Add(serviceUri, cookie);
My problem is that for one in net48 to tell the service to ignore all cert errors we execute the following code
ServicePointManager.ServerCertificateValidationCallback +=
(sender, cert, chain, sslPolicyErrors) => { return true; }
From anywhere in the app and we bypass those errors. But in net5 you have to approach it differently and the only example is given using the HttpClient class and you create the HttpClient with a defined HttpClientHandler callback as in the example below this will ignore the CERT errors just as the code above for net48.
var EndPoint = "https://192.168.0.1/api";
var httpClientHandler = new HttpClientHandler();
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) =>
{
return true;
};
httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(EndPoint) };
In using the SvcUtil.exe generated code with the use of the ClientBase class as a means of interaction with the WCF Service, I cannot find methods or example similar to the above code to ignore the CERT errors. I also cannot find the Cookie Container for the ClientBase either. Do I need to skip using the generated code from SvcUtil.exe and switch to the HttpClient instead of the ClientBase. Or are there similar ways to store the generated cookie and ignore the CERT errors. We don't control the API we are calling and there is no REST version of the API and none coming soon so we are stuck working with what we have.
Any advice would be greatly appreciated and also thank you ahead of time
UPDATE
So i did some more research and digging and i have found that using the following code:
//Right Here we are creating the Service Object
XIEserviceClient _xieServiceRef = null;
_xieServiceRef = new XIEserviceClient();
_xieServiceRef.ChannelFactory.Credentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication()
{
CertificateValidationMode = X509CertificateValidationMode.None,
RevocationMode = X509RevocationMode.NoCheck
};
_xieServiceRef.ChannelFactory.Credentials.UserName.UserName = CalderaConfiguration.SelectedOS4000ApiConnection.Username;
_xieServiceRef.ChannelFactory.Credentials.UserName.UserName = CalderaConfiguration.SelectedOS4000ApiConnection.Password;
We are now able to bypass the cert errors.
Now I'm just trying to I'm to figure out the whole cookie/authentication error, I now get the following Exception:
"The content type text/html of the response message does not match the content type of the binding (text/xml; charset=utf-8)
This i believe, according to Fiddler, appears to be an authentication issue because it appears that a login page is being returned from the service i believe this is the cookie issue I'm still looking into....
There are a few things to consider :
Do you have DNS and line-of-sight to the server?
Are you using the correct name from the certificate?
Is the certificate still valid?
Is a badly configured load balancer messing things up?
Does the new server machine have the clock set correctly (i.e. so that the UTC time is correct [ignore local time, it is largely irrelevent]) - this certainly matters for WCF, so may impact regular SOAP?
Is there a certificate trust chain issue? if you browse from the server to the soap service, can you get SSL?
Related to the above - has the certificate been installed to the correct location? (you may need a copy in Trusted Root Certification Authorities)
is the server's machine-level proxy set correctly? (which different to the user's proxy);see proxycfg for XP / 2003 (not sure about Vista etc)

Bypass invalid SSL certificate errors .Net / c#

I've got a development system which I'm trying to get to communicate to a third-party secure web service.
The third party have provided me with a certificate which I've imported locally. I've made sure the certificate is added to the 'Trusted Root Certification Authorities' store. It seems to have imported correctly, as if I go Chrome and try to access one of the service urls mentioned in the web service WSDL file I firstly get a popup asking to me to confirm which certificate to use (there's only the one option) and it then lets me through. However, if I then use the same WSDL file to create a service reference in Visual Studio, and make a call to one of the services in my code, I get an error saying 'Could not establish secure channel for SSL/TLS with authority'.
Ideally I would get VS to acknowledge the cert when I'm making the webservice call, but seeing as this is a development system I'm also happy to ignore the SSL errors for the time being.
To this end I've added the following to my code, along with variations on the protocols I'm specifying (e.g. only specifying SSL3, taking out SSL3 etc):
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12
| SecurityProtocolType.Ssl3;
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
But no matter what I do I still get the SSL error when I try to make the service call.
If anyone has any suggestions on how to get VS to accept the certificate is present (as Chrome seems to do) or, alternatively, how to get the code to ignore the SSL error for now, so I can proceed with development, it'd be much appreciated.

Invoking Java web service from C# client using JKS and/or PFX certificates

I basically need to secure my requests towards this service.
I've been provided a JAR test client and two files, trust.jks and Client.pfx, but I have no clue how to use them: I understand X509Certificate2 class is involved in some way.
The command line to execute the test client is the following:
java -Djavax.net.ssl.trustStore=trust.jks -Djavax.net.ssl.trustStorePassword=******** -Djavax.net.ssl.trustStoreType=JKS -Djavax.net.ssl.keyStore=Client.pfx -Djavax.net.ssl.keyStoreType=pkcs12 -Djavax.net.ssl.keyStorePassword=******** -jar TestClient.jar https://myServiceurl
It works, so I can both see the service, and the service itself should be properly configured.
My C# client (it's targeting .NET 2.0) uses a normal Web Reference to perform requests:
wsReferenceClient service = new wsReferenceClient();
//certificate code here ?
//maybe service.ClientCertificates.Add(<X509Certificate2 object built somehow>); ?
service.MyRequest(myParameters);
Server settings should be setup properly.
I fumbled around with the X509Certificate2 methods but I can't come out with something that makes sense, so the answer to the 'what have you tried?' question at the moment is 'I don't really know what to try in the first place'.
Any help would be really appreciated.
Turns out I don't need to do anything with the JKS file.
wsReferenceClient service = new wsReferenceClient();
X509Certificate2 cert = new X509Certificate2();
cert.Import("Client.pfx", "<the password>", DefaultKeySet);
service.ClientCertificates.Add(cert);
service.MyRequest(myParameters);
This allows my HTTPS requests to go through successfully.

HttpListenerRequest is not returning a client certificate

I'm using an HttpListener to create a very basic web server. I've got it setup to use SSL using the httpcfg tool to bind to the appropriate port and certificate. This seems to be working fine. I'd now like to use client certificate authentication. So I added a call to GetClientCertificate on the HttpListenerRequest object but it is always coming back with null. My test client is very simple:
HttpWebRequest webReq = (HttpWebRequest) WebRequest.Create("https://127.0.0.1:8080/ssltest/");
webReq.ClientCertificates.Add(new X509Certificate2("ssltest.pfx", "ssltest"));
webReq.GetResponse();
I noticed that the httpcfg tool has a flag that indicates if client certificates should be negotiated so I tried specifying that flag (-f 2) but I'm still not getting the client cert. I also came across this Microsoft support issue which seems pretty relevant but I'm using the latest .NET 2.0 service pack and I've also tried the httpcfg flag both of which should avoid the issue.
I am assuming I am missing something obvious here. Any ideas?
Edit: I just found this question which seems very relevant (maybe even a duplicate?). Unfortunately there is no accepted answer for that question either. The suggested answer makes a suggestion for something I already tried (httpcfg tool with the appropriate flag).
According to http://support.microsoft.com/kb/895971/en-us the HttpWebRequest.ClientCertificates.Add performs validation already so the cert fails validation on the client-side and never gets sent.
The above link contains code to relax the validation... NEVER use that in production!!!

Using WCF service in MonoTouch with Authentication

I am using a WCF service client generated by slsvcutil form Silverlight toolkit version 4. I've also tried version 3 with the same problems. When I use a client instance running on http with no user credentials it runs without problems. But I need to switch to https for productive servers and send user credentials that are hardcoded for my application. I use the following code for that:
var binding = new BasicHttpBinding (BasicHttpSecurityMode.TransportCredentialOnly);
var endpoint = new EndpointAddress (AppSettings.FlareEndPoint);
_service = new TopicAnalystAPIClient(binding, endpoint);
_service.ClientCredentials.UserName.UserName = "xxx";
_service.ClientCredentials.UserName.Password = "xxx";
When I call a method on that service pointing to http with no authentication it works. When I use the this code against http/https with the credential I get "There was an error on processing web request: Status code 401(Unauthorized): Unauthorized" exception. I've checked that the credentials are correct, I am able to open the service reference in my browser. I've also tried several combinations of http/https and SecurityMode value. I've also tried it on four different servers always with the same result.
What can be the problem?
A lot of permutations are possible. BasicHttpSecurityMode.TransportCredentialOnly should be usable without SSL [1] using HTTP itself. This means the server will send one (or more) authentication method(s) to the client (e.g. basic, digest, ntlm) and Mono (including MonoTouch) should be providing support for the most of them.
It is possible that the linker (if used) removes one of them. In that case you could try building and testing without linking (or skip linking of System.Net.dll).
It's also possible that the authentication method that the serve insist on is not supported. You could find which one is used by running a network trace (e.g. wireshark) or, maybe, it will show up in more details in the server log (along with the 401 error).
[1] http://msdn.microsoft.com/en-us/library/system.servicemodel.basichttpsecuritymode%28v=vs.95%29.aspx

Categories