APNS with Google App Engine and PHP SSL error - php

I am trying to send iOS push notifications from a PHP App Engine backend but I am receiving the following errors. I am not sure if there is a problem with the certificate, the way I'm doing it, or something specific to App Engine. This is my first time sending push notifications to iOS.
Here is my code :
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
$fp = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
{
//Handle Error
}
$body['aps'] = array(
'alert' => $data["message"],
'sound' => 'default',
);
$body["postID"] = $data["postID"];
$body["groupID"] = $data["groupID"];
$body["type"] = $data["type"];
$payload = json_encode($body);
foreach ($registrationIds as $registrationID)
{
$deviceToken = $registrationID;
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
$result = fwrite($fp, $msg, strlen($msg));
}
fclose($fp);
Here is the error I get :
PHP Warning: stream_socket_client(): SSL operation failed with code 1. OpenSSL
Error messages: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake
failure in fakefile.php
I have no idea what the cause is. Thanks in Advance
UPDATE :
That is no longer the error I get. Now I get this :
PHP Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error)

May be your port 2195 and 2196 are closed from server side that are blocking push notifications.

In stream_context_set_option you did not include the full path to the ck.pem file . After giving the full path there was no error.
Following is code may help to solve your problem.
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', '/Users/Development/Dev/ck.pem');
Following code for checking port is enable for Push notification.
<?php
chkServer('gateway.sandbox.push.apple.com', 2195);
//chkServer('gateway.push.apple.com',2195);
function chkServer($host, $port)
{
$hostip = #gethostbyname($host);
if ($hostip == $host) {
echo "Server is down or does not exist";
} else {
if (!$x = #fsockopen($hostip, $port, $errno, $errstr, 5)) {
echo "Port $port is closed.";
} else {
echo "Port $port is open.";
if ($x) {
#fclose($x);
}
}
}
}
?>
Happy coding.

Related

SSL error when adding ios push notification code

I have a code which is supposed to send IOS push messages but it is giving me an error.
My code:
$streamContextCreate = stream_context_create();
stream_context_set_option($streamContextCreate, 'ssl', 'local_cert', '/home/devmzad/public_html/public/ios/MzadDevCertificates.pem');
$fp = stream_socket_client(
'ssl://gateway.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $streamContextCreate);
echo "<pre>";
print_r($fp); //gives error here.
die;
the error I receive is below:
stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:
error:14094438:SSL routines:SSL3_READ_BYTES:tlsv1 alert internal error
I would appreciate if someone could help me with it. Thanks.
Please try the below code :
<?php
/* We are using the sandbox version of the APNS for development. For production
environments, change this to ssl://gateway.push.apple.com:2195 */
$apnsServer = 'ssl://gateway.sandbox.push.apple.com:2195';
/* Make sure this is set to the password that you set for your private key
when you exported it to the .pem file using openssl on your OS X */
$privateKeyPassword = '1234';
/* Put your own message here if you want to */
$message = 'Welcome to iOS 7 Push Notifications';
/* Pur your device token here */
$deviceToken =
'05924634A8EB6B84437A1E8CE02E6BE6683DEC83FB38680A7DFD6A04C6CC586E';
/* Replace this with the name of the file that you have placed by your PHP
script file, containing your private key and certificate that you generated
earlier */
$pushCertAndKeyPemFile = 'PushCertificateAndKey.pem';
$stream = stream_context_create();
stream_context_set_option($stream,
'ssl',
'passphrase',
$privateKeyPassword);
stream_context_set_option($stream,
'ssl',
'local_cert',
$pushCertAndKeyPemFile);
$connectionTimeout = 20;
$connectionType = STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT;
$connection = stream_socket_client($apnsServer,
$errorNumber,
$errorString,
$connectionTimeout,
$connectionType,
$stream);
if (!$connection){
echo "Failed to connect to the APNS server. Error no = $errorNumber<br/>";
exit;
} else {
echo "Successfully connected to the APNS. Processing...</br>";
}
$messageBody['aps'] = array('alert' => $message,
'sound' => 'default',
'badge' => 2,
);
$payload = json_encode($messageBody);
$notification = chr(0) .
pack('n', 32) .
pack('H*', $deviceToken) .
pack('n', strlen($payload)) .
$payload;
$wroteSuccessfully = fwrite($connection, $notification, strlen($notification));
if (!$wroteSuccessfully){
echo "Could not send the message<br/>";
}
else {
echo "Successfully sent the message<br/>";
}
fclose($connection);
?>

Push Notifications in IOS - Handshake Failure

Whenever I am trying to give Push notifications it throws me multiple error,
I have researched very well yet no solution.
1.stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:
error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
-
2.Severity: Warning
Message: stream_socket_client(): Failed to enable crypto
-
3.Severity: Warning
Message: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error)
-
4.Failed to connect: 0
Below is my code:
// Sends Push notification for iOS users
public function iOS($data, $devicetoken)
{
$deviceToken = $devicetoken;
$passphrase= "";
$ctx = stream_context_create();
// ck.pem is your certificate file
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);
// Create the payload body
$body['aps'] = array(
'alert' => array(
'title' => $data['mtitle'],
'body' => $data['mdesc'],
),
'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));
// Close the connection to the server
fclose($fp);
if (!$result)
return 'Message not delivered' . PHP_EOL;
else
return 'Message successfully delivered' . PHP_EOL;
}
Can anyone help me to sort it out?
add following line
stream_context_set_option( $ctx , 'ssl', 'verify_peer', false);
if you have set password while generating pem file then you have to mention it in following line
$passphrase= "";
if you have not set then this error due to pem file.Its not generated properly.

Error when try to excute Apple Push Notification through php file

I'm working on push notification in IOS with php server and I produced the certificate and keys of the app also I'm ensure from unblocking port for ssl://gateway.sandbox.push.apple.com:2196 and 2195 but at all time I get this error during try to connect on ssl also I'm sure from the permission of all key files
Warning: stream_socket_client(): SSL: crypto enabling timeout in /Users/samahahmaed/Desktop/CER/newspush.php on line 24
Warning: stream_socket_client(): Failed to enable crypto in /Users/samahahmaed/Desktop/CER/newspush.php on line 24
Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in /Users/samahahmaed/Desktop/CER/newspush.php on line 24
Failed to connect: 0
Edited:
When I'm trying this command
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushCertificate.pem -key PushKey.pem -CApath /etc/ssl/certs/Entrust_Root_Certification_Authority.pem
I get this error
CONNECTED(00000003)
write:errno=54
php file:
<?php
// Put your device token here (without spaces):
$deviceToken = 'mydevicetokenhere';
// Put your private key's passphrase here:
$passphrase = '1234';
$message = $argv[1];
$url = $argv[2];
if (!$message || !$url)
exit('Example Usage: $php newspush.php \'Breaking News!\' \'https://raywenderlich.com\'' . "\n");
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'apple_push_notification_production.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',
'link_url' => $url,
);
// 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);
I searched a lot about this issue and I tried all possible solutions but without any result what I can do now ?
Edited:
After add -debug to openssl command the most strange thing these lines:
stream_context_set_option($ctx, 'ssl', 'local_cert', 'apple_push_notification_production.pem');
This line looks like you are using production certificate to connect to sandbox APNS. Try using development certificate. You can get the same from apple developer dashboard.

unable to connect to APNS (connection time out)

I had succeeded earlier on sending a push notification to my iPhone using raywenderlich's excellent tutorial here http://www.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1 and running the php script using the mac terminal, however, now I am trying to achieve the same thing only now I have the push.php script uploaded to my server and run the script every 5 min via Cron Job but i get this error now:
stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Connection timed out)
Like I said before it was working fine earlier when I was running the script through the terminal. I think the problem is that the php script from the server cannot access my push certificates. How do I give the script access to them? Please help!
Heres the php script if it helps:
<?php
// Assign data into variables
$deviceToken = "e39ffc6b98f649f127d07d2d881bc9faa621a3c5d59f9647e64f6452fc37af6c";
$passphrase = "9q3n6k80";
$sound = '';
$blank = "";
$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' => "mic check",
'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 succesfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
Thank You!
EDIT: Im using the File Manager in Bluehost to upload files

why does Apple push server think I am using SSLv3 when I specify TLS? (apple push switch to tls)

I apologize in advance, but I am asking the same question as here: How to send iOS Push Notifications using TLS and PHP? because the problem remains unresolved. Here is the Ray Wenderlich tutorial php code I am using to try to send a push notification, as modified per SO post's recommendations:
<?php
// Put your device token here (without spaces):
$deviceToken = '325bcd9d15ab8b5f8ff6f4f3d5ab3a5254f1ce775d48828476f4aaff4c5c3d3f';
// Put your private key's passphrase here:
$passphrase = 'pushchat';
// Put your alert message here:
$message = 'My first push notification!';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
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');
// Open a connection to the APNS server
$fp = stream_socket_client(
'tls://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);
I also downloaded the entrust_2048_ca.cer file and ensured that it shows up on the System tab of my keychain access. When I run this php file, I still get the following errors, which is the same set of errors I got before making changes to reflect use of tls:
error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure in /Users/aileenann/Desktop/SimplePush/simplepush.php on line 22
Warning: stream_socket_client(): Failed to enable crypto in /Users/aileenann/Desktop/SimplePush/simplepush.php on line 22
Warning: stream_socket_client(): unable to connect to tls://gateway.sandbox.push.apple.com:2195 (Unknown error) in /Users/aileenann/Desktop/SimplePush/simplepush.php on line 22
Failed to connect: 0
What else needs to be changed? Why does the tls apple server still think I am trying to use SSL3 when I have specified tls in the URL?
Thank you for any suggestions.

Categories