Skip to content

Commit 6e45b8c

Browse files
committed
fix(ocm): switching to IdentityProof
Signed-off-by: Maxence Lange <[email protected]>
1 parent 1d42f2b commit 6e45b8c

File tree

21 files changed

+114
-640
lines changed

21 files changed

+114
-640
lines changed

apps/cloud_federation_api/lib/Capabilities.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*/
99
namespace OCA\CloudFederationAPI;
1010

11-
use NCU\Security\PublicPrivateKeyPairs\Exceptions\KeyPairException;
11+
use NCU\Security\Signature\Exceptions\IdentityNotFoundException;
1212
use NCU\Security\Signature\Exceptions\SignatoryException;
1313
use OC\OCM\OCMSignatoryManager;
1414
use OCP\Capabilities\ICapability;
@@ -79,7 +79,7 @@ public function getCapabilities() {
7979
} else {
8080
$this->logger->debug('ocm public key feature disabled');
8181
}
82-
} catch (SignatoryException|KeyPairException $e) {
82+
} catch (SignatoryException|IdentityNotFoundException $e) {
8383
$this->logger->warning('cannot generate local signatory', ['exception' => $e]);
8484
}
8585

apps/cloud_federation_api/lib/Controller/RequestHandlerController.php

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
namespace OCA\CloudFederationAPI\Controller;
77

8+
use NCU\Security\Signature\Exceptions\IdentityNotFoundException;
89
use NCU\Security\Signature\Exceptions\IncomingRequestException;
910
use NCU\Security\Signature\Exceptions\SignatoryNotFoundException;
1011
use NCU\Security\Signature\Exceptions\SignatureException;
@@ -427,16 +428,10 @@ private function getHostFromFederationId(string $entry): string {
427428
}
428429
[, $rightPart] = explode('@', $entry, 2);
429430

430-
$host = parse_url($rightPart, PHP_URL_HOST);
431-
$port = parse_url($rightPart, PHP_URL_PORT);
432-
if ($port !== null && $port !== false) {
433-
$host .= ':' . $port;
434-
}
435-
436-
if (is_string($host) && $host !== '') {
437-
return $host;
431+
try {
432+
return $this->signatureManager->extractIdentityFromUri($rightPart);
433+
} catch (IdentityNotFoundException) {
434+
throw new IncomingRequestException('invalid host within federation id: ' . $entry);
438435
}
439-
440-
throw new IncomingRequestException('host is empty');
441436
}
442437
}

build/integration/federation_features/cleanup-remote-storage.feature

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ Feature: cleanup-remote-storage
3535
# server may have its own /textfile0.txt" file)
3636
And User "user1" copies file "/textfile0.txt" to "/remote-share.txt"
3737
And User "user1" from server "REMOTE" shares "/remote-share.txt" with user "user0" from server "LOCAL"
38-
And As an "user1"
39-
And sending "GET" to "/apps/files_sharing/api/v1/shares"
40-
And the list of returned shares has 1 shares
4138
And Using server "LOCAL"
4239
# Accept and download the file to ensure that a storage is created for the
4340
# federated share

lib/composer/composer/autoload_classmap.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@
77

88
return array(
99
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
10-
'NCU\\Security\\PublicPrivateKeyPairs\\Exceptions\\KeyPairConflictException' => $baseDir . '/lib/unstable/Security/PublicPrivateKeyPairs/Exceptions/KeyPairConflictException.php',
11-
'NCU\\Security\\PublicPrivateKeyPairs\\Exceptions\\KeyPairException' => $baseDir . '/lib/unstable/Security/PublicPrivateKeyPairs/Exceptions/KeyPairException.php',
12-
'NCU\\Security\\PublicPrivateKeyPairs\\Exceptions\\KeyPairNotFoundException' => $baseDir . '/lib/unstable/Security/PublicPrivateKeyPairs/Exceptions/KeyPairNotFoundException.php',
13-
'NCU\\Security\\PublicPrivateKeyPairs\\IKeyPairManager' => $baseDir . '/lib/unstable/Security/PublicPrivateKeyPairs/IKeyPairManager.php',
14-
'NCU\\Security\\PublicPrivateKeyPairs\\Model\\IKeyPair' => $baseDir . '/lib/unstable/Security/PublicPrivateKeyPairs/Model/IKeyPair.php',
1510
'NCU\\Security\\Signature\\Exceptions\\IdentityNotFoundException' => $baseDir . '/lib/unstable/Security/Signature/Exceptions/IdentityNotFoundException.php',
1611
'NCU\\Security\\Signature\\Exceptions\\IncomingRequestException' => $baseDir . '/lib/unstable/Security/Signature/Exceptions/IncomingRequestException.php',
1712
'NCU\\Security\\Signature\\Exceptions\\IncomingRequestNotFoundException' => $baseDir . '/lib/unstable/Security/Signature/Exceptions/IncomingRequestNotFoundException.php',
@@ -1920,8 +1915,6 @@
19201915
'OC\\Security\\Ip\\Range' => $baseDir . '/lib/private/Security/Ip/Range.php',
19211916
'OC\\Security\\Ip\\RemoteAddress' => $baseDir . '/lib/private/Security/Ip/RemoteAddress.php',
19221917
'OC\\Security\\Normalizer\\IpAddress' => $baseDir . '/lib/private/Security/Normalizer/IpAddress.php',
1923-
'OC\\Security\\PublicPrivateKeyPairs\\KeyPairManager' => $baseDir . '/lib/private/Security/PublicPrivateKeyPairs/KeyPairManager.php',
1924-
'OC\\Security\\PublicPrivateKeyPairs\\Model\\KeyPair' => $baseDir . '/lib/private/Security/PublicPrivateKeyPairs/Model/KeyPair.php',
19251918
'OC\\Security\\RateLimiting\\Backend\\DatabaseBackend' => $baseDir . '/lib/private/Security/RateLimiting/Backend/DatabaseBackend.php',
19261919
'OC\\Security\\RateLimiting\\Backend\\IBackend' => $baseDir . '/lib/private/Security/RateLimiting/Backend/IBackend.php',
19271920
'OC\\Security\\RateLimiting\\Backend\\MemoryCacheBackend' => $baseDir . '/lib/private/Security/RateLimiting/Backend/MemoryCacheBackend.php',

lib/composer/composer/autoload_static.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
4848

4949
public static $classMap = array (
5050
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
51-
'NCU\\Security\\PublicPrivateKeyPairs\\Exceptions\\KeyPairConflictException' => __DIR__ . '/../../..' . '/lib/unstable/Security/PublicPrivateKeyPairs/Exceptions/KeyPairConflictException.php',
52-
'NCU\\Security\\PublicPrivateKeyPairs\\Exceptions\\KeyPairException' => __DIR__ . '/../../..' . '/lib/unstable/Security/PublicPrivateKeyPairs/Exceptions/KeyPairException.php',
53-
'NCU\\Security\\PublicPrivateKeyPairs\\Exceptions\\KeyPairNotFoundException' => __DIR__ . '/../../..' . '/lib/unstable/Security/PublicPrivateKeyPairs/Exceptions/KeyPairNotFoundException.php',
54-
'NCU\\Security\\PublicPrivateKeyPairs\\IKeyPairManager' => __DIR__ . '/../../..' . '/lib/unstable/Security/PublicPrivateKeyPairs/IKeyPairManager.php',
55-
'NCU\\Security\\PublicPrivateKeyPairs\\Model\\IKeyPair' => __DIR__ . '/../../..' . '/lib/unstable/Security/PublicPrivateKeyPairs/Model/IKeyPair.php',
5651
'NCU\\Security\\Signature\\Exceptions\\IdentityNotFoundException' => __DIR__ . '/../../..' . '/lib/unstable/Security/Signature/Exceptions/IdentityNotFoundException.php',
5752
'NCU\\Security\\Signature\\Exceptions\\IncomingRequestException' => __DIR__ . '/../../..' . '/lib/unstable/Security/Signature/Exceptions/IncomingRequestException.php',
5853
'NCU\\Security\\Signature\\Exceptions\\IncomingRequestNotFoundException' => __DIR__ . '/../../..' . '/lib/unstable/Security/Signature/Exceptions/IncomingRequestNotFoundException.php',
@@ -1961,8 +1956,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
19611956
'OC\\Security\\Ip\\Range' => __DIR__ . '/../../..' . '/lib/private/Security/Ip/Range.php',
19621957
'OC\\Security\\Ip\\RemoteAddress' => __DIR__ . '/../../..' . '/lib/private/Security/Ip/RemoteAddress.php',
19631958
'OC\\Security\\Normalizer\\IpAddress' => __DIR__ . '/../../..' . '/lib/private/Security/Normalizer/IpAddress.php',
1964-
'OC\\Security\\PublicPrivateKeyPairs\\KeyPairManager' => __DIR__ . '/../../..' . '/lib/private/Security/PublicPrivateKeyPairs/KeyPairManager.php',
1965-
'OC\\Security\\PublicPrivateKeyPairs\\Model\\KeyPair' => __DIR__ . '/../../..' . '/lib/private/Security/PublicPrivateKeyPairs/Model/KeyPair.php',
19661959
'OC\\Security\\RateLimiting\\Backend\\DatabaseBackend' => __DIR__ . '/../../..' . '/lib/private/Security/RateLimiting/Backend/DatabaseBackend.php',
19671960
'OC\\Security\\RateLimiting\\Backend\\IBackend' => __DIR__ . '/../../..' . '/lib/private/Security/RateLimiting/Backend/IBackend.php',
19681961
'OC\\Security\\RateLimiting\\Backend\\MemoryCacheBackend' => __DIR__ . '/../../..' . '/lib/private/Security/RateLimiting/Backend/MemoryCacheBackend.php',

lib/private/Federation/CloudFederationProviderManager.php

Lines changed: 45 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use OCP\Federation\ICloudFederationProviderManager;
1919
use OCP\Federation\ICloudFederationShare;
2020
use OCP\Federation\ICloudIdManager;
21+
use OCP\Http\Client\IClient;
2122
use OCP\Http\Client\IClientService;
2223
use OCP\Http\Client\IResponse;
2324
use OCP\IAppConfig;
@@ -105,25 +106,11 @@ public function getCloudFederationProvider($resourceType) {
105106
public function sendShare(ICloudFederationShare $share) {
106107
$cloudID = $this->cloudIdManager->resolveCloudId($share->getShareWith());
107108
try {
108-
$ocmProvider = $this->discoveryService->discover($cloudID->getRemote());
109-
} catch (OCMProviderException $e) {
110-
return false;
111-
}
112-
113-
$client = $this->httpClientService->newClient();
114-
try {
115-
// signing the payload using OCMSignatoryManager before initializing the request
116-
$uri = $ocmProvider->getEndPoint() . '/shares';
117-
$payload = array_merge($this->getDefaultRequestOptions(), ['body' => json_encode($share->getShare())]);
118-
if (!$this->appConfig->getValueBool('core', OCMSignatoryManager::APPCONFIG_SIGN_DISABLED, lazy: true)) {
119-
$signedPayload = $this->signatureManager->signOutgoingRequestIClientPayload(
120-
$this->signatoryManager,
121-
$payload,
122-
'post', $uri
123-
);
109+
try {
110+
$response = $this->postOcmPayload($cloudID->getRemote(), '/shares', json_encode($share->getShare()));
111+
} catch (OCMProviderException) {
112+
return false;
124113
}
125-
$response = $client->post($uri, $signedPayload ?? $payload);
126-
127114
if ($response->getStatusCode() === Http::STATUS_CREATED) {
128115
$result = json_decode($response->getBody(), true);
129116
return (is_array($result)) ? $result : [];
@@ -149,22 +136,9 @@ public function sendShare(ICloudFederationShare $share) {
149136
*/
150137
public function sendCloudShare(ICloudFederationShare $share): IResponse {
151138
$cloudID = $this->cloudIdManager->resolveCloudId($share->getShareWith());
152-
$ocmProvider = $this->discoveryService->discover($cloudID->getRemote());
153-
154139
$client = $this->httpClientService->newClient();
155140
try {
156-
// signing the payload using OCMSignatoryManager before initializing the request
157-
$uri = $ocmProvider->getEndPoint() . '/shares';
158-
$payload = array_merge($this->getDefaultRequestOptions(), ['body' => json_encode($share->getShare())]);
159-
if (!$this->appConfig->getValueBool('core', OCMSignatoryManager::APPCONFIG_SIGN_DISABLED, lazy: true)) {
160-
$signedPayload = $this->signatureManager->signOutgoingRequestIClientPayload(
161-
$this->signatoryManager,
162-
$payload,
163-
'post', $uri
164-
);
165-
}
166-
167-
return $client->post($uri, $signedPayload ?? $payload);
141+
return $this->postOcmPayload($cloudID->getRemote(), '/shares', json_encode($share->getShare()), $client);
168142
} catch (\Throwable $e) {
169143
$this->logger->error('Error while sending share to federation server: ' . $e->getMessage(), ['exception' => $e]);
170144
try {
@@ -183,26 +157,11 @@ public function sendCloudShare(ICloudFederationShare $share): IResponse {
183157
*/
184158
public function sendNotification($url, ICloudFederationNotification $notification) {
185159
try {
186-
$ocmProvider = $this->discoveryService->discover($url);
187-
} catch (OCMProviderException $e) {
188-
return false;
189-
}
190-
191-
$client = $this->httpClientService->newClient();
192-
try {
193-
194-
// signing the payload using OCMSignatoryManager before initializing the request
195-
$uri = $ocmProvider->getEndPoint() . '/notifications';
196-
$payload = array_merge($this->getDefaultRequestOptions(), ['body' => json_encode($notification->getMessage())]);
197-
if (!$this->appConfig->getValueBool('core', OCMSignatoryManager::APPCONFIG_SIGN_DISABLED, lazy: true)) {
198-
$signedPayload = $this->signatureManager->signOutgoingRequestIClientPayload(
199-
$this->signatoryManager,
200-
$payload,
201-
'post', $uri
202-
);
160+
try {
161+
$response = $this->postOcmPayload($url, '/notifications', json_encode($notification->getMessage()));
162+
} catch (OCMProviderException) {
163+
return false;
203164
}
204-
$response = $client->post($uri, $signedPayload ?? $payload);
205-
206165
if ($response->getStatusCode() === Http::STATUS_CREATED) {
207166
$result = json_decode($response->getBody(), true);
208167
return (is_array($result)) ? $result : [];
@@ -222,21 +181,9 @@ public function sendNotification($url, ICloudFederationNotification $notificatio
222181
* @throws OCMProviderException
223182
*/
224183
public function sendCloudNotification(string $url, ICloudFederationNotification $notification): IResponse {
225-
$ocmProvider = $this->discoveryService->discover($url);
226-
227184
$client = $this->httpClientService->newClient();
228185
try {
229-
// signing the payload using OCMSignatoryManager before initializing the request
230-
$uri = $ocmProvider->getEndPoint() . '/notifications';
231-
$payload = array_merge($this->getDefaultRequestOptions(), ['body' => json_encode($notification->getMessage())]);
232-
if (!$this->appConfig->getValueBool('core', OCMSignatoryManager::APPCONFIG_SIGN_DISABLED, lazy: true)) {
233-
$signedPayload = $this->signatureManager->signOutgoingRequestIClientPayload(
234-
$this->signatoryManager,
235-
$payload,
236-
'post', $uri
237-
);
238-
}
239-
return $client->post($uri, $signedPayload ?? $payload);
186+
return $this->postOcmPayload($url, '/notifications', json_encode($notification->getMessage()), $client);
240187
} catch (\Throwable $e) {
241188
$this->logger->error('Error while sending notification to federation server: ' . $e->getMessage(), ['exception' => $e]);
242189
try {
@@ -256,6 +203,40 @@ public function isReady() {
256203
return $this->appManager->isEnabledForUser('cloud_federation_api');
257204
}
258205

206+
/**
207+
* @param string $cloudId
208+
* @param string $uri
209+
* @param string $payload
210+
*
211+
* @return IResponse
212+
* @throws OCMProviderException
213+
*/
214+
private function postOcmPayload(string $cloudId, string $uri, string $payload, ?IClient $client = null): IResponse {
215+
$ocmProvider = $this->discoveryService->discover($cloudId);
216+
$uri = $ocmProvider->getEndPoint() . '/' . ltrim($uri, '/');
217+
$client = $client ?? $this->httpClientService->newClient();
218+
return $client->post($uri, $this->prepareOcmPayload($uri, $payload));
219+
}
220+
221+
/**
222+
* @param string $uri
223+
* @param string $payload
224+
*
225+
* @return array
226+
*/
227+
private function prepareOcmPayload(string $uri, string $payload): array {
228+
$payload = array_merge($this->getDefaultRequestOptions(), ['body' => $payload]);
229+
if (!$this->appConfig->getValueBool('core', OCMSignatoryManager::APPCONFIG_SIGN_DISABLED, lazy: true)) {
230+
$signedPayload = $this->signatureManager->signOutgoingRequestIClientPayload(
231+
$this->signatoryManager,
232+
$payload,
233+
'post', $uri
234+
);
235+
}
236+
237+
return $signedPayload ?? $payload;
238+
}
239+
259240
private function getDefaultRequestOptions(): array {
260241
return [
261242
'headers' => ['content-type' => 'application/json'],

lib/private/Files/Storage/DAV.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ class DAV extends Common {
6464
protected $httpClientService;
6565
/** @var ICertificateManager */
6666
protected $certManager;
67-
protected bool $verify = true;
6867
protected LoggerInterface $logger;
6968
protected IEventLogger $eventLogger;
7069
protected IMimeTypeDetector $mimeTypeDetector;
@@ -104,7 +103,6 @@ public function __construct(array $parameters) {
104103
if (isset($parameters['authType'])) {
105104
$this->authType = $parameters['authType'];
106105
}
107-
$this->verify = (($parameters['verify'] ?? true) !== false);
108106
if (isset($parameters['secure'])) {
109107
if (is_string($parameters['secure'])) {
110108
$this->secure = ($parameters['secure'] === 'true');
@@ -164,11 +162,6 @@ protected function init(): void {
164162
}
165163
}
166164

167-
if (!$this->verify) {
168-
$this->client->addCurlSetting(CURLOPT_SSL_VERIFYHOST, 0);
169-
$this->client->addCurlSetting(CURLOPT_SSL_VERIFYPEER, false);
170-
}
171-
172165
$lastRequestStart = 0;
173166
$this->client->on('beforeRequest', function (RequestInterface $request) use (&$lastRequestStart) {
174167
$this->logger->debug('sending dav ' . $request->getMethod() . ' request to external storage: ' . $request->getAbsoluteUrl(), ['app' => 'dav']);

lib/private/OCM/Model/OCMProvider.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,11 @@ private function looksValid(): bool {
210210
* apiVersion: '1.0-proposal1',
211211
* endPoint: string,
212212
* publicKey: ISignatory|null,
213-
* resourceTypes: array{
213+
* resourceTypes: list<array{
214214
* name: string,
215215
* shareTypes: list<string>,
216216
* protocols: array<string, string>
217-
* }[],
217+
* }>,
218218
* version: string
219219
* }
220220
*/

lib/private/OCM/OCMDiscoveryService.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ public function __construct(
4646
*/
4747
public function discover(string $remote, bool $skipCache = false): IOCMProvider {
4848
$remote = rtrim($remote, '/');
49+
if (!str_starts_with($remote, 'http')) {
50+
$remote = 'https://' . $remote;
51+
}
4952

5053
if (!$skipCache) {
5154
try {

lib/private/OCM/OCMSignatoryManager.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,13 @@
88
*/
99
namespace OC\OCM;
1010

11-
use NCU\Security\PublicPrivateKeyPairs\Exceptions\KeyPairConflictException;
12-
use NCU\Security\PublicPrivateKeyPairs\Exceptions\KeyPairNotFoundException;
13-
use NCU\Security\PublicPrivateKeyPairs\IKeyPairManager;
1411
use NCU\Security\Signature\Exceptions\IdentityNotFoundException;
1512
use NCU\Security\Signature\ISignatoryManager;
1613
use NCU\Security\Signature\ISignatureManager;
1714
use NCU\Security\Signature\Model\IIncomingSignedRequest;
1815
use NCU\Security\Signature\Model\ISignatory;
1916
use NCU\Security\Signature\Model\SignatoryType;
17+
use OC\Security\IdentityProof\Manager;
2018
use OC\Security\Signature\Model\Signatory;
2119
use OCP\IAppConfig;
2220
use OCP\IURLGenerator;
@@ -40,7 +38,7 @@ public function __construct(
4038
private readonly IAppConfig $appConfig,
4139
private readonly ISignatureManager $signatureManager,
4240
private readonly IURLGenerator $urlGenerator,
43-
private readonly IKeyPairManager $keyPairManager,
41+
private readonly Manager $identityProofManager,
4442
private readonly OCMDiscoveryService $ocmDiscoveryService,
4543
) {
4644
}
@@ -69,7 +67,6 @@ public function getOptions(): array {
6967
* @inheritDoc
7068
*
7169
* @return ISignatory
72-
* @throws KeyPairConflictException
7370
* @throws IdentityNotFoundException
7471
* @since 31.0.0
7572
*/
@@ -85,13 +82,16 @@ public function getLocalSignatory(): ISignatory {
8582
$keyId = $this->generateKeyId();
8683
}
8784

88-
try {
89-
$keyPair = $this->keyPairManager->getKeyPair('core', 'ocm_external');
90-
} catch (KeyPairNotFoundException) {
91-
$keyPair = $this->keyPairManager->generateKeyPair('core', 'ocm_external');
85+
if ($this->identityProofManager->hasAppKey('core', 'ocm_external')) {
86+
$this->identityProofManager->generateAppKey('core', 'ocm_external', [
87+
'digest_alg' => 'rsa',
88+
'private_key_bits' => 2048,
89+
'private_key_type' => OPENSSL_KEYTYPE_RSA,
90+
]);
9291
}
92+
$keyPair = $this->identityProofManager->getAppKey('core', 'ocm_external');
9393

94-
return new Signatory($keyId, $keyPair->getPublicKey(), $keyPair->getPrivateKey(), local: true);
94+
return new Signatory($keyId, $keyPair->getPublic(), $keyPair->getPrivate(), local: true);
9595
}
9696

9797
/**

0 commit comments

Comments
 (0)