Skip to content

Commit c0b9e0e

Browse files
committed
Push: allow using p8 keys
1 parent 7e9f839 commit c0b9e0e

File tree

6 files changed

+88
-26
lines changed

6 files changed

+88
-26
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ profile
1616
.DS_Store
1717
entrust_root_certification_authority.pem
1818
server_certificates_bundle_sandbox.pem
19+
UniversalPushNotificationClientSSLCertificate.p8
1920
*~
2021
Doc/Reference/html
2122
# Composer

ApnsPHP/Abstract.php

Lines changed: 60 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
*/
2929

3030
use Psr\Log\LoggerInterface;
31+
use Lcobucci\JWT\Signer\Key;
32+
use Lcobucci\JWT\Signer\Ecdsa\Sha256;
33+
use Lcobucci\JWT\Configuration;
3134

3235
/**
3336
* Abstract class: this is the superclass for all Apple Push Notification Service
@@ -64,6 +67,9 @@ abstract class ApnsPHP_Abstract
6467

6568
protected $_sProviderCertificateFile; /**< @type string Provider certificate file with key (Bundled PEM). */
6669
protected $_sProviderCertificatePassphrase; /**< @type string Provider certificate passphrase. */
70+
protected $_sProviderToken; /**< @type string|null Provider Authentication token. */
71+
protected $_sProviderTeamId; /**< @type string|null Apple Team Identifier. */
72+
protected $_sProviderKeyId; /**< @type string|null Apple Key Identifier. */
6773
protected $_sRootCertificationAuthorityFile; /**< @type string Root certification authority file. */
6874

6975
protected $_nWriteInterval; /**< @type integer Write interval in micro seconds. */
@@ -106,7 +112,7 @@ public function __construct($nEnvironment, $sProviderCertificateFile, $nProtocol
106112
);
107113
}
108114
$this->_nProtocol = $nProtocol;
109-
115+
110116
$this->_nConnectTimeout = ini_get("default_socket_timeout");
111117
$this->_nWriteInterval = self::WRITE_INTERVAL;
112118
$this->_nConnectRetryInterval = self::CONNECT_RETRY_INTERVAL;
@@ -167,6 +173,26 @@ public function setProviderCertificatePassphrase($sProviderCertificatePassphrase
167173
$this->_sProviderCertificatePassphrase = $sProviderCertificatePassphrase;
168174
}
169175

176+
/**
177+
* Set the Team Identifier.
178+
*
179+
* @param string $sTeamId Apple Team Identifier.
180+
*/
181+
public function setTeamId($sTeamId)
182+
{
183+
$this->_sProviderTeamId = $sTeamId;
184+
}
185+
186+
/**
187+
* Set the Key Identifier.
188+
*
189+
* @param string $sKeyId Apple Key Identifier.
190+
*/
191+
public function setKeyId($sKeyId)
192+
{
193+
$this->_sProviderKeyId = $sKeyId;
194+
}
195+
170196
/**
171197
* Set the Root Certification Authority file.
172198
*
@@ -401,7 +427,7 @@ protected function _connect()
401427
*/
402428
protected function _httpInit()
403429
{
404-
$this->_log("INFO: Trying to initialize HTTP/2 backend...");
430+
$this->_logger()->info("Trying to initialize HTTP/2 backend...");
405431

406432
$this->_hSocket = curl_init();
407433
if (!$this->_hSocket) {
@@ -413,24 +439,41 @@ protected function _httpInit()
413439
if (!defined('CURL_HTTP_VERSION_2_0')) {
414440
define('CURL_HTTP_VERSION_2_0', 3);
415441
}
416-
417-
if (!curl_setopt_array($this->_hSocket, array(
418-
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
419-
CURLOPT_SSLCERT => $this->_sProviderCertificateFile,
420-
CURLOPT_SSLCERTPASSWD => empty($this->_sProviderCertificatePassphrase) ? null : $this->_sProviderCertificatePassphrase,
421-
CURLOPT_RETURNTRANSFER => true,
422-
CURLOPT_USERAGENT => 'ApnsPHP',
423-
CURLOPT_CONNECTTIMEOUT => 10,
424-
CURLOPT_TIMEOUT => 30,
425-
CURLOPT_SSL_VERIFYPEER => true,
426-
CURLOPT_VERBOSE => false
427-
))) {
442+
$aCurlOpts = array(
443+
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
444+
CURLOPT_RETURNTRANSFER => true,
445+
CURLOPT_USERAGENT => 'ApnsPHP',
446+
CURLOPT_CONNECTTIMEOUT => 10,
447+
CURLOPT_TIMEOUT => 30,
448+
CURLOPT_SSL_VERIFYPEER => true,
449+
CURLOPT_VERBOSE => false
450+
);
451+
452+
if (strpos($this->_sProviderCertificateFile, '.pem') !== false) {
453+
$this->_logger()->info("Initializing HTTP/2 backend with certificate.");
454+
$aCurlOpts[CURLOPT_SSLCERT] = $this->_sProviderCertificateFile;
455+
$aCurlOpts[CURLOPT_SSLCERTPASSWD] = empty($this->_sProviderCertificatePassphrase) ? null : $this->_sProviderCertificatePassphrase;
456+
}
457+
458+
if (strpos($this->_sProviderCertificateFile, '.p8') !== false) {
459+
$this->_logger()->info("Initializing HTTP/2 backend with key.");
460+
$cKey = new Key\LocalFileReference('file://' . $this->_sProviderCertificateFile);
461+
$cToken = Configuration::forUnsecuredSigner()->builder()
462+
->issuedBy($this->_sProviderTeamId)
463+
->issuedAt(new DateTimeImmutable())
464+
->withHeader('kid', $this->_sProviderKeyId)
465+
->getToken(new Sha256(), $cKey);
466+
467+
$this->_sProviderToken = (string) $cToken;
468+
}
469+
470+
if (!curl_setopt_array($this->_hSocket, $aCurlOpts)) {
428471
throw new ApnsPHP_Exception(
429472
"Unable to initialize HTTP/2 backend."
430473
);
431474
}
432475

433-
$this->_log("INFO: Initialized HTTP/2 backend.");
476+
$this->_logger()->info("Initialized HTTP/2 backend.");
434477

435478
return true;
436479
}
@@ -443,7 +486,7 @@ protected function _httpInit()
443486
*/
444487
protected function _binaryConnect($sURL)
445488
{
446-
$this->_log("Trying {$sURL}...");
489+
$this->_logger()->info("Trying {$sURL}...");
447490
$sURL = $this->_aServiceURLs[$this->_nEnvironment];
448491

449492
$this->_logger()->info("Trying {$sURL}...");
@@ -478,7 +521,7 @@ protected function _binaryConnect($sURL)
478521

479522
return true;
480523
}
481-
524+
482525
/**
483526
* Return the Logger (with lazy loading)
484527
*/

ApnsPHP/Push.php

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,11 +255,25 @@ public function send()
255255
*/
256256
private function _httpSend(ApnsPHP_Message $message, &$sReply)
257257
{
258-
$aHeaders = array('Content-Type: application/json');
259-
$sTopic = $message->getTopic();
260-
if (!empty($sTopic)) {
261-
$aHeaders[] = sprintf('apns-topic: %s', $sTopic);
258+
$aHeaders = array('Content-Type: application/json');
259+
if (!empty($message->getTopic())) {
260+
$aHeaders[] = sprintf('apns-topic: %s', $message->getTopic());
262261
}
262+
if (!empty($message->getExpiry())) {
263+
$aHeaders[] = sprintf('apns-expiration: %s', $message->getExpiry());
264+
}
265+
if (!empty($message->getPriority())) {
266+
$aHeaders[] = sprintf('apns-priority: %s', $message->getPriority());
267+
}
268+
if (!empty($message->getCollapseId())) {
269+
$aHeaders[] = sprintf('apns-collapse-id: %s', $message->getCollapseId());
270+
}
271+
if (!empty($message->getCustomIdentifier())) {
272+
$aHeaders[] = sprintf('apns-id: %s', $message->getCustomIdentifier());
273+
}
274+
if (!empty($this->_sProviderToken)) {
275+
$aHeaders[] = sprintf('Authorization: Bearer %s', $this->_sProviderToken);
276+
}
263277

264278
if (!(curl_setopt_array($this->_hSocket, array(
265279
CURLOPT_POST => true,

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
"homepage": "https://github.com/M2mobi/ApnsPHP",
77
"license": "BSD-3-Clause",
88
"require": {
9-
"php": ">=5.3.0",
9+
"php": ">=7.2.0",
1010
"psr/log": "~1.0",
11-
"lib-openssl": "*"
11+
"lib-openssl": "*",
12+
"lcobucci/jwt": "^3.4.3"
1213
},
1314
"autoload": {
1415
"psr-0": {"ApnsPHP_": ""}

sample_push.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848

4949
// Set a custom identifier. To get back this identifier use the getCustomIdentifier() method
5050
// over a ApnsPHP_Message object retrieved with the getErrors() message.
51-
$message->setCustomIdentifier("Message-Badge-3");
51+
$message->setCustomIdentifier('7530A828-E58E-433E-A38F-D8042208CF96');
5252

5353
// Set badge icon to "3"
5454
$message->setBadge(3);

sample_push_http.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,13 @@
3131
// Instantiate a new ApnsPHP_Push object
3232
$push = new ApnsPHP_Push(
3333
ApnsPHP_Abstract::ENVIRONMENT_SANDBOX,
34-
'UniversalPushNotificationClientSSLCertificate.pem',
34+
'UniversalPushNotificationClientSSLCertificate.p8',
3535
ApnsPHP_Abstract::PROTOCOL_HTTP
3636
);
3737

38+
$push->setTeamId('sgfdgfdfgd');
39+
$push->setKeyId('klgjhkojmh75');
40+
3841
// Set the write interval to null for the HTTP/2 Protocol.
3942
$push->setWriteInterval(0);
4043

@@ -52,7 +55,7 @@
5255

5356
// Set a custom identifier. To get back this identifier use the getCustomIdentifier() method
5457
// over a ApnsPHP_Message object retrieved with the getErrors() message.
55-
$message->setCustomIdentifier("Message-Badge-3");
58+
$message->setCustomIdentifier('7530A828-E58E-433E-A38F-D8042208CF96');
5659

5760
// Set badge icon to "3"
5861
$message->setBadge(3);

0 commit comments

Comments
 (0)