API: fix JWT signature verification

Fixes https://github.com/shaarli/Shaarli/issues/737

Added:
- Base64Url utilities

Fixed:
- use URL-safe Base64 encoding/decoding functions
- use byte representations for HMAC digests
- all JWT parts are Base64Url-encoded

See:
- https://en.wikipedia.org/wiki/JSON_Web_Token
- https://tools.ietf.org/html/rfc7519
- https://scotch.io/tutorials/the-anatomy-of-a-json-web-token
- https://jwt.io/introduction/
- https://en.wikipedia.org/wiki/Base64#URL_applications
- https://secure.php.net/manual/en/function.base64-encode.php#103849

Signed-off-by: VirtualTam <virtualtam@flibidi.net>
This commit is contained in:
VirtualTam 2017-01-04 11:41:05 +01:00
parent fc11ab2f29
commit 7a9daac56d
4 changed files with 49 additions and 13 deletions
application/api

View file

@ -1,13 +1,11 @@
<?php
namespace Shaarli\Api;
use Shaarli\Base64Url;
use Shaarli\Api\Exceptions\ApiAuthorizationException;
/**
* Class ApiUtils
*
* Utility functions for the API.
* REST API utilities
*/
class ApiUtils
{
@ -26,17 +24,17 @@ class ApiUtils
throw new ApiAuthorizationException('Malformed JWT token');
}
$genSign = hash_hmac('sha512', $parts[0] .'.'. $parts[1], $secret);
$genSign = Base64Url::encode(hash_hmac('sha512', $parts[0] .'.'. $parts[1], $secret, true));
if ($parts[2] != $genSign) {
throw new ApiAuthorizationException('Invalid JWT signature');
}
$header = json_decode(base64_decode($parts[0]));
$header = json_decode(Base64Url::decode($parts[0]));
if ($header === null) {
throw new ApiAuthorizationException('Invalid JWT header');
}
$payload = json_decode(base64_decode($parts[1]));
$payload = json_decode(Base64Url::decode($parts[1]));
if ($payload === null) {
throw new ApiAuthorizationException('Invalid JWT payload');
}