/libraries/joomla/keychain/keychain.php

https://github.com/andreatarr/joomla-cms · PHP · 200 lines · 88 code · 31 blank · 81 comment · 14 complexity · f2e848f5a374343cd50ae5af9a002c82 MD5 · raw file

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