summary refs log tree commit diff
path: root/crypto/src/asn1/pkcs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/asn1/pkcs')
-rw-r--r--crypto/src/asn1/pkcs/Attribute.cs79
-rw-r--r--crypto/src/asn1/pkcs/AuthenticatedSafe.cs37
-rw-r--r--crypto/src/asn1/pkcs/CertBag.cs46
-rw-r--r--crypto/src/asn1/pkcs/CertificationRequest.cs81
-rw-r--r--crypto/src/asn1/pkcs/CertificationRequestInfo.cs123
-rw-r--r--crypto/src/asn1/pkcs/ContentInfo.cs56
-rw-r--r--crypto/src/asn1/pkcs/DHParameter.cs72
-rw-r--r--crypto/src/asn1/pkcs/EncryptedData.cs104
-rw-r--r--crypto/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs78
-rw-r--r--crypto/src/asn1/pkcs/EncryptionScheme.cs49
-rw-r--r--crypto/src/asn1/pkcs/IssuerAndSerialNumber.cs71
-rw-r--r--crypto/src/asn1/pkcs/KeyDerivationFunc.cs21
-rw-r--r--crypto/src/asn1/pkcs/MacData.cs96
-rw-r--r--crypto/src/asn1/pkcs/PBEParameter.cs60
-rw-r--r--crypto/src/asn1/pkcs/PBES2Parameters.cs66
-rw-r--r--crypto/src/asn1/pkcs/PBKDF2Params.cs86
-rw-r--r--crypto/src/asn1/pkcs/PKCS12PBEParams.cs63
-rw-r--r--crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs256
-rw-r--r--crypto/src/asn1/pkcs/Pfx.cs65
-rw-r--r--crypto/src/asn1/pkcs/PrivateKeyInfo.cs147
-rw-r--r--crypto/src/asn1/pkcs/RC2CBCParameter.cs81
-rw-r--r--crypto/src/asn1/pkcs/RSAESOAEPparams.cs145
-rw-r--r--crypto/src/asn1/pkcs/RSAPrivateKeyStructure.cs145
-rw-r--r--crypto/src/asn1/pkcs/RSASSAPSSparams.cs165
-rw-r--r--crypto/src/asn1/pkcs/SafeBag.cs70
-rw-r--r--crypto/src/asn1/pkcs/SignedData.cs126
-rw-r--r--crypto/src/asn1/pkcs/SignerInfo.cs154
27 files changed, 2280 insertions, 262 deletions
diff --git a/crypto/src/asn1/pkcs/Attribute.cs b/crypto/src/asn1/pkcs/Attribute.cs
new file mode 100644
index 000000000..ceec115bd
--- /dev/null
+++ b/crypto/src/asn1/pkcs/Attribute.cs
@@ -0,0 +1,79 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    public class AttributePkcs
+        : Asn1Encodable
+    {
+        private readonly DerObjectIdentifier attrType;
+        private readonly Asn1Set attrValues;
+
+		/**
+         * return an Attribute object from the given object.
+         *
+         * @param o the object we want converted.
+         * @exception ArgumentException if the object cannot be converted.
+         */
+        public static AttributePkcs GetInstance(
+            object obj)
+        {
+            AttributePkcs attr = obj as AttributePkcs;
+            if (obj == null || attr != null)
+            {
+                return attr;
+            }
+
+			Asn1Sequence seq = obj as Asn1Sequence;
+            if (seq != null)
+            {
+                return new AttributePkcs(seq);
+            }
+
+			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+		}
+
+		private AttributePkcs(
+            Asn1Sequence seq)
+        {
+			if (seq.Count != 2)
+				throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+			attrType = DerObjectIdentifier.GetInstance(seq[0]);
+            attrValues = Asn1Set.GetInstance(seq[1]);
+        }
+
+		public AttributePkcs(
+            DerObjectIdentifier	attrType,
+            Asn1Set				attrValues)
+        {
+            this.attrType = attrType;
+            this.attrValues = attrValues;
+        }
+
+		public DerObjectIdentifier AttrType
+		{
+			get { return attrType; }
+		}
+
+		public Asn1Set AttrValues
+		{
+			get { return attrValues; }
+		}
+
+		/**
+         * Produce an object suitable for an Asn1OutputStream.
+         * <pre>
+         * Attr ::= Sequence {
+         *     attrType OBJECT IDENTIFIER,
+         *     attrValues Set OF AttributeValue
+         * }
+         * </pre>
+         */
+        public override Asn1Object ToAsn1Object()
+        {
+			return new DerSequence(attrType, attrValues);
+        }
+    }
+}
diff --git a/crypto/src/asn1/pkcs/AuthenticatedSafe.cs b/crypto/src/asn1/pkcs/AuthenticatedSafe.cs
new file mode 100644
index 000000000..f3dabb89c
--- /dev/null
+++ b/crypto/src/asn1/pkcs/AuthenticatedSafe.cs
@@ -0,0 +1,37 @@
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    public class AuthenticatedSafe
+        : Asn1Encodable
+    {
+        private readonly ContentInfo[] info;
+
+		public AuthenticatedSafe(
+            Asn1Sequence seq)
+        {
+            info = new ContentInfo[seq.Count];
+
+			for (int i = 0; i != info.Length; i++)
+            {
+                info[i] = ContentInfo.GetInstance(seq[i]);
+            }
+        }
+
+		public AuthenticatedSafe(
+            ContentInfo[] info)
+        {
+            this.info = (ContentInfo[]) info.Clone();
+        }
+
+		public ContentInfo[] GetContentInfo()
+        {
+            return (ContentInfo[]) info.Clone();
+        }
+
+		public override Asn1Object ToAsn1Object()
+        {
+			return new BerSequence(info);
+        }
+    }
+}
diff --git a/crypto/src/asn1/pkcs/CertBag.cs b/crypto/src/asn1/pkcs/CertBag.cs
new file mode 100644
index 000000000..b6f4c8a30
--- /dev/null
+++ b/crypto/src/asn1/pkcs/CertBag.cs
@@ -0,0 +1,46 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    public class CertBag
+        : Asn1Encodable
+    {
+//		private readonly Asn1Sequence seq;
+        private readonly DerObjectIdentifier certID;
+        private readonly Asn1Object certValue;
+
+		public CertBag(
+            Asn1Sequence seq)
+        {
+			if (seq.Count != 2)
+				throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+//			this.seq = seq;
+            this.certID = DerObjectIdentifier.GetInstance(seq[0]);
+            this.certValue = DerTaggedObject.GetInstance(seq[1]).GetObject();
+        }
+
+		public CertBag(
+            DerObjectIdentifier	certID,
+            Asn1Object			certValue)
+        {
+            this.certID = certID;
+            this.certValue = certValue;
+        }
+
+		public DerObjectIdentifier CertID
+		{
+			get { return certID; }
+		}
+
+		public Asn1Object CertValue
+		{
+			get { return certValue; }
+		}
+
+		public override Asn1Object ToAsn1Object()
+        {
+			return new DerSequence(certID, new DerTaggedObject(0, certValue));
+        }
+    }
+}
diff --git a/crypto/src/asn1/pkcs/CertificationRequest.cs b/crypto/src/asn1/pkcs/CertificationRequest.cs
new file mode 100644
index 000000000..32b1612d2
--- /dev/null
+++ b/crypto/src/asn1/pkcs/CertificationRequest.cs
@@ -0,0 +1,81 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    /**
+     * Pkcs10 Certfication request object.
+     * <pre>
+     * CertificationRequest ::= Sequence {
+     *   certificationRequestInfo  CertificationRequestInfo,
+     *   signatureAlgorithm        AlgorithmIdentifier{{ SignatureAlgorithms }},
+     *   signature                 BIT STRING
+     * }
+     * </pre>
+     */
+    public class CertificationRequest
+        : Asn1Encodable
+    {
+        protected CertificationRequestInfo	reqInfo;
+        protected AlgorithmIdentifier		sigAlgId;
+        protected DerBitString				sigBits;
+
+		public static CertificationRequest GetInstance(
+			object obj)
+		{
+			if (obj is CertificationRequest)
+				return (CertificationRequest)obj;
+
+			if (obj != null)
+				return new CertificationRequest((Asn1Sequence)obj);
+
+			return null;
+		}
+
+		protected CertificationRequest()
+        {
+        }
+
+		public CertificationRequest(
+            CertificationRequestInfo	requestInfo,
+            AlgorithmIdentifier			algorithm,
+            DerBitString				signature)
+        {
+            this.reqInfo = requestInfo;
+            this.sigAlgId = algorithm;
+            this.sigBits = signature;
+        }
+
+		public CertificationRequest(
+            Asn1Sequence seq)
+        {
+			if (seq.Count != 3)
+				throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+			reqInfo = CertificationRequestInfo.GetInstance(seq[0]);
+            sigAlgId = AlgorithmIdentifier.GetInstance(seq[1]);
+            sigBits = DerBitString.GetInstance(seq[2]);
+        }
+
+		public CertificationRequestInfo GetCertificationRequestInfo()
+        {
+            return reqInfo;
+        }
+
+		public AlgorithmIdentifier SignatureAlgorithm
+		{
+			get { return sigAlgId; }
+		}
+
+		public DerBitString Signature
+		{
+			get { return sigBits; }
+		}
+
+		public override Asn1Object ToAsn1Object()
+        {
+			return new DerSequence(reqInfo, sigAlgId, sigBits);
+        }
+    }
+}
diff --git a/crypto/src/asn1/pkcs/CertificationRequestInfo.cs b/crypto/src/asn1/pkcs/CertificationRequestInfo.cs
new file mode 100644
index 000000000..690d06878
--- /dev/null
+++ b/crypto/src/asn1/pkcs/CertificationRequestInfo.cs
@@ -0,0 +1,123 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    /**
+     * Pkcs10 CertificationRequestInfo object.
+     * <pre>
+     *  CertificationRequestInfo ::= Sequence {
+     *   version             Integer { v1(0) } (v1,...),
+     *   subject             Name,
+     *   subjectPKInfo   SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
+     *   attributes          [0] Attributes{{ CRIAttributes }}
+     *  }
+     *
+     *  Attributes { ATTRIBUTE:IOSet } ::= Set OF Attr{{ IOSet }}
+     *
+     *  Attr { ATTRIBUTE:IOSet } ::= Sequence {
+     *    type    ATTRIBUTE.&amp;id({IOSet}),
+     *    values  Set SIZE(1..MAX) OF ATTRIBUTE.&amp;Type({IOSet}{\@type})
+     *  }
+     * </pre>
+     */
+    public class CertificationRequestInfo
+        : Asn1Encodable
+    {
+        internal DerInteger				version = new DerInteger(0);
+        internal X509Name				subject;
+        internal SubjectPublicKeyInfo	subjectPKInfo;
+        internal Asn1Set				attributes;
+
+		public static CertificationRequestInfo GetInstance(
+            object  obj)
+        {
+            if (obj is CertificationRequestInfo)
+            {
+                return (CertificationRequestInfo) obj;
+            }
+
+			if (obj is Asn1Sequence)
+            {
+                return new CertificationRequestInfo((Asn1Sequence) obj);
+            }
+
+			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+		}
+
+		public CertificationRequestInfo(
+            X509Name				subject,
+            SubjectPublicKeyInfo	pkInfo,
+            Asn1Set					attributes)
+        {
+            this.subject = subject;
+            this.subjectPKInfo = pkInfo;
+            this.attributes = attributes;
+
+			if (subject == null || version == null || subjectPKInfo == null)
+            {
+                throw new ArgumentException(
+					"Not all mandatory fields set in CertificationRequestInfo generator.");
+            }
+        }
+
+		private CertificationRequestInfo(
+            Asn1Sequence seq)
+        {
+            version = (DerInteger) seq[0];
+
+			subject = X509Name.GetInstance(seq[1]);
+            subjectPKInfo = SubjectPublicKeyInfo.GetInstance(seq[2]);
+
+			//
+            // some CertificationRequestInfo objects seem to treat this field
+            // as optional.
+            //
+            if (seq.Count > 3)
+            {
+                DerTaggedObject tagobj = (DerTaggedObject) seq[3];
+                attributes = Asn1Set.GetInstance(tagobj, false);
+            }
+
+			if (subject == null || version == null || subjectPKInfo == null)
+            {
+                throw new ArgumentException(
+					"Not all mandatory fields set in CertificationRequestInfo generator.");
+            }
+        }
+
+		public DerInteger Version
+		{
+			get { return version; }
+		}
+
+		public X509Name Subject
+		{
+			get { return subject; }
+		}
+
+		public SubjectPublicKeyInfo SubjectPublicKeyInfo
+		{
+			get { return subjectPKInfo; }
+		}
+
+		public Asn1Set Attributes
+		{
+			get { return attributes; }
+		}
+
+		public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(
+				version, subject, subjectPKInfo);
+
+			if (attributes != null)
+            {
+                v.Add(new DerTaggedObject(false, 0, attributes));
+            }
+
+			return new DerSequence(v);
+        }
+    }
+}
diff --git a/crypto/src/asn1/pkcs/ContentInfo.cs b/crypto/src/asn1/pkcs/ContentInfo.cs
index 78213c138..526a3c48e 100644
--- a/crypto/src/asn1/pkcs/ContentInfo.cs
+++ b/crypto/src/asn1/pkcs/ContentInfo.cs
@@ -11,34 +11,28 @@ namespace Org.BouncyCastle.Asn1.Pkcs
         private readonly DerObjectIdentifier	contentType;
         private readonly Asn1Encodable			content;
 
-		public static ContentInfo GetInstance(
-            object obj)
+        public static ContentInfo GetInstance(object obj)
         {
-            if (obj is ContentInfo)
-            {
-                return (ContentInfo) obj;
-            }
-
-			if (obj is Asn1Sequence)
-            {
-                return new ContentInfo((Asn1Sequence) obj);
-            }
-
-			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+            if (obj == null)
+                return null;
+            ContentInfo existing = obj as ContentInfo;
+            if (existing != null)
+                return existing;
+            return new ContentInfo(Asn1Sequence.GetInstance(obj));
         }
 
-		private ContentInfo(
+        private ContentInfo(
             Asn1Sequence seq)
         {
-			contentType = (DerObjectIdentifier) seq[0];
+            contentType = (DerObjectIdentifier) seq[0];
 
-			if (seq.Count > 1)
-			{
-				content = ((Asn1TaggedObject) seq[1]).GetObject();
-			}
+            if (seq.Count > 1)
+            {
+                content = ((Asn1TaggedObject) seq[1]).GetObject();
+            }
         }
 
-		public ContentInfo(
+        public ContentInfo(
             DerObjectIdentifier	contentType,
             Asn1Encodable		content)
         {
@@ -46,17 +40,17 @@ namespace Org.BouncyCastle.Asn1.Pkcs
             this.content = content;
         }
 
-		public DerObjectIdentifier ContentType
-		{
-			get { return contentType; }
-		}
+        public DerObjectIdentifier ContentType
+        {
+            get { return contentType; }
+        }
 
-		public Asn1Encodable Content
-		{
-			get { return content; }
-		}
+        public Asn1Encodable Content
+        {
+            get { return content; }
+        }
 
-		/**
+        /**
          * Produce an object suitable for an Asn1OutputStream.
          * <pre>
          * ContentInfo ::= Sequence {
@@ -69,12 +63,12 @@ namespace Org.BouncyCastle.Asn1.Pkcs
         {
             Asn1EncodableVector v = new Asn1EncodableVector(contentType);
 
-			if (content != null)
+            if (content != null)
             {
                 v.Add(new BerTaggedObject(0, content));
             }
 
-			return new BerSequence(v);
+            return new BerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/pkcs/DHParameter.cs b/crypto/src/asn1/pkcs/DHParameter.cs
new file mode 100644
index 000000000..25a091a97
--- /dev/null
+++ b/crypto/src/asn1/pkcs/DHParameter.cs
@@ -0,0 +1,72 @@
+using Org.BouncyCastle.Asn1;
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    public class DHParameter
+        : Asn1Encodable
+    {
+        internal DerInteger p, g, l;
+
+		public DHParameter(
+            BigInteger	p,
+            BigInteger	g,
+            int			l)
+        {
+            this.p = new DerInteger(p);
+            this.g = new DerInteger(g);
+
+			if (l != 0)
+            {
+                this.l = new DerInteger(l);
+            }
+        }
+
+		public DHParameter(
+            Asn1Sequence seq)
+        {
+            IEnumerator e = seq.GetEnumerator();
+
+			e.MoveNext();
+            p = (DerInteger)e.Current;
+
+			e.MoveNext();
+            g = (DerInteger)e.Current;
+
+			if (e.MoveNext())
+            {
+                l = (DerInteger) e.Current;
+            }
+        }
+
+		public BigInteger P
+		{
+			get { return p.PositiveValue; }
+		}
+
+		public BigInteger G
+		{
+			get { return g.PositiveValue; }
+		}
+
+		public BigInteger L
+		{
+            get { return l == null ? null : l.PositiveValue; }
+        }
+
+		public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(p, g);
+
+			if (this.l != null)
+            {
+                v.Add(l);
+            }
+
+			return new DerSequence(v);
+        }
+    }
+}
diff --git a/crypto/src/asn1/pkcs/EncryptedData.cs b/crypto/src/asn1/pkcs/EncryptedData.cs
new file mode 100644
index 000000000..912064ace
--- /dev/null
+++ b/crypto/src/asn1/pkcs/EncryptedData.cs
@@ -0,0 +1,104 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    /**
+     * The EncryptedData object.
+     * <pre>
+     *      EncryptedData ::= Sequence {
+     *           version Version,
+     *           encryptedContentInfo EncryptedContentInfo
+     *      }
+     *
+     *
+     *      EncryptedContentInfo ::= Sequence {
+     *          contentType ContentType,
+     *          contentEncryptionAlgorithm  ContentEncryptionAlgorithmIdentifier,
+     *          encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
+     *    }
+     *
+     *    EncryptedContent ::= OCTET STRING
+     * </pre>
+     */
+    public class EncryptedData
+        : Asn1Encodable
+    {
+        private readonly Asn1Sequence data;
+//        private readonly DerObjectIdentifier bagId;
+//        private readonly Asn1Object bagValue;
+
+		public static EncryptedData GetInstance(
+             object obj)
+        {
+			if (obj is EncryptedData)
+			{
+				return (EncryptedData) obj;
+			}
+
+			if (obj is Asn1Sequence)
+			{
+				return new EncryptedData((Asn1Sequence) obj);
+			}
+
+			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+		}
+
+		private EncryptedData(
+            Asn1Sequence seq)
+        {
+			if (seq.Count != 2)
+				throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+			int version = ((DerInteger) seq[0]).Value.IntValue;
+			if (version != 0)
+            {
+                throw new ArgumentException("sequence not version 0");
+            }
+
+			this.data = (Asn1Sequence) seq[1];
+        }
+
+		public EncryptedData(
+            DerObjectIdentifier	contentType,
+            AlgorithmIdentifier	encryptionAlgorithm,
+            Asn1Encodable		content)
+        {
+			data = new BerSequence(
+				contentType,
+				encryptionAlgorithm.ToAsn1Object(),
+				new BerTaggedObject(false, 0, content));
+        }
+
+		public DerObjectIdentifier ContentType
+        {
+            get { return (DerObjectIdentifier) data[0]; }
+        }
+
+		public AlgorithmIdentifier EncryptionAlgorithm
+        {
+			get { return AlgorithmIdentifier.GetInstance(data[1]); }
+        }
+
+		public Asn1OctetString Content
+        {
+			get
+			{
+				if (data.Count == 3)
+				{
+					DerTaggedObject o = (DerTaggedObject) data[2];
+
+					return Asn1OctetString.GetInstance(o, false);
+				}
+
+				return null;
+			}
+        }
+
+		public override Asn1Object ToAsn1Object()
+        {
+			return new BerSequence(new DerInteger(0), data);
+        }
+    }
+}
diff --git a/crypto/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs b/crypto/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs
new file mode 100644
index 000000000..b97b8f5ea
--- /dev/null
+++ b/crypto/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    public class EncryptedPrivateKeyInfo
+        : Asn1Encodable
+    {
+        private readonly AlgorithmIdentifier algId;
+        private readonly Asn1OctetString data;
+
+		private EncryptedPrivateKeyInfo(
+            Asn1Sequence seq)
+        {
+			if (seq.Count != 2)
+				throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+            algId = AlgorithmIdentifier.GetInstance(seq[0]);
+            data = Asn1OctetString.GetInstance(seq[1]);
+        }
+
+		public EncryptedPrivateKeyInfo(
+            AlgorithmIdentifier	algId,
+            byte[]				encoding)
+        {
+            this.algId = algId;
+            this.data = new DerOctetString(encoding);
+        }
+
+		public static EncryptedPrivateKeyInfo GetInstance(
+             object obj)
+        {
+			if (obj is EncryptedPrivateKeyInfo)
+			{
+				return (EncryptedPrivateKeyInfo) obj;
+			}
+
+			if (obj is Asn1Sequence)
+			{
+				return new EncryptedPrivateKeyInfo((Asn1Sequence) obj);
+			}
+
+			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+		}
+
+		public AlgorithmIdentifier EncryptionAlgorithm
+		{
+			get { return algId; }
+		}
+
+		public byte[] GetEncryptedData()
+        {
+            return data.GetOctets();
+        }
+
+		/**
+         * Produce an object suitable for an Asn1OutputStream.
+         * <pre>
+         * EncryptedPrivateKeyInfo ::= Sequence {
+         *      encryptionAlgorithm AlgorithmIdentifier {{KeyEncryptionAlgorithms}},
+         *      encryptedData EncryptedData
+         * }
+         *
+         * EncryptedData ::= OCTET STRING
+         *
+         * KeyEncryptionAlgorithms ALGORITHM-IDENTIFIER ::= {
+         *          ... -- For local profiles
+         * }
+         * </pre>
+         */
+        public override Asn1Object ToAsn1Object()
+        {
+			return new DerSequence(algId, data);
+        }
+    }
+}
diff --git a/crypto/src/asn1/pkcs/EncryptionScheme.cs b/crypto/src/asn1/pkcs/EncryptionScheme.cs
new file mode 100644
index 000000000..5b64d6f67
--- /dev/null
+++ b/crypto/src/asn1/pkcs/EncryptionScheme.cs
@@ -0,0 +1,49 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    public class EncryptionScheme
+        : AlgorithmIdentifier
+    {
+		public EncryptionScheme(
+            DerObjectIdentifier	objectID,
+            Asn1Encodable		parameters)
+			: base(objectID, parameters)
+		{
+		}
+
+		internal EncryptionScheme(
+			Asn1Sequence seq)
+			: this((DerObjectIdentifier)seq[0], seq[1])
+        {
+        }
+
+		public new static EncryptionScheme GetInstance(object obj)
+		{
+			if (obj is EncryptionScheme)
+			{
+				return (EncryptionScheme)obj;
+			}
+
+			if (obj is Asn1Sequence)
+			{
+				return new EncryptionScheme((Asn1Sequence)obj);
+			}
+
+			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+		}
+
+		public Asn1Object Asn1Object
+		{
+			get { return Parameters.ToAsn1Object(); }
+		}
+
+		public override Asn1Object ToAsn1Object()
+        {
+			return new DerSequence(ObjectID, Parameters);
+        }
+    }
+}
diff --git a/crypto/src/asn1/pkcs/IssuerAndSerialNumber.cs b/crypto/src/asn1/pkcs/IssuerAndSerialNumber.cs
new file mode 100644
index 000000000..ff608f15b
--- /dev/null
+++ b/crypto/src/asn1/pkcs/IssuerAndSerialNumber.cs
@@ -0,0 +1,71 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    public class IssuerAndSerialNumber
+        : Asn1Encodable
+    {
+        private readonly X509Name name;
+        private readonly DerInteger certSerialNumber;
+
+		public static IssuerAndSerialNumber GetInstance(
+            object obj)
+        {
+            if (obj is IssuerAndSerialNumber)
+            {
+                return (IssuerAndSerialNumber) obj;
+            }
+
+			if (obj is Asn1Sequence)
+            {
+                return new IssuerAndSerialNumber((Asn1Sequence) obj);
+            }
+
+			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+		}
+
+		private IssuerAndSerialNumber(
+            Asn1Sequence seq)
+        {
+			if (seq.Count != 2)
+				throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+			this.name = X509Name.GetInstance(seq[0]);
+            this.certSerialNumber = DerInteger.GetInstance(seq[1]);
+        }
+
+		public IssuerAndSerialNumber(
+            X509Name	name,
+            BigInteger	certSerialNumber)
+        {
+            this.name = name;
+            this.certSerialNumber = new DerInteger(certSerialNumber);
+        }
+
+		public IssuerAndSerialNumber(
+            X509Name	name,
+            DerInteger	certSerialNumber)
+        {
+            this.name = name;
+            this.certSerialNumber = certSerialNumber;
+        }
+
+		public X509Name Name
+		{
+			get { return name; }
+		}
+
+		public DerInteger CertificateSerialNumber
+		{
+			get { return certSerialNumber; }
+		}
+
+		public override Asn1Object ToAsn1Object()
+        {
+			return new DerSequence(name, certSerialNumber);
+        }
+    }
+}
diff --git a/crypto/src/asn1/pkcs/KeyDerivationFunc.cs b/crypto/src/asn1/pkcs/KeyDerivationFunc.cs
new file mode 100644
index 000000000..9fc89853b
--- /dev/null
+++ b/crypto/src/asn1/pkcs/KeyDerivationFunc.cs
@@ -0,0 +1,21 @@
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+	public class KeyDerivationFunc
+		: AlgorithmIdentifier
+	{
+		internal KeyDerivationFunc(Asn1Sequence seq)
+			: base(seq)
+		{
+		}
+
+		public KeyDerivationFunc(
+			DerObjectIdentifier	id,
+			Asn1Encodable		parameters)
+			: base(id, parameters)
+		{
+		}
+	}
+}
\ No newline at end of file
diff --git a/crypto/src/asn1/pkcs/MacData.cs b/crypto/src/asn1/pkcs/MacData.cs
new file mode 100644
index 000000000..780b24153
--- /dev/null
+++ b/crypto/src/asn1/pkcs/MacData.cs
@@ -0,0 +1,96 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    public class MacData
+        : Asn1Encodable
+    {
+        internal DigestInfo	digInfo;
+        internal byte[]		salt;
+        internal BigInteger	iterationCount;
+
+		public static MacData GetInstance(
+            object obj)
+        {
+            if (obj is MacData)
+            {
+                return (MacData) obj;
+            }
+
+			if (obj is Asn1Sequence)
+            {
+                return new MacData((Asn1Sequence) obj);
+            }
+
+			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+		}
+
+		private MacData(
+            Asn1Sequence seq)
+        {
+            this.digInfo = DigestInfo.GetInstance(seq[0]);
+            this.salt = ((Asn1OctetString) seq[1]).GetOctets();
+
+			if (seq.Count == 3)
+            {
+                this.iterationCount = ((DerInteger) seq[2]).Value;
+            }
+            else
+            {
+                this.iterationCount = BigInteger.One;
+            }
+        }
+
+		public MacData(
+            DigestInfo	digInfo,
+            byte[]		salt,
+            int			iterationCount)
+        {
+            this.digInfo = digInfo;
+            this.salt = (byte[]) salt.Clone();
+            this.iterationCount = BigInteger.ValueOf(iterationCount);
+        }
+
+		public DigestInfo Mac
+		{
+			get { return digInfo; }
+		}
+
+		public byte[] GetSalt()
+        {
+            return (byte[]) salt.Clone();
+        }
+
+		public BigInteger IterationCount
+		{
+			get { return iterationCount; }
+		}
+
+		/**
+		 * <pre>
+		 * MacData ::= SEQUENCE {
+		 *     mac      DigestInfo,
+		 *     macSalt  OCTET STRING,
+		 *     iterations INTEGER DEFAULT 1
+		 *     -- Note: The default is for historic reasons and its use is deprecated. A
+		 *     -- higher value, like 1024 is recommended.
+		 * </pre>
+		 * @return the basic DERObject construction.
+		 */
+		public override Asn1Object ToAsn1Object()
+        {
+			Asn1EncodableVector v = new Asn1EncodableVector(digInfo, new DerOctetString(salt));
+
+			if (!iterationCount.Equals(BigInteger.One))
+			{
+				v.Add(new DerInteger(iterationCount));
+			}
+
+			return new DerSequence(v);
+        }
+    }
+}
diff --git a/crypto/src/asn1/pkcs/PBEParameter.cs b/crypto/src/asn1/pkcs/PBEParameter.cs
new file mode 100644
index 000000000..80d5ec3e1
--- /dev/null
+++ b/crypto/src/asn1/pkcs/PBEParameter.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+	public class PbeParameter
+		: Asn1Encodable
+	{
+		private readonly Asn1OctetString	salt;
+		private readonly DerInteger			iterationCount;
+
+		public static PbeParameter GetInstance(object obj)
+		{
+			if (obj is PbeParameter || obj == null)
+			{
+				return (PbeParameter) obj;
+			}
+
+			if (obj is Asn1Sequence)
+			{
+				return new PbeParameter((Asn1Sequence) obj);
+			}
+
+			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+		}
+
+		private PbeParameter(Asn1Sequence seq)
+		{
+			if (seq.Count != 2)
+				throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+			salt = Asn1OctetString.GetInstance(seq[0]);
+			iterationCount = DerInteger.GetInstance(seq[1]);
+		}
+
+		public PbeParameter(byte[] salt, int iterationCount)
+		{
+			this.salt = new DerOctetString(salt);
+			this.iterationCount = new DerInteger(iterationCount);
+		}
+
+		public byte[] GetSalt()
+		{
+			return salt.GetOctets();
+		}
+
+		public BigInteger IterationCount
+		{
+			get { return iterationCount.Value; }
+		}
+
+		public override Asn1Object ToAsn1Object()
+		{
+			return new DerSequence(salt, iterationCount);
+		}
+	}
+}
diff --git a/crypto/src/asn1/pkcs/PBES2Parameters.cs b/crypto/src/asn1/pkcs/PBES2Parameters.cs
index 645bb867c..fc6904eed 100644
--- a/crypto/src/asn1/pkcs/PBES2Parameters.cs
+++ b/crypto/src/asn1/pkcs/PBES2Parameters.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Collections;
 
 namespace Org.BouncyCastle.Asn1.Pkcs
 {
@@ -9,53 +8,58 @@ namespace Org.BouncyCastle.Asn1.Pkcs
         private readonly KeyDerivationFunc func;
         private readonly EncryptionScheme scheme;
 
-		public static PbeS2Parameters GetInstance(
-			object obj)
-		{
-			if (obj == null || obj is PbeS2Parameters)
-				return (PbeS2Parameters) obj;
-
-			if (obj is Asn1Sequence)
-				return new PbeS2Parameters((Asn1Sequence) obj);
+        public static PbeS2Parameters GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            PbeS2Parameters existing = obj as PbeS2Parameters;
+            if (existing != null)
+                return existing;
+            return new PbeS2Parameters(Asn1Sequence.GetInstance(obj));
+        }
 
-			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
-		}
+        public PbeS2Parameters(KeyDerivationFunc keyDevFunc, EncryptionScheme encScheme)
+        {
+            this.func = keyDevFunc;
+            this.scheme = encScheme;
+        }
 
-		public PbeS2Parameters(
+        [Obsolete("Use GetInstance() instead")]
+        public PbeS2Parameters(
             Asn1Sequence seq)
         {
-			if (seq.Count != 2)
-				throw new ArgumentException("Wrong number of elements in sequence", "seq");
+            if (seq.Count != 2)
+                throw new ArgumentException("Wrong number of elements in sequence", "seq");
 
-			Asn1Sequence funcSeq = (Asn1Sequence)seq[0].ToAsn1Object();
+            Asn1Sequence funcSeq = (Asn1Sequence)seq[0].ToAsn1Object();
 
-			// TODO Not sure if this special case is really necessary/appropriate
-			if (funcSeq[0].Equals(PkcsObjectIdentifiers.IdPbkdf2))
+            // TODO Not sure if this special case is really necessary/appropriate
+            if (funcSeq[0].Equals(PkcsObjectIdentifiers.IdPbkdf2))
             {
-				func = new KeyDerivationFunc(PkcsObjectIdentifiers.IdPbkdf2,
-					Pbkdf2Params.GetInstance(funcSeq[1]));
-			}
+                func = new KeyDerivationFunc(PkcsObjectIdentifiers.IdPbkdf2,
+                    Pbkdf2Params.GetInstance(funcSeq[1]));
+            }
             else
             {
                 func = new KeyDerivationFunc(funcSeq);
             }
 
-			scheme = EncryptionScheme.GetInstance(seq[1].ToAsn1Object());
+            scheme = EncryptionScheme.GetInstance(seq[1].ToAsn1Object());
         }
 
-		public KeyDerivationFunc KeyDerivationFunc
-		{
-			get { return func; }
-		}
+        public KeyDerivationFunc KeyDerivationFunc
+        {
+            get { return func; }
+        }
 
-		public EncryptionScheme EncryptionScheme
-		{
-			get { return scheme; }
-		}
+        public EncryptionScheme EncryptionScheme
+        {
+            get { return scheme; }
+        }
 
-		public override Asn1Object ToAsn1Object()
+        public override Asn1Object ToAsn1Object()
         {
-			return new DerSequence(func, scheme);
+            return new DerSequence(func, scheme);
         }
     }
 }
diff --git a/crypto/src/asn1/pkcs/PBKDF2Params.cs b/crypto/src/asn1/pkcs/PBKDF2Params.cs
new file mode 100644
index 000000000..1351b94cf
--- /dev/null
+++ b/crypto/src/asn1/pkcs/PBKDF2Params.cs
@@ -0,0 +1,86 @@
+using System;
+
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+	public class Pbkdf2Params
+		: Asn1Encodable
+	{
+		private readonly Asn1OctetString	octStr;
+		private readonly DerInteger			iterationCount;
+		private readonly DerInteger			keyLength;
+
+		public static Pbkdf2Params GetInstance(
+			object obj)
+		{
+			if (obj == null || obj is Pbkdf2Params)
+				return (Pbkdf2Params)obj;
+
+			if (obj is Asn1Sequence)
+				return new Pbkdf2Params((Asn1Sequence)obj);
+
+			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+		}
+
+		public Pbkdf2Params(
+			Asn1Sequence seq)
+		{
+			if (seq.Count < 2 || seq.Count > 3)
+				throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+			octStr = (Asn1OctetString)seq[0];
+			iterationCount = (DerInteger)seq[1];
+
+			if (seq.Count > 2)
+			{
+				keyLength = (DerInteger)seq[2];
+			}
+		}
+
+		public Pbkdf2Params(
+			byte[] salt,
+			int iterationCount)
+		{
+			this.octStr = new DerOctetString(salt);
+			this.iterationCount = new DerInteger(iterationCount);
+		}
+
+        public Pbkdf2Params(
+            byte[]  salt,
+            int     iterationCount,
+            int     keyLength)
+            : this(salt, iterationCount)
+        {
+            this.keyLength = new DerInteger(keyLength);
+        }
+
+		public byte[] GetSalt()
+		{
+			return octStr.GetOctets();
+		}
+
+		public BigInteger IterationCount
+		{
+			get { return iterationCount.Value; }
+		}
+
+		public BigInteger KeyLength
+		{
+			get { return keyLength == null ? null : keyLength.Value; }
+		}
+
+		public override Asn1Object ToAsn1Object()
+		{
+			Asn1EncodableVector v = new Asn1EncodableVector(
+				octStr, iterationCount);
+
+			if (keyLength != null)
+			{
+				v.Add(keyLength);
+			}
+
+			return new DerSequence(v);
+		}
+	}
+}
diff --git a/crypto/src/asn1/pkcs/PKCS12PBEParams.cs b/crypto/src/asn1/pkcs/PKCS12PBEParams.cs
new file mode 100644
index 000000000..7521f93ea
--- /dev/null
+++ b/crypto/src/asn1/pkcs/PKCS12PBEParams.cs
@@ -0,0 +1,63 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    public class Pkcs12PbeParams
+        : Asn1Encodable
+    {
+        private readonly DerInteger iterations;
+        private readonly Asn1OctetString iv;
+
+		public Pkcs12PbeParams(
+            byte[]	salt,
+            int		iterations)
+        {
+            this.iv = new DerOctetString(salt);
+            this.iterations = new DerInteger(iterations);
+        }
+
+		private Pkcs12PbeParams(
+            Asn1Sequence seq)
+        {
+			if (seq.Count != 2)
+				throw new ArgumentException("Wrong number of elements in sequence", "seq");
+
+			iv = Asn1OctetString.GetInstance(seq[0]);
+            iterations = DerInteger.GetInstance(seq[1]);
+        }
+
+		public static Pkcs12PbeParams GetInstance(
+            object obj)
+        {
+            if (obj is Pkcs12PbeParams)
+            {
+                return (Pkcs12PbeParams) obj;
+            }
+
+			if (obj is Asn1Sequence)
+            {
+                return new Pkcs12PbeParams((Asn1Sequence) obj);
+            }
+
+			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+		}
+
+		public BigInteger Iterations
+		{
+			get { return iterations.Value; }
+		}
+
+		public byte[] GetIV()
+        {
+            return iv.GetOctets();
+        }
+
+		public override Asn1Object ToAsn1Object()
+        {
+			return new DerSequence(iv, iterations);
+        }
+    }
+}
diff --git a/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs b/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs
new file mode 100644
index 000000000..0b2ffa0d1
--- /dev/null
+++ b/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs
@@ -0,0 +1,256 @@
+using System;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    public abstract class PkcsObjectIdentifiers
+    {
+        //
+        // pkcs-1 OBJECT IDENTIFIER ::= {
+        //       iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
+        //
+        public const string Pkcs1 = "1.2.840.113549.1.1";
+
+		public static readonly DerObjectIdentifier RsaEncryption			= new DerObjectIdentifier(Pkcs1 + ".1");
+        public static readonly DerObjectIdentifier MD2WithRsaEncryption		= new DerObjectIdentifier(Pkcs1 + ".2");
+        public static readonly DerObjectIdentifier MD4WithRsaEncryption		= new DerObjectIdentifier(Pkcs1 + ".3");
+        public static readonly DerObjectIdentifier MD5WithRsaEncryption		= new DerObjectIdentifier(Pkcs1 + ".4");
+        public static readonly DerObjectIdentifier Sha1WithRsaEncryption	= new DerObjectIdentifier(Pkcs1 + ".5");
+        public static readonly DerObjectIdentifier SrsaOaepEncryptionSet	= new DerObjectIdentifier(Pkcs1 + ".6");
+        public static readonly DerObjectIdentifier IdRsaesOaep				= new DerObjectIdentifier(Pkcs1 + ".7");
+        public static readonly DerObjectIdentifier IdMgf1					= new DerObjectIdentifier(Pkcs1 + ".8");
+        public static readonly DerObjectIdentifier IdPSpecified				= new DerObjectIdentifier(Pkcs1 + ".9");
+        public static readonly DerObjectIdentifier IdRsassaPss				= new DerObjectIdentifier(Pkcs1 + ".10");
+        public static readonly DerObjectIdentifier Sha256WithRsaEncryption	= new DerObjectIdentifier(Pkcs1 + ".11");
+        public static readonly DerObjectIdentifier Sha384WithRsaEncryption	= new DerObjectIdentifier(Pkcs1 + ".12");
+        public static readonly DerObjectIdentifier Sha512WithRsaEncryption	= new DerObjectIdentifier(Pkcs1 + ".13");
+        public static readonly DerObjectIdentifier Sha224WithRsaEncryption	= new DerObjectIdentifier(Pkcs1 + ".14");
+
+		//
+        // pkcs-3 OBJECT IDENTIFIER ::= {
+        //       iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 3 }
+        //
+        public const string Pkcs3 = "1.2.840.113549.1.3";
+
+		public static readonly DerObjectIdentifier    DhKeyAgreement          = new DerObjectIdentifier(Pkcs3 + ".1");
+
+		//
+        // pkcs-5 OBJECT IDENTIFIER ::= {
+        //       iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 }
+        //
+        public const string Pkcs5 = "1.2.840.113549.1.5";
+
+		public static readonly DerObjectIdentifier PbeWithMD2AndDesCbc    = new DerObjectIdentifier(Pkcs5 + ".1");
+        public static readonly DerObjectIdentifier PbeWithMD2AndRC2Cbc    = new DerObjectIdentifier(Pkcs5 + ".4");
+        public static readonly DerObjectIdentifier PbeWithMD5AndDesCbc    = new DerObjectIdentifier(Pkcs5 + ".3");
+        public static readonly DerObjectIdentifier PbeWithMD5AndRC2Cbc    = new DerObjectIdentifier(Pkcs5 + ".6");
+        public static readonly DerObjectIdentifier PbeWithSha1AndDesCbc   = new DerObjectIdentifier(Pkcs5 + ".10");
+        public static readonly DerObjectIdentifier PbeWithSha1AndRC2Cbc   = new DerObjectIdentifier(Pkcs5 + ".11");
+
+        public static readonly DerObjectIdentifier IdPbeS2 = new DerObjectIdentifier(Pkcs5 + ".13");
+        public static readonly DerObjectIdentifier IdPbkdf2	= new DerObjectIdentifier(Pkcs5 + ".12");
+
+		//
+        // encryptionAlgorithm OBJECT IDENTIFIER ::= {
+        //       iso(1) member-body(2) us(840) rsadsi(113549) 3 }
+        //
+        public const string EncryptionAlgorithm = "1.2.840.113549.3";
+
+		public static readonly DerObjectIdentifier DesEde3Cbc	= new DerObjectIdentifier(EncryptionAlgorithm + ".7");
+        public static readonly DerObjectIdentifier RC2Cbc		= new DerObjectIdentifier(EncryptionAlgorithm + ".2");
+
+		//
+        // object identifiers for digests
+        //
+        public const string DigestAlgorithm = "1.2.840.113549.2";
+
+		//
+        // md2 OBJECT IDENTIFIER ::=
+        //      {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 2}
+        //
+        public static readonly DerObjectIdentifier MD2 = new DerObjectIdentifier(DigestAlgorithm + ".2");
+
+        //
+        // md4 OBJECT IDENTIFIER ::=
+        //      {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 4}
+        //
+        public static readonly DerObjectIdentifier MD4 = new DerObjectIdentifier(DigestAlgorithm + ".4");
+
+        //
+        // md5 OBJECT IDENTIFIER ::=
+        //      {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 5}
+        //
+        public static readonly DerObjectIdentifier MD5 = new DerObjectIdentifier(DigestAlgorithm + ".5");
+
+		public static readonly DerObjectIdentifier IdHmacWithSha1	= new DerObjectIdentifier(DigestAlgorithm + ".7");
+        public static readonly DerObjectIdentifier IdHmacWithSha224	= new DerObjectIdentifier(DigestAlgorithm + ".8");
+        public static readonly DerObjectIdentifier IdHmacWithSha256	= new DerObjectIdentifier(DigestAlgorithm + ".9");
+        public static readonly DerObjectIdentifier IdHmacWithSha384	= new DerObjectIdentifier(DigestAlgorithm + ".10");
+        public static readonly DerObjectIdentifier IdHmacWithSha512	= new DerObjectIdentifier(DigestAlgorithm + ".11");
+
+		//
+        // pkcs-7 OBJECT IDENTIFIER ::= {
+        //       iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 }
+        //
+        public const string Pkcs7 = "1.2.840.113549.1.7";
+
+		public static readonly DerObjectIdentifier Data                    = new DerObjectIdentifier(Pkcs7 + ".1");
+        public static readonly DerObjectIdentifier SignedData              = new DerObjectIdentifier(Pkcs7 + ".2");
+        public static readonly DerObjectIdentifier EnvelopedData           = new DerObjectIdentifier(Pkcs7 + ".3");
+        public static readonly DerObjectIdentifier SignedAndEnvelopedData  = new DerObjectIdentifier(Pkcs7 + ".4");
+        public static readonly DerObjectIdentifier DigestedData            = new DerObjectIdentifier(Pkcs7 + ".5");
+        public static readonly DerObjectIdentifier EncryptedData           = new DerObjectIdentifier(Pkcs7 + ".6");
+
+        //
+        // pkcs-9 OBJECT IDENTIFIER ::= {
+        //       iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 }
+        //
+        public const string Pkcs9 = "1.2.840.113549.1.9";
+
+		public static readonly DerObjectIdentifier Pkcs9AtEmailAddress					= new DerObjectIdentifier(Pkcs9 + ".1");
+        public static readonly DerObjectIdentifier Pkcs9AtUnstructuredName				= new DerObjectIdentifier(Pkcs9 + ".2");
+        public static readonly DerObjectIdentifier Pkcs9AtContentType					= new DerObjectIdentifier(Pkcs9 + ".3");
+        public static readonly DerObjectIdentifier Pkcs9AtMessageDigest					= new DerObjectIdentifier(Pkcs9 + ".4");
+        public static readonly DerObjectIdentifier Pkcs9AtSigningTime					= new DerObjectIdentifier(Pkcs9 + ".5");
+        public static readonly DerObjectIdentifier Pkcs9AtCounterSignature				= new DerObjectIdentifier(Pkcs9 + ".6");
+        public static readonly DerObjectIdentifier Pkcs9AtChallengePassword				= new DerObjectIdentifier(Pkcs9 + ".7");
+        public static readonly DerObjectIdentifier Pkcs9AtUnstructuredAddress			= new DerObjectIdentifier(Pkcs9 + ".8");
+        public static readonly DerObjectIdentifier Pkcs9AtExtendedCertificateAttributes	= new DerObjectIdentifier(Pkcs9 + ".9");
+        public static readonly DerObjectIdentifier Pkcs9AtSigningDescription			= new DerObjectIdentifier(Pkcs9 + ".13");
+        public static readonly DerObjectIdentifier Pkcs9AtExtensionRequest				= new DerObjectIdentifier(Pkcs9 + ".14");
+        public static readonly DerObjectIdentifier Pkcs9AtSmimeCapabilities				= new DerObjectIdentifier(Pkcs9 + ".15");
+        public static readonly DerObjectIdentifier Pkcs9AtFriendlyName					= new DerObjectIdentifier(Pkcs9 + ".20");
+        public static readonly DerObjectIdentifier Pkcs9AtLocalKeyID					= new DerObjectIdentifier(Pkcs9 + ".21");
+
+		[Obsolete("Use X509Certificate instead")]
+        public static readonly DerObjectIdentifier X509CertType = new DerObjectIdentifier(Pkcs9 + ".22.1");
+
+		public const string CertTypes = Pkcs9 + ".22";
+		public static readonly DerObjectIdentifier X509Certificate = new DerObjectIdentifier(CertTypes + ".1");
+		public static readonly DerObjectIdentifier SdsiCertificate = new DerObjectIdentifier(CertTypes + ".2");
+
+		public const string CrlTypes = Pkcs9 + ".23";
+		public static readonly DerObjectIdentifier X509Crl = new DerObjectIdentifier(CrlTypes + ".1");
+
+		public static readonly DerObjectIdentifier IdAlgPwriKek = new DerObjectIdentifier(Pkcs9 + ".16.3.9");
+
+        //
+        // SMIME capability sub oids.
+        //
+        public static readonly DerObjectIdentifier PreferSignedData				= new DerObjectIdentifier(Pkcs9 + ".15.1");
+        public static readonly DerObjectIdentifier CannotDecryptAny				= new DerObjectIdentifier(Pkcs9 + ".15.2");
+        public static readonly DerObjectIdentifier SmimeCapabilitiesVersions	= new DerObjectIdentifier(Pkcs9 + ".15.3");
+
+        //
+        // other SMIME attributes
+        //
+		public static readonly DerObjectIdentifier IdAAReceiptRequest = new DerObjectIdentifier(Pkcs9 + ".16.2.1");
+
+        //
+        // id-ct OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
+        // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1)}
+        //
+        public const string IdCT = "1.2.840.113549.1.9.16.1";
+
+        public static readonly DerObjectIdentifier IdCTAuthData          = new DerObjectIdentifier(IdCT + ".2");
+        public static readonly DerObjectIdentifier IdCTTstInfo           = new DerObjectIdentifier(IdCT + ".4");
+        public static readonly DerObjectIdentifier IdCTCompressedData    = new DerObjectIdentifier(IdCT + ".9");
+		public static readonly DerObjectIdentifier IdCTAuthEnvelopedData = new DerObjectIdentifier(IdCT + ".23");
+		public static readonly DerObjectIdentifier IdCTTimestampedData   = new DerObjectIdentifier(IdCT + ".31");
+
+        //
+        // id-cti OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
+        // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) cti(6)}
+        //
+        public const string IdCti = "1.2.840.113549.1.9.16.6";
+
+        public static readonly DerObjectIdentifier IdCtiEtsProofOfOrigin	= new DerObjectIdentifier(IdCti + ".1");
+        public static readonly DerObjectIdentifier IdCtiEtsProofOfReceipt	= new DerObjectIdentifier(IdCti + ".2");
+        public static readonly DerObjectIdentifier IdCtiEtsProofOfDelivery	= new DerObjectIdentifier(IdCti + ".3");
+        public static readonly DerObjectIdentifier IdCtiEtsProofOfSender	= new DerObjectIdentifier(IdCti + ".4");
+        public static readonly DerObjectIdentifier IdCtiEtsProofOfApproval	= new DerObjectIdentifier(IdCti + ".5");
+        public static readonly DerObjectIdentifier IdCtiEtsProofOfCreation	= new DerObjectIdentifier(IdCti + ".6");
+
+        //
+        // id-aa OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
+        // rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) attributes(2)}
+        //
+        public const string IdAA = "1.2.840.113549.1.9.16.2";
+
+		public static readonly DerObjectIdentifier IdAAContentHint = new DerObjectIdentifier(IdAA + ".4"); // See RFC 2634
+    	public static readonly DerObjectIdentifier IdAAMsgSigDigest = new DerObjectIdentifier(IdAA + ".5");
+    	public static readonly DerObjectIdentifier IdAAContentReference = new DerObjectIdentifier(IdAA + ".10");
+
+		/*
+        * id-aa-encrypKeyPref OBJECT IDENTIFIER ::= {id-aa 11}
+        *
+        */
+        public static readonly DerObjectIdentifier IdAAEncrypKeyPref = new DerObjectIdentifier(IdAA + ".11");
+        public static readonly DerObjectIdentifier IdAASigningCertificate = new DerObjectIdentifier(IdAA + ".12");
+		public static readonly DerObjectIdentifier IdAASigningCertificateV2 = new DerObjectIdentifier(IdAA + ".47");
+
+		public static readonly DerObjectIdentifier IdAAContentIdentifier = new DerObjectIdentifier(IdAA + ".7"); // See RFC 2634
+
+		/*
+		 * RFC 3126
+		 */
+		public static readonly DerObjectIdentifier IdAASignatureTimeStampToken = new DerObjectIdentifier(IdAA + ".14");
+
+		public static readonly DerObjectIdentifier IdAAEtsSigPolicyID = new DerObjectIdentifier(IdAA + ".15");
+		public static readonly DerObjectIdentifier IdAAEtsCommitmentType = new DerObjectIdentifier(IdAA + ".16");
+		public static readonly DerObjectIdentifier IdAAEtsSignerLocation = new DerObjectIdentifier(IdAA + ".17");
+		public static readonly DerObjectIdentifier IdAAEtsSignerAttr = new DerObjectIdentifier(IdAA + ".18");
+		public static readonly DerObjectIdentifier IdAAEtsOtherSigCert = new DerObjectIdentifier(IdAA + ".19");
+		public static readonly DerObjectIdentifier IdAAEtsContentTimestamp = new DerObjectIdentifier(IdAA + ".20");
+		public static readonly DerObjectIdentifier IdAAEtsCertificateRefs = new DerObjectIdentifier(IdAA + ".21");
+		public static readonly DerObjectIdentifier IdAAEtsRevocationRefs = new DerObjectIdentifier(IdAA + ".22");
+		public static readonly DerObjectIdentifier IdAAEtsCertValues = new DerObjectIdentifier(IdAA + ".23");
+		public static readonly DerObjectIdentifier IdAAEtsRevocationValues = new DerObjectIdentifier(IdAA + ".24");
+		public static readonly DerObjectIdentifier IdAAEtsEscTimeStamp = new DerObjectIdentifier(IdAA + ".25");
+		public static readonly DerObjectIdentifier IdAAEtsCertCrlTimestamp = new DerObjectIdentifier(IdAA + ".26");
+		public static readonly DerObjectIdentifier IdAAEtsArchiveTimestamp = new DerObjectIdentifier(IdAA + ".27");
+
+		[Obsolete("Use 'IdAAEtsSigPolicyID' instead")]
+		public static readonly DerObjectIdentifier IdAASigPolicyID = IdAAEtsSigPolicyID;
+		[Obsolete("Use 'IdAAEtsCommitmentType' instead")]
+		public static readonly DerObjectIdentifier IdAACommitmentType = IdAAEtsCommitmentType;
+		[Obsolete("Use 'IdAAEtsSignerLocation' instead")]
+		public static readonly DerObjectIdentifier IdAASignerLocation = IdAAEtsSignerLocation;
+		[Obsolete("Use 'IdAAEtsOtherSigCert' instead")]
+		public static readonly DerObjectIdentifier IdAAOtherSigCert = IdAAEtsOtherSigCert;
+
+		//
+		// id-spq OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
+		// rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) id-spq(5)}
+		//
+		public const string IdSpq = "1.2.840.113549.1.9.16.5";
+
+		public static readonly DerObjectIdentifier IdSpqEtsUri = new DerObjectIdentifier(IdSpq + ".1");
+		public static readonly DerObjectIdentifier IdSpqEtsUNotice = new DerObjectIdentifier(IdSpq + ".2");
+
+		//
+        // pkcs-12 OBJECT IDENTIFIER ::= {
+        //       iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 }
+        //
+        public const string Pkcs12 = "1.2.840.113549.1.12";
+        public const string BagTypes = Pkcs12 + ".10.1";
+
+        public static readonly DerObjectIdentifier KeyBag				= new DerObjectIdentifier(BagTypes + ".1");
+        public static readonly DerObjectIdentifier Pkcs8ShroudedKeyBag	= new DerObjectIdentifier(BagTypes + ".2");
+        public static readonly DerObjectIdentifier CertBag				= new DerObjectIdentifier(BagTypes + ".3");
+        public static readonly DerObjectIdentifier CrlBag				= new DerObjectIdentifier(BagTypes + ".4");
+        public static readonly DerObjectIdentifier SecretBag			= new DerObjectIdentifier(BagTypes + ".5");
+        public static readonly DerObjectIdentifier SafeContentsBag		= new DerObjectIdentifier(BagTypes + ".6");
+
+        public const string Pkcs12PbeIds = Pkcs12 + ".1";
+
+        public static readonly DerObjectIdentifier PbeWithShaAnd128BitRC4			= new DerObjectIdentifier(Pkcs12PbeIds + ".1");
+        public static readonly DerObjectIdentifier PbeWithShaAnd40BitRC4			= new DerObjectIdentifier(Pkcs12PbeIds + ".2");
+        public static readonly DerObjectIdentifier PbeWithShaAnd3KeyTripleDesCbc	= new DerObjectIdentifier(Pkcs12PbeIds + ".3");
+        public static readonly DerObjectIdentifier PbeWithShaAnd2KeyTripleDesCbc	= new DerObjectIdentifier(Pkcs12PbeIds + ".4");
+        public static readonly DerObjectIdentifier PbeWithShaAnd128BitRC2Cbc		= new DerObjectIdentifier(Pkcs12PbeIds + ".5");
+        public static readonly DerObjectIdentifier PbewithShaAnd40BitRC2Cbc			= new DerObjectIdentifier(Pkcs12PbeIds + ".6");
+
+		public static readonly DerObjectIdentifier IdAlgCms3DesWrap = new DerObjectIdentifier("1.2.840.113549.1.9.16.3.6");
+		public static readonly DerObjectIdentifier IdAlgCmsRC2Wrap = new DerObjectIdentifier("1.2.840.113549.1.9.16.3.7");
+	}
+}
diff --git a/crypto/src/asn1/pkcs/Pfx.cs b/crypto/src/asn1/pkcs/Pfx.cs
new file mode 100644
index 000000000..9676f64fc
--- /dev/null
+++ b/crypto/src/asn1/pkcs/Pfx.cs
@@ -0,0 +1,65 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Math;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    /**
+     * the infamous Pfx from Pkcs12
+     */
+    public class Pfx
+        : Asn1Encodable
+    {
+        private ContentInfo	contentInfo;
+        private MacData		macData;
+
+		public Pfx(
+            Asn1Sequence seq)
+        {
+            BigInteger version = ((DerInteger) seq[0]).Value;
+            if (version.IntValue != 3)
+            {
+                throw new ArgumentException("wrong version for PFX PDU");
+            }
+
+			contentInfo = ContentInfo.GetInstance(seq[1]);
+
+			if (seq.Count == 3)
+            {
+                macData = MacData.GetInstance(seq[2]);
+            }
+        }
+
+		public Pfx(
+            ContentInfo	contentInfo,
+            MacData		macData)
+        {
+            this.contentInfo = contentInfo;
+            this.macData = macData;
+        }
+
+		public ContentInfo AuthSafe
+		{
+			get { return contentInfo; }
+		}
+
+		public MacData MacData
+		{
+			get { return macData; }
+		}
+
+		public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(
+				new DerInteger(3), contentInfo);
+
+			if (macData != null)
+            {
+                v.Add(macData);
+            }
+
+			return new BerSequence(v);
+        }
+    }
+}
diff --git a/crypto/src/asn1/pkcs/PrivateKeyInfo.cs b/crypto/src/asn1/pkcs/PrivateKeyInfo.cs
index bd0ef7d1e..404277ba6 100644
--- a/crypto/src/asn1/pkcs/PrivateKeyInfo.cs
+++ b/crypto/src/asn1/pkcs/PrivateKeyInfo.cs
@@ -10,88 +10,100 @@ 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");
+                throw new ArgumentException("wrong version for private key info: " + version.IntValue);
             }
 
-			e.MoveNext();
+            e.MoveNext();
             algID = AlgorithmIdentifier.GetInstance(e.Current);
+            e.MoveNext();
+            privKey = Asn1OctetString.GetInstance(e.Current);
 
-			try
+            if (e.MoveNext())
             {
-				e.MoveNext();
-				Asn1OctetString data = (Asn1OctetString) e.Current;
-
-				privKey = Asn1Object.FromByteArray(data.GetOctets());
-            }
-            catch (IOException)
-            {
-				throw new ArgumentException("Error recoverying private key from sequence");
+                attributes = Asn1Set.GetInstance((Asn1TaggedObject)e.Current, false);
             }
+        }
+
+        public virtual AlgorithmIdentifier PrivateKeyAlgorithm
+        {
+            get { return algID; }
+        }
 
-			if (e.MoveNext())
-			{
-				attributes = Asn1Set.GetInstance((Asn1TaggedObject) e.Current, false);
-			}
-		}
+        [Obsolete("Use 'PrivateKeyAlgorithm' property instead")]
+        public virtual AlgorithmIdentifier AlgorithmID
+        {
+            get { return algID; }
+        }
 
-		public AlgorithmIdentifier AlgorithmID
-		{
-			get { return algID; }
-		}
+        public virtual Asn1Object ParsePrivateKey()
+        {
+            return Asn1Object.FromByteArray(privKey.GetOctets());
+        }
 
-		public Asn1Object PrivateKey
-		{
-			get { return privKey; }
-		}
+        [Obsolete("Use 'ParsePrivateKey' instead")]
+        public virtual Asn1Object PrivateKey
+        {
+            get
+            {
+                try
+                {
+                    return ParsePrivateKey();
+                }
+                catch (IOException)
+                {
+                    throw new InvalidOperationException("unable to parse private key");
+                }
+            }
+        }
 
-    	public Asn1Set Attributes
-    	{
-    		get { return attributes; }
-    	}
+        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/asn1/pkcs/RC2CBCParameter.cs b/crypto/src/asn1/pkcs/RC2CBCParameter.cs
new file mode 100644
index 000000000..f5355d012
--- /dev/null
+++ b/crypto/src/asn1/pkcs/RC2CBCParameter.cs
@@ -0,0 +1,81 @@
+using System;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    public class RC2CbcParameter
+        : Asn1Encodable
+    {
+        internal DerInteger			version;
+        internal Asn1OctetString	iv;
+
+		public static RC2CbcParameter GetInstance(
+            object obj)
+        {
+            if (obj is Asn1Sequence)
+            {
+                return new RC2CbcParameter((Asn1Sequence) obj);
+            }
+
+			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+		}
+
+		public RC2CbcParameter(
+            byte[] iv)
+        {
+            this.iv = new DerOctetString(iv);
+        }
+
+		public RC2CbcParameter(
+            int		parameterVersion,
+            byte[]	iv)
+        {
+            this.version = new DerInteger(parameterVersion);
+            this.iv = new DerOctetString(iv);
+        }
+
+		private RC2CbcParameter(
+            Asn1Sequence seq)
+        {
+            if (seq.Count == 1)
+            {
+                iv = (Asn1OctetString)seq[0];
+            }
+            else
+            {
+                version = (DerInteger)seq[0];
+                iv = (Asn1OctetString)seq[1];
+            }
+        }
+
+		public BigInteger RC2ParameterVersion
+        {
+            get
+            {
+				return version == null ? null : version.Value;
+            }
+        }
+
+		public byte[] GetIV()
+        {
+			return Arrays.Clone(iv.GetOctets());
+        }
+
+		public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector();
+
+			if (version != null)
+            {
+                v.Add(version);
+            }
+
+			v.Add(iv);
+
+			return new DerSequence(v);
+        }
+    }
+}
diff --git a/crypto/src/asn1/pkcs/RSAESOAEPparams.cs b/crypto/src/asn1/pkcs/RSAESOAEPparams.cs
new file mode 100644
index 000000000..5ecb394fd
--- /dev/null
+++ b/crypto/src/asn1/pkcs/RSAESOAEPparams.cs
@@ -0,0 +1,145 @@
+using System;
+
+using Org.BouncyCastle.Asn1.Oiw;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+	public class RsaesOaepParameters
+		: Asn1Encodable
+	{
+		private AlgorithmIdentifier hashAlgorithm;
+		private AlgorithmIdentifier maskGenAlgorithm;
+		private AlgorithmIdentifier pSourceAlgorithm;
+
+		public readonly static AlgorithmIdentifier DefaultHashAlgorithm = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
+		public readonly static AlgorithmIdentifier DefaultMaskGenFunction = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, DefaultHashAlgorithm);
+		public readonly static AlgorithmIdentifier DefaultPSourceAlgorithm = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPSpecified, new DerOctetString(new byte[0]));
+
+		public static RsaesOaepParameters GetInstance(
+			object obj)
+		{
+			if (obj is RsaesOaepParameters)
+			{
+				return (RsaesOaepParameters)obj;
+			}
+			else if (obj is Asn1Sequence)
+			{
+				return new RsaesOaepParameters((Asn1Sequence)obj);
+			}
+
+			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+		}
+
+		/**
+		 * The default version
+		 */
+		public RsaesOaepParameters()
+		{
+			hashAlgorithm = DefaultHashAlgorithm;
+			maskGenAlgorithm = DefaultMaskGenFunction;
+			pSourceAlgorithm = DefaultPSourceAlgorithm;
+		}
+
+		public RsaesOaepParameters(
+			AlgorithmIdentifier hashAlgorithm,
+			AlgorithmIdentifier maskGenAlgorithm,
+			AlgorithmIdentifier pSourceAlgorithm)
+		{
+			this.hashAlgorithm = hashAlgorithm;
+			this.maskGenAlgorithm = maskGenAlgorithm;
+			this.pSourceAlgorithm = pSourceAlgorithm;
+		}
+
+		public RsaesOaepParameters(
+			Asn1Sequence seq)
+		{
+			hashAlgorithm = DefaultHashAlgorithm;
+			maskGenAlgorithm = DefaultMaskGenFunction;
+			pSourceAlgorithm = DefaultPSourceAlgorithm;
+
+			for (int i = 0; i != seq.Count; i++)
+			{
+				Asn1TaggedObject o = (Asn1TaggedObject)seq[i];
+
+				switch (o.TagNo)
+				{
+					case 0:
+						hashAlgorithm = AlgorithmIdentifier.GetInstance(o, true);
+						break;
+					case 1:
+						maskGenAlgorithm = AlgorithmIdentifier.GetInstance(o, true);
+						break;
+					case 2:
+						pSourceAlgorithm = AlgorithmIdentifier.GetInstance(o, true);
+						break;
+					default:
+						throw new ArgumentException("unknown tag");
+				}
+			}
+		}
+
+		public AlgorithmIdentifier HashAlgorithm
+		{
+			get { return hashAlgorithm; }
+		}
+
+		public AlgorithmIdentifier MaskGenAlgorithm
+		{
+			get { return maskGenAlgorithm; }
+		}
+
+		public AlgorithmIdentifier PSourceAlgorithm
+		{
+			get { return pSourceAlgorithm; }
+		}
+
+		/**
+		 * <pre>
+		 *  RSAES-OAEP-params ::= SEQUENCE {
+		 *     hashAlgorithm      [0] OAEP-PSSDigestAlgorithms     DEFAULT sha1,
+		 *     maskGenAlgorithm   [1] PKCS1MGFAlgorithms  DEFAULT mgf1SHA1,
+		 *     pSourceAlgorithm   [2] PKCS1PSourceAlgorithms  DEFAULT pSpecifiedEmpty
+		 *   }
+		 *
+		 *   OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
+		 *     { OID id-sha1 PARAMETERS NULL   }|
+		 *     { OID id-sha256 PARAMETERS NULL }|
+		 *     { OID id-sha384 PARAMETERS NULL }|
+		 *     { OID id-sha512 PARAMETERS NULL },
+		 *     ...  -- Allows for future expansion --
+		 *   }
+		 *   PKCS1MGFAlgorithms    ALGORITHM-IDENTIFIER ::= {
+		 *     { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
+		 *    ...  -- Allows for future expansion --
+		 *   }
+		 *   PKCS1PSourceAlgorithms    ALGORITHM-IDENTIFIER ::= {
+		 *     { OID id-pSpecified PARAMETERS OCTET STRING },
+		 *     ...  -- Allows for future expansion --
+		 *  }
+		 * </pre>
+		 * @return the asn1 primitive representing the parameters.
+		 */
+		public override Asn1Object ToAsn1Object()
+		{
+			Asn1EncodableVector v = new Asn1EncodableVector();
+
+			if (!hashAlgorithm.Equals(DefaultHashAlgorithm))
+			{
+				v.Add(new DerTaggedObject(true, 0, hashAlgorithm));
+			}
+
+			if (!maskGenAlgorithm.Equals(DefaultMaskGenFunction))
+			{
+				v.Add(new DerTaggedObject(true, 1, maskGenAlgorithm));
+			}
+
+			if (!pSourceAlgorithm.Equals(DefaultPSourceAlgorithm))
+			{
+				v.Add(new DerTaggedObject(true, 2, pSourceAlgorithm));
+			}
+
+			return new DerSequence(v);
+		}
+	}
+}
diff --git a/crypto/src/asn1/pkcs/RSAPrivateKeyStructure.cs b/crypto/src/asn1/pkcs/RSAPrivateKeyStructure.cs
index dbb07c744..721299105 100644
--- a/crypto/src/asn1/pkcs/RSAPrivateKeyStructure.cs
+++ b/crypto/src/asn1/pkcs/RSAPrivateKeyStructure.cs
@@ -18,7 +18,21 @@ namespace Org.BouncyCastle.Asn1.Pkcs
         private readonly BigInteger	exponent2;
         private readonly BigInteger	coefficient;
 
-		public RsaPrivateKeyStructure(
+        public static RsaPrivateKeyStructure GetInstance(Asn1TaggedObject obj, bool isExplicit)
+        {
+            return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
+        }
+
+        public static RsaPrivateKeyStructure GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is RsaPrivateKeyStructure)
+                return (RsaPrivateKeyStructure)obj;
+            return new RsaPrivateKeyStructure(Asn1Sequence.GetInstance(obj));
+        }
+
+        public RsaPrivateKeyStructure(
             BigInteger	modulus,
             BigInteger	publicExponent,
             BigInteger	privateExponent,
@@ -38,64 +52,65 @@ namespace Org.BouncyCastle.Asn1.Pkcs
             this.coefficient = coefficient;
         }
 
-		public RsaPrivateKeyStructure(
+        [Obsolete("Use 'GetInstance' method(s) instead")]
+        public RsaPrivateKeyStructure(
             Asn1Sequence seq)
         {
-			BigInteger version = ((DerInteger) seq[0]).Value;
-			if (version.IntValue != 0)
+            BigInteger version = ((DerInteger) seq[0]).Value;
+            if (version.IntValue != 0)
                 throw new ArgumentException("wrong version for RSA private key");
 
-			modulus = ((DerInteger) seq[1]).Value;
-			publicExponent = ((DerInteger) seq[2]).Value;
-			privateExponent = ((DerInteger) seq[3]).Value;
-			prime1 = ((DerInteger) seq[4]).Value;
-			prime2 = ((DerInteger) seq[5]).Value;
-			exponent1 = ((DerInteger) seq[6]).Value;
-			exponent2 = ((DerInteger) seq[7]).Value;
-			coefficient = ((DerInteger) seq[8]).Value;
-		}
-
-		public BigInteger Modulus
-		{
-			get { return modulus; }
-		}
-
-		public BigInteger PublicExponent
-		{
-			get { return publicExponent; }
-		}
-
-		public BigInteger PrivateExponent
-		{
-			get { return privateExponent; }
-		}
-
-		public BigInteger Prime1
-		{
-			get { return prime1; }
-		}
-
-		public BigInteger Prime2
-		{
-			get { return prime2; }
-		}
-
-		public BigInteger Exponent1
-		{
-			get { return exponent1; }
-		}
-
-		public BigInteger Exponent2
-		{
-			get { return exponent2; }
-		}
-
-		public BigInteger Coefficient
-		{
-			get { return coefficient; }
-		}
-
-		/**
+            modulus = ((DerInteger) seq[1]).Value;
+            publicExponent = ((DerInteger) seq[2]).Value;
+            privateExponent = ((DerInteger) seq[3]).Value;
+            prime1 = ((DerInteger) seq[4]).Value;
+            prime2 = ((DerInteger) seq[5]).Value;
+            exponent1 = ((DerInteger) seq[6]).Value;
+            exponent2 = ((DerInteger) seq[7]).Value;
+            coefficient = ((DerInteger) seq[8]).Value;
+        }
+
+        public BigInteger Modulus
+        {
+            get { return modulus; }
+        }
+
+        public BigInteger PublicExponent
+        {
+            get { return publicExponent; }
+        }
+
+        public BigInteger PrivateExponent
+        {
+            get { return privateExponent; }
+        }
+
+        public BigInteger Prime1
+        {
+            get { return prime1; }
+        }
+
+        public BigInteger Prime2
+        {
+            get { return prime2; }
+        }
+
+        public BigInteger Exponent1
+        {
+            get { return exponent1; }
+        }
+
+        public BigInteger Exponent2
+        {
+            get { return exponent2; }
+        }
+
+        public BigInteger Coefficient
+        {
+            get { return coefficient; }
+        }
+
+        /**
          * This outputs the key in Pkcs1v2 format.
          * <pre>
          *      RsaPrivateKey ::= Sequence {
@@ -116,16 +131,16 @@ namespace Org.BouncyCastle.Asn1.Pkcs
          */
         public override Asn1Object ToAsn1Object()
         {
-			return new DerSequence(
-				new DerInteger(0), // version
-				new DerInteger(Modulus),
-				new DerInteger(PublicExponent),
-				new DerInteger(PrivateExponent),
-				new DerInteger(Prime1),
-				new DerInteger(Prime2),
-				new DerInteger(Exponent1),
-				new DerInteger(Exponent2),
-				new DerInteger(Coefficient));
+            return new DerSequence(
+                new DerInteger(0), // version
+                new DerInteger(Modulus),
+                new DerInteger(PublicExponent),
+                new DerInteger(PrivateExponent),
+                new DerInteger(Prime1),
+                new DerInteger(Prime2),
+                new DerInteger(Exponent1),
+                new DerInteger(Exponent2),
+                new DerInteger(Coefficient));
         }
     }
 }
diff --git a/crypto/src/asn1/pkcs/RSASSAPSSparams.cs b/crypto/src/asn1/pkcs/RSASSAPSSparams.cs
new file mode 100644
index 000000000..941620761
--- /dev/null
+++ b/crypto/src/asn1/pkcs/RSASSAPSSparams.cs
@@ -0,0 +1,165 @@
+using System;
+
+using Org.BouncyCastle.Asn1.Oiw;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+	public class RsassaPssParameters
+		: Asn1Encodable
+	{
+		private AlgorithmIdentifier hashAlgorithm;
+		private AlgorithmIdentifier maskGenAlgorithm;
+		private DerInteger saltLength;
+		private DerInteger trailerField;
+
+		public readonly static AlgorithmIdentifier DefaultHashAlgorithm = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
+		public readonly static AlgorithmIdentifier DefaultMaskGenFunction = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, DefaultHashAlgorithm);
+		public readonly static DerInteger DefaultSaltLength = new DerInteger(20);
+		public readonly static DerInteger DefaultTrailerField = new DerInteger(1);
+
+		public static RsassaPssParameters GetInstance(
+			object obj)
+		{
+			if (obj == null || obj is RsassaPssParameters)
+			{
+				return (RsassaPssParameters)obj;
+			}
+
+			if (obj is Asn1Sequence)
+			{
+				return new RsassaPssParameters((Asn1Sequence)obj);
+			}
+
+			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+		}
+
+		/**
+		 * The default version
+		 */
+		public RsassaPssParameters()
+		{
+			hashAlgorithm = DefaultHashAlgorithm;
+			maskGenAlgorithm = DefaultMaskGenFunction;
+			saltLength = DefaultSaltLength;
+			trailerField = DefaultTrailerField;
+		}
+
+		public RsassaPssParameters(
+			AlgorithmIdentifier hashAlgorithm,
+			AlgorithmIdentifier maskGenAlgorithm,
+			DerInteger saltLength,
+			DerInteger trailerField)
+		{
+			this.hashAlgorithm = hashAlgorithm;
+			this.maskGenAlgorithm = maskGenAlgorithm;
+			this.saltLength = saltLength;
+			this.trailerField = trailerField;
+		}
+
+		public RsassaPssParameters(
+			Asn1Sequence seq)
+		{
+			hashAlgorithm = DefaultHashAlgorithm;
+			maskGenAlgorithm = DefaultMaskGenFunction;
+			saltLength = DefaultSaltLength;
+			trailerField = DefaultTrailerField;
+
+			for (int i = 0; i != seq.Count; i++)
+			{
+				Asn1TaggedObject o = (Asn1TaggedObject)seq[i];
+
+				switch (o.TagNo)
+				{
+					case 0:
+						hashAlgorithm = AlgorithmIdentifier.GetInstance(o, true);
+						break;
+					case 1:
+						maskGenAlgorithm = AlgorithmIdentifier.GetInstance(o, true);
+						break;
+					case 2:
+						saltLength = DerInteger.GetInstance(o, true);
+						break;
+					case 3:
+						trailerField = DerInteger.GetInstance(o, true);
+						break;
+					default:
+						throw new ArgumentException("unknown tag");
+				}
+			}
+		}
+
+		public AlgorithmIdentifier HashAlgorithm
+		{
+			get { return hashAlgorithm; }
+		}
+
+		public AlgorithmIdentifier MaskGenAlgorithm
+		{
+			get { return maskGenAlgorithm; }
+		}
+
+		public DerInteger SaltLength
+		{
+			get { return saltLength; }
+		}
+
+		public DerInteger TrailerField
+		{
+			get { return trailerField; }
+		}
+
+		/**
+		 * <pre>
+		 * RSASSA-PSS-params ::= SEQUENCE {
+		 *   hashAlgorithm      [0] OAEP-PSSDigestAlgorithms  DEFAULT sha1,
+		 *    maskGenAlgorithm   [1] PKCS1MGFAlgorithms  DEFAULT mgf1SHA1,
+		 *    saltLength         [2] INTEGER  DEFAULT 20,
+		 *    trailerField       [3] TrailerField  DEFAULT trailerFieldBC
+		 *  }
+		 *
+		 * OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
+		 *    { OID id-sha1 PARAMETERS NULL   }|
+		 *    { OID id-sha256 PARAMETERS NULL }|
+		 *    { OID id-sha384 PARAMETERS NULL }|
+		 *    { OID id-sha512 PARAMETERS NULL },
+		 *    ...  -- Allows for future expansion --
+		 * }
+		 *
+		 * PKCS1MGFAlgorithms    ALGORITHM-IDENTIFIER ::= {
+		 *   { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
+		 *    ...  -- Allows for future expansion --
+		 * }
+		 *
+		 * TrailerField ::= INTEGER { trailerFieldBC(1) }
+		 * </pre>
+		 * @return the asn1 primitive representing the parameters.
+		 */
+		public override Asn1Object ToAsn1Object()
+		{
+			Asn1EncodableVector v = new Asn1EncodableVector();
+
+			if (!hashAlgorithm.Equals(DefaultHashAlgorithm))
+			{
+				v.Add(new DerTaggedObject(true, 0, hashAlgorithm));
+			}
+
+			if (!maskGenAlgorithm.Equals(DefaultMaskGenFunction))
+			{
+				v.Add(new DerTaggedObject(true, 1, maskGenAlgorithm));
+			}
+
+			if (!saltLength.Equals(DefaultSaltLength))
+			{
+				v.Add(new DerTaggedObject(true, 2, saltLength));
+			}
+
+			if (!trailerField.Equals(DefaultTrailerField))
+			{
+				v.Add(new DerTaggedObject(true, 3, trailerField));
+			}
+
+			return new DerSequence(v);
+		}
+	}
+}
diff --git a/crypto/src/asn1/pkcs/SafeBag.cs b/crypto/src/asn1/pkcs/SafeBag.cs
new file mode 100644
index 000000000..4b9350bac
--- /dev/null
+++ b/crypto/src/asn1/pkcs/SafeBag.cs
@@ -0,0 +1,70 @@
+using Org.BouncyCastle.Asn1;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    public class SafeBag
+        : Asn1Encodable
+    {
+        private readonly DerObjectIdentifier bagID;
+        private readonly Asn1Object bagValue;
+        private readonly Asn1Set bagAttributes;
+
+		public SafeBag(
+            DerObjectIdentifier	oid,
+            Asn1Object			obj)
+        {
+            this.bagID = oid;
+            this.bagValue = obj;
+            this.bagAttributes = null;
+        }
+
+		public SafeBag(
+            DerObjectIdentifier	oid,
+            Asn1Object			obj,
+            Asn1Set				bagAttributes)
+        {
+            this.bagID = oid;
+            this.bagValue = obj;
+            this.bagAttributes = bagAttributes;
+        }
+
+		public SafeBag(
+            Asn1Sequence seq)
+        {
+            this.bagID = (DerObjectIdentifier) seq[0];
+            this.bagValue = ((DerTaggedObject) seq[1]).GetObject();
+            if (seq.Count == 3)
+            {
+                this.bagAttributes = (Asn1Set) seq[2];
+            }
+        }
+
+		public DerObjectIdentifier BagID
+		{
+			get { return bagID; }
+		}
+
+		public Asn1Object BagValue
+		{
+			get { return bagValue; }
+		}
+
+		public Asn1Set BagAttributes
+		{
+			get { return bagAttributes; }
+		}
+
+		public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(
+				bagID, new DerTaggedObject(0, bagValue));
+
+			if (bagAttributes != null)
+            {
+                v.Add(bagAttributes);
+            }
+
+			return new DerSequence(v);
+        }
+    }
+}
diff --git a/crypto/src/asn1/pkcs/SignedData.cs b/crypto/src/asn1/pkcs/SignedData.cs
index 10951d37a..6e72bd0a9 100644
--- a/crypto/src/asn1/pkcs/SignedData.cs
+++ b/crypto/src/asn1/pkcs/SignedData.cs
@@ -18,23 +18,17 @@ namespace Org.BouncyCastle.Asn1.Pkcs
         private readonly Asn1Set		crls;
         private readonly Asn1Set		signerInfos;
 
-		public static SignedData GetInstance(
-            object obj)
+        public static SignedData GetInstance(object obj)
         {
-            if (obj is SignedData)
-            {
-                return (SignedData) obj;
-            }
-
-			if (obj is Asn1Sequence)
-            {
-                return new SignedData((Asn1Sequence) obj);
-            }
-
-			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
-		}
+            if (obj == null)
+                return null;
+            SignedData existing = obj as SignedData;
+            if (existing != null)
+                return existing;
+            return new SignedData(Asn1Sequence.GetInstance(obj));
+        }
 
-		public SignedData(
+        public SignedData(
             DerInteger        _version,
             Asn1Set           _digestAlgorithms,
             ContentInfo       _contentInfo,
@@ -50,25 +44,25 @@ namespace Org.BouncyCastle.Asn1.Pkcs
             signerInfos      = _signerInfos;
         }
 
-		private SignedData(
+        private SignedData(
             Asn1Sequence seq)
         {
             IEnumerator e = seq.GetEnumerator();
 
-			e.MoveNext();
+            e.MoveNext();
             version = (DerInteger) e.Current;
 
-			e.MoveNext();
+            e.MoveNext();
             digestAlgorithms = (Asn1Set) e.Current;
 
-			e.MoveNext();
+            e.MoveNext();
             contentInfo = ContentInfo.GetInstance(e.Current);
 
-			while (e.MoveNext())
+            while (e.MoveNext())
             {
                 Asn1Object o = (Asn1Object) e.Current;
 
-				//
+                //
                 // an interesting feature of SignedData is that there appear to be varying implementations...
                 // for the moment we ignore anything which doesn't fit.
                 //
@@ -76,16 +70,16 @@ namespace Org.BouncyCastle.Asn1.Pkcs
                 {
                     DerTaggedObject tagged = (DerTaggedObject) o;
 
-					switch (tagged.TagNo)
+                    switch (tagged.TagNo)
                     {
-						case 0:
-							certificates = Asn1Set.GetInstance(tagged, false);
-							break;
-						case 1:
-							crls = Asn1Set.GetInstance(tagged, false);
-							break;
-						default:
-							throw new ArgumentException("unknown tag value " + tagged.TagNo);
+                        case 0:
+                            certificates = Asn1Set.GetInstance(tagged, false);
+                            break;
+                        case 1:
+                            crls = Asn1Set.GetInstance(tagged, false);
+                            break;
+                        default:
+                            throw new ArgumentException("unknown tag value " + tagged.TagNo);
                     }
                 }
                 else
@@ -95,37 +89,37 @@ namespace Org.BouncyCastle.Asn1.Pkcs
             }
         }
 
-		public DerInteger Version
-		{
-			get { return version; }
-		}
-
-		public Asn1Set DigestAlgorithms
-		{
-			get { return digestAlgorithms; }
-		}
-
-		public ContentInfo ContentInfo
-		{
-			get { return contentInfo; }
-		}
-
-		public Asn1Set Certificates
-		{
-			get { return certificates; }
-		}
-
-		public Asn1Set Crls
-		{
-			get { return crls; }
-		}
-
-		public Asn1Set SignerInfos
-		{
-			get { return signerInfos; }
-		}
-
-		/**
+        public DerInteger Version
+        {
+            get { return version; }
+        }
+
+        public Asn1Set DigestAlgorithms
+        {
+            get { return digestAlgorithms; }
+        }
+
+        public ContentInfo ContentInfo
+        {
+            get { return contentInfo; }
+        }
+
+        public Asn1Set Certificates
+        {
+            get { return certificates; }
+        }
+
+        public Asn1Set Crls
+        {
+            get { return crls; }
+        }
+
+        public Asn1Set SignerInfos
+        {
+            get { return signerInfos; }
+        }
+
+        /**
          * Produce an object suitable for an Asn1OutputStream.
          * <pre>
          *  SignedData ::= Sequence {
@@ -143,21 +137,21 @@ namespace Org.BouncyCastle.Asn1.Pkcs
         public override Asn1Object ToAsn1Object()
         {
             Asn1EncodableVector v = new Asn1EncodableVector(
-				version, digestAlgorithms, contentInfo);
+                version, digestAlgorithms, contentInfo);
 
-			if (certificates != null)
+            if (certificates != null)
             {
                 v.Add(new DerTaggedObject(false, 0, certificates));
             }
 
-			if (crls != null)
+            if (crls != null)
             {
                 v.Add(new DerTaggedObject(false, 1, crls));
             }
 
-			v.Add(signerInfos);
+            v.Add(signerInfos);
 
-			return new BerSequence(v);
+            return new BerSequence(v);
         }
     }
 }
diff --git a/crypto/src/asn1/pkcs/SignerInfo.cs b/crypto/src/asn1/pkcs/SignerInfo.cs
new file mode 100644
index 000000000..1e4694547
--- /dev/null
+++ b/crypto/src/asn1/pkcs/SignerInfo.cs
@@ -0,0 +1,154 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Pkcs
+{
+    /**
+     * a Pkcs#7 signer info object.
+     */
+    public class SignerInfo
+        : Asn1Encodable
+    {
+        private DerInteger              version;
+        private IssuerAndSerialNumber   issuerAndSerialNumber;
+        private AlgorithmIdentifier     digAlgorithm;
+        private Asn1Set                 authenticatedAttributes;
+        private AlgorithmIdentifier     digEncryptionAlgorithm;
+        private Asn1OctetString         encryptedDigest;
+        private Asn1Set                 unauthenticatedAttributes;
+
+		public static SignerInfo GetInstance(
+            object obj)
+        {
+            if (obj is SignerInfo)
+            {
+                return (SignerInfo) obj;
+            }
+
+			if (obj is Asn1Sequence)
+            {
+                return new SignerInfo((Asn1Sequence) obj);
+            }
+
+			throw new ArgumentException("Unknown object in factory: " + obj.GetType().FullName, "obj");
+		}
+
+		public SignerInfo(
+            DerInteger              version,
+            IssuerAndSerialNumber   issuerAndSerialNumber,
+            AlgorithmIdentifier     digAlgorithm,
+            Asn1Set                 authenticatedAttributes,
+            AlgorithmIdentifier     digEncryptionAlgorithm,
+            Asn1OctetString         encryptedDigest,
+            Asn1Set                 unauthenticatedAttributes)
+        {
+            this.version = version;
+            this.issuerAndSerialNumber = issuerAndSerialNumber;
+            this.digAlgorithm = digAlgorithm;
+            this.authenticatedAttributes = authenticatedAttributes;
+            this.digEncryptionAlgorithm = digEncryptionAlgorithm;
+            this.encryptedDigest = encryptedDigest;
+            this.unauthenticatedAttributes = unauthenticatedAttributes;
+        }
+
+		public SignerInfo(
+            Asn1Sequence seq)
+        {
+            IEnumerator e = seq.GetEnumerator();
+
+			e.MoveNext();
+            version = (DerInteger) e.Current;
+
+			e.MoveNext();
+            issuerAndSerialNumber = IssuerAndSerialNumber.GetInstance(e.Current);
+
+			e.MoveNext();
+            digAlgorithm = AlgorithmIdentifier.GetInstance(e.Current);
+
+			e.MoveNext();
+            object obj = e.Current;
+
+			if (obj is Asn1TaggedObject)
+            {
+                authenticatedAttributes = Asn1Set.GetInstance((Asn1TaggedObject) obj, false);
+
+				e.MoveNext();
+                digEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(e.Current);
+            }
+            else
+            {
+                authenticatedAttributes = null;
+                digEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(obj);
+            }
+
+			e.MoveNext();
+            encryptedDigest = DerOctetString.GetInstance(e.Current);
+
+			if (e.MoveNext())
+            {
+                unauthenticatedAttributes = Asn1Set.GetInstance((Asn1TaggedObject)e.Current, false);
+            }
+            else
+            {
+                unauthenticatedAttributes = null;
+            }
+        }
+
+		public DerInteger Version { get { return version; } }
+
+		public IssuerAndSerialNumber IssuerAndSerialNumber { get { return issuerAndSerialNumber; } }
+
+		public Asn1Set AuthenticatedAttributes { get { return authenticatedAttributes; } }
+
+		public AlgorithmIdentifier DigestAlgorithm { get { return digAlgorithm; } }
+
+		public Asn1OctetString EncryptedDigest { get { return encryptedDigest; } }
+
+		public AlgorithmIdentifier DigestEncryptionAlgorithm { get { return digEncryptionAlgorithm; } }
+
+		public Asn1Set UnauthenticatedAttributes { get { return unauthenticatedAttributes; } }
+
+		/**
+         * Produce an object suitable for an Asn1OutputStream.
+         * <pre>
+         *  SignerInfo ::= Sequence {
+         *      version Version,
+         *      issuerAndSerialNumber IssuerAndSerialNumber,
+         *      digestAlgorithm DigestAlgorithmIdentifier,
+         *      authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL,
+         *      digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
+         *      encryptedDigest EncryptedDigest,
+         *      unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL
+         *  }
+         *
+         *  EncryptedDigest ::= OCTET STRING
+         *
+         *  DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+         *
+         *  DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+         * </pre>
+         */
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(
+				version, issuerAndSerialNumber, digAlgorithm);
+
+			if (authenticatedAttributes != null)
+            {
+                v.Add(new DerTaggedObject(false, 0, authenticatedAttributes));
+            }
+
+			v.Add(digEncryptionAlgorithm, encryptedDigest);
+
+			if (unauthenticatedAttributes != null)
+            {
+                v.Add(new DerTaggedObject(false, 1, unauthenticatedAttributes));
+            }
+
+			return new DerSequence(v);
+        }
+    }
+}