From 1af4012df459cf8382b9d184af59161fbe62f192 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sat, 1 Jul 2017 15:57:40 +0100 Subject: [PATCH] New property on AuthorizationServer to receive an encryption key which is used for future encryption/decryption instead of keybased encryption/decryption --- composer.json | 3 ++- src/AuthorizationServer.php | 26 +++++++++++++++++++ src/CryptTrait.php | 25 ++++++++++++++++++ src/Grant/GrantTypeInterface.php | 7 +++++ tests/AuthorizationServerTest.php | 6 +++++ .../AuthorizationServerMiddlewareTest.php | 2 ++ 6 files changed, 68 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 64df3ccb..7ce6374e 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,8 @@ "league/event": "^2.1", "lcobucci/jwt": "^3.1", "paragonie/random_compat": "^1.1 || ^2.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0", + "defuse/php-encryption": "^2.1" }, "require-dev": { "phpunit/phpunit": "^4.8 || ^5.0", diff --git a/src/AuthorizationServer.php b/src/AuthorizationServer.php index 0517124a..4ba9b8d1 100644 --- a/src/AuthorizationServer.php +++ b/src/AuthorizationServer.php @@ -26,6 +26,8 @@ class AuthorizationServer implements EmitterAwareInterface { use EmitterAwareTrait; + const ENCRYPTION_KEY_ERROR = 'You must set the encryption key going forward to improve the security of this library - see this page for more information https://xxxx/xxxx'; + /** * @var GrantTypeInterface[] */ @@ -66,6 +68,11 @@ class AuthorizationServer implements EmitterAwareInterface */ private $scopeRepository; + /** + * @var string + */ + private $encryptionKey; + /** * New server instance. * @@ -101,6 +108,16 @@ class AuthorizationServer implements EmitterAwareInterface $this->responseType = $responseType; } + /** + * Set the encryption key + * + * @param string $key + */ + public function setEncryptionKey($key) + { + $this->encryptionKey = $key; + } + /** * Enable a grant type on the server. * @@ -120,6 +137,11 @@ class AuthorizationServer implements EmitterAwareInterface $grantType->setPublicKey($this->publicKey); $grantType->setEmitter($this->getEmitter()); + if ($this->encryptionKey === null) { + error_log(self::ENCRYPTION_KEY_ERROR); + } + $grantType->setEncryptionKey($this->encryptionKey); + $this->enabledGrantTypes[$grantType->getIdentifier()] = $grantType; $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] = $accessTokenTTL; } @@ -135,6 +157,10 @@ class AuthorizationServer implements EmitterAwareInterface */ public function validateAuthorizationRequest(ServerRequestInterface $request) { + if ($this->encryptionKey === null) { + error_log(self::ENCRYPTION_KEY_ERROR); + } + foreach ($this->enabledGrantTypes as $grantType) { if ($grantType->canRespondToAuthorizationRequest($request)) { return $grantType->validateAuthorizationRequest($request); diff --git a/src/CryptTrait.php b/src/CryptTrait.php index d417e115..8e6808d0 100644 --- a/src/CryptTrait.php +++ b/src/CryptTrait.php @@ -11,6 +11,8 @@ namespace League\OAuth2\Server; +use Defuse\Crypto\Crypto; + trait CryptTrait { /** @@ -23,6 +25,11 @@ trait CryptTrait */ protected $publicKey; + /** + * @var string + */ + protected $encryptionKey; + /** * Set path to private key. * @@ -54,6 +61,10 @@ trait CryptTrait */ protected function encrypt($unencryptedData) { + if ($this->encryptionKey !== null) { + return Crypto::encryptWithPassword($unencryptedData, $this->encryptionKey); + } + $privateKey = openssl_pkey_get_private($this->privateKey->getKeyPath(), $this->privateKey->getPassPhrase()); $privateKeyDetails = @openssl_pkey_get_details($privateKey); if ($privateKeyDetails === null) { @@ -91,6 +102,10 @@ trait CryptTrait */ protected function decrypt($encryptedData) { + if ($this->encryptionKey !== null) { + return Crypto::decryptWithPassword($encryptedData, $this->encryptionKey); + } + $publicKey = openssl_pkey_get_public($this->publicKey->getKeyPath()); $publicKeyDetails = @openssl_pkey_get_details($publicKey); if ($publicKeyDetails === null) { @@ -118,4 +133,14 @@ trait CryptTrait return $output; } + + /** + * Set the encryption key + * + * @param string $key + */ + public function setEncryptionKey($key = null) + { + $this->encryptionKey = $key; + } } diff --git a/src/Grant/GrantTypeInterface.php b/src/Grant/GrantTypeInterface.php index c01a571d..34028ccb 100644 --- a/src/Grant/GrantTypeInterface.php +++ b/src/Grant/GrantTypeInterface.php @@ -132,4 +132,11 @@ interface GrantTypeInterface extends EmitterAwareInterface * @param CryptKey $publicKey */ public function setPublicKey(CryptKey $publicKey); + + /** + * Set the encryption key + * + * @param string|null $key + */ + public function setEncryptionKey($key = null); } diff --git a/tests/AuthorizationServerTest.php b/tests/AuthorizationServerTest.php index 909da159..ead431b3 100644 --- a/tests/AuthorizationServerTest.php +++ b/tests/AuthorizationServerTest.php @@ -36,6 +36,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase 'file://' . __DIR__ . '/Stubs/public.key', new StubResponseType() ); + $server->setEncryptionKey(base64_encode(random_bytes(36))); $server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M')); @@ -66,6 +67,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase 'file://' . __DIR__ . '/Stubs/public.key', new StubResponseType() ); + $server->setEncryptionKey(base64_encode(random_bytes(36))); $server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M')); @@ -87,6 +89,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase 'file://' . __DIR__ . '/Stubs/private.key', 'file://' . __DIR__ . '/Stubs/public.key' ); + $server->setEncryptionKey(base64_encode(random_bytes(36))); $abstractGrantReflection = new \ReflectionClass($server); $method = $abstractGrantReflection->getMethod('getResponseType'); @@ -106,6 +109,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase 'file://' . __DIR__ . '/Stubs/private.key', 'file://' . __DIR__ . '/Stubs/public.key' ); + $server->setEncryptionKey(base64_encode(random_bytes(36))); $authCodeRepository = $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(); $authCodeRepository->method('getNewAuthCode')->willReturn(new AuthCodeEntity()); @@ -152,6 +156,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase 'file://' . __DIR__ . '/Stubs/private.key', 'file://' . __DIR__ . '/Stubs/public.key' ); + $server->setEncryptionKey(base64_encode(random_bytes(36))); $server->enableGrantType($grant); $request = new ServerRequest( @@ -184,6 +189,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase 'file://' . __DIR__ . '/Stubs/private.key', 'file://' . __DIR__ . '/Stubs/public.key' ); + $server->setEncryptionKey(base64_encode(random_bytes(36))); $request = new ServerRequest( [], diff --git a/tests/Middleware/AuthorizationServerMiddlewareTest.php b/tests/Middleware/AuthorizationServerMiddlewareTest.php index affc2a3b..f4c417f0 100644 --- a/tests/Middleware/AuthorizationServerMiddlewareTest.php +++ b/tests/Middleware/AuthorizationServerMiddlewareTest.php @@ -36,6 +36,7 @@ class AuthorizationServerMiddlewareTest extends \PHPUnit_Framework_TestCase 'file://' . __DIR__ . '/../Stubs/public.key', new StubResponseType() ); + $server->setEncryptionKey(base64_encode(random_bytes(36))); $server->enableGrantType(new ClientCredentialsGrant()); @@ -69,6 +70,7 @@ class AuthorizationServerMiddlewareTest extends \PHPUnit_Framework_TestCase 'file://' . __DIR__ . '/../Stubs/public.key', new StubResponseType() ); + $server->setEncryptionKey(base64_encode(random_bytes(36))); $server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M'));