From 107f3c1aca2f863044e7a7b654f75506a213146a Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 5 Nov 2019 15:17:12 +0900 Subject: [PATCH 01/10] WIP --- src/ECPublicKey.php | 161 ++++++++++++++++++++++++++++++++++++++++++++ src/JWT.php | 5 ++ 2 files changed, 166 insertions(+) create mode 100644 src/ECPublicKey.php diff --git a/src/ECPublicKey.php b/src/ECPublicKey.php new file mode 100644 index 00000000..fbb8a723 --- /dev/null +++ b/src/ECPublicKey.php @@ -0,0 +1,161 @@ + '1.2.840.10045.3.1.7', // Len: 64 + // 'P-384' => '1.3.132.0.34', // Len: 96 (not yet supported) + // 'P-521' => '1.3.132.0.35', // Len: 132 (not supported) + ]; + + public function __construct(array $data) + { + if (isset($data['d'])) { + // The key is actually a private key + throw new \Exception('Key data must be for a public key'); + } + + if (empty($data['crv'])) { + throw new \Exception('crv not set'); + } + + if (!isset(self::$curves[$data['crv']])) { + throw new \Exception('Unrecognised or unsupported EC curve'); + } + + $this->data = $data; + } + + public function toPEM() + { + $oid = self::$curves[$this->data['crv']]; + $pem = + self::encodeDER( + self::ASN1_SEQUENCE, + self::encodeDER( + self::ASN1_SEQUENCE, + self::encodeDER( + self::ASN1_OBJECT_IDENTIFIER, + self::encodeOID(self::OID) + ) + . self::encodeDER( + self::ASN1_OBJECT_IDENTIFIER, + self::encodeOID($oid) + ) + ) . + self::encodeDER( + self::ASN1_BIT_STRING, + chr(0x00) . chr(0x04) + . JWT::urlsafeB64Decode($this->data['x']) + . JWT::urlsafeB64Decode($this->data['y']) + ) + ); + + return sprintf( + "-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n", + wordwrap(base64_encode($pem), 64, "\n", true) + ); + } + + /** + * Convert an ECDSA signature to an ASN.1 DER sequence + * + * @param string $sig The ECDSA signature to convert + * @return string The encoded DER object + */ + public static function encodeSignature($sig) + { + // Separate the signature into r-value and s-value + list($r, $s) = str_split($sig, (int) (strlen($sig) / 2)); + + // Trim leading zeros + $r = ltrim($r, "\x00"); + $s = ltrim($s, "\x00"); + + // Convert r-value and s-value from unsigned big-endian integers to + // signed two's complement + if (ord($r[0]) > 0x7f) { + $r = "\x00" . $r; + } + if (ord($s[0]) > 0x7f) { + $s = "\x00" . $s; + } + + return self::encodeDER( + self::ASN1_SEQUENCE, + self::encodeDER(self::ASN1_INTEGER, $r) . + self::encodeDER(self::ASN1_INTEGER, $s) + ); + } + + /** + * Encodes a value into a DER object. + * + * @param int $type DER tag + * @param string $value the value to encode + * @return string the encoded object + */ + private static function encodeDER($type, $value) + { + $tag_header = 0; + if ($type === self::ASN1_SEQUENCE) { + $tag_header |= 0x20; + } + + // Type + $der = chr($tag_header | $type); + + // Length + $der .= chr(strlen($value)); + + return $der . $value; + } + + /** + * Encodes a string into a DER-encoded OID. + * + * @param string $oid the OID string + * @return string the binary DER-encoded OID + */ + private static function encodeOID($oid) + { + $octets = explode('.', $oid); + + // Get the first octet + $oid = chr(array_shift($octets) * 40 + array_shift($octets)); + + // Iterate over subsequent octets + foreach ($octets as $octet) { + if ($octet == 0) { + $oid .= chr(0x00); + continue; + } + $bin = ''; + + while ($octet) { + $bin .= chr(0x80 | ($octet & 0x7f)); + $octet >>= 7; + } + $bin[0] = $bin[0] & chr(0x7f); + + // Convert to big endian if necessary + if (pack('V', 65534) == pack('L', 65534)) { + $oid .= strrev($bin); + } else { + $oid .= $bin; + } + } + + return $oid; + } +} \ No newline at end of file diff --git a/src/JWT.php b/src/JWT.php index 388d671f..93d9572c 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -97,6 +97,11 @@ public static function decode($jwt, $key, array $allowed_algs = array()) if (!in_array($header->alg, $allowed_algs)) { throw new UnexpectedValueException('Algorithm not allowed'); } + if ($header->alg === 'ES256') { + // OpenSSL expects an ASN.1 DER sequence for ES256 signatures + $sig = ECPublicKey::encodeSignature($sig); + } + if (is_array($key) || $key instanceof \ArrayAccess) { if (isset($header->kid)) { if (!isset($key[$header->kid])) { From 0c693a40a80a88d7eb06960205b24c820e8a04e0 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Mon, 10 Feb 2020 10:12:35 -0800 Subject: [PATCH 02/10] removes unnecessary EC logic --- src/ECPublicKey.php | 161 -------------------------------------------- src/JWT.php | 58 +++++++++++++++- 2 files changed, 57 insertions(+), 162 deletions(-) delete mode 100644 src/ECPublicKey.php diff --git a/src/ECPublicKey.php b/src/ECPublicKey.php deleted file mode 100644 index fbb8a723..00000000 --- a/src/ECPublicKey.php +++ /dev/null @@ -1,161 +0,0 @@ - '1.2.840.10045.3.1.7', // Len: 64 - // 'P-384' => '1.3.132.0.34', // Len: 96 (not yet supported) - // 'P-521' => '1.3.132.0.35', // Len: 132 (not supported) - ]; - - public function __construct(array $data) - { - if (isset($data['d'])) { - // The key is actually a private key - throw new \Exception('Key data must be for a public key'); - } - - if (empty($data['crv'])) { - throw new \Exception('crv not set'); - } - - if (!isset(self::$curves[$data['crv']])) { - throw new \Exception('Unrecognised or unsupported EC curve'); - } - - $this->data = $data; - } - - public function toPEM() - { - $oid = self::$curves[$this->data['crv']]; - $pem = - self::encodeDER( - self::ASN1_SEQUENCE, - self::encodeDER( - self::ASN1_SEQUENCE, - self::encodeDER( - self::ASN1_OBJECT_IDENTIFIER, - self::encodeOID(self::OID) - ) - . self::encodeDER( - self::ASN1_OBJECT_IDENTIFIER, - self::encodeOID($oid) - ) - ) . - self::encodeDER( - self::ASN1_BIT_STRING, - chr(0x00) . chr(0x04) - . JWT::urlsafeB64Decode($this->data['x']) - . JWT::urlsafeB64Decode($this->data['y']) - ) - ); - - return sprintf( - "-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n", - wordwrap(base64_encode($pem), 64, "\n", true) - ); - } - - /** - * Convert an ECDSA signature to an ASN.1 DER sequence - * - * @param string $sig The ECDSA signature to convert - * @return string The encoded DER object - */ - public static function encodeSignature($sig) - { - // Separate the signature into r-value and s-value - list($r, $s) = str_split($sig, (int) (strlen($sig) / 2)); - - // Trim leading zeros - $r = ltrim($r, "\x00"); - $s = ltrim($s, "\x00"); - - // Convert r-value and s-value from unsigned big-endian integers to - // signed two's complement - if (ord($r[0]) > 0x7f) { - $r = "\x00" . $r; - } - if (ord($s[0]) > 0x7f) { - $s = "\x00" . $s; - } - - return self::encodeDER( - self::ASN1_SEQUENCE, - self::encodeDER(self::ASN1_INTEGER, $r) . - self::encodeDER(self::ASN1_INTEGER, $s) - ); - } - - /** - * Encodes a value into a DER object. - * - * @param int $type DER tag - * @param string $value the value to encode - * @return string the encoded object - */ - private static function encodeDER($type, $value) - { - $tag_header = 0; - if ($type === self::ASN1_SEQUENCE) { - $tag_header |= 0x20; - } - - // Type - $der = chr($tag_header | $type); - - // Length - $der .= chr(strlen($value)); - - return $der . $value; - } - - /** - * Encodes a string into a DER-encoded OID. - * - * @param string $oid the OID string - * @return string the binary DER-encoded OID - */ - private static function encodeOID($oid) - { - $octets = explode('.', $oid); - - // Get the first octet - $oid = chr(array_shift($octets) * 40 + array_shift($octets)); - - // Iterate over subsequent octets - foreach ($octets as $octet) { - if ($octet == 0) { - $oid .= chr(0x00); - continue; - } - $bin = ''; - - while ($octet) { - $bin .= chr(0x80 | ($octet & 0x7f)); - $octet >>= 7; - } - $bin[0] = $bin[0] & chr(0x7f); - - // Convert to big endian if necessary - if (pack('V', 65534) == pack('L', 65534)) { - $oid .= strrev($bin); - } else { - $oid .= $bin; - } - } - - return $oid; - } -} \ No newline at end of file diff --git a/src/JWT.php b/src/JWT.php index 93d9572c..9546037a 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -21,6 +21,8 @@ */ class JWT { + const ASN1_INTEGER = 0x02; + const ASN1_SEQUENCE = 0x10; /** * When checking nbf, iat or expiration times, @@ -99,7 +101,7 @@ public static function decode($jwt, $key, array $allowed_algs = array()) } if ($header->alg === 'ES256') { // OpenSSL expects an ASN.1 DER sequence for ES256 signatures - $sig = ECPublicKey::encodeSignature($sig); + $sig = self::encodeSignature($sig); } if (is_array($key) || $key instanceof \ArrayAccess) { @@ -382,4 +384,58 @@ private static function safeStrlen($str) } return strlen($str); } + + /** + * Convert an ECDSA signature to an ASN.1 DER sequence + * + * @param string $sig The ECDSA signature to convert + * @return string The encoded DER object + */ + private static function encodeSignature($sig) + { + // Separate the signature into r-value and s-value + list($r, $s) = str_split($sig, (int) (strlen($sig) / 2)); + + // Trim leading zeros + $r = ltrim($r, "\x00"); + $s = ltrim($s, "\x00"); + + // Convert r-value and s-value from unsigned big-endian integers to + // signed two's complement + if (ord($r[0]) > 0x7f) { + $r = "\x00" . $r; + } + if (ord($s[0]) > 0x7f) { + $s = "\x00" . $s; + } + + return self::encodeDER( + self::ASN1_SEQUENCE, + self::encodeDER(self::ASN1_INTEGER, $r) . + self::encodeDER(self::ASN1_INTEGER, $s) + ); + } + + /** + * Encodes a value into a DER object. + * + * @param int $type DER tag + * @param string $value the value to encode + * @return string the encoded object + */ + private static function encodeDER($type, $value) + { + $tag_header = 0; + if ($type === self::ASN1_SEQUENCE) { + $tag_header |= 0x20; + } + + // Type + $der = chr($tag_header | $type); + + // Length + $der .= chr(strlen($value)); + + return $der . $value; + } } From 08ed22ef83e4122e2bdbbdf71b670c554b0eea18 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 11 Feb 2020 14:11:59 -0800 Subject: [PATCH 03/10] adds a test for ecdsa --- src/JWT.php | 4 ++-- tests/JWTTest.php | 16 ++++++++++++++++ tests/publickeys.json | 3 +++ 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 tests/publickeys.json diff --git a/src/JWT.php b/src/JWT.php index 9546037a..06635d3f 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -101,7 +101,7 @@ public static function decode($jwt, $key, array $allowed_algs = array()) } if ($header->alg === 'ES256') { // OpenSSL expects an ASN.1 DER sequence for ES256 signatures - $sig = self::encodeSignature($sig); + $sig = self::signatureToDer($sig); } if (is_array($key) || $key instanceof \ArrayAccess) { @@ -391,7 +391,7 @@ private static function safeStrlen($str) * @param string $sig The ECDSA signature to convert * @return string The encoded DER object */ - private static function encodeSignature($sig) + private static function signatureToDer($sig) { // Separate the signature into r-value and s-value list($r, $s) = str_split($sig, (int) (strlen($sig) / 2)); diff --git a/tests/JWTTest.php b/tests/JWTTest.php index 804a3769..59027c52 100644 --- a/tests/JWTTest.php +++ b/tests/JWTTest.php @@ -282,6 +282,22 @@ public function testVerifyError() self::$opensslVerifyReturnValue = -1; JWT::decode($msg, $pkey, array('RS256')); } + + /** + * @runInSeparateProcess + */ + public function testValidEcdsaToken() + { + if (false === $ecdsaToken = getenv('ECDSA_JWT')) { + $this->markTestSkipped('Set the ECDSA_JWT environment variable'); + } + JWT::$leeway = 100000000; // three years + $keys = json_decode(file_get_contents(__DIR__ . '/publickeys.json'), true); + $decoded = JWT::decode($ecdsaToken, $keys, ['ES256']); + $this->assertTrue((bool) $decoded); + $this->assertEquals($decoded->hd, 'google.com'); + JWT::$leeway = 0; + } } /* diff --git a/tests/publickeys.json b/tests/publickeys.json new file mode 100644 index 00000000..0d813c6a --- /dev/null +++ b/tests/publickeys.json @@ -0,0 +1,3 @@ +{ +"LYyP2g": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESlXFFkJ3JxMsXyXNrqzE3ozl/091\n3PmNbccLLWfeQFUYtJqGtl8ESuYxRwc/QwZp5Wcl0HCq6GuFDx4/Tk18Ig==\n-----END PUBLIC KEY-----\n" +} \ No newline at end of file From af62136f6f0a12b8515c63ed246252881ea0eb24 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 11 Feb 2020 14:34:47 -0800 Subject: [PATCH 04/10] php 5.3 compatibility --- tests/JWTTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/JWTTest.php b/tests/JWTTest.php index 59027c52..80522ab6 100644 --- a/tests/JWTTest.php +++ b/tests/JWTTest.php @@ -293,7 +293,7 @@ public function testValidEcdsaToken() } JWT::$leeway = 100000000; // three years $keys = json_decode(file_get_contents(__DIR__ . '/publickeys.json'), true); - $decoded = JWT::decode($ecdsaToken, $keys, ['ES256']); + $decoded = JWT::decode($ecdsaToken, $keys, array('ES256')); $this->assertTrue((bool) $decoded); $this->assertEquals($decoded->hd, 'google.com'); JWT::$leeway = 0; From 0f151672aed6af32a698471065f7cd763782edb6 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 11 Feb 2020 15:01:59 -0800 Subject: [PATCH 05/10] uses custom pem files --- tests/JWTTest.php | 10 ++++------ tests/ecdsa-private.pem | 18 ++++++++++++++++++ tests/ecdsa-public.pem | 9 +++++++++ tests/publickeys.json | 3 --- 4 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 tests/ecdsa-private.pem create mode 100644 tests/ecdsa-public.pem delete mode 100644 tests/publickeys.json diff --git a/tests/JWTTest.php b/tests/JWTTest.php index 80522ab6..78883dc3 100644 --- a/tests/JWTTest.php +++ b/tests/JWTTest.php @@ -288,14 +288,12 @@ public function testVerifyError() */ public function testValidEcdsaToken() { - if (false === $ecdsaToken = getenv('ECDSA_JWT')) { - $this->markTestSkipped('Set the ECDSA_JWT environment variable'); - } JWT::$leeway = 100000000; // three years - $keys = json_decode(file_get_contents(__DIR__ . '/publickeys.json'), true); - $decoded = JWT::decode($ecdsaToken, $keys, array('ES256')); + $ecdsaToken = 'eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE1ODE0NjE5NDd9.MynE0T4D1gKVZGgQOTLuxuCmbW5w3NA6jCZEh6MEvlhtlGQDKSnbzGqNE3iqI7Ir7uODvDIuaxrgJnF62OQvmw'; + $key = file_get_contents(__DIR__ . '/ecdsa-public.pem'); + $decoded = JWT::decode($ecdsaToken, $key, array('ES256')); $this->assertTrue((bool) $decoded); - $this->assertEquals($decoded->hd, 'google.com'); + $this->assertEquals($decoded->foo, 'bar'); JWT::$leeway = 0; } } diff --git a/tests/ecdsa-private.pem b/tests/ecdsa-private.pem new file mode 100644 index 00000000..5c77adaf --- /dev/null +++ b/tests/ecdsa-private.pem @@ -0,0 +1,18 @@ +-----BEGIN EC PARAMETERS----- +MIH3AgEBMCwGByqGSM49AQECIQD/////AAAAAQAAAAAAAAAAAAAAAP////////// +/////zBbBCD/////AAAAAQAAAAAAAAAAAAAAAP///////////////AQgWsY12Ko6 +k+ez671VdpiGvGUdBrDMU7D2O848PifSYEsDFQDEnTYIhucEk2pmeOETnSa3gZ9+ +kARBBGsX0fLhLEJH+Lzm5WOkQPJ3A32BLeszoPShOUXYmMKWT+NC4v4af5uO5+tK +fA+eFivOM1drMV7Oy7ZAaDe/UfUCIQD/////AAAAAP//////////vOb6racXnoTz +ucrC/GMlUQIBAQ== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MIIBaAIBAQQgyP9e7yS1tjpXa0l6o+80dbSxuMcqx3lUg0n2OT9AmiuggfowgfcC +AQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAAAAAAAAAAAAAA//////////////// +MFsEIP////8AAAABAAAAAAAAAAAAAAAA///////////////8BCBaxjXYqjqT57Pr +vVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSdNgiG5wSTamZ44ROdJreBn36QBEEE +axfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54W +K84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8 +YyVRAgEBoUQDQgAE2klp6aX6y5kAir3EWQt0QAeapTW+db/9fD65KAoDzVajtThx +PVLEf1CufcfTxMQAQPM3wkZhu0NjlWFetcMdcQ== +-----END EC PRIVATE KEY----- diff --git a/tests/ecdsa-public.pem b/tests/ecdsa-public.pem new file mode 100644 index 00000000..31fa053d --- /dev/null +++ b/tests/ecdsa-public.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBSzCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAA +AAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA//// +///////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSd +NgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5 +RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA +//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABNpJaeml+suZAIq9xFkLdEAH +mqU1vnW//Xw+uSgKA81Wo7U4cT1SxH9Qrn3H08TEAEDzN8JGYbtDY5VhXrXDHXE= +-----END PUBLIC KEY----- diff --git a/tests/publickeys.json b/tests/publickeys.json deleted file mode 100644 index 0d813c6a..00000000 --- a/tests/publickeys.json +++ /dev/null @@ -1,3 +0,0 @@ -{ -"LYyP2g": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESlXFFkJ3JxMsXyXNrqzE3ozl/091\n3PmNbccLLWfeQFUYtJqGtl8ESuYxRwc/QwZp5Wcl0HCq6GuFDx4/Tk18Ig==\n-----END PUBLIC KEY-----\n" -} \ No newline at end of file From 8dd27667f8d8bf1b0929dd4793a1619985788fce Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 11 Feb 2020 15:49:37 -0800 Subject: [PATCH 06/10] adds support for encoding in ES256 --- src/JWT.php | 79 +++++++++++++++++++++++++++++++++++++++++++++-- tests/JWTTest.php | 18 ++++++----- 2 files changed, 86 insertions(+), 11 deletions(-) diff --git a/src/JWT.php b/src/JWT.php index 06635d3f..83a2eb7f 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -1,6 +1,7 @@ > 5) & 0x01; + $type = ord($der[$pos++]) & 0x1f; + + // Length + $len = ord($der[$pos++]); + if ($len & 0x80) { + $n = $len & 0x1f; + $len = 0; + while ($n-- && $pos < $size) { + $len = ($len << 8) | ord($der[$pos++]); + } + } + + // Value + if ($type == self::ASN1_BIT_STRING) { + $pos++; // Skip the first contents octet (padding indicator) + $data = substr($der, $pos, $len - 1); + if (!$ignore_bit_strings) { + $pos += $len - 1; + } + } elseif (!$constructed) { + $data = substr($der, $pos, $len); + $pos += $len; + } else { + $data = null; + } + + return [$pos, $data]; + } } diff --git a/tests/JWTTest.php b/tests/JWTTest.php index 78883dc3..6fa06ffa 100644 --- a/tests/JWTTest.php +++ b/tests/JWTTest.php @@ -286,15 +286,17 @@ public function testVerifyError() /** * @runInSeparateProcess */ - public function testValidEcdsaToken() + public function testEncodeAndDecodeEcdsaToken() { - JWT::$leeway = 100000000; // three years - $ecdsaToken = 'eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE1ODE0NjE5NDd9.MynE0T4D1gKVZGgQOTLuxuCmbW5w3NA6jCZEh6MEvlhtlGQDKSnbzGqNE3iqI7Ir7uODvDIuaxrgJnF62OQvmw'; - $key = file_get_contents(__DIR__ . '/ecdsa-public.pem'); - $decoded = JWT::decode($ecdsaToken, $key, array('ES256')); - $this->assertTrue((bool) $decoded); - $this->assertEquals($decoded->foo, 'bar'); - JWT::$leeway = 0; + $privateKey = file_get_contents(__DIR__ . '/ecdsa-private.pem'); + $payload = ['foo' => 'bar']; + $encoded = JWT::encode($payload, $privateKey, 'ES256'); + + // Verify decoding succeeds + $publicKey = file_get_contents(__DIR__ . '/ecdsa-public.pem'); + $decoded = JWT::decode($encoded, $publicKey, array('ES256')); + + $this->assertEquals('bar', $decoded->foo); } } From 350ea0bea4d1a4368a8b04efb7b177e4f013d0e7 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 11 Feb 2020 16:38:12 -0800 Subject: [PATCH 07/10] fixes for php 5.3 --- tests/JWTTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/JWTTest.php b/tests/JWTTest.php index 6fa06ffa..bf87debe 100644 --- a/tests/JWTTest.php +++ b/tests/JWTTest.php @@ -289,7 +289,7 @@ public function testVerifyError() public function testEncodeAndDecodeEcdsaToken() { $privateKey = file_get_contents(__DIR__ . '/ecdsa-private.pem'); - $payload = ['foo' => 'bar']; + $payload = array('foo' => 'bar'); $encoded = JWT::encode($payload, $privateKey, 'ES256'); // Verify decoding succeeds From 968472a9d0efbc250e36a63affa934abe018cfc7 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 11 Feb 2020 16:39:18 -0800 Subject: [PATCH 08/10] consistent casing --- src/JWT.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/JWT.php b/src/JWT.php index 83a2eb7f..7491517c 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -103,7 +103,7 @@ public static function decode($jwt, $key, array $allowed_algs = array()) } if ($header->alg === 'ES256') { // OpenSSL expects an ASN.1 DER sequence for ES256 signatures - $sig = self::signatureToDer($sig); + $sig = self::signatureToDER($sig); } if (is_array($key) || $key instanceof \ArrayAccess) { @@ -396,7 +396,7 @@ private static function safeStrlen($str) * @param string $sig The ECDSA signature to convert * @return string The encoded DER object */ - private static function signatureToDer($sig) + private static function signatureToDER($sig) { // Separate the signature into r-value and s-value list($r, $s) = str_split($sig, (int) (strlen($sig) / 2)); From aa0086a507865ad9cb205d27f4baeb6f9c58eac5 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 11 Feb 2020 16:44:26 -0800 Subject: [PATCH 09/10] more 5.3 fixes --- src/JWT.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/JWT.php b/src/JWT.php index 7491517c..09ffff46 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -509,6 +509,6 @@ private static function readDER($der, $offset = 0) $data = null; } - return [$pos, $data]; + return array($pos, $data); } } From 91f1827a0d68b6e94d992411d939b82d4c077a04 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 11 Feb 2020 16:53:44 -0800 Subject: [PATCH 10/10] fix incorrect doc param --- src/JWT.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/JWT.php b/src/JWT.php index 09ffff46..86357105 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -474,7 +474,7 @@ private static function signatureFromDER($der, $keySize) * Reads binary DER-encoded data and decodes into a single object * * @param string $der the binary data in DER format - * @param int &$offset the offset of the data stream containing the object + * @param int $offset the offset of the data stream containing the object * to decode * @return array [$offset, $data] the new offset and the decoded object */