diff --git a/src/KeyFactory.php b/src/KeyFactory.php index 9fa64d4..08dc2ed 100644 --- a/src/KeyFactory.php +++ b/src/KeyFactory.php @@ -221,7 +221,7 @@ public static function loadEncryptionKey($filePath) * Load, specifically, an encryption public key from a file * * @param string $filePath - * @return EncryptionKey + * @return EncryptionPublicKey */ public static function loadEncryptionPublicKey($filePath) { @@ -235,11 +235,29 @@ public static function loadEncryptionPublicKey($filePath) ); } + /** + * Load, specifically, an encryption public key from a file + * + * @param string $filePath + * @return EncryptionSecretKey + */ + public static function loadEncryptionSecretKey($filePath) + { + if (!\is_readable($filePath)) { + throw new Alerts\CannotPerformOperation( + 'Cannot read keyfile: '. $filePath + ); + } + return new EncryptionSecretKey( + self::loadKeyFile($filePath) + ); + } + /** * Load, specifically, a signature public key from a file * * @param string $filePath - * @return EncryptionKey + * @return SignaturePublicKey */ public static function loadSignaturePublicKey($filePath) { @@ -253,11 +271,29 @@ public static function loadSignaturePublicKey($filePath) ); } + /** + * Load, specifically, a signature secret key from a file + * + * @param string $filePath + * @return SignatureSecretKey + */ + public static function loadSignatureSecretKey($filePath) + { + if (!\is_readable($filePath)) { + throw new Alerts\CannotPerformOperation( + 'Cannot read keyfile: '. $filePath + ); + } + return new SignatureSecretKey( + self::loadKeyFile($filePath) + ); + } + /** * Load an asymmetric encryption key pair from a file * * @param string $filePath - * @return EncryptionKey + * @return EncryptionKeyPair */ public static function loadEncryptionKeyPair($filePath) { @@ -277,7 +313,7 @@ public static function loadEncryptionKeyPair($filePath) * Load an asymmetric signature key pair from a file * * @param string $filePath - * @return EncryptionKey + * @return SignatureKeyPair */ public static function loadSignatureKeyPair($filePath) { diff --git a/test/unit/AsymmetricTest.php b/test/unit/AsymmetricTest.php index 959e440..a1637ca 100644 --- a/test/unit/AsymmetricTest.php +++ b/test/unit/AsymmetricTest.php @@ -1,8 +1,6 @@ assertEquals($plain, $message); - throw new \Exception('ERROR: THIS SHOULD ALWAYS FAIL'); + $this->fail( + 'This should have thrown an InvalidMessage exception!' + ); } catch (CryptoException\InvalidMessage $e) { $this->assertTrue($e instanceof CryptoException\InvalidMessage); } @@ -125,7 +125,9 @@ public function testSealFail() try { $opened = Asymmetric::unseal($sealed, $alice->getSecretKey(), true); $this->assertEquals($opened, $message); - throw new Exception('ERROR: THIS SHOULD ALWAYS FAIL'); + $this->fail( + 'This should have thrown an InvalidMessage exception!' + ); } catch (CryptoException\InvalidKey $e) { $this->assertTrue($e instanceof CryptoException\InvalidKey); } catch (CryptoException\InvalidMessage $e) { diff --git a/test/unit/FileTest.php b/test/unit/FileTest.php index 76a531f..8c420d3 100644 --- a/test/unit/FileTest.php +++ b/test/unit/FileTest.php @@ -37,6 +37,8 @@ public function testEncrypt() \hash_file('sha256', __DIR__.'/tmp/paragon_avatar.png'), \hash_file('sha256', __DIR__.'/tmp/paragon_avatar.decrypted.png') ); + \unlink(__DIR__.'/tmp/paragon_avatar.encrypted.png'); + \unlink(__DIR__.'/tmp/paragon_avatar.decrypted.png'); } public function testEncryptFail() @@ -63,9 +65,13 @@ public function testEncryptFail() __DIR__.'/tmp/paragon_avatar.decrypt_fail.png', $key ); - throw new \Exception('ERROR: THIS SHOULD ALWAYS FAIL'); + $this->fail( + 'This should have thrown an InvalidMessage exception!' + ); } catch (CryptoException\InvalidMessage $e) { $this->assertTrue($e instanceof CryptoException\InvalidMessage); + \unlink(__DIR__.'/tmp/paragon_avatar.encrypt_fail.png'); + \unlink(__DIR__.'/tmp/paragon_avatar.decrypt_fail.png'); } } @@ -96,6 +102,9 @@ public function testSeal() \hash_file('sha256', __DIR__.'/tmp/paragon_avatar.png'), \hash_file('sha256', __DIR__.'/tmp/paragon_avatar.opened.png') ); + + \unlink(__DIR__.'/tmp/paragon_avatar.sealed.png'); + \unlink(__DIR__.'/tmp/paragon_avatar.opened.png'); } public function testSealFail() @@ -122,12 +131,16 @@ public function testSealFail() try { File::unsealFile( __DIR__.'/tmp/paragon_avatar.seal_fail.png', - __DIR__.'/tmp/paragon_avatar.opened.png', + __DIR__.'/tmp/paragon_avatar.open_fail.png', $secretkey ); - throw new \Exception('ERROR: THIS SHOULD ALWAYS FAIL'); + $this->fail( + 'This should have thrown an InvalidMessage exception!' + ); } catch (CryptoException\InvalidMessage $e) { $this->assertTrue($e instanceof CryptoException\InvalidMessage); + \unlink(__DIR__.'/tmp/paragon_avatar.seal_fail.png'); + \unlink(__DIR__.'/tmp/paragon_avatar.open_fail.png'); } } @@ -169,5 +182,6 @@ public function testChecksum() $hash, $file ); + \unlink(__DIR__.'/tmp/garbage.dat'); } } diff --git a/test/unit/KeyTest.php b/test/unit/KeyTest.php index 66c40d2..1a1ee06 100644 --- a/test/unit/KeyTest.php +++ b/test/unit/KeyTest.php @@ -2,8 +2,12 @@ use \ParagonIE\Halite\Key; use \ParagonIE\Halite\KeyFactory; use \ParagonIE\Halite\Asymmetric\Crypto as Asymmetric; -use \ParagonIE\Halite\Asymmetric\SecretKey as ASecretKey; -use \ParagonIE\Halite\Asymmetric\PublicKey as APublicKey; +use \ParagonIE\Halite\Asymmetric\EncryptionPublicKey; +use \ParagonIE\Halite\Asymmetric\EncryptionSecretKey; +use \ParagonIE\Halite\Asymmetric\SignaturePublicKey; +use \ParagonIE\Halite\Asymmetric\SignatureSecretKey; +use \ParagonIE\Halite\Symmetric\AuthenticationKey; +use \ParagonIE\Halite\Symmetric\EncryptionKey; /** * @backupGlobals disabled @@ -43,14 +47,13 @@ public function testDeriveSigningKey() $keypair = KeyFactory::deriveSignatureKeyPair( 'apple', "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f". - "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - Key::CRYPTO_SIGN + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" ); $sign_secret = $keypair->getSecretKey(); $sign_public = $keypair->getPublicKey(); - $this->assertTrue($sign_secret instanceof ASecretKey); - $this->assertTrue($sign_public instanceof APublicKey); + $this->assertTrue($sign_secret instanceof SignatureSecretKey); + $this->assertTrue($sign_public instanceof SignaturePublicKey); // Can this be used? $message = 'This is a test message'; @@ -114,6 +117,69 @@ public function testKeyTypes() $this->assertFalse($sign_public->isSecretKey()); $this->assertTrue($sign_public->isSigningKey()); $this->assertTrue($sign_public->isPublicKey()); + } + + public function testEncKeyStorage() + { + $enc_keypair = KeyFactory::deriveEncryptionKeyPair( + 'apple', + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f". + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + ); + $enc_secret = $enc_keypair->getSecretKey(); + $enc_public = $enc_keypair->getPublicKey(); + + $file_secret = \tempnam(__DIR__.'/tmp', 'key'); + $file_public = \tempnam(__DIR__.'/tmp', 'key'); + + $this->assertTrue( + KeyFactory::save($enc_secret, $file_secret) !== false + ); + $this->assertTrue( + KeyFactory::save($enc_public, $file_public) !== false + ); + + $load_public = KeyFactory::loadEncryptionPublicKey($file_public); + $this->assertTrue( + $load_public instanceof EncryptionPublicKey + ); + $this->assertTrue( + \hash_equals($enc_public->get(), $load_public->get()) + ); + + \unlink($file_secret); + \unlink($file_public); + } + + public function testSignKeyStorage() + { + $sign_keypair = KeyFactory::deriveSignatureKeyPair( + 'apple', + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f". + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + ); + $sign_secret = $sign_keypair->getSecretKey(); + $sign_public = $sign_keypair->getPublicKey(); + + $file_secret = \tempnam(__DIR__.'/tmp', 'key'); + $file_public = \tempnam(__DIR__.'/tmp', 'key'); + + $this->assertTrue( + KeyFactory::save($sign_secret, $file_secret) !== false + ); + $this->assertTrue( + KeyFactory::save($sign_public, $file_public) !== false + ); + + $load_public = KeyFactory::loadSignaturePublicKey($file_public); + $this->assertTrue( + $load_public instanceof SignaturePublicKey + ); + $this->assertTrue( + \hash_equals($sign_public->get(), $load_public->get()) + ); + \unlink($file_secret); + \unlink($file_public); } } diff --git a/test/unit/SymmetricTest.php b/test/unit/SymmetricTest.php index b5f9443..3040233 100644 --- a/test/unit/SymmetricTest.php +++ b/test/unit/SymmetricTest.php @@ -79,7 +79,9 @@ public function testEncryptFail() try { $plain = Symmetric::decrypt($message, $key, true); $this->assertEquals($plain, $message); - throw new Exception('ERROR: THIS SHOULD ALWAYS FAIL'); + $this->fail( + 'This should have thrown an InvalidMessage exception!' + ); } catch (CryptoException\InvalidMessage $e) { $this->assertTrue($e instanceof CryptoException\InvalidMessage); }