Passed
Push — master ( b6376b...9563c7 )
by Morris
11:13 queued 11s
created
lib/private/Authentication/Token/PublicKeyTokenProvider.php 1 patch
Indentation   +340 added lines, -340 removed lines patch added patch discarded remove patch
@@ -34,344 +34,344 @@
 block discarded – undo
34 34
 use OCP\Security\ICrypto;
35 35
 
36 36
 class PublicKeyTokenProvider implements IProvider {
37
-	/** @var PublicKeyTokenMapper */
38
-	private $mapper;
39
-
40
-	/** @var ICrypto */
41
-	private $crypto;
42
-
43
-	/** @var IConfig */
44
-	private $config;
45
-
46
-	/** @var ILogger $logger */
47
-	private $logger;
48
-
49
-	/** @var ITimeFactory $time */
50
-	private $time;
51
-
52
-	public function __construct(PublicKeyTokenMapper $mapper,
53
-								ICrypto $crypto,
54
-								IConfig $config,
55
-								ILogger $logger,
56
-								ITimeFactory $time) {
57
-		$this->mapper = $mapper;
58
-		$this->crypto = $crypto;
59
-		$this->config = $config;
60
-		$this->logger = $logger;
61
-		$this->time = $time;
62
-	}
63
-
64
-	/**
65
-	 * {@inheritDoc}
66
-	 */
67
-	public function generateToken(string $token,
68
-								  string $uid,
69
-								  string $loginName,
70
-								  $password,
71
-								  string $name,
72
-								  int $type = IToken::TEMPORARY_TOKEN,
73
-								  int $remember = IToken::DO_NOT_REMEMBER): IToken {
74
-		$dbToken = $this->newToken($token, $uid, $loginName, $password, $name, $type, $remember);
75
-
76
-		$this->mapper->insert($dbToken);
77
-
78
-		return $dbToken;
79
-	}
80
-
81
-	public function getToken(string $tokenId): IToken {
82
-		try {
83
-			$token = $this->mapper->getToken($this->hashToken($tokenId));
84
-		} catch (DoesNotExistException $ex) {
85
-			throw new InvalidTokenException();
86
-		}
87
-
88
-		if ((int)$token->getExpires() !== 0 && $token->getExpires() < $this->time->getTime()) {
89
-			throw new ExpiredTokenException($token);
90
-		}
91
-
92
-		if ($token->getType() === IToken::WIPE_TOKEN) {
93
-			throw new WipeTokenException($token);
94
-		}
95
-
96
-		return $token;
97
-	}
98
-
99
-	public function getTokenById(int $tokenId): IToken {
100
-		try {
101
-			$token = $this->mapper->getTokenById($tokenId);
102
-		} catch (DoesNotExistException $ex) {
103
-			throw new InvalidTokenException();
104
-		}
105
-
106
-		if ((int)$token->getExpires() !== 0 && $token->getExpires() < $this->time->getTime()) {
107
-			throw new ExpiredTokenException($token);
108
-		}
109
-
110
-		if ($token->getType() === IToken::WIPE_TOKEN) {
111
-			throw new WipeTokenException($token);
112
-		}
113
-
114
-		return $token;
115
-	}
116
-
117
-	public function renewSessionToken(string $oldSessionId, string $sessionId) {
118
-		$token = $this->getToken($oldSessionId);
119
-
120
-		if (!($token instanceof PublicKeyToken)) {
121
-			throw new InvalidTokenException();
122
-		}
123
-
124
-		$password = null;
125
-		if (!is_null($token->getPassword())) {
126
-			$privateKey = $this->decrypt($token->getPrivateKey(), $oldSessionId);
127
-			$password = $this->decryptPassword($token->getPassword(), $privateKey);
128
-		}
129
-
130
-		$this->generateToken(
131
-			$sessionId,
132
-			$token->getUID(),
133
-			$token->getLoginName(),
134
-			$password,
135
-			$token->getName(),
136
-			IToken::TEMPORARY_TOKEN,
137
-			$token->getRemember()
138
-		);
139
-
140
-		$this->mapper->delete($token);
141
-	}
142
-
143
-	public function invalidateToken(string $token) {
144
-		$this->mapper->invalidate($this->hashToken($token));
145
-	}
146
-
147
-	public function invalidateTokenById(string $uid, int $id) {
148
-		$this->mapper->deleteById($uid, $id);
149
-	}
150
-
151
-	public function invalidateOldTokens() {
152
-		$olderThan = $this->time->getTime() - (int) $this->config->getSystemValue('session_lifetime', 60 * 60 * 24);
153
-		$this->logger->debug('Invalidating session tokens older than ' . date('c', $olderThan), ['app' => 'cron']);
154
-		$this->mapper->invalidateOld($olderThan, IToken::DO_NOT_REMEMBER);
155
-		$rememberThreshold = $this->time->getTime() - (int) $this->config->getSystemValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15);
156
-		$this->logger->debug('Invalidating remembered session tokens older than ' . date('c', $rememberThreshold), ['app' => 'cron']);
157
-		$this->mapper->invalidateOld($rememberThreshold, IToken::REMEMBER);
158
-	}
159
-
160
-	public function updateToken(IToken $token) {
161
-		if (!($token instanceof PublicKeyToken)) {
162
-			throw new InvalidTokenException();
163
-		}
164
-		$this->mapper->update($token);
165
-	}
166
-
167
-	public function updateTokenActivity(IToken $token) {
168
-		if (!($token instanceof PublicKeyToken)) {
169
-			throw new InvalidTokenException();
170
-		}
171
-		/** @var DefaultToken $token */
172
-		$now = $this->time->getTime();
173
-		if ($token->getLastActivity() < ($now - 60)) {
174
-			// Update token only once per minute
175
-			$token->setLastActivity($now);
176
-			$this->mapper->update($token);
177
-		}
178
-	}
179
-
180
-	public function getTokenByUser(string $uid): array {
181
-		return $this->mapper->getTokenByUser($uid);
182
-	}
183
-
184
-	public function getPassword(IToken $token, string $tokenId): string {
185
-		if (!($token instanceof PublicKeyToken)) {
186
-			throw new InvalidTokenException();
187
-		}
188
-
189
-		if ($token->getPassword() === null) {
190
-			throw new PasswordlessTokenException();
191
-		}
192
-
193
-		// Decrypt private key with tokenId
194
-		$privateKey = $this->decrypt($token->getPrivateKey(), $tokenId);
195
-
196
-		// Decrypt password with private key
197
-		return $this->decryptPassword($token->getPassword(), $privateKey);
198
-	}
199
-
200
-	public function setPassword(IToken $token, string $tokenId, string $password) {
201
-		if (!($token instanceof PublicKeyToken)) {
202
-			throw new InvalidTokenException();
203
-		}
204
-
205
-		// When changing passwords all temp tokens are deleted
206
-		$this->mapper->deleteTempToken($token);
207
-
208
-		// Update the password for all tokens
209
-		$tokens = $this->mapper->getTokenByUser($token->getUID());
210
-		foreach ($tokens as $t) {
211
-			$publicKey = $t->getPublicKey();
212
-			$t->setPassword($this->encryptPassword($password, $publicKey));
213
-			$this->updateToken($t);
214
-		}
215
-	}
216
-
217
-	public function rotate(IToken $token, string $oldTokenId, string $newTokenId): IToken {
218
-		if (!($token instanceof PublicKeyToken)) {
219
-			throw new InvalidTokenException();
220
-		}
221
-
222
-		// Decrypt private key with oldTokenId
223
-		$privateKey = $this->decrypt($token->getPrivateKey(), $oldTokenId);
224
-		// Encrypt with the new token
225
-		$token->setPrivateKey($this->encrypt($privateKey, $newTokenId));
226
-
227
-		$token->setToken($this->hashToken($newTokenId));
228
-		$this->updateToken($token);
229
-
230
-		return $token;
231
-	}
232
-
233
-	private function encrypt(string $plaintext, string $token): string {
234
-		$secret = $this->config->getSystemValue('secret');
235
-		return $this->crypto->encrypt($plaintext, $token . $secret);
236
-	}
237
-
238
-	/**
239
-	 * @throws InvalidTokenException
240
-	 */
241
-	private function decrypt(string $cipherText, string $token): string {
242
-		$secret = $this->config->getSystemValue('secret');
243
-		try {
244
-			return $this->crypto->decrypt($cipherText, $token . $secret);
245
-		} catch (\Exception $ex) {
246
-			// Delete the invalid token
247
-			$this->invalidateToken($token);
248
-			throw new InvalidTokenException();
249
-		}
250
-	}
251
-
252
-	private function encryptPassword(string $password, string $publicKey): string {
253
-		openssl_public_encrypt($password, $encryptedPassword, $publicKey, OPENSSL_PKCS1_OAEP_PADDING);
254
-		$encryptedPassword = base64_encode($encryptedPassword);
255
-
256
-		return $encryptedPassword;
257
-	}
258
-
259
-	private function decryptPassword(string $encryptedPassword, string $privateKey): string {
260
-		$encryptedPassword = base64_decode($encryptedPassword);
261
-		openssl_private_decrypt($encryptedPassword, $password, $privateKey, OPENSSL_PKCS1_OAEP_PADDING);
262
-
263
-		return $password;
264
-	}
265
-
266
-	private function hashToken(string $token): string {
267
-		$secret = $this->config->getSystemValue('secret');
268
-		return hash('sha512', $token . $secret);
269
-	}
270
-
271
-	/**
272
-	 * Convert a DefaultToken to a publicKeyToken
273
-	 * This will also be updated directly in the Database
274
-	 * @throws \RuntimeException when OpenSSL reports a problem
275
-	 */
276
-	public function convertToken(DefaultToken $defaultToken, string $token, $password): PublicKeyToken {
277
-		$pkToken = $this->newToken(
278
-			$token,
279
-			$defaultToken->getUID(),
280
-			$defaultToken->getLoginName(),
281
-			$password,
282
-			$defaultToken->getName(),
283
-			$defaultToken->getType(),
284
-			$defaultToken->getRemember()
285
-		);
286
-
287
-		$pkToken->setExpires($defaultToken->getExpires());
288
-		$pkToken->setId($defaultToken->getId());
289
-
290
-		return $this->mapper->update($pkToken);
291
-	}
292
-
293
-	/**
294
-	 * @throws \RuntimeException when OpenSSL reports a problem
295
-	 */
296
-	private function newToken(string $token,
297
-							  string $uid,
298
-							  string $loginName,
299
-							  $password,
300
-							  string $name,
301
-							  int $type,
302
-							  int $remember): PublicKeyToken {
303
-		$dbToken = new PublicKeyToken();
304
-		$dbToken->setUid($uid);
305
-		$dbToken->setLoginName($loginName);
306
-
307
-		$config = array_merge([
308
-			'digest_alg' => 'sha512',
309
-			'private_key_bits' => 2048,
310
-		], $this->config->getSystemValue('openssl', []));
311
-
312
-		// Generate new key
313
-		$res = openssl_pkey_new($config);
314
-		if ($res === false) {
315
-			$this->logOpensslError();
316
-			throw new \RuntimeException('OpenSSL reported a problem');
317
-		}
318
-
319
-		if (openssl_pkey_export($res, $privateKey, null, $config) === false) {
320
-			$this->logOpensslError();
321
-			throw new \RuntimeException('OpenSSL reported a problem');
322
-		}
323
-
324
-		// Extract the public key from $res to $pubKey
325
-		$publicKey = openssl_pkey_get_details($res);
326
-		$publicKey = $publicKey['key'];
327
-
328
-		$dbToken->setPublicKey($publicKey);
329
-		$dbToken->setPrivateKey($this->encrypt($privateKey, $token));
330
-
331
-		if (!is_null($password)) {
332
-			$dbToken->setPassword($this->encryptPassword($password, $publicKey));
333
-		}
334
-
335
-		$dbToken->setName($name);
336
-		$dbToken->setToken($this->hashToken($token));
337
-		$dbToken->setType($type);
338
-		$dbToken->setRemember($remember);
339
-		$dbToken->setLastActivity($this->time->getTime());
340
-		$dbToken->setLastCheck($this->time->getTime());
341
-		$dbToken->setVersion(PublicKeyToken::VERSION);
342
-
343
-		return $dbToken;
344
-	}
345
-
346
-	public function markPasswordInvalid(IToken $token, string $tokenId) {
347
-		if (!($token instanceof PublicKeyToken)) {
348
-			throw new InvalidTokenException();
349
-		}
350
-
351
-		$token->setPasswordInvalid(true);
352
-		$this->mapper->update($token);
353
-	}
354
-
355
-	public function updatePasswords(string $uid, string $password) {
356
-		if (!$this->mapper->hasExpiredTokens($uid)) {
357
-			// Nothing to do here
358
-			return;
359
-		}
360
-
361
-		// Update the password for all tokens
362
-		$tokens = $this->mapper->getTokenByUser($uid);
363
-		foreach ($tokens as $t) {
364
-			$publicKey = $t->getPublicKey();
365
-			$t->setPassword($this->encryptPassword($password, $publicKey));
366
-			$this->updateToken($t);
367
-		}
368
-	}
369
-
370
-	private function logOpensslError() {
371
-		$errors = [];
372
-		while ($error = openssl_error_string()) {
373
-			$errors[] = $error;
374
-		}
375
-		$this->logger->critical('Something is wrong with your openssl setup: ' . implode(', ', $errors));
376
-	}
37
+    /** @var PublicKeyTokenMapper */
38
+    private $mapper;
39
+
40
+    /** @var ICrypto */
41
+    private $crypto;
42
+
43
+    /** @var IConfig */
44
+    private $config;
45
+
46
+    /** @var ILogger $logger */
47
+    private $logger;
48
+
49
+    /** @var ITimeFactory $time */
50
+    private $time;
51
+
52
+    public function __construct(PublicKeyTokenMapper $mapper,
53
+                                ICrypto $crypto,
54
+                                IConfig $config,
55
+                                ILogger $logger,
56
+                                ITimeFactory $time) {
57
+        $this->mapper = $mapper;
58
+        $this->crypto = $crypto;
59
+        $this->config = $config;
60
+        $this->logger = $logger;
61
+        $this->time = $time;
62
+    }
63
+
64
+    /**
65
+     * {@inheritDoc}
66
+     */
67
+    public function generateToken(string $token,
68
+                                    string $uid,
69
+                                    string $loginName,
70
+                                    $password,
71
+                                    string $name,
72
+                                    int $type = IToken::TEMPORARY_TOKEN,
73
+                                    int $remember = IToken::DO_NOT_REMEMBER): IToken {
74
+        $dbToken = $this->newToken($token, $uid, $loginName, $password, $name, $type, $remember);
75
+
76
+        $this->mapper->insert($dbToken);
77
+
78
+        return $dbToken;
79
+    }
80
+
81
+    public function getToken(string $tokenId): IToken {
82
+        try {
83
+            $token = $this->mapper->getToken($this->hashToken($tokenId));
84
+        } catch (DoesNotExistException $ex) {
85
+            throw new InvalidTokenException();
86
+        }
87
+
88
+        if ((int)$token->getExpires() !== 0 && $token->getExpires() < $this->time->getTime()) {
89
+            throw new ExpiredTokenException($token);
90
+        }
91
+
92
+        if ($token->getType() === IToken::WIPE_TOKEN) {
93
+            throw new WipeTokenException($token);
94
+        }
95
+
96
+        return $token;
97
+    }
98
+
99
+    public function getTokenById(int $tokenId): IToken {
100
+        try {
101
+            $token = $this->mapper->getTokenById($tokenId);
102
+        } catch (DoesNotExistException $ex) {
103
+            throw new InvalidTokenException();
104
+        }
105
+
106
+        if ((int)$token->getExpires() !== 0 && $token->getExpires() < $this->time->getTime()) {
107
+            throw new ExpiredTokenException($token);
108
+        }
109
+
110
+        if ($token->getType() === IToken::WIPE_TOKEN) {
111
+            throw new WipeTokenException($token);
112
+        }
113
+
114
+        return $token;
115
+    }
116
+
117
+    public function renewSessionToken(string $oldSessionId, string $sessionId) {
118
+        $token = $this->getToken($oldSessionId);
119
+
120
+        if (!($token instanceof PublicKeyToken)) {
121
+            throw new InvalidTokenException();
122
+        }
123
+
124
+        $password = null;
125
+        if (!is_null($token->getPassword())) {
126
+            $privateKey = $this->decrypt($token->getPrivateKey(), $oldSessionId);
127
+            $password = $this->decryptPassword($token->getPassword(), $privateKey);
128
+        }
129
+
130
+        $this->generateToken(
131
+            $sessionId,
132
+            $token->getUID(),
133
+            $token->getLoginName(),
134
+            $password,
135
+            $token->getName(),
136
+            IToken::TEMPORARY_TOKEN,
137
+            $token->getRemember()
138
+        );
139
+
140
+        $this->mapper->delete($token);
141
+    }
142
+
143
+    public function invalidateToken(string $token) {
144
+        $this->mapper->invalidate($this->hashToken($token));
145
+    }
146
+
147
+    public function invalidateTokenById(string $uid, int $id) {
148
+        $this->mapper->deleteById($uid, $id);
149
+    }
150
+
151
+    public function invalidateOldTokens() {
152
+        $olderThan = $this->time->getTime() - (int) $this->config->getSystemValue('session_lifetime', 60 * 60 * 24);
153
+        $this->logger->debug('Invalidating session tokens older than ' . date('c', $olderThan), ['app' => 'cron']);
154
+        $this->mapper->invalidateOld($olderThan, IToken::DO_NOT_REMEMBER);
155
+        $rememberThreshold = $this->time->getTime() - (int) $this->config->getSystemValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15);
156
+        $this->logger->debug('Invalidating remembered session tokens older than ' . date('c', $rememberThreshold), ['app' => 'cron']);
157
+        $this->mapper->invalidateOld($rememberThreshold, IToken::REMEMBER);
158
+    }
159
+
160
+    public function updateToken(IToken $token) {
161
+        if (!($token instanceof PublicKeyToken)) {
162
+            throw new InvalidTokenException();
163
+        }
164
+        $this->mapper->update($token);
165
+    }
166
+
167
+    public function updateTokenActivity(IToken $token) {
168
+        if (!($token instanceof PublicKeyToken)) {
169
+            throw new InvalidTokenException();
170
+        }
171
+        /** @var DefaultToken $token */
172
+        $now = $this->time->getTime();
173
+        if ($token->getLastActivity() < ($now - 60)) {
174
+            // Update token only once per minute
175
+            $token->setLastActivity($now);
176
+            $this->mapper->update($token);
177
+        }
178
+    }
179
+
180
+    public function getTokenByUser(string $uid): array {
181
+        return $this->mapper->getTokenByUser($uid);
182
+    }
183
+
184
+    public function getPassword(IToken $token, string $tokenId): string {
185
+        if (!($token instanceof PublicKeyToken)) {
186
+            throw new InvalidTokenException();
187
+        }
188
+
189
+        if ($token->getPassword() === null) {
190
+            throw new PasswordlessTokenException();
191
+        }
192
+
193
+        // Decrypt private key with tokenId
194
+        $privateKey = $this->decrypt($token->getPrivateKey(), $tokenId);
195
+
196
+        // Decrypt password with private key
197
+        return $this->decryptPassword($token->getPassword(), $privateKey);
198
+    }
199
+
200
+    public function setPassword(IToken $token, string $tokenId, string $password) {
201
+        if (!($token instanceof PublicKeyToken)) {
202
+            throw new InvalidTokenException();
203
+        }
204
+
205
+        // When changing passwords all temp tokens are deleted
206
+        $this->mapper->deleteTempToken($token);
207
+
208
+        // Update the password for all tokens
209
+        $tokens = $this->mapper->getTokenByUser($token->getUID());
210
+        foreach ($tokens as $t) {
211
+            $publicKey = $t->getPublicKey();
212
+            $t->setPassword($this->encryptPassword($password, $publicKey));
213
+            $this->updateToken($t);
214
+        }
215
+    }
216
+
217
+    public function rotate(IToken $token, string $oldTokenId, string $newTokenId): IToken {
218
+        if (!($token instanceof PublicKeyToken)) {
219
+            throw new InvalidTokenException();
220
+        }
221
+
222
+        // Decrypt private key with oldTokenId
223
+        $privateKey = $this->decrypt($token->getPrivateKey(), $oldTokenId);
224
+        // Encrypt with the new token
225
+        $token->setPrivateKey($this->encrypt($privateKey, $newTokenId));
226
+
227
+        $token->setToken($this->hashToken($newTokenId));
228
+        $this->updateToken($token);
229
+
230
+        return $token;
231
+    }
232
+
233
+    private function encrypt(string $plaintext, string $token): string {
234
+        $secret = $this->config->getSystemValue('secret');
235
+        return $this->crypto->encrypt($plaintext, $token . $secret);
236
+    }
237
+
238
+    /**
239
+     * @throws InvalidTokenException
240
+     */
241
+    private function decrypt(string $cipherText, string $token): string {
242
+        $secret = $this->config->getSystemValue('secret');
243
+        try {
244
+            return $this->crypto->decrypt($cipherText, $token . $secret);
245
+        } catch (\Exception $ex) {
246
+            // Delete the invalid token
247
+            $this->invalidateToken($token);
248
+            throw new InvalidTokenException();
249
+        }
250
+    }
251
+
252
+    private function encryptPassword(string $password, string $publicKey): string {
253
+        openssl_public_encrypt($password, $encryptedPassword, $publicKey, OPENSSL_PKCS1_OAEP_PADDING);
254
+        $encryptedPassword = base64_encode($encryptedPassword);
255
+
256
+        return $encryptedPassword;
257
+    }
258
+
259
+    private function decryptPassword(string $encryptedPassword, string $privateKey): string {
260
+        $encryptedPassword = base64_decode($encryptedPassword);
261
+        openssl_private_decrypt($encryptedPassword, $password, $privateKey, OPENSSL_PKCS1_OAEP_PADDING);
262
+
263
+        return $password;
264
+    }
265
+
266
+    private function hashToken(string $token): string {
267
+        $secret = $this->config->getSystemValue('secret');
268
+        return hash('sha512', $token . $secret);
269
+    }
270
+
271
+    /**
272
+     * Convert a DefaultToken to a publicKeyToken
273
+     * This will also be updated directly in the Database
274
+     * @throws \RuntimeException when OpenSSL reports a problem
275
+     */
276
+    public function convertToken(DefaultToken $defaultToken, string $token, $password): PublicKeyToken {
277
+        $pkToken = $this->newToken(
278
+            $token,
279
+            $defaultToken->getUID(),
280
+            $defaultToken->getLoginName(),
281
+            $password,
282
+            $defaultToken->getName(),
283
+            $defaultToken->getType(),
284
+            $defaultToken->getRemember()
285
+        );
286
+
287
+        $pkToken->setExpires($defaultToken->getExpires());
288
+        $pkToken->setId($defaultToken->getId());
289
+
290
+        return $this->mapper->update($pkToken);
291
+    }
292
+
293
+    /**
294
+     * @throws \RuntimeException when OpenSSL reports a problem
295
+     */
296
+    private function newToken(string $token,
297
+                                string $uid,
298
+                                string $loginName,
299
+                                $password,
300
+                                string $name,
301
+                                int $type,
302
+                                int $remember): PublicKeyToken {
303
+        $dbToken = new PublicKeyToken();
304
+        $dbToken->setUid($uid);
305
+        $dbToken->setLoginName($loginName);
306
+
307
+        $config = array_merge([
308
+            'digest_alg' => 'sha512',
309
+            'private_key_bits' => 2048,
310
+        ], $this->config->getSystemValue('openssl', []));
311
+
312
+        // Generate new key
313
+        $res = openssl_pkey_new($config);
314
+        if ($res === false) {
315
+            $this->logOpensslError();
316
+            throw new \RuntimeException('OpenSSL reported a problem');
317
+        }
318
+
319
+        if (openssl_pkey_export($res, $privateKey, null, $config) === false) {
320
+            $this->logOpensslError();
321
+            throw new \RuntimeException('OpenSSL reported a problem');
322
+        }
323
+
324
+        // Extract the public key from $res to $pubKey
325
+        $publicKey = openssl_pkey_get_details($res);
326
+        $publicKey = $publicKey['key'];
327
+
328
+        $dbToken->setPublicKey($publicKey);
329
+        $dbToken->setPrivateKey($this->encrypt($privateKey, $token));
330
+
331
+        if (!is_null($password)) {
332
+            $dbToken->setPassword($this->encryptPassword($password, $publicKey));
333
+        }
334
+
335
+        $dbToken->setName($name);
336
+        $dbToken->setToken($this->hashToken($token));
337
+        $dbToken->setType($type);
338
+        $dbToken->setRemember($remember);
339
+        $dbToken->setLastActivity($this->time->getTime());
340
+        $dbToken->setLastCheck($this->time->getTime());
341
+        $dbToken->setVersion(PublicKeyToken::VERSION);
342
+
343
+        return $dbToken;
344
+    }
345
+
346
+    public function markPasswordInvalid(IToken $token, string $tokenId) {
347
+        if (!($token instanceof PublicKeyToken)) {
348
+            throw new InvalidTokenException();
349
+        }
350
+
351
+        $token->setPasswordInvalid(true);
352
+        $this->mapper->update($token);
353
+    }
354
+
355
+    public function updatePasswords(string $uid, string $password) {
356
+        if (!$this->mapper->hasExpiredTokens($uid)) {
357
+            // Nothing to do here
358
+            return;
359
+        }
360
+
361
+        // Update the password for all tokens
362
+        $tokens = $this->mapper->getTokenByUser($uid);
363
+        foreach ($tokens as $t) {
364
+            $publicKey = $t->getPublicKey();
365
+            $t->setPassword($this->encryptPassword($password, $publicKey));
366
+            $this->updateToken($t);
367
+        }
368
+    }
369
+
370
+    private function logOpensslError() {
371
+        $errors = [];
372
+        while ($error = openssl_error_string()) {
373
+            $errors[] = $error;
374
+        }
375
+        $this->logger->critical('Something is wrong with your openssl setup: ' . implode(', ', $errors));
376
+    }
377 377
 }
Please login to merge, or discard this patch.