Trying to get RabbitMQ wired up to play nice with TLS v1.2. Working with both a Java client and a .NET Core client. The Java client is working but the .NET one is pushing back. Here are my factory settings:
var factory = new ConnectionFactory
{
HostName = hostName,
VirtualHost = vHost,
UserName = username,
Password = password,
Port = 5671,
Ssl = {Enabled = true}
};
I’m getting this exception:
System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception.
---> Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL.
---> Interop+Crypto+OpenSslCryptographicException: error:1409442E:SSL routines:SSL3_READ_BYTES:tlsv1 alert protocol version
Looking at the very tail end of the exception message it appears that the TLS version might be old but I have the latest version of RabbitMQ installed – 4.1.1
Dug into the RabbitMQ source for the ConnectionFactory class but cannot find anything relating to setting the TLS version. In my Java app it works thusly: factory.useSslProtocol("TLSv1.2");
Saw in another SO thread that an old version of Erlang might be the cause but I have the latest version (8.1) installed.
Any pointers on where to look next?
UPDATE: Foound the way to set the TLS property:
factory.Ssl.Version = SslProtocols.Tls12;
But now I'm getting a System.Security.Authentication.AuthenticationException: The remote certificate is invalid exception.
this worked for me:
Ssl = new SslOption
{
Version = SslProtocols.Tls12,
Enabled = true,
}
Related
I a getting an SSL Handshake error on an Ubuntu server in ASP.Net Core
I am getting the following error from an HttpClient request.
Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL.
---> Interop+Crypto+OpenSslCryptographicException: error:0A000152:SSL routines::unsafe legacy renegotiation disabled
I simulated the request in curl and got a similar error.
I was connecting to bluesnap and the error code meant that the endpoint does not allow TLS renegotiation starting below TLS 1.3.
Now, these curl requests worked on Windows, but not Linux. And only for a specific endpoint. It appeared that Windows negotiated TLS version from 1.3 downward while Linux negotiated upwards from 1.0.
In my case I needed to specify TLS 1.3. I did not want to do it globally so I did it like so with my HttpClient:
var handler = new HttpClientHandler() { SslProtocols = SslProtocols.Tls13 };
var client = new HttpClient(handler);
var request = new HttpRequestMessage();
request.RequestUri = new Uri(url);
Check your endpoint and see if it requires a specific version of TLS.
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.
I am implementing the Microsoft EWS api in order to get emails from the on-prem Exchange Server. Considering that the Microsoft has abandoned the development, I am using the sherlock1982 fork from ews api. My app is written in .net core 2.1 and when running on my local PC (win10), everything is working well. Considering that its a Linux, it is not possible to automatically get the Autodiscover url, so I am manually setting it in the code, as suggested on the github page.
public async void GetInbox()
{
string ewsUrl = "https://mail.domain.com/EWS/Exchange.asmx";
try
{
var service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
service.UseDefaultCredentials = false;
// service.Credentials = new NetworkCredential("domainUsername", "password", "domain");
service.Url = new Uri(ewsUrl);
Mailbox mb = new Mailbox("emailAddress");
var cache = new System.Net.CredentialCache();
cache.Add(service.Url, "NTLM", new
System.Net.NetworkCredential("domainUsername", "password",
"domain"));
service.Credentials = cache;
FolderId fid = new FolderId(WellKnownFolderName.Inbox, mb);
Folder inbox = await Folder.Bind(service, fid);
if (inbox != null)
{
_database.LogEvent("LOG", "GetInbox", $"InboxCount: {inbox.TotalCount}");
}
}
catch (Exception e)
{
_database.LogEvent("Error", "GetInbox", $"{e.Message}");
}
}
When deployed to the test server running CentOS7, I am getting following message:
The request failed. The SSL connection could not be established, see inner exception.
at Microsoft.Exchange.WebServices.Data.EwsHttpWebRequest.GetResponse(CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\EwsHttpWebRequest.cs:line 147
at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest request, CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\ServiceRequestBase.cs:line 798
--- End of inner exception stack trace ---
at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest request, CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\ServiceRequestBase.cs:line 808
at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ValidateAndEmitRequest(CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\ServiceRequestBase.cs:line 688
at Microsoft.Exchange.WebServices.Data.SimpleServiceRequestBase.InternalExecuteAsync(CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\SimpleServiceRequestBase.cs:line 57
at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.ExecuteAsync(CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\MultiResponseServiceRequest.cs:line 134
at Microsoft.Exchange.WebServices.Data.ExchangeService.BindToFolder(FolderId folderId, PropertySet propertySet, CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\ExchangeService.cs:line 325
at Microsoft.Exchange.WebServices.Data.ExchangeService.BindToFolder[TFolder](FolderId folderId, PropertySet propertySet, CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\ExchangeService.cs:line 345
at ExchangeFiles.Email.Download_PI_Files_Email() in D:\dev_in_progress\get_emails_v1\ExchangeFiles\Email.cs:line 199
I have tried ignoring the certificate with
ServicePointManager
.ServerCertificateValidationCallback +=
(sender, cert, chain, sslPolicyErrors) => true;
but without luck (I am getting the same error).
UPDATE:
I have added a following piece of code
ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) =>
{
if (cert.GetCertHashString().ToLower() == "someHashCert")
{
return true;
}
if (sslPolicyErrors == SslPolicyErrors.None)
{
return true; //Is valid
}
return false;
}
inside the code for creating HttpClientHandler. Its entering inside the if "cert.GetCertHashString().ToLower()" which is good. I have copied the value of someHashCert from the browser.
I also tried setting the
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
But error with this code (and above when checking the cert) is:
The request failed. The handler does not support custom handling of certificates with this combination of libcurl (7.29.0) and its SSL backend ("NSS/3.44"). An SSL backend based on "OpenSSL/1.0.2k-fips" is required. Consider using System.Net.Http.SocketsHttpHandler.
If I set
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", true);
I am getting:
The request failed. GSSAPI operation failed with error - An unsupported mechanism was requested (Unknown error).
I have also tried to setup the callback for certificate from MS doc cert for ews api but then I am getting "Unable to get local issuer certificate" msg.
Not sure is this is step forward or backward... I have a feeling that I have tried everything...
UPDATE2
The ExchangeSever version is 2016, its using NTLM authentification and TLS1.0/1.1
I tried curl -v -k -i --anyauth -u : mail.server.domain:443 and it says
* About to connect() to mail.server.domain: port 443 (#0)
* Trying xx.xx.xx.xxx...
* Connected to mail.server.domain (xx.xx.xx.xxx) port 443 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: mail.server.domain::443
> Accept: */*
Any idea is welcome... Thanks
Unfortunately, nothing suggested from here worked.
I found some comment about similar issue on github and how updating the project to .NET core 3.1 fixed the error, so I decided to give it a try...
It was not a small work, I had several projects inside the solution, but I can confirm that after updating from .NET core 2.1 to .NET core 3.1, everything is working as it should.
Update your TLS on Cent OS.
TLSv1.2 should be available on CentOS 7.
Some documentation.
Linux OpenSSL 1.1.1 supports TLS v1.3 in different Linux OS.
RHEL 8 - Red Hat Enterprise Linux 8 is the first Enterprise Linux distribution that ships with the TLS v1.3 protocol fully integrated into the operating system.
Older CentOS and RHEL OS versions have OpenSSL v1.0.2 installed by default, so TLS v1.3 is not supported natively.
OpenSSL can be yum updated to OpenSSL v1.1.1 to support TLS v1.3.
Blockquote
How to install OpenSSL v1.1.1 on CentOS RedHat Linux:
Use the OpenSSL Version Command to verify the OpenSSL Version:
openssl version
Install wget(If it is not installed):
yum install wget
Download the latest version using wget:
wget https://ftp.openssl.org/source/old/1.1.1/openssl-1.1.1.tar.gz
Decompress the file:
tar xvf openssl-1.1.1.tar.gz
Further configuration is necessary, Please consult your System Administrators prior to making any changes.
disabled by default system wide. If you enable TLS v1.3 on a system for testing, then
TLS should be supported by OS and .net framework.
Check OS and upgrade it if it does not support TLS 1.2
then use Right .net framework which supports TLS 1.2 /1.3
Install Self signed cert on Cent OS also.
Will TLS 1.3 be supported on .NET?
For .NET, the official guidance at this point (via the best practices page above) is to rely on the underlying OS to provide the TLS version (which will automatically default to the strongest available version of the TLS protocol), and avoid hardcoding/specifying an explicit TLS version in application code.
Starting with .NET Framework 4.7, the default configuration is to use the OS TLS version.
Other links which may be helpful: https://github.com/dotnet/docs/issues/4675 and https://learn.microsoft.com/en-us/dotnet/framework/network-programming/tls
I'm using SSIS to connect to a Cisco web service hosted on the Cisco machine that manages our telephones. I've tested the service in SoapUI and have found everything to be working. I can get/use the WSDL, can connect to the service using authentication credentials, get an expected reply.
I first tried to use a Web Service Task. I set up my Http Connection Manager, selected it to use credentials, and ran the test. The test completed successfully. I downloaded the wsdl and saved it locally. In the Web Service Task I point to the wsdl file and the service and methods are detected in the input pane. But when I execute the task, I get the following exception:
Error: 0xC002F304 at Web Service Task, Web Service Task: An error occurred with the following error message: "Microsoft.SqlServer.Dts.Tasks.WebServiceTask.WebserviceTaskException: The Web Service threw an error during method execution. The error is: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel..
at Microsoft.SqlServer.Dts.Tasks.WebServiceTask.WebMethodInvokerProxy.InvokeMethod(DTSWebMethodInfo methodInfo, String serviceName, Object connection)
at Microsoft.SqlServer.Dts.Tasks.WebServiceTask.WebServiceTaskUtil.Invoke(DTSWebMethodInfo methodInfo, String serviceName, Object connection, VariableDispenser taskVariableDispenser)
at Microsoft.SqlServer.Dts.Tasks.WebServiceTask.WebServiceTask.executeThread()".
Again, my Http connection test passed, and I’ve retyped my credentials that enabled me to successfully test with SoapUI several times now.
After being unable to resolve the issue with a Web Service Task, I tried using a Script Task. I set up a HttpWebRequest and set all the header properties the same way they were while testing in SoapUI. Also, I set the Authorization: Basic value to correct value. I then built the data String that is passed to a StreamWriter exactly the way it was for the SOAP Envelope in SoapUI. The StreamWriter Writes and then Closes, but when I call GetResponse, I get the wonderful exception of:
Warning: 0x0 at Script Task 1, WEB EXCEPTION CAUGHT: : The server committed a protocol violation. Section=ResponseStatusLine
Error: 0x6 at Script Task 1: The script returned a failure result.
For this issue I’ve tried
Setting ProtocolVersion to 1.0 and then tried 1.1
Setting KeepAlive to false
Setting ServicePoint.Expect100Continue = false;
Tried to programmatically set useUnsafeHeaderParsing to true but the script would not compile even though the editor did not indicate any errors (may have been caused by reflection, I don’t know)
Don’t know how to access the configs in my SSIS package to set useUnsafeHeaderParsing to true that way
None of these worked. It doesn’t matter which task I use, I just need one to work. Anybody have any ideas/suggestions or can point me toward anything else I can use to research these issues? (I’ve been Googling for two days now :( ).
Below is a snippet of my code from my script in case anyone else can see an issue I’m overlooking. Thank you for your time and reading my question!
StreamReader responseReader = null;
StreamWriter requestWriter = null;
string data = getPayload();
HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create("http://***********:8443/realtimeservice2/services/RISService");
httpRequest.ProtocolVersion = System.Net.HttpVersion.Version11;
httpRequest.Method = "POST";
httpRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
httpRequest.ContentType = "text/xml;charset=UTF-8";
httpRequest.Accept = "Accept: text/*";
httpRequest.Headers.Add("SOAPAction", "executeCCMSQLStatement");
httpRequest.Headers.Add("Authorization", "Basic ********");
httpRequest.ContentLength = data.Length;
httpRequest.Host = "*********:8443";
httpRequest.KeepAlive = false;
httpRequest.UserAgent = "Apache-HttpClient/4.1.1 (java 1.5)";
requestWriter = new StreamWriter(httpRequest.GetRequestStream(), System.Text.Encoding.ASCII);
requestWriter.Write(data);
requestWriter.Close();
WebResponse webResponse = httpRequest.GetResponse();//EXCEPTION THROWN
UPDATE
So we’ve tried installing the service host’s certificate into the trusted root store of the machine making the call. The connection manager can now test an https successfully, but when I run the package I still get the same ‘Could not establish trust relationship for the SSL/TLS’ issue. My desktop can still successfully connect to the service, make the call, and get back expected results. But for some reason I cannot get the DB server and the service host to play nice together.
The way TLS should be enable depends on the .NET Version used:
NET 4.6 and above. You don’t need to do any additional work to support TLS 1.2, it’s supported by default.
NET 4.5. TLS 1.2 is supported, but it’s not a default protocol. You need to opt-in to use it. The following code will make TLS 1.2 default, make sure to execute it before making a connection to secured resource:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
NET 4.0. TLS 1.2 is not supported, but if you have .NET 4.5 (or above) installed on the system then you still can opt in for TLS 1.2 even if your application framework doesn’t support it. The only problem is that SecurityProtocolType in .NET 4.0 doesn’t have an entry for TLS1.2, so we’d have to use a numerical representation of this enum value:
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
NET 3.5 or below. TLS 1.2 is not supported (*) and there is no workaround. Upgrade your application to more recent version of the framework.
More information: https://blogs.perficient.com/2016/04/28/tsl-1-2-and-net-support/
I'm trying to use RestSharp in Visual Studio 2012 Express on a fresh install of Windows 8.1. The API I'm trying to use supports only RC4-SHA for SSL. The certificate is valid.
var client = new RestClient();
client.BaseUrl = "https://teststore.mybigcommerce.com/api/v2/";
client.Authenticator = new HttpBasicAuthenticator("username", "key");
var request = new RestRequest();
request.Resource = "time.json";
IRestResponse response = client.Execute(bcrequest);
I keep getting an error from the client: The request was aborted: Could not create SSL/TLS secure channel. I thought there were certificate problems, until I finally took a packet capture and discovered there were no cipher suites in common. RC4-SHA is not available on the client end. After installing Windows 7 and running the exact same code, the problem goes away.
Why is RC4-SHA unavailable in RestSharp on Windows 8.1?
I always add the following line of code before making the initial network connection to solve this issue.
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12 | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls11;
I had an application the failed tls handshake after I insalled Win 8.1. My Wireshark captures on working and non working client logons showed missing cipher suites. Installing a real certificate on the server I was connecting to also solved the problem. The server had a self signed certificate.
I finally found this Microsoft article:
RC4 is no longer enabled by default for TLS. Applications (such as
Internet Explorer) might fail to connect if they depend on RC4
You can enable RC4 support by configuring these registry keys with the
following REG command:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4
128/128]"Enabled"=dword:ffffffff
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4
40/128]"Enabled"=dword:ffffffff
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4
56/128]"Enabled"=dword:ffffffff