Skip to content

Commit

Permalink
Merge pull request #60 from sjones608/nullkey
Browse files Browse the repository at this point in the history
require a non-empty key to decode a JWT
  • Loading branch information
robertdimarco committed Jul 22, 2015
2 parents 11855db + 17180b1 commit 37a6b73
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 40 deletions.
83 changes: 43 additions & 40 deletions src/JWT.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Firebase\JWT;
use \DomainException;
use \InvalidArgumentException;
use \UnexpectedValueException;
use \DateTime;

Expand Down Expand Up @@ -56,8 +57,11 @@ class JWT
* @uses jsonDecode
* @uses urlsafeB64Decode
*/
public static function decode($jwt, $key = null, $allowed_algs = array())
public static function decode($jwt, $key, $allowed_algs = array())
{
if (empty($key)) {
throw new InvalidArgumentException('Key may not be empty');
}
$tks = explode('.', $jwt);
if (count($tks) != 3) {
throw new UnexpectedValueException('Wrong number of segments');
Expand All @@ -70,50 +74,49 @@ public static function decode($jwt, $key = null, $allowed_algs = array())
throw new UnexpectedValueException('Invalid claims encoding');
}
$sig = JWT::urlsafeB64Decode($cryptob64);
if (isset($key)) {
if (empty($header->alg)) {
throw new DomainException('Empty algorithm');
}
if (empty(self::$supported_algs[$header->alg])) {
throw new DomainException('Algorithm not supported');
}
if (!is_array($allowed_algs) || !in_array($header->alg, $allowed_algs)) {
throw new DomainException('Algorithm not allowed');
}
if (is_array($key) || $key instanceof \ArrayAccess) {
if (isset($header->kid)) {
$key = $key[$header->kid];
} else {
throw new DomainException('"kid" empty, unable to lookup correct key');
}

if (empty($header->alg)) {
throw new DomainException('Empty algorithm');
}
if (empty(self::$supported_algs[$header->alg])) {
throw new DomainException('Algorithm not supported');
}
if (!is_array($allowed_algs) || !in_array($header->alg, $allowed_algs)) {
throw new DomainException('Algorithm not allowed');
}
if (is_array($key) || $key instanceof \ArrayAccess) {
if (isset($header->kid)) {
$key = $key[$header->kid];
} else {
throw new DomainException('"kid" empty, unable to lookup correct key');
}
}

// Check the signature
if (!JWT::verify("$headb64.$bodyb64", $sig, $key, $header->alg)) {
throw new SignatureInvalidException('Signature verification failed');
}
// Check the signature
if (!JWT::verify("$headb64.$bodyb64", $sig, $key, $header->alg)) {
throw new SignatureInvalidException('Signature verification failed');
}

// Check if the nbf if it is defined. This is the time that the
// token can actually be used. If it's not yet that time, abort.
if (isset($payload->nbf) && $payload->nbf > (time() + self::$leeway)) {
throw new BeforeValidException(
'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf)
);
}
// Check if the nbf if it is defined. This is the time that the
// token can actually be used. If it's not yet that time, abort.
if (isset($payload->nbf) && $payload->nbf > (time() + self::$leeway)) {
throw new BeforeValidException(
'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf)
);
}

// Check that this token has been created before 'now'. This prevents
// using tokens that have been created for later use (and haven't
// correctly used the nbf claim).
if (isset($payload->iat) && $payload->iat > (time() + self::$leeway)) {
throw new BeforeValidException(
'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat)
);
}
// Check that this token has been created before 'now'. This prevents
// using tokens that have been created for later use (and haven't
// correctly used the nbf claim).
if (isset($payload->iat) && $payload->iat > (time() + self::$leeway)) {
throw new BeforeValidException(
'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat)
);
}

// Check if this token has expired.
if (isset($payload->exp) && (time() - self::$leeway) >= $payload->exp) {
throw new ExpiredException('Expired token');
}
// Check if this token has expired.
if (isset($payload->exp) && (time() - self::$leeway) >= $payload->exp) {
throw new ExpiredException('Expired token');
}

return $payload;
Expand Down
20 changes: 20 additions & 0 deletions tests/JWTTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,26 @@ public function testInvalidToken()
$decoded = JWT::decode($encoded, 'my_key2', array('HS256'));
}

public function testNullKeyFails()
{
$payload = array(
"message" => "abc",
"exp" => time() + JWT::$leeway + 20); // time in the future
$encoded = JWT::encode($payload, 'my_key');
$this->setExpectedException('InvalidArgumentException');
$decoded = JWT::decode($encoded, null, array('HS256'));
}

public function testEmptyKeyFails()
{
$payload = array(
"message" => "abc",
"exp" => time() + JWT::$leeway + 20); // time in the future
$encoded = JWT::encode($payload, 'my_key');
$this->setExpectedException('InvalidArgumentException');
$decoded = JWT::decode($encoded, '', array('HS256'));
}

public function testRSEncodeDecode()
{
$privKey = openssl_pkey_new(array('digest_alg' => 'sha256',
Expand Down

0 comments on commit 37a6b73

Please sign in to comment.