Skip to content
This repository has been archived by the owner on Nov 14, 2023. It is now read-only.

WIP: Minimum headers #13

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
17 changes: 16 additions & 1 deletion src/Context.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class Context
*
* @throws Exception
*/
public function __construct($args)
public function __construct($args = null)
{
if (isset($args['keys']) && isset($args['keyStore'])) {
throw new Exception(__CLASS__.' accepts keys or keyStore but not both');
Expand Down Expand Up @@ -104,6 +104,9 @@ private function headerList()
private function keyStore()
{
if (empty($this->keyStore)) {
if (is_null($this->keys)) {
return null;
}
$this->keyStore = new KeyStore($this->keys);
}

Expand All @@ -122,4 +125,16 @@ private function algorithm()
{
return $this->algorithm;
}

public function addKeys($keys)
{
foreach ($keys as $keyId => $keyValue) {
$newKey = new Key($keyId, $keyValue);
$newKeys[$keyId] = $keyValue;
}
if (empty($this->keyStore)) {
$this->keyStore = new KeyStore();
}
$this->keyStore = $this->keyStore->withKeys($newKeys);
}
}
22 changes: 19 additions & 3 deletions src/KeyStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ class KeyStore implements KeyStoreInterface
/**
* @param array $keys
*/
public function __construct($keys)
public function __construct($keys = null)
{
$this->keys = [];
foreach ($keys as $id => $key) {
$this->keys[$id] = new Key($id, $key);
if (!empty($keys)) {
foreach ($keys as $id => $key) {
$this->keys[$id] = new Key($id, $key);
}
}
}

Expand All @@ -33,4 +35,18 @@ public function fetch($keyId)
throw new KeyStoreException("Key '$keyId' not found");
}
}

public function withKeys($keys)
{
foreach ($keys as $keyId => $value) {
$this->keys[$keyId] = new Key($keyId, $value);
}

return $this;
}

public function getCount()
{
return sizeof($this->keys);
}
}
4 changes: 2 additions & 2 deletions src/SignatureParametersParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,15 @@ private function pair($segment)
*/
private function validate($result)
{
$this->validateAllKeysArePresent($result);
$this->validateRequiredKeysArePresent($result);
}

/**
* @param $result
*
* @throws SignatureParseException
*/
private function validateAllKeysArePresent($result)
private function validateRequiredKeysArePresent($result)
{
// Regexp in pair() ensures no unwanted keys exist.
// Ensure that all mandatory keys exist.
Expand Down
2 changes: 1 addition & 1 deletion src/Verification.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Verification
* @param RequestInterface $message
* @param KeyStoreInterface $keyStore
*/
public function __construct($message, KeyStoreInterface $keyStore, $header)
public function __construct($message, KeyStoreInterface $keyStore = null, $header, $headers = [])
{
$this->message = $message;
$this->keyStore = $keyStore;
Expand Down
51 changes: 50 additions & 1 deletion src/Verifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@ class Verifier
/**
* @param KeyStoreInterface $keyStore
*/
public function __construct(KeyStoreInterface $keyStore)
public function __construct(KeyStoreInterface $keyStore = null, $minimumHeaders = [])
{
// if ( $keyStore ) {
$this->keyStore = $keyStore;
// };
$this->minimumHeaders = $minimumHeaders;
$this->status = [];
}

Expand All @@ -30,6 +33,11 @@ public function __construct(KeyStoreInterface $keyStore)
*/
public function isSigned($message)
{
if (is_null($this->keyStore)) {
$this->status[] = 'No keys provided, cannot verify';

return false;
}
$this->status = [];
try {
$verification = new Verification($message, $this->keyStore, 'Signature');
Expand Down Expand Up @@ -83,6 +91,11 @@ public function isSigned($message)
*/
public function isAuthorized($message)
{
if (is_null($this->keyStore)) {
$this->status[] = 'No keys provided, cannot verify';

return false;
}
$this->status = [];
try {
$verification = new Verification($message, $this->keyStore, 'Authorization');
Expand Down Expand Up @@ -184,4 +197,40 @@ public function getStatus()
{
return $this->status;
}

public function getSignatureParameters($message)
{
$signatureLine = $message->getHeader('Signature')[0];
$signatureParametersParser = new SignatureParametersParser(
$signatureLine
);

return $signatureParametersParser->parse();
}

public function getSignatureKeyId($message)
{
return $this->getSignatureParameters($message)['keyId'];
}

public function getSignatureHeaders($message, $parameter)
{
$parameters = $this->getSignatureParameters($message);
if (!isset($parameters['headers'])) {
return ['date'];
}
$headers = explode(' ', $parameters['headers']);

return $headers;
}

public function setMinimumHeaders(array $minimumHeaders)
{
$this->minimumHeaders = $minimumHeaders;
}

public function getMinimumHeaders()
{
return $this->minimumHeaders;
}
}
29 changes: 29 additions & 0 deletions tests/KeyStoreTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,35 @@

class KeyStoreTest extends TestCase
{
public function testKeyStore()
{
$ks = new KeyStore(['testkey' => 'abc123']);
$this->assertEquals(
'abc123',
$ks->fetch('testkey')->getSigningKey()
);
$this->assertEquals(
'secret',
$ks->fetch('testkey')->getType()
);
$ks = $ks->withKeys([
'testkey2' => 'def456',
'testkey3' => 'foo-bar',
]);
$this->assertEquals(
3,
$ks->getCount()
);
$this->assertEquals(
'abc123',
$ks->fetch('testkey')->getSigningKey()
);
$this->assertEquals(
'secret',
$ks->fetch('testkey2')->getType()
);
}

public function testFetchFail()
{
$ks = new KeyStore(['id' => 'secret']);
Expand Down
Loading