Completed
Push — master ( ba9b17...94004c )
by Lukas
05:19 queued 04:59
created

Signer::removeProtocolFromUrl()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 9
rs 9.6666
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 OCP\AppFramework\Utility\ITimeFactory;
25
use OCP\IURLGenerator;
26
use OCP\IUser;
27
use OCP\IUserManager;
28
29
class Signer {
30
	/** @var Manager */
31
	private $keyManager;
32
	/** @var ITimeFactory */
33
	private $timeFactory;
34
	/** @var IURLGenerator */
35
	private $urlGenerator;
36
	/** @var IUserManager */
37
	private $userManager;
38
39
	/**
40
	 * @param Manager $keyManager
41
	 * @param ITimeFactory $timeFactory
42
	 * @param IURLGenerator $urlGenerator
43
	 * @param IUserManager $userManager
44
	 */
45
	public function __construct(Manager $keyManager,
46
								ITimeFactory $timeFactory,
47
								IURLGenerator $urlGenerator,
0 ignored issues
show
Unused Code introduced by
The parameter $urlGenerator is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
48
								IUserManager $userManager) {
49
		$this->keyManager = $keyManager;
50
		$this->timeFactory = $timeFactory;
51
		$this->userManager = $userManager;
52
	}
53
54
	/**
55
	 * Returns a signed blob for $data
56
	 *
57
	 * @param string $type
58
	 * @param array $data
59
	 * @param IUser $user
60
	 * @return array ['message', 'signature']
61
	 */
62
	public function sign($type, array $data, IUser $user) {
63
		$privateKey = $this->keyManager->getKey($user)->getPrivate();
64
		$data = [
65
			'data' => $data,
66
			'type' => $type,
67
			'signer' => $user->getCloudId(),
68
			'timestamp' => $this->timeFactory->getTime(),
69
		];
70
		openssl_sign(json_encode($data), $signature, $privateKey, OPENSSL_ALGO_SHA512);
71
72
		return [
73
			'message' => $data,
74
			'signature' => base64_encode($signature),
75
		];
76
	}
77
78
	/**
79
	 * @param string $url
80
	 * @return string
81
	 */
82
	private function removeProtocolFromUrl($url) {
83
		if (strpos($url, 'https://') === 0) {
84
			return substr($url, strlen('https://'));
85
		} else if (strpos($url, 'http://') === 0) {
86
			return substr($url, strlen('http://'));
87
		}
88
89
		return $url;
90
	}
91
92
	/**
93
	 * Whether the data is signed properly
94
	 *
95
	 * @param array $data
96
	 * @return bool
97
	 */
98
	public function verify(array $data) {
99
		if(isset($data['message'])
100
			&& isset($data['signature'])
101
			&& isset($data['message']['signer'])
102
		) {
103
			$server = $this->urlGenerator->getAbsoluteURL('/');
104
			$postfix = strlen('@' . rtrim($this->removeProtocolFromUrl($server), '/'));
105
			$userId = substr($data['message']['signer'], -$postfix);
106
107
			$user = $this->userManager->get($userId);
108
			if($user !== null) {
109
				$key = $this->keyManager->getKey($user);
110
				return (bool)openssl_verify(
111
					json_encode($data['message']),
112
					base64_decode($data['signature']),
113
					$key->getPublic()
114
				);
115
			}
116
		}
117
118
		return false;
119
	}
120
}
121