Skip to content

Commit b21561b

Browse files
committed
users can specify a PEM file
1 parent 84b9940 commit b21561b

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ There are several good examples and tutorials on the web:
7373
### Authentication
7474
Browsers need to verify your identity. A standard called VAPID can authenticate you for all browsers. You'll need to create and provide a public and private key for your server.
7575

76-
You can specify your authentication details when instantiating WebPush:
76+
You can specify your authentication details when instantiating WebPush. The keys can be passed directly, or you can load a PEM file or its content:
7777
```php
7878
<?php
7979

@@ -87,14 +87,16 @@ $auth = array(
8787
'subject' => 'mailto:[email protected]', // can be a mailto: or your website address
8888
'publicKey' => '~88 chars', // uncompressed public key P-256 encoded in Base64-URL
8989
'privateKey' => '~44 chars', // in fact the secret multiplier of the private key encoded in Base64-URL
90+
'pemFile' => 'path/to/pem', // if you have a PEM file and can link to it on your filesystem
91+
'pem' => 'pemFileContent', // if you have a PEM file and want to hardcode its content
9092
),
9193
);
9294

9395
$webPush = new WebPush($auth);
9496
$webPush->sendNotification($endpoint, null, null, null, true);
9597
```
9698

97-
In order to generate the public and private keys, enter the following in your Linux bash:
99+
In order to generate the uncompressed public and secret key, encoded in Base64, enter the following in your Linux bash:
98100
```
99101
$ openssl ecparam -genkey -name prime256v1 -out private_key.pem
100102
$ openssl ec -in private_key.pem -pubout -outform DER|tail -c 65|base64|tr -d '=' |tr '/+' '_-' >> public_key.txt

src/VAPID.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Jose\Factory\JWKFactory;
1616
use Jose\Factory\JWSFactory;
1717
use Mdanter\Ecc\EccFactory;
18+
use Mdanter\Ecc\Serializer\Point\UncompressedPointSerializer;
1819
use Mdanter\Ecc\Serializer\PrivateKey\DerPrivateKeySerializer;
1920
use Mdanter\Ecc\Serializer\PrivateKey\PemPrivateKeySerializer;
2021

@@ -33,6 +34,33 @@ public static function validate(array $vapid)
3334
throw new \ErrorException('[VAPID] You must provide a subject that is either a mailto: or a URL.');
3435
}
3536

37+
if (array_key_exists('pemFile', $vapid)) {
38+
$vapid['pem'] = file_get_contents($vapid['pemFile']);
39+
40+
if (!$vapid['pem']) {
41+
throw new \ErrorException('Error loading PEM file.');
42+
}
43+
}
44+
45+
if (array_key_exists('pem', $vapid)) {
46+
$pem = $vapid['pem'];
47+
$posStartKey = strpos($pem, '-----BEGIN EC PRIVATE KEY-----');
48+
$posEndKey = strpos($pem, '-----END EC PRIVATE KEY-----');
49+
50+
if ($posStartKey === false || $posEndKey === false) {
51+
throw new \ErrorException('Invalid PEM data.');
52+
}
53+
54+
$posStartKey += 30; // length of '-----BEGIN EC PRIVATE KEY-----'
55+
56+
$pemSerializer = new PemPrivateKeySerializer(new DerPrivateKeySerializer());
57+
$keys = $pemSerializer->parse(substr($pem, $posStartKey, $posEndKey - $posStartKey));
58+
59+
$pointSerializer = new UncompressedPointSerializer(EccFactory::getAdapter());
60+
$vapid['publicKey'] = base64_encode(hex2bin($pointSerializer->serialize($keys->getPublicKey()->getPoint())));
61+
$vapid['privateKey'] = base64_encode(hex2bin(gmp_strval($keys->getSecret(), 16)));
62+
}
63+
3664
if (!array_key_exists('publicKey', $vapid)) {
3765
throw new \ErrorException('[VAPID] You must provide a public key.');
3866
}

0 commit comments

Comments
 (0)