<commit_before><?php
namespace kuralab\jose;

/**
 * Json Web Token Class
 */
class JsonWebToken
{
  private static $supportedAlgorithm = array(
    'HS256' => 'sha256',
    'HS382' => 'sha384',
    'HS512' => 'sha512',
  );

  private $header;
  private $payload;
  private $signature;

  private $headerArray  = array();
  private $payloadArray = array();

  public function __construct( $idToken = null )
  {
    if ( !is_null( $idToken ) && is_string( $idToken ) ) {
      $explodedIdToken = explode( '.', $idToken );
      if ( count( $explodedIdToken ) == 3 ) {
        $this->header    = $explodedIdToken[0];
        $this->payload   = $explodedIdToken[1];
        $this->signature = $explodedIdToken[2];
        $this->headerArray  = json_decode( base64_decode( $this->header ), true );
        if ( $this->headerArray == null ) {
          throw new \UnexpectedValueException( 'unexpected header' );
        }
        $this->payloadArray = json_decode( base64_decode( $this->payload ), true );
        if( $this->payloadArray == null ) {
          throw new \UnexpectedValueException( 'unexpected payload' );
        }
      }
    }
  }

  public function encode( $algorithm, $issuer, $audience, $expiration, $nonce, $secret )
  {
    if ( !array_key_exists( $algorithm, self::$supportedAlgorithm ) ) {
      throw new \Exception( 'unsupported algorithm' );
    }
    $headerArray = array(
      'alg' => $algorithm,
      'typ' => 'JWT'
    );
    $payloadArray = array(
      'iss'   => $issuer,
      'aud'   => $audience,
      'exp'   => $expiration,
      'iat'   => $this->getCurrentTime(),
      'nonce' => $nonce
    );
    $header  = base64_encode( json_encode( $headerArray ) );
    $payload = base64_encode( json_encode( $payloadArray ) );
    $signature = $this->generateSignature(
      $header,
      $payload,
      $algorithm,
      $secret
    );
    return implode( '.', array( $header, $payload, $signature ) );
  }

  public function decode()
  {
    if ( is_null( $this->headerArray ) ||
      is_null( $this->payloadArray ) || is_null( $this->signature ) ) {
      return null;
    }
    $result = array(
      'header'    => $this->headerArray,
      'payload'   => $this->payloadArray,
      'signature' => $this->signature,
    );
    return $result;
  }

  public function getHeader( $key = null )
  {
    if ( is_string( $key ) && array_key_exists( $key, $this->headerArray ) ) {
      return $this->headerArray[$key];
    }
    return $this->headerArray;
  }

  public function getPayload( $key = null )
  {
    if ( is_string( $key ) && array_key_exists( $key, $this->payloadArray ) ) {
      return $this->payloadArray[$key];
    }
    return $this->payloadArray;
  }

  public function verify( $issuer, $audience, $nonce, $secret, $iatLimit = 600 )
  {
    /**
     * check header
     */
    if ( $this->headerArray['typ'] != 'JWT' ) {
      throw new \Exception( 'unexpected type' );
    }

    if ( $this->headerArray['alg'] == null ) {
      throw new \Exception( 'algorithm is null' );
    }

    /**
     * check payload
     */
    // iss
    if ( $this->payloadArray['iss'] != $issuer ) {
      throw new \Exception( 'invalid iss' );
    }

    // aud
    if ( $this->payloadArray['aud'] != $audience ) {
      throw new \Exception( 'invalid aud' );
    }

    // exp
    if ( $this->payloadArray['exp'] < $this->getCurrentTime() ) {
      throw new \Exception( 'expired id token' );
    }

    // iat
    if ( $this->getCurrentTime() - $this->payloadArray['iat'] > $iatLimit ) {
      throw new \Exception( 'expired iat' );
    }

    // nonce
    if ( $this->payloadArray['nonce'] != $nonce ) {
      throw new \Exception( 'invalid nonce' );
    }

    /**
     * check signature
     */
    $sig = $this->generateSignature(
      $this->header,
      $this->payload,
      $this->headerArray['alg'],
      $secret
    );
    if ( $this->signature != $sig ) {
      throw new \Exception( 'signature error' );
    }
  }

  private function generateSignature( $header, $payload, $algorithm, $secret )
  {
    if ( !array_key_exists( $algorithm, self::$supportedAlgorithm ) ) {
      throw new Exception( 'unsupported algorithm' );
    }

    $hash = hash_hmac(
      self::$supportedAlgorithm[$algorithm],
      $header . '.' . $payload,
      $secret,
      true
    );

    $encodedHash = base64_encode( $hash );
    $signature = str_replace( array( '=' ), array( '' ), 
    str_replace( array( '+', '/' ), array( '-', '_' ), $encodedHash ) );

    return $signature;
  }

  public function getCurrentTime()
  {
    return time();
  }
}<commit_msg>supported rsa algorithm.<commit_after><?php
namespace kuralab\jose;

/**
 * Json Web Token Class
 */
class JsonWebToken
{
  private static $supportedAlgorithm = array(
    'HS256' => 'sha256',
    'HS382' => 'sha384',
    'HS512' => 'sha512',
    'RS256' => 'sha256',
    'RS382' => 'sha384',
    'RS512' => 'sha512',
  );

  private $header;
  private $payload;
  private $signature;

  private $headerArray  = array();
  private $payloadArray = array();

  public function __construct( $idToken = null )
  {
    if ( !is_null( $idToken ) && is_string( $idToken ) ) {
      $explodedIdToken = explode( '.', $idToken );
      if ( count( $explodedIdToken ) == 3 ) {
        $this->header    = $explodedIdToken[0];
        $this->payload   = $explodedIdToken[1];
        $this->signature = $explodedIdToken[2];
        $this->headerArray  = json_decode( base64_decode( $this->header ), true );
        if ( $this->headerArray == null ) {
          throw new \UnexpectedValueException( 'unexpected header' );
        }
        $this->payloadArray = json_decode( base64_decode( $this->payload ), true );
        if( $this->payloadArray == null ) {
          throw new \UnexpectedValueException( 'unexpected payload' );
        }
      }
    }
  }

  public function encode( $algorithm, $issuer, $audience, $expiration, $nonce, $secret )
  {
    if ( !array_key_exists( $algorithm, self::$supportedAlgorithm ) ) {
      throw new \Exception( 'unsupported algorithm' );
    }
    $headerArray = array(
      'alg' => $algorithm,
      'typ' => 'JWT'
    );
    $payloadArray = array(
      'iss'   => $issuer,
      'aud'   => $audience,
      'exp'   => $expiration,
      'iat'   => $this->getCurrentTime(),
      'nonce' => $nonce
    );
    $header  = base64_encode( json_encode( $headerArray ) );
    $payload = base64_encode( json_encode( $payloadArray ) );
    $signature = $this->generateSignature(
      $header,
      $payload,
      $algorithm,
      $secret
    );
    return implode( '.', array( $header, $payload, $signature ) );
  }

  public function decode()
  {
    if ( is_null( $this->headerArray ) ||
      is_null( $this->payloadArray ) || is_null( $this->signature ) ) {
      return null;
    }
    $result = array(
      'header'    => $this->headerArray,
      'payload'   => $this->payloadArray,
      'signature' => $this->signature,
    );
    return $result;
  }

  public function getHeader( $key = null )
  {
    if ( is_string( $key ) && array_key_exists( $key, $this->headerArray ) ) {
      return $this->headerArray[$key];
    }
    return $this->headerArray;
  }

  public function getPayload( $key = null )
  {
    if ( is_string( $key ) && array_key_exists( $key, $this->payloadArray ) ) {
      return $this->payloadArray[$key];
    }
    return $this->payloadArray;
  }

  public function verify( $issuer, $audience, $nonce, $secret, $iatLimit = 600 )
  {
    /**
     * check header
     */
    if ( $this->headerArray['typ'] != 'JWT' ) {
      throw new \Exception( 'unexpected type' );
    }

    if ( $this->headerArray['alg'] == null ) {
      throw new \Exception( 'algorithm is null' );
    }

    /**
     * check payload
     */
    // iss
    if ( $this->payloadArray['iss'] != $issuer ) {
      throw new \Exception( 'invalid iss' );
    }

    // aud
    if ( $this->payloadArray['aud'] != $audience ) {
      throw new \Exception( 'invalid aud' );
    }

    // exp
    if ( $this->payloadArray['exp'] < $this->getCurrentTime() ) {
      throw new \Exception( 'expired id token' );
    }

    // iat
    if ( $this->getCurrentTime() - $this->payloadArray['iat'] > $iatLimit ) {
      throw new \Exception( 'expired iat' );
    }

    // nonce
    if ( $this->payloadArray['nonce'] != $nonce ) {
      throw new \Exception( 'invalid nonce' );
    }

    /**
     * check signature
     */
    if ( preg_match( '/^HS/', $this->headerArray['alg'] ) ) {
      $sig = $this->generateSignature(
        $this->header,
        $this->payload,
        $this->headerArray['alg'],
        $secret
      );
      if ( $this->signature != $sig ) {
        throw new \Exception( 'signature error' );
      }
    } else if ( preg_match( '/^RS/', $this->headerArray['alg'] ) ) {
      $signature = str_replace(
        array( '-', '_' ),
        array( '+', '/' ),
        $this->signature
      );
      $publicKey = openssl_pkey_get_public( $secret );
      $result = openssl_verify(
        $this->header . '.' . $this->payload,
        base64_decode( $signature ),
        $publicKey,
        self::$supportedAlgorithm[$this->headerArray['alg']]
      );

      if ( $result != 1 ) {
        throw new \Exception( 'signature error' );
      }
    } else {
      throw new \Exception( 'unsupported algorithm' );
    }
  }

  private function generateSignature( $header, $payload, $algorithm, $secret )
  {
    if ( !array_key_exists( $algorithm, self::$supportedAlgorithm ) ) {
      throw new \Exception( 'unsupported algorithm' );
    }

    if ( preg_match( '/^HS/', $algorithm ) ) {
      $signature = hash_hmac(
        self::$supportedAlgorithm[$algorithm],
        $header . '.' . $payload,
        $secret,
        true
      );
    } else if ( preg_match( '/^RS/', $algorithm ) ) {
      $signature = $this->encryptRsa(
        self::$supportedAlgorithm[$algorithm],
        $header . '.' . $payload,
        $secret
      );
    } else {
      throw new \Exception( 'unsupported algorithm' );
    }

    $encodedHash = base64_encode( $signature );
    $signature = str_replace( array( '=' ), array( '' ), 
    str_replace( array( '+', '/' ), array( '-', '_' ), $encodedHash ) );
    
    return $signature;
  }

  private function encryptRsa( $algorithm, $data, $secret )
  {
    $privateKeyId = openssl_pkey_get_private( $secret );
    openssl_sign( $data, $signature, $privateKeyId, $algorithm );
    openssl_free_key( $privateKeyId );

    return $signature;
  }

  public function getCurrentTime()
  {
    return time();
  }
}
{'fraction_non_alphanumeric': 0.16764372163388805, 'fraction_numerical': 0.008604387291981846, 'mean_word_length': 2.4218699450016175, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 115, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3908279', 'n_tokens_mistral': 3461, 'n_tokens_neox': 3371, 'n_words': 730}