Pushsharp send apple notification failed : SSL Stream Failed to Authenticate as Client - c#

I trying to send push notification to apple devices using Pushsharp library on ASP.NET MVC project hosted on IIS.
My code :
public static void SendAppleNotification()
{
// Configuration (NOTE: .pfx can also be used here)
byte[] arr = File.ReadAllBytes("D:\\MySoftware\\pa_Dev.pem");
var config = new ApnsConfiguration(ApnsConfiguration.ApnsServerEnvironment.Sandbox,
arr, "1234");
// Create a new broker
var apnsBroker = new ApnsServiceBroker(config);
// Wire up events
apnsBroker.OnNotificationFailed += (notification, aggregateEx) => {
aggregateEx.Handle(ex => {
// See what kind of exception it was to further diagnose
if (ex is ApnsNotificationException)
{
var notificationException = (ApnsNotificationException)ex;
// Deal with the failed notification
var apnsNotification = notificationException.Notification;
var statusCode = notificationException.ErrorStatusCode;
Console.WriteLine($"Apple Notification Failed: ID={apnsNotification.Identifier}, Code={statusCode}");
}
else
{
// Inner exception might hold more useful information like an ApnsConnectionException
Console.WriteLine($"Apple Notification Failed for some unknown reason : {ex.InnerException}");
}
// Mark it as handled
return true;
});
};
apnsBroker.OnNotificationSucceeded += (notification) => {
Console.WriteLine("Apple Notification Sent!");
};
// Start the broker
apnsBroker.Start();
// Queue a notification to send
apnsBroker.QueueNotification(new ApnsNotification
{
DeviceToken = "660E4433785EFF2B2AA29D5076B039C969F1AADD839D79261328F40B08D26497",
Payload = JObject.Parse("{\"aps\":{\"badge\":7}}")
});
// Stop the broker, wait for it to finish
// This isn't done after every message, but after you're
// done with the broker
apnsBroker.Stop();
}
Notes :
1- Tried to change pem extension into p12 and same issue still occurred.
2- I tried to send push notification using https://pushtry.com/ and its working fine so issue not from certification file or password.
The issue inside pushsharp or there is configurations missing must done on my machine, Any one have idea ?

This just happened to me as of 23 July, 2019. It looks like Apple is now enforcing TLS 1.2 for the sandbox voip push notification server at
gateway.sandbox.push.apple.com - port 2195
feedback.sandbox.push.apple.com - port 2196
I found that I had to check out the latest code from https://github.com/Redth/PushSharp (master branch), build it, and then manually add a reference to the built DLLs in my project.
Previously I was incuding the NuGet PushSharp package, which is now 3 years old and hasn't been updated. If you look at the recent commits on the master branch there is some change there related to Apple and TLS, so I am certain this has fixed it.

My issue fixed by generating p12 file from pem using the below command not by renaming the file extension.
openssl pkcs12 -export -inkey sofwareKey.pem -in software_Prod.pem -out cert_key.p12
see more
https://www.paypal.com/us/selfhelp/article/how-do-i-convert-my-pem-format-certificate-to-pkcs12-as-required-by-the-java-and-.net-sdks-ts1020
may helpful to anyone.

i think the issue related to the Push Sharp so please try this solution by changeing the SSl3 to Tls in the class called ApplePushChannel.cs
and here is the change
The orginal code in the file is
stream.AuthenticateAsClient(this.appleSettings.Host, this.certificates, System.Security.Authentication.SslProtocols.Ssl3, false);
replace it with
stream.AuthenticateAsClient(this.appleSettings.Host, this.certificates, System.Security.Authentication.SslProtocols.Tls, false);
Hope this will hellp you

Related

Pushsharp Apns notification error: 'InvalidToken'

I am currently working on automatic updates for Passbook (wallet) tickets and am experiencing some trouble using the Pushsharp library by Redth.
I am using a Push notification certificate from the apple developer portal.
I have tried to export my certificate as .p12, .pem and tried to use only the private key as .12 or .pem but nothing works. This is my full certificate (information is blanked out for security reasons):
https://cdn.pbrd.co/images/HUJtb7b.png
I dont have enough reputation to post images so a link is all i can provide.
var succeeded = 0;
var failed = 0;
var attempted = 0;
var config = new ApnsConfiguration(ApnsConfiguration.ApnsServerEnvironment.Sandbox, ConfigManager.CertPath + "PushCertificateV2.p12", ConfigManager.lvppass, false);
var broker = new ApnsServiceBroker(config);
broker.OnNotificationFailed += (notification, exception) =>
{
failed++;
};
broker.OnNotificationSucceeded += (notification) =>
{
succeeded++;
};
broker.Start();
attempted++;
broker.QueueNotification(new ApnsNotification
{
DeviceToken = pushtoken,
Payload = JObject.Parse("{ \"aps\" : { \"alert\" : \"Test notification\" } }")
});
broker.Stop();
The purpose is to send a push notification to the APNS and receive an answer, sadly i am only receiving the error: Apns notification error: 'InvalidToken'.
If it means my Pushtoken from the device is incorrect it would be weird because i am using the pushtoken i recieved from the iPhone and checked it multiple times to be sure.
I have tried searching for solutions on the web but have not found a working one so far, so any help would be greatly appreciated.
Thank you in advance.
Okay, for anyone having the same issues in the future, it turned out i needed to use the same certificate i use for signing the passes and updating them. And that you cannot use the sandbox APNS because all passbook tokens are production tokens.

TLS client certificate authentication on UWP Windows Store app

I'm trying to connect to a server that uses TLS with client certificate authentication. Below is a code snippet:
async Task TestClientCertAuth()
{
int iWinInetError = 0;
Uri theUri = new Uri("http://xxx-xxx");
try
{
using (HttpBaseProtocolFilter baseProtocolFilter = new HttpBaseProtocolFilter())
{
// Task<Certificate> GetClientCertificate() displays a UI with all available
// certificates with and returns the user selecter certificate. An
// oversimplified implementation is included for completeness.
baseProtocolFilter.ClientCertificate = await GetClientCertificate();
baseProtocolFilter.AllowAutoRedirect = false;
baseProtocolFilter.AllowUI = false;
using (HttpClient httpClient = new HttpClient(baseProtocolFilter))
using (HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Get, theUri))
using (HttpResponseMessage httpResponse = await httpClient.SendRequestAsync(httpRequest))
{
httpResponse.EnsureSuccessStatusCode();
// Further HTTP calls using httpClient based on app logic.
}
}
}
catch (Exception ex)
{
iWinInetError = ex.HResult & 0xFFFF;
LogMessage(ex.ToString() + " Error code: " + iWinInetError);
throw;
}
}
// Task<Certificate> GetClientCertificate() displays a UI with all available
// certificates with and returns the user selecter certificate. An
// oversimplified implementation is included for completeness.
private async Task<Certificate> GetClientCertificate()
{
IReadOnlyList<Certificate> certList = await CertificateStores.FindAllAsync();
Certificate clientCert = null;
// Always choose first enumerated certificate. Works so long as there is only one cert
// installed and it's the right one.
if ((null != certList) && (certList.Count > 0))
{
clientCert = certList.First();
}
return clientCert;
}
The SendRequestAsync call throws an exception with HRESULT 0x80072F7D - I believe that means ERROR_INTERNET_SECURITY_CHANNEL_ERROR. There are no problems with the server certificate trust. The client certificate is installed in the app local store and I am abe to retrieve it using CertificateStores.FindAllAsync. Looking at the SSL traces and I can see the client certificate is not being sent.
The the above issue does not occur if HttpBaseProtocolFilter.AllowUI is set to true. In this case, the SendRequestAsync call causes a UI to be displayed asking for consent to use the client certificate. Once 'Allow' is selected on this dialog, I can see the client cert and cert verify messages being sent in the traces and the connection is established successfully.
Question: The app code already handles certificate selection by the user. I would like to know whether there is any way to specify consent to use the client certificate programmatically. Because enabling AllowUI causes other side effects - say for example if the server retruns a 401 HTTP code with a WWW-Authenticate: Basic header, the base protoctol filter pops up it's own UI to accept the user credentials without giving a chance for the caller to handle it. Would like to avoid both of the above UIs since I have already selected the client certificate and obtained credentials from the user with own UIs. Thanks
This Microsoft Blog Entry provides information on why this error occurs when AllowUI is false and provides a workaround. The certificate consent UI cannot be bypassed in any case, so that is something the EU has to go through. It also appears that the behavior on Windows Phone is different. Tried this solution and it seems to work on desktop and surface. The general idea is to 'prime' the certificate for use by the lower level APIs in the current app session by attempting to access the private key. In this case we just try to sign some dummy data. Once the EU grants access to the certificate, TLS session establishment goes through successfully. Need to check how
this behaves on Windows Phone though.
private async Task<bool> RequestCertificateAccess(Certificate cert)
{
bool signOK = false;
try
{
IBuffer data = CryptographicBuffer.ConvertStringToBinary("ABCDEFGHIJKLMNOPQRSTUVWXYZ012345656789",
BinaryStringEncoding.Utf8);
CryptographicKey key = await PersistedKeyProvider.OpenKeyPairFromCertificateAsync(cert,
HashAlgorithmNames.Sha1, CryptographicPadding.RsaPkcs1V15);
IBuffer sign = await CryptographicEngine.SignAsync(key, data);
signOK = CryptographicEngine.VerifySignature(key, data, sign);
}
catch (Exception ex)
{
LogMessage(ex.ToString(), "Certificate access denied or sign/verify failure.");
signOK = false;
}
return signOK;
}
RequestClientCertificateAccess can be called just before setting the client certificate on the base protocol filter.
#Tomas Karban, thanks for the response. I have not used sharedUserCertificates, so any certificate that I can enumerate has to be in the apps' certificate store if I understand correctly. The link I shared might be of some help for your case if you've not seen it already.
I would argue that you don't have the certificate stored in the app's own certificate store. If you set HttpBaseProtocolFilter.AllowUI = true and confirm the dialog, the app gets permission to use the private key from user store. Without the UI confirmation the app can only use private keys from its own certificate store.
The situation on Windows 10 Mobile is even worse -- as far as I can tell you cannot set HttpBaseProtocolFilter.AllowUI to true (see my question Cannot set HttpBaseProtocolFilter.AllowUI to true on Windows 10 Mobile). That leaves the only option to use app's own certificate store.

Getting Exception from HRESULT: 0x80072F0D when posting to a service in Windows phone 8.1

When I am trying to post a data to an API using HttpClient in Windows Phone 8.1, I am always getting Exception from HRESULT: 0x80072F0D exception. In fiddler, it works fine.
try
{
var requestbody="json data"
HttpClient httpClient = new HttpClient();
HttpRequestMessage msg = new HttpRequestMessage(new HttpMethod("POST"), new Uri(addressUri));
msg.Content = new HttpStringContent(requestbody);
msg.Content.Headers.ContentType = new HttpMediaTypeHeaderValue("application/json");
HttpResponseMessage response = await httpClient.SendRequestAsync(msg).AsTask();
}
catch (Exception ex)
{
getting **Exception from HRESULT: 0x80072F0D**
}
Please tell me what went wrong?
---FYI----
For getting additional information about the HRESULT code : Follow this WebErrorStatus enumeration
var exceptionDetail = WebError.GetStatus(ex.GetBaseException().HResult);
if (exceptionDetail == WebErrorStatus.HostNameNotResolved)
{
//
}
This looks like a certificate related problem. Maybe you are using SSL. While lots of programs gracefully override missing certificates if not explicitly necessary (e.g.: browsers) the HttpClient is pretty sensitive against that.
You should try to download the certificate for the connection you're using and store the cert file in your assets folder. When your app starts, push it into the certificate store. This is a snippet I am using in one of my apps. Maybe this makes your exception go away.
Read more here: http://blogs.msdn.com/b/wsdevsol/archive/2014/06/05/including-self-signed-certificates-with-your-windows-runtime-based-windows-phone-8-1-apps.aspx
// Add our custom certificate
try
{
// Read the contents of the Certificate file
System.Uri certificateFile = new System.Uri("ms-appx:///Assets/ca.cer");
Windows.Storage.StorageFile file = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(certificateFile);
Windows.Storage.Streams.IBuffer certBlob = await Windows.Storage.FileIO.ReadBufferAsync(file);
// Create an instance of the Certificate class using the retrieved certificate blob contents
Windows.Security.Cryptography.Certificates.Certificate rootCert = new Windows.Security.Cryptography.Certificates.Certificate(certBlob);
// Get access to the TrustedRootCertificationAuthorities for your own app (not the system one)
Windows.Security.Cryptography.Certificates.CertificateStore trustedStore = Windows.Security.Cryptography.Certificates.CertificateStores.TrustedRootCertificationAuthorities;
// Add the certificate to the TrustedRootCertificationAuthorities store for your app
trustedStore.Add(rootCert);
}
catch (Exception oEx)
{
// Catch that exception. We don't really have a choice here..
var msg = oEx.Message;
}
You might be able to bypass the error with this code:
var baseFilter = new HttpBaseProtocolFilter();
baseFilter.IgnorableServerCertificateErrors.Add(Windows.Security.Cryptography.Certificates.ChainValidationResult.InvalidCertificateAuthorityPolicy);
var httpClient = new HttpClient(baseFilter);
This merely silences the error rather than solving the problem, though. I'm not too knowledgeable with SSL errors, and this may not be a safe option, and may not pass app certification. According to the docs:
SSL server certificate errors should only be ignored in advanced scenarios. Disregarding server certificate errors classified as either Ignorable or Fatal may result in the loss of privacy or integrity of the content passed over the SSL session.
Received the same Error as originator. I do not use a proxy.
This worked for me. netsh winhttp reset proxy
Next Fax transmitted without error.
Experienced the 0x80072efd problem. Has cost me hours if not days to solve. The solution that gave instant resolution is the following command from a admin command prompt:
netsh winhttp reset proxy

PushSharp:Android GCM Push Notification received without push message

I am using PushSharp library to send push notification from my application.
PushService push = new PushService();
var reg_id_d = "APA91bETd-LsqnZjA-HKrnBOY3FbEhmWchpiwuhRkiv4gUdGDuvwDRB7YURICZ131XppDAUNUBLGe_vEPkQ-JR8UaVX7Y-NCkEfastCBLIYcUoFtt5cPafeKXHywi0WGDYW33ZQqr3oy";
var project_id_d = "482885626272";
var api_key_d = "AIzaSyAbh7R5KQR3KM7W_y-yS-Ao-JNiihNz7tE"; // "AIzaSyDcKfuW77GTwA46L6sqD41YhGf2j5S8o2w";
var package_name_d = "com.get.deviceid";
push.StartGoogleCloudMessagingPushService(new GcmPushChannelSettings(project_id_d, api_key_d, package_name_d));
push.QueueNotification(NotificationFactory.AndroidGcm()
.ForDeviceRegistrationId(reg_id_d)
.WithCollapseKey("NONE")
.WithJson("{\"alert\":\"Alert Text!\",\"badge\":\"1\"}"));
I am getting notification on my device but with blank message..
I have tried with sever code available in C# to send GCM push notification, but getting same problem of having blank message.
I tried using PHP to send notification. and it is working as expected. so, I am not sure what is wrong in my above code. Can anyone please help me on this?
I tried using different code available around.. but none of those were working..
finally I tried https://stackoverflow.com/a/11651066/1005741 and it works like a charm!
I encountered the same issue, where I received an empty message. My code was a bit different and i was using different libraries: the client was wrapped with phonegap pushPlugin ,and the server code is as follows :
...
// com.google.android.gcm.server.Sender.Sender(String key)‬
gcmSender = new Sender(androidAPIkey);
// com.google.android.gcm.server.Message
Message message = new Message.Builder().addData("alert", "test message" /*notif.getAlert()*/).build();
Result result = gcmSender.sendNoRetry(message, /* device token */ notif.getToken());
nr.add(result, notif.getToken());
...
The reason why my messages where empty is due to the fact that phonegap looks for "message" , "msgcnt" or "soundname" while parsing the extras from the intent. So, this was the solution in my case :
Message message = new Message.Builder().addData("message", notif.getAlert()).build();
Hope this will help someone
Change alert to message, Please see code below for your reference:
////---------------------------
//// ANDROID GCM NOTIFICATIONS
////---------------------------
////Configure and start Android GCM
////IMPORTANT: The API KEY comes from your Google APIs Console App, under the API Access section,
//// by choosing 'Create new Server key...'
//// You must ensure the 'Google Cloud Messaging for Android' service is enabled in your APIs Console
push.RegisterGcmService(new GcmPushChannelSettings("senderid", "apikey", "com.xx.m"));
//Fluent construction of an Android GCM Notification
//IMPORTANT: For Android you MUST use your own RegistrationId here that gets generated within your Android app itself!
push.QueueNotification(new GcmNotification().ForDeviceRegistrationId("regid")
.WithCollapseKey("score_update")
.WithJson("{\"message\":\"syy!\",\"badge\":7,\"sound\":\"sound.caf\"}")
.WithTimeToLive(108)
);

C# moon APNS: iOS Device Did Not Receive Notification

I'm a newbie in iOS development. Recently, I tried to use moon-APNS to send push notification to my device. I followed every step in arashnorouzi.wordpress.com. And when I run my program and read the log, notification was successfully sent to APNS server, but I never receive notification on my device. What is possibly wrong? Is there some setting I should do on my device or the iOS application? I only change the device token, certificate path, password at the example code. Here is my code:
var payload1 = new NotificationPayload("b8bf91fcc66016a7bf96154f3c65c6c479385df98094394c2514682152c29968", "Message", 1, "default");
payload1.AddCustom("RegionID", "IDQ10150");
var p = new List<NotificationPayload> {payload1};
var push = new PushNotification(false, "D:\\certificate\\aps_development.p12","aswin123");
var rejected = push.SendToApple(p);
foreach (var item in rejected)
{
Console.WriteLine(item);
}
Console.ReadLine();
Anyone can help me? I really appreciate your answers.
Check did you done this:
enabled Push Notification of your app in the appID
check , does you getting token while you run the application

Categories

Resources