|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* @author Björn Schießle <[email protected]> |
|
4
|
|
|
* @author Clark Tomlinson <[email protected]> |
|
5
|
|
|
* @author Thomas Müller <[email protected]> |
|
6
|
|
|
* |
|
7
|
|
|
* @copyright Copyright (c) 2015, ownCloud, Inc. |
|
8
|
|
|
* @license AGPL-3.0 |
|
9
|
|
|
* |
|
10
|
|
|
* This code is free software: you can redistribute it and/or modify |
|
11
|
|
|
* it under the terms of the GNU Affero General Public License, version 3, |
|
12
|
|
|
* as published by the Free Software Foundation. |
|
13
|
|
|
* |
|
14
|
|
|
* This program is distributed in the hope that it will be useful, |
|
15
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
16
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
17
|
|
|
* GNU Affero General Public License for more details. |
|
18
|
|
|
* |
|
19
|
|
|
* You should have received a copy of the GNU Affero General Public License, version 3, |
|
20
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|
21
|
|
|
* |
|
22
|
|
|
*/ |
|
23
|
|
|
namespace OCA\Encryption; |
|
24
|
|
|
|
|
25
|
|
|
use OC\Encryption\Exceptions\DecryptionFailedException; |
|
26
|
|
|
use OCA\Encryption\Crypto\Encryption; |
|
27
|
|
|
use OCA\Encryption\Exceptions\PrivateKeyMissingException; |
|
28
|
|
|
use OCA\Encryption\Exceptions\PublicKeyMissingException; |
|
29
|
|
|
use OCA\Encryption\Crypto\Crypt; |
|
30
|
|
|
use OCP\Encryption\Keys\IStorage; |
|
31
|
|
|
use OCP\IConfig; |
|
32
|
|
|
use OCP\ILogger; |
|
33
|
|
|
use OCP\IUserSession; |
|
34
|
|
|
|
|
35
|
|
|
class KeyManager { |
|
36
|
|
|
|
|
37
|
|
|
/** |
|
38
|
|
|
* @var Session |
|
39
|
|
|
*/ |
|
40
|
|
|
protected $session; |
|
41
|
|
|
/** |
|
42
|
|
|
* @var IStorage |
|
43
|
|
|
*/ |
|
44
|
|
|
private $keyStorage; |
|
45
|
|
|
/** |
|
46
|
|
|
* @var Crypt |
|
47
|
|
|
*/ |
|
48
|
|
|
private $crypt; |
|
49
|
|
|
/** |
|
50
|
|
|
* @var string |
|
51
|
|
|
*/ |
|
52
|
|
|
private $recoveryKeyId; |
|
53
|
|
|
/** |
|
54
|
|
|
* @var string |
|
55
|
|
|
*/ |
|
56
|
|
|
private $publicShareKeyId; |
|
57
|
|
|
/** |
|
58
|
|
|
* @var string |
|
59
|
|
|
*/ |
|
60
|
|
|
private $masterKeyId; |
|
61
|
|
|
/** |
|
62
|
|
|
* @var string UserID |
|
63
|
|
|
*/ |
|
64
|
|
|
private $keyId; |
|
65
|
|
|
/** |
|
66
|
|
|
* @var string |
|
67
|
|
|
*/ |
|
68
|
|
|
private $publicKeyId = 'publicKey'; |
|
69
|
|
|
/** |
|
70
|
|
|
* @var string |
|
71
|
|
|
*/ |
|
72
|
|
|
private $privateKeyId = 'privateKey'; |
|
73
|
|
|
|
|
74
|
|
|
/** |
|
75
|
|
|
* @var string |
|
76
|
|
|
*/ |
|
77
|
|
|
private $shareKeyId = 'shareKey'; |
|
78
|
|
|
|
|
79
|
|
|
/** |
|
80
|
|
|
* @var string |
|
81
|
|
|
*/ |
|
82
|
|
|
private $fileKeyId = 'fileKey'; |
|
83
|
|
|
/** |
|
84
|
|
|
* @var IConfig |
|
85
|
|
|
*/ |
|
86
|
|
|
private $config; |
|
87
|
|
|
/** |
|
88
|
|
|
* @var ILogger |
|
89
|
|
|
*/ |
|
90
|
|
|
private $log; |
|
91
|
|
|
/** |
|
92
|
|
|
* @var Util |
|
93
|
|
|
*/ |
|
94
|
|
|
private $util; |
|
95
|
|
|
|
|
96
|
|
|
/** |
|
97
|
|
|
* @param IStorage $keyStorage |
|
98
|
|
|
* @param Crypt $crypt |
|
99
|
|
|
* @param IConfig $config |
|
100
|
|
|
* @param IUserSession $userSession |
|
101
|
|
|
* @param Session $session |
|
102
|
|
|
* @param ILogger $log |
|
103
|
|
|
* @param Util $util |
|
104
|
|
|
*/ |
|
105
|
42 |
|
public function __construct( |
|
106
|
|
|
IStorage $keyStorage, |
|
107
|
|
|
Crypt $crypt, |
|
108
|
|
|
IConfig $config, |
|
109
|
|
|
IUserSession $userSession, |
|
110
|
|
|
Session $session, |
|
111
|
|
|
ILogger $log, |
|
112
|
|
|
Util $util |
|
113
|
|
|
) { |
|
114
|
|
|
|
|
115
|
42 |
|
$this->util = $util; |
|
116
|
42 |
|
$this->session = $session; |
|
117
|
42 |
|
$this->keyStorage = $keyStorage; |
|
118
|
42 |
|
$this->crypt = $crypt; |
|
119
|
42 |
|
$this->config = $config; |
|
120
|
42 |
|
$this->log = $log; |
|
121
|
|
|
|
|
122
|
42 |
|
$this->recoveryKeyId = $this->config->getAppValue('encryption', |
|
123
|
42 |
|
'recoveryKeyId'); |
|
124
|
42 |
|
if (empty($this->recoveryKeyId)) { |
|
125
|
|
|
$this->recoveryKeyId = 'recoveryKey_' . substr(md5(time()), 0, 8); |
|
126
|
|
|
$this->config->setAppValue('encryption', |
|
127
|
|
|
'recoveryKeyId', |
|
128
|
|
|
$this->recoveryKeyId); |
|
129
|
|
|
} |
|
130
|
|
|
|
|
131
|
42 |
|
$this->publicShareKeyId = $this->config->getAppValue('encryption', |
|
132
|
42 |
|
'publicShareKeyId'); |
|
133
|
42 |
View Code Duplication |
if (empty($this->publicShareKeyId)) { |
|
|
|
|
|
|
134
|
|
|
$this->publicShareKeyId = 'pubShare_' . substr(md5(time()), 0, 8); |
|
135
|
|
|
$this->config->setAppValue('encryption', 'publicShareKeyId', $this->publicShareKeyId); |
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
42 |
|
$this->masterKeyId = $this->config->getAppValue('encryption', |
|
139
|
42 |
|
'masterKeyId'); |
|
140
|
42 |
View Code Duplication |
if (empty($this->masterKeyId)) { |
|
|
|
|
|
|
141
|
|
|
$this->masterKeyId = 'master_' . substr(md5(time()), 0, 8); |
|
142
|
|
|
$this->config->setAppValue('encryption', 'masterKeyId', $this->masterKeyId); |
|
143
|
|
|
} |
|
144
|
|
|
|
|
145
|
42 |
|
$this->keyId = $userSession && $userSession->isLoggedIn() ? $userSession->getUser()->getUID() : false; |
|
146
|
42 |
|
$this->log = $log; |
|
147
|
42 |
|
} |
|
148
|
|
|
|
|
149
|
|
|
/** |
|
150
|
|
|
* check if key pair for public link shares exists, if not we create one |
|
151
|
|
|
*/ |
|
152
|
5 |
View Code Duplication |
public function validateShareKey() { |
|
153
|
5 |
|
$shareKey = $this->getPublicShareKey(); |
|
154
|
5 |
|
if (empty($shareKey)) { |
|
155
|
1 |
|
$keyPair = $this->crypt->createKeyPair(); |
|
156
|
|
|
|
|
157
|
|
|
// Save public key |
|
158
|
1 |
|
$this->keyStorage->setSystemUserKey( |
|
159
|
1 |
|
$this->publicShareKeyId . '.publicKey', $keyPair['publicKey'], |
|
160
|
1 |
|
Encryption::ID); |
|
161
|
|
|
|
|
162
|
|
|
// Encrypt private key empty passphrase |
|
163
|
1 |
|
$encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], ''); |
|
164
|
1 |
|
$header = $this->crypt->generateHeader(); |
|
165
|
1 |
|
$this->setSystemPrivateKey($this->publicShareKeyId, $header . $encryptedKey); |
|
166
|
1 |
|
} |
|
167
|
5 |
|
} |
|
168
|
|
|
|
|
169
|
|
|
/** |
|
170
|
|
|
* check if a key pair for the master key exists, if not we create one |
|
171
|
|
|
*/ |
|
172
|
7 |
View Code Duplication |
public function validateMasterKey() { |
|
173
|
7 |
|
$masterKey = $this->getPublicMasterKey(); |
|
174
|
7 |
|
if (empty($masterKey)) { |
|
175
|
2 |
|
$keyPair = $this->crypt->createKeyPair(); |
|
176
|
|
|
|
|
177
|
|
|
// Save public key |
|
178
|
2 |
|
$this->keyStorage->setSystemUserKey( |
|
179
|
2 |
|
$this->masterKeyId . '.publicKey', $keyPair['publicKey'], |
|
180
|
2 |
|
Encryption::ID); |
|
181
|
|
|
|
|
182
|
|
|
// Encrypt private key with system password |
|
183
|
2 |
|
$encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $this->getMasterKeyPassword(), $this->masterKeyId); |
|
184
|
2 |
|
$header = $this->crypt->generateHeader(); |
|
185
|
2 |
|
$this->setSystemPrivateKey($this->masterKeyId, $header . $encryptedKey); |
|
186
|
2 |
|
} |
|
187
|
7 |
|
} |
|
188
|
|
|
|
|
189
|
|
|
/** |
|
190
|
|
|
* @return bool |
|
191
|
|
|
*/ |
|
192
|
10 |
|
public function recoveryKeyExists() { |
|
193
|
10 |
|
$key = $this->getRecoveryKey(); |
|
194
|
10 |
|
return (!empty($key)); |
|
195
|
|
|
} |
|
196
|
|
|
|
|
197
|
|
|
/** |
|
198
|
|
|
* get recovery key |
|
199
|
|
|
* |
|
200
|
|
|
* @return string |
|
201
|
|
|
*/ |
|
202
|
10 |
|
public function getRecoveryKey() { |
|
203
|
10 |
|
return $this->keyStorage->getSystemUserKey($this->recoveryKeyId . '.publicKey', Encryption::ID); |
|
204
|
|
|
} |
|
205
|
|
|
|
|
206
|
|
|
/** |
|
207
|
|
|
* get recovery key ID |
|
208
|
|
|
* |
|
209
|
|
|
* @return string |
|
210
|
|
|
*/ |
|
211
|
3 |
|
public function getRecoveryKeyId() { |
|
212
|
3 |
|
return $this->recoveryKeyId; |
|
213
|
|
|
} |
|
214
|
|
|
|
|
215
|
|
|
/** |
|
216
|
|
|
* @param $password |
|
217
|
|
|
* @return bool |
|
218
|
|
|
*/ |
|
219
|
1 |
|
public function checkRecoveryPassword($password) { |
|
220
|
1 |
|
$recoveryKey = $this->keyStorage->getSystemUserKey($this->recoveryKeyId . '.privateKey', Encryption::ID); |
|
221
|
1 |
|
$decryptedRecoveryKey = $this->crypt->decryptPrivateKey($recoveryKey, $password); |
|
222
|
|
|
|
|
223
|
1 |
|
if ($decryptedRecoveryKey) { |
|
|
|
|
|
|
224
|
1 |
|
return true; |
|
225
|
|
|
} |
|
226
|
|
|
return false; |
|
227
|
|
|
} |
|
228
|
|
|
|
|
229
|
|
|
/** |
|
230
|
|
|
* @param string $uid |
|
231
|
|
|
* @param string $password |
|
232
|
|
|
* @param string $keyPair |
|
233
|
|
|
* @return bool |
|
234
|
|
|
*/ |
|
235
|
5 |
|
public function storeKeyPair($uid, $password, $keyPair) { |
|
236
|
|
|
// Save Public Key |
|
237
|
5 |
|
$this->setPublicKey($uid, $keyPair['publicKey']); |
|
238
|
|
|
|
|
239
|
5 |
|
$encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $password, $uid); |
|
240
|
|
|
|
|
241
|
5 |
|
$header = $this->crypt->generateHeader(); |
|
242
|
|
|
|
|
243
|
5 |
|
if ($encryptedKey) { |
|
|
|
|
|
|
244
|
5 |
|
$this->setPrivateKey($uid, $header . $encryptedKey); |
|
245
|
5 |
|
return true; |
|
246
|
|
|
} |
|
247
|
|
|
return false; |
|
248
|
|
|
} |
|
249
|
|
|
|
|
250
|
|
|
/** |
|
251
|
|
|
* @param string $password |
|
252
|
|
|
* @param array $keyPair |
|
253
|
|
|
* @return bool |
|
254
|
|
|
*/ |
|
255
|
1 |
|
public function setRecoveryKey($password, $keyPair) { |
|
256
|
|
|
// Save Public Key |
|
257
|
1 |
|
$this->keyStorage->setSystemUserKey($this->getRecoveryKeyId(). |
|
258
|
1 |
|
'.publicKey', |
|
259
|
1 |
|
$keyPair['publicKey'], |
|
260
|
1 |
|
Encryption::ID); |
|
261
|
|
|
|
|
262
|
1 |
|
$encryptedKey = $this->crypt->encryptPrivateKey($keyPair['privateKey'], $password); |
|
263
|
1 |
|
$header = $this->crypt->generateHeader(); |
|
264
|
|
|
|
|
265
|
1 |
|
if ($encryptedKey) { |
|
|
|
|
|
|
266
|
1 |
|
$this->setSystemPrivateKey($this->getRecoveryKeyId(), $header . $encryptedKey); |
|
267
|
1 |
|
return true; |
|
268
|
|
|
} |
|
269
|
|
|
return false; |
|
270
|
|
|
} |
|
271
|
|
|
|
|
272
|
|
|
/** |
|
273
|
|
|
* @param $userId |
|
274
|
|
|
* @param $key |
|
275
|
|
|
* @return bool |
|
276
|
|
|
*/ |
|
277
|
6 |
|
public function setPublicKey($userId, $key) { |
|
278
|
6 |
|
return $this->keyStorage->setUserKey($userId, $this->publicKeyId, $key, Encryption::ID); |
|
279
|
|
|
} |
|
280
|
|
|
|
|
281
|
|
|
/** |
|
282
|
|
|
* @param $userId |
|
283
|
|
|
* @param $key |
|
284
|
|
|
* @return bool |
|
285
|
|
|
*/ |
|
286
|
6 |
|
public function setPrivateKey($userId, $key) { |
|
287
|
6 |
|
return $this->keyStorage->setUserKey($userId, |
|
288
|
6 |
|
$this->privateKeyId, |
|
289
|
6 |
|
$key, |
|
290
|
6 |
|
Encryption::ID); |
|
291
|
|
|
} |
|
292
|
|
|
|
|
293
|
|
|
/** |
|
294
|
|
|
* write file key to key storage |
|
295
|
|
|
* |
|
296
|
|
|
* @param string $path |
|
297
|
|
|
* @param string $key |
|
298
|
|
|
* @return boolean |
|
299
|
|
|
*/ |
|
300
|
5 |
|
public function setFileKey($path, $key) { |
|
301
|
5 |
|
return $this->keyStorage->setFileKey($path, $this->fileKeyId, $key, Encryption::ID); |
|
302
|
|
|
} |
|
303
|
|
|
|
|
304
|
|
|
/** |
|
305
|
|
|
* set all file keys (the file key and the corresponding share keys) |
|
306
|
|
|
* |
|
307
|
|
|
* @param string $path |
|
308
|
|
|
* @param array $keys |
|
309
|
|
|
*/ |
|
310
|
5 |
|
public function setAllFileKeys($path, $keys) { |
|
311
|
5 |
|
$this->setFileKey($path, $keys['data']); |
|
312
|
5 |
|
foreach ($keys['keys'] as $uid => $keyFile) { |
|
313
|
5 |
|
$this->setShareKey($path, $uid, $keyFile); |
|
314
|
5 |
|
} |
|
315
|
5 |
|
} |
|
316
|
|
|
|
|
317
|
|
|
/** |
|
318
|
|
|
* write share key to the key storage |
|
319
|
|
|
* |
|
320
|
|
|
* @param string $path |
|
321
|
|
|
* @param string $uid |
|
322
|
|
|
* @param string $key |
|
323
|
|
|
* @return boolean |
|
324
|
|
|
*/ |
|
325
|
5 |
|
public function setShareKey($path, $uid, $key) { |
|
326
|
5 |
|
$keyId = $uid . '.' . $this->shareKeyId; |
|
327
|
5 |
|
return $this->keyStorage->setFileKey($path, $keyId, $key, Encryption::ID); |
|
328
|
|
|
} |
|
329
|
|
|
|
|
330
|
|
|
/** |
|
331
|
|
|
* Decrypt private key and store it |
|
332
|
|
|
* |
|
333
|
|
|
* @param string $uid userid |
|
334
|
|
|
* @param string $passPhrase users password |
|
335
|
|
|
* @return boolean |
|
336
|
|
|
*/ |
|
337
|
7 |
|
public function init($uid, $passPhrase) { |
|
338
|
|
|
|
|
339
|
7 |
|
$this->session->setStatus(Session::INIT_EXECUTED); |
|
340
|
|
|
|
|
341
|
|
|
|
|
342
|
|
|
try { |
|
343
|
7 |
|
if($this->util->isMasterKeyEnabled()) { |
|
344
|
1 |
|
$uid = $this->getMasterKeyId(); |
|
345
|
1 |
|
$passPhrase = $this->getMasterKeyPassword(); |
|
346
|
1 |
|
$privateKey = $this->getSystemPrivateKey($uid); |
|
347
|
1 |
|
} else { |
|
348
|
6 |
|
$privateKey = $this->getPrivateKey($uid); |
|
349
|
|
|
} |
|
350
|
7 |
|
$privateKey = $this->crypt->decryptPrivateKey($privateKey, $passPhrase, $uid); |
|
351
|
7 |
|
} catch (PrivateKeyMissingException $e) { |
|
352
|
|
|
return false; |
|
353
|
|
|
} catch (DecryptionFailedException $e) { |
|
354
|
|
|
return false; |
|
355
|
|
|
} |
|
356
|
|
|
|
|
357
|
7 |
|
if ($privateKey) { |
|
|
|
|
|
|
358
|
7 |
|
$this->session->setPrivateKey($privateKey); |
|
359
|
7 |
|
$this->session->setStatus(Session::INIT_SUCCESSFUL); |
|
360
|
7 |
|
return true; |
|
361
|
|
|
} |
|
362
|
|
|
|
|
363
|
|
|
return false; |
|
364
|
|
|
} |
|
365
|
|
|
|
|
366
|
|
|
/** |
|
367
|
|
|
* @param $userId |
|
368
|
|
|
* @return mixed |
|
369
|
|
|
* @throws PrivateKeyMissingException |
|
370
|
|
|
*/ |
|
371
|
10 |
View Code Duplication |
public function getPrivateKey($userId) { |
|
372
|
10 |
|
$privateKey = $this->keyStorage->getUserKey($userId, |
|
373
|
10 |
|
$this->privateKeyId, Encryption::ID); |
|
374
|
|
|
|
|
375
|
10 |
|
if (strlen($privateKey) !== 0) { |
|
376
|
8 |
|
return $privateKey; |
|
377
|
|
|
} |
|
378
|
7 |
|
throw new PrivateKeyMissingException($userId); |
|
379
|
|
|
} |
|
380
|
|
|
|
|
381
|
|
|
/** |
|
382
|
|
|
* @param $path |
|
383
|
|
|
* @param $uid |
|
384
|
|
|
* @return string |
|
385
|
|
|
*/ |
|
386
|
13 |
|
public function getFileKey($path, $uid) { |
|
387
|
13 |
|
$encryptedFileKey = $this->keyStorage->getFileKey($path, $this->fileKeyId, Encryption::ID); |
|
388
|
|
|
|
|
389
|
13 |
|
if (is_null($uid)) { |
|
390
|
|
|
$uid = $this->getPublicShareKeyId(); |
|
391
|
|
|
$shareKey = $this->getShareKey($path, $uid); |
|
392
|
|
|
$privateKey = $this->keyStorage->getSystemUserKey($this->publicShareKeyId . '.privateKey', Encryption::ID); |
|
393
|
|
|
$privateKey = $this->crypt->decryptPrivateKey($privateKey); |
|
394
|
|
|
} else { |
|
395
|
|
|
|
|
396
|
13 |
|
if ($this->util->isMasterKeyEnabled()) { |
|
397
|
4 |
|
$uid = $this->getMasterKeyId(); |
|
398
|
4 |
|
} |
|
399
|
|
|
|
|
400
|
13 |
|
$shareKey = $this->getShareKey($path, $uid); |
|
401
|
13 |
|
$privateKey = $this->session->getPrivateKey(); |
|
402
|
|
|
} |
|
403
|
|
|
|
|
404
|
13 |
|
if ($encryptedFileKey && $shareKey && $privateKey) { |
|
405
|
9 |
|
return $this->crypt->multiKeyDecrypt($encryptedFileKey, |
|
406
|
9 |
|
$shareKey, |
|
407
|
9 |
|
$privateKey); |
|
408
|
|
|
} |
|
409
|
|
|
|
|
410
|
9 |
|
return ''; |
|
411
|
|
|
} |
|
412
|
|
|
|
|
413
|
|
|
/** |
|
414
|
|
|
* get the encrypted file key |
|
415
|
|
|
* |
|
416
|
|
|
* @param $path |
|
417
|
|
|
* @return string |
|
418
|
|
|
*/ |
|
419
|
1 |
|
public function getEncryptedFileKey($path) { |
|
420
|
1 |
|
$encryptedFileKey = $this->keyStorage->getFileKey($path, |
|
421
|
1 |
|
$this->fileKeyId, Encryption::ID); |
|
422
|
|
|
|
|
423
|
1 |
|
return $encryptedFileKey; |
|
424
|
|
|
} |
|
425
|
|
|
|
|
426
|
|
|
/** |
|
427
|
|
|
* delete share key |
|
428
|
|
|
* |
|
429
|
|
|
* @param string $path |
|
430
|
|
|
* @param string $keyId |
|
431
|
|
|
* @return boolean |
|
432
|
|
|
*/ |
|
433
|
1 |
|
public function deleteShareKey($path, $keyId) { |
|
434
|
1 |
|
return $this->keyStorage->deleteFileKey( |
|
435
|
1 |
|
$path, |
|
436
|
1 |
|
$keyId . '.' . $this->shareKeyId, |
|
437
|
1 |
|
Encryption::ID); |
|
438
|
|
|
} |
|
439
|
|
|
|
|
440
|
|
|
|
|
441
|
|
|
/** |
|
442
|
|
|
* @param $path |
|
443
|
|
|
* @param $uid |
|
444
|
|
|
* @return mixed |
|
445
|
|
|
*/ |
|
446
|
13 |
|
public function getShareKey($path, $uid) { |
|
447
|
13 |
|
$keyId = $uid . '.' . $this->shareKeyId; |
|
448
|
13 |
|
return $this->keyStorage->getFileKey($path, $keyId, Encryption::ID); |
|
449
|
|
|
} |
|
450
|
|
|
|
|
451
|
|
|
/** |
|
452
|
|
|
* check if user has a private and a public key |
|
453
|
|
|
* |
|
454
|
|
|
* @param string $userId |
|
455
|
|
|
* @return bool |
|
456
|
|
|
* @throws PrivateKeyMissingException |
|
457
|
|
|
* @throws PublicKeyMissingException |
|
458
|
|
|
*/ |
|
459
|
9 |
|
public function userHasKeys($userId) { |
|
460
|
9 |
|
$privateKey = $publicKey = true; |
|
461
|
|
|
|
|
462
|
|
|
try { |
|
463
|
9 |
|
$this->getPrivateKey($userId); |
|
464
|
9 |
|
} catch (PrivateKeyMissingException $e) { |
|
465
|
7 |
|
$privateKey = false; |
|
466
|
7 |
|
$exception = $e; |
|
467
|
|
|
} |
|
468
|
|
|
try { |
|
469
|
9 |
|
$this->getPublicKey($userId); |
|
470
|
9 |
|
} catch (PublicKeyMissingException $e) { |
|
471
|
7 |
|
$publicKey = false; |
|
472
|
7 |
|
$exception = $e; |
|
473
|
|
|
} |
|
474
|
|
|
|
|
475
|
9 |
|
if ($privateKey && $publicKey) { |
|
476
|
1 |
|
return true; |
|
477
|
8 |
|
} elseif (!$privateKey && !$publicKey) { |
|
478
|
6 |
|
return false; |
|
479
|
|
|
} else { |
|
480
|
2 |
|
throw $exception; |
|
481
|
|
|
} |
|
482
|
|
|
} |
|
483
|
|
|
|
|
484
|
|
|
/** |
|
485
|
|
|
* @param $userId |
|
486
|
|
|
* @return mixed |
|
487
|
|
|
* @throws PublicKeyMissingException |
|
488
|
|
|
*/ |
|
489
|
10 |
View Code Duplication |
public function getPublicKey($userId) { |
|
490
|
10 |
|
$publicKey = $this->keyStorage->getUserKey($userId, $this->publicKeyId, Encryption::ID); |
|
491
|
|
|
|
|
492
|
10 |
|
if (strlen($publicKey) !== 0) { |
|
493
|
8 |
|
return $publicKey; |
|
494
|
|
|
} |
|
495
|
7 |
|
throw new PublicKeyMissingException($userId); |
|
496
|
|
|
} |
|
497
|
|
|
|
|
498
|
2 |
|
public function getPublicShareKeyId() { |
|
499
|
2 |
|
return $this->publicShareKeyId; |
|
500
|
|
|
} |
|
501
|
|
|
|
|
502
|
|
|
/** |
|
503
|
|
|
* get public key for public link shares |
|
504
|
|
|
* |
|
505
|
|
|
* @return string |
|
506
|
|
|
*/ |
|
507
|
7 |
|
public function getPublicShareKey() { |
|
508
|
7 |
|
return $this->keyStorage->getSystemUserKey($this->publicShareKeyId . '.publicKey', Encryption::ID); |
|
509
|
|
|
} |
|
510
|
|
|
|
|
511
|
|
|
/** |
|
512
|
|
|
* @param $purpose |
|
513
|
|
|
* @param bool $timestamp |
|
514
|
|
|
* @param bool $includeUserKeys |
|
515
|
|
|
*/ |
|
516
|
|
|
public function backupAllKeys($purpose, $timestamp = true, $includeUserKeys = true) { |
|
|
|
|
|
|
517
|
|
|
// $backupDir = $this->keyStorage->; |
|
518
|
|
|
} |
|
519
|
|
|
|
|
520
|
|
|
/** |
|
521
|
|
|
* @param string $uid |
|
522
|
|
|
*/ |
|
523
|
|
|
public function replaceUserKeys($uid) { |
|
524
|
|
|
$this->backupAllKeys('password_reset'); |
|
525
|
|
|
$this->deletePublicKey($uid); |
|
526
|
|
|
$this->deletePrivateKey($uid); |
|
527
|
|
|
} |
|
528
|
|
|
|
|
529
|
|
|
/** |
|
530
|
|
|
* @param $uid |
|
531
|
|
|
* @return bool |
|
532
|
|
|
*/ |
|
533
|
|
|
public function deletePublicKey($uid) { |
|
534
|
|
|
return $this->keyStorage->deleteUserKey($uid, $this->publicKeyId, Encryption::ID); |
|
535
|
|
|
} |
|
536
|
|
|
|
|
537
|
|
|
/** |
|
538
|
|
|
* @param $uid |
|
539
|
|
|
* @return bool |
|
540
|
|
|
*/ |
|
541
|
1 |
|
private function deletePrivateKey($uid) { |
|
542
|
1 |
|
return $this->keyStorage->deleteUserKey($uid, $this->privateKeyId, Encryption::ID); |
|
543
|
|
|
} |
|
544
|
|
|
|
|
545
|
1 |
|
public function deleteAllFileKeys($path) { |
|
546
|
1 |
|
return $this->keyStorage->deleteAllFileKeys($path); |
|
547
|
|
|
} |
|
548
|
|
|
|
|
549
|
|
|
/** |
|
550
|
|
|
* @param array $userIds |
|
551
|
|
|
* @return array |
|
552
|
|
|
* @throws PublicKeyMissingException |
|
553
|
|
|
*/ |
|
554
|
|
|
public function getPublicKeys(array $userIds) { |
|
555
|
|
|
$keys = []; |
|
556
|
|
|
|
|
557
|
|
|
foreach ($userIds as $userId) { |
|
558
|
|
|
try { |
|
559
|
|
|
$keys[$userId] = $this->getPublicKey($userId); |
|
560
|
|
|
} catch (PublicKeyMissingException $e) { |
|
561
|
|
|
continue; |
|
562
|
|
|
} |
|
563
|
|
|
} |
|
564
|
|
|
|
|
565
|
|
|
return $keys; |
|
566
|
|
|
|
|
567
|
|
|
} |
|
568
|
|
|
|
|
569
|
|
|
/** |
|
570
|
|
|
* @param string $keyId |
|
571
|
|
|
* @return string returns openssl key |
|
572
|
|
|
*/ |
|
573
|
1 |
|
public function getSystemPrivateKey($keyId) { |
|
574
|
1 |
|
return $this->keyStorage->getSystemUserKey($keyId . '.' . $this->privateKeyId, Encryption::ID); |
|
575
|
|
|
} |
|
576
|
|
|
|
|
577
|
|
|
/** |
|
578
|
|
|
* @param string $keyId |
|
579
|
|
|
* @param string $key |
|
580
|
|
|
* @return string returns openssl key |
|
581
|
|
|
*/ |
|
582
|
3 |
|
public function setSystemPrivateKey($keyId, $key) { |
|
583
|
3 |
|
return $this->keyStorage->setSystemUserKey( |
|
584
|
3 |
|
$keyId . '.' . $this->privateKeyId, |
|
585
|
3 |
|
$key, |
|
586
|
3 |
|
Encryption::ID); |
|
587
|
|
|
} |
|
588
|
|
|
|
|
589
|
|
|
/** |
|
590
|
|
|
* add system keys such as the public share key and the recovery key |
|
591
|
|
|
* |
|
592
|
|
|
* @param array $accessList |
|
593
|
|
|
* @param array $publicKeys |
|
594
|
|
|
* @param string $uid |
|
595
|
|
|
* @return array |
|
596
|
|
|
* @throws PublicKeyMissingException |
|
597
|
|
|
*/ |
|
598
|
9 |
|
public function addSystemKeys(array $accessList, array $publicKeys, $uid) { |
|
599
|
9 |
|
if (!empty($accessList['public'])) { |
|
600
|
2 |
|
$publicShareKey = $this->getPublicShareKey(); |
|
601
|
2 |
|
if (empty($publicShareKey)) { |
|
602
|
|
|
throw new PublicKeyMissingException($this->getPublicShareKeyId()); |
|
603
|
|
|
} |
|
604
|
2 |
|
$publicKeys[$this->getPublicShareKeyId()] = $publicShareKey; |
|
605
|
2 |
|
} |
|
606
|
|
|
|
|
607
|
9 |
|
if ($this->recoveryKeyExists() && |
|
608
|
9 |
|
$this->util->isRecoveryEnabledForUser($uid)) { |
|
609
|
|
|
|
|
610
|
2 |
|
$publicKeys[$this->getRecoveryKeyId()] = $this->getRecoveryKey(); |
|
611
|
2 |
|
} |
|
612
|
|
|
|
|
613
|
9 |
|
return $publicKeys; |
|
614
|
|
|
} |
|
615
|
|
|
|
|
616
|
|
|
/** |
|
617
|
|
|
* get master key password |
|
618
|
|
|
* |
|
619
|
|
|
* @return string |
|
620
|
|
|
* @throws \Exception |
|
621
|
|
|
*/ |
|
622
|
3 |
|
protected function getMasterKeyPassword() { |
|
623
|
3 |
|
$password = $this->config->getSystemValue('secret'); |
|
624
|
3 |
|
if (empty($password)){ |
|
625
|
1 |
|
throw new \Exception('Can not get secret from ownCloud instance'); |
|
626
|
|
|
} |
|
627
|
|
|
|
|
628
|
2 |
|
return $password; |
|
629
|
|
|
} |
|
630
|
|
|
|
|
631
|
|
|
/** |
|
632
|
|
|
* return master key id |
|
633
|
|
|
* |
|
634
|
|
|
* @return string |
|
635
|
|
|
*/ |
|
636
|
5 |
|
public function getMasterKeyId() { |
|
637
|
5 |
|
return $this->masterKeyId; |
|
638
|
|
|
} |
|
639
|
|
|
|
|
640
|
|
|
/** |
|
641
|
|
|
* get public master key |
|
642
|
|
|
* |
|
643
|
|
|
* @return string |
|
644
|
|
|
*/ |
|
645
|
6 |
|
public function getPublicMasterKey() { |
|
646
|
6 |
|
return $this->keyStorage->getSystemUserKey($this->masterKeyId . '.publicKey', Encryption::ID); |
|
647
|
|
|
} |
|
648
|
|
|
} |
|
649
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.