diff --git a/.github/workflows/cryptomanana.yml b/.github/workflows/cryptomanana.yml index df00f03..956678c 100644 --- a/.github/workflows/cryptomanana.yml +++ b/.github/workflows/cryptomanana.yml @@ -51,7 +51,10 @@ jobs: restore-keys: ${{ runner.os }}-composer- - name: Project Installation - run: composer install --no-progress --no-interaction --prefer-dist + run: composer install --no-progress --no-interaction --prefer-dist ; cp phpunit.xml.dist phpunit.xml + + - name: Test Suite Configuration + run: if [[ "${{ matrix.php }}" =~ ^(7.3|7.4|8.0|8.1|8.2)$ ]] ; then vendor/bin/phpunit --migrate-configuration; fi - name: Running Tests run: vendor/bin/phpunit --no-coverage @@ -80,7 +83,10 @@ jobs: update: true - name: Project Installation - run: composer install --no-progress --no-interaction --prefer-dist + run: composer install --no-progress --no-interaction --prefer-dist ; cp phpunit.xml.dist phpunit.xml + + - name: Test Suite Configuration + run: if ( ${{ matrix.php }} -ge 7.3 ) { vendor/bin/phpunit --migrate-configuration } - name: Running Tests run: vendor/bin/phpunit --no-coverage @@ -109,7 +115,10 @@ jobs: update: true - name: Project Installation - run: composer install --no-progress --no-interaction --prefer-dist + run: composer install --no-progress --no-interaction --prefer-dist ; cp phpunit.xml.dist phpunit.xml + + - name: Test Suite Configuration + run: if [[ "${{ matrix.php }}" =~ ^(7.3|7.4|8.0|8.1|8.2)$ ]] ; then vendor/bin/phpunit --migrate-configuration; fi - name: Running Tests run: vendor/bin/phpunit --no-coverage diff --git a/.gitignore b/.gitignore index b22398a..ae91a24 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ composer # PHPUnit Related Files and Folders .phpunit.result.cache +.phpunit.cache/ tests/config.php phpunit.phar phpunit.xml diff --git a/.travis.yml b/.travis.yml index 7acdc4d..091ffa9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,13 +31,17 @@ jobs: env: - USE_OPCACHE=1 - php: 8.1 - dist: jammy + dist: focal env: - USE_OPCACHE=1 - php: master dist: jammy env: - USE_OPCACHE=1 +# - php: 8.2 <---- months and no valid build is available (installation failure) +# dist: focal +# env: +# - USE_OPCACHE=1 cache: timeout: 3600 diff --git a/CHANGELOG.md b/CHANGELOG.md index aade2e9..c761908 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,19 @@ CHANGELOG ========= +v1.1.1, 2023-04-08 +------------------ + +- Moved existing tests for cryptographic services and utilities as a separate integration test suite; +- Added true unit tests for cryptographic services and utilities via PHPUnit mocks/stubs; +- Enabled the running of unit tests with PHPUnit 10.x under PHP 8.1 and 8.2; +- Updated the configuration of Travis CI and GitHub actions CI/CD workflow; +- Updated the phpDocumentor schema configuration file and its settings; +- Fixes a few small bugs/typos and updated some of the framework's tests; +- Generated an online DOI number via Zenodo and CERN integration; +- Purged the image caches for the GitHub repository; +- Release is signed with a GitHub GPG signature. + v1.1.0, 2022-12-23 ------------------ diff --git a/Makefile b/Makefile index 1c4cb32..93f6182 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ psr: vendor/autoload.php .PHONY: tests tests: vendor/autoload.php - vendor/bin/phpunit --verbose --no-coverage + vendor/bin/phpunit --no-coverage .PHONY: check-system check-system: @@ -42,7 +42,7 @@ download-new-phpdoc: generate-docs: @if [ -f ./phpdoc.phar ]; then\ rm -rf docs/ && mkdir docs;\ - php -ddisplay_errors=0 -dopcache.enable_cli=0 phpdoc.phar;\ + php -ddisplay_errors=0 -dopcache.enable_cli=0 phpdoc.phar --sourcecode;\ if grep -i -q "No errors have been found" ./docs/api/reports/errors.html; then\ echo 'PHPDoc Inspection: 100%';\ else \ diff --git a/composer.json b/composer.json index d859e7c..e45a425 100644 --- a/composer.json +++ b/composer.json @@ -243,7 +243,7 @@ "ext-mbstring": "*", "ext-reflection": "*", "squizlabs/php_codesniffer": "^3.3", - "phpunit/phpunit": "^9 || ^8 || ^7 || ^6 || ^5.7 || ^4.8" + "phpunit/phpunit": "^10 || ^9 || ^8 || ^7 || ^6 || ^5.7 || ^4.8" }, "suggest": { "ext-mbstring": "Use only for multi-byte string encodings support and implementations.", @@ -277,10 +277,10 @@ "install-phar": "php composer.phar install --profile -vv", "autoload-dev": "composer dump-autoload --profile -vv", "autoload-phar": "php composer.phar dump-autoload --profile -vv", - "execute-tests": "vendor/bin/phpunit --verbose --testdox --no-coverage", - "execute-tests-phar": "php phpunit.phar --verbose --testdox --no-coverage", - "scan-coverage": "vendor/bin/phpunit --coverage-text --verbose --stop-on-failure", - "scan-coverage-phar": "php phpunit.phar --coverage-text --verbose --stop-on-failure", + "execute-tests": "vendor/bin/phpunit --testdox --no-coverage", + "execute-tests-phar": "php phpunit.phar --testdox --no-coverage", + "scan-coverage": "vendor/bin/phpunit --coverage-text --stop-on-failure", + "scan-coverage-phar": "php phpunit.phar --coverage-text --stop-on-failure", "export-testdox": "vendor/bin/phpunit --no-coverage --testdox-html coverage/agile.html", "export-testdox-phar": "php phpunit.phar --no-coverage --testdox-html coverage/agile.html", "export-coverage": "vendor/bin/phpunit --coverage-html coverage/report/", @@ -297,7 +297,7 @@ "check-psr-phar": "php phpcs.phar", "fix-psr": "vendor/bin/phpcbf", "fix-psr-phar": "php phpcbf.phar", - "export-docs-phar": "php -ddisplay_errors=0 phpdoc.phar" + "export-docs-phar": "php -ddisplay_errors=0 -dopcache.enable_cli=0 phpdoc.phar --sourcecode" }, "extra": { "branch-alias": { diff --git a/phpdoc.dist.xml b/phpdoc.dist.xml index f1d5835..52b8fc6 100644 --- a/phpdoc.dist.xml +++ b/phpdoc.dist.xml @@ -2,7 +2,7 @@ - PHPDoc scanning for the CryptoManana Framework. + Technical API Documentation for the CryptoManana Framework diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 3230b20..4c4289f 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -34,8 +34,11 @@ - + + ./tests/CryptoManana/Tests/TestSuite/ + + ./tests/CryptoManana/Tests/IntegrationSuite/ diff --git a/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/AuthenticatedEncryptionTest.php b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/AuthenticatedEncryptionTest.php new file mode 100644 index 0000000..a8d1c5f --- /dev/null +++ b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/AuthenticatedEncryptionTest.php @@ -0,0 +1,590 @@ +getCryptographicProtocolForTesting(); + + $tmp = clone $protocol; + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->authenticatedEncryptData('')); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the serialization of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testSerializationCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $tmp = serialize($protocol); + $tmp = unserialize($tmp); + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->authenticatedEncryptData('')); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the object dumping for debugging. + * + * @throws \Exception Wrong usage errors. + */ + public function testDebugCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $this->assertNotEmpty(var_export($protocol, true)); + } + + /** + * Testing if the basic data encryption and decryption process works. + * + * @throws \Exception If system does not support the algorithm or the randomness source is not available. + */ + public function testBasicDataEncryptionAndDataDecryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setSymmetricCipher($protocol->getSymmetricCipher()); + $protocol->setKeyedDigestionFunction($protocol->getKeyedDigestionFunction()); + + $authenticationMode = [ + $protocol::AUTHENTICATION_MODE_ENCRYPT_AND_MAC, + $protocol::AUTHENTICATION_MODE_MAC_THEN_ENCRYPT, + $protocol::AUTHENTICATION_MODE_ENCRYPT_THEN_MAC, + ]; + + $randomData = random_bytes(16); + + foreach ($authenticationMode as $mode) { + $protocol->setAuthenticationMode($mode); + $this->assertEquals($mode, $protocol->getAuthenticationMode()); + + $encryptedData = $protocol->authenticatedEncryptData($randomData); + $decryptedData = $protocol->authenticatedDecryptData($encryptedData); + + $this->assertEquals($randomData, $decryptedData); + } + + $protocol->setKeyedDigestionFunction($protocol->getKeyedDigestionFunction()->setSalt('1234')); + + $protocol = new AuthenticatedEncryption( + $protocol->getSymmetricCipher(), + $protocol->getKeyedDigestionFunction() + ); + + foreach ($authenticationMode as $mode) { + $protocol->setAuthenticationMode($mode); + $this->assertEquals($mode, $protocol->getAuthenticationMode()); + + $encryptedData = $protocol->authenticatedEncryptData($randomData); + $decryptedData = $protocol->authenticatedDecryptData($encryptedData); + + $this->assertEquals($randomData, $decryptedData); + } + } + + /** + * Testing if the unicode data encryption and decryption process works. + * + * @throws \Exception If system does not support the algorithm or the randomness source is not available. + */ + public function testUnicodeDataEncryptionAndDataDecryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setSymmetricCipher($protocol->getSymmetricCipher()); + $protocol->setKeyedDigestionFunction($protocol->getKeyedDigestionFunction()); + + $authenticationMode = [ + $protocol::AUTHENTICATION_MODE_ENCRYPT_AND_MAC, + $protocol::AUTHENTICATION_MODE_MAC_THEN_ENCRYPT, + $protocol::AUTHENTICATION_MODE_ENCRYPT_THEN_MAC, + ]; + + $unicodeData = "йЗъ 7-М%\v@UОrЯBZ"; + + foreach ($authenticationMode as $mode) { + $protocol->setAuthenticationMode($mode); + $this->assertEquals($mode, $protocol->getAuthenticationMode()); + + $encryptedData = $protocol->authenticatedEncryptData($unicodeData); + $decryptedData = $protocol->authenticatedDecryptData($encryptedData); + + $this->assertEquals($unicodeData, $decryptedData); + } + + $protocol->setKeyedDigestionFunction($protocol->getKeyedDigestionFunction()->setSalt('1234')); + + $protocol = new AuthenticatedEncryption( + $protocol->getSymmetricCipher(), + $protocol->getKeyedDigestionFunction() + ); + + foreach ($authenticationMode as $mode) { + $protocol->setAuthenticationMode($mode); + $this->assertEquals($mode, $protocol->getAuthenticationMode()); + + $encryptedData = $protocol->authenticatedEncryptData($unicodeData); + $decryptedData = $protocol->authenticatedDecryptData($encryptedData); + + $this->assertEquals($unicodeData, $decryptedData); + } + } + + /** + * Testing if encrypting twice the same input returns the same result. + * + * @throws \Exception If system does not support the algorithm or the randomness source is not available. + */ + public function testEncryptingTheSameDataTwice() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $randomData = random_bytes(16); + + $this->assertEquals( + $protocol->authenticatedEncryptData($randomData), + $protocol->authenticatedEncryptData($randomData) + ); + } + + /** + * Testing if encrypting twice the same input returns the same result. + * + * @throws \Exception If system does not support the algorithm or the randomness source is not available. + */ + public function testDecryptingTheSameDataTwice() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $randomData = random_bytes(16); + $encryptedData = $protocol->authenticatedEncryptData($randomData); + + $this->assertEquals( + $protocol->authenticatedDecryptData($encryptedData), + $protocol->authenticatedDecryptData($encryptedData) + ); + } + + /** + * Testing validation case for invalid type of symmetric service used on initialization. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfSymmetricEncryptionServicePassedOnInitialization() + { + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol = new AuthenticatedEncryption(null, null); + } else { + $hasThrown = null; + + try { + $protocol = new AuthenticatedEncryption(null, null); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of input data for encryption passed. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfInputDataForEncryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->authenticatedEncryptData(['wrong']); + } else { + $hasThrown = null; + + try { + $protocol->authenticatedEncryptData(['wrong']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of input data for decryption passed in E&M mode. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfInputDataForDecryptionInEncryptAndMacMode() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setAuthenticationMode($protocol::AUTHENTICATION_MODE_ENCRYPT_AND_MAC); + $authenticationCipherData = new AuthenticatedCipherData('1234', '1234'); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->authenticatedDecryptData($authenticationCipherData); + } else { + $hasThrown = null; + + try { + $protocol->authenticatedDecryptData($authenticationCipherData); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of input data for decryption passed in MtE mode. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfInputDataForDecryptionInMacThenEncryptMode() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setAuthenticationMode($protocol::AUTHENTICATION_MODE_MAC_THEN_ENCRYPT); + $authenticationCipherData = new AuthenticatedCipherData('1234', '1234'); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->authenticatedDecryptData($authenticationCipherData); + } else { + $hasThrown = null; + + try { + $protocol->authenticatedDecryptData($authenticationCipherData); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of input data for decryption passed in EtM mode. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfInputDataForDecryptionInEncryptThenMacMode() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setAuthenticationMode($protocol::AUTHENTICATION_MODE_ENCRYPT_THEN_MAC); + $authenticationCipherData = new AuthenticatedCipherData('1234', '1234'); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->authenticatedDecryptData($authenticationCipherData); + } else { + $hasThrown = null; + + try { + $protocol->authenticatedDecryptData($authenticationCipherData); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid authentication tag for decryption in E&M mode. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidAuthenticationTagForDecryptionInEncryptAndMacMode() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setAuthenticationMode($protocol::AUTHENTICATION_MODE_ENCRYPT_AND_MAC); + $authenticationCipherData = $protocol->authenticatedEncryptData('1234'); + $authenticationCipherData->authenticationTag = 'invalid'; + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol->authenticatedDecryptData($authenticationCipherData); + } else { + $hasThrown = null; + + try { + $protocol->authenticatedDecryptData($authenticationCipherData); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid authentication tag for decryption passed in MtE mode. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidAuthenticationTagForDecryptionInMacThenEncryptMode() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setAuthenticationMode($protocol::AUTHENTICATION_MODE_MAC_THEN_ENCRYPT); + $authenticationCipherData = $protocol->authenticatedEncryptData('1234'); + $authenticationCipherData->authenticationTag = 'invalid'; + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol->authenticatedDecryptData($authenticationCipherData); + } else { + $hasThrown = null; + + try { + $protocol->authenticatedDecryptData($authenticationCipherData); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid authentication tag for decryption passed in EtM mode. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidAuthenticationTagForDecryptionInEncryptThenMacMode() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setAuthenticationMode($protocol::AUTHENTICATION_MODE_ENCRYPT_THEN_MAC); + $authenticationCipherData = $protocol->authenticatedEncryptData('1234'); + $authenticationCipherData->authenticationTag = 'invalid'; + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol->authenticatedDecryptData($authenticationCipherData); + } else { + $hasThrown = null; + + try { + $protocol->authenticatedDecryptData($authenticationCipherData); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of authentication mode. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfAuthenticationMode() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->setAuthenticationMode(-1000); + } else { + $hasThrown = null; + + try { + $protocol->setAuthenticationMode(-1000); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid internal authentication mode used for encryption. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidInternalAuthenticationModeUsedForEncryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + + $reflectionMbString = new \ReflectionProperty( + AuthenticatedEncryption::class, + 'authenticationMode' + ); + + $reflectionMbString->setAccessible(true); + $reflectionMbString->setValue($protocol, -1000); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\OutOfBoundsException::class); + + $protocol->authenticatedEncryptData('1234'); + } else { + $hasThrown = null; + + try { + $protocol->authenticatedEncryptData('1234'); + } catch (\OutOfBoundsException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid internal authentication mode used for decryption. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidInternalAuthenticationModeUsedForDecryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $authenticationCipherData = $protocol->authenticatedEncryptData(''); + + $reflectionMbString = new \ReflectionProperty( + AuthenticatedEncryption::class, + 'authenticationMode' + ); + + $reflectionMbString->setAccessible(true); + $reflectionMbString->setValue($protocol, -1000); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\OutOfBoundsException::class); + + $protocol->authenticatedDecryptData($authenticationCipherData); + } else { + $hasThrown = null; + + try { + $protocol->authenticatedDecryptData($authenticationCipherData); + } catch (\OutOfBoundsException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } +} diff --git a/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/DigitalEnvelopeTest.php b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/DigitalEnvelopeTest.php new file mode 100644 index 0000000..00548a9 --- /dev/null +++ b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/DigitalEnvelopeTest.php @@ -0,0 +1,305 @@ + auto-check on next call, `true` => already generated. + * + * @var null|bool Is the key pair generated. + */ + protected static $isKeyPairGenerated = false; + + /** + * Creates new instances for testing. + * + * @return DigitalEnvelope Testing instance. + * @throws \Exception Wrong usage errors. + */ + private function getCryptographicProtocolForTesting() + { + $rsa = new Rsa1024(); + + if (self::$isKeyPairGenerated === false) { + $generator = new TokenGenerator(); + + $keyPair = $generator->getAsymmetricKeyPair($rsa::KEY_SIZE, $rsa::ALGORITHM_NAME); + + $this->writeToFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS, $keyPair->private); + $this->writeToFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS, $keyPair->public); + + self::$isKeyPairGenerated = true; + } + + $privateKey = $this->readFromFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS); + $publicKey = $this->readFromFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS); + + $keyPair = new KeyPair($privateKey, $publicKey); + + $rsa->setKeyPair($keyPair); + + return new DigitalEnvelope($rsa, new Aes128()); + } + + /** + * Testing the cloning of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testCloningCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $tmp = clone $protocol; + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->sealEnvelope('')); + + unset($tmp); + $this->assertNotNull($protocol); + + $protocol->setKeyedDigestionFunction(new HmacShaTwo384()); + $tmp = clone $protocol; + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->sealEnvelope('')); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the serialization of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testSerializationCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $tmp = serialize($protocol); + $tmp = unserialize($tmp); + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->sealEnvelope('')); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the object dumping for debugging. + * + * @throws \Exception Wrong usage errors. + */ + public function testDebugCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $this->assertNotEmpty(var_export($protocol, true)); + } + + /** + * Testing if the digital sealing and opening process works. + * + * @throws \Exception If system does not support the algorithm or the randomness source is not available. + */ + public function testDigitalEnvelopeSealingAndOpening() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setRandomGenerator($protocol->getRandomGenerator()); + $protocol->setSymmetricCipher($protocol->getSymmetricCipher()); + $protocol->setAsymmetricCipher($protocol->getAsymmetricCipher()); + + $randomData = random_bytes(16); + + $envelopeObject = $protocol->sealEnvelope($randomData); + $receivedData = $protocol->openEnvelope($envelopeObject); + + $this->assertEquals($randomData, $receivedData); + $this->assertEmpty($envelopeObject->authenticationTag); + + $hasher = new HmacShaTwo384(); + + $protocol->setKeyedDigestionFunction($hasher); + $this->assertEquals($hasher, $protocol->getKeyedDigestionFunction()); + + $envelopeObject = $protocol->sealEnvelope($randomData); + $receivedData = $protocol->openEnvelope($envelopeObject); + + $this->assertEquals($randomData, $receivedData); + $this->assertNotEmpty($envelopeObject->authenticationTag); + } + + /** + * Testing validation case for invalid type of asymmetric service used on initialization. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfAsymmetricEncryptionServicePassedOnInitialization() + { + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol = new DigitalEnvelope(null); + } else { + $hasThrown = null; + + try { + $protocol = new DigitalEnvelope(null); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of symmetric service used on initialization. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfSymmetricEncryptionServicePassedOnInitialization() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol = new DigitalEnvelope($protocol->getAsymmetricCipher(), null); + } else { + $hasThrown = null; + + try { + $protocol = new DigitalEnvelope($protocol->getAsymmetricCipher(), null); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of input data for sealing. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfInputDataForEnvelopeSealing() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->sealEnvelope(['wrong']); + } else { + $hasThrown = null; + + try { + $protocol->sealEnvelope(['wrong']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid authentication tag on opening of envelope. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidAuthenticationTagOnEnvelopeOpening() + { + $protocol = $this->getCryptographicProtocolForTesting(); + $protocol->setKeyedDigestionFunction(new HmacShaTwo384()); + + $envelopeObject = $protocol->sealEnvelope('1234'); + $envelopeObject->authenticationTag = 'FFFF'; + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol->openEnvelope($envelopeObject); + } else { + $hasThrown = null; + + try { + $protocol->openEnvelope($envelopeObject); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing the resource cleanup operation. + * + * @throws \Exception Wrong usage errors. + */ + public function testKeyPairResourceCleanupOperation() + { + $this->assertTrue(self::$isKeyPairGenerated); + + $this->deleteTheFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS); + $this->deleteTheFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS); + + self::$isKeyPairGenerated = null; + } +} diff --git a/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/DigitalSignatureTest.php b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/DigitalSignatureTest.php new file mode 100644 index 0000000..c66b3bb --- /dev/null +++ b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/DigitalSignatureTest.php @@ -0,0 +1,247 @@ + auto-check on next call, `true` => already generated. + * + * @var null|bool Is the key pair generated. + */ + protected static $isKeyPairGenerated = false; + + /** + * Creates new instances for testing. + * + * @return DigitalSignature Testing instance. + * @throws \Exception Wrong usage errors. + */ + private function getCryptographicProtocolForTesting() + { + $dsa = new Dsa1024(); + + if (self::$isKeyPairGenerated === false) { + $generator = new TokenGenerator(); + + $keyPair = $generator->getAsymmetricKeyPair($dsa::KEY_SIZE, $dsa::ALGORITHM_NAME); + + $this->writeToFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS, $keyPair->private); + $this->writeToFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS, $keyPair->public); + + self::$isKeyPairGenerated = true; + } + + $privateKey = $this->readFromFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS); + $publicKey = $this->readFromFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS); + + $keyPair = new KeyPair($privateKey, $publicKey); + + $dsa->setKeyPair($keyPair); + + return new DigitalSignature($dsa); + } + + /** + * Testing the cloning of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testCloningCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $tmp = clone $protocol; + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->createSignedData('')); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the serialization of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testSerializationCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $tmp = serialize($protocol); + $tmp = unserialize($tmp); + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->createSignedData('')); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the object dumping for debugging. + * + * @throws \Exception Wrong usage errors. + */ + public function testDebugCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $this->assertNotEmpty(var_export($protocol, true)); + } + + /** + * Testing if the basic data signature generation and verification process works. + * + * @throws \Exception If system does not support the algorithm or the randomness source is not available. + */ + public function testDataSignatureGenerationAndVerification() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setSignatureStandard($protocol->getSignatureStandard()); + + $randomData = random_bytes(16); + + $signedDataObject = $protocol->createSignedData($randomData); + $extractedVerifiedData = $protocol->extractVerifiedData($signedDataObject); + + $this->assertEquals($randomData, $extractedVerifiedData); + } + + /** + * Testing validation case for invalid type of digital signature service used on initialization. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfDigitalSignatureServicePassedOnInitialization() + { + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol = new DigitalSignature(null); + } else { + $hasThrown = null; + + try { + $protocol = new DigitalSignature(null); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of input data for signing. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfInputDataForSigning() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->createSignedData(['wrong']); + } else { + $hasThrown = null; + + try { + $protocol->createSignedData(['wrong']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of input data for signing. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidSignedDataForVerification() + { + $protocol = $this->getCryptographicProtocolForTesting(); + $signedData = $protocol->createSignedData('1234'); + $signedData->signature = 'FFFF'; + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol->extractVerifiedData($signedData); + } else { + $hasThrown = null; + + try { + $protocol->extractVerifiedData($signedData); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing the resource cleanup operation. + * + * @throws \Exception Wrong usage errors. + */ + public function testKeyPairResourceCleanupOperation() + { + $this->assertTrue(self::$isKeyPairGenerated); + + $this->deleteTheFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS); + $this->deleteTheFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS); + + self::$isKeyPairGenerated = null; + } +} diff --git a/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/KeyExchangeTest.php b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/KeyExchangeTest.php new file mode 100644 index 0000000..d8c3ec9 --- /dev/null +++ b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/KeyExchangeTest.php @@ -0,0 +1,379 @@ +setKeyExchangeSize(512); + + return $exchange; + } + + /** + * Testing the cloning of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testCloningCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $tmp = clone $protocol; + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->generateExchangeRequestInformation()); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the serialization of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testSerializationCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $tmp = serialize($protocol); + $tmp = unserialize($tmp); + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->generateExchangeRequestInformation()); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the object dumping for debugging. + * + * @throws \Exception Wrong usage errors. + */ + public function testDebugCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $this->assertNotEmpty(var_export($protocol, true)); + } + + /** + * Testing if the key exchange process works. + * + * @throws \Exception If system does not support the algorithm or the randomness source is not available. + */ + public function testKeyExchangeBetweenTwoParties() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setKeyExchangeSize(15360); + $this->assertEquals(15360, $protocol->getKeyExchangeSize()); + $protocol->setKeyExchangeSize(4096); + $this->assertEquals(4096, $protocol->getKeyExchangeSize()); + $protocol->setKeyExchangeSize(2048); + $this->assertEquals(2048, $protocol->getKeyExchangeSize()); + $protocol->setKeyExchangeSize(512); + $this->assertEquals(512, $protocol->getKeyExchangeSize()); + + // Alice generates key exchange information + $aliceInformation = $protocol->generateExchangeRequestInformation(); + + $alicePrivateKey = $aliceInformation->private; + $aliceInformation->private = ''; + + // Sends to Bob the prime, generator and public key + $bobInformation = $protocol->generateExchangeResponseInformation( + $aliceInformation->prime, + $aliceInformation->generator + ); + + $bobPrivateKey = $bobInformation->private; + $bobInformation->private = ''; + + // Bob computes the shared key + $bobSharedKey = $protocol->computeSharedSecret($aliceInformation->public, $bobPrivateKey); + + // Sends to Alice the public key (optionally the prime and generator) + $aliceSharedKey = $protocol->computeSharedSecret($bobInformation->public, $alicePrivateKey); + + // Both sides must now have the same key + $this->assertEquals($aliceSharedKey, $bobSharedKey); + } + + /** + * Testing validation case for invalid key pair size for the key exchange generation. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForSettingAnInvalidKeyPairSizeForTheKeyExchangeGeneration() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->setKeyExchangeSize(200); + } else { + $hasThrown = null; + + try { + $protocol->setKeyExchangeSize(200); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of key expansion service used on initialization. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfKeyExpansionServicePassedOnInitialization() + { + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol = new KeyExchange(null); + } else { + $hasThrown = null; + + try { + $protocol = new KeyExchange(null); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid prime number for key exchange information generation. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidPrimeNumberForKeyExchangeGeneration() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->generateExchangeResponseInformation(['wrong'], bin2hex(decbin(2))); + } else { + $hasThrown = null; + + try { + $protocol->generateExchangeResponseInformation(['wrong'], bin2hex(decbin(2))); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid generator number for key exchange information generation. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidGeneratorNumberForKeyExchangeGeneration() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->generateExchangeResponseInformation(bin2hex(decbin(17)), ['wrong']); + } else { + $hasThrown = null; + + try { + $protocol->generateExchangeResponseInformation(bin2hex(decbin(17)), ['wrong']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid remote public key used for computing the shared key. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidRemotePublicKeyUsedForComputingOfSharedKey() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $exchangeInformation = $protocol->generateExchangeRequestInformation(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol->computeSharedSecret($exchangeInformation->private, $exchangeInformation->private); + } else { + $hasThrown = null; + + try { + $protocol->computeSharedSecret($exchangeInformation->private, $exchangeInformation->private); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid local private key used for computing the shared key. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidLocalPrivateKeyUsedForComputingOfSharedKey() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $exchangeInformation = $protocol->generateExchangeRequestInformation(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol->computeSharedSecret($exchangeInformation->public, base64_encode('1234')); + } else { + $hasThrown = null; + + try { + $protocol->computeSharedSecret($exchangeInformation->public, base64_encode('1234')); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid format of remote public key used for computing the shared key. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForSettingWrongFormattedStringForPublicKey() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $exchangeInformation = $protocol->generateExchangeRequestInformation(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->computeSharedSecret('яяяя', $exchangeInformation->private); + } else { + $hasThrown = null; + + try { + $protocol->computeSharedSecret('яяяя', $exchangeInformation->private); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid format of remote public key used for computing the shared key. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForSettingWrongFormattedStringForPrivateKey() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $exchangeInformation = $protocol->generateExchangeRequestInformation(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->computeSharedSecret($exchangeInformation->public, 'яяяя'); + } else { + $hasThrown = null; + + try { + $protocol->computeSharedSecret($exchangeInformation->public, 'яяяя'); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } +} diff --git a/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/LayeredEncryptionTest.php b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/LayeredEncryptionTest.php new file mode 100644 index 0000000..86ed01d --- /dev/null +++ b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/LayeredEncryptionTest.php @@ -0,0 +1,458 @@ +getCryptographicProtocolForTesting(); + + $tmp = clone $protocol; + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->layeredEncryptData('')); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the serialization of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testSerializationCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $tmp = serialize($protocol); + $tmp = unserialize($tmp); + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->layeredEncryptData('')); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the object dumping for debugging. + * + * @throws \Exception Wrong usage errors. + */ + public function testDebugCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $this->assertNotEmpty(var_export($protocol, true)); + } + + /** + * Testing if the basic data encryption and decryption process works. + * + * @throws \Exception If system does not support the algorithm or the randomness source is not available. + */ + public function testBasicDataEncryptionAndDataDecryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setLayers($protocol->getLayers()); + + $randomData = random_bytes(16); + + $encryptedData = $protocol->layeredEncryptData($randomData); + $decryptedData = $protocol->layeredDecryptData($encryptedData); + + $this->assertEquals($randomData, $decryptedData); + $this->assertNotEquals($encryptedData, $protocol->layeredEncryptData($randomData, '1')); + $this->assertNotEquals($encryptedData, $protocol->layeredEncryptData($randomData, 'xx')); + $this->assertNotEquals($randomData, $protocol->layeredDecryptData($encryptedData, 'fake')); + + $layers = $protocol->getLayers(); + $layers [] = new EncryptionLayer( + Aes128::class, + 'manana', + 'power', + Aes128::OFB_MODE, + Aes128::ZERO_PADDING, + Aes128::ENCRYPTION_OUTPUT_HEX_LOWER + ); + + $protocol = new LayeredEncryption($layers); + + $encryptedData = $protocol->layeredEncryptData($randomData, 'pad me hard again'); + $decryptedData = $protocol->layeredDecryptData($encryptedData, 'pad me hard again'); + + $this->assertEquals($randomData, $decryptedData); + $this->assertNotEquals($encryptedData, $protocol->layeredEncryptData($randomData, '22')); + $this->assertNotEquals($encryptedData, $protocol->layeredEncryptData($randomData, 'я')); + $this->assertNotEquals($randomData, $protocol->layeredDecryptData($encryptedData, 'fake')); + $this->assertNotEquals($randomData, $protocol->layeredDecryptData($encryptedData)); + } + + /** + * Testing if the unicode data encryption and decryption process works. + * + * @throws \Exception If system does not support the algorithm or the randomness source is not available. + */ + public function testUnicodeDataEncryptionAndDataDecryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setLayers($protocol->getLayers()); + + $unicodeData = "йМx 3-Й$\v@UdrЯ9Ю"; + + $encryptedData = $protocol->layeredEncryptData($unicodeData); + $decryptedData = $protocol->layeredDecryptData($encryptedData); + + $this->assertEquals($unicodeData, $decryptedData); + $this->assertNotEquals($encryptedData, $protocol->layeredEncryptData($encryptedData, '1')); + $this->assertNotEquals($encryptedData, $protocol->layeredEncryptData($encryptedData, 'xx')); + $this->assertNotEquals($unicodeData, $protocol->layeredDecryptData($encryptedData, 'nonce')); + + $layers = $protocol->getLayers(); + $layers [] = new EncryptionLayer( + Aes128::class, + 'manana', + 'power', + Aes128::OFB_MODE, + Aes128::ZERO_PADDING, + Aes128::ENCRYPTION_OUTPUT_HEX_LOWER + ); + + $protocol->setLayers($layers); + + $key = random_bytes(strlen($unicodeData) + 2); + $encryptedData = $protocol->layeredEncryptData($unicodeData, $key); + $decryptedData = $protocol->layeredDecryptData($encryptedData, $key); + + $this->assertEquals($unicodeData, $decryptedData); + $this->assertNotEquals($encryptedData, $protocol->layeredEncryptData($encryptedData, '22')); + $this->assertNotEquals($encryptedData, $protocol->layeredEncryptData($encryptedData, 'я')); + $this->assertNotEquals($unicodeData, $protocol->layeredDecryptData($encryptedData)); + } + + /** + * Testing if encrypting twice the same input returns the same result. + * + * @throws \Exception If system does not support the algorithm or the randomness source is not available. + */ + public function testEncryptingTheSameDataTwice() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $randomData = random_bytes(16); + + $this->assertEquals( + $protocol->layeredEncryptData($randomData), + $protocol->layeredEncryptData($randomData) + ); + + $this->assertEquals( + $protocol->layeredEncryptData($randomData, 'yes'), + $protocol->layeredEncryptData($randomData, 'yes') + ); + + $this->assertNotEquals( + $protocol->layeredEncryptData($randomData, 'yes'), + $protocol->layeredEncryptData($randomData, 'sir') + ); + } + + /** + * Testing if encrypting twice the same input returns the same result. + * + * @throws \Exception If system does not support the algorithm or the randomness source is not available. + */ + public function testDecryptingTheSameDataTwice() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $randomData = random_bytes(16); + $encryptedData = $protocol->layeredEncryptData($randomData); + + $this->assertEquals( + $protocol->layeredDecryptData($encryptedData), + $protocol->layeredDecryptData($encryptedData) + ); + + $encryptedData = $protocol->layeredEncryptData($randomData, 'secret'); + + $this->assertEquals( + $protocol->layeredDecryptData($encryptedData, 'secret'), + $protocol->layeredDecryptData($encryptedData, 'secret') + ); + + $this->assertNotEquals( + $protocol->layeredDecryptData($encryptedData, 'secret'), + $protocol->layeredDecryptData($encryptedData, 'power') + ); + } + + /** + * Testing validation case for invalid type of layer configuration used on initialization. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfLayerConfigurationPassedOnInitialization() + { + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol = new LayeredEncryption([null, null]); + } else { + $hasThrown = null; + + try { + $protocol = new LayeredEncryption([null, null]); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid number of layers set on initialization. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidNumberOfLayersOnInitialization() + { + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol = new LayeredEncryption([1]); + } else { + $hasThrown = null; + + try { + $protocol = new LayeredEncryption([1]); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for one invalid layer set on initialization. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForOneInvalidLayerOnInitialization() + { + $layers = [ + new EncryptionLayer(Aes128::class, 'test', 'me', Aes128::ECB_MODE), + new EncryptionLayer('\HittingItHarder', 'test', 'me', Aes128::ECB_MODE), + ]; + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol = new LayeredEncryption($layers); + } else { + $hasThrown = null; + + try { + $protocol = new LayeredEncryption($layers); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of input data for encryption passed. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfInputDataForEncryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->layeredEncryptData(['wrong']); + } else { + $hasThrown = null; + + try { + $protocol->layeredEncryptData(['wrong']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type or value of the one-time padding string used for encryption. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidOneTimePaddingStringForEncryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->layeredEncryptData('', [-1000]); + } else { + $hasThrown = null; + + try { + $protocol->layeredEncryptData('', [-1000]); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of input data for decryption passed. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfInputDataForDecryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->layeredDecryptData(['wrong']); + } else { + $hasThrown = null; + + try { + $protocol->layeredDecryptData(['wrong']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type or value of the iteration count used for decryption. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidIterationCountForDecryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $encryptedData = $protocol->layeredEncryptData(''); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->layeredDecryptData($encryptedData, -1000); + } else { + $hasThrown = null; + + try { + $protocol->layeredDecryptData($encryptedData, -1000); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } +} diff --git a/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/MultipleEncryptionTest.php b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/MultipleEncryptionTest.php new file mode 100644 index 0000000..6f4a8ff --- /dev/null +++ b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/MultipleEncryptionTest.php @@ -0,0 +1,333 @@ +getCryptographicProtocolForTesting(); + + $tmp = clone $protocol; + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->multipleEncryptData('')); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the serialization of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testSerializationCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $tmp = serialize($protocol); + $tmp = unserialize($tmp); + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->multipleEncryptData('')); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the object dumping for debugging. + * + * @throws \Exception Wrong usage errors. + */ + public function testDebugCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $this->assertNotEmpty(var_export($protocol, true)); + } + + /** + * Testing if the basic data encryption and decryption process works. + * + * @throws \Exception If system does not support the algorithm or the randomness source is not available. + */ + public function testBasicDataEncryptionAndDataDecryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setSymmetricCipher($protocol->getSymmetricCipher()); + $protocol->setKeyExpansionFunction($protocol->getKeyExpansionFunction()); + + $randomData = random_bytes(16); + + $encryptedData = $protocol->multipleEncryptData($randomData, 5); + $decryptedData = $protocol->multipleDecryptData($encryptedData, 5); + + $this->assertEquals($randomData, $decryptedData); + $this->assertNotEquals($encryptedData, $protocol->multipleEncryptData($randomData, 4)); + $this->assertNotEquals($encryptedData, $protocol->multipleEncryptData($randomData, 6)); + + $protocol->setKeyExpansionFunction($protocol->getKeyExpansionFunction()->setSalt('1234')); + $protocol = new MultipleEncryption($protocol->getSymmetricCipher(), $protocol->getKeyExpansionFunction()); + + $encryptedData = $protocol->multipleEncryptData($randomData, 5); + $decryptedData = $protocol->multipleDecryptData($encryptedData, 5); + + $this->assertEquals($randomData, $decryptedData); + $this->assertNotEquals($encryptedData, $protocol->multipleEncryptData($randomData, 4)); + $this->assertNotEquals($encryptedData, $protocol->multipleEncryptData($randomData, 6)); + } + + /** + * Testing if the unicode data encryption and decryption process works. + * + * @throws \Exception If system does not support the algorithm or the randomness source is not available. + */ + public function testUnicodeDataEncryptionAndDataDecryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setSymmetricCipher($protocol->getSymmetricCipher()); + $protocol->setKeyExpansionFunction($protocol->getKeyExpansionFunction()); + + $unicodeData = "йМx 3-Й$\v@UdrЯ9Ю"; + + $encryptedData = $protocol->multipleEncryptData($unicodeData, 5); + $decryptedData = $protocol->multipleDecryptData($encryptedData, 5); + + $this->assertEquals($unicodeData, $decryptedData); + $this->assertNotEquals($encryptedData, $protocol->multipleEncryptData($unicodeData, 4)); + $this->assertNotEquals($encryptedData, $protocol->multipleEncryptData($unicodeData, 6)); + + $protocol->setKeyExpansionFunction($protocol->getKeyExpansionFunction()->setSalt('1234')); + $protocol = new MultipleEncryption($protocol->getSymmetricCipher(), $protocol->getKeyExpansionFunction()); + + $encryptedData = $protocol->multipleEncryptData($unicodeData, 5); + $decryptedData = $protocol->multipleDecryptData($encryptedData, 5); + + $this->assertEquals($unicodeData, $decryptedData); + $this->assertNotEquals($encryptedData, $protocol->multipleEncryptData($unicodeData, 4)); + $this->assertNotEquals($encryptedData, $protocol->multipleEncryptData($unicodeData, 6)); + } + + /** + * Testing if encrypting twice the same input returns the same result. + * + * @throws \Exception If system does not support the algorithm or the randomness source is not available. + */ + public function testEncryptingTheSameDataTwice() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $randomData = random_bytes(16); + + $this->assertEquals( + $protocol->multipleEncryptData($randomData), + $protocol->multipleEncryptData($randomData) + ); + } + + /** + * Testing if encrypting twice the same input returns the same result. + * + * @throws \Exception If system does not support the algorithm or the randomness source is not available. + */ + public function testDecryptingTheSameDataTwice() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $randomData = random_bytes(16); + $encryptedData = $protocol->multipleEncryptData($randomData); + + $this->assertEquals( + $protocol->multipleDecryptData($encryptedData), + $protocol->multipleDecryptData($encryptedData) + ); + } + + /** + * Testing validation case for invalid type of symmetric service used on initialization. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfSymmetricEncryptionServicePassedOnInitialization() + { + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol = new MultipleEncryption(null, null); + } else { + $hasThrown = null; + + try { + $protocol = new MultipleEncryption(null, null); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of input data for encryption passed. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfInputDataForEncryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->multipleEncryptData(['wrong'], 2); + } else { + $hasThrown = null; + + try { + $protocol->multipleEncryptData(['wrong'], 2); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type or value of the iteration count used for encryption. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidIterationCountForEncryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->multipleEncryptData('', -1000); + } else { + $hasThrown = null; + + try { + $protocol->multipleEncryptData('', -1000); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of input data for decryption passed. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfInputDataForDecryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->multipleDecryptData(['wrong'], 2); + } else { + $hasThrown = null; + + try { + $protocol->multipleDecryptData(['wrong'], 2); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type or value of the iteration count used for decryption. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidIterationCountForDecryption() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $encryptedData = $protocol->multipleEncryptData(''); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->multipleDecryptData($encryptedData, -1000); + } else { + $hasThrown = null; + + try { + $protocol->multipleDecryptData($encryptedData, -1000); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } +} diff --git a/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/PasswordBasedAuthenticationTest.php b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/PasswordBasedAuthenticationTest.php new file mode 100644 index 0000000..5739543 --- /dev/null +++ b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/PasswordBasedAuthenticationTest.php @@ -0,0 +1,252 @@ +getCryptographicProtocolForTesting(); + + $tmp = clone $protocol; + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->identifyEntity('', '')); + + unset($tmp); + $this->assertNotNull($protocol); + + $protocol->setVerificationAlgorithm(new Bcrypt()); + $tmp = clone $protocol; + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->identifyEntity('', '')); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the serialization of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testSerializationCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $tmp = serialize($protocol); + $tmp = unserialize($tmp); + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->identifyEntity('', '')); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the object dumping for debugging. + * + * @throws \Exception Wrong usage errors. + */ + public function testDebugCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $this->assertNotEmpty(var_export($protocol, true)); + } + + /** + * Testing the object identification capabilities. + * + * @throws \Exception Wrong usage errors. + */ + public function testClientEntityIdentificationAndVerificationCapabilities() + { + $entityId = '123жЯYd!`5'; + + $protocol = $this->getCryptographicProtocolForTesting(); + + $this->assertTrue($protocol->identifyEntity($entityId, $entityId)); + $this->assertFalse($protocol->identifyEntity($entityId, strrev($entityId))); + } + + /** + * Testing the object authentication capabilities. + * + * @throws \Exception Wrong usage errors. + */ + public function testClientEntityAuthenticationCapabilities() + { + $entityPassword = 'рЯxD4!.x'; + + $protocol = $this->getCryptographicProtocolForTesting(); + + $this->assertTrue($protocol->authenticateEntity($entityPassword, $entityPassword)); + $this->assertFalse($protocol->authenticateEntity($entityPassword, strrev($entityPassword))); + + $hasher = new Bcrypt(); + $hasher->setAlgorithmicCost($hasher::MINIMUM_ALGORITHMIC_COST)->setSaltingMode($hasher::SALTING_MODE_NONE); + + $passwordDigest = $hasher->hashData($entityPassword); + $protocol->setVerificationAlgorithm($hasher); + $this->assertEquals($hasher, $protocol->getVerificationAlgorithm()); + + $this->assertTrue($protocol->authenticateEntity($passwordDigest, $entityPassword)); + $this->assertFalse($protocol->authenticateEntity($passwordDigest, strrev($entityPassword))); + } + + /** + * Testing validation case for invalid type of user string for identification. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfUserStringPassedForIdentification() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->identifyEntity('', ['none']); + } else { + $hasThrown = null; + + try { + $protocol->identifyEntity('', ['none']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of correct string for identification. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfCorrectStringPassedForIdentification() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->identifyEntity(['none'], ''); + } else { + $hasThrown = null; + + try { + $protocol->identifyEntity(['none'], ''); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of user string for authentication. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfUserStringPassedForAuthentication() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->authenticateEntity('', ['none']); + } else { + $hasThrown = null; + + try { + $protocol->authenticateEntity('', ['none']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of correct string for authentication. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfCorrectStringPassedForAuthentication() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->authenticateEntity(['none'], ''); + } else { + $hasThrown = null; + + try { + $protocol->authenticateEntity(['none'], ''); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } +} diff --git a/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/PublicKeyAuthenticationTest.php b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/PublicKeyAuthenticationTest.php new file mode 100644 index 0000000..6450698 --- /dev/null +++ b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/PublicKeyAuthenticationTest.php @@ -0,0 +1,391 @@ + auto-check on next call, `true` => already generated. + * + * @var null|bool Is the key pair generated. + */ + protected static $isKeyPairGenerated = false; + + /** + * Creates new instances for testing. + * + * @return PublicKeyAuthentication Testing instance. + * @throws \Exception Wrong usage errors. + */ + private function getCryptographicProtocolForTesting() + { + $rsa = new Rsa1024(); + + if (self::$isKeyPairGenerated === false) { + $generator = new TokenGenerator(); + + $keyPair = $generator->getAsymmetricKeyPair($rsa::KEY_SIZE, $rsa::ALGORITHM_NAME); + + $this->writeToFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS, $keyPair->private); + $this->writeToFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS, $keyPair->public); + + self::$isKeyPairGenerated = true; + } + + $privateKey = $this->readFromFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS); + $publicKey = $this->readFromFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS); + + $keyPair = new KeyPair($privateKey, $publicKey); + + $rsa->setKeyPair($keyPair); + + return new PublicKeyAuthentication($rsa); + } + + /** + * Testing the cloning of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testCloningCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $tmp = clone $protocol; + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->identifyEntity('', '')); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the serialization of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testSerializationCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $tmp = serialize($protocol); + $tmp = unserialize($tmp); + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->identifyEntity('', '')); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the object dumping for debugging. + * + * @throws \Exception Wrong usage errors. + */ + public function testDebugCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $this->assertNotEmpty(var_export($protocol, true)); + } + + /** + * Testing the object identification capabilities. + * + * @throws \Exception Wrong usage errors. + */ + public function testClientEntityIdentificationAndVerificationCapabilities() + { + $entityId = '123жЯYd!`5'; + + $protocol = $this->getCryptographicProtocolForTesting(); + + $this->assertTrue($protocol->identifyEntity($entityId, $entityId)); + $this->assertFalse($protocol->identifyEntity($entityId, strrev($entityId))); + } + + /** + * Testing the object authentication capabilities. + * + * @throws \Exception Wrong usage errors. + */ + public function testClientEntityAuthenticationCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setAsymmetricCipher($protocol->getAsymmetricCipher()); + $protocol->setRandomGenerator($protocol->getRandomGenerator()); + + $this->assertTrue($protocol->getRandomGenerator() instanceof AbstractGenerator); + $this->assertTrue($protocol->getAsymmetricCipher() instanceof AbstractAsymmetricEncryptionAlgorithm); + $this->assertTrue($protocol->getAsymmetricCipher() instanceof DataEncryptionInterface); + + $tokenObject = $protocol->generateAuthenticationToken(); + $userDecryptedToken = $protocol->extractAuthenticationToken($tokenObject->cipherData); + + $this->assertTrue($protocol->authenticateEntity($tokenObject->tokenData, $userDecryptedToken)); + $this->assertFalse($protocol->authenticateEntity($tokenObject->tokenData, strrev($userDecryptedToken))); + } + + /** + * Testing validation case for invalid type of asymmetric service used on initialization. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfAsymmetricEncryptionServicePassedOnInitialization() + { + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol = new PublicKeyAuthentication(null); + } else { + $hasThrown = null; + + try { + $protocol = new PublicKeyAuthentication(null); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of user string for identification. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfUserStringPassedForIdentification() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->identifyEntity('', ['none']); + } else { + $hasThrown = null; + + try { + $protocol->identifyEntity('', ['none']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of correct string for identification. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfCorrectStringPassedForIdentification() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->identifyEntity(['none'], ''); + } else { + $hasThrown = null; + + try { + $protocol->identifyEntity(['none'], ''); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of user string for authentication. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfUserStringPassedForAuthentication() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->authenticateEntity('', ['none']); + } else { + $hasThrown = null; + + try { + $protocol->authenticateEntity('', ['none']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of correct string for authentication. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfCorrectStringPassedForAuthentication() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->authenticateEntity(['none'], ''); + } else { + $hasThrown = null; + + try { + $protocol->authenticateEntity(['none'], ''); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid output length passed for token generation. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidOutputLengthPassedForTokenGeneration() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\LengthException::class); + + $protocol->generateAuthenticationToken(-1000); + } else { + $hasThrown = null; + + try { + $protocol->generateAuthenticationToken(-1000); + } catch (\LengthException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid cipher token passed for token extraction. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidCipherTokenPassedForTokenExtraction() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->extractAuthenticationToken(['none']); + } else { + $hasThrown = null; + + try { + $protocol->extractAuthenticationToken(['none']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing the resource cleanup operation. + * + * @throws \Exception Wrong usage errors. + */ + public function testKeyPairResourceCleanupOperation() + { + $this->assertTrue(self::$isKeyPairGenerated); + + $this->deleteTheFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS); + $this->deleteTheFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS); + + self::$isKeyPairGenerated = null; + } +} diff --git a/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/SymmetricKeyAuthenticationTest.php b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/SymmetricKeyAuthenticationTest.php new file mode 100644 index 0000000..e631d09 --- /dev/null +++ b/tests/CryptoManana/Tests/IntegrationSuite/CryptographicProtocol/SymmetricKeyAuthenticationTest.php @@ -0,0 +1,335 @@ +getCryptographicProtocolForTesting(); + + $tmp = clone $protocol; + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->identifyEntity('', '')); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the serialization of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testSerializationCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $tmp = serialize($protocol); + $tmp = unserialize($tmp); + + $this->assertEquals($protocol, $tmp); + $this->assertNotEmpty($tmp->identifyEntity('', '')); + + unset($tmp); + $this->assertNotNull($protocol); + } + + /** + * Testing the object dumping for debugging. + * + * @throws \Exception Wrong usage errors. + */ + public function testDebugCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $this->assertNotEmpty(var_export($protocol, true)); + } + + /** + * Testing the object identification capabilities. + * + * @throws \Exception Wrong usage errors. + */ + public function testClientEntityIdentificationAndVerificationCapabilities() + { + $entityId = '123жЯYd!`5'; + + $protocol = $this->getCryptographicProtocolForTesting(); + + $this->assertTrue($protocol->identifyEntity($entityId, $entityId)); + $this->assertFalse($protocol->identifyEntity($entityId, strrev($entityId))); + } + + /** + * Testing the object authentication capabilities. + * + * @throws \Exception Wrong usage errors. + */ + public function testClientEntityAuthenticationCapabilities() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + $protocol->setSymmetricCipher($protocol->getSymmetricCipher()); + $protocol->setRandomGenerator($protocol->getRandomGenerator()); + + $this->assertTrue($protocol->getRandomGenerator() instanceof AbstractGenerator); + $this->assertTrue($protocol->getSymmetricCipher() instanceof AbstractBlockCipherAlgorithm); + $this->assertTrue($protocol->getSymmetricCipher() instanceof DataEncryptionInterface); + + $tokenObject = $protocol->generateAuthenticationToken(); + $userDecryptedToken = $protocol->extractAuthenticationToken($tokenObject->cipherData); + + $this->assertTrue($protocol->authenticateEntity($tokenObject->tokenData, $userDecryptedToken)); + $this->assertFalse($protocol->authenticateEntity($tokenObject->tokenData, strrev($userDecryptedToken))); + } + + /** + * Testing validation case for invalid type of symmetric service used on initialization. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfSymmetricEncryptionServicePassedOnInitialization() + { + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $protocol = new SymmetricKeyAuthentication(null); + } else { + $hasThrown = null; + + try { + $protocol = new SymmetricKeyAuthentication(null); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of user string for identification. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfUserStringPassedForIdentification() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->identifyEntity('', ['none']); + } else { + $hasThrown = null; + + try { + $protocol->identifyEntity('', ['none']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of correct string for identification. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfCorrectStringPassedForIdentification() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->identifyEntity(['none'], ''); + } else { + $hasThrown = null; + + try { + $protocol->identifyEntity(['none'], ''); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of user string for authentication. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfUserStringPassedForAuthentication() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->authenticateEntity('', ['none']); + } else { + $hasThrown = null; + + try { + $protocol->authenticateEntity('', ['none']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid type of correct string for authentication. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidTypeOfCorrectStringPassedForAuthentication() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->authenticateEntity(['none'], ''); + } else { + $hasThrown = null; + + try { + $protocol->authenticateEntity(['none'], ''); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid output length passed for token generation. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidOutputLengthPassedForTokenGeneration() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\LengthException::class); + + $protocol->generateAuthenticationToken(-1000); + } else { + $hasThrown = null; + + try { + $protocol->generateAuthenticationToken(-1000); + } catch (\LengthException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for invalid cipher token passed for token extraction. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidCipherTokenPassedForTokenExtraction() + { + $protocol = $this->getCryptographicProtocolForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $protocol->extractAuthenticationToken(['none']); + } else { + $hasThrown = null; + + try { + $protocol->extractAuthenticationToken(['none']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } +} diff --git a/tests/CryptoManana/Tests/IntegrationSuite/Utilities/DataShufflerTest.php b/tests/CryptoManana/Tests/IntegrationSuite/Utilities/DataShufflerTest.php new file mode 100644 index 0000000..bda48f4 --- /dev/null +++ b/tests/CryptoManana/Tests/IntegrationSuite/Utilities/DataShufflerTest.php @@ -0,0 +1,199 @@ +getDataShufflerForTesting(); + + $tmp = clone $shuffler; + + $this->assertEquals($shuffler, $tmp); + $this->assertNotEmpty($tmp->shuffleString('test')); + + unset($tmp); + $this->assertNotNull($shuffler); + } + + /** + * Testing the serialization of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testSerializationCapabilities() + { + $shuffler = $this->getDataShufflerForTesting(); + + $tmp = serialize($shuffler); + $tmp = unserialize($tmp); + + $this->assertEquals($shuffler, $tmp); + $this->assertNotEmpty($tmp->shuffleString('test')); + + unset($tmp); + $this->assertNotNull($shuffler); + } + + /** + * Testing the object dumping for debugging. + * + * @throws \Exception Wrong usage errors. + */ + public function testDebugCapabilities() + { + $shuffler = $this->getDataShufflerForTesting(); + + $this->assertNotEmpty(var_export($shuffler, true)); + } + + /** + * Testing the dependency injection principle realization. + * + * @throws \Exception Wrong usage errors. + */ + public function testDependencyInjection() + { + $shuffler = $this->getDataShufflerForTesting(); + + $this->assertTrue($shuffler instanceof AbstractRandomnessInjectable); + $this->assertTrue($shuffler->getRandomGenerator() instanceof CryptoRandom); + + $shuffler->setRandomGenerator(new QuasiRandom()); + $this->assertTrue($shuffler->getRandomGenerator() instanceof QuasiRandom); + + $shuffler->setRandomGenerator(new PseudoRandom()); + $this->assertTrue($shuffler->getRandomGenerator() instanceof PseudoRandom); + + $shuffler = $shuffler->setRandomGenerator(new CryptoRandom())->seedRandomGenerator(); + $this->assertTrue($shuffler->getRandomGenerator() instanceof CryptoRandom); + } + + /** + * Testing the string shuffling. + * + * @throws \Exception Wrong usage errors. + */ + public function testStringShuffling() + { + $shuffler = $this->getDataShufflerForTesting(new PseudoRandom()); + $testString = 'Long string for testing in here! #ThisIsNaughty'; + + $resultOne = $shuffler->shuffleString($testString); + $resultTwo = $shuffler->shuffleString($testString); + + $this->assertNotEquals($resultOne, $resultTwo); + + $shuffler->seedRandomGenerator(42); + $resultOne = $shuffler->shuffleString($testString); + + $shuffler->seedRandomGenerator(42); + $resultTwo = $shuffler->shuffleString($testString); + + $this->assertEquals($resultOne, $resultTwo); + } + + /** + * Testing the array shuffling. + * + * @throws \Exception Wrong usage errors. + */ + public function testArrayShuffling() + { + $shuffler = $this->getDataShufflerForTesting(new PseudoRandom()); + $testArray = ['1', [3, 2], new \stdClass(), 33, 'test', [], '1', 69]; + + $resultOne = $shuffler->shuffleArray($testArray); + $resultTwo = $shuffler->shuffleArray($testArray); + + $this->assertNotEquals($resultOne, $resultTwo); + + $shuffler->seedRandomGenerator(42); + $resultOne = $shuffler->shuffleArray($testArray); + + $shuffler->seedRandomGenerator(42); + $resultTwo = $shuffler->shuffleArray($testArray); + + $this->assertEquals($resultOne, $resultTwo); + } + + /** + * Testing the shuffling of supported types with empty values. + * + * @throws \Exception Wrong usage errors. + */ + public function testShufflingOfEmptyInput() + { + $shuffler = $this->getDataShufflerForTesting(); + + $this->assertEmpty($shuffler->shuffleString('')); + $this->assertEmpty($shuffler->shuffleArray([])); + } + + /** + * Testing validation case when a string is not given for string shuffling. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseStringNotGivenForStringShuffling() + { + $generator = $this->getDataShufflerForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $generator->shuffleString(['array']); + } else { + $hasThrown = null; + + try { + $generator->shuffleString(['array']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } +} diff --git a/tests/CryptoManana/Tests/IntegrationSuite/Utilities/ElementPickerTest.php b/tests/CryptoManana/Tests/IntegrationSuite/Utilities/ElementPickerTest.php new file mode 100644 index 0000000..45667c1 --- /dev/null +++ b/tests/CryptoManana/Tests/IntegrationSuite/Utilities/ElementPickerTest.php @@ -0,0 +1,199 @@ +getElementPickerForTesting(); + + $tmp = clone $picker; + + $this->assertEquals($picker, $tmp); + $this->assertNotEmpty($tmp->pickCharacterElement('test')); + + unset($tmp); + $this->assertNotNull($picker); + } + + /** + * Testing the serialization of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testSerializationCapabilities() + { + $picker = $this->getElementPickerForTesting(); + + $tmp = serialize($picker); + $tmp = unserialize($tmp); + + $this->assertEquals($picker, $tmp); + $this->assertNotEmpty($tmp->pickCharacterElement('test')); + + unset($tmp); + $this->assertNotNull($picker); + } + + /** + * Testing the object dumping for debugging. + * + * @throws \Exception Wrong usage errors. + */ + public function testDebugCapabilities() + { + $picker = $this->getElementPickerForTesting(); + + $this->assertNotEmpty(var_export($picker, true)); + } + + /** + * Testing the dependency injection principle realization. + * + * @throws \Exception Wrong usage errors. + */ + public function testDependencyInjection() + { + $picker = $this->getElementPickerForTesting(); + + $this->assertTrue($picker instanceof AbstractRandomnessInjectable); + $this->assertTrue($picker->getRandomGenerator() instanceof CryptoRandom); + + $picker->setRandomGenerator(new QuasiRandom()); + $this->assertTrue($picker->getRandomGenerator() instanceof QuasiRandom); + + $picker->setRandomGenerator(new PseudoRandom()); + $this->assertTrue($picker->getRandomGenerator() instanceof PseudoRandom); + + $picker = $picker->setRandomGenerator(new CryptoRandom())->seedRandomGenerator(); + $this->assertTrue($picker->getRandomGenerator() instanceof CryptoRandom); + } + + /** + * Testing the random picking of a character from a string. + * + * @throws \Exception Wrong usage errors. + */ + public function testPickingRandomCharacterFromString() + { + $picker = $this->getElementPickerForTesting(new PseudoRandom()); + $testString = 'Long string for testing in here! #ThisIsNaughty'; + + $resultOne = $picker->pickCharacterElement($testString); + $resultTwo = $picker->pickCharacterElement($testString); + + $this->assertNotEquals($resultOne, $resultTwo); + + $picker->seedRandomGenerator(42); + $resultOne = $picker->pickCharacterElement($testString); + + $picker->seedRandomGenerator(42); + $resultTwo = $picker->pickCharacterElement($testString); + + $this->assertEquals($resultOne, $resultTwo); + } + + /** + * Testing the random picking of an element from an array. + * + * @throws \Exception Wrong usage errors. + */ + public function testPickingRandomElementFromArray() + { + $picker = $this->getElementPickerForTesting(new PseudoRandom()); + $testArray = ['1', [3, 2], new \stdClass(), 33, 'test', [], '1', 69]; + + $resultOne = $picker->pickArrayElement($testArray); + $resultTwo = $picker->pickArrayElement($testArray); + + $this->assertNotEquals($resultOne, $resultTwo); + + $picker->seedRandomGenerator(42); + $resultOne = $picker->pickArrayElement($testArray); + + $picker->seedRandomGenerator(42); + $resultTwo = $picker->pickArrayElement($testArray); + + $this->assertEquals($resultOne, $resultTwo); + } + + /** + * Testing the element picking in supported types with empty values. + * + * @throws \Exception Wrong usage errors. + */ + public function testPickingFromEmptyInput() + { + $picker = $this->getElementPickerForTesting(); + + $this->assertEmpty($picker->pickCharacterElement('')); + $this->assertEmpty($picker->pickArrayElement([])); + } + + /** + * Testing validation case when a string is not given for character picking. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseStringNotGivenForCharacterPicking() + { + $generator = $this->getElementPickerForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $generator->pickCharacterElement(['array']); + } else { + $hasThrown = null; + + try { + $generator->pickCharacterElement(['array']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } +} diff --git a/tests/CryptoManana/Tests/IntegrationSuite/Utilities/FileShredderTest.php b/tests/CryptoManana/Tests/IntegrationSuite/Utilities/FileShredderTest.php new file mode 100644 index 0000000..781882d --- /dev/null +++ b/tests/CryptoManana/Tests/IntegrationSuite/Utilities/FileShredderTest.php @@ -0,0 +1,209 @@ +getFileShredderForTesting(); + + $tmp = clone $shredder; + + $this->assertEquals($shredder, $tmp); + $this->assertNotEmpty($shredder->getRandomGenerator()); + + unset($tmp); + $this->assertNotNull($shredder); + } + + /** + * Testing the serialization of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testSerializationCapabilities() + { + $shredder = $this->getFileShredderForTesting(); + + $tmp = serialize($shredder); + $tmp = unserialize($tmp); + + $this->assertEquals($shredder, $tmp); + $this->assertNotEmpty($shredder->getRandomGenerator()); + + unset($tmp); + $this->assertNotNull($shredder); + } + + /** + * Testing the object dumping for debugging. + * + * @throws \Exception Wrong usage errors. + */ + public function testDebugCapabilities() + { + $shredder = $this->getFileShredderForTesting(); + + $this->assertNotEmpty(var_export($shredder, true)); + } + + /** + * Testing the dependency injection principle realization. + * + * @throws \Exception Wrong usage errors. + */ + public function testDependencyInjection() + { + $shredder = $this->getFileShredderForTesting(); + + $this->assertTrue($shredder instanceof AbstractRandomnessInjectable); + $this->assertTrue($shredder->getRandomGenerator() instanceof CryptoRandom); + + $shredder->setRandomGenerator(new QuasiRandom()); + $this->assertTrue($shredder->getRandomGenerator() instanceof QuasiRandom); + + $shredder->setRandomGenerator(new PseudoRandom()); + $this->assertTrue($shredder->getRandomGenerator() instanceof PseudoRandom); + + $shredder = $shredder->setRandomGenerator(new CryptoRandom())->seedRandomGenerator(); + $this->assertTrue($shredder->getRandomGenerator() instanceof CryptoRandom); + } + + /** + * Testing the file erasure. + * + * @throws \Exception Wrong usage errors. + */ + public function testSecureFileErasure() + { + $shredder = $this->getFileShredderForTesting(); + $fileName = $this->getTemporaryFilename(); + + $this->writeToFile($fileName, 'test'); + + $shredder->eraseFile($fileName); + + $this->assertEquals('', $this->readFromFile($fileName)); + + // For safety, if the above assert fails + $this->deleteTheFile($fileName); + } + + /** + * Testing the empty file erasure. + * + * @throws \Exception Wrong usage errors. + */ + public function testEmptyFileErasure() + { + $shredder = $this->getFileShredderForTesting(); + $fileName = $this->getTemporaryFilename(); + + $this->writeToFile($fileName, ''); + + $shredder->eraseFile($fileName); + + $this->assertEquals('', $this->readFromFile($fileName)); + + // For safety, if the above assert fails + $this->deleteTheFile($fileName); + } + + /** + * Testing validation case for invalid type of filename used for erasure. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidFileNameUsedForErasure() + { + $shredder = $this->getFileShredderForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $shredder->eraseFile(['wrong']); + } else { + $hasThrown = null; + + try { + $shredder->eraseFile(['wrong']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for non-existing filename used for hashing. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForNonExistingFileNameUsedForErasure() + { + $shredder = $this->getFileShredderForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + + $shredder->eraseFile('non-existing.tmp'); + } else { + $hasThrown = null; + + try { + $shredder->eraseFile('non-existing.tmp'); + } catch (\RuntimeException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } +} diff --git a/tests/CryptoManana/Tests/IntegrationSuite/Utilities/TokenGeneratorTest.php b/tests/CryptoManana/Tests/IntegrationSuite/Utilities/TokenGeneratorTest.php new file mode 100644 index 0000000..e0b1a3b --- /dev/null +++ b/tests/CryptoManana/Tests/IntegrationSuite/Utilities/TokenGeneratorTest.php @@ -0,0 +1,464 @@ +getTokenGeneratorForTesting(); + + $tmp = clone $generator; + + $this->assertEquals($generator, $tmp); + $this->assertNotEmpty($tmp->getTokenString(10)); + + unset($tmp); + $this->assertNotNull($generator); + } + + /** + * Testing the serialization of an instance. + * + * @throws \Exception Wrong usage errors. + */ + public function testSerializationCapabilities() + { + $generator = $this->getTokenGeneratorForTesting(); + + $tmp = serialize($generator); + $tmp = unserialize($tmp); + + $this->assertEquals($generator, $tmp); + $this->assertNotEmpty($tmp->getTokenString(10)); + + unset($tmp); + $this->assertNotNull($generator); + } + + /** + * Testing the object dumping for debugging. + * + * @throws \Exception Wrong usage errors. + */ + public function testDebugCapabilities() + { + $generator = $this->getTokenGeneratorForTesting(); + + $this->assertNotEmpty(var_export($generator, true)); + } + + /** + * Testing the dependency injection principle realization. + * + * @throws \Exception Wrong usage errors. + */ + public function testDependencyInjection() + { + $generator = $this->getTokenGeneratorForTesting(); + + $this->assertTrue($generator instanceof AbstractRandomnessInjectable); + $this->assertTrue($generator->getRandomGenerator() instanceof CryptoRandom); + + $generator->setRandomGenerator(new QuasiRandom()); + $this->assertTrue($generator->getRandomGenerator() instanceof QuasiRandom); + + $generator->setRandomGenerator(new PseudoRandom()); + $this->assertTrue($generator->getRandomGenerator() instanceof PseudoRandom); + + $generator = $generator->setRandomGenerator(new CryptoRandom())->seedRandomGenerator(); + $this->assertTrue($generator->getRandomGenerator() instanceof CryptoRandom); + } + + /** + * Testing secure password generation. + * + * @throws \Exception Wrong usage errors. + */ + public function testPasswordStringGeneration() + { + $generator = $this->getTokenGeneratorForTesting(new PseudoRandom()); + + $resultOne = $generator->getPasswordString(20); + $resultTwo = $generator->getPasswordString(20); + + $this->assertNotEquals($resultOne, $resultTwo); + + $resultOne = $generator->getPasswordString(20, false); + $resultTwo = $generator->getPasswordString(20, false); + + $this->assertNotEquals($resultOne, $resultTwo); + + $generator->seedRandomGenerator(42); + $resultOne = $generator->getPasswordString(20); + + $generator->seedRandomGenerator(42); + $resultTwo = $generator->getPasswordString(20); + + $this->assertEquals($resultOne, $resultTwo); + } + + /** + * Testing secure token generation. + * + * @throws \Exception Wrong usage errors. + */ + public function testTokenStringGeneration() + { + $generator = $this->getTokenGeneratorForTesting(new PseudoRandom()); + + $resultOne = $generator->getTokenString(64); + $resultTwo = $generator->getTokenString(64); + + $this->assertNotEquals($resultOne, $resultTwo); + + $resultOne = $generator->getTokenString(64, false); + $resultTwo = $generator->getTokenString(64, false); + + $this->assertNotEquals($resultOne, $resultTwo); + + $generator->seedRandomGenerator(42); + $resultOne = $generator->getTokenString(64); + + $generator->seedRandomGenerator(42); + $resultTwo = $generator->getTokenString(64); + + $this->assertEquals($resultOne, $resultTwo); + } + + /** + * Testing secure hashing salt generation. + * + * @throws \Exception Wrong usage errors. + */ + public function testHashingSaltGeneration() + { + $generator = $this->getTokenGeneratorForTesting(new PseudoRandom()); + + $resultOne = $generator->getHashingSalt(64); + $resultTwo = $generator->getHashingSalt(64); + + $this->assertNotEquals($resultOne, $resultTwo); + + $resultOne = $generator->getHashingSalt(64, false); + $resultTwo = $generator->getHashingSalt(64, false); + + $this->assertNotEquals($resultOne, $resultTwo); + + $generator->seedRandomGenerator(42); + $resultOne = $generator->getHashingSalt(64); + + $generator->seedRandomGenerator(42); + $resultTwo = $generator->getHashingSalt(64); + + $this->assertEquals($resultOne, $resultTwo); + } + + /** + * Testing secure hashing key generation. + * + * @throws \Exception Wrong usage errors. + */ + public function testHashingKeyGeneration() + { + $generator = $this->getTokenGeneratorForTesting(new PseudoRandom()); + + $resultOne = $generator->getHashingKey(64); + $resultTwo = $generator->getHashingKey(64); + + $this->assertNotEquals($resultOne, $resultTwo); + + $resultOne = $generator->getHashingKey(64, false); + $resultTwo = $generator->getHashingKey(64, false); + + $this->assertNotEquals($resultOne, $resultTwo); + + $generator->seedRandomGenerator(42); + $resultOne = $generator->getHashingKey(64); + + $generator->seedRandomGenerator(42); + $resultTwo = $generator->getHashingKey(64); + + $this->assertEquals($resultOne, $resultTwo); + } + + /** + * Testing secure encryption key generation. + * + * @throws \Exception Wrong usage errors. + */ + public function testEncryptionKeyGeneration() + { + $generator = $this->getTokenGeneratorForTesting(new PseudoRandom()); + + $resultOne = $generator->getEncryptionKey(64); + $resultTwo = $generator->getEncryptionKey(64); + + $this->assertNotEquals($resultOne, $resultTwo); + + $resultOne = $generator->getEncryptionKey(64, false); + $resultTwo = $generator->getEncryptionKey(64, false); + + $this->assertNotEquals($resultOne, $resultTwo); + + $generator->seedRandomGenerator(42); + $resultOne = $generator->getEncryptionKey(64); + + $generator->seedRandomGenerator(42); + $resultTwo = $generator->getEncryptionKey(64); + + $this->assertEquals($resultOne, $resultTwo); + } + + /** + * Testing secure encryption initialization vector generation. + * + * @throws \Exception Wrong usage errors. + */ + public function testInitializationVectorGeneration() + { + $generator = $this->getTokenGeneratorForTesting(new PseudoRandom()); + + $resultOne = $generator->getEncryptionInitializationVector(64); + $resultTwo = $generator->getEncryptionInitializationVector(64); + + $this->assertNotEquals($resultOne, $resultTwo); + + $resultOne = $generator->getEncryptionInitializationVector(64, false); + $resultTwo = $generator->getEncryptionInitializationVector(64, false); + + $this->assertNotEquals($resultOne, $resultTwo); + + $generator->seedRandomGenerator(42); + $resultOne = $generator->getEncryptionInitializationVector(64); + + $generator->seedRandomGenerator(42); + $resultTwo = $generator->getEncryptionInitializationVector(64); + + $this->assertEquals($resultOne, $resultTwo); + } + + /** + * Testing secure asymmetric key pair generation. + * + * @throws \Exception Wrong usage errors. + */ + public function testAsymmetricKeyPairGeneration() + { + $generator = $this->getTokenGeneratorForTesting(); + + $keyPair = $generator->getAsymmetricKeyPair( + $generator::KEY_PAIR_1024_BITS, + $generator::RSA_KEY_PAIR_TYPE + ); + + $this->assertTrue( + is_object($keyPair) && + $keyPair instanceof KeyPair && + isset($keyPair->private) && + isset($keyPair->public) + ); + + $privateKey = $keyPair->private; + $publicKey = $keyPair->public; + + $this->assertTrue( + preg_match('%^[a-zA-Z0-9/+]*={0,2}$%', $privateKey) && strlen($privateKey) % 4 === 0 + ); + $this->assertTrue( + preg_match('%^[a-zA-Z0-9/+]*={0,2}$%', $publicKey) && strlen($publicKey) % 4 === 0 + ); + } + + /** + * Testing validation case for non-positive output length. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForNonPositiveOutputLength() + { + $generator = $this->getTokenGeneratorForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\LengthException::class); + + $generator->getTokenString(0); + } else { + $hasThrown = null; + + try { + $generator->getTokenString(0); + } catch (\LengthException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case invalid asymmetric key pair type. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidAsymmetricKeyPairAlgorithmType() + { + $generator = $this->getTokenGeneratorForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $generator->getAsymmetricKeyPair(512, ['wrong']); + } else { + $hasThrown = null; + + try { + $generator->getAsymmetricKeyPair(512, ['wrong']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + + /** + * Testing validation case invalid asymmetric key pair size. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForInvalidAsymmetricKeyPairSize() + { + $generator = $this->getTokenGeneratorForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $generator->getAsymmetricKeyPair(['wrong']); + } else { + $hasThrown = null; + + try { + $generator->getAsymmetricKeyPair(['wrong']); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for too big asymmetric key pair size. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForTooBigAsymmetricKeyPairSize() + { + $generator = $this->getTokenGeneratorForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $generator->getAsymmetricKeyPair(30000); + } else { + $hasThrown = null; + + try { + $generator->getAsymmetricKeyPair(30000); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } + + /** + * Testing validation case for too small asymmetric key pair size. + * + * @throws \Exception Wrong usage errors. + */ + public function testValidationCaseForTooSmallAsymmetricKeyPairSize() + { + $generator = $this->getTokenGeneratorForTesting(); + + // Backward compatible for different versions of PHPUnit + if (method_exists($this, 'expectException')) { + $this->expectException(\InvalidArgumentException::class); + + $generator->getAsymmetricKeyPair(128); + } else { + $hasThrown = null; + + try { + $generator->getAsymmetricKeyPair(128); + } catch (\InvalidArgumentException $exception) { + $hasThrown = !empty($exception->getMessage()); + } catch (\Exception $exception) { + $hasThrown = $exception->getMessage(); + } + + $this->assertTrue($hasThrown); + + return; + } + } +} diff --git a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/AuthenticatedEncryptionTest.php b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/AuthenticatedEncryptionTest.php index 1ae43e9..437f954 100644 --- a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/AuthenticatedEncryptionTest.php +++ b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/AuthenticatedEncryptionTest.php @@ -8,8 +8,8 @@ use CryptoManana\Tests\TestTypes\AbstractUnitTest; use CryptoManana\CryptographicProtocol\AuthenticatedEncryption; -use CryptoManana\DataStructures\AuthenticatedCipherData; use CryptoManana\SymmetricEncryption\Aes128; +use CryptoManana\Hashing\HmacShaTwo256; /** * Class AuthenticatedEncryptionTest - Testing the authenticated symmetric encryption cryptographic protocol object. @@ -26,7 +26,51 @@ final class AuthenticatedEncryptionTest extends AbstractUnitTest */ private function getCryptographicProtocolForTesting() { - return new AuthenticatedEncryption(new Aes128()); + $encryptor = $this->getMockBuilder(Aes128::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); + + $encryptor->expects($this->atLeast(0)) + ->method('getSecretKey') + ->willReturn('secret'); + + $encryptor->expects($this->atLeast(0)) + ->method('getInitializationVector') + ->willReturn('iv'); + + $encryptor->expects($this->atLeast(0)) + ->method('setSecretKey') + ->willReturnSelf(); + + $encryptor->expects($this->atLeast(0)) + ->method('setInitializationVector') + ->willReturnSelf(); + + $hasher = $this->getMockBuilder(HmacShaTwo256::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); + + $hasher->expects($this->atLeast(0)) + ->method('setKey') + ->willReturnSelf(); + + $hasher->expects($this->atLeast(0)) + ->method('setSalt') + ->willReturnSelf(); + + $hasher->expects($this->atLeast(0)) + ->method('getKey') + ->willReturn('key'); + + $hasher->expects($this->atLeast(0)) + ->method('getSalt') + ->willReturn('salt'); + + return new AuthenticatedEncryption($encryptor, $hasher); } /** @@ -38,26 +82,15 @@ public function testCloningCapabilities() { $protocol = $this->getCryptographicProtocolForTesting(); - $tmp = clone $protocol; - - $this->assertEquals($protocol, $tmp); - $this->assertNotEmpty($tmp->authenticatedEncryptData('')); - - unset($tmp); - $this->assertNotNull($protocol); - } + $protocol->getSymmetricCipher() + ->method('encryptData') + ->willReturn('AAAA'); - /** - * Testing the serialization of an instance. - * - * @throws \Exception Wrong usage errors. - */ - public function testSerializationCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); + $protocol->getKeyedDigestionFunction() + ->method('hashData') + ->willReturn('FFFF'); - $tmp = serialize($protocol); - $tmp = unserialize($tmp); + $tmp = clone $protocol; $this->assertEquals($protocol, $tmp); $this->assertNotEmpty($tmp->authenticatedEncryptData('')); @@ -67,165 +100,49 @@ public function testSerializationCapabilities() } /** - * Testing the object dumping for debugging. - * - * @throws \Exception Wrong usage errors. - */ - public function testDebugCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $this->assertNotEmpty(var_export($protocol, true)); - } - - /** - * Testing if the basic data encryption and decryption process works. - * - * @throws \Exception If system does not support the algorithm or the randomness source is not available. - */ - public function testBasicDataEncryptionAndDataDecryption() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $protocol->setSymmetricCipher($protocol->getSymmetricCipher()); - $protocol->setKeyedDigestionFunction($protocol->getKeyedDigestionFunction()); - - $authenticationMode = [ - $protocol::AUTHENTICATION_MODE_ENCRYPT_AND_MAC, - $protocol::AUTHENTICATION_MODE_MAC_THEN_ENCRYPT, - $protocol::AUTHENTICATION_MODE_ENCRYPT_THEN_MAC, - ]; - - $randomData = random_bytes(16); - - foreach ($authenticationMode as $mode) { - $protocol->setAuthenticationMode($mode); - $this->assertEquals($mode, $protocol->getAuthenticationMode()); - - $encryptedData = $protocol->authenticatedEncryptData($randomData); - $decryptedData = $protocol->authenticatedDecryptData($encryptedData); - - $this->assertEquals($randomData, $decryptedData); - } - - $protocol->setKeyedDigestionFunction($protocol->getKeyedDigestionFunction()->setSalt('1234')); - - $protocol = new AuthenticatedEncryption( - $protocol->getSymmetricCipher(), - $protocol->getKeyedDigestionFunction() - ); - - foreach ($authenticationMode as $mode) { - $protocol->setAuthenticationMode($mode); - $this->assertEquals($mode, $protocol->getAuthenticationMode()); - - $encryptedData = $protocol->authenticatedEncryptData($randomData); - $decryptedData = $protocol->authenticatedDecryptData($encryptedData); - - $this->assertEquals($randomData, $decryptedData); - } - } - - /** - * Testing if the unicode data encryption and decryption process works. + * Testing if the basic data encryption and decryption process works for Encrypt and MAC. * * @throws \Exception If system does not support the algorithm or the randomness source is not available. */ - public function testUnicodeDataEncryptionAndDataDecryption() + public function testEncryptAndMac() { $protocol = $this->getCryptographicProtocolForTesting(); - $protocol->setSymmetricCipher($protocol->getSymmetricCipher()); - $protocol->setKeyedDigestionFunction($protocol->getKeyedDigestionFunction()); + $data = 'test'; - $authenticationMode = [ - $protocol::AUTHENTICATION_MODE_ENCRYPT_AND_MAC, - $protocol::AUTHENTICATION_MODE_MAC_THEN_ENCRYPT, - $protocol::AUTHENTICATION_MODE_ENCRYPT_THEN_MAC, - ]; + $protocol->getSymmetricCipher() + ->method('encryptData') + ->willReturn('AAAA'); - $unicodeData = "йЗъ 7-М%\v@UОrЯBZ"; + $protocol->getSymmetricCipher() + ->method('decryptData') + ->willReturn($data); - foreach ($authenticationMode as $mode) { - $protocol->setAuthenticationMode($mode); - $this->assertEquals($mode, $protocol->getAuthenticationMode()); + $protocol->getKeyedDigestionFunction() + ->method('hashData') + ->willReturn('FFFF'); - $encryptedData = $protocol->authenticatedEncryptData($unicodeData); - $decryptedData = $protocol->authenticatedDecryptData($encryptedData); - - $this->assertEquals($unicodeData, $decryptedData); - } - - $protocol->setKeyedDigestionFunction($protocol->getKeyedDigestionFunction()->setSalt('1234')); - - $protocol = new AuthenticatedEncryption( - $protocol->getSymmetricCipher(), - $protocol->getKeyedDigestionFunction() - ); - - foreach ($authenticationMode as $mode) { - $protocol->setAuthenticationMode($mode); - $this->assertEquals($mode, $protocol->getAuthenticationMode()); - - $encryptedData = $protocol->authenticatedEncryptData($unicodeData); - $decryptedData = $protocol->authenticatedDecryptData($encryptedData); - - $this->assertEquals($unicodeData, $decryptedData); - } - } - - /** - * Testing if encrypting twice the same input returns the same result. - * - * @throws \Exception If system does not support the algorithm or the randomness source is not available. - */ - public function testEncryptingTheSameDataTwice() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $randomData = random_bytes(16); + $protocol->setAuthenticationMode($protocol::AUTHENTICATION_MODE_ENCRYPT_AND_MAC); + $this->assertEquals($protocol::AUTHENTICATION_MODE_ENCRYPT_AND_MAC, $protocol->getAuthenticationMode()); - $this->assertEquals( - $protocol->authenticatedEncryptData($randomData), - $protocol->authenticatedEncryptData($randomData) - ); - } + $encryptedData = $protocol->authenticatedEncryptData($data); + $decryptedData = $protocol->authenticatedDecryptData($encryptedData); - /** - * Testing if encrypting twice the same input returns the same result. - * - * @throws \Exception If system does not support the algorithm or the randomness source is not available. - */ - public function testDecryptingTheSameDataTwice() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $randomData = random_bytes(16); - $encryptedData = $protocol->authenticatedEncryptData($randomData); + $this->assertEquals($data, $decryptedData); - $this->assertEquals( - $protocol->authenticatedDecryptData($encryptedData), - $protocol->authenticatedDecryptData($encryptedData) - ); - } + // Test MAC failure + $encryptedData->authenticationTag = 'AAAAAAAAAAAAAA'; - /** - * Testing validation case for invalid type of symmetric service used on initialization. - * - * @throws \Exception Wrong usage errors. - */ - public function testValidationCaseForInvalidTypeOfSymmetricEncryptionServicePassedOnInitialization() - { // Backward compatible for different versions of PHPUnit if (method_exists($this, 'expectException')) { $this->expectException(\RuntimeException::class); - $protocol = new AuthenticatedEncryption(null, null); + $decryptedData = $protocol->authenticatedDecryptData($encryptedData); } else { $hasThrown = null; try { - $protocol = new AuthenticatedEncryption(null, null); + $decryptedData = $protocol->authenticatedDecryptData($encryptedData); } catch (\RuntimeException $exception) { $hasThrown = !empty($exception->getMessage()); } catch (\Exception $exception) { @@ -239,93 +156,50 @@ public function testValidationCaseForInvalidTypeOfSymmetricEncryptionServicePass } /** - * Testing validation case for invalid type of input data for encryption passed. + * Testing if the basic data encryption and decryption process works for Encrypt Then MAC. * - * @throws \Exception Wrong usage errors. - */ - public function testValidationCaseForInvalidTypeOfInputDataForEncryption() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - // Backward compatible for different versions of PHPUnit - if (method_exists($this, 'expectException')) { - $this->expectException(\InvalidArgumentException::class); - - $protocol->authenticatedEncryptData(['wrong']); - } else { - $hasThrown = null; - - try { - $protocol->authenticatedEncryptData(['wrong']); - } catch (\InvalidArgumentException $exception) { - $hasThrown = !empty($exception->getMessage()); - } catch (\Exception $exception) { - $hasThrown = $exception->getMessage(); - } - - $this->assertTrue($hasThrown); - - return; - } - } - - /** - * Testing validation case for invalid type of input data for decryption passed in E&M mode. - * - * @throws \Exception Wrong usage errors. + * @throws \Exception If system does not support the algorithm or the randomness source is not available. */ - public function testValidationCaseForInvalidTypeOfInputDataForDecryptionInEncryptAndMacMode() + public function testEncryptThenMac() { $protocol = $this->getCryptographicProtocolForTesting(); - $protocol->setAuthenticationMode($protocol::AUTHENTICATION_MODE_ENCRYPT_AND_MAC); - $authenticationCipherData = new AuthenticatedCipherData('1234', '1234'); + $data = 'test'; - // Backward compatible for different versions of PHPUnit - if (method_exists($this, 'expectException')) { - $this->expectException(\InvalidArgumentException::class); + $protocol->getSymmetricCipher() + ->method('encryptData') + ->willReturn('AAAA'); - $protocol->authenticatedDecryptData($authenticationCipherData); - } else { - $hasThrown = null; + $protocol->getSymmetricCipher() + ->method('decryptData') + ->willReturn($data); - try { - $protocol->authenticatedDecryptData($authenticationCipherData); - } catch (\InvalidArgumentException $exception) { - $hasThrown = !empty($exception->getMessage()); - } catch (\Exception $exception) { - $hasThrown = $exception->getMessage(); - } + $protocol->getKeyedDigestionFunction() + ->method('hashData') + ->willReturn('FFFF'); - $this->assertTrue($hasThrown); + $protocol->setAuthenticationMode($protocol::AUTHENTICATION_MODE_ENCRYPT_THEN_MAC); + $this->assertEquals($protocol::AUTHENTICATION_MODE_ENCRYPT_THEN_MAC, $protocol->getAuthenticationMode()); - return; - } - } + $encryptedData = $protocol->authenticatedEncryptData($data); + $decryptedData = $protocol->authenticatedDecryptData($encryptedData); - /** - * Testing validation case for invalid type of input data for decryption passed in MtE mode. - * - * @throws \Exception Wrong usage errors. - */ - public function testValidationCaseForInvalidTypeOfInputDataForDecryptionInMacThenEncryptMode() - { - $protocol = $this->getCryptographicProtocolForTesting(); + $this->assertEquals($data, $decryptedData); - $protocol->setAuthenticationMode($protocol::AUTHENTICATION_MODE_MAC_THEN_ENCRYPT); - $authenticationCipherData = new AuthenticatedCipherData('1234', '1234'); + // Test MAC failure + $encryptedData->authenticationTag = 'AAAAAAAAAAAAAA'; // Backward compatible for different versions of PHPUnit if (method_exists($this, 'expectException')) { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(\RuntimeException::class); - $protocol->authenticatedDecryptData($authenticationCipherData); + $decryptedData = $protocol->authenticatedDecryptData($encryptedData); } else { $hasThrown = null; try { - $protocol->authenticatedDecryptData($authenticationCipherData); - } catch (\InvalidArgumentException $exception) { + $decryptedData = $protocol->authenticatedDecryptData($encryptedData); + } catch (\RuntimeException $exception) { $hasThrown = !empty($exception->getMessage()); } catch (\Exception $exception) { $hasThrown = $exception->getMessage(); @@ -338,62 +212,49 @@ public function testValidationCaseForInvalidTypeOfInputDataForDecryptionInMacThe } /** - * Testing validation case for invalid type of input data for decryption passed in EtM mode. + * Testing if the basic data encryption and decryption process works for MAC then Encrypt. * - * @throws \Exception Wrong usage errors. + * @throws \Exception If system does not support the algorithm or the randomness source is not available. */ - public function testValidationCaseForInvalidTypeOfInputDataForDecryptionInEncryptThenMacMode() + public function testMacThenEncrypt() { $protocol = $this->getCryptographicProtocolForTesting(); - $protocol->setAuthenticationMode($protocol::AUTHENTICATION_MODE_ENCRYPT_THEN_MAC); - $authenticationCipherData = new AuthenticatedCipherData('1234', '1234'); + $data = 'test'; - // Backward compatible for different versions of PHPUnit - if (method_exists($this, 'expectException')) { - $this->expectException(\InvalidArgumentException::class); + $protocol->getSymmetricCipher() + ->method('encryptData') + ->willReturn('AAAA'); - $protocol->authenticatedDecryptData($authenticationCipherData); - } else { - $hasThrown = null; + $protocol->getSymmetricCipher() + ->method('decryptData') + ->willReturn($data . '%7C__%7CFFFF'); - try { - $protocol->authenticatedDecryptData($authenticationCipherData); - } catch (\InvalidArgumentException $exception) { - $hasThrown = !empty($exception->getMessage()); - } catch (\Exception $exception) { - $hasThrown = $exception->getMessage(); - } + $protocol->getKeyedDigestionFunction() + ->method('hashData') + ->willReturn('FFFF'); - $this->assertTrue($hasThrown); + $protocol->setAuthenticationMode($protocol::AUTHENTICATION_MODE_MAC_THEN_ENCRYPT); + $this->assertEquals($protocol::AUTHENTICATION_MODE_MAC_THEN_ENCRYPT, $protocol->getAuthenticationMode()); - return; - } - } + $encryptedData = $protocol->authenticatedEncryptData($data); + $decryptedData = $protocol->authenticatedDecryptData($encryptedData); - /** - * Testing validation case for invalid authentication tag for decryption in E&M mode. - * - * @throws \Exception Wrong usage errors. - */ - public function testValidationCaseForInvalidAuthenticationTagForDecryptionInEncryptAndMacMode() - { - $protocol = $this->getCryptographicProtocolForTesting(); + $this->assertEquals($data, $decryptedData); - $protocol->setAuthenticationMode($protocol::AUTHENTICATION_MODE_ENCRYPT_AND_MAC); - $authenticationCipherData = $protocol->authenticatedEncryptData('1234'); - $authenticationCipherData->authenticationTag = 'invalid'; + // Test MAC failure + $encryptedData->authenticationTag = 'AAAAAAAAAAAAAA'; // Backward compatible for different versions of PHPUnit if (method_exists($this, 'expectException')) { $this->expectException(\RuntimeException::class); - $protocol->authenticatedDecryptData($authenticationCipherData); + $decryptedData = $protocol->authenticatedDecryptData($encryptedData); } else { $hasThrown = null; try { - $protocol->authenticatedDecryptData($authenticationCipherData); + $decryptedData = $protocol->authenticatedDecryptData($encryptedData); } catch (\RuntimeException $exception) { $hasThrown = !empty($exception->getMessage()); } catch (\Exception $exception) { @@ -406,29 +267,24 @@ public function testValidationCaseForInvalidAuthenticationTagForDecryptionInEncr } } + /** - * Testing validation case for invalid authentication tag for decryption passed in MtE mode. + * Testing validation case for invalid type of symmetric service used on initialization. * * @throws \Exception Wrong usage errors. */ - public function testValidationCaseForInvalidAuthenticationTagForDecryptionInMacThenEncryptMode() + public function testValidationCaseForInvalidTypeOfSymmetricEncryptionServicePassedOnInitialization() { - $protocol = $this->getCryptographicProtocolForTesting(); - - $protocol->setAuthenticationMode($protocol::AUTHENTICATION_MODE_MAC_THEN_ENCRYPT); - $authenticationCipherData = $protocol->authenticatedEncryptData('1234'); - $authenticationCipherData->authenticationTag = 'invalid'; - // Backward compatible for different versions of PHPUnit if (method_exists($this, 'expectException')) { $this->expectException(\RuntimeException::class); - $protocol->authenticatedDecryptData($authenticationCipherData); + $protocol = new AuthenticatedEncryption(null, null); } else { $hasThrown = null; try { - $protocol->authenticatedDecryptData($authenticationCipherData); + $protocol = new AuthenticatedEncryption(null, null); } catch (\RuntimeException $exception) { $hasThrown = !empty($exception->getMessage()); } catch (\Exception $exception) { @@ -442,29 +298,25 @@ public function testValidationCaseForInvalidAuthenticationTagForDecryptionInMacT } /** - * Testing validation case for invalid authentication tag for decryption passed in EtM mode. + * Testing validation case for invalid type of input data for encryption passed. * * @throws \Exception Wrong usage errors. */ - public function testValidationCaseForInvalidAuthenticationTagForDecryptionInEncryptThenMacMode() + public function testValidationCaseForInvalidTypeOfInputDataForEncryption() { $protocol = $this->getCryptographicProtocolForTesting(); - $protocol->setAuthenticationMode($protocol::AUTHENTICATION_MODE_ENCRYPT_THEN_MAC); - $authenticationCipherData = $protocol->authenticatedEncryptData('1234'); - $authenticationCipherData->authenticationTag = 'invalid'; - // Backward compatible for different versions of PHPUnit if (method_exists($this, 'expectException')) { - $this->expectException(\RuntimeException::class); + $this->expectException(\InvalidArgumentException::class); - $protocol->authenticatedDecryptData($authenticationCipherData); + $protocol->authenticatedEncryptData(['wrong']); } else { $hasThrown = null; try { - $protocol->authenticatedDecryptData($authenticationCipherData); - } catch (\RuntimeException $exception) { + $protocol->authenticatedEncryptData(['wrong']); + } catch (\InvalidArgumentException $exception) { $hasThrown = !empty($exception->getMessage()); } catch (\Exception $exception) { $hasThrown = $exception->getMessage(); @@ -556,6 +408,18 @@ public function testValidationCaseForInvalidInternalAuthenticationModeUsedForDec { $protocol = $this->getCryptographicProtocolForTesting(); + $protocol->getSymmetricCipher() + ->method('encryptData') + ->willReturn('AAAA'); + + $protocol->getSymmetricCipher() + ->method('decryptData') + ->willReturn('test'); + + $protocol->getKeyedDigestionFunction() + ->method('hashData') + ->willReturn('FFFF'); + $authenticationCipherData = $protocol->authenticatedEncryptData(''); $reflectionMbString = new \ReflectionProperty( diff --git a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/DigitalEnvelopeTest.php b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/DigitalEnvelopeTest.php index 98af62d..b497b15 100644 --- a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/DigitalEnvelopeTest.php +++ b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/DigitalEnvelopeTest.php @@ -10,9 +10,9 @@ use CryptoManana\CryptographicProtocol\DigitalEnvelope; use CryptoManana\AsymmetricEncryption\Rsa1024; use CryptoManana\SymmetricEncryption\Aes128; -use CryptoManana\Utilities\TokenGenerator; +use CryptoManana\Hashing\HmacShaThree384; +use CryptoManana\Randomness\CryptoRandom; use CryptoManana\DataStructures\KeyPair; -use CryptoManana\Hashing\HmacShaTwo384; /** * Class DigitalEnvelopeTest - Testing the digital envelope cryptographic protocol object. @@ -21,25 +21,6 @@ */ final class DigitalEnvelopeTest extends AbstractUnitTest { - /** - * The filename for the private key temporary file. - */ - const PRIVATE_KEY_FILENAME_FOR_TESTS = 'rsa_1024_private.key'; - - /** - * The filename for the public key temporary file. - */ - const PUBLIC_KEY_FILENAME_FOR_TESTS = 'rsa_1024_public.key'; - - /** - * Internal flag for checking of there is a key pair ready for testing. - * - * Note: `false` => auto-check on next call, `true` => already generated. - * - * @var null|bool Is the key pair generated. - */ - protected static $isKeyPairGenerated = false; - /** * Creates new instances for testing. * @@ -48,27 +29,74 @@ final class DigitalEnvelopeTest extends AbstractUnitTest */ private function getCryptographicProtocolForTesting() { - $rsa = new Rsa1024(); - - if (self::$isKeyPairGenerated === false) { - $generator = new TokenGenerator(); - - $keyPair = $generator->getAsymmetricKeyPair($rsa::KEY_SIZE, $rsa::ALGORITHM_NAME); - - $this->writeToFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS, $keyPair->private); - $this->writeToFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS, $keyPair->public); - - self::$isKeyPairGenerated = true; - } - - $privateKey = $this->readFromFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS); - $publicKey = $this->readFromFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS); - - $keyPair = new KeyPair($privateKey, $publicKey); - - $rsa->setKeyPair($keyPair); - - return new DigitalEnvelope($rsa, new Aes128()); + $rsa = $this->getMockBuilder(Rsa1024::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); + + $rsa->setKeyPair(new KeyPair(base64_encode('1234'), base64_encode('1234'))); + + $rsa->expects($this->atLeast(0)) + ->method('setKeyPair') + ->willReturnSelf(); + + $rsa->expects($this->atLeast(0)) + ->method('encryptData') + ->willReturn('AAAA'); + + $aes = $this->getMockBuilder(Aes128::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); + + $aes->expects($this->atLeast(0)) + ->method('getSecretKey') + ->willReturn('secret'); + + $aes->expects($this->atLeast(0)) + ->method('getInitializationVector') + ->willReturn('iv'); + + $aes->expects($this->atLeast(0)) + ->method('setSecretKey') + ->willReturnSelf(); + + $aes->expects($this->atLeast(0)) + ->method('setInitializationVector') + ->willReturnSelf(); + + $aes->expects($this->atLeast(0)) + ->method('encryptData') + ->willReturn('FFFF'); + + $hasher = $this->getMockBuilder(HmacShaThree384::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); + + $hasher->expects($this->atLeast(0)) + ->method('hashData') + ->willReturn('CCCC'); + + $randomness = $this->getMockBuilder(CryptoRandom::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); + + $randomness->expects($this->atLeast(0)) + ->method('getBytes') + ->willReturn("\0"); + + $protocol = new DigitalEnvelope($rsa, $aes); + + $protocol->setKeyedDigestionFunction($hasher) + ->setRandomGenerator($randomness); + + return $protocol; } /** @@ -88,7 +116,6 @@ public function testCloningCapabilities() unset($tmp); $this->assertNotNull($protocol); - $protocol->setKeyedDigestionFunction(new HmacShaTwo384()); $tmp = clone $protocol; $this->assertEquals($protocol, $tmp); @@ -98,37 +125,6 @@ public function testCloningCapabilities() $this->assertNotNull($protocol); } - /** - * Testing the serialization of an instance. - * - * @throws \Exception Wrong usage errors. - */ - public function testSerializationCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $tmp = serialize($protocol); - $tmp = unserialize($tmp); - - $this->assertEquals($protocol, $tmp); - $this->assertNotEmpty($tmp->sealEnvelope('')); - - unset($tmp); - $this->assertNotNull($protocol); - } - - /** - * Testing the object dumping for debugging. - * - * @throws \Exception Wrong usage errors. - */ - public function testDebugCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $this->assertNotEmpty(var_export($protocol, true)); - } - /** * Testing if the digital sealing and opening process works. * @@ -142,24 +138,24 @@ public function testDigitalEnvelopeSealingAndOpening() $protocol->setSymmetricCipher($protocol->getSymmetricCipher()); $protocol->setAsymmetricCipher($protocol->getAsymmetricCipher()); - $randomData = random_bytes(16); - - $envelopeObject = $protocol->sealEnvelope($randomData); - $receivedData = $protocol->openEnvelope($envelopeObject); + $data = 'test'; - $this->assertEquals($randomData, $receivedData); - $this->assertEmpty($envelopeObject->authenticationTag); + $protocol->getSymmetricCipher() + ->method('decryptData') + ->willReturn($data); - $hasher = new HmacShaTwo384(); + $protocol->getSymmetricCipher() + ->method('decryptData') + ->willReturn($data); - $protocol->setKeyedDigestionFunction($hasher); - $this->assertEquals($hasher, $protocol->getKeyedDigestionFunction()); + $protocol->getKeyedDigestionFunction() + ->method('verifyHash') + ->willReturn(true); - $envelopeObject = $protocol->sealEnvelope($randomData); + $envelopeObject = $protocol->sealEnvelope($data); $receivedData = $protocol->openEnvelope($envelopeObject); - $this->assertEquals($randomData, $receivedData); - $this->assertNotEmpty($envelopeObject->authenticationTag); + $this->assertEquals($data, $receivedData); } /** @@ -222,37 +218,6 @@ public function testValidationCaseForInvalidTypeOfSymmetricEncryptionServicePass } } - /** - * Testing validation case for invalid type of input data for sealing. - * - * @throws \Exception Wrong usage errors. - */ - public function testValidationCaseForInvalidTypeOfInputDataForEnvelopeSealing() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - // Backward compatible for different versions of PHPUnit - if (method_exists($this, 'expectException')) { - $this->expectException(\InvalidArgumentException::class); - - $protocol->sealEnvelope(['wrong']); - } else { - $hasThrown = null; - - try { - $protocol->sealEnvelope(['wrong']); - } catch (\InvalidArgumentException $exception) { - $hasThrown = !empty($exception->getMessage()); - } catch (\Exception $exception) { - $hasThrown = $exception->getMessage(); - } - - $this->assertTrue($hasThrown); - - return; - } - } - /** * Testing validation case for invalid authentication tag on opening of envelope. * @@ -261,7 +226,6 @@ public function testValidationCaseForInvalidTypeOfInputDataForEnvelopeSealing() public function testValidationCaseForInvalidAuthenticationTagOnEnvelopeOpening() { $protocol = $this->getCryptographicProtocolForTesting(); - $protocol->setKeyedDigestionFunction(new HmacShaTwo384()); $envelopeObject = $protocol->sealEnvelope('1234'); $envelopeObject->authenticationTag = 'FFFF'; @@ -287,19 +251,4 @@ public function testValidationCaseForInvalidAuthenticationTagOnEnvelopeOpening() return; } } - - /** - * Testing the resource cleanup operation. - * - * @throws \Exception Wrong usage errors. - */ - public function testKeyPairResourceCleanupOperation() - { - $this->assertTrue(self::$isKeyPairGenerated); - - $this->deleteTheFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS); - $this->deleteTheFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS); - - self::$isKeyPairGenerated = null; - } } diff --git a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/DigitalSignatureTest.php b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/DigitalSignatureTest.php index 7efb432..a058d28 100644 --- a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/DigitalSignatureTest.php +++ b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/DigitalSignatureTest.php @@ -9,7 +9,6 @@ use CryptoManana\Tests\TestTypes\AbstractUnitTest; use CryptoManana\CryptographicProtocol\DigitalSignature; use CryptoManana\AsymmetricEncryption\Dsa1024; -use CryptoManana\Utilities\TokenGenerator; use CryptoManana\DataStructures\KeyPair; /** @@ -19,25 +18,6 @@ */ final class DigitalSignatureTest extends AbstractUnitTest { - /** - * The filename for the private key temporary file. - */ - const PRIVATE_KEY_FILENAME_FOR_TESTS = 'dsa_1024_private.key'; - - /** - * The filename for the public key temporary file. - */ - const PUBLIC_KEY_FILENAME_FOR_TESTS = 'dsa_1024_public.key'; - - /** - * Internal flag for checking of there is a key pair ready for testing. - * - * Note: `false` => auto-check on next call, `true` => already generated. - * - * @var null|bool Is the key pair generated. - */ - protected static $isKeyPairGenerated = false; - /** * Creates new instances for testing. * @@ -46,25 +26,21 @@ final class DigitalSignatureTest extends AbstractUnitTest */ private function getCryptographicProtocolForTesting() { - $dsa = new Dsa1024(); - - if (self::$isKeyPairGenerated === false) { - $generator = new TokenGenerator(); - - $keyPair = $generator->getAsymmetricKeyPair($dsa::KEY_SIZE, $dsa::ALGORITHM_NAME); + $dsa = $this->getMockBuilder(Dsa1024::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); - $this->writeToFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS, $keyPair->private); - $this->writeToFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS, $keyPair->public); + $dsa->setKeyPair(new KeyPair(base64_encode('1234'), base64_encode('1234'))); - self::$isKeyPairGenerated = true; - } - - $privateKey = $this->readFromFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS); - $publicKey = $this->readFromFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS); + $dsa->expects($this->atLeast(0)) + ->method('setKeyPair') + ->willReturnSelf(); - $keyPair = new KeyPair($privateKey, $publicKey); - - $dsa->setKeyPair($keyPair); + $dsa->expects($this->atLeast(0)) + ->method('signData') + ->willReturn('FFFF'); return new DigitalSignature($dsa); } @@ -87,37 +63,6 @@ public function testCloningCapabilities() $this->assertNotNull($protocol); } - /** - * Testing the serialization of an instance. - * - * @throws \Exception Wrong usage errors. - */ - public function testSerializationCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $tmp = serialize($protocol); - $tmp = unserialize($tmp); - - $this->assertEquals($protocol, $tmp); - $this->assertNotEmpty($tmp->createSignedData('')); - - unset($tmp); - $this->assertNotNull($protocol); - } - - /** - * Testing the object dumping for debugging. - * - * @throws \Exception Wrong usage errors. - */ - public function testDebugCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $this->assertNotEmpty(var_export($protocol, true)); - } - /** * Testing if the basic data signature generation and verification process works. * @@ -131,6 +76,10 @@ public function testDataSignatureGenerationAndVerification() $randomData = random_bytes(16); + $protocol->getSignatureStandard() + ->method('verifyDataSignature') + ->willReturn(true); + $signedDataObject = $protocol->createSignedData($randomData); $extractedVerifiedData = $protocol->extractVerifiedData($signedDataObject); @@ -208,6 +157,10 @@ public function testValidationCaseForInvalidSignedDataForVerification() $signedData = $protocol->createSignedData('1234'); $signedData->signature = 'FFFF'; + $protocol->getSignatureStandard() + ->method('verifyDataSignature') + ->willReturn(false); + // Backward compatible for different versions of PHPUnit if (method_exists($this, 'expectException')) { $this->expectException(\RuntimeException::class); @@ -229,19 +182,4 @@ public function testValidationCaseForInvalidSignedDataForVerification() return; } } - - /** - * Testing the resource cleanup operation. - * - * @throws \Exception Wrong usage errors. - */ - public function testKeyPairResourceCleanupOperation() - { - $this->assertTrue(self::$isKeyPairGenerated); - - $this->deleteTheFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS); - $this->deleteTheFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS); - - self::$isKeyPairGenerated = null; - } } diff --git a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/KeyExchangeTest.php b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/KeyExchangeTest.php index 03cf6ba..ab2542a 100644 --- a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/KeyExchangeTest.php +++ b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/KeyExchangeTest.php @@ -25,7 +25,17 @@ final class KeyExchangeTest extends AbstractUnitTest */ private function getCryptographicProtocolForTesting() { - $exchange = new KeyExchange(new HkdfShaTwo384()); + $hasher = $this->getMockBuilder(HkdfShaTwo384::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); + + $hasher->expects($this->atLeast(0)) + ->method('hashData') + ->willReturn('CCCC'); + + $exchange = new KeyExchange($hasher); $exchange->setKeyExchangeSize(512); return $exchange; @@ -49,37 +59,6 @@ public function testCloningCapabilities() $this->assertNotNull($protocol); } - /** - * Testing the serialization of an instance. - * - * @throws \Exception Wrong usage errors. - */ - public function testSerializationCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $tmp = serialize($protocol); - $tmp = unserialize($tmp); - - $this->assertEquals($protocol, $tmp); - $this->assertNotEmpty($tmp->generateExchangeRequestInformation()); - - unset($tmp); - $this->assertNotNull($protocol); - } - - /** - * Testing the object dumping for debugging. - * - * @throws \Exception Wrong usage errors. - */ - public function testDebugCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $this->assertNotEmpty(var_export($protocol, true)); - } - /** * Testing if the key exchange process works. * diff --git a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/LayeredEncryptionTest.php b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/LayeredEncryptionTest.php index df8bbac..a3d35b1 100644 --- a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/LayeredEncryptionTest.php +++ b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/LayeredEncryptionTest.php @@ -18,226 +18,6 @@ */ final class LayeredEncryptionTest extends AbstractUnitTest { - /** - * Creates new instances for testing. - * - * @return LayeredEncryption Testing instance. - * @throws \Exception Wrong usage errors. - */ - private function getCryptographicProtocolForTesting() - { - $layers = [ - new EncryptionLayer( - Aes128::class, - 'cryptomanana', - 'framework', - Aes128::CBC_MODE, - Aes128::PKCS7_PADDING, - Aes128::ENCRYPTION_OUTPUT_RAW - ), - new EncryptionLayer( - Aes128::class, - 'hit hard', - 'and run', - Aes128::CFB_MODE - ) - ]; - - return new LayeredEncryption($layers); - } - - /** - * Testing the cloning of an instance. - * - * @throws \Exception Wrong usage errors. - */ - public function testCloningCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $tmp = clone $protocol; - - $this->assertEquals($protocol, $tmp); - $this->assertNotEmpty($tmp->layeredEncryptData('')); - - unset($tmp); - $this->assertNotNull($protocol); - } - - /** - * Testing the serialization of an instance. - * - * @throws \Exception Wrong usage errors. - */ - public function testSerializationCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $tmp = serialize($protocol); - $tmp = unserialize($tmp); - - $this->assertEquals($protocol, $tmp); - $this->assertNotEmpty($tmp->layeredEncryptData('')); - - unset($tmp); - $this->assertNotNull($protocol); - } - - /** - * Testing the object dumping for debugging. - * - * @throws \Exception Wrong usage errors. - */ - public function testDebugCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $this->assertNotEmpty(var_export($protocol, true)); - } - - /** - * Testing if the basic data encryption and decryption process works. - * - * @throws \Exception If system does not support the algorithm or the randomness source is not available. - */ - public function testBasicDataEncryptionAndDataDecryption() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $protocol->setLayers($protocol->getLayers()); - - $randomData = random_bytes(16); - - $encryptedData = $protocol->layeredEncryptData($randomData); - $decryptedData = $protocol->layeredDecryptData($encryptedData); - - $this->assertEquals($randomData, $decryptedData); - $this->assertNotEquals($encryptedData, $protocol->layeredEncryptData($randomData, '1')); - $this->assertNotEquals($encryptedData, $protocol->layeredEncryptData($randomData, 'xx')); - $this->assertNotEquals($randomData, $protocol->layeredDecryptData($encryptedData, 'fake')); - - $layers = $protocol->getLayers(); - $layers [] = new EncryptionLayer( - Aes128::class, - 'manana', - 'power', - Aes128::OFB_MODE, - Aes128::ZERO_PADDING, - Aes128::ENCRYPTION_OUTPUT_HEX_LOWER - ); - - $protocol = new LayeredEncryption($layers); - - $encryptedData = $protocol->layeredEncryptData($randomData, 'pad me hard again'); - $decryptedData = $protocol->layeredDecryptData($encryptedData, 'pad me hard again'); - - $this->assertEquals($randomData, $decryptedData); - $this->assertNotEquals($encryptedData, $protocol->layeredEncryptData($randomData, '22')); - $this->assertNotEquals($encryptedData, $protocol->layeredEncryptData($randomData, 'я')); - $this->assertNotEquals($randomData, $protocol->layeredDecryptData($encryptedData, 'fake')); - $this->assertNotEquals($randomData, $protocol->layeredDecryptData($encryptedData)); - } - - /** - * Testing if the unicode data encryption and decryption process works. - * - * @throws \Exception If system does not support the algorithm or the randomness source is not available. - */ - public function testUnicodeDataEncryptionAndDataDecryption() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $protocol->setLayers($protocol->getLayers()); - - $unicodeData = "йМx 3-Й$\v@UdrЯ9Ю"; - - $encryptedData = $protocol->layeredEncryptData($unicodeData); - $decryptedData = $protocol->layeredDecryptData($encryptedData); - - $this->assertEquals($unicodeData, $decryptedData); - $this->assertNotEquals($encryptedData, $protocol->layeredEncryptData($encryptedData, '1')); - $this->assertNotEquals($encryptedData, $protocol->layeredEncryptData($encryptedData, 'xx')); - $this->assertNotEquals($unicodeData, $protocol->layeredDecryptData($encryptedData, 'nonce')); - - $layers = $protocol->getLayers(); - $layers [] = new EncryptionLayer( - Aes128::class, - 'manana', - 'power', - Aes128::OFB_MODE, - Aes128::ZERO_PADDING, - Aes128::ENCRYPTION_OUTPUT_HEX_LOWER - ); - - $protocol->setLayers($layers); - - $key = random_bytes(strlen($unicodeData) + 2); - $encryptedData = $protocol->layeredEncryptData($unicodeData, $key); - $decryptedData = $protocol->layeredDecryptData($encryptedData, $key); - - $this->assertEquals($unicodeData, $decryptedData); - $this->assertNotEquals($encryptedData, $protocol->layeredEncryptData($encryptedData, '22')); - $this->assertNotEquals($encryptedData, $protocol->layeredEncryptData($encryptedData, 'я')); - $this->assertNotEquals($unicodeData, $protocol->layeredDecryptData($encryptedData)); - } - - /** - * Testing if encrypting twice the same input returns the same result. - * - * @throws \Exception If system does not support the algorithm or the randomness source is not available. - */ - public function testEncryptingTheSameDataTwice() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $randomData = random_bytes(16); - - $this->assertEquals( - $protocol->layeredEncryptData($randomData), - $protocol->layeredEncryptData($randomData) - ); - - $this->assertEquals( - $protocol->layeredEncryptData($randomData, 'yes'), - $protocol->layeredEncryptData($randomData, 'yes') - ); - - $this->assertNotEquals( - $protocol->layeredEncryptData($randomData, 'yes'), - $protocol->layeredEncryptData($randomData, 'sir') - ); - } - - /** - * Testing if encrypting twice the same input returns the same result. - * - * @throws \Exception If system does not support the algorithm or the randomness source is not available. - */ - public function testDecryptingTheSameDataTwice() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $randomData = random_bytes(16); - $encryptedData = $protocol->layeredEncryptData($randomData); - - $this->assertEquals( - $protocol->layeredDecryptData($encryptedData), - $protocol->layeredDecryptData($encryptedData) - ); - - $encryptedData = $protocol->layeredEncryptData($randomData, 'secret'); - - $this->assertEquals( - $protocol->layeredDecryptData($encryptedData, 'secret'), - $protocol->layeredDecryptData($encryptedData, 'secret') - ); - - $this->assertNotEquals( - $protocol->layeredDecryptData($encryptedData, 'secret'), - $protocol->layeredDecryptData($encryptedData, 'power') - ); - } - /** * Testing validation case for invalid type of layer configuration used on initialization. * @@ -304,7 +84,6 @@ public function testValidationCaseForInvalidNumberOfLayersOnInitialization() public function testValidationCaseForOneInvalidLayerOnInitialization() { $layers = [ - new EncryptionLayer(Aes128::class, 'test', 'me', Aes128::ECB_MODE), new EncryptionLayer('\HittingItHarder', 'test', 'me', Aes128::ECB_MODE), ]; @@ -329,130 +108,4 @@ public function testValidationCaseForOneInvalidLayerOnInitialization() return; } } - - /** - * Testing validation case for invalid type of input data for encryption passed. - * - * @throws \Exception Wrong usage errors. - */ - public function testValidationCaseForInvalidTypeOfInputDataForEncryption() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - // Backward compatible for different versions of PHPUnit - if (method_exists($this, 'expectException')) { - $this->expectException(\InvalidArgumentException::class); - - $protocol->layeredEncryptData(['wrong']); - } else { - $hasThrown = null; - - try { - $protocol->layeredEncryptData(['wrong']); - } catch (\InvalidArgumentException $exception) { - $hasThrown = !empty($exception->getMessage()); - } catch (\Exception $exception) { - $hasThrown = $exception->getMessage(); - } - - $this->assertTrue($hasThrown); - - return; - } - } - - /** - * Testing validation case for invalid type or value of the one-time padding string used for encryption. - * - * @throws \Exception Wrong usage errors. - */ - public function testValidationCaseForInvalidOneTimePaddingStringForEncryption() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - // Backward compatible for different versions of PHPUnit - if (method_exists($this, 'expectException')) { - $this->expectException(\InvalidArgumentException::class); - - $protocol->layeredEncryptData('', [-1000]); - } else { - $hasThrown = null; - - try { - $protocol->layeredEncryptData('', [-1000]); - } catch (\InvalidArgumentException $exception) { - $hasThrown = !empty($exception->getMessage()); - } catch (\Exception $exception) { - $hasThrown = $exception->getMessage(); - } - - $this->assertTrue($hasThrown); - - return; - } - } - - /** - * Testing validation case for invalid type of input data for decryption passed. - * - * @throws \Exception Wrong usage errors. - */ - public function testValidationCaseForInvalidTypeOfInputDataForDecryption() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - // Backward compatible for different versions of PHPUnit - if (method_exists($this, 'expectException')) { - $this->expectException(\InvalidArgumentException::class); - - $protocol->layeredDecryptData(['wrong']); - } else { - $hasThrown = null; - - try { - $protocol->layeredDecryptData(['wrong']); - } catch (\InvalidArgumentException $exception) { - $hasThrown = !empty($exception->getMessage()); - } catch (\Exception $exception) { - $hasThrown = $exception->getMessage(); - } - - $this->assertTrue($hasThrown); - - return; - } - } - - /** - * Testing validation case for invalid type or value of the iteration count used for decryption. - * - * @throws \Exception Wrong usage errors. - */ - public function testValidationCaseForInvalidIterationCountForDecryption() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $encryptedData = $protocol->layeredEncryptData(''); - - // Backward compatible for different versions of PHPUnit - if (method_exists($this, 'expectException')) { - $this->expectException(\InvalidArgumentException::class); - - $protocol->layeredDecryptData($encryptedData, -1000); - } else { - $hasThrown = null; - - try { - $protocol->layeredDecryptData($encryptedData, -1000); - } catch (\InvalidArgumentException $exception) { - $hasThrown = !empty($exception->getMessage()); - } catch (\Exception $exception) { - $hasThrown = $exception->getMessage(); - } - - $this->assertTrue($hasThrown); - - return; - } - } } diff --git a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/MultipleEncryptionTest.php b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/MultipleEncryptionTest.php index a2eae34..5714272 100644 --- a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/MultipleEncryptionTest.php +++ b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/MultipleEncryptionTest.php @@ -9,6 +9,7 @@ use CryptoManana\Tests\TestTypes\AbstractUnitTest; use CryptoManana\CryptographicProtocol\MultipleEncryption; use CryptoManana\SymmetricEncryption\Aes128; +use CryptoManana\Hashing\HkdfShaTwo384; /** * Class MultipleEncryptionTest - Testing the multiple symmetric encryption cryptographic protocol object. @@ -25,7 +26,43 @@ final class MultipleEncryptionTest extends AbstractUnitTest */ private function getCryptographicProtocolForTesting() { - return new MultipleEncryption(new Aes128()); + $aes = $this->getMockBuilder(Aes128::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); + + $aes->expects($this->atLeast(0)) + ->method('getSecretKey') + ->willReturn('secret'); + + $aes->expects($this->atLeast(0)) + ->method('getInitializationVector') + ->willReturn('iv'); + + $aes->expects($this->atLeast(0)) + ->method('setSecretKey') + ->willReturnSelf(); + + $aes->expects($this->atLeast(0)) + ->method('setInitializationVector') + ->willReturnSelf(); + + $aes->expects($this->atLeast(0)) + ->method('encryptData') + ->willReturn('FFFF'); + + $hasher = $this->getMockBuilder(HkdfShaTwo384::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); + + $hasher->expects($this->atLeast(0)) + ->method('hashData') + ->willReturn('CCCC'); + + return new MultipleEncryption($aes, $hasher); } /** @@ -46,37 +83,6 @@ public function testCloningCapabilities() $this->assertNotNull($protocol); } - /** - * Testing the serialization of an instance. - * - * @throws \Exception Wrong usage errors. - */ - public function testSerializationCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $tmp = serialize($protocol); - $tmp = unserialize($tmp); - - $this->assertEquals($protocol, $tmp); - $this->assertNotEmpty($tmp->multipleEncryptData('')); - - unset($tmp); - $this->assertNotNull($protocol); - } - - /** - * Testing the object dumping for debugging. - * - * @throws \Exception Wrong usage errors. - */ - public function testDebugCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $this->assertNotEmpty(var_export($protocol, true)); - } - /** * Testing if the basic data encryption and decryption process works. * @@ -89,91 +95,16 @@ public function testBasicDataEncryptionAndDataDecryption() $protocol->setSymmetricCipher($protocol->getSymmetricCipher()); $protocol->setKeyExpansionFunction($protocol->getKeyExpansionFunction()); - $randomData = random_bytes(16); - - $encryptedData = $protocol->multipleEncryptData($randomData, 5); - $decryptedData = $protocol->multipleDecryptData($encryptedData, 5); - - $this->assertEquals($randomData, $decryptedData); - $this->assertNotEquals($encryptedData, $protocol->multipleEncryptData($randomData, 4)); - $this->assertNotEquals($encryptedData, $protocol->multipleEncryptData($randomData, 6)); - - $protocol->setKeyExpansionFunction($protocol->getKeyExpansionFunction()->setSalt('1234')); - $protocol = new MultipleEncryption($protocol->getSymmetricCipher(), $protocol->getKeyExpansionFunction()); - - $encryptedData = $protocol->multipleEncryptData($randomData, 5); - $decryptedData = $protocol->multipleDecryptData($encryptedData, 5); - - $this->assertEquals($randomData, $decryptedData); - $this->assertNotEquals($encryptedData, $protocol->multipleEncryptData($randomData, 4)); - $this->assertNotEquals($encryptedData, $protocol->multipleEncryptData($randomData, 6)); - } - - /** - * Testing if the unicode data encryption and decryption process works. - * - * @throws \Exception If system does not support the algorithm or the randomness source is not available. - */ - public function testUnicodeDataEncryptionAndDataDecryption() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $protocol->setSymmetricCipher($protocol->getSymmetricCipher()); - $protocol->setKeyExpansionFunction($protocol->getKeyExpansionFunction()); - - $unicodeData = "йМx 3-Й$\v@UdrЯ9Ю"; - - $encryptedData = $protocol->multipleEncryptData($unicodeData, 5); - $decryptedData = $protocol->multipleDecryptData($encryptedData, 5); - - $this->assertEquals($unicodeData, $decryptedData); - $this->assertNotEquals($encryptedData, $protocol->multipleEncryptData($unicodeData, 4)); - $this->assertNotEquals($encryptedData, $protocol->multipleEncryptData($unicodeData, 6)); + $data = 'test'; - $protocol->setKeyExpansionFunction($protocol->getKeyExpansionFunction()->setSalt('1234')); - $protocol = new MultipleEncryption($protocol->getSymmetricCipher(), $protocol->getKeyExpansionFunction()); + $protocol->getSymmetricCipher() + ->method('decryptData') + ->willReturn($data); - $encryptedData = $protocol->multipleEncryptData($unicodeData, 5); + $encryptedData = $protocol->multipleEncryptData($data, 5); $decryptedData = $protocol->multipleDecryptData($encryptedData, 5); - $this->assertEquals($unicodeData, $decryptedData); - $this->assertNotEquals($encryptedData, $protocol->multipleEncryptData($unicodeData, 4)); - $this->assertNotEquals($encryptedData, $protocol->multipleEncryptData($unicodeData, 6)); - } - - /** - * Testing if encrypting twice the same input returns the same result. - * - * @throws \Exception If system does not support the algorithm or the randomness source is not available. - */ - public function testEncryptingTheSameDataTwice() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $randomData = random_bytes(16); - - $this->assertEquals( - $protocol->multipleEncryptData($randomData), - $protocol->multipleEncryptData($randomData) - ); - } - - /** - * Testing if encrypting twice the same input returns the same result. - * - * @throws \Exception If system does not support the algorithm or the randomness source is not available. - */ - public function testDecryptingTheSameDataTwice() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $randomData = random_bytes(16); - $encryptedData = $protocol->multipleEncryptData($randomData); - - $this->assertEquals( - $protocol->multipleDecryptData($encryptedData), - $protocol->multipleDecryptData($encryptedData) - ); + $this->assertEquals($data, $decryptedData); } /** @@ -205,37 +136,6 @@ public function testValidationCaseForInvalidTypeOfSymmetricEncryptionServicePass } } - /** - * Testing validation case for invalid type of input data for encryption passed. - * - * @throws \Exception Wrong usage errors. - */ - public function testValidationCaseForInvalidTypeOfInputDataForEncryption() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - // Backward compatible for different versions of PHPUnit - if (method_exists($this, 'expectException')) { - $this->expectException(\InvalidArgumentException::class); - - $protocol->multipleEncryptData(['wrong'], 2); - } else { - $hasThrown = null; - - try { - $protocol->multipleEncryptData(['wrong'], 2); - } catch (\InvalidArgumentException $exception) { - $hasThrown = !empty($exception->getMessage()); - } catch (\Exception $exception) { - $hasThrown = $exception->getMessage(); - } - - $this->assertTrue($hasThrown); - - return; - } - } - /** * Testing validation case for invalid type or value of the iteration count used for encryption. * @@ -267,37 +167,6 @@ public function testValidationCaseForInvalidIterationCountForEncryption() } } - /** - * Testing validation case for invalid type of input data for decryption passed. - * - * @throws \Exception Wrong usage errors. - */ - public function testValidationCaseForInvalidTypeOfInputDataForDecryption() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - // Backward compatible for different versions of PHPUnit - if (method_exists($this, 'expectException')) { - $this->expectException(\InvalidArgumentException::class); - - $protocol->multipleDecryptData(['wrong'], 2); - } else { - $hasThrown = null; - - try { - $protocol->multipleDecryptData(['wrong'], 2); - } catch (\InvalidArgumentException $exception) { - $hasThrown = !empty($exception->getMessage()); - } catch (\Exception $exception) { - $hasThrown = $exception->getMessage(); - } - - $this->assertTrue($hasThrown); - - return; - } - } - /** * Testing validation case for invalid type or value of the iteration count used for decryption. * diff --git a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/PasswordBasedAuthenticationTest.php b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/PasswordBasedAuthenticationTest.php index c68089c..68ff720 100644 --- a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/PasswordBasedAuthenticationTest.php +++ b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/PasswordBasedAuthenticationTest.php @@ -45,27 +45,17 @@ public function testCloningCapabilities() unset($tmp); $this->assertNotNull($protocol); - $protocol->setVerificationAlgorithm(new Bcrypt()); - $tmp = clone $protocol; - - $this->assertEquals($protocol, $tmp); - $this->assertNotEmpty($tmp->identifyEntity('', '')); + $hasher = $this->getMockBuilder(Bcrypt::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); - unset($tmp); - $this->assertNotNull($protocol); - } + $protocol->setVerificationAlgorithm($hasher); - /** - * Testing the serialization of an instance. - * - * @throws \Exception Wrong usage errors. - */ - public function testSerializationCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); + $this->assertEquals($hasher, $protocol->getVerificationAlgorithm()); - $tmp = serialize($protocol); - $tmp = unserialize($tmp); + $tmp = clone $protocol; $this->assertEquals($protocol, $tmp); $this->assertNotEmpty($tmp->identifyEntity('', '')); @@ -74,18 +64,6 @@ public function testSerializationCapabilities() $this->assertNotNull($protocol); } - /** - * Testing the object dumping for debugging. - * - * @throws \Exception Wrong usage errors. - */ - public function testDebugCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $this->assertNotEmpty(var_export($protocol, true)); - } - /** * Testing the object identification capabilities. * @@ -115,15 +93,18 @@ public function testClientEntityAuthenticationCapabilities() $this->assertTrue($protocol->authenticateEntity($entityPassword, $entityPassword)); $this->assertFalse($protocol->authenticateEntity($entityPassword, strrev($entityPassword))); - $hasher = new Bcrypt(); - $hasher->setAlgorithmicCost($hasher::MINIMUM_ALGORITHMIC_COST)->setSaltingMode($hasher::SALTING_MODE_NONE); + $hasher = $this->getMockBuilder(Bcrypt::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); - $passwordDigest = $hasher->hashData($entityPassword); - $protocol->setVerificationAlgorithm($hasher); - $this->assertEquals($hasher, $protocol->getVerificationAlgorithm()); + $hasher->expects($this->atLeast(0)) + ->method('verifyHash') + ->willReturn(true); - $this->assertTrue($protocol->authenticateEntity($passwordDigest, $entityPassword)); - $this->assertFalse($protocol->authenticateEntity($passwordDigest, strrev($entityPassword))); + $protocol->setVerificationAlgorithm($hasher); + $this->assertTrue($protocol->authenticateEntity($entityPassword, $entityPassword)); } /** diff --git a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/PublicKeyAuthenticationTest.php b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/PublicKeyAuthenticationTest.php index c7affc6..7dbd194 100644 --- a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/PublicKeyAuthenticationTest.php +++ b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/PublicKeyAuthenticationTest.php @@ -12,7 +12,7 @@ use CryptoManana\Core\Interfaces\MessageEncryption\DataEncryptionInterface; use CryptoManana\CryptographicProtocol\PublicKeyAuthentication; use CryptoManana\AsymmetricEncryption\Rsa1024; -use CryptoManana\Utilities\TokenGenerator; +use CryptoManana\Randomness\QuasiRandom; use CryptoManana\DataStructures\KeyPair; /** @@ -22,25 +22,6 @@ */ final class PublicKeyAuthenticationTest extends AbstractUnitTest { - /** - * The filename for the private key temporary file. - */ - const PRIVATE_KEY_FILENAME_FOR_TESTS = 'rsa_1024_private.key'; - - /** - * The filename for the public key temporary file. - */ - const PUBLIC_KEY_FILENAME_FOR_TESTS = 'rsa_1024_public.key'; - - /** - * Internal flag for checking of there is a key pair ready for testing. - * - * Note: `false` => auto-check on next call, `true` => already generated. - * - * @var null|bool Is the key pair generated. - */ - protected static $isKeyPairGenerated = false; - /** * Creates new instances for testing. * @@ -49,27 +30,41 @@ final class PublicKeyAuthenticationTest extends AbstractUnitTest */ private function getCryptographicProtocolForTesting() { - $rsa = new Rsa1024(); + $rsa = $this->getMockBuilder(Rsa1024::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); - if (self::$isKeyPairGenerated === false) { - $generator = new TokenGenerator(); + $rsa->setKeyPair(new KeyPair(base64_encode('1234'), base64_encode('1234'))); - $keyPair = $generator->getAsymmetricKeyPair($rsa::KEY_SIZE, $rsa::ALGORITHM_NAME); + $rsa->expects($this->atLeast(0)) + ->method('setKeyPair') + ->willReturnSelf(); - $this->writeToFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS, $keyPair->private); - $this->writeToFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS, $keyPair->public); + $rsa->expects($this->atLeast(0)) + ->method('encryptData') + ->willReturn('FFFF'); - self::$isKeyPairGenerated = true; - } + $randomness = $this->getMockBuilder(QuasiRandom::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); + + $randomness->expects($this->atLeast(0)) + ->method('getBytes') + ->willReturn("\0"); - $privateKey = $this->readFromFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS); - $publicKey = $this->readFromFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS); + $randomness->expects($this->atLeast(0)) + ->method('getAlphaNumeric') + ->willReturn('A1'); - $keyPair = new KeyPair($privateKey, $publicKey); + $protocol = new PublicKeyAuthentication($rsa); - $rsa->setKeyPair($keyPair); + $protocol->setRandomGenerator($randomness); - return new PublicKeyAuthentication($rsa); + return $protocol; } /** @@ -90,37 +85,6 @@ public function testCloningCapabilities() $this->assertNotNull($protocol); } - /** - * Testing the serialization of an instance. - * - * @throws \Exception Wrong usage errors. - */ - public function testSerializationCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $tmp = serialize($protocol); - $tmp = unserialize($tmp); - - $this->assertEquals($protocol, $tmp); - $this->assertNotEmpty($tmp->identifyEntity('', '')); - - unset($tmp); - $this->assertNotNull($protocol); - } - - /** - * Testing the object dumping for debugging. - * - * @throws \Exception Wrong usage errors. - */ - public function testDebugCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $this->assertNotEmpty(var_export($protocol, true)); - } - /** * Testing the object identification capabilities. * @@ -153,6 +117,11 @@ public function testClientEntityAuthenticationCapabilities() $this->assertTrue($protocol->getAsymmetricCipher() instanceof DataEncryptionInterface); $tokenObject = $protocol->generateAuthenticationToken(); + + $protocol->getAsymmetricCipher() + ->method('decryptData') + ->willReturn($tokenObject->tokenData); + $userDecryptedToken = $protocol->extractAuthenticationToken($tokenObject->cipherData); $this->assertTrue($protocol->authenticateEntity($tokenObject->tokenData, $userDecryptedToken)); @@ -342,50 +311,4 @@ public function testValidationCaseForInvalidOutputLengthPassedForTokenGeneration return; } } - - /** - * Testing validation case for invalid cipher token passed for token extraction. - * - * @throws \Exception Wrong usage errors. - */ - public function testValidationCaseForInvalidCipherTokenPassedForTokenExtraction() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - // Backward compatible for different versions of PHPUnit - if (method_exists($this, 'expectException')) { - $this->expectException(\InvalidArgumentException::class); - - $protocol->extractAuthenticationToken(['none']); - } else { - $hasThrown = null; - - try { - $protocol->extractAuthenticationToken(['none']); - } catch (\InvalidArgumentException $exception) { - $hasThrown = !empty($exception->getMessage()); - } catch (\Exception $exception) { - $hasThrown = $exception->getMessage(); - } - - $this->assertTrue($hasThrown); - - return; - } - } - - /** - * Testing the resource cleanup operation. - * - * @throws \Exception Wrong usage errors. - */ - public function testKeyPairResourceCleanupOperation() - { - $this->assertTrue(self::$isKeyPairGenerated); - - $this->deleteTheFile(self::PRIVATE_KEY_FILENAME_FOR_TESTS); - $this->deleteTheFile(self::PUBLIC_KEY_FILENAME_FOR_TESTS); - - self::$isKeyPairGenerated = null; - } } diff --git a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/SymmetricKeyAuthenticationTest.php b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/SymmetricKeyAuthenticationTest.php index a4915f0..aa2df55 100644 --- a/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/SymmetricKeyAuthenticationTest.php +++ b/tests/CryptoManana/Tests/TestSuite/CryptographicProtocol/SymmetricKeyAuthenticationTest.php @@ -12,6 +12,7 @@ use CryptoManana\Core\Interfaces\MessageEncryption\DataEncryptionInterface; use CryptoManana\CryptographicProtocol\SymmetricKeyAuthentication; use CryptoManana\SymmetricEncryption\Aes128; +use CryptoManana\Randomness\CryptoRandom; /** * Class SymmetricKeyAuthenticationTest - Testing the symmetric key authentication cryptographic protocol object. @@ -28,38 +29,63 @@ final class SymmetricKeyAuthenticationTest extends AbstractUnitTest */ private function getCryptographicProtocolForTesting() { - return new SymmetricKeyAuthentication(new Aes128()); - } + $aes = $this->getMockBuilder(Aes128::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); - /** - * Testing the cloning of an instance. - * - * @throws \Exception Wrong usage errors. - */ - public function testCloningCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); + $aes->expects($this->atLeast(0)) + ->method('getSecretKey') + ->willReturn('secret'); - $tmp = clone $protocol; + $aes->expects($this->atLeast(0)) + ->method('getInitializationVector') + ->willReturn('iv'); - $this->assertEquals($protocol, $tmp); - $this->assertNotEmpty($tmp->identifyEntity('', '')); + $aes->expects($this->atLeast(0)) + ->method('setSecretKey') + ->willReturnSelf(); - unset($tmp); - $this->assertNotNull($protocol); + $aes->expects($this->atLeast(0)) + ->method('setInitializationVector') + ->willReturnSelf(); + + $aes->expects($this->atLeast(0)) + ->method('encryptData') + ->willReturn('FFFF'); + + $randomness = $this->getMockBuilder(CryptoRandom::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); + + $randomness->expects($this->atLeast(0)) + ->method('getBytes') + ->willReturn("\0"); + + $randomness->expects($this->atLeast(0)) + ->method('getAlphaNumeric') + ->willReturn('A1'); + + $protocol = new SymmetricKeyAuthentication($aes); + + $protocol->setRandomGenerator($randomness); + + return $protocol; } /** - * Testing the serialization of an instance. + * Testing the cloning of an instance. * * @throws \Exception Wrong usage errors. */ - public function testSerializationCapabilities() + public function testCloningCapabilities() { $protocol = $this->getCryptographicProtocolForTesting(); - $tmp = serialize($protocol); - $tmp = unserialize($tmp); + $tmp = clone $protocol; $this->assertEquals($protocol, $tmp); $this->assertNotEmpty($tmp->identifyEntity('', '')); @@ -68,18 +94,6 @@ public function testSerializationCapabilities() $this->assertNotNull($protocol); } - /** - * Testing the object dumping for debugging. - * - * @throws \Exception Wrong usage errors. - */ - public function testDebugCapabilities() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - $this->assertNotEmpty(var_export($protocol, true)); - } - /** * Testing the object identification capabilities. * @@ -112,6 +126,11 @@ public function testClientEntityAuthenticationCapabilities() $this->assertTrue($protocol->getSymmetricCipher() instanceof DataEncryptionInterface); $tokenObject = $protocol->generateAuthenticationToken(); + + $protocol->getSymmetricCipher() + ->method('decryptData') + ->willReturn($tokenObject->tokenData); + $userDecryptedToken = $protocol->extractAuthenticationToken($tokenObject->cipherData); $this->assertTrue($protocol->authenticateEntity($tokenObject->tokenData, $userDecryptedToken)); @@ -301,35 +320,4 @@ public function testValidationCaseForInvalidOutputLengthPassedForTokenGeneration return; } } - - /** - * Testing validation case for invalid cipher token passed for token extraction. - * - * @throws \Exception Wrong usage errors. - */ - public function testValidationCaseForInvalidCipherTokenPassedForTokenExtraction() - { - $protocol = $this->getCryptographicProtocolForTesting(); - - // Backward compatible for different versions of PHPUnit - if (method_exists($this, 'expectException')) { - $this->expectException(\InvalidArgumentException::class); - - $protocol->extractAuthenticationToken(['none']); - } else { - $hasThrown = null; - - try { - $protocol->extractAuthenticationToken(['none']); - } catch (\InvalidArgumentException $exception) { - $hasThrown = !empty($exception->getMessage()); - } catch (\Exception $exception) { - $hasThrown = $exception->getMessage(); - } - - $this->assertTrue($hasThrown); - - return; - } - } } diff --git a/tests/CryptoManana/Tests/TestSuite/Utilities/DataShufflerTest.php b/tests/CryptoManana/Tests/TestSuite/Utilities/DataShufflerTest.php index 5498e39..4bbb2a5 100644 --- a/tests/CryptoManana/Tests/TestSuite/Utilities/DataShufflerTest.php +++ b/tests/CryptoManana/Tests/TestSuite/Utilities/DataShufflerTest.php @@ -7,11 +7,7 @@ namespace CryptoManana\Tests\TestSuite\Utilities; use CryptoManana\Tests\TestTypes\AbstractUnitTest; -use CryptoManana\Core\Abstractions\Containers\AbstractRandomnessInjectable; -use CryptoManana\Core\Abstractions\Randomness\AbstractRandomness; -use CryptoManana\Randomness\CryptoRandom; use CryptoManana\Randomness\PseudoRandom; -use CryptoManana\Randomness\QuasiRandom; use CryptoManana\Utilities\DataShuffler; /** @@ -24,13 +20,21 @@ final class DataShufflerTest extends AbstractUnitTest /** * Creates new instances for testing. * - * @param AbstractRandomness|CryptoRandom|PseudoRandom|QuasiRandom|null $generator Randomness source. - * * @return DataShuffler Testing instance. * @throws \Exception Wrong usage errors. */ - private function getDataShufflerForTesting($generator = null) + private function getDataShufflerForTesting() { + $generator = $this->getMockBuilder(PseudoRandom::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); + + $generator->expects($this->atLeast(0)) + ->method('getInt') + ->willReturn(0); + return new DataShuffler($generator); } @@ -52,59 +56,6 @@ public function testCloningCapabilities() $this->assertNotNull($shuffler); } - /** - * Testing the serialization of an instance. - * - * @throws \Exception Wrong usage errors. - */ - public function testSerializationCapabilities() - { - $shuffler = $this->getDataShufflerForTesting(); - - $tmp = serialize($shuffler); - $tmp = unserialize($tmp); - - $this->assertEquals($shuffler, $tmp); - $this->assertNotEmpty($tmp->shuffleString('test')); - - unset($tmp); - $this->assertNotNull($shuffler); - } - - /** - * Testing the object dumping for debugging. - * - * @throws \Exception Wrong usage errors. - */ - public function testDebugCapabilities() - { - $shuffler = $this->getDataShufflerForTesting(); - - $this->assertNotEmpty(var_export($shuffler, true)); - } - - /** - * Testing the dependency injection principle realization. - * - * @throws \Exception Wrong usage errors. - */ - public function testDependencyInjection() - { - $shuffler = $this->getDataShufflerForTesting(); - - $this->assertTrue($shuffler instanceof AbstractRandomnessInjectable); - $this->assertTrue($shuffler->getRandomGenerator() instanceof CryptoRandom); - - $shuffler->setRandomGenerator(new QuasiRandom()); - $this->assertTrue($shuffler->getRandomGenerator() instanceof QuasiRandom); - - $shuffler->setRandomGenerator(new PseudoRandom()); - $this->assertTrue($shuffler->getRandomGenerator() instanceof PseudoRandom); - - $shuffler = $shuffler->setRandomGenerator(new CryptoRandom())->seedRandomGenerator(); - $this->assertTrue($shuffler->getRandomGenerator() instanceof CryptoRandom); - } - /** * Testing the string shuffling. * @@ -112,21 +63,15 @@ public function testDependencyInjection() */ public function testStringShuffling() { - $shuffler = $this->getDataShufflerForTesting(new PseudoRandom()); - $testString = 'Long string for testing in here! #ThisIsNaughty'; - - $resultOne = $shuffler->shuffleString($testString); - $resultTwo = $shuffler->shuffleString($testString); - - $this->assertNotEquals($resultOne, $resultTwo); - - $shuffler->seedRandomGenerator(42); - $resultOne = $shuffler->shuffleString($testString); + $shuffler = $this->getDataShufflerForTesting(); + $testArray = '123456789'; - $shuffler->seedRandomGenerator(42); - $resultTwo = $shuffler->shuffleString($testString); + $resultOne = $shuffler->shuffleString($testArray); + $resultTwo = $shuffler->shuffleString($testArray); $this->assertEquals($resultOne, $resultTwo); + + $this->assertEmpty($shuffler->shuffleString('')); } /** @@ -136,33 +81,14 @@ public function testStringShuffling() */ public function testArrayShuffling() { - $shuffler = $this->getDataShufflerForTesting(new PseudoRandom()); + $shuffler = $this->getDataShufflerForTesting(); $testArray = ['1', [3, 2], new \stdClass(), 33, 'test', [], '1', 69]; $resultOne = $shuffler->shuffleArray($testArray); $resultTwo = $shuffler->shuffleArray($testArray); - $this->assertNotEquals($resultOne, $resultTwo); - - $shuffler->seedRandomGenerator(42); - $resultOne = $shuffler->shuffleArray($testArray); - - $shuffler->seedRandomGenerator(42); - $resultTwo = $shuffler->shuffleArray($testArray); - $this->assertEquals($resultOne, $resultTwo); - } - /** - * Testing the shuffling of supported types with empty values. - * - * @throws \Exception Wrong usage errors. - */ - public function testShufflingOfEmptyInput() - { - $shuffler = $this->getDataShufflerForTesting(); - - $this->assertEmpty($shuffler->shuffleString('')); $this->assertEmpty($shuffler->shuffleArray([])); } diff --git a/tests/CryptoManana/Tests/TestSuite/Utilities/ElementPickerTest.php b/tests/CryptoManana/Tests/TestSuite/Utilities/ElementPickerTest.php index 7e961a4..d9b2dc3 100644 --- a/tests/CryptoManana/Tests/TestSuite/Utilities/ElementPickerTest.php +++ b/tests/CryptoManana/Tests/TestSuite/Utilities/ElementPickerTest.php @@ -7,11 +7,7 @@ namespace CryptoManana\Tests\TestSuite\Utilities; use CryptoManana\Tests\TestTypes\AbstractUnitTest; -use CryptoManana\Core\Abstractions\Containers\AbstractRandomnessInjectable; -use CryptoManana\Core\Abstractions\Randomness\AbstractRandomness; -use CryptoManana\Randomness\CryptoRandom; use CryptoManana\Randomness\PseudoRandom; -use CryptoManana\Randomness\QuasiRandom; use CryptoManana\Utilities\ElementPicker; /** @@ -24,13 +20,21 @@ final class ElementPickerTest extends AbstractUnitTest /** * Creates new instances for testing. * - * @param AbstractRandomness|CryptoRandom|PseudoRandom|QuasiRandom|null $generator Randomness source. - * * @return ElementPicker Testing instance. * @throws \Exception Wrong usage errors. */ - private function getElementPickerForTesting($generator = null) + private function getElementPickerForTesting() { + $generator = $this->getMockBuilder(PseudoRandom::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); + + $generator->expects($this->atLeast(0)) + ->method('getInt') + ->willReturn(1); + return new ElementPicker($generator); } @@ -52,59 +56,6 @@ public function testCloningCapabilities() $this->assertNotNull($picker); } - /** - * Testing the serialization of an instance. - * - * @throws \Exception Wrong usage errors. - */ - public function testSerializationCapabilities() - { - $picker = $this->getElementPickerForTesting(); - - $tmp = serialize($picker); - $tmp = unserialize($tmp); - - $this->assertEquals($picker, $tmp); - $this->assertNotEmpty($tmp->pickCharacterElement('test')); - - unset($tmp); - $this->assertNotNull($picker); - } - - /** - * Testing the object dumping for debugging. - * - * @throws \Exception Wrong usage errors. - */ - public function testDebugCapabilities() - { - $picker = $this->getElementPickerForTesting(); - - $this->assertNotEmpty(var_export($picker, true)); - } - - /** - * Testing the dependency injection principle realization. - * - * @throws \Exception Wrong usage errors. - */ - public function testDependencyInjection() - { - $picker = $this->getElementPickerForTesting(); - - $this->assertTrue($picker instanceof AbstractRandomnessInjectable); - $this->assertTrue($picker->getRandomGenerator() instanceof CryptoRandom); - - $picker->setRandomGenerator(new QuasiRandom()); - $this->assertTrue($picker->getRandomGenerator() instanceof QuasiRandom); - - $picker->setRandomGenerator(new PseudoRandom()); - $this->assertTrue($picker->getRandomGenerator() instanceof PseudoRandom); - - $picker = $picker->setRandomGenerator(new CryptoRandom())->seedRandomGenerator(); - $this->assertTrue($picker->getRandomGenerator() instanceof CryptoRandom); - } - /** * Testing the random picking of a character from a string. * @@ -112,21 +63,15 @@ public function testDependencyInjection() */ public function testPickingRandomCharacterFromString() { - $picker = $this->getElementPickerForTesting(new PseudoRandom()); + $picker = $this->getElementPickerForTesting(); $testString = 'Long string for testing in here! #ThisIsNaughty'; $resultOne = $picker->pickCharacterElement($testString); $resultTwo = $picker->pickCharacterElement($testString); - $this->assertNotEquals($resultOne, $resultTwo); - - $picker->seedRandomGenerator(42); - $resultOne = $picker->pickCharacterElement($testString); - - $picker->seedRandomGenerator(42); - $resultTwo = $picker->pickCharacterElement($testString); - $this->assertEquals($resultOne, $resultTwo); + + $this->assertEmpty($picker->pickCharacterElement('')); } /** @@ -136,33 +81,14 @@ public function testPickingRandomCharacterFromString() */ public function testPickingRandomElementFromArray() { - $picker = $this->getElementPickerForTesting(new PseudoRandom()); + $picker = $this->getElementPickerForTesting(); $testArray = ['1', [3, 2], new \stdClass(), 33, 'test', [], '1', 69]; $resultOne = $picker->pickArrayElement($testArray); $resultTwo = $picker->pickArrayElement($testArray); - $this->assertNotEquals($resultOne, $resultTwo); - - $picker->seedRandomGenerator(42); - $resultOne = $picker->pickArrayElement($testArray); - - $picker->seedRandomGenerator(42); - $resultTwo = $picker->pickArrayElement($testArray); - $this->assertEquals($resultOne, $resultTwo); - } - /** - * Testing the element picking in supported types with empty values. - * - * @throws \Exception Wrong usage errors. - */ - public function testPickingFromEmptyInput() - { - $picker = $this->getElementPickerForTesting(); - - $this->assertEmpty($picker->pickCharacterElement('')); $this->assertEmpty($picker->pickArrayElement([])); } diff --git a/tests/CryptoManana/Tests/TestSuite/Utilities/FileShredderTest.php b/tests/CryptoManana/Tests/TestSuite/Utilities/FileShredderTest.php index 1a6889c..b874dea 100644 --- a/tests/CryptoManana/Tests/TestSuite/Utilities/FileShredderTest.php +++ b/tests/CryptoManana/Tests/TestSuite/Utilities/FileShredderTest.php @@ -6,12 +6,8 @@ namespace CryptoManana\Tests\TestSuite\Utilities; -use CryptoManana\Tests\TestTypes\AbstractUnitTest; -use CryptoManana\Core\Abstractions\Containers\AbstractRandomnessInjectable; -use CryptoManana\Core\Abstractions\Randomness\AbstractRandomness; -use CryptoManana\Randomness\CryptoRandom; use CryptoManana\Randomness\PseudoRandom; -use CryptoManana\Randomness\QuasiRandom; +use CryptoManana\Tests\TestTypes\AbstractUnitTest; use CryptoManana\Utilities\FileShredder; /** @@ -24,13 +20,21 @@ final class FileShredderTest extends AbstractUnitTest /** * Creates new instances for testing. * - * @param AbstractRandomness|CryptoRandom|PseudoRandom|QuasiRandom|null $generator Randomness source. - * * @return FileShredder Testing instance. * @throws \Exception Wrong usage errors. */ - private function getFileShredderForTesting($generator = null) + private function getFileShredderForTesting() { + $generator = $this->getMockBuilder(PseudoRandom::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); + + $generator->expects($this->atLeast(0)) + ->method('getBytes') + ->willReturn("\0"); + return new FileShredder($generator); } @@ -52,59 +56,6 @@ public function testCloningCapabilities() $this->assertNotNull($shredder); } - /** - * Testing the serialization of an instance. - * - * @throws \Exception Wrong usage errors. - */ - public function testSerializationCapabilities() - { - $shredder = $this->getFileShredderForTesting(); - - $tmp = serialize($shredder); - $tmp = unserialize($tmp); - - $this->assertEquals($shredder, $tmp); - $this->assertNotEmpty($shredder->getRandomGenerator()); - - unset($tmp); - $this->assertNotNull($shredder); - } - - /** - * Testing the object dumping for debugging. - * - * @throws \Exception Wrong usage errors. - */ - public function testDebugCapabilities() - { - $shredder = $this->getFileShredderForTesting(); - - $this->assertNotEmpty(var_export($shredder, true)); - } - - /** - * Testing the dependency injection principle realization. - * - * @throws \Exception Wrong usage errors. - */ - public function testDependencyInjection() - { - $shredder = $this->getFileShredderForTesting(); - - $this->assertTrue($shredder instanceof AbstractRandomnessInjectable); - $this->assertTrue($shredder->getRandomGenerator() instanceof CryptoRandom); - - $shredder->setRandomGenerator(new QuasiRandom()); - $this->assertTrue($shredder->getRandomGenerator() instanceof QuasiRandom); - - $shredder->setRandomGenerator(new PseudoRandom()); - $this->assertTrue($shredder->getRandomGenerator() instanceof PseudoRandom); - - $shredder = $shredder->setRandomGenerator(new CryptoRandom())->seedRandomGenerator(); - $this->assertTrue($shredder->getRandomGenerator() instanceof CryptoRandom); - } - /** * Testing the file erasure. * diff --git a/tests/CryptoManana/Tests/TestSuite/Utilities/TokenGeneratorTest.php b/tests/CryptoManana/Tests/TestSuite/Utilities/TokenGeneratorTest.php index 4600bc3..0d5cc6c 100644 --- a/tests/CryptoManana/Tests/TestSuite/Utilities/TokenGeneratorTest.php +++ b/tests/CryptoManana/Tests/TestSuite/Utilities/TokenGeneratorTest.php @@ -7,11 +7,7 @@ namespace CryptoManana\Tests\TestSuite\Utilities; use CryptoManana\Tests\TestTypes\AbstractUnitTest; -use CryptoManana\Core\Abstractions\Containers\AbstractRandomnessInjectable; -use CryptoManana\Core\Abstractions\Randomness\AbstractRandomness; -use CryptoManana\Randomness\CryptoRandom; use CryptoManana\Randomness\PseudoRandom; -use CryptoManana\Randomness\QuasiRandom; use CryptoManana\Utilities\TokenGenerator; use CryptoManana\DataStructures\KeyPair; @@ -25,45 +21,50 @@ final class TokenGeneratorTest extends AbstractUnitTest /** * Creates new instances for testing. * - * @param AbstractRandomness|CryptoRandom|PseudoRandom|QuasiRandom|null $generator Randomness source. - * * @return TokenGenerator Testing instance. * @throws \Exception Wrong usage errors. */ - private function getTokenGeneratorForTesting($generator = null) + private function getTokenGeneratorForTesting() { - return new TokenGenerator($generator); - } + $generator = $this->getMockBuilder(PseudoRandom::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); - /** - * Testing the cloning of an instance. - * - * @throws \Exception Wrong usage errors. - */ - public function testCloningCapabilities() - { - $generator = $this->getTokenGeneratorForTesting(); + $generator->expects($this->atLeast(0)) + ->method('getInt') + ->willReturn(1, 2, 3, 4); - $tmp = clone $generator; + $generator->expects($this->atLeast(0)) + ->method('getAlphaNumeric') + ->willReturn('A'); - $this->assertEquals($generator, $tmp); - $this->assertNotEmpty($tmp->getTokenString(10)); + $generator->expects($this->atLeast(0)) + ->method('getHex') + ->willReturn('a'); - unset($tmp); - $this->assertNotNull($generator); + $generator->expects($this->atLeast(0)) + ->method('getAscii') + ->willReturn('b'); + + $generator->expects($this->atLeast(0)) + ->method('getBytes') + ->willReturn("\0"); + + return new TokenGenerator($generator); } /** - * Testing the serialization of an instance. + * Testing the cloning of an instance. * * @throws \Exception Wrong usage errors. */ - public function testSerializationCapabilities() + public function testCloningCapabilities() { $generator = $this->getTokenGeneratorForTesting(); - $tmp = serialize($generator); - $tmp = unserialize($tmp); + $tmp = clone $generator; $this->assertEquals($generator, $tmp); $this->assertNotEmpty($tmp->getTokenString(10)); @@ -72,40 +73,6 @@ public function testSerializationCapabilities() $this->assertNotNull($generator); } - /** - * Testing the object dumping for debugging. - * - * @throws \Exception Wrong usage errors. - */ - public function testDebugCapabilities() - { - $generator = $this->getTokenGeneratorForTesting(); - - $this->assertNotEmpty(var_export($generator, true)); - } - - /** - * Testing the dependency injection principle realization. - * - * @throws \Exception Wrong usage errors. - */ - public function testDependencyInjection() - { - $generator = $this->getTokenGeneratorForTesting(); - - $this->assertTrue($generator instanceof AbstractRandomnessInjectable); - $this->assertTrue($generator->getRandomGenerator() instanceof CryptoRandom); - - $generator->setRandomGenerator(new QuasiRandom()); - $this->assertTrue($generator->getRandomGenerator() instanceof QuasiRandom); - - $generator->setRandomGenerator(new PseudoRandom()); - $this->assertTrue($generator->getRandomGenerator() instanceof PseudoRandom); - - $generator = $generator->setRandomGenerator(new CryptoRandom())->seedRandomGenerator(); - $this->assertTrue($generator->getRandomGenerator() instanceof CryptoRandom); - } - /** * Testing secure password generation. * @@ -113,24 +80,16 @@ public function testDependencyInjection() */ public function testPasswordStringGeneration() { - $generator = $this->getTokenGeneratorForTesting(new PseudoRandom()); + $generator = $this->getTokenGeneratorForTesting(); $resultOne = $generator->getPasswordString(20); $resultTwo = $generator->getPasswordString(20); - $this->assertNotEquals($resultOne, $resultTwo); + $this->assertEquals($resultOne, $resultTwo); $resultOne = $generator->getPasswordString(20, false); $resultTwo = $generator->getPasswordString(20, false); - $this->assertNotEquals($resultOne, $resultTwo); - - $generator->seedRandomGenerator(42); - $resultOne = $generator->getPasswordString(20); - - $generator->seedRandomGenerator(42); - $resultTwo = $generator->getPasswordString(20); - $this->assertEquals($resultOne, $resultTwo); } @@ -141,24 +100,16 @@ public function testPasswordStringGeneration() */ public function testTokenStringGeneration() { - $generator = $this->getTokenGeneratorForTesting(new PseudoRandom()); + $generator = $this->getTokenGeneratorForTesting(); $resultOne = $generator->getTokenString(64); $resultTwo = $generator->getTokenString(64); - $this->assertNotEquals($resultOne, $resultTwo); + $this->assertEquals($resultOne, $resultTwo); $resultOne = $generator->getTokenString(64, false); $resultTwo = $generator->getTokenString(64, false); - $this->assertNotEquals($resultOne, $resultTwo); - - $generator->seedRandomGenerator(42); - $resultOne = $generator->getTokenString(64); - - $generator->seedRandomGenerator(42); - $resultTwo = $generator->getTokenString(64); - $this->assertEquals($resultOne, $resultTwo); } @@ -169,24 +120,16 @@ public function testTokenStringGeneration() */ public function testHashingSaltGeneration() { - $generator = $this->getTokenGeneratorForTesting(new PseudoRandom()); + $generator = $this->getTokenGeneratorForTesting(); $resultOne = $generator->getHashingSalt(64); $resultTwo = $generator->getHashingSalt(64); - $this->assertNotEquals($resultOne, $resultTwo); + $this->assertEquals($resultOne, $resultTwo); $resultOne = $generator->getHashingSalt(64, false); $resultTwo = $generator->getHashingSalt(64, false); - $this->assertNotEquals($resultOne, $resultTwo); - - $generator->seedRandomGenerator(42); - $resultOne = $generator->getHashingSalt(64); - - $generator->seedRandomGenerator(42); - $resultTwo = $generator->getHashingSalt(64); - $this->assertEquals($resultOne, $resultTwo); } @@ -197,24 +140,16 @@ public function testHashingSaltGeneration() */ public function testHashingKeyGeneration() { - $generator = $this->getTokenGeneratorForTesting(new PseudoRandom()); + $generator = $this->getTokenGeneratorForTesting(); $resultOne = $generator->getHashingKey(64); $resultTwo = $generator->getHashingKey(64); - $this->assertNotEquals($resultOne, $resultTwo); + $this->assertEquals($resultOne, $resultTwo); $resultOne = $generator->getHashingKey(64, false); $resultTwo = $generator->getHashingKey(64, false); - $this->assertNotEquals($resultOne, $resultTwo); - - $generator->seedRandomGenerator(42); - $resultOne = $generator->getHashingKey(64); - - $generator->seedRandomGenerator(42); - $resultTwo = $generator->getHashingKey(64); - $this->assertEquals($resultOne, $resultTwo); } @@ -225,24 +160,16 @@ public function testHashingKeyGeneration() */ public function testEncryptionKeyGeneration() { - $generator = $this->getTokenGeneratorForTesting(new PseudoRandom()); + $generator = $this->getTokenGeneratorForTesting(); $resultOne = $generator->getEncryptionKey(64); $resultTwo = $generator->getEncryptionKey(64); - $this->assertNotEquals($resultOne, $resultTwo); + $this->assertEquals($resultOne, $resultTwo); $resultOne = $generator->getEncryptionKey(64, false); $resultTwo = $generator->getEncryptionKey(64, false); - $this->assertNotEquals($resultOne, $resultTwo); - - $generator->seedRandomGenerator(42); - $resultOne = $generator->getEncryptionKey(64); - - $generator->seedRandomGenerator(42); - $resultTwo = $generator->getEncryptionKey(64); - $this->assertEquals($resultOne, $resultTwo); } @@ -253,24 +180,16 @@ public function testEncryptionKeyGeneration() */ public function testInitializationVectorGeneration() { - $generator = $this->getTokenGeneratorForTesting(new PseudoRandom()); + $generator = $this->getTokenGeneratorForTesting(); $resultOne = $generator->getEncryptionInitializationVector(64); $resultTwo = $generator->getEncryptionInitializationVector(64); - $this->assertNotEquals($resultOne, $resultTwo); + $this->assertEquals($resultOne, $resultTwo); $resultOne = $generator->getEncryptionInitializationVector(64, false); $resultTwo = $generator->getEncryptionInitializationVector(64, false); - $this->assertNotEquals($resultOne, $resultTwo); - - $generator->seedRandomGenerator(42); - $resultOne = $generator->getEncryptionInitializationVector(64); - - $generator->seedRandomGenerator(42); - $resultTwo = $generator->getEncryptionInitializationVector(64); - $this->assertEquals($resultOne, $resultTwo); } diff --git a/tests/CryptoManana/Tests/TestTypes/AbstractIntegrationTest.php b/tests/CryptoManana/Tests/TestTypes/AbstractIntegrationTest.php new file mode 100644 index 0000000..42cacdd --- /dev/null +++ b/tests/CryptoManana/Tests/TestTypes/AbstractIntegrationTest.php @@ -0,0 +1,18 @@ +