[TASK] Re-work/simplify copyright header in PHP files - Part 9
[Packages/TYPO3.CMS.git] / typo3 / sysext / rsaauth / Classes / Backend / PhpBackend.php
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
17 /**
18 * This class contains a PHP OpenSSL backend for the TYPO3 RSA authentication
19 * service. See class \TYPO3\CMS\Rsaauth\Backend\AbstractBackend for the information on using
20 * backends.
21 *
22 * @author Dmitry Dulepov <dmitry@typo3.org>
23 */
24 class PhpBackend extends \TYPO3\CMS\Rsaauth\Backend\AbstractBackend {
25 /**
26 * Creates a new key pair for the encryption or gets the existing key pair (if one already has been generated).
27 *
28 * There should only be one key pair per request because the second private key would overwrites the first private
29 * key. So the submitting the form with the first public key would not work anymore.
30 *
31 * @return \TYPO3\CMS\Rsaauth\Keypair|NULL a key pair or NULL in case of error
32 */
33 public function createNewKeyPair() {
34 /** @var $keyPair \TYPO3\CMS\Rsaauth\Keypair */
35 $keyPair = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Rsaauth\\Keypair');
36 if ($keyPair->isReady()) {
37 return $keyPair;
38 }
39
40 $privateKey = @openssl_pkey_new();
41 if ($privateKey !== FALSE) {
42 // Create private key as string
43 $privateKeyStr = '';
44 openssl_pkey_export($privateKey, $privateKeyStr);
45 // Prepare public key information
46 $exportedData = '';
47 $csr = openssl_csr_new(array(), $privateKey);
48 openssl_csr_export($csr, $exportedData, FALSE);
49 // Get public key (in fact modulus) and exponent
50 $publicKey = $this->extractPublicKeyModulus($exportedData);
51 $exponent = $this->extractExponent($exportedData);
52
53 $keyPair->setExponent($exponent);
54 $keyPair->setPrivateKey($privateKeyStr);
55 $keyPair->setPublicKey($publicKey);
56 // Clean up all resources
57 openssl_free_key($privateKey);
58 } else {
59 $keyPair = NULL;
60 }
61
62 return $keyPair;
63 }
64
65 /**
66 * Decrypts data using the private key. This implementation uses PHP OpenSSL
67 * extension.
68 *
69 * @param string $privateKey The private key (obtained from a call to createNewKeyPair())
70 * @param string $data Data to decrypt (base64-encoded)
71 * @return string Decrypted data or NULL in case of a error
72 * @see \TYPO3\CMS\Rsaauth\Backend\AbstractBackend::decrypt()
73 */
74 public function decrypt($privateKey, $data) {
75 $result = '';
76 if (!@openssl_private_decrypt(base64_decode($data), $result, $privateKey)) {
77 $result = NULL;
78 }
79 return $result;
80 }
81
82 /**
83 * Checks if this backend is available for calling. In particular checks if
84 * PHP OpenSSl extension is installed and functional.
85 *
86 * @return void
87 * @see \TYPO3\CMS\Rsaauth\Backend\AbstractBackend::isAvailable()
88 */
89 public function isAvailable() {
90 $result = FALSE;
91 if (is_callable('openssl_pkey_new')) {
92 // PHP extension has to be configured properly. It
93 // can be installed and available but will not work unless
94 // properly configured. So we check if it works.
95 $testKey = @openssl_pkey_new();
96 if (is_resource($testKey)) {
97 openssl_free_key($testKey);
98 $result = TRUE;
99 }
100 }
101 return $result;
102 }
103
104 /**
105 * Extracts the exponent from the OpenSSL CSR
106 *
107 * @param string $data The result of openssl_csr_export()
108 * @return integer The exponent as a number
109 */
110 protected function extractExponent($data) {
111 $index = strpos($data, 'Exponent: ');
112 // We do not check for '$index === FALSE' because the exponent is
113 // always there!
114 return (int)substr($data, $index + 10);
115 }
116
117 /**
118 * Extracts public key modulus from the OpenSSL CSR.
119 *
120 * @param string $data The result of openssl_csr_export()
121 * @return string Modulus as uppercase hex string
122 */
123 protected function extractPublicKeyModulus($data) {
124 $fragment = preg_replace('/.*Modulus.*?\\n(.*)Exponent:.*/ms', '\\1', $data);
125 $fragment = preg_replace('/[\\s\\n\\r:]/', '', $fragment);
126 $result = trim(strtoupper(substr($fragment, 2)));
127 return $result;
128 }
129
130 }