APNS + PHP "stream_socket_client(): Failed to enable crypto" - php

I'm having trouble with using APNS with PHP and getting the following message:
stream_socket_client(): Failed to enable crypto
The problem only happens sometimes, and other times it would actually send the push.
Since I have the test script on a loop of 10 iterations, I would sometimes get this:
stream_socket_client(): SSL: Connection reset by peer
I'm testing using the sandbox server tls://gateway.sandbox.push.apple.com:2195
Here is what I tried:
I tried to reissue the PEM and all certificates with it.
I played around with the request protocol sslv3:// and tls://.
I played around with the passphrase (push worked without the passphrase btw)
I tried searching stackoverflow for a solution and nothing worked.
Checked pem file permissions 644
Checked pem parent directories permissions 755
It seems that all the solutions I found on Google and SO are people having problem pushing altogether.
I feel like the service is rate limited maybe? Because we waited a while (around 15 minutes) and then tried it again, and was able to successfully push around 100 messages until I started getting that message again.

The sandbox push service is rate limited. I have experienced this myself when testing but have never encountered any such limit using the production API.
You might also be hitting their other protections.
Are you opening a connection, sending a message, closing connection and then looping and doing it all over again?
That will get your notifications dropped. Apple wants you to send several push notifications using the same connection, not a new one each time.
Best Practices for Managing Connections
You may establish multiple connections to the same gateway or to
multiple gateway instances. If you need to send a large number of
remote notifications, spread them out over connections to several
different gateways. This improves performance compared to using a
single connection: it lets you send the remote notifications faster,
and it lets APNs deliver them faster.
Keep your connections with APNs open across multiple notifications;
don’t repeatedly open and close connections. APNs treats rapid
connection and disconnection as a denial-of-service attack. You should
leave a connection open unless you know it will be idle for an
extended period of time—for example, if you only send notifications to
your users once a day it is ok to use a new connection each day.
From Apple Docs # https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html

My PHP code was generating following error:
PHP Warning: stream_socket_client(): Failed to enable crypto in /private/tmp/t.php on line 12
PHP Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in /private/tmp/t.php on line 12
PHP Warning: fclose() expects parameter 1 to be resource, boolean given in /private/tmp/t.php on line 24
The problem was, the damn certificate, expired the day before yesterday! :-) Can you believe this?
So, I need to recreate my PEM file.

It is not necessary recreate your pem file
that error happens when you use an incorrect PassPhrase
regards
Emiliano

I had this problem. Disappeared after giving write permission for 'everyone' for the .pem file.

I have this problem because I foolishly forgot to include the file extension (.pem) when supplying the file path for local_cert.

few checks :
device token should be - with out spaces and with out < or >
make sure the path of certificate is correct and expired date of it.
make sure the passphrase you are using is the one u used to make certificate

In my case, the issue was with my mac (OSX Sierra). I uploaded php and cert to my server, ran it, and the notification was delivered.

I tried examples from book of Marin Todorov iOs 6 by Tutorials.
And before I could send push notifications for automatical update I had a lot of headache cause of handshake error - stream_socket_client(): Failed to enable crypto.
I did all of what I found in Stackoverflow - changed permissions on certificate and others.
What I did eventually?
I created selfsigned SSL certificate and setup Apache for serving SSL.
Also I changed SSL protocol from ssl to tls in hostname:
tls://gateway.push.apple.com:2195
After that service works.

Related

ftp_nlist(): data_accept: SSL/TLS handshake failed

Once upon a time, there was a normalish error in PHP land:
Warning: ftp_nlist(): data_accept: SSL/TLS handshake failed in [path] on line 29
But here's the catch, "line 29" is not the connection or login, note how it referenced the ftp_nlist() function:
$ftp = ftp_ssl_connect($cred['host'], $cred['port'], 180);
if (!ftp_login($ftp, $cred['user'], $cred['pass'])) {die("Login Failed");}
ftp_pasv($ftp, true);
$files = ftp_nlist($ftp, '');
OpenSSL is compiled and enabled in phpinfo() as suggested here:
ftp_login() : SSL/TLS handshake failed
Other posts I've seen all seem to reference error in the ftp_ssl_connect() or ftp_login() commands which work for me. What can I check when ftp_login() returns true?
Or... are there any logs to get more details on what is wrong?
I'm using php 5.3.29. The code does work properly on my desktop (php 7), but I'm hoping I don't have to upgrade the server to 7 for this to work
12-28-2017 update:
Upgrading to 5.6 resolved, so looks like Martin is on point.
Although this question is quite old, but in case someone else hits this problem:
If your ftp_ssl_connect and ftp_login works fine but functions like ftp_nlist, ftp_put, ftp_fput don't works the problem might be that your FTP server is using port 21 for Connection but different port ranges for data transfer, that explains why you can connect and login but you can't upload or download data, and you need to allow the Out-going connections to those port range in your firewall
The ftp_nlist opens a data connection. That connection needs TLS/SSL handshake too.
As the control connection handshake succeeded, the problem indeed cannot be with an absent TLS/SSL support in PHP. Neither the problem can be with anything like the server and PHP not being able to find a cipher to agree on.
When TLS/SSL handshake on data connection fails after handshake on control connection succeeded, it's quite usually because the client (PHP) did not reuse TLS/SSL session from control connection on the data connection (see Why is session reuse useful in FTPS?). Some servers do require that. PHP supports the reuse only since 5.6.26. See PHP Bug 70195. So make sure you use that version of PHP at least.

Only from PHP: Unable to connect APNS gateway.push.apple.com:2195

It's a late night. I just spent 10 hours in google/stackoverflow search and experiments. And seems I hate Apple Push Notifications. I'm totally frustrated and will appreciate any help.
Thank you.
The problem:
The PHP code for sending Apple Push Notifications, which successfully worked two weeks ago stopped to work now and throws following errors:
PHP Warning: stream_socket_client(): Failed to enable crypto in /home/...
PHP Warning: stream_socket_client(): unable to connect to ssl://gateway.push.apple.com:2195 (Unknown error) in /home/...
It stopped to work on two separate servers, which are using separate scripts for APNs sending.
Environment:
Servers: CentOS 6.5 with PHP 5.4.32 and Ubuntu 14.04.3 with PHP 5.5.9
APN: In production mode
Certificates: tested with 700+ push notifications.
One of the servers is using https://github.com/immobiliare/ApnsPHP, other - https://github.com/antongorodezkiy/wp-apn, on localhost I tested simple file without using any third party code.
Investigation:
For all cases below I used the same active device token and the same production PEM certificate.
php
However, even this simple code doesn't work on both servers and localhost and return the same error as above:
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', '/absolute/path/to/apn_prod.pem');
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
I also tried to play with stream_context_set_option() options, include entrust_2048_ca.cer, etc, and even some options from this article. Although provided code worked without any modifications before August 2015.
openssl
Connection worked with openssl (link):
openssl s_client -connect gateway.push.apple.com:2195 -cert /absolute/path/to/apn_prod.pem -debug -showcerts -CAfile /absolute/path/to/server-ca-cert.pem
And got with CONNECTED(00000003) and Verify return code: 0 ( ok ).
telnet
Connection worked with telnet:
-sh-4.1$ telnet gateway.push.apple.com 2195
Trying 17.172.233.150...
Connected to gateway.push.apple.com.
pecl apn
It didn't send push notification. I just tried to use adaptation of sample code, but got the error Invalid token. The token is active and same token I used everywhere and for Houston and Ruby too.
houston
It worked with Houston
apn push "0346a53f...231d9d6abe11" -c /absolute/path/to/apn_prod.pem -m "Hello from the command line!" -e "production"
ruby
I'm not a Ruby programmer (yet at least), but after success with Houston, I found and adapted Ruby code without Houston dependency.
And it worked:
#!/usr/bin/env ruby
require 'openssl'
require 'socket'
require 'json'
token = "0346a53f...231d9d6abe11"
cert = File.read("/absolute/path/to/apn_prod.pem")
ctx = OpenSSL::SSL::SSLContext.new
ctx.key = OpenSSL::PKey::RSA.new(cert, '') #set passphrase here, if any
ctx.cert = OpenSSL::X509::Certificate.new(cert)
sock = TCPSocket.new('gateway.push.apple.com', 2195) #development gateway
ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
ssl.connect
payload = {"aps" => {"alert" => "Oh hai!", "badge" => 1, "sound" => 'default'}}
json = payload.to_json()
token = [token.delete(' ')].pack('H*') #something like 2c0cad 01d1465 346786a9 3a07613f2 b03f0b94b6 8dde3993 d9017224 ad068d36
apnsMessage = "\0\0 #{token}\0#{json.length.chr}#{json}"
ssl.write(apnsMessage)
ssl.close
sock.close
puts "End"
Questions:
What's wrong with PHP? Is there some bug related to this issue? (I didn't find bug report though)
Any ideas how to solve this issue?
Any ideas what could be the difference in PHP and Ruby cases (I assume that Python or Perl could work fine too)? I even tried to read PHP sources, but without success to understand how stream_socket_client() implemented.
Please help.
I've found the issue and fixed it.
The problem was in .pem certificate. Somehow there were two certificates in one file for both production and development .pem files. The same .pem file with two certificates was in the repo for a long time but APNs stopped to work only few months ago. Maybe something was upgraded/changed on the Apple's side.
I assume the Ruby code somehow removes certificate duplication or maybe it took only first certificate, so it worked in Ruby.
However, the solution was to remove the second certificate from the .pem file. After that APNs started to work and they work now (I received some just yesterday).
If you're just reusing an old Certificate Signing Request (CSR), make sure to remove the expired/old APNs certificate from your Keychain before exporting the new one and its private key as p12 file. If you don't do that, the PEM file you generated out from the exported p12 will still contain the expired/old certificate which doesn't goes well with Apple's Push provider. Thus resulting to unable to connect to ssl....

problems connecting with bitcoin RPC

I was setting up a faucet to give away some btc at nobanchan.com/faucet
The problem I am having is
Fatal error: Uncaught BitcoinClientException: [0]: Connect error: Connection refused (111) thrown in on line 0
I have the RPC username/password/port in bitcoin.conf exactly the same as I do on config.php for the faucet.
I have forwarded the port from my WAN to my private IP in my router.
I have reopened bitcoin a few times. Also, I have set rpcallowip= my local IP, and my websites IP.
What else should I check?!
I have the same problem with two servers trying to let them communicate.
It seems like you have to set up "JSON-RPC Over SSL" as described here if you don't run client and server on the same machine (e.g. if you do not use "localhost"):
https://en.bitcoin.it/wiki/Enabling_SSL_on_original_client_daemon
I agree with #lagopixel here, I don't think this is a network error.
First, if you want to use RPC commands with the bitcoin core you should add the "server" option (-server on command line or server=1 in bitcoin.conf).
Then, I'm pretty sure this has nothing to do with SSL conections but here are the options related to SSL for the bitcoin core (just in case):
rpcssl: Use OpenSSL (https) for JSON-RPC connections
rpcsslcertificatechainfile=file.cert: Server certificate file (default: server.cert)
rpcsslprivatekeyfile=file.pem: Server private key (default:server.pem)
rpcsslciphers=ciphers: Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:#STRENGTH)
Moreover, note that using JSON-RPC over SSL is strongly discouraged.

Execute Apple Push Notification Server (PHP) from Android Device using "PHP for Android"

I recently downloaded and installed "PHP for Android." I created a .php file that utilizes an SSL connection with port 2195. I followed a guide for writing a php server that sends push notifications to Apple's APNS, and SUCCESSfully ran it on my Mac. When I put both the .php and the .pem onto my Android phone in the same folder and tried to run it with the same WIFI connection, I get the following error message:
Error:14094410:SSL routines:func(148):reason(1040) in /mnt/sdcard/sl4a/scripts/lot.php on line 19
Warning: stream_socket_client(): Failed to enable crypto in /mnt/sdcard/sl4a/scripts/lot.php on line 19
Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in /mnt/sdcard/sl4a/scripts/lot.php on line 19
Does anyone have any ideas of how I can fix this?
THANKS!
I had the SSL error on my Windows desktop, with a PHP script that accessed a HTTPS resource.
The solution was to enable the openssl extension. So maybe it's the same kind of problem you have here, something related to opensll on Php for Android.
I'm not sure how to fix it, but Google has it's own push notification framework. There is an example here: http://code.google.com/android/c2dm/
Edit to Answer:
I think that most likely the problem has to do with the certificates needed to make the call over SSL. It is possible that the PHP for Android app does not have permissions to access security certificates you need.

Apache / PHP Unable to communicate with Tomcat JavaBridge

My project uses PHP JavaBridge, I have installed WAMP, JRE 6.0, and Tomcat 6.0.32
I can now access http://localhost:8080/ successfully but when I run my PHP site it gives me the following error
warning: fsockopen() [function.fsockopen]: unable to connect to localhost:8080 (A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. )
Can anyone please help me with this issue?
EDIT
Forgot to mention that I am using Windows 7
My comment above worked as a solution and hence this answer, so that in future others get it.
Can you 127.0.0.1:8080 instead of localhost:8080? See what do you get?
fsocketopen takes the hostname and it should be a valid domain, in your case, (in general) it could be a valid domain as long as you have an entry for localhost in your hosts file (C:\Windows\System 32\drivers\etc\hosts). See if you have something similar to that.

Categories