05ed160bcb1cacd6cdbe55bdff208432a040a83f
[Packages/TYPO3.CMS.git] / typo3 / sysext / rsaauth / sv1 / backends / class.tx_rsaauth_cmdline_backend.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009-2010 Dmitry Dulepov <dmitry@typo3.org>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25 /**
26 * [CLASS/FUNCTION INDEX of SCRIPT]
27 *
28 * $Id$
29 */
30
31 require_once(t3lib_extMgm::extPath('rsaauth', 'sv1/backends/class.tx_rsaauth_abstract_backend.php'));
32
33 /**
34 * This class contains a OpenSSL backend for the TYPO3 RSA authentication
35 * service. It uses shell version of OpenSSL to perform tasks. See class
36 * tx_rsaauth_abstract_backend for the information on using backends.
37 *
38 * @author Dmitry Dulepov <dmitry@typo3.org>
39 * @package TYPO3
40 * @subpackage tx_rsaauth
41 */
42 class tx_rsaauth_cmdline_backend extends tx_rsaauth_abstract_backend {
43
44 /**
45 * A path to the openssl binary or false if the binary does not exist
46 *
47 * @var mixed
48 */
49 protected $opensslPath;
50
51 /**
52 * Temporary directory. It is best of it is outside of the web site root and
53 * not publically readable.
54 * For now we use typo3temp/.
55 *
56 * @var string
57 */
58 protected $temporaryDirectory;
59
60 /**
61 * Creates an instance of this class. It obtains a path to the OpenSSL
62 * binary.
63 *
64 * @return void
65 */
66 public function __construct() {
67 $this->opensslPath = t3lib_exec::getCommand('openssl');
68 $this->temporaryDirectory = PATH_site . 'typo3temp';
69
70 // Get temporary directory from the configuration
71 $extconf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['rsaauth']);
72 if ($extconf['temporaryDirectory'] != '' &&
73 $extconf['temporaryDirectory']{0} == '/' &&
74 @is_dir($extconf['temporaryDirectory']) &&
75 is_writable($extconf['temporaryDirectory'])) {
76 $this->temporaryDirectory = $extconf['temporaryDirectory'];
77 }
78 }
79
80 /**
81 *
82 * @return tx_rsaauth_keypair A new key pair or null in case of error
83 * @see tx_rsaauth_abstract_backend::createNewKeyPair()
84 */
85 public function createNewKeyPair() {
86 $result = null;
87
88 // Create a temporary file. Security: tempnam() sets permissions to 0600
89 $privateKeyFile = tempnam($this->temporaryDirectory, uniqid());
90
91 // Generate the private key.
92 //
93 // PHP generates 1024 bit key files. We force command line version
94 // to do the same and use the F4 (0x10001) exponent. This is the most
95 // secure.
96 $command = $this->opensslPath . ' genrsa -out ' .
97 escapeshellarg($privateKeyFile) . ' 1024';
98 t3lib_utility_Command::exec($command);
99
100 // Test that we got a private key
101 $privateKey = file_get_contents($privateKeyFile);
102 if (false !== strpos($privateKey, 'BEGIN RSA PRIVATE KEY')) {
103 // Ok, we got the private key. Get the modulus.
104 $command = $this->opensslPath . ' rsa -noout -modulus -in ' .
105 escapeshellarg($privateKeyFile);
106 $value = t3lib_utility_Command::exec($command);
107 if (substr($value, 0, 8) === 'Modulus=') {
108 $publicKey = substr($value, 8);
109
110 // Create a result object
111 $result = t3lib_div::makeInstance('tx_rsaauth_keypair');
112 /* @var $result tx_rsa_keypair */
113 $result->setExponent(0x10001);
114 $result->setPrivateKey($privateKey);
115 $result->setPublicKey($publicKey);
116 }
117 }
118
119 @unlink($privateKeyFile);
120
121 return $result;
122 }
123
124 /**
125 *
126 * @param string $privateKey The private key (obtained from a call to createNewKeyPair())
127 * @param string $data Data to decrypt (base64-encoded)
128 * @return string Decrypted data or null in case of a error
129 * @see tx_rsaauth_abstract_backend::decrypt()
130 */
131 public function decrypt($privateKey, $data) {
132 // Key must be put to the file
133 $privateKeyFile = tempnam($this->temporaryDirectory, uniqid());
134 file_put_contents($privateKeyFile, $privateKey);
135
136 $dataFile = tempnam($this->temporaryDirectory, uniqid());
137 file_put_contents($dataFile, base64_decode($data));
138
139 // Prepare the command
140 $command = $this->opensslPath . ' rsautl -inkey ' .
141 escapeshellarg($privateKeyFile) . ' -in ' .
142 escapeshellarg($dataFile) .
143 ' -decrypt';
144
145 // Execute the command and capture the result
146 $output = array();
147 t3lib_utility_Command::exec($command, $output);
148
149 // Remove the file
150 @unlink($privateKeyFile);
151 @unlink($dataFile);
152
153 return implode(LF, $output);
154 }
155
156 /**
157 * Checks if command line version of the OpenSSL is available and can be
158 * executed successfully.
159 *
160 * @return void
161 * @see tx_rsaauth_abstract_backend::isAvailable()
162 */
163 public function isAvailable() {
164 $result = false;
165 if ($this->opensslPath) {
166 // If path exists, test that command runs and can produce output
167 $test = t3lib_utility_Command::exec($this->opensslPath . ' version');
168 $result = (substr($test, 0, 8) == 'OpenSSL ');
169 }
170 return $result;
171 }
172 }
173
174 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/rsaauth/sv1/backends/class.tx_rsaauth_cmdline_backend.php'])) {
175 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/rsaauth/sv1/backends/class.tx_rsaauth_cmdline_backend.php']);
176 }
177
178 ?>