-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Commit
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace OC\OCM; | ||
|
||
use OCP\Security\Signature\ISignatoryManager; | ||
|
||
class OCMSignatoryManager implements ISignatoryManager { | ||
Check failure on line 9 in lib/private/OCM/OCMSignatoryManager.php GitHub Actions / static-code-analysisMethodSignatureMismatch
Check failure Code scanning / Psalm MethodSignatureMismatch Error
Method OC\OCM\OCMSignatoryManager::generateSignatory with return type 'OC\OCM\ISignatory' is different to return type 'OCP\Security\Signature\Model\ISignatory' of inherited method OCP\Security\Signature\ISignatoryManager::generateSignatory
|
||
|
||
public function generateSignatory(IIncomingSignedRequest $signedRequest): ISignatory { | ||
Check failure on line 11 in lib/private/OCM/OCMSignatoryManager.php GitHub Actions / static-code-analysisUndefinedClass
Check failure on line 11 in lib/private/OCM/OCMSignatoryManager.php GitHub Actions / static-code-analysisMethodSignatureMismatch
Check failure on line 11 in lib/private/OCM/OCMSignatoryManager.php GitHub Actions / static-code-analysisImplementedParamTypeMismatch
Check failure on line 11 in lib/private/OCM/OCMSignatoryManager.php GitHub Actions / static-code-analysisUndefinedClass
Check failure on line 11 in lib/private/OCM/OCMSignatoryManager.php GitHub Actions / static-code-analysisInvalidReturnType
Check failure Code scanning / Psalm UndefinedClass Error
Class, interface or enum named OC\OCM\IIncomingSignedRequest does not exist
Check failure Code scanning / Psalm MethodSignatureMismatch Error
Argument 1 of OC\OCM\OCMSignatoryManager::generateSignatory has wrong type 'OC\OCM\IIncomingSignedRequest', expecting 'OCP\Security\Signature\Model\IIncomingSignedRequest' as defined by OCP\Security\Signature\ISignatoryManager::generateSignatory
Check failure Code scanning / Psalm ImplementedParamTypeMismatch Error
Argument 1 of OC\OCM\OCMSignatoryManager::generateSignatory has wrong type 'OC\OCM\IIncomingSignedRequest', expecting 'OCP\Security\Signature\Model\IIncomingSignedRequest' as defined by OCP\Security\Signature\ISignatoryManager::generateSignatory
Check failure Code scanning / Psalm UndefinedClass Error
Class, interface or enum named OC\OCM\ISignatory does not exist
Check failure Code scanning / Psalm InvalidReturnType Error
Not all code paths of OC\OCM\OCMSignatoryManager::generateSignatory end in a return statement, return type OC\OCM\ISignatory expected
|
||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace OC\Security\PublicPrivateKeyPairs; | ||
|
||
use OC\Security\PublicPrivateKeyPairs\Model\KeyPair; | ||
use OCP\Security\PublicPrivateKeyPairs\IKeyPairManager; | ||
use OCP\Security\PublicPrivateKeyPairs\Model\IKeyPair; | ||
use OCP\IAppConfig; | ||
|
||
class KeyPairManager implements IKeyPairManager { | ||
public function __construct( | ||
private readonly IAppConfig $appConfig, | ||
) { | ||
} | ||
|
||
public function getKeyPair(string $app, string $name, array $options = []): IKeyPair { | ||
if (!$this->appConfig->hasKey($app, $name, lazy: true)) { | ||
return $this->generateKeyPair($app, $name, $options); | ||
} | ||
|
||
$stored = $this->appConfig->getValueArray($app, $name, lazy: true); | ||
if (!array_key_exists('public', $stored) || | ||
!array_key_exists('private', $stored)) { | ||
return $this->generateKeyPair($app, $name); | ||
} | ||
|
||
$keyPair = new KeyPair($app, $name); | ||
$keyPair->setPublicKey($stored['public']) | ||
->setPrivateKey($stored['private']); | ||
|
||
return $keyPair; | ||
} | ||
|
||
public function deleteKeyPair(string $app, string $name): void { | ||
} | ||
|
||
public function testKeyPair(IKeyPair $keyPair): bool { | ||
// encrypt using private key | ||
// decrypt using public key | ||
// compare | ||
return false; | ||
} | ||
|
||
private function generateKeyPair(string $app, string $name, array $options = []): IKeyPair { | ||
$keyPair = new KeyPair($app, $name); | ||
|
||
[$publicKey, $privateKey] = $this->generateKeys($options); | ||
$keyPair->setPublicKey($publicKey); | ||
$keyPair->setPrivateKey($privateKey); | ||
|
||
$this->appConfig->setValueArray( | ||
$app, 'security.keypair.' . $name, | ||
[ | ||
'public' => $keyPair->getPublicKey(), | ||
'private' => $keyPair->getPrivateKey() | ||
], | ||
lazy: true, | ||
sensitive: true | ||
); | ||
|
||
return $keyPair; | ||
} | ||
|
||
/** | ||
* @param array $options | ||
* | ||
* @return array | ||
*/ | ||
private function generateKeys(array $options = []):array { | ||
$res = openssl_pkey_new( | ||
[ | ||
'digest_alg' => $options['algorithm'] ?? 'rsa', | ||
'private_key_bits' => $options['bits'] ?? 2048, | ||
'private_key_type' => $options['type'] ?? OPENSSL_KEYTYPE_RSA, | ||
] | ||
); | ||
|
||
openssl_pkey_export($res, $privateKey); | ||
$publicKey = openssl_pkey_get_details($res)['key']; | ||
|
||
return [$publicKey, $privateKey]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace OC\Security\PublicPrivateKeyPairs\Model; | ||
|
||
use OCP\Security\PublicPrivateKeyPairs\Model\IKeyPair; | ||
|
||
class KeyPair implements IKeyPair { | ||
private string $publicKey = ''; | ||
private string $privateKey = ''; | ||
|
||
public function __construct( | ||
private readonly string $app, | ||
private readonly string $name | ||
) { | ||
} | ||
|
||
public function getApp(): string { | ||
return $this->app; | ||
} | ||
|
||
public function getName(): string { | ||
return $this->name; | ||
} | ||
|
||
public function setPublicKey(string $publicKey): self { | ||
$this->publicKey = $publicKey; | ||
return $this; | ||
} | ||
|
||
public function getPublicKey(): string { | ||
return $this->publicKey; | ||
} | ||
|
||
public function setPrivateKey(string $privateKey): self { | ||
$this->privateKey = $privateKey; | ||
return $this; | ||
} | ||
|
||
public function getPrivateKey(): string { | ||
return $this->privateKey; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
/** | ||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors | ||
* SPDX-License-Identifier: AGPL-3.0-or-later | ||
*/ | ||
|
||
namespace OC\Security\Signature\Model; | ||
|
||
use JsonSerializable; | ||
use OCP\IRequest; | ||
use OCP\Security\Signature\Exceptions\IncomingRequestNotFoundException; | ||
use OCP\Security\Signature\Model\IIncomingSignedRequest; | ||
|
||
class IncomingSignedRequest extends SignedRequest | ||
implements | ||
IIncomingSignedRequest, | ||
JsonSerializable | ||
{ | ||
private ?IRequest $request = null; | ||
private int $time = 0; | ||
private string $origin; | ||
private string $host; | ||
private string $estimatedSignature; | ||
|
||
public function setRequest(IRequest $request): IIncomingSignedRequest { | ||
$this->request = $request; | ||
return $this; | ||
} | ||
|
||
public function getRequest(): IRequest { | ||
if ($this->request === null) { | ||
throw new IncomingRequestNotFoundException(); | ||
} | ||
return $this->request; | ||
} | ||
|
||
public function setTime(int $time): IIncomingSignedRequest { | ||
$this->time = $time; | ||
return $this; | ||
} | ||
|
||
public function getTime(): int { | ||
return $this->time; | ||
} | ||
|
||
public function setOrigin(string $origin): IIncomingSignedRequest { | ||
$this->origin = $origin; | ||
return $this; | ||
} | ||
|
||
public function getOrigin(): string { | ||
return $this->origin; | ||
} | ||
|
||
/** local address */ | ||
public function setHost(string $host): IIncomingSignedRequest { | ||
$this->host = $host; | ||
return $this; | ||
} | ||
|
||
public function getHost(): string { | ||
return $this->host; | ||
} | ||
|
||
public function setEstimatedSignature(string $signature): IIncomingSignedRequest { | ||
$this->estimatedSignature = $signature; | ||
return $this; | ||
} | ||
|
||
public function getEstimatedSignature(): string { | ||
return $this->estimatedSignature; | ||
} | ||
|
||
public function jsonSerialize(): array { | ||
return array_merge( | ||
parent::jsonSerialize(), | ||
[ | ||
'body' => $this->getBody(), | ||
'time' => $this->getTime(), | ||
'incomingRequest' => $this->request ?? false, | ||
'origin' => $this->getOrigin(), | ||
'host' => $this->getHost(), | ||
'estimatedSignature' => $this->getEstimatedSignature(), | ||
] | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
/** | ||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors | ||
* SPDX-License-Identifier: AGPL-3.0-or-later | ||
*/ | ||
|
||
namespace OC\Security\Signature\Model; | ||
|
||
use JsonSerializable; | ||
use OCP\IRequest; | ||
use OCP\Security\Signature\Model\IOutgoingSignedRequest; | ||
|
||
class OutgoingSignedRequest extends SignedRequest | ||
implements | ||
IOutgoingSignedRequest, | ||
JsonSerializable | ||
{ | ||
private IRequest $request; | ||
private string $host = ''; | ||
private string $clearSignature = ''; | ||
|
||
public function setRequest(IRequest $request): IOutgoingSignedRequest { | ||
$this->request = $request; | ||
return $this; | ||
} | ||
|
||
public function getRequest(): IRequest { | ||
return $this->request; | ||
} | ||
|
||
/** remote address */ | ||
public function setHost(string $host): IOutgoingSignedRequest { | ||
$this->host = $host; | ||
return $this; | ||
} | ||
|
||
public function getHost(): string { | ||
return $this->host; | ||
} | ||
|
||
public function setClearSignature(string $estimated): self { | ||
$this->clearSignature = $estimated; | ||
return $this; | ||
} | ||
|
||
public function getClearSignature(): string { | ||
return $this->clearSignature; | ||
} | ||
|
||
public function jsonSerialize(): array { | ||
return array_merge( | ||
parent::jsonSerialize(), | ||
[ | ||
'outgoingRequest' => $this->request ?? false, | ||
Check failure on line 56 in lib/private/Security/Signature/Model/OutgoingSignedRequest.php GitHub Actions / static-code-analysisRedundantPropertyInitializationCheck
Check failure on line 56 in lib/private/Security/Signature/Model/OutgoingSignedRequest.php GitHub Actions / static-code-analysisRedundantPropertyInitializationCheck
Check failure Code scanning / Psalm RedundantPropertyInitializationCheck Error
Property $this->request with type OCP\IRequest should already be set in the constructor
Check failure Code scanning / Psalm RedundantPropertyInitializationCheck Error
Property $this->request with type OCP\IRequest should already be set in the constructor
|
||
'host' => $this->getHost(), | ||
'clearSignature' => $this->getClearSignature(), | ||
] | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
/** | ||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors | ||
* SPDX-License-Identifier: AGPL-3.0-or-later | ||
*/ | ||
|
||
namespace OC\Security\Signature\Model; | ||
|
||
use JsonSerializable; | ||
use OCP\Security\Signature\Model\ISignatory; | ||
|
||
class Signatory implements ISignatory, JsonSerializable { | ||
public function __construct( | ||
private readonly string $publicKey, | ||
private readonly string $privateKey = '' | ||
) { | ||
} | ||
|
||
public function getPublicKey(): string { | ||
return $this->publicKey; | ||
} | ||
|
||
public function getPrivateKey(): string { | ||
return $this->privateKey; | ||
} | ||
|
||
public function jsonSerialize(): array { | ||
return [ | ||
'publicKey' => $this->getPublicKey(), | ||
'publicKeyChecksum' => ($this->getPublicKey() !== '') ? sha1($this->getPublicKey()) : false, | ||
'privateKeyChecksum' => ($this->getPrivateKey() !== '') ? sha1($this->getPrivateKey()) : false | ||
]; | ||
} | ||
} |