Index: typo3/sysext/rsaauth/sv1/backends/class.tx_rsaauth_abstract_backend.php =================================================================== --- typo3/sysext/rsaauth/sv1/backends/class.tx_rsaauth_abstract_backend.php (revision 10402) +++ typo3/sysext/rsaauth/sv1/backends/class.tx_rsaauth_abstract_backend.php (working copy) @@ -62,11 +62,22 @@ protected $error = ''; /** - * Creates a new key pair for the encryption. + * Creates a new key pair for the encryption. (if necessary). * * @return tx_rsaauth_keypair A new key pair or null in case of error + * @deprecated use getKeyPair instead! Reason1: there is no need to create more than one key pare. Reason2: the second private key overwrites the first private key, so the form with the first public key will never work */ - abstract public function createNewKeyPair(); + public function createNewKeyPair(){ + t3lib_div::logDeprecatedFunction(); + return $this->getKeyPair(); + } + + /** + * Get a key pair for the encryption. + * + * @return tx_rsaauth_keypair A key pair or null in case of error + */ + abstract public function getKeyPair(); /** * Decripts the data using the private key. Index: typo3/sysext/rsaauth/sv1/backends/class.tx_rsaauth_cmdline_backend.php =================================================================== --- typo3/sysext/rsaauth/sv1/backends/class.tx_rsaauth_cmdline_backend.php (revision 10402) +++ typo3/sysext/rsaauth/sv1/backends/class.tx_rsaauth_cmdline_backend.php (working copy) @@ -78,46 +78,47 @@ } /** - * + * Creates a new or get an existing public/private key pair or null in case of error + * * @return tx_rsaauth_keypair A new key pair or null in case of error * @see tx_rsaauth_abstract_backend::createNewKeyPair() */ - public function createNewKeyPair() { - $result = null; + public function getKeyPair() { + $result = t3lib_div::makeInstance('tx_rsaauth_keypair'); - // Create a temporary file. Security: tempnam() sets permissions to 0600 - $privateKeyFile = tempnam($this->temporaryDirectory, uniqid()); - - // Generate the private key. - // - // PHP generates 1024 bit key files. We force command line version - // to do the same and use the F4 (0x10001) exponent. This is the most - // secure. - $command = $this->opensslPath . ' genrsa -out ' . - escapeshellarg($privateKeyFile) . ' 1024'; - exec($command); - - // Test that we got a private key - $privateKey = file_get_contents($privateKeyFile); - if (false !== strpos($privateKey, 'BEGIN RSA PRIVATE KEY')) { - // Ok, we got the private key. Get the modulus. - $command = $this->opensslPath . ' rsa -noout -modulus -in ' . - escapeshellarg($privateKeyFile); - $value = exec($command); - if (substr($value, 0, 8) === 'Modulus=') { - $publicKey = substr($value, 8); - - // Create a result object - $result = t3lib_div::makeInstance('tx_rsaauth_keypair'); - /* @var $result tx_rsa_keypair */ - $result->setExponent(0x10001); - $result->setPrivateKey($privateKey); - $result->setPublicKey($publicKey); + if(!$result->isReady()){ + // Create a temporary file. Security: tempnam() sets permissions to 0600 + $privateKeyFile = tempnam($this->temporaryDirectory, uniqid()); + + // Generate the private key. + // + // PHP generates 1024 bit key files. We force command line version + // to do the same and use the F4 (0x10001) exponent. This is the most + // secure. + $command = $this->opensslPath . ' genrsa -out ' . + escapeshellarg($privateKeyFile) . ' 1024'; + exec($command); + + // Test that we got a private key + $privateKey = file_get_contents($privateKeyFile); + if (false !== strpos($privateKey, 'BEGIN RSA PRIVATE KEY')) { + // Ok, we got the private key. Get the modulus. + $command = $this->opensslPath . ' rsa -noout -modulus -in ' . + escapeshellarg($privateKeyFile); + $value = exec($command); + if (substr($value, 0, 8) === 'Modulus=') { + $publicKey = substr($value, 8); + + /* @var $result tx_rsa_keypair */ + $result->setExponent(0x10001); + $result->setPrivateKey($privateKey); + $result->setPublicKey($publicKey); + } } + + @unlink($privateKeyFile); } - @unlink($privateKeyFile); - return $result; } Index: typo3/sysext/rsaauth/sv1/backends/class.tx_rsaauth_keypair.php =================================================================== --- typo3/sysext/rsaauth/sv1/backends/class.tx_rsaauth_keypair.php (revision 10402) +++ typo3/sysext/rsaauth/sv1/backends/class.tx_rsaauth_keypair.php (working copy) @@ -37,28 +37,37 @@ * @package TYPO3 * @subpackage tx_rsaauth */ -final class tx_rsaauth_keypair { +final class tx_rsaauth_keypair implements t3lib_Singleton { /** * RSA public exponent (3 or 0x10001) * * @var int */ - protected $exponent = 0x10001; + protected $exponent; /** * The private key * * @var string */ - protected $privateKey = ''; + protected $privateKey; /** * The public key modulus * * @var string */ - protected $publicKeyModulus = ''; + protected $publicKeyModulus; + + /** + * Check, if there is already a key pair + * + * @return bool + */ + public function isReady(){ + return (isset($this->exponent) && (isset($this->privateKey) && isset($this->publicKeyModulus)); + } /** * Retrieves the exponent. @@ -70,13 +79,20 @@ } /** - * Sets the private key + * Sets the exponent if not already set * - * @param string $privateKey The new private key + * @param string $exponent The new exponent * @return void */ public function setExponent($exponent) { - $this->exponent = $exponent; + if(!$this->isReady()) { + $this->exponent = $exponent; + } else { + throw new Exception( + 'TYPO3 Fatal Error: tx_rsaauth_keypair::setExponent() don\'t set the exponent two times!', + 1296062838 + ); + } } /** @@ -91,20 +107,34 @@ /** * Sets the private key * - * @param string $privateKey The new private key + * @param string $privateKey The new private key if not already set * @return void */ public function setPrivateKey($privateKey) { - $this->privateKey = $privateKey; + if(!$this->isReady()) { + $this->privateKey = $privateKey; + } else { + throw new Exception( + 'TYPO3 Fatal Error: tx_rsaauth_keypair::setPrivateKey() don\'t set the private key two times!', + 1296062838 + ); + } } /** * Retrieves the public key modulus * - * @return string The public key modulus + * @return string The public key modulus if not already set */ public function getPublicKeyModulus() { - return $this->publicKeyModulus; + if(!$this->isReady()) { + $this->publicKeyModulus = $publicKeyModulus; + } else { + throw new Exception( + 'TYPO3 Fatal Error: tx_rsaauth_keypair::setPublicKey() don\'t set the public key two times!', + 1296062838 + ); + } } /** Index: typo3/sysext/rsaauth/sv1/backends/class.tx_rsaauth_php_backend.php =================================================================== --- typo3/sysext/rsaauth/sv1/backends/class.tx_rsaauth_php_backend.php (revision 10402) +++ typo3/sysext/rsaauth/sv1/backends/class.tx_rsaauth_php_backend.php (working copy) @@ -42,37 +42,37 @@ class tx_rsaauth_php_backend extends tx_rsaauth_abstract_backend { /** - * Creates a new public/private key pair using PHP OpenSSL extension. + * Creates a new or get an existing public/private key pair using PHP OpenSSL extension. * * @return tx_rsaauth_keypair A new key pair or null in case of error * @see tx_rsaauth_abstract_backend::createNewKeyPair() */ public function createNewKeyPair() { - $result = null; - $privateKey = @openssl_pkey_new(); - if ($privateKey) { - // Create private key as string - $privateKeyStr = ''; - openssl_pkey_export($privateKey, $privateKeyStr); - - // Prepare public key information - $exportedData = ''; - $csr = openssl_csr_new(array(), $privateKey); - openssl_csr_export($csr, $exportedData, false); - - // Get public key (in fact modulus) and exponent - $publicKey = $this->extractPublicKeyModulus($exportedData); - $exponent = $this->extractExponent($exportedData); - - // Create result object - $result = t3lib_div::makeInstance('tx_rsaauth_keypair'); - /* @var $result tx_rsaauth_keypair */ - $result->setExponent($exponent); - $result->setPrivateKey($privateKeyStr); - $result->setPublicKey($publicKey); - - // Clean up all resources - openssl_free_key($privateKey); + $result = t3lib_div::makeInstance('tx_rsaauth_keypair'); + if(!$result->isReady()){ + $privateKey = @openssl_pkey_new(); + if ($privateKey) { + // Create private key as string + $privateKeyStr = ''; + openssl_pkey_export($privateKey, $privateKeyStr); + + // Prepare public key information + $exportedData = ''; + $csr = openssl_csr_new(array(), $privateKey); + openssl_csr_export($csr, $exportedData, false); + + // Get public key (in fact modulus) and exponent + $publicKey = $this->extractPublicKeyModulus($exportedData); + $exponent = $this->extractExponent($exportedData); + + /* @var $result tx_rsaauth_keypair */ + $result->setExponent($exponent); + $result->setPrivateKey($privateKeyStr); + $result->setPublicKey($publicKey); + + // Clean up all resources + openssl_free_key($privateKey); + } } return $result; }