diff --git a/README.md b/README.md index 15ff13a..b5426fd 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ > Note: RFC8188 relies heavily on base64 URL encoding. +### Simple callback function for encryption key lookup + ```php require_once "vendor/autoload.php"; @@ -35,8 +37,41 @@ $decoded = RFC8188::rfc8188_decode( $this->assertEquals($message, $decoded); ``` +### Invocable class for key lookup +In this example we use a simple incovable class to provide key lookup. This may be more useful in complex framework integrations such as providing middleware that looks up keys from a database. This sample does not cover service injection to the key lookup class. + +```php +use DevJack\EncryptedContentEncoding\RFC8188; +use DevJack\EncryptedContentEncoding\Exception\EncryptionKeyNotFound; +use Base64Url\Base64Url as b64; + +class MockKeyLookupProvider { + + protected $keys = []; + + public function addKey($key, $keyid='') { + $this->keys[$keyid] = $key; + } + public function __invoke($keyid) { + if (in_array($keyid, array_keys($this->keys))) { + return $this->keys[$keyid]; + } + throw new EncryptionKeyNotFound("Encryption key not found."); + } +} +$encoded = b64::decode("uNCkWiNYzKTnBN9ji3-qWAAAABkCYTHOG8chz_gnvgOqdGYovxyjuqRyJFjEDyoF1Fvkj6hQPdPHI51OEUKEpgz3SsLWIqS_uA"); + +$keyProvider = new MockKeyLookupProvider(); +$keyProvider->addKey(b64::decode("BO3ZVPxUlnLORbVGMpbT1Q"), 'a1'); + +$decoded = RFC8188::rfc8188_decode( + $encoded, // data to decode + $keyProvider +); +``` + ## Installation ``` diff --git a/src/Exception/EncryptionKeyNotFound.php b/src/Exception/EncryptionKeyNotFound.php new file mode 100644 index 0000000..33dee93 --- /dev/null +++ b/src/Exception/EncryptionKeyNotFound.php @@ -0,0 +1,7 @@ +keys[$keyid] = $key; + } + public function __invoke($keyid) { + if (in_array($keyid, array_keys($this->keys))) { + return $this->keys[$keyid]; + } + throw new EncryptionKeyNotFound("Encryption key not found."); + } +} \ No newline at end of file diff --git a/test/RFC8188Test.php b/test/RFC8188Test.php index b1de58d..d632f73 100644 --- a/test/RFC8188Test.php +++ b/test/RFC8188Test.php @@ -4,6 +4,8 @@ use PHPUnit\Framework\TestCase; use DevJack\EncryptedContentEncoding\RFC8188; +use DevJack\EncryptedContentEncoding\Test\Mock\MockKeyLookupProvider; +use DevJack\EncryptedContentEncoding\Exception\EncryptionKeyNotFound; use Base64Url\Base64Url as b64; final class RFC8188Test extends TestCase @@ -76,6 +78,32 @@ function($keyid ) use ($key) { return $key; } $this->assertEquals($message, $decoded); } + public function testCanInvokeCallableClassAsKeyProvider() { + $encoded = b64::decode("uNCkWiNYzKTnBN9ji3-qWAAAABkCYTHOG8chz_gnvgOqdGYovxyjuqRyJFjEDyoF1Fvkj6hQPdPHI51OEUKEpgz3SsLWIqS_uA"); + $keyProvider = new MockKeyLookupProvider(); + $keyProvider->addKey(b64::decode("BO3ZVPxUlnLORbVGMpbT1Q"), 'a1'); + $decoded = RFC8188::rfc8188_decode( + $encoded, // data to decode + $keyProvider + ); + + $this->assertEquals("I am the walrus", $decoded); + } + + public function testMockLookupProviderThrowsKeyNotFoundException() { + $encoded = b64::decode("uNCkWiNYzKTnBN9ji3-qWAAAABkCYTHOG8chz_gnvgOqdGYovxyjuqRyJFjEDyoF1Fvkj6hQPdPHI51OEUKEpgz3SsLWIqS_uA"); + + $keyProvider = new MockKeyLookupProvider(); + $keyProvider->addKey(b64::decode("BO3ZVPxUlnLORbVGMpbT1Q"), ''); // intentionally set keyid NOT to 'a1' + + $this->expectException(EncryptionKeyNotFound::class); + + $decoded = RFC8188::rfc8188_decode( + $encoded, // data to decode + $keyProvider + ); + } + /** * @requires PHP 5.6 */