Completed
Push — master ( f6f10b...60ee45 )
by Björn
15:27
created

Manager::generateKeyPair()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 16
rs 9.4285
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016 Lukas Reschke <[email protected]>
4
 *
5
 * @license GNU AGPL version 3 or any later version
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Affero General Public License as
9
 * published by the Free Software Foundation, either version 3 of the
10
 * License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 */
21
22
namespace OC\Security\IdentityProof;
23
24
use OC\Files\AppData\Factory;
25
use OCP\Files\IAppData;
26
use OCP\IConfig;
27
use OCP\IUser;
28
use OCP\Security\ICrypto;
29
30
class Manager {
31
	/** @var IAppData */
32
	private $appData;
33
	/** @var ICrypto */
34
	private $crypto;
35
	/** @var IConfig */
36
	private $config;
37
38
	/**
39
	 * @param Factory $appDataFactory
40
	 * @param ICrypto $crypto
41
	 * @param IConfig $config
42
	 */
43
	public function __construct(Factory $appDataFactory,
44
								ICrypto $crypto,
45
								IConfig $config
46
	) {
47
		$this->appData = $appDataFactory->get('identityproof');
48
		$this->crypto = $crypto;
49
		$this->config = $config;
50
	}
51
52
	/**
53
	 * Calls the openssl functions to generate a public and private key.
54
	 * In a separate function for unit testing purposes.
55
	 *
56
	 * @return array [$publicKey, $privateKey]
57
	 */
58
	protected function generateKeyPair() {
59
		$config = [
60
			'digest_alg' => 'sha512',
61
			'private_key_bits' => 2048,
62
		];
63
64
		// Generate new key
65
		$res = openssl_pkey_new($config);
66
		openssl_pkey_export($res, $privateKey);
67
68
		// Extract the public key from $res to $pubKey
69
		$publicKey = openssl_pkey_get_details($res);
70
		$publicKey = $publicKey['key'];
71
72
		return [$publicKey, $privateKey];
73
	}
74
75
	/**
76
	 * Generate a key for a given ID
77
	 * Note: If a key already exists it will be overwritten
78
	 *
79
	 * @param string $id key id
80
	 * @return Key
81
	 */
82
	protected function generateKey($id) {
83
		list($publicKey, $privateKey) = $this->generateKeyPair();
84
85
		// Write the private and public key to the disk
86
		try {
87
			$this->appData->newFolder($id);
88
		} catch (\Exception $e) {}
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
89
		$folder = $this->appData->getFolder($id);
90
		$folder->newFile('private')
91
			->putContent($this->crypto->encrypt($privateKey));
92
		$folder->newFile('public')
93
			->putContent($publicKey);
94
95
		return new Key($publicKey, $privateKey);
96
	}
97
98
	/**
99
	 * Get key for a specific id
100
	 *
101
	 * @param string $id
102
	 * @return Key
103
	 */
104
	protected function retrieveKey($id) {
105
		try {
106
			$folder = $this->appData->getFolder($id);
107
			$privateKey = $this->crypto->decrypt(
108
				$folder->getFile('private')->getContent()
109
			);
110
			$publicKey = $folder->getFile('public')->getContent();
111
			return new Key($publicKey, $privateKey);
112
		} catch (\Exception $e) {
113
			return $this->generateKey($id);
114
		}
115
	}
116
117
	/**
118
	 * Get public and private key for $user
119
	 *
120
	 * @param IUser $user
121
	 * @return Key
122
	 */
123
	public function getKey(IUser $user) {
124
		$uid = $user->getUID();
125
		return $this->retrieveKey('user-' . $uid);
126
	}
127
128
	/**
129
	 * Get instance wide public and private key
130
	 *
131
	 * @return Key
132
	 * @throws \RuntimeException
133
	 */
134 View Code Duplication
	public function getSystemKey() {
135
		$instanceId = $this->config->getSystemValue('instanceid', null);
136
		if ($instanceId === null) {
137
			throw new \RuntimeException('no instance id!');
138
		}
139
		return $this->retrieveKey('system-' . $instanceId);
140
	}
141
142
143
}
144