keychain.php
5.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
<?php
/**
* @package Joomla.Platform
* @subpackage Keychain
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Keychain Class
*
* @since 3.1.4
* @deprecated 4.0 Deprecated without replacement
*/
class JKeychain extends \Joomla\Registry\Registry
{
/**
* @var string Method to use for encryption.
* @since 3.1.4
*/
public $method = 'aes-128-cbc';
/**
* @var string Initialisation vector for encryption method.
* @since 3.1.4
*/
public $iv = '1234567890123456';
/**
* Create a passphrase file
*
* @param string $passphrase The passphrase to store in the passphrase file.
* @param string $passphraseFile Path to the passphrase file to create.
* @param string $privateKeyFile Path to the private key file to encrypt the passphrase file.
* @param string $privateKeyPassphrase The passphrase for the private key.
*
* @return boolean Result of writing the passphrase file to disk.
*
* @since 3.1.4
* @throws RuntimeException
*/
public function createPassphraseFile($passphrase, $passphraseFile, $privateKeyFile, $privateKeyPassphrase)
{
$privateKey = openssl_get_privatekey(file_get_contents($privateKeyFile), $privateKeyPassphrase);
if (!$privateKey)
{
throw new RuntimeException('Failed to load private key.');
}
$crypted = '';
if (!openssl_private_encrypt($passphrase, $crypted, $privateKey))
{
throw new RuntimeException('Failed to encrypt data using private key.');
}
return file_put_contents($passphraseFile, $crypted);
}
/**
* Delete a registry value (very simple method)
*
* @param string $path Registry Path (e.g. joomla.content.showauthor)
*
* @return mixed Value of old value or boolean false if operation failed
*
* @since 3.1.4
*/
public function deleteValue($path)
{
$result = null;
// Explode the registry path into an array
$nodes = explode('.', $path);
if ($nodes)
{
// Initialize the current node to be the registry root.
$node = $this->data;
// Traverse the registry to find the correct node for the result.
for ($i = 0, $n = count($nodes) - 1; $i < $n; $i++)
{
if (!isset($node->{$nodes[$i]}) && ($i != $n))
{
$node->{$nodes[$i]} = new stdClass;
}
$node = $node->{$nodes[$i]};
}
// Get the old value if exists so we can return it
$result = $node->{$nodes[$i]};
unset($node->{$nodes[$i]});
}
return $result;
}
/**
* Load a keychain file into this object.
*
* @param string $keychainFile Path to the keychain file.
* @param string $passphraseFile The path to the passphrase file to decript the keychain.
* @param string $publicKeyFile The file containing the public key to decrypt the passphrase file.
*
* @return boolean Result of loading the object.
*
* @since 3.1.4
* @throws RuntimeException
*/
public function loadKeychain($keychainFile, $passphraseFile, $publicKeyFile)
{
if (!file_exists($keychainFile))
{
throw new RuntimeException('Attempting to load non-existent keychain file');
}
$passphrase = $this->getPassphraseFromFile($passphraseFile, $publicKeyFile);
$cleartext = openssl_decrypt(file_get_contents($keychainFile), $this->method, $passphrase, true, $this->iv);
if ($cleartext === false)
{
throw new RuntimeException('Failed to decrypt keychain file');
}
return $this->loadObject(json_decode($cleartext));
}
/**
* Save this keychain to a file.
*
* @param string $keychainFile The path to the keychain file.
* @param string $passphraseFile The path to the passphrase file to encrypt the keychain.
* @param string $publicKeyFile The file containing the public key to decrypt the passphrase file.
*
* @return boolean Result of storing the file.
*
* @since 3.1.4
* @throws RuntimeException
*/
public function saveKeychain($keychainFile, $passphraseFile, $publicKeyFile)
{
$passphrase = $this->getPassphraseFromFile($passphraseFile, $publicKeyFile);
$data = $this->toString('JSON');
$encrypted = @openssl_encrypt($data, $this->method, $passphrase, true, $this->iv);
if ($encrypted === false)
{
throw new RuntimeException('Unable to encrypt keychain');
}
return file_put_contents($keychainFile, $encrypted);
}
/**
* Get the passphrase for this keychain
*
* @param string $passphraseFile The file containing the passphrase to encrypt and decrypt.
* @param string $publicKeyFile The file containing the public key to decrypt the passphrase file.
*
* @return string The passphrase in from passphraseFile
*
* @since 3.1.4
* @throws RuntimeException
*/
protected function getPassphraseFromFile($passphraseFile, $publicKeyFile)
{
if (!file_exists($publicKeyFile))
{
throw new RuntimeException('Missing public key file');
}
$publicKey = openssl_get_publickey(file_get_contents($publicKeyFile));
if (!$publicKey)
{
throw new RuntimeException('Failed to load public key.');
}
if (!file_exists($passphraseFile))
{
throw new RuntimeException('Missing passphrase file');
}
$passphrase = '';
if (!openssl_public_decrypt(file_get_contents($passphraseFile), $passphrase, $publicKey))
{
throw new RuntimeException('Failed to decrypt passphrase file');
}
return $passphrase;
}
}