I am trying to make a push certificate for using with my app. In development part.
I have the code for push notification in server already done but it has a part in which it says:
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'iOS_pushCertificate\ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
I need to create thatn ck.pem and also the passphrase. I don't know where do I have to set the passphrase or how to create the certificate.
Ray Wenderlich has a great tutorial in his page explaining exactly that.
Related
Hi I'm having trouble sending push notifications from a cron job invoked php script. However the same script works when I invoke the script from the terminal so I know its a problem retrieving the ck.pem. When I hit the script from the terminal I just use the lines
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
to get the ck.pem and it works because the ck.pem file is right on my desktop and local. When I hit the script thats invoked by the cron job it does not have the ck.pem file locally so I uploaded the ck.pem file to the server so the php script invoked from the cron job could access it and this is the code I use to retrieve it
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', file_get_contents("http://www.website.com/Certificates/ck.pem"));
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
however I get the errors
PHP Warning: stream_socket_client(): Failed to enable crypto
PHP Warning: stream_socket_client(): unable to connect to
ssl://gateway.sandbox.push.apple.com:2195 (Unknown error)
PHP Warning: stream_socket_client(): SSL operation failed with code
1. OpenSSL Error messages:
and all these errors happen on the third line of code in the following segment:
$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;
So like I said Im pretty sure its because of the ck.pem file and I made sure that ports 2195 and 2196 are open so it is not that and I can't figure this out. Any help or suggestions would be greatly greatly appreciated!
Solved this answer with this stack overflow link: iOS push notification does not work when using crontab scheduler
I was retrieving the ck.pem file the wrong way
I have a question about Apples Push Service.
What do following warnings exactly mean?
Warning: stream_socket_client(): Failed to enable crypto in /opt/../xyz.php on line 150
Warning: stream_socket_client(): unable to connect to ssl://gateway.push.apple.com:2195 (Unknown error) in /opt/../xyz.php on line 150
I am using about 5 different php files for sending push (AddFriendPush, ChatMessagePush...) to the iOS Devices and they are working fine. But sometime I get these warnings and I don't know what they mean but push doesn't work when I get these warnings..
I know that they can appear if your pem file is wrong or the port 2195 is blocked. But push works sometimes and sometimes it doesn't. So the pem file has to be right and the port can't be blocked.
I know it is not good to have 5 different scripts for push, I will change it soon.
Do you have any idea what is going on?
My php scripts look like this:
function sendPush($deviceToken, $msg)
{
$deviceToken = $deviceToken;
$passphrase = 'passhrase';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'Production.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
$fp = stream_socket_client(
'ssl://gateway.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp) {
unset($con);
exit();
}
//do the other stuff
//Close the connection to the server
fclose($fp);
}
$certFile = 'ful_path/yourcert.pem';
$context = stream_context_create();
$result = stream_context_set_option($context, 'ssl', 'local_cert',
$certFile);
$result = stream_context_set_option($context, 'ssl', 'verify_peer',
false);
$result = stream_context_set_option($context, 'ssl', 'verify_host',
false);
$result = stream_context_set_option($context, 'ssl',
'allow_self_signed', true);
$sock = stream_socket_client('tls://www.somewhere.com:9999',
$errno,$errstr, 30, STREAM_CLIENT_CONNECT, $context);
have added: www.somewhere.com ca to server certs
have removed &$
have checked yourcert.pem expiry
short of migrating the entire code to curl, i am stuck. it has to be something so obvious as the nose on my face... but what...
First, let me say this:
PHP5.6 defaults to using CA certificate stores managed by your operating system. Unless you're connecting to a DNS name that exposes a self-signed certificate or something you probably don't need an SSL context at all.
Before you do anything else, try connecting without any ssl context. If the remote site's certificate is valid and was signed by any standard certificate authority it should "just work" automagically in PHP 5.6.
That said ... there are several very questionable things in your code snippet. It's really impossible to know which is the real problem without knowing more about what you're trying to do, so I'll just iterate over all of it.
$result = stream_context_set_option($context, 'ssl', 'local_cert',
$certFile);
^ Are you connecting to a site that requires YOU to provide a certificate that the remote server verifies? If not (and this is almost certainly the case), you should not be specifying the "local_cert" option.
$result = stream_context_set_option($context, 'ssl', 'verify_peer',
false);
^ This is a terrible idea as it exposes you to Man-in-the-Middle attacks. You should never do this unless you're testing something in a one-off scenario. DO NOT DO THIS.
$result = stream_context_set_option($context, 'ssl', 'verify_host',
false);
^ This is not even a thing. There's no "verify_host" option in PHP.
$result = stream_context_set_option($context, 'ssl',
'allow_self_signed', true);
So ... in summary there's no good way to answer this with the information you've provided. But I've pointed out the obvious issues ...
I'm having issues reopening a TCP socket connection after its remotely closed. Specifically this is for Apple Push Notification service - when Apple encounters a device token from you that pairs with a device that deleted your application they close the secure TCP socket to their push gateway. I need to immediately reopen this connection (or start a new one) when this issue occurs so I can continue sending notification to other users who still do have the app installed. I have some code using which I try to sort this out but it's freezing my entire Apache server and I have to restart manually to get things running again and I have no idea why. Below is the code with which I attempt to reopen a socket with Apple:
if($error_response == "InvalidToken"){
$results .= "\ntried to restart";
fclose($fp);
usleep(20000);
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck_real.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', '****');
$fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
}
I am trying to upgrade my PHP WebSocket library to SSL, using the wss://-protocol on the client-side. However, I find myself at a loss trying to figure out a) how to set up the server socket, and b) how to decode the incoming messages. Here is my current attempt at the former:
$context = stream_context_create();
// local_cert must be in PEM format
stream_context_set_option($context, 'ssl', 'local_cert', $pemFilePath);
// Pass Phrase (password) of private key
stream_context_set_option($context, 'ssl', 'passphrase', $pemPassPhrase);
stream_context_set_option($context, 'ssl', 'allow_self_signed', true);
stream_context_set_option($context, 'ssl', 'verify_peer', false);
$serverSocket = stream_socket_server('ssl://'.$host.':'.$port, $errNo, $errStr, STREAM_SERVER_BIND|STREAM_SERVER_LISTEN, $context);
However, when using SSL as the server protocol, the client does not seem to be sending any messages, and when using tcp, I get weird, encrypted data, although it was my guess that it would be magically decrypted due to my providing the options to the stream context.
What am I doing wrong?
I ran into the same problem with our implementation, and found a good workaround. Put your websocket server on any firewalled port, and tunnel connections from a secure port port. You can use stunnel with a configuration like this:
[websockets]
accept = 8443
connect = 8080
This way, stunnel does all the security, and your websocket server does all the websockets. Win!