| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | namespace Firebase\JWT; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | use ArrayAccess; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | use DomainException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | use Exception; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | use InvalidArgumentException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | use OpenSSLAsymmetricKey; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | use UnexpectedValueException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | use DateTime; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  |  * JSON Web Token implementation, based on this spec: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |  * https://tools.ietf.org/html/rfc7519 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |  * PHP version 5 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |  * @category Authentication | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |  * @package  Authentication_JWT | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |  * @author   Neuman Vong <[email protected]> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |  * @author   Anant Narayanan <[email protected]> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |  * @license  http://opensource.org/licenses/BSD-3-Clause 3-clause BSD | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |  * @link     https://github.com/firebase/php-jwt | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  | class JWT | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |     const ASN1_INTEGER = 0x02; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |     const ASN1_SEQUENCE = 0x10; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |     const ASN1_BIT_STRING = 0x03; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |      * When checking nbf, iat or expiration times, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |      * we want to provide some extra leeway time to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |      * account for clock skew. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |     public static $leeway = 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |      * Allow the current timestamp to be specified. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |      * Useful for fixing a value within unit testing. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |      * Will default to PHP time() value if null. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |     public static $timestamp = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |     public static $supported_algs = array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |         'ES384' => array('openssl', 'SHA384'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |         'ES256' => array('openssl', 'SHA256'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |         'HS256' => array('hash_hmac', 'SHA256'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |         'HS384' => array('hash_hmac', 'SHA384'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |         'HS512' => array('hash_hmac', 'SHA512'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |         'RS256' => array('openssl', 'SHA256'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |         'RS384' => array('openssl', 'SHA384'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |         'RS512' => array('openssl', 'SHA512'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |         'EdDSA' => array('sodium_crypto', 'EdDSA'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |     ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |      * Decodes a JWT string into a PHP object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |      * @param string                    $jwt            The JWT | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |      * @param Key|array<Key>|mixed      $keyOrKeyArray  The Key or array of Key objects. | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |      *                                                  If the algorithm used is asymmetric, this is the public key | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |      *                                                  Each Key object contains an algorithm and matching key. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |      *                                                  Supported algorithms are 'ES384','ES256', 'HS256', 'HS384', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |      *                                                  'HS512', 'RS256', 'RS384', and 'RS512' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |      * @param array                     $allowed_algs   [DEPRECATED] List of supported verification algorithms. Only | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |      *                                                  should be used for backwards  compatibility. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |      * @return object The JWT's payload as a PHP object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |      * @throws InvalidArgumentException     Provided JWT was empty | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |      * @throws UnexpectedValueException     Provided JWT was invalid | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |      * @throws SignatureInvalidException    Provided JWT was invalid because the signature verification failed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |      * @throws BeforeValidException         Provided JWT is trying to be used before it's eligible as defined by 'nbf' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |      * @throws BeforeValidException         Provided JWT is trying to be used before it's been created as defined by 'iat' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |      * @throws ExpiredException             Provided JWT has since expired, as defined by the 'exp' claim | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |      * @uses jsonDecode | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |      * @uses urlsafeB64Decode | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |     public static function decode($jwt, $keyOrKeyArray, array $allowed_algs = array()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |         $timestamp = \is_null(static::$timestamp) ? \time() : static::$timestamp; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |         if (empty($keyOrKeyArray)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |             throw new InvalidArgumentException('Key may not be empty'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |         $tks = \explode('.', $jwt); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |         if (\count($tks) != 3) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |             throw new UnexpectedValueException('Wrong number of segments'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |         list($headb64, $bodyb64, $cryptob64) = $tks; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |         if (null === ($header = static::jsonDecode(static::urlsafeB64Decode($headb64)))) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |             throw new UnexpectedValueException('Invalid header encoding'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |         if (null === $payload = static::jsonDecode(static::urlsafeB64Decode($bodyb64))) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |             throw new UnexpectedValueException('Invalid claims encoding'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |         if (false === ($sig = static::urlsafeB64Decode($cryptob64))) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |             throw new UnexpectedValueException('Invalid signature encoding'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |         if (empty($header->alg)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |             throw new UnexpectedValueException('Empty algorithm'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |         if (empty(static::$supported_algs[$header->alg])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |             throw new UnexpectedValueException('Algorithm not supported'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |         list($keyMaterial, $algorithm) = self::getKeyMaterialAndAlgorithm( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |             $keyOrKeyArray, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |             empty($header->kid) ? null : $header->kid | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |         if (empty($algorithm)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |             // Use deprecated "allowed_algs" to determine if the algorithm is supported. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |             // This opens up the possibility of an attack in some implementations. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |             // @see https://github.com/firebase/php-jwt/issues/351 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |             if (!\in_array($header->alg, $allowed_algs)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |                 throw new UnexpectedValueException('Algorithm not allowed'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |             // Check the algorithm | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |             if (!self::constantTimeEquals($algorithm, $header->alg)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |                 // See issue #351 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |                 throw new UnexpectedValueException('Incorrect key for this algorithm'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |         if ($header->alg === 'ES256' || $header->alg === 'ES384') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |             // OpenSSL expects an ASN.1 DER sequence for ES256/ES384 signatures | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |             $sig = self::signatureToDER($sig); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |         if (!static::verify("$headb64.$bodyb64", $sig, $keyMaterial, $header->alg)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |             throw new SignatureInvalidException('Signature verification failed'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |         // Check the nbf if it is defined. This is the time that the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |         // token can actually be used. If it's not yet that time, abort. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |         if (isset($payload->nbf) && $payload->nbf > ($timestamp + static::$leeway)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |             throw new BeforeValidException( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |                 'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->nbf) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  |         // Check that this token has been created before 'now'. This prevents | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |         // using tokens that have been created for later use (and haven't | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |         // correctly used the nbf claim). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |         if (isset($payload->iat) && $payload->iat > ($timestamp + static::$leeway)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  |             throw new BeforeValidException( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |                 'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->iat) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |         // Check if this token has expired. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |         if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |             throw new ExpiredException('Expired token'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |         return $payload; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |      * Converts and signs a PHP object or array into a JWT string. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  |      * @param object|array      $payload    PHP object or array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |      * @param string|resource   $key        The secret key. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 |  |  |      *                                      If the algorithm used is asymmetric, this is the private key | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 |  |  |      * @param string            $alg        The signing algorithm. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 |  |  |      *                                      Supported algorithms are 'ES384','ES256', 'HS256', 'HS384', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 |  |  |      *                                      'HS512', 'RS256', 'RS384', and 'RS512' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 |  |  |      * @param mixed             $keyId | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 |  |  |      * @param array             $head       An array with header elements to attach | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 |  |  |      * @return string A signed JWT | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 |  |  |      * @uses jsonEncode | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  |      * @uses urlsafeB64Encode | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 |  |  |     public static function encode($payload, $key, $alg = 'HS256', $keyId = null, $head = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 |  |  |         $header = array('typ' => 'JWT', 'alg' => $alg); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 |  |  |         if ($keyId !== null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 |  |  |             $header['kid'] = $keyId; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 |  |  |         if (isset($head) && \is_array($head)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 |  |  |             $header = \array_merge($head, $header); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 190 |  |  |         $segments = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 191 |  |  |         $segments[] = static::urlsafeB64Encode(static::jsonEncode($header)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 192 |  |  |         $segments[] = static::urlsafeB64Encode(static::jsonEncode($payload)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 193 |  |  |         $signing_input = \implode('.', $segments); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 194 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 195 |  |  |         $signature = static::sign($signing_input, $key, $alg); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 196 |  |  |         $segments[] = static::urlsafeB64Encode($signature); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 197 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 198 |  |  |         return \implode('.', $segments); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 199 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 200 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  |      * Sign a string with a given key and algorithm. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 |  |  |      * @param string            $msg    The message to sign | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 |  |  |      * @param string|resource   $key    The secret key | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 |  |  |      * @param string            $alg    The signing algorithm. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 |  |  |      *                                  Supported algorithms are 'ES384','ES256', 'HS256', 'HS384', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 |  |  |      *                                  'HS512', 'RS256', 'RS384', and 'RS512' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 |  |  |      * @return string An encrypted message | 
            
                                                                                                            
                            
            
                                    
            
            
                | 211 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 212 |  |  |      * @throws DomainException Unsupported algorithm or bad key was specified | 
            
                                                                                                            
                            
            
                                    
            
            
                | 213 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 214 |  |  |     public static function sign($msg, $key, $alg = 'HS256') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 215 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 216 |  |  |         if (empty(static::$supported_algs[$alg])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 217 |  |  |             throw new DomainException('Algorithm not supported'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 218 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 219 |  |  |         list($function, $algorithm) = static::$supported_algs[$alg]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 220 |  |  |         switch ($function) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 221 |  |  |             case 'hash_hmac': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 222 |  |  |                 return \hash_hmac($algorithm, $msg, $key, true); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 223 |  |  |             case 'openssl': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 224 |  |  |                 $signature = ''; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 225 |  |  |                 $success = \openssl_sign($msg, $signature, $key, $algorithm); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 226 |  |  |                 if (!$success) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 227 |  |  |                     throw new DomainException("OpenSSL unable to sign data"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 228 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 229 |  |  |                 if ($alg === 'ES256') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 230 |  |  |                     $signature = self::signatureFromDER($signature, 256); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 231 |  |  |                 } elseif ($alg === 'ES384') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 232 |  |  |                     $signature = self::signatureFromDER($signature, 384); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 233 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 234 |  |  |                 return $signature; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 235 |  |  |             case 'sodium_crypto': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 236 |  |  |                 if (!function_exists('sodium_crypto_sign_detached')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 237 |  |  |                     throw new DomainException('libsodium is not available'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 238 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 239 |  |  |                 try { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 240 |  |  |                     // The last non-empty line is used as the key. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 241 |  |  |                     $lines = array_filter(explode("\n", $key)); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 242 |  |  |                     $key = base64_decode(end($lines)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 243 |  |  |                     return sodium_crypto_sign_detached($msg, $key); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 244 |  |  |                 } catch (Exception $e) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 245 |  |  |                     throw new DomainException($e->getMessage(), 0, $e); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 246 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 247 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 248 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 249 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 250 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 251 |  |  |      * Verify a signature with the message, key and method. Not all methods | 
            
                                                                                                            
                            
            
                                    
            
            
                | 252 |  |  |      * are symmetric, so we must have a separate verify and sign method. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 253 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 254 |  |  |      * @param string            $msg        The original message (header and body) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 255 |  |  |      * @param string            $signature  The original signature | 
            
                                                                                                            
                            
            
                                    
            
            
                | 256 |  |  |      * @param string|resource   $key        For HS*, a string key works. for RS*, must be a resource of an openssl public key | 
            
                                                                                                            
                            
            
                                    
            
            
                | 257 |  |  |      * @param string            $alg        The algorithm | 
            
                                                                                                            
                            
            
                                    
            
            
                | 258 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 259 |  |  |      * @return bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 260 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 261 |  |  |      * @throws DomainException Invalid Algorithm, bad key, or OpenSSL failure | 
            
                                                                                                            
                            
            
                                    
            
            
                | 262 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 263 |  |  |     private static function verify($msg, $signature, $key, $alg) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 264 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 265 |  |  |         if (empty(static::$supported_algs[$alg])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 266 |  |  |             throw new DomainException('Algorithm not supported'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 267 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 268 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 269 |  |  |         list($function, $algorithm) = static::$supported_algs[$alg]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 270 |  |  |         switch ($function) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 271 |  |  |             case 'openssl': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 272 |  |  |                 $success = \openssl_verify($msg, $signature, $key, $algorithm); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 273 |  |  |                 if ($success === 1) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 274 |  |  |                     return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 275 |  |  |                 } elseif ($success === 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 276 |  |  |                     return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 277 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 278 |  |  |                 // returns 1 on success, 0 on failure, -1 on error. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 279 |  |  |                 throw new DomainException( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 280 |  |  |                     'OpenSSL error: ' . \openssl_error_string() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 281 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 282 |  |  |             case 'sodium_crypto': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 283 |  |  |               if (!function_exists('sodium_crypto_sign_verify_detached')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 284 |  |  |                   throw new DomainException('libsodium is not available'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 285 |  |  |               } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 286 |  |  |               try { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 287 |  |  |                   // The last non-empty line is used as the key. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 288 |  |  |                   $lines = array_filter(explode("\n", $key)); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 289 |  |  |                   $key = base64_decode(end($lines)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 290 |  |  |                   return sodium_crypto_sign_verify_detached($signature, $msg, $key); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 291 |  |  |               } catch (Exception $e) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 292 |  |  |                   throw new DomainException($e->getMessage(), 0, $e); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 293 |  |  |               } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 294 |  |  |             case 'hash_hmac': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 295 |  |  |             default: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 296 |  |  |                 $hash = \hash_hmac($algorithm, $msg, $key, true); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 297 |  |  |                 return self::constantTimeEquals($signature, $hash); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 298 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 299 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 300 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 301 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 302 |  |  |      * Decode a JSON string into a PHP object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 303 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 304 |  |  |      * @param string $input JSON string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 305 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 306 |  |  |      * @return object Object representation of JSON string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 307 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 308 |  |  |      * @throws DomainException Provided string was invalid JSON | 
            
                                                                                                            
                            
            
                                    
            
            
                | 309 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 310 |  |  |     public static function jsonDecode($input) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 311 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 312 |  |  |         if (\version_compare(PHP_VERSION, '5.4.0', '>=') && !(\defined('JSON_C_VERSION') && PHP_INT_SIZE > 4)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 313 |  |  |             /** In PHP >=5.4.0, json_decode() accepts an options parameter, that allows you | 
            
                                                                                                            
                            
            
                                    
            
            
                | 314 |  |  |              * to specify that large ints (like Steam Transaction IDs) should be treated as | 
            
                                                                                                            
                            
            
                                    
            
            
                | 315 |  |  |              * strings, rather than the PHP default behaviour of converting them to floats. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 316 |  |  |              */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 317 |  |  |             $obj = \json_decode($input, false, 512, JSON_BIGINT_AS_STRING); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 318 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 319 |  |  |             /** Not all servers will support that, however, so for older versions we must | 
            
                                                                                                            
                            
            
                                    
            
            
                | 320 |  |  |              * manually detect large ints in the JSON string and quote them (thus converting | 
            
                                                                                                            
                            
            
                                    
            
            
                | 321 |  |  |              *them to strings) before decoding, hence the preg_replace() call. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 322 |  |  |              */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 323 |  |  |             $max_int_length = \strlen((string) PHP_INT_MAX) - 1; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 324 |  |  |             $json_without_bigints = \preg_replace('/:\s*(-?\d{'.$max_int_length.',})/', ': "$1"', $input); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 325 |  |  |             $obj = \json_decode($json_without_bigints); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 326 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 327 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 328 |  |  |         if ($errno = \json_last_error()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 329 |  |  |             static::handleJsonError($errno); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 330 |  |  |         } elseif ($obj === null && $input !== 'null') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 331 |  |  |             throw new DomainException('Null result with non-null input'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 332 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 333 |  |  |         return $obj; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 334 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 335 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 336 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 337 |  |  |      * Encode a PHP object into a JSON string. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 338 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 339 |  |  |      * @param object|array $input A PHP object or array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 340 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 341 |  |  |      * @return string JSON representation of the PHP object or array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 342 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 343 |  |  |      * @throws DomainException Provided object could not be encoded to valid JSON | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 344 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 345 |  |  |     public static function jsonEncode($input) | 
            
                                                                        
                            
            
                                    
            
            
                | 346 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 347 |  |  |         $json = \json_encode($input); | 
            
                                                                        
                            
            
                                    
            
            
                | 348 |  |  |         if ($errno = \json_last_error()) { | 
            
                                                                        
                            
            
                                    
            
            
                | 349 |  |  |             static::handleJsonError($errno); | 
            
                                                                        
                            
            
                                    
            
            
                | 350 |  |  |         } elseif ($json === 'null' && $input !== null) { | 
            
                                                                        
                            
            
                                    
            
            
                | 351 |  |  |             throw new DomainException('Null result with non-null input'); | 
            
                                                                        
                            
            
                                    
            
            
                | 352 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 353 |  |  |         return $json; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 354 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 355 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 356 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 357 |  |  |      * Decode a string with URL-safe Base64. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 358 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 359 |  |  |      * @param string $input A Base64 encoded string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 360 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 361 |  |  |      * @return string A decoded string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 362 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 363 |  |  |     public static function urlsafeB64Decode($input) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 364 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 365 |  |  |         $remainder = \strlen($input) % 4; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 366 |  |  |         if ($remainder) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 367 |  |  |             $padlen = 4 - $remainder; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 368 |  |  |             $input .= \str_repeat('=', $padlen); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 369 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 370 |  |  |         return \base64_decode(\strtr($input, '-_', '+/')); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 371 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 372 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 373 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 374 |  |  |      * Encode a string with URL-safe Base64. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 375 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 376 |  |  |      * @param string $input The string you want encoded | 
            
                                                                                                            
                            
            
                                    
            
            
                | 377 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 378 |  |  |      * @return string The base64 encode of what you passed in | 
            
                                                                                                            
                            
            
                                    
            
            
                | 379 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 380 |  |  |     public static function urlsafeB64Encode($input) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 381 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 382 |  |  |         return \str_replace('=', '', \strtr(\base64_encode($input), '+/', '-_')); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 383 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 384 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 385 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 386 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 387 |  |  |      * Determine if an algorithm has been provided for each Key | 
            
                                                                                                            
                            
            
                                    
            
            
                | 388 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 389 |  |  |      * @param Key|array<Key>|mixed $keyOrKeyArray | 
            
                                                                                                            
                            
            
                                    
            
            
                | 390 |  |  |      * @param string|null $kid | 
            
                                                                                                            
                            
            
                                    
            
            
                | 391 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 392 |  |  |      * @throws UnexpectedValueException | 
            
                                                                                                            
                            
            
                                    
            
            
                | 393 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 394 |  |  |      * @return array containing the keyMaterial and algorithm | 
            
                                                                                                            
                            
            
                                    
            
            
                | 395 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 396 |  |  |     private static function getKeyMaterialAndAlgorithm($keyOrKeyArray, $kid = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 397 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 398 |  |  |         if ( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 399 |  |  |             is_string($keyOrKeyArray) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 400 |  |  |             || is_resource($keyOrKeyArray) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 401 |  |  |             || $keyOrKeyArray instanceof OpenSSLAsymmetricKey | 
            
                                                                                                            
                            
            
                                    
            
            
                | 402 |  |  |         ) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 403 |  |  |             return array($keyOrKeyArray, null); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 404 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 405 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 406 |  |  |         if ($keyOrKeyArray instanceof Key) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 407 |  |  |             return array($keyOrKeyArray->getKeyMaterial(), $keyOrKeyArray->getAlgorithm()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 408 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 409 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 410 |  |  |         if (is_array($keyOrKeyArray) || $keyOrKeyArray instanceof ArrayAccess) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 411 |  |  |             if (!isset($kid)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 412 |  |  |                 throw new UnexpectedValueException('"kid" empty, unable to lookup correct key'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 413 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 414 |  |  |             if (!isset($keyOrKeyArray[$kid])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 415 |  |  |                 throw new UnexpectedValueException('"kid" invalid, unable to lookup correct key'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 416 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 417 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 418 |  |  |             $key = $keyOrKeyArray[$kid]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 419 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 420 |  |  |             if ($key instanceof Key) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 421 |  |  |                 return array($key->getKeyMaterial(), $key->getAlgorithm()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 422 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 423 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 424 |  |  |             return array($key, null); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 425 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 426 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 427 |  |  |         throw new UnexpectedValueException( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 428 |  |  |             '$keyOrKeyArray must be a string|resource key, an array of string|resource keys, ' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 429 |  |  |             . 'an instance of Firebase\JWT\Key key or an array of Firebase\JWT\Key keys' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 430 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 431 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 432 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 433 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 434 |  |  |      * @param string $left | 
            
                                                                                                            
                            
            
                                    
            
            
                | 435 |  |  |      * @param string $right | 
            
                                                                                                            
                            
            
                                    
            
            
                | 436 |  |  |      * @return bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 437 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 438 |  |  |     public static function constantTimeEquals($left, $right) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 439 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 440 |  |  |         if (\function_exists('hash_equals')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 441 |  |  |             return \hash_equals($left, $right); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 442 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 443 |  |  |         $len = \min(static::safeStrlen($left), static::safeStrlen($right)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 444 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 445 |  |  |         $status = 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 446 |  |  |         for ($i = 0; $i < $len; $i++) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 447 |  |  |             $status |= (\ord($left[$i]) ^ \ord($right[$i])); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 448 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 449 |  |  |         $status |= (static::safeStrlen($left) ^ static::safeStrlen($right)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 450 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 451 |  |  |         return ($status === 0); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 452 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 453 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 454 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 455 |  |  |      * Helper method to create a JSON error. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 456 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 457 |  |  |      * @param int $errno An error number from json_last_error() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 458 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 459 |  |  |      * @return void | 
            
                                                                                                            
                            
            
                                    
            
            
                | 460 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 461 |  |  |     private static function handleJsonError($errno) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 462 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 463 |  |  |         $messages = array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 464 |  |  |             JSON_ERROR_DEPTH => 'Maximum stack depth exceeded', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 465 |  |  |             JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 466 |  |  |             JSON_ERROR_CTRL_CHAR => 'Unexpected control character found', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 467 |  |  |             JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 468 |  |  |             JSON_ERROR_UTF8 => 'Malformed UTF-8 characters' //PHP >= 5.3.3 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 469 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 470 |  |  |         throw new DomainException( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 471 |  |  |             isset($messages[$errno]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 472 |  |  |             ? $messages[$errno] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 473 |  |  |             : 'Unknown JSON error: ' . $errno | 
            
                                                                                                            
                            
            
                                    
            
            
                | 474 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 475 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 476 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 477 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 478 |  |  |      * Get the number of bytes in cryptographic strings. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 479 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 480 |  |  |      * @param string $str | 
            
                                                                                                            
                            
            
                                    
            
            
                | 481 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 482 |  |  |      * @return int | 
            
                                                                                                            
                            
            
                                    
            
            
                | 483 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 484 |  |  |     private static function safeStrlen($str) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 485 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 486 |  |  |         if (\function_exists('mb_strlen')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 487 |  |  |             return \mb_strlen($str, '8bit'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 488 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 489 |  |  |         return \strlen($str); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 490 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 491 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 492 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 493 |  |  |      * Convert an ECDSA signature to an ASN.1 DER sequence | 
            
                                                                                                            
                            
            
                                    
            
            
                | 494 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 495 |  |  |      * @param   string $sig The ECDSA signature to convert | 
            
                                                                                                            
                            
            
                                    
            
            
                | 496 |  |  |      * @return  string The encoded DER object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 497 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 498 |  |  |     private static function signatureToDER($sig) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 499 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 500 |  |  |         // Separate the signature into r-value and s-value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 501 |  |  |         list($r, $s) = \str_split($sig, (int) (\strlen($sig) / 2)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 502 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 503 |  |  |         // Trim leading zeros | 
            
                                                                                                            
                            
            
                                    
            
            
                | 504 |  |  |         $r = \ltrim($r, "\x00"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 505 |  |  |         $s = \ltrim($s, "\x00"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 506 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 507 |  |  |         // Convert r-value and s-value from unsigned big-endian integers to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 508 |  |  |         // signed two's complement | 
            
                                                                                                            
                            
            
                                    
            
            
                | 509 |  |  |         if (\ord($r[0]) > 0x7f) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 510 |  |  |             $r = "\x00" . $r; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 511 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 512 |  |  |         if (\ord($s[0]) > 0x7f) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 513 |  |  |             $s = "\x00" . $s; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 514 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 515 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 516 |  |  |         return self::encodeDER( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 517 |  |  |             self::ASN1_SEQUENCE, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 518 |  |  |             self::encodeDER(self::ASN1_INTEGER, $r) . | 
            
                                                                                                            
                            
            
                                    
            
            
                | 519 |  |  |             self::encodeDER(self::ASN1_INTEGER, $s) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 520 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 521 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 522 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 523 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 524 |  |  |      * Encodes a value into a DER object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 525 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 526 |  |  |      * @param   int     $type DER tag | 
            
                                                                                                            
                            
            
                                    
            
            
                | 527 |  |  |      * @param   string  $value the value to encode | 
            
                                                                                                            
                            
            
                                    
            
            
                | 528 |  |  |      * @return  string  the encoded object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 529 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 530 |  |  |     private static function encodeDER($type, $value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 531 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 532 |  |  |         $tag_header = 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 533 |  |  |         if ($type === self::ASN1_SEQUENCE) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 534 |  |  |             $tag_header |= 0x20; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 535 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 536 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 537 |  |  |         // Type | 
            
                                                                                                            
                            
            
                                    
            
            
                | 538 |  |  |         $der = \chr($tag_header | $type); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 539 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 540 |  |  |         // Length | 
            
                                                                                                            
                            
            
                                    
            
            
                | 541 |  |  |         $der .= \chr(\strlen($value)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 542 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 543 |  |  |         return $der . $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 544 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 545 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 546 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 547 |  |  |      * Encodes signature from a DER object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 548 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 549 |  |  |      * @param   string  $der binary signature in DER format | 
            
                                                                                                            
                            
            
                                    
            
            
                | 550 |  |  |      * @param   int     $keySize the number of bits in the key | 
            
                                                                                                            
                            
            
                                    
            
            
                | 551 |  |  |      * @return  string  the signature | 
            
                                                                                                            
                            
            
                                    
            
            
                | 552 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 553 |  |  |     private static function signatureFromDER($der, $keySize) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 554 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 555 |  |  |         // OpenSSL returns the ECDSA signatures as a binary ASN.1 DER SEQUENCE | 
            
                                                                                                            
                            
            
                                    
            
            
                | 556 |  |  |         list($offset, $_) = self::readDER($der); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 557 |  |  |         list($offset, $r) = self::readDER($der, $offset); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 558 |  |  |         list($offset, $s) = self::readDER($der, $offset); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 559 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 560 |  |  |         // Convert r-value and s-value from signed two's compliment to unsigned | 
            
                                                                                                            
                            
            
                                    
            
            
                | 561 |  |  |         // big-endian integers | 
            
                                                                                                            
                            
            
                                    
            
            
                | 562 |  |  |         $r = \ltrim($r, "\x00"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 563 |  |  |         $s = \ltrim($s, "\x00"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 564 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 565 |  |  |         // Pad out r and s so that they are $keySize bits long | 
            
                                                                                                            
                            
            
                                    
            
            
                | 566 |  |  |         $r = \str_pad($r, $keySize / 8, "\x00", STR_PAD_LEFT); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 567 |  |  |         $s = \str_pad($s, $keySize / 8, "\x00", STR_PAD_LEFT); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 568 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 569 |  |  |         return $r . $s; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 570 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 571 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 572 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 573 |  |  |      * Reads binary DER-encoded data and decodes into a single object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 574 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 575 |  |  |      * @param string $der the binary data in DER format | 
            
                                                                                                            
                            
            
                                    
            
            
                | 576 |  |  |      * @param int $offset the offset of the data stream containing the object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 577 |  |  |      * to decode | 
            
                                                                                                            
                            
            
                                    
            
            
                | 578 |  |  |      * @return array [$offset, $data] the new offset and the decoded object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 579 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 580 |  |  |     private static function readDER($der, $offset = 0) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 581 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 582 |  |  |         $pos = $offset; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 583 |  |  |         $size = \strlen($der); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 584 |  |  |         $constructed = (\ord($der[$pos]) >> 5) & 0x01; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 585 |  |  |         $type = \ord($der[$pos++]) & 0x1f; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 586 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 587 |  |  |         // Length | 
            
                                                                                                            
                            
            
                                    
            
            
                | 588 |  |  |         $len = \ord($der[$pos++]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 589 |  |  |         if ($len & 0x80) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 590 |  |  |             $n = $len & 0x1f; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 591 |  |  |             $len = 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 592 |  |  |             while ($n-- && $pos < $size) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 593 |  |  |                 $len = ($len << 8) | \ord($der[$pos++]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 594 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 595 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 596 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 597 |  |  |         // Value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 598 |  |  |         if ($type == self::ASN1_BIT_STRING) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 599 |  |  |             $pos++; // Skip the first contents octet (padding indicator) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 600 |  |  |             $data = \substr($der, $pos, $len - 1); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 601 |  |  |             $pos += $len - 1; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 602 |  |  |         } elseif (!$constructed) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 603 |  |  |             $data = \substr($der, $pos, $len); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 604 |  |  |             $pos += $len; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 605 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 606 |  |  |             $data = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 607 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 608 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 609 |  |  |         return array($pos, $data); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 610 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 611 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 612 |  |  |  | 
            
                        
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths