Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Push notification sending error

I am an iOS app developer and don't know much about php. I am following raywenderlich push notification tutorial to generate an SSL certificates and private key for push notification.

I followed the steps 3-4 times but it does not work. I had followed the same steps previously and it worked.

I think the issue is in the response I get when I test connecting to APNS server using SSL certificate. I am getting below response.

CONNECTED(00000003)
depth=1 /C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=iTMS Engineering/CN=gateway.sandbox.push.apple.com
   i:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
 1 s:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
   i:/O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Certification Authority (2048)
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFGzCCBAOgAwIBAgIETBz90jANBgkqhkiG9w0BAQUFADCBsTELMAkGA1UEBhMC
VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
Lm5ldC9ycGEgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
KGMpIDIwMDkgRW50cnVzdCwgSW5jLjEuMCwGA1UEAxMlRW50cnVzdCBDZXJ0aWZp
Y2F0aW9uIEF1dGhvcml0eSAtIEwxQzAeFw0xMjA1MjUyMzM3NDZaFw0xNDA1MzEw
NTA4NDhaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTESMBAG
A1UEBxMJQ3VwZXJ0aW5vMRMwEQYDVQQKEwpBcHBsZSBJbmMuMRkwFwYDVQQLExBp
VE1TIEVuZ2luZWVyaW5nMScwJQYDVQQDEx5nYXRld2F5LnNhbmRib3gucHVzaC5h
cHBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/r1z4BRFu
DIU9/vOboVmd7OwaPPLRtcZiZLWxSyG/6KeRPpaeaC6DScvSDRoJuIeTDBup0bg4
08K0Gzh+lfKRlJOC2sma5Wgvk7oP4sty83My3YCZQv4QvgDhx+seONNs6XiA8Cl4
ingDymWGlzb0sTdfBIE/nWiEOtXQZcg6GKePOWXKSYgWyi/08538UihKK4JZIOL2
eIeBwjEwlaXFFpMlStc36uS/8oy+KMjwvuu3HazNMidvbGK2Z68rBnqnOAaDBtuT
K7rwAa5+i8GYY+sJA0DywMViZxgG/xWWyr4DvhtpHfUjyQgg1ixM8q651LNgdRVf
4sB0PfANitq7AgMBAAGjggFZMIIBVTALBgNVHQ8EBAMCBaAwHQYDVR0lBBYwFAYI
KwYBBQUHAwEGCCsGAQUFBwMCMDMGA1UdHwQsMCowKKAmoCSGImh0dHA6Ly9jcmwu
ZW50cnVzdC5uZXQvbGV2ZWwxYy5jcmwwZQYIKwYBBQUHAQEEWTBXMCMGCCsGAQUF
BzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5ldDAwBggrBgEFBQcwAoYkaHR0cDov
L2FpYS5lbnRydXN0Lm5ldC9sMWMtY2hhaW4uY2VyMEAGA1UdIAQ5MDcwNQYJKoZI
hvZ9B0sCMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuZW50cnVzdC5uZXQvcnBh
MB8GA1UdIwQYMBaAFB7xq4kG+EkPATN37hR67hl8kyhNMB0GA1UdDgQWBBSgNiNR
qtTShi8PuJ7UNUEbeE71STAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBBQUAA4IBAQAS
EDkUyBHVdRJnCLHY8w9ec92NWqBYqKiSGP0uVCvgpsJIWDBkCGIw1Olks6mQuS9+
R7VRJJFg7EhtufmoRIvjgntKpTe49sB/lrmiZVQGnhjd6YdyYm9+OBUWRvwketLM
v0S+nxZD0qLLJ9foVUB8zP8LtutqFJ5IZw1xb9eSNzhpKkQ9ylj8MCd4tpXZxICL
Gt327poTXwmjQ+31fz7HCQCowMHccP8kiKM5SeYC9q+nkmdaozHVvw4e1RsP+EWO
vPtcH1x1BCkTJajmrO7JuRPLuBEnZGSPUVFRKWP9jy0a28VnJek+oA7rRMRD8irU
fMGbLqkGn8YogdPqe5T1
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=iTMS Engineering/CN=gateway.sandbox.push.apple.com
issuer=/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
---
No client certificate CA names sent
---
SSL handshake has read 2731 bytes and written 2177 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES256-SHA
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 0E813189A9AA0F93F3C996DB3D80240F742EB24656AEED9DC18043DCEDD854E9B1C4798098312EB7F6CAB23B10FF343C
    Key-Arg   : None
    Start Time: 1393333259
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)


In beginning of response it gives error verify error:num=20:unable to get local issuer certificate. In later part of response also it says No client certificate CA names sent. I am not aware these things, but I suspect the problem is with these errors.

EDIT : Error I get while sending notification using sample php script provided in tutorial.

Warning: stream_socket_client(): Unable to set private key file `/Users/akashpatel/Desktop/SimplePush/ck.pem' in /Users/akashpatel/Desktop/SimplePush/simplepush.php on line 25

Warning: stream_socket_client(): failed to create an SSL handle in /Users/akashpatel/Desktop/SimplePush/simplepush.php on line 25

Warning: stream_socket_client(): Failed to enable crypto in /Users/akashpatel/Desktop/SimplePush/simplepush.php on line 25

Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in /Users/akashpatel/Desktop/SimplePush/simplepush.php on line 25
Failed to connect: 0 

EDIT : Using this app (suggested by segev in his answer) I tested whether any issue with certificate/private key. I could receive a notification successfully. So I guess problem is not with certificate/private key.

PHP Script I am using :

<?php

$deviceToken = 'r34f34f5g45g5y56u76hj676elfjn4urno43f958gh945g8g7';

// Put your private key's passphrase here:
$passphrase = ‘pasphrase’;

// Put your alert message here:
$message = 'Received push notification!';

////////////////////////////////////////////////////////////////////////////////

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

// Open a connection to the APNS server
$fp = stream_socket_client(
    'ssl://gateway.sandbox.push.apple.com:2195', $err,
    $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

if (!$fp)
    exit("Failed to connect: $err $errstr" . PHP_EOL);

echo 'Connected to APNS' . PHP_EOL;

// Create the payload body
$body['aps'] = array(
    'alert' => $message,
    'sound' => 'default'
    );

// Encode the payload as JSON
$payload = json_encode($body);

// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));

if (!$result)
    echo 'Message not delivered' . PHP_EOL;
else
    echo 'Message successfully delivered' . PHP_EOL;

// Close the connection to the server
fclose($fp);

EDIT : My script works when I use it in production server. But I will keep this question open as it is not working in local server. Suggestions might help others for whom its not working in production server.

like image 607
Geek Avatar asked Feb 25 '14 13:02

Geek


People also ask

Why push notification is not working for iOS?

You can fix an iPhone that's not getting notifications by restarting it or making sure notifications are turned on. You should also make sure your iPhone is connected to the internet so apps can receive notifications. If all else fails, you should try resetting the iPhone — just make sure to back it up first.

Why is my phone not sending push notifications?

If restarting your phone didn't do the job, one of the most common reasons notifications don't show on Android is because of the notification settings of the app in question. It's possible that you may have mistakenly messed up with the default notification settings, and so now you're not receiving them properly.

What is an APNs error?

It usually means that your JSS can't communicate properly with Apple's "feedback" APNS server, which is "feedback.push.apple.com" on port 2196. The JSS sends push notifications via port 2195, and Apple reports their success (or failure) back to the JSS via port 2196.


3 Answers

There are so many things that go wrong with Push Notification that you'll need to approach them one by one.

Forget about the php code for a second. Go here and download the latest release.

This is a great tiny app that does all the server side for you and will send a push notification to your device. If that works you can go on and implement the php code but I suspect that your problem lies with the app certificate \ key.

like image 152
Segev Avatar answered Nov 09 '22 06:11

Segev


See the error:

CONNECTED(00000003) depth=1 /C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C verify error:num=20:unable to get local issuer certificate verify return:0

Look how you set applied the context to stream option:

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

I used the same tutorial as you, on the troobleshooting section read the bullet #3

Unable to get local issuer certificate. This error means that the certificate from the server could not be verified. To fix this you need to download the Entrust CA root certificate. This can be done from the Terminal using the command: curl -O https://www.entrust.net/downloads/binary/entrust_2048_ca.cer You then also need to add stream_context_set_option($ctx, 'ssl', 'cafile', 'entrust_2048_ca.cer');

Download entrust_2048_ca.cer

make sure all your cerificate are in the same directory as the PHP script.

Change your code to the following:

//applying context to stream option
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
stream_context_set_option($ctx, 'ssl', 'cafile', 'entrust_2048_ca.cer');

You should be good now.

like image 30
meda Avatar answered Nov 09 '22 05:11

meda


I don't know what was the problem when I tested using PHP script provided by the tutorial I followed on local server. But when I tested using production server then it was sending notifications.

like image 1
Geek Avatar answered Nov 09 '22 04:11

Geek