I am trying to access a WCF web service, that is using two way SSL encryption. When I try to call the service I get a
System.ServiceModel.Security.SecurityNegotiationException: Could not establish secure channel for SSL/TLS with authority 'XXX.xx'. ---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
I have tried activating wire shark, to see what is sent to and from the server: I see a client hello and a server hello. But there is no client response to the server hello. I was expecting a
"Certificate. Client key exchange. Change cipher. Encrypted handshake Message"
package, but none is sent. I'm thinking it is a problem with the certificate sent by the server, that somehow my client server does not trusy it.
Here is what I have already tried:
I have created the certificate, through the proper authority, though I could have made a mistake in the certificate request without knowing it.
I have added the two root certificates to: trusted root certificates, trusted publishers and trusted people. I have also added the client certificate to trusted people. My colleague has succeded in establishing connection on a win 2008 server (i'm using a 2003, because it is necessary for some odd reason - don't ask). I can't see any differences in our approach, so i'm a bit lost.
Any help would be greatly appreciated.
I resolved this issue:
It turn out that the app-pool did not have read permission on the private key of the certificate. We changed the app-pool to local system (I believe) and it resolved the problem.
Related
I am using MailKit to send emails.
I don't use SSL or TLS and using port 25.
The mail server I am using has port 25 open.
What is hapening is that most of the times emails are sent
without any problems and sometimes I get the following exception
An error occurred while attempting to establish an SSL or TLS
connection.
The SSL certificate presented by the server is not trusted by the
system for one or more of the following reasons:
The server is using a self-signed certificate which cannot be verified.
The local system is missing a Root or Intermediate certificate needed to verify the server's certificate.
The certificate presented by the server is expired or invalid.
See
https://github.com/jstedfast/MailKit/blob/master/FAQ.md#InvalidSslCertificate
for possible solutions. MailKit.Security.SslHandshakeException: An
error occurred while attempting to establish an SSL or TLS
connection.
The SSL certificate presented by the server is not trusted by the
system for one or more of the following reasons:
The server is using a self-signed certificate which cannot be verified.
The local system is missing a Root or Intermediate certificate needed to verify the server's
certificate.
The certificate presented by the server is expired or invalid.
Here is the code sample I use
My questions are :
1 - why it tries to use SSL or TLS given that I set not to use it
2 - why it happens randomly
The ConnectAsync() method that takes a bool useSsl argument only specifies whether the initial connection must use SSL (or, as another way of wording it, it specifies whether the port you are connecting to is SSL-wrapped).
As an example of an SSL-wrapped port, for SMTP that would be port 465.
This option does not tell MailKit whether or not to use the STARTTLS command once the plain-text connection is established.
If you want to disable SSL/TLS completely, use the ConnectAsync() method that takes a SecureSocketOptions argument:
await client.ConnectAsync(m_mailServer, 25, SecureSocketOptions.None);
I have a C# application making a successful TCP TLS 1.0 connection with mutual authentication to another company's server. It is implemented using SslStream class. We are just one of many clients of this very large organisation.
This TCP link above must undergo TLS 1.2 + SHA2 upgrade. After doing all necessary steps on our side and successful testing with our local servers we are still failing all attempts to connect to the remote server. A lengthy investigation revealed that during TLS Handshake the server is sending to us a certificate request with only option for Signature Hash Algorithm = SHA1-RSA (see picture below). Our cerificate is SHA256. As a result, SslStream is not sending our certificate to the server at all and the server sees this as a Handshake Failure and closes down the connection.
The reason for this nuisance is that our counterparty uses very old (10.x) version of F5 firewall to terminate SSL. It only sends SHA1/RSA Signature Hash Algorithm in the certificate request although it supports the client’s SHA2 certificates.
While admitting the facts above, our counterparty is unable to upgrade F5 soon enough. They suggested to ignore the requested Signature Hash Algorithm and send our SHA256 certificate anyway. Apparently other clients connecting to them were able to do that somehow.
Unfortunately,.Net's SslStream does not provide that level of fine tuning for TLS handshake.
Hence the question: is it possible to ignore the server's request for SHA1RSA-based certificate at all? What options do I have? Are there SslStream alternatives that implement TLS 1.2? Is there an open-source third-party solution? Any suggestion would be helpful. Thanks in advance.
The issue above was eventually resolved without any special code changes: a proxy server added on our side. It took care of communication with the other party. The proxy server is able to ignore the specific SHA1/RSA Signature Hash Algorithm in the incoming certificate request.
I'm running IIS 7.5 on Win2k8, and am trying to configure 2-way SSL. I've turned Require Client Certificate on in IIS, I've installed a valid root certificate in my local machine's trusted root store, and I've installed the server cert and configured IIS to use it.
When I first tested this configuration, I was able to connect with a valid cert, and unable to connect with an untrusted cert. So far so good. However, when I revoked a user cert, that user was still able to gain access to the website using the revoked certificate.
I read that the server may have been using a cached copy of the CRL, so I used "certutil -setreg chain\ChainCacheResyncFiletime #now" to clear the cache, reimported my CRL into the Intermediate Certificate Authority store, and tried again. This time, the server rejected ALL attempts to connect, including those with valid certs, returning 403.13 and "The revocation function was unable to check revocation because the revocation server was offline."
My setup is a little unusual because the CA server is not available to my network, so there is no OCSP and no CDP. Instead, I manually import the CRL to the server whenever a new one is issued, call it once a week. So I've enabled 'Verify Client Certificate Revocation' and 'Verify Revocation Using Cached Client Certificate Only', to try to enforce checking for revocation and to prevent the server from trying to go to an unreachable CDP and thus failing the check because the server is unreachable.
Unfortunately, it looks like the server is not using the CRL I loaded into the machine store, and is instead rejecting all users because it thinks it does not have a valid CRL and cannot request a new one.
How do I get client authentication and 2-way SSL working with revocation checking when I don't have access to a CDP?
Don't inport CRLs to store manually. Make access to CDP :)
You could do this:
Find a server in your infrastructure that has connect to the CDP and also to your server.
Then either deploy new CRLs there and change DNS (or change hosts file on your server) to point to this server whenever windows/IIS asks for new CRL.
Or make this new server a proxy (I think it called reverse proxy) delegating requests for new CRL to correct destination at CDP.
Both solutions should work. The first mentioned could be somewhat harder to implement and maintain because you would have to monitor if the script (or person) really deploying the CRLs.
I have .NET 2.0 Windows Forms app that makes an HttpWebRequest to download a file from a secure HTTPS server. This has run flawlessly in test on 3-4 completely separate networks.
My client needs to run this on a very restricted, secure network. Only authorized personnel are allowed to be on that network. Our liason tester who is allowed to install and test the app reports that the it is failing with this error:
The request was aborted: Could not create SSL/TLS secure channel.
Using wireshark, he is able to see that two of the three SSL handshakes occur. Any idea why the third would not occur?
He is able to successfully hit the download link from IE and download the file, which makes me believe that permissions are set up correctly.
In my app, I have set a couple of ServicePoint properties: Expect100Continue = true and require SSL3. Also I have set the validation callback to always return true (accept all certificates). Any idea why the app can't establish and SSL connection, but IE can?
Any help debugging this would be super. Thanks.
UPDATE 3/7/2012
Added System.Net tracing and here is a piece that I found interesting. Algorithm mismatch.
I had this problem too. Cost me a lot of time... In my case I found out the server wants to check the third party's certificate with the Certificate Authority (CA). Only the CA's ip-address got blocked by the firewall. This all happens during the handshake and got me the same error message.
I have a C# console app on a Windows Server 2003 machine that sends data (over SSL) to a web service hosted on a Windows Server 2003 R2 machine. I have the entire certificate chain installed on both the Current User and Local Computer certificate stores in MMC (Microsoft Management Console).
I can hit the web service (.asmx page) in IE and Firefox just fine. I'm assuming because it uses the Current User certificate store. However, my C# app returns the following error:
System.ServiceModel.Security.SecurityNegotiationException: Could not establish trust relationship for the SSL/TLS secure channel with
authority 'www.samplewebservice.com'. ---> System.Net.WebException:
The underlying connection was closed: Could not establish trust
relationship for the SSL/TLS secure channel. --->
System.Security.Authentication.AuthenticationException: The remote
certificate is invalid according to the validation procedure.
It's almost like the certificate isn't stored in the right "account" or "container" in MMC. I browsed through the various service accounts and they all seem to have the cert. I know .NET runs under the "NT AUTHORITY\Network Service" account but "Network Service" isn't listed under the Service Accounts in MMC. I checked the following service accounts and they all had the correct certificates (I never copied them so I'm assuming it's because they're in the Local Computer account):
Computer Browser
Network Connections
Network Manager
I'm completely stumped. It's like .NET doesn't have access to the certificates. I wish I could use a keystore similar to Java. Has anyone ever came across this?
I had a similar issue. I got around by deleting the certificates, reinstalling them and restarting both PC and IIS. Also make sure your certificatess haven't expired and are trusted in the machine's store.
Somewhere early in your processing pipeline:
ServicePointManager.ServerCertificateValidationCallback = (a,b,c,d) => true;
This is to ensure that all certificates are accepted.
Of course as John points out, such general callback could possibly be dangerous so please fine tune it so that on one hand it solves your issue and on the other hand it doesn't introduce any security issues.
I hope John is satisfied now. I should have been more talkative, and so should he :)