TYPO3  7.6
CommandLineBackend.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Rsaauth\Backend;
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
20 
27 {
31  const DEFAULT_EXPONENT = 65537;
32 
38  protected $opensslPath;
39 
48 
53  public function __construct()
54  {
55  $this->opensslPath = CommandUtility::getCommand('openssl');
56  $this->temporaryDirectory = PATH_site . 'typo3temp';
57  // Get temporary directory from the configuration
58  $extconf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['rsaauth']);
59  if (
60  $extconf['temporaryDirectory'] !== ''
61  && $extconf['temporaryDirectory'][0] === '/'
62  && @is_dir($extconf['temporaryDirectory'])
63  && is_writable($extconf['temporaryDirectory'])
64  ) {
65  $this->temporaryDirectory = $extconf['temporaryDirectory'];
66  }
67  }
68 
77  public function createNewKeyPair()
78  {
80  $keyPair = GeneralUtility::makeInstance(\TYPO3\CMS\Rsaauth\Keypair::class);
81  if ($keyPair->isReady()) {
82  return $keyPair;
83  }
84 
85  if ($this->opensslPath === false) {
86  return null;
87  }
88 
89  // Create a temporary file. Security: tempnam() sets permissions to 0600
90  $privateKeyFile = tempnam($this->temporaryDirectory, StringUtility::getUniqueId());
91 
92  // Generate the private key.
93  //
94  // PHP generates 1024 bit key files. We force command line version
95  // to do the same and use the F4 (0x10001) exponent. This is the most
96  // secure.
97  $command = $this->opensslPath . ' genrsa -out ' . escapeshellarg($privateKeyFile) . ' 1024';
98  if (TYPO3_OS === 'WIN') {
99  $command .= ' 2>NUL';
100  } else {
101  $command .= ' 2>/dev/null';
102  }
103  CommandUtility::exec($command);
104  // Test that we got a private key
105  $privateKey = file_get_contents($privateKeyFile);
106  if (false !== strpos($privateKey, 'BEGIN RSA PRIVATE KEY')) {
107  // Ok, we got the private key. Get the modulus.
108  $command = $this->opensslPath . ' rsa -noout -modulus -in ' . escapeshellarg($privateKeyFile);
109  $value = CommandUtility::exec($command);
110  if (substr($value, 0, 8) === 'Modulus=') {
111  $publicKey = substr($value, 8);
112 
113  $keyPair->setExponent(self::DEFAULT_EXPONENT);
114  $keyPair->setPrivateKey($privateKey);
115  $keyPair->setPublicKey($publicKey);
116  }
117  } else {
118  $keyPair = null;
119  }
120 
121  @unlink($privateKeyFile);
122  return $keyPair;
123  }
124 
131  public function decrypt($privateKey, $data)
132  {
133  // Key must be put to the file
134  $privateKeyFile = tempnam($this->temporaryDirectory, StringUtility::getUniqueId());
135  file_put_contents($privateKeyFile, $privateKey);
136  $dataFile = tempnam($this->temporaryDirectory, StringUtility::getUniqueId());
137  file_put_contents($dataFile, base64_decode($data));
138  // Prepare the command
139  $command = $this->opensslPath . ' rsautl -inkey ' . escapeshellarg($privateKeyFile) . ' -in ' . escapeshellarg($dataFile) . ' -decrypt';
140  // Execute the command and capture the result
141  $output = array();
142  CommandUtility::exec($command, $output);
143  // Remove the file
144  @unlink($privateKeyFile);
145  @unlink($dataFile);
146  return implode(LF, $output);
147  }
148 
156  public function isAvailable()
157  {
158  $result = false;
159  if ($this->opensslPath) {
160  // If path exists, test that command runs and can produce output
161  $test = CommandUtility::exec($this->opensslPath . ' version');
162  $result = substr($test, 0, 8) === 'OpenSSL ';
163  }
164  return $result;
165  }
166 }