Passed
Push — master ( b396ae...8037a4 )
by Lukas
15:15 queued 11s
created
lib/private/Security/Crypto.php 2 patches
Indentation   +132 added lines, -132 removed lines patch added patch discarded remove patch
@@ -47,136 +47,136 @@
 block discarded – undo
47 47
  * @package OC\Security
48 48
  */
49 49
 class Crypto implements ICrypto {
50
-	/** @var AES $cipher */
51
-	private $cipher;
52
-	/** @var int */
53
-	private $ivLength = 16;
54
-	/** @var IConfig */
55
-	private $config;
56
-
57
-	/**
58
-	 * @param IConfig $config
59
-	 * @param ISecureRandom $random
60
-	 */
61
-	public function __construct(IConfig $config) {
62
-		$this->cipher = new AES();
63
-		$this->config = $config;
64
-	}
65
-
66
-	/**
67
-	 * @param string $message The message to authenticate
68
-	 * @param string $password Password to use (defaults to `secret` in config.php)
69
-	 * @return string Calculated HMAC
70
-	 */
71
-	public function calculateHMAC(string $message, string $password = ''): string {
72
-		if ($password === '') {
73
-			$password = $this->config->getSystemValue('secret');
74
-		}
75
-
76
-		// Append an "a" behind the password and hash it to prevent reusing the same password as for encryption
77
-		$password = hash('sha512', $password . 'a');
78
-
79
-		$hash = new Hash('sha512');
80
-		$hash->setKey($password);
81
-		return $hash->hash($message);
82
-	}
83
-
84
-	/**
85
-	 * Encrypts a value and adds an HMAC (Encrypt-Then-MAC)
86
-	 *
87
-	 * @param string $plaintext
88
-	 * @param string $password Password to encrypt, if not specified the secret from config.php will be taken
89
-	 * @return string Authenticated ciphertext
90
-	 * @throws Exception if it was not possible to gather sufficient entropy
91
-	 * @throws Exception if encrypting the data failed
92
-	 */
93
-	public function encrypt(string $plaintext, string $password = ''): string {
94
-		if ($password === '') {
95
-			$password = $this->config->getSystemValue('secret');
96
-		}
97
-		$keyMaterial = hash_hkdf('sha512', $password);
98
-		$this->cipher->setPassword(substr($keyMaterial, 0, 32));
99
-
100
-		$iv = \random_bytes($this->ivLength);
101
-		$this->cipher->setIV($iv);
102
-
103
-		/** @var string|false $encrypted */
104
-		$encrypted = $this->cipher->encrypt($plaintext);
105
-		if ($encrypted === false) {
106
-			throw new Exception('Encrypting failed.');
107
-		}
108
-
109
-		$ciphertext = bin2hex($encrypted);
110
-		$iv = bin2hex($iv);
111
-		$hmac = bin2hex($this->calculateHMAC($ciphertext.$iv, substr($keyMaterial, 32)));
112
-
113
-		return $ciphertext.'|'.$iv.'|'.$hmac.'|3';
114
-	}
115
-
116
-	/**
117
-	 * Decrypts a value and verifies the HMAC (Encrypt-Then-Mac)
118
-	 * @param string $authenticatedCiphertext
119
-	 * @param string $password Password to encrypt, if not specified the secret from config.php will be taken
120
-	 * @return string plaintext
121
-	 * @throws Exception If the HMAC does not match
122
-	 * @throws Exception If the decryption failed
123
-	 */
124
-	public function decrypt(string $authenticatedCiphertext, string $password = ''): string {
125
-		if ($password === '') {
126
-			$password = $this->config->getSystemValue('secret');
127
-		}
128
-		$hmacKey = $encryptionKey = $password;
129
-
130
-		$parts = explode('|', $authenticatedCiphertext);
131
-		$partCount = \count($parts);
132
-		if ($partCount < 3 || $partCount > 4) {
133
-			throw new Exception('Authenticated ciphertext could not be decoded.');
134
-		}
135
-
136
-		$ciphertext = $this->hex2bin($parts[0]);
137
-		$iv = $parts[1];
138
-		$hmac = $this->hex2bin($parts[2]);
139
-
140
-		if ($partCount === 4) {
141
-			$version = $parts[3];
142
-			if ($version >= '2') {
143
-				$iv = $this->hex2bin($iv);
144
-			}
145
-
146
-			if ($version === '3') {
147
-				$keyMaterial = hash_hkdf('sha512', $password);
148
-				$encryptionKey = substr($keyMaterial, 0, 32);
149
-				$hmacKey = substr($keyMaterial, 32);
150
-			}
151
-		}
152
-		$this->cipher->setPassword($encryptionKey);
153
-		$this->cipher->setIV($iv);
154
-
155
-		if (!hash_equals($this->calculateHMAC($parts[0] . $parts[1], $hmacKey), $hmac)) {
156
-			throw new Exception('HMAC does not match.');
157
-		}
158
-
159
-		$result = $this->cipher->decrypt($ciphertext);
160
-		if ($result === false) {
161
-			throw new Exception('Decryption failed');
162
-		}
163
-
164
-		return $result;
165
-	}
166
-
167
-	private function hex2bin(string $hex): string {
168
-		if (!ctype_xdigit($hex)) {
169
-			throw new \RuntimeException('String contains non hex chars: ' . $hex);
170
-		}
171
-		if (strlen($hex) % 2 !== 0) {
172
-			throw new \RuntimeException('Hex string is not of even length: ' . $hex);
173
-		}
174
-		$result = hex2bin($hex);
175
-
176
-		if ($result === false) {
177
-			throw new \RuntimeException('Hex to bin conversion failed: ' . $hex);
178
-		}
179
-
180
-		return $result;
181
-	}
50
+    /** @var AES $cipher */
51
+    private $cipher;
52
+    /** @var int */
53
+    private $ivLength = 16;
54
+    /** @var IConfig */
55
+    private $config;
56
+
57
+    /**
58
+     * @param IConfig $config
59
+     * @param ISecureRandom $random
60
+     */
61
+    public function __construct(IConfig $config) {
62
+        $this->cipher = new AES();
63
+        $this->config = $config;
64
+    }
65
+
66
+    /**
67
+     * @param string $message The message to authenticate
68
+     * @param string $password Password to use (defaults to `secret` in config.php)
69
+     * @return string Calculated HMAC
70
+     */
71
+    public function calculateHMAC(string $message, string $password = ''): string {
72
+        if ($password === '') {
73
+            $password = $this->config->getSystemValue('secret');
74
+        }
75
+
76
+        // Append an "a" behind the password and hash it to prevent reusing the same password as for encryption
77
+        $password = hash('sha512', $password . 'a');
78
+
79
+        $hash = new Hash('sha512');
80
+        $hash->setKey($password);
81
+        return $hash->hash($message);
82
+    }
83
+
84
+    /**
85
+     * Encrypts a value and adds an HMAC (Encrypt-Then-MAC)
86
+     *
87
+     * @param string $plaintext
88
+     * @param string $password Password to encrypt, if not specified the secret from config.php will be taken
89
+     * @return string Authenticated ciphertext
90
+     * @throws Exception if it was not possible to gather sufficient entropy
91
+     * @throws Exception if encrypting the data failed
92
+     */
93
+    public function encrypt(string $plaintext, string $password = ''): string {
94
+        if ($password === '') {
95
+            $password = $this->config->getSystemValue('secret');
96
+        }
97
+        $keyMaterial = hash_hkdf('sha512', $password);
98
+        $this->cipher->setPassword(substr($keyMaterial, 0, 32));
99
+
100
+        $iv = \random_bytes($this->ivLength);
101
+        $this->cipher->setIV($iv);
102
+
103
+        /** @var string|false $encrypted */
104
+        $encrypted = $this->cipher->encrypt($plaintext);
105
+        if ($encrypted === false) {
106
+            throw new Exception('Encrypting failed.');
107
+        }
108
+
109
+        $ciphertext = bin2hex($encrypted);
110
+        $iv = bin2hex($iv);
111
+        $hmac = bin2hex($this->calculateHMAC($ciphertext.$iv, substr($keyMaterial, 32)));
112
+
113
+        return $ciphertext.'|'.$iv.'|'.$hmac.'|3';
114
+    }
115
+
116
+    /**
117
+     * Decrypts a value and verifies the HMAC (Encrypt-Then-Mac)
118
+     * @param string $authenticatedCiphertext
119
+     * @param string $password Password to encrypt, if not specified the secret from config.php will be taken
120
+     * @return string plaintext
121
+     * @throws Exception If the HMAC does not match
122
+     * @throws Exception If the decryption failed
123
+     */
124
+    public function decrypt(string $authenticatedCiphertext, string $password = ''): string {
125
+        if ($password === '') {
126
+            $password = $this->config->getSystemValue('secret');
127
+        }
128
+        $hmacKey = $encryptionKey = $password;
129
+
130
+        $parts = explode('|', $authenticatedCiphertext);
131
+        $partCount = \count($parts);
132
+        if ($partCount < 3 || $partCount > 4) {
133
+            throw new Exception('Authenticated ciphertext could not be decoded.');
134
+        }
135
+
136
+        $ciphertext = $this->hex2bin($parts[0]);
137
+        $iv = $parts[1];
138
+        $hmac = $this->hex2bin($parts[2]);
139
+
140
+        if ($partCount === 4) {
141
+            $version = $parts[3];
142
+            if ($version >= '2') {
143
+                $iv = $this->hex2bin($iv);
144
+            }
145
+
146
+            if ($version === '3') {
147
+                $keyMaterial = hash_hkdf('sha512', $password);
148
+                $encryptionKey = substr($keyMaterial, 0, 32);
149
+                $hmacKey = substr($keyMaterial, 32);
150
+            }
151
+        }
152
+        $this->cipher->setPassword($encryptionKey);
153
+        $this->cipher->setIV($iv);
154
+
155
+        if (!hash_equals($this->calculateHMAC($parts[0] . $parts[1], $hmacKey), $hmac)) {
156
+            throw new Exception('HMAC does not match.');
157
+        }
158
+
159
+        $result = $this->cipher->decrypt($ciphertext);
160
+        if ($result === false) {
161
+            throw new Exception('Decryption failed');
162
+        }
163
+
164
+        return $result;
165
+    }
166
+
167
+    private function hex2bin(string $hex): string {
168
+        if (!ctype_xdigit($hex)) {
169
+            throw new \RuntimeException('String contains non hex chars: ' . $hex);
170
+        }
171
+        if (strlen($hex) % 2 !== 0) {
172
+            throw new \RuntimeException('Hex string is not of even length: ' . $hex);
173
+        }
174
+        $result = hex2bin($hex);
175
+
176
+        if ($result === false) {
177
+            throw new \RuntimeException('Hex to bin conversion failed: ' . $hex);
178
+        }
179
+
180
+        return $result;
181
+    }
182 182
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -74,7 +74,7 @@  discard block
 block discarded – undo
74 74
 		}
75 75
 
76 76
 		// Append an "a" behind the password and hash it to prevent reusing the same password as for encryption
77
-		$password = hash('sha512', $password . 'a');
77
+		$password = hash('sha512', $password.'a');
78 78
 
79 79
 		$hash = new Hash('sha512');
80 80
 		$hash->setKey($password);
@@ -152,7 +152,7 @@  discard block
 block discarded – undo
152 152
 		$this->cipher->setPassword($encryptionKey);
153 153
 		$this->cipher->setIV($iv);
154 154
 
155
-		if (!hash_equals($this->calculateHMAC($parts[0] . $parts[1], $hmacKey), $hmac)) {
155
+		if (!hash_equals($this->calculateHMAC($parts[0].$parts[1], $hmacKey), $hmac)) {
156 156
 			throw new Exception('HMAC does not match.');
157 157
 		}
158 158
 
@@ -166,15 +166,15 @@  discard block
 block discarded – undo
166 166
 
167 167
 	private function hex2bin(string $hex): string {
168 168
 		if (!ctype_xdigit($hex)) {
169
-			throw new \RuntimeException('String contains non hex chars: ' . $hex);
169
+			throw new \RuntimeException('String contains non hex chars: '.$hex);
170 170
 		}
171 171
 		if (strlen($hex) % 2 !== 0) {
172
-			throw new \RuntimeException('Hex string is not of even length: ' . $hex);
172
+			throw new \RuntimeException('Hex string is not of even length: '.$hex);
173 173
 		}
174 174
 		$result = hex2bin($hex);
175 175
 
176 176
 		if ($result === false) {
177
-			throw new \RuntimeException('Hex to bin conversion failed: ' . $hex);
177
+			throw new \RuntimeException('Hex to bin conversion failed: '.$hex);
178 178
 		}
179 179
 
180 180
 		return $result;
Please login to merge, or discard this patch.