| Total Complexity | 87 |
| Total Lines | 718 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like KeyManager often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use KeyManager, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 46 | class KeyManager { |
||
| 47 | |||
| 48 | /** |
||
| 49 | * @var Session |
||
| 50 | */ |
||
| 51 | protected $session; |
||
| 52 | /** |
||
| 53 | * @var IStorage |
||
| 54 | */ |
||
| 55 | private $keyStorage; |
||
| 56 | /** |
||
| 57 | * @var Crypt |
||
| 58 | */ |
||
| 59 | private $crypt; |
||
| 60 | /** |
||
| 61 | * @var string |
||
| 62 | */ |
||
| 63 | private $recoveryKeyId; |
||
| 64 | /** |
||
| 65 | * @var string |
||
| 66 | */ |
||
| 67 | private $publicShareKeyId; |
||
| 68 | /** |
||
| 69 | * @var string |
||
| 70 | */ |
||
| 71 | private $masterKeyId; |
||
| 72 | /** |
||
| 73 | * @var string UserID |
||
| 74 | */ |
||
| 75 | private $keyId; |
||
| 76 | /** |
||
| 77 | * @var string |
||
| 78 | */ |
||
| 79 | private $publicKeyId = 'publicKey'; |
||
| 80 | /** |
||
| 81 | * @var string |
||
| 82 | */ |
||
| 83 | private $privateKeyId = 'privateKey'; |
||
| 84 | |||
| 85 | /** |
||
| 86 | * @var string |
||
| 87 | */ |
||
| 88 | private $shareKeyId = 'shareKey'; |
||
| 89 | |||
| 90 | /** |
||
| 91 | * @var string |
||
| 92 | */ |
||
| 93 | private $fileKeyId = 'fileKey'; |
||
| 94 | /** |
||
| 95 | * @var IConfig |
||
| 96 | */ |
||
| 97 | private $config; |
||
| 98 | /** |
||
| 99 | * @var ILogger |
||
| 100 | */ |
||
| 101 | private $log; |
||
| 102 | /** |
||
| 103 | * @var Util |
||
| 104 | */ |
||
| 105 | private $util; |
||
| 106 | |||
| 107 | /** |
||
| 108 | * @var ILockingProvider |
||
| 109 | */ |
||
| 110 | private $lockingProvider; |
||
| 111 | |||
| 112 | /** |
||
| 113 | * @param IStorage $keyStorage |
||
| 114 | * @param Crypt $crypt |
||
| 115 | * @param IConfig $config |
||
| 116 | * @param IUserSession $userSession |
||
| 117 | * @param Session $session |
||
| 118 | * @param ILogger $log |
||
| 119 | * @param Util $util |
||
| 120 | */ |
||
| 121 | public function __construct( |
||
| 122 | IStorage $keyStorage, |
||
| 123 | Crypt $crypt, |
||
| 124 | IConfig $config, |
||
| 125 | IUserSession $userSession, |
||
| 126 | Session $session, |
||
| 127 | ILogger $log, |
||
| 128 | Util $util, |
||
| 129 | ILockingProvider $lockingProvider |
||
| 130 | ) { |
||
| 131 | $this->util = $util; |
||
| 132 | $this->session = $session; |
||
| 133 | $this->keyStorage = $keyStorage; |
||
| 134 | $this->crypt = $crypt; |
||
| 135 | $this->config = $config; |
||
| 136 | $this->log = $log; |
||
| 137 | $this->lockingProvider = $lockingProvider; |
||
| 138 | |||
| 139 | $this->recoveryKeyId = $this->config->getAppValue('encryption', |
||
| 140 | 'recoveryKeyId'); |
||
| 141 | if (empty($this->recoveryKeyId)) { |
||
| 142 | $this->recoveryKeyId = 'recoveryKey_' . substr(md5(time()), 0, 8); |
||
| 143 | $this->config->setAppValue('encryption', |
||
| 144 | 'recoveryKeyId', |
||
| 145 | $this->recoveryKeyId); |
||
| 146 | } |
||
| 147 | |||
| 148 | $this->publicShareKeyId = $this->config->getAppValue('encryption', |
||
| 149 | 'publicShareKeyId'); |
||
| 150 | if (empty($this->publicShareKeyId)) { |
||
| 151 | $this->publicShareKeyId = 'pubShare_' . substr(md5(time()), 0, 8); |
||
| 152 | $this->config->setAppValue('encryption', 'publicShareKeyId', $this->publicShareKeyId); |
||
| 153 | } |
||
| 154 | |||
| 155 | $this->masterKeyId = $this->config->getAppValue('encryption', |
||
| 156 | 'masterKeyId'); |
||
| 157 | if (empty($this->masterKeyId)) { |
||
| 158 | $this->masterKeyId = 'master_' . substr(md5(time()), 0, 8); |
||
| 159 | $this->config->setAppValue('encryption', 'masterKeyId', $this->masterKeyId); |
||
| 160 | } |
||
| 161 | |||
| 162 | $this->keyId = $userSession && $userSession->isLoggedIn() ? $userSession->getUser()->getUID() : false; |
||
|
|
|||
| 163 | $this->log = $log; |
||
| 164 | } |
||
| 165 | |||
| 166 | /** |
||
| 167 | * check if key pair for public link shares exists, if not we create one |
||
| 168 | */ |
||
| 169 | public function validateShareKey() { |
||
| 170 | $shareKey = $this->getPublicShareKey(); |
||
| 171 | if (empty($shareKey)) { |
||
| 172 | $this->lockingProvider->acquireLock('encryption-generateSharedKey', ILockingProvider::LOCK_EXCLUSIVE, 'Encryption: shared key generation'); |
||
| 173 | try { |
||
| 174 | $keyPair = $this->crypt->createKeyPair(); |
||
| 175 | |||
| 176 | // Save public key |
||
| 177 | $this->keyStorage->setSystemUserKey( |
||
| 178 | $this->publicShareKeyId . '.' . $this->publicKeyId, $keyPair['publicKey'], |
||
| 179 | Encryption::ID); |
||
| 180 | |||
| 181 | // Encrypt private key empty passphrase |
||
| 182 | $encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], ''); |
||
| 183 | $header = $this->crypt->generateHeader(); |
||
| 184 | $this->setSystemPrivateKey($this->publicShareKeyId, $header . $encryptedKey); |
||
| 185 | } catch (\Throwable $e) { |
||
| 186 | $this->lockingProvider->releaseLock('encryption-generateSharedKey', ILockingProvider::LOCK_EXCLUSIVE); |
||
| 187 | throw $e; |
||
| 188 | } |
||
| 189 | $this->lockingProvider->releaseLock('encryption-generateSharedKey', ILockingProvider::LOCK_EXCLUSIVE); |
||
| 190 | } |
||
| 191 | } |
||
| 192 | |||
| 193 | /** |
||
| 194 | * check if a key pair for the master key exists, if not we create one |
||
| 195 | */ |
||
| 196 | public function validateMasterKey() { |
||
| 197 | if ($this->util->isMasterKeyEnabled() === false) { |
||
| 198 | return; |
||
| 199 | } |
||
| 200 | |||
| 201 | $publicMasterKey = $this->getPublicMasterKey(); |
||
| 202 | $privateMasterKey = $this->getPrivateMasterKey(); |
||
| 203 | |||
| 204 | if (empty($publicMasterKey) && empty($privateMasterKey)) { |
||
| 205 | // There could be a race condition here if two requests would trigger |
||
| 206 | // the generation the second one would enter the key generation as long |
||
| 207 | // as the first one didn't write the key to the keystorage yet |
||
| 208 | $this->lockingProvider->acquireLock('encryption-generateMasterKey', ILockingProvider::LOCK_EXCLUSIVE, 'Encryption: master key generation'); |
||
| 209 | try { |
||
| 210 | $keyPair = $this->crypt->createKeyPair(); |
||
| 211 | |||
| 212 | // Save public key |
||
| 213 | $this->keyStorage->setSystemUserKey( |
||
| 214 | $this->masterKeyId . '.' . $this->publicKeyId, $keyPair['publicKey'], |
||
| 215 | Encryption::ID); |
||
| 216 | |||
| 217 | // Encrypt private key with system password |
||
| 218 | $encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $this->getMasterKeyPassword(), $this->masterKeyId); |
||
| 219 | $header = $this->crypt->generateHeader(); |
||
| 220 | $this->setSystemPrivateKey($this->masterKeyId, $header . $encryptedKey); |
||
| 221 | } catch (\Throwable $e) { |
||
| 222 | $this->lockingProvider->releaseLock('encryption-generateMasterKey', ILockingProvider::LOCK_EXCLUSIVE); |
||
| 223 | throw $e; |
||
| 224 | } |
||
| 225 | $this->lockingProvider->releaseLock('encryption-generateMasterKey', ILockingProvider::LOCK_EXCLUSIVE); |
||
| 226 | } elseif (empty($publicMasterKey)) { |
||
| 227 | $this->log->error('A private master key is available but the public key could not be found. This should never happen.'); |
||
| 228 | return; |
||
| 229 | } elseif (empty($privateMasterKey)) { |
||
| 230 | $this->log->error('A public master key is available but the private key could not be found. This should never happen.'); |
||
| 231 | return; |
||
| 232 | } |
||
| 233 | |||
| 234 | if (!$this->session->isPrivateKeySet()) { |
||
| 235 | $masterKey = $this->getSystemPrivateKey($this->masterKeyId); |
||
| 236 | $decryptedMasterKey = $this->crypt->decryptPrivateKey($masterKey, $this->getMasterKeyPassword(), $this->masterKeyId); |
||
| 237 | $this->session->setPrivateKey($decryptedMasterKey); |
||
| 238 | } |
||
| 239 | |||
| 240 | // after the encryption key is available we are ready to go |
||
| 241 | $this->session->setStatus(Session::INIT_SUCCESSFUL); |
||
| 242 | } |
||
| 243 | |||
| 244 | /** |
||
| 245 | * @return bool |
||
| 246 | */ |
||
| 247 | public function recoveryKeyExists() { |
||
| 248 | $key = $this->getRecoveryKey(); |
||
| 249 | return !empty($key); |
||
| 250 | } |
||
| 251 | |||
| 252 | /** |
||
| 253 | * get recovery key |
||
| 254 | * |
||
| 255 | * @return string |
||
| 256 | */ |
||
| 257 | public function getRecoveryKey() { |
||
| 258 | return $this->keyStorage->getSystemUserKey($this->recoveryKeyId . '.' . $this->publicKeyId, Encryption::ID); |
||
| 259 | } |
||
| 260 | |||
| 261 | /** |
||
| 262 | * get recovery key ID |
||
| 263 | * |
||
| 264 | * @return string |
||
| 265 | */ |
||
| 266 | public function getRecoveryKeyId() { |
||
| 267 | return $this->recoveryKeyId; |
||
| 268 | } |
||
| 269 | |||
| 270 | /** |
||
| 271 | * @param string $password |
||
| 272 | * @return bool |
||
| 273 | */ |
||
| 274 | public function checkRecoveryPassword($password) { |
||
| 282 | } |
||
| 283 | |||
| 284 | /** |
||
| 285 | * @param string $uid |
||
| 286 | * @param string $password |
||
| 287 | * @param array $keyPair |
||
| 288 | * @return bool |
||
| 289 | */ |
||
| 290 | public function storeKeyPair($uid, $password, $keyPair) { |
||
| 291 | // Save Public Key |
||
| 292 | $this->setPublicKey($uid, $keyPair['publicKey']); |
||
| 293 | |||
| 294 | $encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $password, $uid); |
||
| 295 | |||
| 296 | $header = $this->crypt->generateHeader(); |
||
| 297 | |||
| 298 | if ($encryptedKey) { |
||
| 299 | $this->setPrivateKey($uid, $header . $encryptedKey); |
||
| 300 | return true; |
||
| 301 | } |
||
| 302 | return false; |
||
| 303 | } |
||
| 304 | |||
| 305 | /** |
||
| 306 | * @param string $password |
||
| 307 | * @param array $keyPair |
||
| 308 | * @return bool |
||
| 309 | */ |
||
| 310 | public function setRecoveryKey($password, $keyPair) { |
||
| 311 | // Save Public Key |
||
| 312 | $this->keyStorage->setSystemUserKey($this->getRecoveryKeyId(). |
||
| 313 | '.' . $this->publicKeyId, |
||
| 314 | $keyPair['publicKey'], |
||
| 315 | Encryption::ID); |
||
| 316 | |||
| 317 | $encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $password); |
||
| 318 | $header = $this->crypt->generateHeader(); |
||
| 319 | |||
| 320 | if ($encryptedKey) { |
||
| 321 | $this->setSystemPrivateKey($this->getRecoveryKeyId(), $header . $encryptedKey); |
||
| 322 | return true; |
||
| 323 | } |
||
| 324 | return false; |
||
| 325 | } |
||
| 326 | |||
| 327 | /** |
||
| 328 | * @param $userId |
||
| 329 | * @param $key |
||
| 330 | * @return bool |
||
| 331 | */ |
||
| 332 | public function setPublicKey($userId, $key) { |
||
| 333 | return $this->keyStorage->setUserKey($userId, $this->publicKeyId, $key, Encryption::ID); |
||
| 334 | } |
||
| 335 | |||
| 336 | /** |
||
| 337 | * @param $userId |
||
| 338 | * @param string $key |
||
| 339 | * @return bool |
||
| 340 | */ |
||
| 341 | public function setPrivateKey($userId, $key) { |
||
| 342 | return $this->keyStorage->setUserKey($userId, |
||
| 343 | $this->privateKeyId, |
||
| 344 | $key, |
||
| 345 | Encryption::ID); |
||
| 346 | } |
||
| 347 | |||
| 348 | /** |
||
| 349 | * write file key to key storage |
||
| 350 | * |
||
| 351 | * @param string $path |
||
| 352 | * @param string $key |
||
| 353 | * @return boolean |
||
| 354 | */ |
||
| 355 | public function setFileKey($path, $key) { |
||
| 356 | return $this->keyStorage->setFileKey($path, $this->fileKeyId, $key, Encryption::ID); |
||
| 357 | } |
||
| 358 | |||
| 359 | /** |
||
| 360 | * set all file keys (the file key and the corresponding share keys) |
||
| 361 | * |
||
| 362 | * @param string $path |
||
| 363 | * @param array $keys |
||
| 364 | */ |
||
| 365 | public function setAllFileKeys($path, $keys) { |
||
| 366 | $this->setFileKey($path, $keys['data']); |
||
| 367 | foreach ($keys['keys'] as $uid => $keyFile) { |
||
| 368 | $this->setShareKey($path, $uid, $keyFile); |
||
| 369 | } |
||
| 370 | } |
||
| 371 | |||
| 372 | /** |
||
| 373 | * write share key to the key storage |
||
| 374 | * |
||
| 375 | * @param string $path |
||
| 376 | * @param string $uid |
||
| 377 | * @param string $key |
||
| 378 | * @return boolean |
||
| 379 | */ |
||
| 380 | public function setShareKey($path, $uid, $key) { |
||
| 381 | $keyId = $uid . '.' . $this->shareKeyId; |
||
| 382 | return $this->keyStorage->setFileKey($path, $keyId, $key, Encryption::ID); |
||
| 383 | } |
||
| 384 | |||
| 385 | /** |
||
| 386 | * Decrypt private key and store it |
||
| 387 | * |
||
| 388 | * @param string $uid user id |
||
| 389 | * @param string $passPhrase users password |
||
| 390 | * @return boolean |
||
| 391 | */ |
||
| 392 | public function init($uid, $passPhrase) { |
||
| 393 | $this->session->setStatus(Session::INIT_EXECUTED); |
||
| 394 | |||
| 395 | try { |
||
| 396 | if ($this->util->isMasterKeyEnabled()) { |
||
| 397 | $uid = $this->getMasterKeyId(); |
||
| 398 | $passPhrase = $this->getMasterKeyPassword(); |
||
| 399 | $privateKey = $this->getSystemPrivateKey($uid); |
||
| 400 | } else { |
||
| 401 | $privateKey = $this->getPrivateKey($uid); |
||
| 402 | } |
||
| 403 | $privateKey = $this->crypt->decryptPrivateKey($privateKey, $passPhrase, $uid); |
||
| 404 | } catch (PrivateKeyMissingException $e) { |
||
| 405 | return false; |
||
| 406 | } catch (DecryptionFailedException $e) { |
||
| 407 | return false; |
||
| 408 | } catch (\Exception $e) { |
||
| 409 | $this->log->logException($e, [ |
||
| 410 | 'message' => 'Could not decrypt the private key from user "' . $uid . '"" during login. Assume password change on the user back-end.', |
||
| 411 | 'level' => ILogger::WARN, |
||
| 412 | 'app' => 'encryption', |
||
| 413 | ]); |
||
| 414 | return false; |
||
| 415 | } |
||
| 416 | |||
| 417 | if ($privateKey) { |
||
| 418 | $this->session->setPrivateKey($privateKey); |
||
| 419 | $this->session->setStatus(Session::INIT_SUCCESSFUL); |
||
| 420 | return true; |
||
| 421 | } |
||
| 422 | |||
| 423 | return false; |
||
| 424 | } |
||
| 425 | |||
| 426 | /** |
||
| 427 | * @param $userId |
||
| 428 | * @return string |
||
| 429 | * @throws PrivateKeyMissingException |
||
| 430 | */ |
||
| 431 | public function getPrivateKey($userId) { |
||
| 432 | $privateKey = $this->keyStorage->getUserKey($userId, |
||
| 433 | $this->privateKeyId, Encryption::ID); |
||
| 434 | |||
| 435 | if (strlen($privateKey) !== 0) { |
||
| 436 | return $privateKey; |
||
| 437 | } |
||
| 438 | throw new PrivateKeyMissingException($userId); |
||
| 439 | } |
||
| 440 | |||
| 441 | /** |
||
| 442 | * @param string $path |
||
| 443 | * @param $uid |
||
| 444 | * @return string |
||
| 445 | */ |
||
| 446 | public function getFileKey($path, $uid) { |
||
| 447 | if ($uid === '') { |
||
| 448 | $uid = null; |
||
| 449 | } |
||
| 450 | $publicAccess = is_null($uid); |
||
| 451 | $encryptedFileKey = $this->keyStorage->getFileKey($path, $this->fileKeyId, Encryption::ID); |
||
| 452 | |||
| 453 | if (empty($encryptedFileKey)) { |
||
| 454 | return ''; |
||
| 455 | } |
||
| 456 | |||
| 457 | if ($this->util->isMasterKeyEnabled()) { |
||
| 458 | $uid = $this->getMasterKeyId(); |
||
| 459 | $shareKey = $this->getShareKey($path, $uid); |
||
| 460 | if ($publicAccess) { |
||
| 461 | $privateKey = $this->getSystemPrivateKey($uid); |
||
| 462 | $privateKey = $this->crypt->decryptPrivateKey($privateKey, $this->getMasterKeyPassword(), $uid); |
||
| 463 | } else { |
||
| 464 | // when logged in, the master key is already decrypted in the session |
||
| 465 | $privateKey = $this->session->getPrivateKey(); |
||
| 466 | } |
||
| 467 | } elseif ($publicAccess) { |
||
| 468 | // use public share key for public links |
||
| 469 | $uid = $this->getPublicShareKeyId(); |
||
| 470 | $shareKey = $this->getShareKey($path, $uid); |
||
| 471 | $privateKey = $this->keyStorage->getSystemUserKey($this->publicShareKeyId . '.' . $this->privateKeyId, Encryption::ID); |
||
| 472 | $privateKey = $this->crypt->decryptPrivateKey($privateKey); |
||
| 473 | } else { |
||
| 474 | $shareKey = $this->getShareKey($path, $uid); |
||
| 475 | $privateKey = $this->session->getPrivateKey(); |
||
| 476 | } |
||
| 477 | |||
| 478 | if ($encryptedFileKey && $shareKey && $privateKey) { |
||
| 479 | return $this->crypt->multiKeyDecrypt($encryptedFileKey, |
||
| 480 | $shareKey, |
||
| 481 | $privateKey); |
||
| 482 | } |
||
| 483 | |||
| 484 | return ''; |
||
| 485 | } |
||
| 486 | |||
| 487 | /** |
||
| 488 | * Get the current version of a file |
||
| 489 | * |
||
| 490 | * @param string $path |
||
| 491 | * @param View $view |
||
| 492 | * @return int |
||
| 493 | */ |
||
| 494 | public function getVersion($path, View $view) { |
||
| 495 | $fileInfo = $view->getFileInfo($path); |
||
| 496 | if ($fileInfo === false) { |
||
| 497 | return 0; |
||
| 498 | } |
||
| 499 | return $fileInfo->getEncryptedVersion(); |
||
| 500 | } |
||
| 501 | |||
| 502 | /** |
||
| 503 | * Set the current version of a file |
||
| 504 | * |
||
| 505 | * @param string $path |
||
| 506 | * @param int $version |
||
| 507 | * @param View $view |
||
| 508 | */ |
||
| 509 | public function setVersion($path, $version, View $view) { |
||
| 510 | $fileInfo= $view->getFileInfo($path); |
||
| 511 | |||
| 512 | if ($fileInfo !== false) { |
||
| 513 | $cache = $fileInfo->getStorage()->getCache(); |
||
| 514 | $cache->update($fileInfo->getId(), ['encrypted' => $version, 'encryptedVersion' => $version]); |
||
| 515 | } |
||
| 516 | } |
||
| 517 | |||
| 518 | /** |
||
| 519 | * get the encrypted file key |
||
| 520 | * |
||
| 521 | * @param string $path |
||
| 522 | * @return string |
||
| 523 | */ |
||
| 524 | public function getEncryptedFileKey($path) { |
||
| 529 | } |
||
| 530 | |||
| 531 | /** |
||
| 532 | * delete share key |
||
| 533 | * |
||
| 534 | * @param string $path |
||
| 535 | * @param string $keyId |
||
| 536 | * @return boolean |
||
| 537 | */ |
||
| 538 | public function deleteShareKey($path, $keyId) { |
||
| 539 | return $this->keyStorage->deleteFileKey( |
||
| 540 | $path, |
||
| 541 | $keyId . '.' . $this->shareKeyId, |
||
| 542 | Encryption::ID); |
||
| 543 | } |
||
| 544 | |||
| 545 | |||
| 546 | /** |
||
| 547 | * @param $path |
||
| 548 | * @param $uid |
||
| 549 | * @return mixed |
||
| 550 | */ |
||
| 551 | public function getShareKey($path, $uid) { |
||
| 552 | $keyId = $uid . '.' . $this->shareKeyId; |
||
| 553 | return $this->keyStorage->getFileKey($path, $keyId, Encryption::ID); |
||
| 554 | } |
||
| 555 | |||
| 556 | /** |
||
| 557 | * check if user has a private and a public key |
||
| 558 | * |
||
| 559 | * @param string $userId |
||
| 560 | * @return bool |
||
| 561 | * @throws PrivateKeyMissingException |
||
| 562 | * @throws PublicKeyMissingException |
||
| 563 | */ |
||
| 564 | public function userHasKeys($userId) { |
||
| 565 | $privateKey = $publicKey = true; |
||
| 566 | $exception = null; |
||
| 567 | |||
| 568 | try { |
||
| 569 | $this->getPrivateKey($userId); |
||
| 570 | } catch (PrivateKeyMissingException $e) { |
||
| 571 | $privateKey = false; |
||
| 572 | $exception = $e; |
||
| 573 | } |
||
| 574 | try { |
||
| 575 | $this->getPublicKey($userId); |
||
| 576 | } catch (PublicKeyMissingException $e) { |
||
| 577 | $publicKey = false; |
||
| 578 | $exception = $e; |
||
| 579 | } |
||
| 580 | |||
| 581 | if ($privateKey && $publicKey) { |
||
| 582 | return true; |
||
| 583 | } elseif (!$privateKey && !$publicKey) { |
||
| 584 | return false; |
||
| 585 | } else { |
||
| 586 | throw $exception; |
||
| 587 | } |
||
| 588 | } |
||
| 589 | |||
| 590 | /** |
||
| 591 | * @param $userId |
||
| 592 | * @return mixed |
||
| 593 | * @throws PublicKeyMissingException |
||
| 594 | */ |
||
| 595 | public function getPublicKey($userId) { |
||
| 596 | $publicKey = $this->keyStorage->getUserKey($userId, $this->publicKeyId, Encryption::ID); |
||
| 597 | |||
| 598 | if (strlen($publicKey) !== 0) { |
||
| 599 | return $publicKey; |
||
| 600 | } |
||
| 601 | throw new PublicKeyMissingException($userId); |
||
| 602 | } |
||
| 603 | |||
| 604 | public function getPublicShareKeyId() { |
||
| 606 | } |
||
| 607 | |||
| 608 | /** |
||
| 609 | * get public key for public link shares |
||
| 610 | * |
||
| 611 | * @return string |
||
| 612 | */ |
||
| 613 | public function getPublicShareKey() { |
||
| 614 | return $this->keyStorage->getSystemUserKey($this->publicShareKeyId . '.' . $this->publicKeyId, Encryption::ID); |
||
| 615 | } |
||
| 616 | |||
| 617 | /** |
||
| 618 | * @param string $purpose |
||
| 619 | * @param string $uid |
||
| 620 | */ |
||
| 621 | public function backupUserKeys($purpose, $uid) { |
||
| 622 | $this->keyStorage->backupUserKeys(Encryption::ID, $purpose, $uid); |
||
| 623 | } |
||
| 624 | |||
| 625 | /** |
||
| 626 | * creat a backup of the users private and public key and then delete it |
||
| 627 | * |
||
| 628 | * @param string $uid |
||
| 629 | */ |
||
| 630 | public function deleteUserKeys($uid) { |
||
| 631 | $this->deletePublicKey($uid); |
||
| 632 | $this->deletePrivateKey($uid); |
||
| 633 | } |
||
| 634 | |||
| 635 | /** |
||
| 636 | * @param $uid |
||
| 637 | * @return bool |
||
| 638 | */ |
||
| 639 | public function deletePublicKey($uid) { |
||
| 641 | } |
||
| 642 | |||
| 643 | /** |
||
| 644 | * @param string $uid |
||
| 645 | * @return bool |
||
| 646 | */ |
||
| 647 | private function deletePrivateKey($uid) { |
||
| 648 | return $this->keyStorage->deleteUserKey($uid, $this->privateKeyId, Encryption::ID); |
||
| 649 | } |
||
| 650 | |||
| 651 | /** |
||
| 652 | * @param string $path |
||
| 653 | * @return bool |
||
| 654 | */ |
||
| 655 | public function deleteAllFileKeys($path) { |
||
| 656 | return $this->keyStorage->deleteAllFileKeys($path); |
||
| 657 | } |
||
| 658 | |||
| 659 | /** |
||
| 660 | * @param array $userIds |
||
| 661 | * @return array |
||
| 662 | * @throws PublicKeyMissingException |
||
| 663 | */ |
||
| 664 | public function getPublicKeys(array $userIds) { |
||
| 665 | $keys = []; |
||
| 666 | |||
| 667 | foreach ($userIds as $userId) { |
||
| 668 | try { |
||
| 669 | $keys[$userId] = $this->getPublicKey($userId); |
||
| 670 | } catch (PublicKeyMissingException $e) { |
||
| 671 | continue; |
||
| 672 | } |
||
| 673 | } |
||
| 674 | |||
| 675 | return $keys; |
||
| 676 | } |
||
| 677 | |||
| 678 | /** |
||
| 679 | * @param string $keyId |
||
| 680 | * @return string returns openssl key |
||
| 681 | */ |
||
| 682 | public function getSystemPrivateKey($keyId) { |
||
| 683 | return $this->keyStorage->getSystemUserKey($keyId . '.' . $this->privateKeyId, Encryption::ID); |
||
| 684 | } |
||
| 685 | |||
| 686 | /** |
||
| 687 | * @param string $keyId |
||
| 688 | * @param string $key |
||
| 689 | * @return string returns openssl key |
||
| 690 | */ |
||
| 691 | public function setSystemPrivateKey($keyId, $key) { |
||
| 692 | return $this->keyStorage->setSystemUserKey( |
||
| 693 | $keyId . '.' . $this->privateKeyId, |
||
| 694 | $key, |
||
| 695 | Encryption::ID); |
||
| 696 | } |
||
| 697 | |||
| 698 | /** |
||
| 699 | * add system keys such as the public share key and the recovery key |
||
| 700 | * |
||
| 701 | * @param array $accessList |
||
| 702 | * @param array $publicKeys |
||
| 703 | * @param string $uid |
||
| 704 | * @return array |
||
| 705 | * @throws PublicKeyMissingException |
||
| 706 | */ |
||
| 707 | public function addSystemKeys(array $accessList, array $publicKeys, $uid) { |
||
| 708 | if (!empty($accessList['public'])) { |
||
| 709 | $publicShareKey = $this->getPublicShareKey(); |
||
| 710 | if (empty($publicShareKey)) { |
||
| 711 | throw new PublicKeyMissingException($this->getPublicShareKeyId()); |
||
| 712 | } |
||
| 713 | $publicKeys[$this->getPublicShareKeyId()] = $publicShareKey; |
||
| 714 | } |
||
| 715 | |||
| 716 | if ($this->recoveryKeyExists() && |
||
| 717 | $this->util->isRecoveryEnabledForUser($uid)) { |
||
| 718 | $publicKeys[$this->getRecoveryKeyId()] = $this->getRecoveryKey(); |
||
| 719 | } |
||
| 720 | |||
| 721 | return $publicKeys; |
||
| 722 | } |
||
| 723 | |||
| 724 | /** |
||
| 725 | * get master key password |
||
| 726 | * |
||
| 727 | * @return string |
||
| 728 | * @throws \Exception |
||
| 729 | */ |
||
| 730 | public function getMasterKeyPassword() { |
||
| 731 | $password = $this->config->getSystemValue('secret'); |
||
| 732 | if (empty($password)) { |
||
| 733 | throw new \Exception('Can not get secret from Nextcloud instance'); |
||
| 734 | } |
||
| 735 | |||
| 736 | return $password; |
||
| 737 | } |
||
| 738 | |||
| 739 | /** |
||
| 740 | * return master key id |
||
| 741 | * |
||
| 742 | * @return string |
||
| 743 | */ |
||
| 744 | public function getMasterKeyId() { |
||
| 746 | } |
||
| 747 | |||
| 748 | /** |
||
| 749 | * get public master key |
||
| 750 | * |
||
| 751 | * @return string |
||
| 752 | */ |
||
| 753 | public function getPublicMasterKey() { |
||
| 754 | return $this->keyStorage->getSystemUserKey($this->masterKeyId . '.' . $this->publicKeyId, Encryption::ID); |
||
| 755 | } |
||
| 756 | |||
| 757 | /** |
||
| 758 | * get public master key |
||
| 759 | * |
||
| 760 | * @return string |
||
| 761 | */ |
||
| 762 | public function getPrivateMasterKey() { |
||
| 764 | } |
||
| 765 | } |
||
| 766 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountIdthat can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theidproperty of an instance of theAccountclass. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.