Skip to content
This repository was archived by the owner on Nov 14, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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