diff --git a/.gitattributes b/.gitattributes index d85a794e..24a9c15e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10,4 +10,5 @@ /phpunit.xml.dist export-ignore /CHANGELOG.md export-ignore /CONTRIBUTING.md export-ignore -/README.md export-ignore \ No newline at end of file +/README.md export-ignore + diff --git a/README.md b/README.md index 7f421104..28047d6b 100644 --- a/README.md +++ b/README.md @@ -62,9 +62,7 @@ Bugs and feature request are tracked on [GitHub](https://github.com/thephpleague If you have any questions about OAuth _please_ open a ticket here; please **don't** email the address below. - - Sponsor - + ## Commercial Support diff --git a/src/CryptKey.php b/src/CryptKey.php index 2ede9e33..0d5f5cf6 100644 --- a/src/CryptKey.php +++ b/src/CryptKey.php @@ -14,7 +14,7 @@ namespace League\OAuth2\Server; class CryptKey { const RSA_KEY_PATTERN = - '/^(-----BEGIN (RSA )?(PUBLIC|PRIVATE) KEY-----\n)(.|\n)+(-----END (RSA )?(PUBLIC|PRIVATE) KEY-----)$/'; + '/^(-----BEGIN (RSA )?(PUBLIC|PRIVATE) KEY-----)\R.*(-----END (RSA )?(PUBLIC|PRIVATE) KEY-----)\R?$/s'; /** * @var string diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index e974ded1..122edf00 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -153,7 +153,7 @@ class AuthCodeGrant extends AbstractAuthorizeGrant case 'S256': if ( hash_equals( - hash('sha256', strtr(rtrim(base64_encode($codeVerifier), '='), '+/', '-_')), + strtr(rtrim(base64_encode(hash('sha256', $codeVerifier, true)), '='), '+/', '-_'), $authCodePayload->code_challenge ) === false ) { diff --git a/tests/AuthorizationServerTest.php b/tests/AuthorizationServerTest.php index 068b914d..8b409a00 100644 --- a/tests/AuthorizationServerTest.php +++ b/tests/AuthorizationServerTest.php @@ -35,6 +35,7 @@ class AuthorizationServerTest extends TestCase // Make sure the keys have the correct permissions. chmod(__DIR__ . '/Stubs/private.key', 0600); chmod(__DIR__ . '/Stubs/public.key', 0600); + chmod(__DIR__ . '/Stubs/private.key.crlf', 0600); } public function testRespondToRequestInvalidGrantType() diff --git a/tests/CryptKeyTest.php b/tests/CryptKeyTest.php index f4fd0659..70bbc8d7 100644 --- a/tests/CryptKeyTest.php +++ b/tests/CryptKeyTest.php @@ -33,5 +33,13 @@ class CryptKeyTest extends TestCase 'file://' . sys_get_temp_dir() . '/' . sha1($keyContent) . '.key', $key->getKeyPath() ); + + $keyContent = file_get_contents(__DIR__ . '/Stubs/private.key.crlf'); + $key = new CryptKey($keyContent); + + $this->assertEquals( + 'file://' . sys_get_temp_dir() . '/' . sha1($keyContent) . '.key', + $key->getKeyPath() + ); } } diff --git a/tests/Grant/AuthCodeGrantTest.php b/tests/Grant/AuthCodeGrantTest.php index c72073ec..40e4ef99 100644 --- a/tests/Grant/AuthCodeGrantTest.php +++ b/tests/Grant/AuthCodeGrantTest.php @@ -47,8 +47,12 @@ class AuthCodeGrantTest extends TestCase public function setUp() { $this->cryptStub = new CryptTraitStub; - $this->codeVerifier = rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '='); - $this->codeChallenge = hash('sha256', strtr(rtrim(base64_encode($this->codeVerifier), '='), '+/', '-_')); + + // [RFC 7636] Appendix B. Example for the S256 code_challenge_method + // $this->codeVerifier = 'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk'; + $this->codeVerifier = strtr(rtrim(base64_encode(random_bytes(32)), '='), '+/', '-_'); + // $this->codeChallenge = 'E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM'; + $this->codeChallenge = strtr(rtrim(base64_encode(hash('sha256', $this->codeVerifier, true)), '='), '+/', '-_'); } public function testGetIdentifier() diff --git a/tests/Stubs/.gitattributes b/tests/Stubs/.gitattributes new file mode 100644 index 00000000..ea9fa3f5 --- /dev/null +++ b/tests/Stubs/.gitattributes @@ -0,0 +1 @@ +private.key.crlf text eol=crlf diff --git a/tests/Stubs/private.key.crlf b/tests/Stubs/private.key.crlf new file mode 100644 index 00000000..5e7e5a01 --- /dev/null +++ b/tests/Stubs/private.key.crlf @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAtHYxRBYATiiyDFs3pEhFg6Ei/UiQEmolTaQyQK810xHY23+X +4elLl6HP1J09mefmJ3ZdIgjIOS6rfK1BQnZIvI+IkoC7+qpD92y9f48iL0tCYKsn +i1LFFjP0bESTGDe7XANifQPkp9GvKgJbu7h1/ac8x4CBSU0ZjtEvinQRsdYil6OM +MXLWGozbBy13X8G+Ganv2i1aPZ2B25GyrH6lVIEwztGrSYxUrFVL+8dHhONf6PYX +19gjdzxkXCYQy2AGMc1FevZmnpIqDNQwX7CUUXQ4TDJmiP0aBEni094gUhnRFUr9 +dmGpLQcCb2i0WMh2K+swFk3EutDAJ+73LKoZ3QIDAQABAoIBADo8Tge3xd9zGIoO +QbV9MRmaPW1ZJk0a/fDBRQpEwGzdvIqQ8VWQ8Lj9GdF18LQi9s3TT5i1FtAFNIfm +bUHiY/SdqSgF7SOmIIrPB5QLf6+dbM0/TmKSklFo8L6jnohZK9g0q2rGf9p8Ozem +TS4WB9WUS3PiD1a1T8Mb1Gisri0h7rvI4TIkrcx6lUUCgphCZd2TWUhmE3YmybOg +4h855W685g/ydzjwB+5Y6CS3V6a78Z5Gb4df3l0XfqCWh/xzuNs7nIpRv8CE0vRE +vq9j/cVyKkzMjiagteJaisTCBkDmtAi9dEVL8uaSDoTJq1g+VOGuJxHUm31Pavqr +3RwvXS0CgYEA74jUqmzxAwr/uBWquIkfMg+hsKjJe3gsSAJIAPzcA9OkzZd9w/1R +P8C92N2UaDbCW7ZEl7ZzS+IO6nA4OcR98j77/nBk6cYykyVRkSaj01epz3bRApxc +R18e49MBftSMnI5R7lIJO/UAIRfd0rntX4jkdVAdn9s/VOvG8w4KQXcCgYEAwN3W +b3azSNYlj4CW8+t6qS/3JQ/qpPgVuqkqP9dQXC9O6VlV03pJIwFk2Ldjd7/eXT+0 +hFVB3O71iECfet/1UgustlgFp5I4ZrPmYF/J1nGpx1KIE8P4d0qC8lODtdnsGAcU ++/vBjXinX7pWgM8e6LAJzqNUq/xal/wNY325dEsCgYB7J0+n+/ECToJhhApNbHq0 +g2LvcCh/Ka8iqsGYeGkqMoOWDKBlxvUiIRe6y1nFJvpQquqjUfP/fM+Ma3wM/2B9 +zzJChEjuBK/2BYblaQdr3rN47i7R99BeBaLdIZywN9m/mFC5hkYnJHUXjqzG7j8E +El7bjgBdMx1hrQOR7ZMKSwKBgQC2SXXBiBlPwEdj6I/EH06h1hnrR63pGim/cN/j +0ye62WPmHW+HH888bLbaNgqnRgtvayS85rAHlzst+pZBVqfRUgN9nJhLl2IDgAlA +EYj9TBTBtXmz5MdUSHKXguO73yrMUvU8bOi1Q9I+IipcOGboWmoKikke/LbLa4lj +/ZJpHQKBgQCuDanU+AJKgUQkkC2gHwT8quxPoRcFFErHp3iaDAwd5XsZJG9FHQUP +RkPE+JkSaj65byFLhCPHUayfk4Y4udHEy4cXiv2SxZNK8q1HwuFEvb7uFprj0hNs +14qJunONVt/jzswdwO5kGVbpGlHl7U0JABnTJP71fW/rE5SH4zYxqg== +-----END RSA PRIVATE KEY-----