Skip to content

Commit

Permalink
Seperate decryption process from verifying process
Browse files Browse the repository at this point in the history
  • Loading branch information
moesjarraf committed Nov 11, 2015
1 parent ad9c50b commit 4a08ff2
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 20 deletions.
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ The library can be installed using composer. Add the following to your `composer

## Usage

**System A (Has resources which require authorization)**
``` php
use LegalThings/Authorizer;

Expand All @@ -46,13 +47,29 @@ class FooController
}

if (isset($_GET['authz']) {
$mayAccess = Authorizer::verify('/some/resource', $_GET['authz'], 'path/to/private_key.pem'); // authz is the encrypted secret
$mayAccess = Authorizer::verify('/some/resource', $_GET['authz']); // authz is the decrypted secret

if (!$mayAccess) return $this->forbidden();
$this->output($foo);
}
}
}
```

**System B (Wants resources from system A)**
``` php
use LegalThings/Authorizer;

class Requester
{
public function requestFooAction($id)
{
...

$encryptedSecret = FooService::requestPermission('/some/resource', 'http://requester.localhost/public.pem', $startTime, $endTime); // this request fills up the authzgen in system A. Also, times are unix timestamps

$decryptedSecret = Authorizer::decrypt($encryptedSecret, 'path/to/private_key.pem'); // this request fills up authz in system A
$foo = FooService::trustedRequest('/some/resource', $decryptedSecret);
}
}

```
68 changes: 50 additions & 18 deletions src/Authorizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ class Authorizer
/**
* Sign a resource, granting access to a specific client
*
* @param string $resource
* @param string $authzgen String with the format: {{certificate_url}};{{time_from}};{{time_to}}
* Time restrictions are unix timestamps, but may be omitted
* @param string $allowedResource
* @param string $authzgen String with the format: {{certificate_url}};{{time_from}};{{time_to}}
* Time restrictions are unix timestamps, but may be omitted
* @return string $encryptedSecret
*/
public static function sign($resource, $authzgen)
public static function sign($allowedResource, $authzgen)
{
if (!isset(self::$globalSecret)) trigger_error('$globalSecret is not set', E_USER_WARNING);

Expand All @@ -29,10 +30,9 @@ public static function sign($resource, $authzgen)
$publicKey = self::downloadPublicKey($cerfiticateUrl);

$resourceSecret = join(';', [
$resource,
$timeStart,
$timeEnd,
hash('sha256', $resource . $_SERVER['HTTP_HOST'] . $timeStart . $timeEnd . self::$globalSecret)
self::generateChecksum($allowedResource, $timeStart, $timeEnd)
]);

openssl_public_encrypt($resourceSecret, $encryptedSecret, $publicKey);
Expand All @@ -41,35 +41,67 @@ public static function sign($resource, $authzgen)
}

/**
* Verify if a resource may be accessed by the client by decrypting a secret
* Verify if a resource may be accessed by the client
*
* @param string $allowedResource
* @param string $authz An encrypted secret with the format:
* {{resource}};{{time_from}};{{time_to}};{{hash}}
* @param string $privateKeyPath Path to the private key of the current application
* @param string $allowedResource
* @param string $decryptedSecret can be retrieved with static::decrypt()
*
* @return boolean
*/
public static function verify($allowedResource, $authz, $privateKeyPath)
public static function verify($allowedResource, $decryptedSecret)
{
$currentTime = time();
$privateKey = file_get_contents($privateKeyPath);

openssl_private_decrypt($authz, $decryptedSecret, $privateKey);
list($resource, $timeStart, $timeEnd) = explode(';', $decryptedSecret) + [null, null, null];
list($timeStart, $timeEnd, $checksum) = explode(';', $decryptedSecret) + [null, null, null];

if ($checksum !== self::generateChecksum($allowedResource, $timeStart, $timeEnd) return false;

$timeStart = strlen($timeStart) > 0 ? (int)$timeStart : ($currentTime - 1);
$timeEnd = strlen($timeEnd) > 0 ? (int)$timeEnd : ($currentTime + 1);

if ($resource !== $allowedResource) return false;
if ($currentTime < $timeStart || $currentTime > $timeEnd) return false;

return true;
}

/**
* Generates a checksum
*
* @param string $allowedResource
* @param string $timeStart
* @param string $timeEnd
*
* @return string
*/
private static function generateChecksum($allowedResource, $timeStart, $timeEnd)
{
return hash('sha256', $allowedResource . $_SERVER['HTTP_HOST'] . $timeStart . $timeEnd . self::$globalSecret)
}

/**
* Decrypt an encrypted secret
*
* @param string $encryptedSecret An encrypted secret with the format:
* {{resource}};{{time_from}};{{time_to}};{{hash}}
* @param string $privateKeyPath Path to the private key of the current application
*
* @return string $decryptedSecret String with the format: {{time_from}};{{time_to}};{{checksum}}
*/
public static function decrypt($encryptedSecret, $privateKeyPath)
{
$privateKey = file_get_contents($privateKeyPath);
openssl_private_decrypt($encryptedSecret, $decryptedSecret, $privateKey);

return $decryptedSecret;
}

/**
* Get a public key through a remote url
*
* @param string $url
* @param string $options Options for the guzzle request
* @param string $url
* @param string $options Options for the guzzle request
*
* @return string
*/
private static function downloadPublicKey($url, $options = [])
{
Expand Down

0 comments on commit 4a08ff2

Please sign in to comment.