summary refs log tree commit diff
path: root/crypto/src
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src')
-rw-r--r--crypto/src/asn1/pkcs/PrivateKeyInfo.cs143
-rw-r--r--crypto/src/cms/KeyAgreeRecipientInformation.cs410
-rw-r--r--crypto/src/openssl/MiscPemGenerator.cs470
-rw-r--r--crypto/src/security/PrivateKeyFactory.cs16
4 files changed, 524 insertions, 515 deletions
diff --git a/crypto/src/asn1/pkcs/PrivateKeyInfo.cs b/crypto/src/asn1/pkcs/PrivateKeyInfo.cs
index 91b6fb456..a63595d54 100644
--- a/crypto/src/asn1/pkcs/PrivateKeyInfo.cs
+++ b/crypto/src/asn1/pkcs/PrivateKeyInfo.cs
@@ -10,46 +10,46 @@ namespace Org.BouncyCastle.Asn1.Pkcs
     public class PrivateKeyInfo
         : Asn1Encodable
     {
-        private readonly Asn1Object				privKey;
+        private readonly Asn1OctetString        privKey;
         private readonly AlgorithmIdentifier	algID;
-		private readonly Asn1Set				attributes;
+        private readonly Asn1Set				attributes;
 
-		public static PrivateKeyInfo GetInstance(
-			object obj)
-		{
-			if (obj is PrivateKeyInfo)
-				return (PrivateKeyInfo) obj;
+        public static PrivateKeyInfo GetInstance(Asn1TaggedObject obj, bool explicitly)
+        {
+            return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+        }
 
-			if (obj != null)
-				return new PrivateKeyInfo(Asn1Sequence.GetInstance(obj));
+        public static PrivateKeyInfo GetInstance(
+            object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is PrivateKeyInfo)
+                return (PrivateKeyInfo) obj;
+            return new PrivateKeyInfo(Asn1Sequence.GetInstance(obj));
+        }
 
-			return null;
-		}
+        public PrivateKeyInfo(AlgorithmIdentifier algID, Asn1Object privateKey)
+            : this(algID, privateKey, null)
+        {
+        }
 
-		public PrivateKeyInfo(
+        public PrivateKeyInfo(
             AlgorithmIdentifier	algID,
-            Asn1Object			privateKey)
-			: this(algID, privateKey, null)
-		{
-		}
-
-		public PrivateKeyInfo(
-			AlgorithmIdentifier	algID,
-			Asn1Object			privateKey,
-			Asn1Set				attributes)
-		{
-			this.privKey = privateKey;
-			this.algID = algID;
-			this.attributes = attributes;
-		}
-
-		private PrivateKeyInfo(
-            Asn1Sequence seq)
+            Asn1Object			privateKey,
+            Asn1Set				attributes)
+        {
+            this.algID = algID;
+            this.privKey = new DerOctetString(privateKey.GetEncoded(Asn1Encodable.Der));
+            this.attributes = attributes;
+        }
+
+        private PrivateKeyInfo(Asn1Sequence seq)
         {
             IEnumerator e = seq.GetEnumerator();
 
-			e.MoveNext();
-            BigInteger version = ((DerInteger) e.Current).Value;
+            e.MoveNext();
+            BigInteger version = ((DerInteger)e.Current).Value;
             if (version.IntValue != 0)
             {
                 throw new ArgumentException("wrong version for private key info: " + version.IntValue);
@@ -57,41 +57,53 @@ namespace Org.BouncyCastle.Asn1.Pkcs
 
             e.MoveNext();
             algID = AlgorithmIdentifier.GetInstance(e.Current);
+            e.MoveNext();
+            privKey = Asn1OctetString.GetInstance(e.Current);
 
-			try
-            {
-				e.MoveNext();
-				Asn1OctetString data = (Asn1OctetString) e.Current;
-
-				privKey = Asn1Object.FromByteArray(data.GetOctets());
-            }
-            catch (IOException)
+            if (e.MoveNext())
             {
-				throw new ArgumentException("Error recoverying private key from sequence");
+                attributes = Asn1Set.GetInstance((Asn1TaggedObject)e.Current, false);
             }
+        }
 
-			if (e.MoveNext())
-			{
-				attributes = Asn1Set.GetInstance((Asn1TaggedObject) e.Current, false);
-			}
-		}
+        public virtual AlgorithmIdentifier PrivateKeyAlgorithm
+        {
+            get { return algID; }
+        }
 
-		public AlgorithmIdentifier AlgorithmID
-		{
-			get { return algID; }
-		}
+        [Obsolete("Use 'PrivateKeyAlgorithm' property instead")]
+        public virtual AlgorithmIdentifier AlgorithmID
+        {
+            get { return algID; }
+        }
 
-		public Asn1Object PrivateKey
-		{
-			get { return privKey; }
-		}
+        public virtual Asn1Object ParsePrivateKey()
+        {
+            return Asn1Object.FromByteArray(privKey.GetOctets());
+        }
 
-    	public Asn1Set Attributes
-    	{
-    		get { return attributes; }
-    	}
+        [Obsolete("Use 'ParsePrivateKey' instead")]
+        public virtual Asn1Object PrivateKey
+        {
+            get
+            {
+                try
+                {
+                    return ParsePrivateKey();
+                }
+                catch (IOException e)
+                {
+                    throw new InvalidOperationException("unable to parse private key");
+                }
+            }
+        }
 
-		/**
+        public virtual Asn1Set Attributes
+        {
+            get { return attributes; }
+        }
+
+        /**
          * write out an RSA private key with its associated information
          * as described in Pkcs8.
          * <pre>
@@ -110,17 +122,14 @@ namespace Org.BouncyCastle.Asn1.Pkcs
          */
         public override Asn1Object ToAsn1Object()
         {
-			Asn1EncodableVector v = new Asn1EncodableVector(
-				new DerInteger(0),
-				algID,
-				new DerOctetString(privKey));
+            Asn1EncodableVector v = new Asn1EncodableVector(new DerInteger(0), algID, privKey);
 
-			if (attributes != null)
-			{
-				v.Add(new DerTaggedObject(false, 0, attributes));
-			}
+            if (attributes != null)
+            {
+                v.Add(new DerTaggedObject(false, 0, attributes));
+            }
 
-			return new DerSequence(v);
+            return new DerSequence(v);
         }
     }
 }
diff --git a/crypto/src/cms/KeyAgreeRecipientInformation.cs b/crypto/src/cms/KeyAgreeRecipientInformation.cs
index 38a94b0a4..8e006e545 100644
--- a/crypto/src/cms/KeyAgreeRecipientInformation.cs
+++ b/crypto/src/cms/KeyAgreeRecipientInformation.cs
@@ -18,209 +18,209 @@ using Org.BouncyCastle.X509;
 
 namespace Org.BouncyCastle.Cms
 {
-	/**
-	* the RecipientInfo class for a recipient who has been sent a message
-	* encrypted using key agreement.
-	*/
-	public class KeyAgreeRecipientInformation
-		: RecipientInformation
-	{
-		private KeyAgreeRecipientInfo info;
-		private Asn1OctetString       encryptedKey;
-
-		internal static void ReadRecipientInfo(IList infos, KeyAgreeRecipientInfo info,
-			CmsSecureReadable secureReadable)
-		{
-			try
-			{
-				foreach (Asn1Encodable rek in info.RecipientEncryptedKeys)
-				{
-					RecipientEncryptedKey id = RecipientEncryptedKey.GetInstance(rek.ToAsn1Object());
-
-					RecipientID rid = new RecipientID();
-
-					Asn1.Cms.KeyAgreeRecipientIdentifier karid = id.Identifier;
-
-					Asn1.Cms.IssuerAndSerialNumber iAndSN = karid.IssuerAndSerialNumber;
-					if (iAndSN != null)
-					{
-						rid.Issuer = iAndSN.Name;
-						rid.SerialNumber = iAndSN.SerialNumber.Value;
-					}
-					else
-					{
-						Asn1.Cms.RecipientKeyIdentifier rKeyID = karid.RKeyID;
-
-						// Note: 'date' and 'other' fields of RecipientKeyIdentifier appear to be only informational 
-
-						rid.SubjectKeyIdentifier = rKeyID.SubjectKeyIdentifier.GetOctets();
-					}
-
-					infos.Add(new KeyAgreeRecipientInformation(info, rid, id.EncryptedKey,
-						secureReadable));
-				}
-			}
-			catch (IOException e)
-			{
-				throw new ArgumentException("invalid rid in KeyAgreeRecipientInformation", e);
-			}
-		}
-
-		internal KeyAgreeRecipientInformation(
-			KeyAgreeRecipientInfo	info,
-			RecipientID				rid,
-			Asn1OctetString			encryptedKey,
-			CmsSecureReadable		secureReadable)
-			: base(info.KeyEncryptionAlgorithm, secureReadable)
-		{
-			this.info = info;
-			this.rid = rid;
-			this.encryptedKey = encryptedKey;
-		}
-
-		private AsymmetricKeyParameter GetSenderPublicKey(
-			AsymmetricKeyParameter		receiverPrivateKey,
-			OriginatorIdentifierOrKey	originator)
-		{
-			OriginatorPublicKey opk = originator.OriginatorPublicKey;
-			if (opk != null)
-			{
-				return GetPublicKeyFromOriginatorPublicKey(receiverPrivateKey, opk);
-			}
-			
-			OriginatorID origID = new OriginatorID();
-			
-			Asn1.Cms.IssuerAndSerialNumber iAndSN = originator.IssuerAndSerialNumber;
-			if (iAndSN != null)
-			{
-				origID.Issuer = iAndSN.Name;
-				origID.SerialNumber = iAndSN.SerialNumber.Value;
-			}
-			else
-			{
-				SubjectKeyIdentifier ski = originator.SubjectKeyIdentifier;
-
-				origID.SubjectKeyIdentifier = ski.GetKeyIdentifier();
-			}
-
-			return GetPublicKeyFromOriginatorID(origID);
-		}
-
-		private AsymmetricKeyParameter GetPublicKeyFromOriginatorPublicKey(
-			AsymmetricKeyParameter	receiverPrivateKey,
-			OriginatorPublicKey		originatorPublicKey)
-		{
-			PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(receiverPrivateKey);
-			SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(
-				privInfo.AlgorithmID,
-				originatorPublicKey.PublicKey.GetBytes());
-			return PublicKeyFactory.CreateKey(pubInfo);
-		}
-
-		private AsymmetricKeyParameter GetPublicKeyFromOriginatorID(
-			OriginatorID origID)
-		{
-			// TODO Support all alternatives for OriginatorIdentifierOrKey
-			// see RFC 3852 6.2.2
-			throw new CmsException("No support for 'originator' as IssuerAndSerialNumber or SubjectKeyIdentifier");
-		}
-
-		private KeyParameter CalculateAgreedWrapKey(
-			string					wrapAlg,
-			AsymmetricKeyParameter	senderPublicKey,
-			AsymmetricKeyParameter	receiverPrivateKey)
-		{
-			DerObjectIdentifier agreeAlgID = keyEncAlg.ObjectID;
-
-			ICipherParameters senderPublicParams = senderPublicKey;
-			ICipherParameters receiverPrivateParams = receiverPrivateKey;
-
-			if (agreeAlgID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
-			{
-				byte[] ukmEncoding = info.UserKeyingMaterial.GetOctets();
-				MQVuserKeyingMaterial ukm = MQVuserKeyingMaterial.GetInstance(
-					Asn1Object.FromByteArray(ukmEncoding));
-
-				AsymmetricKeyParameter ephemeralKey = GetPublicKeyFromOriginatorPublicKey(
-					receiverPrivateKey, ukm.EphemeralPublicKey);
-
-				senderPublicParams = new MqvPublicParameters(
-					(ECPublicKeyParameters)senderPublicParams,
-					(ECPublicKeyParameters)ephemeralKey);
-				receiverPrivateParams = new MqvPrivateParameters(
-					(ECPrivateKeyParameters)receiverPrivateParams,
-					(ECPrivateKeyParameters)receiverPrivateParams);
-			}
-
-			IBasicAgreement agreement = AgreementUtilities.GetBasicAgreementWithKdf(
-				agreeAlgID, wrapAlg);
-			agreement.Init(receiverPrivateParams);
-			BigInteger agreedValue = agreement.CalculateAgreement(senderPublicParams);
-
-			int wrapKeySize = GeneratorUtilities.GetDefaultKeySize(wrapAlg) / 8;
-			byte[] wrapKeyBytes = X9IntegerConverter.IntegerToBytes(agreedValue, wrapKeySize);
-			return ParameterUtilities.CreateKeyParameter(wrapAlg, wrapKeyBytes);
-		}
-
-		private KeyParameter UnwrapSessionKey(
-			string			wrapAlg,
-			KeyParameter	agreedKey)
-		{
-			byte[] encKeyOctets = encryptedKey.GetOctets();
-
-			IWrapper keyCipher = WrapperUtilities.GetWrapper(wrapAlg);
-			keyCipher.Init(false, agreedKey);
-			byte[] sKeyBytes = keyCipher.Unwrap(encKeyOctets, 0, encKeyOctets.Length);
-			return ParameterUtilities.CreateKeyParameter(GetContentAlgorithmName(), sKeyBytes);
-		}
-
-		internal KeyParameter GetSessionKey(
-			AsymmetricKeyParameter receiverPrivateKey)
-		{
-			try
-			{
-				string wrapAlg = DerObjectIdentifier.GetInstance(
-					Asn1Sequence.GetInstance(keyEncAlg.Parameters)[0]).Id;
-
-				AsymmetricKeyParameter senderPublicKey = GetSenderPublicKey(
-					receiverPrivateKey, info.Originator);
-
-				KeyParameter agreedWrapKey = CalculateAgreedWrapKey(wrapAlg,
-					senderPublicKey, receiverPrivateKey);
-
-				return UnwrapSessionKey(wrapAlg, agreedWrapKey);
-			}
-			catch (SecurityUtilityException e)
-			{
-				throw new CmsException("couldn't create cipher.", e);
-			}
-			catch (InvalidKeyException e)
-			{
-				throw new CmsException("key invalid in message.", e);
-			}
-			catch (Exception e)
-			{
-				throw new CmsException("originator key invalid.", e);
-			}
-		}
-
-		/**
-		* decrypt the content and return an input stream.
-		*/
-		public override CmsTypedStream GetContentStream(
-			ICipherParameters key)
-		{
-			if (!(key is AsymmetricKeyParameter))
-				throw new ArgumentException("KeyAgreement requires asymmetric key", "key");
-
-			AsymmetricKeyParameter receiverPrivateKey = (AsymmetricKeyParameter) key;
-
-			if (!receiverPrivateKey.IsPrivate)
-				throw new ArgumentException("Expected private key", "key");
-
-			KeyParameter sKey = GetSessionKey(receiverPrivateKey);
-
-			return GetContentFromSessionKey(sKey);
-		}
-	}
+    /**
+    * the RecipientInfo class for a recipient who has been sent a message
+    * encrypted using key agreement.
+    */
+    public class KeyAgreeRecipientInformation
+        : RecipientInformation
+    {
+        private KeyAgreeRecipientInfo info;
+        private Asn1OctetString       encryptedKey;
+
+        internal static void ReadRecipientInfo(IList infos, KeyAgreeRecipientInfo info,
+            CmsSecureReadable secureReadable)
+        {
+            try
+            {
+                foreach (Asn1Encodable rek in info.RecipientEncryptedKeys)
+                {
+                    RecipientEncryptedKey id = RecipientEncryptedKey.GetInstance(rek.ToAsn1Object());
+
+                    RecipientID rid = new RecipientID();
+
+                    Asn1.Cms.KeyAgreeRecipientIdentifier karid = id.Identifier;
+
+                    Asn1.Cms.IssuerAndSerialNumber iAndSN = karid.IssuerAndSerialNumber;
+                    if (iAndSN != null)
+                    {
+                        rid.Issuer = iAndSN.Name;
+                        rid.SerialNumber = iAndSN.SerialNumber.Value;
+                    }
+                    else
+                    {
+                        Asn1.Cms.RecipientKeyIdentifier rKeyID = karid.RKeyID;
+
+                        // Note: 'date' and 'other' fields of RecipientKeyIdentifier appear to be only informational 
+
+                        rid.SubjectKeyIdentifier = rKeyID.SubjectKeyIdentifier.GetOctets();
+                    }
+
+                    infos.Add(new KeyAgreeRecipientInformation(info, rid, id.EncryptedKey,
+                        secureReadable));
+                }
+            }
+            catch (IOException e)
+            {
+                throw new ArgumentException("invalid rid in KeyAgreeRecipientInformation", e);
+            }
+        }
+
+        internal KeyAgreeRecipientInformation(
+            KeyAgreeRecipientInfo	info,
+            RecipientID				rid,
+            Asn1OctetString			encryptedKey,
+            CmsSecureReadable		secureReadable)
+            : base(info.KeyEncryptionAlgorithm, secureReadable)
+        {
+            this.info = info;
+            this.rid = rid;
+            this.encryptedKey = encryptedKey;
+        }
+
+        private AsymmetricKeyParameter GetSenderPublicKey(
+            AsymmetricKeyParameter		receiverPrivateKey,
+            OriginatorIdentifierOrKey	originator)
+        {
+            OriginatorPublicKey opk = originator.OriginatorPublicKey;
+            if (opk != null)
+            {
+                return GetPublicKeyFromOriginatorPublicKey(receiverPrivateKey, opk);
+            }
+            
+            OriginatorID origID = new OriginatorID();
+            
+            Asn1.Cms.IssuerAndSerialNumber iAndSN = originator.IssuerAndSerialNumber;
+            if (iAndSN != null)
+            {
+                origID.Issuer = iAndSN.Name;
+                origID.SerialNumber = iAndSN.SerialNumber.Value;
+            }
+            else
+            {
+                SubjectKeyIdentifier ski = originator.SubjectKeyIdentifier;
+
+                origID.SubjectKeyIdentifier = ski.GetKeyIdentifier();
+            }
+
+            return GetPublicKeyFromOriginatorID(origID);
+        }
+
+        private AsymmetricKeyParameter GetPublicKeyFromOriginatorPublicKey(
+            AsymmetricKeyParameter	receiverPrivateKey,
+            OriginatorPublicKey		originatorPublicKey)
+        {
+            PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(receiverPrivateKey);
+            SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(
+                privInfo.PrivateKeyAlgorithm,
+                originatorPublicKey.PublicKey.GetBytes());
+            return PublicKeyFactory.CreateKey(pubInfo);
+        }
+
+        private AsymmetricKeyParameter GetPublicKeyFromOriginatorID(
+            OriginatorID origID)
+        {
+            // TODO Support all alternatives for OriginatorIdentifierOrKey
+            // see RFC 3852 6.2.2
+            throw new CmsException("No support for 'originator' as IssuerAndSerialNumber or SubjectKeyIdentifier");
+        }
+
+        private KeyParameter CalculateAgreedWrapKey(
+            string					wrapAlg,
+            AsymmetricKeyParameter	senderPublicKey,
+            AsymmetricKeyParameter	receiverPrivateKey)
+        {
+            DerObjectIdentifier agreeAlgID = keyEncAlg.ObjectID;
+
+            ICipherParameters senderPublicParams = senderPublicKey;
+            ICipherParameters receiverPrivateParams = receiverPrivateKey;
+
+            if (agreeAlgID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf))
+            {
+                byte[] ukmEncoding = info.UserKeyingMaterial.GetOctets();
+                MQVuserKeyingMaterial ukm = MQVuserKeyingMaterial.GetInstance(
+                    Asn1Object.FromByteArray(ukmEncoding));
+
+                AsymmetricKeyParameter ephemeralKey = GetPublicKeyFromOriginatorPublicKey(
+                    receiverPrivateKey, ukm.EphemeralPublicKey);
+
+                senderPublicParams = new MqvPublicParameters(
+                    (ECPublicKeyParameters)senderPublicParams,
+                    (ECPublicKeyParameters)ephemeralKey);
+                receiverPrivateParams = new MqvPrivateParameters(
+                    (ECPrivateKeyParameters)receiverPrivateParams,
+                    (ECPrivateKeyParameters)receiverPrivateParams);
+            }
+
+            IBasicAgreement agreement = AgreementUtilities.GetBasicAgreementWithKdf(
+                agreeAlgID, wrapAlg);
+            agreement.Init(receiverPrivateParams);
+            BigInteger agreedValue = agreement.CalculateAgreement(senderPublicParams);
+
+            int wrapKeySize = GeneratorUtilities.GetDefaultKeySize(wrapAlg) / 8;
+            byte[] wrapKeyBytes = X9IntegerConverter.IntegerToBytes(agreedValue, wrapKeySize);
+            return ParameterUtilities.CreateKeyParameter(wrapAlg, wrapKeyBytes);
+        }
+
+        private KeyParameter UnwrapSessionKey(
+            string			wrapAlg,
+            KeyParameter	agreedKey)
+        {
+            byte[] encKeyOctets = encryptedKey.GetOctets();
+
+            IWrapper keyCipher = WrapperUtilities.GetWrapper(wrapAlg);
+            keyCipher.Init(false, agreedKey);
+            byte[] sKeyBytes = keyCipher.Unwrap(encKeyOctets, 0, encKeyOctets.Length);
+            return ParameterUtilities.CreateKeyParameter(GetContentAlgorithmName(), sKeyBytes);
+        }
+
+        internal KeyParameter GetSessionKey(
+            AsymmetricKeyParameter receiverPrivateKey)
+        {
+            try
+            {
+                string wrapAlg = DerObjectIdentifier.GetInstance(
+                    Asn1Sequence.GetInstance(keyEncAlg.Parameters)[0]).Id;
+
+                AsymmetricKeyParameter senderPublicKey = GetSenderPublicKey(
+                    receiverPrivateKey, info.Originator);
+
+                KeyParameter agreedWrapKey = CalculateAgreedWrapKey(wrapAlg,
+                    senderPublicKey, receiverPrivateKey);
+
+                return UnwrapSessionKey(wrapAlg, agreedWrapKey);
+            }
+            catch (SecurityUtilityException e)
+            {
+                throw new CmsException("couldn't create cipher.", e);
+            }
+            catch (InvalidKeyException e)
+            {
+                throw new CmsException("key invalid in message.", e);
+            }
+            catch (Exception e)
+            {
+                throw new CmsException("originator key invalid.", e);
+            }
+        }
+
+        /**
+        * decrypt the content and return an input stream.
+        */
+        public override CmsTypedStream GetContentStream(
+            ICipherParameters key)
+        {
+            if (!(key is AsymmetricKeyParameter))
+                throw new ArgumentException("KeyAgreement requires asymmetric key", "key");
+
+            AsymmetricKeyParameter receiverPrivateKey = (AsymmetricKeyParameter) key;
+
+            if (!receiverPrivateKey.IsPrivate)
+                throw new ArgumentException("Expected private key", "key");
+
+            KeyParameter sKey = GetSessionKey(receiverPrivateKey);
+
+            return GetContentFromSessionKey(sKey);
+        }
+    }
 }
diff --git a/crypto/src/openssl/MiscPemGenerator.cs b/crypto/src/openssl/MiscPemGenerator.cs
index c4c537904..6b91e8b1c 100644
--- a/crypto/src/openssl/MiscPemGenerator.cs
+++ b/crypto/src/openssl/MiscPemGenerator.cs
@@ -21,117 +21,117 @@ using Org.BouncyCastle.X509;
 
 namespace Org.BouncyCastle.OpenSsl
 {
-	/**
-	* PEM generator for the original set of PEM objects used in Open SSL.
-	*/
-	public class MiscPemGenerator
-		: PemObjectGenerator
-	{
-		private object obj;
-		private string algorithm;
-		private char[] password;
-		private SecureRandom random;
-
-		public MiscPemGenerator(object obj)
-		{
-			this.obj = obj;
-		}
-
-		public MiscPemGenerator(
-			object			obj,
-			string			algorithm,
-			char[]			password,
-			SecureRandom	random)
-		{
-			this.obj = obj;
-			this.algorithm = algorithm;
-			this.password = password;
-			this.random = random;
-		}
-
-		private static PemObject CreatePemObject(object obj)
-		{
-			if (obj == null)
-				throw new ArgumentNullException("obj");
-
-			if (obj is AsymmetricCipherKeyPair)
-			{
-				return CreatePemObject(((AsymmetricCipherKeyPair)obj).Private);
-			}
-
-			string type;
-			byte[] encoding;
-
-			if (obj is PemObject)
-				return (PemObject)obj;
-
-			if (obj is PemObjectGenerator)
-				return ((PemObjectGenerator)obj).Generate();
-
-			if (obj is X509Certificate)
-			{
-				// TODO Should we prefer "X509 CERTIFICATE" here?
-				type = "CERTIFICATE";
-				try
-				{
-					encoding = ((X509Certificate)obj).GetEncoded();
-				}
-				catch (CertificateEncodingException e)
-				{
-					throw new IOException("Cannot Encode object: " + e.ToString());
-				}
-			}
-			else if (obj is X509Crl)
-			{
-				type = "X509 CRL";
-				try
-				{
-					encoding = ((X509Crl)obj).GetEncoded();
-				}
-				catch (CrlException e)
-				{
-					throw new IOException("Cannot Encode object: " + e.ToString());
-				}
-			}
-			else if (obj is AsymmetricKeyParameter)
-			{
-				AsymmetricKeyParameter akp = (AsymmetricKeyParameter) obj;
-				if (akp.IsPrivate)
-				{
-					string keyType;
-					encoding = EncodePrivateKey(akp, out keyType);
-
-					type = keyType + " PRIVATE KEY";
-				}
-				else
-				{
-					type = "PUBLIC KEY";
-
-					encoding = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(akp).GetDerEncoded();
-				}
-			}
-			else if (obj is IX509AttributeCertificate)
-			{
-				type = "ATTRIBUTE CERTIFICATE";
-				encoding = ((X509V2AttributeCertificate)obj).GetEncoded();
-			}
-			else if (obj is Pkcs10CertificationRequest)
-			{
-				type = "CERTIFICATE REQUEST";
-				encoding = ((Pkcs10CertificationRequest)obj).GetEncoded();
-			}
-			else if (obj is Asn1.Cms.ContentInfo)
-			{
-				type = "PKCS7";
-				encoding = ((Asn1.Cms.ContentInfo)obj).GetEncoded();
-			}
-			else
-			{
-				throw new PemGenerationException("Object type not supported: " + obj.GetType().FullName);
-			}
-
-			return new PemObject(type, encoding);
-		}
+    /**
+    * PEM generator for the original set of PEM objects used in Open SSL.
+    */
+    public class MiscPemGenerator
+        : PemObjectGenerator
+    {
+        private object obj;
+        private string algorithm;
+        private char[] password;
+        private SecureRandom random;
+
+        public MiscPemGenerator(object obj)
+        {
+            this.obj = obj;
+        }
+
+        public MiscPemGenerator(
+            object			obj,
+            string			algorithm,
+            char[]			password,
+            SecureRandom	random)
+        {
+            this.obj = obj;
+            this.algorithm = algorithm;
+            this.password = password;
+            this.random = random;
+        }
+
+        private static PemObject CreatePemObject(object obj)
+        {
+            if (obj == null)
+                throw new ArgumentNullException("obj");
+
+            if (obj is AsymmetricCipherKeyPair)
+            {
+                return CreatePemObject(((AsymmetricCipherKeyPair)obj).Private);
+            }
+
+            string type;
+            byte[] encoding;
+
+            if (obj is PemObject)
+                return (PemObject)obj;
+
+            if (obj is PemObjectGenerator)
+                return ((PemObjectGenerator)obj).Generate();
+
+            if (obj is X509Certificate)
+            {
+                // TODO Should we prefer "X509 CERTIFICATE" here?
+                type = "CERTIFICATE";
+                try
+                {
+                    encoding = ((X509Certificate)obj).GetEncoded();
+                }
+                catch (CertificateEncodingException e)
+                {
+                    throw new IOException("Cannot Encode object: " + e.ToString());
+                }
+            }
+            else if (obj is X509Crl)
+            {
+                type = "X509 CRL";
+                try
+                {
+                    encoding = ((X509Crl)obj).GetEncoded();
+                }
+                catch (CrlException e)
+                {
+                    throw new IOException("Cannot Encode object: " + e.ToString());
+                }
+            }
+            else if (obj is AsymmetricKeyParameter)
+            {
+                AsymmetricKeyParameter akp = (AsymmetricKeyParameter) obj;
+                if (akp.IsPrivate)
+                {
+                    string keyType;
+                    encoding = EncodePrivateKey(akp, out keyType);
+
+                    type = keyType + " PRIVATE KEY";
+                }
+                else
+                {
+                    type = "PUBLIC KEY";
+
+                    encoding = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(akp).GetDerEncoded();
+                }
+            }
+            else if (obj is IX509AttributeCertificate)
+            {
+                type = "ATTRIBUTE CERTIFICATE";
+                encoding = ((X509V2AttributeCertificate)obj).GetEncoded();
+            }
+            else if (obj is Pkcs10CertificationRequest)
+            {
+                type = "CERTIFICATE REQUEST";
+                encoding = ((Pkcs10CertificationRequest)obj).GetEncoded();
+            }
+            else if (obj is Asn1.Cms.ContentInfo)
+            {
+                type = "PKCS7";
+                encoding = ((Asn1.Cms.ContentInfo)obj).GetEncoded();
+            }
+            else
+            {
+                throw new PemGenerationException("Object type not supported: " + obj.GetType().FullName);
+            }
+
+            return new PemObject(type, encoding);
+        }
 
 //		private string GetHexEncoded(byte[] bytes)
 //		{
@@ -147,130 +147,130 @@ namespace Org.BouncyCastle.OpenSsl
 //			return new string(chars);
 //		}
 
-		private static PemObject CreatePemObject(
-			object			obj,
-			string			algorithm,
-			char[]			password,
-			SecureRandom	random)
-		{
-			if (obj == null)
-				throw new ArgumentNullException("obj");
-			if (algorithm == null)
-				throw new ArgumentNullException("algorithm");
-			if (password == null)
-				throw new ArgumentNullException("password");
-			if (random == null)
-				throw new ArgumentNullException("random");
-
-			if (obj is AsymmetricCipherKeyPair)
-			{
-				return CreatePemObject(((AsymmetricCipherKeyPair)obj).Private, algorithm, password, random);
-			}
-
-			string type = null;
-			byte[] keyData = null;
-
-			if (obj is AsymmetricKeyParameter)
-			{
-				AsymmetricKeyParameter akp = (AsymmetricKeyParameter) obj;
-				if (akp.IsPrivate)
-				{
-					string keyType;
-					keyData = EncodePrivateKey(akp, out keyType);
-
-					type = keyType + " PRIVATE KEY";
-				}
-			}
-
-			if (type == null || keyData == null)
-			{
-				// TODO Support other types?
-				throw new PemGenerationException("Object type not supported: " + obj.GetType().FullName);
-			}
-
-
-			string dekAlgName = Platform.ToUpperInvariant(algorithm);
+        private static PemObject CreatePemObject(
+            object			obj,
+            string			algorithm,
+            char[]			password,
+            SecureRandom	random)
+        {
+            if (obj == null)
+                throw new ArgumentNullException("obj");
+            if (algorithm == null)
+                throw new ArgumentNullException("algorithm");
+            if (password == null)
+                throw new ArgumentNullException("password");
+            if (random == null)
+                throw new ArgumentNullException("random");
+
+            if (obj is AsymmetricCipherKeyPair)
+            {
+                return CreatePemObject(((AsymmetricCipherKeyPair)obj).Private, algorithm, password, random);
+            }
+
+            string type = null;
+            byte[] keyData = null;
+
+            if (obj is AsymmetricKeyParameter)
+            {
+                AsymmetricKeyParameter akp = (AsymmetricKeyParameter) obj;
+                if (akp.IsPrivate)
+                {
+                    string keyType;
+                    keyData = EncodePrivateKey(akp, out keyType);
+
+                    type = keyType + " PRIVATE KEY";
+                }
+            }
+
+            if (type == null || keyData == null)
+            {
+                // TODO Support other types?
+                throw new PemGenerationException("Object type not supported: " + obj.GetType().FullName);
+            }
+
+
+            string dekAlgName = Platform.ToUpperInvariant(algorithm);
 
             // Note: For backward compatibility
-			if (dekAlgName == "DESEDE")
-			{
-				dekAlgName = "DES-EDE3-CBC";
-			}
-
-			int ivLength = dekAlgName.StartsWith("AES-") ? 16 : 8;
-
-			byte[] iv = new byte[ivLength];
-			random.NextBytes(iv);
-
-			byte[] encData = PemUtilities.Crypt(true, keyData, password, dekAlgName, iv);
-
-			IList headers = Platform.CreateArrayList(2);
-
-			headers.Add(new PemHeader("Proc-Type", "4,ENCRYPTED"));
-			headers.Add(new PemHeader("DEK-Info", dekAlgName + "," + Hex.ToHexString(iv)));
-
-			return new PemObject(type, headers, encData);
-		}
-
-		private static byte[] EncodePrivateKey(
-			AsymmetricKeyParameter	akp,
-			out string				keyType)
-		{
-			PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(akp);
-
-			DerObjectIdentifier oid = info.AlgorithmID.ObjectID;
-
-			if (oid.Equals(X9ObjectIdentifiers.IdDsa))
-			{
-				keyType = "DSA";
-
-				DsaParameter p = DsaParameter.GetInstance(info.AlgorithmID.Parameters);
-
-				BigInteger x = ((DsaPrivateKeyParameters) akp).X;
-				BigInteger y = p.G.ModPow(x, p.P);
-
-				// TODO Create an ASN1 object somewhere for this?
-				return new DerSequence(
-					new DerInteger(0),
-					new DerInteger(p.P),
-					new DerInteger(p.Q),
-					new DerInteger(p.G),
-					new DerInteger(y),
-					new DerInteger(x)).GetEncoded();
-			}
-
-			if (oid.Equals(PkcsObjectIdentifiers.RsaEncryption))
-			{
-				keyType = "RSA";
-			}
-			else if (oid.Equals(CryptoProObjectIdentifiers.GostR3410x2001)
-				|| oid.Equals(X9ObjectIdentifiers.IdECPublicKey))
-			{
-				keyType = "EC";
-			}
-			else
-			{
-				throw new ArgumentException("Cannot handle private key of type: " + akp.GetType().FullName, "akp");
-			}
-
-			return info.PrivateKey.GetEncoded();
-		}
-
-		public PemObject Generate()
-		{
-			try
-			{
-				if (algorithm != null)
-				{
-					return CreatePemObject(obj, algorithm, password, random);
-				}
-
-				return CreatePemObject(obj);
-			}
-			catch (IOException e)
-			{
-				throw new PemGenerationException("encoding exception", e);
-			}
-		}
-	}
+            if (dekAlgName == "DESEDE")
+            {
+                dekAlgName = "DES-EDE3-CBC";
+            }
+
+            int ivLength = dekAlgName.StartsWith("AES-") ? 16 : 8;
+
+            byte[] iv = new byte[ivLength];
+            random.NextBytes(iv);
+
+            byte[] encData = PemUtilities.Crypt(true, keyData, password, dekAlgName, iv);
+
+            IList headers = Platform.CreateArrayList(2);
+
+            headers.Add(new PemHeader("Proc-Type", "4,ENCRYPTED"));
+            headers.Add(new PemHeader("DEK-Info", dekAlgName + "," + Hex.ToHexString(iv)));
+
+            return new PemObject(type, headers, encData);
+        }
+
+        private static byte[] EncodePrivateKey(
+            AsymmetricKeyParameter	akp,
+            out string				keyType)
+        {
+            PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(akp);
+            AlgorithmIdentifier algID = info.PrivateKeyAlgorithm;
+            DerObjectIdentifier oid = algID.ObjectID;
+
+            if (oid.Equals(X9ObjectIdentifiers.IdDsa))
+            {
+                keyType = "DSA";
+
+                DsaParameter p = DsaParameter.GetInstance(algID.Parameters);
+
+                BigInteger x = ((DsaPrivateKeyParameters) akp).X;
+                BigInteger y = p.G.ModPow(x, p.P);
+
+                // TODO Create an ASN1 object somewhere for this?
+                return new DerSequence(
+                    new DerInteger(0),
+                    new DerInteger(p.P),
+                    new DerInteger(p.Q),
+                    new DerInteger(p.G),
+                    new DerInteger(y),
+                    new DerInteger(x)).GetEncoded();
+            }
+
+            if (oid.Equals(PkcsObjectIdentifiers.RsaEncryption))
+            {
+                keyType = "RSA";
+            }
+            else if (oid.Equals(CryptoProObjectIdentifiers.GostR3410x2001)
+                || oid.Equals(X9ObjectIdentifiers.IdECPublicKey))
+            {
+                keyType = "EC";
+            }
+            else
+            {
+                throw new ArgumentException("Cannot handle private key of type: " + akp.GetType().FullName, "akp");
+            }
+
+            return info.ParsePrivateKey().GetEncoded();
+        }
+
+        public PemObject Generate()
+        {
+            try
+            {
+                if (algorithm != null)
+                {
+                    return CreatePemObject(obj, algorithm, password, random);
+                }
+
+                return CreatePemObject(obj);
+            }
+            catch (IOException e)
+            {
+                throw new PemGenerationException("encoding exception", e);
+            }
+        }
+    }
 }
diff --git a/crypto/src/security/PrivateKeyFactory.cs b/crypto/src/security/PrivateKeyFactory.cs
index c5ddd5d78..c346352f5 100644
--- a/crypto/src/security/PrivateKeyFactory.cs
+++ b/crypto/src/security/PrivateKeyFactory.cs
@@ -43,7 +43,7 @@ namespace Org.BouncyCastle.Security
         public static AsymmetricKeyParameter CreateKey(
             PrivateKeyInfo keyInfo)
         {
-            AlgorithmIdentifier algID = keyInfo.AlgorithmID;
+            AlgorithmIdentifier algID = keyInfo.PrivateKeyAlgorithm;
             DerObjectIdentifier algOid = algID.ObjectID;
 
             // TODO See RSAUtil.isRsaOid in Java build
@@ -53,7 +53,7 @@ namespace Org.BouncyCastle.Security
                 || algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep))
             {
                 RsaPrivateKeyStructure keyStructure = new RsaPrivateKeyStructure(
-                    Asn1Sequence.GetInstance(keyInfo.PrivateKey));
+                    Asn1Sequence.GetInstance(keyInfo.ParsePrivateKey()));
 
                 return new RsaPrivateCrtKeyParameters(
                     keyStructure.Modulus,
@@ -71,7 +71,7 @@ namespace Org.BouncyCastle.Security
             {
                 DHParameter para = new DHParameter(
                     Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
-                DerInteger derX = (DerInteger)keyInfo.PrivateKey;
+                DerInteger derX = (DerInteger)keyInfo.ParsePrivateKey();
 
                 BigInteger lVal = para.L;
                 int l = lVal == null ? 0 : lVal.IntValue;
@@ -83,7 +83,7 @@ namespace Org.BouncyCastle.Security
             {
                 ElGamalParameter  para = new ElGamalParameter(
                     Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
-                DerInteger derX = (DerInteger)keyInfo.PrivateKey;
+                DerInteger derX = (DerInteger)keyInfo.ParsePrivateKey();
 
                 return new ElGamalPrivateKeyParameters(
                     derX.Value,
@@ -91,7 +91,7 @@ namespace Org.BouncyCastle.Security
             }
             else if (algOid.Equals(X9ObjectIdentifiers.IdDsa))
             {
-                DerInteger derX = (DerInteger) keyInfo.PrivateKey;
+                DerInteger derX = (DerInteger)keyInfo.ParsePrivateKey();
                 Asn1Encodable ae = algID.Parameters;
 
                 DsaParameters parameters = null;
@@ -118,7 +118,7 @@ namespace Org.BouncyCastle.Security
                 }
 
                 ECPrivateKeyStructure ec = new ECPrivateKeyStructure(
-                    Asn1Sequence.GetInstance(keyInfo.PrivateKey));
+                    Asn1Sequence.GetInstance(keyInfo.ParsePrivateKey()));
                 BigInteger d = ec.GetKey();
 
                 if (para.IsNamedCurve)
@@ -135,7 +135,7 @@ namespace Org.BouncyCastle.Security
                     Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
 
                 ECPrivateKeyStructure ec = new ECPrivateKeyStructure(
-                    Asn1Sequence.GetInstance(keyInfo.PrivateKey));
+                    Asn1Sequence.GetInstance(keyInfo.ParsePrivateKey()));
 
                 ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet);
 
@@ -149,7 +149,7 @@ namespace Org.BouncyCastle.Security
                 Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
                     Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
 
-                DerOctetString derX = (DerOctetString) keyInfo.PrivateKey;
+                DerOctetString derX = (DerOctetString)keyInfo.ParsePrivateKey();
                 byte[] keyEnc = derX.GetOctets();
                 byte[] keyBytes = new byte[keyEnc.Length];