ヤミRoot VoidGate
User / IP
:
216.73.216.81
Host / Server
:
146.88.233.70 / dev.loger.cm
System
:
Linux hybrid1120.fr.ns.planethoster.net 3.10.0-957.21.2.el7.x86_64 #1 SMP Wed Jun 5 14:26:44 UTC 2019 x86_64
Command
|
Upload
|
Create
Mass Deface
|
Jumping
|
Symlink
|
Reverse Shell
Ping
|
Port Scan
|
DNS Lookup
|
Whois
|
Header
|
cURL
:
/
home
/
logercm
/
dev.loger.cm
/
fixtures
/
assert
/
Viewing: jose.tar
src/Namshi/JOSE/Base64/Base64Encoder.php 0000644 00000000610 15120137110 0013357 0 ustar 00 <?php namespace Namshi\JOSE\Base64; class Base64Encoder implements Encoder { /** * @param string $data * * @return string */ public function encode($data) { return base64_encode($data); } /** * @param string $data * * @return string */ public function decode($data) { return base64_decode($data); } } src/Namshi/JOSE/Base64/Base64UrlSafeEncoder.php 0000644 00000000461 15120137110 0014645 0 ustar 00 <?php namespace Namshi\JOSE\Base64; class Base64UrlSafeEncoder implements Encoder { public function encode($data) { return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); } public function decode($data) { return base64_decode(strtr($data, '-_', '+/')); } } src/Namshi/JOSE/Base64/Encoder.php 0000644 00000000423 15120137110 0012414 0 ustar 00 <?php namespace Namshi\JOSE\Base64; interface Encoder { /** * @param string $data * * @return string */ public function encode($data); /** * @param string $data * * @return string */ public function decode($data); } src/Namshi/JOSE/Signer/OpenSSL/ECDSA.php 0000644 00000006362 15120137110 0013352 0 ustar 00 <?php namespace Namshi\JOSE\Signer\OpenSSL; use phpseclib\File\ASN1; /** * Class responsible to sign inputs with the a ECDSA algorithm, after hashing it. */ abstract class ECDSA extends PublicKey { public function __construct() { if (version_compare(PHP_VERSION, '7.0.0-dev') >= 0) { throw new \InvalidArgumentException("phpseclib 1.0.0(LTS), even the latest 2.0.0, doesn't support PHP7 yet"); } } /** * {@inheritdoc} */ protected function supportsKey($key) { if (false === parent::supportsKey($key)) { return false; } // openssl_sign with EC keys was introduced in this PHP release $minVersions = array( '5.4' => '5.4.26', '5.5' => '5.5.10', '5.6' => '5.6.0', ); if (isset($minVersions[PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION]) && version_compare(PHP_VERSION, $minVersions[PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION], '<')) { return false; } $keyDetails = openssl_pkey_get_details($key); if (0 === preg_match('/-----BEGIN PUBLIC KEY-----([^-]+)-----END PUBLIC KEY-----/', $keyDetails['key'], $matches)) { return false; } $publicKey = trim($matches[1]); $asn1 = new ASN1(); /* * http://tools.ietf.org/html/rfc3279#section-2.2.3 * AlgorithmIdentifier ::= SEQUENCE { * algorithm OBJECT IDENTIFIER, * parameters ANY DEFINED BY algorithm OPTIONAL * } * For ECDSA Signature Algorithm: * algorithm: ansi-X9-62 => 1.2.840.10045.2.1 * parameters: id-ecSigType => 1.2.840.10045.x.y.z * */ $asnAlgorithmIdentifier = array( 'type' => ASN1::TYPE_SEQUENCE, 'children' => array( 'ansi-X9-62' => array( 'type' => ASN1::TYPE_OBJECT_IDENTIFIER, ), 'id-ecSigType' => array( 'type' => ASN1::TYPE_OBJECT_IDENTIFIER, ), ), ); /* * http://tools.ietf.org/html/rfc5280#section-4.1 * SubjectPublicKeyInfo ::= SEQUENCE { * algorithm AlgorithmIdentifier, * subjectPublicKey BIT STRING * } */ $asnSubjectPublicKeyInfo = array( 'type' => ASN1::TYPE_SEQUENCE, 'children' => array( 'algorithm' => $asnAlgorithmIdentifier, 'subjectPublicKey' => array( 'type' => ASN1::TYPE_BIT_STRING, ), ), ); $decoded = $asn1->decodeBER(base64_decode($publicKey)); $mappedDetails = $asn1->asn1map($decoded[0], $asnSubjectPublicKeyInfo); return isset($mappedDetails['algorithm']['id-ecSigType']) ? $this->getSupportedECDSACurve() === $mappedDetails['algorithm']['id-ecSigType'] : false; } /** * {@inheritdoc} */ protected function getSupportedPrivateKeyType() { return defined('OPENSSL_KEYTYPE_EC') ? OPENSSL_KEYTYPE_EC : false; } /** * Returns the ECDSA curve supported in this signer. * * @return string */ abstract protected function getSupportedECDSACurve(); } src/Namshi/JOSE/Signer/OpenSSL/ES256.php 0000644 00000000632 15120137110 0013271 0 ustar 00 <?php namespace Namshi\JOSE\Signer\OpenSSL; /** * Class responsible to sign inputs with the ECDSA algorithm, after hashing it. */ class ES256 extends ECDSA { public function getHashingAlgorithm() { return version_compare(phpversion(), '5.4.8', '<') ? 'SHA256' : OPENSSL_ALGO_SHA256; } protected function getSupportedECDSACurve() { return '1.2.840.10045.3.1.7'; } } src/Namshi/JOSE/Signer/OpenSSL/ES384.php 0000644 00000000623 15120137110 0013273 0 ustar 00 <?php namespace Namshi\JOSE\Signer\OpenSSL; /** * Class responsible to sign inputs with the ECDSA algorithm, after hashing it. */ class ES384 extends ECDSA { public function getHashingAlgorithm() { return version_compare(phpversion(), '5.4.8', '<') ? 'SHA384' : OPENSSL_ALGO_SHA384; } protected function getSupportedECDSACurve() { return '1.3.132.0.34'; } } src/Namshi/JOSE/Signer/OpenSSL/ES512.php 0000644 00000000623 15120137110 0013264 0 ustar 00 <?php namespace Namshi\JOSE\Signer\OpenSSL; /** * Class responsible to sign inputs with the ECDSA algorithm, after hashing it. */ class ES512 extends ECDSA { public function getHashingAlgorithm() { return version_compare(phpversion(), '5.4.8', '<') ? 'SHA512' : OPENSSL_ALGO_SHA512; } protected function getSupportedECDSACurve() { return '1.3.132.0.35'; } } src/Namshi/JOSE/Signer/OpenSSL/HMAC.php 0000644 00000002546 15120137110 0013243 0 ustar 00 <?php namespace Namshi\JOSE\Signer\OpenSSL; use Namshi\JOSE\Signer\SignerInterface; /** * This class is the base of all HMAC Signers. */ abstract class HMAC implements SignerInterface { /** * {@inheritdoc} */ public function sign($input, $key) { return hash_hmac($this->getHashingAlgorithm(), $input, (string) $key, true); } /** * To prevent timing attacks we are using PHP 5.6 native function hash_equals, * in case of PHP < 5.6 a timing safe equals comparison function. * * more info here: * http://blog.ircmaxell.com/2014/11/its-all-about-time.html * * * {@inheritdoc} */ public function verify($key, $signature, $input) { $signedInput = $this->sign($input, $key); return $this->timingSafeEquals($signedInput, $signature); } /** * A timing safe equals comparison. * * @param string $signature the internal signature to be checked * @param string $signedInput The signed input submitted value * * @return bool true if the two strings are identical. */ public function timingSafeEquals($known, $input) { return hash_equals($known, $input); } /** * Returns the hashing algorithm used in this signer. * * @return string */ abstract public function getHashingAlgorithm(); } src/Namshi/JOSE/Signer/OpenSSL/HS256.php 0000644 00000000300 15120137110 0013264 0 ustar 00 <?php namespace Namshi\JOSE\Signer\OpenSSL; /** * HMAC Signer using SHA-256. */ class HS256 extends HMAC { public function getHashingAlgorithm() { return 'sha256'; } } src/Namshi/JOSE/Signer/OpenSSL/HS384.php 0000644 00000000300 15120137110 0013266 0 ustar 00 <?php namespace Namshi\JOSE\Signer\OpenSSL; /** * HMAC Signer using SHA-384. */ class HS384 extends HMAC { public function getHashingAlgorithm() { return 'sha384'; } } src/Namshi/JOSE/Signer/OpenSSL/HS512.php 0000644 00000000300 15120137110 0013257 0 ustar 00 <?php namespace Namshi\JOSE\Signer\OpenSSL; /** * HMAC Signer using SHA-512. */ class HS512 extends HMAC { public function getHashingAlgorithm() { return 'sha512'; } } src/Namshi/JOSE/Signer/OpenSSL/None.php 0000644 00000000615 15120137110 0013425 0 ustar 00 <?php namespace Namshi\JOSE\Signer\OpenSSL; use Namshi\JOSE\Signer\SignerInterface; /** * None Signer. */ class None implements SignerInterface { /** * {@inheritdoc} */ public function sign($input, $key) { return ''; } /** * {@inheritdoc} */ public function verify($key, $signature, $input) { return $signature === ''; } } src/Namshi/JOSE/Signer/OpenSSL/PublicKey.php 0000644 00000005112 15120137110 0014412 0 ustar 00 <?php namespace Namshi\JOSE\Signer\OpenSSL; use InvalidArgumentException; use Namshi\JOSE\Signer\SignerInterface; use RuntimeException; /** * Class responsible to sign inputs with the a public key algorithm, after hashing it. */ abstract class PublicKey implements SignerInterface { /** * {@inheritdoc} */ public function sign($input, $key, $password = null) { $keyResource = $this->getKeyResource($key, $password); if (!$this->supportsKey($keyResource)) { throw new InvalidArgumentException('Invalid key supplied.'); } $signature = null; openssl_sign($input, $signature, $keyResource, $this->getHashingAlgorithm()); return $signature; } /** * {@inheritdoc} */ public function verify($key, $signature, $input) { $keyResource = $this->getKeyResource($key); if (!$this->supportsKey($keyResource)) { throw new InvalidArgumentException('Invalid key supplied.'); } $result = openssl_verify($input, $signature, $keyResource, $this->getHashingAlgorithm()); if ($result === -1) { throw new RuntimeException('Unknown error during verification.'); } return (bool) $result; } /** * Converts a string representation of a key into an OpenSSL resource. * * @param string|resource $key * @param string $password * * @return resource OpenSSL key resource */ protected function getKeyResource($key, $password = null) { if (is_resource($key)) { return $key; } $resource = openssl_pkey_get_public($key) ?: openssl_pkey_get_private($key, $password); if ($resource === false) { throw new RuntimeException('Could not read key resource: ' . openssl_error_string()); } return $resource; } /** * Check if the key is supported by this signer. * * @param resource $key Public or private key * * @return bool */ protected function supportsKey($key) { // OpenSSL 0.9.8+ $keyDetails = openssl_pkey_get_details($key); return isset($keyDetails['type']) ? $this->getSupportedPrivateKeyType() === $keyDetails['type'] : false; } /** * Returns the hashing algorithm used in this signer. * * @return string */ abstract protected function getHashingAlgorithm(); /** * Returns the private key type supported in this signer. * * @return string */ abstract protected function getSupportedPrivateKeyType(); } src/Namshi/JOSE/Signer/OpenSSL/RS256.php 0000644 00000000463 15120137110 0013310 0 ustar 00 <?php namespace Namshi\JOSE\Signer\OpenSSL; /** * Class responsible to sign inputs with the RSA algorithm, after hashing it. */ class RS256 extends RSA { public function getHashingAlgorithm() { return version_compare(phpversion(), '5.4.8', '<') ? 'SHA256' : OPENSSL_ALGO_SHA256; } } src/Namshi/JOSE/Signer/OpenSSL/RS384.php 0000644 00000000463 15120137110 0013312 0 ustar 00 <?php namespace Namshi\JOSE\Signer\OpenSSL; /** * Class responsible to sign inputs with the RSA algorithm, after hashing it. */ class RS384 extends RSA { public function getHashingAlgorithm() { return version_compare(phpversion(), '5.4.8', '<') ? 'SHA384' : OPENSSL_ALGO_SHA384; } } src/Namshi/JOSE/Signer/OpenSSL/RS512.php 0000644 00000000463 15120137110 0013303 0 ustar 00 <?php namespace Namshi\JOSE\Signer\OpenSSL; /** * Class responsible to sign inputs with the RSA algorithm, after hashing it. */ class RS512 extends RSA { public function getHashingAlgorithm() { return version_compare(phpversion(), '5.4.8', '<') ? 'SHA512' : OPENSSL_ALGO_SHA512; } } src/Namshi/JOSE/Signer/OpenSSL/RSA.php 0000644 00000000541 15120137110 0013151 0 ustar 00 <?php namespace Namshi\JOSE\Signer\OpenSSL; /** * Class responsible to sign inputs with the a RSA algorithm, after hashing it. */ abstract class RSA extends PublicKey { /** * {@inheritdoc} */ protected function getSupportedPrivateKeyType() { return defined('OPENSSL_KEYTYPE_RSA') ? OPENSSL_KEYTYPE_RSA : false; } } src/Namshi/JOSE/Signer/SecLib/PublicKey.php 0000644 00000001642 15120137110 0014274 0 ustar 00 <?php namespace Namshi\JOSE\Signer\SecLib; use InvalidArgumentException; use Namshi\JOSE\Signer\SignerInterface; abstract class PublicKey implements SignerInterface { protected $encryptionAlgorithm; /** * {@inheritdoc} */ public function sign($input, $key, $password = null) { if ($password) { $this->encryptionAlgorithm->setPassword($password); } if (!$this->encryptionAlgorithm->loadKey($key)) { throw new InvalidArgumentException('Invalid key supplied.'); } return $this->encryptionAlgorithm->sign($input); } /** * {@inheritdoc} */ public function verify($key, $signature, $input) { if (!$this->encryptionAlgorithm->loadKey($key)) { throw new InvalidArgumentException('Invalid key supplied.'); } return $this->encryptionAlgorithm->verify($input, $signature); } } src/Namshi/JOSE/Signer/SecLib/RS256.php 0000644 00000000407 15120137110 0013164 0 ustar 00 <?php namespace Namshi\JOSE\Signer\SecLib; class RS256 extends RSA { public function __construct() { parent::__construct(); $this->encryptionAlgorithm->setHash('sha256'); $this->encryptionAlgorithm->setMGFHash('sha256'); } } src/Namshi/JOSE/Signer/SecLib/RS384.php 0000644 00000000407 15120137110 0013166 0 ustar 00 <?php namespace Namshi\JOSE\Signer\SecLib; class RS384 extends RSA { public function __construct() { parent::__construct(); $this->encryptionAlgorithm->setHash('sha384'); $this->encryptionAlgorithm->setMGFHash('sha384'); } } src/Namshi/JOSE/Signer/SecLib/RS512.php 0000644 00000000407 15120137110 0013157 0 ustar 00 <?php namespace Namshi\JOSE\Signer\SecLib; class RS512 extends RSA { public function __construct() { parent::__construct(); $this->encryptionAlgorithm->setHash('sha512'); $this->encryptionAlgorithm->setMGFHash('sha512'); } } src/Namshi/JOSE/Signer/SecLib/RSA.php 0000644 00000000326 15120137110 0013030 0 ustar 00 <?php namespace Namshi\JOSE\Signer\SecLib; use phpseclib\Crypt\RSA as CryptRSA; class RSA extends PublicKey { public function __construct() { $this->encryptionAlgorithm = new CryptRSA(); } } src/Namshi/JOSE/Signer/SignerInterface.php 0000644 00000001151 15120137110 0014307 0 ustar 00 <?php namespace Namshi\JOSE\Signer; interface SignerInterface { /** * Signs the $input with the $key, after hashing it. * * @param string $input * @param resource|string $key * * @return string|null */ public function sign($input, $key); /** * Verifies that the input correspond to the $signature decrypted with the * given public $key. * * @param resource|string $key * @param string $signature * @param string $input * * @return bool */ public function verify($key, $signature, $input); } src/Namshi/JOSE/JWS.php 0000644 00000015330 15120137110 0010457 0 ustar 00 <?php namespace Namshi\JOSE; use InvalidArgumentException; use Namshi\JOSE\Base64\Base64Encoder; use Namshi\JOSE\Base64\Base64UrlSafeEncoder; use Namshi\JOSE\Base64\Encoder; use Namshi\JOSE\Signer\SignerInterface; /** * Class representing a JSON Web Signature. */ class JWS extends JWT { protected $signature; protected $isSigned = false; protected $originalToken; protected $encodedSignature; protected $encryptionEngine; protected $supportedEncryptionEngines = array('OpenSSL', 'SecLib'); /** * Constructor. * * @param array $header An associative array of headers. The value can be any type accepted by json_encode or a JSON serializable object * * @see http://php.net/manual/en/function.json-encode.php * @see http://php.net/manual/en/jsonserializable.jsonserialize.php * @see https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41#section-4 * * @param string $encryptionEngine * } */ public function __construct($header = array(), $encryptionEngine = 'OpenSSL') { if (!in_array($encryptionEngine, $this->supportedEncryptionEngines)) { throw new InvalidArgumentException(sprintf('Encryption engine %s is not supported', $encryptionEngine)); } if ('SecLib' === $encryptionEngine && version_compare(PHP_VERSION, '7.0.0-dev') >= 0) { throw new InvalidArgumentException("phpseclib 1.0.0(LTS), even the latest 2.0.0, doesn't support PHP7 yet"); } $this->encryptionEngine = $encryptionEngine; parent::__construct(array(), $header); } /** * Signs the JWS signininput. * * @param resource|string $key * @param optional string $password * * @return string */ public function sign($key, $password = null) { $this->signature = $this->getSigner()->sign($this->generateSigninInput(), $key, $password); $this->isSigned = true; return $this->signature; } /** * Returns the signature representation of the JWS. * * @return string */ public function getSignature() { if ($this->isSigned()) { return $this->signature; } return; } /** * Checks whether the JSW has already been signed. * * @return bool */ public function isSigned() { return (bool) $this->isSigned; } /** * Returns the string representing the JWT. * * @return string */ public function getTokenString() { $signinInput = $this->generateSigninInput(); return sprintf('%s.%s', $signinInput, $this->encoder->encode($this->getSignature())); } /** * Creates an instance of a JWS from a JWT. * * @param string $jwsTokenString * @param bool $allowUnsecure * @param Encoder $encoder * @param string $encryptionEngine * * @return JWS * * @throws \InvalidArgumentException */ public static function load($jwsTokenString, $allowUnsecure = false, Encoder $encoder = null, $encryptionEngine = 'OpenSSL') { if ($encoder === null) { $encoder = strpbrk($jwsTokenString, '+/=') ? new Base64Encoder() : new Base64UrlSafeEncoder(); } $parts = explode('.', $jwsTokenString); if (count($parts) === 3) { $header = json_decode($encoder->decode($parts[0]), true); $payload = json_decode($encoder->decode($parts[1]), true); if (is_array($header) && is_array($payload)) { if (strtolower($header['alg']) === 'none' && !$allowUnsecure) { throw new InvalidArgumentException(sprintf('The token "%s" cannot be validated in a secure context, as it uses the unallowed "none" algorithm', $jwsTokenString)); } $jws = new static($header, $encryptionEngine); $jws->setEncoder($encoder) ->setHeader($header) ->setPayload($payload) ->setOriginalToken($jwsTokenString) ->setEncodedSignature($parts[2]); return $jws; } } throw new InvalidArgumentException(sprintf('The token "%s" is an invalid JWS', $jwsTokenString)); } /** * Verifies that the internal signin input corresponds to the encoded * signature previously stored (@see JWS::load). * * @param resource|string $key * @param string $algo The algorithms this JWS should be signed with. Use it if you want to restrict which algorithms you want to allow to be validated. * * @return bool */ public function verify($key, $algo = null) { if (empty($key) || ($algo && $this->header['alg'] !== $algo)) { return false; } $decodedSignature = $this->encoder->decode($this->getEncodedSignature()); $signinInput = $this->getSigninInput(); return $this->getSigner()->verify($key, $decodedSignature, $signinInput); } /** * Get the original token signin input if it exists, otherwise generate the * signin input for the current JWS * * @return string */ private function getSigninInput() { $parts = explode('.', $this->originalToken); if (count($parts) >= 2) { return sprintf('%s.%s', $parts[0], $parts[1]); } return $this->generateSigninInput(); } /** * Sets the original base64 encoded token. * * @param string $originalToken * * @return JWS */ private function setOriginalToken($originalToken) { $this->originalToken = $originalToken; return $this; } /** * Returns the base64 encoded signature. * * @return string */ public function getEncodedSignature() { return $this->encodedSignature; } /** * Sets the base64 encoded signature. * * @param string $encodedSignature * * @return JWS */ public function setEncodedSignature($encodedSignature) { $this->encodedSignature = $encodedSignature; return $this; } /** * Returns the signer responsible to encrypting / decrypting this JWS. * * @return SignerInterface * * @throws \InvalidArgumentException */ protected function getSigner() { $signerClass = sprintf('Namshi\\JOSE\\Signer\\%s\\%s', $this->encryptionEngine, $this->header['alg']); if (class_exists($signerClass)) { return new $signerClass(); } throw new InvalidArgumentException( sprintf("The algorithm '%s' is not supported for %s", $this->header['alg'], $this->encryptionEngine)); } } src/Namshi/JOSE/JWT.php 0000644 00000003675 15120137110 0010471 0 ustar 00 <?php namespace Namshi\JOSE; use Namshi\JOSE\Base64\Base64UrlSafeEncoder; use Namshi\JOSE\Base64\Encoder; /** * Class representing a JSON Web Token. */ class JWT { /** * @var array */ protected $payload; /** * @var array */ protected $header; /** * @var Encoder */ protected $encoder; /** * Constructor. * * @param array $payload * @param array $header */ public function __construct(array $payload, array $header) { $this->setPayload($payload); $this->setHeader($header); $this->setEncoder(new Base64UrlSafeEncoder()); } /** * @param Encoder $encoder */ public function setEncoder(Encoder $encoder) { $this->encoder = $encoder; return $this; } /** * Generates the signininput for the current JWT. * * @return string */ public function generateSigninInput() { $base64payload = $this->encoder->encode(json_encode($this->getPayload(), JSON_UNESCAPED_SLASHES)); $base64header = $this->encoder->encode(json_encode($this->getHeader(), JSON_UNESCAPED_SLASHES)); return sprintf('%s.%s', $base64header, $base64payload); } /** * Returns the payload of the JWT. * * @return array */ public function getPayload() { return $this->payload; } /** * Sets the payload of the current JWT. * * @param array $payload */ public function setPayload(array $payload) { $this->payload = $payload; return $this; } /** * Returns the header of the JWT. * * @return array */ public function getHeader() { return $this->header; } /** * Sets the header of this JWT. * * @param array $header */ public function setHeader(array $header) { $this->header = $header; return $this; } } src/Namshi/JOSE/SimpleJWS.php 0000644 00000004276 15120137110 0011640 0 ustar 00 <?php namespace Namshi\JOSE; /** * Class providing an easy to use JWS implementation. */ class SimpleJWS extends JWS { /** * Constructor. * * @param array $header An associative array of headers. The value can be any type accepted by json_encode or a JSON serializable object * * @see http://php.net/manual/en/function.json-encode.php * @see http://php.net/manual/en/jsonserializable.jsonserialize.php * @see https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41#section-4 * } */ public function __construct($header = array(), $encryptionEngine = 'OpenSSL') { if (!isset($header['typ'])) { $header['typ'] = 'JWS'; } parent::__construct($header, $encryptionEngine); } /** * Sets the payload of the current JWS with an issued at value in the 'iat' property. * * @param array $payload * * @return $this */ public function setPayload(array $payload) { if (!isset($payload['iat'])) { $payload['iat'] = time(); } return parent::setPayload($payload); } /** * Checks that the JWS has been signed with a valid private key by verifying it with a public $key * and the token is not expired. * * @param resource|string $key * @param string $algo The algorithms this JWS should be signed with. Use it if you want to restrict which algorithms you want to allow to be validated. * * @return bool */ public function isValid($key, $algo = null) { return $this->verify($key, $algo) && !$this->isExpired(); } /** * Checks whether the token is expired based on the 'exp' value. *it. * * @return bool */ public function isExpired() { $payload = $this->getPayload(); if (isset($payload['exp'])) { $now = new \DateTime('now'); if (is_int($payload['exp'])) { return ($now->getTimestamp() - $payload['exp']) > 0; } if (is_numeric($payload['exp'])) { return ($now->format('U') - $payload['exp']) > 0; } } return false; } } tests/Namshi/JOSE/Test/Signer/OpenSSL/ES256Test.php 0000644 00000002564 15120137110 0015431 0 ustar 00 <?php namespace Namshi\JOSE\Test\OpenSSL\Signer; use Namshi\JOSE\Signer\OpenSSL\ES256; use Namshi\JOSE\Test\Signer\SecLib\SecLibTestCase; class ES256Test extends SecLibTestCase { public function setup() { parent::setup(); // https://github.com/sebastianbergmann/phpunit/issues/1356 if (defined('HHVM_VERSION')) { $this->markTestSkipped(); } $this->privateKey = openssl_pkey_get_private(SSL_KEYS_PATH.'private.es256.key'); $this->public = openssl_pkey_get_public(SSL_KEYS_PATH.'public.es256.key'); $this->signer = new ES256(); } public function testVerificationWorksProperly() { $encrypted = $this->signer->sign('aaa', $this->privateKey); $this->assertInternalType('bool', $this->signer->verify($this->public, $encrypted, 'aaa')); $this->assertTrue($this->signer->verify($this->public, $encrypted, 'aaa')); } /** * @expectedException \InvalidArgumentException * @expectedExceptionMessage Invalid key supplied. */ public function testWrongKeyCurve() { $privateKey512 = openssl_pkey_get_private(SSL_KEYS_PATH.'private.es512.key'); $this->signer->sign('aaa', $privateKey512); } public function testSigningWorksProperly() { $this->assertInternalType('string', $this->signer->sign('aaa', $this->privateKey)); } } tests/Namshi/JOSE/Test/Signer/OpenSSL/ES384Test.php 0000644 00000002103 15120137110 0015420 0 ustar 00 <?php namespace Namshi\JOSE\Test\OpenSSL\Signer; use Namshi\JOSE\Signer\OpenSSL\ES384; use Namshi\JOSE\Test\Signer\SecLib\SecLibTestCase; class ES384Test extends SecLibTestCase { public function setup() { parent::setup(); // https://github.com/sebastianbergmann/phpunit/issues/1356 if (defined('HHVM_VERSION')) { $this->markTestSkipped(); } $this->privateKey = openssl_pkey_get_private(SSL_KEYS_PATH.'private.es384.key', 'tests'); $this->public = openssl_pkey_get_public(SSL_KEYS_PATH.'public.es384.key'); $this->signer = new ES384(); } public function testVerificationWorksProperly() { $encrypted = $this->signer->sign('aaa', $this->privateKey); $this->assertInternalType('bool', $this->signer->verify($this->public, $encrypted, 'aaa')); $this->assertTrue($this->signer->verify($this->public, $encrypted, 'aaa')); } public function testSigningWorksProperly() { $this->assertInternalType('string', $this->signer->sign('aaa', $this->privateKey)); } } tests/Namshi/JOSE/Test/Signer/OpenSSL/ES512Test.php 0000644 00000002072 15120137110 0015416 0 ustar 00 <?php namespace Namshi\JOSE\Test\OpenSSL\Signer; use Namshi\JOSE\Signer\OpenSSL\ES512; use Namshi\JOSE\Test\Signer\SecLib\SecLibTestCase; class ES512Test extends SecLibTestCase { public function setup() { parent::setup(); // https://github.com/sebastianbergmann/phpunit/issues/1356 if (defined('HHVM_VERSION')) { $this->markTestSkipped(); } $this->privateKey = openssl_pkey_get_private(SSL_KEYS_PATH.'private.es512.key'); $this->public = openssl_pkey_get_public(SSL_KEYS_PATH.'public.es512.key'); $this->signer = new ES512(); } public function testVerificationWorksProperly() { $encrypted = $this->signer->sign('aaa', $this->privateKey); $this->assertInternalType('bool', $this->signer->verify($this->public, $encrypted, 'aaa')); $this->assertTrue($this->signer->verify($this->public, $encrypted, 'aaa')); } public function testSigningWorksProperly() { $this->assertInternalType('string', $this->signer->sign('aaa', $this->privateKey)); } } tests/Namshi/JOSE/Test/Signer/OpenSSL/HS256Test.php 0000644 00000001073 15120137110 0015426 0 ustar 00 <?php namespace Namshi\JOSE\Test\OpenSSL\Signer; use Namshi\JOSE\Signer\OpenSSL\HS256; use PHPUnit_Framework_TestCase as TestCase; class HS256Test extends TestCase { public function testSigningAndVerificationWorkProperly() { $signer = new HS256(); $signature = $signer->sign('aaa', 'foo'); $this->assertEquals($signature, base64_decode('P2Pb8e2Ja4P4YnTZ3EF002RKpUpOnfjIy0uLNT0R1J0=')); $this->assertTrue($signer->verify('foo', $signature, 'aaa')); $this->assertFalse($signer->verify('bar', $signature, 'aaa')); } } tests/Namshi/JOSE/Test/Signer/OpenSSL/HS384Test.php 0000644 00000001120 15120137110 0015421 0 ustar 00 <?php namespace Namshi\JOSE\Test\OpenSSL\Signer; use Namshi\JOSE\Signer\OpenSSL\HS384; use PHPUnit_Framework_TestCase as TestCase; class HS384Test extends TestCase { public function testSigningAndVerificationWorkProperly() { $signer = new HS384(); $signature = $signer->sign('aaa', 'foo'); $this->assertEquals($signature, base64_decode('W6Cd7qZknNYIXOxTrpEWFFwfuX0e2j59hTH4kVFh5o+9rcnfNtphLg4V8YXfkXGF')); $this->assertTrue($signer->verify('foo', $signature, 'aaa')); $this->assertFalse($signer->verify('bar', $signature, 'aaa')); } } tests/Namshi/JOSE/Test/Signer/OpenSSL/HS512Test.php 0000644 00000001150 15120137110 0015415 0 ustar 00 <?php namespace Namshi\JOSE\Test\OpenSSL\Signer; use Namshi\JOSE\Signer\OpenSSL\HS512; use PHPUnit_Framework_TestCase as TestCase; class HS512Test extends TestCase { public function testSigningAndVerificationWorkProperly() { $signer = new HS512(); $signature = $signer->sign('aaa', 'foo'); $this->assertEquals($signature, base64_decode('GysqRX8GoD6BCTrI5sJy1ptn9A7vbDlvFOnaAxO/t+BD8KVrVAUVcHMxgM68ZNxnUNkb7kNSq3YxkCV4pBvTjg==')); $this->assertTrue($signer->verify('foo', $signature, 'aaa')); $this->assertFalse($signer->verify('bar', $signature, 'aaa')); } } tests/Namshi/JOSE/Test/Signer/OpenSSL/KeyFormatTest.php 0000644 00000007325 15120137110 0016566 0 ustar 00 <?php namespace Namshi\JOSE\Test\OpenSSL\Signer; use Namshi\JOSE\Signer\OpenSSL\RS256; use PHPUnit_Framework_TestCase as TestCase; class KeyFormatTest extends TestCase { public function setup() { $this->privateKeyResource = openssl_pkey_get_private(SSL_KEYS_PATH.'private.key', 'tests'); $this->privateKeyString = "-----BEGIN PRIVATE KEY-----\nMIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAN91kQxBuaze3WjI\nCNjeR/HD8E3kDzp89+Lhtn3tMish4yQxhNl6BEkabuS3pUj3WDP6+AFjBVqA1j3f\nu8Wqu7hRJDPHOs2kCII+LhIqvqQTLx/nvNOUhW2DimKn0HuHnlwJODq0MHFJEq5R\nrJH+mFGsP9yMGz4MxA04E2RVbUJRAgMBAAECgYEAjrDrO3Fo2GvD5Jn/lER0mnxt\nIb/kvYt5WyaYutbRN1u/SKhaVeklfWzkrSZb5DkV2LOE1JXfoEgvBnms1O9OSJXw\nqDrFF7NDebw95g6JzI+SbkIHw0Cb+/E9K92FjvW3Bi8j9PKIa8c/dpwIAIirc/q8\nuhSTf4WoIOHSFbSaQPECQQD1Wi9vynJLI5lShOs0wPomZOwNrXa73Lj8ciZC4oPS\nt6tWjbLnLsP+vTSLUyEYeQGsjdbY+y5siJmAqnV/ShB9AkEA6Sgna9gQw4dXN0jB\nSjOZSjl4S2/H3wHatclrvlYfbJVU6GlIlqWGaUkdFvCuEr9iXJAY4zpEQ4P370EZ\ntsyVZQJBAOZu/X6RNSc9GBNYo0+4rzjAMLPn50wp0dPHogfPlt+hgVqZWx2l3o6y\nRVdVjA/gFqJp1Q+VWdS1tvYRIqmadkECQCVdqQuwgedEHmcewtNod42crjmwvWBx\nBKMTl6/WT4zwVb41eUujVWo0LHRLuCoK//GDqmloIh6L3MU8MqnIGb0CQFWcpD4/\nroCkMblk0hPoQPpyapJexc438x7XuEGFEhyxxauqC5R4YFKCf+KBS2gZgr4GSwBU\nQww+qZ3eRYM7faM=\n-----END PRIVATE KEY-----"; $this->privateKeyFilePath = SSL_KEYS_PATH.'private-ne.key'; $this->publicKeyResource = openssl_pkey_get_public(SSL_KEYS_PATH.'public.key'); $this->publicKeyString = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfdZEMQbms3t1oyAjY3kfxw/BN\n5A86fPfi4bZ97TIrIeMkMYTZegRJGm7kt6VI91gz+vgBYwVagNY937vFqru4USQz\nxzrNpAiCPi4SKr6kEy8f57zTlIVtg4pip9B7h55cCTg6tDBxSRKuUayR/phRrD/c\njBs+DMQNOBNkVW1CUQIDAQAB\n-----END PUBLIC KEY-----"; $this->publicKeyFilePath = SSL_KEYS_PATH.'public-ne.key'; $this->badPrivateKeyString = "-----BEGIN PRIVATE KEY-----\nfoo\nbar\n-----END PRIVATE KEY-----"; $this->badPrivateKeyFilePath = SSL_KEYS_PATH.'nonexistant.key'; $this->signer = new RS256(); } public function testStringKeyWorksProperly() { $encrypted = $this->signer->sign('aaa', $this->privateKeyString); $this->assertInternalType('bool', $this->signer->verify($this->publicKeyString, $encrypted, 'aaa')); $this->assertTrue($this->signer->verify($this->publicKeyString, $encrypted, 'aaa')); } public function testFilePathKeyWorksProperly() { $encrypted = $this->signer->sign('aaa', $this->privateKeyFilePath); $this->assertInternalType('bool', $this->signer->verify($this->publicKeyFilePath, $encrypted, 'aaa')); $this->assertTrue($this->signer->verify($this->publicKeyFilePath, $encrypted, 'aaa')); } public function testResourceKeyWorksProperly() { $encrypted = $this->signer->sign('aaa', $this->privateKeyResource); $this->assertInternalType('bool', $this->signer->verify($this->publicKeyResource, $encrypted, 'aaa')); $this->assertTrue($this->signer->verify($this->publicKeyResource, $encrypted, 'aaa')); } /** * @requires PHPUnit 5.4 */ public function testBadStringKeyThrowsException() { $this->expectException(\RuntimeException::class); $this->signer->sign('aaa', $this->badPrivateKeyString); } /** * @requires PHPUnit 5.4 */ public function testFilePathKeyThrowsException() { if(defined('HHVM_VERSION')) { // in HHVM, openssl_pkey_get_(public|private) throws an error when // passed a file path that cannot be found $this->expectException('PHPUnit_Framework_Error'); } else { $this->expectException(\RuntimeException::class); } $this->signer->sign('aaa', $this->badPrivateKeyFilePath); } } tests/Namshi/JOSE/Test/Signer/OpenSSL/NoneTest.php 0000644 00000001001 15120137110 0015545 0 ustar 00 <?php namespace Namshi\JOSE\Test\OpenSSL\Signer; use Namshi\JOSE\Signer\OpenSSL\None; use PHPUnit_Framework_TestCase as TestCase; class NoneTest extends TestCase { public function testVerificationWorksProperly() { $signer = new none(); $this->assertTrue($signer->verify('bar', '', 'aaa')); } public function testSigningWorksProperly() { $signer = new none(); $signature = $signer->sign('aaa', 'foo'); $this->assertTrue($signature === ''); } } tests/Namshi/JOSE/Test/Signer/OpenSSL/RS256Test.php 0000644 00000001566 15120137110 0015447 0 ustar 00 <?php namespace Namshi\JOSE\Test\OpenSSL\Signer; use Namshi\JOSE\Signer\OpenSSL\RS256; use PHPUnit_Framework_TestCase as TestCase; class RS256Test extends TestCase { public function setup() { $this->privateKey = openssl_pkey_get_private(SSL_KEYS_PATH.'private.key', 'tests'); $this->public = openssl_pkey_get_public(SSL_KEYS_PATH.'public.key'); $this->signer = new RS256(); } public function testVerificationWorksProperly() { $encrypted = $this->signer->sign('aaa', $this->privateKey); $this->assertInternalType('bool', $this->signer->verify($this->public, $encrypted, 'aaa')); $this->assertTrue($this->signer->verify($this->public, $encrypted, 'aaa')); } public function testSigningWorksProperly() { $this->assertInternalType('string', $this->signer->sign('aaa', $this->privateKey)); } } tests/Namshi/JOSE/Test/Signer/OpenSSL/RS384Test.php 0000644 00000001566 15120137110 0015451 0 ustar 00 <?php namespace Namshi\JOSE\Test\OpenSSL\Signer; use Namshi\JOSE\Signer\OpenSSL\RS384; use PHPUnit_Framework_TestCase as TestCase; class RS384Test extends TestCase { public function setup() { $this->privateKey = openssl_pkey_get_private(SSL_KEYS_PATH.'private.key', 'tests'); $this->public = openssl_pkey_get_public(SSL_KEYS_PATH.'public.key'); $this->signer = new RS384(); } public function testVerificationWorksProperly() { $encrypted = $this->signer->sign('aaa', $this->privateKey); $this->assertInternalType('bool', $this->signer->verify($this->public, $encrypted, 'aaa')); $this->assertTrue($this->signer->verify($this->public, $encrypted, 'aaa')); } public function testSigningWorksProperly() { $this->assertInternalType('string', $this->signer->sign('aaa', $this->privateKey)); } } tests/Namshi/JOSE/Test/Signer/OpenSSL/RS512Test.php 0000644 00000001566 15120137110 0015442 0 ustar 00 <?php namespace Namshi\JOSE\Test\OpenSSL\Signer; use Namshi\JOSE\Signer\OpenSSL\RS512; use PHPUnit_Framework_TestCase as TestCase; class RS512Test extends TestCase { public function setup() { $this->privateKey = openssl_pkey_get_private(SSL_KEYS_PATH.'private.key', 'tests'); $this->public = openssl_pkey_get_public(SSL_KEYS_PATH.'public.key'); $this->signer = new RS512(); } public function testVerificationWorksProperly() { $encrypted = $this->signer->sign('aaa', $this->privateKey); $this->assertInternalType('bool', $this->signer->verify($this->public, $encrypted, 'aaa')); $this->assertTrue($this->signer->verify($this->public, $encrypted, 'aaa')); } public function testSigningWorksProperly() { $this->assertInternalType('string', $this->signer->sign('aaa', $this->privateKey)); } } tests/Namshi/JOSE/Test/Signer/SecLib/RS256TEST.php 0000644 00000001627 15120137110 0015163 0 ustar 00 <?php namespace Namshi\JOSE\Test\Signer\SecLib; use Namshi\JOSE\Signer\SecLib\RS256; class RS256TEST extends SecLibTestCase { public function setup() { parent::setup(); $this->privateKey = file_get_contents(SSL_KEYS_PATH.'private.key'); $this->public = file_get_contents(SSL_KEYS_PATH.'public.key'); $this->password = 'tests'; $this->signer = new RS256(); } public function testVerificationWorksProperly() { $encrypted = $this->signer->sign('aaa', $this->privateKey, $this->password); $this->assertInternalType('bool', $this->signer->verify($this->public, $encrypted, 'aaa')); $this->assertTrue($this->signer->verify($this->public, $encrypted, 'aaa')); } public function testSigningWorksProperly() { $this->assertInternalType('string', $this->signer->sign('aaa', $this->privateKey, $this->password)); } } tests/Namshi/JOSE/Test/Signer/SecLib/RS384Test.php 0000644 00000001627 15120137110 0015325 0 ustar 00 <?php namespace Namshi\JOSE\Test\Signer\SecLib; use Namshi\JOSE\Signer\SecLib\RS384; class RS384Test extends SecLibTestCase { public function setup() { parent::setup(); $this->privateKey = file_get_contents(SSL_KEYS_PATH.'private.key'); $this->public = file_get_contents(SSL_KEYS_PATH.'public.key'); $this->password = 'tests'; $this->signer = new RS384(); } public function testVerificationWorksProperly() { $encrypted = $this->signer->sign('aaa', $this->privateKey, $this->password); $this->assertInternalType('bool', $this->signer->verify($this->public, $encrypted, 'aaa')); $this->assertTrue($this->signer->verify($this->public, $encrypted, 'aaa')); } public function testSigningWorksProperly() { $this->assertInternalType('string', $this->signer->sign('aaa', $this->privateKey, $this->password)); } } tests/Namshi/JOSE/Test/Signer/SecLib/RS512Test.php 0000644 00000001627 15120137110 0015316 0 ustar 00 <?php namespace Namshi\JOSE\Test\Signer\SecLib; use Namshi\JOSE\Signer\SecLib\RS512; class RS512Test extends SecLibTestCase { public function setup() { parent::setup(); $this->privateKey = file_get_contents(SSL_KEYS_PATH.'private.key'); $this->public = file_get_contents(SSL_KEYS_PATH.'public.key'); $this->password = 'tests'; $this->signer = new RS512(); } public function testVerificationWorksProperly() { $encrypted = $this->signer->sign('aaa', $this->privateKey, $this->password); $this->assertInternalType('bool', $this->signer->verify($this->public, $encrypted, 'aaa')); $this->assertTrue($this->signer->verify($this->public, $encrypted, 'aaa')); } public function testSigningWorksProperly() { $this->assertInternalType('string', $this->signer->sign('aaa', $this->privateKey, $this->password)); } } tests/Namshi/JOSE/Test/Signer/SecLib/SecLibTestCase.php 0000644 00000000601 15120137110 0016466 0 ustar 00 <?php namespace Namshi\JOSE\Test\Signer\SecLib; use PHPUnit_Framework_TestCase as TestCase; class SecLibTestCase extends TestCase { public function setup() { if (version_compare(PHP_VERSION, '7.0.0-dev') >= 0) { $this->markTestSkipped("phpseclib 1.0.0(LTS), even the latest 2.0.0, doesn't support PHP7 yet"); } parent::setUp(); } } tests/Namshi/JOSE/Test/BCJWSTest.php 0000644 00000002060 15120137110 0013012 0 ustar 00 <?php namespace Namshi\JOSE\Test; use Namshi\JOSE\Base64\Base64Encoder; use Namshi\JOSE\JWS; use PHPUnit_Framework_TestCase as TestCase; /** * BC test for base64 url-safe fix * Test that tokens generated the old way (non url-safe) will work with url-safe base64 decoding. */ class BCJWSTest extends TestCase { const SSL_KEY_PASSPHRASE = 'tests'; public function testTestBC() { $data = array( array('order_nr' => 'ae123123'), array('username' => 'asdasdasd'), array('anything' => '!@#$%^&*()_+'), ); foreach ($data as $payload) { $jwsOld = new JWS(array('alg' => 'RS256')); $jwsOld->setEncoder(new Base64Encoder()); $jwsOld->setPayload($payload); $jwsOld->sign(openssl_pkey_get_private(SSL_KEYS_PATH.'private.key', self::SSL_KEY_PASSPHRASE)); $t = $jwsOld->getTokenString(); $jwsNew = JWS::load($t); $this->assertTrue($jwsNew->verify(openssl_pkey_get_public(SSL_KEYS_PATH.'public.key'))); } } } tests/Namshi/JOSE/Test/JWSTest.php 0000644 00000021361 15120137110 0012612 0 ustar 00 <?php namespace Namshi\JOSE\Test; use DateTime; use Namshi\JOSE\JWS; use PHPUnit_Framework_TestCase as TestCase; use Prophecy\Argument; use Namshi\JOSE\Signer\OpenSSL\HS256; use Namshi\JOSE\Base64\Base64UrlSafeEncoder; class JWSTest extends TestCase { const SSL_KEY_PASSPHRASE = 'tests'; public function setup() { $date = new DateTime('tomorrow'); $data = array( 'a' => 'b', ); $this->jws = new JWS(array('alg' => 'RS256')); $this->jws->setPayload($data); } /** * @expectedException InvalidArgumentException */ public function testLoadingUnsecureJwsWithNoneAlgo() { $date = new DateTime('tomorrow'); $data = array( 'a' => 'b', 'exp' => $date->format('U'), ); $this->jws = new JWS(array('alg' => 'None')); $this->jws->setPayload($data); $this->jws->sign('111'); $jws = JWS::load($this->jws->getTokenString()); $this->assertFalse($jws->verify('111')); $payload = $jws->getPayload(); $this->assertEquals('b', $payload['a']); } /** * @expectedException InvalidArgumentException */ public function testLoadingUnsecureJwsWithLowercaseNone() { $date = new DateTime('tomorrow'); $data = array( 'a' => 'b', 'exp' => $date->format('U'), ); $this->jws = new JWS(array('alg' => 'none')); $this->jws->setPayload($data); $this->jws->sign('111'); $jws = JWS::load($this->jws->getTokenString()); $this->assertFalse($jws->verify('111')); $payload = $jws->getPayload(); $this->assertEquals('b', $payload['a']); } public function testAllowingUnsecureJws() { $date = new DateTime('tomorrow'); $data = array( 'a' => 'b', 'exp' => $date->format('U'), ); $this->jws = new JWS(array('alg' => 'None')); $this->jws->setPayload($data); $this->jws->sign('111'); $jws = JWS::load($this->jws->getTokenString(), true); $this->assertTrue($jws->verify('111')); $payload = $jws->getPayload(); $this->assertEquals('b', $payload['a']); } public function testRestrictingTheAlgorithmsKo() { $this->jws = new JWS(array('alg' => 'HS256')); $this->jws->sign('12345'); $jws = JWS::load($this->jws->getTokenString()); $this->assertFalse($jws->verify('12345', 'RS256')); } public function testRestrictingTheAlgorithmsOk() { $date = new DateTime('tomorrow'); $data = array( 'a' => 'b', 'exp' => $date->format('U'), ); $this->jws = new JWS(array('alg' => 'HS256')); $this->jws->setPayload($data); $this->jws->sign('123'); $jws = JWS::load($this->jws->getTokenString()); $this->assertTrue($jws->verify('123', 'HS256')); } public function testVerificationRS256() { $privateKey = openssl_pkey_get_private(SSL_KEYS_PATH.'private.key', self::SSL_KEY_PASSPHRASE); $this->jws->sign($privateKey); $jws = JWS::load($this->jws->getTokenString()); $public_key = openssl_pkey_get_public(SSL_KEYS_PATH.'public.key'); $this->assertTrue($jws->verify($public_key)); $payload = $jws->getPayload(); $this->assertEquals('b', $payload['a']); } public function testVerificationRS256KeyAsString() { $privateKey = file_get_contents(TEST_DIR.'/private.key'); $this->jws->sign($privateKey, self::SSL_KEY_PASSPHRASE); $jws = JWS::load($this->jws->getTokenString()); $public_key = openssl_pkey_get_public(SSL_KEYS_PATH.'public.key'); $this->assertTrue($jws->verify($public_key)); $payload = $jws->getPayload(); $this->assertEquals('b', $payload['a']); } public function testUseOfCustomEncoder() { $encoder = $this->prophesize('Namshi\JOSE\Base64\Encoder'); $encoder ->decode(Argument::any()) ->willReturn('{"whatever": "the payload should be"}') ->shouldBeCalled(); $encoder ->decode(Argument::any()) ->willReturn('{"alg": "test"}') ->shouldBeCalled(); JWS::load($this->jws->getTokenString(), false, $encoder->reveal()); } public function testVerificationThatTheJWSIsSigned() { $privateKey = openssl_pkey_get_private(SSL_KEYS_PATH.'private.key', self::SSL_KEY_PASSPHRASE); $this->jws->sign($privateKey); $this->assertTrue($this->jws->isSigned()); } public function testVerificationThatTheJWSIsNotSigned() { $this->assertFalse($this->jws->isSigned()); } /** * @expectedException InvalidArgumentException */ public function testWrongVerificationRS256() { $privateKey = openssl_pkey_get_private(SSL_KEYS_PATH.'private.key', self::SSL_KEY_PASSPHRASE); $this->jws->sign($privateKey); $jws = JWS::load('eyJhbGciOiJ0ZXN0In0=.eyJhbGciOiJ0ZXN0In0=.eyJhbGciOiJ0ZXN0In0='); $public_key = openssl_pkey_get_public(SSL_KEYS_PATH.'public.key'); $this->assertFalse($jws->verify($public_key)); } /** * @expectedException InvalidArgumentException */ public function testLoadingAMalformedTokenString() { JWS::load('test.Test.TEST'); } /** * @expectedException InvalidArgumentException */ public function testLoadingAMalformedTokenString2() { JWS::load('test'); } public function testSignAndVerifyWithFalsePublicKey() { $public_key = false; $jwsHMAC = new JWS(array('alg' => 'HS256')); $jwsHMAC->sign(false); $jws = JWS::load($jwsHMAC->getTokenString()); $this->assertFalse($jws->verify($public_key)); } public function testSignAndVerifyWithEmptyStringPublicKey() { $public_key = false; $jwsHMAC = new JWS(array('alg' => 'HS256')); $jwsHMAC->sign(''); $jws = JWS::load($jwsHMAC->getTokenString()); $this->assertFalse($jws->verify($public_key)); } public function testLoadingWithAnyOrderOfHeaders() { $privateKey = openssl_pkey_get_private(SSL_KEYS_PATH.'private.key', self::SSL_KEY_PASSPHRASE); $public_key = openssl_pkey_get_public(SSL_KEYS_PATH.'public.key'); $this->jws = new JWS(array('alg' => 'RS256', 'custom' => '1')); $header = $this->jws->getHeader(); $reversedHeader = array_reverse($header); $this->assertFalse($header === $reversedHeader); $this->jws->setHeader($reversedHeader); $this->jws->sign($privateKey); $tokenString = $this->jws->getTokenString(); $jws = JWS::load($tokenString); $this->assertTrue($reversedHeader === $jws->getHeader()); } public function testSignAndVerifyWithSecLib() { if (version_compare(PHP_VERSION, '7.0.0-dev') >= 0) { $this->setExpectedException('InvalidArgumentException'); } $jwsRSA = new JWS(array('alg' => 'RS256'), 'SecLib'); $data = array('a' => 'b'); $jwsRSA->setPayload($data); $jwsRSA->sign(file_get_contents(SSL_KEYS_PATH.'private.key'), 'tests'); $jws = JWS::load($jwsRSA->getTokenString(), false, null, 'SecLib'); $this->assertTrue($jws->verify(file_get_contents(SSL_KEYS_PATH.'public.key', 'RS256'))); } public function testConstructionFromHeader() { $header = array('alg' => 'RS256', 'test' => true); $jws = new JWS($header); $this->assertTrue($header == $jws->getHeader()); } public function testVerificationCustomizedHeader() { $header = $this->jws->getHeader(); $header['test'] = true; $this->jws->setHeader($header); $privateKey = openssl_pkey_get_private(SSL_KEYS_PATH.'private.key', self::SSL_KEY_PASSPHRASE); $this->jws->sign($privateKey); $jws = JWS::load($this->jws->getTokenString()); $public_key = openssl_pkey_get_public(SSL_KEYS_PATH.'public.key'); $headerFromSig = $jws->getHeader(); $this->assertSame($headerFromSig['test'], true); $this->assertTrue($jws->verify($public_key)); } public function testVerificationWithJsonThatContainsWhitespace() { $header = '{ "alg": "HS256" }'; $payload = '{ "a": "b" }'; $encoder = new Base64UrlSafeEncoder(); $signer = new HS256(); $token = sprintf('%s.%s', $encoder->encode($header), $encoder->encode($payload)); $signature = $encoder->encode($signer->sign($token, '123')); $jwsToken = sprintf('%s.%s', $token, $signature); $jws = JWS::load($jwsToken); $this->assertTrue($jws->verify('123')); } } tests/Namshi/JOSE/Test/JWTTest.php 0000644 00000002674 15120137110 0012621 0 ustar 00 <?php namespace Namshi\JOSE\Test; use Namshi\JOSE\Base64\Base64UrlSafeEncoder; use Namshi\JOSE\JWT; use PHPUnit_Framework_TestCase as TestCase; class JWTTest extends TestCase { public function testGenerationOfTheSigninInput() { $payload = array('b' => 'a', 'iat' => 1421161177); $header = array('a' => 'b'); $jwt = new JWT($payload, $header); $encoder = new Base64UrlSafeEncoder(); $this->assertEquals(sprintf('%s.%s', $encoder->encode(json_encode($header)), $encoder->encode(json_encode($payload))), $jwt->generateSigninInput()); } public function testGenerationOfTheSigninInputCanHandleSlashes() { $encoder = new Base64UrlSafeEncoder(); $json_string = '{"a":"/b/"}'; $encoded_json_string = $encoder->encode($json_string); $jwt = new JWT(json_decode($json_string, true), json_decode($json_string, true)); $this->assertEquals(sprintf('%s.%s', $encoded_json_string, $encoded_json_string), $jwt->generateSigninInput()); } public function testPayload() { $jwt = new JWT(array('a' => 'b'), array()); $payload = $jwt->getPayload(); $this->assertSame(array('a' => 'b'), $payload); $jwt = new JWT(array('a' => 'b'), array()); $jwt->setPayload(array('b' => 'a')); $payload = $jwt->getPayload(); $this->assertSame($payload['b'], 'a'); $this->assertSame(array('b' => 'a'), $payload); } } tests/Namshi/JOSE/Test/SimpleJWSTest.php 0000644 00000007044 15120137110 0013766 0 ustar 00 <?php namespace Namshi\JOSE\Test; use DateTime; use Namshi\JOSE\SimpleJWS; use PHPUnit_Framework_TestCase as TestCase; class SimpleJWSTest extends TestCase { const SSL_KEY_PASSPHRASE = 'tests'; public function setup() { $date = new DateTime('tomorrow'); $data = array( 'a' => 'b', 'exp' => $date->format('U'), ); $this->jws = new SimpleJWS(array('alg' => 'RS256')); $this->jws->setPayload($data); } public function testConstruction() { $this->assertSame($this->jws->getHeader(), array('alg' => 'RS256', 'typ' => 'JWS')); $this->assertTrue(is_int($this->jws->getPayload()['iat']), 'iat property should be integer value (from construction)'); } public function testValidationOfAValidSimpleJWS() { $privateKey = openssl_pkey_get_private(SSL_KEYS_PATH.'private.key', self::SSL_KEY_PASSPHRASE); $this->jws->sign($privateKey); $jws = SimpleJWS::load($this->jws->getTokenString()); $public_key = openssl_pkey_get_public(SSL_KEYS_PATH.'public.key'); $this->assertTrue($jws->isValid($public_key, 'RS256')); } public function testValidationOfInvalidSimpleJWS() { $date = new DateTime('yesterday'); $this->jws->setPayload(array( 'exp' => $date->format('U'), )); $privateKey = openssl_pkey_get_private(SSL_KEYS_PATH.'private.key', self::SSL_KEY_PASSPHRASE); $this->jws->sign($privateKey); $jws = SimpleJWS::load($this->jws->getTokenString()); $public_key = openssl_pkey_get_public(SSL_KEYS_PATH.'public.key'); $this->assertFalse($jws->isValid($public_key, 'RS256')); } public function testValidationOfValidSimpleJWSWithStringIat() { $date = new DateTime('tomorrow'); $data = array( 'a' => 'b', 'exp' => $date->format('U'), 'iat' => time() ); $this->jws->setPayload($data); $privateKey = openssl_pkey_get_private(SSL_KEYS_PATH.'private.key', self::SSL_KEY_PASSPHRASE); $this->jws->sign($privateKey); $jws = SimpleJWS::load($this->jws->getTokenString()); $public_key = openssl_pkey_get_public(SSL_KEYS_PATH.'public.key'); $this->assertTrue($jws->isValid($public_key, 'RS256')); } public function testValidationOfValidSimpleJWSWithExpAsInt() { $date = new DateTime('tomorrow'); $data = array( 'a' => 'b', 'exp' => $date->getTimestamp(), 'iat' => time() ); $this->jws->setPayload($data); $privateKey = openssl_pkey_get_private(SSL_KEYS_PATH.'private.key', self::SSL_KEY_PASSPHRASE); $this->jws->sign($privateKey); $jws = SimpleJWS::load($this->jws->getTokenString()); $public_key = openssl_pkey_get_public(SSL_KEYS_PATH.'public.key'); $this->assertTrue($jws->isValid($public_key, 'RS256')); } public function testValidationOfInvalidSimpleJWSWithExpAsInt() { $date = new DateTime('yesterday'); $data = array( 'a' => 'b', 'exp' => $date->getTimestamp(), 'iat' => time() ); $this->jws->setPayload($data); $privateKey = openssl_pkey_get_private(SSL_KEYS_PATH.'private.key', self::SSL_KEY_PASSPHRASE); $this->jws->sign($privateKey); $jws = SimpleJWS::load($this->jws->getTokenString()); $public_key = openssl_pkey_get_public(SSL_KEYS_PATH.'public.key'); $this->assertFalse($jws->isValid($public_key, 'RS256')); } } tests/bootstrap.php 0000644 00000000310 15120137110 0010415 0 ustar 00 <?php $loader = require __DIR__.'/../vendor/autoload.php'; $loader->add('Namshi\\JOSE\\Test', __DIR__); define('TEST_DIR', __DIR__); define('SSL_KEYS_PATH', 'file://'.TEST_DIR.DIRECTORY_SEPARATOR); tests/private-ne.key 0000644 00000001624 15120137110 0010464 0 ustar 00 -----BEGIN PRIVATE KEY----- MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAN91kQxBuaze3WjI CNjeR/HD8E3kDzp89+Lhtn3tMish4yQxhNl6BEkabuS3pUj3WDP6+AFjBVqA1j3f u8Wqu7hRJDPHOs2kCII+LhIqvqQTLx/nvNOUhW2DimKn0HuHnlwJODq0MHFJEq5R rJH+mFGsP9yMGz4MxA04E2RVbUJRAgMBAAECgYEAjrDrO3Fo2GvD5Jn/lER0mnxt Ib/kvYt5WyaYutbRN1u/SKhaVeklfWzkrSZb5DkV2LOE1JXfoEgvBnms1O9OSJXw qDrFF7NDebw95g6JzI+SbkIHw0Cb+/E9K92FjvW3Bi8j9PKIa8c/dpwIAIirc/q8 uhSTf4WoIOHSFbSaQPECQQD1Wi9vynJLI5lShOs0wPomZOwNrXa73Lj8ciZC4oPS t6tWjbLnLsP+vTSLUyEYeQGsjdbY+y5siJmAqnV/ShB9AkEA6Sgna9gQw4dXN0jB SjOZSjl4S2/H3wHatclrvlYfbJVU6GlIlqWGaUkdFvCuEr9iXJAY4zpEQ4P370EZ tsyVZQJBAOZu/X6RNSc9GBNYo0+4rzjAMLPn50wp0dPHogfPlt+hgVqZWx2l3o6y RVdVjA/gFqJp1Q+VWdS1tvYRIqmadkECQCVdqQuwgedEHmcewtNod42crjmwvWBx BKMTl6/WT4zwVb41eUujVWo0LHRLuCoK//GDqmloIh6L3MU8MqnIGb0CQFWcpD4/ roCkMblk0hPoQPpyapJexc438x7XuEGFEhyxxauqC5R4YFKCf+KBS2gZgr4GSwBU Qww+qZ3eRYM7faM= -----END PRIVATE KEY----- tests/private.es256.key 0000644 00000000343 15120137110 0010724 0 ustar 00 -----BEGIN EC PRIVATE KEY----- MHcCAQEEIKv1ZMzZ8Uxt/YxwdKpMAP0nlV7ne8gh0+5G+5Gb/tMUoAoGCCqGSM49 AwEHoUQDQgAEvuYsP+QnrqAbM7Iyhzjt08hFSuzapyojCB/gFsBt65Wir4TYr5fS Q96oa4qeGVeTFzl+fGiZFILootvLsiPwAQ== -----END EC PRIVATE KEY----- tests/private.es384.key 0000644 00000000440 15120137110 0010724 0 ustar 00 -----BEGIN EC PRIVATE KEY----- MIGkAgEBBDClxJJett5kQ5oEizsjCpxT0z844zzVeFm44egaCZL/Y90QLBx1BxfO /tbz6VgvRyugBwYFK4EEACKhZANiAATp/5dmyDZO+fQSgRqlD7KUxg22ybwI9/Rx vwcjYSR9j0Gqm3dAzPCUzuZWwVGZoxlvyc6dHCamYSe8DZTzJ1L51uc+/tvBiX6r Wo16HxamOivdU75FO3hx7Q+fbmgYZZQ= -----END EC PRIVATE KEY----- tests/private.es512.key 0000644 00000000551 15120137110 0010720 0 ustar 00 -----BEGIN EC PRIVATE KEY----- MIHbAgEBBEEWnooUpGIch1H/s8/ZUrHPo6RL+mHKhCrDO/Yjz37zM/tBJyvHmvwY Utw3mYII0m3es3dIiAjheghBs14+UCPq8aAHBgUrgQQAI6GBiQOBhgAEAVpvo7TG pQk5P7ZLo0qkBpaT+fFDv6HQrWElBKMxcrJd/mRNapweATsVv83YON4lTIIRXzgG kmWeqbDr6RQO+1cSAIs+MoRmLaiPyG2xmPwQCHX2CGX/uCZiT3iOxTAJEZuUbeSA 828K4WfAA4ODdGiB87YVShhPOkiQswV3LpbpPGhC -----END EC PRIVATE KEY----- tests/private.key 0000644 00000003346 15120137110 0010067 0 ustar 00 -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-256-CBC,510C9E7AAF17A8397C4B79D906DAE432 W0qO1iOiS10gdomVUBbR3LdJOHRmfOmsXAjg4ezG3+Dg/0rfVkj+H3RWIpNnLq2l ciayAqjFzLzlKYPW4/XakyhfmCrZE+mL+kFVEUjhISZ+xXLwHGltL0UeYsei/AUp usjbxO8K0hZ1ZG2bQCEj5ff2YGmC9g1K3C7tE8XR0+QCZ/xaYkdUxDUIfYZ4MebG +C5P+mckds6lmcdZkIZj9H+36LPH2RPlMJAdLmLGytKF37h93gcL/pgePMEY+sVj h0YfScQ2GlE3v3S1CC1X2yjU5CtfxPHuA+2XuFIZ9twlrNFSqUWtvaCMNgSaWPLH KdR9RC8vImz0PEu6eR4t9ytTnykYG+mujCjumeohJoWjrXJymC4ocHIa8p/EA7Hc AWXxVlS897feG1BQ+rAiuvzIDvU8glKO8ZDjs9FUeC4O6ySCI9b4Of/57Uqo7nmQ 0nLTJntvKFeusJ9WnergOEEHg1x93n8ajM49a+eS2uEj+UlIWiT01WTVS2i5wWp7 +wcniYwlEk36HHBWSYBmhK+Uda4isE3SBBiRBa4ETh7Goor3FcxTA5TEqKwsHG0o 1infKNmPHUy2hQTrGttoJrCpAvKq2RuQJUG5Tu5mURibihcRqCCcbyz/uKY/IIJg 9WV3gzsDXrmr2UWovD9Rfudm6mdkhz1Sn+XS69z3irMJHuW/j2sO/bO5JseurPq7 0V9Ms2TCIlyT7ncjsV3Lf0PSmitf/W4KzRKgxKkgORHNWX4W9yLA+yMeP3CfwaBn QiTk/dnN/uwVFQ5YlRkUsWOFxS7/gk/kBv15dTZV/1paqm0iPcExmtXqFvPlxnUr J3NeVl6j6kOUGLPsijk4zIijVMquYug4WfjCHLmzsqEGOYoK+nA6BQwxeMSOxFWT R8QWvvz8B6fm5BigBsUs7kQa3HcksE6YMz8dXr3r0cvINurGUpd3hDYLMdUJ0ttG cjdHXG3+fBOhUD8zkQSpf21V1/B4df2PiFlTKar5Jx1IiplvkTDPv6Nea8zuiVzy 8Wp/PawNbPRs+KQAsr+pvged+VftvsVVGyG+0lXd7kPAJqxo4xEpD+NelHJKDgVy uuQPMoxt1TIvCAP9jD+ENCmnGU2HhpJvngsVQs+7DviCOgbbdIfff91fyrLkSNkb tck4q3RFpKDcKiU9yxjeAaYP6bXSq2ypwHV4YhivftyJN52TxAjGRqkuZCr5cG9P +l3hgwTusJSjiNFkjSv7Tq3sq+s6p3+vdqBs7pS6wH/yfnJtSnPgdOkO9NqvYG67 ALco0hSuBmKWFjr4rk9e/fVPqOFCKZNdJ44ZFViFkF1Ry/YO7XvnxCQCOk17g/aM daMSNDJdZliGsu6lHxzF0/gq7ukTqAYJEh0Jvb7+l8/YMJZRFzxB0SENCTn9rPIY VTrajK8z33GMHUFzbGEyoZoGxNe0F4DarHqFteBjnRLFev0N88go0hlLP0NR2hBB RsNRTJGbzYTVZJwZTDrA11KoU3PaWFrZglsD/ExVb+OYgYv+SlbUdu9znpZBlayj 3wJv6RqhDntrbc2yPzK/27KzToNLlqdBnUO0kl64JaZukkhpDfmKJahWO4nePxvu -----END RSA PRIVATE KEY----- tests/public-ne.key 0000644 00000000420 15120137110 0010261 0 ustar 00 -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfdZEMQbms3t1oyAjY3kfxw/BN 5A86fPfi4bZ97TIrIeMkMYTZegRJGm7kt6VI91gz+vgBYwVagNY937vFqru4USQz xzrNpAiCPi4SKr6kEy8f57zTlIVtg4pip9B7h55cCTg6tDBxSRKuUayR/phRrD/c jBs+DMQNOBNkVW1CUQIDAQAB -----END PUBLIC KEY----- tests/public.es256.key 0000644 00000000262 15120137110 0010530 0 ustar 00 -----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvuYsP+QnrqAbM7Iyhzjt08hFSuza pyojCB/gFsBt65Wir4TYr5fSQ96oa4qeGVeTFzl+fGiZFILootvLsiPwAQ== -----END PUBLIC KEY----- tests/public.es384.key 0000644 00000000327 15120137110 0010534 0 ustar 00 -----BEGIN PUBLIC KEY----- MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE6f+XZsg2Tvn0EoEapQ+ylMYNtsm8CPf0 cb8HI2EkfY9Bqpt3QMzwlM7mVsFRmaMZb8nOnRwmpmEnvA2U8ydS+dbnPv7bwYl+ q1qNeh8Wpjor3VO+RTt4ce0Pn25oGGWU -----END PUBLIC KEY----- tests/public.es512.key 0000644 00000000414 15120137110 0010522 0 ustar 00 -----BEGIN PUBLIC KEY----- MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBWm+jtMalCTk/tkujSqQGlpP58UO/ odCtYSUEozFysl3+ZE1qnB4BOxW/zdg43iVMghFfOAaSZZ6psOvpFA77VxIAiz4y hGYtqI/IbbGY/BAIdfYIZf+4JmJPeI7FMAkRm5Rt5IDzbwrhZ8ADg4N0aIHzthVK GE86SJCzBXculuk8aEI= -----END PUBLIC KEY----- tests/public.key 0000644 00000000703 15120137110 0007665 0 ustar 00 -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtpS1ZmfVKVP5KofIhMBP 0tSWc4qlh6fm2lrZSkuKxUjEaWjzZSzs72gEIGxraWusMdoRuV54xsWRyf5KeZT0 S+I5Prle3Idi3gICiO4NwvMk6JwSBcJWwmSLFEKyUSnB2CtfiGc0/5rQCpcEt/Dn 5iM+BNn7fqpoLIbks8rXKUIj8+qMVqkTXsEKeKinE23t1ykMldsNaaOH+hvGti5J t2DMnH1JjoXdDXfxvSP/0gjUYb0ektudYFXoA6wekmQyJeImvgx4Myz1I4iHtkY/ Cp7J4Mn1ejZ6HNmyvoTE/4OuY1uCeYv4UyXFc1s1uUyYtj4z57qsHGsS4dQ3A2MJ swIDAQAB -----END PUBLIC KEY----- .coveralls.yml 0000644 00000000077 15120137110 0007332 0 ustar 00 service_name: travis-ci coverage_clover: build/logs/clover.xml .gitignore 0000644 00000000033 15120137110 0006517 0 ustar 00 build composer.lock vendor .travis.yml 0000644 00000000501 15120137110 0006640 0 ustar 00 language: php php: - 5.5 - 5.6 - 7.0 - hhvm sudo: false install: travis_retry composer install --no-interaction --prefer-source before_script: mkdir -p build/logs script: php vendor/bin/phpunit -c phpunit.xml.dist --coverage-clover ./build/logs/clover.xml after_success: php vendor/bin/coveralls -v CHANGELOG.md 0000644 00000001750 15120137110 0006347 0 ustar 00 ### 6.1.0 - Dropped support for PHP 5.4 - phpseclib ~2.0.x ### 6.0.4 - Added styleci config, add styleci-php-cs bridge to check formatting - Removed composer.lock - Fix #34: strlen() and substr() can misbehave with mbstring.func_overload - Fix: Don't cast to boolean the result of openssl_verify() - Enhancement: support phpseclib 1.x.x ### 6.x.x - Not Backwards Compatible - Dropped support for PHP 5.3 - Don't escape slashes when generating signin input. This may render tokens generated with earlier versions of Jose incompatible. - **DON'T** install version 6.0.2! It's using phpseclib version 2 instead of version 1 and some classes are broken ### 3.x.x to 4.x.x - Not Backwards Compatible Added the ability to set custom properties in the header. Moved automatic inclusion of certain claims into an SimpleJWS class from the base JWS class. ### 2.x.x to 3.x.x Introduced the ability to specify an encryption engine. Added support of PHPSecLib to the existing OpenSSL implementation. LICENSE 0000644 00000002067 15120137110 0005545 0 ustar 00 The MIT License Copyright (c) 2014 Alessandro Nadalin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. README.md 0000644 00000015073 15120137110 0006020 0 ustar 00 # NAMSHI | JOSE [](https://travis-ci.org/namshi/jose) [](https://packagist.org/packages/namshi/jose) [](https://packagist.org/packages/namshi/jose) [](https://packagist.org/packages/namshi/jose) This library provides a lightweight implementation of the JWS ([JSON Web Signature](http://tools.ietf.org/html/draft-jones-json-web-signature-04)) specification. ## Prerequisites This library needs PHP 5.5+ and the library OpenSSL. It has been tested using `PHP5.5` to `PHP7.0` and `HHVM`. ## Installation You can install the library directly from composer / [packagist](https://packagist.org/packages/namshi/jose): ``` "namshi/jose": "7.0.*" ``` ## Usage Using it is pretty straightforward: imagine that you want to offer a service the ability to authenticate a user via a cookie, and the service is built with javascript; what you would need to do is to generate a JWS (after verifying the credentials once), store it as a cookie and then pass it from your JavaScript app everytime you want to authenticate that user. First, generate the JWS: ``` php <?php use Namshi\JOSE\SimpleJWS; if ($username == 'correctUsername' && $pass == 'ok') { $user = Db::loadUserByUsername($username); $jws = new SimpleJWS(array( 'alg' => 'RS256' )); $jws->setPayload(array( 'uid' => $user->getid(), )); $privateKey = openssl_pkey_get_private("file://path/to/private.key", self::SSL_KEY_PASSPHRASE); $jws->sign($privateKey); setcookie('identity', $jws->getTokenString()); } ``` Then your JS app can use the available cookie to execute authenticated calls, without sending passwords or credentials. Once a request is submitted, you only have to verify that it is a valid call: ``` php <?php use Namshi\JOSE\SimpleJWS; $jws = SimpleJWS::load($_COOKIE['identity']); $public_key = openssl_pkey_get_public("/path/to/public.key"); // verify that the token is valid and had the same values // you emitted before while setting it as a cookie if ($jws->isValid($public_key, 'RS256')) { $payload = $jws->getPayload(); echo sprintf("Hey, my JS app just did an action authenticated as user #%s", $payload['uid']); } ``` > PROTIP: you can omit the second argument of the isValid() method, so jose will try to validate the token with the algorithm specified in the token's header, though this might expose you to some security issues. > > For now we recommend to always explicitely set the algorithm you want to use to validate tokens. ### PHPSECLIB For RSA Verification You may find that you need to use this library in an environment where [PHP's wrappers for OpenSSL](http://php.net/manual/en/ref.openssl.php) do not work, or OpenSSL simply is not installed. This library uses OpenSSL to encrypt by default, but you can specify that you want to use [PHPSecLib](http://phpseclib.sourceforge.net/) for a pure PHP implementation of RSA encryption. In these cases, simply add the optional `'SecLib'` parameter when constructing a JWS: ```php $jws = new JWS(array('alg' => 'RS256'), 'SecLib'); ``` You can now use the PHPSecLib implementation of RSA signing. If you use a password protected private key, you can still submit the private key to use for signing as a string, as long as you pass the password as the second parameter into the `sign` method: ```php $jws->sign(file_get_contents(SSL_KEYS_PATH . "private.key"), 'tests'); ``` You may also load a JWS using the PHPSecLib implementation of RSA verification: ```php $jws = JWS::load($tokenString, false, $encoder, 'SecLib'); ``` ## Under the hood In order to [validate the JWS](https://github.com/namshi/jose/blob/master/src/Namshi/JOSE/SimpleJWS.php#L43), the signature is first [verified](https://github.com/namshi/jose/blob/master/src/Namshi/JOSE/JWS.php#L113) with a public key and then we will check whether the [token is expired](https://github.com/namshi/jose/blob/master/src/Namshi/JOSE/SimpleJWS.php#L55). To give a JWS a TTL, just use the standard `exp` value in the payload: ``` php $date = new DateTime('tomorrow'); $this->jws = new SimpleJWS(array('alg' => 'RS256')); $this->jws->setPayload(array( 'exp' => $date->format('U'), )); ``` ### Unsecure JWSes You can allow [unsecure JWSes](https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#page-12) by setting the `$allowUnsecure` flag while loading JWSes: ``` php JWS::load($this->jws->getTokenString(), true); ``` This allows tokens signed with the 'none' algorithms to go through, which is something you probably don't want to do. Proceed with caution :) **Unsecure JWSes are disabled by default since version 2.2.2. You should **not** use previous versions other than 2.2.2 as they have a security vulnerability. More info [here](http://tech.namshi.com/blog/2015/02/19/update-your-namshi-slash-jose-installations-as-a-security-vulnerability-was-found/).** ## Using a custom encoder If, for some reason, you need to encode the token in a different way, you can inject any implementation of `Namshi\JOSE\Base64\Encoder` in a `JWS` instance. Likewise, `JWS::load()` accepts such an implementation as a second argument. ## Implementation Specifics The library provides a base JWT Class that implements what is needed just for JSON Web Tokens. The JWS Class then extends the JWT class and adds the implementation for signing and verifying using JSON Web Signatures. The SimpleJWS class extends the base JWS class and adds validation of a TTL and inclusion of automatic claims. ## Major Versions ### 2.x.x to 3.x.x Introduced the ability to specify an encryption engine. Added support of PHPSecLib to the existing OpenSSL implementation. ### 3.x.x to 4.x.x - Not Backwards Compatible Added the ability to set custom properties in the header. Moved automatic inclusion of certain claims into an SimpleJWS class from the base JWS class. ### 6.x.x - Not Backwards Compatible #### 6.1.x - Dropped support for PHP 5.4 - phpseclib 2.0 #### 6.0.x - Dropped support for PHP 5.3 - Don't escape slashes when generating signin input. This may render tokens generated with earlier versions of Jose incompatible. ### 7.x.x #### 7.0.x Moved phpseclib and the openssl extension as suggested dependencies. ## Tests Tests are written using PHPUnit for this library. After doing composer install you can execute the following command to run tests: ``` ./vendor/bin/phpunit ``` ## Credits This library has been inspired by the [initial work done by @ritou](https://github.com/ritou/php-Akita_JOSE). composer.json 0000644 00000002330 15120137110 0007253 0 ustar 00 { "name": "namshi/jose", "description": "JSON Object Signing and Encryption library for PHP.", "license": "MIT", "keywords": ["jws", "jwt", "json", "json web token", "json web signature", "token"], "authors": [ { "name": "Alessandro Nadalin", "email": "alessandro.nadalin@gmail.com" }, { "name": "Alessandro Cinelli (cirpo)", "email": "alessandro.cinelli@gmail.com" } ], "autoload": { "psr-4": { "Namshi\\JOSE\\": "src/Namshi/JOSE/" } }, "autoload-dev": { "psr-4": { "Namshi\\JOSE\\Test\\": "test/Namshi/JOSE/Test/" } }, "require": { "ext-date": "*", "ext-hash": "*", "ext-json": "*", "ext-pcre": "*", "ext-spl": "*", "php": ">=5.5", "symfony/polyfill-php56": "^1.0" }, "require-dev": { "phpunit/phpunit": "^4.5|^5.0", "satooshi/php-coveralls": "^1.0", "phpseclib/phpseclib": "^2.0" }, "suggest": { "ext-openssl": "Allows to use OpenSSL as crypto engine.", "phpseclib/phpseclib": "Allows to use Phpseclib as crypto engine, use version ^2.0." } } phpunit.xml.dist 0000644 00000001536 15120137110 0007713 0 ustar 00 <?xml version="1.0" encoding="UTF-8"?> <phpunit backupGlobals="false" backupStaticAttributes="false" beStrictAboutTestsThatDoNotTestAnything="true" beStrictAboutOutputDuringTests="true" bootstrap="tests/bootstrap.php" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnError="false" stopOnFailure="false" verbose="true" > <testsuites> <testsuite name="JOSE Test Suite"> <directory suffix="Test.php">./tests</directory> </testsuite> </testsuites> <filter> <whitelist processUncoveredFilesFromWhitelist="true"> <directory suffix=".php">./src</directory> </whitelist> </filter> </phpunit>
Coded With 💗 by
0x6ick