summary refs log tree commit diff
path: root/crypto/test/src/openssl
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/test/src/openssl')
-rw-r--r--crypto/test/src/openssl/test/AllTests.cs133
-rw-r--r--crypto/test/src/openssl/test/ReaderTest.cs380
-rw-r--r--crypto/test/src/openssl/test/WriterTest.cs185
3 files changed, 698 insertions, 0 deletions
diff --git a/crypto/test/src/openssl/test/AllTests.cs b/crypto/test/src/openssl/test/AllTests.cs
new file mode 100644
index 000000000..921208179
--- /dev/null
+++ b/crypto/test/src/openssl/test/AllTests.cs
@@ -0,0 +1,133 @@
+using System;
+using System.IO;
+using System.Text;
+
+using NUnit.Core;
+using NUnit.Framework;
+
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.OpenSsl.Tests
+{
+	[TestFixture]
+	public class AllTests
+	{
+		private class Password
+			: IPasswordFinder
+		{
+			private readonly char[] password;
+
+			public Password(
+				char[] word)
+			{
+				this.password = (char[]) word.Clone();
+			}
+
+			public char[] GetPassword()
+			{
+				return (char[]) password.Clone();
+			}
+		}
+		
+		[Suite]
+		public static TestSuite Suite
+		{
+			get
+			{
+				TestSuite suite = new TestSuite("OpenSSL Tests");
+				suite.Add(new AllTests());
+				return suite;
+			}
+		}
+
+		[Test]
+		public void TestOpenSsl()
+		{
+			Org.BouncyCastle.Utilities.Test.ITest[] tests = new Org.BouncyCastle.Utilities.Test.ITest[]{
+				new ReaderTest(),
+				new WriterTest()
+			};
+
+			foreach (Org.BouncyCastle.Utilities.Test.ITest test in tests)
+			{
+				SimpleTestResult result = (SimpleTestResult)test.Perform();
+
+				if (!result.IsSuccessful())
+				{
+					Assert.Fail(result.ToString());
+				}
+			}
+		}
+
+		[Test]
+		public void TestPkcs8Encrypted()
+		{
+			IAsymmetricCipherKeyPairGenerator kpGen = GeneratorUtilities.GetKeyPairGenerator("RSA");
+			kpGen.Init(new KeyGenerationParameters(new SecureRandom(), 1024));
+
+			AsymmetricKeyParameter privKey = kpGen.GenerateKeyPair().Private;
+
+			// FIXME see PbeUtilities and Pkcs8Generator
+//			EncryptedTest(privKey, Pkcs8Generator.Aes256Cbc);
+//			EncryptedTest(privKey, Pkcs8Generator.Des3Cbc);
+			EncryptedTest(privKey, Pkcs8Generator.PbeSha1_3DES);
+		}
+
+		private void EncryptedTest(AsymmetricKeyParameter privKey, string algorithm)
+		{
+			StringWriter sw = new StringWriter();
+			PemWriter pWrt = new PemWriter(sw);
+			Pkcs8Generator pkcs8 = new Pkcs8Generator(privKey, algorithm);
+			pkcs8.Password = "hello".ToCharArray();
+
+			pWrt.WriteObject(pkcs8);
+			pWrt.Writer.Close();
+
+			String result = sw.ToString();
+
+			PemReader pRd = new PemReader(new StringReader(result), new Password("hello".ToCharArray()));
+
+			AsymmetricKeyParameter rdKey = (AsymmetricKeyParameter)pRd.ReadObject();
+			pRd.Reader.Close();
+
+			Assert.AreEqual(privKey, rdKey);
+		}
+
+		[Test]
+		public void TestPkcs8Plain()
+		{
+			IAsymmetricCipherKeyPairGenerator kpGen = GeneratorUtilities.GetKeyPairGenerator("RSA");
+			kpGen.Init(new KeyGenerationParameters(new SecureRandom(), 1024));
+
+			AsymmetricKeyParameter privKey = kpGen.GenerateKeyPair().Private;
+
+			StringWriter sw = new StringWriter();
+			PemWriter pWrt = new PemWriter(sw);
+
+			Pkcs8Generator pkcs8 = new Pkcs8Generator(privKey);
+			pWrt.WriteObject(pkcs8);
+			pWrt.Writer.Close();
+
+			string result = sw.ToString();
+
+			PemReader pRd = new PemReader(new StringReader(result), new Password("hello".ToCharArray()));
+
+			AsymmetricKeyParameter rdKey = (AsymmetricKeyParameter)pRd.ReadObject();
+			pRd.Reader.Close();
+
+			Assert.AreEqual(privKey, rdKey);
+		}
+
+        public static void Main(
+			string[] args)
+        {
+            //junit.textui.TestRunner.run(suite());
+            EventListener el = new NullListener();
+            Suite.Run(el);
+        }
+	}
+}
diff --git a/crypto/test/src/openssl/test/ReaderTest.cs b/crypto/test/src/openssl/test/ReaderTest.cs
new file mode 100644
index 000000000..d27ed742f
--- /dev/null
+++ b/crypto/test/src/openssl/test/ReaderTest.cs
@@ -0,0 +1,380 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.OpenSsl.Tests
+{
+	/**
+	* basic class for reading test.pem - the password is "secret"
+	*/
+	[TestFixture]
+	public class ReaderTest
+		: SimpleTest
+	{
+		private class Password
+			: IPasswordFinder
+		{
+			private readonly char[] password;
+
+			public Password(
+				char[] word)
+			{
+				this.password = (char[]) word.Clone();
+			}
+
+			public char[] GetPassword()
+			{
+				return (char[]) password.Clone();
+			}
+		}
+
+		public override string Name
+		{
+			get { return "PEMReaderTest"; }
+		}
+
+		public override void PerformTest()
+		{
+			IPasswordFinder pGet = new Password("secret".ToCharArray());
+			PemReader pemRd = OpenPemResource("test.pem", pGet);
+			AsymmetricCipherKeyPair pair;
+
+			object o;
+			while ((o = pemRd.ReadObject()) != null)
+			{
+//				if (o is AsymmetricCipherKeyPair)
+//				{
+//					ackp = (AsymmetricCipherKeyPair)o;
+//
+//					Console.WriteLine(ackp.Public);
+//					Console.WriteLine(ackp.Private);
+//				}
+//				else
+//				{
+//					Console.WriteLine(o.ToString());
+//				}
+			}
+
+			//
+			// pkcs 7 data
+			//
+			pemRd = OpenPemResource("pkcs7.pem", null);
+
+			ContentInfo d = (ContentInfo)pemRd.ReadObject();    
+	
+			if (!d.ContentType.Equals(CmsObjectIdentifiers.EnvelopedData))
+			{
+				Fail("failed envelopedData check");
+			}
+
+			/*
+			{
+				//
+				// ECKey
+				//
+				pemRd = OpenPemResource("eckey.pem", null);
+	
+				// TODO Resolve return type issue with EC keys and fix PemReader to return parameters
+//				ECNamedCurveParameterSpec spec = (ECNamedCurveParameterSpec)pemRd.ReadObject();
+	
+				pair = (AsymmetricCipherKeyPair)pemRd.ReadObject();
+				ISigner sgr = SignerUtilities.GetSigner("ECDSA");
+	
+				sgr.Init(true, pair.Private);
+	
+				byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' };
+	
+				sgr.BlockUpdate(message, 0, message.Length);
+	
+				byte[] sigBytes = sgr.GenerateSignature();
+	
+				sgr.Init(false, pair.Public);
+	
+				sgr.BlockUpdate(message, 0, message.Length);
+	
+				if (!sgr.VerifySignature(sigBytes))
+				{
+					Fail("EC verification failed");
+				}
+
+				// TODO Resolve this issue with the algorithm name, study Java version
+//				if (!((ECPublicKeyParameters) pair.Public).AlgorithmName.Equals("ECDSA"))
+//				{
+//					Fail("wrong algorithm name on public got: " + ((ECPublicKeyParameters) pair.Public).AlgorithmName);
+//				}
+//	
+//				if (!((ECPrivateKeyParameters) pair.Private).AlgorithmName.Equals("ECDSA"))
+//				{
+//					Fail("wrong algorithm name on private got: " + ((ECPrivateKeyParameters) pair.Private).AlgorithmName);
+//				}
+			}
+			*/
+
+			//
+			// writer/parser test
+			//
+			IAsymmetricCipherKeyPairGenerator kpGen = GeneratorUtilities.GetKeyPairGenerator("RSA");
+			kpGen.Init(
+				new RsaKeyGenerationParameters(
+				BigInteger.ValueOf(0x10001),
+				new SecureRandom(),
+				768,
+				25));
+
+			pair = kpGen.GenerateKeyPair();
+
+			keyPairTest("RSA", pair);
+
+//			kpGen = KeyPairGenerator.getInstance("DSA");
+//			kpGen.initialize(512, new SecureRandom());
+			DsaParametersGenerator pGen = new DsaParametersGenerator();
+			pGen.Init(512, 80, new SecureRandom());
+
+			kpGen = GeneratorUtilities.GetKeyPairGenerator("DSA");
+			kpGen.Init(
+				new DsaKeyGenerationParameters(
+					new SecureRandom(),
+					pGen.GenerateParameters()));
+
+			pair = kpGen.GenerateKeyPair();
+
+			keyPairTest("DSA", pair);
+
+			//
+			// PKCS7
+			//
+			MemoryStream bOut = new MemoryStream();
+			PemWriter pWrt = new PemWriter(new StreamWriter(bOut));
+
+			pWrt.WriteObject(d);
+			pWrt.Writer.Close();
+
+			pemRd = new PemReader(new StreamReader(new MemoryStream(bOut.ToArray(), false)));
+			d = (ContentInfo)pemRd.ReadObject();    
+
+			if (!d.ContentType.Equals(CmsObjectIdentifiers.EnvelopedData))
+			{
+				Fail("failed envelopedData recode check");
+			}
+
+
+			// OpenSSL test cases (as embedded resources)
+			doOpenSslDsaTest("unencrypted");
+			doOpenSslRsaTest("unencrypted");
+
+			doOpenSslTests("aes128");
+			doOpenSslTests("aes192");
+			doOpenSslTests("aes256");
+			doOpenSslTests("blowfish");
+			doOpenSslTests("des1");
+			doOpenSslTests("des2");
+			doOpenSslTests("des3");
+			doOpenSslTests("rc2_128");
+
+			doOpenSslDsaTest("rc2_40_cbc");
+			doOpenSslRsaTest("rc2_40_cbc");
+			doOpenSslDsaTest("rc2_64_cbc");
+			doOpenSslRsaTest("rc2_64_cbc");
+
+			// TODO Figure out why exceptions differ for commented out cases
+			doDudPasswordTest("7fd98", 0, "Corrupted stream - out of bounds length found");
+			doDudPasswordTest("ef677", 1, "Corrupted stream - out of bounds length found");
+//			doDudPasswordTest("800ce", 2, "cannot recognise object in stream");
+			doDudPasswordTest("b6cd8", 3, "DEF length 81 object truncated by 56");
+			doDudPasswordTest("28ce09", 4, "DEF length 110 object truncated by 28");
+			doDudPasswordTest("2ac3b9", 5, "DER length more than 4 bytes: 11");
+			doDudPasswordTest("2cba96", 6, "DEF length 100 object truncated by 35");
+			doDudPasswordTest("2e3354", 7, "DEF length 42 object truncated by 9");
+			doDudPasswordTest("2f4142", 8, "DER length more than 4 bytes: 14");
+			doDudPasswordTest("2fe9bb", 9, "DER length more than 4 bytes: 65");
+			doDudPasswordTest("3ee7a8", 10, "DER length more than 4 bytes: 57");
+			doDudPasswordTest("41af75", 11, "malformed sequence in DSA private key");
+			doDudPasswordTest("1704a5", 12, "corrupted stream detected");
+//			doDudPasswordTest("1c5822", 13, "corrupted stream detected");
+//			doDudPasswordTest("5a3d16", 14, "corrupted stream detected");
+			doDudPasswordTest("8d0c97", 15, "corrupted stream detected");
+			doDudPasswordTest("bc0daf", 16, "corrupted stream detected");
+			doDudPasswordTest("aaf9c4d",17, "Corrupted stream - out of bounds length found");
+
+			// encrypted private key test
+			pGet = new Password("password".ToCharArray());
+			pemRd = OpenPemResource("enckey.pem", pGet);
+
+			RsaPrivateCrtKeyParameters privKey = (RsaPrivateCrtKeyParameters)pemRd.ReadObject();
+
+			if (!privKey.PublicExponent.Equals(new BigInteger("10001", 16)))
+			{
+				Fail("decryption of private key data check failed");
+			}
+
+			// general PKCS8 test
+			pGet = new Password("password".ToCharArray());
+			pemRd = OpenPemResource("pkcs8test.pem", pGet);
+
+			while ((privKey = (RsaPrivateCrtKeyParameters)pemRd.ReadObject()) != null)
+			{
+				if (!privKey.PublicExponent.Equals(new BigInteger("10001", 16)))
+				{
+					Fail("decryption of private key data check failed");
+				}
+			}
+		}
+
+		private void keyPairTest(
+			string					name,
+			AsymmetricCipherKeyPair	pair) 
+		{
+			MemoryStream bOut = new MemoryStream();
+			PemWriter pWrt = new PemWriter(new StreamWriter(bOut));
+
+			pWrt.WriteObject(pair.Public);
+			pWrt.Writer.Close();
+
+			PemReader pemRd = new PemReader(new StreamReader(new MemoryStream(bOut.ToArray(), false)));
+
+			AsymmetricKeyParameter pubK = (AsymmetricKeyParameter) pemRd.ReadObject();
+			if (!pubK.Equals(pair.Public))
+			{
+				Fail("Failed public key read: " + name);
+			}
+
+			bOut = new MemoryStream();
+			pWrt = new PemWriter(new StreamWriter(bOut));
+
+			pWrt.WriteObject(pair.Private);
+			pWrt.Writer.Close();
+
+			pemRd = new PemReader(new StreamReader(new MemoryStream(bOut.ToArray(), false)));
+
+			AsymmetricCipherKeyPair kPair = (AsymmetricCipherKeyPair) pemRd.ReadObject();
+			if (!kPair.Private.Equals(pair.Private))
+			{
+				Fail("Failed private key read: " + name);
+			}
+	        
+			if (!kPair.Public.Equals(pair.Public))
+			{
+				Fail("Failed private key public read: " + name);
+			}
+		}
+
+		private void doOpenSslTests(
+			string baseName)
+		{
+			doOpenSslDsaModesTest(baseName);
+			doOpenSslRsaModesTest(baseName);
+		}
+
+		private void doOpenSslDsaModesTest(
+			string baseName)
+		{
+			doOpenSslDsaTest(baseName + "_cbc");
+			doOpenSslDsaTest(baseName + "_cfb");
+			doOpenSslDsaTest(baseName + "_ecb");
+			doOpenSslDsaTest(baseName + "_ofb");
+		}
+
+		private void doOpenSslRsaModesTest(
+			string baseName)
+		{
+			doOpenSslRsaTest(baseName + "_cbc");
+			doOpenSslRsaTest(baseName + "_cfb");
+			doOpenSslRsaTest(baseName + "_ecb");
+			doOpenSslRsaTest(baseName + "_ofb");
+		}
+
+		private void doOpenSslDsaTest(
+			string name)
+		{
+			string fileName = "dsa.openssl_dsa_" + name + ".pem";
+
+			doOpenSslTestFile(fileName, typeof(DsaPrivateKeyParameters));
+		}
+
+		private void doOpenSslRsaTest(
+			string name)
+		{
+			string fileName = "rsa.openssl_rsa_" + name + ".pem";
+
+			doOpenSslTestFile(fileName, typeof(RsaPrivateCrtKeyParameters));
+		}
+
+		private void doOpenSslTestFile(
+			string	fileName,
+			Type	expectedPrivKeyType)
+		{
+			PemReader pr = OpenPemResource(fileName, new Password("changeit".ToCharArray()));
+			AsymmetricCipherKeyPair kp = pr.ReadObject() as AsymmetricCipherKeyPair;
+			pr.Reader.Close();
+
+			if (kp == null)
+			{
+				Fail("Didn't find OpenSSL key");
+			}
+
+			if (!expectedPrivKeyType.IsInstanceOfType(kp.Private))
+			{
+				Fail("Returned key not of correct type");
+			}
+		}
+
+		private void doDudPasswordTest(string password, int index, string message)
+		{
+			// illegal state exception check - in this case the wrong password will
+			// cause an underlying class cast exception.
+			try
+			{
+				IPasswordFinder pGet = new Password(password.ToCharArray());
+				PemReader pemRd = OpenPemResource("test.pem", pGet);
+
+				Object o;
+				while ((o = pemRd.ReadObject()) != null)
+				{
+				}
+
+				Fail("issue not detected: " + index);
+			}
+			catch (IOException e)
+			{
+				if (e.Message.IndexOf(message) < 0)
+				{
+					Console.Error.WriteLine(message);
+					Console.Error.WriteLine(e.Message);
+					Fail("issue " + index + " exception thrown, but wrong message");
+				}
+			}
+		}
+
+		private static PemReader OpenPemResource(
+			string			fileName,
+			IPasswordFinder	pGet)
+		{
+			Stream data = GetTestDataAsStream("openssl." + fileName);
+			TextReader tr = new StreamReader(data);
+			return new PemReader(tr, pGet);
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new ReaderTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}
diff --git a/crypto/test/src/openssl/test/WriterTest.cs b/crypto/test/src/openssl/test/WriterTest.cs
new file mode 100644
index 000000000..41f371708
--- /dev/null
+++ b/crypto/test/src/openssl/test/WriterTest.cs
@@ -0,0 +1,185 @@
+using System;
+using System.IO;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Utilities.IO.Pem;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.OpenSsl.Tests
+{
+	[TestFixture]
+	public class WriterTest
+		: SimpleTest
+	{
+		private static readonly SecureRandom random = new SecureRandom();
+
+		// TODO Replace with a randomly generated key each test run?
+		private static readonly RsaPrivateCrtKeyParameters testRsaKey = new RsaPrivateCrtKeyParameters(
+			new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
+			new BigInteger("11", 16),
+			new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16),
+			new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16),
+			new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16),
+			new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16),
+			new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16),
+			new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16));
+
+		private static readonly DsaParameters testDsaParams = new DsaParameters(
+			new BigInteger("7434410770759874867539421675728577177024889699586189000788950934679315164676852047058354758883833299702695428196962057871264685291775577130504050839126673"),
+			new BigInteger("1138656671590261728308283492178581223478058193247"),
+			new BigInteger("4182906737723181805517018315469082619513954319976782448649747742951189003482834321192692620856488639629011570381138542789803819092529658402611668375788410"));
+
+//		private static readonly PKCS8EncodedKeySpec testEcDsaKeySpec = new PKCS8EncodedKeySpec(
+//			Base64.Decode("MIG/AgEAMBAGByqGSM49AgEGBSuBBAAiBIGnMIGkAgEBBDCSBU3vo7ieeKs0ABQamy/ynxlde7Ylr8HmyfLaNnMr" +
+//				"jAwPp9R+KMUEhB7zxSAXv9KgBwYFK4EEACKhZANiAQQyyolMpg+TyB4o9kPWqafHIOe8o9K1glus+w2sY8OIPQQWGb5i5LdAyi" +
+//				"/SscwU24rZM0yiL3BHodp9ccwyhLrFYgXJUOQcCN2dno1GMols5497in5gL5+zn0yMsRtyv5o=")
+//		);
+		private static readonly byte[] testEcDsaKeyBytes = Base64.Decode(
+			  "MIG/AgEAMBAGByqGSM49AgEGBSuBBAAiBIGnMIGkAgEBBDCSBU3vo7ieeKs0ABQamy/ynxlde7Ylr8HmyfLaNnMr"
+			+ "jAwPp9R+KMUEhB7zxSAXv9KgBwYFK4EEACKhZANiAQQyyolMpg+TyB4o9kPWqafHIOe8o9K1glus+w2sY8OIPQQWGb5i5LdAyi"
+			+ "/SscwU24rZM0yiL3BHodp9ccwyhLrFYgXJUOQcCN2dno1GMols5497in5gL5+zn0yMsRtyv5o=");
+
+		private static readonly char[] testPassword = "bouncy".ToCharArray();
+
+		private static readonly string[] algorithms = new string[]
+		{
+			"AES-128-CBC", "AES-128-CFB", "AES-128-ECB", "AES-128-OFB",
+			"AES-192-CBC", "AES-192-CFB", "AES-192-ECB", "AES-192-OFB",
+			"AES-256-CBC", "AES-256-CFB", "AES-256-ECB", "AES-256-OFB",
+			"BF-CBC", "BF-CFB", "BF-ECB", "BF-OFB",
+			"DES-CBC", "DES-CFB", "DES-ECB", "DES-OFB",
+			"DES-EDE", "DES-EDE-CBC", "DES-EDE-CFB", "DES-EDE-ECB", "DES-EDE-OFB",
+			"DES-EDE3", "DES-EDE3-CBC", "DES-EDE3-CFB", "DES-EDE3-ECB", "DES-EDE3-OFB",
+			"RC2-CBC", "RC2-CFB", "RC2-ECB", "RC2-OFB",
+			"RC2-40-CBC",
+			"RC2-64-CBC",
+		};
+
+		private class Password
+			: IPasswordFinder
+		{
+			private readonly char[] password;
+
+			public Password(
+				char[] word)
+			{
+				this.password = (char[]) word.Clone();
+			}
+
+			public char[] GetPassword()
+			{
+				return (char[]) password.Clone();
+			}
+		}
+
+		public override string Name
+		{
+			get { return "PEMWriterTest"; }
+		}
+
+		public override void PerformTest()
+		{
+			IAsymmetricCipherKeyPairGenerator dsaKpg = GeneratorUtilities.GetKeyPairGenerator("DSA");
+			dsaKpg.Init(new DsaKeyGenerationParameters(random, testDsaParams));
+			AsymmetricCipherKeyPair testDsaKp = dsaKpg.GenerateKeyPair();
+			AsymmetricKeyParameter testDsaKey = testDsaKp.Private;
+
+			doWriteReadTest(testDsaKey);
+			doWriteReadTests(testDsaKey, algorithms);
+
+			doWriteReadTest(testRsaKey);
+			doWriteReadTests(testRsaKey, algorithms);
+
+			AsymmetricKeyParameter ecPriv = PrivateKeyFactory.CreateKey(testEcDsaKeyBytes);
+			doWriteReadTest(ecPriv);
+			doWriteReadTests(ecPriv, algorithms);
+
+			IAsymmetricCipherKeyPairGenerator ecKpg = GeneratorUtilities.GetKeyPairGenerator("ECDSA");
+			ecKpg.Init(new KeyGenerationParameters(random, 239));
+			ecPriv = ecKpg.GenerateKeyPair().Private;
+			doWriteReadTest(ecPriv);
+			doWriteReadTests(ecPriv, algorithms);
+
+			// override test
+			PemWriter pWrt = new PemWriter(new StringWriter());
+
+			object o = new PemObject("FRED", new byte[100]);
+			pWrt.WriteObject(o);
+
+			pWrt.Writer.Close();
+		}
+
+		private void doWriteReadTests(
+			AsymmetricKeyParameter	akp,
+			string[]				algorithms)
+		{
+			foreach (string algorithm in algorithms)
+			{
+				doWriteReadTest(akp, algorithm);
+			}
+		}
+
+		private void doWriteReadTest(
+			AsymmetricKeyParameter	akp)
+		{
+			StringWriter sw = new StringWriter();
+			PemWriter pw = new PemWriter(sw);
+
+			pw.WriteObject(akp);
+			pw.Writer.Close();
+
+			string data = sw.ToString();
+
+			PemReader pr = new PemReader(new StringReader(data));
+
+			AsymmetricCipherKeyPair kp = pr.ReadObject() as AsymmetricCipherKeyPair;
+
+			if (kp == null || !kp.Private.Equals(akp))
+			{
+				Fail("Failed to read back test key");
+			}
+		}
+
+		private void doWriteReadTest(
+			AsymmetricKeyParameter	akp,
+			string					algorithm)
+		{
+			StringWriter sw = new StringWriter();
+			PemWriter pw = new PemWriter(sw);
+
+			pw.WriteObject(akp, algorithm, testPassword, random);
+			pw.Writer.Close();
+
+			string data = sw.ToString();
+
+			PemReader pr = new PemReader(new StringReader(data), new Password(testPassword));
+
+			AsymmetricCipherKeyPair kp = pr.ReadObject() as AsymmetricCipherKeyPair;
+
+			if (kp == null || !kp.Private.Equals(akp))
+			{
+				Fail("Failed to read back test key encoded with: " + algorithm);
+			}
+		}
+
+		public static void Main(
+			string[] args)
+		{
+			RunTest(new WriterTest());
+		}
+
+		[Test]
+		public void TestFunction()
+		{
+			string resultText = Perform().ToString();
+
+			Assert.AreEqual(Name + ": Okay", resultText);
+		}
+	}
+}