2

I checked this url and followed the steps to generated pem file from p12 file. Below is the code to generate the pem file.

....
if ($this->file->save($uploadDirectory . $filename . '.' . $ext)) {
   $filenamewithpath = $uploadDirectory . $filename . '.' . $ext;
   $handle = fopen($filenamewithpath, 'r');
   $p12buf = fread($handle, filesize($filenamewithpath));
   fclose($file); 
   $password = @$p12pwd;
   $results = array();
   $worked = openssl_pkcs12_read($p12buf, $results, $password);
   //d($results); exit;
   if ($worked) {
      //echo '<pre>', print_r($results, true), '</pre>';
      $new_password = null;
      $result = null;
      $worked = openssl_pkey_export($results['pkey'], $result, $new_password);
      if($worked) {
         //echo "<pre>It worked!  Your new pkey is:\n", $result, '</pre>';
         file_put_contents( $uploadDirectory . $filename . '.pem',$result);
         return array(
            'success' => true,
            'filename'=>$filename . '.pem',
            'uploaddir' =>$uploadDirectory,
         );
      } else {
         return array('error' => openssl_error_string());
      }

   } else {
      return array('error' => openssl_error_string());
   }
}
....

I got it working fine and generated pem file is stored in given directory. Now i am trying to use this pem file for push notification. Check the below code,

<?php 
   $apnsHost = 'gateway.sandbox.push.apple.com';
   //$apnsHost = 'gateway.push.apple.com';

   $apnsCert = 'test.pem';
   $apnsPort = 2195;

   $streamContext = stream_context_create(); 
   stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);

   $apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
   $payload['aps'] = array('alert' => 'this is test!', 'badge' => 1, 'sound' => 'default');
   $output = json_encode($payload);
   $token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
   $token = pack('H*', str_replace(' ', '', $token)); 
   $apnsMessage = chr(0) . chr(0) . chr(32) . $token . chr(0) . chr(strlen($output)) . $output;
   //var_dump($apnsMessage); exit;
   fwrite($apns, $apnsMessage);

   @socket_close($apns);
   fclose($apns);
?>

When i ran this code, i got below error,

Warning: stream_socket_client(): Unable to set local cert chain file `test.pem'; Check that your cafile/capath settings include details of your certificate and its issuer in /var/www/html/myserver/apns/test.php on line 13
Warning: stream_socket_client(): failed to create an SSL handle in /var/www/html/myserver/apns/test.php on line 13 
Warning: stream_socket_client(): Failed to enable crypto in /var/www/html/ela/apns/test.php on line 13 
Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in /var/www/html/myserver/apns/test.php on line 13 
Warning: fwrite() expects parameter 1 to be resource, boolean given in /var/www/html/myserver/apns/test.php on line 20 
Warning: fclose() expects parameter 1 to be resource, boolean given in /var/www/html/myserver/apns/test.php on line 23 

Kindly advice to fix this issue.

Community
  • 1
  • 1
mymotherland
  • 7,968
  • 14
  • 65
  • 122
  • You may need to add the intermediate certs inside the pem as well, or perhaps a recent ca bundle will do as well. – Ja͢ck Aug 17 '12 at 08:32
  • @jack thanks, this one ["cert"] => string(1996) "-----BEGIN CERTIFICATE----- (taken from $results array) needed to add ? – mymotherland Aug 17 '12 at 09:21
  • Having a cert is one thing, but you need something to verify it against, you can google curl cacert for a bundle file to download – Ja͢ck Aug 17 '12 at 10:06

2 Answers2

1

I would have called

'openssl pkcs12  -in cert.p12  -inpass pass:password  ...something.. ..something...'

on the command line and tried to pick up or pipe its output back. Perhaps there is a wrapper for that in php, otherwise a system command seems the most easy route.

eirikma
  • 657
  • 5
  • 13
  • @eirikima I found this http://forum.nusphere.com/converting-cer-to-pem-via-php-script-t8451.html and tried it. But not working. – mymotherland Aug 17 '12 at 14:35
0

I had the same kind of issue when developing for iOS. We howerve got *.cer certificates and changed them to *.pem using the following command line:
openssl x509 -inform der -in aps_production_identity.cer -out aps_production_identity.pem

If this does not work make sure to include the private key as indicated here: Apple Push Notification Service

Community
  • 1
  • 1
Adrien Hingert
  • 1,416
  • 5
  • 26
  • 51