Calling HTTPS JBoss service from C# code throws an authentication error - c#

I'm trying to call a JBoss service from a C# program and I'm getting an annoyingly vague error.
JbossService proxy = new JbossService();
proxy.Credentials = new NetworkCredential("ME", "thepwd");
proxy.Url = //https url snipped
proxy.CookieContainer = new CookieContainer();
proxy.PreAuthenticate = true;
Console.WriteLine("Calling service...");
queryResponse qr = proxy.query();
Console.WriteLine("Done.");
The exception and inner exception thrown are as follows:
exception : The underlying connection was closed: An unexpected error occurred on a send.
inner exception : Authentication failed because the remote party has closed the transport stream.
I'm not quite sure what this means, other than perhaps that JBoss likes me even less than I like it. I'm calling from the local machine so I don't think it's a networking issue. Has anyone seen this before?

This usually happens when your client cannot verify trust over https with the server (usually because the server certificate is self signed or if it is signed by a root authority not installed on your client machine.
Easy fix (although there are security consequences)....somewhere in your initialization code add the following:
System.Net.ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { return true;};
Basically this replaces the application wide handling of server certificate validation and causes your application to accept any certificate. If you want to get finer grained, you can examine the certificate and put some logic in the method.
This works for anything based on System.Net, so it should work for Web Services and any thing based on WebRequest.

I haven't used JBOSS. This is how I troubleshoot similar problems, when using Microsoft technologies -- the same issues may be affecting your program:
Firewall settings or network issue (try connecting manually, to rule this out)
Self-service certificate issues:
Check the following certificate values:
Ensure the server's certificate issuer has a valid, matching issuing trusted root Certificate Authority (CA), on the same machine
The server certificate subject name matches the machine name exactly
The machine name the client is accessing matches that defined in the server certificate
An administrator account set (server) certificate thumbprint
Try recreating the SSL Certificate on both servers)
Try creating your own CA cert, add to trusted publishers, and then create an SSL sert based on that

Related

Mailkit IMapClient not hitting ServerCertificateValidationCallback & SslHandshakeException

I'm attempting to connect to an IMAP server using the following code on a Windows Server 2019 machine:
using (var client = new ImapClient(new ProtocolLogger("protocol.log")))
{
var address = EnvReader.GetStringValue("EMAIL_ADDRESS");
var password = EnvReader.GetStringValue("EMAIL_PASSWORD");
var creds = new NetworkCredential(address, password);
client.CheckCertificateRevocation = false;
client.ServerCertificateValidationCallback = (s, c, h, e) =>
{
Console.WriteLine("ALL UP IN THIS CALLBACK" + e.ToString());
return true;
};
client.Connect("outlook.office365.com", 993, SecureSocketOptions.SslOnConnect);
client.Authenticate(address, password);
}
On my Mac, this code runs perfectly fine, I can connect and subsequently authenticate just fine.
On the Windows machine I receive the following exception:
MailKit.Security.SslHandshakeException: An error occurred while attempting to establish an SSL or TLS connection.
This usually means that the SSL certificate presented by the server is not trusted by the system for one or more of
the following reasons:
1. The server is using a self-signed certificate which cannot be verified.
2. The local system is missing a Root or Intermediate certificate needed to verify the server's certificate.
3. A Certificate Authority CRL server for one or more of the certificates in the chain is temporarily unavailable.
4. The certificate presented by the server is expired or invalid.
5. The set of SSL/TLS protocols supported by the client and server do not match.
6. You are trying to connect to a port which does not support SSL/TLS.
See https://github.com/jstedfast/MailKit/blob/master/FAQ.md#SslHandshakeException for possible solutions
Based on the info in the linked FAQ, I added the ServerCertificateValidationCallback, however the callback is never hit (The previously mentioned exception is still thrown, the relevant console logging never occurs, and a breakpoint inside the callback is never hit while debugging).
From my reading, the ServerCertificateValidationCallback should handle cases #1-4 that the exception message mentions. The fact that I can connect on the specified port on my Mac would seem to rule out case #6 (I also tried port 143 + SecureSocketOptions.StartTls). That leaves case #5, however, I can't find any information suggesting that Windows Server 2019 can't handle SSL/TSL protocols.
Any ideas for a) dealing with this exception and/or b) figuring out why the ServerCertificateValidationCallback is not firing would be greatly appreciated.
Edit: My project is referencing .NET 5.0
Let's go through each of the possibilities:
The server is using a self-signed certificate which cannot be verified.
outlook.office365.com would not be using a self-signed certificate, so that wouldn't be an issue in this case.
The local system is missing a Root or Intermediate certificate needed to verify the server's certificate.
This one is very possible, but the ServerCertificateValidationCallback override should be overriding this failure. However, it's not getting hit... so it's not actually bypassing this potential error.
A Certificate Authority CRL server for one or more of the certificates in the chain is temporarily unavailable.
This would be negated by client.CheckCertificateRevocation = false;
The certificate presented by the server is expired or invalid.
This is not the case because the certificate does not expire until 1/21/2022.
The set of SSL/TLS protocols supported by the client and server do not match.
The server supports at least TLSv1.2 which is a default TLS protocol version supported by MailKit in all target framework versions (.NET 4.5 -> 5.0 + netstandard2.x's).
You are trying to connect to a port which does not support SSL/TLS.
Port 993 is the correct port and SslOnConnect is the correct option, so this is not the issue.
Assuming there isn't a bug in MailKit's SslStream.AuthenticateAsClientAsync() call that passes in the validation callback method (.NET 5.0 is different than other versions), what is the InnerException? Maybe that will provide some insight.

Using custom SSL certificates in titanium web proxy

I have used Titanium web proxy for a windows forms application and there, I intercept https traffic and update it. I have first used titanium root certificate and it worked fine.
when I was trying to use custom ssl certificate as below
proxyServer.CertificateManager.RootCertificate = new X509Certificate2("default.pfx",
"password",
X509KeyStorageFlags.MachineKeySet);
proxyServer.CertificateManager.TrustRootCertificate(true);
but I couldn't able to decrypt the https traffic and it says
"The underlying connection was closed: An unexpected error occurred on a send." innerException says "
Authentication failed because the remote party has closed the transport stream."
how to decrypt the https traffic using custom ssl certificate in titanium-web proxy.
Issue was fixed when I add custom certification name and issuer name to proxyserver constructor and didn't needed any of above code. just fixed the issue by below code and certificate needs to installed in the machine
ProxyServer proxyServer = new ProxyServer("certificate.pfx", "Issuer Name",true,true,true);
proxyServer.CertificateManager.PfxPassword = "Password";

"The remote certificate is invalid according to the validation procedure" using HttpClient

Can't solve the problem with certificate validation.
There's Web API server, that uses HTTPS to handle requests. Server's certificate has this certification path: RCA (root) -> ICA (intermediate) -> Web API server. RCA, ICA and Web API server are members of the same Active Directory domain.
Client application (desktop, computer is joined to the same domain) uses HttpClient to communicate with server and supports two scenarios:
connected to corporate network;
disconnected from corporate network (Internet access).
Both scenarios use basic authentication.
RCA and ICA certificates are placed in "Trusted Root Certification Authorities" and "Intermediate Certification Authorities" respectively for local computer account. RCA certificate is self-signed.
Now, when client is connected to corporate network, certificate validation works as expected, and user can "talk" to Web API.
When client is disconnected (only Internet connection is available), certificate validation fails with AuthenticationException ("The remote certificate is invalid according to the validation procedure").
I don't want to turn off certificate validation completely, but just need a way to tell validation system, that this particular certificate is valid.
Also, client application uses SignalR, which by default uses it's own transport. Hence, this and this are not options.
Why placing RCA an ICA certificates to "Trusted..." and "Intermediate..." folders doesn't help?
Is there any workaround?
The issue you are experiencing is because the subject CN presented by the certificate does not match the host name in the Uri.
Make sure that the certificate bound to the public IP address of the host does have a matching CN with the host name you are using to access the resource.
To easily verify, open the Url in a browser and view the certificate.
The Issued to field should contain a FQDN and match the host name part in the Uri. In your case, it does not.
Insert this piece of code on procedure body:
static void Main(string[] args)
{
ServicePointManager.ServerCertificateValidationCallback =
delegate (object sender, X509Certificate certificate, X509Chain
chain, SslPolicyErrors sslPolicyErrors)
{
return true;
};
....
}
The answer from #Qosai was unfortunately not enough for me, at least in a SignalR 3.1 client, as the websocket part also validates SSL certificates. ClientCertificateOptions needs to be set to Manual as well.
I found a post by a SignalR contributor that got me working:
_connection = new HubConnectionBuilder()
.WithUrl(new Uri(hub_uri), options => {
options
.Cookies
.Add(http_helper.loginCookie);
var handler = new HttpClientHandler
{
ClientCertificateOptions = ClientCertificateOption.Manual,
ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true
};
options.HttpMessageHandlerFactory = _ => handler;
options.WebSocketConfiguration = sockets =>
{
sockets.RemoteCertificateValidationCallback = (sender, certificate, chain, policyErrors) => true;
};
})
.Build();
PS: If you still have issues, have a look at this article on how to enable logging properly. For my case it was a bit tricky because xUnit does not show console output. Therefore i enabled debugging logging to a file (not in the snippet)

How to set certificate in C# Win Application

Im using a webservice in my program.
this is the web service : "https://X.Y.Z.W/ib/ws/openbill.asmx?wsdl"
It works as local. when I write this on Internet Explorer, I can see the proper page after selecting "Continue to this website (not recommended)" in this attachment :
but when I want to access to this, in my c# code, I get this exception :
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
So how can I access this in my c# program?
I think you should first acquire a certificate file, and then use it in your code. For example, to set it for a SMTPClient object:
string certificate = "Certificate.cer";
X509Certificate cert = new X509Certificate2(certificate);
MailMessage message = new MailMessage(from, to);
SmtpClient client = new SmtpClient(server);
client.ClientCertificates.Add(cert);
client.Send(message);
The web service that you are trying to connect to is using SSL/TLS. When you open the web service via internet explorer, it is giving you a warning that it cannot validate the certificate of the web service.
This has many reasons, and I guess in your case it is that the certificate that the web service is using is not for X.Y.Z.W.
Another reason could be that your machine does not trust the root issuer of the web service certificate. But from the error message that you have, I don't think this is the case.
You can view the certificate in IE by click on "Continue on this web site..", and the clicking on "Certificate Error", and the "View certificates".
From there, you will view the certificate. Go to details, and look for DNS Name inside Subject Alternative Name.
The DNS name is the name of the machine that the web service certificate was given for.
I guess in your case it will not be X.Y.Z.W.
Is the web service yours? can you obtain a different certificate for it? If so, can make sure you create a certificate that has the correct DNS name.
As a last resort, you can skip certificate validation from your code (this is not recommended). Take a look at this question.

Installing self signed certificate does not resolve security error in Windows 7

I am developing a C# application which consumes a test version of a 3rd party WCF service where the server has a self signed cert. Up until now I have taken a sledgehammer approach in the setup of my integration tests of:
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
However I'd now like to make things available for UAT testing.
I have tried adding the cert to my Trusted Root Certification Authorities as detailed here:
http://blogs.adobe.com/livecycle/2012/04/rights-management-how-to-get-windows-7-to-trust-a-self-signed-server-certificate.html
Following these instructions the cert gets added to the store but I'm still getting a "Could not establish trust relationship for the SSL/TLS secure channel."
I've noticed that the "issued to" and "issued from" values are different in the cert - could this be causing the the problem?
Also, I stepped back to see if I can simply get trust to work at simply the browser level when navigating to the service URL but this generates a SSL error too.
In the end I don't care about the SSL error as it will be resolved when we switch to using a live server but I don't want to put the kludge in production code.
Any thoughts on:
the reason why installing the cert fails to resolve the failure to connect?
ways I might resolve this
Thanks in advance
For what it is worth, in our past experience (especially with self-signed certificates) we have seen the “Could not establish trust relationship for the SSL/TLS secure channel” error for two primary reasons:
The certificate was not properly saved in the certificate store
The url and certificate had a “name” mismatch
Since you seem to have tried a few certificate store locations, your issue may be a name mismatch. The following link explains the name mismatch.
http://www.digicert.com/ssl-support/certificate-name-mismatch-error.htm
Regards,

Categories