[BUGFIX] Only create one keypair in rsaauth 85/10485/10
authorTom Ruether <info@redscout.de>
Fri, 22 Nov 2013 10:47:37 +0000 (11:47 +0100)
committerMarkus Klein <klein.t3@mfc-linz.at>
Thu, 9 Jan 2014 00:43:59 +0000 (01:43 +0100)
If there are two login forms on one page the second form's private
key overwrites the first form's private key so the first form doesn't
work. With this patch only one keypair gets created and it doesn't
matter how many login forms you have one one page.

Change-Id: I42660140aea72d1888cc73d56e83b823206a0797
Fixes: #24877
Fixes: #6708
Releases: 6.2, 6.1, 6.0, 4.5
Reviewed-on: https://review.typo3.org/10485
Reviewed-by: Stefan Neufeind
Reviewed-by: Benjamin Mack
Tested-by: Benjamin Mack
Reviewed-by: Daniel Gorges
Tested-by: Daniel Gorges
Reviewed-by: Markus Klein
Tested-by: Markus Klein
typo3/sysext/rsaauth/Classes/Backend/AbstractBackend.php
typo3/sysext/rsaauth/Classes/Backend/CommandLineBackend.php
typo3/sysext/rsaauth/Classes/Backend/PhpBackend.php
typo3/sysext/rsaauth/Classes/Hook/FrontendLoginHook.php
typo3/sysext/rsaauth/Classes/Keypair.php
typo3/sysext/rsaauth/Tests/Unit/Backend/CommandLineBackendTest.php [new file with mode: 0644]
typo3/sysext/rsaauth/Tests/Unit/Backend/PhpBackendTest.php [new file with mode: 0644]
typo3/sysext/rsaauth/Tests/Unit/KeypairTest.php [new file with mode: 0644]

index 9ae211d..f323d84 100644 (file)
@@ -53,9 +53,12 @@ abstract class AbstractBackend {
        protected $error = '';
 
        /**
-        * Creates a new key pair for the encryption.
+        * Creates a new key pair for the encryption or gets the existing key pair (if one already has been generated).
         *
-        * @return \TYPO3\CMS\Rsaauth\Keypair A new key pair or NULL in case of error
+        * There should only be one key pair per request because the second private key would overwrites the first private
+        * key. So the submitting the form with the first public key would not work anymore.
+        *
+        * @return \TYPO3\CMS\Rsaauth\Keypair|NULL a key pair or NULL in case of error
         */
        abstract public function createNewKeyPair();
 
@@ -84,4 +87,4 @@ abstract class AbstractBackend {
                return $this->error;
        }
 
-}
+}
\ No newline at end of file
index 3154d10..5e09106 100644 (file)
@@ -23,6 +23,9 @@ namespace TYPO3\CMS\Rsaauth\Backend;
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
+
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
 /**
  * This class contains a OpenSSL backend for the TYPO3 RSA authentication
  * service. It uses shell version of OpenSSL to perform tasks. See class
@@ -31,6 +34,10 @@ namespace TYPO3\CMS\Rsaauth\Backend;
  * @author Dmitry Dulepov <dmitry@typo3.org>
  */
 class CommandLineBackend extends \TYPO3\CMS\Rsaauth\Backend\AbstractBackend {
+       /**
+        * @var integer
+        */
+       const DEFAULT_EXPONENT = 65537;
 
        /**
         * A path to the openssl binary or FALSE if the binary does not exist
@@ -41,7 +48,7 @@ class CommandLineBackend extends \TYPO3\CMS\Rsaauth\Backend\AbstractBackend {
 
        /**
         * Temporary directory. It is best of it is outside of the web site root and
-        * not publically readable.
+        * not publicly readable.
         * For now we use typo3temp/.
         *
         * @var string
@@ -51,8 +58,6 @@ class CommandLineBackend extends \TYPO3\CMS\Rsaauth\Backend\AbstractBackend {
        /**
         * Creates an instance of this class. It obtains a path to the OpenSSL
         * binary.
-        *
-        * @return void
         */
        public function __construct() {
                $this->opensslPath = \TYPO3\CMS\Core\Utility\CommandUtility::getCommand('openssl');
@@ -65,13 +70,23 @@ class CommandLineBackend extends \TYPO3\CMS\Rsaauth\Backend\AbstractBackend {
        }
 
        /**
-        * @return \TYPO3\CMS\Rsaauth\Keypair A new key pair or NULL in case of error
-        * @see \TYPO3\CMS\Rsaauth\Backend\AbstractBackend::createNewKeyPair()
+        * Creates a new key pair for the encryption or gets the existing key pair (if one already has been generated).
+        *
+        * There should only be one key pair per request because the second private key would overwrites the first private
+        * key. So the submitting the form with the first public key would not work anymore.
+        *
+        * @return \TYPO3\CMS\Rsaauth\Keypair|NULL a key pair or NULL in case of error
         */
        public function createNewKeyPair() {
-               $result = NULL;
+               /** @var $keyPair \TYPO3\CMS\Rsaauth\Keypair */
+               $keyPair = GeneralUtility::makeInstance('TYPO3\\CMS\\Rsaauth\\Keypair');
+               if ($keyPair->isReady()) {
+                       return $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
@@ -87,16 +102,17 @@ class CommandLineBackend extends \TYPO3\CMS\Rsaauth\Backend\AbstractBackend {
                        $value = \TYPO3\CMS\Core\Utility\CommandUtility::exec($command);
                        if (substr($value, 0, 8) === 'Modulus=') {
                                $publicKey = substr($value, 8);
-                               // Create a result object
-                               $result = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Rsaauth\\Keypair');
-                               /** @var $result tx_rsa_keypair */
-                               $result->setExponent(65537);
-                               $result->setPrivateKey($privateKey);
-                               $result->setPublicKey($publicKey);
+
+                               $keyPair->setExponent(self::DEFAULT_EXPONENT);
+                               $keyPair->setPrivateKey($privateKey);
+                               $keyPair->setPublicKey($publicKey);
                        }
+               } else {
+                       $keyPair = NULL;
                }
+
                @unlink($privateKeyFile);
-               return $result;
+               return $keyPair;
        }
 
        /**
@@ -139,4 +155,4 @@ class CommandLineBackend extends \TYPO3\CMS\Rsaauth\Backend\AbstractBackend {
                return $result;
        }
 
-}
+}
\ No newline at end of file
index 9467df0..b1472b9 100644 (file)
@@ -23,6 +23,7 @@ namespace TYPO3\CMS\Rsaauth\Backend;
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
+
 /**
  * This class contains a PHP OpenSSL backend for the TYPO3 RSA authentication
  * service. See class \TYPO3\CMS\Rsaauth\Backend\AbstractBackend for the information on using
@@ -31,17 +32,23 @@ namespace TYPO3\CMS\Rsaauth\Backend;
  * @author Dmitry Dulepov <dmitry@typo3.org>
  */
 class PhpBackend extends \TYPO3\CMS\Rsaauth\Backend\AbstractBackend {
-
        /**
-        * Creates a new public/private key pair using PHP OpenSSL extension.
+        * Creates a new key pair for the encryption or gets the existing key pair (if one already has been generated).
         *
-        * @return \TYPO3\CMS\Rsaauth\Keypair A new key pair or NULL in case of error
-        * @see \TYPO3\CMS\Rsaauth\Backend\AbstractBackend::createNewKeyPair()
+        * There should only be one key pair per request because the second private key would overwrites the first private
+        * key. So the submitting the form with the first public key would not work anymore.
+        *
+        * @return \TYPO3\CMS\Rsaauth\Keypair|NULL a key pair or NULL in case of error
         */
        public function createNewKeyPair() {
-               $result = NULL;
+               /** @var $keyPair \TYPO3\CMS\Rsaauth\Keypair */
+               $keyPair = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Rsaauth\\Keypair');
+               if ($keyPair->isReady()) {
+                       return $keyPair;
+               }
+
                $privateKey = @openssl_pkey_new();
-               if ($privateKey) {
+               if ($privateKey !== FALSE) {
                        // Create private key as string
                        $privateKeyStr = '';
                        openssl_pkey_export($privateKey, $privateKeyStr);
@@ -52,16 +59,17 @@ class PhpBackend extends \TYPO3\CMS\Rsaauth\Backend\AbstractBackend {
                        // Get public key (in fact modulus) and exponent
                        $publicKey = $this->extractPublicKeyModulus($exportedData);
                        $exponent = $this->extractExponent($exportedData);
-                       // Create result object
-                       $result = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Rsaauth\\Keypair');
-                       /** @var $result \TYPO3\CMS\Rsaauth\Keypair */
-                       $result->setExponent($exponent);
-                       $result->setPrivateKey($privateKeyStr);
-                       $result->setPublicKey($publicKey);
+
+                       $keyPair->setExponent($exponent);
+                       $keyPair->setPrivateKey($privateKeyStr);
+                       $keyPair->setPublicKey($publicKey);
                        // Clean up all resources
                        openssl_free_key($privateKey);
+               } else {
+                       $keyPair = NULL;
                }
-               return $result;
+
+               return $keyPair;
        }
 
        /**
@@ -129,4 +137,4 @@ class PhpBackend extends \TYPO3\CMS\Rsaauth\Backend\AbstractBackend {
                return $result;
        }
 
-}
+}
\ No newline at end of file
index a92ace8..741c7f6 100644 (file)
@@ -51,9 +51,13 @@ class FrontendLoginHook {
                                        'jsbn/base64.js',
                                        'rsaauth_min.js'
                                );
+
+                               $additionalHeader = '';
                                foreach ($files as $file) {
-                                       $result[1] .= '<script type="text/javascript" src="' . \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . $javascriptPath . $file . '"></script>';
+                                       $additionalHeader .= '<script type="text/javascript" src="' . \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . $javascriptPath . $file . '"></script>';
                                }
+                               $GLOBALS['TSFE']->additionalHeaderData['rsaauth_js'] = $additionalHeader;
+
                                // Generate a new key pair
                                $keyPair = $backend->createNewKeyPair();
                                // Save private key
index cd989ba..0e2c175 100644 (file)
@@ -23,20 +23,20 @@ namespace TYPO3\CMS\Rsaauth;
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
+
 /**
- * This class contain an RSA keypair class. Its purpose is to keep to keys
- * and trasnfer these keys between other PHP classes.
+ * This class contain an RSA key pair. Its purpose is to keep to keys
+ * and transfer these keys between other PHP classes.
  *
  * @author Dmitry Dulepov <dmitry@typo3.org>
  */
-class Keypair {
-
+class Keypair implements \TYPO3\CMS\Core\SingletonInterface {
        /**
         * RSA public exponent (3 or 0x10001)
         *
         * @var integer
         */
-       protected $exponent = 65537;
+       protected $exponent = 0;
 
        /**
         * The private key
@@ -48,30 +48,57 @@ class Keypair {
        /**
         * The public key modulus
         *
-        * @var string
+        * @var integer
         */
-       protected $publicKeyModulus = '';
+       protected $publicKeyModulus = 0;
+
+       /**
+        * Checks if this key pair already has been provided with all data.
+        *
+        * @return boolean
+        */
+       public function isReady() {
+               return $this->hasExponent() && $this->hasPrivateKey() && $this->hasPublicKeyModulus();
+       }
 
        /**
         * Retrieves the exponent.
         *
-        * @return string The exponent
+        * @return integer the exponent
         */
        public function getExponent() {
                return $this->exponent;
        }
 
        /**
-        * Sets the private key
+        * Sets the exponent
+        *
+        * Note: This method must not be called more than one time.
+        *
+        * @param integer $exponent the new exponent
         *
-        * @param string $privateKey The new private key
         * @return void
+        *
+        * @throws \BadMethodCallException if the method was called more than one time
         */
        public function setExponent($exponent) {
+               if ($this->hasExponent()) {
+                       throw new \BadMethodCallException('setExponent() must not be called more than one time.', 1296062830);
+               }
+
                $this->exponent = $exponent;
        }
 
        /**
+        * Checks whether an exponent already has been set.
+        *
+        * @return boolean
+        */
+       protected function hasExponent() {
+               return $this->getExponent() !== 0;
+       }
+
+       /**
         * Retrieves the private key.
         *
         * @return string The private key
@@ -81,32 +108,67 @@ class Keypair {
        }
 
        /**
-        * Sets the private key
+        * Sets the private key.
+        *
+        * Note: This method must not be called more than one time.
         *
         * @param string $privateKey The new private key
+        *
         * @return void
+        *
+        * @throws \BadMethodCallException if the method was called more than one time
         */
        public function setPrivateKey($privateKey) {
+               if ($this->hasPrivateKey()) {
+                       throw new \BadMethodCallException('setPrivateKey() must not be called more than one time.', 1296062831);
+               }
+
                $this->privateKey = $privateKey;
        }
 
        /**
+        * Checks whether a private key already has been set.
+        *
+        * @return boolean
+        */
+       protected function hasPrivateKey() {
+               return $this->getPrivateKey() !== '';
+       }
+
+       /**
         * Retrieves the public key modulus
         *
-        * @return string The public key modulus
+        * @return integer the public key modulus
         */
        public function getPublicKeyModulus() {
                return $this->publicKeyModulus;
        }
 
        /**
-        * Sets the public key modulus
+        * Sets the public key modulus.
+        *
+        * Note: This method must not be called more than one time.
+        *
+        * @param integer $publicKeyModulus the new public key modulus
         *
-        * @param string $publicKeyModulus The new public key modulus
         * @return void
+        *
+        * @throws \BadMethodCallException if the method was called more than one time
         */
        public function setPublicKey($publicKeyModulus) {
+               if ($this->hasPublicKeyModulus()) {
+                       throw new \BadMethodCallException('setPublicKey() must not be called more than one time.', 1296062832);
+               }
+
                $this->publicKeyModulus = $publicKeyModulus;
        }
 
-}
+       /**
+        * Checks whether a public key modulus already has been set.
+        *
+        * @return boolean
+        */
+       protected function hasPublicKeyModulus() {
+               return $this->getPublicKeyModulus() !== 0;
+       }
+}
\ No newline at end of file
diff --git a/typo3/sysext/rsaauth/Tests/Unit/Backend/CommandLineBackendTest.php b/typo3/sysext/rsaauth/Tests/Unit/Backend/CommandLineBackendTest.php
new file mode 100644 (file)
index 0000000..70df761
--- /dev/null
@@ -0,0 +1,78 @@
+<?php
+namespace TYPO3\CMS\Rsaauth\Tests\Unit\Backend;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2013 Oliver Klee <typo3-coding@oliverklee.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+use TYPO3\CMS\Rsaauth\Backend\CommandLineBackend;
+
+/**
+ * Test case.
+ *
+ * @author Oliver Klee <typo3-coding@oliverklee.de>
+ */
+class CommandLineBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase  {
+       /**
+        * @var CommandLineBackend
+        */
+       protected $subject = NULL;
+
+       public function setUp() {
+               $this->subject = new CommandLineBackend();
+       }
+
+       public function tearDown() {
+               unset($this->subject);
+       }
+
+       /**
+        * @test
+        */
+       public function createNewKeyPairCreatesReadyKeyPair() {
+               $this->assertTrue(
+                       $this->subject->createNewKeyPair()->isReady()
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function createNewKeyPairCreatesKeyPairWithDefaultExponent() {
+               $this->assertSame(
+                       CommandLineBackend::DEFAULT_EXPONENT,
+                       $this->subject->createNewKeyPair()->getExponent()
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function createNewKeyPairCalledTwoTimesReturnsSameKeyPairInstance() {
+               $this->assertSame(
+                       $this->subject->createNewKeyPair(),
+                       $this->subject->createNewKeyPair()
+               );
+       }
+}
\ No newline at end of file
diff --git a/typo3/sysext/rsaauth/Tests/Unit/Backend/PhpBackendTest.php b/typo3/sysext/rsaauth/Tests/Unit/Backend/PhpBackendTest.php
new file mode 100644 (file)
index 0000000..6f13558
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+namespace TYPO3\CMS\Rsaauth\Tests\Unit\Backend;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2013 Oliver Klee <typo3-coding@oliverklee.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+use TYPO3\CMS\Rsaauth\Backend\PhpBackend;
+
+/**
+ * Test case.
+ *
+ * @author Oliver Klee <typo3-coding@oliverklee.de>
+ */
+class PhpBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase  {
+       /**
+        * @var PhpBackend
+        */
+       protected $subject = NULL;
+
+       public function setUp() {
+               $this->subject = new PhpBackend();
+       }
+
+       public function tearDown() {
+               unset($this->subject);
+       }
+
+       /**
+        * @test
+        */
+       public function createNewKeyPairCreatesReadyKeyPair() {
+               $this->assertTrue(
+                       $this->subject->createNewKeyPair()->isReady()
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function createNewKeyPairCalledTwoTimesReturnsSameKeyPairInstance() {
+               $this->assertSame(
+                       $this->subject->createNewKeyPair(),
+                       $this->subject->createNewKeyPair()
+               );
+       }
+}
\ No newline at end of file
diff --git a/typo3/sysext/rsaauth/Tests/Unit/KeypairTest.php b/typo3/sysext/rsaauth/Tests/Unit/KeypairTest.php
new file mode 100644 (file)
index 0000000..277a86d
--- /dev/null
@@ -0,0 +1,213 @@
+<?php
+namespace TYPO3\CMS\Rsaauth\Tests\Unit;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2013 Oliver Klee <typo3-coding@oliverklee.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+use TYPO3\CMS\Rsaauth\Keypair;
+
+/**
+ * Test case.
+ *
+ * @author Oliver Klee <typo3-coding@oliverklee.de>
+ */
+class KeypairTest extends \TYPO3\CMS\Core\Tests\UnitTestCase  {
+       /**
+        * @var Keypair
+        */
+       protected $subject = NULL;
+
+       public function setUp() {
+               $this->subject = new Keypair();
+       }
+
+       public function tearDown() {
+               unset($this->subject);
+       }
+
+       /**
+        * @test
+        */
+       public function classIsSingleton() {
+               $this->assertInstanceOf(
+                       'TYPO3\\CMS\\Core\\SingletonInterface',
+                       $this->subject
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function getExponentInitiallyReturnsZero() {
+               $this->assertSame(
+                       0,
+                       $this->subject->getExponent()
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function setExponentSetsExponent() {
+               $this->subject->setExponent(123456);
+
+               $this->assertSame(
+                       123456,
+                       $this->subject->getExponent()
+               );
+       }
+
+       /**
+        * @test
+        *
+        * @expectedException \BadMethodCallException
+        */
+       public function setExponentCalledTwoTimesThrowsException() {
+               $this->subject->setExponent(123456);
+               $this->subject->setExponent(123456);
+       }
+
+       /**
+        * @test
+        */
+       public function getPrivateKeyInitiallyReturnsEmptyString() {
+               $this->assertSame(
+                       '',
+                       $this->subject->getPrivateKey()
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function setPrivateKeySetsPrivateKey() {
+               $this->subject->setPrivateKey('foo bar');
+
+               $this->assertSame(
+                       'foo bar',
+                       $this->subject->getPrivateKey()
+               );
+       }
+
+       /**
+        * @test
+        *
+        * @expectedException \BadMethodCallException
+        */
+       public function setPrivateKeyCalledTwoTimesThrowsException() {
+               $this->subject->setPrivateKey('foo');
+               $this->subject->setPrivateKey('foo');
+       }
+
+       /**
+        * @test
+        */
+       public function getPublicKeyModulusInitiallyReturnsZero() {
+               $this->assertSame(
+                       0,
+                       $this->subject->getPublicKeyModulus()
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function setPublicKeySetsPublicKeyModulus() {
+               $this->subject->setPublicKey(123456);
+
+               $this->assertSame(
+                       123456,
+                       $this->subject->getPublicKeyModulus()
+               );
+       }
+
+       /**
+        * @test
+        *
+        * @expectedException \BadMethodCallException
+        */
+       public function setPublicKeyCalledTwoTimesThrowsException() {
+               $this->subject->setPublicKey(123456);
+               $this->subject->setPublicKey(123456);
+       }
+
+       /**
+        * @test
+        */
+       public function isReadyForExponentSetAndPrivateKeySetAndPublicKeyModulusSetReturnsTrue() {
+               $this->subject->setExponent(1861234);
+               $this->subject->setPrivateKey('lkjasbe');
+               $this->subject->setPublicKey(745786268712);
+
+               $this->assertTrue(
+                       $this->subject->isReady()
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function isReadyForNothingSetReturnsFalse() {
+               $this->assertFalse(
+                       $this->subject->isReady()
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function isReadyForExponentSetAndPrivateKeySetAndPublicKeyModulusMissingReturnsFalse() {
+               $this->subject->setExponent(1861234);
+               $this->subject->setPrivateKey('lkjasbe');
+
+               $this->assertFalse(
+                       $this->subject->isReady()
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function isReadyForExponentSetAndPrivateMissingSetAndPublicKeyModulusSetReturnsFalse() {
+               $this->subject->setExponent(1861234);
+               $this->subject->setPublicKey(745786268712);
+
+               $this->assertFalse(
+                       $this->subject->isReady()
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function isReadyForExponentMissingAndPrivateKeySetAndPublicKeyModulusSetReturnsFalse() {
+               $this->subject->setPrivateKey('lkjasbe');
+               $this->subject->setPublicKey(745786268712);
+
+               $this->assertFalse(
+                       $this->subject->isReady()
+               );
+       }
+}
\ No newline at end of file