Redth / PushSharp

A server-side library for sending Push Notifications to iOS (iPhone/iPad APNS), Android (C2DM and GCM - Google Cloud Message), Windows Phone, Windows 8, Amazon, Blackberry, and (soon) FirefoxOS devices!
Other
4.39k stars 1.52k forks source link

APNS only allows insecure TLS 1.0 protocol #819

Open rbalean opened 7 years ago

rbalean commented 7 years ago

What version of PushSharp are you using?

4.0.10

Describe your issue:

We disabled TLS1.0 on our server because it is insecure and we have been told we cannot allow it on our network. Unfortunately, PushSharp then no longer works (Exception: The client and server cannot communicate, because they do not possess a common algorithm). We looked into the source and saw that you explicitly try to send messages using TLS1.0. You can easily fix this by allowing other TLS versions in your source.

e.g.

System.Security.Authentication.SslProtocols proto = System.Security.Authentication.SslProtocols.Tls | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls12;
stream.AuthenticateAsClient (Configuration.Host, certificates, proto, false);

The problems seem to be in the files PushSharp.Apple/ApnsConnection.cs and PushSharp.Apple/ApnsFeedbackService.cs

What are the steps required to reproduce this issue?

Disable TLS1.0 on the server that sends the APNS message

Please provide any Exception Stack Traces

Apple Notification Exception: System.ComponentModel.Win32Exception (0x80004005): The client and server cannot communicate, because they do not possess a common algorithm at System.Net.SSPIWrapper.AcquireCredentialsHandle(SSPIInterface SecModule, String package, CredentialUse intent, SecureCredential scc) at System.Net.Security.SecureChannel.AcquireCredentialsHandle(CredentialUse credUsage, SecureCredential& secureCredential) at System.Net.Security.SecureChannel.AcquireClientCredentials(Byte[]& thumbPrint) at System.Net.Security.SecureChannel.GenerateToken(Byte[] input, Int32 offset, Int32 count, Byte[]& output) at System.Net.Security.SecureChannel.NextMessage(Byte[] incoming, Int32 offset, Int32 count) at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) at PushSharp.Apple.ApnsConnection.d25.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at PushSharp.Apple.ApnsConnection.d21.MoveNext()

ghulammustafa commented 7 years ago

Similar issue exist for Android as well i.e. GCM Push Notifications don't work if TLS 1.0 is disabled.

Applying following changes to PushHttpClient and ServiceBroker constructors worked for us:

..\PushSharp.Core\PushHttpClient.cs(15): ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

..\PushSharp.Core\ServiceBroker.cs(17): ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Hope this helps, and save someone else's time.

Thanks, Mustafa

jekcom commented 6 years ago

Any status on this? will it be resolved?

TonyLugg commented 6 years ago

This has bit us badly. Can you fix it @Redth?

MrCsabaToth commented 6 years ago

I wonder if the cause is on Apple's end?

TonyLugg commented 6 years ago

Well, Apple's end is ridiculously complicated, which stopped us from trying to build our own service. Will try Azure Notification Hub I guess.

Redth commented 6 years ago

Use Azure... rolling your own is overly complex and fraught with errors when you can just use azure.

TonyLugg commented 6 years ago

That is my plan. I enjoyed your PushSharp for a number of years, though! 🥇

emmanuelware commented 6 years ago

I really don't think switching Services just because one stopped working is the best solution to solving anything. There is always a solution to every problem. For anyone else facing the same issue, this is how I was able to get it working: First clone or Download the current repository then along with @ghulammustafa 's fix above, I also added the following

-------------------------------------------------Android-------------------------------------------------- For Android PushSharp/PushSharp.Google/Xmpp/GcmXmppConnection.cs

Line 101 CHANGE sslStream.AuthenticateAsClient(Configuration.Host,certificates,System.Security.Authentication.SslProtocols.Tls, false); stream = sslStream;

TO var tls = System.Security.Authentication.SslProtocols.Tls | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls12; sslStream.AuthenticateAsClient (Configuration.Host, certificates, tls, false); stream = sslStream;

-------------------------------------------------iOS-------------------------------------------------- For iOS There is a pending commit into Redth:master from narensoni83:master. That solves the APNS problem. But you can go ahead and add the changes to your local repository.

PushSharp.Apple/ApnsConnection.cs

Line 357 CHANGE stream.AuthenticateAsClient(Configuration.Host,certificates,System.Security.Authentication.SslProtocols.Tls, false);

TO var tls = System.Security.Authentication.SslProtocols.Tls | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls12; stream.AuthenticateAsClient(Configuration.Host, certificates, tls, false);

AND

PushSharp.Apple/ApnsFeedbackService.cs

Line 41 CHANGE stream.AuthenticateAsClient(Configuration.FeedbackHost,certificates,System.Security.Authentication.SslProtocols.Tls, false);

TO var tls = System.Security.Authentication.SslProtocols.Tls | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls12; stream.AuthenticateAsClient(Configuration.FeedbackHost, certificates, tls, false);

After making those changes everything is working great again. Azure not required! :)

lakshaydulani commented 6 years ago

can someone pls provide the dll files? i dont have access to a windows machine

TonyLugg commented 6 years ago

I made the switch to Azure Notification Hubs and it was simple and works well. And it is inexpensive, almost free.