diff --git a/PgpCore.Tests/TestFactory.cs b/PgpCore.Tests/TestFactory.cs index 14f4eac..64c3e32 100644 --- a/PgpCore.Tests/TestFactory.cs +++ b/PgpCore.Tests/TestFactory.cs @@ -173,7 +173,7 @@ public void Arrange(FileType fileType) { using (StreamWriter streamWriter = ContentFileInfo.CreateText()) { - streamWriter.WriteLine(Constants.CONTENT); + streamWriter.Write(Constants.CONTENT); } } else if (fileType == FileType.GeneratedMedium) diff --git a/PgpCore.Tests/TestHelper.cs b/PgpCore.Tests/TestHelper.cs new file mode 100644 index 0000000..f0c4214 --- /dev/null +++ b/PgpCore.Tests/TestHelper.cs @@ -0,0 +1,46 @@ +using Org.BouncyCastle.Bcpg.OpenPgp; +using Org.BouncyCastle.Bcpg; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PgpCore.Tests +{ + internal static class TestHelper + { + internal static PgpPublicKey ReadPublicKey(Stream inputStream) + { + PgpPublicKeyRingBundle pgpPub = new PgpPublicKeyRingBundle(PgpUtilities.GetDecoderStream(inputStream)); + foreach (PgpPublicKeyRing kRing in pgpPub.GetKeyRings()) + { + foreach (PgpPublicKey k in kRing.GetPublicKeys()) + { + if (k.IsEncryptionKey) + return k; + } + } + throw new ArgumentException("No encryption key found in public key ring."); + } + + internal static IEnumerable GetEnumValues() where T : struct, IConvertible + { + foreach (T enumValue in Enum.GetValues(typeof(T))) + { + yield return enumValue; + } + } + + internal static IEnumerable GetAllCombinations() + { + foreach (CompressionAlgorithmTag compressionAlgorithmTag in GetEnumValues()) + foreach (HashAlgorithmTag hashAlgorithmTag in GetEnumValues()) + foreach (SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag in GetEnumValues()) + { + yield return new object[] { compressionAlgorithmTag, hashAlgorithmTag, symmetricKeyAlgorithmTag }; + } + } + } +} diff --git a/PgpCore.Tests/UnitTests/Decrypt/DecryptAsync.File.cs b/PgpCore.Tests/UnitTests/Decrypt/DecryptAsync.File.cs new file mode 100644 index 0000000..1a70730 --- /dev/null +++ b/PgpCore.Tests/UnitTests/Decrypt/DecryptAsync.File.cs @@ -0,0 +1,539 @@ +using FluentAssertions; +using FluentAssertions.Execution; +using Org.BouncyCastle.Bcpg; +using Org.BouncyCastle.Bcpg.OpenPgp; +using Org.BouncyCastle.Security; +using PgpCore.Models; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace PgpCore.Tests.UnitTests.Decrypt +{ + public class DecryptAsync_File : TestBase + { + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptEncryptedMessage_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + await pgpEncrypt.EncryptAsync(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo); + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptBinaryEncryptedMessage_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + await pgpEncrypt.EncryptAsync(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo, armor: false); + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory.EncryptedContentFileInfo.FullName).Should().NotStartWith("-----BEGIN PGP MESSAGE-----"); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetCompressionAlgorithimTags))] + public async Task DecryptAsync_DecryptEncryptedCompressedMessage_ShouldDecryptMessage(CompressionAlgorithmTag compressionAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + CompressionAlgorithm = compressionAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + await pgpEncrypt.EncryptAsync(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo); + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetCompressionAlgorithimTags))] + public async Task DecryptAsync_DecryptBinaryEncryptedCompressedMessage_ShouldDecryptMessage(CompressionAlgorithmTag compressionAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + CompressionAlgorithm = compressionAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + await pgpEncrypt.EncryptAsync(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo, armor: false); + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory.EncryptedContentFileInfo.FullName).Should().NotStartWith("-----BEGIN PGP MESSAGE-----"); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetHashAlgorithimTags))] + public async Task DecryptAsync_DecryptEncryptedWithSpecifiedHashAlgorithim_ShouldDecryptMessage(HashAlgorithmTag hashAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + HashAlgorithmTag = hashAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + await pgpEncrypt.EncryptAsync(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo); + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetHashAlgorithimTags))] + public async Task DecryptAsync_DecryptBinaryEncryptedWithSpecifiedHashAlgorithim_ShouldDecryptMessage(HashAlgorithmTag hashAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + HashAlgorithmTag = hashAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + await pgpEncrypt.EncryptAsync(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo, armor: false); + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory.EncryptedContentFileInfo.FullName).Should().NotStartWith("-----BEGIN PGP MESSAGE-----"); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetSymmetricAlgorithimTags))] + public async Task DecryptAsync_DecryptEncryptedWithSpecifiedSymetricKeyAlgorithim_ShouldDecryptMessage(SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = symmetricKeyAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + await pgpEncrypt.EncryptAsync(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo); + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + PgpInspectResult pgpInspectResult = await pgpDecrypt.InspectAsync(testFactory.EncryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + pgpInspectResult.SymmetricKeyAlgorithm.Should().Be(symmetricKeyAlgorithmTag); + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetSymmetricAlgorithimTags))] + public async Task DecryptAsync_DecryptBinaryEncryptedWithSpecifiedSymetricKeyAlgorithim_ShouldDecryptMessage(SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = symmetricKeyAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + await pgpEncrypt.EncryptAsync(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo, armor: false); + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + PgpInspectResult pgpInspectResult = await pgpDecrypt.InspectAsync(testFactory.EncryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory.EncryptedContentFileInfo.FullName).Should().NotStartWith("-----BEGIN PGP MESSAGE-----"); + } + + pgpInspectResult.SymmetricKeyAlgorithm.Should().Be(symmetricKeyAlgorithmTag); + + // Teardown + testFactory.Teardown(); + } + + [Fact] + public async Task DecryptAsync_DecryptEncryptedWithNullSymetricKeyAlgorithim_ShouldThrowException() + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = SymmetricKeyAlgorithmTag.Null + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + var ex = await Assert.ThrowsAsync(async () => await pgpEncrypt.EncryptAsync(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo)); + + // Assert + using (new AssertionScope()) + { + ex.Should().BeAssignableTo(); + ex.Message.Should().Be("unknown symmetric algorithm: Null"); + } + + // Teardown + testFactory.Teardown(); + } + + [Fact] + public async Task DecryptAsync_DecryptEncryptedWithSaferSymetricKeyAlgorithim_ShouldThrowException() + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = SymmetricKeyAlgorithmTag.Safer + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + var ex = await Assert.ThrowsAsync(async () => await pgpEncrypt.EncryptAsync(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo)); + + // Assert + using (new AssertionScope()) + { + ex.Should().BeAssignableTo(); + ex.Message.Should().Be("Algorithm SAFER not recognised."); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptEncryptedWithMultipleKeys_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + await testFactory2.ArrangeAsync(KeyType.Generated, FileType.Known); + + List keys = new List() + { + testFactory.PublicKeyFileInfo, + testFactory2.PublicKeyFileInfo + }; + + EncryptionKeys encryptionKeys = new EncryptionKeys(keys, testFactory.PrivateKeyFileInfo, testFactory.Password); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory2.PrivateKeyFileInfo, testFactory2.Password); + + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + await pgpEncrypt.EncryptAsync(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo); + await pgpEncrypt.DecryptAsync(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentFileInfo, testFactory2.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory2.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory2.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + testFactory2.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptSignedAndEncryptedMessage_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + await testFactory2.ArrangeAsync(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptionAndSigningKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo, testFactory2.PrivateKeyFileInfo, testFactory2.Password); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptionAndSigningKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + await pgpEncryptAndSign.EncryptAndSignAsync(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo); + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptUnencryptedMessage_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpDecrypt = new PGP(decryptionKeys); + File.WriteAllText(testFactory.ContentFileInfo.FullName, testFactory.Content); + + // Act + var ex = await Assert.ThrowsAsync(async () => await pgpDecrypt.DecryptAsync(testFactory.ContentFileInfo, testFactory.DecryptedContentFileInfo)); + + // Assert + using (new AssertionScope()) + { + ex.Should().BeAssignableTo(); + ex.Message.Should().StartWith("Failed to detect encrypted content format."); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptEncryptedMessageWithWrongKey_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + await testFactory2.ArrangeAsync(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKey); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory2.PrivateKeyFileInfo, testFactory2.Password); + + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + await pgpEncrypt.EncryptAsync(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo); + var ex = await Assert.ThrowsAsync(async () => await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo)); + + // Assert + using (new AssertionScope()) + { + ex.Should().BeAssignableTo(); + ex.Message.Should().Be("Secret key for message not found."); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAndVerifyAsync_DecryptSignedAndEncryptedMessage_ShouldDecryptAndVerifyMessage(KeyType keyType) + { + // Arrange + TestFactory encryptTestFactory = new TestFactory(); + TestFactory signTestFactory = new TestFactory(); + + await encryptTestFactory.ArrangeAsync(keyType, FileType.Known); + await signTestFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptAndSignKeys = new EncryptionKeys(encryptTestFactory.PublicKeyFileInfo, signTestFactory.PrivateKeyFileInfo, signTestFactory.Password); + EncryptionKeys decryptAndVerifyKeys = new EncryptionKeys(signTestFactory.PublicKeyFileInfo, encryptTestFactory.PrivateKeyFileInfo, encryptTestFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptAndSignKeys); + PGP pgpDecryptAndVerify = new PGP(decryptAndVerifyKeys); + + // Act + await pgpEncryptAndSign.EncryptAndSignAsync(encryptTestFactory.ContentFileInfo, encryptTestFactory.EncryptedContentFileInfo); + await pgpDecryptAndVerify.DecryptAndVerifyAsync(encryptTestFactory.EncryptedContentFileInfo, encryptTestFactory.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + encryptTestFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + encryptTestFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(encryptTestFactory.DecryptedContentFileInfo.FullName).Should().Be(encryptTestFactory.Content); + } + + // Teardown + encryptTestFactory.Teardown(); + signTestFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAndVerifyAsync_DecryptSignedAndEncryptedMessageWithWrongKey_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory encryptTestFactory = new TestFactory(); + TestFactory signTestFactory = new TestFactory(); + + await encryptTestFactory.ArrangeAsync(keyType, FileType.Known); + await signTestFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptAndSignKeys = new EncryptionKeys(encryptTestFactory.PublicKeyFileInfo, encryptTestFactory.PrivateKeyFileInfo, encryptTestFactory.Password); + EncryptionKeys decryptAndVerifyKeys = new EncryptionKeys(signTestFactory.PublicKeyFileInfo, encryptTestFactory.PrivateKeyFileInfo, encryptTestFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptAndSignKeys); + PGP pgpDecryptAndVerify = new PGP(decryptAndVerifyKeys); + + // Act + await pgpEncryptAndSign.EncryptAndSignAsync(encryptTestFactory.ContentFileInfo, encryptTestFactory.EncryptedContentFileInfo); + var ex = await Assert.ThrowsAsync(async () => await pgpDecryptAndVerify.DecryptAndVerifyAsync(encryptTestFactory.EncryptedContentFileInfo, encryptTestFactory.DecryptedContentFileInfo)); + + // Assert + using (new AssertionScope()) + { + encryptTestFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + ex.Should().BeAssignableTo(); + ex.Message.Should().Be("Failed to verify file."); + } + + // Teardown + encryptTestFactory.Teardown(); + signTestFactory.Teardown(); + } + } +} diff --git a/PgpCore.Tests/UnitTests/Decrypt/DecryptAsync.Stream.cs b/PgpCore.Tests/UnitTests/Decrypt/DecryptAsync.Stream.cs new file mode 100644 index 0000000..6fc3aeb --- /dev/null +++ b/PgpCore.Tests/UnitTests/Decrypt/DecryptAsync.Stream.cs @@ -0,0 +1,588 @@ +using FluentAssertions.Execution; +using FluentAssertions; +using Org.BouncyCastle.Bcpg.OpenPgp; +using Org.BouncyCastle.Bcpg; +using Org.BouncyCastle.Security; +using PgpCore.Models; +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using Xunit; + +namespace PgpCore.Tests.UnitTests.Decrypt +{ + public class DecryptAsync_Stream : TestBase + { + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptEncryptedMessage_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + await pgpEncrypt.EncryptAsync(testFactory.ContentStream, outputFileStream); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptBinaryEncryptedMessage_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + await pgpEncrypt.EncryptAsync(testFactory.ContentStream, outputFileStream, armor: false); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory.EncryptedContentFileInfo.FullName).Should().NotStartWith("-----BEGIN PGP MESSAGE-----"); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetCompressionAlgorithimTags))] + public async Task DecryptAsync_DecryptEncryptedCompressedMessage_ShouldDecryptMessage(CompressionAlgorithmTag compressionAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + CompressionAlgorithm = compressionAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + await pgpEncrypt.EncryptAsync(testFactory.ContentStream, outputFileStream); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetCompressionAlgorithimTags))] + public async Task DecryptAsync_DecryptBinaryEncryptedCompressedMessage_ShouldDecryptMessage(CompressionAlgorithmTag compressionAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + CompressionAlgorithm = compressionAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + await pgpEncrypt.EncryptAsync(testFactory.ContentStream, outputFileStream, armor: false); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory.EncryptedContentFileInfo.FullName).Should().NotStartWith("-----BEGIN PGP MESSAGE-----"); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetHashAlgorithimTags))] + public async Task DecryptAsync_DecryptEncryptedWithSpecifiedHashAlgorithim_ShouldDecryptMessage(HashAlgorithmTag hashAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + HashAlgorithmTag = hashAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + await pgpEncrypt.EncryptAsync(testFactory.ContentStream, outputFileStream); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetHashAlgorithimTags))] + public async Task DecryptAsync_DecryptBinaryEncryptedWithSpecifiedHashAlgorithim_ShouldDecryptMessage(HashAlgorithmTag hashAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + HashAlgorithmTag = hashAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + await pgpEncrypt.EncryptAsync(testFactory.ContentStream, outputFileStream, armor: false); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory.EncryptedContentFileInfo.FullName).Should().NotStartWith("-----BEGIN PGP MESSAGE-----"); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetSymmetricAlgorithimTags))] + public async Task DecryptAsync_DecryptEncryptedWithSpecifiedSymetricKeyAlgorithim_ShouldDecryptMessage(SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = symmetricKeyAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + await pgpEncrypt.EncryptAsync(testFactory.ContentStream, outputFileStream); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentStream, outputFileStream); + + PgpInspectResult pgpInspectResult = await pgpDecrypt.InspectAsync(testFactory.EncryptedContentStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + pgpInspectResult.SymmetricKeyAlgorithm.Should().Be(symmetricKeyAlgorithmTag); + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetSymmetricAlgorithimTags))] + public async Task DecryptAsync_DecryptBinaryEncryptedWithSpecifiedSymetricKeyAlgorithim_ShouldDecryptMessage(SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = symmetricKeyAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + await pgpEncrypt.EncryptAsync(testFactory.ContentStream, outputFileStream, armor: false); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentStream, outputFileStream); + + PgpInspectResult pgpInspectResult = await pgpDecrypt.InspectAsync(testFactory.EncryptedContentStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory.EncryptedContentFileInfo.FullName).Should().NotStartWith("-----BEGIN PGP MESSAGE-----"); + } + + pgpInspectResult.SymmetricKeyAlgorithm.Should().Be(symmetricKeyAlgorithmTag); + + // Teardown + testFactory.Teardown(); + } + + [Fact] + public async Task DecryptAsync_DecryptEncryptedWithNullSymetricKeyAlgorithim_ShouldThrowException() + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = SymmetricKeyAlgorithmTag.Null + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + + // Assert + using (new AssertionScope()) + { + using (Stream outputStream = testFactory.EncryptedContentFileInfo.Create()) + { + Func act = async () => await pgpEncrypt.EncryptAsync(testFactory.ContentStream, outputStream); + await act.Should().ThrowAsync().Where(e => e.Message == "unknown symmetric algorithm: Null"); + } + } + + // Teardown + testFactory.Teardown(); + } + + [Fact] + public async Task DecryptAsync_DecryptEncryptedWithSaferSymetricKeyAlgorithim_ShouldThrowException() + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = SymmetricKeyAlgorithmTag.Safer + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + + // Assert + using (new AssertionScope()) + { + using (Stream outputStream = testFactory.DecryptedContentFileInfo.Create()) + { + Func act = async () => await pgpEncrypt.EncryptAsync(testFactory.ContentStream, outputStream); + await act.Should().ThrowAsync().Where(e => e.Message == "Algorithm SAFER not recognised."); + } + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptEncryptedWithMultipleKeys_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + await testFactory2.ArrangeAsync(KeyType.Generated, FileType.Known); + + List keys = new List() + { + testFactory.PublicKeyStream, + testFactory2.PublicKeyStream + }; + + EncryptionKeys encryptionKeys = new EncryptionKeys(keys, testFactory.PrivateKeyStream, testFactory.Password); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory2.PrivateKeyStream, testFactory2.Password); + + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + await pgpEncrypt.EncryptAsync(testFactory.ContentStream, outputFileStream); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentStream, outputFileStream); + + using (Stream outputFileStream = testFactory2.DecryptedContentFileInfo.Create()) + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory2.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory2.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + testFactory2.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptSignedAndEncryptedMessage_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + await testFactory2.ArrangeAsync(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptionAndSigningKeys = new EncryptionKeys(testFactory.PublicKeyStream, testFactory2.PrivateKeyStream, testFactory2.Password); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptionAndSigningKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + await pgpEncryptAndSign.EncryptAndSignAsync(testFactory.ContentStream, outputFileStream); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptUnencryptedMessage_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpDecrypt = new PGP(decryptionKeys); + File.WriteAllText(testFactory.ContentFileInfo.FullName, testFactory.Content); + + // Act + + // Assert + using (new AssertionScope()) + { + using (Stream outputStream = testFactory.DecryptedContentFileInfo.Create()) + { + Func act = async () => await pgpDecrypt.DecryptAsync(testFactory.ContentStream, outputStream); + await act.Should().ThrowAsync().Where(e => e.Message.StartsWith("Failed to detect encrypted content format.")); + } + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptEncryptedMessageWithWrongKey_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + await testFactory2.ArrangeAsync(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory2.PrivateKeyStream, testFactory2.Password); + + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputStream = testFactory.EncryptedContentFileInfo.Create()) + await pgpEncrypt.EncryptAsync(testFactory.ContentStream, outputStream); + + // Assert + using (new AssertionScope()) + { + using (Stream outputStream = testFactory.DecryptedContentFileInfo.Create()) + { + Func act = async () => await pgpDecrypt.DecryptAsync(testFactory.EncryptedContentStream, outputStream); + await act.Should().ThrowAsync().Where(e => e.Message == "Secret key for message not found."); + } + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAndVerifyAsync_DecryptSignedAndEncryptedMessage_ShouldDecryptAndVerifyMessage(KeyType keyType) + { + // Arrange + TestFactory encryptTestFactory = new TestFactory(); + TestFactory signTestFactory = new TestFactory(); + + await encryptTestFactory.ArrangeAsync(keyType, FileType.Known); + await signTestFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptAndSignKeys = new EncryptionKeys(encryptTestFactory.PublicKeyStream, signTestFactory.PrivateKeyStream, signTestFactory.Password); + EncryptionKeys decryptAndVerifyKeys = new EncryptionKeys(signTestFactory.PublicKeyStream, encryptTestFactory.PrivateKeyStream, encryptTestFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptAndSignKeys); + PGP pgpDecryptAndVerify = new PGP(decryptAndVerifyKeys); + + // Act + using (Stream outputFileStream = encryptTestFactory.EncryptedContentFileInfo.Create()) + await pgpEncryptAndSign.EncryptAndSignAsync(encryptTestFactory.ContentStream, outputFileStream); + + using (Stream outputFileStream = signTestFactory.DecryptedContentFileInfo.Create()) + await pgpDecryptAndVerify.DecryptAndVerifyAsync(encryptTestFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + encryptTestFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + signTestFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(signTestFactory.DecryptedContentFileInfo.FullName).Should().Be(encryptTestFactory.Content); + } + + // Teardown + encryptTestFactory.Teardown(); + signTestFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAndVerifyAsync_DecryptSignedAndEncryptedMessageWithWrongKey_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory encryptTestFactory = new TestFactory(); + TestFactory signTestFactory = new TestFactory(); + + await encryptTestFactory.ArrangeAsync(keyType, FileType.Known); + await signTestFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptAndSignKeys = new EncryptionKeys(encryptTestFactory.PublicKeyStream, encryptTestFactory.PrivateKeyStream, encryptTestFactory.Password); + EncryptionKeys decryptAndVerifyKeys = new EncryptionKeys(signTestFactory.PublicKeyStream, encryptTestFactory.PrivateKeyStream, encryptTestFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptAndSignKeys); + PGP pgpDecryptAndVerify = new PGP(decryptAndVerifyKeys); + + // Act + using (Stream outputFileStream = encryptTestFactory.EncryptedContentFileInfo.Create()) + await pgpEncryptAndSign.EncryptAndSignAsync(encryptTestFactory.ContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + using (Stream inputStream = encryptTestFactory.EncryptedContentFileInfo.OpenRead()) + using (Stream outputStream = signTestFactory.DecryptedContentFileInfo.Create()) + { + Func act = async () => await pgpDecryptAndVerify.DecryptAndVerifyAsync(inputStream, outputStream); + await act.Should().ThrowAsync().Where(e => e.Message == "Failed to verify file."); + } + + encryptTestFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + } + + // Teardown + encryptTestFactory.Teardown(); + signTestFactory.Teardown(); + } + } +} diff --git a/PgpCore.Tests/UnitTests/Decrypt/DecryptAsync.String.cs b/PgpCore.Tests/UnitTests/Decrypt/DecryptAsync.String.cs new file mode 100644 index 0000000..3e87f60 --- /dev/null +++ b/PgpCore.Tests/UnitTests/Decrypt/DecryptAsync.String.cs @@ -0,0 +1,414 @@ +using FluentAssertions.Execution; +using FluentAssertions; +using Org.BouncyCastle.Bcpg.OpenPgp; +using Org.BouncyCastle.Bcpg; +using Org.BouncyCastle.Security; +using PgpCore.Models; +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using Xunit; + +namespace PgpCore.Tests.UnitTests.Decrypt +{ + public class DecryptAsync_String : TestBase + { + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptEncryptedMessage_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKey); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKey, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + string encryptedContent = await pgpEncrypt.EncryptAsync(testFactory.Content); + string decryptedContent = await pgpDecrypt.DecryptAsync(encryptedContent); + + // Assert + using (new AssertionScope()) + { + encryptedContent.Should().NotBeNullOrEmpty(); + decryptedContent.Should().NotBeNullOrEmpty(); + decryptedContent.Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetCompressionAlgorithimTags))] + public async Task DecryptAsync_DecryptEncryptedCompressedMessage_ShouldDecryptMessage(CompressionAlgorithmTag compressionAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKey); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKey, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + CompressionAlgorithm = compressionAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + string encryptedContent = await pgpEncrypt.EncryptAsync(testFactory.Content); + string decryptedContent = await pgpDecrypt.DecryptAsync(encryptedContent); + + // Assert + using (new AssertionScope()) + { + encryptedContent.Should().NotBeNullOrEmpty(); + decryptedContent.Should().NotBeNullOrEmpty(); + decryptedContent.Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetHashAlgorithimTags))] + public async Task DecryptAsync_DecryptEncryptedWithSpecifiedHashAlgorithim_ShouldDecryptMessage(HashAlgorithmTag hashAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKey); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKey, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + HashAlgorithmTag = hashAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + string encryptedContent = await pgpEncrypt.EncryptAsync(testFactory.Content); + string decryptedContent = await pgpDecrypt.DecryptAsync(encryptedContent); + + // Assert + using (new AssertionScope()) + { + encryptedContent.Should().NotBeNullOrEmpty(); + decryptedContent.Should().NotBeNullOrEmpty(); + decryptedContent.Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetSymmetricAlgorithimTags))] + public async Task DecryptAsync_DecryptEncryptedWithSpecifiedSymetricKeyAlgorithim_ShouldDecryptMessage(SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKey); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKey, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = symmetricKeyAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + string encryptedContent = await pgpEncrypt.EncryptAsync(testFactory.Content); + string decryptedContent = await pgpDecrypt.DecryptAsync(encryptedContent); + + PgpInspectResult pgpInspectResult = await pgpDecrypt.InspectAsync(encryptedContent); + + // Assert + using (new AssertionScope()) + { + encryptedContent.Should().NotBeNullOrEmpty(); + decryptedContent.Should().NotBeNullOrEmpty(); + decryptedContent.Should().Be(testFactory.Content); + } + + pgpInspectResult.SymmetricKeyAlgorithm.Should().Be(symmetricKeyAlgorithmTag); + + // Teardown + testFactory.Teardown(); + } + + [Fact] + public async Task DecryptAsync_DecryptEncryptedWithNullSymetricKeyAlgorithim_ShouldThrowException() + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKey); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKey, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = SymmetricKeyAlgorithmTag.Null + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + + // Assert + using (new AssertionScope()) + { + using (Stream outputStream = testFactory.EncryptedContentFileInfo.Create()) + { + Func act = async () => await pgpEncrypt.EncryptAsync(testFactory.Content); + await act.Should().ThrowAsync().Where(e => e.Message == "unknown symmetric algorithm: Null"); + } + } + + // Teardown + testFactory.Teardown(); + } + + [Fact] + public async Task DecryptAsync_DecryptEncryptedWithSaferSymetricKeyAlgorithim_ShouldThrowException() + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKey); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKey, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = SymmetricKeyAlgorithmTag.Safer + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + + // Assert + using (new AssertionScope()) + { + using (Stream outputStream = testFactory.DecryptedContentFileInfo.Create()) + { + Func act = async () => await pgpEncrypt.EncryptAsync(testFactory.Content); + await act.Should().ThrowAsync().Where(e => e.Message == "Algorithm SAFER not recognised."); + } + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptEncryptedWithMultipleKeys_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + await testFactory2.ArrangeAsync(KeyType.Generated, FileType.Known); + + List keys = new List() + { + testFactory.PublicKey, + testFactory2.PublicKey + }; + + EncryptionKeys encryptionKeys = new EncryptionKeys(keys, testFactory.PrivateKey, testFactory.Password); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory2.PrivateKey, testFactory2.Password); + + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + string encrypted = await pgpEncrypt.EncryptAsync(testFactory.Content); + string decrypted = await pgpDecrypt.DecryptAsync(encrypted); + string decrypted2 = await pgpDecrypt.DecryptAsync(encrypted); + + // Assert + using (new AssertionScope()) + { + encrypted.Should().NotBeNullOrEmpty(); + decrypted.Should().NotBeNullOrEmpty(); + decrypted2.Should().NotBeNullOrEmpty(); + decrypted.Should().Be(testFactory.Content); + decrypted2.Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + testFactory2.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptSignedAndEncryptedMessage_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + await testFactory2.ArrangeAsync(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptionAndSigningKeys = new EncryptionKeys(testFactory.PublicKey, testFactory2.PrivateKey, testFactory2.Password); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKey, testFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptionAndSigningKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + string encryptedAndSigned = await pgpEncryptAndSign.EncryptAndSignAsync(testFactory.Content); + string decrypted = await pgpDecrypt.DecryptAsync(encryptedAndSigned); + + // Assert + using (new AssertionScope()) + { + encryptedAndSigned.Should().NotBeNullOrEmpty(); + decrypted.Should().NotBeNullOrEmpty(); + decrypted.Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptUnencryptedMessage_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKey, testFactory.Password); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + + // Assert + using (new AssertionScope()) + { + using (Stream outputStream = testFactory.DecryptedContentFileInfo.Create()) + { + Func act = async () => await pgpDecrypt.DecryptAsync(testFactory.Content); + await act.Should().ThrowAsync().Where(e => e.Message.StartsWith("Failed to detect encrypted content format.")); + } + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAsync_DecryptEncryptedMessageWithWrongKey_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + await testFactory.ArrangeAsync(keyType, FileType.Known); + await testFactory2.ArrangeAsync(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKey); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory2.PrivateKey, testFactory2.Password); + + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + string encrypted = await pgpEncrypt.EncryptAsync(testFactory.Content); + + // Assert + using (new AssertionScope()) + { + using (Stream outputStream = testFactory.DecryptedContentFileInfo.Create()) + { + Func act = async () => await pgpDecrypt.DecryptAsync(encrypted); + await act.Should().ThrowAsync().Where(e => e.Message == "Secret key for message not found."); + } + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAndVerifyAsync_DecryptSignedAndEncryptedMessage_ShouldDecryptAndVerifyMessage(KeyType keyType) + { + // Arrange + TestFactory encryptTestFactory = new TestFactory(); + TestFactory signTestFactory = new TestFactory(); + + await encryptTestFactory.ArrangeAsync(keyType, FileType.Known); + await signTestFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptAndSignKeys = new EncryptionKeys(encryptTestFactory.PublicKey, signTestFactory.PrivateKey, signTestFactory.Password); + EncryptionKeys decryptAndVerifyKeys = new EncryptionKeys(signTestFactory.PublicKey, encryptTestFactory.PrivateKey, encryptTestFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptAndSignKeys); + PGP pgpDecryptAndVerify = new PGP(decryptAndVerifyKeys); + + // Act + string encryptedAndSigned = await pgpEncryptAndSign.EncryptAndSignAsync(encryptTestFactory.Content); + string decryptedAndVerified = await pgpDecryptAndVerify.DecryptAndVerifyAsync(encryptedAndSigned); + + // Assert + using (new AssertionScope()) + { + encryptedAndSigned.Should().NotBeNullOrEmpty(); + decryptedAndVerified.Should().NotBeNullOrEmpty(); + decryptedAndVerified.Should().Be(encryptTestFactory.Content); + } + + // Teardown + encryptTestFactory.Teardown(); + signTestFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public async Task DecryptAndVerifyAsync_DecryptSignedAndEncryptedMessageWithWrongKey_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory encryptTestFactory = new TestFactory(); + TestFactory signTestFactory = new TestFactory(); + + await encryptTestFactory.ArrangeAsync(keyType, FileType.Known); + await signTestFactory.ArrangeAsync(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptAndSignKeys = new EncryptionKeys(encryptTestFactory.PublicKey, encryptTestFactory.PrivateKey, encryptTestFactory.Password); + EncryptionKeys decryptAndVerifyKeys = new EncryptionKeys(signTestFactory.PublicKey, encryptTestFactory.PrivateKey, encryptTestFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptAndSignKeys); + PGP pgpDecryptAndVerify = new PGP(decryptAndVerifyKeys); + + // Act + string encryptedAndSigned = await pgpEncryptAndSign.EncryptAndSignAsync(encryptTestFactory.Content); + + // Assert + using (new AssertionScope()) + { + encryptedAndSigned.Should().NotBeNullOrEmpty(); + Func act = async () => await pgpDecryptAndVerify.DecryptAndVerifyAsync(encryptedAndSigned); + await act.Should().ThrowAsync().Where(e => e.Message == "Failed to verify file."); + } + + // Teardown + encryptTestFactory.Teardown(); + signTestFactory.Teardown(); + } + } +} diff --git a/PgpCore.Tests/UnitTests/Decrypt/DecryptSync.File.cs b/PgpCore.Tests/UnitTests/Decrypt/DecryptSync.File.cs new file mode 100644 index 0000000..a47893d --- /dev/null +++ b/PgpCore.Tests/UnitTests/Decrypt/DecryptSync.File.cs @@ -0,0 +1,538 @@ +using FluentAssertions; +using FluentAssertions.Execution; +using Org.BouncyCastle.Bcpg; +using Org.BouncyCastle.Bcpg.OpenPgp; +using Org.BouncyCastle.Security; +using PgpCore.Models; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace PgpCore.Tests.UnitTests.Decrypt +{ + public class DecryptSync_File : TestBase + { + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptEncryptedMessage_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + pgpEncrypt.Encrypt(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo); + pgpDecrypt.Decrypt(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptBinaryEncryptedMessage_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + pgpEncrypt.Encrypt(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo, armor: false); + pgpDecrypt.Decrypt(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory.EncryptedContentFileInfo.FullName).Should().NotStartWith("-----BEGIN PGP MESSAGE-----"); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetCompressionAlgorithimTags))] + public void Decrypt_DecryptEncryptedCompressedMessage_ShouldDecryptMessage(CompressionAlgorithmTag compressionAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + CompressionAlgorithm = compressionAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + pgpEncrypt.Encrypt(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo); + pgpDecrypt.Decrypt(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetCompressionAlgorithimTags))] + public void Decrypt_DecryptBinaryEncryptedCompressedMessage_ShouldDecryptMessage(CompressionAlgorithmTag compressionAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + CompressionAlgorithm = compressionAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + pgpEncrypt.Encrypt(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo, armor: false); + pgpDecrypt.Decrypt(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory.EncryptedContentFileInfo.FullName).Should().NotStartWith("-----BEGIN PGP MESSAGE-----"); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetHashAlgorithimTags))] + public void Decrypt_DecryptEncryptedWithSpecifiedHashAlgorithim_ShouldDecryptMessage(HashAlgorithmTag hashAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + HashAlgorithmTag = hashAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + pgpEncrypt.Encrypt(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo); + pgpDecrypt.Decrypt(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetHashAlgorithimTags))] + public void Decrypt_DecryptBinaryEncryptedWithSpecifiedHashAlgorithim_ShouldDecryptMessage(HashAlgorithmTag hashAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + HashAlgorithmTag = hashAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + pgpEncrypt.Encrypt(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo, armor: false); + pgpDecrypt.Decrypt(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory.EncryptedContentFileInfo.FullName).Should().NotStartWith("-----BEGIN PGP MESSAGE-----"); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetSymmetricAlgorithimTags))] + public void Decrypt_DecryptEncryptedWithSpecifiedSymetricKeyAlgorithim_ShouldDecryptMessage(SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = symmetricKeyAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + pgpEncrypt.Encrypt(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo); + pgpDecrypt.Decrypt(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + PgpInspectResult pgpInspectResult = pgpDecrypt.Inspect(testFactory.EncryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + pgpInspectResult.SymmetricKeyAlgorithm.Should().Be(symmetricKeyAlgorithmTag); + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetSymmetricAlgorithimTags))] + public void Decrypt_DecryptBinaryEncryptedWithSpecifiedSymetricKeyAlgorithim_ShouldDecryptMessage(SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = symmetricKeyAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + pgpEncrypt.Encrypt(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo, armor: false); + pgpDecrypt.Decrypt(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + PgpInspectResult pgpInspectResult = pgpDecrypt.Inspect(testFactory.EncryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory.EncryptedContentFileInfo.FullName).Should().NotStartWith("-----BEGIN PGP MESSAGE-----"); + } + + pgpInspectResult.SymmetricKeyAlgorithm.Should().Be(symmetricKeyAlgorithmTag); + + // Teardown + testFactory.Teardown(); + } + + [Fact] + public void Decrypt_DecryptEncryptedWithNullSymetricKeyAlgorithim_ShouldThrowException() + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = SymmetricKeyAlgorithmTag.Null + }; + + // Act + var ex = Assert.Throws(() => pgpEncrypt.Encrypt(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo)); + + // Assert + using (new AssertionScope()) + { + ex.Should().BeAssignableTo(); + ex.Message.Should().Be("unknown symmetric algorithm: Null"); + } + + // Teardown + testFactory.Teardown(); + } + + [Fact] + public void Decrypt_DecryptEncryptedWithSaferSymetricKeyAlgorithim_ShouldThrowException() + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = SymmetricKeyAlgorithmTag.Safer + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + var ex = Assert.Throws(() => pgpEncrypt.Encrypt(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo)); + + // Assert + using (new AssertionScope()) + { + ex.Should().BeAssignableTo(); + ex.Message.Should().Be("Algorithm SAFER not recognised."); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptEncryptedWithMultipleKeys_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + testFactory2.Arrange(KeyType.Generated, FileType.Known); + + List keys = new List() + { + testFactory.PublicKeyFileInfo, + testFactory2.PublicKeyFileInfo + }; + + EncryptionKeys encryptionKeys = new EncryptionKeys(keys, testFactory.PrivateKeyFileInfo, testFactory.Password); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory2.PrivateKeyFileInfo, testFactory2.Password); + + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + pgpEncrypt.Encrypt(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo); + pgpEncrypt.Decrypt(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + pgpDecrypt.Decrypt(testFactory.EncryptedContentFileInfo, testFactory2.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory2.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory2.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + testFactory2.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptSignedAndEncryptedMessage_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + testFactory2.Arrange(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptionAndSigningKeys = new EncryptionKeys(testFactory.PublicKeyFileInfo, testFactory2.PrivateKeyFileInfo, testFactory2.Password); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptionAndSigningKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + pgpEncryptAndSign.EncryptAndSign(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo); + pgpDecrypt.Decrypt(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptUnencryptedMessage_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyFileInfo, testFactory.Password); + PGP pgpDecrypt = new PGP(decryptionKeys); + File.WriteAllText(testFactory.ContentFileInfo.FullName, testFactory.Content); + + // Act + var ex = Assert.Throws(() => pgpDecrypt.Decrypt(testFactory.ContentFileInfo, testFactory.DecryptedContentFileInfo)); + + // Assert + using (new AssertionScope()) + { + ex.Should().BeAssignableTo(); + ex.Message.Should().StartWith("Failed to detect encrypted content format."); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptEncryptedMessageWithWrongKey_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + testFactory2.Arrange(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKey); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory2.PrivateKeyFileInfo, testFactory2.Password); + + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + pgpEncrypt.Encrypt(testFactory.ContentFileInfo, testFactory.EncryptedContentFileInfo); + var ex = Assert.Throws(() => pgpDecrypt.Decrypt(testFactory.EncryptedContentFileInfo, testFactory.DecryptedContentFileInfo)); + + // Assert + using (new AssertionScope()) + { + ex.Should().BeAssignableTo(); + ex.Message.Should().Be("Secret key for message not found."); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void DecryptAndVerify_DecryptSignedAndEncryptedMessage_ShouldDecryptAndVerifyMessage(KeyType keyType) + { + // Arrange + TestFactory encryptTestFactory = new TestFactory(); + TestFactory signTestFactory = new TestFactory(); + + encryptTestFactory.Arrange(keyType, FileType.Known); + signTestFactory.Arrange(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptAndSignKeys = new EncryptionKeys(encryptTestFactory.PublicKeyFileInfo, signTestFactory.PrivateKeyFileInfo, signTestFactory.Password); + EncryptionKeys decryptAndVerifyKeys = new EncryptionKeys(signTestFactory.PublicKeyFileInfo, encryptTestFactory.PrivateKeyFileInfo, encryptTestFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptAndSignKeys); + PGP pgpDecryptAndVerify = new PGP(decryptAndVerifyKeys); + + // Act + pgpEncryptAndSign.EncryptAndSign(encryptTestFactory.ContentFileInfo, encryptTestFactory.EncryptedContentFileInfo); + pgpDecryptAndVerify.DecryptAndVerify(encryptTestFactory.EncryptedContentFileInfo, encryptTestFactory.DecryptedContentFileInfo); + + // Assert + using (new AssertionScope()) + { + encryptTestFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + encryptTestFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(encryptTestFactory.DecryptedContentFileInfo.FullName).Should().Be(encryptTestFactory.Content); + } + + // Teardown + encryptTestFactory.Teardown(); + signTestFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void DecryptAndVerify_DecryptSignedAndEncryptedMessageWithWrongKey_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory encryptTestFactory = new TestFactory(); + TestFactory signTestFactory = new TestFactory(); + + encryptTestFactory.Arrange(keyType, FileType.Known); + signTestFactory.Arrange(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptAndSignKeys = new EncryptionKeys(encryptTestFactory.PublicKeyFileInfo, encryptTestFactory.PrivateKeyFileInfo, encryptTestFactory.Password); + EncryptionKeys decryptAndVerifyKeys = new EncryptionKeys(signTestFactory.PublicKeyFileInfo, encryptTestFactory.PrivateKeyFileInfo, encryptTestFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptAndSignKeys); + PGP pgpDecryptAndVerify = new PGP(decryptAndVerifyKeys); + + // Act + pgpEncryptAndSign.EncryptAndSign(encryptTestFactory.ContentFileInfo, encryptTestFactory.EncryptedContentFileInfo); + var ex = Assert.Throws(() => pgpDecryptAndVerify.DecryptAndVerify(encryptTestFactory.EncryptedContentFileInfo, encryptTestFactory.DecryptedContentFileInfo)); + + // Assert + using (new AssertionScope()) + { + encryptTestFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + ex.Should().BeAssignableTo(); + ex.Message.Should().Be("Failed to verify file."); + } + + // Teardown + encryptTestFactory.Teardown(); + signTestFactory.Teardown(); + } + } +} diff --git a/PgpCore.Tests/UnitTests/Decrypt/DecryptSync.Stream.cs b/PgpCore.Tests/UnitTests/Decrypt/DecryptSync.Stream.cs new file mode 100644 index 0000000..6386d6f --- /dev/null +++ b/PgpCore.Tests/UnitTests/Decrypt/DecryptSync.Stream.cs @@ -0,0 +1,587 @@ +using FluentAssertions.Execution; +using FluentAssertions; +using Org.BouncyCastle.Bcpg.OpenPgp; +using Org.BouncyCastle.Bcpg; +using Org.BouncyCastle.Security; +using PgpCore.Models; +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using Xunit; + +namespace PgpCore.Tests.UnitTests.Decrypt +{ + public class DecryptSync_Stream : TestBase + { + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptEncryptedMessage_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + pgpEncrypt.Encrypt(testFactory.ContentStream, outputFileStream); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + pgpDecrypt.Decrypt(testFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptBinaryEncryptedMessage_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + pgpEncrypt.Encrypt(testFactory.ContentStream, outputFileStream, armor: false); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + pgpDecrypt.Decrypt(testFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory.EncryptedContentFileInfo.FullName).Should().NotStartWith("-----BEGIN PGP MESSAGE-----"); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetCompressionAlgorithimTags))] + public void Decrypt_DecryptEncryptedCompressedMessage_ShouldDecryptMessage(CompressionAlgorithmTag compressionAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + CompressionAlgorithm = compressionAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + pgpEncrypt.Encrypt(testFactory.ContentStream, outputFileStream); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + pgpDecrypt.Decrypt(testFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetCompressionAlgorithimTags))] + public void Decrypt_DecryptBinaryEncryptedCompressedMessage_ShouldDecryptMessage(CompressionAlgorithmTag compressionAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + CompressionAlgorithm = compressionAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + pgpEncrypt.Encrypt(testFactory.ContentStream, outputFileStream, armor: false); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + pgpDecrypt.Decrypt(testFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory.EncryptedContentFileInfo.FullName).Should().NotStartWith("-----BEGIN PGP MESSAGE-----"); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetHashAlgorithimTags))] + public void Decrypt_DecryptEncryptedWithSpecifiedHashAlgorithim_ShouldDecryptMessage(HashAlgorithmTag hashAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + HashAlgorithmTag = hashAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + pgpEncrypt.Encrypt(testFactory.ContentStream, outputFileStream); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + pgpDecrypt.Decrypt(testFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetHashAlgorithimTags))] + public void Decrypt_DecryptBinaryEncryptedWithSpecifiedHashAlgorithim_ShouldDecryptMessage(HashAlgorithmTag hashAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + HashAlgorithmTag = hashAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + pgpEncrypt.Encrypt(testFactory.ContentStream, outputFileStream, armor: false); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + pgpDecrypt.Decrypt(testFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory.EncryptedContentFileInfo.FullName).Should().NotStartWith("-----BEGIN PGP MESSAGE-----"); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetSymmetricAlgorithimTags))] + public void Decrypt_DecryptEncryptedWithSpecifiedSymetricKeyAlgorithim_ShouldDecryptMessage(SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = symmetricKeyAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + pgpEncrypt.Encrypt(testFactory.ContentStream, outputFileStream); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + pgpDecrypt.Decrypt(testFactory.EncryptedContentStream, outputFileStream); + + PgpInspectResult pgpInspectResult = pgpDecrypt.Inspect(testFactory.EncryptedContentStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + pgpInspectResult.SymmetricKeyAlgorithm.Should().Be(symmetricKeyAlgorithmTag); + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetSymmetricAlgorithimTags))] + public void Decrypt_DecryptBinaryEncryptedWithSpecifiedSymetricKeyAlgorithim_ShouldDecryptMessage(SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = symmetricKeyAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + pgpEncrypt.Encrypt(testFactory.ContentStream, outputFileStream, armor: false); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + pgpDecrypt.Decrypt(testFactory.EncryptedContentStream, outputFileStream); + + PgpInspectResult pgpInspectResult = pgpDecrypt.Inspect(testFactory.EncryptedContentStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory.EncryptedContentFileInfo.FullName).Should().NotStartWith("-----BEGIN PGP MESSAGE-----"); + } + + pgpInspectResult.SymmetricKeyAlgorithm.Should().Be(symmetricKeyAlgorithmTag); + + // Teardown + testFactory.Teardown(); + } + + [Fact] + public void Decrypt_DecryptEncryptedWithNullSymetricKeyAlgorithim_ShouldThrowException() + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = SymmetricKeyAlgorithmTag.Null + }; + + // Act + + // Assert + using (new AssertionScope()) + { + using (Stream outputStream = testFactory.EncryptedContentFileInfo.Create()) + { + Action act = () => pgpEncrypt.Encrypt(testFactory.ContentStream, outputStream); + act.Should().Throw().Where(e => e.Message == "unknown symmetric algorithm: Null"); + } + } + + // Teardown + testFactory.Teardown(); + } + + [Fact] + public void Decrypt_DecryptEncryptedWithSaferSymetricKeyAlgorithim_ShouldThrowException() + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = SymmetricKeyAlgorithmTag.Safer + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + + // Assert + using (new AssertionScope()) + { + using (Stream outputStream = testFactory.DecryptedContentFileInfo.Create()) + { + Action act = () => pgpEncrypt.Encrypt(testFactory.ContentStream, outputStream); + act.Should().Throw().Where(e => e.Message == "Algorithm SAFER not recognised."); + } + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptEncryptedWithMultipleKeys_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + testFactory2.Arrange(KeyType.Generated, FileType.Known); + + List keys = new List() + { + testFactory.PublicKeyStream, + testFactory2.PublicKeyStream + }; + + EncryptionKeys encryptionKeys = new EncryptionKeys(keys, testFactory.PrivateKeyStream, testFactory.Password); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory2.PrivateKeyStream, testFactory2.Password); + + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + pgpEncrypt.Encrypt(testFactory.ContentStream, outputFileStream); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + pgpDecrypt.Decrypt(testFactory.EncryptedContentStream, outputFileStream); + + using (Stream outputFileStream = testFactory2.DecryptedContentFileInfo.Create()) + pgpDecrypt.Decrypt(testFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory2.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + File.ReadAllText(testFactory2.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + testFactory2.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptSignedAndEncryptedMessage_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + testFactory2.Arrange(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptionAndSigningKeys = new EncryptionKeys(testFactory.PublicKeyStream, testFactory2.PrivateKeyStream, testFactory2.Password); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptionAndSigningKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputFileStream = testFactory.EncryptedContentFileInfo.Create()) + pgpEncryptAndSign.EncryptAndSign(testFactory.ContentStream, outputFileStream); + + using (Stream outputFileStream = testFactory.DecryptedContentFileInfo.Create()) + pgpDecrypt.Decrypt(testFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + testFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + testFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(testFactory.DecryptedContentFileInfo.FullName).Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptUnencryptedMessage_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKeyStream, testFactory.Password); + PGP pgpDecrypt = new PGP(decryptionKeys); + File.WriteAllText(testFactory.ContentFileInfo.FullName, testFactory.Content); + + // Act + + // Assert + using (new AssertionScope()) + { + using (Stream outputStream = testFactory.DecryptedContentFileInfo.Create()) + { + Action act = () => pgpDecrypt.Decrypt(testFactory.ContentStream, outputStream); + act.Should().Throw().Where(e => e.Message.StartsWith("Failed to detect encrypted content format.")); + } + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptEncryptedMessageWithWrongKey_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + testFactory2.Arrange(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKeyStream); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory2.PrivateKeyStream, testFactory2.Password); + + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + using (Stream outputStream = testFactory.EncryptedContentFileInfo.Create()) + pgpEncrypt.Encrypt(testFactory.ContentStream, outputStream); + + // Assert + using (new AssertionScope()) + { + using (Stream outputStream = testFactory.DecryptedContentFileInfo.Create()) + { + Action act = () => pgpDecrypt.Decrypt(testFactory.EncryptedContentStream, outputStream); + act.Should().Throw().Where(e => e.Message == "Secret key for message not found."); + } + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void DecryptAndVerify_DecryptSignedAndEncryptedMessage_ShouldDecryptAndVerifyMessage(KeyType keyType) + { + // Arrange + TestFactory encryptTestFactory = new TestFactory(); + TestFactory signTestFactory = new TestFactory(); + + encryptTestFactory.Arrange(keyType, FileType.Known); + signTestFactory.Arrange(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptAndSignKeys = new EncryptionKeys(encryptTestFactory.PublicKeyStream, signTestFactory.PrivateKeyStream, signTestFactory.Password); + EncryptionKeys decryptAndVerifyKeys = new EncryptionKeys(signTestFactory.PublicKeyStream, encryptTestFactory.PrivateKeyStream, encryptTestFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptAndSignKeys); + PGP pgpDecryptAndVerify = new PGP(decryptAndVerifyKeys); + + // Act + using (Stream outputFileStream = encryptTestFactory.EncryptedContentFileInfo.Create()) + pgpEncryptAndSign.EncryptAndSign(encryptTestFactory.ContentStream, outputFileStream); + + using (Stream outputFileStream = signTestFactory.DecryptedContentFileInfo.Create()) + pgpDecryptAndVerify.DecryptAndVerify(encryptTestFactory.EncryptedContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + encryptTestFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + signTestFactory.DecryptedContentFileInfo.Exists.Should().BeTrue(); + File.ReadAllText(signTestFactory.DecryptedContentFileInfo.FullName).Should().Be(encryptTestFactory.Content); + } + + // Teardown + encryptTestFactory.Teardown(); + signTestFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void DecryptAndVerify_DecryptSignedAndEncryptedMessageWithWrongKey_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory encryptTestFactory = new TestFactory(); + TestFactory signTestFactory = new TestFactory(); + + encryptTestFactory.Arrange(keyType, FileType.Known); + signTestFactory.Arrange(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptAndSignKeys = new EncryptionKeys(encryptTestFactory.PublicKeyStream, encryptTestFactory.PrivateKeyStream, encryptTestFactory.Password); + EncryptionKeys decryptAndVerifyKeys = new EncryptionKeys(signTestFactory.PublicKeyStream, encryptTestFactory.PrivateKeyStream, encryptTestFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptAndSignKeys); + PGP pgpDecryptAndVerify = new PGP(decryptAndVerifyKeys); + + // Act + using (Stream outputFileStream = encryptTestFactory.EncryptedContentFileInfo.Create()) + pgpEncryptAndSign.EncryptAndSign(encryptTestFactory.ContentStream, outputFileStream); + + // Assert + using (new AssertionScope()) + { + using (Stream inputStream = encryptTestFactory.EncryptedContentFileInfo.OpenRead()) + using (Stream outputStream = signTestFactory.DecryptedContentFileInfo.Create()) + { + Action act = () => pgpDecryptAndVerify.DecryptAndVerify(inputStream, outputStream); + act.Should().Throw().Where(e => e.Message == "Failed to verify file."); + } + + encryptTestFactory.EncryptedContentFileInfo.Exists.Should().BeTrue(); + } + + // Teardown + encryptTestFactory.Teardown(); + signTestFactory.Teardown(); + } + } +} diff --git a/PgpCore.Tests/UnitTests/Decrypt/DecryptSync.String.cs b/PgpCore.Tests/UnitTests/Decrypt/DecryptSync.String.cs new file mode 100644 index 0000000..5470380 --- /dev/null +++ b/PgpCore.Tests/UnitTests/Decrypt/DecryptSync.String.cs @@ -0,0 +1,414 @@ +using FluentAssertions.Execution; +using FluentAssertions; +using Org.BouncyCastle.Bcpg.OpenPgp; +using Org.BouncyCastle.Bcpg; +using Org.BouncyCastle.Security; +using PgpCore.Models; +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using Xunit; + +namespace PgpCore.Tests.UnitTests.Decrypt +{ + public class DecryptSync_String : TestBase + { + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptEncryptedMessage_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKey); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKey, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + string encryptedContent = pgpEncrypt.Encrypt(testFactory.Content); + string decryptedContent = pgpDecrypt.Decrypt(encryptedContent); + + // Assert + using (new AssertionScope()) + { + encryptedContent.Should().NotBeNullOrEmpty(); + decryptedContent.Should().NotBeNullOrEmpty(); + decryptedContent.Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetCompressionAlgorithimTags))] + public void Decrypt_DecryptEncryptedCompressedMessage_ShouldDecryptMessage(CompressionAlgorithmTag compressionAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKey); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKey, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + CompressionAlgorithm = compressionAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + string encryptedContent = pgpEncrypt.Encrypt(testFactory.Content); + string decryptedContent = pgpDecrypt.Decrypt(encryptedContent); + + // Assert + using (new AssertionScope()) + { + encryptedContent.Should().NotBeNullOrEmpty(); + decryptedContent.Should().NotBeNullOrEmpty(); + decryptedContent.Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetHashAlgorithimTags))] + public void Decrypt_DecryptEncryptedWithSpecifiedHashAlgorithim_ShouldDecryptMessage(HashAlgorithmTag hashAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKey); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKey, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + HashAlgorithmTag = hashAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + string encryptedContent = pgpEncrypt.Encrypt(testFactory.Content); + string decryptedContent = pgpDecrypt.Decrypt(encryptedContent); + + // Assert + using (new AssertionScope()) + { + encryptedContent.Should().NotBeNullOrEmpty(); + decryptedContent.Should().NotBeNullOrEmpty(); + decryptedContent.Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [MemberData(nameof(GetSymmetricAlgorithimTags))] + public void Decrypt_DecryptEncryptedWithSpecifiedSymetricKeyAlgorithim_ShouldDecryptMessage(SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKey); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKey, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = symmetricKeyAlgorithmTag + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + string encryptedContent = pgpEncrypt.Encrypt(testFactory.Content); + string decryptedContent = pgpDecrypt.Decrypt(encryptedContent); + + PgpInspectResult pgpInspectResult = pgpDecrypt.Inspect(encryptedContent); + + // Assert + using (new AssertionScope()) + { + encryptedContent.Should().NotBeNullOrEmpty(); + decryptedContent.Should().NotBeNullOrEmpty(); + decryptedContent.Should().Be(testFactory.Content); + } + + pgpInspectResult.SymmetricKeyAlgorithm.Should().Be(symmetricKeyAlgorithmTag); + + // Teardown + testFactory.Teardown(); + } + + [Fact] + public void Decrypt_DecryptEncryptedWithNullSymetricKeyAlgorithim_ShouldThrowException() + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKey); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKey, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = SymmetricKeyAlgorithmTag.Null + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + + // Assert + using (new AssertionScope()) + { + using (Stream outputStream = testFactory.EncryptedContentFileInfo.Create()) + { + Action act = () => pgpEncrypt.Encrypt(testFactory.Content); + act.Should().Throw().Where(e => e.Message == "unknown symmetric algorithm: Null"); + } + } + + // Teardown + testFactory.Teardown(); + } + + [Fact] + public void Decrypt_DecryptEncryptedWithSaferSymetricKeyAlgorithim_ShouldThrowException() + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(KeyType.Generated, FileType.Known); + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKey); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKey, testFactory.Password); + PGP pgpEncrypt = new PGP(encryptionKeys) + { + SymmetricKeyAlgorithm = SymmetricKeyAlgorithmTag.Safer + }; + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + + // Assert + using (new AssertionScope()) + { + using (Stream outputStream = testFactory.DecryptedContentFileInfo.Create()) + { + Action act = () => pgpEncrypt.Encrypt(testFactory.Content); + act.Should().Throw().Where(e => e.Message == "Algorithm SAFER not recognised."); + } + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptEncryptedWithMultipleKeys_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + testFactory2.Arrange(KeyType.Generated, FileType.Known); + + List keys = new List() + { + testFactory.PublicKey, + testFactory2.PublicKey + }; + + EncryptionKeys encryptionKeys = new EncryptionKeys(keys, testFactory.PrivateKey, testFactory.Password); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory2.PrivateKey, testFactory2.Password); + + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + string encrypted = pgpEncrypt.Encrypt(testFactory.Content); + string decrypted = pgpDecrypt.Decrypt(encrypted); + string decrypted2 = pgpDecrypt.Decrypt(encrypted); + + // Assert + using (new AssertionScope()) + { + encrypted.Should().NotBeNullOrEmpty(); + decrypted.Should().NotBeNullOrEmpty(); + decrypted2.Should().NotBeNullOrEmpty(); + decrypted.Should().Be(testFactory.Content); + decrypted2.Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + testFactory2.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptSignedAndEncryptedMessage_ShouldDecryptMessage(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + testFactory2.Arrange(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptionAndSigningKeys = new EncryptionKeys(testFactory.PublicKey, testFactory2.PrivateKey, testFactory2.Password); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKey, testFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptionAndSigningKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + string encryptedAndSigned = pgpEncryptAndSign.EncryptAndSign(testFactory.Content); + string decrypted = pgpDecrypt.Decrypt(encryptedAndSigned); + + // Assert + using (new AssertionScope()) + { + encryptedAndSigned.Should().NotBeNullOrEmpty(); + decrypted.Should().NotBeNullOrEmpty(); + decrypted.Should().Be(testFactory.Content); + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptUnencryptedMessage_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory.PrivateKey, testFactory.Password); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + + // Assert + using (new AssertionScope()) + { + using (Stream outputStream = testFactory.DecryptedContentFileInfo.Create()) + { + Action act = () => pgpDecrypt.Decrypt(testFactory.Content); + act.Should().Throw().Where(e => e.Message.StartsWith("Failed to detect encrypted content format.")); + } + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void Decrypt_DecryptEncryptedMessageWithWrongKey_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory testFactory = new TestFactory(); + TestFactory testFactory2 = new TestFactory(); + testFactory.Arrange(keyType, FileType.Known); + testFactory2.Arrange(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptionKeys = new EncryptionKeys(testFactory.PublicKey); + EncryptionKeys decryptionKeys = new EncryptionKeys(testFactory2.PrivateKey, testFactory2.Password); + + PGP pgpEncrypt = new PGP(encryptionKeys); + PGP pgpDecrypt = new PGP(decryptionKeys); + + // Act + string encrypted = pgpEncrypt.Encrypt(testFactory.Content); + + // Assert + using (new AssertionScope()) + { + using (Stream outputStream = testFactory.DecryptedContentFileInfo.Create()) + { + Action act = () => pgpDecrypt.Decrypt(encrypted); + act.Should().Throw().Where(e => e.Message == "Secret key for message not found."); + } + } + + // Teardown + testFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void DecryptAndVerify_DecryptSignedAndEncryptedMessage_ShouldDecryptAndVerifyMessage(KeyType keyType) + { + // Arrange + TestFactory encryptTestFactory = new TestFactory(); + TestFactory signTestFactory = new TestFactory(); + + encryptTestFactory.Arrange(keyType, FileType.Known); + signTestFactory.Arrange(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptAndSignKeys = new EncryptionKeys(encryptTestFactory.PublicKey, signTestFactory.PrivateKey, signTestFactory.Password); + EncryptionKeys decryptAndVerifyKeys = new EncryptionKeys(signTestFactory.PublicKey, encryptTestFactory.PrivateKey, encryptTestFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptAndSignKeys); + PGP pgpDecryptAndVerify = new PGP(decryptAndVerifyKeys); + + // Act + string encryptedAndSigned = pgpEncryptAndSign.EncryptAndSign(encryptTestFactory.Content); + string decryptedAndVerified = pgpDecryptAndVerify.DecryptAndVerify(encryptedAndSigned); + + // Assert + using (new AssertionScope()) + { + encryptedAndSigned.Should().NotBeNullOrEmpty(); + decryptedAndVerified.Should().NotBeNullOrEmpty(); + decryptedAndVerified.Should().Be(encryptTestFactory.Content); + } + + // Teardown + encryptTestFactory.Teardown(); + signTestFactory.Teardown(); + } + + [Theory] + [InlineData(KeyType.Generated)] + [InlineData(KeyType.Known)] + [InlineData(KeyType.KnownGpg)] + public void DecryptAndVerify_DecryptSignedAndEncryptedMessageWithWrongKey_ShouldThrowException(KeyType keyType) + { + // Arrange + TestFactory encryptTestFactory = new TestFactory(); + TestFactory signTestFactory = new TestFactory(); + + encryptTestFactory.Arrange(keyType, FileType.Known); + signTestFactory.Arrange(KeyType.Generated, FileType.Known); + + EncryptionKeys encryptAndSignKeys = new EncryptionKeys(encryptTestFactory.PublicKey, encryptTestFactory.PrivateKey, encryptTestFactory.Password); + EncryptionKeys decryptAndVerifyKeys = new EncryptionKeys(signTestFactory.PublicKey, encryptTestFactory.PrivateKey, encryptTestFactory.Password); + PGP pgpEncryptAndSign = new PGP(encryptAndSignKeys); + PGP pgpDecryptAndVerify = new PGP(decryptAndVerifyKeys); + + // Act + string encryptedAndSigned = pgpEncryptAndSign.EncryptAndSign(encryptTestFactory.Content); + + // Assert + using (new AssertionScope()) + { + encryptedAndSigned.Should().NotBeNullOrEmpty(); + Action act = () => pgpDecryptAndVerify.DecryptAndVerify(encryptedAndSigned); + act.Should().Throw().Where(e => e.Message == "Failed to verify file."); + } + + // Teardown + encryptTestFactory.Teardown(); + signTestFactory.Teardown(); + } + } +} diff --git a/PgpCore.Tests/UnitTests/GenerateKey/KeyAsync.cs b/PgpCore.Tests/UnitTests/GenerateKey/KeyAsync.cs new file mode 100644 index 0000000..5296c7b --- /dev/null +++ b/PgpCore.Tests/UnitTests/GenerateKey/KeyAsync.cs @@ -0,0 +1,334 @@ +using FluentAssertions.Execution; +using FluentAssertions; +using System.Threading.Tasks; +using Xunit; +using Org.BouncyCastle.Bcpg.OpenPgp; +using System.IO; +using Org.BouncyCastle.Utilities.Zlib; +using System; +using System.Collections.Generic; +using Org.BouncyCastle.Bcpg; +using System.Security.Cryptography.X509Certificates; + +namespace PgpCore.Tests.UnitTests.GenerateKey +{ + public class KeyAsync + { +#if NETFRAMEWORK + public const string VERSION = "Version: BouncyCastle.NET Cryptography (net461) v2.1.1+851feee009"; +#else + public const string VERSION = "Version: BouncyCastle.NET Cryptography (net6.0) v2.1.1+851feee009"; +#endif + + [Fact] + public async Task GenerateKeyAsync_CreatePublicAndPrivateKeys_ShouldCreateKeysWithDefaultProperties() + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(); + PGP pgp = new PGP(); + + // Act + await pgp.GenerateKeyAsync( + testFactory.PublicKeyFileInfo, + testFactory.PrivateKeyFileInfo, + testFactory.UserName, + testFactory.Password + ); + + // Assert + // Assert that the keys were created + using (new AssertionScope()) + { + testFactory.PublicKeyFileInfo.Exists.Should().BeTrue(); + testFactory.PrivateKeyFileInfo.Exists.Should().BeTrue(); + } + + // Assert public key properties + using (new AssertionScope()) + { + File.ReadAllText(testFactory.PublicKeyFileInfo.FullName).Should().Contain(VERSION); + + using (Stream publicKeyStream = testFactory.PublicKeyFileInfo.OpenRead()) + { + PgpPublicKey publicKey = publicKey = ReadPublicKey(publicKeyStream); + // If we successfully read the public key without exceptions, it is considered valid + publicKey.Should().NotBeNull(); + publicKey.Version.Should().Be(4); + publicKey.CreationTime.Should().BeCloseTo(DateTime.UtcNow, new TimeSpan(0, 0, 10)); + publicKey.IsEncryptionKey.Should().BeTrue(); + publicKey.IsMasterKey.Should().BeTrue(); + publicKey.IsRevoked().Should().BeFalse(); + publicKey.BitStrength.Should().Be(1024); + } + + } + + // Assert private key properties + using (new AssertionScope()) + { + File.ReadAllText(testFactory.PrivateKeyFileInfo.FullName).Should().Contain(VERSION); + + using (Stream privateKeyStream = testFactory.PrivateKeyFileInfo.OpenRead()) + { + PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream)); + foreach (PgpSecretKeyRing kRing in pgpSec.GetKeyRings()) + { + foreach (PgpSecretKey k in kRing.GetSecretKeys()) + { + if (k.IsSigningKey) + { + k.Should().NotBeNull(); + k.IsSigningKey.Should().BeTrue(); + k.IsMasterKey.Should().BeTrue(); + k.KeyEncryptionAlgorithm.Should().Be(SymmetricKeyAlgorithmTag.TripleDes); + } + } + } + } + } + } + + [Fact] + public async Task GenerateKeyAsync_CreatePublicAndPrivateKeysWithKeyStrength_ShouldCreateKeysWithSpecifiedProperties() + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(); + PGP pgp = new PGP(); + + // Act + await pgp.GenerateKeyAsync( + testFactory.PublicKeyFileInfo, + testFactory.PrivateKeyFileInfo, + testFactory.UserName, + testFactory.Password, + strength: 2048 + ); + + // Assert + // Assert that the keys were created + using (new AssertionScope()) + { + testFactory.PublicKeyFileInfo.Exists.Should().BeTrue(); + testFactory.PrivateKeyFileInfo.Exists.Should().BeTrue(); + } + + // Assert public key properties + using (new AssertionScope()) + { + File.ReadAllText(testFactory.PublicKeyFileInfo.FullName).Should().Contain(VERSION); + + using (Stream publicKeyStream = testFactory.PublicKeyFileInfo.OpenRead()) + { + PgpPublicKey publicKey = publicKey = ReadPublicKey(publicKeyStream); + // If we successfully read the public key without exceptions, it is considered valid + publicKey.Should().NotBeNull(); + publicKey.Version.Should().Be(4); + publicKey.CreationTime.Should().BeCloseTo(DateTime.UtcNow, new TimeSpan(0, 0, 10)); + publicKey.IsEncryptionKey.Should().BeTrue(); + publicKey.IsMasterKey.Should().BeTrue(); + publicKey.IsRevoked().Should().BeFalse(); + publicKey.BitStrength.Should().Be(2048); + } + } + + // Assert private key properties + using (new AssertionScope()) + { + File.ReadAllText(testFactory.PrivateKeyFileInfo.FullName).Should().Contain(VERSION); + + using (Stream privateKeyStream = testFactory.PrivateKeyFileInfo.OpenRead()) + { + PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream)); + foreach (PgpSecretKeyRing kRing in pgpSec.GetKeyRings()) + { + foreach (PgpSecretKey k in kRing.GetSecretKeys()) + { + if (k.IsSigningKey) + { + k.Should().NotBeNull(); + k.IsSigningKey.Should().BeTrue(); + k.IsMasterKey.Should().BeTrue(); + k.KeyEncryptionAlgorithm.Should().Be(SymmetricKeyAlgorithmTag.TripleDes); + } + } + } + } + } + } + + [Fact] + public async Task GenerateKeyAsync_CreatePublicAndPrivateKeysWithoutVersion_ShouldCreateKeysWithSpecifiedProperties() + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(); + PGP pgp = new PGP(); + + // Act + await pgp.GenerateKeyAsync( + testFactory.PublicKeyFileInfo, + testFactory.PrivateKeyFileInfo, + testFactory.UserName, + testFactory.Password, + emitVersion: false + ); + + // Assert + // Assert that the keys were created + using (new AssertionScope()) + { + testFactory.PublicKeyFileInfo.Exists.Should().BeTrue(); + testFactory.PrivateKeyFileInfo.Exists.Should().BeTrue(); + } + + // Assert public key properties + using (new AssertionScope()) + { + File.ReadAllText(testFactory.PublicKeyFileInfo.FullName).Should().NotContain(VERSION); + + using (Stream publicKeyStream = testFactory.PublicKeyFileInfo.OpenRead()) + { + PgpPublicKey publicKey = ReadPublicKey(publicKeyStream); + // If we successfully read the public key without exceptions, it is considered valid + publicKey.Should().NotBeNull(); + publicKey.Version.Should().Be(4); + publicKey.CreationTime.Should().BeCloseTo(DateTime.UtcNow, new TimeSpan(0, 0, 10)); + publicKey.IsEncryptionKey.Should().BeTrue(); + publicKey.IsMasterKey.Should().BeTrue(); + publicKey.IsRevoked().Should().BeFalse(); + publicKey.BitStrength.Should().Be(1024); + } + + } + + // Assert private key properties + using (new AssertionScope()) + { + File.ReadAllText(testFactory.PrivateKeyFileInfo.FullName).Should().NotContain(VERSION); + + using (Stream privateKeyStream = testFactory.PrivateKeyFileInfo.OpenRead()) + { + PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream)); + foreach (PgpSecretKeyRing kRing in pgpSec.GetKeyRings()) + { + foreach (PgpSecretKey k in kRing.GetSecretKeys()) + { + if (k.IsSigningKey) + { + k.Should().NotBeNull(); + k.IsSigningKey.Should().BeTrue(); + k.IsMasterKey.Should().BeTrue(); + k.KeyEncryptionAlgorithm.Should().Be(SymmetricKeyAlgorithmTag.TripleDes); + } + } + } + } + } + } + + [Fact] + public async Task GenerateKeyAsync_CreatePublicAndPrivateKeysWithExpiryDate_ShouldCreateKeysWithSpecifiedProperties() + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(); + PGP pgp = new PGP(); + + // Act + await pgp.GenerateKeyAsync( + testFactory.PublicKeyFileInfo, + testFactory.PrivateKeyFileInfo, + testFactory.UserName, + testFactory.Password, + keyExpirationInSeconds: 60 + ); + + // Assert + // Assert that the keys were created + using (new AssertionScope()) + { + testFactory.PublicKeyFileInfo.Exists.Should().BeTrue(); + testFactory.PrivateKeyFileInfo.Exists.Should().BeTrue(); + } + + // Assert public key properties + using (new AssertionScope()) + { + File.ReadAllText(testFactory.PublicKeyFileInfo.FullName).Should().Contain(VERSION); + + using (Stream publicKeyStream = testFactory.PublicKeyFileInfo.OpenRead()) + { + PgpPublicKey publicKey = ReadPublicKey(publicKeyStream); + // If we successfully read the public key without exceptions, it is considered valid + publicKey.Should().NotBeNull(); + publicKey.Version.Should().Be(4); + publicKey.CreationTime.Should().BeCloseTo(DateTime.UtcNow, new TimeSpan(0, 0, 10)); + publicKey.IsEncryptionKey.Should().BeTrue(); + publicKey.IsMasterKey.Should().BeTrue(); + publicKey.IsRevoked().Should().BeFalse(); + publicKey.BitStrength.Should().Be(1024); + publicKey.GetValidSeconds().Should().Be(60); + } + + } + + // Assert private key properties + using (new AssertionScope()) + { + File.ReadAllText(testFactory.PrivateKeyFileInfo.FullName).Should().Contain(VERSION); + + using (Stream privateKeyStream = testFactory.PrivateKeyFileInfo.OpenRead()) + { + PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream)); + foreach (PgpSecretKeyRing kRing in pgpSec.GetKeyRings()) + { + foreach (PgpSecretKey k in kRing.GetSecretKeys()) + { + if (k.IsSigningKey) + { + k.Should().NotBeNull(); + k.IsSigningKey.Should().BeTrue(); + k.IsMasterKey.Should().BeTrue(); + k.KeyEncryptionAlgorithm.Should().Be(SymmetricKeyAlgorithmTag.TripleDes); + } + } + } + } + } + } + + private static PgpPublicKey ReadPublicKey(Stream inputStream) + { + PgpPublicKeyRingBundle pgpPub = new PgpPublicKeyRingBundle(PgpUtilities.GetDecoderStream(inputStream)); + foreach (PgpPublicKeyRing kRing in pgpPub.GetKeyRings()) + { + foreach (PgpPublicKey k in kRing.GetPublicKeys()) + { + if (k.IsEncryptionKey) + return k; + } + } + throw new ArgumentException("No encryption key found in public key ring."); + } + + private static IEnumerable GetEnumValues() where T : struct, IConvertible + { + foreach (T enumValue in Enum.GetValues(typeof(T))) + { + yield return enumValue; + } + } + + public static IEnumerable GetAllCombinations() + { + foreach (CompressionAlgorithmTag compressionAlgorithmTag in GetEnumValues()) + foreach (HashAlgorithmTag hashAlgorithmTag in GetEnumValues()) + foreach (SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag in GetEnumValues()) + { + yield return new object[] { compressionAlgorithmTag, hashAlgorithmTag, symmetricKeyAlgorithmTag }; + } + } + } +} diff --git a/PgpCore.Tests/UnitTests/GenerateKey/KeySync.cs b/PgpCore.Tests/UnitTests/GenerateKey/KeySync.cs new file mode 100644 index 0000000..da0a804 --- /dev/null +++ b/PgpCore.Tests/UnitTests/GenerateKey/KeySync.cs @@ -0,0 +1,334 @@ +using FluentAssertions.Execution; +using FluentAssertions; +using System.Threading.Tasks; +using Xunit; +using Org.BouncyCastle.Bcpg.OpenPgp; +using System.IO; +using Org.BouncyCastle.Utilities.Zlib; +using System; +using System.Collections.Generic; +using Org.BouncyCastle.Bcpg; +using System.Security.Cryptography.X509Certificates; + +namespace PgpCore.Tests.UnitTests.GenerateKey +{ + public class KeySync + { +#if NETFRAMEWORK + public const string VERSION = "Version: BouncyCastle.NET Cryptography (net461) v2.1.1+851feee009"; +#else + public const string VERSION = "Version: BouncyCastle.NET Cryptography (net6.0) v2.1.1+851feee009"; +#endif + + [Fact] + public void GenerateKey_CreatePublicAndPrivateKeys_ShouldCreateKeysWithDefaultProperties() + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(); + PGP pgp = new PGP(); + + // Act + pgp.GenerateKey( + testFactory.PublicKeyFileInfo, + testFactory.PrivateKeyFileInfo, + testFactory.UserName, + testFactory.Password + ); + + // Assert + // Assert that the keys were created + using (new AssertionScope()) + { + testFactory.PublicKeyFileInfo.Exists.Should().BeTrue(); + testFactory.PrivateKeyFileInfo.Exists.Should().BeTrue(); + } + + // Assert public key properties + using (new AssertionScope()) + { + File.ReadAllText(testFactory.PublicKeyFileInfo.FullName).Should().Contain(VERSION); + + using (Stream publicKeyStream = testFactory.PublicKeyFileInfo.OpenRead()) + { + PgpPublicKey publicKey = publicKey = ReadPublicKey(publicKeyStream); + // If we successfully read the public key without exceptions, it is considered valid + publicKey.Should().NotBeNull(); + publicKey.Version.Should().Be(4); + publicKey.CreationTime.Should().BeCloseTo(DateTime.UtcNow, new TimeSpan(0, 0, 10)); + publicKey.IsEncryptionKey.Should().BeTrue(); + publicKey.IsMasterKey.Should().BeTrue(); + publicKey.IsRevoked().Should().BeFalse(); + publicKey.BitStrength.Should().Be(1024); + } + + } + + // Assert private key properties + using (new AssertionScope()) + { + File.ReadAllText(testFactory.PrivateKeyFileInfo.FullName).Should().Contain(VERSION); + + using (Stream privateKeyStream = testFactory.PrivateKeyFileInfo.OpenRead()) + { + PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream)); + foreach (PgpSecretKeyRing kRing in pgpSec.GetKeyRings()) + { + foreach (PgpSecretKey k in kRing.GetSecretKeys()) + { + if (k.IsSigningKey) + { + k.Should().NotBeNull(); + k.IsSigningKey.Should().BeTrue(); + k.IsMasterKey.Should().BeTrue(); + k.KeyEncryptionAlgorithm.Should().Be(SymmetricKeyAlgorithmTag.TripleDes); + } + } + } + } + } + } + + [Fact] + public void GenerateKey_CreatePublicAndPrivateKeysWithKeyStrength_ShouldCreateKeysWithSpecifiedProperties() + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(); + PGP pgp = new PGP(); + + // Act + pgp.GenerateKey( + testFactory.PublicKeyFileInfo, + testFactory.PrivateKeyFileInfo, + testFactory.UserName, + testFactory.Password, + strength: 2048 + ); + + // Assert + // Assert that the keys were created + using (new AssertionScope()) + { + testFactory.PublicKeyFileInfo.Exists.Should().BeTrue(); + testFactory.PrivateKeyFileInfo.Exists.Should().BeTrue(); + } + + // Assert public key properties + using (new AssertionScope()) + { + File.ReadAllText(testFactory.PublicKeyFileInfo.FullName).Should().Contain(VERSION); + + using (Stream publicKeyStream = testFactory.PublicKeyFileInfo.OpenRead()) + { + PgpPublicKey publicKey = publicKey = ReadPublicKey(publicKeyStream); + // If we successfully read the public key without exceptions, it is considered valid + publicKey.Should().NotBeNull(); + publicKey.Version.Should().Be(4); + publicKey.CreationTime.Should().BeCloseTo(DateTime.UtcNow, new TimeSpan(0, 0, 10)); + publicKey.IsEncryptionKey.Should().BeTrue(); + publicKey.IsMasterKey.Should().BeTrue(); + publicKey.IsRevoked().Should().BeFalse(); + publicKey.BitStrength.Should().Be(2048); + } + } + + // Assert private key properties + using (new AssertionScope()) + { + File.ReadAllText(testFactory.PrivateKeyFileInfo.FullName).Should().Contain(VERSION); + + using (Stream privateKeyStream = testFactory.PrivateKeyFileInfo.OpenRead()) + { + PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream)); + foreach (PgpSecretKeyRing kRing in pgpSec.GetKeyRings()) + { + foreach (PgpSecretKey k in kRing.GetSecretKeys()) + { + if (k.IsSigningKey) + { + k.Should().NotBeNull(); + k.IsSigningKey.Should().BeTrue(); + k.IsMasterKey.Should().BeTrue(); + k.KeyEncryptionAlgorithm.Should().Be(SymmetricKeyAlgorithmTag.TripleDes); + } + } + } + } + } + } + + [Fact] + public void GenerateKey_CreatePublicAndPrivateKeysWithoutVersion_ShouldCreateKeysWithSpecifiedProperties() + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(); + PGP pgp = new PGP(); + + // Act + pgp.GenerateKey( + testFactory.PublicKeyFileInfo, + testFactory.PrivateKeyFileInfo, + testFactory.UserName, + testFactory.Password, + emitVersion: false + ); + + // Assert + // Assert that the keys were created + using (new AssertionScope()) + { + testFactory.PublicKeyFileInfo.Exists.Should().BeTrue(); + testFactory.PrivateKeyFileInfo.Exists.Should().BeTrue(); + } + + // Assert public key properties + using (new AssertionScope()) + { + File.ReadAllText(testFactory.PublicKeyFileInfo.FullName).Should().NotContain(VERSION); + + using (Stream publicKeyStream = testFactory.PublicKeyFileInfo.OpenRead()) + { + PgpPublicKey publicKey = ReadPublicKey(publicKeyStream); + // If we successfully read the public key without exceptions, it is considered valid + publicKey.Should().NotBeNull(); + publicKey.Version.Should().Be(4); + publicKey.CreationTime.Should().BeCloseTo(DateTime.UtcNow, new TimeSpan(0, 0, 10)); + publicKey.IsEncryptionKey.Should().BeTrue(); + publicKey.IsMasterKey.Should().BeTrue(); + publicKey.IsRevoked().Should().BeFalse(); + publicKey.BitStrength.Should().Be(1024); + } + + } + + // Assert private key properties + using (new AssertionScope()) + { + File.ReadAllText(testFactory.PrivateKeyFileInfo.FullName).Should().NotContain(VERSION); + + using (Stream privateKeyStream = testFactory.PrivateKeyFileInfo.OpenRead()) + { + PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream)); + foreach (PgpSecretKeyRing kRing in pgpSec.GetKeyRings()) + { + foreach (PgpSecretKey k in kRing.GetSecretKeys()) + { + if (k.IsSigningKey) + { + k.Should().NotBeNull(); + k.IsSigningKey.Should().BeTrue(); + k.IsMasterKey.Should().BeTrue(); + k.KeyEncryptionAlgorithm.Should().Be(SymmetricKeyAlgorithmTag.TripleDes); + } + } + } + } + } + } + + [Fact] + public void GenerateKey_CreatePublicAndPrivateKeysWithExpiryDate_ShouldCreateKeysWithSpecifiedProperties() + { + // Arrange + TestFactory testFactory = new TestFactory(); + testFactory.Arrange(); + PGP pgp = new PGP(); + + // Act + pgp.GenerateKey( + testFactory.PublicKeyFileInfo, + testFactory.PrivateKeyFileInfo, + testFactory.UserName, + testFactory.Password, + keyExpirationInSeconds: 60 + ); + + // Assert + // Assert that the keys were created + using (new AssertionScope()) + { + testFactory.PublicKeyFileInfo.Exists.Should().BeTrue(); + testFactory.PrivateKeyFileInfo.Exists.Should().BeTrue(); + } + + // Assert public key properties + using (new AssertionScope()) + { + File.ReadAllText(testFactory.PublicKeyFileInfo.FullName).Should().Contain(VERSION); + + using (Stream publicKeyStream = testFactory.PublicKeyFileInfo.OpenRead()) + { + PgpPublicKey publicKey = ReadPublicKey(publicKeyStream); + // If we successfully read the public key without exceptions, it is considered valid + publicKey.Should().NotBeNull(); + publicKey.Version.Should().Be(4); + publicKey.CreationTime.Should().BeCloseTo(DateTime.UtcNow, new TimeSpan(0, 0, 10)); + publicKey.IsEncryptionKey.Should().BeTrue(); + publicKey.IsMasterKey.Should().BeTrue(); + publicKey.IsRevoked().Should().BeFalse(); + publicKey.BitStrength.Should().Be(1024); + publicKey.GetValidSeconds().Should().Be(60); + } + + } + + // Assert private key properties + using (new AssertionScope()) + { + File.ReadAllText(testFactory.PrivateKeyFileInfo.FullName).Should().Contain(VERSION); + + using (Stream privateKeyStream = testFactory.PrivateKeyFileInfo.OpenRead()) + { + PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream)); + foreach (PgpSecretKeyRing kRing in pgpSec.GetKeyRings()) + { + foreach (PgpSecretKey k in kRing.GetSecretKeys()) + { + if (k.IsSigningKey) + { + k.Should().NotBeNull(); + k.IsSigningKey.Should().BeTrue(); + k.IsMasterKey.Should().BeTrue(); + k.KeyEncryptionAlgorithm.Should().Be(SymmetricKeyAlgorithmTag.TripleDes); + } + } + } + } + } + } + + private static PgpPublicKey ReadPublicKey(Stream inputStream) + { + PgpPublicKeyRingBundle pgpPub = new PgpPublicKeyRingBundle(PgpUtilities.GetDecoderStream(inputStream)); + foreach (PgpPublicKeyRing kRing in pgpPub.GetKeyRings()) + { + foreach (PgpPublicKey k in kRing.GetPublicKeys()) + { + if (k.IsEncryptionKey) + return k; + } + } + throw new ArgumentException("No encryption key found in public key ring."); + } + + private static IEnumerable GetEnumValues() where T : struct, IConvertible + { + foreach (T enumValue in Enum.GetValues(typeof(T))) + { + yield return enumValue; + } + } + + public static IEnumerable GetAllCombinations() + { + foreach (CompressionAlgorithmTag compressionAlgorithmTag in GetEnumValues()) + foreach (HashAlgorithmTag hashAlgorithmTag in GetEnumValues()) + foreach (SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag in GetEnumValues()) + { + yield return new object[] { compressionAlgorithmTag, hashAlgorithmTag, symmetricKeyAlgorithmTag }; + } + } + } +} diff --git a/PgpCore.Tests/UnitTests/TestBase.cs b/PgpCore.Tests/UnitTests/TestBase.cs new file mode 100644 index 0000000..eb9a93c --- /dev/null +++ b/PgpCore.Tests/UnitTests/TestBase.cs @@ -0,0 +1,40 @@ +using Org.BouncyCastle.Bcpg; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PgpCore.Tests.UnitTests +{ + public class TestBase + { + public static IEnumerable GetCompressionAlgorithimTags() + { + foreach (CompressionAlgorithmTag compressionAlgorithmTag in TestHelper.GetEnumValues()) + { + yield return new object[] { compressionAlgorithmTag }; + } + } + + public static IEnumerable GetHashAlgorithimTags() + { + foreach (HashAlgorithmTag hashAlgorithmTag in TestHelper.GetEnumValues()) + { + yield return new object[] { hashAlgorithmTag }; + } + } + + public static IEnumerable GetSymmetricAlgorithimTags() + { + foreach (SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag in TestHelper.GetEnumValues()) + { + // Exclude as null is not for encryption and safer is not supported. + if (symmetricKeyAlgorithmTag == SymmetricKeyAlgorithmTag.Null || symmetricKeyAlgorithmTag == SymmetricKeyAlgorithmTag.Safer) + continue; + + yield return new object[] { symmetricKeyAlgorithmTag }; + } + } + } +} diff --git a/PgpCore/Abstractions/IPGP.EncryptAsync.cs b/PgpCore/Abstractions/IPGP.EncryptAsync.cs index 79f8936..b94285f 100644 --- a/PgpCore/Abstractions/IPGP.EncryptAsync.cs +++ b/PgpCore/Abstractions/IPGP.EncryptAsync.cs @@ -9,16 +9,16 @@ public interface IEncryptAsync : IDisposable { Task EncryptAsync(FileInfo inputFile, FileInfo outputFile, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); Task EncryptAsync(Stream inputStream, Stream outputStream, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); - Task EncryptAsync(string input, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); + Task EncryptAsync(string input, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); Task EncryptAndSignAsync(FileInfo inputFile, FileInfo outputFile, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); Task EncryptAndSignAsync(Stream inputStream, Stream outputStream, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); - Task EncryptAndSignAsync(string input, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); + Task EncryptAndSignAsync(string input, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); Task EncryptFileAsync(FileInfo inputFile, FileInfo outputFile, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); Task EncryptStreamAsync(Stream inputStream, Stream outputStream, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); - Task EncryptArmoredStringAsync(string input, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); + Task EncryptArmoredStringAsync(string input, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); Task EncryptFileAndSignAsync(FileInfo inputFile, FileInfo outputFile, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); Task EncryptStreamAndSignAsync(Stream inputStream, Stream outputStream, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); - Task EncryptArmoredStringAndSignAsync(string input, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); + Task EncryptArmoredStringAndSignAsync(string input, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); } } \ No newline at end of file diff --git a/PgpCore/Abstractions/IPGP.EncryptSync.cs b/PgpCore/Abstractions/IPGP.EncryptSync.cs index 2dd8748..64af1cd 100644 --- a/PgpCore/Abstractions/IPGP.EncryptSync.cs +++ b/PgpCore/Abstractions/IPGP.EncryptSync.cs @@ -10,16 +10,16 @@ public interface IEncryptSync : IDisposable { void Encrypt(FileInfo inputFile, FileInfo outputFile, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); void Encrypt(Stream inputStream, Stream outputStream, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); - string Encrypt(string input, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); + string Encrypt(string input, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); void EncryptAndSign(FileInfo inputFile, FileInfo outputFile, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); void EncryptAndSign(Stream inputStream, Stream outputStream, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); - string EncryptAndSign(string input, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); + string EncryptAndSign(string input, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); void EncryptFile(FileInfo inputFile, FileInfo outputFile, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); void EncryptStream(Stream inputStream, Stream outputStream, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); - string EncryptArmoredString(string input, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); + string EncryptArmoredString(string input, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); void EncryptFileAndSign(FileInfo inputFile, FileInfo outputFile, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); void EncryptStreamAndSign(Stream inputStream, Stream outputStream, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); - string EncryptArmoredStringAndSign(string input, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); + string EncryptArmoredStringAndSign(string input, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false); } } diff --git a/PgpCore/Abstractions/IPGP.SignAsync.cs b/PgpCore/Abstractions/IPGP.SignAsync.cs index 5bc44e4..afd3bd8 100644 --- a/PgpCore/Abstractions/IPGP.SignAsync.cs +++ b/PgpCore/Abstractions/IPGP.SignAsync.cs @@ -9,14 +9,14 @@ public interface ISignAsync : IDisposable { Task SignAsync(FileInfo inputFile, FileInfo outputFile, bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false); Task SignAsync(Stream inputStream, Stream outputStream, bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false); - Task SignAsync(string input, bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false); + Task SignAsync(string input, string name = null, IDictionary headers = null, bool oldFormat = false); Task ClearSignAsync(FileInfo inputFile, FileInfo outputFile, IDictionary headers = null); Task ClearSignAsync(Stream inputStream, Stream outputStream, IDictionary headers = null); Task ClearSignAsync(string input, IDictionary headers = null); Task SignFileAsync(FileInfo inputFile, FileInfo outputFile, bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false); Task SignStreamAsync(Stream inputStream, Stream outputStream, bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false); - Task SignArmoredStringAsync(string input, bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false); + Task SignArmoredStringAsync(string input, string name = null, IDictionary headers = null, bool oldFormat = false); Task ClearSignFileAsync(FileInfo inputFile, FileInfo outputFile, IDictionary headers = null); Task ClearSignStreamAsync(Stream inputStream, Stream outputStream, IDictionary headers = null); Task ClearSignArmoredStringAsync(string input, IDictionary headers = null); diff --git a/PgpCore/Abstractions/IPGP.SignSync.cs b/PgpCore/Abstractions/IPGP.SignSync.cs index d67ca46..9450a52 100644 --- a/PgpCore/Abstractions/IPGP.SignSync.cs +++ b/PgpCore/Abstractions/IPGP.SignSync.cs @@ -10,14 +10,14 @@ public interface ISignSync : IDisposable { void Sign(FileInfo inputFile, FileInfo outputFile, bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false); void Sign(Stream inputStream, Stream outputStream, bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false); - string Sign(string input, bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false); + string Sign(string input, string name = null, IDictionary headers = null, bool oldFormat = false); void ClearSign(FileInfo inputFile, FileInfo outputFile, IDictionary headers = null); void ClearSign(Stream inputStream, Stream outputStream, IDictionary headers = null); string ClearSign(string input, IDictionary headers = null); void SignFile(FileInfo inputFile, FileInfo outputFile, bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false); void SignStream(Stream inputStream, Stream outputStream, bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false); - string SignArmoredString(string input, bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false); + string SignArmoredString(string input, string name = null, IDictionary headers = null, bool oldFormat = false); void ClearSignFile(FileInfo inputFile, FileInfo outputFile, IDictionary headers = null); void ClearSignStream(Stream inputStream, Stream outputStream, IDictionary headers = null); string ClearSignArmoredString(string input, IDictionary headers = null); diff --git a/PgpCore/Extensions/StreamExtensions.cs b/PgpCore/Extensions/StreamExtensions.cs index a169dba..94cc41a 100644 --- a/PgpCore/Extensions/StreamExtensions.cs +++ b/PgpCore/Extensions/StreamExtensions.cs @@ -7,21 +7,21 @@ namespace PgpCore.Extensions { internal static class StreamExtensions { - public static string GetString(this Stream inputStream) + internal static string GetString(this Stream inputStream) { var reader = new StreamReader(inputStream); var output = reader.ReadToEnd(); return output; } - public static async Task GetStringAsync(this Stream inputStream) + internal static async Task GetStringAsync(this Stream inputStream) { var reader = new StreamReader(inputStream); var output = await reader.ReadToEndAsync(); return output; } - public static Encoding GetEncoding(this Stream inputStream) + internal static Encoding GetEncoding(this Stream inputStream) { Encoding defaultEncodingIfNoBom = Encoding.UTF8; diff --git a/PgpCore/PGP.EncryptAsync.cs b/PgpCore/PGP.EncryptAsync.cs index 2bd7b9e..64f2b14 100644 --- a/PgpCore/PGP.EncryptAsync.cs +++ b/PgpCore/PGP.EncryptAsync.cs @@ -127,14 +127,12 @@ public async Task EncryptAsync( /// PGP Encrypt the string. /// /// Plain string to be encrypted - /// True, means a binary data representation as an ASCII-only text. Otherwise, false /// True, to perform integrity packet check on input file. Otherwise, false /// Name of encrypted file in message, defaults to the input file name /// Optional headers to be added to the output /// True, to use old format for encryption if you need compatibility with PGP 2.6.x. Otherwise, false public async Task EncryptAsync( string input, - bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, @@ -148,7 +146,7 @@ public async Task EncryptAsync( using (Stream inputStream = await input.GetStreamAsync()) using (Stream outputStream = new MemoryStream()) { - await EncryptAsync(inputStream, outputStream, armor, withIntegrityCheck, name, headers, oldFormat); + await EncryptAsync(inputStream, outputStream, true, withIntegrityCheck, name, headers, oldFormat); outputStream.Seek(0, SeekOrigin.Begin); return await outputStream.GetStringAsync(); } @@ -158,7 +156,7 @@ public async Task EncryptAsync( public async Task EncryptStreamAsync(Stream inputStream, Stream outputStream, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false) => await EncryptAsync(inputStream, outputStream, armor, withIntegrityCheck, name, headers, oldFormat); - public async Task EncryptArmoredStringAsync(string input, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false) => await EncryptAsync(input, armor, withIntegrityCheck, name, headers, oldFormat); + public async Task EncryptArmoredStringAsync(string input, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false) => await EncryptAsync(input, withIntegrityCheck, name, headers, oldFormat); #endregion EncryptAsync @@ -263,14 +261,12 @@ public async Task EncryptAndSignAsync( /// This method will include the signature within the encrypted message and is different from first encrypting a file and then signing it. /// /// Plain string to be encrypted and signed - /// True, means a binary data representation as an ASCII-only text. Otherwise, false /// True to include integrity packet during signing /// Name of encrypted file in message, defaults to the input file name /// Optional headers to be added to the output /// True, to use old format for encryption if you need compatibility with PGP 2.6.x. Otherwise, false public async Task EncryptAndSignAsync( string input, - bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, @@ -284,7 +280,7 @@ public async Task EncryptAndSignAsync( using (Stream inputStream = await input.GetStreamAsync()) using (Stream outputStream = new MemoryStream()) { - await EncryptAndSignAsync(inputStream, outputStream, armor, withIntegrityCheck, name, headers, oldFormat); + await EncryptAndSignAsync(inputStream, outputStream, true, withIntegrityCheck, name, headers, oldFormat); outputStream.Seek(0, SeekOrigin.Begin); return await outputStream.GetStringAsync(); } @@ -294,7 +290,7 @@ public async Task EncryptAndSignAsync( public async Task EncryptStreamAndSignAsync(Stream inputStream, Stream outputStream, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false) => await EncryptAndSignAsync(inputStream, outputStream, armor, withIntegrityCheck, name, headers, oldFormat); - public async Task EncryptArmoredStringAndSignAsync(string input, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false) => await EncryptAndSignAsync(input, armor, withIntegrityCheck, name, headers, oldFormat); + public async Task EncryptArmoredStringAndSignAsync(string input, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false) => await EncryptAndSignAsync(input, withIntegrityCheck, name, headers, oldFormat); #endregion EncryptAndSignAsync } diff --git a/PgpCore/PGP.EncryptSync.cs b/PgpCore/PGP.EncryptSync.cs index 609f7b6..2aae1dd 100644 --- a/PgpCore/PGP.EncryptSync.cs +++ b/PgpCore/PGP.EncryptSync.cs @@ -126,14 +126,12 @@ public void Encrypt( /// PGP Encrypt the string. /// /// Plain string to be encrypted - /// True, means a binary data representation as an ASCII-only text. Otherwise, false /// True, to perform integrity packet check on input file. Otherwise, false /// Name of encrypted file in message, defaults to the input file name /// Optional headers to be added to the output /// True, to use old format for encryption if you need compatibility with PGP 2.6.x. Otherwise, false public string Encrypt( string input, - bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, @@ -147,13 +145,13 @@ public string Encrypt( using (Stream inputStream = input.GetStream()) using (Stream outputStream = new MemoryStream()) { - Encrypt(inputStream, outputStream, armor, withIntegrityCheck, name, headers, oldFormat); + Encrypt(inputStream, outputStream, true, withIntegrityCheck, name, headers, oldFormat); outputStream.Seek(0, SeekOrigin.Begin); return outputStream.GetString(); } } - public string EncryptArmoredString(string input, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false) => Encrypt(input, armor, withIntegrityCheck, name, headers, oldFormat); + public string EncryptArmoredString(string input, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false) => Encrypt(input, withIntegrityCheck, name, headers, oldFormat); public void EncryptFile(FileInfo inputFile, FileInfo outputFile, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false) => Encrypt(inputFile, outputFile, armor, withIntegrityCheck, name, headers, oldFormat); @@ -266,7 +264,6 @@ public void EncryptAndSign( /// True, to use old format for encryption if you need compatibility with PGP 2.6.x. Otherwise, false public string EncryptAndSign( string input, - bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, @@ -280,13 +277,13 @@ public string EncryptAndSign( using (Stream inputStream = input.GetStream()) using (Stream outputStream = new MemoryStream()) { - EncryptAndSign(inputStream, outputStream, armor, withIntegrityCheck, name, headers, oldFormat); + EncryptAndSign(inputStream, outputStream, true, withIntegrityCheck, name, headers, oldFormat); outputStream.Seek(0, SeekOrigin.Begin); return outputStream.GetString(); } } - public string EncryptArmoredStringAndSign(string input, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false) => EncryptAndSign(input, armor, withIntegrityCheck, name, headers, oldFormat); + public string EncryptArmoredStringAndSign(string input, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false) => EncryptAndSign(input, withIntegrityCheck, name, headers, oldFormat); public void EncryptFileAndSign(FileInfo inputFile, FileInfo outputFile, bool armor = true, bool withIntegrityCheck = true, string name = null, IDictionary headers = null, bool oldFormat = false) => EncryptAndSign(inputFile, outputFile, armor, withIntegrityCheck, name, headers, oldFormat); diff --git a/PgpCore/PGP.SignAsync.cs b/PgpCore/PGP.SignAsync.cs index f047153..568fc91 100644 --- a/PgpCore/PGP.SignAsync.cs +++ b/PgpCore/PGP.SignAsync.cs @@ -111,7 +111,6 @@ public async Task SignAsync( /// True, to use old format for encryption if you need compatibility with PGP 2.6.x. Otherwise, false public async Task SignAsync( string input, - bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false) @@ -124,7 +123,7 @@ public async Task SignAsync( using (Stream inputStream = await input.GetStreamAsync()) using (Stream outputStream = new MemoryStream()) { - await SignAsync(inputStream, outputStream, armor, name, headers, oldFormat); + await SignAsync(inputStream, outputStream, true, name, headers, oldFormat); outputStream.Seek(0, SeekOrigin.Begin); return await outputStream.GetStringAsync(); } @@ -134,7 +133,7 @@ public async Task SignAsync( public async Task SignStreamAsync(Stream inputStream, Stream outputStream, bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false) => await SignAsync(inputStream, outputStream, armor, name, headers, oldFormat); - public async Task SignArmoredStringAsync(string input, bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false) => await SignAsync(input, armor, name, headers, oldFormat); + public async Task SignArmoredStringAsync(string input, string name = null, IDictionary headers = null, bool oldFormat = false) => await SignAsync(input, name, headers, oldFormat); #endregion SignAsync diff --git a/PgpCore/PGP.SignSync.cs b/PgpCore/PGP.SignSync.cs index b7ba7f0..a575c5d 100644 --- a/PgpCore/PGP.SignSync.cs +++ b/PgpCore/PGP.SignSync.cs @@ -111,7 +111,6 @@ public void Sign( /// True, to use old format for encryption if you need compatibility with PGP 2.6.x. Otherwise, false public string Sign( string input, - bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false) @@ -124,7 +123,7 @@ public string Sign( using (Stream inputStream = input.GetStream()) using (Stream outputStream = new MemoryStream()) { - Sign(inputStream, outputStream, armor, name, headers, oldFormat); + Sign(inputStream, outputStream, true, name, headers, oldFormat); outputStream.Seek(0, SeekOrigin.Begin); return outputStream.GetString(); } @@ -134,7 +133,7 @@ public string Sign( public void SignStream(Stream inputStream, Stream outputStream, bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false) => Sign(inputStream, outputStream, armor, name, headers, oldFormat); - public string SignArmoredString(string input, bool armor = true, string name = null, IDictionary headers = null, bool oldFormat = false) => Sign(input, armor, name, headers, oldFormat); + public string SignArmoredString(string input, string name = null, IDictionary headers = null, bool oldFormat = false) => Sign(input, name, headers, oldFormat); #endregion Sign diff --git a/PgpCore/PgpCore.csproj b/PgpCore/PgpCore.csproj index d3a5587..ff330fa 100644 --- a/PgpCore/PgpCore.csproj +++ b/PgpCore/PgpCore.csproj @@ -10,10 +10,10 @@ https://github.com/mattosaurus/PgpCore https://github.com/mattosaurus/PgpCore PGP .NET Core - 6.3.0.0 + 6.4.0.0 6.0.0.0 - 6.3.0 - v6.3.0 - Bug fixes + 6.4.0 + v6.4.0 - Remove armor option from string methods MIT true true